File Coverage

yacc/spvm_yacc.y
Criterion Covered Total %
statement 380 382 99.4
branch 41 42 97.6
condition n/a
subroutine n/a
pod n/a
total 421 424 99.2


line stmt bran cond sub pod time code
1             // Copyright (c) 2023 Yuki Kimoto
2             // MIT License
3              
4             %pure-parser
5             %parse-param { SPVM_COMPILER* compiler }
6             %lex-param { SPVM_COMPILER* compiler }
7              
8             %{
9             #include
10            
11             #include "spvm_compiler.h"
12             #include "spvm_yacc_util.h"
13             #include "spvm_toke.h"
14             #include "spvm_op.h"
15             #include "spvm_dumper.h"
16             #include "spvm_constant.h"
17             #include "spvm_type.h"
18             #include "spvm_block.h"
19             #include "spvm_list.h"
20             #include "spvm_attribute.h"
21             #include "spvm_string.h"
22             %}
23              
24             %token CLASS HAS METHOD OUR ENUM MY USE AS REQUIRE ALIAS ALLOW CURRENT_CLASS MUTABLE
25             %token ATTRIBUTE MAKE_READ_ONLY INTERFACE EVAL_ERROR_ID ARGS_WIDTH VERSION_DECL
26             %token IF UNLESS ELSIF ELSE FOR WHILE LAST NEXT SWITCH CASE DEFAULT BREAK EVAL
27             %token SYMBOL_NAME VAR_NAME CONSTANT EXCEPTION_VAR
28             %token UNDEF VOID BYTE SHORT INT LONG FLOAT DOUBLE STRING OBJECT TRUE FALSE END_OF_FILE
29             %token FATCAMMA RW RO WO INIT NEW OF BASIC_TYPE_ID EXTENDS SUPER
30             %token RETURN WEAKEN DIE WARN PRINT SAY CURRENT_CLASS_NAME UNWEAKEN '[' '{' '('
31              
32             %type grammar
33             %type opt_classes classes class class_block version_decl
34             %type opt_definitions definitions definition
35             %type enumeration enumeration_block opt_enumeration_values enumeration_values enumeration_value
36             %type method anon_method opt_args args arg has use require alias our anon_method_has_list anon_method_has
37             %type opt_attributes attributes
38             %type opt_statements statements statement if_statement else_statement
39             %type for_statement while_statement foreach_statement
40             %type switch_statement case_statement case_statements opt_case_statements default_statement
41             %type block eval_block init_block switch_block if_require_statement
42             %type unary_operator binary_operator comparison_operator isa isa_error is_type is_error is_compile_type
43             %type call_method
44             %type array_access field_access weaken_field unweaken_field isweak_field convert array_length
45             %type assign inc dec allow can
46             %type new array_init die warn opt_extends
47             %type var_decl var interface union_type
48             %type operator opt_operators operators opt_operator logical_operator void_return_operator
49             %type field_name method_name alias_name is_read_only
50             %type type qualified_type basic_type array_type class_type
51             %type array_type_with_length ref_type return_type type_comment opt_type_comment
52              
53             %right ASSIGN SPECIAL_ASSIGN
54             %left LOGICAL_OR
55             %left LOGICAL_AND
56             %left BIT_OR BIT_XOR
57             %left BIT_AND
58             %nonassoc NUMEQ NUMNE STREQ STRNE
59             %nonassoc NUMGT NUMGE NUMLT NUMLE STRGT STRGE STRLT STRLE ISA ISA_ERROR IS_TYPE IS_ERROR IS_COMPILE_TYPE NUMERIC_CMP STRING_CMP CAN
60             %left SHIFT
61             %left '+' '-' '.'
62             %left '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG REMAINDER REMAINDER_UNSIGNED_INT REMAINDER_UNSIGNED_LONG
63             %right LOGICAL_NOT BIT_NOT '@' CREATE_REF DEREF PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK REFCNT TYPE_NAME COMPILE_TYPE_NAME DUMP NEW_STRING_LEN IS_READ_ONLY COPY
64             %nonassoc INC DEC
65             %left ARROW
66              
67             %%
68              
69             grammar
70             : opt_classes
71              
72             opt_classes
73             : /* Empty */
74             {
75 1765           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
76             }
77             | classes
78             {
79 1842 100         if ($1->id == SPVM_OP_C_ID_LIST) {
80 1672           $$ = $1;
81             }
82             else {
83 170           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
84 170           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
85 170           $$ = op_list;
86             }
87             }
88            
89             classes
90             : classes class
91             {
92             SPVM_OP* op_list;
93 32968 100         if ($1->id == SPVM_OP_C_ID_LIST) {
94 31233           op_list = $1;
95             }
96             else {
97 1735           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
98 1735           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
99             }
100 32968           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
101            
102 32968           $$ = op_list;
103             }
104             | class
105              
106             class
107             : CLASS class_type opt_extends class_block END_OF_FILE
108             {
109 20729           $$ = SPVM_OP_build_class(compiler, $1, $2, $4, NULL, $3);
110             }
111             | CLASS class_type opt_extends ':' opt_attributes class_block END_OF_FILE
112             {
113 9583           $$ = SPVM_OP_build_class(compiler, $1, $2, $6, $5, $3);
114             }
115             | CLASS class_type opt_extends ';' END_OF_FILE
116             {
117 4506           $$ = SPVM_OP_build_class(compiler, $1, $2, NULL, NULL, $3);
118             }
119             | CLASS class_type opt_extends ':' opt_attributes ';' END_OF_FILE
120             {
121 55           $$ = SPVM_OP_build_class(compiler, $1, $2, NULL, $5, $3);
122             }
123              
124             opt_extends
125             : /* Empty */
126             {
127 31805           $$ = NULL;
128             }
129             | EXTENDS basic_type
130             {
131 3131           $$ = SPVM_OP_build_extends(compiler, $1, $2);
132             }
133              
134             class_block
135             : '{' opt_definitions '}'
136             {
137 30314           SPVM_OP* op_class_block = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_CLASS_BLOCK, $1->file, $1->line);
138 30314           SPVM_OP_insert_child(compiler, op_class_block, op_class_block->last, $2);
139 30314           $$ = op_class_block;
140             }
141              
142             opt_definitions
143             : /* Empty */
144             {
145 33           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
146             }
147             | definitions
148             {
149 30281 100         if ($1->id == SPVM_OP_C_ID_LIST) {
150 22438           $$ = $1;
151             }
152             else {
153 7843           $$ = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
154 7843           SPVM_OP_insert_child(compiler, $$, $$->last, $1);
155             }
156             }
157              
158             definitions
159             : definitions definition
160             {
161             SPVM_OP* op_list;
162 277347 100         if ($1->id == SPVM_OP_C_ID_LIST) {
163 254907           op_list = $1;
164             }
165             else {
166 22440           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
167 22440           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
168             }
169 277347           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
170            
171 277347           $$ = op_list;
172             }
173             | definition
174              
175             definition
176             : version_decl
177             | use
178             | alias
179             | allow
180             | interface
181             | init_block
182             | enumeration
183             | our
184             | has ';'
185             | method
186              
187             init_block
188             : INIT block
189             {
190 1548           $$ = SPVM_OP_build_init_block(compiler, $1, $2);
191             }
192              
193             version_decl
194             : VERSION_DECL CONSTANT ';'
195             {
196 206           $$ = SPVM_OP_build_version_decl(compiler, $1, $2);
197             }
198              
199             use
200             : USE basic_type ';'
201             {
202 29397           int32_t is_require = 0;
203 29397           SPVM_OP* op_name_alias = NULL;
204 29397           $$ = SPVM_OP_build_use(compiler, $1, $2, op_name_alias, is_require);
205             }
206             | USE basic_type AS alias_name ';'
207             {
208 14           int32_t is_require = 0;
209 14           $$ = SPVM_OP_build_use(compiler, $1, $2, $4, is_require);
210             }
211              
212             require
213             : REQUIRE basic_type
214             {
215 12           SPVM_OP* op_use = SPVM_OP_new_op_use(compiler, compiler->current_file, compiler->current_line);
216 12           int32_t is_require = 1;
217 12           $$ = SPVM_OP_build_use(compiler, op_use, $2, NULL, is_require);
218             }
219              
220             alias
221             : ALIAS basic_type AS alias_name ';'
222             {
223 2           SPVM_OP* op_use = SPVM_OP_new_op_use(compiler, compiler->current_file, compiler->current_line);
224 2           $$ = SPVM_OP_build_alias(compiler, op_use, $2, $4);
225             }
226              
227             allow
228             : ALLOW basic_type ';'
229             {
230 533           $$ = SPVM_OP_build_allow(compiler, $1, $2);
231             }
232              
233             interface
234             : INTERFACE basic_type ';'
235             {
236 1386           $$ = SPVM_OP_build_implement(compiler, $1, $2);
237             }
238              
239             enumeration
240             : opt_attributes ENUM enumeration_block
241             {
242 3249           $$ = SPVM_OP_build_enumeration_definition(compiler, $2, $3, $1);
243             }
244              
245             enumeration_block
246             : '{' opt_enumeration_values '}'
247             {
248 3249           SPVM_OP* op_enum_block = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ENUM_BLOCK, $1->file, $1->line);
249 3249           SPVM_OP_insert_child(compiler, op_enum_block, op_enum_block->last, $2);
250 3249           $$ = op_enum_block;
251             }
252              
253             opt_enumeration_values
254             : /* Empty */
255             {
256 1           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
257             }
258             | enumeration_values
259             {
260 3248 100         if ($1->id == SPVM_OP_C_ID_LIST) {
261 541           $$ = $1;
262             }
263             else {
264 2707           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
265 2707           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
266 2707           $$ = op_list;
267             }
268             }
269            
270             enumeration_values
271             : enumeration_values ',' enumeration_value
272             {
273             SPVM_OP* op_list;
274 557 100         if ($1->id == SPVM_OP_C_ID_LIST) {
275 16           op_list = $1;
276             }
277             else {
278 541           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
279 541           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
280             }
281 557           SPVM_OP_insert_child(compiler, op_list, op_list->last, $3);
282            
283 557           $$ = op_list;
284             }
285             | enumeration_values ','
286             | enumeration_value
287            
288             enumeration_value
289             : method_name
290             {
291 51           $$ = SPVM_OP_build_enumeration_value(compiler, $1, NULL);
292             }
293             | method_name ASSIGN CONSTANT
294             {
295 3754           $$ = SPVM_OP_build_enumeration_value(compiler, $1, $3);
296             }
297              
298             our
299             : OUR VAR_NAME ':' opt_attributes qualified_type opt_type_comment ';'
300             {
301 8179           $$ = SPVM_OP_build_class_var_definition(compiler, $1, $2, $4, $5);
302             }
303              
304             has
305             : HAS field_name ':' opt_attributes qualified_type opt_type_comment
306             {
307 27795           $$ = SPVM_OP_build_field_definition(compiler, $1, $2, $4, $5);
308             }
309              
310             method
311             : opt_attributes METHOD method_name ':' return_type '(' opt_args ')' block
312             {
313 163253           $$ = SPVM_OP_build_method_definition(compiler, $2, $3, $5, $7, $1, $9, NULL, 0, 0);
314             }
315             | opt_attributes METHOD method_name ':' return_type '(' opt_args ')' ';'
316             {
317 67235           $$ = SPVM_OP_build_method_definition(compiler, $2, $3, $5, $7, $1, NULL, NULL, 0, 0);
318             }
319             | opt_attributes METHOD ':' return_type '(' opt_args ')' block
320             {
321 55           $$ = SPVM_OP_build_method_definition(compiler, $2, NULL, $4, $6, $1, $8, NULL, 0, 0);
322             }
323             | opt_attributes METHOD ':' return_type '(' opt_args ')' ';'
324             {
325 4820           $$ = SPVM_OP_build_method_definition(compiler, $2, NULL, $4, $6, $1, NULL, NULL, 0, 0);
326             }
327              
328             anon_method
329             : opt_attributes METHOD ':' return_type '(' opt_args ')' block
330             {
331 8191           int32_t is_init = 0;
332 8191           int32_t is_anon = 1;
333 8191           $$ = SPVM_OP_build_method_definition(compiler, $2, NULL, $4, $6, $1, $8, NULL, is_init, is_anon);
334             }
335             | '[' anon_method_has_list ']' opt_attributes METHOD ':' return_type '(' opt_args ')' block
336             {
337             SPVM_OP* op_list_args;
338 22 100         if ($2->id == SPVM_OP_C_ID_LIST) {
339 13           op_list_args = $2;
340             }
341             else {
342 9           op_list_args = SPVM_OP_new_op_list(compiler, $2->file, $2->line);
343 9           SPVM_OP_insert_child(compiler, op_list_args, op_list_args->last, $2);
344             }
345            
346 22           int32_t is_init = 0;
347 22           int32_t is_anon = 1;
348 22           $$ = SPVM_OP_build_method_definition(compiler, $5, NULL, $7, $9, $4, $11, op_list_args, is_init, is_anon);
349             }
350              
351             opt_args
352             : /* Empty */
353             {
354 67619           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
355             }
356             | args
357             {
358 176006 100         if ($1->id == SPVM_OP_C_ID_LIST) {
359 99461           $$ = $1;
360             }
361             else {
362 76545           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
363 76545           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
364 76545           $$ = op_list;
365             }
366             }
367              
368             args
369             : args ',' arg
370             {
371             SPVM_OP* op_list;
372 217209 100         if ($1->id == SPVM_OP_C_ID_LIST) {
373 117748           op_list = $1;
374             }
375             else {
376 99461           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
377 99461           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
378             }
379 217209           SPVM_OP_insert_child(compiler, op_list, op_list->last, $3);
380            
381 217209           $$ = op_list;
382             }
383             | args ','
384             | arg
385              
386             arg
387             : var ':' qualified_type opt_type_comment
388             {
389 332431           $$ = SPVM_OP_build_arg(compiler, $1, $3, NULL, NULL);
390             }
391             | var ':' qualified_type opt_type_comment ASSIGN operator
392             {
393 60784           $$ = SPVM_OP_build_arg(compiler, $1, $3, NULL, $6);
394             }
395              
396             anon_method_has_list
397             : anon_method_has_list ',' anon_method_has
398             {
399             SPVM_OP* op_list;
400 13 50         if ($1->id == SPVM_OP_C_ID_LIST) {
401 0           op_list = $1;
402             }
403             else {
404 13           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
405 13           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
406             }
407 13           SPVM_OP_insert_child(compiler, op_list, op_list->last, $3);
408            
409 13           $$ = op_list;
410             }
411             | anon_method_has_list ','
412             | anon_method_has
413              
414             anon_method_has
415             : has ASSIGN operator
416             {
417 27           $$ = SPVM_OP_build_anon_method_field_definition(compiler, $1, $3);
418             }
419             | has
420             {
421 8           $$ = SPVM_OP_build_anon_method_field_definition(compiler, $1, NULL);
422             }
423              
424             opt_attributes
425             : /* Empty */
426             {
427 64106           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
428             }
429             | attributes
430             {
431 228398 100         if ($1->id == SPVM_OP_C_ID_LIST) {
432 75919           $$ = $1;
433             }
434             else {
435 152479           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
436 152479           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
437 152479           $$ = op_list;
438             }
439             }
440            
441             attributes
442             : attributes ATTRIBUTE
443             {
444             SPVM_OP* op_list;
445 81232 100         if ($1->id == SPVM_OP_C_ID_LIST) {
446 5313           op_list = $1;
447             }
448             else {
449 75919           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
450 75919           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
451             }
452 81232           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
453            
454 81232           $$ = op_list;
455             }
456             | ATTRIBUTE
457              
458             opt_statements
459             : /* Empty */
460             {
461 1461           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
462             }
463             | statements
464             {
465 630532 100         if ($1->id == SPVM_OP_C_ID_LIST) {
466 226611           $$ = $1;
467             }
468             else {
469 403921           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
470 403921           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
471 403921           $$ = op_list;
472             }
473             }
474            
475             statements
476             : statements statement
477             {
478             SPVM_OP* op_list;
479 797204 100         if ($1->id == SPVM_OP_C_ID_LIST) {
480 570593           op_list = $1;
481             }
482             else {
483 226611           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
484 226611           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
485             }
486 797204           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
487            
488 797204           $$ = op_list;
489             }
490             | statement
491              
492             statement
493             : if_statement
494             | for_statement
495             | foreach_statement
496             | while_statement
497             | block
498             | switch_statement
499             | case_statement
500             | default_statement
501             | eval_block
502             | if_require_statement
503             | LAST ';'
504             | NEXT ';'
505             | BREAK ';'
506             | RETURN ';'
507             {
508 12238           $$ = SPVM_OP_build_return(compiler, $1, NULL);
509             }
510             | RETURN operator ';'
511             {
512 159700           $$ = SPVM_OP_build_return(compiler, $1, $2);
513             }
514             | operator ';'
515             {
516 710076           $$ = SPVM_OP_build_operator_statement(compiler, $1);
517             }
518             | void_return_operator ';'
519             | ';'
520             {
521 2070           $$ = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_DO_NOTHING, compiler->current_file, compiler->current_line);
522             }
523             | die ';'
524              
525             die
526             : DIE operator
527             {
528 142687           $$ = SPVM_OP_build_die(compiler, $1, $2, NULL);
529             }
530             | DIE
531             {
532 7           $$ = SPVM_OP_build_die(compiler, $1, NULL, NULL);
533             }
534             | DIE type operator
535             {
536 6           $$ = SPVM_OP_build_die(compiler, $1, $3, $2);
537             }
538             | DIE type
539             {
540 3           $$ = SPVM_OP_build_die(compiler, $1, NULL, $2);
541             }
542              
543             void_return_operator
544             : warn
545             | PRINT operator
546             {
547 253           $$ = SPVM_OP_build_print(compiler, $1, $2);
548             }
549             | SAY operator
550             {
551 60           $$ = SPVM_OP_build_print(compiler, $1, $2);
552             }
553             | weaken_field
554             | unweaken_field
555             | MAKE_READ_ONLY operator
556             {
557 1068           $$ = SPVM_OP_build_make_read_only(compiler, $1, $2);
558             }
559              
560             warn
561             : WARN operator
562             {
563 245           $$ = SPVM_OP_build_warn(compiler, $1, $2);
564             }
565             | WARN
566             {
567 17           $$ = SPVM_OP_build_warn(compiler, $1, NULL);
568             }
569              
570             for_statement
571             : FOR '(' opt_operator ';' operator ';' opt_operator ')' block
572             {
573 42725           $$ = SPVM_OP_build_for_statement(compiler, $1, $3, $5, $7, $9);
574             }
575              
576             foreach_statement
577             : FOR var_decl '(' '@' operator ')' block
578             {
579 539           $$ = SPVM_OP_build_foreach_statement(compiler, $1, $2, $5, $7);
580             }
581             | FOR var_decl '(' '@' '{' operator '}' ')' block
582             {
583 5           $$ = SPVM_OP_build_foreach_statement(compiler, $1, $2, $6, $9);
584             }
585              
586             while_statement
587             : WHILE '(' operator ')' block
588             {
589 26572           $$ = SPVM_OP_build_while_statement(compiler, $1, $3, $5);
590             }
591              
592             switch_statement
593             : SWITCH '(' operator ')' switch_block
594             {
595 1675           $$ = SPVM_OP_build_switch_statement(compiler, $1, $3, $5);
596             }
597              
598             switch_block
599             : '{' opt_case_statements '}'
600             {
601 1099           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, compiler->current_file, compiler->current_line);
602 1099           op_block->uv.block->id = SPVM_BLOCK_C_ID_SWITCH;
603 1099           $$ = SPVM_OP_build_switch_block(compiler, op_block, $2, NULL);
604             }
605             | '{' opt_case_statements default_statement '}'
606             {
607 576           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, compiler->current_file, compiler->current_line);
608 576           op_block->uv.block->id = SPVM_BLOCK_C_ID_SWITCH;
609 576           $$ = SPVM_OP_build_switch_block(compiler, op_block, $2, $3);
610             }
611              
612             opt_case_statements
613             : /* Empty */
614             {
615 8           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
616             }
617             | case_statements
618             {
619 1668 100         if ($1->id == SPVM_OP_C_ID_LIST) {
620 1643           $$ = $1;
621             }
622             else {
623 25           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
624 25           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
625 25           $$ = op_list;
626             }
627             }
628              
629             case_statements
630             : case_statements case_statement
631             {
632             SPVM_OP* op_list;
633 8051 100         if ($1->id == SPVM_OP_C_ID_LIST) {
634 6408           op_list = $1;
635             }
636             else {
637 1643           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
638 1643           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
639             }
640 8051           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
641            
642 8051           $$ = op_list;
643             }
644             | case_statement
645             {
646 1668           $$ = $1;
647             }
648              
649             case_statement
650             : CASE operator ':' block
651             {
652 7593           $$ = SPVM_OP_build_case_statement(compiler, $1, $2, $4);
653             }
654             | CASE operator ':'
655             {
656 2126           $$ = SPVM_OP_build_case_statement(compiler, $1, $2, NULL);
657             }
658              
659             default_statement
660             : DEFAULT ':' block
661             {
662 557           $$ = SPVM_OP_build_default_statement(compiler, $1, $3);
663             }
664             | DEFAULT ':'
665             {
666 20           $$ = SPVM_OP_build_default_statement(compiler, $1, NULL);
667             }
668              
669             if_require_statement
670             : IF '(' require ')' block
671             {
672 8           SPVM_OP* op_if_require = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_IF_REQUIRE, compiler->current_file, compiler->current_line);
673            
674 8           $$ = SPVM_OP_build_if_require_statement(compiler, op_if_require, $3, $5, NULL);
675             }
676             | IF '(' require ')' block ELSE block
677             {
678 4           SPVM_OP* op_if_require = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_IF_REQUIRE, compiler->current_file, compiler->current_line);
679            
680 4           $$ = SPVM_OP_build_if_require_statement(compiler, op_if_require, $3, $5, $7);
681             }
682             if_statement
683             : IF '(' operator ')' block else_statement
684             {
685 140734           SPVM_OP* op_if = SPVM_OP_build_if_statement(compiler, $1, $3, $5, $6, 0);
686            
687             // if is wraped with block to allow the following syntax
688             // if (var_decl $var = 3) { ... }
689 140734           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, $1->file, $1->line);
690 140734           SPVM_OP_insert_child(compiler, op_block, op_block->last, op_if);
691            
692 140734           $$ = op_block;
693             }
694             | UNLESS '(' operator ')' block else_statement
695             {
696 159090           SPVM_OP* op_if = SPVM_OP_build_if_statement(compiler, $1, $3, $5, $6, 0);
697            
698             // if is wraped with block to allow the following syntax
699             // if (var_decl $var = 3) { ... }
700 159090           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, $1->file, $1->line);
701 159090           SPVM_OP_insert_child(compiler, op_block, op_block->last, op_if);
702            
703 159090           $$ = op_block;
704             }
705              
706             else_statement
707             : /* NULL */
708             {
709 251880           $$ = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_DO_NOTHING, compiler->current_file, compiler->current_line);
710             };
711             | ELSE block
712             {
713 47944           $$ = $2;
714             }
715             | ELSIF '(' operator ')' block else_statement
716             {
717 25614           $$ = SPVM_OP_build_if_statement(compiler, $1, $3, $5, $6, 0);
718             }
719              
720             block
721             : '{' opt_statements '}'
722             {
723 631993           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, $1->file, $1->line);
724 631993           SPVM_OP_insert_child(compiler, op_block, op_block->last, $2);
725 631993           $$ = op_block;
726             }
727              
728             eval_block
729             : EVAL block
730             {
731 2075           $$ = SPVM_OP_build_eval(compiler, $1, $2);
732             }
733              
734             opt_operators
735             : /* Empty */
736             {
737 4627           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
738             }
739             | operators
740             {
741 186697 100         if ($1->id == SPVM_OP_C_ID_LIST) {
742 115671           $$ = $1;
743             }
744             else {
745 71026           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
746 71026           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
747 71026           $$ = op_list;
748             }
749             }
750            
751             opt_operator
752             : /* Empty */
753             {
754 1070           $$ = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_DO_NOTHING, compiler->current_file, compiler->current_line);
755             }
756             | operator
757              
758             operator
759             : var
760             | EXCEPTION_VAR
761             | CONSTANT
762             | UNDEF
763             | call_method
764             | field_access
765             | array_access
766             | convert
767             | new
768             | array_init
769             | array_length
770             | var_decl
771             | unary_operator
772             | binary_operator
773             | assign
774             | inc
775             | dec
776             | '(' operators ')'
777             {
778 23263 100         if ($2->id == SPVM_OP_C_ID_LIST) {
779 5           SPVM_OP* op_operator = $2->first;
780 5           SPVM_OP* op_sequence = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_SEQUENCE, compiler->current_file, compiler->current_line);
781 18 100         while ((op_operator = SPVM_OP_sibling(compiler, op_operator))) {
782 13           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_operator);
783 13           SPVM_OP_insert_child(compiler, op_sequence, op_sequence->last, op_operator);
784 13           op_operator = op_stab;
785             }
786 5           $$ = op_sequence;
787             }
788             else {
789 23258           $$ = $2;
790             }
791             }
792             | CURRENT_CLASS_NAME
793             | isweak_field
794             | comparison_operator
795             | isa
796             | isa_error
797             | is_type
798             | is_error
799             | is_compile_type
800             | TRUE
801             {
802 30           $$ = SPVM_OP_new_op_true(compiler, $1);
803             }
804             | FALSE
805             {
806 28           $$ = SPVM_OP_new_op_false(compiler, $1);
807             }
808             | is_read_only
809             | can
810             | logical_operator
811             | BASIC_TYPE_ID type
812             {
813 64           $$ = SPVM_OP_build_basic_type_id(compiler, $1, $2);
814             }
815             | EVAL_ERROR_ID
816             | ARGS_WIDTH
817              
818             operators
819             : operators ',' operator
820             {
821             SPVM_OP* op_list;
822 339468 100         if ($1->id == SPVM_OP_C_ID_LIST) {
823 223228           op_list = $1;
824             }
825             else {
826 116240           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
827 116240           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
828             }
829 339468           SPVM_OP_insert_child(compiler, op_list, op_list->last, $3);
830            
831 339468           $$ = op_list;
832             }
833             | operators ','
834             {
835 10           $$ = $1;
836             }
837             | operator
838             {
839 210525           $$ = $1;
840             }
841              
842             unary_operator
843             : '+' operator %prec PLUS
844             {
845 40           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_PLUS, $1->file, $1->line);
846 40           $$ = SPVM_OP_build_unary_op(compiler, operator, $2);
847             }
848             | '-' operator %prec MINUS
849             {
850 1104           SPVM_OP* op_negate = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_MINUS, $1->file, $1->line);
851 1104           $$ = SPVM_OP_build_unary_op(compiler, op_negate, $2);
852             }
853             | BIT_NOT operator
854             {
855 38           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
856             }
857             | REFCNT operator
858             {
859 0           $$ = SPVM_OP_build_unary_op_var(compiler, $1, $2);
860             }
861             | TYPE_NAME operator
862             {
863 2137           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
864             }
865             | COMPILE_TYPE_NAME operator
866             {
867 14           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
868             }
869             | STRING_LENGTH operator
870             {
871 20746           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
872             }
873             | DUMP operator
874             {
875 58           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
876             }
877             | DEREF var
878             {
879 2516           $$ = SPVM_OP_build_unary_op_var(compiler, $1, $2);
880             }
881             | CREATE_REF operator
882             {
883 5114           $$ = SPVM_OP_build_unary_op_var(compiler, $1, $2);
884             }
885             | NEW_STRING_LEN operator
886             {
887 4797           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
888             }
889             | COPY operator
890             {
891 1657           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
892             }
893              
894             is_read_only
895             : IS_READ_ONLY operator
896             {
897 1073           $$ = SPVM_OP_build_is_read_only(compiler, $1, $2);
898             }
899              
900             inc
901             : INC operator
902             {
903 9684           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_PRE_INC, $1->file, $1->line);
904 9684           $$ = SPVM_OP_build_inc(compiler, operator, $2);
905             }
906             | operator INC
907             {
908 72554           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_POST_INC, $2->file, $2->line);
909 72554           $$ = SPVM_OP_build_inc(compiler, operator, $1);
910             }
911              
912             dec
913             : DEC operator
914             {
915 2219           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_PRE_DEC, $1->file, $1->line);
916 2219           $$ = SPVM_OP_build_dec(compiler, operator, $2);
917             }
918             | operator DEC
919             {
920 8134           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_POST_DEC, $2->file, $2->line);
921 8134           $$ = SPVM_OP_build_dec(compiler, operator, $1);
922             }
923              
924             binary_operator
925             : operator '+' operator
926             {
927 101369           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ADD, $2->file, $2->line);
928 101369           $$ = SPVM_OP_build_binary_op(compiler, operator, $1, $3);
929             }
930             | operator '-' operator
931             {
932 61237           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_SUBTRACT, $2->file, $2->line);
933 61237           $$ = SPVM_OP_build_binary_op(compiler, operator, $1, $3);
934             }
935             | operator '*' operator
936             {
937 7169           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_MULTIPLY, $2->file, $2->line);
938 7169           $$ = SPVM_OP_build_binary_op(compiler, operator, $1, $3);
939             }
940             | operator DIVIDE operator
941             {
942 5478           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
943             }
944             | operator DIVIDE_UNSIGNED_INT operator
945             {
946 7           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
947             }
948             | operator DIVIDE_UNSIGNED_LONG operator
949             {
950 7           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
951             }
952             | operator REMAINDER operator
953             {
954 2204           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
955             }
956             | operator REMAINDER_UNSIGNED_INT operator
957             {
958 7           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
959             }
960             | operator REMAINDER_UNSIGNED_LONG operator
961             {
962 538           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
963             }
964             | operator BIT_XOR operator
965             {
966 36           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
967             }
968             | operator BIT_AND operator
969             {
970 1120           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
971             }
972             | operator BIT_OR operator
973             {
974 36           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
975             }
976             | operator SHIFT operator
977             {
978 100           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
979             }
980             | operator '.' operator
981             {
982 28784           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
983             }
984              
985             comparison_operator
986             : operator NUMEQ operator
987             {
988 69271           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
989             }
990             | operator NUMNE operator
991             {
992 18314           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
993             }
994             | operator NUMGT operator
995             {
996 21460           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
997             }
998             | operator NUMGE operator
999             {
1000 70800           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1001             }
1002             | operator NUMLT operator
1003             {
1004 81700           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1005             }
1006             | operator NUMLE operator
1007             {
1008 75942           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1009             }
1010             | operator NUMERIC_CMP operator
1011             {
1012 6584           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1013             }
1014             | operator STREQ operator
1015             {
1016 10599           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1017             }
1018             | operator STRNE operator
1019             {
1020 576           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1021             }
1022             | operator STRGT operator
1023             {
1024 46           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1025             }
1026             | operator STRGE operator
1027             {
1028 46           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1029             }
1030             | operator STRLT operator
1031             {
1032 46           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1033             }
1034             | operator STRLE operator
1035             {
1036 46           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1037             }
1038             | operator STRING_CMP operator
1039             {
1040 1657           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1041             }
1042              
1043             isa
1044             : operator ISA type
1045             {
1046 4645           $$ = SPVM_OP_build_isa(compiler, $2, $1, $3);
1047             }
1048              
1049             isa_error
1050             : operator ISA_ERROR type
1051             {
1052 20           $$ = SPVM_OP_build_isa_error(compiler, $2, $1, $3);
1053             }
1054              
1055             is_type
1056             : operator IS_TYPE type
1057             {
1058 3809           $$ = SPVM_OP_build_is_type(compiler, $2, $1, $3);
1059             }
1060            
1061             is_error
1062             : operator IS_ERROR type
1063             {
1064 18           $$ = SPVM_OP_build_is_error(compiler, $2, $1, $3);
1065             }
1066            
1067             is_compile_type
1068             : operator IS_COMPILE_TYPE type
1069             {
1070 16           $$ = SPVM_OP_build_is_compile_type(compiler, $2, $1, $3);
1071             }
1072            
1073             logical_operator
1074             : operator LOGICAL_OR operator
1075             {
1076 8210           $$ = SPVM_OP_build_logical_or(compiler, $2, $1, $3);
1077             }
1078             | operator LOGICAL_AND operator
1079             {
1080 49161           $$ = SPVM_OP_build_logical_and(compiler, $2, $1, $3);
1081             }
1082             | LOGICAL_NOT operator
1083             {
1084 3203           $$ = SPVM_OP_build_logical_not(compiler, $1, $2);
1085             }
1086              
1087             assign
1088             : operator ASSIGN operator
1089             {
1090 574345           $$ = SPVM_OP_build_assign(compiler, $2, $1, $3);
1091             }
1092             | operator SPECIAL_ASSIGN operator
1093             {
1094 15105           $$ = SPVM_OP_build_special_assign(compiler, $2, $1, $3);
1095             }
1096              
1097             new
1098             : NEW basic_type
1099             {
1100 18286           $$ = SPVM_OP_build_new(compiler, $1, $2, NULL);
1101             }
1102             | NEW array_type_with_length
1103             {
1104 21628           SPVM_OP* op_length = $2->last;
1105 21628           SPVM_OP_cut_op(compiler, $2->last);
1106 21628           $$ = SPVM_OP_build_new(compiler, $1, $2, op_length);
1107             }
1108             | anon_method
1109             {
1110 8213           $$ = SPVM_OP_build_anon_method(compiler, $1);
1111             }
1112              
1113             array_init
1114             : '[' opt_operators ']'
1115             {
1116 8076           SPVM_OP* op_array_init = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_INIT, compiler->current_file, compiler->current_line);
1117 8076           int32_t is_key_values = 0;
1118 8076           $$ = SPVM_OP_build_array_init(compiler, op_array_init, $2, is_key_values);
1119             }
1120             | '{' operators '}'
1121             {
1122 564           SPVM_OP* op_array_init = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_INIT, compiler->current_file, compiler->current_line);
1123 564           int32_t is_key_values = 1;
1124 564           $$ = SPVM_OP_build_array_init(compiler, op_array_init, $2, is_key_values);
1125             }
1126             | '{' '}'
1127             {
1128 28           SPVM_OP* op_array_init = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_INIT, compiler->current_file, compiler->current_line);
1129 28           int32_t is_key_values = 1;
1130 28           SPVM_OP* op_list_elements = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
1131 28           $$ = SPVM_OP_build_array_init(compiler, op_array_init, op_list_elements, is_key_values);
1132             }
1133              
1134             convert
1135             : '(' qualified_type ')' operator %prec CONVERT
1136             {
1137 46259           SPVM_OP* op_convert = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, $2->file, $2->line);
1138 46259           $$ = SPVM_OP_build_type_cast(compiler, op_convert, $2, $4, NULL);
1139             }
1140             | operator ARROW '(' qualified_type ')' %prec CONVERT
1141             {
1142 6556           SPVM_OP* op_convert = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, $4->file, $4->line);
1143 6556           $$ = SPVM_OP_build_type_cast(compiler, op_convert, $4, $1, NULL);
1144             }
1145              
1146             call_method
1147             : CURRENT_CLASS SYMBOL_NAME '(' opt_operators ')'
1148             {
1149 45727           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1150 45727           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $2, $4);
1151             }
1152             | CURRENT_CLASS SYMBOL_NAME
1153             {
1154 5438           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1155 5438           SPVM_OP* op_operators = SPVM_OP_new_op_list(compiler, $1->file, $2->line);
1156 5438           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $2, op_operators);
1157             }
1158             | basic_type ARROW method_name '(' opt_operators ')'
1159             {
1160 77619           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1161 77619           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $3, $5);
1162             }
1163             | basic_type ARROW method_name
1164             {
1165 11895           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1166 11895           SPVM_OP* op_operators = SPVM_OP_new_op_list(compiler, $1->file, $2->line);
1167 11895           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $3, op_operators);
1168             }
1169             | operator ARROW method_name '(' opt_operators ')'
1170             {
1171 54530           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1172 54530           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $3, $5);
1173             }
1174             | operator ARROW method_name
1175             {
1176 28410           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1177 28410           SPVM_OP* op_operators = SPVM_OP_new_op_list(compiler, $1->file, $2->line);
1178 28410           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $3, op_operators);
1179             }
1180             | operator ARROW '(' opt_operators ')'
1181             {
1182 5372           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1183 5372           SPVM_OP* op_method_name = SPVM_OP_new_op_name(compiler, "", $2->file, $2->line);
1184 5372           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, op_method_name, $4);
1185             }
1186              
1187             array_access
1188             : operator ARROW '[' operator ']'
1189             {
1190 156676           SPVM_OP* op_array_access = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_ACCESS, compiler->current_file, compiler->current_line);
1191 156676           $$ = SPVM_OP_build_array_access(compiler, op_array_access, $1, $4);
1192             }
1193             | array_access '[' operator ']'
1194             {
1195 200           SPVM_OP* op_array_access = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_ACCESS, compiler->current_file, compiler->current_line);
1196 200           $$ = SPVM_OP_build_array_access(compiler, op_array_access, $1, $3);
1197             }
1198             | field_access '[' operator ']'
1199             {
1200 8614           SPVM_OP* op_array_access = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_ACCESS, compiler->current_file, compiler->current_line);
1201 8614           $$ = SPVM_OP_build_array_access(compiler, op_array_access, $1, $3);
1202             }
1203              
1204             field_access
1205             : operator ARROW '{' field_name '}'
1206             {
1207 151509           SPVM_OP* op_field_access = SPVM_OP_new_op_field_access(compiler, compiler->current_file, compiler->current_line);
1208 151509           $$ = SPVM_OP_build_field_access(compiler, op_field_access, $1, $4);
1209             }
1210             | field_access '{' field_name '}'
1211             {
1212 66           SPVM_OP* op_field_access = SPVM_OP_new_op_field_access(compiler, compiler->current_file, compiler->current_line);
1213 66           $$ = SPVM_OP_build_field_access(compiler, op_field_access, $1, $3);
1214             }
1215             | array_access '{' field_name '}'
1216             {
1217 2289           SPVM_OP* op_array_access = $1;
1218 2289           SPVM_OP* op_field_access = SPVM_OP_new_op_field_access(compiler, compiler->current_file, compiler->current_line);
1219 2289           $$ = SPVM_OP_build_field_access(compiler, op_field_access, op_array_access, $3);
1220             }
1221              
1222             weaken_field
1223             : WEAKEN var ARROW '{' field_name '}'
1224             {
1225 45           SPVM_OP* op_field_access = SPVM_OP_new_op_field_access(compiler, compiler->current_file, compiler->current_line);
1226 45           SPVM_OP_build_field_access(compiler, op_field_access, $2, $5);
1227 45           $$ = SPVM_OP_build_weaken_field(compiler, $1, op_field_access);
1228             }
1229              
1230             unweaken_field
1231             : UNWEAKEN var ARROW '{' field_name '}'
1232             {
1233 4           SPVM_OP* op_field_access = SPVM_OP_new_op_field_access(compiler, compiler->current_file, compiler->current_line);
1234 4           SPVM_OP_build_field_access(compiler, op_field_access, $2, $5);
1235 4           $$ = SPVM_OP_build_unweaken_field(compiler, $1, op_field_access);
1236             }
1237              
1238             isweak_field
1239             : ISWEAK var ARROW '{' field_name '}'
1240             {
1241 8           SPVM_OP* op_field_access = SPVM_OP_new_op_field_access(compiler, compiler->current_file, compiler->current_line);
1242 8           SPVM_OP_build_field_access(compiler, op_field_access, $2, $5);
1243 8           $$ = SPVM_OP_build_isweak_field(compiler, $1, op_field_access);
1244             }
1245              
1246             can
1247             : operator CAN method_name
1248             {
1249 15           $$ = SPVM_OP_build_can(compiler, $2, $1, $3);
1250             }
1251             | operator CAN CONSTANT
1252             {
1253 4           $$ = SPVM_OP_build_can(compiler, $2, $1, $3);
1254             }
1255              
1256             array_length
1257             : '@' operator
1258             {
1259 51354           SPVM_OP* op_array_length = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_LENGTH, compiler->current_file, compiler->current_line);
1260 51354           $$ = SPVM_OP_build_array_length(compiler, op_array_length, $2);
1261             }
1262             | '@' '{' operator '}'
1263             {
1264 4786           SPVM_OP* op_array_length = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_LENGTH, compiler->current_file, compiler->current_line);
1265 4786           $$ = SPVM_OP_build_array_length(compiler, op_array_length, $3);
1266             }
1267             | SCALAR '@' operator
1268             {
1269 5           SPVM_OP* op_array_length = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_LENGTH, compiler->current_file, compiler->current_line);
1270 5           $$ = SPVM_OP_build_array_length(compiler, op_array_length, $3);
1271             }
1272             | SCALAR '@' '{' operator '}'
1273             {
1274 5           SPVM_OP* op_array_length = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_LENGTH, compiler->current_file, compiler->current_line);
1275 5           $$ = SPVM_OP_build_array_length(compiler, op_array_length, $4);
1276             }
1277              
1278             var_decl
1279             : MY var ':' qualified_type opt_type_comment
1280             {
1281 8916           $$ = SPVM_OP_build_var_decl(compiler, $1, $2, $4, NULL);
1282             }
1283             | MY var
1284             {
1285 351819           $$ = SPVM_OP_build_var_decl(compiler, $1, $2, NULL, NULL);
1286             }
1287              
1288             var
1289             : VAR_NAME
1290             {
1291 2870470           $$ = SPVM_OP_build_var(compiler, $1);
1292             }
1293              
1294             qualified_type
1295             : type
1296             | MUTABLE type {
1297 9661           $$ = SPVM_OP_build_mutable_type(compiler, $2);
1298             }
1299              
1300             type
1301             : basic_type
1302             | array_type
1303             | ref_type
1304              
1305             class_type
1306             : basic_type
1307              
1308             basic_type
1309             : SYMBOL_NAME
1310             {
1311 249347           $$ = SPVM_OP_build_basic_type(compiler, $1);
1312             }
1313             | BYTE
1314             {
1315 25534           SPVM_OP* op_type = SPVM_OP_new_op_byte_type(compiler, $1->file, $1->line);
1316            
1317 25534           $$ = op_type;
1318             }
1319             | SHORT
1320             {
1321 19758           SPVM_OP* op_type = SPVM_OP_new_op_short_type(compiler, $1->file, $1->line);
1322            
1323 19758           $$ = op_type;
1324             }
1325             | INT
1326             {
1327 301806           SPVM_OP* op_type = SPVM_OP_new_op_int_type(compiler, $1->file, $1->line);
1328            
1329 301806           $$ = op_type;
1330             }
1331             | LONG
1332             {
1333 36195           SPVM_OP* op_type = SPVM_OP_new_op_long_type(compiler, $1->file, $1->line);
1334            
1335 36195           $$ = op_type;
1336             }
1337             | FLOAT
1338             {
1339 25607           SPVM_OP* op_type = SPVM_OP_new_op_float_type(compiler, $1->file, $1->line);
1340            
1341 25607           $$ = op_type;
1342             }
1343             | DOUBLE
1344             {
1345 31672           SPVM_OP* op_type = SPVM_OP_new_op_double_type(compiler, $1->file, $1->line);
1346            
1347 31672           $$ = op_type;
1348             }
1349             | OBJECT
1350             {
1351 51685           SPVM_OP* op_type = SPVM_OP_new_op_any_object_type(compiler, $1->file, $1->line);
1352 51685           $$ = op_type;
1353             }
1354             | STRING
1355             {
1356 131102           SPVM_OP* op_type = SPVM_OP_new_op_string_type(compiler, $1->file, $1->line);
1357            
1358 131102           $$ = op_type;
1359             }
1360              
1361             ref_type
1362             : basic_type '*'
1363             {
1364 2940           $$ = SPVM_OP_build_ref_type(compiler, $1);
1365             }
1366              
1367             array_type
1368             : basic_type '[' ']'
1369             {
1370 113056           $$ = SPVM_OP_build_array_type(compiler, $1, NULL);
1371             }
1372             | array_type '[' ']'
1373             {
1374 101           $$ = SPVM_OP_build_array_type(compiler, $1, NULL);
1375             }
1376              
1377             array_type_with_length
1378             : basic_type '[' operator ']'
1379             {
1380 21581           $$ = SPVM_OP_build_array_type(compiler, $1, $3);
1381             }
1382             | array_type '[' operator ']'
1383             {
1384 47           $$ = SPVM_OP_build_array_type(compiler, $1, $3);
1385             }
1386              
1387             return_type
1388             : qualified_type opt_type_comment
1389             | VOID
1390             {
1391 69296           $$ = SPVM_OP_new_op_void_type(compiler, compiler->current_file, compiler->current_line);
1392             }
1393              
1394             opt_type_comment
1395             : /* Empty */
1396             {
1397 612414           $$ = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_DO_NOTHING, compiler->current_file, compiler->current_line);
1398             }
1399             | type_comment
1400              
1401             type_comment
1402             : OF union_type
1403             {
1404 20           $$ = $2;
1405             }
1406              
1407             union_type
1408             : union_type BIT_OR type
1409             {
1410             SPVM_OP* op_list;
1411 6 100         if ($1->id == SPVM_OP_C_ID_LIST) {
1412 2           op_list = $1;
1413             }
1414             else {
1415 4           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
1416 4           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
1417             }
1418 6           SPVM_OP_insert_child(compiler, op_list, op_list->last, $3);
1419            
1420 6           $$ = op_list;
1421             }
1422             | type
1423             {
1424 20           $$ = $1;
1425             }
1426              
1427             field_name
1428             : SYMBOL_NAME
1429              
1430             method_name
1431             : SYMBOL_NAME
1432              
1433             alias_name
1434             : SYMBOL_NAME
1435              
1436             %%