BSD 3 development
[unix-history] / usr / src / cmd / lisp / lam3.c
CommitLineData
8cd657f4
JF
1# include "global.h"
2lispval
3Lalfalp()
4{
5 register lispval first, second;
6 register struct argent *inp;
7 snpand(3); /* clobber save mask */
8
9 chkarg(2);
10 inp = lbot;
11 first = (inp)->val;
12 second = (inp+1)->val;
13 if( (TYPE(first))!=ATOM || (TYPE(second))!=ATOM)
14 error("alphalessp expects atoms");
15 if(strcmp(first->pname,second->pname) <= 0)
16 return(tatom);
17 else
18 return(nil);
19}
20
21lispval
22Lncons()
23{
24 register lispval handy;
25 snpand(1); /* clobber save mask */
26
27 chkarg(1);
28 handy = newdot();
29 handy -> cdr = nil;
30 handy -> car = lbot->val;
31 return(handy);
32}
33lispval
34Lzerop()
35{
36 register lispval handy;
37 snpand(1); /* clobber save mask */
38
39 chkarg(1);
40 handy = lbot->val;
41 switch(TYPE(handy)) {
42 case INT:
43 return(handy->i==0?tatom:nil);
44 case DOUB:
45 return(handy->r==0.0?tatom:nil);
46 }
47 return(nil);
48}
49lispval
50Lonep()
51{
52 register lispval handy; lispval Ladd();
53 snpand(1); /* clobber save mask */
54
55 chkarg(1);
56 handy = lbot->val;
57 switch(TYPE(handy)) {
58 case INT:
59 return(handy->i==1?tatom:nil);
60 case DOUB:
61 return(handy->r==1.0?tatom:nil);
62 case SDOT:
63 protect(inewint(0));
64 handy = Ladd();
65 if(TYPE(handy)!=INT || handy->i !=1)
66 return(nil);
67 else
68 return(tatom);
69 }
70 return(nil);
71}
72
73lispval
74cmpx(lssp)
75{
76 register struct argent *argp;
77 register struct argent *outarg;
78 register struct argent *handy;
79 register count;
80 register struct argent *lbot;
81 register struct argent *np;
82 struct argent *onp = np;
83
84
85 argp = lbot + 1;
86 outarg = np;
87 while(argp < onp) {
88
89 np = outarg + 2;
90 lbot = outarg;
91 if(lssp)
92 *outarg = argp[-1], outarg[1] = *argp++;
93 else
94 outarg[1] = argp[-1], *outarg = *argp++;
95 lbot->val = Lsub();
96 np = lbot + 1;
97 if(Lnegp()==nil) return(nil);
98 }
99 return(tatom);
100}
101
102lispval
103Lgreaterp()
104{
105 return(cmpx(FALSE));
106}
107
108lispval
109Llessp()
110{
111 return(cmpx(TRUE));
112}
113
114lispval
115Ldiff()
116{
117 register lispval arg1,arg2; register handy = 0;
118 snpand(3); /* clobber save mask */
119
120
121 chkarg(2);
122 arg1 = lbot->val;
123 arg2 = (lbot+1)->val;
124 if(TYPE(arg1)==INT && TYPE(arg2)==INT) {
125 handy=arg1->i - arg2->i;
126 }
127 else error("non-numeric argument",FALSE);
128 return(inewint(handy));
129}
130
131lispval
132Lmod()
133{
134 register lispval arg1,arg2; lispval handy;
135 struct sdot fake1, fake2;
136 fake2.CDR = 0;
137 fake1.CDR = 0;
138 snpand(2); /* clobber save mask */
139
140 chkarg(2);
141 handy = arg1 = lbot->val;
142 arg2 = (lbot+1)->val;
143 switch(TYPE(arg1)) {
144 case SDOT:
145 break;
146 case INT:
147 fake1.I = arg1->i;
148 arg1 =(lispval) &fake1;
149 break;
150 default:
151 error("non-numeric argument",FALSE);
152 }
153 switch(TYPE(arg2)) {
154 case SDOT:
155 break;
156 case INT:
157 fake2.I = arg2->i;
158 arg2 =(lispval) &fake2;
159 break;
160 default:
161 error("non-numeric argument",FALSE);
162 }
163 if(Lzerop()!=nil) return(handy);
164 divbig(arg1,arg2,0,&handy);
165 if(handy==((lispval)&fake1))
166 handy = inewint(fake1.I);
167 if(handy==((lispval)&fake2))
168 handy = inewint(fake2.I);
169 return(handy);
170
171}
172
173
174lispval
175Ladd1()
176{
177 register lispval handy;
178 lispval Ladd();
179 snpand(1); /* fixup entry mask */
180
181 handy = rdrint;
182 handy->i = 1;
183 protect(handy);
184 return(Ladd());
185
186}
187
188lispval
189Lsub1()
190{
191 register lispval handy;
192 lispval Ladd();
193 snpand(1); /* fixup entry mask */
194
195 handy = rdrint;
196 handy->i = - 1;
197 protect(handy);
198 return(Ladd());
199}
200
201lispval
202Lminus()
203{
204 register lispval arg1, handy;
205 register temp;
206 lispval subbig();
207 snpand(3); /* clobber save mask */
208
209 chkarg(1);
210 arg1 = lbot->val;
211 handy = nil;
212 switch(TYPE(arg1)) {
213 case INT:
214 handy= inewint(0 - arg1->i);
215 break;
216 case DOUB:
217 handy = newdoub();
218 handy->r = -arg1->r;
219 break;
220 case SDOT:
221 handy = rdrsdot;
222 handy->I = 0;
223 handy->CDR = (lispval) 0;
224 handy = subbig(handy,arg1);
225 break;
226
227 default:
228 error("non-numeric argument",FALSE);
229 }
230 return(handy);
231}
232
233lispval
234Lnegp()
235{
236 register lispval handy = np[-1].val, work;
237 register flag = 0;
238 snpand(3); /* clobber save mask */
239
240loop:
241 switch(TYPE(handy)) {
242 case INT:
243 if(handy->i < 0) flag = TRUE;
244 break;
245 case DOUB:
246 if(handy->r < 0) flag = TRUE;
247 break;
248 case SDOT:
249 for(work = handy; work->CDR!=(lispval) 0; work = work->CDR);
250 if(work->I < 0) flag = TRUE;
251 break;
252 default:
253 handy = errorh(Vermisc,
254 "minusp: Non-(int,real,bignum) arg: ",
255 nil,
256 TRUE,
257 0,
258 handy);
259 goto loop;
260 }
261 if(flag) return(tatom);
262 return(nil);
263}
264
265lispval
266Labsval()
267{
268 register lispval arg1, handy;
269 register temp;
270 snpand(3); /* clobber save mask */
271
272 chkarg(1);
273 arg1 = lbot->val;
274 if(Lnegp()!=nil) return(Lminus());
275
276 return(arg1);
277}
278
279#include "frame.h"
280/* new version of showstack,
281 We will set fp to point where the register fp points.
282 Then fp+2 = saved ap
283 fp+4 = saved pc
284 fp+3 = saved fp
285 ap+1 = first arg
286 If we find that the saved pc is somewhere in the routine eval,
287 then we print the first argument to that eval frame. This is done
288 by looking one beyond the saved ap.
289*/
290lispval
291Lshostk()
292{ lispval isho();
293 return(isho(1));
294}
295static lispval
296isho(f)
297int f;
298{
299 register struct frame *myfp; register lispval handy;
300 int **fp; /* this must be the first local */
301 int virgin=1;
302 lispval _qfuncl(),tynames(); /* locations in qfuncl */
303
304 if(f==1)
305 printf("Forms in evaluation:\n");
306 else
307 printf("Backtrace:\n\n");
308
309 myfp = (struct frame *) (&fp +1); /* point to current frame */
310
311 while(TRUE)
312 {
313 if( (myfp->pc > eval && /* interpreted code */
314 myfp->pc < popnames)
315 ||
316 (myfp->pc > _qfuncl && /* compiled code */
317 myfp->pc < tynames) )
318 {
319 handy = (myfp->ap[1]);
320 if(f==1)
321 printr(handy,stdout), putchar('\n');
322 else {
323 if(virgin)
324 virgin = 0;
325 else
326 printf(" -- ");
327 printr((TYPE(handy)==DTPR)?handy->car:handy,stdout);
328 }
329
330 }
331
332 if(myfp > myfp->fp) break; /* end of frames */
333 else myfp = myfp->fp;
334 }
335 putchar('\n');
336 return(nil);
337}
338lispval
339Lbaktrace()
340{
341 isho(0);
342}
343/* ===========================================================
344-
345**** baktrace **** (moved back by kls)
346-
347- baktrace will print the names of all functions being evaluated
348- from the current one (baktrace) down to the first one.
349- currently it only prints the function name. Planned is a
350- list of local variables in all stack frames.
351- written by jkf.
352-
353-============================================================*/
354
355/*=============================================================
356-
357-*** oblist ****
358-
359- oblist returns a list of all symbols in the oblist
360-
361- written by jkf.
362============================================================*/
363
364lispval
365Loblist()
366{
367 int indx;
368 lispval headp, tailp ;
369 struct atom *symb ;
370
371 headp = tailp = newdot(); /* allocate first DTPR */
372 protect(headp); /*protect the list from garbage collection*/
373 /*line added by kls */
374
375 for( indx=0 ; indx <= HASHTOP-1 ; indx++ ) /* though oblist */
376 {
377 for( symb = hasht[indx] ;
378 symb != (struct atom *) CNIL ;
379 symb = symb-> hshlnk)
380 {
381 tailp->car = (lispval) symb ; /* remember this atom */
382 tailp = tailp->cdr = newdot() ; /* link to next DTPR */
383 }
384 }
385
386 tailp->cdr = nil ; /* close the list unfortunately throwing away
387 the last DTPR
388 */
389 return(headp);
390}
391
392/*
393 * Maclisp setsyntax function:
394 * (setsyntax c s x)
395 * c represents character either by fixnum or atom
396 * s is the atom "macro" or the atom "splicing" (in which case x is the
397 * macro to be invoked); or nil (meaning don't change syntax of c); or
398 * (well thats enough for now) if s is a fixnum then we modify the bits
399 * for c in the readtable.
400 */
401#define VMAC 0316
402#define VSPL 0315
403#define VDQ 0212
404#define VESC 0217
405#include "chkrtab.h"
406
407lispval
408Lsetsyn()
409{
410 register lispval s, c;
411 register struct argent *mynp;
412 register index;
413 register struct argent *lbot, *np;
414 lispval x;
415 extern char *ctable;
416 int value;
417
418 chkarg(3);
419 s = Vreadtable->clb;
420 chkrtab(s);
421 mynp = lbot;
422 c = (mynp++)->val;
423 s = (mynp++)->val;
424 x = (mynp++)->val;
425
426 switch(TYPE(c)) {
427 default:
428 error("neither fixnum nor atom as char to setsyntax",FALSE);
429
430 case ATOM:
431 index = *(c->pname);
432 if((c->pname)[1])error("Only 1 char atoms to setsyntax",FALSE);
433 break;
434
435 case INT:
436 index = c->i;
437 }
438 switch(TYPE(s)) {
439 case INT:
440 if(s->i == VESC) Xesc = (char) index;
441 else if(s->i == VDQ) Xdqc = (char) index;
442
443 if(ctable[index] == VESC /* if we changed the current esc */
444 && s->i != VESC /* to something else, pick current */
445 && Xesc == (char) index) {
446 ctable[index] = s->i;
447 rpltab(VESC,&Xesc);
448 }
449 else if(ctable[index] == VDQ /* likewise for double quote */
450 && s->i != VDQ
451 && Xdqc == (char) index) {
452 ctable[index] = s->i;
453 rpltab(VDQ,&Xdqc);
454 }
455 else ctable[index] = s->i;
456
457 break;
458 case ATOM:
459 if(s==splice)
460 ctable[index] = VSPL;
461 else if(s==macro)
462 ctable[index] = VMAC;
463 if(TYPE(c)!=ATOM) {
464 strbuf[0] = index;
465 strbuf[1] = 0;
466 c = (getatom());
467 }
468 Iputprop(c,x,macro);
469 }
470 return(tatom);
471}
472
473
474
475/* this aux function is used by setsyntax to determine the new current
476 escape or double quote character. It scans the character table for
477 the first character with the given class (either VESC or VDQ) and
478 puts that character in Xesc or Xdqc (whichever is pointed to by
479 addr).
480*/
481rpltab(cclass,addr)
482char cclass;
483char *addr;
484{
485 register int i;
486 extern char *ctable;
487 for(i=0; i<=127 && ctable[i] != cclass; i++);
488 if(i<=127) *addr = (char) i;
489 else *addr = '\0';
490}
491
492
493
494lispval
495Lzapline()
496{
497 register FILE *port;
498 extern FILE * rdrport;
499
500 port = rdrport;
501 while (!feof(port) && (getc(port)!='\n') );
502 return(nil);
503}
504