=================================================================== RCS file: /home/cvs/OpenXM/src/kan96xx/Kan/stackmachine.c,v retrieving revision 1.7 retrieving revision 1.29 diff -u -p -r1.7 -r1.29 --- OpenXM/src/kan96xx/Kan/stackmachine.c 2001/05/04 01:06:25 1.7 +++ OpenXM/src/kan96xx/Kan/stackmachine.c 2004/09/19 00:47:47 1.29 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM/src/kan96xx/Kan/stackmachine.c,v 1.6 2001/01/27 05:48:46 takayama Exp $ */ +/* $OpenXM: OpenXM/src/kan96xx/Kan/stackmachine.c,v 1.28 2004/09/17 02:42:57 takayama Exp $ */ /* stackmachin.c */ #include @@ -14,8 +14,8 @@ /* #define OPERAND_STACK_SIZE 2000 */ #define OPERAND_STACK_SIZE 30000 #define SYSTEM_DICTIONARY_SIZE 200 -/* #define USER_DICTIONARY_SIZE 1223, 3581 */ -#define USER_DICTIONARY_SIZE 27449 +/* #define USER_DICTIONARY_SIZE 1223, 3581, 27449 */ +#define USER_DICTIONARY_SIZE 59359 /* The value of USER_DICTIONARY_SIZE must be prime number, because of hashing method */ #define ARGV_WORK_MAX (AGLIMIT+100) @@ -54,6 +54,8 @@ struct context *PrimitiveContextp = &StandardContext; static struct object ObjTmp; /* for poor compiler */ +int Calling_ctrlC_hook = 0; + int StandardMacros = 1; int StartAFile = 0; char *StartFile; @@ -72,14 +74,19 @@ static strToInteger(char *); static power(int s,int i); static void pstack(void); static struct object executableStringToExecutableArray(char *str); +static int isThereExecutableArrayOnStack(int n); extern int SerialCurrent; +extern int QuoteMode; int SGClock = 0; int UserCtrlC = 0; int OXlock = 0; int OXlockSaved = 0; +char *UD_str; +int UD_attr; + struct object * newObject() { struct object *r; @@ -215,7 +222,7 @@ int putUserDictionary(str,h0,h1,ob,dic) } r = x; if (Strict2) { - switch((dic[x]).attr) { + switch(((dic[x]).attr) & (PROTECT | ABSOLUTE_PROTECT)) { case PROTECT: r = -PROTECT; /* Protected, but we rewrite it. */ break; @@ -223,7 +230,7 @@ int putUserDictionary(str,h0,h1,ob,dic) r = -ABSOLUTE_PROTECT; /* Protected and we do not rewrite it. */ return(r); default: - (dic[x]).attr = 0; + /* (dic[x]).attr = 0; */ /* It is not necesarry, I think. */ break; } } @@ -246,14 +253,19 @@ struct object findUserDictionary(str,h0,h1,cp) char *str; /* key */ int h0,h1; /* The hashing values of the key. */ struct context *cp; + /* Set char *UD_str, int UD_attr (attributes) */ { int x; struct dictionary *dic; + extern char *UD_str; + extern int UD_attr; + UD_str = NULL; UD_attr = -1; dic = cp->userDictionary; x = h0; while (1) { if ((dic[x]).key == EMPTY) { break; } if (strcmp((dic[x]).key,str) == 0) { + UD_str = (dic[x]).key; UD_attr = (dic[x]).attr; return( (dic[x]).obj ); } x = (x+h1) % USER_DICTIONARY_SIZE; @@ -284,6 +296,12 @@ int putUserDictionary2(str,h0,h1,attr,dic) } return(0); } + if (OR_ATTR_FOR_ALL_WORDS & attr) { + for (i=0; i= 1) { fprintf(Fstack,"\nscanner> "); } - KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */ + if (!Calling_ctrlC_hook) { /* to avoid recursive call of ctrlC-hook. */ + Calling_ctrlC_hook = 1; RestrictedMode = 0; + KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */ + RestrictedMode = RestrictedMode_saved; + } + Calling_ctrlC_hook = 0; + KSexecuteString(" (Computation is interrupted.) "); /* move to ctrlC-hook? */ + InSendmsg2 = 0; + infixOn = 0; continue ; } else { } if (DebugStack >= 1) { printOperandStack(); } - token = getokenSM(GET); - if ((tmp=executeToken(token)) < 0) break; - /***if (tmp == 1) fprintf(stderr," --- exit --- \n");*/ + token = getokenSM(GET); + if ((status=executeToken(token)) < 0) break; + /***if (status == 1) fprintf(stderr," --- exit --- \n");*/ + /* fprintf(stderr,"token.token=%s, status=%d, infixOn=%d\n",token.token,status,infixOn); */ + if (status & STATUS_INFIX) { + infixOn = 1; infixToken = token; infixToken.tflag |= NO_DELAY; + }else if (infixOn) { + infixOn = 0; + if ((status=executeToken(infixToken)) < 0) break; + } } } @@ -826,14 +897,20 @@ void ctrlC(sig) extern int SGClock; extern int UserCtrlC; extern int OXlock; - + extern int RestrictedMode, RestrictedMode_saved; + signal(sig,SIG_IGN); /* see 133p */ + RestrictedMode = RestrictedMode_saved; + cancelAlarm(); + if (sig == SIGALRM) { + fprintf(stderr,"ctrlC by SIGALRM\n"); + } if (SGClock) { UserCtrlC = 1; fprintf(stderr,"ctrl-c is locked because of gc.\n"); - signal(SIGINT,ctrlC); + signal(sig,ctrlC); if (sig == SIGALRM) alarm((unsigned int)10); return; } if (OXlock) { @@ -846,13 +923,15 @@ void ctrlC(sig) unlockCtrlCForOx(); } fprintf(stderr,"ctrl-c is locked because of ox lock %d.\n",UserCtrlC); - signal(SIGINT,ctrlC); + signal(sig,ctrlC); if (sig == SIGALRM) alarm((unsigned int)10); return; } if (ErrorMessageMode != 1) { + (void *) traceShowStack(); fprintf(Fstack,"User interruption by ctrl-C. We are in the top-level.\n"); fprintf(Fstack,"Type in quit in order to exit sm1.\n"); } + traceClearStack(); if (GotoP) { fprintf(Fstack,"The interpreter was looking for the label <<%s>>. It is also aborted.\n",GotoLabel); GotoP = 0; @@ -867,7 +946,11 @@ void ctrlC(sig) */ getokenSM(INIT); /* It might fix the bug above. 1992/11/14 */ signal(SIGINT,ctrlC); +#if defined(__CYGWIN__) + siglongjmp(EnvOfStackMachine,2); +#else longjmp(EnvOfStackMachine,2); /* returns 2 for ctrl-C */ +#endif } int executeToken(token) @@ -877,11 +960,14 @@ int executeToken(token) int primitive; int size; int status; - struct tokens *tokenArray; int i,h0,h1; extern int WarningMessageMode; extern int Strict; + extern int InSendmsg2; + extern int RestrictedMode, RestrictedMode_saved; + int localRestrictedMode_saved; + localRestrictedMode_saved = 0; if (GotoP) { /* for goto */ if (token.kind == ID && isLiteral(token.token)) { if (strcmp(&((token.token)[1]),GotoLabel) == 0) { @@ -927,24 +1013,51 @@ int executeToken(token) h1 = ((token.object.lc.op)->rc).ival; ob=findUserDictionary(token.token,h0,h1,CurrentContextp); primitive = ((token.object.rc.op)->lc).ival; + if (!(token.tflag & NO_DELAY)) { + if ((ob.tag >= 0) && (UD_attr & ATTR_INFIX)) { + return STATUS_INFIX; + } + } if (ob.tag >= 0) { /* there is a definition in the user dictionary */ if (ob.tag == SexecutableArray) { - tokenArray = ob.lc.tokenArray; - size = ob.rc.ival; - for (i=0; i>. It is also aborted.\n",GotoLabel); GotoP = 0; @@ -1071,6 +1189,7 @@ KSexecuteString(s) jmp_buf saved_EnvOfStackMachine; void (*sigfunc)(); int localCatchCtrlC ; + extern int RestrictedMode, RestrictedMode_saved; localCatchCtrlC = CatchCtrlC; /* If CatchCtrlC is rewrited in this program, @@ -1083,7 +1202,11 @@ KSexecuteString(s) if (KSPushEnvMode) { *saved_EnvOfStackMachine = *EnvOfStackMachine; +#if defined(__CYGWIN__) + if (jval = sigsetjmp(EnvOfStackMachine,1)) { +#else if (jval = setjmp(EnvOfStackMachine)) { +#endif *EnvOfStackMachine = *saved_EnvOfStackMachine; if (jval == 2) { if (ErrorMessageMode == 1 || ErrorMessageMode == 2) { @@ -1092,11 +1215,22 @@ KSexecuteString(s) } recursive--; if (localCatchCtrlC) { signal(SIGINT, sigfunc); } + if (!Calling_ctrlC_hook) { + Calling_ctrlC_hook = 1; RestrictedMode = 0; + KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */ + RestrictedMode_saved; + } + Calling_ctrlC_hook = 0; + KSexecuteString(" (Computation is interrupted.) "); /* move to ctrlC-hook?*/ return(-1); }else{ } }else{ if (recursive == 0) { +#if defined(__CYGWIN__) + if (jval=sigsetjmp(EnvOfStackMachine,1)) { +#else if (jval=setjmp(EnvOfStackMachine)) { +#endif if (jval == 2) { if (ErrorMessageMode == 1 || ErrorMessageMode == 2) { pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C.")); @@ -1104,6 +1238,14 @@ KSexecuteString(s) } recursive = 0; if (localCatchCtrlC) { signal(SIGINT, sigfunc); } + if (!Calling_ctrlC_hook) { + Calling_ctrlC_hook = 1; RestrictedMode = 0; + KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */ + RestrictedMode = RestrictedMode_saved; + } + Calling_ctrlC_hook = 0; + Calling_ctrlC_hook = 0; + KSexecuteString(" (Computation is interrupted.) "); return(-1); }else { } } @@ -1111,9 +1253,9 @@ KSexecuteString(s) recursive++; token.token = s; - token.kind = EXECUTABLE_STRING; + token.kind = EXECUTABLE_STRING; token.tflag = 0; executeToken(token); - token.kind = ID; + token.kind = ID; token.tflag = 0; token.token = "exec"; token = lookupTokens(token); /* no use */ tmp = findSystemDictionary(token.token); @@ -1132,10 +1274,10 @@ KSdefineMacros() { struct object ob; if (StandardMacros && (strlen(SMacros))) { - token.kind = EXECUTABLE_STRING; + token.kind = EXECUTABLE_STRING; token.tflag = 0; token.token = SMacros; executeToken(token); /* execute startup commands */ - token.kind = ID; + token.kind = ID; token.tflag = 0; token.token = "exec"; token = lookupTokens(token); /* no use */ tmp = findSystemDictionary(token.token); @@ -1165,14 +1307,14 @@ void KSstart() { } else { } */ /* setup quiet mode or not */ - token.kind = EXECUTABLE_STRING; + token.kind = EXECUTABLE_STRING; token.tflag = 0; if (Quiet) { token.token = " /@@@.quiet 1 def "; }else { token.token = " /@@@.quiet 0 def "; } executeToken(token); /* execute startup commands */ - token.kind = ID; + token.kind = ID; token.tflag = 0; token.token = "exec"; token = lookupTokens(token); /* set hashing values */ tmp = findSystemDictionary(token.token); @@ -1450,4 +1592,105 @@ struct object KSdupErrors() { } return(rob); } + +void cancelAlarm() { + alarm((unsigned int) 0); + signal(SIGALRM,SIG_DFL); +} + +/* back-trace */ +#define TraceNameStackSize 3000 +char *TraceNameStack[TraceNameStackSize]; +int TraceNameStackp = 0; +void tracePushName(char *s) { + char *t; + /* + t = (char *)sGC_malloc(strlen(s)+1); + if (t == NULL) { + fprintf(stderr,"No more memory.\n"); return; + } + strcpy(t,s); + */ + t = s; + TraceNameStack[TraceNameStackp++] = t; + if (TraceNameStackp >= TraceNameStackSize) { + fprintf(stderr,"Warning: TraceNameStack overflow. Clearing the stack.\n"); + TraceNameStackp = 0; + } +} +void traceClearStack(void) { + TraceNameStackp = 0; +} +char *tracePopName(void) { + if (TraceNameStackp <= 0) return (char *) NULL; + return TraceNameStack[--TraceNameStackp]; +} +#define TRACE_MSG_SIZE 320 +char *traceShowStack(void) { + char *s; + char *t; + int p; + s = (char *) sGC_malloc(TRACE_MSG_SIZE); + if (s == NULL) { + fprintf(stderr,"No more memory.\n"); return NULL; + } + sprintf(s,"Trace: "); + p = strlen(s); + do { + t = tracePopName(); + if (t == NULL) { + s[p] = ';'; s[p+1] = 0; + break; + }else if ((strlen(t) + p) > (TRACE_MSG_SIZE-10)) { + /* fprintf(stderr,"p=%d, TraceNameStackp=%d, strlen(t)=%d, t=%s\n",p,TraceNameStackp,strlen(t),t); */ + strcpy(&(s[p])," ..."); + break; + } + strcpy(&(s[p]),t); p += strlen(t); + strcpy(&(s[p]),"<-"); p += 2; + } while (t != (char *)NULL); + fprintf(stderr,"%s\n",s); + return s; +} + +/* + if (fname != NULL) fname is pushed to the trace stack. + */ +int executeExecutableArray(struct object ob,char *fname,int withGotoP) { + struct tokens *tokenArray; + int size,i; + int status; + int infixOn; + struct tokens infixToken; + extern int GotoP; + infixOn = 0; + if (ob.tag != SexecutableArray) errorStackmachine("Error (executeTokenArray): the argument is not a token array."); + + if (fname != NULL) tracePushName(fname); + tokenArray = ob.lc.tokenArray; + size = ob.rc.ival; + for (i=0; i