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