diff options
Diffstat (limited to 'src/cmd/grap/for.c')
-rw-r--r-- | src/cmd/grap/for.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/cmd/grap/for.c b/src/cmd/grap/for.c new file mode 100644 index 00000000..84de388d --- /dev/null +++ b/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; + } +} |