BSD 3 development
[unix-history] / usr / src / cmd / lisp / fex2.c
CommitLineData
8cd657f4
JF
1#include "global.h"
2#define NDOVARS 15
3#include <assert.h>
4/*
5 * Ndo maclisp do function.
6 */
7lispval
8Ndo()
9{
10 register lispval current, where, handy;
11 register struct nament *mybnp;
12 register struct argent *lbot, *np;
13 lispval atom, temp;
14 lispval body, endtest, endform, varstuf, renewals[NDOVARS] ;
15 struct argent *start, *last, *getem, *savedlbot;
16 struct nament *savedbnp, *lastbnd;
17 int count, index, saveme[SAVSIZE], virgin = 1;
18 int myerrp; extern int errp;
19
20 savedlbot = lbot;
21 myerrp = errp;
22 savedbnp = bnp;
23 getexit(saveme); /* common nonlocal return */
24 if(retval = setexit()) {
25 errp = myerrp;
26 if(retval == BRRETN) {
27 resexit(saveme);
28 lbot = savedlbot;
29 popnames(savedbnp);
30 return((lispval) contval);
31 } else {
32 resexit(saveme);
33 lbot = savedlbot;
34 reset(retval);
35 }
36 }
37 current = lbot->val;
38 varstuf = current->car;
39 switch( TYPE(varstuf) ) {
40
41 case ATOM: /* This is old style maclisp do;
42 atom is var, cadr(current) = init;
43 caddr(current) = repeat etc. */
44 atom = varstuf;
45 if(varstuf==nil) goto newstyle;
46 bnp->atm = atom; /* save current binding of atom */
47 bnp++->val = atom->clb;
48 if(bnp > bnplim)
49 binderr();
50 current = current->cdr;
51 atom->clb = eval(current->car);
52 /* Init var. */
53 *renewals = (current = current->cdr)->car;
54 /* get repeat form */
55 endtest = (current = current->cdr)->car;
56 body = current->cdr;
57
58 while(TRUE) {
59 if(eval(endtest)!=nil) {
60 resexit(saveme);
61 popnames(savedbnp);
62 return(nil);
63 }
64 doprog(body);
65 atom->clb = eval(*renewals);
66 }
67
68
69 newstyle:
70 case DTPR: /* New style maclisp do; atom is
71 list of things of the form
72 (var init repeat) */
73 count = 0;
74 start = np;
75 for(where = varstuf; where != nil; where = where->cdr) {
76 /* do inits and count do vars. */
77 /* requires "simultaneous" eval
78 of all inits */
79 handy = where->car->cdr;
80 temp = nil;
81 if(handy !=nil)
82 temp = eval(handy->car);
83 protect(temp);
84 count++;
85 }
86 if(count > NDOVARS)
87 error("More than 15 do vars",FALSE);
88 bnp += count;
89 if(bnp >= bnplim) {
90 bnp = savedbnp;
91 namerr();
92 }
93 last = np;
94 where = varstuf;
95 mybnp = savedbnp;
96 getem = start;
97 for(index = 0; index < count; index++) {
98
99 handy = where->car;
100 /* get var name from group */
101 atom = handy->car;
102 mybnp->atm = atom;
103 mybnp->val = atom->clb;
104 /* Swap current binding of atom
105 for init val pushed on stack */
106
107 atom->clb = getem++->val;
108 /* As long as we are down here in the
109 list, save repeat form */
110 handy = handy->cdr->cdr;
111 if(handy==nil)
112 handy = CNIL; /* be sure not to rebind later */
113 else
114 handy = handy->car;
115 renewals[index] = handy;
116
117 /* more loop "increments" */
118 where = where->cdr;
119 mybnp++;
120 }
121 /* Examine End test and End form */
122 current = current->cdr;
123 handy = current->car;
124 body = current->cdr;
125 if (handy == nil) {
126 doprog(body);
127 popnames(savedbnp);
128 resexit(saveme);
129 return(nil);
130 }
131 endtest = handy->car;
132 endform = handy->cdr;
133 /* The following is the loop: */
134 loop:
135 if(eval(endtest)!=nil) {
136 for(handy = nil; endform!=nil; endform = endform->cdr){
137 handy = eval(endform->car);
138 }
139 resexit(saveme);
140 popnames(savedbnp);
141 return(handy);
142 }
143 doprog(body);
144 /* Simultaneously eval repeat forms */
145 for(index = 0; index < count; index++) {
146
147 temp = renewals[index];
148 if (temp == nil || temp == CNIL)
149 protect(temp);
150 else
151 protect(eval(temp));
152 }
153 getem = (np = last);
154 /* now simult. rebind all the atoms */
155 mybnp = savedbnp;
156 for(index = 0; index < count; index++, getem++) {
157 if( (getem)->val != CNIL ) /* if this atom has a repeat form */
158 mybnp->atm->clb = (getem)->val; /* rebind */
159 mybnp++;
160 }
161 goto loop;
162 }
163}
164doprog(body)
165register lispval body;
166 {
167 int saveme[SAVSIZE];
168 register lispval where, temp;
169 /*register struct nament *savednp = np, *savedlbot = lbot;*/
170 extern int errp; int myerrp = errp;
171 struct nament *savedbnp = bnp;
172 snpand(2);
173
174 where = body;
175 getexit(saveme);
176 if(retval = setexit()) {
177 errp = myerrp;
178 switch (retval) {
179
180 default: resexit(saveme);
181 reset(retval);
182
183 case BRGOTO:
184 for(where = body;
185 where->car != (lispval) contval; where = where->cdr) {
186
187 if(where==nil) {
188 resexit(saveme);
189 reset(retval);
190 }
191 /* np is automatically restored here by
192 virtue of being a register */
193 }
194 popnames(savedbnp);
195 }
196 }
197 while (TYPE(where) == DTPR) {
198 temp = where->car;
199 if((TYPE(temp))!=ATOM) eval(temp);
200 where = where->cdr;
201 }
202 resexit(saveme);
203}
204lispval
205Nprogv()
206{
207 register lispval argptr, where, handy, atoms;
208 register struct argent *lbot, *np;
209 struct argent *namptr, *start;
210 struct nament *oldbnp = bnp;
211
212 where = lbot->val;
213 protect(eval(where->car)); /* list of vars */
214 atoms = lbot[1].val;
215 protect(eval((where = where->cdr)->car));
216 /* list of vals */
217 handy = lbot[2].val;
218 start = np;
219 for(;handy!=nil; handy = handy->cdr) {
220 (np++)->val = eval(handy->car);
221 TNP;
222 }
223 rebind(atoms,start);
224 handy = nil;
225 for(where = where->cdr; where != nil; where = where->cdr)
226 handy = eval(where->car);
227 popnames(oldbnp);
228 return(handy);
229}
230
231lispval
232Nprogn()
233{
234 register lispval result, where;
235 snpand(2);
236
237 result = nil;
238 for(where = lbot->val; where != nil; where = where->cdr)
239 result = eval(where->car);
240 return(result);
241
242
243}
244lispval
245Nprog2()
246{
247 register lispval result, where;
248 snpand(2);
249
250 where = lbot->val;
251 eval(where->car);
252 result = eval((where = where->cdr)->car);
253 protect(result);
254 for(where = where->cdr; where != nil; where = where->cdr)
255 eval(where->car);
256 return(result);
257}