/* $OpenXM: OpenXM/src/kan96xx/Kan/primitive.c,v 1.26 2020/10/06 11:33:46 takayama Exp $ */ /* primitive.c */ /* The functions in this module were in stackmachine.c */ #include #include #include #include #include #include #include "datatype.h" #include "stackm.h" #include "extern.h" #include "extern2.h" #include "gradedset.h" #include "kclass.h" #include #include #include "mysig.h" int PrintDollar = 1; /* flag for printObject() */ int PrintComma = 1; /* flag for printObject() */ int InSendmsg2 = 0; #define OB_ARRAY_MAX (AGLIMIT+100) extern int GotoP; extern char *GotoLabel; extern int Osp; extern int Sdp; extern int ClassTypes[]; /* kclass.c */ extern struct context *PrimitiveContextp; extern struct context *CurrentContextp; extern struct dictionary *SystemDictionary; extern int QuoteMode; static char *operatorType(int i); static char *operatorType(type) int type; { int i; for (i=0; i= 2) { /*fprintf(fp,"@@@");*/ switch (ob.tag) { case 0: fprintf(fp," "); /* null object */ break; case Sinteger: fprintf(fp," "); break; case Sstring: fprintf(fp," "); break; case Soperator: fprintf(fp," "); break; case Sdollar: fprintf(fp," "); break; case SexecutableArray: fprintf(fp," "); break; case Sarray: fprintf(fp," "); break; case SleftBraceTag: fprintf(fp," "); break; case SrightBraceTag: fprintf(fp," "); break; case Spoly: fprintf(fp," "); break; case SarrayOfPOLY: fprintf(fp," "); break; case SmatrixOfPOLY: fprintf(fp," "); break; case Slist: fprintf(fp," "); break; case Sfile: fprintf(fp," "); break; case Sring: fprintf(fp," "); break; case SuniversalNumber: fprintf(fp," "); break; case Sclass: fprintf(fp," "); break; case SrationalFunction: fprintf(fp," "); break; case Sdouble: fprintf(fp," "); break; case SbyteArray: fprintf(fp," "); break; default: fprintf(fp,"",ob.tag); break; } } switch (ob.tag) { case 0: fprintf(fp,"%%[null]"); /* null object */ break; case Sinteger: fprintf(fp,"%d",ob.lc.ival); break; case Sstring: fprintf(fp,"%s",ob.lc.str); break; case Soperator: fprintf(fp,"%s %%[operator] ",operatorType(ob.lc.ival)); break; case Sdollar: if (PrintDollar == 2) { fprintf(fp,"(%s)",ob.lc.str); } else if (PrintDollar == 0 ) { fprintf(fp,"%s",ob.lc.str); } else { fprintf(fp,"$%s$",ob.lc.str); } break; case SexecutableArray: size = ob.rc.ival; ta = ob.lc.tokenArray; fprintf(fp,"{ "); for (i=0; i>%s ",(ta[i]).token); break; case EXECUTABLE_STRING: fprintf(fp,"<>{%s} ",(ta[i]).token); break; case EXECUTABLE_ARRAY: printObject((ta[i]).object,nl,fp); break; case DOLLAR: fprintf(fp,"<>%s ",(ta[i]).token); break; default: fprintf(fp,"Unknown token type\n"); break; } } fprintf(fp," }"); break; case Sarray: printObjectArray(ob,0,fp); break; case SleftBraceTag: fprintf(fp,"[ "); break; case SrightBraceTag: fprintf(fp,"] "); break; case Spoly: fprintf(fp,"%s",KPOLYToString(ob.lc.poly)); break; case SarrayOfPOLY: fprintf(fp,"Sorry! The object arrayOfPOLY cannot be printed."); break; case SmatrixOfPOLY: fprintf(fp,"Sorry! The object matrixOfPOLY cannot be printed."); break; case Slist: printObjectList(&ob); break; case Sfile: fprintf(fp,"Name=%s, FILE *=%p ",ob.lc.str,ob.rc.file); break; case Sring: fprintf(fp,"Ring."); KshowRing(KopRingp(ob)); break; case SuniversalNumber: fprintf(fp,"%s",coeffToString(ob.lc.universalNumber)); break; case SrationalFunction: fprintf(fp,"("); printObject(*(Knumerator(ob)),nl,fp); fprintf(fp,")/(");printObject(*(Kdenominator(ob)),nl,fp); fprintf(fp,")"); break; case Sclass: /* fprintf(fp,"Class: "); */ fprintClass(fp,ob); break; case Sdouble: fprintf(fp,"%f",KopDouble(ob)); break; case SbyteArray: printObject(byteArrayToArray(ob),nl,fp); /* Todo: I should save memory.*/ break; default: fprintf(fp,"[Unknown object tag.]"); break; } if (nl) fprintf(fp,"\n"); } void printObjectArray(ob,nl,fp) struct object ob; int nl; FILE *fp; { int size; int i; extern char *LeftBracket, *RightBracket; size = ob.lc.ival; fprintf(fp,"%s ",LeftBracket); for (i=0; i= 2) { fprintf(Fstack,"In execute %d\n",ob.lc.ival); printOperandStack(); } if (RestrictedMode) { switch(ob.lc.ival) { case SleftBrace: case SrightBrace: case Sexec: break; default: fprintf(stderr,"primitive No = %d : ", ob.lc.ival); errorStackmachine("You cannot use this primitive in the RestrictedMode.\n"); } } if (GotoP) return(0); switch (ob.lc.ival) { /* Postscript primitives :stack */ case Sgoto: ob1 = Kpop(); if (ob1.tag != Sstring) { if (DebugStack>=2) printObject(ob1,0,Fstack); errorStackmachine("Usage:goto"); } GotoLabel = ob1.lc.str; GotoP = 1; break; case Spop: ob1 = Kpop(); break; case Sdup: ob1 = Kpop(); Kpush(ob1); Kpush(ob1); break; case Scopy: /* copy values. cf. dup */ ob1 = Kpop(); switch(ob1.tag) { case Sinteger: break; default: errorStackmachine("Usage:copy"); } size = ob1.lc.ival; k = 0; for (i=size-1; i>=0; i--) { ob2 = peek(i+k); switch(ob2.tag) { case Sdollar: /* copy by value */ str = (char *)sGC_malloc(strlen(ob2.lc.str)+3); if (str == (char *)NULL) errorStackmachine("No memory (copy)"); strcpy(str,ob2.lc.str); Kpush(KpoString(str)); break; case Spoly: errorStackmachine("no pCopy (copy)"); break; case Sarray: n = ob2.lc.ival; ob3 = newObjectArray(n); for (j=0; j=0?k: k+n); Kpush(obArray[k]); j--; } break; case Spstack: printOperandStack(); break; /* Postscript primitives :arithmetic */ case Sadd: ob1 = Kpop(); ob2 = Kpop(); evalEA(ob1); evalEA(ob2); rob = KooAdd(ob1,ob2); Kpush(rob); break; case Ssub: ob2 = Kpop(); ob1 = Kpop(); evalEA(ob1); evalEA(ob2); rob = KooSub(ob1,ob2); Kpush(rob); break; case Smult: ob2 = Kpop(); ob1 = Kpop(); evalEA(ob1); evalEA(ob2); rob = KooMult(ob1,ob2); Kpush(rob); break; case Sidiv: ob2 = Kpop(); ob1 = Kpop(); evalEA(ob1); evalEA(ob2); rob = KooDiv(ob1,ob2); Kpush(rob); break; case Sdiv: ob2 = Kpop(); ob1 = Kpop(); evalEA(ob1); evalEA(ob2); rob = KooDiv2(ob1,ob2); Kpush(rob); break; /* Postscript primitives :array */ case SleftBrace: rob.tag = SleftBraceTag; Kpush(rob); break; case SrightBrace: size = 0; ob1 = peek(size); while (!(Osp-size-1 < 0)) { /* while the stack is not underflow */ if (ob1.tag == SleftBraceTag) { rob = newObjectArray(size); for (i=0; i 0) { /* if (lim < i) errorStackmachine("The initial value must not be greater than limit value (for).\n"); */ for ( ; i<=lim; i += inc) { Kpush(KpoInteger(i)); status = executeExecutableArray(ob1,(char *)NULL,1); if ((status & STATUS_BREAK) || GotoP) goto xyz; } }else{ /* if (lim > i) errorStackmachine("The initial value must not be less than limit value (for).\n"); */ for ( ; i>=lim; i += inc) { Kpush(KpoInteger(i)); status = executeExecutableArray(ob1,(char *)NULL,1); if ((status & STATUS_BREAK) || GotoP) goto xyz; } } xyz: ; } break; case Smap: ob2 = Kpop(); ob1 = Kpop(); switch(ob1.tag) { case Sarray: break; default: errorStackmachine("Usage:map The 1st argument must be an array."); break; } switch(ob2.tag) { case SexecutableArray: break; default: errorStackmachine("Usage:map The 2nd argument must be an executable array."); break; } { int osize,size; int i,j; osize = getoaSize(ob1); /*KSexecuteString("[");*/ rob.tag = SleftBraceTag; Kpush(rob); for (i=0; ilc).ival, (ob1.rc.op->rc).ival,ob2, CurrentContextp->userDictionary); if (k < 0) { str = (char *)sGC_malloc(sizeof(char)*(strlen(ob1.lc.str) + 256)); if (str == (char *)NULL) { errorStackmachine("No memory.\n"); } if (k == -PROTECT) { sprintf(str,"You rewrited the protected symbol %s.\n",ob1.lc.str); /* cf. [(chattr) num sym] extension */ warningStackmachine(str); } else if (k == -ABSOLUTE_PROTECT) { sprintf(str,"You cannot rewrite the protected symbol %s.\n",ob1.lc.str); errorStackmachine(str); } else errorStackmachine("Unknown return value of putUserDictioanry\n"); } break; case Sload: ob1 = Kpop(); switch(ob1.tag) { case Sstring: break; default: errorStackmachine("Usage:load"); } ob1 = findUserDictionary(ob1.lc.str, (ob1.rc.op->lc).ival, (ob1.rc.op->rc).ival, CurrentContextp); if (ob1.tag == -1) Kpush(NullObject); else Kpush(ob1); break; case Sset: ob1 = Kpop(); ob2 = Kpop(); switch(ob1.tag) { case Sstring: break; default: errorStackmachine("Usage:set"); } k= putUserDictionary(ob1.lc.str,(ob1.rc.op->lc).ival, (ob1.rc.op->rc).ival,ob2, CurrentContextp->userDictionary); if (k < 0) { str = (char *)sGC_malloc(sizeof(char)*(strlen(ob1.lc.str) + 256)); if (str == (char *)NULL) { errorStackmachine("No memory.\n"); } if (k == -PROTECT) { sprintf(str,"You rewrited the protected symbol %s. \n",ob1.lc.str); warningStackmachine(str); } else if (k == -ABSOLUTE_PROTECT) { sprintf(str,"You cannot rewrite the protected symbol %s.\n",ob1.lc.str); errorStackmachine(str); } else errorStackmachine("Unknown return value of putUserDictioanry\n"); } break; case Sshow_systemdictionary: fprintf(Fstack,"------------- system dictionary -------------------\n"); showSystemDictionary(0); break; case Sshow_user_dictionary: showUserDictionary(); break; /* Postscript primitives : convert */ case Sdata_conversion: ob2 = Kpop(); ob1 = Kpop(); switch(ob2.tag) { case Sdollar: if (ob1.tag != Sclass) { rob = KdataConversion(ob1,ob2.lc.str); }else{ rob = KclassDataConversion(ob1,ob2); } break; case Sarray: rob = KclassDataConversion(ob1,ob2); break; default: errorStackmachine("Usage:data_conversion"); } Kpush(rob); break; /* Postscript ptimitives :file */ case Srun: ob1 = Kpop(); switch(ob1.tag) { case Sdollar: break; case Sstring: break; default: errorStackmachine("Usage:run"); break; } getokenSM(OPEN,ob1.lc.str); /* open the file, $filename$ run */ break; case Sprint: ob1 = Kpop(); printObject(ob1,0,Fstack); break; case Sfileopen: /* filename mode file descripter */ /* ob2 ob1 */ ob1 = Kpop(); ob2 = Kpop(); if (SecureMode) errorStackmachine("Security violation: you cannot open a file."); switch(ob1.tag) { case Sdollar: break; default: errorStackmachine("Usage:file"); } switch(ob2.tag) { case Sinteger: break; case Sdollar: break; default:errorStackmachine("Usage:file"); } rob = NullObject; if (ob2.tag == Sdollar) { if (strcmp(ob2.lc.str,"%stdin") == 0) { rob.tag = Sfile; rob.lc.str="%stdin"; rob.rc.file = stdin; }else if (strcmp(ob2.lc.str,"%stdout") == 0) { rob.tag = Sfile; rob.lc.str="%stdout"; rob.rc.file = stdout; }else if (strcmp(ob2.lc.str,"%stderr") == 0) { rob.tag = Sfile; rob.lc.str="%stderr"; rob.rc.file = stderr; }else if ( (rob.rc.file = fopen(ob2.lc.str,ob1.lc.str)) != (FILE *)NULL) { rob.tag = Sfile; rob.lc.str = ob2.lc.str; }else { errorStackmachine("I cannot open the file."); } }else { rob.rc.file = fdopen(ob2.lc.ival,ob1.lc.str); if ( rob.rc.file != (FILE *)NULL) { rob.tag = Sfile; rob.lc.ival = ob2.lc.ival; }else{ errorStackmachine("I cannot fdopen the given fd."); } } Kpush(rob); break; case Swritestring: /* file string writestring ob2 ob1 */ ob1 = Kpop(); ob2 = Kpop(); switch(ob2.tag) { case Sfile: break; default: errorStackmachine("Usage:writestring"); } switch(ob1.tag) { case Sdollar: break; default: errorStackmachine("Usage:writestring"); } fprintf(ob2.rc.file,"%s",ob1.lc.str); break; case Sclosefile: ob1 = Kpop(); switch(ob1.tag) { case Sfile: break; default: errorStackmachine("Usage:closefile"); } if (fclose(ob1.rc.file) == EOF) { errorStackmachine("I couldn't close the file.\n"); } break; case Spushfile: /* filename pushfile string */ /* ob2 */ ob2 = Kpop(); switch(ob2.tag) { case Sdollar: break; default:errorStackmachine("Usage:pushfile"); } rob = NullObject; if (strcmp(ob2.lc.str,"%stdin") == 0) { ob1.tag = Sfile; ob1.lc.str="%stdin"; ob1.rc.file = stdin; }else if (strcmp(ob2.lc.str,"%stdout") == 0) { ob1.tag = Sfile; ob1.lc.str="%stdout"; ob1.rc.file = stdout; }else if (strcmp(ob2.lc.str,"%stderr") == 0) { ob1.tag = Sfile; ob1.lc.str="%stderr"; ob1.rc.file = stderr; }else if ( (ob1.rc.file = fopen(ob2.lc.str,"r")) != (FILE *)NULL) { ob1.tag = Sfile; ob1.lc.str = ob2.lc.str; }else { if (ob1.rc.file == (FILE *)NULL) { char fname2[1024]; strcpy(fname2,getLOAD_SM1_PATH()); strcat(fname2,ob2.lc.str); ob1.rc.file = fopen(fname2,"r"); if (ob1.rc.file == (FILE *)NULL) { strcpy(fname2,LOAD_SM1_PATH); strcat(fname2,ob2.lc.str); ob1.rc.file = fopen(fname2,"r"); if (ob1.rc.file == (FILE *)NULL) { fprintf(stderr,"Warning: Cannot open the file <<%s>> for loading in the current directory nor the library directories %s and %s.\n",ob2.lc.str,getLOAD_SM1_PATH(),LOAD_SM1_PATH); errorStackmachine("I cannot open the file."); } } } } /* read the strings */ n = 256; j=0; rob.tag = Sdollar; rob.lc.str = (char *) sGC_malloc(sizeof(char)*n); if (rob.lc.str == (char *)NULL) errorStackmachine("No more memory."); while ((i = fgetc(ob1.rc.file)) != EOF) { if (j >= n-1) { n = 2*n; if (n <= 0) errorStackmachine("Too large file to put on the stack."); str = (char *)sGC_malloc(sizeof(char)*n); if (str == (char *)NULL) errorStackmachine("No more memory."); for (k=0; k< n/2; k++) str[k] = (rob.lc.str)[k]; rob.lc.str = str; } (rob.lc.str)[j] = i; (rob.lc.str)[j+1] = '\0'; j++; } fclose(ob1.rc.file); Kpush(rob); break; /* Postscript primitives :misc */ case Squit: Kclose(); stackmachine_close(); exit(0); break; case Ssystem: ob1 = Kpop(); switch(ob1.tag) { case Sdollar: break; case Sstring: break; default: errorStackmachine("Usage:system"); } if (SecureMode) errorStackmachine("Security violation."); {int rr; rr=system( ob1.lc.str );} break; case Scat_n: ob1 = Kpop(); switch(ob1.tag) { case Sinteger: break; default: errorStackmachine("Usage:cat_n"); } size = ob1.lc.ival; k = 0; for (i=size-1; i>=0; i--) { ob2 = peek(i); switch(ob2.tag) { case Sdollar: break; default: errorStackmachine("Usage:cat_n"); } k += strlen(ob2.lc.str); } ob1.tag = Sdollar; ob1.lc.str = (char *)sGC_malloc(sizeof(char)*(k+1)); if (ob1.lc.str == (char *)NULL) { errorStackmachine("No more memory.\n"); } /* concatnate */ k = 0; for (i=size-1; i>=0; i--) { ob2 = peek(i); strcpy(&((ob1.lc.str)[k]),ob2.lc.str); k = strlen(ob1.lc.str); } /* clear the arguments */ for (i=size-1; i>=0; i--) { ob2 = Kpop(); } Kpush(ob1); break; case Sset_timer: /* 118p */ if (timerStart) { before_real = time(&before_real); times(&before); timerStart = 0; TimerOn = 1; }else{ times(&after); after_real = time(&after_real); if (TimerOn) { printf("User time: %f seconds, System time: %f seconds, Real time: %d s\n", ((double)(after.tms_utime - before.tms_utime)) /100.0, ((double)(after.tms_stime - before.tms_stime)) /100.0, (int) (after_real-before_real)); /* In cases of Solaris and Linux, the unit of tms_utime seems to be given 0.01 seconds. */ } timerStart = 1; TimerOn = 0; } break; case Susage: ob1 = Kpop(); Kusage(ob1); break; case Sto_records: ob1 = Kpop(); switch(ob1.tag) { case Sdollar: break; default: errorStackmachine("Usage:to_records"); } ob2 = KtoRecords(ob1); size = getoaSize(ob2); for (i=0; i 0) { if (getoa(ob2,getoaSize(ob2)-1).tag == Spoly) { Kpush(oInitW(ob2,newObjectArray(0))); }else{ ob1 = Kpop(); Kpush(oInitW(ob1,ob2)); } }else{ ob1 = Kpop(); Kpush(oInitW(ob1,ob2)); } } break; case Sextension: ob1 = Kpop(); Kpush(Kextension(ob1)); break; case Sgbext: ob1 = Kpop(); Kpush(KgbExtension(ob1)); break; case Snewstack: ob1 = Kpop(); switch(ob1.tag) { case Sinteger: Kpush(newOperandStack(ob1.lc.ival)); break; default: errorStackmachine("Usage:newstack"); break; } break; case Ssetstack: ob1 = Kpop(); switch(ob1.tag) { case Sclass: setOperandStack(ob1); break; default: errorStackmachine("Usage:setstack"); break; } break; case Sstdstack: stdOperandStack(); break; case Slc: ob1 = Kpop(); switch (ob1.tag) { case Sclass: Kpush(KpoInteger(ob1.lc.ival)); break; default: errorStackmachine("Usage:lc"); break; } break; case Src: ob1 = Kpop(); switch (ob1.tag) { case Sclass: if (ClassTypes[ob1.lc.ival] == CLASS_OBJ) { Kpush(*(ob1.rc.op)); }else{ warningStackmachine("<> works only for a class object with CLASS_OBJ attribute.\n"); Kpush(ob1); } break; default: errorStackmachine("Usage:rc"); break; } break; case Snewcontext: ob1 = Kpop(); ob2 = Kpop(); switch(ob1.tag) { case Sclass: if (ob2.tag == Sdollar) { Kpush(KnewContext(ob1,KopString(ob2))); }else errorStackmachine("Usage:newcontext"); break; default: errorStackmachine("Usage:newcontext"); break; } break; case Ssetcontext: ob1 = Kpop(); switch(ob1.tag) { case Sclass: KsetContext(ob1); break; default: errorStackmachine("Usage:setcontext"); break; } break; case Ssupercontext: ob1 = Kpop(); switch(ob1.tag) { case Sclass: Kpush(getSuperContext(ob1)); break; default: errorStackmachine("Usage:supercontext"); break; } break; case Ssendmsg: /* ob2 { .........} sendmsg */ /* cf. debug/kobj.sm1 */ ob1 = Kpop(); ob2 = Kpop(); switch(ob1.tag) { case SexecutableArray: break; default: errorStackmachine("Usage:sendmsg"); } ccflag = 0; if (ob2.tag == Sarray ) { if (getoaSize(ob2) >= 1) { ob3 = getoa(ob2,0); if (ectag(ob3) == CLASSNAME_CONTEXT) { contextControl(CCPUSH); ccflag = 1; /* push the current context. */ CurrentContextp = (struct context *)ecbody(ob3); } } } if (!ccflag) { contextControl(CCPUSH); ccflag = 1; CurrentContextp = PrimitiveContextp; } /* normal exec. */ Kpush(ob2); status = executeExecutableArray(ob1,(char *)NULL,0); if (ccflag) { contextControl(CCPOP); ccflag = 0; /* recover the Current context. */ } break; case Ssendmsg2: /* ob2 ob4 { .........} sendmsg2 */ /* Context is determined by ob2 or ob1 */ ob1 = Kpop(); ob4 = Kpop(); ob2 = Kpop(); switch(ob1.tag) { case SexecutableArray: break; default: errorStackmachine("Usage:sendmsg2"); } ccflag = 0; if (ob2.tag == Sarray ) { if (getoaSize(ob2) >= 1) { ob3 = getoa(ob2,0); if (ectag(ob3) == CLASSNAME_CONTEXT) { contextControl(CCPUSH); ccflag = 1; /* push the current context. */ CurrentContextp = (struct context *)ecbody(ob3); } } } if (!ccflag && ob4.tag == Sarray) { if (getoaSize(ob4) >= 1) { ob3 = getoa(ob4,0); if (ectag(ob3) == CLASSNAME_CONTEXT) { contextControl(CCPUSH); ccflag = 1; /* push the current context. */ CurrentContextp = (struct context *)ecbody(ob3); } } } if (!ccflag) { contextControl(CCPUSH); ccflag = 1; CurrentContextp = PrimitiveContextp; } /* normal exec. */ Kpush(ob2); Kpush(ob4); /* We cannot use executeExecutableArray(ob1,(char *)NULL) because of the quote mode. Think about it later. */ tokenArray = ob1.lc.tokenArray; size = ob1.rc.ival; for (i=0; icontextName)); } putoa(qattr,0,qattr2); putoa(qob,1,qattr); putoa(qob,2,ob4); /* Argument */ qob = KpoTree(qob); Kpush(qob); } else if (status & STATUS_BREAK) break; } if (ccflag) { contextControl(CCPOP); ccflag = 0; /* recover the Current context. */ /* Note that it is not recovered in case of error. */ } break; case Sprimmsg: /* { .........} primmsg */ /* Context is PrimitiveContext. */ ob1 = Kpop(); switch(ob1.tag) { case SexecutableArray: break; default: errorStackmachine("Usage:primmsg"); } contextControl(CCPUSH); ccflag = 1; CurrentContextp = PrimitiveContextp; /* normal exec. */ status = executeExecutableArray(ob1,(char *)NULL,0); contextControl(CCPOP); /* recover the Current context. */ break; case Ssupmsg2: /* ob2 ob4 { .........} supmsg2 */ /* Context is super class of ob2 */ ob1 = Kpop(); ob4 = Kpop(); ob2 = Kpop(); switch(ob1.tag) { case SexecutableArray: break; default: errorStackmachine("Usage:supmsg2"); } ccflag = 0; if (ob2.tag == Sarray ) { if (getoaSize(ob2) >= 1) { ob3 = getoa(ob2,0); if (ectag(ob3) == CLASSNAME_CONTEXT) { if (((struct context *)ecbody(ob3))->super == NULL) { errorStackmachine("supmsg2: SuperClass is NIL."); } contextControl(CCPUSH); ccflag = 1; /* push the current context. */ CurrentContextp = ((struct context *)ecbody(ob3))->super; } } } if (!ccflag && (ob4.tag == Sarray) ) { if (getoaSize(ob4) >= 1) { ob3 = getoa(ob4,0); if (ectag(ob3) == CLASSNAME_CONTEXT) { if (((struct context *)ecbody(ob3))->super == NULL) { errorStackmachine("supmsg2: SuperClass is NIL."); } contextControl(CCPUSH); ccflag = 1; /* push the current context. */ CurrentContextp = ((struct context *)ecbody(ob3))->super; } } } if (!ccflag) { contextControl(CCPUSH); ccflag = 1; CurrentContextp = PrimitiveContextp; } /* normal exec. */ Kpush(ob2); Kpush(ob4); status = executeExecutableArray(ob1,(char *)NULL,0); if (ccflag) { contextControl(CCPOP); ccflag = 0; /* recover the Current context. */ } break; case Serror: ob1 = peek(0); if (ob1.tag == Sdollar) { /* compose error message */ ob = Kpop(); str = (char *) sGC_malloc(sizeof(char)*(strlen("error operator : ")+ strlen(KopString(ob1))+ 10)); if (str == NULL) errorStackmachine("No more memory."); strcpy(str,"error operator : "); strcat(str,KopString(ob1)); errorStackmachine(str); }else{ errorStackmachine("error operator."); } break; case Smpzext: ob1 = Kpop(); Kpush(KmpzExtension(ob1)); break; case Scclass: ob3 = Kpop(); ob2 = Kpop(); ob1 = Kpop(); /* [class-tag super-obj] size [class-tag] cclass */ Kpush(KcreateClassIncetance(ob1,ob2,ob3)); break; case Stest: /* test is used for a test of a new function. */ ob2 = Kpop(); ob1 = Kpop(); Kpush(hilberto(ob1,ob2)); /* { ob1 = Kpop(); Kpush(test(ob1)); } */ break; case Soxshell: ob1 = Kpop(); Kpush(KoxShell(ob1)); break; case Stlimit: /* { } time tlimit */ ob2 = Kpop(); ob1 = Kpop(); switch(ob2.tag) { case Sinteger: break; default: errorStackmachine("Usage:tlimit"); break; } switch(ob1.tag) { case SexecutableArray: break; default: errorStackmachine("Usage:tlimit"); break; } n = ob2.lc.ival; if (n > 0) { mysignal(SIGALRM,ctrlC); alarm((unsigned int) n); status = executeExecutableArray(ob1,(char *)NULL,0); cancelAlarm(); }else{ before_real = time(&before_real); times(&before); status = executeExecutableArray(ob1,(char *)NULL,0); times(&after); after_real = time(&after_real); ob1 = newObjectArray(3); putoa(ob1,0,KpoInteger((int) after.tms_utime - before.tms_utime)); putoa(ob1,1,KpoInteger((int) after.tms_stime - before.tms_stime)); putoa(ob1,2,KpoInteger((int) (after_real-before_real))); Kpush(ob1); } break; default: errorStackmachine("Unknown Soperator type. \n"); } return(0); /* normal exit */ }