Annotation of OpenXM/src/kan96xx/Kan/stackmachine.c, Revision 1.14
1.14 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/Kan/stackmachine.c,v 1.13 2003/11/20 09:20:36 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) {
954: tokenArray = ob.lc.tokenArray;
955: size = ob.rc.ival;
956: for (i=0; i<size; i++) {
957: status = executeToken(tokenArray[i]);
958: if (status != 0) return(status);
959: }
960: }else {
961: Kpush(ob);
962: }
1.1 maekawa 963: } else if (primitive) {
1.7 takayama 964: /* system operator */
965: ob.tag = Soperator;
966: ob.lc.ival = primitive;
967: return(executePrimitive(ob));
1.1 maekawa 968: } else {
1.14 ! takayama 969: if (QuoteMode) {
! 970: if (InSendmsg2) return(DO_QUOTE);
! 971: else {
! 972: Kpush(KpoString(token.token));
! 973: return(0); /* normal exit.*/
! 974: }
1.13 takayama 975: }
1.7 takayama 976: if (WarningMessageMode == 1 || WarningMessageMode == 2) {
977: char tmpc[1024];
978: if (strlen(token.token) < 900) {
979: sprintf(tmpc,"\n%%Warning: The identifier <<%s>> is not in the system dictionary\n%% nor in the user dictionaries. Push NullObject.\n",token.token);
980: }else {strcpy(tmpc,"Warning: identifier is not in the dictionaries.");}
981: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,tmpc));
982: }
983: if (WarningMessageMode != 1) {
984: fprintf(Fstack,"\n%%Warning: The identifier <<%s>> is not in the system dictionary\n%% nor in the user dictionaries. Push NullObject.\n",token.token);
985: /*fprintf(Fstack,"(%d,%d)\n",h0,h1);*/
986: }
987: if (Strict) {
988: errorStackmachine("Warning: identifier is not in the dictionaries");
989: }
990: Kpush(NullObject);
1.1 maekawa 991: }
992: }
993: } else if (token.kind == EXECUTABLE_STRING) {
994: Kpush(executableStringToExecutableArray(token.token));
995: } else if (token.kind == EXECUTABLE_ARRAY) {
996: Kpush(token.object);
997: } else if ((token.kind == -1) || (token.kind == -2)) { /* eof token */
998: return(-1);
999: } else {
1000: /*fprintf(Fstack,"\n%%Error: Unknown token type\n");***/
1001: fprintf(stderr,"\nUnknown token type = %d\n",token.kind);
1002: fprintf(stderr,"\ntype in ctrl-\\ if you like to make core-dump.\n");
1003: fprintf(stderr,"If you like to continue, type in RETURN key.\n");
1004: fprintf(stderr,"Note that you cannot input null string.\n");
1005: getchar();
1006: errorStackmachine("Error: Unknown token type.\n");
1007: /* return(-2); /* exit */
1008: }
1009: return(0); /* normal exit */
1010: }
1011:
1012:
1013:
1014:
1015: errorStackmachine(str)
1.7 takayama 1016: char *str;
1.1 maekawa 1017: {
1018: int i,j,k;
1019: static char *u="Usage:";
1020: char message0[1024];
1021: char *message;
1022: extern int ErrorMessageMode;
1.10 takayama 1023: cancelAlarm();
1.1 maekawa 1024: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1025: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,str));
1026: }
1027: if (ErrorMessageMode != 1) {
1028: message = message0;
1029: i = 0;
1030: while (i<6 && str[i]!='0') {
1031: if (str[i] != u[i]) break;
1032: i++;
1033: }
1034: if (i==6) {
1035: fprintf(stderr,"ERROR(sm): \n");
1036: while (str[i] != '\0' && str[i] != ' ') {
1.7 takayama 1037: i++;
1.1 maekawa 1038: }
1039: if (str[i] == ' ') {
1.7 takayama 1040: fprintf(stderr," %s\n",&(str[i+1]));
1041: k = 0;
1042: if (i-6 > 1022) message = (char *)sGC_malloc(sizeof(char)*i);
1043: for (j=6; j<i ; j++) {
1044: message[k] = str[j];
1045: message[k+1] = '\0';
1046: k++;
1047: }
1048: Kusage2(stderr,message);
1.1 maekawa 1049: }else{
1.7 takayama 1050: Kusage2(stderr,&(str[6]));
1.1 maekawa 1051: }
1052: }else {
1053: fprintf(stderr,"ERROR(sm): ");
1054: fprintf(stderr,str);
1055: }
1056: fprintf(stderr,"\n");
1057: }
1058: if (GotoP) {
1059: fprintf(Fstack,"The interpreter was looking for the label <<%s>>. It is also aborted.\n",GotoLabel);
1060: GotoP = 0;
1061: }
1062: stdOperandStack(); contextControl(CCRESTORE);
1063: getokenSM(INIT); /* It might fix the bug. 1996/3/10 */
1064: /* fprintf(stderr,"Now, Long jump!\n"); */
1065: longjmp(EnvOfStackMachine,1);
1066: }
1067:
1068: warningStackmachine(str)
1.7 takayama 1069: char *str;
1.1 maekawa 1070: {
1071: extern int WarningMessageMode;
1072: extern int Strict;
1073: if (WarningMessageMode == 1 || WarningMessageMode == 2) {
1074: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,str));
1075: }
1076: if (WarningMessageMode != 1) {
1077: fprintf(stderr,"WARNING(sm): ");
1078: fprintf(stderr,str);
1079: }
1080: if (Strict) errorStackmachine(" ");
1081: return(0);
1082: }
1083:
1084:
1085: /* exports */
1086: /* NOTE: If you call this function and an error occured,
1087: you have to reset the jump buffer by setjmp(EnvOfStackMachine).
1088: cf. kxx/memo1.txt, kxx/stdserver00.c 1998, 2/6 */
1089: KSexecuteString(s)
1.7 takayama 1090: char *s;
1.1 maekawa 1091: {
1092: struct tokens token;
1093: struct object ob;
1094: int tmp;
1095: extern int CatchCtrlC;
1096: int jval;
1097: static int recursive = 0;
1098: extern int ErrorMessageMode;
1099: extern int KSPushEnvMode;
1100: jmp_buf saved_EnvOfStackMachine;
1101: void (*sigfunc)();
1102: int localCatchCtrlC ;
1103:
1104: localCatchCtrlC = CatchCtrlC;
1105: /* If CatchCtrlC is rewrited in this program,
1106: we crash. So, we use localCatchCtrlC. */
1107:
1108: if (localCatchCtrlC) {
1109: sigfunc = signal(SIGINT,SIG_IGN);
1110: signal(SIGINT,ctrlC);
1111: }
1112:
1113: if (KSPushEnvMode) {
1114: *saved_EnvOfStackMachine = *EnvOfStackMachine;
1.9 takayama 1115: #if defined(__CYGWIN__)
1116: if (jval = sigsetjmp(EnvOfStackMachine,1)) {
1117: #else
1.1 maekawa 1118: if (jval = setjmp(EnvOfStackMachine)) {
1.9 takayama 1119: #endif
1.1 maekawa 1120: *EnvOfStackMachine = *saved_EnvOfStackMachine;
1121: if (jval == 2) {
1.7 takayama 1122: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1123: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
1124: }
1.1 maekawa 1125: }
1126: recursive--;
1127: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1.11 takayama 1128: KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */
1.12 takayama 1129: KSexecuteString(" (Computation is interrupted.) "); /* move to ctrlC-hook?*/
1.1 maekawa 1130: return(-1);
1131: }else{ }
1132: }else{
1133: if (recursive == 0) {
1.9 takayama 1134: #if defined(__CYGWIN__)
1135: if (jval=sigsetjmp(EnvOfStackMachine,1)) {
1136: #else
1.1 maekawa 1137: if (jval=setjmp(EnvOfStackMachine)) {
1.9 takayama 1138: #endif
1.7 takayama 1139: if (jval == 2) {
1140: if (ErrorMessageMode == 1 || ErrorMessageMode == 2) {
1141: pushErrorStack(KnewErrorPacket(SerialCurrent,-1,"User interrupt by ctrl-C."));
1142: }
1143: }
1144: recursive = 0;
1145: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1.11 takayama 1146: KSexecuteString(" ctrlC-hook "); /* Execute User Defined functions. */
1147: KSexecuteString(" (Computation is interrupted.) ");
1.7 takayama 1148: return(-1);
1.1 maekawa 1149: }else { }
1150: }
1151: }
1152:
1153: recursive++;
1154: token.token = s;
1155: token.kind = EXECUTABLE_STRING;
1156: executeToken(token);
1157: token.kind = ID;
1158: token.token = "exec";
1159: token = lookupTokens(token); /* no use */
1160: tmp = findSystemDictionary(token.token);
1161: ob.tag = Soperator;
1162: ob.lc.ival = tmp;
1163: executePrimitive(ob);
1164: recursive--;
1165: if (KSPushEnvMode) *EnvOfStackMachine = *saved_EnvOfStackMachine;
1166: if (localCatchCtrlC) { signal(SIGINT, sigfunc); }
1167: return(0);
1168: }
1169:
1170: KSdefineMacros() {
1171: struct tokens token;
1172: int tmp;
1173: struct object ob;
1174:
1175: if (StandardMacros && (strlen(SMacros))) {
1176: token.kind = EXECUTABLE_STRING;
1177: token.token = SMacros;
1.7 takayama 1178: executeToken(token); /* execute startup commands */
1.1 maekawa 1179: token.kind = ID;
1180: token.token = "exec";
1181: token = lookupTokens(token); /* no use */
1182: tmp = findSystemDictionary(token.token);
1183: ob.tag = Soperator;
1184: ob.lc.ival = tmp;
1.7 takayama 1185: executePrimitive(ob); /* exec */
1.1 maekawa 1186: }
1187: return(0);
1188:
1189: }
1190:
1191: void KSstart() {
1192: struct tokens token;
1193: int tmp;
1194: struct object ob;
1195: extern int Quiet;
1196:
1197: stackmachine_init(); KinitKan();
1198: getokenSM(INIT); initSystemDictionary();
1199:
1200: /* The following line may cause a core dump, if you do not setjmp properly
1201: after calling KSstart().*/
1202: /*
1.7 takayama 1203: if (setjmp(EnvOfStackMachine)) {
1.1 maekawa 1204: fprintf(stderr,"KSstart(): An error or interrupt in reading macros, files and command strings.\n");
1205: exit(10);
1.7 takayama 1206: } else { } */
1.1 maekawa 1207:
1208: /* setup quiet mode or not */
1209: token.kind = EXECUTABLE_STRING;
1210: if (Quiet) {
1211: token.token = " /@@@.quiet 1 def ";
1212: }else {
1213: token.token = " /@@@.quiet 0 def ";
1214: }
1215: executeToken(token); /* execute startup commands */
1216: token.kind = ID;
1217: token.token = "exec";
1218: token = lookupTokens(token); /* set hashing values */
1219: tmp = findSystemDictionary(token.token);
1220: ob.tag = Soperator;
1221: ob.lc.ival = tmp;
1222: executePrimitive(ob); /* exec */
1223:
1224: KSdefineMacros();
1225: }
1226:
1227: void KSstop() {
1228: Kclose(); stackmachine_close();
1229: }
1230:
1231:
1232: struct object KSpop() {
1233: return(Kpop());
1234: }
1235:
1236: void KSpush(ob)
1.7 takayama 1237: struct object ob;
1.1 maekawa 1238: {
1239: Kpush(ob);
1.4 takayama 1240: }
1241:
1242: struct object KSpeek(k) {
1243: return(peek(k));
1.1 maekawa 1244: }
1245:
1246: char *KSstringPop() {
1247: /* pop a string */
1248: struct object rob;
1249: rob = Kpop();
1250: if (rob.tag == Sdollar) {
1251: return(rob.lc.str);
1252: }else{
1253: return((char *)NULL);
1254: }
1255: }
1256:
1257: char *KSpopString() {
1258: return(KSstringPop());
1259: }
1260:
1261: int KSset(char *name) {
1262: char *tmp2;
1263: char tmp[1024];
1264: tmp2 = tmp;
1265: if (strlen(name) < 1000) {
1266: sprintf(tmp2," /%s set ",name);
1267: }else{
1268: tmp2 = sGC_malloc(sizeof(char)*(strlen(name)+20));
1269: if (tmp2 == (char *)NULL) errorStackmachine("Out of memory.");
1270: sprintf(tmp2," /%s set ",name);
1271: }
1272: return( KSexecuteString(tmp2) );
1273: }
1274:
1275: int KSpushBinary(int size,char *data) {
1276: /* struct object KbinaryToObject(int size, char *data); */
1277: errorStackmachine("KSpushBinary is not implemented.\n");
1278: return(-1);
1279: }
1280:
1281: char *KSpopBinary(int *size) {
1282: /* char *KobjectToBinary(struct object ob,int *size); */
1283: errorStackmachine("KSpopBinary is not implemented.\n");
1284: *size = 0;
1285: return((char *)NULL);
1286: }
1287:
1288: int pushErrorStack(struct object obj)
1289: {
1290: if (CurrentOperandStack == &ErrorStack) {
1291: fprintf(stderr,"You cannot call pushErrorStack when ErrorStack is the CurrentOperandStack. \n");
1292: return(-1);
1293: }
1294: (ErrorStack.ostack)[(ErrorStack.sp)++] = obj;
1295: /* printf("ErrorStack.sp = %d\n",ErrorStack.sp); */
1296: if ((ErrorStack.sp) >= (ErrorStack.size)) {
1297: ErrorStack.sp = 0;
1298: fprintf(stderr,"pushErrorStack():ErrorStack overflow. It is reset.\n");
1299: /* Note that it avoids recursive call.*/
1300: return(-1);
1301: }
1302: return(0);
1303: }
1304:
1305: struct object popErrorStack(void) {
1306: if (CurrentOperandStack == &ErrorStack) {
1307: fprintf(stderr,"You cannot call popErrorStack when ErrorStack is the CurrentOperandStack. \n");
1308: return(NullObject);
1309: }
1310: if ((ErrorStack.sp) <= 0) {
1311: return( NullObject );
1312: }else{
1313: return( (ErrorStack.ostack)[--(ErrorStack.sp)]);
1314: }
1315: }
1316:
1317: char *popErrorStackByString(void) {
1318: struct object obj;
1319: struct object eobj;
1320: eobj = popErrorStack();
1321: if (ectag(eobj) != CLASSNAME_ERROR_PACKET) {
1322: return(NULL);
1323: }else{
1324: obj = *(KopErrorPacket(eobj));
1325: }
1326: if (obj.tag != Sarray || getoaSize(obj) != 3) {
1327: fprintf(stderr,"errorPacket format error.\n");
1328: printObject(eobj,0,stderr); fflush(stderr);
1329: return("class errorPacket format error. Bug of sm1.");
1330: }
1331: obj = getoa(obj,2);
1332: if (obj.tag != Sdollar) {
1333: fprintf(stderr,"errorPacket format error at position 2..\n");
1334: printObject(eobj,0,stderr); fflush(stderr);
1335: return("class errorPacket format error at the position 2. Bug of sm1.");
1336: }
1337: return(KopString(obj));
1338: }
1339:
1340:
1341: int KScheckErrorStack(void)
1342: {
1343: return(ErrorStack.sp);
1344: }
1345:
1346: struct object KnewErrorPacket(int serial,int no,char *message)
1347: {
1348: struct object obj;
1349: struct object *myop;
1350: char *s;
1351: /* Set extended tag. */
1352: obj.tag = Sclass; obj.lc.ival = CLASSNAME_ERROR_PACKET ;
1353: myop = (struct object *)sGC_malloc(sizeof(struct object));
1354: if (myop == (struct object *)NULL) errorStackmachine("No memory\n");
1355: *myop = newObjectArray(3);
1356: /*fprintf(stderr,"newErrorPacket() in stackmachine.c: [%d, %d, %s] \n",serial,no,message); **kxx:CMO_ERROR */
1357: putoa((*myop),0,KpoInteger(serial));
1358: putoa((*myop),1,KpoInteger(no));
1359: s = (char *)sGC_malloc(sizeof(char)*(strlen(message)+2));
1360: if (s == (char *)NULL) errorStackmachine("No memory\n");
1361: strcpy(s,message);
1362: putoa((*myop),2,KpoString(s));
1363: obj.rc.op = myop;
1364: return(obj);
1365: }
1366:
1367:
1368: struct object KnewErrorPacketObj(struct object ob1)
1369: {
1370: struct object obj;
1371: struct object *myop;
1372: char *s;
1373: /* Set extended tag. */
1374: obj.tag = Sclass; obj.lc.ival = CLASSNAME_ERROR_PACKET ;
1375: myop = (struct object *)sGC_malloc(sizeof(struct object));
1376: if (myop == (struct object *)NULL) errorStackmachine("No memory\n");
1377: *myop = ob1;
1378: obj.rc.op = myop;
1379: return(obj);
1380: }
1381:
1382: void *sGC_malloc(size_t n) { /* synchronized function */
1383: void *c;
1384: int id;
1385: extern int SGClock, UserCtrlC;
1386:
1387: SGClock = 1;
1388: c = GC_malloc(n);
1389: SGClock = 0;
1390: if (UserCtrlC) {
1391: UserCtrlC = 0;
1392: id = getpid();
1393: kill(id,SIGINT);
1394: return(c);
1395: }else{
1396: return(c);
1397: }
1398: }
1399:
1400: void *sGC_realloc(void *p,size_t new) { /* synchronized function */
1401: void *c;
1402: int id;
1403: extern int SGClock, UserCtrlC;
1404:
1405: SGClock = 1;
1406: c = GC_realloc(p,new);
1407: SGClock = 0;
1408: if (UserCtrlC) {
1409: UserCtrlC = 0;
1410: id = getpid();
1411: kill(id,SIGINT);
1412: return(c);
1413: }else{
1414: return(c);
1415: }
1416: }
1417:
1418: void sGC_free(void *c) { /* synchronized function */
1419: int id;
1420: extern int SGClock, UserCtrlC;
1421:
1422: SGClock = 1;
1423: GC_free(c);
1424: SGClock = 0;
1425: if (UserCtrlC) {
1426: UserCtrlC = 0;
1427: id = getpid();
1428: kill(id,SIGINT);
1429: return;
1430: }else{
1431: return;
1432: }
1433: }
1434:
1435: void lockCtrlCForOx() {
1436: extern int OXlock;
1437: extern int OXlockSaved;
1438: OXlockSaved = OXlock;
1439: OXlock = 1;
1440: }
1441:
1442: void unlockCtrlCForOx() {
1443: int id;
1444: extern int OXlock, UserCtrlC;
1445: extern int OXlockSaved;
1446: OXlockSaved = OXlock;
1447: OXlock = 0;
1448: if (UserCtrlC) {
1449: UserCtrlC = 0;
1450: id = getpid();
1451: kill(id,SIGINT);
1452: return;
1453: }else{
1454: return;
1455: }
1456: }
1457:
1458: void restoreLockCtrlCForOx() {
1459: extern int OXlock;
1460: extern int OXlockSaved;
1461: OXlock = OXlockSaved;
1462: }
1463:
1464: int KSstackPointer() {
1465: return(Osp);
1466: }
1467:
1468: struct object KSdupErrors() {
1469: struct object rob;
1470: struct object ob;
1471: int i;
1472: int n;
1473: int m;
1474:
1475: n = KSstackPointer();
1476: m = 0;
1477: for (i=0; i<n; i++) {
1478: ob = peek(i);
1479: if (ob.tag == Sclass && ectag(ob) == CLASSNAME_ERROR_PACKET) {
1480: m++;
1481: }
1482: }
1483: rob = newObjectArray(m);
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: putoa(rob, m, ob);
1489: m++;
1490: }
1491: }
1492: return(rob);
1493: }
1.10 takayama 1494:
1495: void cancelAlarm() {
1496: alarm((unsigned int) 0);
1497: signal(SIGALRM,SIG_DFL);
1498: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>