xref: /plan9/sys/src/cmd/pic/for.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
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 
forloop(char * var,double from,double to,int op,double by,char * str)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 
nextfor(void)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 
endfor(void)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 
ifstat(double expr,char * thenpart,char * elsepart)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 }
96