#ifndef lint static char *rcsid = "$Header: lamr.c,v 1.6 84/04/06 23:14:05 layer Exp $"; #endif /* -[Sat Jan 29 13:09:59 1983 by jkf]- * lamr.c $Locker: $ * lambda functions * * (c) copyright 1982, Regents of the University of California */ # include "global.h" /* * * Lalloc * * This lambda allows allocation of pages from lisp. The first * argument is the name of a space, n pages of which are allocated, * if possible. Returns the number of pages allocated. */ lispval Lalloc() { long n; chkarg(2,"alloc"); if(TYPE((lbot+1)->val) != INT && (lbot+1)->val != nil ) error("2nd argument to allocate must be an integer",FALSE); n = 1; if((lbot+1)->val != nil) n = (lbot+1)->val->i; return(alloc((lbot)->val,n)); /* call alloc to do the work */ } lispval Lsizeof() { chkarg(1,"sizeof"); return(inewint(csizeof(lbot->val))); } lispval Lsegment() { chkarg(2,"segment"); chek: while(TYPE(np[-1].val) != INT ) np[-1].val=error("LENGTH ARG TO SEGMENT MUST BE INTEGER",TRUE); if( np[-1].val->i < 0 ) { np[-1].val = error("LENGTH ARG TO SEGMENT MUST BE POSITIVE",TRUE); goto chek; } return(csegment(typenum((lbot)->val),(int)(np[-1].val->i),FALSE)); } /* Lforget *************************************************************/ /* */ /* This function removes an atom from the hash table. */ lispval Lforget() { char *name; struct atom *buckpt; int hash; chkarg(1,"forget"); if(TYPE(lbot->val) != ATOM) error("remob: non-atom argument",FALSE); name = lbot->val->a.pname; hash = hashfcn(name); /* We have found the hash bucket for the atom, now we remove it */ if( hasht[hash] == (struct atom *)lbot->val ) { hasht[hash] = lbot->val->a.hshlnk; lbot->val->a.hshlnk = (struct atom *)CNIL; return(lbot->val); } buckpt = hasht[hash]; while(buckpt != (struct atom *)CNIL) { if(buckpt->hshlnk == (struct atom *)lbot->val) { buckpt->hshlnk = lbot->val->a.hshlnk; lbot->val->a.hshlnk = (struct atom *)CNIL; return(lbot->val); } buckpt = buckpt->hshlnk; } /* Whoops! Guess it wasn't in the hash table after all. */ return(lbot->val); } lispval Lgetl() { chkarg(1,"getlength"); if(TYPE(lbot->val) != ARRAY) error("ARG TO GETLENGTH MUST BE AN ARRAY",TRUE); return(lbot->val->ar.length); } lispval Lputl() { chkarg(2,"putlength"); if(TYPE((lbot)->val) != ARRAY) error("ARG TO PUTLENGTH MUST BE AN ARRAY",FALSE); chek: while(TYPE(np[-1].val) != INT) np[-1].val = error("ARRAY LENGTH MUST BE AN INTEGER",FALSE); if(np[-1].val->i <= 0) { np[-1].val = error("ARRAY LENGTH MUST BE POSITIVE",TRUE); goto chek; } return((lbot)->val->ar.length = np[-1].val); } lispval Lgetdel() { chkarg(1,"getdelta"); if(TYPE(lbot->val) != ARRAY) error("ARG TO GETDELTA MUST BE AN ARRAY",FALSE); return(lbot->val->ar.delta); } lispval Lputdel() { chkarg(2,"putdelta"); if(TYPE((np-2)->val) != ARRAY) error("ARG TO PUTDELTA MUST BE AN ARRAY",FALSE); chek: while(TYPE(np[-1].val) != INT) np[-1].val = error("ARRAY LENGTH MUST BE AN INTEGER",TRUE); if(np[-1].val->i <= 0) { np[-1].val = error("Array delta must be positive",TRUE); goto chek; } return((lbot)->val->ar.delta = np[-1].val); } lispval Lgetaux() { chkarg(1,"getaux"); if(TYPE(lbot->val)!=ARRAY) error("Arg to getaux must be an array", FALSE); return(lbot->val->ar.aux); } lispval Lputaux() { chkarg(2,"putaux"); if(TYPE((lbot)->val)!=ARRAY) error("1st Arg to putaux must be array", FALSE); return((lbot)->val->ar.aux = np[-1].val); } lispval Lgetdata() { chkarg(1,"getdata"); if(TYPE(lbot->val)!=ARRAY) error("Arg to getdata must be an array", FALSE); return((lispval)lbot->val->ar.data); } lispval Lputdata() { chkarg(2,"putdata"); if(TYPE(lbot->val)!=ARRAY) error("1st Arg to putaux must be array", FALSE); return((lispval)(lbot->val->ar.data = (char *)(lbot[1].val))); } lispval Lgeta() { chkarg(1,"getaccess"); if(TYPE(lbot->val) != ARRAY) error("ARG TO GETACCESS MUST BE AN ARRAY",FALSE); return(lbot->val->ar.accfun); } lispval Lputa() { chkarg(2,"putaccess"); if(TYPE((lbot)->val) != ARRAY) error("ARG TO PUTACCESS MUST BE ARRAY",FALSE); return((lbot)->val->ar.accfun = np[-1].val); } lispval Lmarray() { register lispval handy; chkarg(5,"marray"); (handy = newarray()); /* get a new array cell */ handy->ar.data=(char *)lbot->val;/* insert data address */ handy->ar.accfun = lbot[1].val; /* insert access function */ handy->ar.aux = lbot[2].val; /* insert aux data */ handy->ar.length = lbot[3].val; /* insert length */ handy->ar.delta = lbot[4].val; /* push delta arg */ return(handy); } lispval Lgtentry() { chkarg(1,"getentry"); if( TYPE(lbot->val) != BCD ) error("ARG TO GETENTRY MUST BE FUNCTION",FALSE); return((lispval)(lbot->val->bcd.start)); } lispval Lgetlang() { chkarg(1,"getlang"); while(TYPE(lbot->val)!=BCD) lbot->val = error("ARG TO GETLANG MUST BE FUNCTION DESCRIPTOR",TRUE); return(lbot->val->bcd.language); } lispval Lputlang() { chkarg(2,"putlang"); while(TYPE((lbot)->val)!=BCD) lbot->val = error("FIRST ARG TO PUTLANG MUST BE FUNCTION DESCRIPTOR",TRUE); (lbot)->val->bcd.language = np[-1].val; return(np[-1].val); } lispval Lgetparams() { chkarg(1,"getparams"); if(TYPE(np[-1].val)!=BCD) error("ARG TO GETPARAMS MUST BE A FUNCTION DESCRIPTOR",FALSE); return(np[-1].val->bcd.params); } lispval Lputparams() { chkarg(2,"putparams"); if(TYPE((lbot)->val)!=BCD) error("1st ARG TO PUTPARAMS MUST BE FUNCTION DESCRIPTOR",FALSE); return((lbot)->val->bcd.params = np[-1].val); } lispval Lgetdisc() { chkarg(1,"getdisc"); if(TYPE(np[-1].val) != BCD) error("ARGUMENT OF GETDISC MUST BE FUNCTION",FALSE); return(np[-1].val->bcd.discipline); } lispval Lputdisc() { chkarg(2,"putdisc"); if(TYPE(np[-2].val) != BCD) error("ARGUMENT OF PUTDISC MUST BE FUNCTION",FALSE); return((np-2)->val->bcd.discipline = np[-1].val); } lispval Lgetloc() { chkarg(1,"getloc"); if(TYPE(lbot->val)!=BCD) error("ARGUMENT TO GETLOC MUST BE FUNCTION",FALSE); return(lbot->val->bcd.loctab); } lispval Lputloc() { chkarg(2,"putloc"); if(TYPE((lbot+1)->val)!=BCD); error("FIRST ARGUMENT TO PUTLOC MUST BE FUNCTION",FALSE); (lbot)->val->bcd.loctab = (lbot+1)->val; return((lbot+1)->val); } lispval Lmfunction() { register lispval handy; chkarg(2,"mfunction"); handy = (newfunct()); /* get a new function cell */ handy->bcd.start = (lispval (*)())((lbot)->val); /* insert entry point */ handy->bcd.discipline = ((lbot+1)->val); /* insert discipline */ return(handy); } /** Lreplace ************************************************************/ /* */ /* Destructively modifies almost any kind of data. */ lispval Lreplace() { register lispval a1, a2; register int t; chkarg(2,"replace"); if((t = TYPE(a1 = (lbot)->val)) != TYPE(a2 = np[-1].val)) error("REPLACE ARGS MUST BE SAME TYPE",FALSE); switch( t ) { case VALUE: a1->l = a2->l; return( a1 ); case INT: a1->i = a2->i; return( a1 ); case ARRAY: a1->ar.data = a2->ar.data; a1->ar.accfun = a2->ar.accfun; a1->ar.length = a2->ar.length; a1->ar.delta = a2->ar.delta; return( a1 ); case DOUB: a1->r = a2->r; return( a1 ); case SDOT: case DTPR: a1->d.car = a2->d.car; a1->d.cdr = a2->d.cdr; return( a1 ); case BCD: a1->bcd.start = a2->bcd.start; a1->bcd.discipline = a2->bcd.discipline; return( a1 ); default: errorh1(Vermisc,"Replace: cannot handle the type of this arg", nil,FALSE,0,a1); } /* NOTREACHED */ } /* Lvaluep */ lispval Lvaluep() { chkarg(1,"valuep"); if( TYPE(lbot->val) == VALUE ) return(tatom); else return(nil); } CNTTYP() { return; /* HI! COUNT ONE TYPE CALL! */ } lispval Lod() { int i; chkarg(2,"od"); while( TYPE(np[-1].val) != INT ) np[-1].val = error("2nd ARG TO OD MUST BE INTEGER",TRUE); for( i = 0; i < np->val->i; ++i ) printf(copval(odform,CNIL)->a.pname,((int *)(np[-2].val))[i]); dmpport(poport); return(nil); } lispval Lfake() { chkarg(1,"fake"); if( TYPE(lbot->val) != INT ) error("ARG TO FAKE MUST BE INTEGER",TRUE); return((lispval)(lbot->val->i)); } /* this used to be Lwhat, but was changed to Lmaknum for maclisp compatiblity */ lispval Lmaknum() { chkarg(1,"maknum"); return(inewint((int)(lbot->val))); } lispval Lderef() { chkarg(1,"deref"); if( TYPE(lbot->val) != INT ) error("arg to deref must be integer",TRUE); return(inewint(*(int *)(lbot->val->i))); } lispval Lpname() { chkarg(1,"pname"); if(TYPE(lbot->val) != ATOM) error("ARG TO PNAME MUST BE AN ATOM",FALSE); return((lispval)(lbot->val->a.pname)); } lispval Larayref() { chkarg(2,"arrayref"); if(TYPE((lbot)->val) != ARRAY) error("FIRST ARG TO ARRAYREF MUST BE ARRAY",FALSE); vtemp = (lbot + 1)->val; chek: while(TYPE(vtemp) != INT) vtemp = error("SECOND ARG TO ARRAYREF MUST BE INTEGER",TRUE); if( vtemp->i < 0 ) { vtemp = error("NEGATIVE ARRAY OFFSET",TRUE); goto chek; } if( vtemp->i >= (np-2)->val->ar.length->i ) { vtemp = error("ARRAY OFFSET TOO LARGE",TRUE); goto chek; } vtemp = (lispval)((np-2)->val->ar.data + ((np-2)->val->ar.delta->i)*(vtemp->i)); /* compute address of desired item */ return(vtemp); } lispval Lptr() { chkarg(1,"ptr"); return(inewval(lbot->val)); } lispval Llctrace() { chkarg(1,"lctrace"); lctrace = (int)(lbot->val->a.clb); return((lispval)lctrace); } lispval Lslevel() { return(inewint(np-orgnp-2)); } lispval Lsimpld() { register lispval pt; register char *cpt = strbuf; chkarg(1,"simpld"); for(atmlen=1, pt=np->val; NOTNIL(pt); ++atmlen, pt = pt->d.cdr); if( atmlen > STRBLEN ) { error("LCODE WAS TOO LONG",TRUE); return((lispval)inewstr("")); } for(pt=np->val; NOTNIL(pt); pt = pt->d.cdr) *(cpt++) = pt->d.car->i; *cpt = 0; return((lispval)newstr(1)); } /* Lopval *************************************************************/ /* */ /* Routine which allows system registers and options to be examined */ /* and modified. Calls copval, the routine which is called by c code */ /* to do the same thing from inside the system. */ lispval Lopval() { lispval quant; if( lbot == np ) return(error("bad call to opval",TRUE)); quant = lbot->val; /* get name of sys variable */ while( TYPE(quant) != ATOM ) quant = error("first arg to opval must be an atom",TRUE); if(np > lbot+1) vtemp = (lbot+1)->val ; else vtemp = CNIL; return(copval(quant,vtemp)); }