rsc | b6d9846 | 2006-04-14 00:04:03 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include "pic.h" |
| 3 | #include "y.tab.h" |
| 4 | |
| 5 | #define SLOP 1.001 |
| 6 | |
| 7 | typedef struct { |
| 8 | char *var; /* index variable */ |
| 9 | double to; /* limit */ |
| 10 | double by; |
| 11 | int op; /* operator */ |
| 12 | char *str; /* string to push back */ |
| 13 | } For; |
| 14 | |
| 15 | For forstk[10]; /* stack of for loops */ |
| 16 | For *forp = forstk; /* pointer to current top */ |
| 17 | |
| 18 | void |
| 19 | forloop(char *var, double from, double to, int op, double by, char *str) /* set up a for loop */ |
| 20 | { |
| 21 | dprintf("# for %s from %g to %g by %c %g \n", |
| 22 | var, from, to, op, by); |
| 23 | if (++forp >= forstk+10) |
| 24 | ERROR "for loop nested too deep" FATAL; |
| 25 | forp->var = var; |
| 26 | forp->to = to; |
| 27 | forp->op = op; |
| 28 | forp->by = by; |
| 29 | forp->str = str; |
| 30 | setfval(var, from); |
| 31 | nextfor(); |
| 32 | unput('\n'); |
| 33 | } |
| 34 | |
| 35 | void |
| 36 | nextfor(void) /* do one iteration of a for loop */ |
| 37 | { |
| 38 | /* BUG: this should depend on op and direction */ |
| 39 | if (getfval(forp->var) > SLOP * forp->to) { /* loop is done */ |
| 40 | free(forp->str); |
| 41 | if (--forp < forstk) |
| 42 | ERROR "forstk popped too far" FATAL; |
| 43 | } else { /* another iteration */ |
| 44 | pushsrc(String, "\nEndfor\n"); |
| 45 | pushsrc(String, forp->str); |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | void |
| 50 | endfor(void) /* end one iteration of for loop */ |
| 51 | { |
| 52 | struct symtab *p = lookup(forp->var); |
| 53 | |
| 54 | switch (forp->op) { |
| 55 | case '+': |
| 56 | case ' ': |
| 57 | p->s_val.f += forp->by; |
| 58 | break; |
| 59 | case '-': |
| 60 | p->s_val.f -= forp->by; |
| 61 | break; |
| 62 | case '*': |
| 63 | p->s_val.f *= forp->by; |
| 64 | break; |
| 65 | case '/': |
| 66 | p->s_val.f /= forp->by; |
| 67 | break; |
| 68 | } |
| 69 | nextfor(); |
| 70 | } |
| 71 | |
| 72 | char* |
| 73 | ifstat(double expr, char *thenpart, char *elsepart) |
| 74 | { |
| 75 | dprintf("if %g then <%s> else <%s>\n", expr, thenpart, elsepart? elsepart : ""); |
| 76 | if (expr) { |
| 77 | unput('\n'); |
| 78 | pushsrc(Free, thenpart); |
| 79 | pushsrc(String, thenpart); |
| 80 | unput('\n'); |
| 81 | if (elsepart) |
| 82 | free(elsepart); |
| 83 | return thenpart; /* to be freed later */ |
| 84 | } else { |
| 85 | free(thenpart); |
| 86 | if (elsepart) { |
| 87 | unput('\n'); |
| 88 | pushsrc(Free, elsepart); |
| 89 | pushsrc(String, elsepart); |
| 90 | unput('\n'); |
| 91 | } |
| 92 | return elsepart; |
| 93 | } |
| 94 | } |