[BACK]Return to stackmachine.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / kan96xx / Kan

Annotation of OpenXM/src/kan96xx/Kan/stackmachine.c, Revision 1.28

1.28    ! takayama    1: /* $OpenXM: OpenXM/src/kan96xx/Kan/stackmachine.c,v 1.27 2004/09/16 23:53:44 takayama Exp $ */
1.1       maekawa     2: /*   stackmachin.c */
                      3:
                      4: #include <stdio.h>
                      5: #include "datatype.h"
                      6: #include "stackm.h"
                      7: #include "extern.h"
                      8: #include "gradedset.h"
                      9: #include "kclass.h"
                     10: #include <signal.h>
                     11: #include <sys/types.h>
                     12:
                     13:
                     14: /* #define OPERAND_STACK_SIZE  2000 */
                     15: #define OPERAND_STACK_SIZE 30000
                     16: #define SYSTEM_DICTIONARY_SIZE 200
1.8       takayama   17: /* #define USER_DICTIONARY_SIZE   1223, 3581, 27449 */
                     18: #define USER_DICTIONARY_SIZE  59359
1.1       maekawa    19: /* The value of USER_DICTIONARY_SIZE must be prime number, because of hashing
                     20:    method */
                     21: #define ARGV_WORK_MAX  (AGLIMIT+100)
                     22: #define EMPTY (char *)NULL
                     23:
                     24:
                     25: /* global variables */
                     26: struct object StandardStackA[OPERAND_STACK_SIZE];
                     27: int StandardStackP = 0;
                     28: int StandardStackMax = OPERAND_STACK_SIZE;
                     29: struct operandStack StandardStack;
                     30: /* Initialization of operandStack will be done in initSystemDictionary(). */
                     31: #define ERROR_STACK_SIZE 100
                     32: struct object ErrorStackA[ERROR_STACK_SIZE];
                     33: int ErrorStackP = 0;
                     34: int ErrorStackMax = ERROR_STACK_SIZE;
                     35: struct operandStack ErrorStack;
                     36: /* Initialization of ErrorStack will be done in initSystemDictionary(). */
                     37:
                     38: struct operandStack *CurrentOperandStack = &StandardStack;
                     39: struct object *OperandStack = StandardStackA;
                     40: int Osp = 0;   /* OperandStack pointer */
                     41: int OspMax = OPERAND_STACK_SIZE;
                     42:
                     43: struct dictionary SystemDictionary[SYSTEM_DICTIONARY_SIZE];
                     44: int Sdp = 0;   /* SystemDictionary pointer */
                     45: struct dictionary UserDictionary[USER_DICTIONARY_SIZE];
                     46:
                     47: struct context StandardContext ;
                     48: /* Initialization of StructContext will be done in initSystemDictionary(). */
                     49: /* hashInitialize is done in global.c (initStackmachine()) */
                     50: struct context *StandardContextp = &StandardContext;
                     51: struct context *CurrentContextp = &StandardContext;
                     52: struct context *PrimitiveContextp = &StandardContext;
                     53:
                     54:
                     55: static struct object ObjTmp; /* for poor compiler */
                     56:
1.16      takayama   57: int Calling_ctrlC_hook = 0;
                     58:
1.1       maekawa    59: int StandardMacros = 1;
                     60: int StartAFile = 0;
                     61: char *StartFile;
                     62:
                     63: int StartAString = 0;
                     64: char *StartString;
                     65:
                     66: char *GotoLabel = (char *)NULL;
                     67: int GotoP = 0;
                     68:
                     69: static char *SMacros =
                     70: #include "smacro.h"
                     71:
                     72: static isInteger(char *);
                     73: static strToInteger(char *);
                     74: static power(int s,int i);
                     75: static void pstack(void);
                     76: static struct object executableStringToExecutableArray(char *str);
                     77:
                     78: extern int SerialCurrent;
1.13      takayama   79: extern int QuoteMode;
1.1       maekawa    80:
                     81: int SGClock = 0;
                     82: int UserCtrlC = 0;
                     83: int OXlock = 0;
                     84: int OXlockSaved = 0;
                     85:
1.19      takayama   86: char *UD_str;
                     87: int  UD_attr;
                     88:
1.1       maekawa    89: struct object * newObject()
                     90: {
                     91:   struct object *r;
                     92:   r = (struct object *)sGC_malloc(sizeof(struct object));
                     93:   if (r == (struct object *)NULL) errorStackmachine("No memory\n");
                     94:   r->tag = 0;
                     95:   (r->lc).ival = 0;
                     96:   (r->rc).ival = 0;
                     97:   return(r);
                     98: }
                     99:
                    100: struct object newObjectArray(size)
1.7       takayama  101:      int size;
1.1       maekawa   102: {
                    103:   struct object rob;
                    104:   struct object *op;
                    105:   if (size < 0) return(NullObject);
                    106:   if (size > 0) {
                    107:     op = (struct object *)sGC_malloc(size*sizeof(struct object));
                    108:     if (op == (struct object *)NULL) errorStackmachine("No memory\n");
                    109:   }else{
                    110:     op = (struct object *)NULL;
                    111:   }
                    112:   rob.tag = Sarray;
                    113:   rob.lc.ival = size;
                    114:   rob.rc.op = op;
                    115:   return(rob);
                    116: }
                    117:
                    118: isNullObject(obj)
1.7       takayama  119:      struct object obj;
1.1       maekawa   120: {
                    121:   if (obj.tag == 0) return(1);
                    122:   else return(0);
                    123: }
                    124:
                    125: int putSystemDictionary(str,ob)
1.7       takayama  126:      char *str;   /* key */
                    127:      struct object ob; /* value */
1.1       maekawa   128: {
                    129:   int i;
                    130:   int j;
                    131:   int flag = 0;
                    132:
                    133:   for (i = Sdp-1; i>=0; i--) {
                    134:     /*printf("Add %d %s\n",i,str);*/
                    135:     if (strcmp(str,(SystemDictionary[i]).key) > 0) {
                    136:       for (j=Sdp-1; j>=i+1; j--) {
1.7       takayama  137:         (SystemDictionary[j+1]).key = (SystemDictionary[j]).key;
                    138:         (SystemDictionary[j+1]).obj = (SystemDictionary[j]).obj;
1.1       maekawa   139:       }
                    140:       (SystemDictionary[i+1]).key = str;
                    141:       (SystemDictionary[i+1]).obj = ob;
                    142:       flag = 1;
                    143:       break;
                    144:     }
                    145:   }
                    146:   if (!flag) { /* str is the minimum element */
                    147:     for (j=Sdp-1; j>=0; j--) {
                    148:       (SystemDictionary[j+1]).key = (SystemDictionary[j]).key;
                    149:       (SystemDictionary[j+1]).obj = (SystemDictionary[j]).obj;
                    150:     }
                    151:     (SystemDictionary[0]).key = str;
                    152:     (SystemDictionary[0]).obj = ob;
                    153:   }
                    154:   Sdp++;
                    155:   if (Sdp >= SYSTEM_DICTIONARY_SIZE) {
                    156:     warningStackmachine("No space for system dictionary area.\n");
                    157:     Sdp--;
                    158:     return(-1);
                    159:   }
                    160:   return(Sdp-1);
                    161: }
                    162:
                    163: int findSystemDictionary(str)
                    164:      /* only used for primitive functions */
                    165:      /* returns 0, if there is no item. */
                    166:      /* This function assumes that the dictionary is sorted by strcmp() */
                    167:      char *str;    /* key */
                    168: {
                    169:   int first,last,rr,middle;
                    170:
                    171:   /* binary search */
                    172:   first = 0; last = Sdp-1;
                    173:   while (1) {
                    174:     if (first > last) {
                    175:       return(0);
                    176:     } else if (first == last) {
                    177:       if (strcmp(str,(SystemDictionary[first]).key) == 0) {
1.7       takayama  178:         return((SystemDictionary[first]).obj.lc.ival);
1.1       maekawa   179:       }else {
1.7       takayama  180:         return(0);
1.1       maekawa   181:       }
                    182:     } else if (last - first == 1) { /* This case is necessary */
                    183:       if (strcmp(str,(SystemDictionary[first]).key) == 0) {
1.7       takayama  184:         return((SystemDictionary[first]).obj.lc.ival);
1.1       maekawa   185:       }else if (strcmp(str,(SystemDictionary[last]).key) == 0) {
1.7       takayama  186:         return((SystemDictionary[last]).obj.lc.ival);
1.1       maekawa   187:       }else return(0);
                    188:     }
                    189:
                    190:     middle = (first + last)/2;
                    191:     rr = strcmp(str,(SystemDictionary[middle]).key);
                    192:     if (rr < 0) { /* str < middle */
                    193:       last = middle;
                    194:     }else if (rr == 0) {
                    195:       return((SystemDictionary[middle]).obj.lc.ival);
                    196:     }else {       /* str > middle */
                    197:       first = middle;
                    198:     }
                    199:   }
                    200: }
                    201:
                    202: int putUserDictionary(str,h0,h1,ob,dic)
1.7       takayama  203:      char *str;   /* key */
                    204:      int h0,h1;   /* Hash values of the key */
                    205:      struct object ob; /* value */
                    206:      struct dictionary *dic;
