mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
96 lines
1.9 KiB
C
96 lines
1.9 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "pic.h"
|
||
|
#include "y.tab.h"
|
||
|
|
||
|
#define SLOP 1.001
|
||
|
|
||
|
typedef struct {
|
||
|
char *var; /* index variable */
|
||
|
double to; /* limit */
|
||
|
double by;
|
||
|
int op; /* operator */
|
||
|
char *str; /* string to push back */
|
||
|
} For;
|
||
|
|
||
|
For forstk[10]; /* stack of for loops */
|
||
|
For *forp = forstk; /* pointer to current top */
|
||
|
|
||
|
void setfval(char *, double);
|
||
|
void nextfor(void);
|
||
|
|
||
|
void forloop(char *var, double from, double to, int op,
|
||
|
double by, char *str) /* set up a for loop */
|
||
|
{
|
||
|
dprintf("# for %s from %g to %g by %c %g \n",
|
||
|
var, from, to, op, by);
|
||
|
if (++forp >= forstk+10)
|
||
|
ERROR "for loop nested too deep" FATAL;
|
||
|
forp->var = var;
|
||
|
forp->to = to;
|
||
|
forp->op = op;
|
||
|
forp->by = by;
|
||
|
forp->str = str;
|
||
|
setfval(var, from);
|
||
|
nextfor();
|
||
|
unput('\n');
|
||
|
}
|
||
|
|
||
|
void nextfor(void) /* do one iteration of a for loop */
|
||
|
{
|
||
|
/* BUG: this should depend on op and direction */
|
||
|
if (getfval(forp->var) > SLOP * forp->to) { /* loop is done */
|
||
|
free(forp->str);
|
||
|
if (--forp < forstk)
|
||
|
ERROR "forstk popped too far" FATAL;
|
||
|
} else { /* another iteration */
|
||
|
pushsrc(String, "\nEndfor\n");
|
||
|
pushsrc(String, forp->str);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void endfor(void) /* end one iteration of for loop */
|
||
|
{
|
||
|
struct symtab *p = lookup(forp->var);
|
||
|
|
||
|
switch (forp->op) {
|
||
|
case '+':
|
||
|
case ' ':
|
||
|
p->s_val.f += forp->by;
|
||
|
break;
|
||
|
case '-':
|
||
|
p->s_val.f -= forp->by;
|
||
|
break;
|
||
|
case '*':
|
||
|
p->s_val.f *= forp->by;
|
||
|
break;
|
||
|
case '/':
|
||
|
p->s_val.f /= forp->by;
|
||
|
break;
|
||
|
}
|
||
|
nextfor();
|
||
|
}
|
||
|
|
||
|
char *ifstat(double expr, char *thenpart, char *elsepart)
|
||
|
{
|
||
|
dprintf("if %g then <%s> else <%s>\n", expr, thenpart, elsepart? elsepart : "");
|
||
|
if (expr) {
|
||
|
unput('\n');
|
||
|
pushsrc(Free, thenpart);
|
||
|
pushsrc(String, thenpart);
|
||
|
unput('\n');
|
||
|
if (elsepart)
|
||
|
free(elsepart);
|
||
|
return thenpart; /* to be freed later */
|
||
|
} else {
|
||
|
free(thenpart);
|
||
|
if (elsepart) {
|
||
|
unput('\n');
|
||
|
pushsrc(Free, elsepart);
|
||
|
pushsrc(String, elsepart);
|
||
|
unput('\n');
|
||
|
}
|
||
|
return elsepart;
|
||
|
}
|
||
|
}
|