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