1.1       maekawa   207: {
                    208:   int x,r;
                    209:   extern int Strict2;
                    210:   x = h0;
                    211:   if (str[0] == '\0') {
                    212:     errorKan1("%s\n","putUserDictionary(): You are defining a value with the null key.");
                    213:   }
                    214:   while (1) {
                    215:     if ((dic[x]).key == EMPTY) break;
                    216:     if (strcmp((dic[x]).key,str) == 0) break;
                    217:     x = (x+h1) % USER_DICTIONARY_SIZE;
                    218:     if (x == h0) {
                    219:       errorStackmachine("User dictionary is full. loop hashing.\n");
                    220:     }
                    221:   }
                    222:   r = x;
                    223:   if (Strict2) {
1.20      takayama  224:     switch(((dic[x]).attr) & (PROTECT | ABSOLUTE_PROTECT)) {
1.1       maekawa   225:     case PROTECT:
                    226:       r = -PROTECT;   /* Protected, but we rewrite it. */
                    227:       break;
                    228:     case ABSOLUTE_PROTECT:
                    229:       r = -ABSOLUTE_PROTECT;  /* Protected and we do not rewrite it. */
                    230:       return(r);
                    231:     default:
1.20      takayama  232:       /* (dic[x]).attr = 0; */ /* It is not necesarry, I think. */
1.1       maekawa   233:       break;
                    234:     }
                    235:   }
                    236:   (dic[x]).key = str;
                    237:   (dic[x]).obj = ob;
                    238:   (dic[x]).h0 = h0;
                    239:   (dic[x]).h1 = h1;
                    240:   return(r);
                    241: }
                    242:
                    243: struct object KputUserDictionary(char *str,struct object ob)
                    244: {
                    245:   int r;
                    246:   r = putUserDictionary(str,hash0(str),hash1(str),ob,CurrentContextp->userDictionary);
                    247:   return(KpoInteger(r));
                    248: }
                    249:
                    250: struct object findUserDictionary(str,h0,h1,cp)
1.7       takayama  251:      /* returns NoObject, if there is no item. */
                    252:      char *str;    /* key */
                    253:      int h0,h1;    /* The hashing values of the key. */
                    254:      struct context *cp;
1.19      takayama  255:         /* Set char *UD_str, int UD_attr (attributes) */
1.1       maekawa   256: {
                    257:   int x;
                    258:   struct dictionary *dic;
1.19      takayama  259:   extern char *UD_str;
                    260:   extern int UD_attr;
                    261:   UD_str = NULL; UD_attr = -1;
1.1       maekawa   262:   dic = cp->userDictionary;
                    263:   x = h0;
                    264:   while (1) {
                    265:     if ((dic[x]).key == EMPTY) { break; }
                    266:     if (strcmp((dic[x]).key,str) == 0) {
1.19      takayama  267:          UD_str = (dic[x]).key; UD_attr = (dic[x]).attr;
1.1       maekawa   268:       return( (dic[x]).obj );
                    269:     }
                    270:     x = (x+h1) % USER_DICTIONARY_SIZE;
                    271:     if (x == h0) {
                    272:       errorStackmachine("User dictionary is full. loop hashing in findUserDictionary.\n");
                    273:     }
                    274:   }
                    275:   if (cp->super == (struct context *)NULL) return(NoObject);
                    276:   else return(findUserDictionary(str,h0,h1,cp->super));
                    277:
                    278: }
                    279:
                    280: struct object KfindUserDictionary(char *str) {
                    281:   return(findUserDictionary(str,hash0(str),hash1(str),CurrentContextp));
                    282: }
                    283:
                    284: int putUserDictionary2(str,h0,h1,attr,dic)
1.7       takayama  285:      char *str;   /* key */
                    286:      int h0,h1;   /* Hash values of the key */
                    287:      int attr;    /* attribute field */
                    288:      struct dictionary *dic;
1.1       maekawa   289: {
                    290:   int x;
                    291:   int i;
                    292:   if (SET_ATTR_FOR_ALL_WORDS & attr) {
                    293:     for (i=0; i<USER_DICTIONARY_SIZE; i++) {
                    294:       if ((dic[i]).key !=EMPTY) (dic[i]).attr = attr&(~SET_ATTR_FOR_ALL_WORDS);
1.27      takayama  295:     }
                    296:     return(0);
                    297:   }
                    298:   if (OR_ATTR_FOR_ALL_WORDS & attr) {
                    299:     for (i=0; i<USER_DICTIONARY_SIZE; i++) {
                    300:       if ((dic[i]).key !=EMPTY) (dic[i]).attr |= attr&(~OR_ATTR_FOR_ALL_WORDS);
1.1       maekawa   301:     }
                    302:     return(0);
                    303:   }
                    304:   x = h0;
                    305:   if (str[0] == '\0') {
                    306:     errorKan1("%s\n","putUserDictionary2(): You are defining a value with the null key.");
                    307:   }
                    308:   while (1) {
                    309:     if ((dic[x]).key == EMPTY) return(-1);
                    310:     if (strcmp((dic[x]).key,str) == 0) break;
                    311:     x = (x+h1) % USER_DICTIONARY_SIZE;
                    312:     if (x == h0) {
                    313:       errorStackmachine("User dictionary is full. loop hashing.\n");
                    314:     }
                    315:   }
                    316:   (dic[x]).attr = attr;
                    317:   return(x);
                    318: }
                    319:
                    320:
                    321: int putPrimitiveFunction(str,number)
1.7       takayama  322:      char *str;
                    323:      int number;
1.1       maekawa   324: {
                    325:   struct object ob;
                    326:   ob.tag = Soperator;
                    327:   ob.lc.ival = number;
                    328:   return(putSystemDictionary(str,ob));
                    329: }
                    330:
                    331: struct tokens lookupTokens(t)
1.7       takayama  332:      struct tokens t;
1.1       maekawa   333: {
                    334:   struct object *left;
                    335:   struct object *right;
                    336:   t.object.tag = Slist;
                    337:   left = t.object.lc.op = newObject();
                    338:   right = t.object.rc.op = newObject();
                    339:   left->tag = Sinteger;
                    340:   (left->lc).ival = hash0(t.token);
                    341:   (left->rc).ival = hash1(t.token);
                    342:   right->tag = Sinteger;
                    343:   (right->lc).ival = findSystemDictionary(t.token);
                    344:   return(t);
                    345: }
                    346:
                    347: struct object lookupLiteralString(s)
1.7       takayama  348:      char *s; /* s must be a literal string */
1.1       maekawa   349: {
                    350:   struct object ob;
                    351:   ob.tag = Slist;
                    352:   ob.lc.op = newObject();
                    353:   ob.rc.op = (struct object *)NULL;
                    354:   ob.lc.op->tag = Sinteger;
                    355:   (ob.lc.op->lc).ival = hash0(&(s[1]));
                    356:   (ob.lc.op->rc).ival = hash1(&(s[1]));
                    357:   return(ob);
                    358: }
                    359:
                    360:
                    361: int hash0(str)
1.7       takayama  362:      char *str;
1.1       maekawa   363: {
                    364:   int h=0;
                    365:   while (*str != '\0') {
1.17      takayama  366:     h = ((h*128)+((unsigned char)(*str))) % USER_DICTIONARY_SIZE;
1.1       maekawa   367:     str++;
                    368:   }
                    369:   return(h);
                    370: }
                    371:
                    372: int hash1(str)
1.7       takayama  373:      char *str;
1.1       maekawa   374: {
1.17      takayama  375:   return(8-((unsigned char)(str[0])%8));
1.1       maekawa   376: }
                    377:
                    378: void hashInitialize(struct dictionary *dic)
                    379: {
                    380:   int i;
                    381:   for (i=0; i<USER_DICTIONARY_SIZE; i++) {
                    382:     (dic[i]).key = EMPTY; (dic[i]).attr = 0;
                    383:   }
                    384: }
                    385:
                    386: static isInteger(str)
1.7       takayama  387:      char *str;
1.1       maekawa   388: {
                    389:   int i;
                    390:   int n;
                    391:   int start;
                    392:
                    393:   n = strlen(str);
                    394:   if ((str[0] == '+') ||  (str[0] == '-'))
                    395:     start = 1;
                    396:   else
                    397:     start = 0;
                    398:   if (start >= n) return(0);
                    399:
                    400:   for (i=start; i<n; i++) {
                    401:     if (('0' <= str[i]) && (str[i] <= '9')) ;
                    402:     else return(0);
                    403:   }
                    404:   return(1);
                    405: }
                    406:
                    407: static strToInteger(str)
1.7       takayama  408:      char *str;
1.1       maekawa   409: {
                    410:   int i;
                    411:   int n;
                    412:   int r;
                    413:   int start;
                    414:
                    415:   if ((str[0] == '+') || (str[0] == '-'))
                    416:     start = 1;
                    417:   else
                    418:     start = 0;
                    419:   n = strlen(str);
                    420:   r = 0;
                    421:   for (i=n-1; i>=start ; i--) {
                    422:     r += (int)(str[i]-'0') *power(10,n-1-i);
                    423:   }
                    424:   if (str[0] == '-') r = -r;
                    425:   return(r);
                    426: }
                    427:
                    428: static power(s,i)
1.7       takayama  429:      int s;
                    430:      int i;
1.1       maekawa   431: {
                    432:   if (i == 0) return 1;
                    433:   else return( s*power(s,i-1) );
                    434: }
                    435:
                    436: int Kpush(ob)
