Annotation of OpenXM/src/kan96xx/Kan/primitive.c, Revision 1.15
1.15 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/Kan/primitive.c,v 1.14 2004/09/12 08:55:36 takayama Exp $ */
1.1 maekawa 2: /* primitive.c */
3: /* The functions in this module were in stackmachine.c */
4:
5: #include <stdio.h>
1.5 takayama 6: #include <signal.h>
1.1 maekawa 7: #include "datatype.h"
8: #include "stackm.h"
9: #include "extern.h"
10: #include "gradedset.h"
11: #include "kclass.h"
12: #include <sys/types.h>
13: #include <sys/times.h>
14:
15: int PrintDollar = 1; /* flag for printObject() */
16: int PrintComma = 1; /* flag for printObject() */
1.10 takayama 17: int InSendmsg2 = 0;
1.1 maekawa 18: #define OB_ARRAY_MAX (AGLIMIT+100)
19:
20: extern int GotoP;
21: extern char *GotoLabel;
22: extern int Osp;
23: extern int Sdp;
24: extern int ClassTypes[]; /* kclass.c */
25: extern struct context *PrimitiveContextp;
26: extern struct context *CurrentContextp;
27: extern struct dictionary *SystemDictionary;
1.8 takayama 28: extern int QuoteMode;
1.1 maekawa 29:
30: static char *operatorType(int i);
31:
32: static char *operatorType(type)
1.4 takayama 33: int type;
1.1 maekawa 34: { int i;
1.4 takayama 35: for (i=0; i<Sdp; i++) {
36: if (type == (SystemDictionary[i]).obj.lc.ival) {
37: return((SystemDictionary[i]).key);
38: }
39: }
40: return("Unknown operator");
1.1 maekawa 41: }
42:
43: /****** primitive functions *****************************************
44: the values must be greater than 1. 0 is used for special purposes.*/
45: #define Sadd 1
46: #define Ssub 2
47: #define Smult 3
48: #define Sset_up_ring 4
49: #define Soptions 6
50: #define Sgroebner 7
51: #define Sdef 8
52: #define Spop 9
53: #define Sput 10
54: #define Sprint 11
55: #define Spstack 12
56: #define Sshow_ring 13
57: #define Sshow_systemdictionary 15
58: #define Slength 16
59: #define Sfor 17
60: #define Sroll 18
61: #define Squit 19
62: #define Stest 20 /* this is used for test of new function*/
63: #define Sfileopen 23
64: #define Sclosefile 24
65: #define Sidiv 25
66: #define Sdup 26
67: #define Smap 27
68: #define Sreduction 28
69: #define Sreplace 29
70: #define SleftBrace 30 /* primitive [ */
71: #define SrightBrace 31 /* primitive ] */
72: #define Srun 32 /* run from a file */
73: #define Sloop 33
74: #define Saload 34
75: #define Sifelse 35
76: #define Sequal 36
77: #define Sexec 37
78: #define Sset 38
79: #define Sget 41
80: #define Scopy 43
81: #define Sindex 44
82: #define Ssystem 45
83: #define Sset_order_by_matrix 50
84: #define Sshow_user_dictionary 54
85: #define Selimination_order 55
86: #define Sswitch_function 58
87: #define Sprint_switch_status 59
88: #define Scat_n 62
89: #define Sless 63
90: #define Sgreater 64
91: #define Swritestring 66
92: #define Sset_timer 67
93: #define Sspol 68
94: #define Susage 69
95: #define Sto_records 70
96: #define Scoefficients 71
97: #define Ssystem_variable 72
98: #define Sdata_conversion 73
99: #define Sdegree 74
100: #define Sinit 75
101: #define Sload 76
102: #define Seval 77
103: #define Shomogenize 78
104: #define Sprincipal 79
105: #define Spushfile 80
106: #define Sdiv 81
107: #define Sgoto 82
108: #define Sextension 83
109: #define Snewstack 84
110: #define Ssetstack 85
111: #define Sstdstack 86
112: #define Slc 87
113: #define Src 88
114: #define Sgbext 89
115: #define Snewcontext 90
116: #define Ssetcontext 91
117: #define Ssupercontext 92
118: #define Ssendmsg 93
119: #define Serror 94
120: #define Smpzext 95
121: #define Ssendmsg2 96
122: #define Sprimmsg 97
123: #define Ssupmsg2 98
124: #define Scclass 99
125: #define Scoeff2 100
1.5 takayama 126: #define Stlimit 101
1.9 takayama 127: #define Soxshell 102
1.1 maekawa 128: /***********************************************/
129: void printObject(ob,nl,fp)
1.4 takayama 130: struct object ob;
131: int nl;
132: FILE *fp;
133: /* print the object on the top of the stack. */
1.1 maekawa 134: {
135:
136: int size;
137: int i;
138: struct tokens *ta;
139:
140: if (VerboseStack >= 2) {
141: /*fprintf(fp,"@@@");*/
142: switch (ob.tag) {
143: case 0:
144: fprintf(fp,"<null> "); /* null object */
145: break;
146: case Sinteger:
147: fprintf(fp,"<integer> ");
148: break;
149: case Sstring:
150: fprintf(fp,"<literal-string> ");
151: break;
152: case Soperator:
153: fprintf(fp,"<operator> ");
154: break;
155: case Sdollar:
156: fprintf(fp,"<string(dollar)> ");
157: break;
158: case SexecutableArray:
159: fprintf(fp,"<executable array> ");
160: break;
161: case Sarray:
162: fprintf(fp,"<array> ");
163: break;
164: case SleftBraceTag:
165: fprintf(fp,"<leftBraceTag> ");
166: break;
167: case SrightBraceTag:
168: fprintf(fp,"<rightBraceTag> ");
169: break;
170: case Spoly:
171: fprintf(fp,"<poly> ");
172: break;
173: case SarrayOfPOLY:
174: fprintf(fp,"<arrayOfPOLY> ");
175: break;
176: case SmatrixOfPOLY:
177: fprintf(fp,"<matrixOfPOLY> ");
178: break;
179: case Slist:
180: fprintf(fp,"<list> ");
181: break;
182: case Sfile:
183: fprintf(fp,"<file> ");
184: break;
185: case Sring:
186: fprintf(fp,"<ring> ");
187: break;
188: case SuniversalNumber:
189: fprintf(fp,"<universalNumber> ");
190: break;
191: case Sclass:
192: fprintf(fp,"<class> ");
193: break;
194: case SrationalFunction:
195: fprintf(fp,"<rationalFunction> ");
196: break;
197: case Sdouble:
198: fprintf(fp,"<double> ");
199: break;
200: default:
201: fprintf(fp,"<Unknown object tag. %d >",ob.tag);
202: break;
203: }
204: }
205: switch (ob.tag) {
206: case 0:
207: fprintf(fp,"%%[null]"); /* null object */
208: break;
209: case Sinteger:
210: fprintf(fp,"%d",ob.lc.ival);
211: break;
212: case Sstring:
213: fprintf(fp,"%s",ob.lc.str);
214: break;
215: case Soperator:
216: fprintf(fp,"%s %%[operator] ",operatorType(ob.lc.ival));
217: break;
218: case Sdollar:
219: if (PrintDollar == 2) {
220: fprintf(fp,"(%s)",ob.lc.str);
221: } else if (PrintDollar == 0 ) {
222: fprintf(fp,"%s",ob.lc.str);
223: } else {
224: fprintf(fp,"$%s$",ob.lc.str);
225: }
226: break;
227: case SexecutableArray:
228: size = ob.rc.ival;
229: ta = ob.lc.tokenArray;
230: fprintf(fp,"{ ");
231: for (i=0; i<size; i++) {
232: switch ((ta[i]).kind) {
233: case ID:
1.4 takayama 234: fprintf(fp,"<<ID>>%s ",(ta[i]).token);
235: break;
1.1 maekawa 236: case EXECUTABLE_STRING:
1.4 takayama 237: fprintf(fp,"<<EXECUTABLE_STRING>>{%s} ",(ta[i]).token);
238: break;
1.1 maekawa 239: case EXECUTABLE_ARRAY:
1.4 takayama 240: printObject((ta[i]).object,nl,fp);
241: break;
1.1 maekawa 242: case DOLLAR:
1.4 takayama 243: fprintf(fp,"<<STRING(DOLLAR)>>%s ",(ta[i]).token);
244: break;
1.1 maekawa 245: default:
1.4 takayama 246: fprintf(fp,"Unknown token type\n");
247: break;
1.1 maekawa 248: }
249: }
250: fprintf(fp," }");
251: break;
252: case Sarray:
253: printObjectArray(ob,0,fp);
254: break;
255: case SleftBraceTag:
256: fprintf(fp,"[ ");
257: break;
258: case SrightBraceTag:
259: fprintf(fp,"] ");
260: break;
261: case Spoly:
262: fprintf(fp,"%s",KPOLYToString(ob.lc.poly));
263: break;
264: case SarrayOfPOLY:
265: fprintf(fp,"Sorry! The object arrayOfPOLY cannot be printed.");
266: break;
267: case SmatrixOfPOLY:
268: fprintf(fp,"Sorry! The object matrixOfPOLY cannot be printed.");
269: break;
270: case Slist:
271: printObjectList(&ob);
272: break;
273: case Sfile:
274: fprintf(fp,"Name=%s, FILE *=%x ",ob.lc.str,(int) ob.rc.file);
275: break;
276: case Sring:
277: fprintf(fp,"Ring."); KshowRing(KopRingp(ob));
278: break;
279: case SuniversalNumber:
280: fprintf(fp,"%s",coeffToString(ob.lc.universalNumber));
281: break;
282: case SrationalFunction:
283: fprintf(fp,"("); printObject(*(Knumerator(ob)),nl,fp);
284: fprintf(fp,")/(");printObject(*(Kdenominator(ob)),nl,fp);
285: fprintf(fp,")");
286: break;
287: case Sclass:
288: /* fprintf(fp,"Class: "); */
289: fprintClass(fp,ob);
290: break;
291: case Sdouble:
292: fprintf(fp,"%f",KopDouble(ob));
293: break;
294: default:
295: fprintf(fp,"[Unknown object tag.]");
296: break;
297: }
298: if (nl) fprintf(fp,"\n");
299: }
300:
301: void printObjectArray(ob,nl,fp)
1.4 takayama 302: struct object ob;
303: int nl;
304: FILE *fp;
1.1 maekawa 305: {
306: int size;
307: int i;
1.2 takayama 308: extern char *LeftBracket, *RightBracket;
1.1 maekawa 309: size = ob.lc.ival;
1.2 takayama 310: fprintf(fp,"%s ",LeftBracket);
1.1 maekawa 311: for (i=0; i<size; i++) {
312: if (PrintComma && (i != 0)) {
313: fprintf(fp," , ");
314: }else{
315: fprintf(fp," ");
316: }
317: printObject((ob.rc.op)[i],0,fp);
318: }
1.2 takayama 319: fprintf(fp," %s ",RightBracket);
1.1 maekawa 320: if (nl) fprintf(fp,"\n");
321: }
322:
323: void KdefinePrimitiveFunctions() {
324: /* It is recommended to sort the follows for performance */
325: putPrimitiveFunction("mul",Smult);
326: putPrimitiveFunction("add",Sadd);
327: putPrimitiveFunction("sub",Ssub);
328: putPrimitiveFunction("lt",Sless);
329: putPrimitiveFunction("set",Sset);
330: putPrimitiveFunction("eq",Sequal);
331: putPrimitiveFunction("gt",Sgreater);
332: putPrimitiveFunction("QUIT",Squit);
333: putPrimitiveFunction("[",SleftBrace);
334: putPrimitiveFunction("]",SrightBrace);
335: putPrimitiveFunction("bye",Squit);
336: putPrimitiveFunction("length",Slength);
337: putPrimitiveFunction("for",Sfor);
338: putPrimitiveFunction("roll",Sroll);
339: putPrimitiveFunction("cat_n",Scat_n);
340: putPrimitiveFunction("coefficients",Scoefficients);
341: putPrimitiveFunction("copy",Scopy);
342: putPrimitiveFunction("data_conversion",Sdata_conversion);
343: putPrimitiveFunction("aload",Saload);
344: putPrimitiveFunction("def",Sdef);
345: putPrimitiveFunction("degree",Sdegree);
346: putPrimitiveFunction("elimination_order",Selimination_order);
347: putPrimitiveFunction("exec",Sexec);
348: putPrimitiveFunction("exit",Squit);
349: putPrimitiveFunction("get",Sget);
350: putPrimitiveFunction("groebner",Sgroebner);
351: putPrimitiveFunction("ifelse",Sifelse);
352: putPrimitiveFunction("index",Sindex);
353: putPrimitiveFunction("dup",Sdup);
354: putPrimitiveFunction("init",Sinit);
355: putPrimitiveFunction("loop",Sloop);
356: putPrimitiveFunction("options",Soptions);
357: putPrimitiveFunction("pop",Spop);
358: putPrimitiveFunction("put",Sput);
359: putPrimitiveFunction("print",Sprint);
360: putPrimitiveFunction("pstack",Spstack);
361: putPrimitiveFunction("print_switch_status",Sprint_switch_status);
362: putPrimitiveFunction("quit",Squit);
363: putPrimitiveFunction("file",Sfileopen);
364: putPrimitiveFunction("closefile",Sclosefile);
365: putPrimitiveFunction("idiv",Sidiv);
366: putPrimitiveFunction("reduction",Sreduction);
367: putPrimitiveFunction("replace",Sreplace);
368: putPrimitiveFunction("run",Srun);
369: putPrimitiveFunction("set_order_by_matrix",Sset_order_by_matrix);
370: putPrimitiveFunction("set_timer",Sset_timer);
371: putPrimitiveFunction("set_up_ring@",Sset_up_ring);
372: putPrimitiveFunction("show_ring",Sshow_ring);
373: putPrimitiveFunction("show_systemdictionary",Sshow_systemdictionary);
374: putPrimitiveFunction("show_user_dictionary",Sshow_user_dictionary);
375: putPrimitiveFunction("spol",Sspol);
376: putPrimitiveFunction("switch_function",Sswitch_function);
377: putPrimitiveFunction("system",Ssystem);
378: putPrimitiveFunction("system_variable",Ssystem_variable);
379: putPrimitiveFunction("test",Stest);
1.5 takayama 380: putPrimitiveFunction("tlimit",Stlimit);
1.9 takayama 381: putPrimitiveFunction("oxshell",Soxshell);
1.1 maekawa 382: putPrimitiveFunction("map",Smap);
383: putPrimitiveFunction("to_records",Sto_records);
384: putPrimitiveFunction("Usage",Susage);
385: putPrimitiveFunction("load",Sload);
386: putPrimitiveFunction("writestring",Swritestring);
387: putPrimitiveFunction("eval",Seval);
388: putPrimitiveFunction("homogenize",Shomogenize);
389: putPrimitiveFunction("principal",Sprincipal);
390: putPrimitiveFunction("pushfile",Spushfile);
391: putPrimitiveFunction("div",Sdiv);
392: putPrimitiveFunction("goto",Sgoto);
393: putPrimitiveFunction("extension",Sextension);
394: putPrimitiveFunction("newstack",Snewstack);
395: putPrimitiveFunction("setstack",Ssetstack);
396: putPrimitiveFunction("stdstack",Sstdstack);
397: putPrimitiveFunction("lc",Slc);
398: putPrimitiveFunction("rc",Src);
399: putPrimitiveFunction("gbext",Sgbext);
400: putPrimitiveFunction("newcontext",Snewcontext);
401: putPrimitiveFunction("setcontext",Ssetcontext);
402: putPrimitiveFunction("supercontext",Ssupercontext);
403: putPrimitiveFunction("sendmsg",Ssendmsg);
404: putPrimitiveFunction("error",Serror);
405: putPrimitiveFunction("mpzext",Smpzext);
406: putPrimitiveFunction("sendmsg2",Ssendmsg2);
407: putPrimitiveFunction("primmsg",Sprimmsg);
408: putPrimitiveFunction("supmsg2",Ssupmsg2);
409: putPrimitiveFunction("cclass",Scclass);
410: putPrimitiveFunction("coeff",Scoeff2);
411: }
412:
413: int executePrimitive(ob)
1.4 takayama 414: struct object ob;
1.1 maekawa 415: {
416: struct object ob1;
417: struct object ob2;
418: struct object ob3;
419: struct object ob4;
420: struct object ob5;
421: struct object rob;
422: struct object obArray[OB_ARRAY_MAX];
423: struct object obArray2[OB_ARRAY_MAX];
424: int size;
425: int i,j,k,n;
426: int status;
1.13 takayama 427: int infixOn;
428: struct tokens infixToken;
1.1 maekawa 429: struct tokens *tokenArray;
430: struct tokens token;
431: FILE *fp;
432: char *fname;
433: int rank;
434: struct object oMat;
435: static int timerStart = 1;
436: static struct tms before, after;
437: static time_t before_real, after_real;
438: struct object oInput;
439: char *str;
440: int ccflag = 0;
441: extern int KeepInput;
442: extern int History;
443: extern struct ring *CurrentRingp;
444: extern TimerOn;
1.3 takayama 445: extern SecureMode;
1.1 maekawa 446:
1.13 takayama 447: infixOn = 0;
448:
1.1 maekawa 449: if (DebugStack >= 2) {
450: fprintf(Fstack,"In execute %d\n",ob.lc.ival); printOperandStack();
451: }
452:
453: if (GotoP) return(0);
454: switch (ob.lc.ival) {
455: /* Postscript primitives :stack */
456: case Sgoto:
457: ob1 = Kpop();
458: if (ob1.tag != Sstring) {
459: if (DebugStack>=2) printObject(ob1,0,Fstack);
460: errorStackmachine("Usage:goto");
461: }
462: GotoLabel = ob1.lc.str;
463: GotoP = 1;
464: break;
465: case Spop:
466: ob1 = Kpop();
467: break;
468:
469: case Sdup:
470: ob1 = Kpop();
471: Kpush(ob1); Kpush(ob1);
472: break;
473: case Scopy: /* copy values. cf. dup */
474: ob1 = Kpop();
475: switch(ob1.tag) {
476: case Sinteger: break;
477: default: errorStackmachine("Usage:copy");
478: }
479: size = ob1.lc.ival;
480: k = 0;
481: for (i=size-1; i>=0; i--) {
482: ob2 = peek(i+k);
483: switch(ob2.tag) {
484: case Sdollar: /* copy by value */
1.4 takayama 485: str = (char *)sGC_malloc(strlen(ob2.lc.str)+3);
486: if (str == (char *)NULL) errorStackmachine("No memory (copy)");
487: strcpy(str,ob2.lc.str);
488: Kpush(KpoString(str));
489: break;
1.1 maekawa 490: case Spoly:
1.4 takayama 491: errorStackmachine("no pCopy (copy)");
492: break;
1.1 maekawa 493: case Sarray:
1.4 takayama 494: n = ob2.lc.ival;
495: ob3 = newObjectArray(n);
496: for (j=0; j<n; j++) {
497: putoa(ob3,j,getoa(ob2,j));
498: }
499: Kpush(ob3);
500: break;
1.1 maekawa 501: default:
1.4 takayama 502: Kpush(ob2);
503: break;
1.1 maekawa 504: }
505: k++;
506: }
507: break;
508: case Sroll:
509: ob1 = Kpop();
510: ob2 = Kpop();
511: switch(ob1.tag) {
512: case Sinteger:
513: j = ob1.lc.ival;
514: break;
515: default: errorStackmachine("Usage:roll");
516: }
517: switch(ob2.tag) {
518: case Sinteger:
519: n = ob2.lc.ival;
520: break;
521: default: errorStackmachine("Usage:roll");
522: }
523: for (i=0; i<n; i++) {
524: if (i < OB_ARRAY_MAX) {
1.4 takayama 525: obArray[i] = Kpop();
1.1 maekawa 526: }else{
1.4 takayama 527: errorStackmachine("exceeded OB_ARRAY_MAX (roll)\n");
1.1 maekawa 528: }
529: }
530: for (i=0; i<n; i++) {
531: k = (j-1)%n;
532: k = (k>=0?k: k+n);
533: Kpush(obArray[k]);
534: j--;
535: }
536: break;
537: case Spstack:
538: printOperandStack();
539: break;
540:
541: /* Postscript primitives :arithmetic */
542: case Sadd:
543: ob1 = Kpop();
544: ob2 = Kpop();
545: rob = KooAdd(ob1,ob2);
546: Kpush(rob);
547: break;
548: case Ssub:
549: ob2 = Kpop();
550: ob1 = Kpop();
551: rob = KooSub(ob1,ob2);
552: Kpush(rob);
553: break;
554: case Smult:
555: ob2 = Kpop();
556: ob1 = Kpop();
557: rob = KooMult(ob1,ob2);
558: Kpush(rob);
559: break;
560: case Sidiv:
561: ob2 = Kpop(); ob1 = Kpop();
562: rob = KooDiv(ob1,ob2);
563: Kpush(rob);
564: break;
565:
566: case Sdiv:
567: ob2 = Kpop(); ob1 = Kpop();
568: rob = KooDiv2(ob1,ob2);
569: Kpush(rob);
570: break;
571:
572: /* Postscript primitives :array */
573: case SleftBrace:
574: rob.tag = SleftBraceTag;
575: Kpush(rob);
576: break;
577:
578: case SrightBrace:
579: size = 0;
580: ob1 = peek(size);
581: while (!(Osp-size-1 < 0)) { /* while the stack is not underflow */
582: if (ob1.tag == SleftBraceTag) {
1.4 takayama 583: rob = newObjectArray(size);
584: for (i=0; i<size; i++) {
585: (rob.rc.op)[i] = peek(size-1-i);
586: }
587: for (i=0; i<size+1; i++) {
588: Kpop();
589: }
590: break;
1.1 maekawa 591: }
592: size++;
593: ob1 = peek(size);
594: }
595: Kpush(rob);
596: break;
597:
598: case Sget:
599: /* [a_0 ... a_{n-1}] i get a_i */
600: /* ob2 ob1 get */
601: ob1 = Kpop();
602: ob2 = Kpop();
1.12 takayama 603: Kpush(Kget(ob2,ob1));
1.1 maekawa 604: break;
605:
606: case Sput:
607: /* [a_0 ... a_{n-1}] index any put */
608: /* ob3 ob2 ob1 put */
609: /* Or; [[a_00 ....] [a_10 ....] ....] [1 0] any put. MultiIndex. */
610: ob1 = Kpop(); ob2 = Kpop(); ob3 = Kpop();
611: switch(ob2.tag) {
612: case Sinteger:
613: switch(ob3.tag) {
614: case Sarray:
1.4 takayama 615: i = ob2.lc.ival;
616: size = getoaSize(ob3);
617: if ((0 <= i) && (i<size)) {
618: getoa(ob3,i) = ob1;
619: }else{
620: errorStackmachine("Index is out of bound. (put)\n");
621: }
622: break;
1.1 maekawa 623: case Sdollar:
1.4 takayama 624: i = ob2.lc.ival;
625: size = strlen(ob3.lc.str);
626: if ((0 <= i) && (i<size)) {
627: if (ob1.tag == Sdollar) {
628: (ob3.lc.str)[i] = (ob1.lc.str)[0];
629: }else{
630: (ob3.lc.str)[i] = ob1.lc.ival;
631: }
632: }else{
633: errorStackmachine("Index is out of bound. (put)\n");
634: }
635: break;
1.1 maekawa 636: default: errorStackmachine("Usage:put");
637: }
638: break;
639: case Sarray:
640: ob5 = ob3;
641: n = getoaSize(ob2);
642: for (i=0; i<n; i++) {
1.4 takayama 643: if (ob5.tag != Sarray)
644: errorStackmachine("Object pointed by the multi-index is not array (put)\n");
645: ob4 = getoa(ob2,i);
646: if (ob4.tag != Sinteger)
647: errorStackmachine("Index has to be an integer. (put)\n");
648: k = ob4.lc.ival;
649: size = getoaSize(ob5);
650: if ((0 <= k) && (k<size)) {
651: if (i == n-1) {
652: getoa(ob5,k) = ob1;
653: }else{
654: ob5 = getoa(ob5,k);
655: }
656: }else{
657: errorStackmachine("Index is out of bound for the multi-index. (put)\n");
658: }
1.1 maekawa 659: }
660: break;
661: default: errorStackmachine("Usage:put");
662: }
663: break;
664:
665: case Sindex:
666: ob1 = Kpop();
667: switch(ob1.tag) {
668: case Sinteger: break;
669: default: errorStackmachine("Usage:index");
670: }
671: size = ob1.lc.ival;
672: Kpush(peek(size-1));
673: break;
674:
675: case Saload:
676: /* [a1 a2 ... an] aload a1 a2 ... an [a1 ... an] */
677: ob1 = Kpop();
678: switch(ob1.tag) {
679: case Sarray: break;
680: default:
681: errorStackmachine("Usage:aload");
682: }
683: size = getoaSize(ob1);
684: for (i=0; i<size; i++) {
685: Kpush(getoa(ob1,i));
686: }
687: Kpush(ob1);
688:
689: break;
690:
691: case Slength:
692: /* [a_0 ... a_{n-1}] length n */
693: /* ob1 length rob */
694: ob1 = Kpop();
695: switch(ob1.tag) {
696: case Sarray:
697: size = getoaSize(ob1);
698: Kpush(KpoInteger(size));
699: break;
700: case Sdollar:
701: Kpush(KpoInteger(strlen(ob1.lc.str)));
702: break;
703: case Spoly:
704: Kpush(KpoInteger(KpolyLength(KopPOLY(ob1))));
705: break;
706: default: errorStackmachine("Usage:length");
707: }
708: break;
709:
710: /* Postscript primitives :relation */
711: case Sequal:
712: /* obj1 obj2 == bool */
713: ob2 = Kpop();
714: ob1 = Kpop();
715: if(KooEqualQ(ob1,ob2)) {
716: Kpush(KpoInteger(1));
717: }else{
718: Kpush(KpoInteger(0));
719: }
720: break;
721:
722: case Sless:
723: /* obj1 obj2 < bool */
724: ob2 = Kpop();
725: ob1 = Kpop();
726: Kpush(KooLess(ob1,ob2));
727: break;
728:
729: case Sgreater:
730: /* obj1 obj2 < bool */
731: ob2 = Kpop();
732: ob1 = Kpop();
733: Kpush(KooGreater(ob1,ob2));
734: break;
735:
736:
737: /* Postscript primitives :controle */
738: case Sloop:
739: /* { .... exit .....} loop */
740: ob1 = Kpop();
741: switch(ob1.tag) {
742: case SexecutableArray: break;
743: default:
744: errorStackmachine("Usage:loop");
745: break;
746: }
747: while (1) {
1.15 ! takayama 748: status = executeExecutableArray(ob1,(char *)NULL,1);
1.13 takayama 749: if ((status & STATUS_BREAK) || GotoP) break;
1.1 maekawa 750: /* here, do not return 1. Do not propagate exit signal outside of the
1.4 takayama 751: loop. */
1.1 maekawa 752: }
753: break;
754:
755: case Sfor:
756: /* init inc limit { } for */
757: /* ob4 ob3 ob2 ob1 */
758: ob1 =Kpop(); ob2 = Kpop(); ob3 = Kpop(); ob4 = Kpop();
759: switch(ob1.tag) {
760: case SexecutableArray: break;
761: default: errorStackmachine("Usage:for");
762: }
763: switch(ob2.tag) {
764: case Sinteger: break;
765: default:
766: errorStackmachine("Usage:for The 3rd argument must be integer.");
767: }
768: switch(ob3.tag) {
769: case Sinteger: break;
770: default: errorStackmachine("Usage:for The 2nd argument must be integer.");
771: }
772: switch(ob4.tag) {
773: case Sinteger: break;
774: default: errorStackmachine("Usage:for The 1st argument must be integer.");
775: }
776: {
777: int i,lim,inc,j;
778: i = ob4.lc.ival;
779: lim = ob2.lc.ival;
780: inc = ob3.lc.ival;
781: if (inc > 0) {
782: /*
1.4 takayama 783: if (lim < i) errorStackmachine("The initial value must not be greater than limit value (for).\n");
1.1 maekawa 784: */
1.4 takayama 785: for ( ; i<=lim; i += inc) {
786: Kpush(KpoInteger(i));
1.15 ! takayama 787: status = executeExecutableArray(ob1,(char *)NULL,1);
1.14 takayama 788: if ((status & STATUS_BREAK) || GotoP) goto xyz;
1.13 takayama 789: }
1.1 maekawa 790: }else{
791: /*
1.4 takayama 792: if (lim > i) errorStackmachine("The initial value must not be less than limit value (for).\n");
1.1 maekawa 793: */
1.4 takayama 794: for ( ; i>=lim; i += inc) {
795: Kpush(KpoInteger(i));
1.15 ! takayama 796: status = executeExecutableArray(ob1,(char *)NULL,1);
1.14 takayama 797: if ((status & STATUS_BREAK) || GotoP) goto xyz;
1.4 takayama 798: }
1.1 maekawa 799: }
1.4 takayama 800: xyz: ;
1.1 maekawa 801: }
802: break;
803:
804: case Smap:
805: ob2 = Kpop(); ob1 = Kpop();
806: switch(ob1.tag) {
807: case Sarray: break;
808: default:
809: errorStackmachine("Usage:map The 1st argument must be an array.");
810: break;
811: }
812: switch(ob2.tag) {
813: case SexecutableArray: break;
814: default:
815: errorStackmachine("Usage:map The 2nd argument must be an executable array.");
816: break;
817: }
818: { int osize,size;
1.4 takayama 819: int i,j;
820: osize = getoaSize(ob1);
1.1 maekawa 821:
1.4 takayama 822: /*KSexecuteString("[");*/
823: rob.tag = SleftBraceTag;
824: Kpush(rob);
1.1 maekawa 825:
1.4 takayama 826: for (i=0; i<osize; i++) {
827: Kpush(getoa(ob1,i));
1.15 ! takayama 828: status = executeExecutableArray(ob2,(char *)NULL,0);
! 829: if (status & STATUS_BREAK) goto foor;
1.4 takayama 830: }
1.1 maekawa 831: foor: ;
1.4 takayama 832: /*KSexecuteString("]");*/
833: {
834: size = 0;
835: ob1 = peek(size);
836: while (!(Osp-size-1 < 0)) { /* while the stack is not underflow */
837: if (ob1.tag == SleftBraceTag) {
838: rob = newObjectArray(size);
839: for (i=0; i<size; i++) {
840: (rob.rc.op)[i] = peek(size-1-i);
841: }
842: for (i=0; i<size+1; i++) {
843: Kpop();
844: }
845: break;
846: }
847: size++;
848: ob1 = peek(size);
1.1 maekawa 849: }
1.4 takayama 850: Kpush(rob);
851: }
1.1 maekawa 852: }
853: break;
854:
855:
856: case Sifelse:
857: /* bool { } { } ifelse */
858: ob1 = Kpop();
859: ob2 = Kpop();
860: ob3 = Kpop();
861: switch (ob1.tag) {
862: case SexecutableArray: break;
863: default: errorStackmachine("Usage:ifelse");
864: }
865: switch (ob2.tag) {
866: case SexecutableArray: break;
867: default: errorStackmachine("Usage:ifelse");
868: }
869: switch (ob3.tag) {
870: case Sinteger: break;
871: default: errorStackmachine("Usage:ifelse");
872: }
873: if (ob3.lc.ival) {
874: /* execute ob2 */
875: ob1 = ob2;
876: }
877: /* execute ob1 */
1.15 ! takayama 878: status = executeExecutableArray(ob1,(char *)NULL,0);
1.14 takayama 879: if (status & STATUS_BREAK) return(status);
1.13 takayama 880:
1.1 maekawa 881: break;
882:
883: case Sexec:
884: /* { .........} exec */
885: ob1 = Kpop();
886: switch(ob1.tag) {
887: case SexecutableArray: break;
888: default: errorStackmachine("Usage:exec");
889: }
1.15 ! takayama 890: status = executeExecutableArray(ob1,(char *)NULL,0);
1.1 maekawa 891: break;
892:
1.4 takayama 893: /* Postscript primitives :dictionary */
1.1 maekawa 894: case Sdef:
895: ob2 = Kpop();
896: ob1 = Kpop();
897: /* type check */
898: switch(ob1.tag) {
899: case Sstring: break;
900: default:
901: errorStackmachine("Usage:def");
902: break;
903: }
904: k=putUserDictionary(ob1.lc.str,(ob1.rc.op->lc).ival,
1.4 takayama 905: (ob1.rc.op->rc).ival,ob2,
906: CurrentContextp->userDictionary);
1.1 maekawa 907: if (k < 0) {
908: str = (char *)sGC_malloc(sizeof(char)*(strlen(ob1.lc.str) + 256));
909: if (str == (char *)NULL) {
1.4 takayama 910: errorStackmachine("No memory.\n");
1.1 maekawa 911: }
912: if (k == -PROTECT) {
1.4 takayama 913: sprintf(str,"You rewrited the protected symbol %s.\n",ob1.lc.str);
914: /* cf. [(chattr) num sym] extension */
915: warningStackmachine(str);
1.1 maekawa 916: } else if (k == -ABSOLUTE_PROTECT) {
1.4 takayama 917: sprintf(str,"You cannot rewrite the protected symbol %s.\n",ob1.lc.str);
918: errorStackmachine(str);
1.1 maekawa 919: } else errorStackmachine("Unknown return value of putUserDictioanry\n");
920: }
921: break;
922:
923: case Sload:
924: ob1 = Kpop();
925: switch(ob1.tag) {
926: case Sstring: break;
927: default: errorStackmachine("Usage:load");
928: }
929: ob1 = findUserDictionary(ob1.lc.str,
1.4 takayama 930: (ob1.rc.op->lc).ival,
931: (ob1.rc.op->rc).ival,
932: CurrentContextp);
1.1 maekawa 933: if (ob1.tag == -1) Kpush(NullObject);
934: else Kpush(ob1);
935:
936: break;
937:
938: case Sset:
939: ob1 = Kpop();
940: ob2 = Kpop();
941: switch(ob1.tag) {
942: case Sstring: break;
943: default: errorStackmachine("Usage:set");
944: }
945: k= putUserDictionary(ob1.lc.str,(ob1.rc.op->lc).ival,
1.4 takayama 946: (ob1.rc.op->rc).ival,ob2,
947: CurrentContextp->userDictionary);
1.1 maekawa 948: if (k < 0) {
949: str = (char *)sGC_malloc(sizeof(char)*(strlen(ob1.lc.str) + 256));
950: if (str == (char *)NULL) {
1.4 takayama 951: errorStackmachine("No memory.\n");
1.1 maekawa 952: }
953: if (k == -PROTECT) {
1.4 takayama 954: sprintf(str,"You rewrited the protected symbol %s. \n",ob1.lc.str);
955: warningStackmachine(str);
1.1 maekawa 956: } else if (k == -ABSOLUTE_PROTECT) {
1.4 takayama 957: sprintf(str,"You cannot rewrite the protected symbol %s.\n",ob1.lc.str);
958: errorStackmachine(str);
1.1 maekawa 959: } else errorStackmachine("Unknown return value of putUserDictioanry\n");
960: }
961: break;
962:
963:
964: case Sshow_systemdictionary:
965: fprintf(Fstack,"------------- system dictionary -------------------\n");
966: showSystemDictionary(0);
967: break;
968:
969: case Sshow_user_dictionary:
970: showUserDictionary();
971: break;
972:
973:
974:
975: /* Postscript primitives : convert */
976: case Sdata_conversion:
977: ob2 = Kpop();
978: ob1 = Kpop();
979: switch(ob2.tag) {
980: case Sdollar:
981: if (ob1.tag != Sclass) {
1.4 takayama 982: rob = KdataConversion(ob1,ob2.lc.str);
1.1 maekawa 983: }else{
1.4 takayama 984: rob = KclassDataConversion(ob1,ob2);
1.1 maekawa 985: }
986: break;
987: case Sarray:
988: rob = KclassDataConversion(ob1,ob2); break;
989: default: errorStackmachine("Usage:data_conversion");
990: }
991: Kpush(rob);
992: break;
993:
994:
995: /* Postscript ptimitives :file */
996: case Srun:
997: ob1 = Kpop();
998: switch(ob1.tag) {
999: case Sdollar: break;
1000: case Sstring: break;
1001: default:
1002: errorStackmachine("Usage:run");
1003: break;
1004: }
1005: getokenSM(OPEN,ob1.lc.str); /* open the file, $filename$ run */
1006: break;
1007:
1008: case Sprint:
1009: ob1 = Kpop();
1010: printObject(ob1,0,Fstack);
1011: break;
1012:
1013: case Sfileopen: /* filename mode file descripter */
1.4 takayama 1014: /* ob2 ob1 */
1.1 maekawa 1015: ob1 = Kpop();
1016: ob2 = Kpop();
1.4 takayama 1017: if (SecureMode) errorStackmachine("Security violation: you cannot open a file.");
1.1 maekawa 1018: switch(ob1.tag) {
1019: case Sdollar: break;
1020: default: errorStackmachine("Usage:file");
1021: }
1022: switch(ob2.tag) {
1023: case Sinteger: break;
1024: case Sdollar: break;
1025: default:errorStackmachine("Usage:file");
1026: }
1027: rob = NullObject;
1028: if (ob2.tag == Sdollar) {
1029: if (strcmp(ob2.lc.str,"%stdin") == 0) {
1.4 takayama 1030: rob.tag = Sfile; rob.lc.str="%stdin"; rob.rc.file = stdin;
1.1 maekawa 1031: }else if (strcmp(ob2.lc.str,"%stdout") == 0) {
1.4 takayama 1032: rob.tag = Sfile; rob.lc.str="%stdout"; rob.rc.file = stdout;
1.1 maekawa 1033: }else if (strcmp(ob2.lc.str,"%stderr") == 0) {
1.4 takayama 1034: rob.tag = Sfile; rob.lc.str="%stderr"; rob.rc.file = stderr;
1.1 maekawa 1035: }else if ( (rob.rc.file = fopen(ob2.lc.str,ob1.lc.str)) != (FILE *)NULL) {
1.4 takayama 1036: rob.tag = Sfile; rob.lc.str = ob2.lc.str;
1.1 maekawa 1037: }else {
1.4 takayama 1038: errorStackmachine("I cannot open the file.");
1.1 maekawa 1039: }
1040: }else {
1041: rob.rc.file = fdopen(ob2.lc.ival,ob1.lc.str);
1042: if ( rob.rc.file != (FILE *)NULL) {
1.4 takayama 1043: rob.tag = Sfile; rob.lc.ival = ob2.lc.ival;
1.1 maekawa 1044: }else{
1.4 takayama 1045: errorStackmachine("I cannot fdopen the given fd.");
1.1 maekawa 1046: }
1047: }
1048:
1049: Kpush(rob);
1050: break;
1051:
1052:
1053: case Swritestring:
1054: /* file string writestring
1055: ob2 ob1
1056: */
1057: ob1 = Kpop();
1058: ob2 = Kpop();
1059: switch(ob2.tag) {
1060: case Sfile: break;
1061: default: errorStackmachine("Usage:writestring");
1062: }
1063: switch(ob1.tag) {
1064: case Sdollar: break;
1065: default: errorStackmachine("Usage:writestring");
1066: }
1067: fprintf(ob2.rc.file,"%s",ob1.lc.str);
1068: break;
1069:
1070: case Sclosefile:
1071: ob1 = Kpop();
1072: switch(ob1.tag) {
1073: case Sfile: break;
1074: default: errorStackmachine("Usage:closefile");
1075: }
1076: if (fclose(ob1.rc.file) == EOF) {
1077: errorStackmachine("I couldn't close the file.\n");
1078: }
1079: break;
1080:
1081: case Spushfile: /* filename pushfile string */
1.4 takayama 1082: /* ob2 */
1.1 maekawa 1083: ob2 = Kpop();
1084: switch(ob2.tag) {
1085: case Sdollar: break;
1086: default:errorStackmachine("Usage:pushfile");
1087: }
1088: rob = NullObject;
1089: if (strcmp(ob2.lc.str,"%stdin") == 0) {
1090: ob1.tag = Sfile; ob1.lc.str="%stdin"; ob1.rc.file = stdin;
1091: }else if (strcmp(ob2.lc.str,"%stdout") == 0) {
1092: ob1.tag = Sfile; ob1.lc.str="%stdout"; ob1.rc.file = stdout;
1093: }else if (strcmp(ob2.lc.str,"%stderr") == 0) {
1094: ob1.tag = Sfile; ob1.lc.str="%stderr"; ob1.rc.file = stderr;
1095: }else if ( (ob1.rc.file = fopen(ob2.lc.str,"r")) != (FILE *)NULL) {
1096: ob1.tag = Sfile; ob1.lc.str = ob2.lc.str;
1097: }else {
1098: if (ob1.rc.file == (FILE *)NULL) {
1.4 takayama 1099: char fname2[1024];
1100: strcpy(fname2,getLOAD_SM1_PATH());
1101: strcat(fname2,ob2.lc.str);
1102: ob1.rc.file = fopen(fname2,"r");
1103: if (ob1.rc.file == (FILE *)NULL) {
1104: strcpy(fname2,LOAD_SM1_PATH);
1105: strcat(fname2,ob2.lc.str);
1106: ob1.rc.file = fopen(fname2,"r");
1107: if (ob1.rc.file == (FILE *)NULL) {
1108: fprintf(stderr,"Warning: Cannot open the file <<%s>> for loading in the current directory nor the library directories %s and %s.\n",ob2.lc.str,getLOAD_SM1_PATH(),LOAD_SM1_PATH);
1109: errorStackmachine("I cannot open the file.");
1110: }
1111: }
1.1 maekawa 1112: }
1113: }
1114:
1115: /* read the strings
1.4 takayama 1116: */
1.1 maekawa 1117: n = 256; j=0;
1118: rob.tag = Sdollar; rob.lc.str = (char *) sGC_malloc(sizeof(char)*n);
1119: if (rob.lc.str == (char *)NULL) errorStackmachine("No more memory.");
1120: while ((i = fgetc(ob1.rc.file)) != EOF) {
1121: if (j >= n-1) {
1.4 takayama 1122: n = 2*n;
1123: if (n <= 0) errorStackmachine("Too large file to put on the stack.");
1.1 maekawa 1124: str = (char *)sGC_malloc(sizeof(char)*n);
1.4 takayama 1125: if (str == (char *)NULL) errorStackmachine("No more memory.");
1126: for (k=0; k< n/2; k++) str[k] = (rob.lc.str)[k];
1127: rob.lc.str = str;
1.1 maekawa 1128: }
1129: (rob.lc.str)[j] = i; (rob.lc.str)[j+1] = '\0';
1130: j++;
1131: }
1132:
1133: fclose(ob1.rc.file);
1134: Kpush(rob);
1135: break;
1136:
1137: /* Postscript primitives :misc */
1138: case Squit:
1139: Kclose(); stackmachine_close();
1140: exit(0);
1141: break;
1142:
1143: case Ssystem:
1144: ob1 = Kpop();
1145: switch(ob1.tag) {
1146: case Sdollar: break;
1147: case Sstring: break;
1148: default: errorStackmachine("Usage:system");
1149: }
1.4 takayama 1150: if (SecureMode) errorStackmachine("Security violation.");
1.1 maekawa 1151: system( ob1.lc.str );
1152: break;
1153:
1154: case Scat_n:
1155: ob1 = Kpop();
1156: switch(ob1.tag) {
1157: case Sinteger: break;
1158: default: errorStackmachine("Usage:cat_n");
1159: }
1160: size = ob1.lc.ival;
1161: k = 0;
1162: for (i=size-1; i>=0; i--) {
1163: ob2 = peek(i);
1164: switch(ob2.tag) {
1165: case Sdollar: break;
1.4 takayama 1166: default: errorStackmachine("Usage:cat_n");
1.1 maekawa 1167: }
1168: k += strlen(ob2.lc.str);
1169: }
1170: ob1.tag = Sdollar;
1171: ob1.lc.str = (char *)sGC_malloc(sizeof(char)*(k+1));
1172: if (ob1.lc.str == (char *)NULL) {
1173: errorStackmachine("No more memory.\n");
1174: }
1175: /* concatnate */
1176: k = 0;
1177: for (i=size-1; i>=0; i--) {
1178: ob2 = peek(i);
1179: strcpy(&((ob1.lc.str)[k]),ob2.lc.str);
1180: k = strlen(ob1.lc.str);
1181: }
1182: /* clear the arguments */
1183: for (i=size-1; i>=0; i--) {
1184: ob2 = Kpop();
1185: }
1186: Kpush(ob1);
1187: break;
1188:
1189: case Sset_timer:
1190: /* 118p */
1191: if (timerStart) {
1192: before_real = time(&before_real);
1193: times(&before);
1194: timerStart = 0; TimerOn = 1;
1195: }else{
1196: times(&after);
1197: after_real = time(&after_real);
1198: if (TimerOn) {
1.4 takayama 1199: printf("User time: %f seconds, System time: %f seconds, Real time: %d s\n",
1200: ((double)(after.tms_utime - before.tms_utime)) /100.0,
1201: ((double)(after.tms_stime - before.tms_stime)) /100.0,
1202: (int) (after_real-before_real));
1203: /* In cases of Solaris and Linux, the unit of tms_utime seems to
1204: be given 0.01 seconds. */
1.1 maekawa 1205:
1206: }
1207: timerStart = 1; TimerOn = 0;
1208: }
1209: break;
1210:
1211: case Susage:
1212: ob1 = Kpop();
1213: Kusage(ob1);
1214: break;
1215:
1216: case Sto_records:
1217: ob1 = Kpop();
1218: switch(ob1.tag) {
1219: case Sdollar: break;
1220: default: errorStackmachine("Usage:to_records");
1221: }
1222: ob2 = KtoRecords(ob1);
1223: size = getoaSize(ob2);
1224: for (i=0; i<size; i++) {
1225: Kpush(getoa(ob2,i));
1226: }
1227: rob.tag = Sinteger;
1228: rob.lc.ival = size;
1229: Kpush(rob);
1230: break;
1231:
1232: case Ssystem_variable:
1233: ob1 = Kpop();
1234: switch(ob1.tag) {
1235: case Sarray: break;
1236: default: errorStackmachine("Usage:system_variable");
1237: }
1238: Kpush(KsystemVariable(ob1));
1239: break;
1240:
1241: /* kan primitives :kan :ring */
1242: case Sset_order_by_matrix:
1243: ob1 = Kpop();
1244: KsetOrderByObjArray(ob1);
1245: break;
1246: case Sset_up_ring:
1.7 takayama 1247: KresetDegreeShift();
1.1 maekawa 1248: ob5 = Kpop(); ob4=Kpop(); ob3=Kpop(); ob2=Kpop(); ob1=Kpop();
1249: KsetUpRing(ob1,ob2,ob3,ob4,ob5);
1250: break;
1251: case Sshow_ring:
1252: KshowRing(CurrentRingp);
1253: break;
1254: case Sswitch_function:
1255: ob1 = Kpop();
1256: ob2 = Kpop();
1257: ob3 = KswitchFunction(ob2,ob1);
1258: if (!isNullObject(ob3)) {
1259: Kpush(ob3);
1260: }
1261: break;
1262: case Sprint_switch_status:
1263: KprintSwitchStatus();
1264: break;
1265: case Sreplace:
1266: ob2 = Kpop();
1267: ob1 = Kpop();
1268: Kpush(KoReplace(ob1,ob2));
1269: break;
1270:
1271: case Scoefficients:
1272: ob2 = Kpop();
1273: ob1 = Kpop();
1274: Kpush(Kparts(ob1,ob2));
1275: break;
1276:
1277: case Scoeff2:
1278: ob2 = Kpop();
1279: ob1 = Kpop();
1280: Kpush(Kparts2(ob1,ob2));
1281: break;
1282:
1283: case Sdegree:
1284: ob2 = Kpop();
1285: ob1 = Kpop();
1286: Kpush(Kdegree(ob1,ob2));
1287: break;
1288: case Sspol:
1289: ob2 = Kpop();
1290: ob1 = Kpop();
1291: Kpush(Ksp(ob1,ob2));
1292: break;
1293:
1294: case Seval:
1295: ob1 = Kpop();
1296: Kpush(Keval(ob1));
1297: break;
1298:
1299: case Sreduction:
1300: ob2 = Kpop();
1301: ob1 = Kpop();
1302: Kpush(Kreduction(ob1,ob2));
1303: break;
1304:
1305: case Sgroebner :
1306: ob1 = Kpop();
1307: Kpush(Kgroebner(ob1));
1308: break;
1309:
1310: case Shomogenize :
1311: ob1 = Kpop();
1312: Kpush(homogenizeObject(ob1,&i));
1313: break;
1314:
1315: case Sprincipal :
1316: ob1 = Kpop();
1317: Kpush(oPrincipalPart(ob1));
1318: break;
1319:
1320: case Sinit:
1321: ob2 = Kpop();
1322: if (ob2.tag != Sarray) {
1323: Kpush(Khead(ob2));
1324: }else{
1.6 takayama 1325: if (getoaSize(ob2) > 0) {
1326: if (getoa(ob2,getoaSize(ob2)-1).tag == Spoly) {
1327: Kpush(oInitW(ob2,newObjectArray(0)));
1328: }else{
1329: ob1 = Kpop();
1330: Kpush(oInitW(ob1,ob2));
1331: }
1332: }else{
1333: ob1 = Kpop();
1334: Kpush(oInitW(ob1,ob2));
1335: }
1.1 maekawa 1336: }
1337: break;
1338:
1339: case Sextension:
1340: ob1 = Kpop();
1341: Kpush(Kextension(ob1));
1342: break;
1343:
1344: case Sgbext:
1345: ob1 = Kpop();
1346: Kpush(KgbExtension(ob1));
1347: break;
1348:
1349: case Snewstack:
1350: ob1 = Kpop();
1351: switch(ob1.tag) {
1352: case Sinteger:
1353: Kpush(newOperandStack(ob1.lc.ival));
1354: break;
1355: default:
1356: errorStackmachine("Usage:newstack");
1357: break;
1358: }
1359: break;
1360:
1361: case Ssetstack:
1362: ob1 = Kpop();
1363: switch(ob1.tag) {
1364: case Sclass:
1365: setOperandStack(ob1);
1366: break;
1367: default:
1368: errorStackmachine("Usage:setstack");
1369: break;
1370: }
1371: break;
1372:
1373: case Sstdstack:
1374: stdOperandStack();
1375: break;
1376:
1377: case Slc:
1378: ob1 = Kpop();
1379: switch (ob1.tag) {
1380: case Sclass:
1381: Kpush(KpoInteger(ob1.lc.ival));
1382: break;
1383: default:
1384: errorStackmachine("Usage:lc");
1385: break;
1386: }
1387: break;
1388:
1389: case Src:
1390: ob1 = Kpop();
1391: switch (ob1.tag) {
1392: case Sclass:
1393: if (ClassTypes[ob1.lc.ival] == CLASS_OBJ) {
1.4 takayama 1394: Kpush(*(ob1.rc.op));
1.1 maekawa 1395: }else{
1.4 takayama 1396: warningStackmachine("<<obj rc >> works only for a class object with CLASS_OBJ attribute.\n");
1397: Kpush(ob1);
1.1 maekawa 1398: }
1399: break;
1400: default:
1401: errorStackmachine("Usage:rc");
1402: break;
1403: }
1404: break;
1405:
1406: case Snewcontext:
1407: ob1 = Kpop();
1408: ob2 = Kpop();
1409: switch(ob1.tag) {
1410: case Sclass:
1411: if (ob2.tag == Sdollar) {
1.4 takayama 1412: Kpush(KnewContext(ob1,KopString(ob2)));
1.1 maekawa 1413: }else errorStackmachine("Usage:newcontext");
1414: break;
1415: default:
1416: errorStackmachine("Usage:newcontext");
1417: break;
1418: }
1419: break;
1420:
1421: case Ssetcontext:
1422: ob1 = Kpop();
1423: switch(ob1.tag) {
1424: case Sclass:
1425: KsetContext(ob1);
1426: break;
1427: default:
1428: errorStackmachine("Usage:setcontext");
1429: break;
1430: }
1431: break;
1432:
1433: case Ssupercontext:
1434: ob1 = Kpop();
1435: switch(ob1.tag) {
1436: case Sclass:
1437: Kpush(getSuperContext(ob1));
1438: break;
1439: default:
1440: errorStackmachine("Usage:supercontext");
1441: break;
1442: }
1443: break;
1444:
1445: case Ssendmsg:
1446: /* ob2 { .........} sendmsg */
1447: /* cf. debug/kobj.sm1 */
1448: ob1 = Kpop();
1449: ob2 = Kpop();
1450: switch(ob1.tag) {
1451: case SexecutableArray: break;
1452: default: errorStackmachine("Usage:sendmsg");
1453: }
1454: ccflag = 0;
1455: if (ob2.tag == Sarray ) {
1456: if (getoaSize(ob2) >= 1) {
1.4 takayama 1457: ob3 = getoa(ob2,0);
1458: if (ectag(ob3) == CLASSNAME_CONTEXT) {
1459: contextControl(CCPUSH); ccflag = 1; /* push the current context. */
1460: CurrentContextp = (struct context *)ecbody(ob3);
1461: }
1.1 maekawa 1462: }
1463: }
1464: if (!ccflag) {
1465: contextControl(CCPUSH); ccflag = 1;
1466: CurrentContextp = PrimitiveContextp;
1467: }
1468: /* normal exec. */
1469: Kpush(ob2);
1.15 ! takayama 1470: status = executeExecutableArray(ob1,(char *)NULL,0);
1.13 takayama 1471:
1.1 maekawa 1472: if (ccflag) {
1473: contextControl(CCPOP); ccflag = 0; /* recover the Current context. */
1474: }
1.14 takayama 1475:
1.1 maekawa 1476: break;
1477: case Ssendmsg2:
1478: /* ob2 ob4 { .........} sendmsg2 */
1479: /* Context is determined by ob2 or ob1 */
1480: ob1 = Kpop();
1481: ob4 = Kpop();
1482: ob2 = Kpop();
1483: switch(ob1.tag) {
1484: case SexecutableArray: break;
1485: default: errorStackmachine("Usage:sendmsg2");
1486: }
1487: ccflag = 0;
1488: if (ob2.tag == Sarray ) {
1489: if (getoaSize(ob2) >= 1) {
1.4 takayama 1490: ob3 = getoa(ob2,0);
1491: if (ectag(ob3) == CLASSNAME_CONTEXT) {
1492: contextControl(CCPUSH); ccflag = 1; /* push the current context. */
1493: CurrentContextp = (struct context *)ecbody(ob3);
1494: }
1.1 maekawa 1495: }
1496: }
1497: if (!ccflag && ob4.tag == Sarray) {
1498: if (getoaSize(ob4) >= 1) {
1.4 takayama 1499: ob3 = getoa(ob4,0);
1500: if (ectag(ob3) == CLASSNAME_CONTEXT) {
1501: contextControl(CCPUSH); ccflag = 1; /* push the current context. */
1502: CurrentContextp = (struct context *)ecbody(ob3);
1503: }
1.1 maekawa 1504: }
1505: }
1506: if (!ccflag) {
1507: contextControl(CCPUSH); ccflag = 1;
1508: CurrentContextp = PrimitiveContextp;
1509: }
1510: /* normal exec. */
1511: Kpush(ob2); Kpush(ob4);
1.14 takayama 1512:
1513: /* We cannot use executeExecutableArray(ob1,(char *)NULL) because of
1514: the quote mode. Think about it later. */
1.1 maekawa 1515: tokenArray = ob1.lc.tokenArray;
1516: size = ob1.rc.ival;
1517: for (i=0; i<size; i++) {
1518: token = tokenArray[i];
1.10 takayama 1519: InSendmsg2 = 1;
1.1 maekawa 1520: status = executeToken(token);
1.10 takayama 1521: InSendmsg2 = 0;
1.13 takayama 1522:
1523: if (status & STATUS_INFIX) {
1524: if (status & DO_QUOTE) errorStackmachine("infix op with DO_QUOTE\n");
1525: if (i == size-1) errorStackmachine("infix operator at the end(sendmsg2).\n");
1526: infixOn = 1; infixToken = tokenArray[i];
1527: infixToken.tflag |= NO_DELAY; continue;
1528: }else if (infixOn) {
1529: infixOn = 0; status = executeToken(infixToken);
1530: if (status & STATUS_BREAK) break;
1531: }
1532:
1533: if (QuoteMode && (status & DO_QUOTE)) {
1.8 takayama 1534: /* generate tree object, for kan/k0 */
1535: struct object qob;
1536: struct object qattr;
1537: struct object qattr2;
1538: if (i==0) { Kpop(); Kpop();}
1539: qob = newObjectArray(3);
1540: qattr = newObjectArray(1);
1541: qattr2 = newObjectArray(2);
1542: /* Set the node name of the tree. */
1543: if (token.kind == ID) {
1544: putoa(qob,0,KpoString(token.token));
1545: }else{
1546: putoa(qob,0,KpoString("unknown"));
1547: }
1548: /* Set the attibute list; class=className */
1549: if (ob2.tag == Sdollar) {
1.11 takayama 1550: putoa(qattr2,0,KpoString("cd"));
1.8 takayama 1551: putoa(qattr2,1,ob2);
1552: }else{
1.11 takayama 1553: putoa(qattr2,0,KpoString("class"));
1.8 takayama 1554: putoa(qattr2,1,KpoString(CurrentContextp->contextName));
1555: }
1556: putoa(qattr,0,qattr2);
1557: putoa(qob,1,qattr);
1558: putoa(qob,2,ob4); /* Argument */
1559: qob = KpoTree(qob);
1560: Kpush(qob);
1.13 takayama 1561: } else if (status & STATUS_BREAK) break;
1562:
1.1 maekawa 1563: }
1564: if (ccflag) {
1565: contextControl(CCPOP); ccflag = 0;
1566: /* recover the Current context. */
1567: /* Note that it is not recovered in case of error. */
1568: }
1569:
1570: break;
1571: case Sprimmsg:
1572: /* { .........} primmsg */
1573: /* Context is PrimitiveContext. */
1574: ob1 = Kpop();
1575: switch(ob1.tag) {
1576: case SexecutableArray: break;
1577: default: errorStackmachine("Usage:primmsg");
1578: }
1579: contextControl(CCPUSH); ccflag = 1;
1580: CurrentContextp = PrimitiveContextp;
1581: /* normal exec. */
1.15 ! takayama 1582: status = executeExecutableArray(ob1,(char *)NULL,0);
1.1 maekawa 1583: contextControl(CCPOP); /* recover the Current context. */
1584: break;
1585:
1586: case Ssupmsg2:
1587: /* ob2 ob4 { .........} supmsg2 */
1588: /* Context is super class of ob2 */
1589: ob1 = Kpop();
1590: ob4 = Kpop();
1591: ob2 = Kpop();
1592: switch(ob1.tag) {
1593: case SexecutableArray: break;
1594: default: errorStackmachine("Usage:supmsg2");
1595: }
1596: ccflag = 0;
1597: if (ob2.tag == Sarray ) {
1598: if (getoaSize(ob2) >= 1) {
1.4 takayama 1599: ob3 = getoa(ob2,0);
1600: if (ectag(ob3) == CLASSNAME_CONTEXT) {
1601: if (((struct context *)ecbody(ob3))->super == NULL) {
1602: errorStackmachine("supmsg2: SuperClass is NIL.");
1603: }
1604: contextControl(CCPUSH); ccflag = 1; /* push the current context. */
1605: CurrentContextp = ((struct context *)ecbody(ob3))->super;
1606: }
1.1 maekawa 1607: }
1608: }
1609: if (!ccflag && (ob4.tag == Sarray) ) {
1610: if (getoaSize(ob4) >= 1) {
1.4 takayama 1611: ob3 = getoa(ob4,0);
1612: if (ectag(ob3) == CLASSNAME_CONTEXT) {
1613: if (((struct context *)ecbody(ob3))->super == NULL) {
1614: errorStackmachine("supmsg2: SuperClass is NIL.");
1615: }
1616: contextControl(CCPUSH); ccflag = 1; /* push the current context. */
1617: CurrentContextp = ((struct context *)ecbody(ob3))->super;
1618: }
1.1 maekawa 1619: }
1620: }
1621: if (!ccflag) {
1622: contextControl(CCPUSH); ccflag = 1;
1623: CurrentContextp = PrimitiveContextp;
1624: }
1625: /* normal exec. */
1626: Kpush(ob2); Kpush(ob4);
1.15 ! takayama 1627: status = executeExecutableArray(ob1,(char *)NULL,0);
1.1 maekawa 1628: if (ccflag) {
1629: contextControl(CCPOP); ccflag = 0; /* recover the Current context. */
1630: }
1631:
1632: break;
1633:
1634: case Serror:
1635: ob1 = peek(0);
1636: if (ob1.tag == Sdollar) {
1637: /* compose error message */
1638: ob = Kpop();
1639: str = (char *) sGC_malloc(sizeof(char)*(strlen("error operator : ")+
1.4 takayama 1640: strlen(KopString(ob1))+ 10));
1.1 maekawa 1641: if (str == NULL) errorStackmachine("No more memory.");
1642: strcpy(str,"error operator : ");
1643: strcat(str,KopString(ob1));
1644: errorStackmachine(str);
1645: }else{
1646: errorStackmachine("error operator.");
1647: }
1648: break;
1649: case Smpzext:
1650: ob1 = Kpop();
1651: Kpush(KmpzExtension(ob1));
1652: break;
1653:
1654: case Scclass:
1655: ob3 = Kpop();
1656: ob2 = Kpop();
1657: ob1 = Kpop();
1658: /* [class-tag super-obj] size [class-tag] cclass */
1659: Kpush(KcreateClassIncetance(ob1,ob2,ob3));
1660: break;
1661:
1662: case Stest:
1663: /* test is used for a test of a new function. */
1664: ob2 = Kpop();
1665: ob1 = Kpop();
1666: Kpush(hilberto(ob1,ob2));
1667: /*
1.4 takayama 1668: {
1669: ob1 = Kpop();
1670: Kpush(test(ob1));
1.1 maekawa 1671:
1.4 takayama 1672: }
1.1 maekawa 1673: */
1.9 takayama 1674: break;
1675:
1676: case Soxshell:
1677: ob1 = Kpop();
1678: Kpush(KoxShell(ob1));
1.1 maekawa 1679: break;
1.5 takayama 1680:
1681: case Stlimit:
1682: /* { } time tlimit */
1683: ob2 = Kpop();
1684: ob1 = Kpop();
1685: switch(ob2.tag) {
1686: case Sinteger: break;
1687: default: errorStackmachine("Usage:tlimit"); break;
1688: }
1689: switch(ob1.tag) {
1690: case SexecutableArray: break;
1691: default:
1692: errorStackmachine("Usage:tlimit");
1693: break;
1694: }
1695: n = ob2.lc.ival;
1696: if (n > 0) {
1697: signal(SIGALRM,ctrlC); alarm((unsigned int) n);
1.15 ! takayama 1698: status = executeExecutableArray(ob1,(char *)NULL,0);
1.5 takayama 1699: cancelAlarm();
1700: }else{
1701: before_real = time(&before_real);
1702: times(&before);
1.15 ! takayama 1703: status = executeExecutableArray(ob1,(char *)NULL,0);
1.5 takayama 1704: times(&after);
1705: after_real = time(&after_real);
1706: ob1 = newObjectArray(3);
1707: putoa(ob1,0,KpoInteger((int) after.tms_utime - before.tms_utime));
1708: putoa(ob1,1,KpoInteger((int) after.tms_stime - before.tms_stime));
1709: putoa(ob1,2,KpoInteger((int) (after_real-before_real)));
1710: Kpush(ob1);
1711: }
1712: break;
1.1 maekawa 1713:
1714:
1715: default:
1716: errorStackmachine("Unknown Soperator type. \n");
1717: }
1718: return(0); /* normal exit */
1719: }
1720:
1721:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>