| #include <stdio.h> |
| #include <stdlib.h> |
| #include "pic.h" |
| #include "y.tab.h" |
| |
| #define SLOP 1.001 |
| |
| typedef struct { |
| char *var; /* index variable */ |
| double to; /* limit */ |
| double by; |
| int op; /* operator */ |
| char *str; /* string to push back */ |
| } For; |
| |
| For forstk[10]; /* stack of for loops */ |
| For *forp = forstk; /* pointer to current top */ |
| |
| void setfval(char *, double); |
| void nextfor(void); |
| |
| void forloop(char *var, double from, double to, int op, |
| double by, char *str) /* set up a for loop */ |
| { |
| dprintf("# for %s from %g to %g by %c %g \n", |
| var, from, to, op, by); |
| if (++forp >= forstk+10) |
| ERROR "for loop nested too deep" FATAL; |
| forp->var = var; |
| forp->to = to; |
| forp->op = op; |
| forp->by = by; |
| forp->str = str; |
| setfval(var, from); |
| nextfor(); |
| unput('\n'); |
| } |
| |
| void nextfor(void) /* do one iteration of a for loop */ |
| { |
| /* BUG: this should depend on op and direction */ |
| if (getfval(forp->var) > 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 */ |
| { |
| struct symtab *p = lookup(forp->var); |
| |
| switch (forp->op) { |
| case '+': |
| case ' ': |
| p->s_val.f += forp->by; |
| break; |
| case '-': |
| p->s_val.f -= forp->by; |
| break; |
| case '*': |
| p->s_val.f *= forp->by; |
| break; |
| case '/': |
| p->s_val.f /= 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; |
| } |
| } |