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