]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/grap/for.c
aux/realemu: run cpuproc in same fd group as fileserver
[plan9front.git] / sys / src / cmd / grap / for.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "grap.h"
4 #include "y.tab.h"
5
6 typedef struct {
7         Obj     *var;   /* index variable */
8         double  to;     /* limit */
9         double  by;
10         int     op;     /* operator */
11         char    *str;   /* string to push back */
12 } For;
13
14 #define MAXFOR  10
15
16 For     forstk[MAXFOR]; /* stack of for loops */
17 For     *forp = forstk; /* pointer to current top */
18
19 void forloop(Obj *var, double from, double to, int op, double by, char *str)    /* set up a for loop */
20 {
21         fprintf(tfd, "# for %s from %g to %g by %c %g \n",
22                 var->name, from, to, op, by);
23         if (++forp >= forstk+MAXFOR)
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         setvar(var, from);
31         nextfor();
32         unput('\n');
33 }
34
35 void nextfor(void)      /* do one iteration of a for loop */
36 {
37         /* BUG:  this should depend on op and direction */
38         if (forp->var->fval > SLOP * forp->to) {        /* loop is done */
39                 free(forp->str);
40                 if (--forp < forstk)
41                         ERROR "forstk popped too far" FATAL;
42         } else {                /* another iteration */
43                 pushsrc(String, "\nEndfor\n");
44                 pushsrc(String, forp->str);
45         }
46 }
47
48 void endfor(void)       /* end one iteration of for loop */
49 {
50         switch (forp->op) {
51         case '+':
52         case ' ':
53                 forp->var->fval += forp->by;
54                 break;
55         case '-':
56                 forp->var->fval -= forp->by;
57                 break;
58         case '*':
59                 forp->var->fval *= forp->by;
60                 break;
61         case '/':
62                 forp->var->fval /= forp->by;
63                 break;
64         }
65         nextfor();
66 }
67
68 char *ifstat(double expr, char *thenpart, char *elsepart)
69 {
70         dprintf("if %g then <%s> else <%s>\n", expr, thenpart, elsepart? elsepart : "");
71         if (expr) {
72                 unput('\n');
73                 pushsrc(Free, thenpart);
74                 pushsrc(String, thenpart);
75                 unput('\n');
76                 if (elsepart)
77                         free(elsepart);
78                 return thenpart;        /* to be freed later */
79         } else {
80                 free(thenpart);
81                 if (elsepart) {
82                         unput('\n');
83                         pushsrc(Free, elsepart);
84                         pushsrc(String, elsepart);
85                         unput('\n');
86                 }
87                 return elsepart;
88         }
89 }