plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

for.c (1949B)


      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 
     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 
     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 
     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 
     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 }