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