1.7       takayama  437:      struct object ob;
1.1       maekawa   438: {
                    439:   OperandStack[Osp++] = ob;
                    440:   if (Osp >= OspMax) {
                    441:     warningStackmachine("Operand stack overflow. \n");
                    442:     Osp--;
                    443:     return(-1);
                    444:   }
                    445:   return(0);
                    446: }
                    447:
                    448: struct object Kpop()
                    449: {
                    450:   if (Osp <= 0) {
                    451:     return( NullObject );
                    452:   }else{
                    453:     return( OperandStack[--Osp]);
                    454:   }
                    455: }
                    456:
                    457: struct object peek(k)
1.7       takayama  458:      int k;
1.1       maekawa   459: {
                    460:   if ((Osp-k-1) < 0) {
                    461:     return( NullObject );
                    462:   }else{
                    463:     return( OperandStack[Osp-k-1]);
                    464:   }
                    465: }
                    466:
                    467:
                    468: struct object newOperandStack(int size)
                    469: {
                    470:   struct operandStack *os ;
                    471:   struct object ob;
                    472:   os = (struct operandStack *)sGC_malloc(sizeof(struct operandStack));
                    473:   if (os == (void *)NULL) errorStackmachine("No more memory.");
                    474:   if (size <= 0) errorStackmachine("Size of stack must be more than 1.");
                    475:   os->size = size;
                    476:   os->sp = 0;
                    477:   os->ostack = (struct object *)sGC_malloc(sizeof(struct object)*(size+1));
                    478:   if (os->ostack == (void *)NULL) errorStackmachine("No more memory.");
                    479:   ob.tag = Sclass;
                    480:   ob.lc.ival = CLASSNAME_OPERANDSTACK;
                    481:   ob.rc.voidp = os;
                    482:   return(ob);
                    483: }
                    484:
                    485: void setOperandStack(struct object ob) {
                    486:   if (ob.tag != Sclass) errorStackmachine("The argument must be class.");
                    487:   if (ob.lc.ival != CLASSNAME_OPERANDSTACK)
                    488:     errorStackmachine("The argument must be class.OperandStack.");
                    489:   CurrentOperandStack->ostack = OperandStack;
                    490:   CurrentOperandStack->sp = Osp;
                    491:   CurrentOperandStack->size = OspMax;
                    492:   OperandStack = ((struct operandStack *)(ob.rc.voidp))->ostack;
                    493:   Osp = ((struct operandStack *)(ob.rc.voidp))->sp;
                    494:   OspMax = ((struct operandStack *)(ob.rc.voidp))->size;
                    495:   CurrentOperandStack = ob.rc.voidp;
                    496: }
                    497:
                    498: void stdOperandStack(void) {
                    499:   CurrentOperandStack->ostack = OperandStack;
                    500:   CurrentOperandStack->sp = Osp;
                    501:   CurrentOperandStack->size = OspMax;
                    502:
                    503:   CurrentOperandStack = &StandardStack;
                    504:   OperandStack =   CurrentOperandStack->ostack;
                    505:   Osp =  CurrentOperandStack->sp;
                    506:   OspMax = CurrentOperandStack->size;
                    507: }
                    508:
                    509: /* functions to handle contexts. */
                    510: void fprintContext(FILE *fp,struct context *cp) {
                    511:   if (cp == (struct context *)NULL) {
                    512:     fprintf(fp," Context=NIL \n");
                    513:     return;
                    514:   }
                    515:   fprintf(fp,"  ContextName = %s, ",cp->contextName);
                    516:   fprintf(fp,"Super = ");
                    517:   if (cp->super == (struct context *)NULL) fprintf(fp,"NIL");
                    518:   else {
                    519:     fprintf(fp,"%s",cp->super->contextName);
                    520:   }
                    521:   fprintf(fp,"\n");
                    522: }
                    523:
                    524: struct context *newContext0(struct context *super,char *name) {
                    525:   struct context *cp;
                    526:   cp = sGC_malloc(sizeof(struct context));
                    527:   if (cp == (struct context *)NULL) errorStackmachine("No memory (newContext0)");
                    528:   cp->userDictionary=sGC_malloc(sizeof(struct dictionary)*USER_DICTIONARY_SIZE);
                    529:   if (cp->userDictionary==(struct dictionary *)NULL)
                    530:     errorStackmachine("No memory (newContext0)");
                    531:   hashInitialize(cp->userDictionary);
                    532:   cp->contextName = name;
                    533:   cp->super = super;
                    534:   return(cp);
                    535: }
                    536:
                    537: void KsetContext(struct object contextObj)  {
                    538:   if (contextObj.tag != Sclass) {
                    539:     errorStackmachine("Usage:setcontext");
                    540:   }
                    541:   if (contextObj.lc.ival != CLASSNAME_CONTEXT) {
                    542:     errorStackmachine("Usage:setcontext");
                    543:   }
                    544:   if (contextObj.rc.voidp == NULL) {
                    545:     errorStackmachine("You cannot set NullContext to the CurrentContext.");
                    546:   }
                    547:   CurrentContextp = (struct context *)(contextObj.rc.voidp);
                    548: }
                    549:
                    550:
                    551: struct object getSuperContext(struct object contextObj) {
                    552:   struct object rob;
                    553:   struct context *cp;
                    554:   if (contextObj.tag != Sclass) {
                    555:     errorStackmachine("Usage:supercontext");
                    556:   }
                    557:   if (contextObj.lc.ival != CLASSNAME_CONTEXT) {
                    558:     errorStackmachine("Usage:supercontext");
                    559:   }
                    560:   cp = (struct context *)(contextObj.rc.voidp);
                    561:   if (cp->super == (struct context *)NULL) {
                    562:     return(NullObject);
                    563:   }else{
                    564:     rob.tag = Sclass;
                    565:     rob.lc.ival = CLASSNAME_CONTEXT;
                    566:     rob.rc.voidp = cp->super;
                    567:   }
                    568:   return(rob);
                    569: }
                    570:
                    571: #define CSTACK_SIZE 1000
                    572: void contextControl(actionOfContextControl ctl) {
                    573:   static struct context *cstack[CSTACK_SIZE];
                    574:   static int cstackp = 0;
                    575:   switch(ctl) {
                    576:   case CCRESTORE:
                    577:     if (cstackp == 0) return;
                    578:     else {
                    579:       CurrentContextp = cstack[0];
                    580:       cstackp = 0;
                    581:     }
                    582:     break;
                    583:   case CCPUSH:
                    584:     if (cstackp < CSTACK_SIZE) {
                    585:       cstack[cstackp] = CurrentContextp;
                    586:       cstackp++;
                    587:     }else{
                    588:       contextControl(CCRESTORE);
                    589:       errorStackmachine("Context stack (cstack) is overflow. CurrentContext is restored.\n");
                    590:     }
                    591:     break;
                    592:   case CCPOP:
                    593:     if (cstackp > 0) {
                    594:       cstackp--;
                    595:       CurrentContextp = cstack[cstackp];
                    596:     }
                    597:     break;
                    598:   default:
                    599:     break;
                    600:   }
                    601:   return;
                    602: }
                    603:
                    604:
                    605:
                    606: int isLiteral(str)
1.7       takayama  607:      char *str;
1.1       maekawa   608: {
                    609:   if (strlen(str) <2) return(0);
                    610:   else {
                    611:     if ((str[0] == '/') && (str[1] != '/')) return(1);
                    612:     else return(0);
                    613:   }
                    614: }
                    615:
                    616: void printOperandStack() {
                    617:   int i;
                    618:   struct object ob;
                    619:   int vs;
                    620:   vs = VerboseStack; VerboseStack = 2;
                    621:   for (i=Osp-1; i>=0; i--) {
                    622:     fprintf(Fstack,"[%d] ",i);
                    623:     ob = OperandStack[i];
                    624:     printObject(ob,1,Fstack);
                    625:   }
                    626:   VerboseStack = vs;
                    627: }
                    628:
                    629:
                    630:
                    631: static initSystemDictionary()
