|
|
1.1 root 1: static char *sccsid = "@(#)lam6.c 34.2 10/6/80";
2:
3: #include "global.h"
4: #include <signal.h>
5: FILE *
6: mkstFI(base,count,flag)
7: char *base;
8: char flag;
9: {
10: register FILE *p = stderr;
11:
12: /* find free file descriptor */
13: for(;p->_flag&(_IOREAD|_IOWRT);p++)
14: if(p >= _iob + _NFILE)
15: error("Too many open files to do readlist",FALSE);
16: p->_flag = _IOSTRG | flag;
17: p->_cnt = count;
18: p->_base = base;
19: p->_ptr = base;
20: p->_file = -1;
21: return(p);
22: }
23: lispval
24: Lreadli()
25: {
26: register lispval work, handy;
27: register FILE *p;
28: register char *string;
29: register struct argent *lbot, *np;
30: struct argent *olbot;
31: FILE *opiport = piport;
32: lispval Lread();
33: int count;
34:
35: if(lbot->val==nil) { /*effectively, return(matom(""));*/
36: strbuf[0] = 0;
37: return(getatom());
38: }
39: chkarg(1,"readlist");
40: count = 1;
41:
42: /* compute length of list */
43: for(work = lbot->val; TYPE(work)==DTPR; work=work->d.cdr)
44: count++;
45: string = (char *) alloca(count);
46: p = mkstFI(string, count - 1, _IOREAD);
47: for(work = lbot->val; TYPE(work)==DTPR; work=work->d.cdr) {
48: handy = work->d.car;
49: switch(TYPE(handy)) {
50: case SDOT:
51: case INT:
52: *string++=handy->i;
53: break;
54: case ATOM:
55: *string++ = *(handy->a.pname);
56: break;
57: case STRNG:
58: *string++ = *(char *)handy;
59: break;
60: default:
61: error("Non atom or int to readlist",FALSE);
62: }
63: }
64: *string = 0;
65: olbot = lbot;
66: lbot = np;
67: protect(P(p));
68: work = Lread();
69: lbot = olbot;
70: frstFI(p);
71: return(work);
72: }
73: frstFI(p)
74: register FILE *p;
75: {
76: p->_flag=0;
77: p->_base=0;
78: p->_cnt = 0;
79: p->_ptr = 0;
80: p->_file = 0;
81: }
82: lispval
83: Lgetenv()
84: {
85: register struct argent *mylbot=lbot;
86: snpand(1);
87: if((TYPE(mylbot->val))!=ATOM)
88: error("argument to getenv must be atom",FALSE);
89:
90: strcpy(strbuf,getenv(mylbot->val->a.pname));
91: return(getatom());
92: }
93: lispval
94: Lboundp()
95: {
96: register struct argent *mynp=lbot;
97: register lispval result, handy;
98: snpand(3);
99:
100: if((TYPE(mynp->val))!=ATOM)
101: error("argument to boundp must be atom",FALSE);
102: if( (handy = mynp->val)->a.clb==CNIL)
103: result = nil;
104: else
105: (result = newdot())->d.cdr = handy->a.clb;
106: return(result);
107: }
108: lispval
109: Lplist()
110: {
111: register lispval atm;
112: snpand(1);
113: /* get property list of an atom or disembodied property list */
114:
115: chkarg(1,"plist");
116: atm = lbot->val;
117: switch(TYPE(atm)) {
118: case ATOM:
119: case DTPR:
120: break;
121: default:
122: error("Only Atoms and disembodied property lists allowed for plist",FALSE);
123: }
124: if(atm==nil) return(nilplist);
125: return(atm->a.plist);
126: }
127: lispval
128: Lsetpli()
129: { /* set the property list of the given atom to the given list */
130: register lispval atm, vall;
131: register lispval dum1, dum2;
132: register struct argent *lbot, *np;
133:
134: chkarg(2,"setplist");
135: atm = lbot->val;
136: if (TYPE(atm) != ATOM) error("First argument must be an atom",FALSE);
137: vall = (np-1)->val;
138: if (TYPE(vall)!= DTPR && vall !=nil)
139: error("Second argument must be a list",FALSE);
140: if (atm==nil)
141: nilplist = vall;
142: else
143: atm->a.plist = vall;
144: return(vall);
145: }
146:
147: lispval
148: Lsignal()
149: {
150: register struct argent *mylbot = lbot;
151: int i; register lispval handy, old;
152:
153: snpand(3);
154: if(lbot-np==1)protect(nil);
155: chkarg(2,"signal");
156: handy = mylbot[AD].val;
157: if(TYPE(handy)!=INT)
158: error("First arg to signal must be an int",FALSE);
159: i = handy->i & 15;
160: handy = mylbot[AD+1].val;
161: if(TYPE(handy)!=ATOM)
162: error("Second arg to signal must be an atom",FALSE);
163: old = sigacts[i];
164: if(old==0) old = nil;
165: if(handy==nil)
166: sigacts[i]=((lispval) 0);
167: else
168: sigacts[i]=handy;
169: return(old);
170: }
171: lispval
172: Lassq()
173: {
174: register lispval work, handy, dum1, dum2;
175: register struct argent *lbot, *np;
176:
177: chkarg(2,"assq");
178: for(work = lbot[AD+1].val;
179: work->d.car->d.car!=lbot->val&& work!=nil;
180: work = work->d.cdr);
181: return(work->d.car);
182: }
183: lispval
184: Lkilcopy()
185: {
186: if(fork()==0) {
187: asm(".byte 0");
188: }
189: }
190: lispval
191: Larg()
192: {
193: register lispval handy; register offset, count;
194: snpand(3);
195:
196: handy = lexpr_atom->a.clb;
197: if(handy==CNIL || TYPE(handy)!=DTPR)
198: error("Arg: not in context of Lexpr.",FALSE);
199: count = ((long *)handy->d.cdr) -1 - (long *)handy->d.car;
200: if(np==lbot || lbot->val==nil)
201: return(inewint(count+1));
202: if(TYPE(lbot->val)!=INT || (offset = lbot->val->i - 1) > count || offset < 0 )
203: error("Out of bounds: arg to \"Arg\"",FALSE);
204: return( ((struct argent *)handy->d.car)[offset].val);
205: }
206: lispval
207: Lsetarg()
208: {
209: register lispval handy, work;
210: register limit, index;
211: register struct argent *lbot, *np;
212:
213: chkarg(2,"setarg");
214: handy = lexpr_atom->a.clb;
215: if(handy==CNIL || TYPE(handy)!=DTPR)
216: error("Arg: not in context of Lexpr.",FALSE);
217: limit = ((long *)handy->d.cdr) - 1 - (long *)(work = handy->d.car);
218: handy = lbot->val;
219: if(TYPE(handy)!=INT)
220: error("setarg: first argument not integer",FALSE);
221: if((index = handy->i - 1) < 0 || index > limit)
222: error("setarg: index out of range");
223: return(((struct argent *) work)[index].val = lbot[1].val);
224: }
225: lispval
226: Lptime(){
227: extern int GCtime;
228: int lgctime = GCtime;
229: static struct tbuf {
230: long mytime;
231: long allelse[3];
232: } current;
233: register lispval result, handy;
234:
235: snpand(2);
236: times(¤t);
237: result = newdot();
238: handy = result;
239: protect(result);
240: result->d.cdr = newdot();
241: result->d.car = inewint(current.mytime);
242: handy = result->d.cdr;
243: handy->d.car = inewint(lgctime);
244: handy->d.cdr = nil;
245: if(GCtime==0)
246: GCtime = 1;
247: return(result);
248: }
249:
250: /* (err [value] [flag])
251: where if value is present, it is the value to throw to the errset.
252: flag if present must evaluate to nil, as we always evaluate value
253: before unwinding stack
254: */
255:
256: lispval Lerr()
257: {
258: register lispval handy;
259: lispval errorh();
260: char *mesg = "call to err"; /* default message */
261:
262: snpand(1);
263: if(np==lbot) protect(nil);
264:
265: if ((np >= lbot + 2) && ((lbot+1)->val != nil))
266: error("Second arg to err must be nil",FALSE);
267: if ((lbot->val != nil) && (TYPE(lbot->val) == ATOM))
268: mesg = lbot->val->a.pname; /* new message if atom */
269:
270: return(errorh(Vererr,mesg,lbot->val,nil));
271: }
272: lispval
273: Ltyi()
274: {
275: register FILE *port;
276: char val;
277: snpand(1);
278:
279: if(lbot-np==0)protect(nil);
280: port = okport(lbot->val,okport(Vpiport->a.clb,stdin));
281:
282:
283: fflush(stdout); /* flush any pending output characters */
284: val = getc(port);
285: if(val==EOF)
286: {
287: clearerr(port);
288: if(sigintcnt > 0) sigcall(SIGINT); /* eof might mean int */
289: }
290: return(inewint(val));
291: }
292: lispval
293: Ltyipeek()
294: {
295: register FILE *port;
296: char val;
297: snpand(1);
298:
299: if(lbot-np==0) protect(nil);
300: port = okport(lbot->val,okport(Vpiport->a.clb,stdin));
301:
302: fflush(stdout); /* flush any pending output characters */
303: val = getc(port);
304: if(val==EOF)
305: clearerr(port);
306: ungetc(val,port);
307: return(inewint(val));
308: }
309: lispval
310: Ltyo()
311: {
312: register FILE *port;
313: register lispval handy, where;
314: char val;
315:
316: snpand(3);
317:
318: switch(np-lbot) {
319: case 1:
320: protect(nil);
321: case 2: break;
322: default:
323: argerr("tyo");
324: }
325: handy = lbot->val;
326: if(TYPE(handy)!=INT)
327: error("Tyo demands number for 1st arg",FALSE);
328: val = handy->i;
329:
330: where = lbot[1].val;
331: port = (FILE *) okport(where,okport(Vpoport->a.clb,stdout));
332: putc(val,port);
333: return(handy);
334: }
335:
336: #include "chkrtab.h"
337:
338: lispval
339: Imkrtab(current)
340: {
341: extern struct rtab {
342: char ctable[132];
343: } initread;
344: register lispval handy; extern lispval lastrtab;
345:
346: static int cycle = 0;
347: static char *nextfree;
348:
349: if((cycle++)%3==0) {
350: nextfree = (char *) csegment(str_name,512,FALSE);
351: }
352: handy = newarray();
353: handy->ar.data = nextfree;
354: if(current == 0)
355: *(struct rtab *)nextfree = initread;
356: else
357: *(struct rtab *)nextfree = *(struct rtab *)ctable;
358: handy->ar.delta = inewint(4);
359: handy->ar.length = inewint(sizeof(struct rtab)/sizeof(int));
360: handy->ar.accfun = handy->ar.aux = nil;
361: nextfree += sizeof(struct rtab);
362: return(handy);
363: }
364:
365: /* makereadtable - arg : t or nil
366: returns a readtable, t means return a copy of the initial readtable
367:
368: nil means return a copy of the current readtable
369: */
370: lispval
371: Lmakertbl()
372: {
373: lispval handy = Vreadtable->a.clb;
374: chkrtab(handy);
375:
376: if(lbot==np) error("makereadtable: wrong number of args",FALSE);
377:
378: if(TYPE(lbot->val) != ATOM)
379: error("makereadtable: arg must be atom",FALSE);
380:
381: if(lbot->val == nil) return(Imkrtab(1));
382: else return(Imkrtab(0));
383: }
384:
385: lispval
386: Lcpy1()
387: {
388: register lispval handy = lbot->val, result = handy;
389:
390: top:
391: switch(TYPE(handy))
392: {
393: case INT:
394: result = inewint(handy->i);
395: break;
396: case VALUE:
397: (result = newval())->l = handy->l;
398: break;
399: case DOUB:
400: (result = newdoub())->r = handy->r;
401: break;
402: default:
403: lbot->val =
404: errorh(Vermisc,"Bad arg to cpy1",nil,TRUE,67,handy);
405: goto top;
406: }
407: return(result);
408: }
409:
410: /* copyint* . This returns a copy of its integer argument. The copy will
411: * be a fresh integer cell, and will not point into the read only
412: * small integer table.
413: */
414: lispval
415: Lcopyint()
416: {
417: register lispval handy = lbot->val;
418: register lispval ret;
419:
420: while (TYPE(handy) != INT)
421: { handy=errorh(Vermisc,"copyint* : non integer arg",nil,TRUE,0,handy);}
422: (ret = newint())->i = handy->i;
423: return(ret);
424: }
425:
426:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.