[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.15

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

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