* (flatsize thing max) returns the smaller of max and the number of chars
* required to print thing linearly.
static flen
; /*Internal to this module, used as a running counter of flatsize*/
static fmax
; /*used for maximum for quick reference */
register lispval current
, temp
;
register struct argent
*mylbot
= lbot
;
snpand(3); /* fixup entry mask */
flen
= 0; fmax
= mylbot
[1].val
->i
;
protect(nil
); /*create space for argument to pntlen*/
* Iflatsi does the real work of the calculation for flatsize
register lispval current
;
if(flen
> fmax
) return(fmax
);
case INT
: case ATOM
: case DOUB
:
case INT
: case ATOM
: case DOUB
:
/* r *********************************************************************/
/* this function maps the desired read function into the system-defined */
/* reading functions after testing for a legal port. */
register char c
; register lispval result
;
int orlevel
; extern int rlevel
;
struct nament
*oldbnp
= bnp
;
result
= Vreadtable
->clb
;
ttemp
= okport(Vpiport
->clb
,stdin
);
ttemp
= okport(lbot
->val
,ttemp
);
/*printf("entering switch\n");*/
fflush(stdout
); /* flush any pending characters */
case EADC
: rlevel
= orlevel
;
switch (ctable
[c
= getc(ttemp
)] & 0377)
return((lispval
)getatom());
case ATOM
: rlevel
= orlevel
;
result
= (ratomr(ttemp
));
case EAD
: PUSHDOWN(Vpiport
,P(ttemp
)); /* rebind Vpiport */
popnames(oldbnp
); /* unwind bindings */
/* Lload *****************************************************************/
/* Reads in and executes forms from the specified file. This should */
/* really be an nlambda taking multiple arguments, but the error */
/* handling gets funny in that case (one file out of several not */
/* openable, for instance). */
register char *p
; register lispval ttemp
, vtemp
;
register struct argent
*lbot
, *np
;
struct nament
*oldbnp
= bnp
;
if(TYPE(ttemp
)!=ATOM
) return(error("FILENAME MUST BE ATOMIC",FALSE
));
strcpy(longname
,"/usr/lib/lisp/" );
for(p
= longname
; *p
; p
++);
if ((port
= fopen(shortname
,"r")) == NULL
&&
(port
= fopen(longname
, "r")) == NULL
) {
if ((port
= fopen(shortname
,"r")) == NULL
&&
(port
= fopen(longname
, "r")) == NULL
)
error("CAN'T OPEN FILE", FALSE
);
if(ISNIL(copval(gcload
,CNIL
)) &&
ISNIL(copval(gcdis
,CNIL
)))
gc(CNIL
); /* do a gc if gc will be off */
/* shallow bind the value of lisp atom piport */
/* so readmacros will work */
PUSHDOWN(Vpiport
,P(port
));
PUSHDOWN(loading
,tatom
); /* set indication of loading status */
while ((vtemp
= readr(port
)) != eofa
) {
popnames(oldbnp
); /* unbind piport, loading */
/* concat **************************************************
- use: (concat arg1 arg2 ... )
- concatenates the print names of all of its arguments.
- the arguments may be atoms, integers or real numbers.
- *********************************************************/
register struct argent
*temnp
;
register int atmlen
; /* Passt auf! atmlen in the external
sense calculated by newstr */
/* loop for each argument */
for(temnp
= lbot
+ AD
; temnp
< np
; temnp
++)
strcpy(&strbuf
[atmlen
], ((struct atom
*) cur
) -> pname
) ;
sprintf(&strbuf
[atmlen
],"%d",cur
->i
);
sprintf(&strbuf
[atmlen
],"%f",cur
->f
);
cur
= error("Non atom or number to concat",TRUE
);
goto loop
; /* if returns value, try it */
return( (lispval
) newatom());
return( (lispval
) getatom()) ;
register struct argent
*argp
= lbot
;
return(Iputprop(argp
->val
,argp
[1].val
,argp
[2].val
));
register lispval prop
, ind
, atm
;
lispval
*tack
; /* place to begin property list */
if(atm
== nil
) tack
= &nilplist
;
else tack
= &(atm
->plist
);
for (pptr
= atm
->cdr
; pptr
!= nil
; pptr
= pptr
->cdr
->cdr
)
if(TYPE(pptr
) != DTPR
|| TYPE(pptr
->cdr
) != DTPR
) break;
"putprop: bad disembodied property list",
tack
= (lispval
*) &(atm
->cdr
);
errorh(Vermisc
,"putprop: Bad first argument: ",nil
,FALSE
,0,atm
);
pptr
= *tack
; /* start of property list */
for (pptr
= *tack
; pptr
!= nil
; pptr
= pptr
->cdr
->cdr
)
else tack
= &(pptr
->cdr
->cdr
) ;
pptr
= pptr
->cdr
= (lispval
) newdot();
/* get from property list
* there are three routines to accomplish this
* Lget - lisp callable, the first arg can be a symbol or a disembodied
* property list. In the latter case we check to make sure it
* is a real one (as best we can).
* Iget - internal routine, the first arg must be a symbol, no disembodied
* Igetplist - internal routine, the first arg is the plist to search.
register lispval ind
, atm
;
register lispval dum1
, dum2
;
if(atm
==nil
) atm
= nilplist
;
for (dum1
= atm
->cdr
; dum1
!= nil
; dum1
= dum1
->cdr
->cdr
)
if((TYPE(dum1
) != DTPR
) ||
(TYPE(dum1
->cdr
) != DTPR
)) break; /* bad prop list */
"putprop: bad disembodied property list",
/* remove since maclisp doesnt treat
return(errorh(Vermisc,"get: bad first argument: ",
return(Igetplist(atm
,ind
));
* Iget - the first arg must be a symbol.
register lispval atm
, ind
;
return(Igetplist(atm
,ind
));
register lispval pptr
,ind
;
return ((pptr
->cdr
)->car
);
"getd: ONLY ATOMS HAVE FUNCTION DEFINITIONS",
register lispval atom
, list
;
register lispval dum1
, dum2
;
register struct argent
*lbot
, *np
;
if (TYPE(atom
) != ATOM
) error("ONLY ATOMS HAVE FUNCTION DEFINITIONS",FALSE
);
/* ===========================================================
- mapping functions which return a list of the answers
- mapcar applies the given function to successive elements
- maplist applies the given function to successive sublists
- ===========================================================*/
int maptyp
; /* 0 = mapcar, 1 = maplist */
int join
; /* 0 = the above, 1 = s/car/can/ */
register struct argent
*namptr
;
register lispval current
;
register struct argent
*lbot
;
register struct argent
*np
;
struct argent
*first
, *last
;
lispval lists
[25], result
;
if (count
<= 0) return (nil
);
/*oldlbot = lbot; /* lbot saved by virtue of entry mask */
result
= current
= (lispval
) np
;
protect(nil
); /* set up space for returned list */
protect(lbot
->val
); /*copy funarg for call to funcall */
for(index
= 0; index
< count
; index
++) {
if (TYPE (temp
) != DTPR
&& temp
!=nil
)
error ( "bad list argument to map",FALSE
);
for(namptr
=first
,index
=0; index
<count
; index
++) {
if(maptyp
==0) (namptr
++)->val
= temp
->car
;
else (namptr
++)->val
= temp
;
lists
[index
] = temp
->cdr
;
current
->l
->car
= Lfuncal();
current
= (lispval
) ¤t
->l
->cdr
;
if ( TYPE ( current
-> l
) != DTPR
&& current
->l
!= nil
)
error("bad type returned from funcall inside map",FALSE
);
else while ( current
-> l
!= nil
)
current
= (lispval
) & (current
->l
->cdr
);
done
: if (join
== 0)current
->l
= nil
;
/* ============================
- =============================*/
return(Lmapcrx(0,0)); } /* call general routine */
/* ============================
- ==============================*/
return(Lmapcrx(1,0)); } /* call general routine */
/* ================================================
- mapping functions which return the value of the last function application.
- ===================================================*/
int maptyp
; /* 0= mapc , 1= map */
register struct argent
*namptr
;
register struct argent
*lbot
;
register struct argent
*np
;
lispval lists
[25], errorh();
if(count
<= 0) return(nil
);
result
= lbot
[1].val
; /*This is what macsyma wants so ... */
/*copy funarg for call to funcall */
lbot
= np
; protect((namptr
- 1)->val
);
for(index
= 0; index
< count
; index
++) {
while(temp
!=nil
&& TYPE(temp
)!=DTPR
)
temp
= errorh(Vermisc
,"Inappropriate list argument to mapc",nil
,TRUE
,0,temp
);
for(namptr
=first
,index
=0; index
<count
; index
++) {
(namptr
++)->val
= temp
->car
;
lists
[index
] = temp
->cdr
;
/* ==================================
- mapc map the car of the lists
- ==================================*/
/* =================================
- map map the cdr of the lists
- ===================================*/
return ( Lmapcrx ( 0,1 ) );
return ( Lmapcrx ( 1,1 ) );