Annotation of OpenXM/src/k097/simple.y, Revision 1.1.1.1
1.1 maekawa 1:
2: /* simple.y 1996, 1/1 --- 1/6 */
3: /* simple.y.ccc, 1996, 4/1 --- */
4: %{
5: #include <stdio.h>
6: #include "d.h"
7: %}
8:
9:
10: %token ID QUOTE SINGLEQUOTE NUMBER
11:
12: /* You have to change isReserved() [d.c], too */
13: %token CLASS SUPER OPERATOR FINAL EXTENDS INCETANCEVARIABLE
14: %token THIS NEW SIZEOFTHISCLASS STARTOFTHISCLASS
15: %token MODULE PRINT LOCAL DEF SM1 LOAD TEST SPECIAL
16: %token AUTO BREAK CASE CHAR CONST CONTINUE DEFAULT DO DOUBLE ELSE ENUM
17: %token EXTERN FLOAT FOR GOTO IF INT LONG REGISTER
18: %token RETURN SHORT SIGNED SIZEOF STATIC STRUCT SWITCH TYPEDEF UNION
19: %token UNSIGNED VOLATILE VOID WHILE PSFOR PROMPT
20:
21: %right '=' PUT MULTPUT NEGATEPUT RESIDUEPUT
22:
23: %left OR
24: %left AND
25: %left '|'
26: %left '&'
27: %left EQUAL NOTEQUAL
28: %left '<' '>' LESSEQUAL GREATEREQUAL
29: %left LEFTSHIFT RIGHTSHIFT
30: %left '+' '-'
31: %left '*' '/' '%'
32:
33: %left UNARYMINUS '!' INCREMENT DECREMENT '~'
34: %right '^'
35:
36: %left '.'
37: %left MEMBER
38: %%
39:
40: /* Mathematica-like parser */
41: program
42: : globalstatements
43: ;
44:
45: globalstatements
46: :
47: sentence globalstatements
48: | sentence
49: ;
50:
51: sentence /* { ... } {...} : ; does not need. */
52: :
53: for
54: | PSfor
55: | while
56: | if
57: | functionDefinition {sendKan(0); }
58: | exp ';' {sendKan(0); }
59: | exp ':' {pkkan(" [ ] {showln} sendmsg2 \n"); sendKan(0); }
60: | ';' {sendKan(0); }
61: | class_definition {sendKan(0); }
62: | error ';'
63: | PROMPT ';' {sendKan(10); }
64: ;
65:
66: statements
67: :
68: localsentence statements
69: | localsentence
70: ;
71:
72: localsentence
73: :
74: for
75: | PSfor
76: | while
77: | if
78: | exp ';'
79: | return ';'
80: | break ';'
81: | ';'
82: ;
83:
84: argList
85: : exp ',' argList
86: | exp /* It does not cause reduce-reduce conflict
87: between "program"! */
88: ;
89:
90: return :
91: RETURN exp { pkkan(" /FunctionValue set {/ExitPoint goto} exec %%return\n");}
92: | RETURN {pkkan(" {/ExitPoint goto} exec %%return void\n");}
93: ;
94:
95: break : BREAK { pkkan(" exit "); }
96:
97: list_prefix
98: :
99: '[' { pkkan("[ "); }
100: ;
101: list
102: : list_prefix ']' { pkkan(" ] "); }
103: | list_prefix argList ']' { pkkan(" ] "); }
104: ;
105:
106: curryBrace
107: : '{' '}'
108: | '{' statements '}'
109: ;
110:
111: if_prefix
112: : IF '(' exp ')' { pkkan(" %% if-condition\n { %%ifbody\n"); }
113: ;
114: if_body
115: : localsentence { pkkan(" }%%end if if body\n { %%if- else part\n"); }
116: | curryBrace { pkkan(" }%%end if if body\n { %%if- else part\n"); }
117: ;
118: if
119: : if_prefix if_body { pkkan(" } ifelse\n"); }
120: /* The line cause 1 shift/reduce conflict. Look up a book. */
121: | if_prefix if_body ELSE localsentence { pkkan(" } ifelse\n"); }
122: | if_prefix if_body ELSE curryBrace { pkkan(" } ifelse\n"); }
123: ;
124:
125:
126: for_prefix0
127: : FOR '(' exp ';' { pkkan("%%for init.\n%%for\n{ "); }
128: | FOR '(' ';' { pkkan("%%nothing for init.\n%%for\n{ "); }
129: ;
130: for_exit
131: : exp ';' { pkkan(" { } {exit} ifelse\n[ {%%increment\n"); }
132: | ';' { pkkan("%%no exit rule.\n[ {%%increment\n"); }
133: ;
134: for_inc
135: : exp { pkkan("} %%end of increment{A}\n"); }
136: ;
137: /* [{ A } { B } roll 2 1] {exec} map ---> B A */
138: for_prefix
139: : for_prefix0 for_exit for_inc ')'
140: { pkkan("{%%start of B part{B}\n"); }
141: | for_prefix0 for_exit ')'
142: { pkkan(" } %% dummy A\n{%%start of B part{B}\n"); }
143: ;
144: for
145: : for_prefix curryBrace
146: { pkkan("} %% end of B part. {B}\n");
147: pkkan(" 2 1 roll] {exec} map pop\n} loop %%end of for\n"); }
148:
149: PSfor_prefix
150: : PSFOR '(' ID '=' exp ';'
151: { pkkan("%%PSfor initvalue.\n (integer) data_conversion \n");
152: ips($3);
153: }
154: ID '<' exp ';' ID INCREMENT ')'
155: { ips($7); ips($10);
156: /* They must be equal id, but it is not checked. */
157: pkkan(" (1).. sub (integer) data_conversion 1 2 -1 roll \n");
158: pkkan("{ %% for body\n (universalNumber) data_conversion ");
159: pkkan("/"); printObjectSymbol($3); pkkan(" set \n");
160: }
161: ;
162: PSfor
163: : PSfor_prefix curryBrace
164: { pkkan(" } for \n"); }
165: ;
166:
167: while_prefix0
168: : WHILE '(' { pkkan("\n%%while\n{ "); }
169: ;
170:
171: while_prefix
172: : while_prefix0 exp ')' { pkkan(" { } {exit} ifelse\n "); }
173: | while_prefix0 ')' { pkkan("%%no exit condition.\n "); }
174: ;
175:
176: while
177: : while_prefix curryBrace { pkkan("} loop\n"); }
178: ;
179:
180:
181: print
182: : PRINT '(' exp ')' { pkkan(" print\n");}
183: ;
184:
185: sm1 :
186: SM1 '(' sm1ArgList ')'
187: ;
188:
189: load :
190: LOAD '(' QUOTE ')' { loadFile($3); }
191: | LOAD '(' ID ')' { loadFile($3); }
192: | LOAD ID { loadFile($2); }
193: | LOAD QUOTE { loadFile($2); }
194: | LOAD '[' QUOTE ']' { loadFileWithCpp($3); }
195:
196: sm1ArgList :
197: | sm1ArgList ',' QUOTE { pkkan(" "); printObjectSymbol($3); pkkan(" "); }
198: | QUOTE { pkkan(" "); printObjectSymbol($1); pkkan(" "); }
199: | sm1ArgList ',' ID { pkkan(" "); printObjectSymbol($3); pkkan(" "); }
200: | ID { pkkan(" "); printObjectSymbol($1); pkkan(" "); }
201: ;
202:
203: primitive
204: : ID
205: { int tmp0;
206: if ((tmp0 = K00getIncetanceVariable(objectSymbolToString($1))) != -1) {
207: pkkan(" this "); pkkanInteger(tmp0); pkkan(" get ");
208: } else {
209: printObjectSymbol($1); pkkan(" ");
210: }
211: }
212: | QUOTE { pkkan("("); printObjectSymbol($1); pkkan(") "); }
213: | SINGLEQUOTE
214: | NUMBER { pkkan("("); printObjectSymbol($1); pkkan(").. ");}
215: | THIS { pkkan(" this "); }
216: | '(' exp ')'
217: | functionCall
218: | list
219: | print
220: | sm1
221: | load
222: | test
223: | special
224: | set
225: | arrayValue
226: ;
227:
228: functionCall_prefix
229: :
230: ID '(' { pkkan("this [ %% function args \n"); $$ = $1 }
231: ;
232:
233: /* function call. cf. Schreiner 19p */
234: /* If you want to have a strong binding s.t.
235: ID[1,2], then you need to define a new non-terminal
236: such as primitive. ????*/
237: functionCall
238: :
239: functionCall_prefix argList ')'
240: {pkkan("] {");printObjectSymbol($1);pkkan("} sendmsg2 \n");}
241: | functionCall_prefix ')'
242: {pkkan("] {");printObjectSymbol($1);pkkan("} sendmsg2 \n");}
243:
244: ;
245: idList
246: : idList ',' ID { pkkan("/");printObjectSymbol($3); pkkan(" "); ips($3);}
247: | ID { pkkan("/");printObjectSymbol($1); pkkan(" "); ips($1);}
248: ;
249:
250: functionHead
251: : DEF ID
252: { pkkan("/"); printObjectSymbol($2); pkkan(" {\n"); ips($2);
253: pkdebug("In function : ", objectSymbolToString($2),
254: " of class ",K00getCurrentContextName());
255: pkkan(" /Arglist set /Argthis set /FunctionValue [ ] def\n [/this ");
256: $$ = $2;}
257: ;
258:
259: voidfunctionHead
260: : DEF VOID ID
261: { pkkan("/"); printObjectSymbol($3); pkkan(" {\n"); ips($3);
262: pkdebug("In function : ", objectSymbolToString($3),
263: " of class ",K00getCurrentContextName());
264: pkkan(" /Arglist set /Argthis set /FunctionValue [ ] def\n [/this ");
265: $$ = $2;}
266: ;
267:
268: functionArg
269: : '(' idList ')' '{'
270: {pkkan(" ] /ArgNames set ArgNames pushVariables [ %%function body\n");
271: pkkan(" [Argthis] Arglist join ArgNames mapset\n");}
272: | '(' ')' '{'
273: {pkkan(" ] /ArgNames set ArgNames pushVariables [ %%function body\n");
274: pkkan(" [Argthis] ArgNames mapset\n"); }
275: ;
276:
277: functionBody
278: :
279: declaration extern_declaration statements '}'
280: { pkkan("/ExitPoint ]pop popVariables %%pop the local variables\n"); }
281: | extern_declaration statements '}'
282: ;
283:
284:
285: functionDefinition
286: : functionHead functionArg functionBody
287: {pkkan("/ExitPoint ]pop popVariables %%pop argValues\n");
288: pkdebug2();
289: pkkan("FunctionValue } def\n%%end of function\n\n"); }
290: | operatorfunctionHead functionArg functionBody
291: {pkkan("/ExitPoint ]pop popVariables %%pop argValues\n");
292: pkdebug2();
293: pkkan("FunctionValue } def\n%%end of function\n\n"); }
294: | voidfunctionHead functionArg functionBody
295: {pkkan("/ExitPoint ]pop popVariables %%pop argValues\n");
296: pkdebug2();
297: pkkan("} def\n%%end of function\n\n"); }
298: ;
299:
300: declaration_prefix
301: : LOCAL { pkkan("[ %%start of local variables\n"); }
302: ;
303:
304: declaration
305: : declaration_prefix idList ';'
306: { pkkan("] pushVariables [ %%local variables\n"); }
307: ;
308:
309: extern_idList
310: : extern_idList ',' ID
311: { ;}
312: | ID { ;}
313: ;
314:
315: extern_declaration_prefix
316: : EXTERN { ; }
317: ;
318:
319: extern_declaration
320: : extern_declaration_prefix extern_idList ';'
321: { ; }
322: |
323: ;
324:
325: arrayValue :
326: array { pkkan(" Get\n"); }
327: ;
328: array :
329: array_prefix arrayIndex ']' {pkkan(" ] "); }
330: ;
331: arrayIndex :
332: exp ',' arrayIndex
333: | exp
334: ;
335: array_prefix :
336: ID '['
337: { int tmp0;
338: if ((tmp0 = K00getIncetanceVariable(objectSymbolToString($1))) != -1) {
339: pkkan(" this "); pkkanInteger(tmp0); pkkan(" get [");
340: } else {
341: printObjectSymbol($1); pkkan(" [");
342: }
343: }
344: ;
345:
346:
347: id_set
348: : ID { $$ = $1;}
349: ;
350: set
351: : id_set '=' exp
352: { int tmp0;
353: if ((tmp0 = K00getIncetanceVariable(objectSymbolToString($1))) != -1) {
354: pkkan(" this "); pkkanInteger(tmp0);
355: pkkan(" 3 -1 roll put\n");
356: }else {
357: pkkan("/"); printObjectSymbol($1); pkkan(" "); ips($1); pkkan(" set\n");
358: }
359: }
360: | array '=' exp { pkkan(" Put\n"); }
361: | THIS '=' exp { pkkan(" /this set \n"); }
362: ;
363:
364: exp
365: : primitive
366: | new
367: | '!' exp { pkkan(" not\n"); }
368: | '~' exp
369: | '-' exp { pkkan(" (0).. 2 1 roll {sub} sendmsg \n"); }
370: | exp '+' exp { pkkan(" {add} sendmsg2 \n"); }
371: | exp '-' exp { pkkan(" {sub} sendmsg2 \n"); }
372: | exp '*' exp { pkkan(" {mul} sendmsg2 \n"); }
373: | exp '/' exp { pkkan(" {div} sendmsg2 \n"); }
374: | exp '%' exp
375: | exp '^' exp { pkkan(" power\n"); }
376: | exp '&' exp
377: | exp '|' exp
378: | exp EQUAL exp { pkkan(" eq\n"); }
379: | exp '<' exp { pkkan(" lt\n"); }
380: | exp '>' exp { pkkan(" gt\n"); }
381: | exp LESSEQUAL exp { pkkan(" lessThanOrEqual\n"); }
382: | exp LEFTSHIFT exp
383: | exp GREATEREQUAL exp { pkkan(" greaterThanOrEqual\n"); }
384: | exp RIGHTSHIFT exp
385: | exp AND exp { pkkan(" and\n"); }
386: | exp OR exp { pkkan(" or\n"); }
387: | exp NOTEQUAL exp { pkkan(" eq not\n"); }
388: | exp PUT exp
389: | id_set INCREMENT { pkkan("/");
390: printObjectSymbol($1); ips($1);
391: pkkan(" "); printObjectSymbol($1);
392: pkkan(" (1).. {add} sendmsg2 "); pkkan("def\n"); }
393: | id_set DECREMENT { pkkan("/");
394: printObjectSymbol($1); ips($1);
395: pkkan(" "); printObjectSymbol($1);
396: pkkan(" (1).. {sub} sendmsg2 "); pkkan("def\n"); }
397: | exp MEMBER exp
398: | exp '.' member_functionCall { pkkan(" sendmsg2 \n"); }
399: | exp '.' ID { /* Not implemented yet. */ }
400: | super '.' member_functionCall { pkkan(" supmsg2 \n"); }
401: | NUMBER '.' NUMBER { pkkan("("); printObjectSymbol($1);
402: pkkan(").. (double) dc ");
403: pkkan("("); printObjectSymbol($3); pkkan(").. ");
404: pkkan("("); printTens($3); pkkan(").. ");
405: pkkan(" div (double) dc add\n"); }
406: | exp RESIDUEPUT exp
407: | exp NEGATEPUT exp
408: | exp MULTPUT exp
409: | SIZEOFTHISCLASS
410: {
411: int tmp0;
412: tmp0 = K00getIncetanceVariable("K00sizeof");
413: pkkan(" ("); pkkanInteger(tmp0); pkkan(").. ");
414: }
415:
416: | STARTOFTHISCLASS
417: {
418: int tmp0;
419: tmp0 = K00getIncetanceVariable("K00start");
420: pkkan(" ("); pkkanInteger(tmp0); pkkan(").. ");
421: }
422: ;
423:
424: test : TEST '(' exp ')'
425: { /* It is not used now. */
426: sendKan(1);
427: Sm1obj = KSpop();
428: if (Sm1obj.tag != Sdollar) {
429: fprintf(stderr," Argument of test must be a string.\n");
430: }
431: testNewFunction((struct Object *)&Sm1obj);
432: }
433: ;
434:
435: special : SPECIAL '(' list ')'
436: {
437: fprintf(stderr," special is used to extend the function. \n");
438: }
439: ;
440:
441:
442: member_functionCall
443: :
444: member_functionCall_prefix argList ')'
445: {pkkan("] {");printObjectSymbol($1);pkkan("} ");}
446: | member_functionCall_prefix ')'
447: {pkkan("] {");printObjectSymbol($1);pkkan("} ");}
448:
449: ;
450: member_functionCall_prefix
451: :
452: ID '(' { pkkan(" [ %% function args \n"); $$ = $1 }
453: ;
454:
455:
456: class_definition
457: :
458: class_definition_prefix incetance_variables globalstatements '}'
459: { pkkan(" PrimitiveContextp setcontext ");
460: /* debug */ K00foo1();
461: K00toPrimitiveClass();
462: }
463: |
464: class_definition_prefix globalstatements '}'
465: { pkkan(" PrimitiveContextp setcontext ");
466: K00putIncetanceVariable(IEXIT," ");
467: /* debug */ K00foo1();
468: K00toPrimitiveClass();
469: }
470: ;
471:
472: class_definition_prefix
473: :
474: CLASS ID EXTENDS ID '{'
475: { ips($2);
476: pkkan("[ $") ; printObjectSymbol($2); pkkan("$ ");
477: printObjectSymbol($4); pkkan(" 0 get newcontext ] /");
478: printObjectSymbol($2); pkkan(" set \n");
479: printObjectSymbol($2); pkkan(" 0 get setcontext \n");
480:
481: if (K00declareClass(objectSymbolToString($2),
482: objectSymbolToString($4)) == -1) {
483: /* error */
484: KCerror("Super class has not been defined or Invalid class name.");
485: }else{
486: K00putIncetanceVariable(IRESET," ");
487: }
488: }
489:
490: incetance_variables
491: : LOCAL incetance_variables_list ';'
492: {
493: K00putIncetanceVariable(IEXIT," ");
494: }
495: ;
496: incetance_variables_list
497: : incetance_variables_list ',' ID
498: {
499: K00putIncetanceVariable(IPUT,objectSymbolToString($3));
500: }
501: | ID
502: {
503: K00putIncetanceVariable(IPUT,objectSymbolToString($1));
504: }
505:
506: operatorfunctionHead
507: : DEF OPERATOR ID
508: { pkkan("/"); printObjectSymbol($3); pkkan(" {\n"); ips($3);
509: pkdebug("In function : ", objectSymbolToString($3),", of class ",
510: K00getCurrentContextName());
511: pkkan(" /Arglist set /Arglist [Arglist] def ");
512: pkkan(" /Argthis set /FunctionValue [ ] def\n [/this ");
513: $$ = $3;}
514: ;
515:
516: super
517: : SUPER { pkkan(" this "); }
518: ;
519:
520: new
521: : NEW '(' exp ')'
522: { int tmp;
523: tmp = K00getIncetanceVariable("K00sizeof")
524: +K00getIncetanceVariable("K00start");
525: pkkanInteger(tmp);
526: pkkan(" ");
527: pkkan(K00getCurrentContextName());
528: pkkan(" cclass \n");
529: }
530: | NEW '(' ')'
531: { int tmp;
532: pkkan(" PrimitiveObject ");
533: tmp = K00getIncetanceVariable("K00sizeof")
534: +K00getIncetanceVariable("K00start");
535: pkkanInteger(tmp);
536: pkkan(" ");
537: pkkan(K00getCurrentContextName());
538: pkkan(" cclass \n");
539: }
540: ;
541:
542:
543:
544:
545:
546:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>