|
|
1.1 root 1: /* Copyright (c) 1988 AT&T */
2: /* All Rights Reserved */
3:
4: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
5: /* The copyright notice above does not evidence any */
6: /* actual or intended publication of such source code. */
7:
8: /* @(#)picasso:for.c 1.0 */
9: #include "picasso.h"
10: #include "y.tab.h"
11:
12: #define SLOP 1.001
13:
14: typedef struct {
15: struct symtab *sym; /* index variable */
16: float to; /* limit */
17: float by;
18: int op; /* operator */
19: char *str; /* string to push back */
20: } For;
21:
22: For forstk[10]; /* stack of for loops */
23: For *forp = forstk; /* pointer to current top */
24:
25: forloop(var, from, to, op, by, str) /* set up a for loop */
26: char *var;
27: double from, to, by;
28: int op;
29: char *str;
30: {
31: if (++forp >= forstk+10)
32: fatal("for loop nested too deep");
33:
34: /* note: actually we here want to take a vector variable and construct its */
35: /* values directly, then access them one at a time below; the current */
36: /* version is a temporary concession to old pic's version of the 'for' */
37:
38: forp->sym = findvar(var, VARNAME);
39: if (forp->sym->s_dim && forp->sym->s_val.a)
40: free(forp->sym->s_val.a);
41: forp->sym->s_dim = 0;
42: forp->sym->s_val.f = from;
43: forp->to = to;
44: if (by == 0.)
45: fatal("step size of 0 not allowed");
46:
47: /* For additive or subtractive step, make sure step is positive.
48: Otherwise, make sure step is greater than 1 in absolute value. */
49: if ((op == ' ' || op == '+') && by < 0.) {
50: op = '-';
51: by = -by;
52: }
53: else if (op == '-' && by < 0.) {
54: op = '+';
55: by = -by;
56: }
57: else if (op == '*' && fabs(by) < 1.) {
58: op = '/';
59: by = 1 / by;
60: }
61: else if (op == '/' && fabs(by) < 1.) {
62: op = '*';
63: by = 1 / by;
64: }
65: forp->op = op;
66: forp->by = by;
67: forp->str = str;
68: nextfor();
69: unput('\n');
70: }
71:
72: nextfor() /* do one iteration of a for loop */
73: {
74: int done;
75: float v = forp->sym->s_val.f;
76:
77: switch (forp->op) {
78: case '+':
79: case ' ':
80: done = v > forp->to;
81: break;
82: case '-':
83: done = v < forp->to;
84: break;
85: case '*':
86: done = v * forp->to < 0. ? (fabs(forp->by) > 0)
87: : (fabs(v) > fabs(forp->to)) ;
88: break;
89: case '/':
90: done = v * forp->to < 0. ? (fabs(forp->by) > 0)
91: : (fabs(v) < fabs(forp->to)) ;
92: break;
93: }
94: if (done) {
95: free(forp->str);
96: if (--forp < forstk)
97: fatal("forstk popped too far");
98: } else { /* another iteration */
99: pushsrc(pString, "\n_Endfor\n");
100: pushsrc(pString, forp->str);
101: }
102: }
103:
104: endfor() /* end one iteration of for loop */
105: {
106: switch (forp->op) {
107: case '+':
108: case ' ':
109: forp->sym->s_val.f += forp->by;
110: break;
111: case '-':
112: forp->sym->s_val.f -= forp->by;
113: break;
114: case '*':
115: forp->sym->s_val.f *= forp->by;
116: break;
117: case '/':
118: forp->sym->s_val.f /= forp->by;
119: break;
120: }
121: nextfor();
122: }
123:
124: char *ifstat(expr, thenpart, elsepart)
125: double expr;
126: char *thenpart, *elsepart;
127: {
128: if (expr) {
129: unput('\n');
130: pushsrc(Free, thenpart);
131: pushsrc(pString, thenpart);
132: unput('\n');
133: if (elsepart)
134: free(elsepart);
135: return thenpart; /* to be freed later */
136: } else {
137: free(thenpart);
138: if (elsepart) {
139: unput('\n');
140: pushsrc(Free, elsepart);
141: pushsrc(pString, elsepart);
142: unput('\n');
143: }
144: return elsepart;
145: }
146: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.