home *** CD-ROM | disk | FTP | other *** search
- /* xsfun2.c - xscheme built-in functions - part 2 */
- /* Copyright (c) 1988, by David Michael Betz
- All Rights Reserved
- Permission is granted for unrestricted non-commercial use */
-
- #include "xscheme.h"
-
- /* external variables */
- extern jmp_buf top_level;
- extern LVAL eof_object,true_lval;
- extern LVAL xlfun,xlenv,xlval;
- extern int prbreadth,prdepth;
- extern FILE *tfp;
-
- /* external routines */
- extern xlprin1(),xlprinc();
-
- /* forward declarations */
- FORWARD LVAL setit();
- FORWARD LVAL strcompare();
- FORWARD LVAL chrcompare();
-
- /* xapply - built-in function 'apply' */
- LVAL xapply()
- {
- LVAL args,*p;
-
- /* get the function and argument list */
- xlval = xlgetarg();
- args = xlgalist();
- xllastarg();
-
- /* get the argument count and make space on the stack */
- xlargc = length(args);
- check(xlargc);
-
- /* copy the arguments onto the stack */
- for (xlsp -= xlargc, p = xlsp; consp(args); args = cdr(args))
- *p++ = car(args);
-
- /* apply the function to the arguments */
- xlapply();
- }
-
- /* xcallcc - built-in function 'call-with-current-continuation' */
- LVAL xcallcc()
- {
- LVAL cont,*src,*dst;
- int size;
-
- /* get the function to call */
- xlval = xlgetarg();
- xllastarg();
-
- /* create a continuation object */
- size = (int)(xlstktop - xlsp);
- cont = newcontinuation(size);
- for (src = xlsp, dst = &cont->n_vdata[0]; --size >= 0; )
- *dst++ = *src++;
-
- /* setup the argument list */
- cpush(cont);
- xlargc = 1;
-
- /* apply the function */
- xlapply();
- }
-
- /* xmap - built-in function 'map' */
- LVAL xmap()
- {
- if (xlargc < 2) xltoofew();
- xlval = NIL;
- do_maploop(NIL);
- }
-
- /* do_maploop - setup for the next application */
- do_maploop(last)
- LVAL last;
- {
- extern LVAL cs_map1;
- LVAL *oldsp,*p,x;
- int cnt;
-
- /* get a pointer to the end of the argument list */
- p = &xlsp[xlargc];
- oldsp = xlsp;
-
- /* save a continuation */
- if (xlval) { check(5); push(xlval); push(last); }
- else { check(4); push(NIL); }
- push(cvfixnum((FIXTYPE)xlargc));
- push(cs_map1);
- push(xlenv);
-
- /* build the argument list for the next application */
- for (cnt = xlargc; --cnt >= 1; ) {
- x = *--p;
- if (consp(x)) {
- cpush(car(x));
- *p = cdr(x);
- }
- else {
- xlsp = oldsp;
- drop(xlargc);
- xlreturn();
- return;
- }
- }
- xlval = *--p; /* get the function to apply */
- xlargc -= 1; /* count shouldn't include the function itself */
- xlapply(); /* apply the function */
- }
-
- /* xmap1 - continuation for xmap */
- LVAL xmap1()
- {
- LVAL last,tmp;
-
- /* get the argument count */
- tmp = pop();
-
- /* get the tail of the value list */
- if (last = pop()) {
- rplacd(last,cons(xlval,NIL)); /* add the new value to the tail */
- last = cdr(last); /* remember the new tail */
- xlval = pop(); /* restore the head of the list */
- }
- else
- xlval = last = cons(xlval,NIL); /* build the initial value list */
-
- /* convert the argument count and loop */
- xlargc = (int)getfixnum(tmp);
- do_maploop(last);
- }
-
- /* xforeach - built-in function 'for-each' */
- LVAL xforeach()
- {
- if (xlargc < 2) xltoofew();
- do_forloop();
- }
-
- /* do_forloop - setup for the next application */
- do_forloop()
- {
- extern LVAL cs_foreach1;
- LVAL *oldsp,*p,x;
- int cnt;
-
- /* get a pointer to the end of the argument list */
- p = &xlsp[xlargc];
- oldsp = xlsp;
-
- /* save a continuation */
- check(3);
- push(cvfixnum((FIXTYPE)xlargc));
- push(cs_foreach1);
- push(xlenv);
-
- /* build the argument list for the next application */
- for (cnt = xlargc; --cnt >= 1; ) {
- x = *--p;
- if (consp(x)) {
- cpush(car(x));
- *p = cdr(x);
- }
- else {
- xlsp = oldsp;
- drop(xlargc);
- xlval = NIL;
- xlreturn();
- return;
- }
- }
- xlval = *--p; /* get the function to apply */
- xlargc -= 1; /* count shouldn't include the function itself */
- xlapply(); /* apply the function */
- }
-
- /* xforeach1 - continuation for xforeach */
- LVAL xforeach1()
- {
- LVAL tmp;
-
- /* get the argument count */
- tmp = pop();
-
- /* convert the argument count and loop */
- xlargc = (int)getfixnum(tmp);
- do_forloop();
- }
-
- /* xcallwi - built-in function 'call-with-input-file' */
- LVAL xcallwi()
- {
- do_withfile(PF_INPUT,"r");
- }
-
- /* xcallwo - built-in function 'call-with-output-file' */
- LVAL xcallwo()
- {
- do_withfile(PF_OUTPUT,"w");
- }
-
- /* do_withfile - handle the 'call-with-xxx-file' functions */
- do_withfile(flags,mode)
- int flags; char *mode;
- {
- extern LVAL cs_withfile1;
- extern FILE *osaopen();
- LVAL name,file;
- FILE *fp;
-
- /* get the function to call */
- name = xlgastring();
- xlval = xlgetarg();
- xllastarg();
-
- /* create a file object */
- file = cvport(NULL,flags);
- if ((fp = osaopen(getstring(name),mode)) == NULL)
- xlerror("can't open file",name);
- setfile(file,fp);
-
- /* save a continuation */
- check(3);
- push(file);
- push(cs_withfile1);
- push(xlenv);
-
- /* setup the argument list */
- cpush(file);
- xlargc = 1;
-
- /* apply the function */
- xlapply();
- }
-
- /* xwithfile1 - continuation for xcallwi and xcallwo */
- LVAL xwithfile1()
- {
- osclose(getfile(top()));
- setfile(pop(),NULL);
- xlreturn();
- }
-
- /* xload - built-in function 'load' */
- LVAL xload()
- {
- do_load(NIL);
- }
-
- /* xloadnoisily - built-in function 'load-noisily' */
- LVAL xloadnoisily()
- {
- do_load(true_lval);
- }
-
- /* do_load - open the file and setup the load loop */
- do_load(print)
- LVAL print;
- {
- extern FILE *osaopen();
- LVAL file;
- FILE *fp;
-
- /* get the function to call */
- xlval = xlgastring();
- xllastarg();
-
- /* create a file object */
- file = cvport(NULL,PF_INPUT);
- if ((fp = osaopen(getstring(xlval),"r")) == NULL) {
- xlval = NIL;
- xlreturn();
- return;
- }
- setfile(file,fp);
- xlval = file;
-
- /* do the first read */
- do_loadloop(print);
- }
-
- /* do_loadloop - read the next expression and setup to evaluate it */
- do_loadloop(print)
- LVAL print;
- {
- extern LVAL cs_load1,s_eval;
- LVAL expr;
-
- /* try to read the next expression from the file */
- if (xlread(xlval,&expr)) {
-
- /* save a continuation */
- check(4);
- push(xlval);
- push(print);
- push(cs_load1);
- push(xlenv);
-
- /* setup the argument list */
- xlval = getvalue(s_eval);
- cpush(expr);
- xlargc = 1;
-
- /* apply the function */
- xlapply();
- }
- else {
- osclose(getfile(xlval));
- setfile(xlval,NULL);
- xlval = true_lval;
- xlreturn();
- }
- }
-
- /* xload1 - continuation for xload */
- LVAL xload1()
- {
- LVAL print;
-
- /* print the value if the print variable is set */
- if (print = pop()) {
- xlprin1(xlval,curoutput());
- xlterpri(curoutput());
- }
- xlval = pop();
-
- /* setup for the next read */
- do_loadloop(print);
- }
-
- /* xforce - built-in function 'force' */
- LVAL xforce()
- {
- extern LVAL cs_force1;
-
- /* get the promise */
- xlval = xlgetarg();
- xllastarg();
-
- /* check for a promise */
- if (promisep(xlval)) {
-
- /* force the promise the first time */
- if ((xlfun = getpproc(xlval)) != NIL) {
- check(3);
- push(xlval);
- push(cs_force1);
- push(xlenv);
- xlval = xlfun;
- xlargc = 0;
- xlapply();
- }
-
- /* return the saved value if the promise has already been forced */
- else {
- xlval = getpvalue(xlval);
- xlreturn();
- }
-
- }
-
- /* otherwise, just return the argument */
- else
- xlreturn();
- }
-
- /* xforce1 - continuation for xforce */
- LVAL xforce1()
- {
- LVAL promise;
- promise = pop();
- setpvalue(promise,xlval);
- setpproc(promise,NIL);
- xlreturn();
- }
-
- /* xsymstr - built-in function 'symbol->string' */
- LVAL xsymstr()
- {
- xlval = xlgasymbol();
- xllastarg();
- return (getpname(xlval));
- }
-
- /* xstrsym - built-in function 'string->symbol' */
- LVAL xstrsym()
- {
- xlval = xlgastring();
- xllastarg();
- return (xlenter(getstring(xlval)));
- }
-
- /* xread - built-in function 'read' */
- LVAL xread()
- {
- LVAL fptr,val;
-
- /* get file pointer and eof value */
- fptr = (moreargs() ? xlgaiport() : curinput());
- xllastarg();
-
- /* read an expression */
- if (!xlread(fptr,&val))
- val = eof_object;
-
- /* return the expression */
- return (val);
- }
-
- /* xrdchar - built-in function 'read-char' */
- LVAL xrdchar()
- {
- LVAL fptr;
- int ch;
- fptr = (moreargs() ? xlgaiport() : curinput());
- xllastarg();
- return ((ch = xlgetc(fptr)) == EOF ? eof_object : cvchar(ch));
- }
-
- /* xrdbyte - built-in function 'read-byte' */
- LVAL xrdbyte()
- {
- LVAL fptr;
- int ch;
- fptr = (moreargs() ? xlgaiport() : curinput());
- xllastarg();
- return ((ch = xlgetc(fptr)) == EOF ? eof_object : cvfixnum((FIXTYPE)ch));
- }
-
- /* xrdshort - built-in function 'read-short' */
- LVAL xrdshort()
- {
- unsigned char *p;
- short int val=0;
- LVAL fptr;
- int ch,n;
- fptr = (moreargs() ? xlgaiport() : curinput());
- xllastarg();
- for (n = sizeof(short int), p = (unsigned char *)&val; --n >= 0; ) {
- if ((ch = xlgetc(fptr)) == EOF)
- return (eof_object);
- *p++ = ch;
- }
- return (cvfixnum((FIXTYPE)val));
- }
-
- /* xrdlong - built-in function 'read-long' */
- LVAL xrdlong()
- {
- unsigned char *p;
- long int val=0;
- LVAL fptr;
- int ch,n;
- fptr = (moreargs() ? xlgaiport() : curinput());
- xllastarg();
- for (n = sizeof(long int), p = (unsigned char *)&val; --n >= 0; ) {
- if ((ch = xlgetc(fptr)) == EOF)
- return (eof_object);
- *p++ = ch;
- }
- return (cvfixnum((FIXTYPE)val));
- }
-
- /* xeofobjectp - built-in function 'eof-object?' */
- LVAL xeofobjectp()
- {
- LVAL arg;
- arg = xlgetarg();
- xllastarg();
- return (arg == eof_object ? true_lval : NIL);
- }
-
- /* xwrite - built-in function 'write' */
- LVAL xwrite()
- {
- LVAL fptr,val;
-
- /* get expression to print and file pointer */
- val = xlgetarg();
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
-
- /* print the value */
- xlprin1(val,fptr);
- return (true_lval);
- }
-
- /* xprint - built-in function 'print' */
- LVAL xprint()
- {
- LVAL fptr,val;
-
- /* get expression to print and file pointer */
- val = xlgetarg();
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
-
- /* print the value */
- xlprin1(val,fptr);
- xlterpri(fptr);
- return (true_lval);
- }
-
- /* xwrchar - built-in function 'write-char' */
- LVAL xwrchar()
- {
- LVAL fptr,ch;
- ch = xlgachar();
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
- xlputc(fptr,(int)getchcode(ch));
- return (true_lval);
- }
-
- /* xwrbyte - built-in function 'write-byte' */
- LVAL xwrbyte()
- {
- LVAL fptr,ch;
- ch = xlgafixnum();
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
- xlputc(fptr,(int)getfixnum(ch));
- return (true_lval);
- }
-
- /* xwrshort - built-in function 'write-short' */
- LVAL xwrshort()
- {
- unsigned char *p;
- short int val;
- LVAL fptr,v;
- int n;
- v = xlgafixnum(); val = (short int)getfixnum(v);
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
- for (n = sizeof(short int), p = (unsigned char *)&val; --n >= 0; )
- xlputc(fptr,*p++);
- return (true_lval);
- }
-
- /* xwrlong - built-in function 'write-long' */
- LVAL xwrlong()
- {
- unsigned char *p;
- long int val;
- LVAL fptr,v;
- int n;
- v = xlgafixnum(); val = (long int)getfixnum(v);
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
- for (n = sizeof(long int), p = (unsigned char *)&val; --n >= 0; )
- xlputc(fptr,*p++);
- return (true_lval);
- }
-
- /* xdisplay - built-in function 'display' */
- LVAL xdisplay()
- {
- LVAL fptr,val;
-
- /* get expression to print and file pointer */
- val = xlgetarg();
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
-
- /* print the value */
- xlprinc(val,fptr);
- return (true_lval);
- }
-
- /* xnewline - terminate the current print line */
- LVAL xnewline()
- {
- LVAL fptr;
-
- /* get file pointer */
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
-
- /* terminate the print line and return nil */
- xlterpri(fptr);
- return (true_lval);
- }
-
- /* xprbreadth - set the maximum number of elements to be printed */
- LVAL xprbreadth()
- {
- return (setit(&prbreadth));
- }
-
- /* xprdepth - set the maximum depth of nested lists to be printed */
- LVAL xprdepth()
- {
- return (setit(&prdepth));
- }
-
- /* setit - common routine for prbreadth/prdepth */
- LOCAL LVAL setit(pvar)
- int *pvar;
- {
- LVAL arg;
-
- /* get the optional argument */
- if (moreargs()) {
- arg = xlgetarg();
- xllastarg();
- *pvar = (fixp(arg) ? (int)getfixnum(arg) : -1);
- }
-
- /* return the value of the variable */
- return (*pvar >= 0 ? cvfixnum((FIXTYPE)*pvar) : NIL);
- }
-
- /* xopeni - built-in function 'open-input-file' */
- LVAL xopeni()
- {
- LVAL openfile();
- return (openfile(PF_INPUT,"r"));
- }
-
- /* xopeno - built-in function 'open-output-file' */
- LVAL xopeno()
- {
- LVAL openfile();
- return (openfile(PF_OUTPUT,"w"));
- }
-
- /* xopena - built-in function 'open-append-file' */
- LVAL xopena()
- {
- LVAL openfile();
- return (openfile(PF_OUTPUT,"a"));
- }
-
- /* xopenu - built-in function 'open-update-file' */
- LVAL xopenu()
- {
- LVAL openfile();
- return (openfile(PF_INPUT|PF_OUTPUT,"r+"));
- }
-
- /* openfile - open an ascii or binary file */
- LOCAL LVAL openfile(flags,mode)
- int flags; char *mode;
- {
- extern FILE *osaopen(),*osbopen();
- LVAL file,modekey;
- char *name;
- FILE *fp;
-
- /* get the file name and direction */
- name = (char *)getstring(xlgastring());
- modekey = (moreargs() ? xlgasymbol() : NIL);
- xllastarg();
-
- /* check for binary mode */
- if (modekey != NIL) {
- if (modekey == xlenter("BINARY"))
- flags |= PF_BINARY;
- else if (modekey != xlenter("TEXT"))
- xlerror("unrecognized open mode",modekey);
- }
-
- /* try to open the file */
- file = cvport(NULL,flags);
- fp = ((flags & PF_BINARY) == 0 ? osaopen(name,mode) : osbopen(name,mode));
- if (fp == NULL)
- return (NIL);
- setfile(file,fp);
- return (file);
- }
-
- /* xclose - built-in function 'close-port' */
- LVAL xclose()
- {
- LVAL fptr;
- fptr = xlgaport();
- xllastarg();
- if (getfile(fptr))
- osclose(getfile(fptr));
- setfile(fptr,NULL);
- return (NIL);
- }
-
- /* xclosei - built-in function 'close-input-port' */
- LVAL xclosei()
- {
- LVAL fptr;
- fptr = xlgaiport();
- xllastarg();
- if (getfile(fptr))
- osclose(getfile(fptr));
- setfile(fptr,NULL);
- return (NIL);
- }
-
- /* xcloseo - built-in function 'close-output-port' */
- LVAL xcloseo()
- {
- LVAL fptr;
- fptr = xlgaoport();
- xllastarg();
- if (getfile(fptr))
- osclose(getfile(fptr));
- setfile(fptr,NULL);
- return (NIL);
- }
-
- /* xgetfposition - built-in function 'get-file-position' */
- LVAL xgetfposition()
- {
- extern long ostell();
- LVAL fptr;
- fptr = xlgaport();
- xllastarg();
- return (cvfixnum(ostell(getfile(fptr))));
- }
-
- /* xsetfposition - built-in function 'set-file-position!' */
- LVAL xsetfposition()
- {
- LVAL fptr,val;
- long position;
- int whence;
- fptr = xlgaport();
- val = xlgafixnum(); position = getfixnum(val);
- val = xlgafixnum(); whence = (int)getfixnum(val);
- xllastarg();
- return (osseek(getfile(fptr),position,whence) == 0 ? true_lval : NIL);
- }
-
- /* xcurinput - built-in function 'current-input-port' */
- LVAL xcurinput()
- {
- xllastarg();
- return (curinput());
- }
-
- /* xcuroutput - built-in function 'current-output-port' */
- LVAL xcuroutput()
- {
- xllastarg();
- return (curoutput());
- }
-
- /* xportp - built-in function 'port?' */
- LVAL xportp()
- {
- LVAL arg;
- arg = xlgetarg();
- xllastarg();
- return (portp(arg) ? true_lval : NIL);
- }
-
- /* xinputportp - built-in function 'input-port?' */
- LVAL xinputportp()
- {
- LVAL arg;
- arg = xlgetarg();
- xllastarg();
- return (iportp(arg) ? true_lval : NIL);
- }
-
- /* xoutputportp - built-in function 'output-port?' */
- LVAL xoutputportp()
- {
- LVAL arg;
- arg = xlgetarg();
- xllastarg();
- return (oportp(arg) ? true_lval : NIL);
- }
-
- /* xtranson - built-in function 'transcript-on' */
- LVAL xtranson()
- {
- extern FILE *osaopen();
- char *name;
-
- /* get the file name and direction */
- name = (char *)getstring(xlgastring());
- xllastarg();
-
- /* close any currently open transcript file */
- if (tfp) { osclose(tfp); tfp = NULL; }
-
- /* try to open the file */
- return ((tfp = osaopen(name,"w")) == NULL ? NIL : true_lval);
- }
-
- /* xtransoff - built-in function 'transcript-off' */
- LVAL xtransoff()
- {
- /* make sure there aren't any arguments */
- xllastarg();
-
- /* make sure the transcript is open */
- if (tfp == NULL)
- return (NIL);
-
- /* close the transcript and return successfully */
- osclose(tfp); tfp = NULL;
- return (true_lval);
- }
-
- /* xstrlen - built-in function 'string-length' */
- LVAL xstrlen()
- {
- LVAL str;
- str = xlgastring();
- xllastarg();
- return (cvfixnum((FIXTYPE)(getslength(str)-1)));
- }
-
- /* xstrnullp - built-in function 'string-null?' */
- LVAL xstrnullp()
- {
- LVAL str;
- str = xlgastring();
- xllastarg();
- return (getslength(str) == 1 ? true_lval : NIL);
- }
-
- /* xstrappend - built-in function 'string-append' */
- LVAL xstrappend()
- {
- LVAL *savesp,tmp,val;
- unsigned char *str;
- int saveargc,len;
-
- /* save the argument list */
- saveargc = xlargc;
- savesp = xlsp;
-
- /* find the length of the new string */
- for (len = 0; moreargs(); ) {
- tmp = xlgastring();
- len += (int)getslength(tmp) - 1;
- }
-
- /* restore the argument list */
- xlargc = saveargc;
- xlsp = savesp;
-
- /* create the result string */
- val = newstring(len+1);
- str = getstring(val);
-
- /* combine the strings */
- for (*str = '\0'; moreargs(); ) {
- tmp = nextarg();
- strcat(str,getstring(tmp));
- }
-
- /* return the new string */
- return (val);
- }
-
- /* xstrref - built-in function 'string-ref' */
- LVAL xstrref()
- {
- LVAL str,num;
- int n;
-
- /* get the string and the index */
- str = xlgastring();
- num = xlgafixnum();
- xllastarg();
-
- /* range check the index */
- if ((n = (int)getfixnum(num)) < 0 || n >= getslength(str) - 1)
- xlerror("index out of range",num);
-
- /* return the character */
- return (cvchar(getstring(str)[n]));
- }
-
- /* xsubstring - built-in function 'substring' */
- LVAL xsubstring()
- {
- unsigned char *srcp,*dstp;
- int start,end,len;
- LVAL src,dst;
-
- /* get string and starting and ending positions */
- src = xlgastring();
-
- /* get the starting position */
- dst = xlgafixnum(); start = (int)getfixnum(dst);
- if (start < 0 || start > getslength(src) - 1)
- xlerror("index out of range",dst);
-
- /* get the ending position */
- if (moreargs()) {
- dst = xlgafixnum(); end = (int)getfixnum(dst);
- if (end < 0 || end > getslength(src) - 1)
- xlerror("index out of range",dst);
- }
- else
- end = getslength(src) - 1;
- xllastarg();
-
- /* setup the source pointer */
- srcp = getstring(src) + start;
- len = end - start;
-
- /* make a destination string and setup the pointer */
- dst = newstring(len+1);
- dstp = getstring(dst);
-
- /* copy the source to the destination */
- while (--len >= 0)
- *dstp++ = *srcp++;
- *dstp = '\0';
-
- /* return the substring */
- return (dst);
- }
-
- /* xstrlist - built-in function 'string->list' */
- LVAL xstrlist()
- {
- unsigned char *p;
- LVAL str;
- int size;
-
- /* get the vector */
- str = xlgastring();
- xllastarg();
-
- /* make a list from the vector */
- cpush(str);
- size = getslength(str)-1;
- for (xlval = NIL, p = &getstring(str)[size]; --size >= 0; )
- xlval = cons(cvchar(*--p),xlval);
- drop(1);
- return (xlval);
- }
-
- /* xliststring - built-in function 'list->string' */
- LVAL xliststring()
- {
- unsigned char *p;
- LVAL str;
- int size;
-
- /* get the list */
- xlval = xlgalist();
- xllastarg();
-
- /* make a vector from the list */
- size = length(xlval);
- str = newstring(size+1);
- for (p = getstring(str); --size >= 0; xlval = cdr(xlval))
- if (charp(car(xlval)))
- *p++ = getchcode(car(xlval));
- else
- xlbadtype(car(xlval));
- *p = '\0';
- return (str);
- }
-
- /* string comparision functions */
- LVAL xstrlss() { return (strcompare('<',FALSE)); } /* string<? */
- LVAL xstrleq() { return (strcompare('L',FALSE)); } /* string<=? */
- LVAL xstreql() { return (strcompare('=',FALSE)); } /* string=? */
- LVAL xstrgeq() { return (strcompare('G',FALSE)); } /* string>=? */
- LVAL xstrgtr() { return (strcompare('>',FALSE)); } /* string>? */
-
- /* string comparison functions (case insensitive) */
- LVAL xstrilss() { return (strcompare('<',TRUE)); } /* string-ci<? */
- LVAL xstrileq() { return (strcompare('L',TRUE)); } /* string-ci<=? */
- LVAL xstrieql() { return (strcompare('=',TRUE)); } /* string-ci=? */
- LVAL xstrigeq() { return (strcompare('G',TRUE)); } /* string-ci>=? */
- LVAL xstrigtr() { return (strcompare('>',TRUE)); } /* string-ci>? */
-
- /* strcompare - compare strings */
- LOCAL LVAL strcompare(fcn,icase)
- int fcn,icase;
- {
- int start1,end1,start2,end2,ch1,ch2;
- unsigned char *p1,*p2;
- LVAL str1,str2;
-
- /* get the strings */
- str1 = xlgastring();
- str2 = xlgastring();
- xllastarg();
-
- /* setup the string pointers */
- p1 = getstring(str1); start1 = 0; end1 = getslength(str1);
- p2 = getstring(str2); start2 = 0; end2 = getslength(str2);
-
- /* compare the strings */
- for (; start1 < end1 && start2 < end2; ++start1,++start2) {
- ch1 = *p1++;
- ch2 = *p2++;
- if (icase) {
- if (isupper(ch1)) ch1 = tolower(ch1);
- if (isupper(ch2)) ch2 = tolower(ch2);
- }
- if (ch1 != ch2)
- switch (fcn) {
- case '<': return (ch1 < ch2 ? true_lval : NIL);
- case 'L': return (ch1 <= ch2 ? true_lval : NIL);
- case '=': return (NIL);
- case 'G': return (ch1 >= ch2 ? true_lval : NIL);
- case '>': return (ch1 > ch2 ? true_lval : NIL);
- }
- }
-
- /* check the termination condition */
- switch (fcn) {
- case '<': return (start1 >= end1 && start2 < end2 ? true_lval : NIL);
- case 'L': return (start1 >= end1 ? true_lval : NIL);
- case '=': return (start1 >= end1 && start2 >= end2 ? true_lval : NIL);
- case 'G': return (start2 >= end2 ? true_lval : NIL);
- case '>': return (start2 >= end2 && start1 < end1 ? true_lval : NIL);
- }
- }
-
- /* xcharint - built-in function 'char->integer' */
- LVAL xcharint()
- {
- LVAL arg;
- arg = xlgachar();
- xllastarg();
- return (cvfixnum((FIXTYPE)getchcode(arg)));
- }
-
- /* xintchar - built-in function 'integer->char' */
- LVAL xintchar()
- {
- LVAL arg;
- arg = xlgafixnum();
- xllastarg();
- return (cvchar((int)getfixnum(arg)));
- }
-
- /* character comparision functions */
- LVAL xchrlss() { return (chrcompare('<',FALSE)); } /* char<? */
- LVAL xchrleq() { return (chrcompare('L',FALSE)); } /* char<=? */
- LVAL xchreql() { return (chrcompare('=',FALSE)); } /* char=? */
- LVAL xchrgeq() { return (chrcompare('G',FALSE)); } /* char>=? */
- LVAL xchrgtr() { return (chrcompare('>',FALSE)); } /* char>? */
-
- /* character comparision functions (case insensitive) */
- LVAL xchrilss() { return (chrcompare('<',TRUE)); } /* char-ci<? */
- LVAL xchrileq() { return (chrcompare('L',TRUE)); } /* char-ci<=? */
- LVAL xchrieql() { return (chrcompare('=',TRUE)); } /* char-ci=? */
- LVAL xchrigeq() { return (chrcompare('G',TRUE)); } /* char-ci>=? */
- LVAL xchrigtr() { return (chrcompare('>',TRUE)); } /* char-ci>? */
-
- /* chrcompare - compare characters */
- LOCAL LVAL chrcompare(fcn,icase)
- int fcn,icase;
- {
- int ch1,ch2;
- LVAL arg;
-
- /* get the characters */
- arg = xlgachar(); ch1 = getchcode(arg);
- arg = xlgachar(); ch2 = getchcode(arg);
- xllastarg();
-
- /* convert to lowercase if case insensitive */
- if (icase) {
- if (isupper(ch1)) ch1 = tolower(ch1);
- if (isupper(ch2)) ch2 = tolower(ch2);
- }
-
- /* compare the characters */
- switch (fcn) {
- case '<': return (ch1 < ch2 ? true_lval : NIL);
- case 'L': return (ch1 <= ch2 ? true_lval : NIL);
- case '=': return (ch1 == ch2 ? true_lval : NIL);
- case 'G': return (ch1 >= ch2 ? true_lval : NIL);
- case '>': return (ch1 > ch2 ? true_lval : NIL);
- }
- }
-
- /* xcompile - built-in function 'compile' */
- LVAL xcompile()
- {
- extern LVAL xlcompile();
- LVAL env;
-
- /* get the expression to compile and the environment */
- xlval = xlgetarg();
- env = (moreargs() ? xlgaenv() : NIL);
- xllastarg();
-
- /* build the closure */
- cpush(env);
- xlval = xlcompile(xlval,env);
- xlval = cvclosure(xlval,env);
- drop(1);
- return (xlval);
- }
-
- /* xdecompile - built-in function 'decompile' */
- LVAL xdecompile()
- {
- LVAL fun,fptr;
-
- /* get the closure (or code) and file pointer */
- fun = xlgetarg();
- fptr = (moreargs() ? xlgaoport() : curoutput());
- xllastarg();
-
- /* make sure we got either a closure or a code object */
- if (!closurep(fun) && !methodp(fun))
- xlbadtype(fun);
-
- /* decompile (disassemble) the procedure */
- decode_procedure(fptr,fun);
- return (NIL);
- }
-
- /* xsave - save the memory image */
- LVAL xsave()
- {
- unsigned char *name;
-
- /* get the file name, verbose flag and print flag */
- name = getstring(xlgastring());
- xllastarg();
-
- /* save the memory image */
- return (xlisave(name) ? true_lval : NIL);
- }
-
- /* xrestore - restore a saved memory image */
- LVAL xrestore()
- {
- extern jmp_buf top_level;
- unsigned char *name;
-
- /* get the file name, verbose flag and print flag */
- name = getstring(xlgastring());
- xllastarg();
-
- /* restore the saved memory image */
- if (!xlirestore(name))
- return (NIL);
-
- /* return directly to the top level */
- stdputstr("[ returning to the top level ]\n");
- longjmp(top_level,1);
- }
-
- /* xgc - function to force garbage collection */
- LVAL xgc()
- {
- extern FIXTYPE nnodes,nfree,gccalls,total;
- extern int nscount,vscount;
- int arg1,arg2;
- LVAL arg;
-
- /* check the argument list and call the garbage collector */
- if (moreargs()) {
- arg = xlgafixnum(); arg1 = (int)getfixnum(arg);
- arg = xlgafixnum(); arg2 = (int)getfixnum(arg);
- xllastarg();
- while (--arg1 >= 0) nexpand(NSSIZE);
- while (--arg2 >= 0) vexpand(VSSIZE);
- }
- else
- gc();
-
- /* return (gccalls nnodes nfree nscount vscount total) */
- xlval = cons(cvfixnum(total),NIL);
- xlval = cons(cvfixnum((FIXTYPE)vscount),xlval);
- xlval = cons(cvfixnum((FIXTYPE)nscount),xlval);
- xlval = cons(cvfixnum(nfree),xlval);
- xlval = cons(cvfixnum(nnodes),xlval);
- xlval = cons(cvfixnum(gccalls),xlval);
- return (xlval);
- }
-
- /* xerror - built-in function 'error' */
- LVAL xerror()
- {
- extern jmp_buf top_level;
- LVAL msg;
-
- /* display the error message */
- msg = xlgastring();
- errputstr("error: ");
- errputstr(getstring(msg));
- errputstr("\n");
-
- /* print each of the remaining arguments on separate lines */
- while (moreargs()) {
- errputstr(" ");
- errprint(xlgetarg());
- }
-
- /* print the function where the error occurred */
- errputstr("happened in: ");
- errprint(xlfun);
-
- /* call the handler */
- callerrorhandler();
- }
-
- /* xreset - built-in function 'reset' */
- LVAL xreset()
- {
- extern jmp_buf top_level;
- xllastarg();
- longjmp(top_level,1);
- }
-
- /* xgetarg - return a command line argument */
- LVAL xgetarg()
- {
- extern char **clargv;
- extern int clargc;
- LVAL arg;
- int n;
- arg = xlgafixnum(); n = (int)getfixnum(arg);
- xllastarg();
- return (n >= 0 && n < clargc ? cvstring(clargv[n]) : NIL);
- }
-
- /* xexit - exit to the operating system */
- LVAL xexit()
- {
- xllastarg();
- wrapup();
- }
-