1.7       takayama  632: {
1.1       maekawa   633:   StandardStack.ostack = StandardStackA;
                    634:   StandardStack.sp = StandardStackP;
                    635:   StandardStack.size = OPERAND_STACK_SIZE;
                    636:
                    637:   ErrorStack.ostack = ErrorStackA;
                    638:   ErrorStack.sp = ErrorStackP;
                    639:   ErrorStack.size = ErrorStackMax;
                    640:
                    641:   StandardContext.userDictionary = UserDictionary;
                    642:   StandardContext.contextName = "StandardContext";
                    643:   StandardContext.super = (struct context *)NULL;
                    644:
                    645:   KdefinePrimitiveFunctions();
                    646:
1.7       takayama  647: }
1.1       maekawa   648:
                    649: struct object showSystemDictionary(int f) {
                    650:   int i;
                    651:   int maxl;
                    652:   char format[1000];
                    653:   int nl;
                    654:   struct object rob;
                    655:   rob = NullObject;
                    656:   if (f != 0) {
                    657:     rob = newObjectArray(Sdp);
                    658:     for (i=0; i<Sdp; i++) {
                    659:       putoa(rob,i,KpoString((SystemDictionary[i]).key));
                    660:     }
                    661:     return(rob);
                    662:   }
                    663:   maxl = 1;
                    664:   for (i=0; i<Sdp; i++) {
                    665:     if (strlen((SystemDictionary[i]).key) >maxl)
                    666:       maxl = strlen((SystemDictionary[i]).key);
                    667:   }
                    668:   maxl += 3;
                    669:   nl = 80/maxl;
                    670:   if (nl < 2) nl = 2;
                    671:   sprintf(format,"%%-%ds",maxl);
                    672:   for (i=0; i<Sdp; i++) {
                    673:     fprintf(Fstack,format,(SystemDictionary[i]).key);
                    674:     if (i % nl == nl-1) fprintf(Fstack,"\n");
                    675:   }
                    676:   fprintf(Fstack,"\n");
                    677:   return(rob);
                    678: }
                    679:
                    680: int showUserDictionary()
                    681: {
                    682:   int i,j;
                    683:   int maxl;
                    684:   char format[1000];
                    685:   int nl;
                    686:   struct dictionary *dic;
                    687:   dic = CurrentContextp->userDictionary;
                    688:   fprintf(Fstack,"DictionaryName=%s, super= ",CurrentContextp->contextName);
                    689:   if (CurrentContextp->super == (struct context *)NULL) {
                    690:     fprintf(Fstack,"NIL\n");
                    691:   }else{
                    692:     fprintf(Fstack,"%s\n",CurrentContextp->super->contextName);
                    693:   }
                    694:   maxl = 1;
                    695:   for (i=0; i<USER_DICTIONARY_SIZE; i++) {
                    696:     if ((dic[i]).key != EMPTY) {
                    697:       if (strlen((dic[i]).key) >maxl)
1.7       takayama  698:         maxl = strlen((dic[i]).key);
1.1       maekawa   699:     }
                    700:   }
                    701:   maxl += 3;
                    702:   nl = 80/maxl;
                    703:   if (nl < 2) nl = 2;
                    704:   sprintf(format,"%%-%ds",maxl);
                    705:   for (i=0,j=0; i<USER_DICTIONARY_SIZE; i++) {
                    706:     if ((dic[i]).key != EMPTY) {
                    707:       fprintf(Fstack,format,(dic[i]).key);
                    708:       /*{ char *sss; int ii,h0,h1;
1.7       takayama  709:         sss = dic[i].key;
                    710:         h0 = dic[i].h0;
                    711:         h1 = dic[i].h1;
                    712:         for (ii=0; ii<strlen(sss); ii++) fprintf(Fstack,"%x ",sss[ii]);
                    713:         fprintf(Fstack,": h0=%d, h1=%d, %d\n",h0,h1,i);
                    714:         }*/
1.1       maekawa   715:       if (j % nl == nl-1) fprintf(Fstack,"\n");
                    716:       j++;
                    717:     }
                    718:   }
                    719:   fprintf(Fstack,"\n");
                    720: }
                    721:
                    722:
                    723: static struct object executableStringToExecutableArray(s)
