/* xlmath - xlisp builtin arithmetic functions */ #ifdef AZTEC #include "stdio.h" #else #include #endif #include "xlisp.h" /* external variables */ extern struct node *xlstack; extern struct node *true; /* forward declarations */ FORWARD struct node *unary(); FORWARD struct node *binary(); FORWARD struct node *compare(); /* xadd - builtin function for addition */ LOCAL int add(val,arg) int val,arg; { return (val + arg); } struct node *xadd(args) struct node *args; { return (binary(args,add)); } /* xsub - builtin function for subtraction */ LOCAL int sub(val,arg) int val,arg; { return (val - arg); } struct node *xsub(args) struct node *args; { return (binary(args,sub)); } /* xmul - builtin function for multiplication */ LOCAL int mul(val,arg) int val,arg; { return (val * arg); } struct node *xmul(args) struct node *args; { return (binary(args,mul)); } /* xdiv - builtin function for division */ LOCAL int div(val,arg) int val,arg; { return (val / arg); } struct node *xdiv(args) struct node *args; { return (binary(args,div)); } /* xrem - builtin function for remainder */ LOCAL int rem(val,arg) int val,arg; { return (val % arg); } struct node *xrem(args) struct node *args; { return (binary(args,rem)); } /* xmin - builtin function for minimum */ LOCAL int min(val,arg) int val,arg; { return (val < arg ? val : arg); } struct node *xmin(args) struct node *args; { return (binary(args,min)); } /* xmax - builtin function for maximum */ LOCAL int max(val,arg) int val,arg; { return (val > arg ? val : arg); } struct node *xmax(args) struct node *args; { return (binary(args,max)); } /* xbitand - builtin function for bitwise and */ LOCAL int bitand(val,arg) int val,arg; { return (val & arg); } struct node *xbitand(args) struct node *args; { return (binary(args,bitand)); } /* xbitior - builtin function for bitwise inclusive or */ LOCAL int bitior(val,arg) int val,arg; { return (val | arg); } struct node *xbitior(args) struct node *args; { return (binary(args,bitior)); } /* xbitxor - builtin function for bitwise exclusive or */ LOCAL int bitxor(val,arg) int val,arg; { return (val ^ arg); } struct node *xbitxor(args) struct node *args; { return (binary(args,bitxor)); } /* xbitnot - bitwise not */ LOCAL int bitnot(arg) int arg; { return (~arg); } struct node *xbitnot(args) struct node *args; { return (unary(args,bitnot)); } /* xabs - builtin function for absolute value */ LOCAL int abs(arg) int arg; { return (arg >= 0 ? arg : -arg); } struct node *xabs(args) struct node *args; { return (unary(args,abs)); } /* xadd1 - builtin function for adding one */ LOCAL int add1(arg) int arg; { return (arg + 1); } struct node *xadd1(args) struct node *args; { return (unary(args,add1)); } /* xsub1 - builtin function for subtracting one */ LOCAL int sub1(arg) int arg; { return (arg - 1); } struct node *xsub1(args) struct node *args; { return (unary(args,sub1)); } /* xminus - negate a value */ LOCAL int minus(arg) int arg; { return (-arg); } struct node *xminus(args) struct node *args; { return (unary(args,minus)); } /* unary - handle unary operations */ LOCAL struct node *unary(args,fcn) struct node *args; int (*fcn)(); { struct node *rval; int val; /* evaluate the argument */ val = xlmatch(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 = (*fcn)(val); /* return the result value */ return (rval); } /* binary - handle binary operations */ LOCAL struct node *binary(args,funct) struct node *args; int (*funct)(); { int first,ival,iarg; struct node *val; /* initialize */ first = TRUE; ival = 0; /* evaluate and sum each argument */ while (args != NULL) { /* get the next argument */ iarg = xlmatch(INT,&args)->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; /* return the result value */ return (val); } /* xlss - builtin function for < */ LOCAL int lss(cmp) int cmp; { return (cmp < 0); } struct node *xlss(args) struct node *args; { return (compare(args,lss)); } /* xleq - builtin function for <= */ LOCAL int leq(cmp) int cmp; { return (cmp <= 0); } struct node *xleq(args) struct node *args; { return (compare(args,leq)); } /* eql - builtin function for = */ LOCAL int eql(cmp) int cmp; { return (cmp == 0); } struct node *xeql(args) struct node *args; { return (compare(args,eql)); } /* xneq - builtin function for /= */ LOCAL int neq(cmp) int cmp; { return (cmp != 0); } struct node *xneq(args) struct node *args; { return (compare(args,neq)); } /* xgeq - builtin function for >= */ LOCAL int geq(cmp) int cmp; { return (cmp >= 0); } struct node *xgeq(args) struct node *args; { return (compare(args,geq)); } /* xgtr - builtin function for > */ LOCAL int gtr(cmp) int cmp; { return (cmp > 0); } struct node *xgtr(args) struct node *args; { return (compare(args,gtr)); } /* compare - common compare function */ LOCAL struct node *compare(args,funct) struct node *args; int (*funct)(); { struct node *arg1,*arg2; int type1,type2,cmp; /* get argument 1 */ arg1 = xlarg(&args); type1 = gettype(arg1); /* get argument 2 */ arg2 = xlarg(&args); type2 = gettype(arg2); /* make sure there aren't any more arguments */ xllastarg(args); /* do the compare */ if (type1 == STR && type2 == STR) cmp = strcmp(arg1->n_str,arg2->n_str); else if (type1 == INT && type2 == INT) cmp = arg1->n_int - arg2->n_int; else cmp = arg1 - arg2; /* return result of the compare */ if ((*funct)(cmp)) return (true); else return (NULL); } /* gettype - return the type of an argument */ LOCAL int gettype(arg) struct node *arg; { if (arg == NULL) return (LIST); else return (arg->n_type); }