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 1715           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
76             }
77             | classes
78             {
79 1814 100         if ($1->id == SPVM_OP_C_ID_LIST) {
80 1654           $$ = $1;
81             }
82             else {
83 160           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
84 160           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
85 160           $$ = op_list;
86             }
87             }
88            
89             classes
90             : classes class
91             {
92             SPVM_OP* op_list;
93 32516 100         if ($1->id == SPVM_OP_C_ID_LIST) {
94 30799           op_list = $1;
95             }
96             else {
97 1717           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
98 1717           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
99             }
100 32516           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
101            
102 32516           $$ = op_list;
103             }
104             | class
105              
106             class
107             : CLASS class_type opt_extends class_block END_OF_FILE
108             {
109 20430           $$ = 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 9458           $$ = SPVM_OP_build_class(compiler, $1, $2, $6, $5, $3);
114             }
115             | CLASS class_type opt_extends ';' END_OF_FILE
116             {
117 4446           $$ = SPVM_OP_build_class(compiler, $1, $2, NULL, NULL, $3);
118             }
119             | CLASS class_type opt_extends ':' opt_attributes ';' END_OF_FILE
120             {
121 59           $$ = SPVM_OP_build_class(compiler, $1, $2, NULL, $5, $3);
122             }
123              
124             opt_extends
125             : /* Empty */
126             {
127 31363           $$ = NULL;
128             }
129             | EXTENDS basic_type
130             {
131 3093           $$ = SPVM_OP_build_extends(compiler, $1, $2);
132             }
133              
134             class_block
135             : '{' opt_definitions '}'
136             {
137 29890           SPVM_OP* op_class_block = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_CLASS_BLOCK, $1->file, $1->line);
138 29890           SPVM_OP_insert_child(compiler, op_class_block, op_class_block->last, $2);
139 29890           $$ = 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 29857 100         if ($1->id == SPVM_OP_C_ID_LIST) {
150 22108           $$ = $1;
151             }
152             else {
153 7749           $$ = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
154 7749           SPVM_OP_insert_child(compiler, $$, $$->last, $1);
155             }
156             }
157              
158             definitions
159             : definitions definition
160             {
161             SPVM_OP* op_list;
162 273643 100         if ($1->id == SPVM_OP_C_ID_LIST) {
163 251533           op_list = $1;
164             }
165             else {
166 22110           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
167 22110           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
168             }
169 273643           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
170            
171 273643           $$ = 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 1530           $$ = SPVM_OP_build_init_block(compiler, $1, $2);
191             }
192              
193             version_decl
194             : VERSION_DECL CONSTANT ';'
195             {
196 210           $$ = SPVM_OP_build_version_decl(compiler, $1, $2);
197             }
198              
199             use
200             : USE basic_type ';'
201             {
202 28899           int32_t is_require = 0;
203 28899           SPVM_OP* op_name_alias = NULL;
204 28899           $$ = 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 525           $$ = SPVM_OP_build_allow(compiler, $1, $2);
231             }
232              
233             interface
234             : INTERFACE basic_type ';'
235             {
236 1394           $$ = SPVM_OP_build_implement(compiler, $1, $2);
237             }
238              
239             enumeration
240             : opt_attributes ENUM enumeration_block
241             {
242 3203           $$ = SPVM_OP_build_enumeration_definition(compiler, $2, $3, $1);
243             }
244              
245             enumeration_block
246             : '{' opt_enumeration_values '}'
247             {
248 3203           SPVM_OP* op_enum_block = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ENUM_BLOCK, $1->file, $1->line);
249 3203           SPVM_OP_insert_child(compiler, op_enum_block, op_enum_block->last, $2);
250 3203           $$ = 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 3202 100         if ($1->id == SPVM_OP_C_ID_LIST) {
261 533           $$ = $1;
262             }
263             else {
264 2669           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
265 2669           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
266 2669           $$ = op_list;
267             }
268             }
269            
270             enumeration_values
271             : enumeration_values ',' enumeration_value
272             {
273             SPVM_OP* op_list;
274 549 100         if ($1->id == SPVM_OP_C_ID_LIST) {
275 16           op_list = $1;
276             }
277             else {
278 533           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
279 533           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
280             }
281 549           SPVM_OP_insert_child(compiler, op_list, op_list->last, $3);
282            
283 549           $$ = op_list;
284             }
285             | enumeration_values ','
286             | enumeration_value
287            
288             enumeration_value
289             : method_name
290             {
291 53           $$ = SPVM_OP_build_enumeration_value(compiler, $1, NULL);
292             }
293             | method_name ASSIGN CONSTANT
294             {
295 3698           $$ = 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 8115           $$ = 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 27459           $$ = 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 161219           $$ = 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 66165           $$ = 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 59           $$ = 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 4750           $$ = 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 8071           int32_t is_init = 0;
332 8071           int32_t is_anon = 1;
333 8071           $$ = 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 66875           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
355             }
356             | args
357             {
358 173460 100         if ($1->id == SPVM_OP_C_ID_LIST) {
359 98027           $$ = $1;
360             }
361             else {
362 75433           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
363 75433           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
364 75433           $$ = op_list;
365             }
366             }
367              
368             args
369             : args ',' arg
370             {
371             SPVM_OP* op_list;
372 214063 100         if ($1->id == SPVM_OP_C_ID_LIST) {
373 116036           op_list = $1;
374             }
375             else {
376 98027           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
377 98027           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
378             }
379 214063           SPVM_OP_insert_child(compiler, op_list, op_list->last, $3);
380            
381 214063           $$ = op_list;
382             }
383             | args ','
384             | arg
385              
386             arg
387             : var ':' qualified_type opt_type_comment
388             {
389 327607           $$ = SPVM_OP_build_arg(compiler, $1, $3, NULL, NULL);
390             }
391             | var ':' qualified_type opt_type_comment ASSIGN operator
392             {
393 59916           $$ = 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 63226           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
428             }
429             | attributes
430             {
431 225421 100         if ($1->id == SPVM_OP_C_ID_LIST) {
432 75163           $$ = $1;
433             }
434             else {
435 150258           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
436 150258           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
437 150258           $$ = op_list;
438             }
439             }
440            
441             attributes
442             : attributes ATTRIBUTE
443             {
444             SPVM_OP* op_list;
445 80396 100         if ($1->id == SPVM_OP_C_ID_LIST) {
446 5233           op_list = $1;
447             }
448             else {
449 75163           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
450 75163           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
451             }
452 80396           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
453            
454 80396           $$ = op_list;
455             }
456             | ATTRIBUTE
457              
458             opt_statements
459             : /* Empty */
460             {
461 1449           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
462             }
463             | statements
464             {
465 622208 100         if ($1->id == SPVM_OP_C_ID_LIST) {
466 223651           $$ = $1;
467             }
468             else {
469 398557           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
470 398557           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
471 398557           $$ = op_list;
472             }
473             }
474            
475             statements
476             : statements statement
477             {
478             SPVM_OP* op_list;
479 786744 100         if ($1->id == SPVM_OP_C_ID_LIST) {
480 563093           op_list = $1;
481             }
482             else {
483 223651           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
484 223651           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
485             }
486 786744           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
487            
488 786744           $$ = 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 12054           $$ = SPVM_OP_build_return(compiler, $1, NULL);
509             }
510             | RETURN operator ';'
511             {
512 158100           $$ = SPVM_OP_build_return(compiler, $1, $2);
513             }
514             | operator ';'
515             {
516 700486           $$ = SPVM_OP_build_operator_statement(compiler, $1);
517             }
518             | void_return_operator ';'
519             | ';'
520             {
521 2148           $$ = 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 140545           $$ = 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 203           $$ = 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 1052           $$ = SPVM_OP_build_make_read_only(compiler, $1, $2);
558             }
559              
560             warn
561             : WARN operator
562             {
563 247           $$ = 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 42073           $$ = SPVM_OP_build_for_statement(compiler, $1, $3, $5, $7, $9);
574             }
575              
576             foreach_statement
577             : FOR var_decl '(' '@' operator ')' block
578             {
579 531           $$ = 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 26172           $$ = SPVM_OP_build_while_statement(compiler, $1, $3, $5);
590             }
591              
592             switch_statement
593             : SWITCH '(' operator ')' switch_block
594             {
595 1651           $$ = SPVM_OP_build_switch_statement(compiler, $1, $3, $5);
596             }
597              
598             switch_block
599             : '{' opt_case_statements '}'
600             {
601 1083           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, compiler->current_file, compiler->current_line);
602 1083           op_block->uv.block->id = SPVM_BLOCK_C_ID_SWITCH;
603 1083           $$ = SPVM_OP_build_switch_block(compiler, op_block, $2, NULL);
604             }
605             | '{' opt_case_statements default_statement '}'
606             {
607 568           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, compiler->current_file, compiler->current_line);
608 568           op_block->uv.block->id = SPVM_BLOCK_C_ID_SWITCH;
609 568           $$ = 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 1644 100         if ($1->id == SPVM_OP_C_ID_LIST) {
620 1619           $$ = $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 7931 100         if ($1->id == SPVM_OP_C_ID_LIST) {
634 6312           op_list = $1;
635             }
636             else {
637 1619           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
638 1619           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
639             }
640 7931           SPVM_OP_insert_child(compiler, op_list, op_list->last, $2);
641            
642 7931           $$ = op_list;
643             }
644             | case_statement
645             {
646 1644           $$ = $1;
647             }
648              
649             case_statement
650             : CASE operator ':' block
651             {
652 7481           $$ = SPVM_OP_build_case_statement(compiler, $1, $2, $4);
653             }
654             | CASE operator ':'
655             {
656 2094           $$ = SPVM_OP_build_case_statement(compiler, $1, $2, NULL);
657             }
658              
659             default_statement
660             : DEFAULT ':' block
661             {
662 549           $$ = 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 138828           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 138828           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, $1->file, $1->line);
690 138828           SPVM_OP_insert_child(compiler, op_block, op_block->last, op_if);
691            
692 138828           $$ = op_block;
693             }
694             | UNLESS '(' operator ')' block else_statement
695             {
696 156994           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 156994           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, $1->file, $1->line);
701 156994           SPVM_OP_insert_child(compiler, op_block, op_block->last, op_if);
702            
703 156994           $$ = op_block;
704             }
705              
706             else_statement
707             : /* NULL */
708             {
709 248590           $$ = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_DO_NOTHING, compiler->current_file, compiler->current_line);
710             };
711             | ELSE block
712             {
713 47232           $$ = $2;
714             }
715             | ELSIF '(' operator ')' block else_statement
716             {
717 25232           $$ = SPVM_OP_build_if_statement(compiler, $1, $3, $5, $6, 0);
718             }
719              
720             block
721             : '{' opt_statements '}'
722             {
723 623657           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, $1->file, $1->line);
724 623657           SPVM_OP_insert_child(compiler, op_block, op_block->last, $2);
725 623657           $$ = op_block;
726             }
727              
728             eval_block
729             : EVAL block
730             {
731 2153           $$ = SPVM_OP_build_eval(compiler, $1, $2);
732             }
733              
734             opt_operators
735             : /* Empty */
736             {
737 4697           $$ = SPVM_OP_new_op_list(compiler, compiler->current_file, compiler->current_line);
738             }
739             | operators
740             {
741 184257 100         if ($1->id == SPVM_OP_C_ID_LIST) {
742 114089           $$ = $1;
743             }
744             else {
745 70168           SPVM_OP* op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
746 70168           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
747 70168           $$ = op_list;
748             }
749             }
750            
751             opt_operator
752             : /* Empty */
753             {
754 1054           $$ = 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 22931 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 22926           $$ = $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 32           $$ = SPVM_OP_new_op_true(compiler, $1);
803             }
804             | FALSE
805             {
806 30           $$ = 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 334666 100         if ($1->id == SPVM_OP_C_ID_LIST) {
823 220016           op_list = $1;
824             }
825             else {
826 114650           op_list = SPVM_OP_new_op_list(compiler, $1->file, $1->line);
827 114650           SPVM_OP_insert_child(compiler, op_list, op_list->last, $1);
828             }
829 334666           SPVM_OP_insert_child(compiler, op_list, op_list->last, $3);
830            
831 334666           $$ = op_list;
832             }
833             | operators ','
834             {
835 10           $$ = $1;
836             }
837             | operator
838             {
839 207745           $$ = $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 1088           SPVM_OP* op_negate = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_MINUS, $1->file, $1->line);
851 1088           $$ = 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 2105           $$ = 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 20434           $$ = 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 2496           $$ = SPVM_OP_build_unary_op_var(compiler, $1, $2);
880             }
881             | CREATE_REF operator
882             {
883 5054           $$ = SPVM_OP_build_unary_op_var(compiler, $1, $2);
884             }
885             | NEW_STRING_LEN operator
886             {
887 4725           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
888             }
889             | COPY operator
890             {
891 1633           $$ = SPVM_OP_build_unary_op(compiler, $1, $2);
892             }
893              
894             is_read_only
895             : IS_READ_ONLY operator
896             {
897 1057           $$ = SPVM_OP_build_is_read_only(compiler, $1, $2);
898             }
899              
900             inc
901             : INC operator
902             {
903 9540           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_PRE_INC, $1->file, $1->line);
904 9540           $$ = SPVM_OP_build_inc(compiler, operator, $2);
905             }
906             | operator INC
907             {
908 71454           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_POST_INC, $2->file, $2->line);
909 71454           $$ = SPVM_OP_build_inc(compiler, operator, $1);
910             }
911              
912             dec
913             : DEC operator
914             {
915 2187           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_PRE_DEC, $1->file, $1->line);
916 2187           $$ = SPVM_OP_build_dec(compiler, operator, $2);
917             }
918             | operator DEC
919             {
920 8014           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_POST_DEC, $2->file, $2->line);
921 8014           $$ = SPVM_OP_build_dec(compiler, operator, $1);
922             }
923              
924             binary_operator
925             : operator '+' operator
926             {
927 99897           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ADD, $2->file, $2->line);
928 99897           $$ = SPVM_OP_build_binary_op(compiler, operator, $1, $3);
929             }
930             | operator '-' operator
931             {
932 60325           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_SUBTRACT, $2->file, $2->line);
933 60325           $$ = SPVM_OP_build_binary_op(compiler, operator, $1, $3);
934             }
935             | operator '*' operator
936             {
937 7067           SPVM_OP* operator = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_MULTIPLY, $2->file, $2->line);
938 7067           $$ = SPVM_OP_build_binary_op(compiler, operator, $1, $3);
939             }
940             | operator DIVIDE operator
941             {
942 5398           $$ = 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 2172           $$ = 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 530           $$ = 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 1104           $$ = 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 28424           $$ = SPVM_OP_build_binary_op(compiler, $2, $1, $3);
983             }
984              
985             comparison_operator
986             : operator NUMEQ operator
987             {
988 68531           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
989             }
990             | operator NUMNE operator
991             {
992 18050           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
993             }
994             | operator NUMGT operator
995             {
996 21140           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
997             }
998             | operator NUMGE operator
999             {
1000 69734           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1001             }
1002             | operator NUMLT operator
1003             {
1004 80464           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1005             }
1006             | operator NUMLE operator
1007             {
1008 74796           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1009             }
1010             | operator NUMERIC_CMP operator
1011             {
1012 6488           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1013             }
1014             | operator STREQ operator
1015             {
1016 10455           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1017             }
1018             | operator STRNE operator
1019             {
1020 568           $$ = 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 1633           $$ = SPVM_OP_build_comparison_op(compiler, $2, $1, $3);
1041             }
1042              
1043             isa
1044             : operator ISA type
1045             {
1046 4599           $$ = 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 3753           $$ = 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 8092           $$ = SPVM_OP_build_logical_or(compiler, $2, $1, $3);
1077             }
1078             | operator LOGICAL_AND operator
1079             {
1080 48421           $$ = SPVM_OP_build_logical_and(compiler, $2, $1, $3);
1081             }
1082             | LOGICAL_NOT operator
1083             {
1084 3157           $$ = SPVM_OP_build_logical_not(compiler, $1, $2);
1085             }
1086              
1087             assign
1088             : operator ASSIGN operator
1089             {
1090 566523           $$ = SPVM_OP_build_assign(compiler, $2, $1, $3);
1091             }
1092             | operator SPECIAL_ASSIGN operator
1093             {
1094 14881           $$ = SPVM_OP_build_special_assign(compiler, $2, $1, $3);
1095             }
1096              
1097             new
1098             : NEW basic_type
1099             {
1100 18074           $$ = SPVM_OP_build_new(compiler, $1, $2, NULL);
1101             }
1102             | NEW array_type_with_length
1103             {
1104 21330           SPVM_OP* op_length = $2->last;
1105 21330           SPVM_OP_cut_op(compiler, $2->last);
1106 21330           $$ = SPVM_OP_build_new(compiler, $1, $2, op_length);
1107             }
1108             | anon_method
1109             {
1110 8093           $$ = SPVM_OP_build_anon_method(compiler, $1);
1111             }
1112              
1113             array_init
1114             : '[' opt_operators ']'
1115             {
1116 8008           SPVM_OP* op_array_init = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_INIT, compiler->current_file, compiler->current_line);
1117 8008           int32_t is_key_values = 0;
1118 8008           $$ = SPVM_OP_build_array_init(compiler, op_array_init, $2, is_key_values);
1119             }
1120             | '{' operators '}'
1121             {
1122 556           SPVM_OP* op_array_init = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_INIT, compiler->current_file, compiler->current_line);
1123 556           int32_t is_key_values = 1;
1124 556           $$ = 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 45727           SPVM_OP* op_convert = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, $2->file, $2->line);
1138 45727           $$ = SPVM_OP_build_type_cast(compiler, op_convert, $2, $4, NULL);
1139             }
1140             | operator ARROW '(' qualified_type ')' %prec CONVERT
1141             {
1142 6460           SPVM_OP* op_convert = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, $4->file, $4->line);
1143 6460           $$ = 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 45077           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1150 45077           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $2, $4);
1151             }
1152             | CURRENT_CLASS SYMBOL_NAME
1153             {
1154 5360           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1155 5360           SPVM_OP* op_operators = SPVM_OP_new_op_list(compiler, $1->file, $2->line);
1156 5360           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $2, op_operators);
1157             }
1158             | basic_type ARROW method_name '(' opt_operators ')'
1159             {
1160 76805           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1161 76805           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $3, $5);
1162             }
1163             | basic_type ARROW method_name
1164             {
1165 11953           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1166 11953           SPVM_OP* op_operators = SPVM_OP_new_op_list(compiler, $1->file, $2->line);
1167 11953           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $3, op_operators);
1168             }
1169             | operator ARROW method_name '(' opt_operators ')'
1170             {
1171 53772           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1172 53772           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $3, $5);
1173             }
1174             | operator ARROW method_name
1175             {
1176 28006           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1177 28006           SPVM_OP* op_operators = SPVM_OP_new_op_list(compiler, $1->file, $2->line);
1178 28006           $$ = SPVM_OP_build_call_method(compiler, op_call_method, $1, $3, op_operators);
1179             }
1180             | operator ARROW '(' opt_operators ')'
1181             {
1182 5292           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, compiler->current_file, compiler->current_line);
1183 5292           SPVM_OP* op_method_name = SPVM_OP_new_op_name(compiler, "", $2->file, $2->line);
1184 5292           $$ = 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 154402           SPVM_OP* op_array_access = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_ACCESS, compiler->current_file, compiler->current_line);
1191 154402           $$ = 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 8486           SPVM_OP* op_array_access = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_ACCESS, compiler->current_file, compiler->current_line);
1201 8486           $$ = SPVM_OP_build_array_access(compiler, op_array_access, $1, $3);
1202             }
1203              
1204             field_access
1205             : operator ARROW '{' field_name '}'
1206             {
1207 149457           SPVM_OP* op_field_access = SPVM_OP_new_op_field_access(compiler, compiler->current_file, compiler->current_line);
1208 149457           $$ = SPVM_OP_build_field_access(compiler, op_field_access, $1, $4);
1209             }
1210             | field_access '{' field_name '}'
1211             {
1212 72           SPVM_OP* op_field_access = SPVM_OP_new_op_field_access(compiler, compiler->current_file, compiler->current_line);
1213 72           $$ = 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 50586           SPVM_OP* op_array_length = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_LENGTH, compiler->current_file, compiler->current_line);
1260 50586           $$ = SPVM_OP_build_array_length(compiler, op_array_length, $2);
1261             }
1262             | '@' '{' operator '}'
1263             {
1264 4714           SPVM_OP* op_array_length = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ARRAY_LENGTH, compiler->current_file, compiler->current_line);
1265 4714           $$ = 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 8826           $$ = SPVM_OP_build_var_decl(compiler, $1, $2, $4, NULL);
1282             }
1283             | MY var
1284             {
1285 347019           $$ = SPVM_OP_build_var_decl(compiler, $1, $2, NULL, NULL);
1286             }
1287              
1288             var
1289             : VAR_NAME
1290             {
1291 2829252           $$ = SPVM_OP_build_var(compiler, $1);
1292             }
1293              
1294             qualified_type
1295             : type
1296             | MUTABLE type {
1297 9517           $$ = 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 246339           $$ = SPVM_OP_build_basic_type(compiler, $1);
1312             }
1313             | BYTE
1314             {
1315 25240           SPVM_OP* op_type = SPVM_OP_new_op_byte_type(compiler, $1->file, $1->line);
1316            
1317 25240           $$ = op_type;
1318             }
1319             | SHORT
1320             {
1321 19552           SPVM_OP* op_type = SPVM_OP_new_op_short_type(compiler, $1->file, $1->line);
1322            
1323 19552           $$ = op_type;
1324             }
1325             | INT
1326             {
1327 297836           SPVM_OP* op_type = SPVM_OP_new_op_int_type(compiler, $1->file, $1->line);
1328            
1329 297836           $$ = op_type;
1330             }
1331             | LONG
1332             {
1333 35735           SPVM_OP* op_type = SPVM_OP_new_op_long_type(compiler, $1->file, $1->line);
1334            
1335 35735           $$ = op_type;
1336             }
1337             | FLOAT
1338             {
1339 25295           SPVM_OP* op_type = SPVM_OP_new_op_float_type(compiler, $1->file, $1->line);
1340            
1341 25295           $$ = op_type;
1342             }
1343             | DOUBLE
1344             {
1345 31278           SPVM_OP* op_type = SPVM_OP_new_op_double_type(compiler, $1->file, $1->line);
1346            
1347 31278           $$ = op_type;
1348             }
1349             | OBJECT
1350             {
1351 50937           SPVM_OP* op_type = SPVM_OP_new_op_any_object_type(compiler, $1->file, $1->line);
1352 50937           $$ = op_type;
1353             }
1354             | STRING
1355             {
1356 129056           SPVM_OP* op_type = SPVM_OP_new_op_string_type(compiler, $1->file, $1->line);
1357            
1358 129056           $$ = op_type;
1359             }
1360              
1361             ref_type
1362             : basic_type '*'
1363             {
1364 2912           $$ = SPVM_OP_build_ref_type(compiler, $1);
1365             }
1366              
1367             array_type
1368             : basic_type '[' ']'
1369             {
1370 111370           $$ = 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 21283           $$ = 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 68250           $$ = SPVM_OP_new_op_void_type(compiler, compiler->current_file, compiler->current_line);
1392             }
1393              
1394             opt_type_comment
1395             : /* Empty */
1396             {
1397 603988           $$ = 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             %%