File Coverage

lib/SPVM/Builder/src/spvm_check.c
Criterion Covered Total %
statement 2060 2157 95.5
branch 1013 1156 87.6
condition n/a
subroutine n/a
pod n/a
total 3073 3313 92.7


line stmt bran cond sub pod time code
1             // Copyright (c) 2023 Yuki Kimoto
2             // MIT License
3              
4             #include
5             #include
6             #include
7             #include
8             #include
9             #include
10              
11             #include "spvm_compiler.h"
12             #include "spvm_list.h"
13             #include "spvm_hash.h"
14             #include "spvm_allocator.h"
15             #include "spvm_op.h"
16             #include "spvm_check.h"
17             #include "spvm_method.h"
18             #include "spvm_constant.h"
19             #include "spvm_field.h"
20             #include "spvm_var_decl.h"
21             #include "spvm_var.h"
22             #include "spvm_type.h"
23             #include "spvm_field_access.h"
24             #include "spvm_call_method.h"
25             #include "spvm_type.h"
26             #include "spvm_switch_info.h"
27             #include "spvm_class_var.h"
28             #include "spvm_class_var_access.h"
29             #include "spvm_block.h"
30             #include "spvm_basic_type.h"
31             #include "spvm_case_info.h"
32             #include "spvm_array_field_access.h"
33             #include "spvm_string_buffer.h"
34             #include "spvm_use.h"
35             #include "spvm_interface.h"
36             #include "spvm_string.h"
37             #include "spvm_attribute.h"
38             #include "spvm_dumper.h"
39             #include "spvm_allow.h"
40              
41 3492           void SPVM_CHECK_check(SPVM_COMPILER* compiler) {
42             // Check type ops
43 3492           SPVM_CHECK_check_op_types(compiler);
44 3492 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
45 2           return;
46             }
47            
48             // Check basic types
49 3490           SPVM_CHECK_check_basic_types(compiler);
50 3490 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
51 371           return;
52             }
53            
54             #ifdef SPVM_DEBUG_COMPILE
55             if (SPVM_COMPILER_get_error_messages_length(compiler) == 0) {
56             fprintf(stderr, "\n[Basic types]\n");
57             SPVM_DUMPER_dump_basic_types(compiler, compiler->basic_types);
58             }
59             #endif
60             }
61              
62 3490           void SPVM_CHECK_check_basic_types(SPVM_COMPILER* compiler) {
63            
64 3490           SPVM_CHECK_check_basic_types_relation(compiler);
65 3490 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
66 9           return;
67             }
68            
69 3481           SPVM_CHECK_check_basic_types_class_var(compiler);
70 3481 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
71 1           return;
72             }
73            
74 3480           SPVM_CHECK_check_basic_types_field(compiler);
75 3480 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
76 8           return;
77             }
78            
79 3472           SPVM_CHECK_check_basic_types_method(compiler);
80 3472 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
81 28           return;
82             }
83            
84 3444           SPVM_CHECK_check_basic_types_ast(compiler);
85 3444 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
86 325           return;
87             }
88             }
89              
90 3490           void SPVM_CHECK_check_basic_types_relation(SPVM_COMPILER* compiler) {
91 58798 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
92 55315           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
93            
94 55315           const char* basic_type_name = basic_type->name;
95            
96 55315           const char* parent_basic_type_name = basic_type->parent_name;
97 55315 100         if (parent_basic_type_name) {
98 2773           SPVM_BASIC_TYPE* parent_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, parent_basic_type_name, strlen(parent_basic_type_name));
99              
100 2773 100         if (!SPVM_BASIC_TYPE_is_class_type(compiler, parent_basic_type->id)) {
101 2           SPVM_COMPILER_error(compiler, "The parant class must be a class type.\n at %s line %d", basic_type->op_extends->file, basic_type->op_extends->line);
102 2           return;
103             }
104 2771 100         if (!SPVM_BASIC_TYPE_is_class_type(compiler, basic_type->id)) {
105 1           SPVM_COMPILER_error(compiler, "The current class must be a class type when the class becomes a child class.\n at %s line %d", basic_type->op_extends->file, basic_type->op_extends->line);
106 1           return;
107             }
108            
109 2770 100         if (strcmp(basic_type->name, parent_basic_type->name) == 0) {
110 2           SPVM_COMPILER_error(compiler, "The name of the parant class must be different from the name of the class.\n at %s line %d", basic_type->op_extends->file, basic_type->op_extends->line);
111 2           return;
112             }
113 2768           basic_type->parent = parent_basic_type;
114             }
115            
116             // Add interface_basic_types
117 56680 100         for (int32_t i = 0; i < basic_type->interface_decls->length; i++) {
118 1372           SPVM_INTERFACE* interface_decl = SPVM_LIST_get(basic_type->interface_decls, i);
119 1372           SPVM_BASIC_TYPE* interface_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, interface_decl->op_type->uv.type->unresolved_basic_type_name, strlen(interface_decl->op_type->uv.type->unresolved_basic_type_name));
120            
121 1372 100         if (!SPVM_BASIC_TYPE_is_interface_type(compiler, interface_basic_type->id)) {
122 2           SPVM_COMPILER_error(compiler, "The interface specified by the interface statement must be an interface type.\n at %s line %d", interface_decl->op_interface->file, interface_decl->op_interface->line);
123 2           return;
124             }
125            
126 1370           SPVM_LIST_push(basic_type->interface_basic_types, interface_basic_type);
127 1370           SPVM_HASH_set(basic_type->interface_basic_symtable, interface_basic_type->name, strlen(interface_basic_type->name), interface_basic_type);
128             }
129             }
130            
131 58625 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
132 55144           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
133 55144           SPVM_BASIC_TYPE* parent_basic_type = basic_type->parent;
134             while (1) {
135 57900 100         if (parent_basic_type) {
136 2758 100         if (strcmp(parent_basic_type->name, basic_type->name) == 0) {
137 2           SPVM_COMPILER_error(compiler, "Recursive inheritance. Found the current class \"%s\" in a super class.\n at %s line %d", basic_type->name, basic_type->op_extends->file, basic_type->op_extends->line);
138 2           return;
139             }
140 2756           parent_basic_type = parent_basic_type->parent;
141             }
142             else {
143 55142           break;
144             }
145 2756           }
146             }
147            
148 58577 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
149 55096           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
150             // Merge inheritance
151 55096           SPVM_LIST* basic_type_merge_stack = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
152 55096           SPVM_LIST_push(basic_type_merge_stack, basic_type);
153            
154 55096           SPVM_LIST* merged_interface_basic_types = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
155            
156 55096           SPVM_BASIC_TYPE* parent_basic_type = basic_type->parent;
157             while (1) {
158 57845 100         if (parent_basic_type) {
159 2749           SPVM_LIST_push(basic_type_merge_stack, parent_basic_type);
160 2749           parent_basic_type = parent_basic_type->parent;
161             }
162             else {
163 55096           break;
164             }
165 2749           }
166            
167 55096           SPVM_BASIC_TYPE* current_basic_type = basic_type;
168 112941 100         for (int32_t basic_type_id = basic_type_merge_stack->length - 1; basic_type_id >= 0; basic_type_id--) {
169 57845           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(basic_type_merge_stack, basic_type_id);
170            
171             // All interface_basic_types
172 57845           SPVM_LIST* interface_basic_types = basic_type->interface_basic_types;
173 59351 100         for (int32_t interface_index = 0; interface_index < interface_basic_types->length; interface_index++) {
174 1506           SPVM_BASIC_TYPE* interface_basic_type = SPVM_LIST_get(interface_basic_types, interface_index);
175 1506           SPVM_LIST_push(merged_interface_basic_types, interface_basic_type);
176             }
177             }
178            
179             // Add parent interface_basic_types
180 55096           basic_type->interface_basic_types = merged_interface_basic_types;
181 56738 100         for (int32_t i = 0; i < merged_interface_basic_types->length; i++) {
182 1642           SPVM_BASIC_TYPE* interface_basic_type = SPVM_LIST_get(merged_interface_basic_types, i);
183 1642           SPVM_BASIC_TYPE* found_interface_basic_type = SPVM_HASH_get(basic_type->interface_basic_symtable, interface_basic_type->name, strlen(interface_basic_type->name));
184 1642 100         if (!found_interface_basic_type) {
185 136           SPVM_LIST_push(basic_type->interface_basic_types, interface_basic_type);
186 136           SPVM_HASH_set(basic_type->interface_basic_symtable, interface_basic_type->name, strlen(interface_basic_type->name), interface_basic_type);
187             }
188             }
189            
190 55096           SPVM_LIST_free(basic_type_merge_stack);
191             }
192            
193             // Outer class
194 58577 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
195 55096           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
196 55096 100         if (basic_type->is_anon) {
197            
198 8196           char* found_ptr = strstr(basic_type->name, "::anon::");
199 8196 50         assert(found_ptr);
200 8196           int32_t outer_basic_type_name_length = (int32_t)(found_ptr - basic_type->name);
201            
202 8196           SPVM_BASIC_TYPE* outer_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, basic_type->name, outer_basic_type_name_length);
203 8196 50         assert(outer_basic_type);
204            
205 8196           basic_type->outer = outer_basic_type;
206             }
207             }
208             }
209              
210 3481           void SPVM_CHECK_check_basic_types_class_var(SPVM_COMPILER* compiler) {
211            
212 58575 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
213 55095           int32_t compile_error = 0;
214 55095           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
215 55095           const char* basic_type_name = basic_type->name;
216            
217             // Check class var
218 62324 100         for (int32_t class_var_index = 0; class_var_index < basic_type->class_vars->length; class_var_index++) {
219 7230           SPVM_CLASS_VAR* class_var = SPVM_LIST_get(basic_type->class_vars, class_var_index);
220 7230           SPVM_TYPE* class_var_type = SPVM_CHECK_get_type(compiler, class_var->op_class_var);
221 7230           int32_t is_mulnum_t = SPVM_TYPE_is_mulnum_type(compiler, class_var_type->basic_type->id, class_var_type->dimension, class_var_type->flag);
222            
223             // valut_t cannnot become class variable
224 7230 100         if (is_mulnum_t) {
225 1           SPVM_COMPILER_error(compiler, "The multi-numeric type cannnot used in the definition of the class variable.\n at %s line %d", class_var->op_class_var->file, class_var->op_class_var->line);
226 1           return;
227             }
228             }
229             }
230             }
231              
232 3480           void SPVM_CHECK_check_basic_types_field(SPVM_COMPILER* compiler) {
233 58538 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
234 55066           int32_t compile_error = 0;
235 55066           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
236 55066           const char* basic_type_name = basic_type->name;
237            
238             // Check class var
239 62290 100         for (int32_t class_var_index = 0; class_var_index < basic_type->class_vars->length; class_var_index++) {
240 7224           SPVM_CLASS_VAR* class_var = SPVM_LIST_get(basic_type->class_vars, class_var_index);
241 7224           SPVM_TYPE* class_var_type = SPVM_CHECK_get_type(compiler, class_var->op_class_var);
242 7224           int32_t is_mulnum_t = SPVM_TYPE_is_mulnum_type(compiler, class_var_type->basic_type->id, class_var_type->dimension, class_var_type->flag);
243            
244             // valut_t cannnot become class variable
245 7224 50         if (is_mulnum_t) {
246 0           SPVM_COMPILER_error(compiler, "The multi-numeric type cannnot used in the definition of the class variable.\n at %s line %d", class_var->op_class_var->file, class_var->op_class_var->line);
247 0           return;
248             }
249             }
250            
251             // Class variable
252 62290 100         for (int32_t i = 0; i < basic_type->class_vars->length; i++) {
253 7224           SPVM_CLASS_VAR* class_var = SPVM_LIST_get(basic_type->class_vars, i);
254            
255 7224           class_var->index = i;
256             }
257            
258             // Multi-numeric type limitation
259 55066 100         if (basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_MULNUM) {
260 270           SPVM_LIST* fields = basic_type->unmerged_fields;
261 270           SPVM_FIELD* first_field = SPVM_LIST_get(fields, 0);
262 270           SPVM_TYPE* first_field_type = SPVM_CHECK_get_type(compiler, first_field->op_field);
263 270 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_field_type->basic_type->id, first_field_type->dimension, first_field_type->flag)) {
264 1           SPVM_COMPILER_error(compiler, "The multi-numeric type must have the only fields of numeric types.\n at %s line %d", first_field->op_field->file, first_field->op_field->line);
265 1           return;
266             }
267            
268             int32_t field_index;
269 1295 100         for (field_index = 0; field_index < basic_type->unmerged_fields->length; field_index++) {
270 1027           SPVM_FIELD* field = SPVM_LIST_get(fields, field_index);
271 1027           SPVM_TYPE* field_type = SPVM_CHECK_get_type(compiler, field->op_field);
272 1027 100         if (!(field_type->basic_type->id == first_field_type->basic_type->id && field_type->dimension == first_field_type->dimension)) {
    50          
273 1           SPVM_COMPILER_error(compiler, "The fields of the multi-numeric type must be of the same type.\n at %s line %d", field_type->basic_type->name, field->op_field->file, field->op_field->line);
274 1           return;
275             }
276             }
277            
278             // Check type name
279 268           char* tail_name = SPVM_ALLOCATOR_alloc_memory_block_permanent(compiler->current_each_compile_allocator, 255);
280 268           switch (first_field_type->basic_type->id) {
281             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE:
282 27           sprintf(tail_name, "_%db", fields->length);
283 27           break;
284             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT:
285 27           sprintf(tail_name, "_%ds", fields->length);
286 27           break;
287             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT:
288 29           sprintf(tail_name, "_%di", fields->length);
289 29           break;
290             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG:
291 27           sprintf(tail_name, "_%dl", fields->length);
292 27           break;
293             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT:
294 53           sprintf(tail_name, "_%df", fields->length);
295 53           break;
296             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE:
297 105           sprintf(tail_name, "_%dd", fields->length);
298 105           break;
299             default:
300 0           assert(0);
301             }
302 268           int32_t tail_name_length = (int32_t)strlen(tail_name);
303 268           int32_t basic_type_name_length = strlen(basic_type_name);
304            
305 268           char* found_pos_ptr = strstr(basic_type_name + basic_type_name_length - tail_name_length, tail_name);
306 268 100         if (!found_pos_ptr) {
307 2           SPVM_COMPILER_error(compiler, "The type name for the %s multi-numeric with the field length of %d must end with \"%s\".\n at %s line %d", first_field_type->basic_type->name, basic_type->unmerged_fields->length, tail_name, basic_type->op_class->file, basic_type->op_class->line);
308 2           return;
309             }
310             }
311            
312             // Check fields
313 81206 100         for (int32_t field_index = 0; field_index < basic_type->unmerged_fields->length; field_index++) {
314 26145           SPVM_FIELD* field = SPVM_LIST_get(basic_type->unmerged_fields, field_index);
315 26145           SPVM_TYPE* field_type = SPVM_CHECK_get_type(compiler, field->op_field);
316              
317             // valut_t cannnot become field
318 26145           int32_t is_mulnum_t = SPVM_TYPE_is_mulnum_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag);
319 26145 100         if (is_mulnum_t) {
320 1           SPVM_COMPILER_error(compiler, "The multi-numeric type cannnot used in the definition of the field.\n at %s line %d", field->op_field->file, field->op_field->line);
321 1           return;
322             }
323             }
324            
325             {
326             // Merge fields
327 55061           SPVM_LIST* basic_type_merge_stack = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
328 55061           SPVM_LIST_push(basic_type_merge_stack, basic_type);
329            
330 55061           SPVM_LIST* merged_fields = SPVM_LIST_new_list_permanent(compiler->current_each_compile_allocator, 0);
331            
332 55061           SPVM_BASIC_TYPE* parent_basic_type = basic_type->parent;
333             while (1) {
334 57807 100         if (parent_basic_type) {
335 2746           SPVM_LIST_push(basic_type_merge_stack, parent_basic_type);
336 2746           parent_basic_type = parent_basic_type->parent;
337             }
338             else {
339 55061           break;
340             }
341 2746           }
342            
343 55061           SPVM_BASIC_TYPE* current_basic_type = basic_type;
344 55061           int32_t merged_fields_index = 0;
345 112865 100         for (int32_t basic_type_id = basic_type_merge_stack->length - 1; basic_type_id >= 0; basic_type_id--) {
346 57807           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(basic_type_merge_stack, basic_type_id);
347            
348 57807           SPVM_LIST* fields = basic_type->unmerged_fields;
349 57807           int32_t field_index = 0;
350 57807           int32_t fields_length = fields->length;
351 84089 100         for (int32_t field_index = 0; field_index < fields_length; field_index++) {
352 26285           SPVM_FIELD* field = SPVM_LIST_get(fields, field_index);
353              
354 26285           SPVM_FIELD* found_field_in_super_class = SPVM_CHECK_search_unmerged_field(compiler, basic_type->parent, field->name);
355 26285 100         if (found_field_in_super_class) {
356 3           SPVM_COMPILER_error(compiler, "The \"%s\" field cannot be defined. This field is already defined in the super class of the \"%s\" class.\n at %s line %d", field->name, basic_type->name, field->op_field->file, field->op_field->line);
357 3           compile_error = 1;
358 3           break;
359             }
360            
361             SPVM_FIELD* new_field;
362 26282 100         if (strcmp(field->current_basic_type->name, current_basic_type->name) == 0) {
363 26141           new_field = field;
364             }
365             // Clone field
366             else {
367 141           new_field = SPVM_FIELD_new(compiler);
368 141           new_field->name = field->name;
369 141           new_field->current_basic_type = current_basic_type;
370 141           new_field->type = field->type;
371 141           new_field->access_control_type = field->access_control_type;
372             }
373 26282           SPVM_LIST_push(merged_fields, new_field);
374 26282           merged_fields_index++;
375             }
376 57807 100         if (compile_error) {
377 3           break;
378             }
379             }
380            
381 55061 50         if (!(merged_fields->length <= 65535)) {
382 0           SPVM_COMPILER_error(compiler, "The length of the merged fields in the \"%s\" class must be lower than 65535.\n at %s line %d", basic_type->op_class->file, basic_type->op_class->line);
383 0           return;
384             }
385            
386 81343 100         for (int32_t field_index = 0; field_index < merged_fields->length; field_index++) {
387 26282           SPVM_FIELD* field = SPVM_LIST_get(merged_fields, field_index);
388 26282           field->index = field_index;
389 26282           SPVM_HASH_set(basic_type->field_symtable, field->name, strlen(field->name), field);
390             }
391            
392 55061           basic_type->fields = merged_fields;
393            
394             // Resove field offset
395 55061           SPVM_CHECK_check_field_offset(compiler, basic_type);
396            
397 55061           SPVM_LIST_free(basic_type_merge_stack);
398 55061 100         if (compile_error) {
399 3           return;
400             }
401             }
402            
403             }
404             }
405              
406 3472           void SPVM_CHECK_check_basic_types_method(SPVM_COMPILER* compiler) {
407              
408 58285 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
409 54841           int32_t compile_error = 0;
410 54841           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
411 54841           const char* basic_type_name = basic_type->name;
412            
413             // Edit INIT block
414             // The INIT mehtods that is the parent basic type and used basic types in the order.
415 54841           SPVM_METHOD* init_method = basic_type->init_method;
416 54841 100         if (init_method) {
417 34422           SPVM_OP* op_block = init_method->op_block;
418 34422           SPVM_OP* op_list_statement = op_block->first;
419            
420 34422           SPVM_LIST* use_basic_type_names = basic_type->use_basic_type_names;
421            
422 63777 100         for (int32_t i = use_basic_type_names->length - 1; i >= 0; i--) {
423 29355           const char* use_basic_type_name = SPVM_LIST_get(use_basic_type_names, i);
424            
425 29355           SPVM_BASIC_TYPE* use_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, use_basic_type_name, strlen(use_basic_type_name));
426 29355 50         if (use_basic_type) {
427 29355 100         if (use_basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS) {
428 24181           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, op_block->file, op_block->line);
429 24181           SPVM_OP* op_name_invocant = SPVM_OP_new_op_name(compiler, use_basic_type_name, op_block->file, op_block->line);
430 24181           SPVM_OP* op_name_method = SPVM_OP_new_op_name(compiler, "INIT", op_block->file, op_block->line);
431 24181           SPVM_OP* op_operators = SPVM_OP_new_op_list(compiler, op_block->file, op_block->line);
432 24181           SPVM_OP* op_type_invocant = SPVM_OP_build_basic_type(compiler, op_name_invocant);
433 24181           SPVM_OP_build_call_method(compiler, op_call_method, op_type_invocant, op_name_method, op_operators);
434 24181           SPVM_OP_insert_child(compiler, op_list_statement, op_list_statement->first, op_call_method);
435             }
436             }
437             }
438            
439 34422           const char* parent_basic_type_name = basic_type->parent_name;
440 34422 100         if (parent_basic_type_name) {
441 2719           SPVM_OP* op_call_method = SPVM_OP_new_op_call_method(compiler, op_block->file, op_block->line);
442 2719           SPVM_OP* op_name_invocant = SPVM_OP_new_op_name(compiler, parent_basic_type_name, op_block->file, op_block->line);
443 2719           SPVM_OP* op_name_method = SPVM_OP_new_op_name(compiler, "INIT", op_block->file, op_block->line);
444 2719           SPVM_OP* op_operators = SPVM_OP_new_op_list(compiler, op_block->file, op_block->line);
445 2719           SPVM_OP* op_type_invocant = SPVM_OP_build_basic_type(compiler, op_name_invocant);
446 2719           SPVM_OP_build_call_method(compiler, op_call_method, op_type_invocant, op_name_method, op_operators);
447 2719           SPVM_OP_insert_child(compiler, op_list_statement, op_list_statement->first, op_call_method);
448             }
449             }
450            
451             // Check methods
452 358946 100         for (int32_t i = 0; i < basic_type->methods->length; i++) {
453 304122           SPVM_METHOD* method = SPVM_LIST_get(basic_type->methods, i);
454            
455             // Argument limit check
456 304122           int32_t args_width = 0;
457 304122           SPVM_TYPE* last_arg_type = NULL;
458 304122           int32_t found_optional_arg = 0;
459 811420 100         for (int32_t arg_index = 0; arg_index < method->args_length; arg_index++) {
460 507310           SPVM_VAR_DECL* arg_var_decl = SPVM_LIST_get(method->var_decls, arg_index);
461            
462 507310           SPVM_TYPE* arg_type = arg_var_decl->type;
463            
464 507310           int32_t is_arg_type_is_mulnum_type = SPVM_TYPE_is_mulnum_type(compiler, arg_type->basic_type->id, arg_type->dimension, arg_type->flag);
465            
466             // Optional argument
467 507310           SPVM_OP* op_optional_arg_default = arg_var_decl->op_optional_arg_default;
468 507310 100         if (op_optional_arg_default) {
469 60618           found_optional_arg = 1;
470 60618 100         if (SPVM_TYPE_is_numeric_type(compiler, arg_type->basic_type->id, arg_type->dimension, arg_type->flag)) {
471 56391 100         if (op_optional_arg_default->id != SPVM_OP_C_ID_CONSTANT) {
472 2           SPVM_COMPILER_error(compiler, "The default value of the optional argument \"%s\" must be a constant value.\n at %s line %d", arg_var_decl->var->name, method->op_method->file, method->op_method->line);
473 2           return;
474             }
475             else {
476 56389           SPVM_TYPE* constant_type = SPVM_CHECK_get_type(compiler, op_optional_arg_default);
477 56389           int32_t need_implicite_conversion = 0;
478 56389           int32_t allow_narrowing_conversion = SPVM_CHECK_check_allow_narrowing_conversion(compiler, arg_type, op_optional_arg_default);
479 56389           int32_t assignability = SPVM_TYPE_can_assign(
480             compiler,
481 56389           arg_type->basic_type->id, arg_type->dimension, arg_type->flag,
482 56389           constant_type->basic_type->id, constant_type->dimension, constant_type->flag,
483             &need_implicite_conversion, allow_narrowing_conversion
484             );
485            
486 56389 100         if (!assignability) {
487 2           SPVM_COMPILER_error(compiler, "The default value of the optional argument \"%s\" must be able to be assigned to the argument.\n at %s line %d", arg_var_decl->var->name, method->op_method->file, method->op_method->line);
488 56389           return;
489             }
490             }
491             }
492 4227 100         else if (SPVM_TYPE_is_object_type(compiler, arg_type->basic_type->id, arg_type->dimension, arg_type->flag)) {
493 4222 100         if (op_optional_arg_default->id != SPVM_OP_C_ID_UNDEF) {
494 1           SPVM_COMPILER_error(compiler, "The default value of the optional argument \"%s\" must be undef.\n at %s line %d", arg_var_decl->var->name, method->op_method->file, method->op_method->line);
495 1           return;
496             }
497             }
498             else {
499 5           SPVM_COMPILER_error(compiler, "The types other than the numeric type and the object type cannnot be used in the optional argument.\n at %s line %d", method->op_method->file, method->op_method->line);
500 5           return;
501             }
502             }
503             else {
504 446692 100         if (found_optional_arg) {
505 2           SPVM_COMPILER_error(compiler, "Arguments after optional arguments must be optional arguments.\n at %s line %d", method->op_method->file, method->op_method->line);
506 2           return;
507             }
508             }
509            
510 507298           arg_var_decl->arg_stack_index = args_width;
511            
512 507298 100         if (is_arg_type_is_mulnum_type) {
513 140           args_width += arg_type->basic_type->unmerged_fields->length;
514             }
515             else {
516 507158           args_width++;
517             }
518            
519 507298 100         if (arg_index == method->args_length - 1) {
520 228543           last_arg_type = arg_type;
521             }
522             }
523            
524 304110 100         if (!(args_width <= 255)) {
525 4           SPVM_COMPILER_error(compiler, "The width of the arguments must be less than or equal to 255.\n at %s line %d", method->op_method->file, method->op_method->line);
526 4           return;
527             }
528            
529             // Can't return refernece type
530 304106 100         if (SPVM_TYPE_is_ref_type(compiler, method->return_type->basic_type->id, method->return_type->dimension, method->return_type->flag)) {
531 1           SPVM_COMPILER_error(compiler, "The return type cannnot be a reference type.\n at %s line %d", method->op_method->file, method->op_method->line);
532 1           return;
533             }
534            
535             // Copy has_precomile_attribute from anon method defined basic type
536 304105 100         if (method->outer_basic_type_name) {
537 8196           SPVM_BASIC_TYPE* anon_method_defined_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, method->outer_basic_type_name, strlen(method->outer_basic_type_name));
538 8196           basic_type->is_precompile = anon_method_defined_basic_type->is_precompile;
539             }
540             }
541            
542 54824           SPVM_LIST* methods = basic_type->methods;
543            
544             // Sort methods by name
545 54824           qsort(methods->values, methods->length, sizeof(SPVM_METHOD*), &SPVM_CHECK_method_name_compare_cb);
546            
547             // Create method IDs
548 358929 100         for (int32_t i = 0; i < basic_type->methods->length; i++) {
549 304105           SPVM_METHOD* method = SPVM_LIST_get(basic_type->methods, i);
550            
551             // Set method precompile flag if basic type have precompile attribute
552 304105 100         if (basic_type->is_precompile) {
553             int32_t can_precompile;
554 6403 100         if (method->is_init) {
555 385           can_precompile = 0;
556             }
557 6018 100         else if (method->is_enum) {
558 23           can_precompile = 0;
559             }
560             // native method, methods of interface type
561 5995 100         else if (!method->op_block) {
562 1615           can_precompile = 0;
563             }
564             else {
565 4380           can_precompile = 1;
566             }
567            
568 6403 100         if (can_precompile) {
569 4380           method->is_precompile = 1;
570             }
571             }
572            
573 304105           method->index = i;
574             }
575            
576 358926 100         for (int32_t method_index = 0; method_index < basic_type->methods->length; method_index++) {
577 304105           SPVM_METHOD* method = SPVM_LIST_get(basic_type->methods, method_index);
578            
579             // Check super class method compatibility
580 304105 100         if (!method->is_class_method) {
581 114517           SPVM_BASIC_TYPE* parent_basic_type = basic_type->parent;
582             while (1) {
583 114834 100         if (!parent_basic_type) {
584 114514           break;
585             }
586            
587 320           SPVM_METHOD* parent_method = SPVM_HASH_get(parent_basic_type->method_symtable, method->name, strlen(method->name));
588            
589 320 100         if (parent_method) {
590 251           int32_t method_compatibility = SPVM_BASIC_TYPE_check_method_compatibility(compiler, basic_type, method, parent_basic_type, parent_method, "class");
591            
592 251 100         if (method_compatibility == 0) {
593 3           return;
594             }
595             }
596 317           parent_basic_type = parent_basic_type->parent;
597 317           }
598             }
599            
600 304102 50         assert(method->current_basic_type->class_file);
601            
602             // Add variable declarations if the block does not exist
603 304102 100         if (!method->op_block) {
604 192096 100         for (int32_t arg_index = 0; arg_index < method->args_length; arg_index++) {
605 120144           SPVM_VAR_DECL* arg_var_decl = SPVM_LIST_get(method->var_decls, arg_index);
606 120144           SPVM_LIST_push(method->var_decls, arg_var_decl);
607             }
608             }
609             }
610            
611             // Check interface method compatibility
612 56433 100         for (int32_t interface_basic_type_index = 0; interface_basic_type_index < basic_type->interface_basic_types->length; interface_basic_type_index++) {
613            
614 1620           SPVM_BASIC_TYPE* interface_basic_type = SPVM_LIST_get(basic_type->interface_basic_types, interface_basic_type_index);
615 3526 100         for (int32_t interface_method_index = 0; interface_method_index < interface_basic_type->methods->length; interface_method_index++) {
616 1914           SPVM_METHOD* interface_method = SPVM_LIST_get(interface_basic_type->methods, interface_method_index);
617            
618             // Check super class method compatibility
619 1914           SPVM_BASIC_TYPE* parent_basic_type = basic_type;
620             while (1) {
621 4090 100         if (!parent_basic_type) {
622 1906           break;
623             }
624            
625 2184           SPVM_METHOD* parent_method = SPVM_HASH_get(parent_basic_type->method_symtable, interface_method->name, strlen(interface_method->name));
626            
627 2184 100         if (parent_method) {
628 1952           int32_t method_compatibility = SPVM_BASIC_TYPE_check_method_compatibility(compiler, parent_basic_type, parent_method, interface_basic_type, interface_method, "interface");
629            
630 1952 100         if (method_compatibility == 0) {
631 8           return;
632             }
633             }
634 2176           parent_basic_type = parent_basic_type->parent;
635 2176           }
636             }
637             }
638             }
639             }
640              
641            
642 3444           void SPVM_CHECK_check_basic_types_ast(SPVM_COMPILER* compiler) {
643 56782 100         for (int32_t basic_type_id = compiler->basic_types_base_id; basic_type_id < compiler->basic_types->length; basic_type_id++) {
644 53663           SPVM_BASIC_TYPE* basic_type = SPVM_LIST_get(compiler->basic_types, basic_type_id);
645            
646 53663           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, basic_type->name, strlen(basic_type->name));
647            
648 53663 100         if (basic_type->class_dir) {
649 24315           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, basic_type->class_dir, strlen(basic_type->class_dir));
650             }
651 53663 100         if (basic_type->class_rel_file) {
652 39627           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, basic_type->class_rel_file, strlen(basic_type->class_rel_file));
653             }
654 53663 100         if (basic_type->version_string) {
655 167           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, basic_type->version_string, strlen(basic_type->version_string));
656             }
657            
658            
659 60694 100         for (int32_t class_var_index = 0; class_var_index < basic_type->class_vars->length; class_var_index++) {
660 7031           SPVM_CLASS_VAR* class_var = SPVM_LIST_get(basic_type->class_vars, class_var_index);
661 7031           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, class_var->name, strlen(class_var->name));
662             }
663            
664 79277 100         for (int32_t field_index = 0; field_index < basic_type->fields->length; field_index++) {
665 25614           SPVM_FIELD* field = SPVM_LIST_get(basic_type->fields, field_index);
666 25614           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, field->name, strlen(field->name));
667             }
668            
669 352940 100         for (int32_t method_index = 0; method_index < basic_type->methods->length; method_index++) {
670 299277           SPVM_METHOD* method = SPVM_LIST_get(basic_type->methods, method_index);
671 299277           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, method->name, strlen(method->name));
672             }
673            
674 53663           int32_t compile_error = 0;
675 352615 100         for (int32_t method_index = 0; method_index < basic_type->methods->length; method_index++) {
676 299277           SPVM_METHOD* method = SPVM_LIST_get(basic_type->methods, method_index);
677             // AST traversals
678 299277 100         if (method->op_block) {
679 227981           SPVM_CHECK_check_ast_check_op_types(compiler, basic_type, method);
680 227981 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
681 10           return;
682             }
683            
684             // AST traversal - Check syntax and generate some operations
685 227971           SPVM_CHECK_check_ast_check_syntax(compiler, basic_type, method);
686 227971 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
687 315           return;
688             }
689            
690             // AST traversal - assign an unassigned operator to a variable
691 227656           SPVM_CHECK_check_ast_assign_unassigned_op_to_var(compiler, basic_type, method);
692 227656 50         assert(SPVM_COMPILER_get_error_messages_length(compiler) == 0);
693            
694             // AST traversal - Check if a block needs "leave scope" operation
695 227656           SPVM_CHECK_check_ast_check_if_block_need_leave_scope(compiler, basic_type, method);
696 227656 50         assert(SPVM_COMPILER_get_error_messages_length(compiler) == 0);
697            
698             // AST traversal - Check call stack ids of variable declarations
699 227656           SPVM_CHECK_check_ast_check_runtime_var_indexs(compiler, basic_type, method);
700 227656 50         assert(SPVM_COMPILER_get_error_messages_length(compiler) == 0);
701             }
702             }
703            
704             // String pool must end with "\0"
705             // This is not needed, but maybe there are bugs in other places
706 53338           SPVM_STRING_BUFFER_add_len(basic_type->string_pool, "\0\0\0\0", 4);
707             }
708             }
709              
710 3098359           void SPVM_CHECK_check_op_type(SPVM_COMPILER* compiler, SPVM_OP* op_type) {
711            
712 3098359           SPVM_TYPE* type = op_type->uv.type;
713            
714 3098359 100         if (type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_UNKNOWN) {
715 443273           const char* unresolved_basic_type_name = type->unresolved_basic_type_name;
716            
717 443273 50         assert(unresolved_basic_type_name);
718            
719 443273           SPVM_BASIC_TYPE* found_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, unresolved_basic_type_name, strlen(unresolved_basic_type_name));
720 443273 100         if (found_basic_type) {
721 443262           type->basic_type = found_basic_type;
722             }
723             }
724            
725             // Basic type name
726 3098359           const char* basic_type_name = type->basic_type->name;
727            
728 3098359 100         if (type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_UNKNOWN) {
729 11           const char* if_require_not_found_basic_type_name = SPVM_HASH_get(compiler->if_require_not_found_basic_type_name_symtable, type->unresolved_basic_type_name, strlen(type->unresolved_basic_type_name));
730            
731 11 100         if (!if_require_not_found_basic_type_name) {
732 6           SPVM_COMPILER_error(compiler, "The \"%s\" class is not found.\n at %s line %d", type->unresolved_basic_type_name, op_type->file, op_type->line);
733 6           return;
734             }
735             }
736            
737             // Reference type must be numeric refernce type or multi-numeric reference type
738 3098353 100         if (SPVM_TYPE_is_ref_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
739 4062 100         if (!(SPVM_TYPE_is_numeric_ref_type(compiler, type->basic_type->id, type->dimension, type->flag) || SPVM_TYPE_is_mulnum_ref_type(compiler, type->basic_type->id, type->dimension, type->flag))) {
    100          
740 2           SPVM_COMPILER_error(compiler, "The reference type must be a numeric refernce type or a multi-numeric reference type.\n at %s line %d", op_type->file, op_type->line);
741             }
742             }
743              
744             // mutable only allow string type
745 3098353 100         if (type->flag & SPVM_NATIVE_C_TYPE_FLAG_MUTABLE && !(type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_STRING && type->dimension == 0)) {
    100          
    100          
746 3           SPVM_COMPILER_error(compiler, "The type qualifier \"mutable\" is only allowed in the string type.\n at %s line %d", op_type->file, op_type->line);
747             }
748            
749 3098353 100         if (type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_ANY_OBJECT && type->dimension > 1) {
    100          
750 2           const char* type_name = SPVM_TYPE_new_type_name(compiler, type->basic_type->id, type->dimension, type->flag);
751 2           SPVM_COMPILER_error(compiler, "The multi dimensional array of any object is not allowed.\n at %s line %d", op_type->file, op_type->line);
752             }
753            
754              
755             }
756              
757 3492           void SPVM_CHECK_check_op_types(SPVM_COMPILER* compiler) {
758            
759 3492           SPVM_LIST* op_types = compiler->op_types;
760            
761             // Check type names
762 3086268 100         for (int32_t i = 0; i < op_types->length; i++) {
763 3082776           SPVM_OP* op_type = SPVM_LIST_get(op_types, i);
764            
765 3082776 100         if (!op_type->uv.type->resolved_in_ast) {
766 2561134           SPVM_CHECK_check_op_type(compiler, op_type);
767             }
768             }
769 3492           }
770              
771 26140           void SPVM_CHECK_check_class_var_access(SPVM_COMPILER* compiler, SPVM_OP* op_class_var_access, const char* current_basic_type_name) {
772            
773 26140 100         if (op_class_var_access->uv.class_var_access->class_var) {
774 13068           return;
775             }
776 13072 50         assert(op_class_var_access->uv.class_var_access);
777            
778 13072           SPVM_OP* op_name = op_class_var_access->uv.class_var_access->op_name;
779            
780             char* basic_type_name;
781             char* base_name;
782            
783 13072           const char* name = op_name->uv.name;
784            
785 13072           char* colon_ptr = strrchr(name, ':');
786 13072 100         if (colon_ptr) {
787             // Basic type name
788             // (end - start + 1) - $ - colon * 2
789 504           int32_t basic_type_name_length = (colon_ptr - name + 1) - 1 - 2;
790 504           basic_type_name = SPVM_ALLOCATOR_alloc_memory_block_permanent(compiler->current_each_compile_allocator, basic_type_name_length + 1);
791 504           memcpy(basic_type_name, name + 1, basic_type_name_length);
792            
793             // Base name($foo)
794 504           int32_t base_name_length = 1 + (name + strlen(name) - 1) - colon_ptr;
795 504           base_name = SPVM_ALLOCATOR_alloc_memory_block_permanent(compiler->current_each_compile_allocator, base_name_length + 1);
796 504           base_name[0] = '$';
797 504           memcpy(base_name + 1, colon_ptr + 1, base_name_length);
798             }
799             else {
800 12568           basic_type_name = (char*)current_basic_type_name;
801 12568           base_name = (char*)name;
802             }
803            
804 13072           SPVM_BASIC_TYPE* found_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, basic_type_name, strlen(basic_type_name));
805 13072 50         if (found_basic_type) {
806 13072           SPVM_CLASS_VAR* found_class_var = SPVM_HASH_get(found_basic_type->class_var_symtable, base_name, strlen(base_name));
807 13072 100         if (found_class_var) {
808 13068           op_class_var_access->uv.class_var_access->class_var = found_class_var;
809             }
810             }
811             }
812              
813 174621           void SPVM_CHECK_check_field_access(SPVM_COMPILER* compiler, SPVM_OP* op_field_access) {
814              
815 174621           SPVM_FIELD_ACCESS* field_access = op_field_access->uv.field_access;
816              
817 174621 50         if (field_access->field) {
818 0           return;
819             }
820              
821 174621           SPVM_OP* op_operand = op_field_access->first;
822 174621           SPVM_OP* op_name = field_access->op_name;
823            
824 174621           SPVM_TYPE* invocant_type = SPVM_CHECK_get_type(compiler, op_operand);
825 174621           SPVM_BASIC_TYPE* basic_type = SPVM_HASH_get(compiler->basic_type_symtable, invocant_type->basic_type->name, strlen(invocant_type->basic_type->name));
826 174621           const char* field_name = op_name->uv.name;
827              
828             // Search the field of the super class
829 174621           SPVM_FIELD* found_field = NULL;
830 174621           SPVM_BASIC_TYPE* parent_basic_type = basic_type;
831            
832             while (1) {
833 174622           found_field = SPVM_HASH_get(
834             parent_basic_type->field_symtable,
835             field_name,
836 174622           strlen(field_name)
837             );
838 174622 100         if (found_field) {
839 174619           break;
840             }
841 3           parent_basic_type = parent_basic_type->parent;
842 3 100         if (!parent_basic_type) {
843 2           break;
844             }
845 1           }
846            
847 174621 100         if (found_field) {
848 174619           op_field_access->uv.field_access->field = found_field;
849             }
850             else {
851 2           SPVM_COMPILER_error(compiler, "The \"%s\" field is not found in the \"%s\" class and its super classes.\n at %s line %d", field_name, basic_type->name, op_field_access->file, op_field_access->line);
852 2           return;
853             }
854             }
855              
856 55061           void SPVM_CHECK_check_field_offset(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type) {
857 55061 100         if (basic_type->category != SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_CLASS) {
858 20528           return;
859             }
860            
861             int32_t alignment_size;
862             if (sizeof(void*) > sizeof(int64_t)) {
863             alignment_size = sizeof(void*);
864             }
865             else {
866 34533           alignment_size = sizeof(int64_t);
867             }
868            
869 34533           int32_t alignment_index = 0;
870 34533           int32_t offset = 0;
871             int32_t offset_size;
872            
873             // 8 byte data
874 59809 100         for (int32_t field_index = 0; field_index < basic_type->fields->length; field_index++) {
875 25276           SPVM_FIELD* field = SPVM_LIST_get(basic_type->fields, field_index);
876 25276           SPVM_TYPE* field_type = field->type;
877            
878             int32_t next_offset;
879 25276 100         if (SPVM_TYPE_is_double_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag)
880 23862 100         || SPVM_TYPE_is_long_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag)) {
881 2828           offset_size = 8;
882             }
883 22448 100         else if (SPVM_TYPE_is_float_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag)
884 21034 100         || SPVM_TYPE_is_int_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag)) {
885 10072           offset_size = 4;
886             }
887 12376 100         else if (SPVM_TYPE_is_short_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag)) {
888 1414           offset_size = 2;
889             }
890 10962 100         else if (SPVM_TYPE_is_byte_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag)) {
891 2137           offset_size = 1;
892             }
893 8825 50         else if (SPVM_TYPE_is_object_type(compiler, field_type->basic_type->id, field_type->dimension, field_type->flag)) {
894 8825           offset_size = sizeof(void*);
895             }
896             else {
897 0           assert(0);
898             }
899            
900 25276           next_offset = offset + offset_size;
901            
902 25276 100         if (next_offset % offset_size != 0) {
903 756           offset += (offset_size - offset % offset_size);
904             }
905            
906 25276 100         if (next_offset == alignment_size * (alignment_index + 1)) {
907 12839           alignment_index++;
908             }
909 12437 100         else if (next_offset > alignment_size * (alignment_index + 1)) {
910 1566           alignment_index++;
911             // Next alignment
912 1566           offset += (alignment_size - offset % alignment_size);
913            
914 1566 50         assert(offset % alignment_size == 0);
915             }
916            
917 25276           field->offset = offset;
918            
919 25276           offset += offset_size;
920             }
921            
922 34533           basic_type->fields_size = offset;
923             }
924              
925 251795           void SPVM_CHECK_check_call_method(SPVM_COMPILER* compiler, SPVM_OP* op_call_method, const char* current_basic_type_name) {
926            
927 251795           SPVM_CALL_METHOD* call_method = op_call_method->uv.call_method;
928            
929 251795 50         if (call_method->method) {
930 0           return;
931             }
932            
933 251795           const char* method_name = call_method->op_name->uv.name;
934            
935             // Class method call
936 251795 100         if (call_method->is_class_method) {
937 165151           SPVM_METHOD* found_method = NULL;
938             // Basic type name + method name
939             const char* basic_type_name;
940 165151 100         if (call_method->is_current) {
941 50309           basic_type_name = current_basic_type_name;
942             }
943             else {
944 114842           SPVM_OP* op_type_basic_type = op_call_method->last;
945 114842           basic_type_name = op_type_basic_type->uv.type->basic_type->name;
946             }
947            
948 165151           SPVM_BASIC_TYPE* found_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, basic_type_name, strlen(basic_type_name));
949            
950 165151           found_method = SPVM_HASH_get(
951             found_basic_type->method_symtable,
952             method_name,
953 165151           strlen(method_name)
954             );
955            
956 165151 100         if (found_method && !found_method->is_class_method) {
    100          
957 1           found_method = NULL;
958             }
959            
960 165151 100         if (found_method) {
961 165146           call_method->method = found_method;
962             }
963             else {
964 5           SPVM_COMPILER_error(compiler, "The \"%s\" method in the \"%s\" class is not found.\n at %s line %d", method_name, found_basic_type->name, op_call_method->file, op_call_method->line);
965 165151           return;
966             }
967             }
968             // Instance method call
969             else {
970 86644           SPVM_OP* op_list_args = op_call_method->first;
971 86644           SPVM_OP* op_invocant = SPVM_OP_sibling(compiler, op_list_args->first);
972            
973 86644           SPVM_TYPE* type = SPVM_CHECK_get_type(compiler, op_invocant);
974 86644 100         if (!(SPVM_TYPE_is_class_type(compiler, type->basic_type->id, type->dimension, type->flag) || SPVM_TYPE_is_interface_type(compiler, type->basic_type->id, type->dimension, type->flag))) {
    100          
975 2           SPVM_COMPILER_error(compiler, "The invocant of the \"%s\" method must be a class type or an interface type.\n at %s line %d", method_name, op_call_method->file, op_call_method->line);
976 2           return;
977             }
978            
979 86642           const char* basic_type_name = type->basic_type->name;
980            
981 86642           SPVM_BASIC_TYPE* basic_type = SPVM_HASH_get(compiler->basic_type_symtable, basic_type_name, strlen(basic_type_name));
982              
983             // Static instance method call
984 86642           char* last_colon_pos = strrchr(method_name, ':');
985 86642 100         if (last_colon_pos) {
986 114           const char* abs_method_name = method_name;
987 114           call_method->is_class_method_instance_method_call = 1;
988 114           method_name = last_colon_pos + 1;
989 114           int32_t basic_type_name_length = (last_colon_pos - 1) - abs_method_name;
990            
991             // SUPER::
992 114           SPVM_METHOD* found_method = NULL;
993 114 100         if (strstr(abs_method_name, "SUPER::") == abs_method_name) {
994 105           SPVM_BASIC_TYPE* parent_basic_type = basic_type->parent;
995 105 100         if (parent_basic_type) {
996             // Search the method of the super class
997 105           found_method = SPVM_CHECK_search_method(compiler, parent_basic_type, method_name);
998             }
999             }
1000             else {
1001 9           SPVM_BASIC_TYPE* found_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, abs_method_name, basic_type_name_length);
1002 9 50         if (!found_basic_type) {
1003 0           basic_type = found_method->current_basic_type;
1004 0           SPVM_COMPILER_error(compiler, "The class specified in the \"%s\" method call is not found..\n at %s line %d", abs_method_name, op_call_method->file, op_call_method->line);
1005 0           return;
1006             }
1007 9 50         if (found_basic_type) {
1008 9           found_method = SPVM_HASH_get(
1009             found_basic_type->method_symtable,
1010             method_name,
1011 9           strlen(method_name)
1012             );
1013             }
1014             }
1015            
1016 114 100         if (found_method) {
1017 112           basic_type = found_method->current_basic_type;
1018 112 50         if (found_method->is_class_method) {
1019 0           SPVM_COMPILER_error(compiler, "The \"%s\" method in the \"%s\" class is found, but this is not an instance method.\n at %s line %d", abs_method_name, basic_type->name, op_call_method->file, op_call_method->line);
1020 0           return;
1021             }
1022 112           call_method->method = found_method;
1023             }
1024             else {
1025 2           SPVM_COMPILER_error(compiler, "The \"%s\" method is not found.\n at %s line %d", abs_method_name, op_call_method->file, op_call_method->line);
1026 114           return;
1027             }
1028             }
1029             // Instance method
1030             else {
1031 86528           SPVM_METHOD* found_method = SPVM_CHECK_search_method(compiler, basic_type, method_name);
1032            
1033 86528 100         if (found_method) {
1034 86523 100         if (found_method->is_class_method) {
1035 3           basic_type = found_method->current_basic_type;
1036 3           SPVM_COMPILER_error(compiler, "The \"%s\" method in the \"%s\" class is found, but this is not an instance method.\n at %s line %d", method_name, basic_type->name, op_call_method->file, op_call_method->line);
1037 3           return;
1038             }
1039 86520           call_method->method = found_method;
1040             }
1041             else {
1042 5           SPVM_COMPILER_error(compiler, "The \"%s\" method is not found in the \"%s\" class and its super classes .\n at %s line %d", method_name, basic_type->name, op_call_method->file, op_call_method->line);
1043 5           return;
1044             }
1045             }
1046             }
1047             }
1048              
1049 227981           void SPVM_CHECK_check_ast_check_op_types(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, SPVM_METHOD* method) {
1050            
1051             // Run OPs
1052 227981           SPVM_OP* op_root = method->op_block;
1053 227981           SPVM_OP* op_cur = op_root;
1054 227981           int32_t finish = 0;
1055 17655410 50         while (op_cur) {
1056             // [START]Preorder traversal position
1057 17655410 100         if (op_cur->id == SPVM_OP_C_ID_IF_REQUIRE) {
1058 12           SPVM_USE* use = op_cur->first->uv.use;
1059 12           SPVM_OP* op_block_true = SPVM_OP_sibling(compiler, op_cur->first);
1060 12           SPVM_OP* op_block_false = op_cur->last;
1061            
1062             // Execute false block
1063 12           const char* use_basic_type_name = use->op_type->uv.type->unresolved_basic_type_name;
1064            
1065 12           SPVM_BASIC_TYPE* found_basic_type = SPVM_HASH_get(compiler->basic_type_symtable, use_basic_type_name, strlen(use_basic_type_name));
1066            
1067 12 100         if (found_basic_type) {
1068 7           SPVM_OP_cut_op(compiler, op_block_true);
1069 7           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
1070 7           SPVM_OP_replace_op(compiler, op_stab, op_block_true);
1071 7           op_cur = op_block_true;
1072             }
1073             // Execute true block
1074             else {
1075 5           SPVM_OP_cut_op(compiler, op_block_false);
1076 5           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
1077 5           SPVM_OP_replace_op(compiler, op_stab, op_block_false);
1078 5           op_cur = op_block_false;
1079             }
1080             }
1081            
1082 17655410 100         if (op_cur->first) {
1083 9442085           op_cur = op_cur->first;
1084             }
1085             else {
1086             while (1) {
1087             // [START]Postorder traversal position
1088 17655378 100         switch (op_cur->id) {
1089             case SPVM_OP_C_ID_TYPE: {
1090 763662           SPVM_OP* op_type = op_cur;
1091 763662 100         if (op_type->uv.type->resolved_in_ast) {
1092 537225           const char* unresolved_basic_type_name_maybe_alias = op_type->uv.type->unresolved_basic_type_name;
1093            
1094 537225           SPVM_HASH* alias_symtable = NULL;
1095 537225 100         if (basic_type->is_anon) {
1096 24224           alias_symtable = basic_type->outer->alias_symtable;
1097             }
1098             else {
1099 513001           alias_symtable = basic_type->alias_symtable;
1100             }
1101            
1102 537225           const char* unresolved_basic_type_name = SPVM_HASH_get(alias_symtable, unresolved_basic_type_name_maybe_alias, strlen(unresolved_basic_type_name_maybe_alias));
1103 537225 100         if (unresolved_basic_type_name) {
1104 10           op_type->uv.type->unresolved_basic_type_name = unresolved_basic_type_name;
1105 10           op_type->uv.type->basic_type = SPVM_LIST_get(compiler->basic_types, 0);
1106             }
1107            
1108 537225           SPVM_CHECK_check_op_type(compiler, op_type);
1109 537225 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1110 10           return;
1111             }
1112            
1113 537215           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, op_type->uv.type->basic_type->name, strlen(op_type->uv.type->basic_type->name));
1114             }
1115 763652           break;
1116             }
1117             }
1118            
1119 17655368 100         if (op_cur == op_root) {
1120            
1121             // Finish
1122 227971           finish = 1;
1123            
1124 227971           break;
1125             }
1126            
1127             // Next sibling
1128 17427397 100         if (op_cur->moresib) {
1129 7985344           op_cur = SPVM_OP_sibling(compiler, op_cur);
1130 7985344           break;
1131             }
1132             // Next is parent
1133             else {
1134 9442053           op_cur = op_cur->sibparent;
1135             }
1136 9442053           }
1137 8213315 100         if (finish) {
1138 227971           break;
1139             }
1140             }
1141             }
1142             }
1143              
1144 227971           void SPVM_CHECK_check_ast_check_syntax(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, SPVM_METHOD* method) {
1145            
1146 227971 50         if (!method->op_block) {
1147 0           return;
1148             }
1149            
1150             // Eval block stack length
1151 227971           int32_t eval_block_stack_length = 0;
1152            
1153             // Loop block stack length
1154 227971           int32_t loop_block_stack_length = 0;
1155            
1156 227971           SPVM_LIST* var_decl_stack = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_PERMANENT);
1157 227971           SPVM_LIST* var_decl_scope_base_stack = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_PERMANENT);
1158 227971           SPVM_LIST* op_switch_stack = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_PERMANENT);
1159            
1160             // Check tree
1161 227971           SPVM_OP* op_root = method->op_block;
1162 227971           SPVM_OP* op_cur = op_root;
1163 227971           int32_t finish = 0;
1164 17654639 50         while (op_cur) {
1165             // [START]Preorder traversal position
1166            
1167 17654639           switch (op_cur->id) {
1168             case SPVM_OP_C_ID_BLOCK: {
1169 1550488           SPVM_BLOCK* block = op_cur->uv.block;
1170             // Start scope
1171 1550488 100         if (!block->no_scope) {
1172 1318493           int32_t block_var_decl_base = var_decl_stack->length;
1173 1318493           SPVM_LIST_push(var_decl_scope_base_stack, (void*)(intptr_t)block_var_decl_base);
1174             }
1175            
1176 1550488 100         if (block->id == SPVM_BLOCK_C_ID_LOOP_STATEMENTS) {
1177 68679           loop_block_stack_length++;
1178             }
1179 1481809 100         else if (block->id == SPVM_BLOCK_C_ID_EVAL) {
1180 2074           eval_block_stack_length++;
1181             }
1182            
1183 1550488           break;
1184             }
1185             case SPVM_OP_C_ID_SWITCH: {
1186 1648           SPVM_LIST_push(op_switch_stack, op_cur);
1187 1648           break;
1188             }
1189             }
1190             // [END]Preorder traversal position
1191            
1192 17654639 100         if (op_cur->first) {
1193 9441832           op_cur = op_cur->first;
1194             }
1195             else {
1196             while (1) {
1197             // [START]Postorder traversal position
1198 17653825           switch (op_cur->id) {
1199             case SPVM_OP_C_ID_NEXT: {
1200 23 100         if (loop_block_stack_length == 0) {
1201 2           SPVM_COMPILER_error(compiler, "The next statement must be in a loop block.\n at %s line %d", op_cur->file, op_cur->line);
1202 2           return;
1203             }
1204 21           break;
1205             }
1206             case SPVM_OP_C_ID_LAST: {
1207 12035 100         if (loop_block_stack_length == 0) {
1208 2           SPVM_COMPILER_error(compiler, "The last statement must be in a loop block.\n at %s line %d", op_cur->file, op_cur->line);
1209 2           return;
1210             }
1211 12033           break;
1212             }
1213             case SPVM_OP_C_ID_BREAK: {
1214 8000 100         if (op_switch_stack->length == 0) {
1215 2           SPVM_COMPILER_error(compiler, "The break statement must be in a switch block.\n at %s line %d", op_cur->file, op_cur->line);
1216 2           return;
1217             }
1218 7998           break;
1219             }
1220             case SPVM_OP_C_ID_CURRENT_CLASS_NAME: {
1221 3           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
1222 3           SPVM_OP* op_constant = SPVM_OP_new_op_constant_string(compiler, basic_type->name, strlen(basic_type->name), op_cur->file, op_cur->line);
1223 3           SPVM_OP_replace_op(compiler, op_stab, op_constant);
1224 3           op_cur = op_constant;
1225            
1226 3           break;
1227             }
1228             case SPVM_OP_C_ID_TYPE_NAME: {
1229            
1230 2101           SPVM_OP* op_operand = op_cur->first;
1231            
1232 2101           SPVM_TYPE* operand_type = SPVM_CHECK_get_type(compiler, op_operand);
1233            
1234             // Must be object type
1235 2101 100         if (!SPVM_TYPE_is_object_type(compiler, operand_type->basic_type->id, operand_type->dimension, operand_type->flag)) {
1236 1           SPVM_COMPILER_error(compiler, "The operand of the type_name operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
1237 1           return;
1238             }
1239            
1240 2100           break;
1241             }
1242             case SPVM_OP_C_ID_COMPILE_TYPE_NAME: {
1243            
1244 14           SPVM_OP* op_operand = op_cur->first;
1245            
1246 14           SPVM_TYPE* operand_type = SPVM_CHECK_get_type(compiler, op_operand);
1247 14           const char* type_name = SPVM_TYPE_new_type_name(compiler, operand_type->basic_type->id, operand_type->dimension, operand_type->flag);
1248 14           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
1249 14           SPVM_OP* op_constant_string = SPVM_OP_new_op_constant_string(compiler, type_name, strlen(type_name), op_cur->file, op_cur->line);
1250 14           SPVM_OP_replace_op(compiler, op_stab, op_constant_string);
1251 14           op_cur = op_constant_string;
1252            
1253 14           break;
1254             }
1255             case SPVM_OP_C_ID_DUMP: {
1256            
1257 58           SPVM_OP* op_operand = op_cur->first;
1258            
1259 58           SPVM_TYPE* operand_type = SPVM_CHECK_get_type(compiler, op_operand);
1260            
1261             // Must be object type
1262 58 100         if (!SPVM_TYPE_is_object_type(compiler, operand_type->basic_type->id, operand_type->dimension, operand_type->flag)) {
1263 1           SPVM_COMPILER_error(compiler, "The operand of the dump operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
1264 1           return;
1265             }
1266            
1267 57           break;
1268             }
1269             case SPVM_OP_C_ID_NEW_STRING_LEN: {
1270            
1271 4716           SPVM_OP* op_length = op_cur->first;
1272            
1273 4716           SPVM_TYPE* length_type = SPVM_CHECK_get_type(compiler, op_length);
1274            
1275 4716 50         assert(length_type);
1276            
1277 4716 100         if (!SPVM_TYPE_is_integer_type_within_int(compiler, length_type->basic_type->id, length_type->dimension, length_type->flag)) {
1278 1           SPVM_COMPILER_error(compiler, "The operand of the new_string_len operator must be an integer type within int.\n at %s line %d", op_cur->file, op_cur->line);
1279 1           return;
1280             }
1281            
1282 4715           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_length);
1283            
1284 4715           break;
1285             }
1286            
1287             case SPVM_OP_C_ID_BASIC_TYPE_ID: {
1288            
1289             // Nothing to do
1290            
1291 64           break;
1292             }
1293             case SPVM_OP_C_ID_SWITCH: {
1294            
1295 1645           SPVM_OP* op_switch_condition = op_cur->first;
1296            
1297             // Perform numeric widening conversion
1298            
1299 1645           SPVM_TYPE* operand_type = SPVM_CHECK_get_type(compiler, op_switch_condition->first);
1300 1645 100         if (!SPVM_TYPE_is_integer_type_within_int(compiler, operand_type->basic_type->id, operand_type->dimension, operand_type->flag)) {
1301 1           SPVM_COMPILER_error(compiler, "The condition of the switch statement must be an integer type within int.\n at %s line %d", op_cur->file, op_cur->line);
1302 1           return;
1303             }
1304            
1305 1644           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_switch_condition->first->first);
1306            
1307 1644           SPVM_SWITCH_INFO* switch_info = op_cur->uv.switch_info;
1308 1644           SPVM_LIST* cases = switch_info->case_infos;
1309 1644           int32_t cases_length = cases->length;
1310            
1311             // sort by asc order
1312 11197 100         for (int32_t i = 0; i < switch_info->case_infos->length; i++) {
1313 39951 100         for (int32_t j = i + 1; j < switch_info->case_infos->length; j++) {
1314 30398           SPVM_CASE_INFO* case_i = SPVM_LIST_get(switch_info->case_infos, i);
1315 30398           SPVM_CASE_INFO* case_j = SPVM_LIST_get(switch_info->case_infos, j);
1316 30398           int32_t match_i = case_i->case_value;
1317 30398           int32_t match_j = case_j->case_value;
1318            
1319 30398 100         if (match_i > match_j) {
1320 5228           SPVM_LIST_set(switch_info->case_infos, i, case_j);
1321 5228           SPVM_LIST_set(switch_info->case_infos, j, case_i);
1322             }
1323             }
1324             }
1325            
1326             // Check duplication
1327 9560 100         for (int32_t i = 0; i < switch_info->case_infos->length - 1; i++) {
1328 7916           SPVM_CASE_INFO* case_info = SPVM_LIST_get(switch_info->case_infos, i);
1329 7916           SPVM_CASE_INFO* case_info_next = SPVM_LIST_get(switch_info->case_infos, i + 1);
1330 7916 100         if (case_info->case_value == case_info_next->case_value) {
1331 2           SPVM_COMPILER_error(compiler, "The value of the case statement cannnot be duplicated.\n at %s line %d", case_info->op_case_info->file, case_info->op_case_info->line);
1332             }
1333             }
1334            
1335 1644           SPVM_LIST_pop(op_switch_stack);
1336            
1337             // Decide switch type
1338 1644           switch_info->id = SPVM_SWITCH_INFO_C_ID_LOOKUP_SWITCH;
1339            
1340 1644 100         if (!switch_info->op_default) {
1341 1077           SPVM_OP* op_switch_block = op_cur->last;
1342            
1343 1077           SPVM_OP* op_default = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_DEFAULT, op_cur->file, op_cur->line);
1344 1077           SPVM_OP* op_block = SPVM_OP_new_op_block(compiler, op_cur->file, op_cur->line);
1345 1077           SPVM_OP_build_default_statement(compiler, op_default, op_block);
1346            
1347 1077           SPVM_OP_insert_child(compiler, op_switch_block, op_switch_block->last, op_default);
1348             }
1349            
1350 1644           break;
1351             }
1352             case SPVM_OP_C_ID_CASE: {
1353 9556 50         if (op_switch_stack->length > 0) {
1354 9556           SPVM_OP* op_switch = SPVM_LIST_get(op_switch_stack, op_switch_stack->length - 1);
1355 9556           SPVM_SWITCH_INFO* switch_info = op_switch->uv.switch_info;
1356 9556           SPVM_LIST_push(switch_info->case_infos, op_cur->uv.case_info);
1357             }
1358            
1359 9556           SPVM_CASE_INFO* case_info = op_cur->uv.case_info;
1360 9556           SPVM_OP* op_constant = op_cur->first;
1361 9556           SPVM_CONSTANT* constant = op_constant->uv.constant;
1362            
1363 9556           SPVM_TYPE* case_value_type = SPVM_CHECK_get_type(compiler, op_constant);
1364 19110           if (!(
1365 9556           op_constant->id == SPVM_OP_C_ID_CONSTANT &&
1366             (
1367 12312 100         SPVM_TYPE_is_byte_type(compiler, case_value_type->basic_type->id, case_value_type->dimension, case_value_type->flag) ||
1368 2758           SPVM_TYPE_is_int_type(compiler, case_value_type->basic_type->id, case_value_type->dimension, case_value_type->flag)
1369             )
1370             ))
1371             {
1372 3           SPVM_COMPILER_error(compiler, "The operand of the case statement must be an integer literal of the int type, a character litaral, or an enumeration value.\n at %s line %d", op_cur->file, op_cur->line);
1373 3           return;
1374             }
1375            
1376             // Upgrade byte to int
1377 9553 100         if (constant->type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE) {
1378 6796           constant->type = SPVM_TYPE_new_int_type(compiler);
1379 6796           constant->value.ival = (int32_t)constant->value.bval;
1380             }
1381            
1382 9553           case_info->case_value = constant->value.ival;
1383            
1384             // Remove case value operation because this is a constant value for a case statemenet.
1385 9553           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur->first);
1386 9553           SPVM_OP* op_do_nothing = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_DO_NOTHING, op_cur->first->file, op_cur->first->line);
1387 9553           SPVM_OP_replace_op(compiler, op_stab, op_do_nothing);
1388            
1389 9553           break;
1390             }
1391             case SPVM_OP_C_ID_DEFAULT: {
1392 567 50         if (op_switch_stack->length > 0) {
1393 567           SPVM_OP* op_switch = SPVM_LIST_get(op_switch_stack, op_switch_stack->length - 1);
1394 567           SPVM_SWITCH_INFO* switch_info = op_switch->uv.switch_info;
1395            
1396 567           switch_info->op_default = op_cur;
1397             }
1398 567           break;
1399             }
1400             case SPVM_OP_C_ID_BOOL: {
1401 680453           SPVM_OP* op_first = op_cur->first;
1402 680453           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1403            
1404             int32_t is_valid_type;
1405            
1406             // undef type
1407 680453 100         if (SPVM_TYPE_is_undef_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1408            
1409 9           is_valid_type = 1;
1410            
1411 9           SPVM_OP* op_constant_zero = SPVM_OP_new_op_constant_int(compiler, 0, op_first->file, op_first->line);
1412 9           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_first);
1413 9           SPVM_OP_replace_op(compiler, op_stab, op_constant_zero);
1414             }
1415             // Numeric type
1416 680444 100         else if (SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag))
1417             {
1418             // Convert byte or short type to int type
1419 607480           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_first);
1420 607480 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1421 0           return;
1422             }
1423 607480           is_valid_type = 1;
1424             }
1425             // Object type
1426 72964 100         else if (SPVM_TYPE_is_object_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1427 72957           is_valid_type = 1;
1428             }
1429             // Reference type
1430 7 100         else if (SPVM_TYPE_is_ref_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1431 6           is_valid_type = 1;
1432             }
1433             else {
1434 1           is_valid_type = 0;
1435             }
1436            
1437 680453 100         if (!is_valid_type) {
1438 1           SPVM_COMPILER_error(compiler, "The operand of the bool type conversion must be a numeric type or an object type or the reference type or the undef type.\n at %s line %d", op_cur->file, op_cur->line);
1439 1           return;
1440             }
1441            
1442 680452           break;
1443             }
1444             case SPVM_OP_C_ID_NUMERIC_EQ: {
1445 68252           SPVM_OP* op_first = op_cur->first;
1446              
1447 68252           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1448 68252           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1449            
1450             // undef == undef
1451 68257 100         if (SPVM_TYPE_is_undef_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_undef_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    100          
1452             // Constant 1
1453 5           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
1454 5           SPVM_OP* op_constant_one = SPVM_OP_new_op_constant_int(compiler, 1, op_first->file, op_first->line);
1455 5           SPVM_OP_replace_op(compiler, op_stab, op_constant_one);
1456 5           op_cur = op_constant_one;
1457             }
1458             // value_op == undef
1459 85175 100         else if (!SPVM_TYPE_is_undef_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_undef_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    100          
1460 16929           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1461 16929 100         if (!SPVM_TYPE_is_object_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1462 1           SPVM_COMPILER_error(compiler, "The left operand of the == operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
1463 1           return;
1464             }
1465             }
1466             // undef == value_op
1467 51323 100         else if (SPVM_TYPE_is_undef_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && !SPVM_TYPE_is_undef_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    50          
1468 6           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1469 6 100         if (!SPVM_TYPE_is_object_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1470 1           SPVM_COMPILER_error(compiler, "The right operand of the == operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
1471 1           return;
1472             }
1473             }
1474             // value_op == value_op
1475             else {
1476             int32_t is_valid_type;
1477            
1478             // Numeric type
1479 51312 100         if (SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    100          
1480            
1481 50521           is_valid_type = 1;
1482            
1483 50521           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
1484 50521 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1485 0           return;
1486             }
1487             }
1488             // Object type
1489 791 100         else if (SPVM_TYPE_is_object_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_object_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    50          
1490 790           is_valid_type = 1;
1491             }
1492             // Reference type
1493 1 50         else if (SPVM_TYPE_is_ref_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_ref_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    0          
1494 0           is_valid_type = 1;
1495             }
1496             else {
1497 1           is_valid_type = 0;
1498             }
1499            
1500 51312 100         if (!is_valid_type) {
1501 1           SPVM_COMPILER_error(compiler, "The left and right operands of the == operator must be numeric types or object types or reference types.\n at %s line %d", op_cur->file, op_cur->line);
1502 1           return;
1503             }
1504             }
1505            
1506 68249           break;
1507             }
1508             case SPVM_OP_C_ID_NUMERIC_NE: {
1509 18004           SPVM_OP* op_first = op_cur->first;
1510              
1511 18004           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1512 18004           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1513            
1514             // undef == undef
1515 18009 100         if (SPVM_TYPE_is_undef_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_undef_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    100          
1516             // Constant 0
1517 5           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
1518 5           SPVM_OP* op_constant_zero = SPVM_OP_new_op_constant_int(compiler, 0, op_first->file, op_first->line);
1519 5           SPVM_OP_replace_op(compiler, op_stab, op_constant_zero);
1520 5           op_cur = op_constant_zero;
1521             }
1522             // value_op == undef
1523 26357 100         else if (!SPVM_TYPE_is_undef_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_undef_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    100          
1524 8359           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1525 8359 100         if (!SPVM_TYPE_is_object_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1526 1           SPVM_COMPILER_error(compiler, "The left operand of the != operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
1527 1           return;
1528             }
1529             }
1530             // undef == value_op
1531 9644 100         else if (SPVM_TYPE_is_undef_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && !SPVM_TYPE_is_undef_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    50          
1532 5           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1533 5 100         if (!SPVM_TYPE_is_object_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1534 1           SPVM_COMPILER_error(compiler, "The right operand of the != operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
1535 1           return;
1536             }
1537             }
1538             // value_op == value_op
1539             else {
1540             int32_t is_valid_type;
1541            
1542             // Numeric type
1543 9635 100         if (SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    100          
1544            
1545 9596           is_valid_type = 1;
1546            
1547 9596           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
1548 9596 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1549 0           return;
1550             }
1551             }
1552             // Object type
1553 39 100         else if (SPVM_TYPE_is_object_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_object_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    50          
1554 30           is_valid_type = 1;
1555             }
1556             // Reference type
1557 9 100         else if (SPVM_TYPE_is_ref_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) && SPVM_TYPE_is_ref_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    50          
1558 8           is_valid_type = 1;
1559             }
1560             else {
1561 1           is_valid_type = 0;
1562             }
1563            
1564 9635 100         if (!is_valid_type) {
1565 1           SPVM_COMPILER_error(compiler, "The left and right operands of the != operator must be numeric types or object types or reference types.\n at %s line %d", op_cur->file, op_cur->line);
1566 1           return;
1567             }
1568             }
1569            
1570 18001           break;
1571             }
1572             case SPVM_OP_C_ID_NUMERIC_GT: {
1573              
1574 21100           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1575 21100           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1576              
1577             // Left operand must be a numeric type
1578 21100 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1579 2           SPVM_COMPILER_error(compiler, "The left operand of the > operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1580 2           return;
1581             }
1582              
1583             // Right operand must be a numeric type
1584 21098 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1585 1           SPVM_COMPILER_error(compiler, "The right operand of the > operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1586 1           return;
1587             }
1588              
1589             // Apply binary numeric conversion
1590 21097           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
1591 21097 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1592 0           return;
1593             }
1594            
1595 21097           break;
1596             }
1597             case SPVM_OP_C_ID_NUMERIC_GE: {
1598              
1599 69612           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1600 69612           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1601              
1602             // Left operand must be a numeric type
1603 69612 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1604 2           SPVM_COMPILER_error(compiler, "The left operand of the >= operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1605 2           return;
1606             }
1607              
1608             // Right operand must be a numeric type
1609 69610 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1610 1           SPVM_COMPILER_error(compiler, "The right operand of the >= operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1611 1           return;
1612             }
1613              
1614             // Apply binary numeric conversion
1615 69609           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
1616 69609 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1617 0           return;
1618             }
1619            
1620 69609           break;
1621             }
1622             case SPVM_OP_C_ID_NUMERIC_LT: {
1623              
1624 80875           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1625 80875           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1626            
1627             // Left operand must be a numeric type
1628 80875 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1629 2           SPVM_COMPILER_error(compiler, "The left operand of the < operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1630 2           return;
1631             }
1632              
1633             // Right operand must be a numeric type
1634 80873 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1635 1           SPVM_COMPILER_error(compiler, "The right operand of the < operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1636 1           return;
1637             }
1638              
1639             // Apply binary numeric conversion
1640 80872           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
1641 80872 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1642 0           return;
1643             }
1644              
1645 80872           break;
1646             }
1647             case SPVM_OP_C_ID_NUMERIC_LE: {
1648              
1649 74664           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1650 74664           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1651              
1652             // Left operand must be a numeric type
1653 74664 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1654 2           SPVM_COMPILER_error(compiler, "The left operand of the <= operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1655 2           return;
1656             }
1657              
1658             // Right operand must be a numeric type
1659 74662 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1660 1           SPVM_COMPILER_error(compiler, "The right operand of the <= operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1661 1           return;
1662             }
1663              
1664             // Apply binary numeric conversion
1665 74661           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
1666 74661 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1667 0           return;
1668             }
1669            
1670 74661           break;
1671             }
1672             case SPVM_OP_C_ID_NUMERIC_CMP: {
1673              
1674 6476           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1675 6476           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1676              
1677             // Left operand must be a numeric type
1678 6476 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1679 1           SPVM_COMPILER_error(compiler, "The left operand of the <=> operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1680 1           return;
1681             }
1682              
1683             // Right operand must be a numeric type
1684 6475 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1685 1           SPVM_COMPILER_error(compiler, "The right operand of the <=> operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
1686 1           return;
1687             }
1688              
1689             // Apply binary numeric conversion
1690 6474           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
1691 6474 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1692 0           return;
1693             }
1694            
1695 6474           break;
1696             }
1697             case SPVM_OP_C_ID_STRING_EQ: {
1698 10437           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1699 10437           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1700            
1701             // Left operand must be the string type
1702 10437 50         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1703 0           SPVM_COMPILER_error(compiler, "The left operand of the eq operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1704 0           return;
1705             }
1706            
1707             // Right operand must be the string type
1708 10437 50         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1709 0           SPVM_COMPILER_error(compiler, "The right operand of the eq operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1710 0           return;
1711             }
1712            
1713 10437           break;
1714             }
1715             case SPVM_OP_C_ID_STRING_NE: {
1716 567           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1717 567           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1718            
1719             // Left operand must be the string type
1720 567 50         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1721 0           SPVM_COMPILER_error(compiler, "The left operand of the ne operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1722 0           return;
1723             }
1724            
1725             // Right operand must be the string type
1726 567 50         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1727 0           SPVM_COMPILER_error(compiler, "The right operand of the ne operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1728 0           return;
1729             }
1730            
1731 567           break;
1732             }
1733             case SPVM_OP_C_ID_STRING_GT: {
1734 46           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1735 46           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1736            
1737             // Left operand must be the string type
1738 46 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1739 1           SPVM_COMPILER_error(compiler, "The left operand of the gt operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1740 1           return;
1741             }
1742            
1743             // Right operand must be the string type
1744 45 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1745 1           SPVM_COMPILER_error(compiler, "The right operand of the gt operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1746 1           return;
1747             }
1748            
1749 44           break;
1750             }
1751             case SPVM_OP_C_ID_STRING_GE: {
1752 46           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1753 46           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1754            
1755             // Left operand must be the string type
1756 46 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1757 1           SPVM_COMPILER_error(compiler, "The left operand of the ge operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1758 1           return;
1759             }
1760            
1761             // Right operand must be the string type
1762 45 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1763 1           SPVM_COMPILER_error(compiler, "The right operand of the ge operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1764 1           return;
1765             }
1766            
1767 44           break;
1768             }
1769             case SPVM_OP_C_ID_STRING_LT: {
1770 46           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1771 46           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1772            
1773             // Left operand must be the string type
1774 46 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1775 1           SPVM_COMPILER_error(compiler, "The left operand of the lt operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1776 1           return;
1777             }
1778            
1779             // Right operand must be the string type
1780 45 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1781 1           SPVM_COMPILER_error(compiler, "The right operand of the lt operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1782 1           return;
1783             }
1784            
1785 44           break;
1786             }
1787             case SPVM_OP_C_ID_STRING_LE: {
1788 46           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1789 46           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1790            
1791             // Left operand must be the string type
1792 46 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1793 1           SPVM_COMPILER_error(compiler, "The left operand of the le operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1794 1           return;
1795             }
1796            
1797             // Right operand must be the string type
1798 45 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1799 1           SPVM_COMPILER_error(compiler, "The right operand of the le operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1800 1           return;
1801             }
1802            
1803 44           break;
1804             }
1805             case SPVM_OP_C_ID_STRING_CMP: {
1806 1630           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1807 1630           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1808            
1809             // Left operand must be the string type
1810 1630 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1811 1           SPVM_COMPILER_error(compiler, "The left operand of the cmp operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1812 1           return;
1813             }
1814            
1815             // Right operand must be the string type
1816 1629 100         if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1817 1           SPVM_COMPILER_error(compiler, "The right operand of the cmp operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1818 1           return;
1819             }
1820            
1821 1628           break;
1822             }
1823             case SPVM_OP_C_ID_CONCAT: {
1824 36385           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1825 36385           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1826            
1827             // Left type is numeric type
1828 36385 100         if (SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1829 146           SPVM_CHECK_perform_numeric_to_string_conversion(compiler, op_cur->first);
1830 146 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1831 0           return;
1832             }
1833             }
1834             // Left type is not string type or byte array type
1835 36239 100         else if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
1836 2           SPVM_COMPILER_error(compiler, "The left operand of the . operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1837 2           return;
1838             }
1839            
1840             // Right operand is numeric type
1841 36383 100         if (SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1842 1481           SPVM_CHECK_perform_numeric_to_string_conversion(compiler, op_cur->last);
1843 1481 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1844 0           return;
1845             }
1846             }
1847             // Right operand is not string type or byte array type
1848 34902 100         else if (!SPVM_TYPE_is_string_or_byte_array_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
1849 3           SPVM_COMPILER_error(compiler, "The right operand of the . operator must be the string type or the byte[] type.\n at %s line %d", op_cur->file, op_cur->line);
1850 3           return;
1851             }
1852            
1853 36380           break;
1854             }
1855             case SPVM_OP_C_ID_CONSTANT : {
1856 936703           SPVM_OP* op_constant = op_cur;
1857            
1858 936703           SPVM_TYPE* constant_type = SPVM_CHECK_get_type(compiler, op_constant);
1859            
1860 936703 100         if (SPVM_TYPE_is_string_type(compiler, constant_type->basic_type->id, constant_type->dimension, constant_type->flag)) {
1861 195193           SPVM_CONSTANT* constant = op_constant->uv.constant;
1862            
1863 195193           const char* constant_string_value = constant->value.oval;
1864 195193           int32_t constant_string_length = constant->string_length;
1865            
1866 195193           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, constant_string_value, constant_string_length);
1867             }
1868            
1869 936703           break;
1870             }
1871             case SPVM_OP_C_ID_NEW: {
1872 54016           SPVM_OP* op_new = op_cur;
1873            
1874 54016 50         assert(op_new->first);
1875 54016 100         assert(op_new->first->id == SPVM_OP_C_ID_TYPE || op_new->first->id == SPVM_OP_C_ID_VAR);
    50          
1876            
1877 54016           SPVM_TYPE* type = SPVM_CHECK_get_type(compiler, op_new);
1878            
1879 54016           SPVM_BASIC_TYPE* new_basic_type = type->basic_type;
1880            
1881             // Array type
1882 54016 100         if (SPVM_TYPE_is_array_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
1883            
1884 29859           SPVM_OP* op_length = op_new->last;
1885            
1886 29859           SPVM_TYPE* length_type = SPVM_CHECK_get_type(compiler, op_length);
1887            
1888 29859 50         assert(length_type);
1889 29859 100         if (!SPVM_TYPE_is_integer_type_within_int(compiler, length_type->basic_type->id, length_type->dimension, length_type->flag)) {
1890 1           const char* type_name = SPVM_TYPE_new_type_name(compiler, type->basic_type->id, type->dimension, type->flag);
1891 1           SPVM_COMPILER_error(compiler, "The array length specified by the new operator must be an integer type within int.\n at %s line %d", op_new->file, op_new->line);
1892 1           return;
1893             }
1894 29858           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_length);
1895             }
1896             // Numeric type
1897 24157 100         else if (SPVM_TYPE_is_numeric_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
1898 1           SPVM_COMPILER_error(compiler, "The operand of the new operator cannnot be a numeric type.\n at %s line %d", op_new->file, op_new->line);
1899 1           return;
1900             }
1901             // Object type
1902 24156 50         else if (SPVM_TYPE_is_object_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
1903 24156           SPVM_BASIC_TYPE* basic_type = SPVM_HASH_get(compiler->basic_type_symtable, type->basic_type->name, strlen(type->basic_type->name));
1904            
1905 24156 100         if (basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_INTERFACE) {
1906 1           SPVM_COMPILER_error(compiler, "The operand of the new operator cannnot be an interface type.\n at %s line %d", op_new->file, op_new->line);
1907 1           return;
1908             }
1909 24155 50         else if (basic_type->category == SPVM_NATIVE_C_BASIC_TYPE_CATEGORY_MULNUM) {
1910 0           SPVM_COMPILER_error(compiler, "The operand of the new operator cannnot be a multi-numeric type.\n at %s line %d", op_new->file, op_new->line);
1911 0           return;
1912             }
1913              
1914 24155           SPVM_BASIC_TYPE* current_basic_type = method->current_basic_type;
1915 24155 100         if (!SPVM_CHECK_can_access(compiler, current_basic_type, new_basic_type, new_basic_type->access_control_type)) {
1916 1049 100         if (!SPVM_OP_is_allowed(compiler, current_basic_type, new_basic_type)) {
1917 3           SPVM_COMPILER_error(compiler, "The object of the %s \"%s\" class cannnot be created from the current class \"%s\".\n at %s line %d", SPVM_ATTRIBUTE_get_name(compiler, new_basic_type->access_control_type), new_basic_type->name, current_basic_type->name, op_new->file, op_new->line);
1918 24155           return;
1919             }
1920             }
1921             }
1922             else {
1923 0           assert(0);
1924             }
1925            
1926 54010           break;
1927             }
1928             case SPVM_OP_C_ID_BIT_XOR: {
1929 46           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1930 46           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
1931            
1932             // Can receive only integer type
1933 46 100         if (!SPVM_TYPE_is_integer_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) || !SPVM_TYPE_is_integer_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
    100          
1934 2           SPVM_COMPILER_error(compiler, "The left and right operand of the ^ operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
1935 2           return;
1936             }
1937            
1938 44           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
1939 44 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
1940 0           return;
1941             }
1942            
1943 44           break;
1944             }
1945             case SPVM_OP_C_ID_ISA: {
1946 4582           SPVM_TYPE* left_operand_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1947 4582           SPVM_OP* op_type = op_cur->last;
1948            
1949 4582           SPVM_TYPE* right_type = op_type->uv.type;
1950            
1951             int32_t compile_time_check;
1952 4582 100         if (SPVM_TYPE_is_numeric_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
1953 522           compile_time_check = 1;
1954             }
1955 4060 100         else if (SPVM_TYPE_is_mulnum_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
1956 4           compile_time_check = 1;
1957             }
1958 4056 100         else if (SPVM_TYPE_is_any_object_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
1959 2           compile_time_check = 1;
1960             }
1961 4054 50         else if (SPVM_TYPE_is_ref_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
1962 0           compile_time_check = 1;
1963             }
1964 4054 50         else if (SPVM_TYPE_is_object_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
1965 4054           compile_time_check = 0;
1966             }
1967             else {
1968 0           assert(0);
1969             }
1970            
1971 4582 100         if (compile_time_check) {
1972             // If left type is same as right type, this return true, otherwise return false
1973 1052 100         if (left_operand_type->basic_type->id == right_type->basic_type->id && left_operand_type->dimension == right_type->dimension) {
    50          
1974 524           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
1975 524           SPVM_OP* op_constant_true = SPVM_OP_new_op_constant_int(compiler, 1, op_cur->file, op_cur->line);
1976 524           SPVM_OP_replace_op(compiler, op_stab, op_constant_true);
1977 524           op_cur = op_constant_true;
1978             }
1979             else {
1980 4           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
1981 4           SPVM_OP* op_constant_false = SPVM_OP_new_op_constant_int(compiler, 0, op_cur->file, op_cur->line);
1982 4           SPVM_OP_replace_op(compiler, op_stab, op_constant_false);
1983 528           op_cur = op_constant_false;
1984             }
1985             }
1986             else {
1987             // Left left_operand must be object type
1988 4054 100         if (!SPVM_TYPE_is_object_type(compiler, left_operand_type->basic_type->id, left_operand_type->dimension, left_operand_type->flag)) {
1989 2           SPVM_COMPILER_error(compiler, "The left operand of the isa operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
1990 2           return;
1991             }
1992             }
1993            
1994 4580           break;
1995             }
1996             case SPVM_OP_C_ID_ISA_ERROR: {
1997            
1998 20           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
1999 20           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2000            
2001             // Left operand must be a numeric type
2002 20 100         if (!SPVM_TYPE_is_integer_type_within_int(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2003 1           SPVM_COMPILER_error(compiler, "The left operand of the isa_error operator must be an integer type within int.\n at %s line %d", op_cur->file, op_cur->line);
2004 1           return;
2005             }
2006 19           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->first);
2007            
2008 19 100         if (!SPVM_TYPE_is_class_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2009 2           SPVM_COMPILER_error(compiler, "The right operand of the isa_error operator must be a class type.\n at %s line %d", op_cur->file, op_cur->line);
2010 2           return;
2011             }
2012            
2013 17           break;
2014             }
2015             case SPVM_OP_C_ID_IS_TYPE: {
2016            
2017 3746           SPVM_TYPE* left_operand_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2018 3746           SPVM_OP* op_type = op_cur->last;
2019            
2020 3746           SPVM_TYPE* right_type = op_type->uv.type;
2021            
2022 3746 100         if (!SPVM_TYPE_is_object_type(compiler, left_operand_type->basic_type->id, left_operand_type->dimension, left_operand_type->flag)) {
2023 1           SPVM_COMPILER_error(compiler, "The left operand of the is_type operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
2024 1           return;
2025             }
2026            
2027 3745 100         if (!SPVM_TYPE_is_object_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
2028 1           SPVM_COMPILER_error(compiler, "The right type of the is_type operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
2029 1           return;
2030             }
2031            
2032 3744 100         if (SPVM_TYPE_is_any_object_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
2033 1           SPVM_COMPILER_error(compiler, "The right type of the is_type operator cannnot be the any object type.\n at %s line %d", op_cur->file, op_cur->line);
2034 1           return;
2035             }
2036            
2037 3743 100         if (SPVM_TYPE_is_any_object_array_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
2038 1           SPVM_COMPILER_error(compiler, "The right type of the is_type operator cannnot be the any object array type.\n at %s line %d", op_cur->file, op_cur->line);
2039 1           return;
2040             }
2041            
2042 3742 100         if (SPVM_TYPE_is_interface_type(compiler, right_type->basic_type->id, right_type->dimension, right_type->flag)) {
2043 1           SPVM_COMPILER_error(compiler, "The right type of the is_type operator cannnot be an interface type.\n at %s line %d", op_cur->file, op_cur->line);
2044 1           return;
2045             }
2046            
2047 3741           break;
2048             }
2049             case SPVM_OP_C_ID_IS_ERROR: {
2050            
2051 18           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2052 18           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2053            
2054             // Left operand must be a numeric type
2055 18 100         if (!SPVM_TYPE_is_integer_type_within_int(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2056 1           SPVM_COMPILER_error(compiler, "The left operand of the is_error operator must be an integer type within int.\n at %s line %d", op_cur->file, op_cur->line);
2057 1           return;
2058             }
2059 17           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->first);
2060            
2061 17 100         if (!SPVM_TYPE_is_class_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2062 2           SPVM_COMPILER_error(compiler, "The right operand of the is_error operator must be a class type.\n at %s line %d", op_cur->file, op_cur->line);
2063 2           return;
2064             }
2065            
2066 15           break;
2067             }
2068             case SPVM_OP_C_ID_IS_COMPILE_TYPE: {
2069 16           SPVM_TYPE* left_operand_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2070 16           SPVM_OP* op_type = op_cur->last;
2071            
2072 16           SPVM_TYPE* right_type = op_type->uv.type;
2073            
2074             // If left type is same as right type, this return true, otherwise return false
2075 32 50         if (left_operand_type->basic_type->id == right_type->basic_type->id && left_operand_type->dimension == right_type->dimension) {
    50          
2076 16           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
2077 16           SPVM_OP* op_constant_true = SPVM_OP_new_op_constant_int(compiler, 1, op_cur->file, op_cur->line);
2078 16           SPVM_OP_replace_op(compiler, op_stab, op_constant_true);
2079 16           op_cur = op_constant_true;
2080             }
2081             else {
2082 0           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
2083 0           SPVM_OP* op_constant_false = SPVM_OP_new_op_constant_int(compiler, 0, op_cur->file, op_cur->line);
2084 0           SPVM_OP_replace_op(compiler, op_stab, op_constant_false);
2085 0           op_cur = op_constant_false;
2086             }
2087            
2088 16           break;
2089             }
2090             case SPVM_OP_C_ID_ARRAY_LENGTH: {
2091 55740           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2092            
2093             // First value must be an array
2094 55740 100         if (!SPVM_TYPE_is_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2095 1           SPVM_COMPILER_error(compiler, "The right operand of the @ operator must be an array type.\n at %s line %d", op_cur->file, op_cur->line);
2096 1           return;
2097             }
2098            
2099 55739           break;
2100             }
2101             case SPVM_OP_C_ID_STRING_LENGTH: {
2102 20395           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2103            
2104             // First must be the string type
2105 20395 100         if (!SPVM_TYPE_is_string_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2106 1           SPVM_COMPILER_error(compiler, "The operand of the length operator must be the string type.\n at %s line %d", op_cur->file, op_cur->line);
2107 1           return;
2108             }
2109            
2110 20394           break;
2111             }
2112             case SPVM_OP_C_ID_ASSIGN: {
2113 2061542           SPVM_OP* op_dist = op_cur->last;
2114 2061542           SPVM_OP* op_src = op_cur->first;
2115            
2116 2061542           SPVM_TYPE* dist_type = SPVM_CHECK_get_type(compiler, op_dist);
2117            
2118             // Type inference
2119 2061542 100         if (op_dist->id == SPVM_OP_C_ID_VAR) {
2120 1789586           SPVM_VAR_DECL* var_decl = op_dist->uv.var->var_decl;
2121 1789586 100         if (var_decl->type == NULL) {
2122 477919           var_decl->type = SPVM_CHECK_get_type(compiler, op_src);
2123             }
2124 1789586 50         assert(var_decl->type);
2125 1789586 100         if (SPVM_TYPE_is_undef_type(compiler, var_decl->type->basic_type->id, var_decl->type->dimension, var_decl->type->flag)) {
2126 2           SPVM_COMPILER_error(compiler, "The type of \"%s\" cannnot be detected.\n at %s line %d", op_dist->uv.var->name, var_decl->op_var_decl->file, var_decl->op_var_decl->line);
2127 2           return;
2128             }
2129 1789584           op_dist->uv.var->is_initialized = 1;
2130             }
2131            
2132             // Check if source can be assigned to dist
2133             // If needed, numeric conversion op is added
2134 2061540           dist_type = SPVM_CHECK_get_type(compiler, op_dist);
2135 2061540           SPVM_CHECK_check_assign(compiler, dist_type, op_src, "the assignment operator", op_cur->file, op_cur->line);
2136 2061540 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2137 73           return;
2138             }
2139              
2140             // If dist is string access and const, it is invalid
2141 2061467 100         if (op_dist->id == SPVM_OP_C_ID_ARRAY_ACCESS && op_dist->flag & SPVM_OP_C_FLAG_ARRAY_ACCESS_STRING) {
    100          
2142 5777           SPVM_OP* op_array = op_dist->first;
2143 5777           SPVM_TYPE* array_type = SPVM_CHECK_get_type(compiler, op_array);
2144 5777           int32_t is_mutable = array_type->flag & SPVM_NATIVE_C_TYPE_FLAG_MUTABLE;
2145              
2146 5777 100         if(!is_mutable) {
2147 2           SPVM_COMPILER_error(compiler, "Characters cannot be set to non-mutable strings.\n at %s line %d", op_dist->file, op_dist->line);
2148 2           return;
2149             }
2150             }
2151            
2152 2061465           break;
2153             }
2154             case SPVM_OP_C_ID_RETURN: {
2155            
2156 421235           SPVM_OP* op_operand = op_cur->first;
2157            
2158             // Void type
2159 421235 100         if (SPVM_TYPE_is_void_type(compiler, method->return_type->basic_type->id, method->return_type->dimension, method->return_type->flag)) {
2160 99636 100         if (op_operand) {
2161 1           SPVM_COMPILER_error(compiler, "The void method cannnot return the value.\n at %s line %d", op_cur->file, op_cur->line);
2162 1           return;
2163             }
2164             }
2165             else {
2166 321599 100         if (op_operand) {
2167             // Automatical numeric conversion
2168 321598           SPVM_CHECK_check_assign(compiler, method->return_type, op_operand, "the return statement", op_cur->file, op_cur->line);
2169 321598 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2170 1           return;
2171             }
2172             }
2173             else {
2174 1           SPVM_COMPILER_error(compiler, "The non-void method must return a value.\n at %s line %d", op_cur->file, op_cur->line);
2175 1           return;
2176             }
2177             }
2178              
2179 421232           break;
2180             }
2181             case SPVM_OP_C_ID_PLUS: {
2182 40           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2183            
2184             // Operand must be a numeric type
2185 40 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2186 2           SPVM_COMPILER_error(compiler, "The operand of the unary + operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2187 2           return;
2188             }
2189              
2190             // Apply unary widening conversion
2191 38           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->first);
2192 38 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2193 0           return;
2194             }
2195            
2196 38           break;
2197             }
2198             case SPVM_OP_C_ID_MINUS: {
2199 1086           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2200            
2201             // Operand must be a numeric type
2202 1086 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2203 2           SPVM_COMPILER_error(compiler, "The operand of the unary - operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2204 2           return;
2205             }
2206            
2207             // Apply unary widening conversion
2208 1084           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->first);
2209 1084 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2210 0           return;
2211             }
2212            
2213 1084           break;
2214             }
2215             case SPVM_OP_C_ID_COPY: {
2216 1630           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2217            
2218             // Operand must be a numeric type
2219 1630 100         if (!SPVM_TYPE_is_object_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2220 1           SPVM_COMPILER_error(compiler, "The operand of the copy operator must be an object type.\n at %s line %d", op_cur->file, op_cur->line);
2221 1           return;
2222             }
2223            
2224 1629           break;
2225             }
2226             case SPVM_OP_C_ID_BIT_NOT: {
2227 38           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2228            
2229             // Operand must be a numeric type
2230 38 100         if (!SPVM_TYPE_is_integer_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2231 1           SPVM_COMPILER_error(compiler, "The operand of the ~ operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2232 1           return;
2233             }
2234              
2235             // Apply unary widening conversion
2236 37           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->first);
2237 37 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2238 0           return;
2239             }
2240            
2241 37           break;
2242             }
2243             case SPVM_OP_C_ID_ADD: {
2244 186938           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2245 186938           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2246            
2247             // Left operand must be a numeric type
2248 186938 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2249 4 100         if (op_cur->original_id == SPVM_OP_C_ID_PRE_INC || op_cur->original_id == SPVM_OP_C_ID_POST_INC) {
    100          
2250 2           SPVM_COMPILER_error(compiler, "The operand of the increment operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2251             }
2252             else {
2253 2           SPVM_COMPILER_error(compiler, "The left operand of the + operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2254             }
2255            
2256 4           return;
2257             }
2258            
2259             // Right operand must be a numeric type
2260 186934 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2261 2           SPVM_COMPILER_error(compiler, "The right operand of the + operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2262 2           return;
2263             }
2264            
2265             // Apply binary numeric conversion
2266 186932           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
2267 186932 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2268 0           return;
2269             }
2270            
2271 186932           break;
2272             }
2273             case SPVM_OP_C_ID_SUBTRACT: {
2274 70406           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2275 70406           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2276            
2277             // Left operand must be a numeric type
2278 70406 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2279 4 100         if (op_cur->original_id == SPVM_OP_C_ID_PRE_DEC || op_cur->original_id == SPVM_OP_C_ID_POST_DEC) {
    100          
2280 2           SPVM_COMPILER_error(compiler, "The operand of the decrement operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2281             }
2282             else {
2283 2           SPVM_COMPILER_error(compiler, "The left operand of the - operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2284             }
2285 4           return;
2286             }
2287              
2288             // Right operand must be a numeric type
2289 70402 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2290 2           SPVM_COMPILER_error(compiler, "The right operand of the - operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2291 2           return;
2292             }
2293            
2294             // Apply binary numeric conversion
2295 70400           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
2296 70400 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2297 0           return;
2298             }
2299            
2300 70400           break;
2301             }
2302             case SPVM_OP_C_ID_MULTIPLY: {
2303 7587           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2304 7587           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2305            
2306             // Left operand must be a numeric type
2307 7587 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2308 2           SPVM_COMPILER_error(compiler, "The left operand of the * operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2309 2           return;
2310             }
2311              
2312             // Right operand must be a numeric type
2313 7585 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2314 2           SPVM_COMPILER_error(compiler, "The right operand of the * operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2315 2           return;
2316             }
2317              
2318             // Apply binary numeric conversion
2319 7583           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
2320 7583 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2321 0           return;
2322             }
2323            
2324 7583           break;
2325             }
2326             case SPVM_OP_C_ID_DIVIDE: {
2327 5402           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2328 5402           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2329            
2330             // Left operand must be a numeric type
2331 5402 100         if (!SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2332 2           SPVM_COMPILER_error(compiler, "The left operand of the / operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2333 2           return;
2334             }
2335              
2336             // Right operand must be a numeric type
2337 5400 100         if (!SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2338 2           SPVM_COMPILER_error(compiler, "The right operand of the / operator must be a numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2339 2           return;
2340             }
2341            
2342             // Apply binary numeric conversion
2343 5398           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
2344 5398 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2345 0           return;
2346             }
2347              
2348 5398           break;
2349             }
2350             case SPVM_OP_C_ID_DIVIDE_UNSIGNED_INT: {
2351 7           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2352 7           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2353            
2354             // Left operand must be a numeric type
2355 7 100         if (!SPVM_TYPE_is_int_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2356 2           SPVM_COMPILER_error(compiler, "The left operand of the divui operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2357 2           return;
2358             }
2359              
2360             // Right operand must be a numeric type
2361 5 100         if (!SPVM_TYPE_is_int_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2362 2           SPVM_COMPILER_error(compiler, "The right operand of the divui operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2363 2           return;
2364             }
2365            
2366 3           break;
2367             }
2368             case SPVM_OP_C_ID_DIVIDE_UNSIGNED_LONG: {
2369 7           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2370 7           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2371            
2372             // Left operand must be a numeric type
2373 7 100         if (!SPVM_TYPE_is_long_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2374 2           SPVM_COMPILER_error(compiler, "The left operand of the divul operator must be the long type.\n at %s line %d", op_cur->file, op_cur->line);
2375 2           return;
2376             }
2377              
2378             // Right operand must be a numeric type
2379 5 100         if (!SPVM_TYPE_is_long_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2380 2           SPVM_COMPILER_error(compiler, "The right operand of the divul operator must be the long type.\n at %s line %d", op_cur->file, op_cur->line);
2381 2           return;
2382             }
2383            
2384 3           break;
2385             }
2386             case SPVM_OP_C_ID_REMAINDER: {
2387 2178           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2388 2178           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2389            
2390             // Left operand must be integer type
2391 2178 100         if (!SPVM_TYPE_is_integer_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2392 3           SPVM_COMPILER_error(compiler, "The left operand of the %% operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2393 3           return;
2394             }
2395              
2396             // Right operand must be integer type
2397 2175 100         if (!SPVM_TYPE_is_integer_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2398 3           SPVM_COMPILER_error(compiler, "The right operand of the %% operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2399 3           return;
2400             }
2401            
2402             // Apply binary numeric conversion
2403 2172           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
2404 2172 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2405 0           return;
2406             }
2407            
2408 2172           break;
2409             }
2410             case SPVM_OP_C_ID_REMAINDER_UNSIGNED_INT: {
2411 7           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2412 7           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2413            
2414             // Left operand must be a numeric type
2415 7 100         if (!SPVM_TYPE_is_int_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2416 2           SPVM_COMPILER_error(compiler, "The left operand of the remui operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2417 2           return;
2418             }
2419              
2420             // Right operand must be a numeric type
2421 5 100         if (!SPVM_TYPE_is_int_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2422 2           SPVM_COMPILER_error(compiler, "The right operand of the remui operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2423 2           return;
2424             }
2425            
2426 3           break;
2427             }
2428             case SPVM_OP_C_ID_REMAINDER_UNSIGNED_LONG: {
2429 529           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2430 529           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2431            
2432             // Left operand must be a numeric type
2433 529 100         if (!SPVM_TYPE_is_long_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2434 2           SPVM_COMPILER_error(compiler, "The left operand of the remul operator must be the long type.\n at %s line %d", op_cur->file, op_cur->line);
2435 2           return;
2436             }
2437              
2438             // Right operand must be a numeric type
2439 527 100         if (!SPVM_TYPE_is_long_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2440 2           SPVM_COMPILER_error(compiler, "The right operand of the remul operator must be the long type.\n at %s line %d", op_cur->file, op_cur->line);
2441 2           return;
2442             }
2443            
2444 525           break;
2445             }
2446             case SPVM_OP_C_ID_BIT_AND: {
2447 1112           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2448 1112           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2449            
2450             // Left operand must be integer type
2451 1112 100         if (!SPVM_TYPE_is_integer_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2452 1           SPVM_COMPILER_error(compiler, "The left operand of the & operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2453 1           return;
2454             }
2455              
2456             // Right operand must be integer type
2457 1111 100         if (!SPVM_TYPE_is_integer_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2458 1           SPVM_COMPILER_error(compiler, "The right operand of the & operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2459 1           return;
2460             }
2461            
2462 1110           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
2463 1110 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2464 0           return;
2465             }
2466            
2467 1110           break;
2468             }
2469             case SPVM_OP_C_ID_BIT_OR: {
2470 46           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2471 46           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2472            
2473             // Left operand must be integer type
2474 46 100         if (!SPVM_TYPE_is_integer_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2475 1           SPVM_COMPILER_error(compiler, "The left operand of the | operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2476 1           return;
2477             }
2478              
2479             // Right operand must be integer type
2480 45 100         if (!SPVM_TYPE_is_integer_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2481 1           SPVM_COMPILER_error(compiler, "The right operand of the | operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2482 1           return;
2483             }
2484            
2485 44           SPVM_CHECK_perform_binary_numeric_conversion(compiler, op_cur->first, op_cur->last);
2486 44 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2487 0           return;
2488             }
2489            
2490 44           break;
2491             }
2492             case SPVM_OP_C_ID_LEFT_SHIFT: {
2493 54           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2494 54           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2495            
2496             // Left operand must be a numeric type
2497 54 100         if (SPVM_TYPE_is_integer_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2498 53           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->first);
2499 53 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2500 0           return;
2501             }
2502             }
2503             else {
2504 1           SPVM_COMPILER_error(compiler, "The left operand of the << operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2505 1           return;
2506             }
2507            
2508             // Right operand must be int type
2509 53 100         if (SPVM_TYPE_is_integer_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2510 52           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->last);
2511 52 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2512 0           return;
2513             }
2514            
2515 52 50         if (last_type->dimension == 0 && last_type->basic_type->id >= SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) {
    100          
2516 1           SPVM_COMPILER_error(compiler, "The right operand of the << operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2517 1           return;
2518             }
2519             }
2520             else {
2521 1           SPVM_COMPILER_error(compiler, "The right operand of the << operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2522 1           return;
2523             }
2524            
2525 51           break;
2526             }
2527             case SPVM_OP_C_ID_RIGHT_ARITHMETIC_SHIFT: {
2528 38           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2529 38           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2530            
2531             // Left operand must be a numeric type
2532 38 100         if (SPVM_TYPE_is_integer_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2533 37           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->first);
2534 37 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2535 0           return;
2536             }
2537             }
2538             else {
2539 1           SPVM_COMPILER_error(compiler, "The left operand of the >> operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2540 1           return;
2541             }
2542            
2543             // Right operand must be int type
2544 37 100         if (SPVM_TYPE_is_integer_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2545 36           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->last);
2546 36 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2547 0           return;
2548             }
2549            
2550 36 50         if (last_type->dimension == 0 && last_type->basic_type->id >= SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) {
    100          
2551 1           SPVM_COMPILER_error(compiler, "The right operand of the >> operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2552 1           return;
2553             }
2554             }
2555             else {
2556 1           SPVM_COMPILER_error(compiler, "The right operand of the >> operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2557 1           return;
2558             }
2559            
2560 35           break;
2561             }
2562             case SPVM_OP_C_ID_RIGHT_LOGICAL_SHIFT: {
2563 38           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2564 38           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2565            
2566             // Left operand must be a numeric type
2567 38 100         if (SPVM_TYPE_is_integer_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2568 37           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->first);
2569 37 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2570 0           return;
2571             }
2572             }
2573             else {
2574 1           SPVM_COMPILER_error(compiler, "The left operand of the >>> operator must be an integer type.\n at %s line %d", op_cur->file, op_cur->line);
2575 1           return;
2576             }
2577            
2578             // Right operand must be int type
2579 37 100         if (SPVM_TYPE_is_integer_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2580 36           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->last);
2581 36 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2582 0           return;
2583             }
2584            
2585 36 50         if (last_type->dimension == 0 && last_type->basic_type->id >= SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) {
    100          
2586 1           SPVM_COMPILER_error(compiler, "The right operand of the >>> operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2587 1           return;
2588             }
2589             }
2590             else {
2591 1           SPVM_COMPILER_error(compiler, "The right operand of the >>> operator must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2592 1           return;
2593             }
2594            
2595 35           break;
2596             }
2597             case SPVM_OP_C_ID_DIE: {
2598 140297           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2599            
2600 140297 100         if (!SPVM_TYPE_is_class_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2601 1           SPVM_COMPILER_error(compiler, "The error class of the die statement must be a class type.\n at %s line %d", op_cur->file, op_cur->line);
2602             }
2603            
2604 140297           break;
2605             }
2606             case SPVM_OP_C_ID_WARN: {
2607 260           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2608            
2609 260 100         if (SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2610 23           SPVM_CHECK_perform_numeric_to_string_conversion(compiler, op_cur->first);
2611 23 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2612 0           return;
2613             }
2614             }
2615            
2616 260           first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2617            
2618 261           if (!(SPVM_TYPE_is_string_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)
2619 1           || SPVM_TYPE_is_undef_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag))) {
2620 1           SPVM_COMPILER_error(compiler, "The operand of the warn operator must be the string type or the undef type.\n at %s line %d", op_cur->file, op_cur->line);
2621 1           return;
2622             }
2623 259           break;
2624             }
2625             case SPVM_OP_C_ID_PRINT: {
2626 253           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2627            
2628 253 50         if (SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2629 0           SPVM_CHECK_perform_numeric_to_string_conversion(compiler, op_cur->first);
2630 0 0         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2631 0           return;
2632             }
2633             }
2634            
2635 253           first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2636            
2637 253 100         if (!SPVM_TYPE_is_string_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2638 1           SPVM_COMPILER_error(compiler, "The operand of the print operator must be the string type.\n at %s line %d", op_cur->file, op_cur->line);
2639 1           return;
2640             }
2641 252           break;
2642             }
2643             case SPVM_OP_C_ID_SAY: {
2644 60           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2645            
2646 60 50         if (SPVM_TYPE_is_numeric_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2647 0           SPVM_CHECK_perform_numeric_to_string_conversion(compiler, op_cur->first);
2648 0 0         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2649 0           return;
2650             }
2651             }
2652            
2653 60           first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2654            
2655 60 50         if (!SPVM_TYPE_is_string_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2656 0           SPVM_COMPILER_error(compiler, "The operand of the say operator must be the string type.\n at %s line %d", op_cur->file, op_cur->line);
2657 0           return;
2658             }
2659 60           break;
2660             }
2661             case SPVM_OP_C_ID_MAKE_READ_ONLY: {
2662 1050           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2663            
2664 1050           first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2665            
2666 1050 100         if (!SPVM_TYPE_is_string_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2667 1           SPVM_COMPILER_error(compiler, "The operand of the make_read_only operator must be the string type.\n at %s line %d", op_cur->file, op_cur->line);
2668 1           return;
2669             }
2670 1049           break;
2671             }
2672             case SPVM_OP_C_ID_IS_READ_ONLY: {
2673 1055           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2674            
2675 1055           first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2676            
2677 1055 100         if (!SPVM_TYPE_is_string_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2678 1           SPVM_COMPILER_error(compiler, "The operand of the is_read_only operator must be the string type.\n at %s line %d", op_cur->file, op_cur->line);
2679 1           return;
2680             }
2681 1054           break;
2682             }
2683             case SPVM_OP_C_ID_BLOCK: {
2684 1550156           SPVM_BLOCK* block = op_cur->uv.block;
2685             // End of scope
2686 1550156 100         if (!block->no_scope) {
2687             // Pop block var_decl variable base
2688 1318163 50         assert(var_decl_scope_base_stack->length > 0);
2689 1318163           int32_t block_var_decl_base = (intptr_t)SPVM_LIST_pop(var_decl_scope_base_stack);
2690            
2691 1318163           int32_t var_decl_stack_pop_count = var_decl_stack->length - block_var_decl_base;
2692            
2693 2551894 100         for (int32_t i = 0; i < var_decl_stack_pop_count; i++) {
2694 1233731           SPVM_LIST_pop(var_decl_stack);
2695             }
2696             }
2697            
2698             // Pop loop block var_decl variable base
2699 1550156 100         if (block->id == SPVM_BLOCK_C_ID_LOOP_STATEMENTS) {
2700 68679           loop_block_stack_length--;
2701             }
2702             // Pop try block var_decl variable base
2703 1481477 100         else if (block->id == SPVM_BLOCK_C_ID_EVAL) {
2704 2074           eval_block_stack_length--;
2705             }
2706            
2707 1550156           break;
2708             }
2709             case SPVM_OP_C_ID_CREATE_REF: {
2710            
2711 5032           SPVM_OP* op_var = op_cur->first;
2712 5032           SPVM_TYPE* var_type = SPVM_CHECK_get_type(compiler, op_var);
2713 5032 100         if (!(SPVM_TYPE_is_numeric_type(compiler, var_type->basic_type->id, var_type->dimension, var_type->flag) || SPVM_TYPE_is_mulnum_type(compiler, var_type->basic_type->id, var_type->dimension, var_type->flag))) {
    100          
2714 1           SPVM_COMPILER_error(compiler, "The operand of the refernece operator must be a numeric type or a multi-numeric type.\n at %s line %d", op_cur->file, op_cur->line);
2715 1           return;
2716             }
2717            
2718 5031           break;
2719             }
2720             case SPVM_OP_C_ID_DEREF: {
2721 3584           SPVM_OP* op_var = op_cur->first;
2722 3584           SPVM_TYPE* var_type = SPVM_CHECK_get_type(compiler, op_var);
2723            
2724 3584 100         if (!(SPVM_TYPE_is_numeric_ref_type(compiler, var_type->basic_type->id, var_type->dimension, var_type->flag) || SPVM_TYPE_is_mulnum_ref_type(compiler, var_type->basic_type->id, var_type->dimension, var_type->flag))) {
    100          
2725 1           SPVM_COMPILER_error(compiler, "The operand of the dereference operaotr must be a numeric reference type or a multi-numeric reference type.\n at %s line %d", op_cur->file, op_cur->line);
2726 1           return;
2727             }
2728            
2729 3583           break;
2730             }
2731             // Local variable or class variable
2732             case SPVM_OP_C_ID_VAR: {
2733            
2734 4847328 100         if (op_cur->uv.var->is_declaration) {
2735            
2736 1234287           SPVM_VAR_DECL* var_decl = op_cur->uv.var->var_decl;
2737            
2738             // Redeclaration error if same name variable is declare in same block
2739 1234287           int32_t found = 0;
2740 1234287           int32_t block_var_decl_base = (intptr_t)SPVM_LIST_get(var_decl_scope_base_stack, var_decl_scope_base_stack->length - 1);
2741 4078573 100         for (int32_t i = block_var_decl_base; i < var_decl_stack->length; i++) {
2742 2844290           SPVM_VAR_DECL* bef_var_decl = SPVM_LIST_get(var_decl_stack, i);
2743            
2744 2844290 100         if (strcmp(var_decl->var->name, bef_var_decl->var->name) == 0) {
2745             // Temporaly variable is not duplicated
2746 4 50         if (strncmp(var_decl->var->name, "$.", 2) != 0) {
2747 4           found = 1;
2748             }
2749 4           break;
2750             }
2751             }
2752            
2753 1234287 100         if (found) {
2754 4           SPVM_COMPILER_error(compiler, "Redeclaration of the variable \"%s\".\n at %s line %d", var_decl->var->name, var_decl->op_var_decl->file, var_decl->op_var_decl->line);
2755 4           return;
2756             }
2757             else {
2758 1234283           var_decl->index = method->var_decls->length;
2759 1234283           SPVM_LIST_push(method->var_decls, var_decl);
2760 1234283           SPVM_LIST_push(var_decl_stack, var_decl);
2761             }
2762            
2763             // Type cannnot be detected
2764 1234283 100         if (!op_cur->is_dist && var_decl->type == NULL) {
    100          
2765 4           SPVM_COMPILER_error(compiler, "The type of the variable \"%s\" must be defined.\n at %s line %d", op_cur->uv.var->name, var_decl->op_var_decl->file, var_decl->op_var_decl->line);
2766 4           return;
2767             }
2768             }
2769            
2770 4847320           SPVM_VAR* var = op_cur->uv.var;
2771            
2772             // Search same name variable
2773 4847320           SPVM_VAR_DECL* found_var_decl = NULL;
2774 15554811 100         for (int32_t i = var_decl_stack->length - 1; i >= 0; i--) {
2775 15541739           SPVM_VAR_DECL* var_decl = SPVM_LIST_get(var_decl_stack, i);
2776 15541739 50         assert(var_decl);
2777 15541739 100         if (strcmp(var->name, var_decl->var->name) == 0) {
2778 4834248           found_var_decl = var_decl;
2779 4834248           break;
2780             }
2781             }
2782            
2783 4847320 100         if (found_var_decl) {
2784             // Add var_decl var information to var
2785 4834248           var->var_decl = found_var_decl;
2786             }
2787             else {
2788             // Search the class variable
2789 13072           SPVM_OP* op_name_basic_type_var = SPVM_OP_new_op_name(compiler, op_cur->uv.var->name, op_cur->file, op_cur->line);
2790 13072           SPVM_OP* op_class_var_access = SPVM_OP_new_op_class_var_access(compiler, op_name_basic_type_var);
2791            
2792 13072           op_class_var_access->is_dist = op_cur->is_dist;
2793            
2794 13072           SPVM_CHECK_check_class_var_access(compiler, op_class_var_access, basic_type->name);
2795 13072 100         if (op_class_var_access->uv.class_var_access->class_var) {
2796            
2797 13068           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
2798            
2799             // Check field name
2800 13068           SPVM_CHECK_check_class_var_access(compiler, op_class_var_access, basic_type->name);
2801 13068 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2802 0           return;
2803             }
2804            
2805 13068           SPVM_CLASS_VAR_ACCESS* class_var_access = op_class_var_access->uv.class_var_access;
2806 13068           SPVM_CLASS_VAR* class_var = class_var_access->class_var;
2807 13068           SPVM_BASIC_TYPE* class_var_access_basic_type = class_var->current_basic_type;
2808            
2809 13068 100         if (!SPVM_CHECK_can_access(compiler, method->current_basic_type, class_var_access_basic_type, class_var_access->class_var->access_control_type)) {
2810 6 100         if (!SPVM_OP_is_allowed(compiler, method->current_basic_type, class_var_access_basic_type)) {
2811 2           SPVM_COMPILER_error(compiler, "The %s \"%s\" class variable in the \"%s\" class cannnot be accessed from the current class \"%s\".\n at %s line %d", SPVM_ATTRIBUTE_get_name(compiler, class_var_access->class_var->access_control_type), class_var->name, class_var_access_basic_type->name, method->current_basic_type->name, op_class_var_access->file, op_class_var_access->line);
2812 2           return;
2813             }
2814             }
2815            
2816 13066           var->class_var = class_var;
2817            
2818 13066           SPVM_OP_replace_op(compiler, op_stab, op_class_var_access);
2819            
2820 13066           op_cur = op_class_var_access;
2821             }
2822             else {
2823 4           SPVM_COMPILER_error(compiler, "The variable \"%s\" is not found.\n at %s line %d", var->name, op_cur->file, op_cur->line);
2824 4           return;
2825             }
2826             }
2827            
2828 4847314           break;
2829             }
2830             case SPVM_OP_C_ID_CALL_METHOD: {
2831            
2832 251795           SPVM_OP* op_call_method = op_cur;
2833              
2834 251795 50         assert(op_cur->first->id == SPVM_OP_C_ID_LIST);
2835            
2836            
2837             // Check method
2838 251795           SPVM_CHECK_check_call_method(compiler, op_cur, basic_type->name);
2839 251795 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2840 17           return;
2841             }
2842            
2843 251778           SPVM_OP* op_list_args = op_cur->first;
2844            
2845 251778           SPVM_CALL_METHOD* call_method = op_call_method->uv.call_method;
2846 251778           const char* method_name = call_method->method->name;
2847              
2848 251778 100         if (!SPVM_CHECK_can_access(compiler, method->current_basic_type, call_method->method->current_basic_type, call_method->method->access_control_type)) {
2849 2 50         if (!SPVM_OP_is_allowed(compiler, method->current_basic_type, call_method->method->current_basic_type)) {
2850 2           SPVM_COMPILER_error(compiler, "The %s \"%s\" method in the \"%s\" class cannnot be called from the current class \"%s\".\n at %s line %d", SPVM_ATTRIBUTE_get_name(compiler, call_method->method->access_control_type), call_method->method->name, call_method->method->current_basic_type->name, method->current_basic_type->name, op_cur->file, op_cur->line);
2851 2           return;
2852             }
2853             }
2854            
2855 251776           int32_t args_length = call_method->method->args_length;
2856            
2857 251776           int32_t call_method_args_length = 0;
2858             {
2859 251776           SPVM_OP* op_operand = op_list_args->first;
2860 839455 100         while ((op_operand = SPVM_OP_sibling(compiler, op_operand))) {
2861 587683           call_method_args_length++;
2862 587683 100         if (call_method_args_length > args_length) {
2863 1           int32_t args_length_for_user = args_length;
2864 1 50         if (!call_method->method->is_class_method) {
2865 1           args_length_for_user--;
2866             }
2867            
2868 1           SPVM_COMPILER_error(compiler, "Too many arguments are passed to the \"%s\" method in the \"%s\" class.\n at %s line %d", method_name, op_cur->uv.call_method->method->current_basic_type->name, op_cur->file, op_cur->line);
2869            
2870 4           return;
2871             }
2872            
2873 587682           SPVM_VAR_DECL* arg_var_decl = SPVM_LIST_get(call_method->method->var_decls, call_method_args_length - 1);
2874 587682           SPVM_TYPE* arg_var_decl_type = arg_var_decl->type;
2875            
2876             // Check if source can be assigned to dist
2877             // If needed, numeric conversion op is added
2878             char place[255];
2879 587682           int32_t call_method_args_length_for_user = call_method_args_length;
2880 587682 100         if (!call_method->method->is_class_method) {
2881 163775           call_method_args_length_for_user--;
2882             }
2883 587682           sprintf(place, "the %dth argument of the \"%s\" method in the \"%s\" class", call_method_args_length_for_user, method_name, op_cur->uv.call_method->method->current_basic_type->name);
2884            
2885             // Invocant is not checked.
2886 587682           op_operand = SPVM_CHECK_check_assign(compiler, arg_var_decl_type, op_operand, place, op_cur->file, op_cur->line);
2887            
2888 587682 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2889 587682           return;
2890             }
2891             }
2892             }
2893            
2894 251772 100         if (call_method_args_length < call_method->method->required_args_length) {
2895 2           int32_t required_args_length_for_user = call_method->method->required_args_length;
2896 2 100         if (!call_method->method->is_class_method) {
2897 1           required_args_length_for_user--;
2898             }
2899            
2900 2           SPVM_COMPILER_error(compiler, "Too few arguments are passed to the \"%s\" method in the \"%s\" class.\n at %s line %d", method_name, op_cur->uv.call_method->method->current_basic_type->name, op_cur->file, op_cur->line);
2901            
2902 2           return;
2903             }
2904            
2905 251770           call_method->args_length = call_method_args_length;
2906            
2907             // A method call to get a enumeration value is replaced to a constant value
2908 251770 100         if (call_method->method->is_enum) {
2909             // Replace method to constant
2910 5808           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
2911            
2912 5808           int32_t enum_value = call_method->method->enum_value;
2913 5808           SPVM_OP* op_constant = SPVM_OP_new_op_constant_int(compiler, enum_value, op_cur->file, op_cur->line);
2914            
2915 5808           SPVM_OP_replace_op(compiler, op_stab, op_constant);
2916            
2917 5808           op_cur = op_constant;
2918             }
2919            
2920 251770 100         if (call_method->method->is_class_method) {
2921 165141           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, call_method->method->current_basic_type->name, strlen(call_method->method->current_basic_type->name));
2922             }
2923            
2924 251770           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, call_method->method->name, strlen(call_method->method->name));
2925            
2926 251770           break;
2927             }
2928             case SPVM_OP_C_ID_ARRAY_ACCESS: {
2929 180556           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_cur->first);
2930 180556           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2931            
2932             // Left operand must be an array or string
2933 205622           if (!SPVM_TYPE_is_array_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag) &&
2934 25066           !SPVM_TYPE_is_string_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)
2935             )
2936             {
2937 1           SPVM_COMPILER_error(compiler, "The invocant of the array access must be an array type or the string type.\n at %s line %d", op_cur->file, op_cur->line);
2938 1           return;
2939             }
2940            
2941             // String access
2942 180555 100         if (SPVM_TYPE_is_string_type(compiler, first_type->basic_type->id, first_type->dimension, first_type->flag)) {
2943 25065           op_cur->flag |= SPVM_OP_C_FLAG_ARRAY_ACCESS_STRING;
2944             }
2945            
2946             // Right operand must be integer
2947 180555 100         if (SPVM_TYPE_is_numeric_type(compiler, last_type->basic_type->id, last_type->dimension, last_type->flag)) {
2948 180554           SPVM_CHECK_perform_integer_promotional_conversion(compiler, op_cur->last);
2949 180554 50         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
2950 0           return;
2951             }
2952            
2953 180554           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_cur->last);
2954            
2955 180554 50         if (last_type->dimension == 0 && last_type->basic_type->id != SPVM_NATIVE_C_BASIC_TYPE_ID_INT) {
    100          
2956 1           SPVM_COMPILER_error(compiler, "The index of the array access must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2957 180554           return;
2958             }
2959             }
2960             else {
2961 1           SPVM_COMPILER_error(compiler, "The index of the array access must be the int type.\n at %s line %d", op_cur->file, op_cur->line);
2962 1           return;
2963             }
2964            
2965 180553           break;
2966             }
2967             case SPVM_OP_C_ID_FIELD_ACCESS: {
2968 174622           SPVM_OP* op_invocant = op_cur->first;
2969 174622           SPVM_OP* op_name = op_cur->uv.field_access->op_name;
2970            
2971 174622 50         if (op_invocant->id == SPVM_OP_C_ID_ASSIGN) {
2972 0           op_invocant = op_invocant->first;
2973             }
2974            
2975             // Invoker type check
2976 174622           SPVM_TYPE* invocant_type = SPVM_CHECK_get_type(compiler, op_invocant);
2977             int32_t is_valid_invocant_type;
2978 174622 50         if (invocant_type) {
2979 174622 100         if (SPVM_TYPE_is_class_type(compiler, invocant_type->basic_type->id, invocant_type->dimension, invocant_type->flag)) {
2980 170008           is_valid_invocant_type = 1;
2981             }
2982 4614 100         else if (SPVM_TYPE_is_mulnum_type(compiler, invocant_type->basic_type->id, invocant_type->dimension, invocant_type->flag)) {
2983 4297           is_valid_invocant_type = 1;
2984             }
2985 317 100         else if (SPVM_TYPE_is_mulnum_ref_type(compiler, invocant_type->basic_type->id, invocant_type->dimension, invocant_type->flag)) {
2986 316           is_valid_invocant_type = 1;
2987             }
2988             else {
2989 174622           is_valid_invocant_type = 0;
2990             }
2991             }
2992             else {
2993 0           is_valid_invocant_type = 0;
2994             }
2995 174622 100         if (!is_valid_invocant_type) {
2996 1           SPVM_COMPILER_error(compiler, "The invocant of the field access must be a class type, or a multi-numeric type, or a multi-numeric reference type.\n at %s line %d", op_cur->file, op_cur->line);
2997 1           return;
2998             }
2999            
3000             // Check field name
3001 174621           SPVM_CHECK_check_field_access(compiler, op_cur);
3002 174621 100         if (SPVM_COMPILER_get_error_messages_length(compiler) > 0) {
3003 2           return;
3004             }
3005            
3006 174619           SPVM_FIELD* field = op_cur->uv.field_access->field;
3007            
3008 174619 50         if (!field) {
3009 0           const char* invocant_type_name = SPVM_TYPE_new_type_name(compiler, invocant_type->basic_type->id, invocant_type->dimension, invocant_type->flag);
3010 0           SPVM_COMPILER_error(compiler, "The \"%s\" field in the \"%s\" class is not found.\n at %s line %d", op_name->uv.name, invocant_type_name, op_cur->file, op_cur->line);
3011 0           return;
3012             }
3013            
3014             // weaken operator
3015 174619 100         if (op_cur->flag & SPVM_OP_C_FLAG_FIELD_ACCESS_WEAKEN) {
3016 45 100         if (!SPVM_TYPE_is_object_type(compiler, field->type->basic_type->id, field->type->dimension, field->type->flag)) {
3017 2           SPVM_COMPILER_error(compiler, "The \"%s\" field in the \"%s\" class operated by the weaken operator must be an object type.\n at %s line %d", field->op_name->uv.name, field->current_basic_type->name, op_cur->file, op_cur->line);
3018 2           return;
3019             }
3020             }
3021             // unweaken operator
3022 174574 100         else if (op_cur->flag & SPVM_OP_C_FLAG_FIELD_ACCESS_UNWEAKEN) {
3023 4 100         if (!SPVM_TYPE_is_object_type(compiler, field->type->basic_type->id, field->type->dimension, field->type->flag)) {
3024 2           SPVM_COMPILER_error(compiler, "The \"%s\" field in the \"%s\" class operated by the unweaken operator must be an object type.\n at %s line %d", field->op_name->uv.name, field->current_basic_type->name, op_cur->file, op_cur->line);
3025 2           return;
3026             }
3027             }
3028             // isweak operator
3029 174570 100         else if (op_cur->flag & SPVM_OP_C_FLAG_FIELD_ACCESS_ISWEAK) {
3030 8 100         if (!SPVM_TYPE_is_object_type(compiler, field->type->basic_type->id, field->type->dimension, field->type->flag)) {
3031 2           SPVM_COMPILER_error(compiler, "The \"%s\" field in the \"%s\" class operated by the isweak operator must be an object type.\n at %s line %d", field->op_name->uv.name, field->current_basic_type->name, op_cur->file, op_cur->line);
3032 2           return;
3033             }
3034             }
3035              
3036 174613           SPVM_FIELD_ACCESS* field_access = op_cur->uv.field_access;
3037            
3038 174613 100         if (!SPVM_CHECK_can_access(compiler, method->current_basic_type, field_access->field->current_basic_type, field_access->field->access_control_type)) {
3039 18276 100         if (!SPVM_OP_is_allowed(compiler, method->current_basic_type, field->current_basic_type)) {
3040 2           SPVM_COMPILER_error(compiler, "The %s \"%s\" field in the \"%s\" class cannnot be accessed from the current class \"%s\".\n at %s line %d", SPVM_ATTRIBUTE_get_name(compiler, field_access->field->access_control_type), field->name, field->current_basic_type->name, method->current_basic_type->name, op_cur->file, op_cur->line);
3041 2           return;
3042             }
3043             }
3044            
3045             // If invocant is array access and array access object is mulnum_t, this op is multi-numeric array field access
3046 174611 100         if (op_invocant->id == SPVM_OP_C_ID_ARRAY_ACCESS) {
3047 3945           SPVM_OP* op_array_access = op_invocant;
3048            
3049 3945           SPVM_TYPE* array_element_type = SPVM_CHECK_get_type(compiler, op_array_access);
3050            
3051 3945           int32_t is_basic_type_mulnum_t = SPVM_BASIC_TYPE_is_mulnum_type(compiler, array_element_type->basic_type->id);
3052 3945 100         if (is_basic_type_mulnum_t && array_element_type->dimension == 0) {
    50          
3053 2283           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
3054            
3055 2283           SPVM_OP* op_array_field_access = SPVM_OP_new_op_array_field_access(compiler, op_cur->file, op_cur->line);
3056 2283           op_array_field_access->is_dist = op_cur->is_dist;
3057              
3058 2283           SPVM_ARRAY_FIELD_ACCESS* array_field_access = op_array_field_access->uv.array_field_access;
3059 2283           array_field_access->field = field;
3060            
3061 2283           SPVM_OP* op_array = op_array_access->first;
3062 2283           SPVM_OP* op_index = op_array_access->last;
3063 2283           SPVM_OP_cut_op(compiler, op_array_access->first);
3064 2283           SPVM_OP_cut_op(compiler, op_array_access->last);
3065            
3066 2283           SPVM_OP_insert_child(compiler, op_array_field_access, op_array_field_access->last, op_array);
3067 2283           SPVM_OP_insert_child(compiler, op_array_field_access, op_array_field_access->last, op_index);
3068            
3069 2283           SPVM_OP_replace_op(compiler, op_stab, op_array_field_access);
3070            
3071 2283           op_cur = op_array_field_access;
3072             }
3073             }
3074            
3075            
3076 174611           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, field_access->field->current_basic_type->name, strlen(field_access->field->current_basic_type->name));
3077            
3078 174611           SPVM_BASIC_TYPE_add_constant_string(compiler, basic_type, field_access->field->name, strlen(field_access->field->name));
3079            
3080 174611           break;
3081             }
3082             case SPVM_OP_C_ID_CAN: {
3083 17           SPVM_OP* op_var = op_cur->first;
3084 17           SPVM_OP* op_name_method = op_cur->last;
3085            
3086 17           SPVM_TYPE* type = SPVM_CHECK_get_type(compiler, op_var);
3087            
3088 17 100         if (!(SPVM_TYPE_is_class_type(compiler, type->basic_type->id, type->dimension, type->flag) || SPVM_TYPE_is_interface_type(compiler, type->basic_type->id, type->dimension, type->flag))) {
    100          
3089 1           SPVM_COMPILER_error(compiler, "The invocant of the can operator must be a class type or an interface type.\n at %s line %d", op_cur->file, op_cur->line);
3090 1           return;
3091             }
3092            
3093 16           const char* basic_type_name = type->basic_type->name;
3094 16           SPVM_BASIC_TYPE* basic_type = SPVM_HASH_get(compiler->basic_type_symtable, basic_type_name, strlen(basic_type_name));
3095            
3096 16           const char* method_name = op_name_method->uv.name;
3097 16           SPVM_METHOD* found_method = SPVM_HASH_get(
3098             basic_type->method_symtable,
3099             method_name,
3100 16           strlen(method_name)
3101             );
3102            
3103 16 100         if (!found_method) {
3104 1           SPVM_COMPILER_error(compiler, "The \"%s\" method in the \"%s\" class checked by the can operator must be defined.\n at %s line %d", method_name, basic_type_name, op_name_method->file, op_name_method->line);
3105 1           return;
3106             }
3107            
3108 15           break;
3109             }
3110             case SPVM_OP_C_ID_TYPE_CAST: {
3111            
3112 53609           SPVM_OP* op_src = op_cur->first;
3113 53609           SPVM_OP* op_cast = op_cur->last;
3114            
3115 53609           SPVM_TYPE* src_type = SPVM_CHECK_get_type(compiler, op_src);
3116 53609 50         assert(src_type);
3117            
3118 53609           SPVM_TYPE* cast_type = SPVM_CHECK_get_type(compiler, op_cast);
3119 53609 50         assert(cast_type);
3120            
3121 53609           int32_t castability = SPVM_TYPE_can_cast(
3122             compiler,
3123 53609           cast_type->basic_type->id, cast_type->dimension, cast_type->flag,
3124 53609           src_type->basic_type->id, src_type->dimension, src_type->flag
3125             );
3126              
3127 53609 100         if (!castability) {
3128 38           const char* src_type_name = SPVM_TYPE_new_type_name(compiler, src_type->basic_type->id, src_type->dimension, src_type->flag);
3129 38           const char* cast_type_name = SPVM_TYPE_new_type_name(compiler, cast_type->basic_type->id, cast_type->dimension, cast_type->flag);
3130 38           SPVM_COMPILER_error(compiler, "The type cast from \"%s\" to \"%s\" is not allowed.\n at %s line %d", src_type_name, cast_type_name, op_src->file, op_src->line);
3131 38           return;
3132             }
3133            
3134             // Remove type cast op if not needed
3135 53571 100         if (SPVM_TYPE_equals(compiler, cast_type->basic_type->id, cast_type->dimension, cast_type->flag, src_type->basic_type->id, src_type->dimension, src_type->flag)) {
3136 2591           SPVM_OP_cut_op(compiler, op_src);
3137 2591           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_cur);
3138 2591           SPVM_OP_replace_op(compiler, op_stab, op_src);
3139 2591           op_cur = op_src;
3140             }
3141             }
3142 53571           break;
3143             }
3144            
3145             // [END]Postorder traversal position
3146            
3147 17653513 100         if (op_cur == op_root) {
3148              
3149             // Finish
3150 227659           finish = 1;
3151            
3152 227659           break;
3153             }
3154            
3155             // Next sibling
3156 17425854 100         if (op_cur->moresib) {
3157 7984836           op_cur = SPVM_OP_sibling(compiler, op_cur);
3158 7984836           break;
3159             }
3160             // Next is parent
3161             else {
3162 9441018           op_cur = op_cur->sibparent;
3163             }
3164 9441018           }
3165 8212495 100         if (finish) {
3166 227659           break;
3167             }
3168             }
3169             }
3170             }
3171              
3172 227656           void SPVM_CHECK_check_ast_assign_unassigned_op_to_var(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, SPVM_METHOD* method) {
3173            
3174 227656 50         if (!method->op_block) {
3175 0           return;
3176             }
3177            
3178             // check AST
3179 227656           SPVM_OP* op_root = method->op_block;
3180 227656           SPVM_OP* op_cur = op_root;
3181 227656           int32_t finish = 0;
3182 20795894 50         while (op_cur) {
3183             // [START]Preorder traversal position
3184 20795894 100         switch (op_cur->id) {
3185             case SPVM_OP_C_ID_ASSIGN: {
3186 2061384 100         if (op_cur->last->id == SPVM_OP_C_ID_VAR) {
3187 1789433           op_cur->first->is_assigned_to_var = 1;
3188             }
3189 2061384           break;
3190             }
3191             }
3192            
3193 20795894 100         if (op_cur->first) {
3194 11005170           op_cur = op_cur->first;
3195             }
3196             else {
3197             while (1) {
3198             // [START]Postorder traversal position
3199            
3200             // Convert an operator to a assign operator
3201             {
3202 22275895           int32_t convert_to_assign = 0;
3203            
3204 22275895 100         if (!op_cur->is_dist && !op_cur->is_assigned_to_var) {
    100          
3205 16945077           switch (op_cur->id) {
3206             case SPVM_OP_C_ID_TYPE_CAST:
3207             case SPVM_OP_C_ID_WARN:
3208             case SPVM_OP_C_ID_PRINT:
3209             case SPVM_OP_C_ID_SAY:
3210             case SPVM_OP_C_ID_MAKE_READ_ONLY:
3211             case SPVM_OP_C_ID_IS_READ_ONLY:
3212             case SPVM_OP_C_ID_ADD:
3213             case SPVM_OP_C_ID_SUBTRACT:
3214             case SPVM_OP_C_ID_MULTIPLY:
3215             case SPVM_OP_C_ID_DIVIDE:
3216             case SPVM_OP_C_ID_DIVIDE_UNSIGNED_INT:
3217             case SPVM_OP_C_ID_DIVIDE_UNSIGNED_LONG:
3218             case SPVM_OP_C_ID_REMAINDER:
3219             case SPVM_OP_C_ID_REMAINDER_UNSIGNED_INT:
3220             case SPVM_OP_C_ID_REMAINDER_UNSIGNED_LONG:
3221             case SPVM_OP_C_ID_BIT_AND:
3222             case SPVM_OP_C_ID_BIT_OR:
3223             case SPVM_OP_C_ID_BIT_XOR:
3224             case SPVM_OP_C_ID_BIT_NOT:
3225             case SPVM_OP_C_ID_LEFT_SHIFT:
3226             case SPVM_OP_C_ID_RIGHT_ARITHMETIC_SHIFT:
3227             case SPVM_OP_C_ID_RIGHT_LOGICAL_SHIFT:
3228             case SPVM_OP_C_ID_MINUS:
3229             case SPVM_OP_C_ID_PLUS:
3230             case SPVM_OP_C_ID_COPY:
3231             case SPVM_OP_C_ID_ARRAY_LENGTH:
3232             case SPVM_OP_C_ID_STRING_LENGTH:
3233             case SPVM_OP_C_ID_NEW:
3234             case SPVM_OP_C_ID_BASIC_TYPE_ID:
3235             case SPVM_OP_C_ID_EVAL_ERROR_ID:
3236             case SPVM_OP_C_ID_ARGS_WIDTH:
3237             case SPVM_OP_C_ID_CONCAT:
3238             case SPVM_OP_C_ID_TYPE_NAME:
3239             case SPVM_OP_C_ID_COMPILE_TYPE_NAME:
3240             case SPVM_OP_C_ID_DUMP:
3241             case SPVM_OP_C_ID_NEW_STRING_LEN:
3242             case SPVM_OP_C_ID_EXCEPTION_VAR:
3243             case SPVM_OP_C_ID_CLASS_VAR_ACCESS:
3244             case SPVM_OP_C_ID_ARRAY_FIELD_ACCESS:
3245             case SPVM_OP_C_ID_CREATE_REF:
3246             case SPVM_OP_C_ID_DEREF:
3247             case SPVM_OP_C_ID_FIELD_ACCESS:
3248             case SPVM_OP_C_ID_ARRAY_ACCESS:
3249             case SPVM_OP_C_ID_CALL_METHOD:
3250             case SPVM_OP_C_ID_TRUE:
3251             case SPVM_OP_C_ID_FALSE:
3252             case SPVM_OP_C_ID_CONSTANT:
3253             {
3254 1480001           convert_to_assign = 1;
3255 1480001           break;
3256             }
3257             case SPVM_OP_C_ID_LOOP_INCREMENT:
3258             case SPVM_OP_C_ID_CONDITION:
3259             case SPVM_OP_C_ID_CONDITION_NOT:
3260             case SPVM_OP_C_ID_NEXT:
3261             case SPVM_OP_C_ID_LAST:
3262             case SPVM_OP_C_ID_SWITCH:
3263             case SPVM_OP_C_ID_SWITCH_CONDITION:
3264             case SPVM_OP_C_ID_DEFAULT:
3265             case SPVM_OP_C_ID_CASE:
3266             case SPVM_OP_C_ID_BREAK:
3267             case SPVM_OP_C_ID_RETURN:
3268             case SPVM_OP_C_ID_DIE:
3269             case SPVM_OP_C_ID_VAR:
3270             case SPVM_OP_C_ID_ASSIGN:
3271             case SPVM_OP_C_ID_LIST:
3272             case SPVM_OP_C_ID_PUSHMARK:
3273             case SPVM_OP_C_ID_NAME:
3274             case SPVM_OP_C_ID_TYPE:
3275             case SPVM_OP_C_ID_BLOCK:
3276             case SPVM_OP_C_ID_IF:
3277             case SPVM_OP_C_ID_LOOP:
3278             case SPVM_OP_C_ID_EVAL:
3279             case SPVM_OP_C_ID_UNDEF:
3280             case SPVM_OP_C_ID_SEQUENCE:
3281             case SPVM_OP_C_ID_DO_NOTHING:
3282             case SPVM_OP_C_ID_WEAKEN_FIELD:
3283             case SPVM_OP_C_ID_UNWEAKEN_FIELD:
3284             {
3285             // Do nothing
3286 15465076           break;
3287             }
3288             case SPVM_OP_C_ID_NUMERIC_EQ:
3289             case SPVM_OP_C_ID_NUMERIC_NE:
3290             case SPVM_OP_C_ID_NUMERIC_GT:
3291             case SPVM_OP_C_ID_NUMERIC_GE:
3292             case SPVM_OP_C_ID_NUMERIC_LT:
3293             case SPVM_OP_C_ID_NUMERIC_LE:
3294             case SPVM_OP_C_ID_NUMERIC_CMP:
3295             case SPVM_OP_C_ID_STRING_EQ:
3296             case SPVM_OP_C_ID_STRING_NE:
3297             case SPVM_OP_C_ID_STRING_GT:
3298             case SPVM_OP_C_ID_STRING_GE:
3299             case SPVM_OP_C_ID_STRING_LT:
3300             case SPVM_OP_C_ID_STRING_LE:
3301             case SPVM_OP_C_ID_STRING_CMP:
3302             case SPVM_OP_C_ID_ISA:
3303             case SPVM_OP_C_ID_ISA_ERROR:
3304             case SPVM_OP_C_ID_IS_TYPE:
3305             case SPVM_OP_C_ID_IS_ERROR:
3306             case SPVM_OP_C_ID_IS_COMPILE_TYPE:
3307             case SPVM_OP_C_ID_BOOL:
3308             {
3309 0           assert(0);
3310             break;
3311             }
3312             default: {
3313 0           fprintf(stderr, "[Unexpected Error]The %s operator", SPVM_OP_get_op_name(compiler, op_cur->id));
3314 0           assert(0);
3315             }
3316             }
3317             }
3318            
3319 22275895 100         if (convert_to_assign) {
3320 1480001           SPVM_TYPE* tmp_var_type = SPVM_CHECK_get_type(compiler, op_cur);
3321 1480001           SPVM_OP* op_var_tmp = SPVM_CHECK_new_op_var_tmp(compiler, tmp_var_type, method, op_cur->file, op_cur->line);
3322            
3323 1480001 50         if (op_var_tmp == NULL) {
3324 0           return;
3325             }
3326            
3327             // Cut new op
3328 1480001           SPVM_OP* op_target = op_cur;
3329            
3330 1480001           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_target);
3331              
3332             // Assing op
3333 1480001           SPVM_OP* op_assign = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_ASSIGN, op_cur->file, op_cur->line);
3334 1480001           SPVM_OP* op_build_assign = SPVM_OP_build_assign(compiler, op_assign, op_var_tmp, op_target);
3335            
3336             // Convert cur new op to var
3337 1480001           SPVM_OP_replace_op(compiler, op_stab, op_build_assign);
3338 1480001           op_target->uv = op_cur->uv;
3339            
3340 1480001           op_cur = op_target;
3341             }
3342             }
3343            
3344 22275895 100         if (op_cur == op_root) {
3345              
3346             // Finish
3347 227656           finish = 1;
3348            
3349 227656           break;
3350             }
3351            
3352             // Next sibling
3353 22048239 100         if (op_cur->moresib) {
3354 9563068           op_cur = SPVM_OP_sibling(compiler, op_cur);
3355 9563068           break;
3356             }
3357             // Next is parent
3358             else {
3359 12485171           op_cur = op_cur->sibparent;
3360             }
3361 12485171           }
3362 9790724 100         if (finish) {
3363 227656           break;
3364             }
3365             }
3366             }
3367             }
3368              
3369 227656           void SPVM_CHECK_check_ast_check_if_block_need_leave_scope(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, SPVM_METHOD* method) {
3370            
3371             // Block stack
3372 227656           SPVM_LIST* op_block_stack = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3373            
3374             // Run OPs
3375 227656           SPVM_OP* op_root = method->op_block;
3376 227656           SPVM_OP* op_cur = op_root;
3377 227656           int32_t finish = 0;
3378 22275895 50         while (op_cur) {
3379             // [START]Preorder traversal position
3380 22275895 100         switch (op_cur->id) {
3381             // Start scope
3382             case SPVM_OP_C_ID_BLOCK: {
3383 1551214           SPVM_BLOCK* block = op_cur->uv.block;
3384            
3385             // Push block
3386 1551214           SPVM_LIST_push(op_block_stack, op_cur);
3387            
3388 1551214           break;
3389             }
3390             }
3391            
3392 22275895 100         if (op_cur->first) {
3393 12485171           op_cur = op_cur->first;
3394             }
3395             else {
3396             while (1) {
3397             // [START]Postorder traversal position
3398 22275895           switch (op_cur->id) {
3399             case SPVM_OP_C_ID_BLOCK: {
3400 1551214           SPVM_OP* op_block_current = op_cur;
3401 1551214           SPVM_BLOCK* block_current = op_block_current->uv.block;
3402            
3403 1551214           SPVM_LIST_pop(op_block_stack);
3404            
3405             // The current block needs the LEAVE_SCOPE opcode
3406 1551214 100         if (block_current->has_object_var_decls && !block_current->no_scope) {
    100          
3407 618639           block_current->need_leave_scope = 1;
3408             }
3409            
3410             // The parent block needs the LEAVE_SCOPE opcode if the child block has object variable declarations
3411 1551214 100         if (op_block_stack->length > 0) {
3412 1323558           SPVM_OP* op_block_parent = SPVM_LIST_get(op_block_stack, op_block_stack->length - 1);
3413 1323558           SPVM_BLOCK* block_parent = op_block_parent->uv.block;
3414            
3415 1323558 100         if (block_current->has_object_var_decls) {
3416 456784           block_parent->has_object_var_decls = 1;
3417             }
3418            
3419 1323558 100         if (block_current->has_object_var_decls && !block_parent->no_scope) {
    50          
3420 456784           block_parent->need_leave_scope = 1;
3421             }
3422             }
3423            
3424 1551214           break;
3425             }
3426             case SPVM_OP_C_ID_VAR: {
3427 6313064           SPVM_OP* op_var = op_cur;
3428            
3429 6313064           SPVM_OP* op_block_current = SPVM_LIST_get(op_block_stack, op_block_stack->length - 1);
3430 6313064           SPVM_BLOCK* block_current = op_block_current->uv.block;
3431            
3432 6313064 100         if (op_var->uv.var->is_declaration) {
3433 2713729           SPVM_TYPE* var_type = SPVM_CHECK_get_type(compiler, op_var);
3434 2713729 100         if (SPVM_TYPE_is_object_type(compiler, var_type->basic_type->id, var_type->dimension, var_type->flag)) {
3435 773819           block_current->has_object_var_decls = 1;
3436             }
3437             }
3438            
3439 6313064           break;
3440             }
3441             }
3442            
3443 22275895 100         if (op_cur == op_root) {
3444            
3445             // Finish
3446 227656           finish = 1;
3447            
3448 227656           break;
3449             }
3450            
3451             // Next sibling
3452 22048239 100         if (op_cur->moresib) {
3453 9563068           op_cur = SPVM_OP_sibling(compiler, op_cur);
3454 9563068           break;
3455             }
3456             // Next is parent
3457             else {
3458 12485171           op_cur = op_cur->sibparent;
3459             }
3460 12485171           }
3461 9790724 100         if (finish) {
3462 227656           break;
3463             }
3464             }
3465             }
3466 227656           SPVM_LIST_free(op_block_stack);
3467 227656           }
3468              
3469 227656           void SPVM_CHECK_check_ast_check_runtime_var_indexs(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, SPVM_METHOD* method) {
3470            
3471 227656           SPVM_LIST* tmp_var_decl_stack = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3472              
3473 227656           SPVM_LIST* runtime_vars_byte = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3474 227656           SPVM_LIST* runtime_vars_short = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3475 227656           SPVM_LIST* runtime_vars_int = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3476 227656           SPVM_LIST* runtime_vars_long = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3477 227656           SPVM_LIST* runtime_vars_float = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3478 227656           SPVM_LIST* runtime_vars_double = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3479 227656           SPVM_LIST* runtime_vars_object = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3480 227656           SPVM_LIST* runtime_vars_ref = SPVM_LIST_new(compiler->current_each_compile_allocator, 0, SPVM_ALLOCATOR_C_ALLOC_TYPE_TMP);
3481              
3482             // Run OPs
3483 227656           SPVM_OP* op_root = method->op_block;
3484 227656           SPVM_OP* op_cur = op_root;
3485 227656           int32_t finish = 0;
3486 22275895 50         while (op_cur) {
3487             // [START]Preorder traversal position
3488 22275895           switch (op_cur->id) {
3489             }
3490              
3491 22275895 100         if (op_cur->first) {
3492 12485171           op_cur = op_cur->first;
3493             }
3494             else {
3495             while (1) {
3496             // [START]Postorder traversal position
3497 22275895           switch (op_cur->id) {
3498             case SPVM_OP_C_ID_BLOCK: {
3499 1551214           SPVM_BLOCK* block = op_cur->uv.block;
3500             // Move loop condition to last sibling before opcode building
3501 1551214 100         if (op_cur->uv.block->id == SPVM_BLOCK_C_ID_LOOP_INIT) {
3502 68679           SPVM_OP* op_init = op_cur->first;
3503 68679           SPVM_OP* op_condition = op_cur->first->sibparent;
3504 68679           SPVM_OP* op_block_statements = op_cur->first->sibparent->sibparent;
3505 68679           SPVM_OP* op_loop_increment = op_cur->first->sibparent->sibparent->sibparent;
3506            
3507 68679           op_init->sibparent = op_block_statements;
3508 68679           op_loop_increment->sibparent = op_condition;
3509 68679           op_loop_increment->moresib = 1;
3510            
3511 68679           op_condition->sibparent = op_cur;
3512 68679           op_condition->moresib = 0;
3513             }
3514            
3515 1551214           break;
3516             }
3517             case SPVM_OP_C_ID_VAR: {
3518 6313064 100         if (op_cur->uv.var->is_declaration) {
3519 2713729           SPVM_VAR_DECL* var_decl = op_cur->uv.var->var_decl;
3520            
3521 2713729           SPVM_TYPE* type = SPVM_CHECK_get_type(compiler, var_decl->op_var_decl);
3522            
3523             // Check mem id
3524             int32_t runtime_var_index;
3525 2713729 100         if (SPVM_TYPE_is_object_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
3526 773819           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_object, var_decl);
3527             }
3528 1939910 100         else if (SPVM_TYPE_is_ref_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
3529 6720           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_ref, var_decl);
3530             }
3531 1933190 100         else if (SPVM_TYPE_is_mulnum_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
3532 523           SPVM_FIELD* first_field = SPVM_LIST_get(type->basic_type->fields, 0);
3533 523 50         assert(first_field);
3534            
3535 523           SPVM_TYPE* field_type = SPVM_CHECK_get_type(compiler, first_field->op_field);
3536            
3537 523           switch (field_type->basic_type->id) {
3538             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
3539 78           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_byte, var_decl);
3540 523           break;
3541             }
3542             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
3543 70           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_short, var_decl);
3544 70           break;
3545             }
3546             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
3547 70           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_int, var_decl);
3548 70           break;
3549             }
3550             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
3551 70           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_long, var_decl);
3552 70           break;
3553             }
3554             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
3555 70           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_float, var_decl);
3556 70           break;
3557             }
3558             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
3559 165           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_double, var_decl);
3560 165           break;
3561             }
3562             default:
3563 0           assert(0);
3564             }
3565             }
3566 1932667 100         else if (SPVM_TYPE_is_numeric_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
3567 1807269           SPVM_TYPE* numeric_type = SPVM_CHECK_get_type(compiler, var_decl->op_var_decl);
3568 1807269           switch(numeric_type->basic_type->id) {
3569             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
3570 80825           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_byte, var_decl);
3571 1807269           break;
3572             }
3573             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
3574 14889           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_short, var_decl);
3575 14889           break;
3576             }
3577             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
3578 1617185           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_int, var_decl);
3579 1617185 100         if (strcmp(var_decl->var->name, "$.condition_flag") == 0) {
3580 227656 50         assert(runtime_var_index == 0);
3581             }
3582 1617185           break;
3583             }
3584             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
3585 42075           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_long, var_decl);
3586 42075           break;
3587             }
3588             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
3589 22177           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_float, var_decl);
3590 22177           break;
3591             }
3592             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
3593 30118           runtime_var_index = SPVM_CHECK_get_runtime_var_index(compiler, runtime_vars_double, var_decl);
3594 30118           break;
3595             }
3596             default:
3597 0           assert(0);
3598             }
3599             }
3600 125398 50         else if (SPVM_TYPE_is_void_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
3601 125398           runtime_var_index = -1;
3602             }
3603             else {
3604 0           assert(0);
3605             }
3606 2713729           var_decl->runtime_var_index = runtime_var_index;
3607            
3608             }
3609 6313064           break;
3610             }
3611             }
3612              
3613 22275895 100         if (op_cur == op_root) {
3614             // Finish
3615 227656           finish = 1;
3616            
3617 227656           break;
3618             }
3619            
3620             // Next sibling
3621 22048239 100         if (op_cur->moresib) {
3622 9563068           op_cur = SPVM_OP_sibling(compiler, op_cur);
3623 9563068           break;
3624             }
3625             // Next is parent
3626             else {
3627 12485171           op_cur = op_cur->sibparent;
3628             }
3629 12485171           }
3630 9790724 100         if (finish) {
3631 227656           break;
3632             }
3633             }
3634             }
3635            
3636 227656           method->byte_vars_width = runtime_vars_byte->length;
3637 227656           method->short_vars_width = runtime_vars_short->length;
3638 227656           method->int_vars_width = runtime_vars_int->length;
3639 227656           method->long_vars_width = runtime_vars_long->length;
3640 227656           method->float_vars_width = runtime_vars_float->length;
3641 227656           method->double_vars_width = runtime_vars_double->length;
3642 227656           method->object_vars_width = runtime_vars_object->length;
3643 227656           method->ref_vars_width = runtime_vars_ref->length;
3644            
3645 227656           SPVM_LIST_free(tmp_var_decl_stack);
3646            
3647 227656           SPVM_LIST_free(runtime_vars_byte);
3648 227656           SPVM_LIST_free(runtime_vars_short);
3649 227656           SPVM_LIST_free(runtime_vars_int);
3650 227656           SPVM_LIST_free(runtime_vars_long);
3651 227656           SPVM_LIST_free(runtime_vars_float);
3652 227656           SPVM_LIST_free(runtime_vars_double);
3653 227656           SPVM_LIST_free(runtime_vars_object);
3654 227656           SPVM_LIST_free(runtime_vars_ref);
3655 227656           }
3656              
3657 86632           SPVM_METHOD* SPVM_CHECK_search_method(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, const char* method_name) {
3658 86632           SPVM_METHOD* found_method = NULL;
3659            
3660 86632           SPVM_BASIC_TYPE* parent_basic_type = basic_type;
3661             while (1) {
3662 86893           found_method = SPVM_HASH_get(
3663             parent_basic_type->method_symtable,
3664             method_name,
3665 86893           strlen(method_name)
3666             );
3667 86893 100         if (found_method) {
3668 86627           break;
3669             }
3670 266           parent_basic_type = parent_basic_type->parent;
3671            
3672 266 100         if (!parent_basic_type) {
3673 5           break;
3674             }
3675 261           }
3676            
3677 86632           return found_method;
3678             }
3679              
3680 26285           SPVM_FIELD* SPVM_CHECK_search_unmerged_field(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type, const char* field_name) {
3681 26285           SPVM_FIELD* found_field = NULL;
3682            
3683 26285 100         if (basic_type) {
3684 68           SPVM_BASIC_TYPE* parent_basic_type = basic_type;
3685             while (1) {
3686 69           found_field = SPVM_HASH_get(
3687             parent_basic_type->unmerged_field_symtable,
3688             field_name,
3689 69           strlen(field_name)
3690             );
3691 69 100         if (found_field) {
3692 3           break;
3693             }
3694 66           parent_basic_type = parent_basic_type->parent;
3695            
3696 66 100         if (!parent_basic_type) {
3697 65           break;
3698             }
3699 1           }
3700             }
3701            
3702 26285           return found_field;
3703             }
3704              
3705 463614           int32_t SPVM_CHECK_can_access(SPVM_COMPILER* compiler, SPVM_BASIC_TYPE* basic_type_from, SPVM_BASIC_TYPE* basic_type_to, int32_t access_controll_flag_to) {
3706            
3707 463614           int32_t can_access = 0;
3708            
3709 463614 100         if (basic_type_from->is_anon) {
3710 149           basic_type_from = basic_type_from->outer;
3711             }
3712            
3713 463614 100         if (access_controll_flag_to == SPVM_ATTRIBUTE_C_ID_PRIVATE) {
3714 226924 100         if (strcmp(basic_type_from->name, basic_type_to->name) == 0) {
3715 207592           can_access = 1;
3716             }
3717             else {
3718 226924           can_access = 0;
3719             }
3720             }
3721 236690 100         else if (access_controll_flag_to == SPVM_ATTRIBUTE_C_ID_PROTECTED) {
3722 236 100         if (strcmp(basic_type_from->name, basic_type_to->name) == 0) {
3723 182           can_access = 1;
3724             }
3725             else {
3726 54 100         if (SPVM_BASIC_TYPE_is_super_class(compiler, basic_type_to->id, basic_type_from->id)) {
3727 53           can_access = 1;
3728             }
3729             else {
3730 236           can_access = 0;
3731             }
3732             }
3733             }
3734 236454 50         else if (access_controll_flag_to == SPVM_ATTRIBUTE_C_ID_PUBLIC) {
3735 236454           can_access = 1;
3736             }
3737             else {
3738 0           assert(0);
3739             }
3740            
3741 463614           return can_access;
3742             }
3743              
3744 808836           int SPVM_CHECK_method_name_compare_cb(const void* method1_ptr, const void* method2_ptr) {
3745            
3746 808836           SPVM_METHOD* method1 = *(SPVM_METHOD**)method1_ptr;
3747 808836           SPVM_METHOD* method2 = *(SPVM_METHOD**)method2_ptr;
3748            
3749 808836           const char* method1_name = method1->name;
3750 808836           const char* method2_name = method2->name;
3751            
3752 808836           return strcmp(method1_name, method2_name);
3753             }
3754              
3755 1650           void SPVM_CHECK_perform_numeric_to_string_conversion(SPVM_COMPILER* compiler, SPVM_OP* op_operand) {
3756            
3757 1650           SPVM_TYPE* type = SPVM_CHECK_get_type(compiler, op_operand);
3758            
3759             SPVM_TYPE* dist_type;
3760 1650 50         if (SPVM_TYPE_is_numeric_type(compiler, type->basic_type->id, type->dimension, type->flag)) {
3761 1650           SPVM_OP* op_dist_type = SPVM_OP_new_op_string_type(compiler, op_operand->file, op_operand->line);
3762 1650           dist_type = op_dist_type->uv.type;
3763             }
3764             else {
3765 0           return;
3766             }
3767            
3768 1650           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_operand);
3769            
3770 1650           SPVM_OP* op_type_cast = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, op_operand->file, op_operand->line);
3771 1650           SPVM_OP* op_dist_type = SPVM_CHECK_new_op_type_shared(compiler, dist_type, op_operand->file, op_operand->line);
3772 1650           SPVM_OP_build_type_cast(compiler, op_type_cast, op_dist_type, op_operand, NULL);
3773            
3774 1650           SPVM_OP_replace_op(compiler, op_stab, op_type_cast);
3775             }
3776              
3777 825697           void SPVM_CHECK_perform_integer_promotional_conversion(SPVM_COMPILER* compiler, SPVM_OP* op_operand) {
3778            
3779 825697           SPVM_TYPE* type = SPVM_CHECK_get_type(compiler, op_operand);
3780            
3781             SPVM_TYPE* dist_type;
3782 1650652 50         if (type->dimension == 0 && type->basic_type->id <= SPVM_NATIVE_C_BASIC_TYPE_ID_INT) {
    100          
3783 824955           SPVM_OP* op_dist_type = SPVM_OP_new_op_int_type(compiler, op_operand->file, op_operand->line);
3784 824955           dist_type = op_dist_type->uv.type;
3785             }
3786             else {
3787 742           return;
3788             }
3789            
3790 824955 100         if (!(type->basic_type->id == dist_type->basic_type->id && type->dimension == dist_type->dimension)) {
    50          
3791 74           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_operand);
3792            
3793 74           SPVM_OP* op_type_cast = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, op_operand->file, op_operand->line);
3794 74           SPVM_OP* op_dist_type = SPVM_CHECK_new_op_type_shared(compiler, dist_type, op_operand->file, op_operand->line);
3795 74           SPVM_OP_build_type_cast(compiler, op_type_cast, op_dist_type, op_operand, NULL);
3796            
3797 74           SPVM_TYPE* type = SPVM_CHECK_get_type(compiler, op_type_cast);
3798            
3799 74           SPVM_OP_replace_op(compiler, op_stab, op_type_cast);
3800             }
3801             }
3802              
3803 586513           void SPVM_CHECK_perform_binary_numeric_conversion(SPVM_COMPILER* compiler, SPVM_OP* op_first, SPVM_OP* op_last) {
3804            
3805 586513           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op_first);
3806 586513           SPVM_TYPE* last_type = SPVM_CHECK_get_type(compiler, op_last);
3807            
3808             SPVM_TYPE* dist_type;
3809 592338 50         if ((first_type->dimension == 0 && first_type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE) || (last_type->dimension == 0 && last_type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE)) {
    100          
    50          
    100          
3810 5825           SPVM_OP* op_dist_type = SPVM_OP_new_op_double_type(compiler, op_first->file, op_first->line);
3811 5825           dist_type = op_dist_type->uv.type;
3812             }
3813 583681 50         else if ((first_type->dimension == 0 && first_type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT) || (last_type->dimension == 0 && last_type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT)) {
    100          
    50          
    100          
3814 2993           SPVM_OP* op_dist_type = SPVM_OP_new_op_float_type(compiler, op_first->file, op_first->line);
3815 2993           dist_type = op_dist_type->uv.type;
3816             }
3817 584005 50         else if ((first_type->dimension == 0 && first_type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) || (last_type->dimension == 0 && last_type->basic_type->id == SPVM_NATIVE_C_BASIC_TYPE_ID_LONG)) {
    100          
    50          
    100          
3818 6310           SPVM_OP* op_dist_type = SPVM_OP_new_op_long_type(compiler, op_first->file, op_first->line);
3819 6310           dist_type = op_dist_type->uv.type;
3820             }
3821             else {
3822 571385           SPVM_OP* op_dist_type = SPVM_OP_new_op_int_type(compiler, op_first->file, op_first->line);
3823 571385           dist_type = op_dist_type->uv.type;
3824             }
3825            
3826 586513 100         if (!(first_type->basic_type->id == dist_type->basic_type->id && first_type->dimension == dist_type->dimension)) {
    50          
3827 26740           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_first);
3828            
3829 26740           SPVM_OP* op_type_cast = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, op_first->file, op_first->line);
3830 26740           SPVM_OP* op_dist_type = SPVM_CHECK_new_op_type_shared(compiler, dist_type, op_first->file, op_first->line);
3831 26740           SPVM_OP_build_type_cast(compiler, op_type_cast, op_dist_type, op_first, NULL);
3832            
3833 26740           SPVM_OP_replace_op(compiler, op_stab, op_type_cast);
3834             }
3835            
3836 586513 100         if (!(last_type->basic_type->id == dist_type->basic_type->id && last_type->dimension == dist_type->dimension)) {
    50          
3837 49459           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_last);
3838            
3839 49459           SPVM_OP* op_type_cast = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, op_last->file, op_last->line);
3840 49459           SPVM_OP* op_dist_type = SPVM_CHECK_new_op_type_shared(compiler, dist_type, op_last->file, op_last->line);
3841 49459           SPVM_OP_build_type_cast(compiler, op_type_cast, op_dist_type, op_last, NULL);
3842 49459           SPVM_OP_replace_op(compiler, op_stab, op_type_cast);
3843             }
3844 586513           }
3845              
3846 3027208           int32_t SPVM_CHECK_check_allow_narrowing_conversion(SPVM_COMPILER* compiler, SPVM_TYPE* dist_type, SPVM_OP* op_src) {
3847            
3848 3027208           int32_t allow_narrowing_conversion = 0;
3849 3027208 100         if (op_src->allow_narrowing_conversion) {
3850 106432           allow_narrowing_conversion = 1;
3851             }
3852             else {
3853 2920776           SPVM_TYPE* src_type = SPVM_CHECK_get_type(compiler, op_src);
3854            
3855 2920776           int32_t dist_type_basic_type_id = dist_type->basic_type->id;
3856 2920776           int32_t dist_type_dimension = dist_type->dimension;
3857 2920776           int32_t dist_type_flag = dist_type->flag;
3858            
3859 2920776           int32_t src_type_basic_type_id = src_type->basic_type->id;
3860 2920776           int32_t src_type_dimension = src_type->dimension;
3861 2920776           int32_t src_type_flag = src_type->flag;
3862            
3863 2920776           SPVM_CONSTANT* src_constant = NULL;
3864 2920776 100         if (op_src->id == SPVM_OP_C_ID_CONSTANT) {
3865 456946           src_constant = op_src->uv.constant;
3866             }
3867            
3868             // Dist type is numeric type
3869 2920776 100         if (SPVM_TYPE_is_numeric_type(compiler, dist_type_basic_type_id, dist_type_dimension, dist_type_flag)) {
3870             // Soruce type is numeric type
3871 2106440 100         if (SPVM_TYPE_is_numeric_type(compiler, src_type_basic_type_id, src_type_dimension, src_type_flag)) {
3872             // Dist type is same as source type
3873 2102212 100         if (src_type_basic_type_id == dist_type_basic_type_id) {
3874            
3875             }
3876             // Dist type is more wide than source type
3877 17423 100         else if (dist_type_basic_type_id > src_type_basic_type_id) {
3878            
3879             }
3880             // Dist type is narrow than source type
3881 2327 50         else if (dist_type_basic_type_id < src_type_basic_type_id) {
3882 2327 100         if (src_constant) {
3883 2322 50         assert(src_type_dimension == 0);
3884 4643 100         if (src_type_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_INT || src_type_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) {
    100          
3885             int64_t src_constant_value;
3886 2321 100         if (src_type_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_INT) {
3887 2312           src_constant_value = src_constant->value.ival;
3888             }
3889 9 50         else if (src_type_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_LONG) {
3890 9           src_constant_value = src_constant->value.lval;
3891             }
3892             else {
3893 0           assert(0);
3894             }
3895            
3896 2321 100         if (dist_type_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE) {
3897 1224 100         if (src_constant_value >= INT8_MIN && src_constant_value <= INT8_MAX) {
    100          
3898 1220           allow_narrowing_conversion = 1;
3899             }
3900             else {
3901 1224           allow_narrowing_conversion = 0;
3902             }
3903             }
3904 1097 100         else if (dist_type_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT) {
3905 1090 100         if (src_constant_value >= INT16_MIN && src_constant_value <= INT16_MAX) {
    100          
3906 1087           allow_narrowing_conversion = 1;
3907             }
3908             else {
3909 1090           allow_narrowing_conversion = 0;
3910             }
3911             }
3912 7 50         else if (dist_type_basic_type_id == SPVM_NATIVE_C_BASIC_TYPE_ID_INT) {
3913 7 100         if (src_constant_value >= INT32_MIN && src_constant_value <= INT32_MAX) {
    100          
3914 5           allow_narrowing_conversion = 1;
3915             }
3916             else {
3917 7           allow_narrowing_conversion = 0;
3918             }
3919             }
3920             else {
3921 0           assert(0);
3922             }
3923             }
3924             else {
3925 1           allow_narrowing_conversion = 0;
3926             }
3927             }
3928             }
3929             }
3930             }
3931             }
3932            
3933 3027208           return allow_narrowing_conversion;
3934             }
3935              
3936 2970820           SPVM_OP* SPVM_CHECK_check_assign(SPVM_COMPILER* compiler, SPVM_TYPE* dist_type, SPVM_OP* op_src, const char* place, const char* file, int32_t line) {
3937 2970820           SPVM_TYPE* src_type = SPVM_CHECK_get_type(compiler, op_src);
3938            
3939 2970820           int32_t dist_type_basic_type_id = dist_type->basic_type->id;
3940 2970820           int32_t dist_type_dimension = dist_type->dimension;
3941 2970820           int32_t dist_type_flag = dist_type->flag;
3942            
3943 2970820           int32_t src_type_basic_type_id = src_type->basic_type->id;
3944 2970820           int32_t src_type_dimension = src_type->dimension;
3945 2970820           int32_t src_type_flag = src_type->flag;
3946              
3947 2970820           const char* src_type_name = SPVM_TYPE_new_type_name(compiler, src_type_basic_type_id, src_type_dimension, src_type_flag);
3948 2970820           const char* dist_type_name = SPVM_TYPE_new_type_name(compiler, dist_type_basic_type_id, dist_type_dimension, dist_type_flag);
3949              
3950 2970820 100         if (SPVM_TYPE_is_void_type(compiler, src_type_basic_type_id, src_type_dimension, src_type_flag)) {
3951 1           SPVM_COMPILER_error(compiler, "The void type cannnot be assigned in %s.\n at %s line %d", place, file, line);
3952 1           return NULL;
3953             }
3954              
3955 2970819           int32_t need_implicite_conversion = 0;
3956 2970819           int32_t allow_narrowing_conversion = SPVM_CHECK_check_allow_narrowing_conversion(compiler, dist_type, op_src);
3957            
3958 2970819           int32_t assignability = SPVM_TYPE_can_assign(
3959             compiler,
3960             dist_type_basic_type_id, dist_type_dimension, dist_type_flag,
3961             src_type_basic_type_id, src_type_dimension, src_type_flag,
3962             &need_implicite_conversion, allow_narrowing_conversion
3963             );
3964            
3965 2970819 100         if (!assignability) {
3966 76           SPVM_COMPILER_error(compiler, "The implicite type conversion from \"%s\" to \"%s\" in %s is not allowed.\n at %s line %d", src_type_name, dist_type_name, place, file, line);
3967 76           return NULL;
3968             }
3969            
3970 2970743 100         if (need_implicite_conversion) {
3971 23898           SPVM_OP* op_stab = SPVM_OP_cut_op(compiler, op_src);
3972            
3973 23898           SPVM_OP* op_type_cast = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE_CAST, file, line);
3974 23898           SPVM_OP* op_dist_type = SPVM_CHECK_new_op_type_shared(compiler, dist_type, file, line);
3975 23898           SPVM_OP_build_type_cast(compiler, op_type_cast, op_dist_type, op_src, NULL);
3976            
3977 23898           SPVM_OP_replace_op(compiler, op_stab, op_type_cast);
3978 23898           return op_type_cast;
3979             }
3980            
3981 2970820           return op_src;
3982             }
3983              
3984 2588331           int32_t SPVM_CHECK_get_runtime_var_index(SPVM_COMPILER* compiler, SPVM_LIST* runtime_vars, SPVM_VAR_DECL* var_decl) {
3985            
3986 2588331           int32_t found_runtime_var_index = -1;
3987            
3988 2588331           SPVM_TYPE* var_decl_type = var_decl->type;
3989              
3990 2588331           int32_t var_width = SPVM_TYPE_get_width(compiler, var_decl_type->basic_type->id, var_decl_type->dimension, var_decl_type->flag);
3991            
3992             // Search free memory
3993 2588331           int32_t found = 0;
3994 27439785 100         for (int32_t runtime_var_index = 0; runtime_var_index < runtime_vars->length; runtime_var_index++) {
3995 24851454 100         if (runtime_var_index + var_width <= runtime_vars->length) {
3996 24850613           int32_t is_used = 0;
3997 24850613 50         for (int32_t i = 0; i < var_width; i++) {
3998 24850613           int32_t var_decl_id = (intptr_t)SPVM_LIST_get(runtime_vars, runtime_var_index + i);
3999 24850613 50         if (var_decl_id >= 0) {
4000 24850613           is_used = 1;
4001 24850613           break;
4002             }
4003             }
4004 24850613 50         if (!is_used) {
4005 0           found = 1;
4006 0           found_runtime_var_index = runtime_var_index;
4007 0 0         for (int32_t i = 0; i < var_width; i++) {
4008 0           runtime_vars->values[runtime_var_index + i] = (void*)(intptr_t)var_decl->index;
4009             }
4010 0           break;
4011             }
4012             }
4013            
4014 24851454 50         if (found) {
4015 0           break;
4016             }
4017             }
4018            
4019             // Add stack
4020 2588331 50         if (!found) {
4021 2588331           found_runtime_var_index = runtime_vars->length;
4022 5178083 100         for (int32_t i = 0; i < var_width; i++) {
4023 2589752           SPVM_LIST_push(runtime_vars, (void*)(intptr_t)var_decl->index);
4024             }
4025             }
4026            
4027 2588331           return found_runtime_var_index;
4028             }
4029              
4030 1480001           SPVM_OP* SPVM_CHECK_new_op_var_tmp(SPVM_COMPILER* compiler, SPVM_TYPE* type, SPVM_METHOD* method, const char* file, int32_t line) {
4031            
4032             // Temparary variable name
4033 1480001           char* name = SPVM_ALLOCATOR_alloc_memory_block_permanent(compiler->current_each_compile_allocator, strlen("$.tmp_in_method2147483647") + 1);
4034 1480001           sprintf(name, "$.tmp_in_method%d", method->tmp_vars_length);
4035 1480001           method->tmp_vars_length++;
4036 1480001           SPVM_OP* op_name = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_NAME, file, line);
4037 1480001           op_name->uv.name = name;
4038 1480001           SPVM_OP* op_var_tmp = SPVM_OP_build_var(compiler, op_name);
4039 1480001           SPVM_OP* op_var_tmp_decl = SPVM_OP_new_op_var_decl(compiler, file, line);
4040 1480001 50         assert(type);
4041 1480001           SPVM_OP* op_type = SPVM_CHECK_new_op_type_shared(compiler, type, file, line);
4042            
4043 1480001           SPVM_OP_build_var_decl(compiler, op_var_tmp_decl, op_var_tmp, op_type, NULL);
4044            
4045 1480001           op_var_tmp->uv.var->is_initialized = 1;
4046            
4047 1480001           op_var_tmp->uv.var->var_decl->index = method->var_decls->length;
4048 1480001           SPVM_LIST_push(method->op_method->uv.method->var_decls, op_var_tmp->uv.var->var_decl);
4049            
4050 1480001           return op_var_tmp;
4051             }
4052              
4053             // Don't use this method in spvm_op.c because types must not be shared in builiding AST.
4054 1581822           SPVM_OP* SPVM_CHECK_new_op_type_shared(SPVM_COMPILER* compiler, SPVM_TYPE* type, const char* file, int32_t line) {
4055 1581822           SPVM_OP* op_type = SPVM_OP_new_op(compiler, SPVM_OP_C_ID_TYPE, file, line);
4056 1581822           op_type->uv.type = type;
4057            
4058 1581822           SPVM_LIST_push(compiler->op_types, op_type);
4059            
4060 1581822           return op_type;
4061             }
4062              
4063             // Don't use this method in spvm_op.c because types must not be shared in builiding AST.
4064 38677639           SPVM_TYPE* SPVM_CHECK_get_type(SPVM_COMPILER* compiler, SPVM_OP* op) {
4065            
4066 38677639           SPVM_TYPE* type = NULL;
4067            
4068 38677639           switch (op->id) {
4069             case SPVM_OP_C_ID_TRUE:
4070             case SPVM_OP_C_ID_FALSE:
4071             {
4072 0           type = SPVM_TYPE_new_bool_object_type(compiler);
4073 0           break;
4074             }
4075             case SPVM_OP_C_ID_RETURN:
4076             case SPVM_OP_C_ID_LOOP_INCREMENT:
4077             case SPVM_OP_C_ID_CONDITION:
4078             case SPVM_OP_C_ID_CONDITION_NOT:
4079             case SPVM_OP_C_ID_SWITCH:
4080             case SPVM_OP_C_ID_DEFAULT:
4081             case SPVM_OP_C_ID_CASE:
4082             case SPVM_OP_C_ID_LAST:
4083             case SPVM_OP_C_ID_NEXT:
4084             case SPVM_OP_C_ID_BREAK:
4085             case SPVM_OP_C_ID_DIE:
4086             case SPVM_OP_C_ID_WARN:
4087             case SPVM_OP_C_ID_PRINT:
4088             case SPVM_OP_C_ID_SAY:
4089             case SPVM_OP_C_ID_MAKE_READ_ONLY:
4090             {
4091             // Dummy int variable
4092 1620           type = SPVM_TYPE_new_int_type(compiler);
4093 1620           break;
4094             }
4095             case SPVM_OP_C_ID_NUMERIC_EQ:
4096             case SPVM_OP_C_ID_NUMERIC_NE:
4097             case SPVM_OP_C_ID_NUMERIC_GT:
4098             case SPVM_OP_C_ID_NUMERIC_GE:
4099             case SPVM_OP_C_ID_NUMERIC_LT:
4100             case SPVM_OP_C_ID_NUMERIC_LE:
4101             case SPVM_OP_C_ID_NUMERIC_CMP:
4102             case SPVM_OP_C_ID_BOOL:
4103             case SPVM_OP_C_ID_STRING_EQ:
4104             case SPVM_OP_C_ID_STRING_NE:
4105             case SPVM_OP_C_ID_STRING_GT:
4106             case SPVM_OP_C_ID_STRING_GE:
4107             case SPVM_OP_C_ID_STRING_LT:
4108             case SPVM_OP_C_ID_STRING_LE:
4109             case SPVM_OP_C_ID_STRING_CMP:
4110             case SPVM_OP_C_ID_ISA:
4111             case SPVM_OP_C_ID_ISA_ERROR:
4112             case SPVM_OP_C_ID_IS_TYPE:
4113             case SPVM_OP_C_ID_IS_ERROR:
4114             case SPVM_OP_C_ID_IF:
4115             case SPVM_OP_C_ID_ISWEAK_FIELD:
4116             case SPVM_OP_C_ID_IS_READ_ONLY:
4117             case SPVM_OP_C_ID_CAN:
4118             case SPVM_OP_C_ID_BASIC_TYPE_ID:
4119             case SPVM_OP_C_ID_EVAL_ERROR_ID:
4120             case SPVM_OP_C_ID_ARGS_WIDTH:
4121             {
4122 2201619           type = SPVM_TYPE_new_int_type(compiler);
4123 2201619           break;
4124             }
4125             case SPVM_OP_C_ID_ARRAY_LENGTH:
4126             case SPVM_OP_C_ID_STRING_LENGTH:
4127             {
4128 230999           type = SPVM_TYPE_new_int_type(compiler);
4129 230999           break;
4130             }
4131             case SPVM_OP_C_ID_ARRAY_ACCESS: {
4132 561639           SPVM_TYPE* first_type = SPVM_CHECK_get_type(compiler, op->first);
4133 561639           SPVM_BASIC_TYPE* basic_type = SPVM_HASH_get(compiler->basic_type_symtable, first_type->basic_type->name, strlen(first_type->basic_type->name));
4134 561639 100         if (SPVM_TYPE_is_string_type(compiler, basic_type->id, first_type->dimension, 0)) {
4135 88184           type = SPVM_TYPE_new_byte_type(compiler);
4136             }
4137 473455 100         else if (SPVM_TYPE_is_any_object_array_type(compiler, basic_type->id, first_type->dimension, 0)) {
4138 136456           type = SPVM_TYPE_new_any_object_type(compiler);
4139             }
4140             else {
4141 336999           type = SPVM_TYPE_new(compiler, basic_type->id, first_type->dimension - 1, 0);
4142             }
4143            
4144 561639           break;
4145             }
4146             case SPVM_OP_C_ID_ADD:
4147             case SPVM_OP_C_ID_SUBTRACT:
4148             case SPVM_OP_C_ID_MULTIPLY:
4149             case SPVM_OP_C_ID_DIVIDE:
4150             case SPVM_OP_C_ID_DIVIDE_UNSIGNED_INT:
4151             case SPVM_OP_C_ID_DIVIDE_UNSIGNED_LONG:
4152             case SPVM_OP_C_ID_REMAINDER:
4153             case SPVM_OP_C_ID_REMAINDER_UNSIGNED_INT:
4154             case SPVM_OP_C_ID_REMAINDER_UNSIGNED_LONG:
4155             case SPVM_OP_C_ID_INC:
4156             case SPVM_OP_C_ID_PRE_INC:
4157             case SPVM_OP_C_ID_POST_INC:
4158             case SPVM_OP_C_ID_DEC:
4159             case SPVM_OP_C_ID_PRE_DEC:
4160             case SPVM_OP_C_ID_POST_DEC:
4161             case SPVM_OP_C_ID_LEFT_SHIFT:
4162             case SPVM_OP_C_ID_RIGHT_ARITHMETIC_SHIFT:
4163             case SPVM_OP_C_ID_RIGHT_LOGICAL_SHIFT:
4164             case SPVM_OP_C_ID_BIT_XOR:
4165             case SPVM_OP_C_ID_BIT_OR:
4166             case SPVM_OP_C_ID_BIT_AND:
4167             case SPVM_OP_C_ID_BIT_NOT:
4168             case SPVM_OP_C_ID_PLUS:
4169             case SPVM_OP_C_ID_MINUS:
4170             case SPVM_OP_C_ID_CHECK_CONVERT:
4171             case SPVM_OP_C_ID_ARRAY_INIT:
4172             case SPVM_OP_C_ID_COPY:
4173             {
4174 691861           type = SPVM_CHECK_get_type(compiler, op->first);
4175 691861           break;
4176             }
4177             case SPVM_OP_C_ID_NEW: {
4178 266463 100         if (op->first->id == SPVM_OP_C_ID_TYPE) {
4179 223843           type = op->first->uv.type;
4180             }
4181 42620 50         else if (op->first->id == SPVM_OP_C_ID_VAR) {
4182 42620           SPVM_OP* op_var_element = op->first;
4183 42620           SPVM_TYPE* element_type = SPVM_CHECK_get_type(compiler, op_var_element);
4184 42620           type = SPVM_TYPE_new(compiler, element_type->basic_type->id, element_type->dimension + 1, element_type->flag);
4185             }
4186             else {
4187 0           assert(0);
4188             }
4189 266463           break;
4190             }
4191             case SPVM_OP_C_ID_LIST:
4192             case SPVM_OP_C_ID_SEQUENCE:
4193 31848           type = SPVM_CHECK_get_type(compiler, op->last);
4194 31848           break;
4195             case SPVM_OP_C_ID_ASSIGN: {
4196 2103715           type = SPVM_CHECK_get_type(compiler, op->last);
4197 2103715           break;
4198             }
4199             case SPVM_OP_C_ID_TYPE_CAST: {
4200 267138           SPVM_OP* op_type = op->last;
4201 267138           type = SPVM_CHECK_get_type(compiler, op_type);
4202 267138           break;
4203             }
4204             case SPVM_OP_C_ID_TYPE: {
4205 760702 50         if (op->uv.type) {
4206 760702           type = op->uv.type;
4207             }
4208 760702           break;
4209             }
4210             case SPVM_OP_C_ID_SWITCH_CONDITION : {
4211 1645           type = SPVM_CHECK_get_type(compiler, op->first);
4212 1645           break;
4213             }
4214             case SPVM_OP_C_ID_UNDEF : {
4215 57742           type = SPVM_TYPE_new_undef_type(compiler);
4216 57742           break;
4217             }
4218             case SPVM_OP_C_ID_CONSTANT: {
4219 3808014           SPVM_CONSTANT* constant = op->uv.constant;
4220 3808014           type = constant->type;
4221 3808014           break;
4222             }
4223             case SPVM_OP_C_ID_VAR: {
4224 18922587           SPVM_VAR* var = op->uv.var;
4225 18922587           type = var->var_decl->type;
4226 18922587           break;
4227             }
4228             case SPVM_OP_C_ID_CLASS_VAR_ACCESS: {
4229 46075           SPVM_CLASS_VAR* class_var = op->uv.class_var_access->class_var;
4230 46075 50         if (class_var->type) {
4231 46075           type = class_var->type;
4232             }
4233 46075           break;
4234             }
4235             case SPVM_OP_C_ID_CLASS_VAR: {
4236 14454           SPVM_CLASS_VAR* class_var = op->uv.class_var;
4237 14454 50         if (class_var->type) {
4238 14454           type = class_var->type;
4239             }
4240 14454           break;
4241             }
4242             case SPVM_OP_C_ID_CONCAT:
4243             case SPVM_OP_C_ID_TYPE_NAME:
4244             case SPVM_OP_C_ID_COMPILE_TYPE_NAME:
4245             case SPVM_OP_C_ID_DUMP:
4246             case SPVM_OP_C_ID_EXCEPTION_VAR:
4247             case SPVM_OP_C_ID_NEW_STRING_LEN:
4248             {
4249 371831           type = SPVM_TYPE_new_string_type(compiler);
4250 371831           break;
4251             }
4252             case SPVM_OP_C_ID_VAR_DECL: {
4253            
4254 7203751           SPVM_VAR_DECL* var_decl = op->uv.var_decl;
4255 7203751           type = var_decl->type;
4256 7203751           break;
4257             }
4258             case SPVM_OP_C_ID_CALL_METHOD: {
4259 459950           SPVM_CALL_METHOD*call_method = op->uv.call_method;
4260 459950           const char*call_method_method_name =call_method->method->name;
4261 459950           SPVM_METHOD* method = SPVM_HASH_get(call_method->method->current_basic_type->method_symtable,call_method_method_name, strlen(call_method_method_name));
4262 459950           type = method->return_type;
4263 459950           break;
4264             }
4265             case SPVM_OP_C_ID_FIELD_ACCESS: {
4266 611476 100         if (op->flag & (SPVM_OP_C_FLAG_FIELD_ACCESS_WEAKEN|SPVM_OP_C_FLAG_FIELD_ACCESS_UNWEAKEN|SPVM_OP_C_FLAG_FIELD_ACCESS_ISWEAK)) {
4267 57           type = SPVM_TYPE_new_int_type(compiler);
4268             }
4269             else {
4270 611419           SPVM_FIELD_ACCESS* field_access = op->uv.field_access;
4271 611419           SPVM_FIELD* field = field_access->field;
4272 611419           type = field->type;
4273             }
4274 611476           break;
4275             }
4276             case SPVM_OP_C_ID_ARRAY_FIELD_ACCESS: {
4277 7596           SPVM_ARRAY_FIELD_ACCESS* array_field_access = op->uv.array_field_access;
4278 7596           SPVM_FIELD* field = array_field_access->field;
4279 7596           type = field->type;
4280 7596           break;
4281             }
4282             case SPVM_OP_C_ID_FIELD: {
4283 28709           SPVM_FIELD* field = op->uv.field;
4284 28709           type = field->type;
4285 28709           break;
4286             }
4287             case SPVM_OP_C_ID_CREATE_REF: {
4288 15085           SPVM_TYPE* operand_type = SPVM_CHECK_get_type(compiler, op->first);
4289 15085 50         assert(operand_type->dimension == 0);
4290 15085           switch (operand_type->basic_type->id) {
4291             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
4292 108           type = SPVM_TYPE_new_byte_ref_type(compiler);
4293 108           break;
4294             }
4295             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
4296 102           type = SPVM_TYPE_new_short_ref_type(compiler);
4297 102           break;
4298             }
4299             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
4300 14398           type = SPVM_TYPE_new_int_ref_type(compiler);
4301 14398           break;
4302             }
4303             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
4304 102           type = SPVM_TYPE_new_long_ref_type(compiler);
4305 102           break;
4306             }
4307             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
4308 102           type = SPVM_TYPE_new_float_ref_type(compiler);
4309 102           break;
4310             }
4311             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
4312 111           type = SPVM_TYPE_new_double_ref_type(compiler);
4313 111           break;
4314             }
4315             default: {
4316 162 50         assert(SPVM_TYPE_is_mulnum_type(compiler, operand_type->basic_type->id, operand_type->dimension, operand_type->flag));
4317 162           type = SPVM_TYPE_new(compiler, operand_type->basic_type->id, operand_type->dimension, operand_type->flag | SPVM_NATIVE_C_TYPE_FLAG_REF);
4318             }
4319             }
4320 15085           break;
4321             }
4322             case SPVM_OP_C_ID_DEREF: {
4323 11120           SPVM_TYPE* operand_type = SPVM_CHECK_get_type(compiler, op->first);
4324 11120 50         assert(operand_type->dimension == 0);
4325 11120           switch (operand_type->basic_type->id) {
4326             case SPVM_NATIVE_C_BASIC_TYPE_ID_BYTE: {
4327 254           type = SPVM_TYPE_new_byte_type(compiler);
4328 254           break;
4329             }
4330             case SPVM_NATIVE_C_BASIC_TYPE_ID_SHORT: {
4331 246           type = SPVM_TYPE_new_short_type(compiler);
4332 246           break;
4333             }
4334             case SPVM_NATIVE_C_BASIC_TYPE_ID_INT: {
4335 9784           type = SPVM_TYPE_new_int_type(compiler);
4336 9784           break;
4337             }
4338             case SPVM_NATIVE_C_BASIC_TYPE_ID_LONG: {
4339 254           type = SPVM_TYPE_new_long_type(compiler);
4340 254           break;
4341             }
4342             case SPVM_NATIVE_C_BASIC_TYPE_ID_FLOAT: {
4343 254           type = SPVM_TYPE_new_float_type(compiler);
4344 254           break;
4345             }
4346             case SPVM_NATIVE_C_BASIC_TYPE_ID_DOUBLE: {
4347 264           type = SPVM_TYPE_new_double_type(compiler);
4348 264           break;
4349             }
4350             default: {
4351 64 50         assert(SPVM_TYPE_is_mulnum_ref_type(compiler, operand_type->basic_type->id, operand_type->dimension, operand_type->flag));
4352 64           type = SPVM_TYPE_new(compiler, operand_type->basic_type->id, operand_type->dimension, operand_type->flag & ~SPVM_NATIVE_C_TYPE_FLAG_REF);
4353             }
4354             }
4355 11120           break;
4356             }
4357             default: {
4358 0           assert(0);
4359             }
4360             }
4361            
4362 38677639           return type;
4363             }