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