diff --git a/Makefile b/Makefile index 81b490d..c33c432 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,9 @@ IR_OBJECTS = $(IR_SOURCES:.c=.o) RUNTIME_SOURCES = runtime/runtime.c runtime/runtime_array.c runtime/runtime_object.c runtime/runtime_collections.c runtime/labeltable.c runtime/methodcache.c runtime/fastframe.c runtime/superinst.c RUNTIME_OBJECTS = $(RUNTIME_SOURCES:.c=.o) +LOADER_SOURCES = loader/loader.c +LOADER_OBJECTS = $(LOADER_SOURCES:.c=.o) + PHASE0_SOURCES = runtime/fastframe.c runtime/labeltable.c runtime/methodcache.c PHASE0_OBJECTS = $(PHASE0_SOURCES:.c=.o) @@ -125,13 +128,22 @@ TEST_FORLOOP_OBJECTS = $(TEST_FORLOOP_SOURCES:.c=.o) TEST_PRINTLN_SOURCES = tests/test_println.c TEST_PRINTLN_OBJECTS = $(TEST_PRINTLN_SOURCES:.c=.o) +TEST_LOADER_SOURCES = tests/test_loader.c +TEST_LOADER_OBJECTS = $(TEST_LOADER_SOURCES:.c=.o) + +TEST_OBJECT_METHODS_SOURCES = tests/test_object_methods.c +TEST_OBJECT_METHODS_OBJECTS = $(TEST_OBJECT_METHODS_SOURCES:.c=.o) + +TEST_AUTOBOX_SOURCES = tests/test_autobox.c +TEST_AUTOBOX_OBJECTS = $(TEST_AUTOBOX_SOURCES:.c=.o) + UNITTEST_SOURCES = tests/unittest.c UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o) TEST_UNITTEST_DEMO_SOURCES = tests/test_unittest_demo.c TEST_UNITTEST_DEMO_OBJECTS = $(TEST_UNITTEST_DEMO_SOURCES:.c=.o) -all: test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections test_super test_inheritance test_break test_elseif test_forloop test_println +all: test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections test_super test_inheritance test_break test_elseif test_forloop test_println test_loader test_object_methods test_autobox test_lexer: $(LEXER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_LEXER_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) @@ -145,94 +157,103 @@ test_semantic: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OB test_ir: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) runtime/labeltable.o $(UNITTEST_OBJECTS) $(TEST_IR_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_runtime: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_RUNTIME_OBJECTS) +test_runtime: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_RUNTIME_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_strings: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_STRINGS_OBJECTS) +test_strings: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_STRINGS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_arrays: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ARRAYS_OBJECTS) +test_arrays: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ARRAYS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_objects: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_OBJECTS_OBJECTS) +test_objects: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_OBJECTS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_instance_methods: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INSTANCE_OBJECTS) +test_instance_methods: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INSTANCE_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_fileio: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_FILEIO_OBJECTS) +test_fileio: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_FILEIO_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_dowhile: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_DOWHILE_OBJECTS) +test_dowhile: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_DOWHILE_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_switch: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_SWITCH_OBJECTS) +test_switch: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_SWITCH_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_math: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_MATH_OBJECTS) +test_math: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_MATH_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_string_methods: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_STRING_METHODS_OBJECTS) +test_string_methods: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_STRING_METHODS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_static: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_STATIC_OBJECTS) +test_static: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_STATIC_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_interfaces: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INTERFACES_OBJECTS) +test_interfaces: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INTERFACES_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_exceptions: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_EXCEPTIONS_OBJECTS) +test_exceptions: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_EXCEPTIONS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_ternary: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_TERNARY_OBJECTS) +test_ternary: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_TERNARY_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_bitwise: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_BITWISE_OBJECTS) +test_bitwise: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_BITWISE_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_enhanced_for: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ENHANCED_FOR_OBJECTS) +test_enhanced_for: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ENHANCED_FOR_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_array_init: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ARRAY_INIT_OBJECTS) +test_array_init: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ARRAY_INIT_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_instanceof: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INSTANCEOF_OBJECTS) +test_instanceof: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INSTANCEOF_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_shortcircuit: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_SHORTCIRCUIT_OBJECTS) +test_shortcircuit: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_SHORTCIRCUIT_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_multidim_arrays: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_MULTIDIM_ARRAYS_OBJECTS) +test_multidim_arrays: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_MULTIDIM_ARRAYS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_static_init: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_STATIC_INIT_OBJECTS) +test_static_init: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_STATIC_INIT_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_negative: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_NEGATIVE_OBJECTS) +test_negative: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_NEGATIVE_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_enums: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ENUMS_OBJECTS) +test_enums: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ENUMS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_collections: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_COLLECTIONS_OBJECTS) +test_collections: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_COLLECTIONS_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_super: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_SUPER_OBJECTS) +test_super: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_SUPER_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_inheritance: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INHERITANCE_OBJECTS) +test_inheritance: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_INHERITANCE_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_break: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_BREAK_OBJECTS) +test_break: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_BREAK_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_elseif: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ELSEIF_OBJECTS) +test_elseif: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_ELSEIF_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_forloop: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_FORLOOP_OBJECTS) +test_forloop: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_FORLOOP_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_println: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_PRINTLN_OBJECTS) +test_println: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_PRINTLN_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_loader: $(LOADER_OBJECTS) $(RUNTIME_OBJECTS) $(IR_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_LOADER_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_object_methods: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_OBJECT_METHODS_OBJECTS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +test_autobox: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_AUTOBOX_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) test_unittest_demo: $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) @@ -244,7 +265,7 @@ test_unittest_demo: $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) TEST_BENCHMARK_SOURCES = tests/test_benchmark.c TEST_BENCHMARK_OBJECTS = $(TEST_BENCHMARK_SOURCES:.c=.o) -test_benchmark: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(TEST_BENCHMARK_OBJECTS) +test_benchmark: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(TEST_BENCHMARK_OBJECTS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) benchmark: test_benchmark @@ -299,12 +320,12 @@ pgo: test_benchmark_pgo ./test_benchmark_pgo clean: - rm -f $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) \ + rm -f $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) \ $(PHASE0_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) \ $(TEST_LEXER_OBJECTS) $(TEST_PARSER_OBJECTS) $(TEST_SEMANTIC_OBJECTS) $(TEST_IR_OBJECTS) $(TEST_RUNTIME_OBJECTS) \ $(TEST_STRINGS_OBJECTS) $(TEST_ARRAYS_OBJECTS) $(TEST_OBJECTS_OBJECTS) $(TEST_INSTANCE_OBJECTS) $(TEST_FILEIO_OBJECTS) \ - $(TEST_DOWHILE_OBJECTS) $(TEST_SWITCH_OBJECTS) $(TEST_MATH_OBJECTS) $(TEST_STRING_METHODS_OBJECTS) $(TEST_STATIC_OBJECTS) $(TEST_INTERFACES_OBJECTS) $(TEST_EXCEPTIONS_OBJECTS) $(TEST_TERNARY_OBJECTS) $(TEST_BITWISE_OBJECTS) $(TEST_ENHANCED_FOR_OBJECTS) $(TEST_ARRAY_INIT_OBJECTS) $(TEST_INSTANCEOF_OBJECTS) $(TEST_SHORTCIRCUIT_OBJECTS) $(TEST_MULTIDIM_ARRAYS_OBJECTS) $(TEST_STATIC_INIT_OBJECTS) $(TEST_NEGATIVE_OBJECTS) $(TEST_ENUMS_OBJECTS) $(TEST_COLLECTIONS_OBJECTS) $(TEST_SUPER_OBJECTS) $(TEST_INHERITANCE_OBJECTS) $(TEST_BREAK_OBJECTS) $(TEST_ELSEIF_OBJECTS) $(TEST_FORLOOP_OBJECTS) $(TEST_PRINTLN_OBJECTS) $(TEST_BENCHMARK_OBJECTS) \ - test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections test_super test_inheritance test_break test_elseif test_forloop test_println test_benchmark \ + $(TEST_DOWHILE_OBJECTS) $(TEST_SWITCH_OBJECTS) $(TEST_MATH_OBJECTS) $(TEST_STRING_METHODS_OBJECTS) $(TEST_STATIC_OBJECTS) $(TEST_INTERFACES_OBJECTS) $(TEST_EXCEPTIONS_OBJECTS) $(TEST_TERNARY_OBJECTS) $(TEST_BITWISE_OBJECTS) $(TEST_ENHANCED_FOR_OBJECTS) $(TEST_ARRAY_INIT_OBJECTS) $(TEST_INSTANCEOF_OBJECTS) $(TEST_SHORTCIRCUIT_OBJECTS) $(TEST_MULTIDIM_ARRAYS_OBJECTS) $(TEST_STATIC_INIT_OBJECTS) $(TEST_NEGATIVE_OBJECTS) $(TEST_ENUMS_OBJECTS) $(TEST_COLLECTIONS_OBJECTS) $(TEST_SUPER_OBJECTS) $(TEST_INHERITANCE_OBJECTS) $(TEST_BREAK_OBJECTS) $(TEST_ELSEIF_OBJECTS) $(TEST_FORLOOP_OBJECTS) $(TEST_PRINTLN_OBJECTS) $(TEST_LOADER_OBJECTS) $(TEST_OBJECT_METHODS_OBJECTS) $(TEST_AUTOBOX_OBJECTS) $(TEST_BENCHMARK_OBJECTS) \ + test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections test_super test_inheritance test_break test_elseif test_forloop test_println test_loader test_object_methods test_autobox test_benchmark \ test_nanbox test_fastframe test_labeltable test_methodcache test_benchmark_pgo test_unittest_demo *.gcda */*.gcda .PHONY: all clean benchmark test_phase0 pgo test_benchmark_pgo_gen pgo_run test_benchmark_pgo test @@ -318,5 +339,6 @@ test: all ./test_bitwise && ./test_enhanced_for && ./test_array_init && ./test_instanceof && \ ./test_shortcircuit && ./test_multidim_arrays && ./test_static_init && ./test_negative && \ ./test_enums && ./test_collections && ./test_super && ./test_inheritance && ./test_break && \ - ./test_elseif && ./test_forloop && ./test_println && \ + ./test_elseif && ./test_forloop && ./test_println && ./test_loader && ./test_object_methods && \ + ./test_autobox && \ echo "" && echo "=== All Tests Passed ===" diff --git a/runtime/runtime.c b/runtime/runtime.c index 9d868de..8b6ef34 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -504,7 +504,8 @@ RavaVM_t* rava_vm_create(RavaProgram_t *program) { vm->static_fields = rava_static_field_table_create(); vm->method_cache = rava_methodcache_create(); vm->exception_stack = rava_exception_stack_create(); - if (!vm->call_stack || !vm->static_fields || !vm->method_cache || !vm->exception_stack) { + vm->native_registry = rava_native_registry_create(); + if (!vm->call_stack || !vm->static_fields || !vm->method_cache || !vm->exception_stack || !vm->native_registry) { rava_vm_destroy(vm); return NULL; } @@ -532,6 +533,7 @@ void rava_vm_destroy(RavaVM_t *vm) { rava_methodcache_destroy((MethodCache_t*)vm->method_cache); } rava_exception_stack_destroy(vm->exception_stack); + rava_native_registry_destroy(vm->native_registry); for (size_t i = 0; i < RAVA_INTERN_TABLE_SIZE; i++) { free(vm->intern_table.strings[i]); } @@ -951,6 +953,25 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R if (strcmp(instr->operand.call.method_name, "") == 0 && instr->operand.call.arg_count == 0) { break; } + const char *mname = instr->operand.call.method_name; + if (strcmp(mname, "hashCode") == 0 && instr->operand.call.arg_count == 0) { + rava_stack_push(stack, rava_value_int(rava_object_hashcode(obj_val))); + break; + } + if (strcmp(mname, "equals") == 0 && instr->operand.call.arg_count == 1) { + rava_stack_push(stack, rava_value_boolean(rava_object_equals(obj_val, args[0]))); + break; + } + if (strcmp(mname, "toString") == 0 && instr->operand.call.arg_count == 0) { + char *str = rava_object_tostring(obj_val); + rava_stack_push(stack, rava_value_string(str)); + free(str); + break; + } + if (strcmp(mname, "getClass") == 0 && instr->operand.call.arg_count == 0) { + rava_stack_push(stack, rava_value_string(rava_object_getclass(obj_val))); + break; + } vm->had_error = true; vm->error_message = malloc(RAVA_ERROR_BUFFER_SIZE); snprintf(vm->error_message, RAVA_ERROR_BUFFER_SIZE, "Method not found: %s.%s", @@ -3628,11 +3649,54 @@ uf_call_virtual: { vm->had_error = true; goto uf_done; } + const char *mname = instr->operand.call.method_name; + if (!rava_nanbox_is_object(obj_val)) { + RavaValue_t val = rava_nanbox_to_value(obj_val); + if (strcmp(mname, "hashCode") == 0 && arg_count == 0) { + UF_PUSH(rava_nanbox_int(rava_object_hashcode(val))); + UF_DISPATCH(); + } + if (strcmp(mname, "equals") == 0 && arg_count == 1) { + RavaValue_t other = rava_nanbox_to_value(args[0]); + UF_PUSH(rava_nanbox_bool(rava_object_equals(val, other))); + UF_DISPATCH(); + } + if (strcmp(mname, "toString") == 0 && arg_count == 0) { + char *str = rava_object_tostring(val); + UF_PUSH(rava_nanbox_string(str)); + UF_DISPATCH(); + } + if (strcmp(mname, "getClass") == 0 && arg_count == 0) { + UF_PUSH(rava_nanbox_string(rava_object_getclass(val))); + UF_DISPATCH(); + } + vm->had_error = true; + goto uf_done; + } RavaObject_t *obj = rava_nanbox_as_object(obj_val); const char *class_name = obj->class_name; RavaMethod_t *target = _rava_vm_find_method_cached(vm, class_name, instr->operand.call.method_name); if (!target) { - if (strcmp(instr->operand.call.method_name, "") == 0 && arg_count == 0) { + if (strcmp(mname, "") == 0 && arg_count == 0) { + UF_DISPATCH(); + } + RavaValue_t val = rava_nanbox_to_value(obj_val); + if (strcmp(mname, "hashCode") == 0 && arg_count == 0) { + UF_PUSH(rava_nanbox_int(rava_object_hashcode(val))); + UF_DISPATCH(); + } + if (strcmp(mname, "equals") == 0 && arg_count == 1) { + RavaValue_t other = rava_nanbox_to_value(args[0]); + UF_PUSH(rava_nanbox_bool(rava_object_equals(val, other))); + UF_DISPATCH(); + } + if (strcmp(mname, "toString") == 0 && arg_count == 0) { + char *str = rava_object_tostring(val); + UF_PUSH(rava_nanbox_string(str)); + UF_DISPATCH(); + } + if (strcmp(mname, "getClass") == 0 && arg_count == 0) { + UF_PUSH(rava_nanbox_string(rava_object_getclass(val))); UF_DISPATCH(); } vm->had_error = true; @@ -4734,3 +4798,111 @@ RavaValue_t rava_vm_get_result(RavaVM_t *vm) { } return rava_value_int(0); } + +RavaNativeValue_t rava_value_to_native(RavaValue_t value) { + RavaNativeValue_t native; + switch (value.type) { + case RAVA_VAL_INT: + native.type = RAVA_NATIVE_INT; + native.data.int_val = value.data.int_val; + break; + case RAVA_VAL_LONG: + native.type = RAVA_NATIVE_LONG; + native.data.long_val = value.data.long_val; + break; + case RAVA_VAL_FLOAT: + case RAVA_VAL_DOUBLE: + native.type = RAVA_NATIVE_DOUBLE; + native.data.double_val = (value.type == RAVA_VAL_FLOAT) ? + (double)value.data.float_val : value.data.double_val; + break; + case RAVA_VAL_BOOLEAN: + native.type = RAVA_NATIVE_BOOLEAN; + native.data.bool_val = value.data.bool_val; + break; + case RAVA_VAL_STRING: + native.type = RAVA_NATIVE_STRING; + native.data.string_val = value.data.string_val; + break; + case RAVA_VAL_OBJECT: + native.type = RAVA_NATIVE_OBJECT; + native.data.object_val = value.data.object_val; + break; + case RAVA_VAL_ARRAY: + native.type = RAVA_NATIVE_ARRAY; + native.data.array_val = value.data.array_val; + break; + default: + native.type = RAVA_NATIVE_VOID; + break; + } + return native; +} + +RavaValue_t rava_native_to_value(RavaNativeValue_t native) { + RavaValue_t value; + switch (native.type) { + case RAVA_NATIVE_INT: + value = rava_value_int(native.data.int_val); + break; + case RAVA_NATIVE_LONG: + value = rava_value_long(native.data.long_val); + break; + case RAVA_NATIVE_DOUBLE: + value = rava_value_double(native.data.double_val); + break; + case RAVA_NATIVE_BOOLEAN: + value = rava_value_boolean(native.data.bool_val); + break; + case RAVA_NATIVE_STRING: + value = rava_value_string(native.data.string_val); + break; + case RAVA_NATIVE_OBJECT: + value.type = RAVA_VAL_OBJECT; + value.data.object_val = native.data.object_val; + break; + case RAVA_NATIVE_ARRAY: + value.type = RAVA_VAL_ARRAY; + value.data.array_val = native.data.array_val; + break; + default: + value = rava_value_null(); + break; + } + return value; +} + +bool rava_vm_load_native_library(RavaVM_t *vm, const char *path) { + if (!vm || !vm->native_registry || !path) return false; + RavaNativeLibrary_t *lib = rava_native_library_load(vm->native_registry, path); + return lib != NULL; +} + +bool rava_vm_register_native(RavaVM_t *vm, const char *class_name, const char *method_name, + RavaNativeType_e return_type, RavaNativeType_e *param_types, + size_t param_count, RavaNativeFunction_fn function, void *user_data) { + if (!vm || !vm->native_registry) return false; + return rava_native_register_method(vm->native_registry, class_name, method_name, + return_type, param_types, param_count, function, user_data); +} + +RavaValue_t rava_vm_call_native(RavaVM_t *vm, const char *class_name, const char *method_name, + RavaValue_t *args, size_t arg_count) { + if (!vm || !vm->native_registry) return rava_value_null(); + + RavaNativeMethod_t *method = rava_native_find_method(vm->native_registry, class_name, method_name); + if (!method) { + vm->had_error = true; + vm->error_message = malloc(256); + snprintf(vm->error_message, 256, "Native method not found: %s.%s", class_name, method_name); + return rava_value_null(); + } + + RavaNativeValue_t native_args[RAVA_MAX_METHOD_PARAMS]; + for (size_t i = 0; i < arg_count && i < RAVA_MAX_METHOD_PARAMS; i++) { + native_args[i] = rava_value_to_native(args[i]); + } + + RavaNativeValue_t result = rava_native_invoke(method, native_args, arg_count); + return rava_native_to_value(result); +} diff --git a/runtime/runtime.h b/runtime/runtime.h index 33434f5..956d3a4 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -3,6 +3,7 @@ #include "../ir/ir.h" #include "../types/types.h" +#include "../loader/loader.h" #include #include #include @@ -162,6 +163,7 @@ typedef struct { RavaCallStack_t *call_stack; RavaStaticFieldTable_t *static_fields; struct MethodCache_s *method_cache; + RavaNativeRegistry_t *native_registry; char *error_message; bool had_error; bool has_exception; @@ -270,6 +272,11 @@ int rava_object_get_field_index(RavaObject_t *obj, const char *name); RavaValue_t rava_object_get_field_by_index(RavaObject_t *obj, int index); void rava_object_set_field_by_index(RavaObject_t *obj, int index, RavaValue_t value); +int32_t rava_object_hashcode(RavaValue_t value); +bool rava_object_equals(RavaValue_t a, RavaValue_t b); +char* rava_object_tostring(RavaValue_t value); +const char* rava_object_getclass(RavaValue_t value); + RavaArrayList_t* rava_arraylist_create(void); void rava_arraylist_destroy(RavaArrayList_t *list); void rava_arraylist_add(RavaArrayList_t *list, RavaValue_t value); @@ -311,4 +318,14 @@ void rava_vm_destroy(RavaVM_t *vm); bool rava_vm_execute(RavaVM_t *vm, const char *class_name, const char *method_name); RavaValue_t rava_vm_get_result(RavaVM_t *vm); +bool rava_vm_load_native_library(RavaVM_t *vm, const char *path); +bool rava_vm_register_native(RavaVM_t *vm, const char *class_name, const char *method_name, + RavaNativeType_e return_type, RavaNativeType_e *param_types, + size_t param_count, RavaNativeFunction_fn function, void *user_data); +RavaValue_t rava_vm_call_native(RavaVM_t *vm, const char *class_name, const char *method_name, + RavaValue_t *args, size_t arg_count); + +RavaNativeValue_t rava_value_to_native(RavaValue_t value); +RavaValue_t rava_native_to_value(RavaNativeValue_t native); + #endif diff --git a/runtime/runtime_object.c b/runtime/runtime_object.c index c29fc7c..d00b810 100644 --- a/runtime/runtime_object.c +++ b/runtime/runtime_object.c @@ -3,6 +3,8 @@ #include "../utils/safe_alloc.h" #include #include +#include +#include static inline uint32_t _rava_field_hash(const char *name) { uint32_t hash = 5381; @@ -131,3 +133,176 @@ void rava_object_set_field_by_index(RavaObject_t *obj, int index, RavaValue_t va if (!obj || index < 0 || (size_t)index >= obj->field_count) return; obj->field_values[index] = value; } + +int32_t rava_object_hashcode(RavaValue_t value) { + switch (value.type) { + case RAVA_VAL_NULL: + return 0; + case RAVA_VAL_INT: + return value.data.int_val; + case RAVA_VAL_LONG: { + int64_t v = value.data.long_val; + return (int32_t)(v ^ (v >> 32)); + } + case RAVA_VAL_FLOAT: { + union { float f; int32_t i; } u; + u.f = value.data.float_val; + return u.i; + } + case RAVA_VAL_DOUBLE: { + union { double d; int64_t l; } u; + u.d = value.data.double_val; + return (int32_t)(u.l ^ (u.l >> 32)); + } + case RAVA_VAL_BOOLEAN: + return value.data.bool_val ? 1231 : 1237; + case RAVA_VAL_CHAR: + return (int32_t)value.data.char_val; + case RAVA_VAL_STRING: { + if (!value.data.string_val) return 0; + int32_t hash = 0; + for (const char *p = value.data.string_val; *p; p++) { + hash = 31 * hash + (int32_t)(unsigned char)*p; + } + return hash; + } + case RAVA_VAL_OBJECT: + case RAVA_VAL_ARRAY: + case RAVA_VAL_ARRAYLIST: + case RAVA_VAL_HASHMAP: + return (int32_t)((uintptr_t)value.data.object_val >> 3); + } + return 0; +} + +bool rava_object_equals(RavaValue_t a, RavaValue_t b) { + if (a.type == RAVA_VAL_NULL && b.type == RAVA_VAL_NULL) { + return true; + } + if (a.type == RAVA_VAL_NULL || b.type == RAVA_VAL_NULL) { + return false; + } + + if (a.type == RAVA_VAL_STRING && b.type == RAVA_VAL_STRING) { + if (!a.data.string_val && !b.data.string_val) return true; + if (!a.data.string_val || !b.data.string_val) return false; + return strcmp(a.data.string_val, b.data.string_val) == 0; + } + + if (a.type != b.type) { + return false; + } + + switch (a.type) { + case RAVA_VAL_INT: + return a.data.int_val == b.data.int_val; + case RAVA_VAL_LONG: + return a.data.long_val == b.data.long_val; + case RAVA_VAL_FLOAT: + return a.data.float_val == b.data.float_val; + case RAVA_VAL_DOUBLE: + return a.data.double_val == b.data.double_val; + case RAVA_VAL_BOOLEAN: + return a.data.bool_val == b.data.bool_val; + case RAVA_VAL_CHAR: + return a.data.char_val == b.data.char_val; + case RAVA_VAL_OBJECT: + case RAVA_VAL_ARRAY: + case RAVA_VAL_ARRAYLIST: + case RAVA_VAL_HASHMAP: + return a.data.object_val == b.data.object_val; + default: + return false; + } +} + +char* rava_object_tostring(RavaValue_t value) { + char *buffer = malloc(128); + if (!buffer) return NULL; + + switch (value.type) { + case RAVA_VAL_NULL: + strcpy(buffer, "null"); + break; + case RAVA_VAL_INT: + snprintf(buffer, 128, "%d", value.data.int_val); + break; + case RAVA_VAL_LONG: + snprintf(buffer, 128, "%ld", value.data.long_val); + break; + case RAVA_VAL_FLOAT: + snprintf(buffer, 128, "%g", (double)value.data.float_val); + break; + case RAVA_VAL_DOUBLE: + snprintf(buffer, 128, "%g", value.data.double_val); + break; + case RAVA_VAL_BOOLEAN: + strcpy(buffer, value.data.bool_val ? "true" : "false"); + break; + case RAVA_VAL_CHAR: + snprintf(buffer, 128, "%c", value.data.char_val); + break; + case RAVA_VAL_STRING: + free(buffer); + return value.data.string_val ? strdup(value.data.string_val) : strdup("null"); + case RAVA_VAL_OBJECT: + if (!value.data.object_val) { + strcpy(buffer, "null"); + } else { + snprintf(buffer, 128, "%s@%x", + value.data.object_val->class_name, + (unsigned int)((uintptr_t)value.data.object_val >> 3)); + } + break; + case RAVA_VAL_ARRAY: + if (!value.data.array_val) { + strcpy(buffer, "null"); + } else { + snprintf(buffer, 128, "[array@%x]", + (unsigned int)((uintptr_t)value.data.array_val >> 3)); + } + break; + case RAVA_VAL_ARRAYLIST: + snprintf(buffer, 128, "ArrayList@%x", + (unsigned int)((uintptr_t)value.data.arraylist_val >> 3)); + break; + case RAVA_VAL_HASHMAP: + snprintf(buffer, 128, "HashMap@%x", + (unsigned int)((uintptr_t)value.data.hashmap_val >> 3)); + break; + } + return buffer; +} + +const char* rava_object_getclass(RavaValue_t value) { + switch (value.type) { + case RAVA_VAL_NULL: + return "null"; + case RAVA_VAL_INT: + return "Integer"; + case RAVA_VAL_LONG: + return "Long"; + case RAVA_VAL_FLOAT: + return "Float"; + case RAVA_VAL_DOUBLE: + return "Double"; + case RAVA_VAL_BOOLEAN: + return "Boolean"; + case RAVA_VAL_CHAR: + return "Character"; + case RAVA_VAL_STRING: + return "String"; + case RAVA_VAL_OBJECT: + if (value.data.object_val) { + return value.data.object_val->class_name; + } + return "null"; + case RAVA_VAL_ARRAY: + return "Array"; + case RAVA_VAL_ARRAYLIST: + return "ArrayList"; + case RAVA_VAL_HASHMAP: + return "HashMap"; + } + return "Object"; +} diff --git a/tests/test_array_init.o b/tests/test_array_init.o index 37d7817..8f05162 100644 Binary files a/tests/test_array_init.o and b/tests/test_array_init.o differ diff --git a/tests/test_arrays.o b/tests/test_arrays.o index 49ee78d..079bbcc 100644 Binary files a/tests/test_arrays.o and b/tests/test_arrays.o differ diff --git a/tests/test_bitwise.o b/tests/test_bitwise.o index 7e40f49..79aeb78 100644 Binary files a/tests/test_bitwise.o and b/tests/test_bitwise.o differ diff --git a/tests/test_collections.o b/tests/test_collections.o index c0cc6b3..6827f0f 100644 Binary files a/tests/test_collections.o and b/tests/test_collections.o differ diff --git a/tests/test_dowhile.o b/tests/test_dowhile.o index 0f2c888..f4d8d3e 100644 Binary files a/tests/test_dowhile.o and b/tests/test_dowhile.o differ diff --git a/tests/test_enhanced_for.o b/tests/test_enhanced_for.o index 00308d2..a393a38 100644 Binary files a/tests/test_enhanced_for.o and b/tests/test_enhanced_for.o differ diff --git a/tests/test_enums.o b/tests/test_enums.o index 2075c1b..0811719 100644 Binary files a/tests/test_enums.o and b/tests/test_enums.o differ diff --git a/tests/test_exceptions.o b/tests/test_exceptions.o index f16342d..bf9c1cf 100644 Binary files a/tests/test_exceptions.o and b/tests/test_exceptions.o differ diff --git a/tests/test_fileio.o b/tests/test_fileio.o index f165647..8533c77 100644 Binary files a/tests/test_fileio.o and b/tests/test_fileio.o differ diff --git a/tests/test_instance_methods.o b/tests/test_instance_methods.o index 44fd209..a68d49e 100644 Binary files a/tests/test_instance_methods.o and b/tests/test_instance_methods.o differ diff --git a/tests/test_instanceof.o b/tests/test_instanceof.o index af3a3c6..2165025 100644 Binary files a/tests/test_instanceof.o and b/tests/test_instanceof.o differ diff --git a/tests/test_interfaces.o b/tests/test_interfaces.o index bcf1e6b..eb1cc9d 100644 Binary files a/tests/test_interfaces.o and b/tests/test_interfaces.o differ diff --git a/tests/test_math.o b/tests/test_math.o index a9dbb98..0166160 100644 Binary files a/tests/test_math.o and b/tests/test_math.o differ diff --git a/tests/test_multidim_arrays.o b/tests/test_multidim_arrays.o index 3d22bbe..cd23d45 100644 Binary files a/tests/test_multidim_arrays.o and b/tests/test_multidim_arrays.o differ diff --git a/tests/test_objects.o b/tests/test_objects.o index aa09ff5..bfc273c 100644 Binary files a/tests/test_objects.o and b/tests/test_objects.o differ diff --git a/tests/test_runtime.o b/tests/test_runtime.o index e580ee5..28bc361 100644 Binary files a/tests/test_runtime.o and b/tests/test_runtime.o differ diff --git a/tests/test_shortcircuit.o b/tests/test_shortcircuit.o index c196174..2523eb0 100644 Binary files a/tests/test_shortcircuit.o and b/tests/test_shortcircuit.o differ diff --git a/tests/test_static.o b/tests/test_static.o index b2aeabe..a07644d 100644 Binary files a/tests/test_static.o and b/tests/test_static.o differ diff --git a/tests/test_static_init.o b/tests/test_static_init.o index 2dbf158..0e9c032 100644 Binary files a/tests/test_static_init.o and b/tests/test_static_init.o differ diff --git a/tests/test_string_methods.o b/tests/test_string_methods.o index 62c1f22..52e32cc 100644 Binary files a/tests/test_string_methods.o and b/tests/test_string_methods.o differ diff --git a/tests/test_strings.o b/tests/test_strings.o index ef58009..011819a 100644 Binary files a/tests/test_strings.o and b/tests/test_strings.o differ diff --git a/tests/test_switch.o b/tests/test_switch.o index ebd911c..de00357 100644 Binary files a/tests/test_switch.o and b/tests/test_switch.o differ diff --git a/tests/test_ternary.o b/tests/test_ternary.o index a025891..765dde2 100644 Binary files a/tests/test_ternary.o and b/tests/test_ternary.o differ diff --git a/types/types.c b/types/types.c index d953c23..8e662ea 100644 --- a/types/types.c +++ b/types/types.c @@ -118,6 +118,27 @@ bool rava_type_is_reference(RavaType_t *type) { type->kind == RAVA_TYPE_NULL; } +static RavaTypeKind_e _get_wrapper_primitive(RavaType_t *type) { + if (type->kind != RAVA_TYPE_CLASS || !type->data.class_type.class_name) { + return RAVA_TYPE_UNKNOWN; + } + const char *name = type->data.class_type.class_name; + if (strcmp(name, "Integer") == 0) return RAVA_TYPE_INT; + if (strcmp(name, "Long") == 0) return RAVA_TYPE_LONG; + if (strcmp(name, "Double") == 0) return RAVA_TYPE_DOUBLE; + if (strcmp(name, "Float") == 0) return RAVA_TYPE_FLOAT; + if (strcmp(name, "Boolean") == 0) return RAVA_TYPE_BOOLEAN; + if (strcmp(name, "Character") == 0) return RAVA_TYPE_CHAR; + if (strcmp(name, "Byte") == 0) return RAVA_TYPE_BYTE; + if (strcmp(name, "Short") == 0) return RAVA_TYPE_SHORT; + return RAVA_TYPE_UNKNOWN; +} + +static bool _is_wrapper_for_primitive(RavaType_t *wrapper, RavaType_t *primitive) { + RavaTypeKind_e wk = _get_wrapper_primitive(wrapper); + return wk != RAVA_TYPE_UNKNOWN && wk == primitive->kind; +} + bool rava_type_equals(RavaType_t *a, RavaType_t *b) { if (!a || !b) return false; if (a->kind != b->kind) return false; @@ -149,6 +170,14 @@ bool rava_type_is_assignable_to(RavaType_t *from, RavaType_t *to) { return from_rank <= to_rank; } + if (rava_type_is_primitive(from) && _is_wrapper_for_primitive(to, from)) { + return true; + } + + if (rava_type_is_primitive(to) && _is_wrapper_for_primitive(from, to)) { + return true; + } + return false; }