|
|
1.1 root 1: static char *sccsid = "@(#)lam4.c 34.1 10/3/80";
2:
3: #include "global.h"
4: typedef struct argent *ap;
5: static int prunep; lispval adbig(),subbig(),mulbig();
6: lispval
7: Ladd()
8: {
9: register lispval work;
10: register ap result, mynp, oldnp, lbot, np;
11: int itemp,restype;
12:
13: oldnp = result = np;
14: protect(rdrsdot);
15: rdrsdot->s.CDR = (lispval) 0;
16: rdrsdot->s.I =0;
17: restype = SDOT;
18: prunep = TRUE;
19:
20: for(mynp = lbot; mynp < oldnp; mynp++)
21: {
22: work = mynp->val;
23: switch(TYPE(work)) {
24: case INT:
25: switch(restype) {
26: case DOUB:
27: result->val->r += work->i;
28: break;
29: case SDOT:
30: dmlad(result->val,1,work->i);
31: prunep = TRUE;
32: break;
33: default:
34: goto urk;
35: }
36: break;
37: case SDOT:
38: switch(restype) {
39: case DOUB:
40: error("Don't know how to make bignums into reals, yet",FALSE);
41: break;
42: case SDOT:
43: result->val = adbig(work,result->val);
44: restype = TYPE(result->val);
45: if(restype==INT) {
46: rdrsdot->s.I=result->val->s.I;
47: rdrsdot->s.CDR = (lispval) 0;
48: result->val = rdrsdot;
49: restype=SDOT;
50: prunep = TRUE;
51: } else
52: prunep = FALSE;
53: break;
54: default:
55: goto urk;
56: }
57: break;
58: case DOUB:
59: switch(restype) {
60: case SDOT:
61: if(result->val->s.CDR==(lispval) 0) {
62: protect(newdoub());
63: np[-1].val->r = result->val->i+work->r;
64: result->val = np[-1].val;
65: np--;
66: restype = DOUB;
67: } else
68: error("Don't know how to make bignums into reals, yet",FALSE);
69: break;
70: case DOUB:
71: result->val->r += work->r;
72: break;
73: default:
74: goto urk;
75: }
76: break;
77: default:
78: errorh(Vermisc,"Non-number to add",nil,0,FALSE,work);
79: }
80: }
81: if(restype==DOUB || prunep==FALSE)
82: return(result->val);
83: else if (result->val->s.CDR==(lispval) 0)
84: return(inewint(result->val->s.I));
85: else {
86: struct sdot dummybig;
87:
88: dummybig.I = 0;
89: dummybig.CDR = (lispval) 0;
90: return(adbig(&dummybig,result->val));
91: }
92: urk:
93: error("Internal error in (add,sub,quo,times)",FALSE);
94: }
95: lispval
96: Lsub()
97: {
98: register lispval work;
99: register ap result, mynp, oldnp, lbot, np;
100: int itemp,restype;
101: lispval Lminus();
102:
103: oldnp = result = np;
104: mynp = lbot + 1;
105: protect(rdrsdot);
106: rdrsdot->s.CDR = (lispval) 0;
107: rdrsdot->s.I =0;
108: restype = SDOT;
109: prunep = TRUE;
110: if(oldnp==lbot)
111: goto out;
112: if(oldnp==mynp) {
113: np--;
114: return(Lminus());
115: }
116: work = lbot->val;
117: switch(TYPE(work)) {
118: case INT:
119: rdrsdot->s.I = work->i;
120: break;
121: case SDOT:
122: result->val = adbig(result->val,work);
123: if(TYPE(result->val)==INT) {
124: rdrsdot->s.I = result->val->i;
125: result->val = rdrsdot;
126: }
127: break;
128: case DOUB:
129: (result->val = newdoub())->r = work->r;
130: restype = DOUB;
131: }
132:
133: for(; mynp < oldnp; mynp++)
134: {
135: work = mynp->val;
136: switch(TYPE(work)) {
137: case INT:
138: switch(restype) {
139: case DOUB:
140: result->val->r -= work->i;
141: break;
142: case SDOT:
143: dmlad(result->val,1, -work->i);
144: prunep = TRUE;
145: break;
146: default:
147: goto urk;
148: }
149: break;
150: case SDOT:
151: switch(restype) {
152: case DOUB:
153: errorh(Vermisc,
154: "difference: Don't know how to make bignums into reals, yet",
155: nil,FALSE,0,work);
156: break;
157: case SDOT:
158: result->val = subbig(result->val,work);
159: restype = TYPE(result->val);
160: if(restype==INT) {
161: rdrsdot->s.I=result->val->s.I;
162: rdrsdot->s.CDR = (lispval) 0;
163: result->val = rdrsdot;
164: restype=SDOT;
165: prunep = TRUE;
166: } else
167: prunep = FALSE;
168: break;
169: default:
170: goto urk;
171: }
172: break;
173: case DOUB:
174: switch(restype) {
175: case SDOT:
176: if(result->val->s.CDR==(lispval) 0) {
177: protect(newdoub());
178: np[-1].val->r = result->val->i-work->r;
179: result->val = np[-1].val;
180: np--;
181: restype = DOUB;
182: } else
183: errorh(Vermisc,
184: "difference: Don't know how to make bignums into reals ",nil,FALSE,0,work);
185: break;
186: case DOUB:
187: result->val->r -= work->r;
188: break;
189: default:
190: goto urk;
191: }
192: break;
193: default:
194: errorh(Vermisc,"Non-number to minus",nil,FALSE,0,work);
195: }
196: }
197: out:
198: if(restype==DOUB || prunep==FALSE)
199: return(result->val);
200: else if (result->val->s.CDR==(lispval) 0)
201: return(inewint(result->val->s.I));
202: else {
203: struct sdot dummybig;
204:
205: dummybig.I = 0;
206: dummybig.CDR = (lispval) 0;
207: return(adbig(&dummybig,result->val));
208: }
209: urk:
210: error("Internal error in (add,sub,quo,times)",FALSE);
211: }
212: lispval
213: Ltimes()
214: {
215: register lispval work;
216: register ap result, mynp, oldnp, lbot, np;
217: int itemp,restype;
218:
219: oldnp = result = np;
220: protect(rdrsdot);
221: rdrsdot->s.CDR = (lispval) 0;
222: rdrsdot->s.I = 1;
223: restype = SDOT;
224: prunep = TRUE;
225:
226: for(mynp = lbot; mynp < oldnp; mynp++)
227: {
228: work = mynp->val;
229: switch(TYPE(work)) {
230: case INT:
231: switch(restype) {
232: case DOUB:
233: result->val->r *= work->i;
234: break;
235: case SDOT:
236: dmlad(result->val,work->i,0);
237: prunep = TRUE;
238: break;
239: default:
240: goto urk;
241: }
242: break;
243: case SDOT:
244: switch(restype) {
245: case DOUB:
246: error("Don't know how to make bignums into reals, yet",FALSE);
247: break;
248: case SDOT:
249: result->val = mulbig(work,result->val);
250: restype = TYPE(result->val);
251: if(restype==INT) {
252: if(result->val->i==0)
253: return(result->val);
254: rdrsdot->s.I=result->val->s.I;
255: rdrsdot->s.CDR = (lispval) 0;
256: result->val = rdrsdot;
257: restype=SDOT;
258: prunep = TRUE;
259: } else
260: prunep = FALSE;
261: break;
262: default:
263: goto urk;
264: }
265: break;
266: case DOUB:
267: switch(restype) {
268: case SDOT:
269: if(result->val->s.CDR==(lispval) 0) {
270: protect(newdoub());
271: np[-1].val->r = result->val->i*work->r;
272: result->val = np[-1].val;
273: np--;
274: restype = DOUB;
275: } else
276: error("Don't know how to make bignums into reals, yet",FALSE);
277: break;
278: case DOUB:
279: result->val->r *= work->r;
280: break;
281: default:
282: goto urk;
283: }
284: break;
285: default:
286: error("Non-number to times",FALSE);
287: }
288: }
289: if(restype==DOUB || prunep==FALSE)
290: return(result->val);
291: else if (result->val->s.CDR==(lispval) 0)
292: return(inewint(result->val->s.I));
293: else {
294: struct sdot dummybig;
295:
296: dummybig.I = 0;
297: dummybig.CDR = (lispval) 0;
298: return(adbig(&dummybig,result->val));
299: }
300: urk:
301: error("Internal error in (add,sub,quo,times)",FALSE);
302: }
303: lispval
304: Lquo()
305: {
306: register lispval work;
307: register lispval result;
308: register struct argent *mynp;
309: register struct argent *oldnp, *lbot, *np;
310: int bigflag = 0, realflag = 0, itemp;
311: struct sdot dummybig;
312: lispval divbig(), *resaddr;
313:
314: mynp = lbot;
315: oldnp = np-1;
316: dummybig.CDR = (lispval) 0;
317: dummybig.I = 1;
318: if(mynp > oldnp) goto out;
319: work = (mynp++)->val;
320: itemp = TYPE(work);
321: switch(itemp) {
322: case INT:
323: if(mynp <= oldnp) dummybig.I = work->i;
324: else dummybig.I = 1/work->i;
325: break;
326: case DOUB:
327: realflag = 1;
328: protect(result = newdoub());
329: if(mynp <= oldnp) result->r = work->r;
330: else result->r = 1.0/work->r;
331: break;
332: case SDOT: /* must be fixed for the inverse case */
333: protect(work);
334: resaddr = &(np[-1].val);
335: bigflag = 1;
336: break;
337: default:
338: error("Don't know how to divide this type.",FALSE);
339: }
340: for(;mynp <= oldnp; mynp++) {
341: work = mynp->val;
342: itemp = TYPE(work);
343: switch(itemp) {
344:
345: case INT:
346: if (work->i==0)
347: kill(getpid(),8);
348: if (realflag)
349: result->r /= work->i;
350: else if(bigflag) {
351: dummybig.I = work->i;
352: divbig(*resaddr, &dummybig, resaddr, 0);
353: } else {
354: dummybig.I /= work->i;
355: }
356: break;
357: case DOUB:
358: if(realflag)
359: result->r /= work->r;
360: else if(bigflag)
361: error("Don't know how to make bignums into reals, yet",FALSE);
362: else {
363: realflag = 1;
364: result = newdoub();
365: result->r = (double) dummybig.I / work->r;
366: protect(result);
367: }
368: break;
369: case SDOT:
370: if(realflag)
371: error("Don't know how to divide reals by bignums ",FALSE);
372: else if(bigflag)
373: divbig(*resaddr, work, resaddr, 0);
374: else {
375: bigflag = 1;
376: protect(newsdot());
377: resaddr = &(np[-1].val);
378: np[-1].val->i = dummybig.I;
379: divbig(*resaddr, work, resaddr, 0);
380: }
381: break;
382: default:
383: error("Don't know how to divide this type",FALSE);
384:
385: }
386: }
387: out:
388: if(realflag)
389: return(result);
390: else if (bigflag)
391: return(*resaddr);
392: else {
393: result = inewint( dummybig.I );
394: return(result);
395: }
396: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.