xref: /plan9/sys/src/cmd/grap/for.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "grap.h"
4 #include "y.tab.h"
5 
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;
13 
14 #define	MAXFOR	10
15 
16 For	forstk[MAXFOR];	/* stack of for loops */
17 For	*forp = forstk;	/* pointer to current top */
18 
forloop(Obj * var,double from,double to,int op,double by,char * str)19 void forloop(Obj *var, double from, double to, int op, double by, char *str)	/* set up a for loop */
20 {
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');
33 }
34 
nextfor(void)35 void nextfor(void)	/* do one iteration of a for loop */
36 {
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);
45 	}
46 }
47 
endfor(void)48 void endfor(void)	/* end one iteration of for loop */
49 {
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;
64 	}
65 	nextfor();
66 }
67 
ifstat(double expr,char * thenpart,char * elsepart)68 char *ifstat(double expr, char *thenpart, char *elsepart)
69 {
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');
86 		}
87 		return elsepart;
88 	}
89 }
90