This commit is contained in:
retoor 2025-12-04 23:51:05 +01:00
parent 5b5d2e1009
commit e953861621
28 changed files with 453 additions and 38 deletions

View File

@ -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_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) 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_SOURCES = runtime/fastframe.c runtime/labeltable.c runtime/methodcache.c
PHASE0_OBJECTS = $(PHASE0_SOURCES:.c=.o) 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_SOURCES = tests/test_println.c
TEST_PRINTLN_OBJECTS = $(TEST_PRINTLN_SOURCES:.c=.o) 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_SOURCES = tests/unittest.c
UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o) UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o)
TEST_UNITTEST_DEMO_SOURCES = tests/test_unittest_demo.c TEST_UNITTEST_DEMO_SOURCES = tests/test_unittest_demo.c
TEST_UNITTEST_DEMO_OBJECTS = $(TEST_UNITTEST_DEMO_SOURCES:.c=.o) 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) test_lexer: $(LEXER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_LEXER_OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(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) test_ir: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) runtime/labeltable.o $(UNITTEST_OBJECTS) $(TEST_IR_OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(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) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
test_unittest_demo: $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) 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_SOURCES = tests/test_benchmark.c
TEST_BENCHMARK_OBJECTS = $(TEST_BENCHMARK_SOURCES:.c=.o) 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) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
benchmark: test_benchmark benchmark: test_benchmark
@ -299,12 +320,12 @@ pgo: test_benchmark_pgo
./test_benchmark_pgo ./test_benchmark_pgo
clean: 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) \ $(PHASE0_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_UNITTEST_DEMO_OBJECTS) \
$(TEST_LEXER_OBJECTS) $(TEST_PARSER_OBJECTS) $(TEST_SEMANTIC_OBJECTS) $(TEST_IR_OBJECTS) $(TEST_RUNTIME_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_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_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_benchmark \ 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 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 .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_bitwise && ./test_enhanced_for && ./test_array_init && ./test_instanceof && \
./test_shortcircuit && ./test_multidim_arrays && ./test_static_init && ./test_negative && \ ./test_shortcircuit && ./test_multidim_arrays && ./test_static_init && ./test_negative && \
./test_enums && ./test_collections && ./test_super && ./test_inheritance && ./test_break && \ ./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 ===" echo "" && echo "=== All Tests Passed ==="

View File

@ -504,7 +504,8 @@ RavaVM_t* rava_vm_create(RavaProgram_t *program) {
vm->static_fields = rava_static_field_table_create(); vm->static_fields = rava_static_field_table_create();
vm->method_cache = rava_methodcache_create(); vm->method_cache = rava_methodcache_create();
vm->exception_stack = rava_exception_stack_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); rava_vm_destroy(vm);
return NULL; return NULL;
} }
@ -532,6 +533,7 @@ void rava_vm_destroy(RavaVM_t *vm) {
rava_methodcache_destroy((MethodCache_t*)vm->method_cache); rava_methodcache_destroy((MethodCache_t*)vm->method_cache);
} }
rava_exception_stack_destroy(vm->exception_stack); 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++) { for (size_t i = 0; i < RAVA_INTERN_TABLE_SIZE; i++) {
free(vm->intern_table.strings[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, "<init>") == 0 && instr->operand.call.arg_count == 0) { if (strcmp(instr->operand.call.method_name, "<init>") == 0 && instr->operand.call.arg_count == 0) {
break; 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->had_error = true;
vm->error_message = malloc(RAVA_ERROR_BUFFER_SIZE); vm->error_message = malloc(RAVA_ERROR_BUFFER_SIZE);
snprintf(vm->error_message, RAVA_ERROR_BUFFER_SIZE, "Method not found: %s.%s", snprintf(vm->error_message, RAVA_ERROR_BUFFER_SIZE, "Method not found: %s.%s",
@ -3628,11 +3649,54 @@ uf_call_virtual: {
vm->had_error = true; vm->had_error = true;
goto uf_done; 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); RavaObject_t *obj = rava_nanbox_as_object(obj_val);
const char *class_name = obj->class_name; const char *class_name = obj->class_name;
RavaMethod_t *target = _rava_vm_find_method_cached(vm, class_name, instr->operand.call.method_name); RavaMethod_t *target = _rava_vm_find_method_cached(vm, class_name, instr->operand.call.method_name);
if (!target) { if (!target) {
if (strcmp(instr->operand.call.method_name, "<init>") == 0 && arg_count == 0) { if (strcmp(mname, "<init>") == 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(); UF_DISPATCH();
} }
vm->had_error = true; vm->had_error = true;
@ -4734,3 +4798,111 @@ RavaValue_t rava_vm_get_result(RavaVM_t *vm) {
} }
return rava_value_int(0); 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);
}

View File

@ -3,6 +3,7 @@
#include "../ir/ir.h" #include "../ir/ir.h"
#include "../types/types.h" #include "../types/types.h"
#include "../loader/loader.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@ -162,6 +163,7 @@ typedef struct {
RavaCallStack_t *call_stack; RavaCallStack_t *call_stack;
RavaStaticFieldTable_t *static_fields; RavaStaticFieldTable_t *static_fields;
struct MethodCache_s *method_cache; struct MethodCache_s *method_cache;
RavaNativeRegistry_t *native_registry;
char *error_message; char *error_message;
bool had_error; bool had_error;
bool has_exception; 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); 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); 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); RavaArrayList_t* rava_arraylist_create(void);
void rava_arraylist_destroy(RavaArrayList_t *list); void rava_arraylist_destroy(RavaArrayList_t *list);
void rava_arraylist_add(RavaArrayList_t *list, RavaValue_t value); 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); bool rava_vm_execute(RavaVM_t *vm, const char *class_name, const char *method_name);
RavaValue_t rava_vm_get_result(RavaVM_t *vm); 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 #endif

View File

@ -3,6 +3,8 @@
#include "../utils/safe_alloc.h" #include "../utils/safe_alloc.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include <stdint.h>
static inline uint32_t _rava_field_hash(const char *name) { static inline uint32_t _rava_field_hash(const char *name) {
uint32_t hash = 5381; 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; if (!obj || index < 0 || (size_t)index >= obj->field_count) return;
obj->field_values[index] = value; 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";
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -118,6 +118,27 @@ bool rava_type_is_reference(RavaType_t *type) {
type->kind == RAVA_TYPE_NULL; 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) { bool rava_type_equals(RavaType_t *a, RavaType_t *b) {
if (!a || !b) return false; if (!a || !b) return false;
if (a->kind != b->kind) 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; 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; return false;
} }