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>