diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/grap/for.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/grap/for.c')
-rwxr-xr-x | sys/src/cmd/grap/for.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/sys/src/cmd/grap/for.c b/sys/src/cmd/grap/for.c new file mode 100755 index 000000000..84de388d4 --- /dev/null +++ b/sys/src/cmd/grap/for.c @@ -0,0 +1,89 @@ +#include <stdio.h> +#include <stdlib.h> +#include "grap.h" +#include "y.tab.h" + +typedef struct { + Obj *var; /* index variable */ + double to; /* limit */ + double by; + int op; /* operator */ + char *str; /* string to push back */ +} For; + +#define MAXFOR 10 + +For forstk[MAXFOR]; /* stack of for loops */ +For *forp = forstk; /* pointer to current top */ + +void forloop(Obj *var, double from, double to, int op, double by, char *str) /* set up a for loop */ +{ + fprintf(tfd, "# for %s from %g to %g by %c %g \n", + var->name, from, to, op, by); + if (++forp >= forstk+MAXFOR) + ERROR "for loop nested too deep" FATAL; + forp->var = var; + forp->to = to; + forp->op = op; + forp->by = by; + forp->str = str; + setvar(var, from); + nextfor(); + unput('\n'); +} + +void nextfor(void) /* do one iteration of a for loop */ +{ + /* BUG: this should depend on op and direction */ + if (forp->var->fval > SLOP * forp->to) { /* loop is done */ + free(forp->str); + if (--forp < forstk) + ERROR "forstk popped too far" FATAL; + } else { /* another iteration */ + pushsrc(String, "\nEndfor\n"); + pushsrc(String, forp->str); + } +} + +void endfor(void) /* end one iteration of for loop */ +{ + switch (forp->op) { + case '+': + case ' ': + forp->var->fval += forp->by; + break; + case '-': + forp->var->fval -= forp->by; + break; + case '*': + forp->var->fval *= forp->by; + break; + case '/': + forp->var->fval /= forp->by; + break; + } + nextfor(); +} + +char *ifstat(double expr, char *thenpart, char *elsepart) +{ + dprintf("if %g then <%s> else <%s>\n", expr, thenpart, elsepart? elsepart : ""); + if (expr) { + unput('\n'); + pushsrc(Free, thenpart); + pushsrc(String, thenpart); + unput('\n'); + if (elsepart) + free(elsepart); + return thenpart; /* to be freed later */ + } else { + free(thenpart); + if (elsepart) { + unput('\n'); + pushsrc(Free, elsepart); + pushsrc(String, elsepart); + unput('\n'); + } + return elsepart; + } +} |