allow to call a function defined later in the source
[bosc.git] / src / parser.y
blob3942db242b2c269c4a1feae8ed2752f3414c66cd
1 %{
2 #include <cstdio>
3 #include <map>
4 #include <list>
6 #include "logging.h"
7 #include "ast.h"
9 using namespace std;
10 extern "C"
12 extern char *curfile;
13 extern int lineno;
14 extern double linear_const, angular_const;
16 int yyparse(void);
17 int yylex(void);
18 int yywrap()
20 return 1;
22 void yyerror(const char* str)
24 fprintf(stderr, "%s:%d: %s\n", curfile, lineno, str);
28 RootBlock *root = new RootBlock();
33 %token SET_SIGNAL_MASK RAISE_SIGNAL DO_TURN DO_MOVE DO_SPIN
34 %token ACCELERATE SPEED ALONG AROUND TO SPEED_NOW EXPLODE_TYPE EXPLODE
35 %token DECL_STATIC_VAR DECL_VAR DECL_PIECE EMIT_SFX EMIT_FROM
36 %token START_SCRIPT CALL_SCRIPT RANDOM_NUMBER
37 %token SHADE DONT_SHADE CACHE DONT_CACHE SHOW HIDE
38 %token COB_GET COB_SET COB_SLEEP
39 %token WAIT_FOR_MOVE WAIT_FOR_TURN STOP_SPIN
40 %token ATTACH_UNIT DROP_UNIT
41 %token LINENO PRAGMA
42 %token BOOL_AND "&&" BOOL_OR "||"
43 %token PLAY_SOUND CONTINUE BREAK RETURN GOTO
45 %token CMP_EQ "==" CMP_GT CMP_LT CMP_GTE ">=" CMP_LTE "<=" CMP_NEQ "!="
46 %token INCREMENT "++" DECREMENT "--" FOR WHILE IF ELSE DO
47 %token SHIFT_LEFT "<<" SHIFT_RIGHT ">>"
49 %token ANGULAR_EXPR_OPEN "<("
50 %token ANGULAR_EXPR_CLOSE ")>"
52 %union {
53 ASTNode *ast;
54 double number;
55 char *string;
58 %token <string> IDENTIFIER
59 %token <number> NUMBER
60 %token <number> AXIS
62 %type <ast> expression primary_expression postfix_expression get_expression
63 %type <ast> rand_expression unary_expression additive_expression
64 %type <ast> multiplicative_expression shift_expression
65 %type <ast> relational_expression equality_expression
66 %type <ast> exclusive_or_expression inclusive_or_expression
67 %type <ast> and_expression logical_and_expression
68 %type <ast> logical_or_expression assignment_expression
69 %type <ast> argument_expression_list conditional_expression
70 //%type <ast> constant_expression
72 %type <ast> statement expression_statement jump_statement
73 %type <ast> selection_statement iteration_statement
74 %type <ast> set_statement labeled_statement
75 %type <ast> compound_statement move_statement spin_statement
76 %type <ast> wait_statement sleep_statement emit_sfx_statement
77 %type <ast> script_statement misc_statement attach_statement
78 %type <ast> visibility_statement explode_statement signal_statement
79 %type <ast> declaration_list declaration
80 %type <ast> statement_list
82 %type <ast> type_specifier init_declarator_list init_declarator declarator
83 %type <ast> initializer identifier_list pragma function_definition
84 %type <ast> translation_unit external_declaration
87 %start translation_unit
88 %error-verbose
89 %defines
90 %debug
94 primary_expression
95 : IDENTIFIER { $$ = new Ident($1); }
96 | NUMBER { $$ = new Number($1); }
97 | AXIS { $$ = new Axis($1); }
98 // | STRING_LITERAL
99 | '(' expression ')' { $$ = $2; }
100 | '[' expression ']' { $$ = new Multiply(new Number(linear_const), $2); }
101 //| '<' expression '>' { $$ = new Multiply(new Number(angular_const), $2); }
102 | "<(" expression ")>" { $$ = new Multiply(new Number(angular_const), $2); }
105 postfix_expression
106 : primary_expression
107 | postfix_expression '(' ')' { $$ = new CallExpr($1, 0); }
108 | postfix_expression '(' argument_expression_list ')' { $$ = new CallExpr($1, $3); }
109 | postfix_expression INCREMENT { $$ = new Increment($1); }
110 | postfix_expression DECREMENT { $$ = new Decrement($1); }
114 argument_expression_list
115 : assignment_expression
116 | argument_expression_list ',' assignment_expression { $$ = new Comma($1, $3) }
119 unary_expression
120 : postfix_expression
121 | INCREMENT unary_expression { $$ = new Increment($2); }
122 | DECREMENT unary_expression { $$ = new Decrement($2); }
123 | '+' unary_expression { $$ = $2; }
124 | '-' unary_expression { $$ = new Negation($2); }
125 | '!' unary_expression { $$ = new LogicalNot($2); }
126 | '~' unary_expression { $$ = new BitwiseNot($2); }
127 | get_expression
128 | rand_expression
131 get_expression
132 : COB_GET primary_expression { $$ = new GetOp($2); }
133 | COB_GET primary_expression '(' ')' { $$ = new GetOp($2); }
134 | COB_GET primary_expression '(' assignment_expression ')'
135 { $$ = new GetOp($2, $4); }
136 | COB_GET primary_expression '(' assignment_expression ','
137 assignment_expression ')' { $$ = new GetOp($2, $4, $6); }
138 | COB_GET primary_expression '(' assignment_expression ','
139 assignment_expression ',' assignment_expression ')'
140 { $$ = new GetOp($2, $4, $6, $8); }
141 | COB_GET primary_expression '(' assignment_expression ','
142 assignment_expression ',' assignment_expression ','
143 assignment_expression ')' { $$ = new GetOp($2, $4, $6, $8, $10); }
146 rand_expression
147 : RANDOM_NUMBER '(' assignment_expression ',' assignment_expression ')'
148 { $$ = new TAOperation("rand", $3, $5); }
151 multiplicative_expression
152 : unary_expression
153 | multiplicative_expression '*' unary_expression { $$ = new Multiply($1, $3); }
154 | multiplicative_expression '/' unary_expression { $$ = new Divide($1, $3); }
155 | multiplicative_expression '%' unary_expression { $$ = new Modulo($1, $3); }
158 additive_expression
159 : multiplicative_expression
160 | additive_expression '+' multiplicative_expression { $$ = new Add($1, $3); }
161 | additive_expression '-' multiplicative_expression { $$ = new Subtract($1, $3); }
164 shift_expression
165 : additive_expression
166 | shift_expression SHIFT_LEFT additive_expression { $$ = new ShiftLeft($1, $3); }
167 | shift_expression SHIFT_RIGHT additive_expression { $$ = new ShiftRight($1, $3); }
170 relational_expression
171 : shift_expression
172 | relational_expression '<' shift_expression { $$ = new LessThan($1, $3); }
173 | relational_expression '>' shift_expression { $$ = new GreaterThan($1, $3); }
174 | relational_expression CMP_GTE shift_expression { $$ = new GreaterEqual($1, $3); }
175 | relational_expression CMP_LTE shift_expression { $$ = new LessEqual($1, $3); }
178 equality_expression
179 : relational_expression
180 | equality_expression CMP_EQ relational_expression { $$ = new Equal($1, $3); }
181 | equality_expression CMP_NEQ relational_expression { $$ = new NotEqual($1, $3); }
184 and_expression
185 : equality_expression
186 | and_expression '&' equality_expression { $$ = new BitwiseAnd($1, $3); }
189 exclusive_or_expression
190 : and_expression
191 | exclusive_or_expression '^' and_expression { $$ = new BitwiseXor($1, $3); }
194 inclusive_or_expression
195 : exclusive_or_expression
196 | inclusive_or_expression '|' exclusive_or_expression { $$ = new BitwiseOr($1, $3); }
199 logical_and_expression
200 : inclusive_or_expression
201 | logical_and_expression BOOL_AND inclusive_or_expression { $$ = new LogicalOr($1, $3); }
204 logical_or_expression
205 : logical_and_expression
206 | logical_or_expression BOOL_OR logical_and_expression { $$ = new LogicalAnd($1, $3); }
210 conditional_expression
211 : logical_or_expression
212 | logical_or_expression '?' expression ':' conditional_expression
213 { $$ = new IfThenElse($1, $3, $5); }
216 assignment_expression
217 : conditional_expression
218 // too expressive?
219 // | unary_expression '=' assignment_expression
220 | IDENTIFIER '=' assignment_expression
221 { $$ = new Assign(new Ident($1), $3); }
225 assignment_operator
226 : '='
227 | MUL_ASSIGN
228 | DIV_ASSIGN
229 | MOD_ASSIGN
230 | ADD_ASSIGN
231 | SUB_ASSIGN
232 | LEFT_ASSIGN
233 | RIGHT_ASSIGN
234 | AND_ASSIGN
235 | XOR_ASSIGN
236 | OR_ASSIGN
240 expression
241 : assignment_expression
242 | expression ',' assignment_expression { $$ = new Comma($1, $3); }
246 constant_expression
247 : conditional_expression
251 declaration
252 : type_specifier ';' { $$ = $1; }
253 | type_specifier init_declarator_list ';' { $$ = new Declaration($1, $2); }
257 init_declarator_list
258 : init_declarator
259 | init_declarator_list ',' init_declarator { $$ = new Comma($1, $3); }
262 init_declarator
263 : declarator
264 | declarator '=' initializer { $$ = new Assign($1, $3); }
267 type_specifier
268 : DECL_STATIC_VAR { $$ = new Typename("static-var"); }
269 | DECL_VAR { $$ = new Typename("var"); }
270 | DECL_PIECE { $$ = new Typename("piece"); }
273 declarator
274 : IDENTIFIER { $$ = new Ident($1) }
275 | '(' declarator ')' { $$ = $2 }
276 | IDENTIFIER '(' identifier_list ')' { $$ = new FunctionProto($1, $3) }
277 | IDENTIFIER '(' ')' { $$ = new FunctionProto($1, 0) }
280 identifier_list
281 : IDENTIFIER { $$ = new Ident($1) }
282 | identifier_list ',' IDENTIFIER { $$ = new Comma($1, new Ident($3)) }
285 initializer
286 : assignment_expression
289 statement
290 : labeled_statement
291 | compound_statement
292 | expression_statement
293 | selection_statement
294 | iteration_statement
295 | declaration_list
296 | jump_statement
297 | set_statement
298 | move_statement
299 | spin_statement
300 | wait_statement
301 | sleep_statement
302 | emit_sfx_statement
303 | script_statement
304 | misc_statement // cache, shade
305 | attach_statement
306 | visibility_statement
307 | explode_statement
308 | signal_statement
310 | play_sound_statement
315 ///////////////////////////////////////////////////////////////////////
316 // spring ops
317 set_statement
318 : COB_SET expression TO expression { $$ = new SetOp($2, $4); }
321 move_statement
322 : DO_MOVE expression TO primary_expression expression SPEED_NOW
323 { $$ = new TAOperation("move-now", $2, $4, $5); }
324 | DO_MOVE expression TO primary_expression expression SPEED expression
325 { $$ = new TAOperation("move", $2, $4, $5, $7); }
326 | DO_MOVE expression TO primary_expression expression SPEED expression ACCELERATE expression
327 { $$ = new TAOperation("move", $2, $4, $5, $7, $9); }
328 | DO_TURN expression TO primary_expression expression SPEED_NOW
329 { $$ = new TAOperation("turn-now", $2, $4, $5); }
330 | DO_TURN expression TO primary_expression expression SPEED expression
331 { $$ = new TAOperation("turn", $2, $4, $5, $7); }
332 | DO_TURN expression TO primary_expression expression SPEED expression ACCELERATE expression
333 { $$ = new TAOperation("turn", $2, $4, $5, $7, $9); }
336 spin_statement
337 : DO_SPIN expression AROUND expression SPEED expression
338 { $$ = new TAOperation("spin", $2, $4, $6); }
339 | DO_SPIN expression AROUND expression SPEED expression ACCELERATE expression
340 { $$ = new TAOperation("spin", $2, $4, $6, $8); }
341 | STOP_SPIN expression
342 { $$ = new TAOperation("stop-spin", $2); }
343 | STOP_SPIN expression AROUND expression
344 { $$ = new TAOperation("stop-spin", $2, $4); }
347 wait_statement
348 : WAIT_FOR_MOVE expression ALONG expression
349 { $$ = new TAOperation("wait-for-move", $2, $4); }
350 | WAIT_FOR_TURN expression AROUND expression
351 { $$ = new TAOperation("wait-for-turn", $2, $4); }
354 sleep_statement
355 : COB_SLEEP expression
356 { $$ = new TAOperation("sleep", $2); }
359 emit_sfx_statement
360 : EMIT_SFX expression EMIT_FROM expression
361 { $$ = new TAOperation("emit-sfx", $2, $4); }
364 script_statement
365 : CALL_SCRIPT IDENTIFIER '(' argument_expression_list ')'
366 { $$ = new Call($2, $4); }
367 | CALL_SCRIPT IDENTIFIER '(' ')'
368 { $$ = new Call($2); }
369 | START_SCRIPT IDENTIFIER '(' argument_expression_list ')'
370 { $$ = new StartScript($2, $4); }
371 | START_SCRIPT IDENTIFIER '(' ')'
372 { $$ = new StartScript($2); }
375 // mostly no-ops in spring
376 misc_statement
377 : CACHE expression { $$ = $2 }
378 | DONT_CACHE expression { $$ = $2 }
379 | SHADE expression { $$ = $2 }
380 | DONT_SHADE expression { $$ = $2 }
383 attach_statement
384 : ATTACH_UNIT expression TO expression
385 { $$ = new TAOperation("attach-unit", $2, $4); }
386 | DROP_UNIT expression
387 { $$ = new TAOperation("drop-unit", $2); }
390 visibility_statement
391 : SHOW expression
392 { $$ = new TAOperation("show", $2); }
393 | HIDE expression
394 { $$ = new TAOperation("hide", $2); }
397 signal_statement
398 : RAISE_SIGNAL expression
399 { $$ = new TAOperation("signal", $2); }
400 | SET_SIGNAL_MASK expression
401 { $$ = new TAOperation("set-signal-mask", $2); }
404 explode_statement
405 : EXPLODE expression EXPLODE_TYPE expression
406 { $$ = new TAOperation("explode", $2, $4); }
409 ///////////////////////////////////////////////////////////////////////
411 labeled_statement
412 : IDENTIFIER ':' statement { $$ = new Label($1, $3); }
414 | CASE constant_expression ':' statement
415 | DEFAULT ':' statement
419 compound_statement
420 : '{' '}' { $$ = new ASTNode() }
421 | '{' statement_list '}' { $$ = $2 }
424 declaration_list
425 : declaration
426 | declaration_list declaration { $$ = new Semicolon($1, $2) }
429 statement_list
430 : statement
431 | statement_list statement { $$ = new Semicolon($1, $2) }
434 expression_statement
435 : ';' { $$ = new ASTNode() }
436 | expression ';' { $$ = $1; }
439 selection_statement
440 : IF '(' expression ')' statement { $$ = new IfThenElse($3, $5); }
441 | IF '(' expression ')' statement ELSE statement
442 { $$ = new IfThenElse($3, $5, $7); }
443 /*| SWITCH '(' expression ')' statement*/
446 // Loop(body, init, precond, postcond, before, after)
447 iteration_statement
448 : WHILE '(' expression ')' statement
449 { $$ = new Loop($5, 0, $3, 0, 0, 0); }
450 | DO statement WHILE '(' expression ')' ';'
451 { $$ = new Loop($2, 0, 0, $5, 0, 0); }
452 | FOR '(' expression_statement expression_statement ')' statement
453 { $$ = new Loop($6, $3, $4, 0, 0, 0); }
454 | FOR '(' expression_statement expression_statement expression ')' statement
455 { $$ = new Loop($7, $3, $4, 0, 0, $5); }
456 // scriptor compatibility
457 | FOR '(' expression_statement expression_statement expression_statement ')' statement
458 { $$ = new Loop($7, $3, $4, 0, 0, $5); }
461 jump_statement
462 : GOTO IDENTIFIER ';' { $$ = new Jump($2); }
463 | CONTINUE ';' { $$ = new Continue(); }
464 | BREAK ';' { $$ = new Break(); }
465 | RETURN ';' { $$ = new Return(0); }
466 | RETURN expression ';' { $$ = new Return($2); }
469 translation_unit
470 : external_declaration { $$ = $1; $$->parent = root; root->list.push_back($1); }
471 | translation_unit external_declaration { $$ = $2; $$->parent = root; root->list.push_back($2); }
472 | /* empty */ { }
475 external_declaration
476 : function_definition
477 | declaration
478 | pragma
481 function_definition
482 : declarator compound_statement { $$ = new Function($1, $2) }
485 pragma
486 : PRAGMA IDENTIFIER NUMBER { $$ = new Pragma($2, $3); }
487 | PRAGMA IDENTIFIER IDENTIFIER { $$ = new Pragma($2, $3); }
488 | PRAGMA IDENTIFIER { $$ = new Pragma($2, 0); }