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