home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
languags
/
xlisp
/
xlisp11.ark
/
XLLIST.C
< prev
next >
Wrap
Text File
|
1986-10-12
|
12KB
|
515 lines
/* xllist - xlisp list builtin functions */
#ifdef AZTEC
#include "a:stdio.h"
#else
#include <stdio.h>
#endif
#include "xlisp.h"
/* external variables */
extern struct node *xlstack;
/* local variables */
static struct node *t;
static struct node *a_subr;
static struct node *a_list;
static struct node *a_sym;
static struct node *a_int;
static struct node *a_str;
static struct node *a_obj;
static struct node *a_fptr;
static struct node *a_kmap;
/* xlist - builtin function list */
static struct node *xlist(args)
struct node *args;
{
struct node *oldstk,arg,list,val,*last,*lptr;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,&val,NULL);
/* initialize */
arg.n_ptr = args;
/* evaluate and append each argument */
for (last = NULL; arg.n_ptr != NULL; last = lptr) {
/* evaluate the next argument */
val.n_ptr = xlevarg(&arg.n_ptr);
/* append this argument to the end of the list */
lptr = newnode(LIST);
if (last == NULL)
list.n_ptr = lptr;
else
last->n_listnext = lptr;
lptr->n_listvalue = val.n_ptr;
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the list */
return (list.n_ptr);
}
/* cond - builtin function cond */
static struct node *cond(args)
struct node *args;
{
struct node *oldstk,arg,list,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,NULL);
/* initialize */
arg.n_ptr = args;
/* initialize the return value */
val = NULL;
/* find a predicate that is true */
while (arg.n_ptr != NULL) {
/* get the next conditional */
list.n_ptr = xlmatch(LIST,&arg.n_ptr);
/* evaluate the predicate part */
if (xlevarg(&list.n_ptr) != NULL) {
/* evaluate each expression */
while (list.n_ptr != NULL)
val = xlevarg(&list.n_ptr);
/* exit the loop */
break;
}
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the value */
return (val);
}
/* atom - is this an atom? */
static struct node *atom(args)
struct node *args;
{
struct node *arg;
/* get the argument */
if ((arg = xlevarg(&args)) == NULL || arg->n_type != LIST)
return (t);
else
return (NULL);
}
/* null - is this null? */
static struct node *null(args)
struct node *args;
{
/* get the argument */
if (xlevarg(&args) == NULL)
return (t);
else
return (NULL);
}
/* type - return type of a thing */
static struct node *type(args)
struct node *args;
{
struct node *arg;
if (!(arg = xlevarg(&args)))
return (NULL);
switch (arg->n_type) {
case SUBR: return (a_subr);
case LIST: return (a_list);
case SYM: return (a_sym);
case INT: return (a_int);
case STR: return (a_str);
case OBJ: return (a_obj);
case FPTR: return (a_fptr);
case KMAP: return (a_kmap);
default: xlfail("Bad node.");
}
}
/* listp - is this a list? */
static struct node *listp(args)
struct node *args;
{
/* get the argument */
if (xlistp(xlevarg(&args)))
return (t);
else
return (NULL);
}
/* xlistp - internal listp function */
static int xlistp(arg)
struct node *arg;
{
return (arg == NULL || arg->n_type == LIST);
}
/* eq - are these equal? */
static struct node *eq(args)
struct node *args;
{
struct node *oldstk,arg,arg1,arg2,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,&arg1,&arg2,NULL);
/* initialize */
arg.n_ptr = args;
/* first argument */
arg1.n_ptr = xlevarg(&arg.n_ptr);
/* second argument */
arg2.n_ptr = xlevarg(&arg.n_ptr);
/* make sure there aren't any more arguments */
xllastarg(arg.n_ptr);
/* compare the arguments */
if (xeq(arg1.n_ptr,arg2.n_ptr))
val = t;
else
val = NULL;
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xeq - internal eq function */
static int xeq(arg1,arg2)
struct node *arg1,*arg2;
{
/* compare the arguments */
if (arg1 != NULL && arg1->n_type == INT &&
arg2 != NULL && arg2->n_type == INT)
return (arg1->n_int == arg2->n_int);
else
return (arg1 == arg2);
}
/* equal - are these equal? */
static struct node *equal(args)
struct node *args;
{
struct node *oldstk,arg,arg1,arg2,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,&arg1,&arg2,NULL);
/* initialize */
arg.n_ptr = args;
/* first argument */
arg1.n_ptr = xlevarg(&arg.n_ptr);
/* second argument */
arg2.n_ptr = xlevarg(&arg.n_ptr);
/* make sure there aren't any more arguments */
xllastarg(arg.n_ptr);
/* compare the arguments */
if (xequal(arg1.n_ptr,arg2.n_ptr))
val = t;
else
val = NULL;
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xequal - internal equal function */
static int xequal(arg1,arg2)
struct node *arg1,*arg2;
{
/* compare the arguments */
if (xeq(arg1,arg2))
return (TRUE);
else if (xlistp(arg1) && xlistp(arg2))
return (xequal(arg1->n_listvalue,arg2->n_listvalue) &&
xequal(arg1->n_listnext, arg2->n_listnext));
else
return (FALSE);
}
/* head - return the head of a list */
static struct node *head(args)
struct node *args;
{
struct node *list;
/* get the list */
if ((list = xlevmatch(LIST,&args)) == NULL)
xlfail("null list");
/* make sure this is the only argument */
xllastarg(args);
/* return the head of the list */
return (list->n_listvalue);
}
/* tail - return the tail of a list */
static struct node *tail(args)
struct node *args;
{
struct node *list;
/* get the list */
if ((list = xlevmatch(LIST,&args)) == NULL)
xlfail("null list");
/* make sure this is the only argument */
xllastarg(args);
/* return the tail of the list */
return (list->n_listnext);
}
/* nth - return the nth element of a list */
static struct node *nth(args)
struct node *args;
{
struct node *oldstk,arg,list;
int n;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,NULL);
/* initialize */
arg.n_ptr = args;
/* get n */
if ((n = xlevmatch(INT,&arg.n_ptr)->n_int) < 1)
xlfail("invalid argument");
/* get the list */
if ((list.n_ptr = xlevmatch(LIST,&arg.n_ptr)) == NULL)
xlfail("invalid argument");
/* make sure this is the only argument */
xllastarg(arg.n_ptr);
/* find the nth element */
for (; n > 1; n--) {
list.n_ptr = list.n_ptr->n_listnext;
if (list.n_ptr == NULL || list.n_ptr->n_type != LIST)
xlfail("invalid argument");
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the list nth list element */
return (list.n_ptr->n_listvalue);
}
/* length - return the length of a list */
static struct node *length(args)
struct node *args;
{
struct node *oldstk,list,*val;
int n;
/* create a new stack frame */
oldstk = xlsave(&list,NULL);
/* get the list */
list.n_ptr = xlevmatch(LIST,&args);
/* make sure this is the only argument */
xllastarg(args);
/* find the length */
for (n = 0; list.n_ptr != NULL; n++)
list.n_ptr = list.n_ptr->n_listnext;
/* restore the previous stack frame */
xlstack = oldstk;
/* create the value node */
val = newnode(INT);
val->n_int = n;
/* return the length */
return (val);
}
/* append - builtin function append */
static struct node *append(args)
struct node *args;
{
struct node *oldstk,arg,list,last,val,*lptr;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,&last,&val,NULL);
/* initialize */
arg.n_ptr = args;
/* evaluate and append each argument */
while (arg.n_ptr != NULL) {
/* evaluate the next argument */
list.n_ptr = xlevmatch(LIST,&arg.n_ptr);
/* append each element of this list to the result list */
while (list.n_ptr != NULL && list.n_ptr->n_type == LIST) {
/* append this element */
lptr = newnode(LIST);
if (last.n_ptr == NULL)
val.n_ptr = lptr;
else
last.n_ptr->n_listnext = lptr;
lptr->n_listvalue = list.n_ptr->n_listvalue;
/* save the new last element */
last.n_ptr = lptr;
/* move to the next element */
list.n_ptr = list.n_ptr->n_listnext;
}
/* make sure the list ended in a nil */
if (list.n_ptr != NULL)
xlfail("bad list");
}
/* restore previous stack frame */
xlstack = oldstk;
/* return the list */
return (val.n_ptr);
}
/* reverse - builtin function reverse */
static struct node *reverse(args)
struct node *args;
{
struct node *oldstk,list,val,*lptr;
/* create a new stack frame */
oldstk = xlsave(&list,&val,NULL);
/* get the list to reverse */
list.n_ptr = xlevmatch(LIST,&args);
/* make sure there aren't any more arguments */
xllastarg(args);
/* append each element of this list to the result list */
while (list.n_ptr != NULL && list.n_ptr->n_type == LIST) {
/* append this element */
lptr = newnode(LIST);
lptr->n_listvalue = list.n_ptr->n_listvalue;
lptr->n_listnext = val.n_ptr;
val.n_ptr = lptr;
/* move to the next element */
list.n_ptr = list.n_ptr->n_listnext;
}
/* make sure the list ended in a nil */
if (list.n_ptr != NULL)
xlfail("bad list");
/* restore previous stack frame */
xlstack = oldstk;
/* return the list */
return (val.n_ptr);
}
/* cons - construct a new list cell */
static struct node *cons(args)
struct node *args;
{
struct node *oldstk,arg,arg1,arg2,*lptr;
/* create a new stack frame */
oldstk = xlsave(&arg,&arg1,&arg2,NULL);
/* initialize */
arg.n_ptr = args;
/* first argument */
arg1.n_ptr = xlevarg(&arg.n_ptr);
/* second argument */
arg2.n_ptr = xlevarg(&arg.n_ptr);
/* make sure there aren't any more arguments */
xllastarg(arg.n_ptr);
/* construct a new list element */
lptr = newnode(LIST);
lptr->n_listvalue = arg1.n_ptr;
lptr->n_listnext = arg2.n_ptr;
/* restore the previous stack frame */
xlstack = oldstk;
/* return the list */
return (lptr);
}
/* xllinit - xlisp list initialization routine */
xllinit()
{
/* define some symbols */
t = xlenter("t");
a_subr = xlenter("SUBR");
a_list = xlenter("LIST");
a_sym = xlenter("SYM");
a_int = xlenter("INT");
a_str = xlenter("STR");
a_obj = xlenter("OBJ");
a_fptr = xlenter("FPTR");
a_kmap = xlenter("KMAP");
/* functions with reasonable names */
xlsubr("head",head);
xlsubr("tail",tail);
xlsubr("nth",nth);
/* real lisp functions */
xlsubr("atom",atom);
xlsubr("eq",eq);
xlsubr("equal",equal);
xlsubr("null",null);
xlsubr("type",type);
xlsubr("listp",listp);
xlsubr("cond",cond);
xlsubr("list",xlist);
xlsubr("cons",cons);
xlsubr("car",head);
xlsubr("cdr",tail);
xlsubr("append",append);
xlsubr("reverse",reverse);
xlsubr("length",length);
}