1.7       takayama  724:      char *s;
1.1       maekawa   725: {
                    726:   struct tokens *tokenArray;
                    727:   struct object ob;
                    728:   int i;
                    729:   int size;
                    730:   tokenArray = decomposeToTokens(s,&size);
                    731:   ob.tag = SexecutableArray;
                    732:   ob.lc.tokenArray = tokenArray;
                    733:   ob.rc.ival = size;
                    734:   for (i=0; i<size; i++) {
                    735:     if ( ((ob.lc.tokenArray)[i]).kind == EXECUTABLE_STRING) {
                    736:       ((ob.lc.tokenArray)[i]).kind = EXECUTABLE_ARRAY;
                    737:       ((ob.lc.tokenArray)[i]).object =
1.7       takayama  738:         executableStringToExecutableArray(((ob.lc.tokenArray)[i]).token);
1.1       maekawa   739:     }
                    740:   }
                    741:   return(ob);
                    742: }
                    743: /****************  stack machine **************************/
                    744: void scanner() {
                    745:   struct tokens token;
                    746:   struct object ob;
                    747:   extern int Quiet;
                    748:   extern void ctrlC();
1.22      takayama  749:   int tmp, status;
1.1       maekawa   750:   char *tmp2;
                    751:   extern int ErrorMessageMode;
                    752:   int jval;
1.14      takayama  753:   extern int InSendmsg2;
1.22      takayama  754:   int infixOn = 0;
                    755:   struct tokens infixToken;
1.28    ! takayama  756:   extern int RestrictedMode, RestrictedMode_saved;
1.1       maekawa   757:   getokenSM(INIT);
                    758:   initSystemDictionary();
                    759:
1.9       takayama  760: #if defined(__CYGWIN__)
                    761:   if (sigsetjmp(EnvOfStackMachine,1)) {
                    762: #else
1.1       maekawa   763:   if (setjmp(EnvOfStackMachine)) {
1.9       takayama  764: #endif
1.1       maekawa   765:     /* do nothing in the case of error */
                    766:     fprintf(stderr,"An error or interrupt in reading macros, files and command strings.\n");
                    767:     exit(10);
                    768:   } else {  }
                    769:   if (signal(SIGINT,SIG_IGN) != SIG_IGN) {
                    770:     signal(SIGINT,ctrlC);
                    771:   }
                    772:
                    773:   /* setup quiet mode or not */
1.21      takayama  774:   token.kind = EXECUTABLE_STRING; token.tflag = 0;
1.1       maekawa   775:   if (Quiet) {
                    776:     token.token = " /@@@.quiet 1 def ";
                    777:   }else {
                    778:     token.token = " /@@@.quiet 0 def ";
                    779:   }
                    780:   executeToken(token); /* execute startup commands */
1.21      takayama  781:   token.kind = ID; token.tflag = 0;
1.1       maekawa   782:   token.token = "exec";
                    783:   token = lookupTokens(token); /* set hashing values */
                    784:   tmp = findSystemDictionary(token.token);
                    785:   ob.tag = Soperator;
                    786:   ob.lc.ival = tmp;
                    787:   executePrimitive(ob); /* exec */
                    788:
                    789:
                    790:   KSdefineMacros();
                    791:
                    792:   if (StartAFile) {
                    793:     tmp2 = StartFile;
                    794:     StartFile = (char *)sGC_malloc(sizeof(char)*(strlen(StartFile)+
1.7       takayama  795:                                                  40));
1.1       maekawa   796:     sprintf(StartFile,"$%s$ run\n",tmp2);
1.21      takayama  797:     token.kind = EXECUTABLE_STRING; token.tflag = 0;
1.1       maekawa   798:     token.token = StartFile;
1.7       takayama  799:     executeToken(token);    /* execute startup commands */
1.21      takayama  800:     token.kind = ID; token.tflag = 0;
1.1       maekawa   801:     token.token = "exec";
                    802:     token = lookupTokens(token); /* set hashing values */
                    803:     tmp = findSystemDictionary(token.token);
                    804:     ob.tag = Soperator;
                    805:     ob.lc.ival = tmp;
1.7       takayama  806:     executePrimitive(ob);   /* exec */
1.1       maekawa   807:   }
                    808:
                    809:   if (StartAString) {
1.21      takayama  810:     token.kind = EXECUTABLE_STRING;  token.tflag = 0;
1.1       maekawa   811:     token.token = StartString;
1.7       takayama  812:     executeToken(token);    /* execute startup commands */
1.21      takayama  813:     token.kind = ID; token.tflag = 0;
1.1       maekawa   814:     token.token = "exec";
                    815:     token = lookupTokens(token); /* set hashing values */
                    816:     tmp = findSystemDictionary(token.token);
                    817:     ob.tag = Soperator;
                    818:     ob.lc.ival = tmp;
1.7       takayama  819:     executePrimitive(ob);   /* exec */
1.1       maekawa   820:   }
                    821:
                    822:
                    823:   for (;;) {
1.9       takayama  824: #if defined(__CYGWIN__)
                    825:     if (jval=sigsetjmp(EnvOfStackMachine,1)) {
                    826: #else
1.1       maekawa   827:     if (jval=setjmp(EnvOfStackMachine)) {
1.9       takayama  828: #endif
1.1       maekawa   829:       /* ***  The following does not work properly.  ****
1.7       takayama  830:          if (jval == 2) {
                    831:          if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
                    832:          pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
                    833:          }
                    834:          }
                    835:          **** */
1.1       maekawa   836:       if (DebugStack >= 1) {
1.7       takayama  837:         fprintf(Fstack,"\nscanner> ");
1.1       maekawa   838:       }
1.16      takayama  839:       if (!Calling_ctrlC_hook) { /* to avoid recursive call of ctrlC-hook. */
1.28    ! takayama  840:         Calling_ctrlC_hook = 1; RestrictedMode = 0;
1.16      takayama  841:         KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */
1.28    ! takayama  842:         RestrictedMode = RestrictedMode_saved;
1.16      takayama  843:       }
                    844:       Calling_ctrlC_hook = 0;
1.12      takayama  845:       KSexecuteString(" (Computation is interrupted.) "); /* move to ctrlC-hook? */
1.14      takayama  846:       InSendmsg2 = 0;
1.22      takayama  847:       infixOn = 0;
1.7       takayama  848:       continue ;
1.1       maekawa   849:     } else {  }
                    850:     if (DebugStack >= 1) { printOperandStack(); }
1.22      takayama  851:     token = getokenSM(GET);
                    852:     if ((status=executeToken(token)) < 0) break;
                    853:     /***if (status == 1) fprintf(stderr," --- exit --- \n");*/
                    854:     /* fprintf(stderr,"token.token=%s, status=%d, infixOn=%d\n",token.token,status,infixOn); */
                    855:     if (status & STATUS_INFIX) {
                    856:       infixOn = 1;  infixToken = token; infixToken.tflag |= NO_DELAY;
                    857:     }else if (infixOn) {
                    858:       infixOn = 0;
                    859:       if ((status=executeToken(infixToken)) < 0) break;
                    860:     }
1.1       maekawa   861:   }
                    862: }
                    863:
                    864:
                    865: void ctrlC(sig)
1.7       takayama  866:      int sig;
1.1       maekawa   867: {
                    868:   extern void ctrlC();
                    869:   extern int ErrorMessageMode;
                    870:   extern int SGClock;
                    871:   extern int UserCtrlC;
                    872:   extern int OXlock;
1.28    ! takayama  873:   extern int RestrictedMode, RestrictedMode_saved;
1.14      takayama  874:
1.1       maekawa   875:   signal(sig,SIG_IGN);
                    876:   /* see 133p */
1.28    ! takayama  877:   RestrictedMode = RestrictedMode_saved;
1.10      takayama  878:   cancelAlarm();
                    879:   if (sig == SIGALRM) {
                    880:     fprintf(stderr,"ctrlC by SIGALRM\n");
                    881:   }
1.1       maekawa   882:
                    883:   if (SGClock) {
                    884:     UserCtrlC = 1;
                    885:     fprintf(stderr,"ctrl-c is locked because of gc.\n");
1.10      takayama  886:     signal(sig,ctrlC);  if (sig == SIGALRM) alarm((unsigned int)10);
1.1       maekawa   887:     return;
                    888:   }
                    889:   if (OXlock) {
                    890:     if (UserCtrlC > 0) UserCtrlC++;
                    891:     else UserCtrlC = 1;
                    892:     if (UserCtrlC > 3) {
                    893:       fprintf(stderr,"OK. You are eager to cancel the computation.\n");
                    894:       fprintf(stderr,"You should close the ox communication cannel.\n");
                    895:       signal(SIGINT,ctrlC);
                    896:       unlockCtrlCForOx();
                    897:     }
                    898:     fprintf(stderr,"ctrl-c is locked because of ox lock %d.\n",UserCtrlC);
1.10      takayama  899:     signal(sig,ctrlC);  if (sig == SIGALRM) alarm((unsigned int)10);
1.1       maekawa   900:     return;
                    901:   }
                    902:   if (ErrorMessageMode != 1) {
1.16      takayama  903:     (void *) traceShowStack();
1.1       maekawa   904:     fprintf(Fstack,"User interruption by ctrl-C. We are in the top-level.\n");
                    905:     fprintf(Fstack,"Type in quit in order to exit sm1.\n");
                    906:   }
1.16      takayama  907:   traceClearStack();
1.1       maekawa   908:   if (GotoP) {
                    909:     fprintf(Fstack,"The interpreter was looking for the label <<%s>>. It is also aborted.\n",GotoLabel);
                    910:     GotoP = 0;
                    911:   }
                    912:   stdOperandStack(); contextControl(CCRESTORE);
                    913:   /*fprintf(Fstack,"Warning! The handler of ctrl-C has a bug, so you might have a core-dump.\n");*/
                    914:   /*
                    915:     $(x0+1)^50$ $x1 x0 + x1^20$ 2 groebner_n
                    916:     ctrl-C
                    917:     $(x0+1)^50$ $x1 x0 + x1^20$ 2 groebner_n
                    918:     It SOMETIMES makes core dump.
                    919:   */
                    920:   getokenSM(INIT); /* It might fix the bug above. 1992/11/14 */
                    921:   signal(SIGINT,ctrlC);
1.9       takayama  922: #if defined(__CYGWIN__)
                    923:   siglongjmp(EnvOfStackMachine,2);
                    924: #else
1.1       maekawa   925:   longjmp(EnvOfStackMachine,2); /* returns 2 for ctrl-C */
1.9       takayama  926: #endif
1.1       maekawa   927: }
                    928:
                    929: int executeToken(token)
1.7       takayama  930:      struct tokens token;
1.1       maekawa   931: {
                    932:   struct object ob;
                    933:   int primitive;
                    934:   int size;
                    935:   int status;
                    936:   int i,h0,h1;
                    937:   extern int WarningMessageMode;
                    938:   extern int Strict;
1.14      takayama  939:   extern int InSendmsg2;
1.28    ! takayama  940:   extern int RestrictedMode, RestrictedMode_saved;
        !           941:   int localRestrictedMode_saved;
1.1       maekawa   942:
1.28    ! takayama  943:   localRestrictedMode_saved = 0;
1.1       maekawa   944:   if (GotoP) { /* for goto */
                    945:     if (token.kind == ID && isLiteral(token.token)) {
                    946:       if (strcmp(&((token.token)[1]),GotoLabel) == 0) {
1.7       takayama  947:         GotoP = 0;
                    948:         return(0); /* normal exit */
1.1       maekawa   949:       }
                    950:     }
                    951:     return(0);  /* normal exit */
                    952:   }
                    953:   if (token.kind == DOLLAR) {
                    954:     ob.tag = Sdollar;
                    955:     ob.lc.str = token.token;
                    956:     Kpush(ob);
                    957:   } else if (token.kind == ID) {  /* ID */
                    958:
                    959:     if (strcmp(token.token,"exit") == 0) return(1);
                    960:     /* "exit" is not primitive here. */
                    961:
                    962:     if (isLiteral(token.token)) {
                    963:       /* literal object */
                    964:       ob.tag = Sstring;
                    965:       ob.lc.str = (char *)sGC_malloc((strlen(token.token)+1)*sizeof(char));
                    966:       if (ob.lc.str == (char *)NULL) errorStackmachine("No space.");
                    967:       strcpy(ob.lc.str, &((token.token)[1]));
                    968:
                    969:       if (token.object.tag != Slist) {
1.7       takayama  970:         fprintf(Fstack,"\n%%Warning: The hashing values for the <<%s>> are not set.\n",token.token);
                    971:         token.object = lookupLiteralString(token.token);
1.1       maekawa   972:       }
                    973:       ob.rc.op = token.object.lc.op;
                    974:       Kpush(ob);
                    975:     } else if (isInteger(token.token)) {
                    976:       /* integer object */
                    977:       ob.tag = Sinteger ;
                    978:       ob.lc.ival = strToInteger(token.token);
                    979:       Kpush(ob);
                    980:     } else {
                    981:       if (token.object.tag != Slist) {
1.7       takayama  982:         fprintf(Fstack,"\n%%Warning: The hashing values for the <<%s>> are not set.\n",token.token);
                    983:         token = lookupTokens(token);
1.1       maekawa   984:       }
                    985:       h0 = ((token.object.lc.op)->lc).ival;
                    986:       h1 = ((token.object.lc.op)->rc).ival;
                    987:       ob=findUserDictionary(token.token,h0,h1,CurrentContextp);
                    988:       primitive = ((token.object.rc.op)->lc).ival;
1.22      takayama  989:       if (!(token.tflag & NO_DELAY)) {
                    990:         if ((ob.tag >= 0) && (UD_attr & ATTR_INFIX)) {
1.24      takayama  991:           return STATUS_INFIX;
1.22      takayama  992:         }
                    993:       }
1.1       maekawa   994:       if (ob.tag >= 0) {
1.7       takayama  995:         /* there is a definition in the user dictionary */
                    996:         if (ob.tag == SexecutableArray) {
1.28    ! takayama  997:           if (RestrictedMode) {
        !           998:             if (UD_attr & ATTR_EXPORT) {
        !           999:               localRestrictedMode_saved = RestrictedMode; RestrictedMode = 0;
        !          1000:             }else{
        !          1001:               tracePushName(token.token);
        !          1002:               errorStackmachine("You cannot execute this function in restricted mode.\n");
        !          1003:             }
        !          1004:           }
        !          1005:
1.25      takayama 1006:           status = executeExecutableArray(ob,token.token,0);
1.28    ! takayama 1007:
        !          1008:           if (localRestrictedMode_saved) RestrictedMode = localRestrictedMode_saved;
1.24      takayama 1009:           if ((status & STATUS_BREAK) || (status < 0)) return status;
1.7       takayama 1010:         }else {
                   1011:           Kpush(ob);
                   1012:         }
1.1       maekawa  1013:       } else if (primitive) {
1.15      takayama 1014:         tracePushName(token.token);
1.7       takayama 1015:         /* system operator */
                   1016:         ob.tag = Soperator;
                   1017:         ob.lc.ival = primitive;
1.15      takayama 1018:         status = executePrimitive(ob);
1.18      takayama 1019:         tracePopName();
1.15      takayama 1020:         return(status);
1.1       maekawa  1021:       } else {
1.14      takayama 1022:         if (QuoteMode) {
                   1023:           if (InSendmsg2) return(DO_QUOTE);
                   1024:           else {
                   1025:             Kpush(KpoString(token.token));
                   1026:             return(0); /* normal exit.*/
                   1027:           }
1.13      takayama 1028:                }
1.7       takayama 1029:         if (WarningMessageMode == 1 || WarningMessageMode == 2) {
                   1030:           char tmpc[1024];
                   1031:           if (strlen(token.token) < 900) {
                   1032:             sprintf(tmpc,"\n%%Warning: The identifier <<%s>> is not in the system dictionary\n%%   nor in the user dictionaries. Push NullObject.\n",token.token);
                   1033:           }else {strcpy(tmpc,"Warning: identifier is not in the dictionaries.");}
                   1034:           pushErrorStack(KnewErrorPacket(SerialCurrent,-1,tmpc));
                   1035:         }
                   1036:         if (WarningMessageMode != 1) {
                   1037:           fprintf(Fstack,"\n%%Warning: The identifier <<%s>> is not in the system dictionary\n%%   nor in the user dictionaries. Push NullObject.\n",token.token);
                   1038:           /*fprintf(Fstack,"(%d,%d)\n",h0,h1);*/
                   1039:         }
                   1040:         if (Strict) {
                   1041:           errorStackmachine("Warning: identifier is not in the dictionaries");
                   1042:         }
                   1043:         Kpush(NullObject);
1.1       maekawa  1044:       }
                   1045:     }
                   1046:   } else if (token.kind == EXECUTABLE_STRING) {
                   1047:     Kpush(executableStringToExecutableArray(token.token));
                   1048:   } else if (token.kind == EXECUTABLE_ARRAY) {
                   1049:     Kpush(token.object);
                   1050:   } else if ((token.kind == -1) || (token.kind == -2)) { /* eof token */
                   1051:     return(-1);
                   1052:   } else {
                   1053:     /*fprintf(Fstack,"\n%%Error: Unknown token type\n");***/
                   1054:     fprintf(stderr,"\nUnknown token type = %d\n",token.kind);
                   1055:     fprintf(stderr,"\ntype in ctrl-\\ if you like to make core-dump.\n");
                   1056:     fprintf(stderr,"If you like to continue, type in RETURN key.\n");
                   1057:     fprintf(stderr,"Note that you cannot input null string.\n");
                   1058:     getchar();
                   1059:     errorStackmachine("Error: Unknown token type.\n");
                   1060:     /* return(-2); /* exit */
                   1061:   }
                   1062:   return(0); /* normal exit */
                   1063: }
                   1064:
                   1065:
                   1066:
                   1067:
                   1068: errorStackmachine(str)
1.7       takayama 1069:      char *str;
1.1       maekawa  1070: {
                   1071:   int i,j,k;
                   1072:   static char *u="Usage:";
                   1073:   char message0[1024];
                   1074:   char *message;
                   1075:   extern int ErrorMessageMode;
1.28    ! takayama 1076:   extern int RestrictedMode, RestrictedMode_saved;
        !          1077:   RestrictedMode = RestrictedMode_saved;
1.10      takayama 1078:   cancelAlarm();
1.1       maekawa  1079:   if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
                   1080:     pushErrorStack(KnewErrorPacket(SerialCurrent,-1,str));
                   1081:   }
                   1082:   if (ErrorMessageMode != 1) {
                   1083:     message = message0;
                   1084:     i = 0;
                   1085:     while (i<6 && str[i]!='0') {
                   1086:       if (str[i] != u[i]) break;
                   1087:       i++;
                   1088:     }
                   1089:     if (i==6) {
                   1090:       fprintf(stderr,"ERROR(sm): \n");
                   1091:       while (str[i] != '\0' && str[i] != ' ') {
1.7       takayama 1092:         i++;
1.1       maekawa  1093:       }
                   1094:       if (str[i] == ' ') {
1.7       takayama 1095:         fprintf(stderr,"  %s\n",&(str[i+1]));
                   1096:         k = 0;
                   1097:         if (i-6 > 1022) message = (char *)sGC_malloc(sizeof(char)*i);
                   1098:         for (j=6; j<i ; j++) {
                   1099:           message[k] = str[j];
                   1100:           message[k+1] = '\0';
                   1101:           k++;
                   1102:         }
                   1103:         Kusage2(stderr,message);
1.1       maekawa  1104:       }else{
1.7       takayama 1105:         Kusage2(stderr,&(str[6]));
1.1       maekawa  1106:       }
                   1107:     }else {
                   1108:       fprintf(stderr,"ERROR(sm): ");
                   1109:       fprintf(stderr,str);
                   1110:     }
                   1111:     fprintf(stderr,"\n");
1.16      takayama 1112:     (void) traceShowStack();
1.1       maekawa  1113:   }
1.16      takayama 1114:   traceClearStack();
1.1       maekawa  1115:   if (GotoP) {
                   1116:     fprintf(Fstack,"The interpreter was looking for the label <<%s>>. It is also aborted.\n",GotoLabel);
                   1117:     GotoP = 0;
                   1118:   }
                   1119:   stdOperandStack(); contextControl(CCRESTORE);
                   1120:   getokenSM(INIT); /* It might fix the bug. 1996/3/10 */
                   1121:   /* fprintf(stderr,"Now, Long jump!\n"); */
                   1122:   longjmp(EnvOfStackMachine,1);
                   1123: }
                   1124:
                   1125: warningStackmachine(str)
1.7       takayama 1126:      char *str;
1.1       maekawa  1127: {
                   1128:   extern int WarningMessageMode;
                   1129:   extern int Strict;
                   1130:   if (WarningMessageMode == 1 || WarningMessageMode == 2) {
                   1131:     pushErrorStack(KnewErrorPacket(SerialCurrent,-1,str));
                   1132:   }
                   1133:   if (WarningMessageMode != 1) {
                   1134:     fprintf(stderr,"WARNING(sm): ");
                   1135:     fprintf(stderr,str);
                   1136:   }
                   1137:   if (Strict) errorStackmachine(" ");
                   1138:   return(0);
                   1139: }
                   1140:
                   1141:
                   1142: /* exports */
                   1143: /* NOTE:  If you call this function and an error occured,
                   1144:    you have to reset the jump buffer by setjmp(EnvOfStackMachine).
                   1145:    cf. kxx/memo1.txt, kxx/stdserver00.c 1998, 2/6 */
                   1146: KSexecuteString(s)
1.7       takayama 1147:      char *s;
1.1       maekawa  1148: {
                   1149:   struct tokens token;
                   1150:   struct object ob;
                   1151:   int tmp;
                   1152:   extern int CatchCtrlC;
                   1153:   int jval;
                   1154:   static int recursive = 0;
                   1155:   extern int ErrorMessageMode;
                   1156:   extern int KSPushEnvMode;
                   1157:   jmp_buf saved_EnvOfStackMachine;
                   1158:   void (*sigfunc)();
                   1159:   int localCatchCtrlC ;
1.28    ! takayama 1160:   extern int RestrictedMode, RestrictedMode_saved;
1.1       maekawa  1161:
                   1162:   localCatchCtrlC = CatchCtrlC;
                   1163:   /* If CatchCtrlC is rewrited in this program,
                   1164:      we crash. So, we use localCatchCtrlC. */
                   1165:
                   1166:   if (localCatchCtrlC) {
                   1167:     sigfunc = signal(SIGINT,SIG_IGN);
                   1168:     signal(SIGINT,ctrlC);
                   1169:   }
                   1170:
                   1171:   if (KSPushEnvMode) {
                   1172:     *saved_EnvOfStackMachine = *EnvOfStackMachine;
1.9       takayama 1173: #if defined(__CYGWIN__)
                   1174:     if (jval = sigsetjmp(EnvOfStackMachine,1)) {
                   1175: #else
1.1       maekawa  1176:     if (jval = setjmp(EnvOfStackMachine)) {
1.9       takayama 1177: #endif
1.1       maekawa  1178:       *EnvOfStackMachine = *saved_EnvOfStackMachine;
                   1179:       if (jval == 2) {
1.7       takayama 1180:         if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
                   1181:           pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
                   1182:         }
1.1       maekawa  1183:       }
                   1184:       recursive--;
                   1185:       if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1.16      takayama 1186:       if (!Calling_ctrlC_hook) {
1.28    ! takayama 1187:         Calling_ctrlC_hook = 1; RestrictedMode = 0;
1.16      takayama 1188:         KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */
1.28    ! takayama 1189:         RestrictedMode_saved;
1.16      takayama 1190:       }
                   1191:       Calling_ctrlC_hook = 0;
1.12      takayama 1192:       KSexecuteString(" (Computation is interrupted.) "); /* move to ctrlC-hook?*/
1.1       maekawa  1193:       return(-1);
                   1194:     }else{ }
                   1195:   }else{
                   1196:     if (recursive == 0) {
1.9       takayama 1197: #if defined(__CYGWIN__)
                   1198:       if (jval=sigsetjmp(EnvOfStackMachine,1)) {
                   1199: #else
1.1       maekawa  1200:       if (jval=setjmp(EnvOfStackMachine)) {
1.9       takayama 1201: #endif
1.7       takayama 1202:         if (jval == 2) {
                   1203:           if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
                   1204:             pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
                   1205:           }
                   1206:         }
                   1207:         recursive = 0;
                   1208:         if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1.16      takayama 1209:         if (!Calling_ctrlC_hook) {
1.28    ! takayama 1210:           Calling_ctrlC_hook = 1; RestrictedMode = 0;
1.16      takayama 1211:           KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */
1.28    ! takayama 1212:           RestrictedMode = RestrictedMode_saved;
1.16      takayama 1213:         }
                   1214:         Calling_ctrlC_hook = 0;
                   1215:         Calling_ctrlC_hook = 0;
1.11      takayama 1216:                KSexecuteString(" (Computation is interrupted.) ");
1.7       takayama 1217:         return(-1);
1.1       maekawa  1218:       }else { }
                   1219:     }
                   1220:   }
                   1221:
                   1222:   recursive++;
                   1223:   token.token = s;
1.21      takayama 1224:   token.kind = EXECUTABLE_STRING; token.tflag = 0;
1.1       maekawa  1225:   executeToken(token);
1.21      takayama 1226:   token.kind = ID; token.tflag = 0;
1.1       maekawa  1227:   token.token = "exec";
                   1228:   token = lookupTokens(token); /* no use */
                   1229:   tmp = findSystemDictionary(token.token);
                   1230:   ob.tag = Soperator;
                   1231:   ob.lc.ival = tmp;
                   1232:   executePrimitive(ob);
                   1233:   recursive--;
                   1234:   if (KSPushEnvMode) *EnvOfStackMachine = *saved_EnvOfStackMachine;
                   1235:   if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
                   1236:   return(0);
                   1237: }
                   1238:
                   1239: KSdefineMacros() {
                   1240:   struct tokens token;
                   1241:   int tmp;
                   1242:   struct object ob;
                   1243:
                   1244:   if (StandardMacros && (strlen(SMacros))) {
1.21      takayama 1245:     token.kind = EXECUTABLE_STRING; token.tflag = 0;
1.1       maekawa  1246:     token.token = SMacros;
1.7       takayama 1247:     executeToken(token);    /* execute startup commands */
1.21      takayama 1248:     token.kind = ID; token.tflag = 0;
1.1       maekawa  1249:     token.token = "exec";
                   1250:     token = lookupTokens(token); /* no use */
                   1251:     tmp = findSystemDictionary(token.token);
                   1252:     ob.tag = Soperator;
                   1253:     ob.lc.ival = tmp;
1.7       takayama 1254:     executePrimitive(ob);   /* exec */
1.1       maekawa  1255:   }
                   1256:   return(0);
                   1257:
                   1258: }
                   1259:
                   1260: void KSstart() {
                   1261:   struct tokens token;
                   1262:   int tmp;
                   1263:   struct object ob;
                   1264:   extern int Quiet;
                   1265:
                   1266:   stackmachine_init(); KinitKan();
                   1267:   getokenSM(INIT); initSystemDictionary();
                   1268:
                   1269:   /* The following line may cause a core dump, if you do not setjmp properly
                   1270:      after calling KSstart().*/
                   1271:   /*
1.7       takayama 1272:     if (setjmp(EnvOfStackMachine)) {
1.1       maekawa  1273:     fprintf(stderr,"KSstart(): An error or interrupt in reading macros, files and command strings.\n");
                   1274:     exit(10);
1.7       takayama 1275:     } else {  }  */
1.1       maekawa  1276:
                   1277:   /* setup quiet mode or not */
1.21      takayama 1278:   token.kind = EXECUTABLE_STRING; token.tflag = 0;
1.1       maekawa  1279:   if (Quiet) {
                   1280:     token.token = " /@@@.quiet 1 def ";
                   1281:   }else {
                   1282:     token.token = " /@@@.quiet 0 def ";
                   1283:   }
                   1284:   executeToken(token); /* execute startup commands */
1.21      takayama 1285:   token.kind = ID; token.tflag = 0;
1.1       maekawa  1286:   token.token = "exec";
                   1287:   token = lookupTokens(token); /* set hashing values */
                   1288:   tmp = findSystemDictionary(token.token);
                   1289:   ob.tag = Soperator;
                   1290:   ob.lc.ival = tmp;
                   1291:   executePrimitive(ob); /* exec */
                   1292:
                   1293:   KSdefineMacros();
                   1294: }
                   1295:
                   1296: void KSstop() {
                   1297:   Kclose(); stackmachine_close();
                   1298: }
                   1299:
                   1300:
                   1301: struct object KSpop() {
                   1302:   return(Kpop());
                   1303: }
                   1304:
                   1305: void KSpush(ob)
1.7       takayama 1306:      struct object ob;
1.1       maekawa  1307: {
                   1308:   Kpush(ob);
1.4       takayama 1309: }
                   1310:
                   1311: struct object KSpeek(k) {
                   1312:   return(peek(k));
1.1       maekawa  1313: }
                   1314:
                   1315: char *KSstringPop() {
                   1316:   /* pop a string */
                   1317:   struct object rob;
                   1318:   rob = Kpop();
                   1319:   if (rob.tag == Sdollar) {
                   1320:     return(rob.lc.str);
                   1321:   }else{
                   1322:     return((char *)NULL);
                   1323:   }
                   1324: }
                   1325:
                   1326: char *KSpopString() {
                   1327:   return(KSstringPop());
                   1328: }
                   1329:
                   1330: int KSset(char *name) {
                   1331:   char *tmp2;
                   1332:   char tmp[1024];
                   1333:   tmp2 = tmp;
                   1334:   if (strlen(name) < 1000) {
                   1335:     sprintf(tmp2," /%s set ",name);
                   1336:   }else{
                   1337:     tmp2 = sGC_malloc(sizeof(char)*(strlen(name)+20));
                   1338:     if (tmp2 == (char *)NULL) errorStackmachine("Out of memory.");
                   1339:     sprintf(tmp2," /%s set ",name);
                   1340:   }
                   1341:   return( KSexecuteString(tmp2) );
                   1342: }
                   1343:
                   1344: int KSpushBinary(int size,char *data) {
                   1345:   /* struct object KbinaryToObject(int size, char *data); */
                   1346:   errorStackmachine("KSpushBinary is not implemented.\n");
                   1347:   return(-1);
                   1348: }
                   1349:
                   1350: char *KSpopBinary(int *size) {
                   1351:   /* char *KobjectToBinary(struct object ob,int *size); */
                   1352:   errorStackmachine("KSpopBinary is not implemented.\n");
                   1353:   *size = 0;
                   1354:   return((char *)NULL);
                   1355: }
                   1356:
                   1357: int pushErrorStack(struct object obj)
                   1358: {
                   1359:   if (CurrentOperandStack == &ErrorStack) {
                   1360:     fprintf(stderr,"You cannot call pushErrorStack when ErrorStack is the CurrentOperandStack. \n");
                   1361:     return(-1);
                   1362:   }
                   1363:   (ErrorStack.ostack)[(ErrorStack.sp)++] = obj;
                   1364:   /* printf("ErrorStack.sp = %d\n",ErrorStack.sp); */
                   1365:   if ((ErrorStack.sp) >= (ErrorStack.size)) {
                   1366:     ErrorStack.sp = 0;
                   1367:     fprintf(stderr,"pushErrorStack():ErrorStack overflow. It is reset.\n");
                   1368:     /* Note that it avoids recursive call.*/
                   1369:     return(-1);
                   1370:   }
                   1371:   return(0);
                   1372: }
                   1373:
                   1374: struct object popErrorStack(void) {
                   1375:   if (CurrentOperandStack == &ErrorStack) {
                   1376:     fprintf(stderr,"You cannot call popErrorStack when ErrorStack is the CurrentOperandStack. \n");
                   1377:     return(NullObject);
                   1378:   }
                   1379:   if ((ErrorStack.sp) <= 0) {
                   1380:     return( NullObject );
                   1381:   }else{
                   1382:     return( (ErrorStack.ostack)[--(ErrorStack.sp)]);
                   1383:   }
                   1384: }
                   1385:
                   1386: char *popErrorStackByString(void) {
                   1387:   struct object obj;
                   1388:   struct object eobj;
                   1389:   eobj = popErrorStack();
                   1390:   if (ectag(eobj) != CLASSNAME_ERROR_PACKET) {
                   1391:     return(NULL);
                   1392:   }else{
                   1393:     obj = *(KopErrorPacket(eobj));
                   1394:   }
                   1395:   if (obj.tag != Sarray || getoaSize(obj) != 3) {
                   1396:     fprintf(stderr,"errorPacket format error.\n");
                   1397:     printObject(eobj,0,stderr); fflush(stderr);
                   1398:     return("class errorPacket format error. Bug of sm1.");
                   1399:   }
                   1400:   obj = getoa(obj,2);
                   1401:   if (obj.tag != Sdollar) {
                   1402:     fprintf(stderr,"errorPacket format error at position 2..\n");
                   1403:     printObject(eobj,0,stderr); fflush(stderr);
                   1404:     return("class errorPacket format error at the position 2. Bug of sm1.");
                   1405:   }
                   1406:   return(KopString(obj));
                   1407: }
                   1408:
                   1409:
                   1410: int KScheckErrorStack(void)
                   1411: {
                   1412:   return(ErrorStack.sp);
                   1413: }
                   1414:
                   1415: struct object KnewErrorPacket(int serial,int no,char *message)
                   1416: {
                   1417:   struct object obj;
                   1418:   struct object *myop;
                   1419:   char *s;
                   1420:   /* Set extended tag. */
                   1421:   obj.tag = Sclass;  obj.lc.ival = CLASSNAME_ERROR_PACKET ;
                   1422:   myop = (struct object *)sGC_malloc(sizeof(struct object));
                   1423:   if (myop == (struct object *)NULL) errorStackmachine("No memory\n");
                   1424:   *myop = newObjectArray(3);
                   1425:   /*fprintf(stderr,"newErrorPacket() in stackmachine.c: [%d, %d, %s] \n",serial,no,message);  **kxx:CMO_ERROR  */
                   1426:   putoa((*myop),0,KpoInteger(serial));
                   1427:   putoa((*myop),1,KpoInteger(no));
                   1428:   s = (char *)sGC_malloc(sizeof(char)*(strlen(message)+2));
                   1429:   if (s == (char *)NULL) errorStackmachine("No memory\n");
                   1430:   strcpy(s,message);
                   1431:   putoa((*myop),2,KpoString(s));
                   1432:   obj.rc.op = myop;
                   1433:   return(obj);
                   1434: }
                   1435:
                   1436:
                   1437: struct object KnewErrorPacketObj(struct object ob1)
                   1438: {
                   1439:   struct object obj;
                   1440:   struct object *myop;
                   1441:   char *s;
                   1442:   /* Set extended tag. */
                   1443:   obj.tag = Sclass;  obj.lc.ival = CLASSNAME_ERROR_PACKET ;
                   1444:   myop = (struct object *)sGC_malloc(sizeof(struct object));
                   1445:   if (myop == (struct object *)NULL) errorStackmachine("No memory\n");
                   1446:   *myop = ob1;
                   1447:   obj.rc.op = myop;
                   1448:   return(obj);
                   1449: }
                   1450:
                   1451: void *sGC_malloc(size_t n) { /* synchronized function */
                   1452:   void *c;
                   1453:   int id;
                   1454:   extern int SGClock, UserCtrlC;
                   1455:
                   1456:   SGClock = 1;
                   1457:   c = GC_malloc(n);
                   1458:   SGClock = 0;
                   1459:   if (UserCtrlC) {
                   1460:     UserCtrlC = 0;
                   1461:     id = getpid();
                   1462:     kill(id,SIGINT);
                   1463:     return(c);
                   1464:   }else{
                   1465:     return(c);
                   1466:   }
                   1467: }
                   1468:
                   1469: void *sGC_realloc(void *p,size_t new) { /* synchronized function */
                   1470:   void *c;
                   1471:   int id;
                   1472:   extern int SGClock, UserCtrlC;
                   1473:
                   1474:   SGClock = 1;
                   1475:   c = GC_realloc(p,new);
                   1476:   SGClock = 0;
                   1477:   if (UserCtrlC) {
                   1478:     UserCtrlC = 0;
                   1479:     id = getpid();
                   1480:     kill(id,SIGINT);
                   1481:     return(c);
                   1482:   }else{
                   1483:     return(c);
                   1484:   }
                   1485: }
                   1486:
                   1487: void sGC_free(void *c) { /* synchronized function */
                   1488:   int id;
                   1489:   extern int SGClock, UserCtrlC;
                   1490:
                   1491:   SGClock = 1;
                   1492:   GC_free(c);
                   1493:   SGClock = 0;
                   1494:   if (UserCtrlC) {
                   1495:     UserCtrlC = 0;
                   1496:     id = getpid();
                   1497:     kill(id,SIGINT);
                   1498:     return;
                   1499:   }else{
                   1500:     return;
                   1501:   }
                   1502: }
                   1503:
                   1504: void lockCtrlCForOx() {
                   1505:   extern int OXlock;
                   1506:   extern int OXlockSaved;
                   1507:   OXlockSaved = OXlock;
                   1508:   OXlock = 1;
                   1509: }
                   1510:
                   1511: void unlockCtrlCForOx() {
                   1512:   int id;
                   1513:   extern int OXlock, UserCtrlC;
                   1514:   extern int OXlockSaved;
                   1515:   OXlockSaved = OXlock;
                   1516:   OXlock = 0;
                   1517:   if (UserCtrlC) {
                   1518:     UserCtrlC = 0;
                   1519:     id = getpid();
                   1520:     kill(id,SIGINT);
                   1521:     return;
                   1522:   }else{
                   1523:     return;
                   1524:   }
                   1525: }
                   1526:
                   1527: void restoreLockCtrlCForOx() {
                   1528:   extern int OXlock;
                   1529:   extern int OXlockSaved;
                   1530:   OXlock = OXlockSaved;
                   1531: }
                   1532:
                   1533: int KSstackPointer() {
                   1534:   return(Osp);
                   1535: }
                   1536:
                   1537: struct object KSdupErrors() {
                   1538:   struct object rob;
                   1539:   struct object ob;
                   1540:   int i;
                   1541:   int n;
                   1542:   int m;
                   1543:
                   1544:   n = KSstackPointer();
                   1545:   m = 0;
                   1546:   for (i=0; i<n; i++) {
                   1547:     ob = peek(i);
                   1548:     if (ob.tag == Sclass && ectag(ob) == CLASSNAME_ERROR_PACKET) {
                   1549:       m++;
                   1550:     }
                   1551:   }
                   1552:   rob = newObjectArray(m);
                   1553:   m = 0;
                   1554:   for (i=0; i<n; i++) {
                   1555:     ob = peek(i);
                   1556:     if (ob.tag == Sclass && ectag(ob) == CLASSNAME_ERROR_PACKET) {
                   1557:       putoa(rob, m, ob);
                   1558:       m++;
                   1559:     }
                   1560:   }
                   1561:   return(rob);
                   1562: }
1.10      takayama 1563:
                   1564: void cancelAlarm() {
                   1565:   alarm((unsigned int) 0);
                   1566:   signal(SIGALRM,SIG_DFL);
1.15      takayama 1567: }
                   1568:
                   1569: /* back-trace */
                   1570: #define TraceNameStackSize 3000
                   1571: char *TraceNameStack[TraceNameStackSize];
                   1572: int TraceNameStackp = 0;
                   1573: void tracePushName(char *s) {
                   1574:   char *t;
                   1575:   /*
                   1576:   t = (char *)sGC_malloc(strlen(s)+1);
                   1577:   if (t == NULL) {
                   1578:     fprintf(stderr,"No more memory.\n"); return;
                   1579:   }
                   1580:   strcpy(t,s);
                   1581:   */
                   1582:   t = s;
                   1583:   TraceNameStack[TraceNameStackp++] = t;
                   1584:   if (TraceNameStackp >= TraceNameStackSize) {
                   1585:     fprintf(stderr,"Warning: TraceNameStack overflow. Clearing the stack.\n");
                   1586:     TraceNameStackp = 0;
                   1587:   }
                   1588: }
                   1589: void traceClearStack(void) {
                   1590:   TraceNameStackp = 0;
                   1591: }
                   1592: char *tracePopName(void) {
                   1593:   if (TraceNameStackp <= 0) return (char *) NULL;
                   1594:   return TraceNameStack[--TraceNameStackp];
                   1595: }
                   1596: #define TRACE_MSG_SIZE 320
                   1597: char *traceShowStack(void) {
                   1598:   char *s;
                   1599:   char *t;
                   1600:   int p;
                   1601:   s = (char *) sGC_malloc(TRACE_MSG_SIZE);
                   1602:   if (s == NULL) {
                   1603:     fprintf(stderr,"No more memory.\n"); return NULL;
                   1604:   }
                   1605:   sprintf(s,"Trace: ");
                   1606:   p = strlen(s);
                   1607:   do {
                   1608:     t = tracePopName();
                   1609:     if (t == NULL) {
                   1610:       s[p] = ';'; s[p+1] = 0;
                   1611:       break;
1.26      takayama 1612:     }else if ((strlen(t) + p) > (TRACE_MSG_SIZE-10)) {
                   1613:          /* fprintf(stderr,"p=%d, TraceNameStackp=%d, strlen(t)=%d, t=%s\n",p,TraceNameStackp,strlen(t),t); */
1.15      takayama 1614:       strcpy(&(s[p])," ...");
                   1615:       break;
                   1616:     }
                   1617:     strcpy(&(s[p]),t); p += strlen(t);
                   1618:     strcpy(&(s[p]),"<-"); p += 2;
                   1619:   } while (t != (char *)NULL);
                   1620:   fprintf(stderr,"%s\n",s);
                   1621:   return s;
1.24      takayama 1622: }
                   1623:
                   1624: /*
                   1625:   if (fname != NULL) fname is pushed to the trace stack.
                   1626:  */
1.25      takayama 1627: int executeExecutableArray(struct object ob,char *fname,int withGotoP) {
1.24      takayama 1628:   struct tokens *tokenArray;
                   1629:   int size,i;
                   1630:   int status;
                   1631:   int infixOn;
                   1632:   struct tokens infixToken;
                   1633:   extern int GotoP;
                   1634:
                   1635:   infixOn = 0;
                   1636:   if (ob.tag != SexecutableArray) errorStackmachine("Error (executeTokenArray): the argument is not a token array.");
                   1637:
                   1638:   if (fname != NULL) tracePushName(fname);
                   1639:   tokenArray = ob.lc.tokenArray;
                   1640:   size = ob.rc.ival;
                   1641:   for (i=0; i<size; i++) {
                   1642:     status = executeToken(tokenArray[i]);
1.25      takayama 1643:     if ((status & STATUS_BREAK) || (status < 0) || (withGotoP && GotoP)) {
1.24      takayama 1644:       if (fname != NULL) tracePopName();
                   1645:       return(status);
                   1646:     }
                   1647:
                   1648:     if (status & STATUS_INFIX) {
                   1649:       if (i == size-1) errorStackmachine("Infix operator at the end of an executable array.");
                   1650:       infixOn = 1; infixToken = tokenArray[i];
                   1651:       infixToken.tflag |= NO_DELAY;
                   1652:       continue;
                   1653:     }else if (infixOn) {
                   1654:       infixOn = 0;
                   1655:       status = executeToken(infixToken);
1.25      takayama 1656:       if ((status & STATUS_BREAK) || (status < 0) || (withGotoP && GotoP)) {
1.24      takayama 1657:         if (fname != NULL) tracePopName();
                   1658:         return(status);
                   1659:       }
                   1660:     }
                   1661:   }
                   1662:   if (fname != NULL) tracePopName();
                   1663:   return(0); /* normal exit */
1.10      takayama 1664: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>