home *** CD-ROM | disk | FTP | other *** search
- /* xlmath - xlisp builtin arithmetic 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 *true;
-
- /* forward declarations (the extern hack is for decusc) */
- extern struct node *arith();
- extern struct node *compare();
-
- /* add - builtin function for addition */
- static int xadd(val,arg)
- int val,arg;
- {
- return (val + arg);
- }
- static struct node *add(args)
- struct node *args;
- {
- return (arith(args,xadd));
- }
-
- /* sub - builtin function for subtraction */
- static int xsub(val,arg)
- int val,arg;
- {
- return (val - arg);
- }
- static struct node *sub(args)
- struct node *args;
- {
- return (arith(args,xsub));
- }
-
- /* mul - builtin function for multiplication */
- static int xmul(val,arg)
- int val,arg;
- {
- return (val * arg);
- }
- static struct node *mul(args)
- struct node *args;
- {
- return (arith(args,xmul));
- }
-
- /* div - builtin function for division */
- static int xdiv(val,arg)
- int val,arg;
- {
- return (val / arg);
- }
- static struct node *div(args)
- struct node *args;
- {
- return (arith(args,xdiv));
- }
-
- /* mod - builtin function for modulus */
- static int xmod(val,arg)
- int val,arg;
- {
- return (val % arg);
- }
- static struct node *mod(args)
- struct node *args;
- {
- return (arith(args,xmod));
- }
-
- /* and - builtin function for modulus */
- static int xand(val,arg)
- int val,arg;
- {
- return (val & arg);
- }
- static struct node *and(args)
- struct node *args;
- {
- return (arith(args,xand));
- }
-
- /* or - builtin function for modulus */
- static int xor(val,arg)
- int val,arg;
- {
- return (val | arg);
- }
- static struct node *or(args)
- struct node *args;
- {
- return (arith(args,xor));
- }
-
- /* not - bitwise not */
- static struct node *not(args)
- struct node *args;
- {
- struct node *rval;
- int val;
-
- /* evaluate the argument */
- val = xlevmatch(INT,&args)->n_int;
-
- /* make sure there aren't any more arguments */
- xllastarg(args);
-
- /* convert and check the value */
- rval = newnode(INT);
- rval->n_int = ~val;
-
- /* return the result value */
- return (rval);
- }
-
- /* abs - absolute value */
- static struct node *abs(args)
- struct node *args;
- {
- struct node *rval;
- int val;
-
- /* evaluate the argument */
- val = xlevmatch(INT,&args)->n_int;
-
- /* make sure there aren't any more arguments */
- xllastarg(args);
-
- /* convert and check the value */
- rval = newnode(INT);
- rval->n_int = val >= 0 ? val : -val ;
-
- /* return the result value */
- return (rval);
- }
-
- /* min - builtin function for minimum */
- static int xmin(val,arg)
- int val,arg;
- {
- return (val < arg ? val : arg);
- }
- static struct node *min(args)
- struct node *args;
- {
- return (arith(args,xmin));
- }
-
- /* max - builtin function for maximum */
- static int xmax(val,arg)
- int val,arg;
- {
- return (val > arg ? val : arg);
- }
- static struct node *max(args)
- struct node *args;
- {
- return (arith(args,xmax));
- }
-
- /* arith - common arithmetic function */
- static struct node *arith(args,funct)
- struct node *args; int (*funct)();
- {
- struct node *oldstk,arg,*val;
- int first,ival,iarg;
-
- /* create a new stack frame */
- oldstk = xlsave(&arg,NULL);
-
- /* initialize */
- arg.n_ptr = args;
- first = TRUE;
- ival = 0;
-
- /* evaluate and sum each argument */
- while (arg.n_ptr != NULL) {
-
- /* get the next argument */
- iarg = xlevmatch(INT,&arg.n_ptr)->n_int;
-
- /* accumulate the result value */
- if (first) {
- ival = iarg;
- first = FALSE;
- }
- else
- ival = (*funct)(ival,iarg);
- }
-
- /* initialize value */
- val = newnode(INT);
- val->n_int = ival;
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the result value */
- return (val);
- }
-
- /* land - logical and */
- static struct node *land(args)
- struct node *args;
- {
- struct node *oldstk,arg,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&arg,NULL);
-
- /* initialize */
- arg.n_ptr = args;
- val = true;
-
- /* evaluate each argument */
- while (arg.n_ptr != NULL)
-
- /* get the next argument */
- if (xlevarg(&arg.n_ptr) == NULL) {
- val = NULL;
- break;
- }
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the result value */
- return (val);
- }
-
- /* lor - logical or */
- static struct node *lor(args)
- struct node *args;
- {
- struct node *oldstk,arg,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&arg,NULL);
-
- /* initialize */
- arg.n_ptr = args;
- val = NULL;
-
- /* evaluate each argument */
- while (arg.n_ptr != NULL)
- if (xlevarg(&arg.n_ptr) != NULL) {
- val = true;
- break;
- }
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the result value */
- return (val);
- }
-
- /* lnot - logical not */
- static struct node *lnot(args)
- struct node *args;
- {
- struct node *val;
-
- /* evaluate the argument */
- val = xlevarg(&args);
-
- /* make sure there aren't any more arguments */
- xllastarg(args);
-
- /* convert and check the value */
- if (val == NULL)
- return (true);
- else
- return (NULL);
- }
-
- /* lss - builtin function for < */
- static int xlss(cmp)
- int cmp;
- {
- return (cmp < 0);
- }
- static struct node *lss(args)
- struct node *args;
- {
- return (compare(args,xlss));
- }
-
- /* leq - builtin function for <= */
- static int xleq(cmp)
- int cmp;
- {
- return (cmp <= 0);
- }
- static struct node *leq(args)
- struct node *args;
- {
- return (compare(args,xleq));
- }
-
- /* eql - builtin function for == */
- static int xeql(cmp)
- int cmp;
- {
- return (cmp == 0);
- }
- static struct node *eql(args)
- struct node *args;
- {
- return (compare(args,xeql));
- }
-
- /* neq - builtin function for != */
- static int xneq(cmp)
- int cmp;
- {
- return (cmp != 0);
- }
- static struct node *neq(args)
- struct node *args;
- {
- return (compare(args,xneq));
- }
-
- /* geq - builtin function for >= */
- static int xgeq(cmp)
- int cmp;
- {
- return (cmp >= 0);
- }
- static struct node *geq(args)
- struct node *args;
- {
- return (compare(args,xgeq));
- }
-
- /* gtr - builtin function for > */
- static int xgtr(cmp)
- int cmp;
- {
- return (cmp > 0);
- }
- static struct node *gtr(args)
- struct node *args;
- {
- return (compare(args,xgtr));
- }
-
- /* compare - common compare function */
- static struct node *compare(args,funct)
- struct node *args; int (*funct)();
- {
- struct node *oldstk,arg,arg1,arg2;
- int type1,type2,cmp;
-
- /* create a new stack frame */
- oldstk = xlsave(&arg,&arg1,&arg2,NULL);
-
- /* initialize */
- arg.n_ptr = args;
-
- /* get argument 1 */
- arg1.n_ptr = xlevarg(&arg.n_ptr);
- type1 = gettype(arg1.n_ptr);
-
- /* get argument 2 */
- arg2.n_ptr = xlevarg(&arg.n_ptr);
- type2 = gettype(arg2.n_ptr);
-
- /* make sure there aren't any more arguments */
- xllastarg(arg.n_ptr);
-
- /* do the compare */
- if (type1 == STR && type2 == STR)
- cmp = strcmp(arg1.n_ptr->n_str,arg2.n_ptr->n_str);
- else if (type1 == INT && type2 == INT)
- cmp = arg1.n_ptr->n_int - arg2.n_ptr->n_int;
- else
- cmp = arg1.n_ptr - arg2.n_ptr;
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return result of the compare */
- if ((*funct)(cmp))
- return (true);
- else
- return (NULL);
- }
-
- /* gettype - return the type of an argument */
- static int gettype(arg)
- struct node *arg;
- {
- if (arg == NULL)
- return (LIST);
- else
- return (arg->n_type);
- }
-
- /* xlminit - xlisp math initialization routine */
- xlminit()
- {
- xlsubr("+",add);
- xlsubr("-",sub);
- xlsubr("*",mul);
- xlsubr("/",div);
- xlsubr("%",mod);
- xlsubr("&",and);
- xlsubr("|",or);
- xlsubr("~",not);
- xlsubr("<",lss);
- xlsubr("<=",leq);
- xlsubr("==",eql);
- xlsubr("!=",neq);
- xlsubr(">=",geq);
- xlsubr(">",gtr);
- xlsubr("&&",land);
- xlsubr("||",lor);
- xlsubr("!",lnot);
- xlsubr("min",min);
- xlsubr("max",max);
- xlsubr("abs",abs);
- true = xlenter("t");
- true->n_symvalue = true;
- }
-