mkdev: remove devutf/C*
[troff.git] / grap / for.c
blob84de388d4d7ac4f8b82e5e1b2eb344e58640839b
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "grap.h"
4 #include "y.tab.h"
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;
14 #define MAXFOR 10
16 For forstk[MAXFOR]; /* stack of for loops */
17 For *forp = forstk; /* pointer to current top */
19 void forloop(Obj *var, double from, double to, int op, double by, char *str) /* set up a for loop */
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');
35 void nextfor(void) /* do one iteration of a for loop */
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);
48 void endfor(void) /* end one iteration of for loop */
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;
65 nextfor();
68 char *ifstat(double expr, char *thenpart, char *elsepart)
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');
87 return elsepart;