|
|
researchv10 Norman
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* @(#)picasso:for.c 1.0 */
#include "picasso.h"
#include "y.tab.h"
#define SLOP 1.001
typedef struct {
struct symtab *sym; /* index variable */
float to; /* limit */
float 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 */
forloop(var, from, to, op, by, str) /* set up a for loop */
char *var;
double from, to, by;
int op;
char *str;
{
if (++forp >= forstk+10)
fatal("for loop nested too deep");
/* note: actually we here want to take a vector variable and construct its */
/* values directly, then access them one at a time below; the current */
/* version is a temporary concession to old pic's version of the 'for' */
forp->sym = findvar(var, VARNAME);
if (forp->sym->s_dim && forp->sym->s_val.a)
free(forp->sym->s_val.a);
forp->sym->s_dim = 0;
forp->sym->s_val.f = from;
forp->to = to;
if (by == 0.)
fatal("step size of 0 not allowed");
/* For additive or subtractive step, make sure step is positive.
Otherwise, make sure step is greater than 1 in absolute value. */
if ((op == ' ' || op == '+') && by < 0.) {
op = '-';
by = -by;
}
else if (op == '-' && by < 0.) {
op = '+';
by = -by;
}
else if (op == '*' && fabs(by) < 1.) {
op = '/';
by = 1 / by;
}
else if (op == '/' && fabs(by) < 1.) {
op = '*';
by = 1 / by;
}
forp->op = op;
forp->by = by;
forp->str = str;
nextfor();
unput('\n');
}
nextfor() /* do one iteration of a for loop */
{
int done;
float v = forp->sym->s_val.f;
switch (forp->op) {
case '+':
case ' ':
done = v > forp->to;
break;
case '-':
done = v < forp->to;
break;
case '*':
done = v * forp->to < 0. ? (fabs(forp->by) > 0)
: (fabs(v) > fabs(forp->to)) ;
break;
case '/':
done = v * forp->to < 0. ? (fabs(forp->by) > 0)
: (fabs(v) < fabs(forp->to)) ;
break;
}
if (done) {
free(forp->str);
if (--forp < forstk)
fatal("forstk popped too far");
} else { /* another iteration */
pushsrc(pString, "\n_Endfor\n");
pushsrc(pString, forp->str);
}
}
endfor() /* end one iteration of for loop */
{
switch (forp->op) {
case '+':
case ' ':
forp->sym->s_val.f += forp->by;
break;
case '-':
forp->sym->s_val.f -= forp->by;
break;
case '*':
forp->sym->s_val.f *= forp->by;
break;
case '/':
forp->sym->s_val.f /= forp->by;
break;
}
nextfor();
}
char *ifstat(expr, thenpart, elsepart)
double expr;
char *thenpart, *elsepart;
{
if (expr) {
unput('\n');
pushsrc(Free, thenpart);
pushsrc(pString, thenpart);
unput('\n');
if (elsepart)
free(elsepart);
return thenpart; /* to be freed later */
} else {
free(thenpart);
if (elsepart) {
unput('\n');
pushsrc(Free, elsepart);
pushsrc(pString, elsepart);
unput('\n');
}
return elsepart;
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.