Compare commits

..
28 Commits
Author SHA1 Message Date
retoor d7677d7941 Updated Readme
CI / Optimization Infrastructure Tests (push) Successful in 19s
CI / Unit Tests (push) Successful in 39s
CI / Integration Tests (push) Successful in 44s
CI / Performance Benchmark (push) Successful in 59s
PGO Build / Profile-Guided Optimization Build (push) Failing after 1m5s
2025-12-05 12:36:51 +01:00
retoor a92ed68948 Repl.
CI / Optimization Infrastructure Tests (push) Successful in 16s
CI / Unit Tests (push) Successful in 30s
CI / Integration Tests (push) Successful in 27s
CI / Performance Benchmark (push) Successful in 39s
2025-12-05 12:32:09 +01:00
retoor 9ad8893ea9 Hmm. 2025-12-05 11:16:00 +01:00
retoor f7df28e897 Update, finaly an interpreter. 2025-12-05 11:04:14 +01:00
retoor faec0e0d9e Upgrade to int64 2025-12-05 10:58:43 +01:00
retoor fca0ade573 Update.
CI / Optimization Infrastructure Tests (push) Successful in 22s
CI / Unit Tests (push) Successful in 23s
CI / Integration Tests (push) Successful in 31s
CI / Performance Benchmark (push) Successful in 56s
2025-12-05 01:23:43 +01:00
retoor b46f0d9ff4 UPdate. 2025-12-05 01:12:39 +01:00
retoor e33fa20c60 Update. 2025-12-05 01:12:25 +01:00
retoor de7f824feb IUpdate. 2025-12-05 00:28:01 +01:00
retoor e2e0788953 Update. 2025-12-04 23:51:34 +01:00
retoor e953861621 Update. 2025-12-04 23:51:05 +01:00
retoor 5b5d2e1009 Update. 2025-12-04 23:00:10 +01:00
retoor f58f42a4a2 Update. 2025-12-04 22:54:41 +01:00
retoor cdcfdf375c Update.
CI / Optimization Infrastructure Tests (push) Successful in 17s
CI / Unit Tests (push) Successful in 19s
CI / Integration Tests (push) Successful in 25s
CI / Performance Benchmark (push) Successful in 42s
2025-12-04 22:46:38 +01:00
retoor 56212ecef1 Update.
CI / Optimization Infrastructure Tests (push) Successful in 19s
CI / Unit Tests (push) Successful in 20s
CI / Integration Tests (push) Successful in 36s
CI / Performance Benchmark (push) Successful in 42s
2025-12-04 22:38:05 +01:00
retoor 0d11a127e2 Update.
CI / Unit Tests (push) Successful in 19s
CI / Optimization Infrastructure Tests (push) Successful in 19s
CI / Integration Tests (push) Successful in 40s
CI / Performance Benchmark (push) Successful in 35s
2025-12-04 16:55:18 +01:00
retoor 1afd91c1c7 Update.
CI / Optimization Infrastructure Tests (push) Failing after 13s
CI / Unit Tests (push) Failing after 29s
CI / Integration Tests (push) Has been skipped
CI / Performance Benchmark (push) Has been skipped
2025-12-04 16:49:20 +01:00
retoor e1ddf91281 Power up./plot.py 2025-12-04 06:14:22 +01:00
retoor c8fe57191c Upgrade.
CI / Optimization Infrastructure Tests (push) Failing after 15s
CI / Unit Tests (push) Failing after 17s
CI / Integration Tests (push) Has been skipped
CI / Performance Benchmark (push) Has been skipped
2025-12-03 23:51:38 +01:00
retoor 388bf28102 Beating python on all benchmarks. 2025-12-03 17:55:37 +01:00
retoor 253b87c9ae Performance fixes. 2025-12-03 15:01:02 +01:00
retoor a3cad2b743 Update, multi dimentional arrays.
CI / Optimization Infrastructure Tests (push) Failing after 12s
CI / Unit Tests (push) Failing after 25s
CI / Integration Tests (push) Has been skipped
CI / Performance Benchmark (push) Has been skipped
2025-12-03 14:08:55 +01:00
retoor 7c4f92484a Update.
CI / Unit Tests (push) Failing after 12s
CI / Integration Tests (push) Has been skipped
CI / Performance Benchmark (push) Has been skipped
CI / Optimization Infrastructure Tests (push) Failing after 23s
2025-12-02 22:04:26 +01:00
retoor 44126e4ac0 Update.
CI / Unit Tests (push) Failing after 14s
CI / Optimization Infrastructure Tests (push) Failing after 14s
CI / Integration Tests (push) Has been skipped
CI / Performance Benchmark (push) Has been skipped
2025-12-02 21:15:14 +01:00
retoor de48b1e64c Update. 2025-12-02 21:12:50 +01:00
retoor 3872c52997 Gitea build steps + README.md
CI / Unit Tests (push) Failing after 14s
CI / Integration Tests (push) Has been skipped
CI / Performance Benchmark (push) Has been skipped
CI / Optimization Infrastructure Tests (push) Failing after 27s
2025-12-02 07:28:38 +01:00
retoor 50b9fedb36 Added README.md 2025-12-02 06:55:27 +01:00
retoor c9cf356cbd Initial commit of dem beast./plot.py 2025-12-02 06:54:32 +01:00
89 changed files with 1098 additions and 6239 deletions
+6 -3
View File
@@ -124,7 +124,10 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y gcc make python3 default-jdk sudo apt-get install -y gcc make python3
- name: Run benchmark suite - name: Build benchmark
run: make benchmark run: make test_benchmark
- name: Run benchmark
run: ./test_benchmark
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
gcc -Wall -Wextra -std=gnu99 -O3 -march=native -I. -fprofile-use -fprofile-correction \ gcc -Wall -Wextra -std=gnu99 -O3 -march=native -I. -fprofile-use -fprofile-correction \
-o test_benchmark_pgo \ -o test_benchmark_pgo \
lexer/lexer_tokenizer.c lexer/lexer_keywords.c lexer/lexer_literals.c \ lexer/lexer_tokenizer.c lexer/lexer_keywords.c lexer/lexer_literals.c \
parser/parser.c parser/parser_expressions.c parser/parser_statements.c parser/parser_declarations.c \ parser/parser.c parser/parser_expressions.c parser/parser_statements.c parser/parser_declarations.c parser/parser_printer.c \
types/types.c \ types/types.c \
semantic/symbol_table.c semantic/semantic.c \ semantic/symbol_table.c semantic/semantic.c \
ir/ir.c ir/ir_gen.c \ ir/ir.c ir/ir_gen.c \
-4
View File
@@ -6,7 +6,3 @@ merge.py
*.o *.o
run_examples run_examples
rava rava
*.gcno
*.gcda
coverage_report
*.info
+4 -149
View File
@@ -5,7 +5,7 @@ LDFLAGS = -ldl -lm
LEXER_SOURCES = lexer/lexer_tokenizer.c lexer/lexer_keywords.c lexer/lexer_literals.c LEXER_SOURCES = lexer/lexer_tokenizer.c lexer/lexer_keywords.c lexer/lexer_literals.c
LEXER_OBJECTS = $(LEXER_SOURCES:.c=.o) LEXER_OBJECTS = $(LEXER_SOURCES:.c=.o)
PARSER_SOURCES = parser/parser.c parser/parser_expressions.c parser/parser_statements.c parser/parser_declarations.c PARSER_SOURCES = parser/parser.c parser/parser_expressions.c parser/parser_statements.c parser/parser_declarations.c parser/parser_printer.c
PARSER_OBJECTS = $(PARSER_SOURCES:.c=.o) PARSER_OBJECTS = $(PARSER_SOURCES:.c=.o)
TYPES_SOURCES = types/types.c TYPES_SOURCES = types/types.c
@@ -20,8 +20,7 @@ IR_OBJECTS = $(IR_SOURCES:.c=.o)
GC_SOURCES = runtime/gc/gc.c runtime/gc/gc_heap.c runtime/gc/gc_mark.c runtime/gc/gc_sweep.c runtime/gc/gc_roots.c GC_SOURCES = runtime/gc/gc.c runtime/gc/gc_heap.c runtime/gc/gc_mark.c runtime/gc/gc_sweep.c runtime/gc/gc_roots.c
GC_OBJECTS = $(GC_SOURCES:.c=.o) GC_OBJECTS = $(GC_SOURCES:.c=.o)
RUNTIME_CORE_SOURCES = runtime/runtime_value.c runtime/runtime_stack.c runtime/runtime_static.c runtime/runtime_exception.c runtime/runtime_intern.c runtime/runtime_lookup.c RUNTIME_SOURCES = runtime/runtime.c runtime/runtime_array.c runtime/runtime_object.c runtime/runtime_collections.c runtime/runtime_socket.c runtime/runtime_method_ref.c runtime/labeltable.c runtime/methodcache.c runtime/fastframe.c runtime/superinst.c $(GC_SOURCES)
RUNTIME_SOURCES = runtime/runtime.c $(RUNTIME_CORE_SOURCES) runtime/runtime_array.c runtime/runtime_object.c runtime/runtime_collections.c runtime/runtime_socket.c runtime/runtime_method_ref.c runtime/labeltable.c runtime/methodcache.c runtime/fastframe.c runtime/superinst.c $(GC_SOURCES)
RUNTIME_OBJECTS = $(RUNTIME_SOURCES:.c=.o) RUNTIME_OBJECTS = $(RUNTIME_SOURCES:.c=.o)
LOADER_SOURCES = loader/loader.c LOADER_SOURCES = loader/loader.c
@@ -57,12 +56,6 @@ TEST_ARRAYS_OBJECTS = $(TEST_ARRAYS_SOURCES:.c=.o)
TEST_OBJECTS_SOURCES = tests/test_objects.c TEST_OBJECTS_SOURCES = tests/test_objects.c
TEST_OBJECTS_OBJECTS = $(TEST_OBJECTS_SOURCES:.c=.o) TEST_OBJECTS_OBJECTS = $(TEST_OBJECTS_SOURCES:.c=.o)
TEST_OVERLOADING_SOURCES = tests/test_overloading.c
TEST_OVERLOADING_OBJECTS = $(TEST_OVERLOADING_SOURCES:.c=.o)
TEST_OVERLOADING_RUNTIME_SOURCES = tests/test_overloading_runtime.c
TEST_OVERLOADING_RUNTIME_OBJECTS = $(TEST_OVERLOADING_RUNTIME_SOURCES:.c=.o)
TEST_INSTANCE_SOURCES = tests/test_instance_methods.c TEST_INSTANCE_SOURCES = tests/test_instance_methods.c
TEST_INSTANCE_OBJECTS = $(TEST_INSTANCE_SOURCES:.c=.o) TEST_INSTANCE_OBJECTS = $(TEST_INSTANCE_SOURCES:.c=.o)
@@ -165,7 +158,7 @@ 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: rava 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_sockets test_method_ref test_gc 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_sockets test_method_ref test_gc
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)
@@ -191,12 +184,6 @@ test_arrays: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJE
test_objects: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_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_overloading: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_OVERLOADING_OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
test_overloading_runtime: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(UNITTEST_OBJECTS) $(TEST_OVERLOADING_RUNTIME_OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
test_instance_methods: $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_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)
@@ -317,20 +304,6 @@ benchmark: test_benchmark
@echo "========================================" @echo "========================================"
@python3 examples/benchmark.py @python3 examples/benchmark.py
@echo "" @echo ""
@if command -v javac >/dev/null 2>&1; then \
echo "========================================"; \
echo " JAVA (OpenJDK)"; \
echo "========================================"; \
javac examples/20_Benchmark.java -d /tmp; \
java -cp /tmp Benchmark; \
rm -f /tmp/Benchmark.class; \
else \
echo "========================================"; \
echo " JAVA (OpenJDK) - SKIPPED"; \
echo "========================================"; \
echo "Java/JDK not installed. Install with: apt install default-jdk"; \
fi
@echo ""
rava: rava.o $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(REPL_OBJECTS) rava: rava.o $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS) $(REPL_OBJECTS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lreadline $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lreadline
@@ -391,125 +364,7 @@ clean:
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_sockets test_method_ref test_gc 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_sockets test_method_ref test_gc test_benchmark \
test_nanbox test_fastframe test_labeltable test_methodcache test_benchmark_pgo test_unittest_demo rava rava.o *.gcda */*.gcda test_nanbox test_fastframe test_labeltable test_methodcache test_benchmark_pgo test_unittest_demo rava rava.o *.gcda */*.gcda
.PHONY: all clean benchmark test_phase0 pgo test_benchmark_pgo_gen pgo_run test_benchmark_pgo test test_repl examples coverage coverage-clean coverage-report .PHONY: all clean benchmark test_phase0 pgo test_benchmark_pgo_gen pgo_run test_benchmark_pgo test test_repl examples
COVERAGE_CFLAGS = -Wall -Wextra -Werror -std=gnu99 -O0 -g --coverage -I.
COVERAGE_LDFLAGS = -ldl -lm --coverage
coverage-clean:
rm -f *.gcda *.gcno *.gcov
rm -f */*.gcda */*.gcno */*.gcov
rm -f */*/*.gcda */*/*.gcno */*/*.gcov
rm -rf coverage_report
coverage: coverage-clean
@echo "=== Building with coverage instrumentation ==="
$(MAKE) clean
$(MAKE) CC="$(CC)" CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" all
$(MAKE) CC="$(CC)" CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" test_overloading test_overloading_runtime
@echo ""
@echo "=== Running ALL tests to collect coverage data ==="
-./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_static_init
-./test_interfaces
-./test_exceptions
-./test_ternary
-./test_bitwise
-./test_enhanced_for
-./test_array_init
-./test_instanceof
-./test_shortcircuit
-./test_multidim_arrays
-./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_sockets
-./test_method_ref
-./test_gc
-./test_nanbox
-./test_fastframe
-./test_labeltable
-./test_methodcache
-./test_benchmark
-./test_overloading
-./test_overloading_runtime
@echo ""
@echo "=== Running ALL example programs ==="
-./rava examples/01_Fibonacci.java Fibonacci main
-./rava examples/02_PrimeNumbers.java PrimeNumbers main
-./rava examples/03_FactorialVariations.java FactorialVariations main
-./rava examples/04_GCD_LCM.java GCD_LCM main
-./rava examples/05_PowerFunction.java PowerFunction main
-./rava examples/06_ArrayOperations.java ArrayOperations main
-./rava examples/06_BubbleSort.java BubbleSort main
-./rava examples/07_CollatzConjecture.java CollatzConjecture main
-./rava examples/08_PascalTriangle.java PascalTriangle main
-./rava examples/09_TowerOfHanoi.java TowerOfHanoi main
-./rava examples/10_AckermannFunction.java AckermannFunction main
-./rava examples/11_ArrayOperations.java ArrayOperations main
-./rava examples/11_SimpleArray.java SimpleArray main
-./rava examples/11_TowerOfHanoiStatic.java TowerOfHanoiStatic main
-./rava examples/12_StringBasics.java StringBasics main
-./rava examples/13_SimpleObject.java SimpleObject main
-./rava examples/14_InstanceMethods.java InstanceMethods main
-./rava examples/15_FileIO.java FileIO main
-./rava examples/16_ForLoop.java ForLoop main
-./rava examples/17_Inheritance.java Inheritance main
-./rava examples/18_ElseIf.java ElseIf main
-./rava examples/19_BreakContinue.java BreakContinue main
-./rava examples/20_Benchmark.java Benchmark main
-./rava examples/21_DoWhile.java DoWhile main
-./rava examples/HelloWorld.java HelloWorld main
@echo ""
@echo "=== Generating coverage report ==="
$(MAKE) coverage-report
coverage-report:
@echo "=== Coverage Summary ==="
@echo ""
@for dir in lexer parser types semantic ir runtime loader; do \
echo "--- $$dir/ ---"; \
for f in $$dir/*.c; do \
gcov -n "$$f" 2>/dev/null | grep -A1 "^File" | grep -v "^--$$" || true; \
done; \
echo ""; \
done
@echo "=== Detailed .gcov files generated in source directories ==="
@echo "Run 'gcov <file.c>' for detailed line-by-line coverage"
@echo "Run 'make coverage-html' for HTML report (requires lcov)"
coverage-html:
@echo "=== Generating HTML coverage report ==="
@which lcov > /dev/null || (echo "ERROR: lcov not installed. Run: sudo apt-get install lcov" && exit 1)
lcov --capture --directory . --output-file coverage.info --ignore-errors inconsistent,unused
lcov --remove coverage.info '/usr/*' '*/tests/*' --output-file coverage.info --ignore-errors inconsistent,unused
genhtml coverage.info --output-directory coverage_report --ignore-errors inconsistent,unused
@echo ""
@echo "=== HTML report generated in coverage_report/ ==="
@xdg-open coverage_report/index.html 2>/dev/null || open coverage_report/index.html 2>/dev/null || echo "Open coverage_report/index.html in a browser"
test: all test: all
@echo "=== Running All Tests ===" @echo "=== Running All Tests ==="
+7 -84
View File
@@ -147,92 +147,15 @@ make test_repl
## Performance ## Performance
Rava beats Python on 18 out of 21 benchmarks (85.7% win rate). Rava beats Python on all benchmarks.
### Comprehensive Benchmark Results | Benchmark | Rava | Python | Speedup |
|-----------|------|--------|---------|
| Fibonacci(30) | 257ms | 291ms | 1.13x faster |
| Primes(100k) | 273ms | 416ms | 1.52x faster |
| Sum(10M) | 666ms | 1104ms | 1.66x faster |
| Benchmark | Rava | Python | Winner | Speedup | Started at 1402ms for Fibonacci. After 9 optimization phases: 257ms. That is 5.5x faster.
|-----------|------|--------|--------|---------|
| Fibonacci(30) recursive | 219ms | 587ms | **Rava** | **2.68x** |
| Fibonacci(40) iterative | 0ms | 0ms | Tie | 1.00x |
| Primes (100K) | 337ms | 685ms | **Rava** | **2.03x** |
| Sum (10M) | 690ms | 1317ms | **Rava** | **1.91x** |
| Array sum (1M) | 161ms | 331ms | **Rava** | **2.06x** |
| Array reverse (1M) | 258ms | 278ms | **Rava** | **1.08x** |
| Nested loops (1000x1000) | 86ms | 119ms | **Rava** | **1.38x** |
| Factorial(15) recursive | 0ms | 0ms | Tie | 1.00x |
| Ackermann(3,6) | 16ms | 84ms | **Rava** | **5.25x** |
| Method calls (10M) | 1439ms | 2032ms | **Rava** | **1.41x** |
| Arithmetic ops (10M) | 1632ms | 4259ms | **Rava** | **2.61x** |
| Conditional branches (10M) | 1384ms | 2035ms | **Rava** | **1.47x** |
| Complex conditions (10M) | 2797ms | 3369ms | **Rava** | **1.20x** |
| Matrix multiply (50x50) | 32ms | 31ms | Python | 0.97x |
| Bubble sort (5000) | 3405ms | 4391ms | **Rava** | **1.29x** |
| Quick sort (1000) | 108ms | 110ms | **Rava** | **1.02x** |
| Insertion sort (3000) | 791ms | 1029ms | **Rava** | **1.30x** |
| Binary search (100K) | 13ms | 16ms | **Rava** | **1.23x** |
| String concat (50K) | 19ms | 29ms | **Rava** | **1.53x** |
| Bitwise ops (10M) | 2735ms | 7392ms | **Rava** | **2.70x** |
| Array copy (1M) | 328ms | 240ms | Python | 0.73x |
### Notable Victories
- **Ackermann function: 5.25x faster** - Deep recursion handling
- **Bitwise operations: 2.70x faster** - Efficient bit manipulation
- **Fibonacci recursive: 2.68x faster** - Optimized function calls
- **Arithmetic operations: 2.61x faster** - Fast numeric computation
- **Array sum: 2.06x faster** - Optimized array access
- **Primes: 2.03x faster** - Efficient loop execution
Started at 1402ms for Fibonacci(30). After optimization: 219ms. **6.4x improvement**.
### Three-Way Benchmark: Rava vs Python vs Java
5-run averages comparing Rava interpreter against Python 3 interpreter and Java OpenJDK (JIT compiled):
**Note:** Java uses Just-In-Time compilation to native machine code, while Rava and Python are pure interpreters executing bytecode. Despite this unfair advantage, Rava still manages to beat Java at string concatenation and consistently outperforms Python across most benchmarks. This demonstrates the effectiveness of Rava's interpreter optimization techniques: NaN-boxing, fast frames, method caching, superinstructions, and bounds check elimination.
| Benchmark | Rava | Python | Java | Winner | Best Speedup |
|-----------|------|--------|------|--------|--------------|
| Fibonacci(30) recursive | 270ms | 293ms | 13ms | **Java** | **20.1x** |
| Fibonacci(40) iterative | 0ms | 0ms | 0ms | Tie | - |
| Primes (100K) | 387ms | 361ms | 24ms | **Java** | **15.0x** |
| Sum (10M) | 832ms | 916ms | 15ms | **Java** | **56.2x** |
| Array sum (1M) | 223ms | 243ms | 23ms | **Java** | **9.9x** |
| Array reverse (1M) | 232ms | 265ms | 24ms | **Java** | **9.7x** |
| Nested loops (1000x1000) | 105ms | 140ms | 11ms | **Java** | **9.2x** |
| Factorial(15) recursive | 0ms | 0ms | 0ms | Tie | - |
| Ackermann(3,6) | 36ms | 70ms | 4ms | **Java** | **10.0x** |
| Method calls (10M) | 1626ms | 1687ms | 22ms | **Java** | **75.3x** |
| Arithmetic ops (10M) | 1819ms | 2971ms | 62ms | **Java** | **29.4x** |
| Conditional branches (10M) | 1456ms | 1472ms | 20ms | **Java** | **72.1x** |
| Complex conditions (10M) | 2950ms | 2256ms | 40ms | **Java** | **56.1x** |
| Matrix multiply (50x50) | 29ms | 23ms | 4ms | **Java** | **6.3x** |
| Bubble sort (5000) | 3483ms | 3188ms | 42ms | **Java** | **75.6x** |
| Quick sort (1000) | 84ms | 62ms | 9ms | **Java** | **7.0x** |
| Insertion sort (3000) | 757ms | 791ms | 19ms | **Java** | **40.3x** |
| Binary search (100K) | 13ms | 13ms | 4ms | **Java** | **3.6x** |
| String concat (50K) | 17ms | 22ms | 144ms | **Rava** | **8.4x vs Java** |
| Bitwise ops (10M) | 2239ms | 5144ms | 35ms | **Java** | **64.7x** |
| Array copy (1M) | 217ms | 206ms | 25ms | **Java** | **8.1x** |
**Overall Win Rates:**
- Java (JIT): 18/21 benchmarks (85.7%)
- Rava: 1/21 benchmarks (4.8%)
- Python: 0/21 benchmarks (0.0%)
**Interpreter Battle (Rava vs Python):**
- Rava wins: 13/21 benchmarks (61.9%)
- Python wins: 8/21 benchmarks (38.1%)
**Rava's Victory:**
- **String concatenation: 8.4x faster than Java, 1.3x faster than Python**
**Key Insights:**
- Java's JIT compiler dominates raw performance
- Rava interpreter beats Python interpreter on 62% of benchmarks
- Rava's string handling outperforms both interpreters AND Java's JIT
- Rava excels at: bitwise ops (2.3x vs Python), recursion (2.0x), arithmetic (1.6x)
## Structure ## Structure
+3 -175
View File
@@ -1,4 +1,4 @@
class Benchmark { public class Benchmark {
public static int fibonacci(int n) { public static int fibonacci(int n) {
if (n <= 1) { if (n <= 1) {
return n; return n;
@@ -187,120 +187,7 @@ class Benchmark {
return arr[0]; return arr[0];
} }
public static int quickSortPartition(int[] arr, int low, int high) { public static int main() {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
int swap = arr[i];
arr[i] = arr[j];
arr[j] = swap;
}
}
int swap2 = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = swap2;
return i + 1;
}
public static int quickSortHelper(int[] arr, int low, int high) {
if (low < high) {
int pi = quickSortPartition(arr, low, high);
quickSortHelper(arr, low, pi - 1);
quickSortHelper(arr, pi + 1, high);
}
return 0;
}
public static int quickSort(int size) {
int[] arr = new int[size];
for (int i = 0; i < size; i++) {
arr[i] = size - i;
}
quickSortHelper(arr, 0, size - 1);
return arr[0];
}
public static int binarySearch(int[] arr, int target, int low, int high) {
if (low > high) {
return -1;
}
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
return mid;
}
if (arr[mid] > target) {
return binarySearch(arr, target, low, mid - 1);
}
return binarySearch(arr, target, mid + 1, high);
}
public static int binarySearchBench(int size) {
int[] arr = new int[size];
for (int i = 0; i < size; i++) {
arr[i] = i;
}
int sum = 0;
for (int ii = 0; ii < size; ii = ii + 100) {
int result = binarySearch(arr, ii, 0, size - 1);
sum = sum + result;
}
return sum;
}
public static int stringConcat(int iterations) {
int len = 0;
for (int i = 0; i < iterations; i++) {
String s = "Hello";
s = s + "World";
s = s + i;
len = len + s.length();
}
return len;
}
public static int bitwiseOps(int iterations) {
int result = 0;
for (int i = 1; i < iterations; i++) {
result = result ^ (i << 1);
result = result | (i >> 1);
result = result & (i >>> 2);
result = result ^ ~i;
}
return result;
}
public static int arrayCopy(int size) {
int[] src = new int[size];
for (int i = 0; i < size; i++) {
src[i] = i;
}
int[] dst = new int[size];
for (int ii = 0; ii < size; ii++) {
dst[ii] = src[ii];
}
return dst[size - 1];
}
public static int insertionSort(int size) {
int[] arr = new int[size];
for (int i = 0; i < size; i++) {
arr[i] = size - i;
}
for (int ii = 1; ii < size; ii++) {
int key = arr[ii];
int j = ii - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
return arr[0];
}
public static void main(String[] args) {
System.out.println("=== Rava Comprehensive Benchmark Suite ==="); System.out.println("=== Rava Comprehensive Benchmark Suite ===");
long start = System.nanoTime(); long start = System.nanoTime();
@@ -453,66 +340,7 @@ class Benchmark {
System.out.print(bubbleTime); System.out.print(bubbleTime);
System.out.println(" ms"); System.out.println(" ms");
start = System.nanoTime();
int quick = quickSort(1000);
end = System.nanoTime();
long quickTime = (end - start) / 1000000;
System.out.print("Quick sort (1000 elements) = ");
System.out.println(quick);
System.out.print("Time: ");
System.out.print(quickTime);
System.out.println(" ms");
start = System.nanoTime();
int insertion = insertionSort(3000);
end = System.nanoTime();
long insertionTime = (end - start) / 1000000;
System.out.print("Insertion sort (3000 elements) = ");
System.out.println(insertion);
System.out.print("Time: ");
System.out.print(insertionTime);
System.out.println(" ms");
start = System.nanoTime();
int binsearch = binarySearchBench(100000);
end = System.nanoTime();
long binsearchTime = (end - start) / 1000000;
System.out.print("Binary search (100K, 1K searches) = ");
System.out.println(binsearch);
System.out.print("Time: ");
System.out.print(binsearchTime);
System.out.println(" ms");
start = System.nanoTime();
int strconcat = stringConcat(50000);
end = System.nanoTime();
long strconcatTime = (end - start) / 1000000;
System.out.print("String concatenation (50K) = ");
System.out.println(strconcat);
System.out.print("Time: ");
System.out.print(strconcatTime);
System.out.println(" ms");
start = System.nanoTime();
int bitwise = bitwiseOps(10000000);
end = System.nanoTime();
long bitwiseTime = (end - start) / 1000000;
System.out.print("Bitwise operations (10M) = ");
System.out.println(bitwise);
System.out.print("Time: ");
System.out.print(bitwiseTime);
System.out.println(" ms");
start = System.nanoTime();
int arrcopy = arrayCopy(1000000);
end = System.nanoTime();
long arrcopyTime = (end - start) / 1000000;
System.out.print("Array copy (1M elements) = ");
System.out.println(arrcopy);
System.out.print("Time: ");
System.out.print(arrcopyTime);
System.out.println(" ms");
System.out.println("=== Benchmark Complete ==="); System.out.println("=== Benchmark Complete ===");
return 0;
} }
} }
-104
View File
@@ -1,104 +0,0 @@
public class ComprehensiveSocketExample {
public static void testInetAddress() {
System.out.println("\n--- InetAddress Tests ---");
InetAddress loopback = InetAddress.getLoopbackAddress();
System.out.println("Loopback address: " + loopback.getHostAddress());
System.out.println("Is loopback: " + loopback.isLoopbackAddress());
System.out.println("Is multicast: " + loopback.isMulticastAddress());
InetAddress localhost = InetAddress.getByName("localhost");
System.out.println("Localhost: " + localhost.getHostName());
System.out.println("Localhost IP: " + localhost.getHostAddress());
int reachable = localhost.isReachable(1000) ? 1 : 0;
System.out.println("Localhost reachable: " + reachable);
InetAddress.getAllByName("localhost");
localhost.getAddress();
System.out.println("InetAddress methods executed");
}
public static void testServerSocket() {
System.out.println("\n--- ServerSocket Tests ---");
ServerSocket server = new ServerSocket(0);
int port = server.getLocalPort();
System.out.println("Server port: " + port);
int bound = server.isBound() ? 1 : 0;
System.out.println("Server is bound: " + bound);
int closed = server.isClosed() ? 1 : 0;
System.out.println("Server is closed: " + closed);
server.setSoTimeout(5000);
int timeout = server.getSoTimeout();
System.out.println("Server timeout: " + timeout);
server.setReceiveBufferSize(16384);
int bufSize = server.getReceiveBufferSize();
System.out.println("Receive buffer size: " + bufSize);
server.setReuseAddress(true);
int reuse = server.getReuseAddress() ? 1 : 0;
System.out.println("Reuse address enabled: " + reuse);
System.out.println("ServerSocket configured successfully");
}
public static void testSocketOptions() {
System.out.println("\n--- Socket Options Tests ---");
Socket sock = new Socket();
sock.setSoTimeout(3000);
int timeout = sock.getSoTimeout();
System.out.println("Socket timeout: " + timeout);
sock.setTcpNoDelay(true);
int nodelay = sock.getTcpNoDelay() ? 1 : 0;
System.out.println("TCP NoDelay: " + nodelay);
sock.setSendBufferSize(8192);
int sendBuf = sock.getSendBufferSize();
System.out.println("Send buffer: " + sendBuf);
sock.setReceiveBufferSize(8192);
int recvBuf = sock.getReceiveBufferSize();
System.out.println("Receive buffer: " + recvBuf);
sock.setKeepAlive(true);
int keepAlive = sock.getKeepAlive() ? 1 : 0;
System.out.println("Keep alive: " + keepAlive);
sock.setReuseAddress(true);
int reuse = sock.getReuseAddress() ? 1 : 0;
System.out.println("Reuse address: " + reuse);
int connected = sock.isConnected() ? 1 : 0;
System.out.println("Socket connected: " + connected);
int sockClosed = sock.isClosed() ? 1 : 0;
System.out.println("Socket closed: " + sockClosed);
sock.close();
System.out.println("Socket options configured successfully");
}
public static int main() {
System.out.println("========================================");
System.out.println("Comprehensive Socket API Example");
System.out.println("========================================");
testInetAddress();
testServerSocket();
testSocketOptions();
System.out.println("========================================");
System.out.println("All Socket API tests completed successfully");
System.out.println("========================================");
return 0;
}
}
-29
View File
@@ -1,29 +0,0 @@
public class InetAddressExample {
public static int main() {
System.out.println("InetAddress Methods Example");
System.out.println("============================");
InetAddress loopback = InetAddress.getLoopbackAddress();
System.out.println("Loopback: " + loopback.getHostAddress());
System.out.println("Is loopback: " + loopback.isLoopbackAddress());
System.out.println("Is multicast: " + loopback.isMulticastAddress());
InetAddress localhost = InetAddress.getByName("localhost");
System.out.println("Localhost: " + localhost.getHostName());
System.out.println("Localhost address: " + localhost.getHostAddress());
System.out.println("Testing reachability...");
int reachable = localhost.isReachable(1000) ? 1 : 0;
System.out.println("Localhost reachable: " + reachable);
System.out.println("Getting all addresses for localhost...");
InetAddress.getAllByName("localhost");
System.out.println("Getting byte address...");
localhost.getAddress();
System.out.println("InetAddress tests completed");
return 0;
}
}
-701
View File
@@ -1,701 +0,0 @@
class Point {
int x;
int y;
}
class Rectangle {
int width;
int height;
int area;
Rectangle(int w, int h) {
this.width = w;
this.height = h;
this.area = w * h;
}
}
class Counter {
int count;
Counter() {
this.count = 0;
}
void increment() {
this.count = this.count + 1;
}
int getCount() {
return this.count;
}
}
class MathUtils {
int x;
}
class Animal {
int name;
int speak() {
return 0;
}
}
class Dog extends Animal {
int breed;
int speak() {
return 1;
}
}
class Cat extends Animal {
int indoor;
int speak() {
return 2;
}
}
interface Shape {
int getArea();
}
class Circle implements Shape {
int radius;
Circle(int r) {
this.radius = r;
}
int getArea() {
return (int)(3.14159 * this.radius * this.radius);
}
}
class Square implements Shape {
int side;
Square(int s) {
this.side = s;
}
int getArea() {
return this.side * this.side;
}
}
public class JavaKungFu {
static int staticCounter = 0;
static int fibCalls = 0;
int instanceValue;
JavaKungFu() {
this.instanceValue = 100;
}
JavaKungFu(int val) {
this.instanceValue = val;
}
int getValue() {
return this.instanceValue;
}
void setValue(int v) {
this.instanceValue = v;
}
int add(int x) {
return this.instanceValue + x;
}
public static int square(int x) {
return x * x;
}
public static int cube(int x) {
return x * x * x;
}
public static int fibonacci(int n) {
JavaKungFu.fibCalls = JavaKungFu.fibCalls + 1;
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
public static int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a % b);
}
public static boolean isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
int i = 5;
while (i * i <= n) {
if (n % i == 0 || n % (i + 2) == 0) return false;
i = i + 6;
}
return true;
}
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
public static boolean testPrimitiveTypes() {
int i = 42;
long l = 9876543210L;
double d = 3.14159;
boolean b = true;
char c = 'A';
if (i != 42) return false;
if (l != 9876543210L) return false;
if (d < 3.14 || d > 3.15) return false;
if (b != true) return false;
if (c != 'A') return false;
return true;
}
public static boolean testArithmeticOperators() {
int a = 20;
int b = 6;
if (a + b != 26) return false;
if (a - b != 14) return false;
if (a * b != 120) return false;
if (a / b != 3) return false;
if (a % b != 2) return false;
if (-a != -20) return false;
int x = 10;
x += 5;
if (x != 15) return false;
x -= 3;
if (x != 12) return false;
x *= 2;
if (x != 24) return false;
x /= 4;
if (x != 6) return false;
int y = 5;
if (++y != 6) return false;
if (--y != 5) return false;
return true;
}
public static boolean testBitwiseOperators() {
int a = 12;
int b = 10;
if ((a & b) != 8) return false;
if ((a | b) != 14) return false;
if ((a ^ b) != 6) return false;
int c = 1;
if ((c << 4) != 16) return false;
if ((16 >> 2) != 4) return false;
return true;
}
public static boolean testComparisonOperators() {
int a = 10;
int b = 20;
int c = 10;
if ((a == c) != true) return false;
if ((a != b) != true) return false;
if ((a < b) != true) return false;
if ((a <= c) != true) return false;
if ((b > a) != true) return false;
if ((b >= a) != true) return false;
return true;
}
public static boolean testLogicalOperators() {
boolean t = true;
boolean f = false;
if ((t && t) != true) return false;
if ((t && f) != false) return false;
if ((t || f) != true) return false;
if ((f || f) != false) return false;
if ((!t) != false) return false;
if ((!f) != true) return false;
return true;
}
public static boolean testTernaryOperator() {
int a = 10;
int b = 20;
int max = a > b ? a : b;
if (max != 20) return false;
int min = a < b ? a : b;
if (min != 10) return false;
int nested = a > 5 ? (a > 15 ? 2 : 1) : 0;
if (nested != 1) return false;
return true;
}
public static boolean testIfElse() {
int x = 15;
int result = 0;
if (x > 20) {
result = 1;
} else if (x > 10) {
result = 2;
} else if (x > 5) {
result = 3;
} else {
result = 4;
}
if (result != 2) return false;
return true;
}
public static boolean testWhileLoop() {
int sum = 0;
int i = 1;
while (i <= 10) {
sum = sum + i;
i = i + 1;
}
if (sum != 55) return false;
return true;
}
public static boolean testDoWhileLoop() {
int count = 0;
do {
count = count + 1;
} while (count < 5);
if (count != 5) return false;
return true;
}
public static boolean testForLoop() {
int sum = 0;
for (int a = 0; a < 10; a++) {
sum = sum + a;
}
if (sum != 45) return false;
int nested = 0;
for (int b = 0; b < 3; b++) {
for (int c = 0; c < 3; c++) {
nested = nested + 1;
}
}
if (nested != 9) return false;
return true;
}
public static boolean testBreakContinue() {
int sum = 0;
for (int a = 0; a < 100; a++) {
if (a >= 10) break;
sum = sum + a;
}
if (sum != 45) return false;
sum = 0;
for (int b = 0; b < 10; b++) {
if (b % 2 == 0) continue;
sum = sum + b;
}
if (sum != 25) return false;
return true;
}
public static boolean testSwitchStatement() {
int day = 3;
int result = 0;
switch (day) {
case 1: result = 10; break;
case 2: result = 20; break;
case 3: result = 30; break;
default: result = -1;
}
if (result != 30) return false;
return true;
}
public static boolean testArrays() {
int[] arr = new int[5];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
if (arr.length != 5) return false;
if (arr[2] != 30) return false;
int sum = 0;
for (int a = 0; a < arr.length; a++) {
sum = sum + arr[a];
}
if (sum != 150) return false;
return true;
}
public static boolean testEnhancedFor() {
int[] numbers = {1, 2, 3, 4, 5};
int sum = 0;
for (int n : numbers) {
sum = sum + n;
}
if (sum != 15) return false;
return true;
}
public static boolean testMultiDimArrays() {
int[][] matrix = new int[3][3];
for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {
matrix[a][b] = a * 3 + b;
}
}
if (matrix[0][0] != 0) return false;
if (matrix[1][1] != 4) return false;
if (matrix[2][2] != 8) return false;
return true;
}
public static boolean testObjectCreation() {
Point p1 = new Point();
p1.x = 10;
p1.y = 20;
if (p1.x != 10) return false;
if (p1.y != 20) return false;
Rectangle r = new Rectangle(4, 5);
if (r.width != 4) return false;
if (r.height != 5) return false;
if (r.area != 20) return false;
return true;
}
public static boolean testInstanceMethods() {
Rectangle r = new Rectangle(10, 5);
if (r.area != 50) return false;
if (r.width != 10) return false;
if (r.height != 5) return false;
return true;
}
public static boolean testStaticMembers() {
JavaKungFu.staticCounter = 0;
JavaKungFu.staticCounter = JavaKungFu.staticCounter + 1;
JavaKungFu.staticCounter = JavaKungFu.staticCounter + 1;
if (JavaKungFu.staticCounter != 2) return false;
int result = square(5);
if (result != 25) return false;
result = cube(3);
if (result != 27) return false;
return true;
}
public static boolean testInheritance() {
Dog dog = new Dog();
dog.name = 42;
dog.breed = 7;
if (dog.name != 42) return false;
if (dog.breed != 7) return false;
return true;
}
public static boolean testMethodOverride() {
Animal animal = new Animal();
if (animal.speak() != 0) return false;
Dog dog = new Dog();
if (dog.speak() != 1) return false;
Cat cat = new Cat();
if (cat.speak() != 2) return false;
return true;
}
public static boolean testInterfaces() {
Circle circle = new Circle(5);
int area = circle.getArea();
if (area < 75 || area > 79) return false;
Square square = new Square(4);
if (square.getArea() != 16) return false;
return true;
}
public static boolean testInstanceOf() {
Dog dog = new Dog();
boolean dogIsAnimal = dog instanceof Animal;
boolean dogIsDog = dog instanceof Dog;
if (dogIsAnimal != true) return false;
if (dogIsDog != true) return false;
return true;
}
public static boolean testRecursion() {
int fib10 = fibonacci(10);
if (fib10 != 55) return false;
int fact5 = factorial(5);
if (fact5 != 120) return false;
int gcdVal = gcd(48, 18);
if (gcdVal != 6) return false;
return true;
}
public static boolean testMathLibrary() {
if (Math.abs(-42) != 42) return false;
if (Math.min(10, 20) != 10) return false;
if (Math.max(10, 20) != 20) return false;
double sqrt = Math.sqrt(16.0);
if (sqrt < 3.99 || sqrt > 4.01) return false;
double pow = Math.pow(2.0, 10.0);
if (pow < 1023.0 || pow > 1025.0) return false;
return true;
}
public static boolean testStringOperations() {
String s = "Hello World";
if (s.length() != 11) return false;
if (s.charAt(0) != 'H') return false;
String sub = s.substring(0, 5);
if (sub.equals("Hello") == false) return false;
if (s.indexOf("World") != 6) return false;
if (s.contains("World") != true) return false;
if (s.startsWith("Hello") != true) return false;
if (s.endsWith("World") != true) return false;
String upper = s.toUpperCase();
if (upper.equals("HELLO WORLD") == false) return false;
String concat = "Hello" + " " + "World";
if (concat.equals("Hello World") == false) return false;
return true;
}
public static boolean testArrayList() {
ArrayList list = new ArrayList();
if (list.isEmpty() != true) return false;
list.add(10);
list.add(20);
list.add(30);
if (list.size() != 3) return false;
if ((int)list.get(0) != 10) return false;
if ((int)list.get(1) != 20) return false;
list.set(1, 25);
if ((int)list.get(1) != 25) return false;
list.clear();
if (list.size() != 0) return false;
return true;
}
public static boolean testHashMap() {
HashMap map = new HashMap();
map.put("one", 1);
map.put("two", 2);
map.put("three", 3);
if (map.size() != 3) return false;
if ((int)map.get("one") != 1) return false;
if ((int)map.get("two") != 2) return false;
if (map.containsKey("one") != true) return false;
if (map.containsKey("four") != false) return false;
map.put("two", 22);
if ((int)map.get("two") != 22) return false;
map.clear();
if (map.size() != 0) return false;
return true;
}
public static boolean testExceptions() {
int result = 0;
try {
throw 42;
} catch (Exception e) {
result = e;
}
if (result != 42) return false;
result = 0;
try {
result = 1;
} catch (Exception e) {
result = -1;
}
if (result != 1) return false;
return true;
}
public static boolean testAlgorithms() {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
bubbleSort(arr);
for (int a = 0; a < arr.length - 1; a++) {
if (arr[a] > arr[a + 1]) return false;
}
int[] sorted = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
int idx = binarySearch(sorted, 11);
if (idx != 5) return false;
idx = binarySearch(sorted, 10);
if (idx != -1) return false;
if (isPrime(17) == false) return false;
if (isPrime(18) == true) return false;
if (isPrime(2) == false) return false;
return true;
}
public static int main() {
System.out.println("=== JAVA KUNG-FU DEMONSTRATION ===");
System.out.println("");
int totalTests = 0;
int passedTests = 0;
totalTests = totalTests + 1;
if (testPrimitiveTypes() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Primitive Types"); }
else { System.out.println("[FAIL] Primitive Types"); }
totalTests = totalTests + 1;
if (testArithmeticOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Arithmetic Operators"); }
else { System.out.println("[FAIL] Arithmetic Operators"); }
totalTests = totalTests + 1;
if (testBitwiseOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Bitwise Operators"); }
else { System.out.println("[FAIL] Bitwise Operators"); }
totalTests = totalTests + 1;
if (testComparisonOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Comparison Operators"); }
else { System.out.println("[FAIL] Comparison Operators"); }
totalTests = totalTests + 1;
if (testLogicalOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Logical Operators"); }
else { System.out.println("[FAIL] Logical Operators"); }
totalTests = totalTests + 1;
if (testTernaryOperator() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Ternary Operator"); }
else { System.out.println("[FAIL] Ternary Operator"); }
totalTests = totalTests + 1;
if (testIfElse() == true) { passedTests = passedTests + 1; System.out.println("[PASS] If-Else Statements"); }
else { System.out.println("[FAIL] If-Else Statements"); }
totalTests = totalTests + 1;
if (testWhileLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] While Loop"); }
else { System.out.println("[FAIL] While Loop"); }
totalTests = totalTests + 1;
if (testDoWhileLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Do-While Loop"); }
else { System.out.println("[FAIL] Do-While Loop"); }
totalTests = totalTests + 1;
if (testForLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] For Loop"); }
else { System.out.println("[FAIL] For Loop"); }
totalTests = totalTests + 1;
if (testBreakContinue() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Break/Continue"); }
else { System.out.println("[FAIL] Break/Continue"); }
totalTests = totalTests + 1;
if (testSwitchStatement() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Switch Statement"); }
else { System.out.println("[FAIL] Switch Statement"); }
totalTests = totalTests + 1;
if (testArrays() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Arrays"); }
else { System.out.println("[FAIL] Arrays"); }
totalTests = totalTests + 1;
if (testEnhancedFor() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Enhanced For Loop"); }
else { System.out.println("[FAIL] Enhanced For Loop"); }
totalTests = totalTests + 1;
if (testMultiDimArrays() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Multi-Dimensional Arrays"); }
else { System.out.println("[FAIL] Multi-Dimensional Arrays"); }
totalTests = totalTests + 1;
if (testObjectCreation() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Object Creation"); }
else { System.out.println("[FAIL] Object Creation"); }
totalTests = totalTests + 1;
if (testInstanceMethods() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Instance Methods"); }
else { System.out.println("[FAIL] Instance Methods"); }
totalTests = totalTests + 1;
if (testStaticMembers() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Static Members"); }
else { System.out.println("[FAIL] Static Members"); }
totalTests = totalTests + 1;
if (testInheritance() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Inheritance"); }
else { System.out.println("[FAIL] Inheritance"); }
totalTests = totalTests + 1;
if (testMethodOverride() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Method Override"); }
else { System.out.println("[FAIL] Method Override"); }
totalTests = totalTests + 1;
if (testInterfaces() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Interfaces"); }
else { System.out.println("[FAIL] Interfaces"); }
totalTests = totalTests + 1;
if (testInstanceOf() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Instanceof"); }
else { System.out.println("[FAIL] Instanceof"); }
totalTests = totalTests + 1;
if (testRecursion() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Recursion"); }
else { System.out.println("[FAIL] Recursion"); }
totalTests = totalTests + 1;
if (testMathLibrary() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Math Library"); }
else { System.out.println("[FAIL] Math Library"); }
totalTests = totalTests + 1;
if (testStringOperations() == true) { passedTests = passedTests + 1; System.out.println("[PASS] String Operations"); }
else { System.out.println("[FAIL] String Operations"); }
totalTests = totalTests + 1;
if (testArrayList() == true) { passedTests = passedTests + 1; System.out.println("[PASS] ArrayList"); }
else { System.out.println("[FAIL] ArrayList"); }
totalTests = totalTests + 1;
if (testHashMap() == true) { passedTests = passedTests + 1; System.out.println("[PASS] HashMap"); }
else { System.out.println("[FAIL] HashMap"); }
totalTests = totalTests + 1;
if (testExceptions() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Exceptions"); }
else { System.out.println("[FAIL] Exceptions"); }
totalTests = totalTests + 1;
if (testAlgorithms() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Algorithms"); }
else { System.out.println("[FAIL] Algorithms"); }
System.out.println("");
System.out.println("=== RESULTS ===");
System.out.print("Passed: ");
System.out.print(passedTests);
System.out.print(" / ");
System.out.println(totalTests);
if (passedTests == totalTests) {
System.out.println("ALL TESTS PASSED!");
}
return passedTests == totalTests ? 0 : 1;
}
}
-54
View File
@@ -1,54 +0,0 @@
public class SimpleHttpClient {
public static int main() {
System.out.println("=================================");
System.out.println("Rava HTTP Client Example");
System.out.println("=================================");
System.out.println("");
String host = "127.0.0.1";
int port = 8080;
System.out.println("Connecting to " + host + ":" + port);
Socket socket = new Socket(host, port);
System.out.println("Connected successfully");
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
System.out.println("");
System.out.println("Sending HTTP GET request...");
out.write("GET / HTTP/1.1\r\n");
out.write("Host: localhost\r\n");
out.write("Connection: close\r\n");
out.write("\r\n");
out.flush();
System.out.println("Request sent, reading response...");
System.out.println("");
System.out.println("--- HTTP Response ---");
int bytesRead = 0;
int maxBytes = 1000;
while (bytesRead < maxBytes) {
int ch = in.read();
if (ch < 0) {
break;
}
System.out.print((char)ch);
bytesRead = bytesRead + 1;
}
System.out.println("");
System.out.println("--- End of Response ---");
System.out.println("");
socket.close();
System.out.println("Connection closed");
System.out.println("");
System.out.println("HTTP client example completed successfully!");
System.out.println("Total bytes received: " + bytesRead);
return 0;
}
}
-72
View File
@@ -1,72 +0,0 @@
public class SimpleHttpServer {
public static int main() {
int port = 8080;
System.out.println("=================================");
System.out.println("Rava HTTP Server Example");
System.out.println("=================================");
System.out.println("");
System.out.println("Starting HTTP server on port " + port);
ServerSocket server = new ServerSocket(port);
server.setReuseAddress(true);
System.out.println("Server listening on http://localhost:" + port);
System.out.println("Send an HTTP request to see the response");
System.out.println("");
System.out.println("Example:");
System.out.println(" curl http://localhost:8080/");
System.out.println(" or visit http://localhost:8080/ in your browser");
System.out.println("");
System.out.println("Waiting for connection...");
Socket client = server.accept();
System.out.println("Connection accepted!");
InputStream in = client.getInputStream();
OutputStream out = client.getOutputStream();
System.out.println("Reading request...");
int bytesRead = 0;
while (bytesRead < 100) {
int ch = in.read();
if (ch < 0) {
break;
}
bytesRead = bytesRead + 1;
}
System.out.println("Sending response...");
out.write("HTTP/1.1 200 OK\r\n");
out.write("Content-Type: text/html\r\n");
out.write("Connection: close\r\n");
out.write("\r\n");
out.write("<html>\n");
out.write("<head><title>Rava HTTP Server</title></head>\n");
out.write("<body style=\"font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px;\">\n");
out.write("<h1 style=\"color: #333;\">Hello from Rava!</h1>\n");
out.write("<p>This is a simple HTTP server written in Java and running on the <b>Rava</b> Java interpreter.</p>\n");
out.write("<h2>Features Demonstrated:</h2>\n");
out.write("<ul>\n");
out.write("<li>ServerSocket - listening for connections</li>\n");
out.write("<li>Socket - accepting client connections</li>\n");
out.write("<li>InputStream - reading HTTP requests</li>\n");
out.write("<li>OutputStream - sending HTTP responses</li>\n");
out.write("</ul>\n");
out.write("<hr>\n");
out.write("<p><small>Powered by <b>Rava</b> - A Java interpreter written in C</small></p>\n");
out.write("</body>\n");
out.write("</html>\n");
out.flush();
System.out.println("Response sent successfully");
client.close();
server.close();
System.out.println("");
System.out.println("Server shut down");
System.out.println("HTTP server example completed successfully!");
return 0;
}
}
-17
View File
@@ -1,17 +0,0 @@
public class SocketBindDebug {
public static int main() {
Socket sock = new Socket();
System.out.print("Before bind, isBound: ");
System.out.println(sock.isBound());
sock.bind("0.0.0.0", 8888);
System.out.print("After bind, isBound: ");
boolean bound = sock.isBound();
System.out.println(bound);
sock.close();
return bound ? 1 : 0;
}
}
-21
View File
@@ -1,21 +0,0 @@
public class SocketBindExample {
public static int main() {
System.out.println("Socket Bind Example");
System.out.println("==================");
Socket sock = new Socket();
System.out.print("Socket bound before bind(): ");
System.out.println(sock.isBound());
sock.bind("127.0.0.1", 8888);
System.out.print("Socket bound after bind(): ");
System.out.println(sock.isBound());
sock.close();
System.out.println("Socket bind example completed successfully");
return 0;
}
}
-29
View File
@@ -1,29 +0,0 @@
public class SocketBufferSizeExample {
public static int main() {
System.out.println("Socket Buffer Size Example");
System.out.println("==========================");
Socket sock = new Socket();
System.out.print("Initial send buffer size: ");
System.out.println(sock.getSendBufferSize());
System.out.print("Initial receive buffer size: ");
System.out.println(sock.getReceiveBufferSize());
System.out.println("\nSetting buffer sizes to 32KB...");
sock.setSendBufferSize(32768);
sock.setReceiveBufferSize(32768);
System.out.print("New send buffer size: ");
System.out.println(sock.getSendBufferSize());
System.out.print("New receive buffer size: ");
System.out.println(sock.getReceiveBufferSize());
sock.close();
System.out.println("\nBuffer size configuration completed successfully");
return 0;
}
}
-55
View File
@@ -1,55 +0,0 @@
public class SocketLifecycleExample {
public static int main() {
System.out.println("Socket Lifecycle Example");
System.out.println("========================");
Socket client = new Socket();
System.out.println("\nInitial state:");
System.out.print(" Connected: ");
System.out.println(client.isConnected());
System.out.print(" Closed: ");
System.out.println(client.isClosed());
System.out.print(" Bound: ");
System.out.println(client.isBound());
System.out.println("\nBinding socket to local address...");
client.bind("127.0.0.1", 6666);
System.out.print(" Bound: ");
System.out.println(client.isBound());
System.out.println("\nCreating server and connecting...");
ServerSocket server = new ServerSocket(6667);
InetAddress addr = InetAddress.getLoopbackAddress();
client.connect(addr, 6667);
System.out.print(" Connected: ");
System.out.println(client.isConnected());
System.out.println("\nShutdown state:");
System.out.print(" Input shutdown: ");
System.out.println(client.isInputShutdown());
System.out.print(" Output shutdown: ");
System.out.println(client.isOutputShutdown());
System.out.println("\nPerforming half-close (shutdown output)...");
client.shutdownOutput();
System.out.print(" Output shutdown: ");
System.out.println(client.isOutputShutdown());
System.out.print(" Still connected: ");
System.out.println(client.isConnected());
System.out.println("\nClosing socket...");
client.close();
System.out.print(" Closed: ");
System.out.println(client.isClosed());
server.close();
System.out.println("\nSocket lifecycle example completed successfully");
return 0;
}
}
-43
View File
@@ -1,43 +0,0 @@
public class SocketOptionsExample {
public static int main() {
Socket socket = new Socket();
System.out.println("Socket Options Example");
System.out.println("=====================");
System.out.print("Initial KeepAlive: ");
System.out.println(socket.getKeepAlive());
socket.setKeepAlive(true);
System.out.print("After setKeepAlive(true): ");
System.out.println(socket.getKeepAlive());
socket.setKeepAlive(false);
System.out.print("After setKeepAlive(false): ");
System.out.println(socket.getKeepAlive());
System.out.print("Initial ReuseAddress: ");
System.out.println(socket.getReuseAddress());
socket.setReuseAddress(true);
System.out.print("After setReuseAddress(true): ");
System.out.println(socket.getReuseAddress());
socket.setReuseAddress(false);
System.out.print("After setReuseAddress(false): ");
System.out.println(socket.getReuseAddress());
socket.setSendBufferSize(32768);
System.out.print("Send buffer size: ");
System.out.println(socket.getSendBufferSize());
socket.setReceiveBufferSize(32768);
System.out.print("Receive buffer size: ");
System.out.println(socket.getReceiveBufferSize());
socket.close();
System.out.println("Socket closed");
return 0;
}
}
-146
View File
@@ -1,146 +0,0 @@
public class SocketPerformanceBenchmark {
public static int main() {
System.out.println("================================================");
System.out.println("Socket API Performance Benchmark");
System.out.println("================================================");
System.out.println("");
System.out.println("This benchmark measures Socket API operations");
System.out.println("to demonstrate networking performance in Rava.");
System.out.println("");
int iterations = 10;
System.out.println("Test 1: ServerSocket Creation and Binding");
System.out.println("------------------------------------------");
long start1 = System.currentTimeMillis();
int i = 0;
while (i < iterations) {
ServerSocket server = new ServerSocket(0);
int port = server.getLocalPort();
server.close();
i = i + 1;
}
long end1 = System.currentTimeMillis();
long time1 = end1 - start1;
System.out.println("Created and closed " + iterations + " ServerSockets in " + time1 + "ms");
if (time1 > 0) {
long avg1 = time1 / iterations;
System.out.println("Average: " + avg1 + "ms per ServerSocket");
}
System.out.println("");
System.out.println("Test 2: Socket Object Creation");
System.out.println("-------------------------------");
long start2 = System.currentTimeMillis();
int j = 0;
while (j < iterations) {
Socket sock = new Socket();
sock.close();
j = j + 1;
}
long end2 = System.currentTimeMillis();
long time2 = end2 - start2;
System.out.println("Created and closed " + iterations + " Sockets in " + time2 + "ms");
if (time2 > 0) {
long avg2 = time2 / iterations;
System.out.println("Average: " + avg2 + "ms per Socket");
}
System.out.println("");
System.out.println("Test 3: Socket Option Configuration");
System.out.println("------------------------------------");
long start3 = System.currentTimeMillis();
int k = 0;
while (k < iterations) {
Socket socket = new Socket();
socket.setKeepAlive(true);
socket.setTcpNoDelay(true);
socket.setReuseAddress(true);
socket.setSendBufferSize(8192);
socket.setReceiveBufferSize(8192);
int keepAlive = socket.getKeepAlive() ? 1 : 0;
int noDelay = socket.getTcpNoDelay() ? 1 : 0;
int reuse = socket.getReuseAddress() ? 1 : 0;
int sendBuf = socket.getSendBufferSize();
int recvBuf = socket.getReceiveBufferSize();
socket.close();
k = k + 1;
}
long end3 = System.currentTimeMillis();
long time3 = end3 - start3;
System.out.println("Configured " + iterations + " Sockets with 5 options in " + time3 + "ms");
if (time3 > 0) {
long avg3 = time3 / iterations;
System.out.println("Average: " + avg3 + "ms per Socket configuration");
}
System.out.println("");
System.out.println("Test 4: InetAddress Resolution");
System.out.println("-------------------------------");
long start4 = System.currentTimeMillis();
int m = 0;
while (m < iterations) {
InetAddress local = InetAddress.getLoopbackAddress();
InetAddress localhost = InetAddress.getByName("localhost");
String host = localhost.getHostName();
String addr = localhost.getHostAddress();
int isLoop = localhost.isLoopbackAddress() ? 1 : 0;
m = m + 1;
}
long end4 = System.currentTimeMillis();
long time4 = end4 - start4;
System.out.println("Resolved " + iterations + " InetAddresses in " + time4 + "ms");
if (time4 > 0) {
long avg4 = time4 / iterations;
System.out.println("Average: " + avg4 + "ms per resolution");
}
System.out.println("");
System.out.println("Test 5: ServerSocket Options");
System.out.println("-----------------------------");
long start5 = System.currentTimeMillis();
int n = 0;
while (n < iterations) {
ServerSocket srv = new ServerSocket(0);
srv.setReuseAddress(true);
srv.setReceiveBufferSize(16384);
srv.setSoTimeout(5000);
int reuseAddr = srv.getReuseAddress() ? 1 : 0;
int bufferSize = srv.getReceiveBufferSize();
int socketTimeout = srv.getSoTimeout();
srv.close();
n = n + 1;
}
long end5 = System.currentTimeMillis();
long time5 = end5 - start5;
System.out.println("Configured " + iterations + " ServerSockets in " + time5 + "ms");
if (time5 > 0) {
long avg5 = time5 / iterations;
System.out.println("Average: " + avg5 + "ms per ServerSocket");
}
System.out.println("");
long totalTime = time1 + time2 + time3 + time4 + time5;
int totalOps = iterations * 5;
System.out.println("================================================");
System.out.println("Summary");
System.out.println("================================================");
System.out.println("Total operations: " + totalOps);
System.out.println("Total time: " + totalTime + "ms");
if (totalTime > 0) {
long avgOp = totalTime / totalOps;
long opsPerSec = (totalOps * 1000) / totalTime;
System.out.println("Average time per operation: " + avgOp + "ms");
System.out.println("Operations per second: " + opsPerSec);
}
System.out.println("");
System.out.println("Benchmark completed successfully!");
return 0;
}
}
-36
View File
@@ -1,36 +0,0 @@
public class SocketShutdownExample {
public static int main() {
System.out.println("Socket Graceful Shutdown Example");
System.out.println("=================================");
ServerSocket server = new ServerSocket(7777);
Socket client = new Socket();
InetAddress addr = InetAddress.getLoopbackAddress();
client.connect(addr, 7777);
System.out.print("Input shutdown: ");
System.out.println(client.isInputShutdown());
System.out.print("Output shutdown: ");
System.out.println(client.isOutputShutdown());
System.out.println("\nShutting down input...");
client.shutdownInput();
System.out.print("Input shutdown after shutdownInput(): ");
System.out.println(client.isInputShutdown());
System.out.println("\nShutting down output...");
client.shutdownOutput();
System.out.print("Output shutdown after shutdownOutput(): ");
System.out.println(client.isOutputShutdown());
client.close();
server.close();
System.out.println("\nGraceful shutdown example completed successfully");
return 0;
}
}
-22
View File
@@ -1,22 +0,0 @@
public class StreamMethodsExample {
public static int main() {
System.out.println("Stream Methods Example");
System.out.println("======================");
System.out.println("Stream methods flush() and skip() are now available");
System.out.println("These methods work with InputStream and OutputStream");
System.out.println("obtained from Socket connections.");
System.out.println("\nExample usage:");
System.out.println(" InputStream in = socket.getInputStream();");
System.out.println(" long skipped = in.skip(100); // Skip 100 bytes");
System.out.println(" ");
System.out.println(" OutputStream out = socket.getOutputStream();");
System.out.println(" out.write(data);");
System.out.println(" out.flush(); // Flush buffered data");
System.out.println("\nStream methods implementation complete!");
return 0;
}
}
-69
View File
@@ -1,69 +0,0 @@
public class StringErrorHandlingTest {
public static int main() {
System.out.println("===========================================");
System.out.println("String Error Handling & Edge Cases Test");
System.out.println("===========================================");
System.out.println("");
String test = "Hello";
System.out.println("Test string: \"" + test + "\" (length: " + test.length() + ")");
System.out.println("");
System.out.println("Test 1: charAt() with out of bounds index");
System.out.println("Trying charAt(10) on string of length 5...");
char outOfBounds = test.charAt(10);
System.out.println("Result: " + outOfBounds);
System.out.println("(Should handle gracefully or throw error)");
System.out.println("");
System.out.println("Test 2: charAt() with negative index");
System.out.println("Trying charAt(-1)...");
char negative = test.charAt(-1);
System.out.println("Result: " + negative);
System.out.println("");
System.out.println("Test 3: substring() with invalid range");
System.out.println("Trying substring(3, 1) (end before start)...");
String badRange = test.substring(3, 1);
System.out.println("Result: \"" + badRange + "\"");
System.out.println("");
System.out.println("Test 4: substring() with out of bounds end");
System.out.println("Trying substring(0, 100)...");
String badEnd = test.substring(0, 100);
System.out.println("Result: \"" + badEnd + "\"");
System.out.println("");
System.out.println("Test 5: substring() with negative indices");
System.out.println("Trying substring(-1, 3)...");
String negStart = test.substring(-1, 3);
System.out.println("Result: \"" + negStart + "\"");
System.out.println("");
System.out.println("Test 6: indexOf() with empty string");
System.out.println("Trying indexOf(\"\")...");
int emptyIdx = test.indexOf("");
System.out.println("Result: " + emptyIdx);
System.out.println("");
System.out.println("Test 7: Empty string operations");
String empty = "";
System.out.println("Empty string length: " + empty.length());
System.out.println("Empty equals empty: " + (empty.equals("") ? "true" : "false"));
System.out.println("Empty contains empty: " + (empty.contains("") ? "true" : "false"));
System.out.println("");
System.out.println("Test 8: String with special characters");
String special = "Hello\nWorld\t!";
System.out.println("String with newline and tab:");
System.out.println(" Length: " + special.length());
System.out.println(" indexOf(\"\\n\"): " + special.indexOf("\n"));
System.out.println("");
System.out.println("===========================================");
System.out.println("Error handling test complete");
System.out.println("===========================================");
return 0;
}
}
-106
View File
@@ -1,106 +0,0 @@
public class StringMethodsDemo {
public static int main() {
System.out.println("==========================================");
System.out.println("String Methods Demonstration");
System.out.println("==========================================");
System.out.println("");
String original = "Hello World";
System.out.println("Original string: \"" + original + "\"");
System.out.println("");
System.out.println("1. length() - Get string length");
int len = original.length();
System.out.println(" Length: " + len);
System.out.println("");
System.out.println("2. charAt(index) - Get character at position");
char first = original.charAt(0);
char space = original.charAt(5);
char last = original.charAt(10);
System.out.println(" charAt(0): " + first + " (H)");
System.out.println(" charAt(5): " + space + " (space)");
System.out.println(" charAt(10): " + last + " (d)");
System.out.println("");
System.out.println("3. substring(start, end) - Extract portion");
String hello = original.substring(0, 5);
String world = original.substring(6, 11);
System.out.println(" substring(0, 5): \"" + hello + "\"");
System.out.println(" substring(6, 11): \"" + world + "\"");
System.out.println("");
System.out.println("4. equals(other) - Compare strings");
String same = "Hello World";
String different = "hello world";
int eq1 = original.equals(same) ? 1 : 0;
int eq2 = original.equals(different) ? 1 : 0;
System.out.println(" equals(\"Hello World\"): " + (eq1 == 1 ? "true" : "false"));
System.out.println(" equals(\"hello world\"): " + (eq2 == 1 ? "true" : "false"));
System.out.println("");
System.out.println("5. indexOf(substring) - Find position");
int pos1 = original.indexOf("World");
int pos2 = original.indexOf("xyz");
System.out.println(" indexOf(\"World\"): " + pos1);
System.out.println(" indexOf(\"xyz\"): " + pos2 + " (not found)");
System.out.println("");
System.out.println("6. contains(substring) - Check if contains");
int has1 = original.contains("World") ? 1 : 0;
int has2 = original.contains("xyz") ? 1 : 0;
System.out.println(" contains(\"World\"): " + (has1 == 1 ? "true" : "false"));
System.out.println(" contains(\"xyz\"): " + (has2 == 1 ? "true" : "false"));
System.out.println("");
System.out.println("7. startsWith/endsWith - Check boundaries");
int starts = original.startsWith("Hello") ? 1 : 0;
int ends = original.endsWith("World") ? 1 : 0;
System.out.println(" startsWith(\"Hello\"): " + (starts == 1 ? "true" : "false"));
System.out.println(" endsWith(\"World\"): " + (ends == 1 ? "true" : "false"));
System.out.println("");
System.out.println("8. toLowerCase/toUpperCase - Case conversion");
String lower = original.toLowerCase();
String upper = original.toUpperCase();
System.out.println(" toLowerCase(): \"" + lower + "\"");
System.out.println(" toUpperCase(): \"" + upper + "\"");
System.out.println("");
System.out.println("9. trim() - Remove whitespace");
String padded = " Hello World ";
String trimmed = padded.trim();
System.out.println(" Original: \"" + padded + "\"");
System.out.println(" Trimmed: \"" + trimmed + "\"");
System.out.println("");
System.out.println("10. compareTo() - Lexicographic comparison");
int cmp1 = original.compareTo("Hello World");
int cmp2 = original.compareTo("ABC");
int cmp3 = original.compareTo("XYZ");
System.out.println(" compareTo(\"Hello World\"): " + cmp1 + " (equal)");
System.out.println(" compareTo(\"ABC\"): " + (cmp2 > 0 ? "positive" : "negative") + " (after ABC)");
System.out.println(" compareTo(\"XYZ\"): " + (cmp3 < 0 ? "negative" : "positive") + " (before XYZ)");
System.out.println("");
System.out.println("11. String concatenation with +");
String part1 = "Hello";
String part2 = " ";
String part3 = "World";
String concat = part1 + part2 + part3;
System.out.println(" \"" + part1 + "\" + \"" + part2 + "\" + \"" + part3 + "\" = \"" + concat + "\"");
System.out.println("");
System.out.println("12. Concatenation with numbers");
int num = 42;
String withNum = "The answer is " + num;
System.out.println(" \"The answer is \" + 42 = \"" + withNum + "\"");
System.out.println("");
System.out.println("==========================================");
System.out.println("All String methods working correctly!");
System.out.println("==========================================");
return 0;
}
}
-124
View File
@@ -1,8 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import time import time
import sys
sys.setrecursionlimit(10000)
def fibonacci(n): def fibonacci(n):
if n <= 1: if n <= 1:
@@ -139,85 +136,6 @@ def bubble_sort(size):
return arr[0] return arr[0]
def quick_sort_partition(arr, low, high):
pivot = arr[high]
i = low - 1
for j in range(low, high):
if arr[j] < pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
def quick_sort_helper(arr, low, high):
if low < high:
pi = quick_sort_partition(arr, low, high)
quick_sort_helper(arr, low, pi - 1)
quick_sort_helper(arr, pi + 1, high)
def quick_sort(size):
arr = [0] * size
for i in range(size):
arr[i] = size - i
quick_sort_helper(arr, 0, size - 1)
return arr[0]
def binary_search(arr, target, low, high):
if low > high:
return -1
mid = low + (high - low) // 2
if arr[mid] == target:
return mid
if arr[mid] > target:
return binary_search(arr, target, low, mid - 1)
return binary_search(arr, target, mid + 1, high)
def binary_search_bench(size):
arr = [i for i in range(size)]
total = 0
for i in range(0, size, 100):
result = binary_search(arr, i, 0, size - 1)
total += result
return total
def string_concat(iterations):
length = 0
for i in range(iterations):
s = "Hello"
s = s + "World"
s = s + str(i)
length += len(s)
return length
def bitwise_ops(iterations):
result = 0
for i in range(1, iterations):
result ^= (i << 1)
result |= (i >> 1)
result &= (i >> 2)
result ^= ~i
return result
def array_copy(size):
src = [i for i in range(size)]
dst = [0] * size
for i in range(size):
dst[i] = src[i]
return dst[size - 1]
def insertion_sort(size):
arr = [0] * size
for i in range(size):
arr[i] = size - i
for i in range(1, size):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
return arr[0]
def main(): def main():
print("=== Python Comprehensive Benchmark Suite ===") print("=== Python Comprehensive Benchmark Suite ===")
@@ -326,48 +244,6 @@ def main():
print(f"Bubble sort (5000 elements) = {bubble}") print(f"Bubble sort (5000 elements) = {bubble}")
print(f"Time: {bubble_time} ms") print(f"Time: {bubble_time} ms")
start = time.perf_counter_ns()
quick = quick_sort(1000)
end = time.perf_counter_ns()
quick_time = (end - start) // 1000000
print(f"Quick sort (1000 elements) = {quick}")
print(f"Time: {quick_time} ms")
start = time.perf_counter_ns()
insertion = insertion_sort(3000)
end = time.perf_counter_ns()
insertion_time = (end - start) // 1000000
print(f"Insertion sort (3000 elements) = {insertion}")
print(f"Time: {insertion_time} ms")
start = time.perf_counter_ns()
binsearch = binary_search_bench(100000)
end = time.perf_counter_ns()
binsearch_time = (end - start) // 1000000
print(f"Binary search (100K, 1K searches) = {binsearch}")
print(f"Time: {binsearch_time} ms")
start = time.perf_counter_ns()
strconcat = string_concat(50000)
end = time.perf_counter_ns()
strconcat_time = (end - start) // 1000000
print(f"String concatenation (50K) = {strconcat}")
print(f"Time: {strconcat_time} ms")
start = time.perf_counter_ns()
bitwise = bitwise_ops(10000000)
end = time.perf_counter_ns()
bitwise_time = (end - start) // 1000000
print(f"Bitwise operations (10M) = {bitwise}")
print(f"Time: {bitwise_time} ms")
start = time.perf_counter_ns()
arrcopy = array_copy(1000000)
end = time.perf_counter_ns()
arrcopy_time = (end - start) // 1000000
print(f"Array copy (1M elements) = {arrcopy}")
print(f"Time: {arrcopy_time} ms")
print("=== Benchmark Complete ===") print("=== Benchmark Complete ===")
if __name__ == "__main__": if __name__ == "__main__":
-45
View File
@@ -290,55 +290,10 @@ static const char* _rava_opcode_name(RavaOpCode_e opcode) {
case RAVA_OP_SOCKET_GET_INPUT_STREAM: return "SOCKET_GET_INPUT_STREAM"; case RAVA_OP_SOCKET_GET_INPUT_STREAM: return "SOCKET_GET_INPUT_STREAM";
case RAVA_OP_SOCKET_GET_OUTPUT_STREAM: return "SOCKET_GET_OUTPUT_STREAM"; case RAVA_OP_SOCKET_GET_OUTPUT_STREAM: return "SOCKET_GET_OUTPUT_STREAM";
case RAVA_OP_INPUT_STREAM_READ: return "INPUT_STREAM_READ"; case RAVA_OP_INPUT_STREAM_READ: return "INPUT_STREAM_READ";
case RAVA_OP_INPUT_STREAM_READ_BYTES: return "INPUT_STREAM_READ_BYTES";
case RAVA_OP_INPUT_STREAM_AVAILABLE: return "INPUT_STREAM_AVAILABLE";
case RAVA_OP_INPUT_STREAM_SKIP: return "INPUT_STREAM_SKIP";
case RAVA_OP_OUTPUT_STREAM_WRITE: return "OUTPUT_STREAM_WRITE"; case RAVA_OP_OUTPUT_STREAM_WRITE: return "OUTPUT_STREAM_WRITE";
case RAVA_OP_OUTPUT_STREAM_FLUSH: return "OUTPUT_STREAM_FLUSH";
case RAVA_OP_STREAM_CLOSE: return "STREAM_CLOSE"; case RAVA_OP_STREAM_CLOSE: return "STREAM_CLOSE";
case RAVA_OP_INETADDRESS_GET_BY_NAME: return "INETADDRESS_GET_BY_NAME";
case RAVA_OP_INETADDRESS_GET_LOCAL_HOST: return "INETADDRESS_GET_LOCAL_HOST";
case RAVA_OP_INETADDRESS_GET_LOOPBACK: return "INETADDRESS_GET_LOOPBACK";
case RAVA_OP_INETADDRESS_GET_HOST_NAME: return "INETADDRESS_GET_HOST_NAME";
case RAVA_OP_INETADDRESS_GET_HOST_ADDRESS: return "INETADDRESS_GET_HOST_ADDRESS";
case RAVA_OP_INETADDRESS_IS_LOOPBACK: return "INETADDRESS_IS_LOOPBACK";
case RAVA_OP_INETADDRESS_IS_ANY_LOCAL: return "INETADDRESS_IS_ANY_LOCAL";
case RAVA_OP_INETADDRESS_GET_ALL_BY_NAME: return "INETADDRESS_GET_ALL_BY_NAME";
case RAVA_OP_INETADDRESS_GET_ADDRESS: return "INETADDRESS_GET_ADDRESS";
case RAVA_OP_INETADDRESS_IS_MULTICAST_ADDRESS: return "INETADDRESS_IS_MULTICAST_ADDRESS";
case RAVA_OP_INETADDRESS_IS_REACHABLE: return "INETADDRESS_IS_REACHABLE";
case RAVA_OP_SOCKET_GET_PORT: return "SOCKET_GET_PORT";
case RAVA_OP_SOCKET_GET_LOCAL_PORT: return "SOCKET_GET_LOCAL_PORT";
case RAVA_OP_SOCKET_GET_INET_ADDRESS: return "SOCKET_GET_INET_ADDRESS";
case RAVA_OP_SOCKET_GET_LOCAL_ADDRESS: return "SOCKET_GET_LOCAL_ADDRESS";
case RAVA_OP_SERVER_SOCKET_GET_LOCAL_PORT: return "SERVER_SOCKET_GET_LOCAL_PORT";
case RAVA_OP_SERVER_SOCKET_IS_BOUND: return "SERVER_SOCKET_IS_BOUND";
case RAVA_OP_SERVER_SOCKET_IS_CLOSED: return "SERVER_SOCKET_IS_CLOSED";
case RAVA_OP_SERVER_SOCKET_SET_RECEIVE_BUFFER_SIZE: return "SERVER_SOCKET_SET_RECEIVE_BUFFER_SIZE";
case RAVA_OP_SERVER_SOCKET_GET_RECEIVE_BUFFER_SIZE: return "SERVER_SOCKET_GET_RECEIVE_BUFFER_SIZE";
case RAVA_OP_SERVER_SOCKET_SET_REUSE_ADDRESS: return "SERVER_SOCKET_SET_REUSE_ADDRESS";
case RAVA_OP_SERVER_SOCKET_GET_REUSE_ADDRESS: return "SERVER_SOCKET_GET_REUSE_ADDRESS";
case RAVA_OP_SOCKET_SET_SO_TIMEOUT: return "SOCKET_SET_SO_TIMEOUT";
case RAVA_OP_SOCKET_GET_SO_TIMEOUT: return "SOCKET_GET_SO_TIMEOUT";
case RAVA_OP_SOCKET_SET_TCP_NODELAY: return "SOCKET_SET_TCP_NODELAY";
case RAVA_OP_SOCKET_GET_TCP_NODELAY: return "SOCKET_GET_TCP_NODELAY";
case RAVA_OP_SOCKET_BIND: return "SOCKET_BIND";
case RAVA_OP_SOCKET_IS_CONNECTED: return "SOCKET_IS_CONNECTED";
case RAVA_OP_SOCKET_SHUTDOWN_INPUT: return "SOCKET_SHUTDOWN_INPUT";
case RAVA_OP_SOCKET_SHUTDOWN_OUTPUT: return "SOCKET_SHUTDOWN_OUTPUT";
case RAVA_OP_SOCKET_IS_INPUT_SHUTDOWN: return "SOCKET_IS_INPUT_SHUTDOWN";
case RAVA_OP_SOCKET_IS_OUTPUT_SHUTDOWN: return "SOCKET_IS_OUTPUT_SHUTDOWN";
case RAVA_OP_SOCKET_SET_SEND_BUFFER_SIZE: return "SOCKET_SET_SEND_BUFFER_SIZE";
case RAVA_OP_SOCKET_GET_SEND_BUFFER_SIZE: return "SOCKET_GET_SEND_BUFFER_SIZE";
case RAVA_OP_SOCKET_SET_RECEIVE_BUFFER_SIZE: return "SOCKET_SET_RECEIVE_BUFFER_SIZE";
case RAVA_OP_SOCKET_GET_RECEIVE_BUFFER_SIZE: return "SOCKET_GET_RECEIVE_BUFFER_SIZE";
case RAVA_OP_SOCKET_SET_KEEP_ALIVE: return "SOCKET_SET_KEEP_ALIVE";
case RAVA_OP_SOCKET_GET_KEEP_ALIVE: return "SOCKET_GET_KEEP_ALIVE";
case RAVA_OP_SOCKET_SET_REUSE_ADDRESS: return "SOCKET_SET_REUSE_ADDRESS";
case RAVA_OP_SOCKET_GET_REUSE_ADDRESS: return "SOCKET_GET_REUSE_ADDRESS";
case RAVA_OP_METHOD_REF: return "METHOD_REF"; case RAVA_OP_METHOD_REF: return "METHOD_REF";
case RAVA_OP_METHOD_REF_INVOKE: return "METHOD_REF_INVOKE"; case RAVA_OP_METHOD_REF_INVOKE: return "METHOD_REF_INVOKE";
case RAVA_OP_ARRAY_CMP_SWAP_INT: return "ARRAY_CMP_SWAP_INT";
default: return "UNKNOWN"; default: return "UNKNOWN";
} }
} }
+1 -57
View File
@@ -113,7 +113,6 @@ typedef enum {
RAVA_OP_LOAD_TWO_LOCALS, RAVA_OP_LOAD_TWO_LOCALS,
RAVA_OP_ADD_LOCAL_TO_LOCAL, RAVA_OP_ADD_LOCAL_TO_LOCAL,
RAVA_OP_LOAD_LOCAL_LT_LOCAL_JUMPFALSE, RAVA_OP_LOAD_LOCAL_LT_LOCAL_JUMPFALSE,
RAVA_OP_ARRAY_CMP_SWAP_INT,
RAVA_OP_MATH_ABS, RAVA_OP_MATH_ABS,
RAVA_OP_MATH_SQRT, RAVA_OP_MATH_SQRT,
@@ -157,59 +156,9 @@ typedef enum {
RAVA_OP_SOCKET_GET_INPUT_STREAM, RAVA_OP_SOCKET_GET_INPUT_STREAM,
RAVA_OP_SOCKET_GET_OUTPUT_STREAM, RAVA_OP_SOCKET_GET_OUTPUT_STREAM,
RAVA_OP_INPUT_STREAM_READ, RAVA_OP_INPUT_STREAM_READ,
RAVA_OP_INPUT_STREAM_READ_BYTES,
RAVA_OP_INPUT_STREAM_AVAILABLE,
RAVA_OP_INPUT_STREAM_SKIP,
RAVA_OP_OUTPUT_STREAM_WRITE, RAVA_OP_OUTPUT_STREAM_WRITE,
RAVA_OP_OUTPUT_STREAM_FLUSH,
RAVA_OP_STREAM_CLOSE, RAVA_OP_STREAM_CLOSE,
RAVA_OP_INETADDRESS_GET_BY_NAME,
RAVA_OP_INETADDRESS_GET_LOCAL_HOST,
RAVA_OP_INETADDRESS_GET_LOOPBACK,
RAVA_OP_INETADDRESS_GET_HOST_NAME,
RAVA_OP_INETADDRESS_GET_HOST_ADDRESS,
RAVA_OP_INETADDRESS_IS_LOOPBACK,
RAVA_OP_INETADDRESS_IS_ANY_LOCAL,
RAVA_OP_INETADDRESS_GET_ALL_BY_NAME,
RAVA_OP_INETADDRESS_GET_ADDRESS,
RAVA_OP_INETADDRESS_IS_MULTICAST_ADDRESS,
RAVA_OP_INETADDRESS_IS_REACHABLE,
RAVA_OP_SOCKET_GET_PORT,
RAVA_OP_SOCKET_GET_LOCAL_PORT,
RAVA_OP_SOCKET_GET_INET_ADDRESS,
RAVA_OP_SOCKET_GET_LOCAL_ADDRESS,
RAVA_OP_SERVER_SOCKET_GET_LOCAL_PORT,
RAVA_OP_SERVER_SOCKET_IS_BOUND,
RAVA_OP_SERVER_SOCKET_IS_CLOSED,
RAVA_OP_SERVER_SOCKET_SET_RECEIVE_BUFFER_SIZE,
RAVA_OP_SERVER_SOCKET_GET_RECEIVE_BUFFER_SIZE,
RAVA_OP_SERVER_SOCKET_SET_REUSE_ADDRESS,
RAVA_OP_SERVER_SOCKET_GET_REUSE_ADDRESS,
RAVA_OP_SOCKET_SET_SO_TIMEOUT,
RAVA_OP_SOCKET_GET_SO_TIMEOUT,
RAVA_OP_SOCKET_SET_TCP_NODELAY,
RAVA_OP_SOCKET_GET_TCP_NODELAY,
RAVA_OP_SOCKET_BIND,
RAVA_OP_SOCKET_IS_CONNECTED,
RAVA_OP_SOCKET_SHUTDOWN_INPUT,
RAVA_OP_SOCKET_SHUTDOWN_OUTPUT,
RAVA_OP_SOCKET_IS_INPUT_SHUTDOWN,
RAVA_OP_SOCKET_IS_OUTPUT_SHUTDOWN,
RAVA_OP_SOCKET_SET_SEND_BUFFER_SIZE,
RAVA_OP_SOCKET_GET_SEND_BUFFER_SIZE,
RAVA_OP_SOCKET_SET_RECEIVE_BUFFER_SIZE,
RAVA_OP_SOCKET_GET_RECEIVE_BUFFER_SIZE,
RAVA_OP_SOCKET_SET_KEEP_ALIVE,
RAVA_OP_SOCKET_GET_KEEP_ALIVE,
RAVA_OP_SOCKET_SET_REUSE_ADDRESS,
RAVA_OP_SOCKET_GET_REUSE_ADDRESS,
RAVA_OP_METHOD_REF, RAVA_OP_METHOD_REF,
RAVA_OP_METHOD_REF_INVOKE RAVA_OP_METHOD_REF_INVOKE
} RavaOpCode_e; } RavaOpCode_e;
@@ -232,7 +181,6 @@ typedef union {
struct { struct {
char *class_name; char *class_name;
char *field_name; char *field_name;
void *cached_ptr;
} field; } field;
struct { struct {
int local_index; int local_index;
@@ -264,16 +212,12 @@ typedef union {
bool is_constructor; bool is_constructor;
bool is_static; bool is_static;
} method_ref; } method_ref;
struct {
int array_local;
int index_local;
} array_cmp_swap;
} RavaOperand_u; } RavaOperand_u;
typedef struct { typedef struct {
RavaOpCode_e opcode; RavaOpCode_e opcode;
int line;
RavaOperand_u operand; RavaOperand_u operand;
int line;
} RavaInstruction_t; } RavaInstruction_t;
typedef struct { typedef struct {
+3 -392
View File
@@ -255,17 +255,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
strcmp(index_name, gen->loop_context->loop_var_name) == 0) { strcmp(index_name, gen->loop_context->loop_var_name) == 0) {
use_unchecked = true; use_unchecked = true;
} }
} else if (index_node->type == RAVA_AST_BINARY_EXPR &&
(index_node->data.binary.op == RAVA_BINOP_ADD ||
index_node->data.binary.op == RAVA_BINOP_SUB)) {
RavaASTNode_t *left = index_node->data.binary.left;
RavaASTNode_t *right = index_node->data.binary.right;
if (left->type == RAVA_AST_IDENTIFIER_EXPR &&
right->type == RAVA_AST_LITERAL_EXPR &&
gen->loop_context->loop_var_name &&
strcmp(left->data.identifier.name, gen->loop_context->loop_var_name) == 0) {
use_unchecked = true;
}
} }
} }
@@ -281,7 +270,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
instr.opcode = RAVA_OP_STORE_STATIC; instr.opcode = RAVA_OP_STORE_STATIC;
instr.operand.field.class_name = strdup(obj_name); instr.operand.field.class_name = strdup(obj_name);
instr.operand.field.field_name = strdup(target_member->data.member_access.member); instr.operand.field.field_name = strdup(target_member->data.member_access.member);
instr.operand.field.cached_ptr = NULL;
_rava_ir_emit(gen, instr); _rava_ir_emit(gen, instr);
break; break;
} }
@@ -313,7 +301,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
instr.opcode = RAVA_OP_LOAD_STATIC; instr.opcode = RAVA_OP_LOAD_STATIC;
instr.operand.field.class_name = strdup(obj_name); instr.operand.field.class_name = strdup(obj_name);
instr.operand.field.field_name = strdup(expr->data.member_access.member); instr.operand.field.field_name = strdup(expr->data.member_access.member);
instr.operand.field.cached_ptr = NULL;
_rava_ir_emit(gen, instr); _rava_ir_emit(gen, instr);
break; break;
} }
@@ -334,24 +321,12 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
bool use_unchecked = false; bool use_unchecked = false;
if (gen->loop_context && gen->loop_context->has_bounds_check) { if (gen->loop_context && gen->loop_context->has_bounds_check) {
RavaASTNode_t *index_node = expr->data.array_access.index; if (expr->data.array_access.index->type == RAVA_AST_IDENTIFIER_EXPR) {
if (index_node->type == RAVA_AST_IDENTIFIER_EXPR) { const char *index_name = expr->data.array_access.index->data.identifier.name;
const char *index_name = index_node->data.identifier.name;
if (gen->loop_context->loop_var_name && if (gen->loop_context->loop_var_name &&
strcmp(index_name, gen->loop_context->loop_var_name) == 0) { strcmp(index_name, gen->loop_context->loop_var_name) == 0) {
use_unchecked = true; use_unchecked = true;
} }
} else if (index_node->type == RAVA_AST_BINARY_EXPR &&
(index_node->data.binary.op == RAVA_BINOP_ADD ||
index_node->data.binary.op == RAVA_BINOP_SUB)) {
RavaASTNode_t *left = index_node->data.binary.left;
RavaASTNode_t *right = index_node->data.binary.right;
if (left->type == RAVA_AST_IDENTIFIER_EXPR &&
right->type == RAVA_AST_LITERAL_EXPR &&
gen->loop_context->loop_var_name &&
strcmp(left->data.identifier.name, gen->loop_context->loop_var_name) == 0) {
use_unchecked = true;
}
} }
} }
@@ -538,52 +513,7 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
bool is_socket_get_output_stream = false; bool is_socket_get_output_stream = false;
bool is_server_socket_accept = false; bool is_server_socket_accept = false;
bool is_input_stream_read = false; bool is_input_stream_read = false;
bool is_input_stream_read_bytes = false;
bool is_input_stream_available = false;
bool is_input_stream_skip = false;
bool is_output_stream_write = false; bool is_output_stream_write = false;
bool is_output_stream_flush = false;
bool is_inetaddress_get_by_name = false;
bool is_inetaddress_get_local_host = false;
bool is_inetaddress_get_loopback = false;
bool is_inetaddress_get_host_name = false;
bool is_inetaddress_get_host_address = false;
bool is_inetaddress_is_loopback = false;
bool is_inetaddress_is_any_local = false;
bool is_inetaddress_get_all_by_name = false;
bool is_inetaddress_get_address = false;
bool is_inetaddress_is_multicast_address = false;
bool is_inetaddress_is_reachable = false;
bool is_socket_get_port = false;
bool is_socket_get_local_port = false;
bool is_socket_get_inet_address = false;
bool is_socket_get_local_address = false;
bool is_server_socket_get_local_port = false;
bool is_server_socket_is_bound = false;
bool is_server_socket_is_closed = false;
bool is_server_socket_set_receive_buffer_size = false;
bool is_server_socket_get_receive_buffer_size = false;
bool is_server_socket_set_reuse_address = false;
bool is_server_socket_get_reuse_address = false;
bool is_socket_set_so_timeout = false;
bool is_socket_get_so_timeout = false;
bool is_socket_set_tcp_nodelay = false;
bool is_socket_get_tcp_nodelay = false;
bool is_socket_bind = false;
bool is_socket_is_connected = false;
bool is_socket_shutdown_input = false;
bool is_socket_shutdown_output = false;
bool is_socket_is_input_shutdown = false;
bool is_socket_is_output_shutdown = false;
bool is_socket_set_send_buffer_size = false;
bool is_socket_get_send_buffer_size = false;
bool is_socket_set_receive_buffer_size = false;
bool is_socket_get_receive_buffer_size = false;
bool is_socket_set_keep_alive = false;
bool is_socket_get_keep_alive = false;
bool is_socket_set_reuse_address = false;
bool is_socket_get_reuse_address = false;
RavaASTNode_t *inetaddress_object = NULL;
RavaASTNode_t *string_object = NULL; RavaASTNode_t *string_object = NULL;
RavaASTNode_t *collection_object = NULL; RavaASTNode_t *collection_object = NULL;
RavaASTNode_t *socket_object = NULL; RavaASTNode_t *socket_object = NULL;
@@ -655,19 +585,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
is_math_random = true; is_math_random = true;
} }
} }
if (member->data.member_access.object->type == RAVA_AST_IDENTIFIER_EXPR &&
strcmp(member->data.member_access.object->data.identifier.name, "InetAddress") == 0) {
const char *method = member->data.member_access.member;
if (strcmp(method, "getByName") == 0 && expr->data.call.arguments_count == 1) {
is_inetaddress_get_by_name = true;
} else if (strcmp(method, "getLocalHost") == 0 && expr->data.call.arguments_count == 0) {
is_inetaddress_get_local_host = true;
} else if (strcmp(method, "getLoopbackAddress") == 0 && expr->data.call.arguments_count == 0) {
is_inetaddress_get_loopback = true;
} else if (strcmp(method, "getAllByName") == 0 && expr->data.call.arguments_count == 1) {
is_inetaddress_get_all_by_name = true;
}
}
if (strcmp(member->data.member_access.member, "length") == 0 && expr->data.call.arguments_count == 0) { if (strcmp(member->data.member_access.member, "length") == 0 && expr->data.call.arguments_count == 0) {
is_string_length = true; is_string_length = true;
string_object = member->data.member_access.object; string_object = member->data.member_access.object;
@@ -743,132 +660,15 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
} else if (strcmp(member->data.member_access.member, "accept") == 0 && expr->data.call.arguments_count == 0) { } else if (strcmp(member->data.member_access.member, "accept") == 0 && expr->data.call.arguments_count == 0) {
is_server_socket_accept = true; is_server_socket_accept = true;
socket_object = member->data.member_access.object; socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "read") == 0 && expr->data.call.arguments_count == 0) { } else if (strcmp(member->data.member_access.member, "read") == 0) {
is_input_stream_read = true; is_input_stream_read = true;
socket_object = member->data.member_access.object; socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "read") == 0 && expr->data.call.arguments_count == 3) {
is_input_stream_read_bytes = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "available") == 0 && expr->data.call.arguments_count == 0) {
is_input_stream_available = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "skip") == 0 && expr->data.call.arguments_count == 1) {
is_input_stream_skip = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "write") == 0) { } else if (strcmp(member->data.member_access.member, "write") == 0) {
is_output_stream_write = true; is_output_stream_write = true;
socket_object = member->data.member_access.object; socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "flush") == 0 && expr->data.call.arguments_count == 0) {
is_output_stream_flush = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "close") == 0 && expr->data.call.arguments_count == 0) { } else if (strcmp(member->data.member_access.member, "close") == 0 && expr->data.call.arguments_count == 0) {
is_socket_close = true; is_socket_close = true;
socket_object = member->data.member_access.object; socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getHostName") == 0 && expr->data.call.arguments_count == 0) {
is_inetaddress_get_host_name = true;
inetaddress_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getHostAddress") == 0 && expr->data.call.arguments_count == 0) {
is_inetaddress_get_host_address = true;
inetaddress_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isLoopbackAddress") == 0 && expr->data.call.arguments_count == 0) {
is_inetaddress_is_loopback = true;
inetaddress_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isAnyLocalAddress") == 0 && expr->data.call.arguments_count == 0) {
is_inetaddress_is_any_local = true;
inetaddress_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getAddress") == 0 && expr->data.call.arguments_count == 0) {
is_inetaddress_get_address = true;
inetaddress_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isMulticastAddress") == 0 && expr->data.call.arguments_count == 0) {
is_inetaddress_is_multicast_address = true;
inetaddress_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isReachable") == 0 && expr->data.call.arguments_count == 1) {
is_inetaddress_is_reachable = true;
inetaddress_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getPort") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_port = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getLocalPort") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_local_port = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getInetAddress") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_inet_address = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getLocalAddress") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_local_address = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isBound") == 0 && expr->data.call.arguments_count == 0) {
is_server_socket_is_bound = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isClosed") == 0 && expr->data.call.arguments_count == 0) {
is_server_socket_is_closed = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "setReceiveBufferSize") == 0 && expr->data.call.arguments_count == 1) {
is_server_socket_set_receive_buffer_size = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getReceiveBufferSize") == 0 && expr->data.call.arguments_count == 0) {
is_server_socket_get_receive_buffer_size = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "setReuseAddress") == 0 && expr->data.call.arguments_count == 1) {
is_server_socket_set_reuse_address = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getReuseAddress") == 0 && expr->data.call.arguments_count == 0) {
is_server_socket_get_reuse_address = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "setSoTimeout") == 0 && expr->data.call.arguments_count == 1) {
is_socket_set_so_timeout = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getSoTimeout") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_so_timeout = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "setTcpNoDelay") == 0 && expr->data.call.arguments_count == 1) {
is_socket_set_tcp_nodelay = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getTcpNoDelay") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_tcp_nodelay = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "bind") == 0 && expr->data.call.arguments_count == 2) {
is_socket_bind = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isConnected") == 0 && expr->data.call.arguments_count == 0) {
is_socket_is_connected = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "shutdownInput") == 0 && expr->data.call.arguments_count == 0) {
is_socket_shutdown_input = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "shutdownOutput") == 0 && expr->data.call.arguments_count == 0) {
is_socket_shutdown_output = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isInputShutdown") == 0 && expr->data.call.arguments_count == 0) {
is_socket_is_input_shutdown = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "isOutputShutdown") == 0 && expr->data.call.arguments_count == 0) {
is_socket_is_output_shutdown = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "setSendBufferSize") == 0 && expr->data.call.arguments_count == 1) {
is_socket_set_send_buffer_size = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getSendBufferSize") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_send_buffer_size = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "setReceiveBufferSize") == 0 && expr->data.call.arguments_count == 1) {
is_socket_set_receive_buffer_size = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getReceiveBufferSize") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_receive_buffer_size = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "setKeepAlive") == 0 && expr->data.call.arguments_count == 1) {
is_socket_set_keep_alive = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getKeepAlive") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_keep_alive = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "setReuseAddress") == 0 && expr->data.call.arguments_count == 1) {
is_socket_set_reuse_address = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getReuseAddress") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_reuse_address = true;
socket_object = member->data.member_access.object;
} }
} }
@@ -1076,22 +876,6 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
_rava_ir_gen_expression(gen, socket_object); _rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_INPUT_STREAM_READ; instr.opcode = RAVA_OP_INPUT_STREAM_READ;
_rava_ir_emit(gen, instr); _rava_ir_emit(gen, instr);
} else if (is_input_stream_read_bytes) {
_rava_ir_gen_expression(gen, socket_object);
for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
_rava_ir_gen_expression(gen, expr->data.call.arguments[i]);
}
instr.opcode = RAVA_OP_INPUT_STREAM_READ_BYTES;
_rava_ir_emit(gen, instr);
} else if (is_input_stream_available) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_INPUT_STREAM_AVAILABLE;
_rava_ir_emit(gen, instr);
} else if (is_input_stream_skip) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_INPUT_STREAM_SKIP;
_rava_ir_emit(gen, instr);
} else if (is_output_stream_write) { } else if (is_output_stream_write) {
_rava_ir_gen_expression(gen, socket_object); _rava_ir_gen_expression(gen, socket_object);
for (size_t i = 0; i < expr->data.call.arguments_count; i++) { for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
@@ -1100,183 +884,10 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
instr.opcode = RAVA_OP_OUTPUT_STREAM_WRITE; instr.opcode = RAVA_OP_OUTPUT_STREAM_WRITE;
instr.operand.int_value = expr->data.call.arguments_count; instr.operand.int_value = expr->data.call.arguments_count;
_rava_ir_emit(gen, instr); _rava_ir_emit(gen, instr);
} else if (is_output_stream_flush) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_OUTPUT_STREAM_FLUSH;
_rava_ir_emit(gen, instr);
} else if (is_socket_close) { } else if (is_socket_close) {
_rava_ir_gen_expression(gen, socket_object); _rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_CLOSE; instr.opcode = RAVA_OP_SOCKET_CLOSE;
_rava_ir_emit(gen, instr); _rava_ir_emit(gen, instr);
} else if (is_inetaddress_get_by_name) {
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_INETADDRESS_GET_BY_NAME;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_get_local_host) {
instr.opcode = RAVA_OP_INETADDRESS_GET_LOCAL_HOST;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_get_loopback) {
instr.opcode = RAVA_OP_INETADDRESS_GET_LOOPBACK;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_get_host_name) {
_rava_ir_gen_expression(gen, inetaddress_object);
instr.opcode = RAVA_OP_INETADDRESS_GET_HOST_NAME;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_get_host_address) {
_rava_ir_gen_expression(gen, inetaddress_object);
instr.opcode = RAVA_OP_INETADDRESS_GET_HOST_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_is_loopback) {
_rava_ir_gen_expression(gen, inetaddress_object);
instr.opcode = RAVA_OP_INETADDRESS_IS_LOOPBACK;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_is_any_local) {
_rava_ir_gen_expression(gen, inetaddress_object);
instr.opcode = RAVA_OP_INETADDRESS_IS_ANY_LOCAL;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_get_all_by_name) {
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_INETADDRESS_GET_ALL_BY_NAME;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_get_address) {
_rava_ir_gen_expression(gen, inetaddress_object);
instr.opcode = RAVA_OP_INETADDRESS_GET_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_is_multicast_address) {
_rava_ir_gen_expression(gen, inetaddress_object);
instr.opcode = RAVA_OP_INETADDRESS_IS_MULTICAST_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_inetaddress_is_reachable) {
_rava_ir_gen_expression(gen, inetaddress_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_INETADDRESS_IS_REACHABLE;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_port) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_PORT;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_local_port) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_LOCAL_PORT;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_inet_address) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_INET_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_local_address) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_LOCAL_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_server_socket_get_local_port) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SERVER_SOCKET_GET_LOCAL_PORT;
_rava_ir_emit(gen, instr);
} else if (is_server_socket_is_bound) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SERVER_SOCKET_IS_BOUND;
_rava_ir_emit(gen, instr);
} else if (is_server_socket_is_closed) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SERVER_SOCKET_IS_CLOSED;
_rava_ir_emit(gen, instr);
} else if (is_server_socket_set_receive_buffer_size) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_SERVER_SOCKET_SET_RECEIVE_BUFFER_SIZE;
_rava_ir_emit(gen, instr);
} else if (is_server_socket_get_receive_buffer_size) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SERVER_SOCKET_GET_RECEIVE_BUFFER_SIZE;
_rava_ir_emit(gen, instr);
} else if (is_server_socket_set_reuse_address) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_SERVER_SOCKET_SET_REUSE_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_server_socket_get_reuse_address) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SERVER_SOCKET_GET_REUSE_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_socket_set_so_timeout) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_SOCKET_SET_SO_TIMEOUT;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_so_timeout) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_SO_TIMEOUT;
_rava_ir_emit(gen, instr);
} else if (is_socket_set_tcp_nodelay) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_SOCKET_SET_TCP_NODELAY;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_tcp_nodelay) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_TCP_NODELAY;
_rava_ir_emit(gen, instr);
} else if (is_socket_bind) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
_rava_ir_gen_expression(gen, expr->data.call.arguments[1]);
instr.opcode = RAVA_OP_SOCKET_BIND;
_rava_ir_emit(gen, instr);
} else if (is_socket_is_connected) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_IS_CONNECTED;
_rava_ir_emit(gen, instr);
} else if (is_socket_shutdown_input) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_SHUTDOWN_INPUT;
_rava_ir_emit(gen, instr);
} else if (is_socket_shutdown_output) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_SHUTDOWN_OUTPUT;
_rava_ir_emit(gen, instr);
} else if (is_socket_is_input_shutdown) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_IS_INPUT_SHUTDOWN;
_rava_ir_emit(gen, instr);
} else if (is_socket_is_output_shutdown) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_IS_OUTPUT_SHUTDOWN;
_rava_ir_emit(gen, instr);
} else if (is_socket_set_send_buffer_size) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_SOCKET_SET_SEND_BUFFER_SIZE;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_send_buffer_size) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_SEND_BUFFER_SIZE;
_rava_ir_emit(gen, instr);
} else if (is_socket_set_receive_buffer_size) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_SOCKET_SET_RECEIVE_BUFFER_SIZE;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_receive_buffer_size) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_RECEIVE_BUFFER_SIZE;
_rava_ir_emit(gen, instr);
} else if (is_socket_set_keep_alive) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_SOCKET_SET_KEEP_ALIVE;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_keep_alive) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_KEEP_ALIVE;
_rava_ir_emit(gen, instr);
} else if (is_socket_set_reuse_address) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_SOCKET_SET_REUSE_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_reuse_address) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_REUSE_ADDRESS;
_rava_ir_emit(gen, instr);
} else if (is_println || is_print) { } else if (is_println || is_print) {
for (size_t i = 0; i < expr->data.call.arguments_count; i++) { for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
_rava_ir_gen_expression(gen, expr->data.call.arguments[i]); _rava_ir_gen_expression(gen, expr->data.call.arguments[i]);
+4 -4
View File
@@ -17,12 +17,12 @@
typedef struct { typedef struct {
RavaMethod_t* method; RavaMethod_t* method;
size_t pc;
size_t stack_top;
bool has_this;
RavaNanboxValue_t this_ref;
RavaNanboxValue_t locals[RAVA_MAX_LOCALS_FIXED]; RavaNanboxValue_t locals[RAVA_MAX_LOCALS_FIXED];
RavaNanboxValue_t stack[RAVA_MAX_STACK_FIXED]; RavaNanboxValue_t stack[RAVA_MAX_STACK_FIXED];
size_t stack_top;
size_t pc;
bool has_this;
RavaNanboxValue_t this_ref;
} FastFrame_t; } FastFrame_t;
typedef struct { typedef struct {
-3
View File
@@ -31,7 +31,6 @@ RavaMethod_t* rava_methodcache_lookup(MethodCache_t* cache,
slot->method_hash == method_hash && slot->method_hash == method_hash &&
slot->method != NULL) { slot->method != NULL) {
entry->lru = (uint8_t)i; entry->lru = (uint8_t)i;
slot->hit_count++;
return slot->method; return slot->method;
} }
} }
@@ -56,7 +55,6 @@ void rava_methodcache_insert(MethodCache_t* cache,
entry->slots[i].class_hash = class_hash; entry->slots[i].class_hash = class_hash;
entry->slots[i].method_hash = method_hash; entry->slots[i].method_hash = method_hash;
entry->slots[i].method = method; entry->slots[i].method = method;
entry->slots[i].hit_count = 0;
entry->lru = (uint8_t)i; entry->lru = (uint8_t)i;
return; return;
} }
@@ -66,7 +64,6 @@ void rava_methodcache_insert(MethodCache_t* cache,
entry->slots[evict].class_hash = class_hash; entry->slots[evict].class_hash = class_hash;
entry->slots[evict].method_hash = method_hash; entry->slots[evict].method_hash = method_hash;
entry->slots[evict].method = method; entry->slots[evict].method = method;
entry->slots[evict].hit_count = 0;
entry->lru = (uint8_t)evict; entry->lru = (uint8_t)evict;
} }
-1
View File
@@ -13,7 +13,6 @@ typedef struct {
uint32_t class_hash; uint32_t class_hash;
uint32_t method_hash; uint32_t method_hash;
RavaMethod_t* method; RavaMethod_t* method;
uint64_t hit_count;
} MethodCacheSlot_t; } MethodCacheSlot_t;
typedef struct { typedef struct {
-19
View File
@@ -157,23 +157,4 @@ static inline bool rava_nanbox_to_bool(RavaNanboxValue_t v) {
return true; return true;
} }
#define RAVA_NANBOX_BOTH_INT(a, b) (((a | b) & RAVA_TAG_MASK) == RAVA_TAG_LONG)
#define RAVA_NANBOX_BOTH_LONG(a, b) (((a | b) & RAVA_TAG_MASK) == RAVA_TAG_LONG)
static inline int64_t rava_nanbox_as_int_unchecked(RavaNanboxValue_t v) {
int64_t payload = (int64_t)(v & RAVA_PAYLOAD_MASK);
if (payload & 0x800000000000ULL) {
payload |= (int64_t)0xFFFF000000000000ULL;
}
return payload;
}
static inline int64_t rava_nanbox_as_long_unchecked(RavaNanboxValue_t v) {
int64_t payload = (int64_t)(v & RAVA_PAYLOAD_MASK);
if (payload & 0x800000000000ULL) {
payload |= (int64_t)0xFFFF000000000000ULL;
}
return payload;
}
#endif #endif
+610 -1068
View File
File diff suppressed because it is too large Load Diff
+2 -77
View File
@@ -32,8 +32,7 @@ typedef enum {
RAVA_VAL_HASHMAP, RAVA_VAL_HASHMAP,
RAVA_VAL_SOCKET, RAVA_VAL_SOCKET,
RAVA_VAL_STREAM, RAVA_VAL_STREAM,
RAVA_VAL_METHOD_REF, RAVA_VAL_METHOD_REF
RAVA_VAL_INETADDRESS
} RavaValueType_e; } RavaValueType_e;
typedef struct { typedef struct {
@@ -50,7 +49,6 @@ typedef struct RavaHashMap_t RavaHashMap_t;
typedef struct RavaSocket_t RavaSocket_t; typedef struct RavaSocket_t RavaSocket_t;
typedef struct RavaStream_t RavaStream_t; typedef struct RavaStream_t RavaStream_t;
typedef struct RavaMethodRef_t RavaMethodRef_t; typedef struct RavaMethodRef_t RavaMethodRef_t;
typedef struct RavaInetAddress_t RavaInetAddress_t;
#define RAVA_OBJECT_HASH_SIZE 32 #define RAVA_OBJECT_HASH_SIZE 32
@@ -81,7 +79,6 @@ struct RavaValue_t {
RavaSocket_t *socket_val; RavaSocket_t *socket_val;
RavaStream_t *stream_val; RavaStream_t *stream_val;
RavaMethodRef_t *method_ref_val; RavaMethodRef_t *method_ref_val;
RavaInetAddress_t *inetaddress_val;
} data; } data;
}; };
@@ -99,9 +96,9 @@ struct RavaArrayList_t {
#define RAVA_HASHMAP_BUCKET_SIZE 32 #define RAVA_HASHMAP_BUCKET_SIZE 32
typedef struct { typedef struct {
bool occupied;
char *key; char *key;
RavaValue_t value; RavaValue_t value;
bool occupied;
} RavaHashMapEntry_t; } RavaHashMapEntry_t;
struct RavaHashMap_t { struct RavaHashMap_t {
@@ -121,9 +118,6 @@ struct RavaSocket_t {
int fd; int fd;
bool connected; bool connected;
bool closed; bool closed;
bool bound;
bool input_shutdown;
bool output_shutdown;
}; };
#define RAVA_STREAM_TYPE_INPUT 1 #define RAVA_STREAM_TYPE_INPUT 1
@@ -146,17 +140,6 @@ struct RavaMethodRef_t {
bool has_target; bool has_target;
}; };
#define RAVA_INETADDRESS_IPV4 1
#define RAVA_INETADDRESS_IPV6 2
struct RavaInetAddress_t {
RavaGCHeader_t gc;
int address_type;
uint8_t address[16];
char *hostname;
char *hostaddress;
};
typedef struct { typedef struct {
RavaValue_t *values; RavaValue_t *values;
size_t capacity; size_t capacity;
@@ -382,63 +365,6 @@ int rava_stream_read_byte(RavaStream_t *stream);
void rava_stream_write(RavaStream_t *stream, const char *data); void rava_stream_write(RavaStream_t *stream, const char *data);
void rava_stream_write_byte(RavaStream_t *stream, int byte); void rava_stream_write_byte(RavaStream_t *stream, int byte);
void rava_stream_close(RavaStream_t *stream); void rava_stream_close(RavaStream_t *stream);
int rava_stream_read_bytes(RavaStream_t *stream, RavaArray_t *arr, int off, int len);
int rava_stream_available(RavaStream_t *stream);
void rava_stream_flush(RavaStream_t *stream);
long rava_stream_skip(RavaStream_t *stream, long n);
RavaInetAddress_t* rava_inetaddress_create(void);
RavaInetAddress_t* rava_inetaddress_get_by_name(const char *host);
RavaInetAddress_t* rava_inetaddress_get_local_host(void);
RavaInetAddress_t* rava_inetaddress_get_loopback(void);
char* rava_inetaddress_get_host_name(RavaInetAddress_t *addr);
char* rava_inetaddress_get_host_address(RavaInetAddress_t *addr);
bool rava_inetaddress_is_loopback(RavaInetAddress_t *addr);
bool rava_inetaddress_is_any_local(RavaInetAddress_t *addr);
RavaArray_t* rava_inetaddress_get_all_by_name(const char *host);
RavaArray_t* rava_inetaddress_get_address(RavaInetAddress_t *addr);
bool rava_inetaddress_is_multicast_address(RavaInetAddress_t *addr);
bool rava_inetaddress_is_reachable(RavaInetAddress_t *addr, int timeout);
int rava_socket_get_port(RavaSocket_t *socket);
int rava_socket_get_local_port(RavaSocket_t *socket);
RavaInetAddress_t* rava_socket_get_inet_address(RavaSocket_t *socket);
RavaInetAddress_t* rava_socket_get_local_address(RavaSocket_t *socket);
int rava_server_socket_get_local_port(RavaSocket_t *socket);
bool rava_server_socket_is_bound(RavaSocket_t *socket);
bool rava_server_socket_is_closed(RavaSocket_t *socket);
void rava_server_socket_set_so_timeout(RavaSocket_t *socket, int timeout);
int rava_server_socket_get_so_timeout(RavaSocket_t *socket);
void rava_server_socket_set_receive_buffer_size(RavaSocket_t *socket, int size);
int rava_server_socket_get_receive_buffer_size(RavaSocket_t *socket);
void rava_server_socket_set_reuse_address(RavaSocket_t *socket, bool reuse);
bool rava_server_socket_get_reuse_address(RavaSocket_t *socket);
void rava_socket_set_so_timeout(RavaSocket_t *socket, int timeout_ms);
int rava_socket_get_so_timeout(RavaSocket_t *socket);
void rava_socket_set_tcp_nodelay(RavaSocket_t *socket, bool nodelay);
bool rava_socket_get_tcp_nodelay(RavaSocket_t *socket);
void rava_socket_bind(RavaSocket_t *socket, const char *host, int port);
bool rava_socket_is_connected(RavaSocket_t *socket);
bool rava_socket_is_closed(RavaSocket_t *socket);
bool rava_socket_is_bound(RavaSocket_t *socket);
void rava_socket_shutdown_input(RavaSocket_t *socket);
void rava_socket_shutdown_output(RavaSocket_t *socket);
bool rava_socket_is_input_shutdown(RavaSocket_t *socket);
bool rava_socket_is_output_shutdown(RavaSocket_t *socket);
void rava_socket_set_send_buffer_size(RavaSocket_t *socket, int size);
int rava_socket_get_send_buffer_size(RavaSocket_t *socket);
void rava_socket_set_receive_buffer_size(RavaSocket_t *socket, int size);
int rava_socket_get_receive_buffer_size(RavaSocket_t *socket);
void rava_socket_set_keep_alive(RavaSocket_t *socket, bool keepalive);
bool rava_socket_get_keep_alive(RavaSocket_t *socket);
void rava_socket_set_reuse_address(RavaSocket_t *socket, bool reuse);
bool rava_socket_get_reuse_address(RavaSocket_t *socket);
static inline RavaValue_t rava_value_inetaddress(RavaInetAddress_t *addr) {
RavaValue_t val;
val.type = RAVA_VAL_INETADDRESS;
val.data.inetaddress_val = addr;
return val;
}
static inline RavaValue_t rava_value_socket(RavaSocket_t *socket) { static inline RavaValue_t rava_value_socket(RavaSocket_t *socket) {
RavaValue_t val; RavaValue_t val;
@@ -511,7 +437,6 @@ RavaValue_t rava_native_to_value(RavaNativeValue_t native);
#define RAVA_GC_TYPE_SOCKET 6 #define RAVA_GC_TYPE_SOCKET 6
#define RAVA_GC_TYPE_STREAM 7 #define RAVA_GC_TYPE_STREAM 7
#define RAVA_GC_TYPE_METHODREF 8 #define RAVA_GC_TYPE_METHODREF 8
#define RAVA_GC_TYPE_INETADDRESS 9
void rava_gc_init(void); void rava_gc_init(void);
void rava_gc_shutdown(void); void rava_gc_shutdown(void);
-16
View File
@@ -101,19 +101,3 @@ size_t rava_array_length(RavaArray_t *array) {
if (!array) return 0; if (!array) return 0;
return array->length; return array->length;
} }
static inline void rava_array_set_int_unchecked(RavaArray_t *array, size_t index, int64_t value) {
((int64_t*)array->data)[index] = value;
}
static inline int64_t rava_array_get_int_unchecked(RavaArray_t *array, size_t index) {
return ((int64_t*)array->data)[index];
}
static inline void rava_array_set_value_unchecked(RavaArray_t *array, size_t index, RavaValue_t value) {
((RavaValue_t*)array->data)[index] = value;
}
static inline RavaValue_t rava_array_get_value_unchecked(RavaArray_t *array, size_t index) {
return ((RavaValue_t*)array->data)[index];
}
+10 -11
View File
@@ -54,9 +54,8 @@ RavaValue_t rava_arraylist_remove(RavaArrayList_t *list, size_t index) {
return rava_value_null(); return rava_value_null();
} }
RavaValue_t removed = list->data[index]; RavaValue_t removed = list->data[index];
if (index < list->size - 1) { for (size_t i = index; i < list->size - 1; i++) {
memmove(&list->data[index], &list->data[index + 1], list->data[i] = list->data[i + 1];
(list->size - index - 1) * sizeof(RavaValue_t));
} }
list->size--; list->size--;
return removed; return removed;
@@ -125,14 +124,14 @@ void rava_hashmap_put(RavaHashMap_t *map, const char *key, RavaValue_t value) {
} }
unsigned int hash = _rava_hash_string(key); unsigned int hash = _rava_hash_string(key);
size_t index = hash & (map->bucket_count - 1); size_t index = hash % map->bucket_count;
while (map->buckets[index].occupied) { while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) { if (strcmp(map->buckets[index].key, key) == 0) {
map->buckets[index].value = value; map->buckets[index].value = value;
return; return;
} }
index = (index + 1) & (map->bucket_count - 1); index = (index + 1) % map->bucket_count;
} }
map->buckets[index].key = strdup(key); map->buckets[index].key = strdup(key);
@@ -143,14 +142,14 @@ void rava_hashmap_put(RavaHashMap_t *map, const char *key, RavaValue_t value) {
RavaValue_t rava_hashmap_get(RavaHashMap_t *map, const char *key) { RavaValue_t rava_hashmap_get(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key); unsigned int hash = _rava_hash_string(key);
size_t index = hash & (map->bucket_count - 1); size_t index = hash % map->bucket_count;
size_t start = index; size_t start = index;
while (map->buckets[index].occupied) { while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) { if (strcmp(map->buckets[index].key, key) == 0) {
return map->buckets[index].value; return map->buckets[index].value;
} }
index = (index + 1) & (map->bucket_count - 1); index = (index + 1) % map->bucket_count;
if (index == start) break; if (index == start) break;
} }
@@ -159,7 +158,7 @@ RavaValue_t rava_hashmap_get(RavaHashMap_t *map, const char *key) {
RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key) { RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key); unsigned int hash = _rava_hash_string(key);
size_t index = hash & (map->bucket_count - 1); size_t index = hash % map->bucket_count;
size_t start = index; size_t start = index;
while (map->buckets[index].occupied) { while (map->buckets[index].occupied) {
@@ -171,7 +170,7 @@ RavaValue_t rava_hashmap_remove(RavaHashMap_t *map, const char *key) {
map->size--; map->size--;
return removed; return removed;
} }
index = (index + 1) & (map->bucket_count - 1); index = (index + 1) % map->bucket_count;
if (index == start) break; if (index == start) break;
} }
@@ -184,14 +183,14 @@ size_t rava_hashmap_size(RavaHashMap_t *map) {
bool rava_hashmap_containskey(RavaHashMap_t *map, const char *key) { bool rava_hashmap_containskey(RavaHashMap_t *map, const char *key) {
unsigned int hash = _rava_hash_string(key); unsigned int hash = _rava_hash_string(key);
size_t index = hash & (map->bucket_count - 1); size_t index = hash % map->bucket_count;
size_t start = index; size_t start = index;
while (map->buckets[index].occupied) { while (map->buckets[index].occupied) {
if (strcmp(map->buckets[index].key, key) == 0) { if (strcmp(map->buckets[index].key, key) == 0) {
return true; return true;
} }
index = (index + 1) & (map->bucket_count - 1); index = (index + 1) % map->bucket_count;
if (index == start) break; if (index == start) break;
} }
-23
View File
@@ -1,23 +0,0 @@
#include "runtime_internal.h"
RavaExceptionStack_t* rava_exception_stack_create(void) {
RavaExceptionStack_t *stack = calloc(1, sizeof(RavaExceptionStack_t));
if (!stack) return NULL;
stack->count = 0;
return stack;
}
void rava_exception_stack_destroy(RavaExceptionStack_t *stack) {
free(stack);
}
void rava_exception_stack_push(RavaExceptionStack_t *stack, RavaExceptionHandler_t handler) {
if (stack->count >= RAVA_MAX_EXCEPTION_DEPTH) return;
stack->handlers[stack->count++] = handler;
}
bool rava_exception_stack_pop(RavaExceptionStack_t *stack, RavaExceptionHandler_t *handler) {
if (stack->count == 0) return false;
*handler = stack->handlers[--stack->count];
return true;
}
-25
View File
@@ -1,25 +0,0 @@
#include "runtime_internal.h"
const char* _rava_intern_string(RavaVM_t *vm, const char *str) {
uint32_t h = _intern_hash(str);
for (size_t i = 0; i < RAVA_INTERN_TABLE_SIZE; i++) {
size_t idx = (h + i) & (RAVA_INTERN_TABLE_SIZE - 1);
if (vm->intern_table.strings[idx] == NULL) {
if (vm->intern_table.count >= RAVA_INTERN_TABLE_SIZE - 1) {
static bool warned = false;
if (!warned) {
fprintf(stderr, "Warning: String intern table full (%d entries)\n",
RAVA_INTERN_TABLE_SIZE);
warned = true;
}
}
vm->intern_table.strings[idx] = strdup(str);
vm->intern_table.count++;
return vm->intern_table.strings[idx];
}
if (strcmp(vm->intern_table.strings[idx], str) == 0) {
return vm->intern_table.strings[idx];
}
}
return strdup(str);
}
-177
View File
@@ -1,177 +0,0 @@
#ifndef RAVA_RUNTIME_INTERNAL_H
#define RAVA_RUNTIME_INTERNAL_H
#define _POSIX_C_SOURCE 200809L
#include "runtime.h"
#include "labeltable.h"
#include "methodcache.h"
#include "nanbox.h"
#include "fastframe.h"
#include "superinst.h"
#include "../utils/safe_alloc.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
#ifdef __GNUC__
#define LIKELY(x) __builtin_expect(!!(x), 1)
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif
#define STACK_ENSURE_CAPACITY(stack) do { \
if ((stack)->top >= (stack)->capacity) { \
(stack)->capacity *= 2; \
RavaValue_t *_new_values = realloc((stack)->values, sizeof(RavaValue_t) * (stack)->capacity); \
if (_new_values) (stack)->values = _new_values; \
} \
} while(0)
#define STACK_PUSH(stack, val) do { \
STACK_ENSURE_CAPACITY(stack); \
(stack)->values[(stack)->top++] = (val); \
} while(0)
#define STACK_POP(stack) ((stack)->top > 0 ? (stack)->values[--(stack)->top] : (RavaValue_t){0})
#define STACK_PEEK(stack) ((stack)->top > 0 ? (stack)->values[(stack)->top - 1] : (RavaValue_t){0})
#define STACK_PUSH_INT(stack, v) do { \
STACK_ENSURE_CAPACITY(stack); \
RavaValue_t _v; _v.type = RAVA_VAL_INT; _v.data.int_val = (v); \
(stack)->values[(stack)->top++] = _v; \
} while(0)
#define STACK_PUSH_LONG(stack, v) do { \
STACK_ENSURE_CAPACITY(stack); \
RavaValue_t _v; _v.type = RAVA_VAL_LONG; _v.data.long_val = (v); \
(stack)->values[(stack)->top++] = _v; \
} while(0)
#define STACK_PUSH_BOOL(stack, v) do { \
STACK_ENSURE_CAPACITY(stack); \
RavaValue_t _v; _v.type = RAVA_VAL_BOOLEAN; _v.data.bool_val = (v); \
(stack)->values[(stack)->top++] = _v; \
} while(0)
#define VALUE_IS_INT(v) ((v).type == RAVA_VAL_INT)
#define VALUE_IS_LONG(v) ((v).type == RAVA_VAL_LONG)
#define VALUE_AS_INT_FAST(v) ((v).data.int_val)
#define VALUE_AS_LONG_FAST(v) ((v).data.long_val)
static inline RavaNanboxValue_t rava_value_to_nanbox(RavaValue_t val) {
switch (val.type) {
case RAVA_VAL_INT: return rava_nanbox_int(val.data.int_val);
case RAVA_VAL_LONG: return rava_nanbox_long(val.data.long_val);
case RAVA_VAL_DOUBLE: return rava_nanbox_double(val.data.double_val);
case RAVA_VAL_FLOAT: return rava_nanbox_double((double)val.data.float_val);
case RAVA_VAL_BOOLEAN: return rava_nanbox_bool(val.data.bool_val);
case RAVA_VAL_NULL: return rava_nanbox_null();
case RAVA_VAL_STRING: return rava_nanbox_string(val.data.string_val);
case RAVA_VAL_OBJECT: return rava_nanbox_object(val.data.object_val);
case RAVA_VAL_ARRAY: return rava_nanbox_array(val.data.array_val);
default: return rava_nanbox_null();
}
}
static inline RavaValue_t rava_nanbox_to_value(RavaNanboxValue_t nb) {
RavaValue_t val;
if (rava_nanbox_is_int(nb)) {
val.type = RAVA_VAL_INT;
val.data.int_val = rava_nanbox_as_int(nb);
} else if (rava_nanbox_is_long(nb)) {
val.type = RAVA_VAL_LONG;
val.data.long_val = rava_nanbox_as_long(nb);
} else if (rava_nanbox_is_double(nb)) {
val.type = RAVA_VAL_DOUBLE;
val.data.double_val = rava_nanbox_as_double(nb);
} else if (rava_nanbox_is_bool(nb)) {
val.type = RAVA_VAL_BOOLEAN;
val.data.bool_val = rava_nanbox_as_bool(nb);
} else if (rava_nanbox_is_null(nb)) {
val.type = RAVA_VAL_NULL;
val.data.object_val = NULL;
} else if (rava_nanbox_is_string(nb)) {
val.type = RAVA_VAL_STRING;
val.data.string_val = (char*)rava_nanbox_as_string(nb);
} else if (rava_nanbox_is_object(nb)) {
val.type = RAVA_VAL_OBJECT;
val.data.object_val = rava_nanbox_as_object(nb);
} else if (rava_nanbox_is_array(nb)) {
val.type = RAVA_VAL_ARRAY;
val.data.array_val = rava_nanbox_as_array(nb);
} else {
val.type = RAVA_VAL_NULL;
val.data.object_val = NULL;
}
return val;
}
static inline uint32_t _rava_field_hash(const char *name) {
uint32_t hash = 5381;
while (*name) {
hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
}
return hash;
}
static inline uint32_t _rava_class_hash(const char *name) {
uint32_t hash = 5381;
while (*name) hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
return hash & (RAVA_CLASS_HASH_SIZE - 1);
}
static inline uint32_t _rava_method_hash(const char *name) {
uint32_t hash = 5381;
while (*name) hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
return hash & (RAVA_METHOD_HASH_SIZE - 1);
}
static inline uint32_t _rava_static_hash(const char *class_name, const char *field_name) {
uint32_t hash = 5381;
while (*class_name) hash = ((hash << 5) + hash) ^ (uint32_t)*class_name++;
hash = ((hash << 5) + hash) ^ (uint32_t)'.';
while (*field_name) hash = ((hash << 5) + hash) ^ (uint32_t)*field_name++;
return hash;
}
static inline uint32_t _intern_hash(const char *str) {
uint32_t hash = 5381;
while (*str) hash = ((hash << 5) + hash) ^ (uint32_t)*str++;
return hash;
}
char* _rava_get_string_buffer(RavaVM_t *vm, size_t needed);
const char* _rava_intern_string(RavaVM_t *vm, const char *str);
void _rava_object_set_field_vm(RavaObject_t *obj, const char *name, RavaValue_t value, RavaVM_t *vm);
RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name);
bool _rava_vm_instanceof(RavaVM_t *vm, const char *object_class, const char *target_class);
RavaMethod_t* _rava_vm_find_method(RavaVM_t *vm, const char *class_name, const char *method_name);
RavaMethod_t* _rava_vm_find_method_cached(RavaVM_t *vm, const char *class_name, const char *method_name);
RavaMethod_t* _rava_vm_find_method_overload(RavaVM_t *vm, const char *class_name, const char *method_name, RavaValue_t *args, size_t arg_count);
RavaMethod_t* _rava_vm_find_method_overload_nb(RavaVM_t *vm, const char *class_name, const char *method_name, RavaNanboxValue_t *args, size_t arg_count);
RavaStaticFieldTable_t* rava_static_field_table_create(void);
void rava_static_field_table_destroy(RavaStaticFieldTable_t *table);
RavaValue_t* rava_static_field_table_get(RavaStaticFieldTable_t *table, const char *class_name, const char *field_name);
void rava_static_field_table_set(RavaStaticFieldTable_t *table, const char *class_name, const char *field_name, RavaValue_t value);
RavaExceptionStack_t* rava_exception_stack_create(void);
void rava_exception_stack_destroy(RavaExceptionStack_t *stack);
void rava_exception_stack_push(RavaExceptionStack_t *stack, RavaExceptionHandler_t handler);
bool rava_exception_stack_pop(RavaExceptionStack_t *stack, RavaExceptionHandler_t *handler);
bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, RavaInstruction_t *instr);
bool _rava_vm_execute_fast(RavaVM_t *vm, RavaCallFrame_t *frame);
bool _rava_vm_execute_ultrafast(RavaVM_t *vm, RavaMethod_t *entry_method);
bool _rava_vm_run_static_initializers(RavaVM_t *vm);
extern bool g_gc_initialized;
#endif
-146
View File
@@ -1,146 +0,0 @@
#include "runtime_internal.h"
bool g_gc_initialized = false;
RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name) {
uint32_t h = _rava_class_hash(class_name);
int idx = vm->class_hash[h];
if (idx >= 0 && (size_t)idx < vm->program->class_count &&
strcmp(vm->program->classes[idx]->name, class_name) == 0) {
return vm->program->classes[idx];
}
for (size_t i = 0; i < vm->program->class_count; i++) {
if (strcmp(vm->program->classes[i]->name, class_name) == 0) {
vm->class_hash[h] = (int)i;
return vm->program->classes[i];
}
}
return NULL;
}
bool _rava_vm_instanceof(RavaVM_t *vm, const char *object_class, const char *target_class) {
if (!object_class || !target_class) return false;
if (strcmp(object_class, target_class) == 0) return true;
const char *current = object_class;
while (current) {
RavaClass_t *cls = _rava_vm_find_class(vm, current);
if (!cls) break;
if (cls->superclass && strcmp(cls->superclass, target_class) == 0) return true;
current = cls->superclass;
}
return false;
}
static bool _rava_vm_method_signature_matches(RavaMethod_t *method, RavaValue_t *args, size_t arg_count) {
if (!method) return false;
if (method->param_count != arg_count) return false;
for (size_t i = 0; i < arg_count; i++) {
RavaValue_t arg = args[i];
RavaType_t *param_type = method->param_types[i];
RavaType_t *arg_type = NULL;
switch (arg.type) {
case RAVA_VAL_INT:
arg_type = rava_type_create_primitive(RAVA_TYPE_INT);
break;
case RAVA_VAL_LONG:
arg_type = rava_type_create_primitive(RAVA_TYPE_LONG);
break;
case RAVA_VAL_DOUBLE:
arg_type = rava_type_create_primitive(RAVA_TYPE_DOUBLE);
break;
case RAVA_VAL_FLOAT:
arg_type = rava_type_create_primitive(RAVA_TYPE_FLOAT);
break;
case RAVA_VAL_BOOLEAN:
arg_type = rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
break;
case RAVA_VAL_CHAR:
arg_type = rava_type_create_primitive(RAVA_TYPE_CHAR);
break;
case RAVA_VAL_OBJECT:
case RAVA_VAL_STRING:
case RAVA_VAL_ARRAY:
arg_type = rava_type_create_primitive(RAVA_TYPE_CLASS);
break;
default:
arg_type = NULL;
break;
}
bool assignable = arg_type && rava_type_is_assignable_to(arg_type, param_type);
if (arg_type && arg_type->kind != RAVA_TYPE_CLASS) {
rava_type_destroy(arg_type);
}
if (!assignable) return false;
}
return true;
}
RavaMethod_t* _rava_vm_find_method(RavaVM_t *vm, const char *class_name, const char *method_name) {
const char *current_class = class_name;
while (current_class) {
RavaClass_t *class = _rava_vm_find_class(vm, current_class);
if (!class) break;
uint32_t h = _rava_method_hash(method_name);
int idx = class->method_hash[h];
if (idx >= 0 && (size_t)idx < class->method_count &&
strcmp(class->methods[idx]->name, method_name) == 0) {
return class->methods[idx];
}
for (size_t j = 0; j < class->method_count; j++) {
if (strcmp(class->methods[j]->name, method_name) == 0) {
class->method_hash[h] = (int)j;
return class->methods[j];
}
}
current_class = class->superclass;
}
return NULL;
}
RavaMethod_t* _rava_vm_find_method_overload(RavaVM_t *vm, const char *class_name, const char *method_name, RavaValue_t *args, size_t arg_count) {
const char *current_class = class_name;
while (current_class) {
RavaClass_t *class = _rava_vm_find_class(vm, current_class);
if (!class) break;
RavaMethod_t *best_match = NULL;
for (size_t j = 0; j < class->method_count; j++) {
if (strcmp(class->methods[j]->name, method_name) == 0) {
if (_rava_vm_method_signature_matches(class->methods[j], args, arg_count)) {
best_match = class->methods[j];
break;
}
}
}
if (best_match) return best_match;
current_class = class->superclass;
}
return NULL;
}
RavaMethod_t* _rava_vm_find_method_cached(RavaVM_t *vm, const char *class_name, const char *method_name) {
MethodCache_t *cache = (MethodCache_t*)vm->method_cache;
RavaMethod_t *cached = rava_methodcache_lookup(cache, class_name, method_name);
if (cached) return cached;
RavaMethod_t *method = _rava_vm_find_method(vm, class_name, method_name);
if (method) {
rava_methodcache_insert(cache, class_name, method_name, method);
}
return method;
}
RavaMethod_t* _rava_vm_find_method_overload_nb(RavaVM_t *vm, const char *class_name, const char *method_name, RavaNanboxValue_t *args, size_t arg_count) {
if (arg_count == 0) {
return _rava_vm_find_method_overload(vm, class_name, method_name, NULL, 0);
}
RavaValue_t converted_args[16];
size_t count = arg_count > 16 ? 16 : arg_count;
for (size_t i = 0; i < count; i++) {
converted_args[i] = rava_nanbox_to_value(args[i]);
}
return _rava_vm_find_method_overload(vm, class_name, method_name, converted_args, count);
}
-11
View File
@@ -178,8 +178,6 @@ int32_t rava_object_hashcode(RavaValue_t value) {
return (int32_t)((uintptr_t)value.data.socket_val >> 3); return (int32_t)((uintptr_t)value.data.socket_val >> 3);
case RAVA_VAL_STREAM: case RAVA_VAL_STREAM:
return (int32_t)((uintptr_t)value.data.stream_val >> 3); return (int32_t)((uintptr_t)value.data.stream_val >> 3);
case RAVA_VAL_INETADDRESS:
return (int32_t)((uintptr_t)value.data.inetaddress_val >> 3);
case RAVA_VAL_METHOD_REF: case RAVA_VAL_METHOD_REF:
return (int32_t)((uintptr_t)value.data.method_ref_val >> 3); return (int32_t)((uintptr_t)value.data.method_ref_val >> 3);
} }
@@ -289,13 +287,6 @@ char* rava_object_tostring(RavaValue_t value) {
snprintf(buffer, 128, "Stream@%x", snprintf(buffer, 128, "Stream@%x",
(unsigned int)((uintptr_t)value.data.stream_val >> 3)); (unsigned int)((uintptr_t)value.data.stream_val >> 3));
break; break;
case RAVA_VAL_INETADDRESS:
if (value.data.inetaddress_val && value.data.inetaddress_val->hostaddress) {
snprintf(buffer, 128, "/%s", value.data.inetaddress_val->hostaddress);
} else {
strcpy(buffer, "/null");
}
break;
case RAVA_VAL_METHOD_REF: case RAVA_VAL_METHOD_REF:
if (value.data.method_ref_val) { if (value.data.method_ref_val) {
snprintf(buffer, 128, "%s::%s", snprintf(buffer, 128, "%s::%s",
@@ -342,8 +333,6 @@ const char* rava_object_getclass(RavaValue_t value) {
return "Socket"; return "Socket";
case RAVA_VAL_STREAM: case RAVA_VAL_STREAM:
return "Stream"; return "Stream";
case RAVA_VAL_INETADDRESS:
return "InetAddress";
case RAVA_VAL_METHOD_REF: case RAVA_VAL_METHOD_REF:
return "MethodReference"; return "MethodReference";
} }
-614
View File
@@ -9,14 +9,6 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <errno.h> #include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <netinet/tcp.h>
#include <fcntl.h>
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif
RavaSocket_t* rava_socket_create(void) { RavaSocket_t* rava_socket_create(void) {
RavaSocket_t *sock = rava_gc_alloc(sizeof(RavaSocket_t), RAVA_GC_TYPE_SOCKET); RavaSocket_t *sock = rava_gc_alloc(sizeof(RavaSocket_t), RAVA_GC_TYPE_SOCKET);
@@ -70,8 +62,6 @@ RavaSocket_t* rava_server_socket_create(int port) {
return sock; return sock;
} }
sock->bound = true;
if (listen(sock->fd, 10) < 0) { if (listen(sock->fd, 10) < 0) {
close(sock->fd); close(sock->fd);
sock->fd = -1; sock->fd = -1;
@@ -214,607 +204,3 @@ void rava_stream_close(RavaStream_t *stream) {
if (!stream) return; if (!stream) return;
stream->closed = true; stream->closed = true;
} }
int rava_stream_read_bytes(RavaStream_t *stream, RavaArray_t *arr, int off, int len) {
if (!stream || stream->closed || stream->fd < 0) return -1;
if (stream->stream_type != RAVA_STREAM_TYPE_INPUT) return -1;
if (!arr || off < 0 || len <= 0) return -1;
if ((size_t)(off + len) > arr->length) return -1;
char *buffer = malloc(len);
if (!buffer) return -1;
ssize_t bytes_read = read(stream->fd, buffer, len);
if (bytes_read <= 0) {
free(buffer);
return -1;
}
for (ssize_t i = 0; i < bytes_read; i++) {
rava_array_set_value(arr, off + i, rava_value_int((unsigned char)buffer[i]));
}
free(buffer);
return (int)bytes_read;
}
int rava_stream_available(RavaStream_t *stream) {
if (!stream || stream->closed || stream->fd < 0) return 0;
if (stream->stream_type != RAVA_STREAM_TYPE_INPUT) return 0;
int available = 0;
if (ioctl(stream->fd, FIONREAD, &available) < 0) {
return 0;
}
return available;
}
void rava_stream_flush(RavaStream_t *stream) {
if (!stream || stream->closed || stream->fd < 0) return;
if (stream->stream_type != RAVA_STREAM_TYPE_OUTPUT) return;
fsync(stream->fd);
}
long rava_stream_skip(RavaStream_t *stream, long n) {
if (!stream || stream->closed || stream->fd < 0) return 0;
if (stream->stream_type != RAVA_STREAM_TYPE_INPUT) return 0;
if (n <= 0) return 0;
long skipped = 0;
char buffer[1024];
while (skipped < n) {
long to_read = (n - skipped > 1024) ? 1024 : (n - skipped);
ssize_t read_count = read(stream->fd, buffer, (size_t)to_read);
if (read_count <= 0) break;
skipped += read_count;
}
return skipped;
}
RavaInetAddress_t* rava_inetaddress_create(void) {
RavaInetAddress_t *addr = rava_gc_alloc(sizeof(RavaInetAddress_t), RAVA_GC_TYPE_INETADDRESS);
if (!addr) return NULL;
memset((char*)addr + sizeof(RavaGCHeader_t), 0, sizeof(RavaInetAddress_t) - sizeof(RavaGCHeader_t));
addr->address_type = RAVA_INETADDRESS_IPV4;
return addr;
}
RavaInetAddress_t* rava_inetaddress_get_by_name(const char *host) {
if (!host) return NULL;
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int status = getaddrinfo(host, NULL, &hints, &res);
if (status != 0) return NULL;
RavaInetAddress_t *addr = rava_inetaddress_create();
if (!addr) {
freeaddrinfo(res);
return NULL;
}
addr->hostname = strdup(host);
if (res->ai_family == AF_INET) {
addr->address_type = RAVA_INETADDRESS_IPV4;
struct sockaddr_in *ipv4 = (struct sockaddr_in*)res->ai_addr;
memcpy(addr->address, &ipv4->sin_addr, 4);
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ipv4->sin_addr, ip, sizeof(ip));
addr->hostaddress = strdup(ip);
} else if (res->ai_family == AF_INET6) {
addr->address_type = RAVA_INETADDRESS_IPV6;
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)res->ai_addr;
memcpy(addr->address, &ipv6->sin6_addr, 16);
char ip[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &ipv6->sin6_addr, ip, sizeof(ip));
addr->hostaddress = strdup(ip);
}
freeaddrinfo(res);
return addr;
}
RavaInetAddress_t* rava_inetaddress_get_local_host(void) {
char hostname[256];
if (gethostname(hostname, sizeof(hostname)) != 0) {
return rava_inetaddress_get_loopback();
}
RavaInetAddress_t *addr = rava_inetaddress_get_by_name(hostname);
if (!addr) {
return rava_inetaddress_get_loopback();
}
return addr;
}
RavaInetAddress_t* rava_inetaddress_get_loopback(void) {
RavaInetAddress_t *addr = rava_inetaddress_create();
if (!addr) return NULL;
addr->address_type = RAVA_INETADDRESS_IPV4;
addr->address[0] = 127;
addr->address[1] = 0;
addr->address[2] = 0;
addr->address[3] = 1;
addr->hostname = strdup("localhost");
addr->hostaddress = strdup("127.0.0.1");
return addr;
}
char* rava_inetaddress_get_host_name(RavaInetAddress_t *addr) {
if (!addr) return NULL;
if (addr->hostname) return addr->hostname;
char host[NI_MAXHOST];
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
memcpy(&sa.sin_addr, addr->address, 4);
int result = getnameinfo((struct sockaddr*)&sa, sizeof(sa), host, sizeof(host), NULL, 0, 0);
if (result == 0) {
addr->hostname = strdup(host);
return addr->hostname;
}
return addr->hostaddress;
}
char* rava_inetaddress_get_host_address(RavaInetAddress_t *addr) {
if (!addr) return NULL;
if (addr->hostaddress) return addr->hostaddress;
char ip[INET6_ADDRSTRLEN];
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
inet_ntop(AF_INET, addr->address, ip, sizeof(ip));
} else {
inet_ntop(AF_INET6, addr->address, ip, sizeof(ip));
}
addr->hostaddress = strdup(ip);
return addr->hostaddress;
}
bool rava_inetaddress_is_loopback(RavaInetAddress_t *addr) {
if (!addr) return false;
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
return addr->address[0] == 127;
}
static const uint8_t ipv6_loopback[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
return memcmp(addr->address, ipv6_loopback, 16) == 0;
}
bool rava_inetaddress_is_any_local(RavaInetAddress_t *addr) {
if (!addr) return false;
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
return addr->address[0] == 0 && addr->address[1] == 0 &&
addr->address[2] == 0 && addr->address[3] == 0;
}
static const uint8_t ipv6_any[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
return memcmp(addr->address, ipv6_any, 16) == 0;
}
RavaArray_t* rava_inetaddress_get_all_by_name(const char *host) {
if (!host) return NULL;
struct addrinfo hints, *res, *p;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(host, NULL, &hints, &res) != 0) {
return NULL;
}
size_t count = 0;
for (p = res; p != NULL; p = p->ai_next) {
count++;
}
RavaArray_t *array = rava_gc_alloc(sizeof(RavaArray_t), RAVA_GC_TYPE_ARRAY);
if (!array) {
freeaddrinfo(res);
return NULL;
}
array->length = count;
array->element_type = RAVA_VAL_INETADDRESS;
array->data = calloc(count, sizeof(RavaValue_t));
if (!array->data && count > 0) {
freeaddrinfo(res);
return NULL;
}
RavaValue_t *values = (RavaValue_t *)array->data;
size_t i = 0;
for (p = res; p != NULL; p = p->ai_next) {
RavaInetAddress_t *addr = rava_inetaddress_create();
if (addr) {
if (p->ai_family == AF_INET) {
addr->address_type = RAVA_INETADDRESS_IPV4;
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
memcpy(addr->address, &ipv4->sin_addr, 4);
} else if (p->ai_family == AF_INET6) {
addr->address_type = RAVA_INETADDRESS_IPV6;
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
memcpy(addr->address, &ipv6->sin6_addr, 16);
}
addr->hostname = host ? strdup(host) : NULL;
values[i] = rava_value_inetaddress(addr);
}
i++;
}
freeaddrinfo(res);
return array;
}
RavaArray_t* rava_inetaddress_get_address(RavaInetAddress_t *addr) {
if (!addr) return NULL;
size_t len = (addr->address_type == RAVA_INETADDRESS_IPV4) ? 4 : 16;
RavaArray_t *array = rava_gc_alloc(sizeof(RavaArray_t), RAVA_GC_TYPE_ARRAY);
if (!array) return NULL;
array->length = len;
array->element_type = RAVA_VAL_INT;
array->data = calloc(len, sizeof(int64_t));
if (!array->data && len > 0) {
return NULL;
}
int64_t *values = (int64_t *)array->data;
for (size_t i = 0; i < len; i++) {
values[i] = addr->address[i];
}
return array;
}
bool rava_inetaddress_is_multicast_address(RavaInetAddress_t *addr) {
if (!addr) return false;
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
return (addr->address[0] >= 224 && addr->address[0] <= 239);
} else {
return addr->address[0] == 0xff;
}
}
bool rava_inetaddress_is_reachable(RavaInetAddress_t *addr, int timeout) {
if (!addr) return false;
int sock = socket(addr->address_type == RAVA_INETADDRESS_IPV4 ? AF_INET : AF_INET6, SOCK_STREAM, 0);
if (sock < 0) return false;
struct timeval tv;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
fcntl(sock, F_SETFL, O_NONBLOCK);
bool result = false;
if (addr->address_type == RAVA_INETADDRESS_IPV4) {
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(7);
memcpy(&sa.sin_addr, addr->address, 4);
int res = connect(sock, (struct sockaddr*)&sa, sizeof(sa));
if (res == 0 || (res < 0 && errno == EINPROGRESS)) {
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
struct timeval tv2;
tv2.tv_sec = timeout / 1000;
tv2.tv_usec = (timeout % 1000) * 1000;
if (select(sock + 1, NULL, &fdset, NULL, &tv2) > 0) {
int so_error;
socklen_t len = sizeof(so_error);
getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
result = (so_error == 0);
}
}
}
close(sock);
return result;
}
int rava_socket_get_port(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return -1;
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
if (getpeername(socket->fd, (struct sockaddr*)&addr, &len) < 0) {
return -1;
}
return ntohs(addr.sin_port);
}
int rava_socket_get_local_port(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return -1;
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
if (getsockname(socket->fd, (struct sockaddr*)&addr, &len) < 0) {
return -1;
}
return ntohs(addr.sin_port);
}
RavaInetAddress_t* rava_socket_get_inet_address(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return NULL;
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
if (getpeername(socket->fd, (struct sockaddr*)&addr, &len) < 0) {
return NULL;
}
RavaInetAddress_t *inet_addr = rava_inetaddress_create();
if (!inet_addr) return NULL;
inet_addr->address_type = RAVA_INETADDRESS_IPV4;
memcpy(inet_addr->address, &addr.sin_addr, 4);
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip));
inet_addr->hostaddress = strdup(ip);
return inet_addr;
}
RavaInetAddress_t* rava_socket_get_local_address(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return NULL;
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
if (getsockname(socket->fd, (struct sockaddr*)&addr, &len) < 0) {
return NULL;
}
RavaInetAddress_t *inet_addr = rava_inetaddress_create();
if (!inet_addr) return NULL;
inet_addr->address_type = RAVA_INETADDRESS_IPV4;
memcpy(inet_addr->address, &addr.sin_addr, 4);
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip));
inet_addr->hostaddress = strdup(ip);
return inet_addr;
}
int rava_server_socket_get_local_port(RavaSocket_t *socket) {
return rava_socket_get_local_port(socket);
}
bool rava_server_socket_is_bound(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return false;
return socket->bound;
}
bool rava_server_socket_is_closed(RavaSocket_t *socket) {
if (!socket) return true;
return socket->closed;
}
void rava_server_socket_set_so_timeout(RavaSocket_t *socket, int timeout) {
if (!socket || socket->fd < 0) return;
struct timeval tv;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
setsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
}
int rava_server_socket_get_so_timeout(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return 0;
struct timeval tv;
socklen_t len = sizeof(tv);
if (getsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
return 0;
}
return (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
void rava_server_socket_set_receive_buffer_size(RavaSocket_t *socket, int size) {
if (!socket || socket->fd < 0) return;
setsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
}
int rava_server_socket_get_receive_buffer_size(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return 0;
int size = 0;
socklen_t len = sizeof(size);
if (getsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &size, &len) == 0) {
return size;
}
return 0;
}
void rava_server_socket_set_reuse_address(RavaSocket_t *socket, bool reuse) {
if (!socket || socket->fd < 0) return;
int val = reuse ? 1 : 0;
setsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
}
bool rava_server_socket_get_reuse_address(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return false;
int val = 0;
socklen_t len = sizeof(val);
if (getsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, &len) == 0) {
return val != 0;
}
return false;
}
void rava_socket_set_so_timeout(RavaSocket_t *socket, int timeout_ms) {
if (!socket || socket->fd < 0) return;
struct timeval tv;
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
setsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
setsockopt(socket->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
}
int rava_socket_get_so_timeout(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return 0;
struct timeval tv;
socklen_t len = sizeof(tv);
if (getsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
return 0;
}
return (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
void rava_socket_set_tcp_nodelay(RavaSocket_t *socket, bool nodelay) {
if (!socket || socket->fd < 0) return;
int flag = nodelay ? 1 : 0;
setsockopt(socket->fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
}
bool rava_socket_get_tcp_nodelay(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return false;
int flag = 0;
socklen_t len = sizeof(flag);
if (getsockopt(socket->fd, IPPROTO_TCP, TCP_NODELAY, &flag, &len) < 0) {
return false;
}
return flag != 0;
}
void rava_socket_bind(RavaSocket_t *socket, const char *host, int port) {
if (!socket || socket->fd < 0) return;
if (socket->bound) return;
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (host && strcmp(host, "0.0.0.0") != 0) {
if (inet_pton(AF_INET, host, &addr.sin_addr) <= 0) {
return;
}
} else {
addr.sin_addr.s_addr = INADDR_ANY;
}
if (bind(socket->fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
socket->bound = true;
}
}
bool rava_socket_is_connected(RavaSocket_t *socket) {
if (!socket) return false;
return socket->connected && !socket->closed;
}
bool rava_socket_is_closed(RavaSocket_t *socket) {
if (!socket) return true;
return socket->closed;
}
bool rava_socket_is_bound(RavaSocket_t *socket) {
if (!socket) return false;
return socket->bound;
}
void rava_socket_shutdown_input(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return;
if (socket->input_shutdown) return;
shutdown(socket->fd, SHUT_RD);
socket->input_shutdown = true;
}
void rava_socket_shutdown_output(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return;
if (socket->output_shutdown) return;
shutdown(socket->fd, SHUT_WR);
socket->output_shutdown = true;
}
bool rava_socket_is_input_shutdown(RavaSocket_t *socket) {
if (!socket) return false;
return socket->input_shutdown;
}
bool rava_socket_is_output_shutdown(RavaSocket_t *socket) {
if (!socket) return false;
return socket->output_shutdown;
}
void rava_socket_set_send_buffer_size(RavaSocket_t *socket, int size) {
if (!socket || socket->fd < 0) return;
setsockopt(socket->fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
}
int rava_socket_get_send_buffer_size(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return 0;
int size = 0;
socklen_t len = sizeof(size);
if (getsockopt(socket->fd, SOL_SOCKET, SO_SNDBUF, &size, &len) == 0) {
return size;
}
return 0;
}
void rava_socket_set_receive_buffer_size(RavaSocket_t *socket, int size) {
if (!socket || socket->fd < 0) return;
setsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
}
int rava_socket_get_receive_buffer_size(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return 0;
int size = 0;
socklen_t len = sizeof(size);
if (getsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &size, &len) == 0) {
return size;
}
return 0;
}
void rava_socket_set_keep_alive(RavaSocket_t *socket, bool keepalive) {
if (!socket || socket->fd < 0) return;
int val = keepalive ? 1 : 0;
setsockopt(socket->fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
}
bool rava_socket_get_keep_alive(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return false;
int val = 0;
socklen_t len = sizeof(val);
if (getsockopt(socket->fd, SOL_SOCKET, SO_KEEPALIVE, &val, &len) == 0) {
return val != 0;
}
return false;
}
void rava_socket_set_reuse_address(RavaSocket_t *socket, bool reuse) {
if (!socket || socket->fd < 0) return;
int val = reuse ? 1 : 0;
setsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
}
bool rava_socket_get_reuse_address(RavaSocket_t *socket) {
if (!socket || socket->fd < 0) return false;
int val = 0;
socklen_t len = sizeof(val);
if (getsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, &len) == 0) {
return val != 0;
}
return false;
}
-127
View File
@@ -1,127 +0,0 @@
#include "runtime_internal.h"
RavaStack_t* rava_stack_create(size_t capacity) {
RavaStack_t *stack = malloc(sizeof(RavaStack_t));
if (!stack) return NULL;
stack->capacity = capacity;
stack->values = malloc(sizeof(RavaValue_t) * capacity);
if (!stack->values) {
free(stack);
return NULL;
}
stack->top = 0;
return stack;
}
void rava_stack_destroy(RavaStack_t *stack) {
if (!stack) return;
free(stack->values);
free(stack);
}
void rava_stack_push(RavaStack_t *stack, RavaValue_t value) {
if (stack->top >= stack->capacity) {
stack->capacity *= 2;
RavaValue_t *new_values = rava_safe_realloc(stack->values, sizeof(RavaValue_t) * stack->capacity);
if (!new_values) return;
stack->values = new_values;
}
stack->values[stack->top++] = value;
}
RavaValue_t rava_stack_pop(RavaStack_t *stack) {
if (stack->top == 0) {
return rava_value_int(0);
}
return stack->values[--stack->top];
}
RavaValue_t rava_stack_peek(RavaStack_t *stack) {
if (stack->top == 0) {
return rava_value_int(0);
}
return stack->values[stack->top - 1];
}
bool rava_stack_is_empty(RavaStack_t *stack) {
return stack->top == 0;
}
RavaCallFrame_t* rava_call_frame_create(RavaMethod_t *method) {
RavaCallFrame_t *frame = calloc(1, sizeof(RavaCallFrame_t));
if (!frame) return NULL;
frame->method = method;
frame->local_count = method->local_count;
frame->locals = calloc(method->local_count, sizeof(RavaValue_t));
if (!frame->locals && method->local_count > 0) {
free(frame);
return NULL;
}
frame->pc = 0;
size_t stack_size = method->max_stack > 0 ? (size_t)method->max_stack : 64;
frame->operand_stack = rava_stack_create(stack_size);
if (!frame->operand_stack) {
free(frame->locals);
free(frame);
return NULL;
}
frame->has_this = false;
frame->this_ref = rava_value_null();
return frame;
}
void rava_call_frame_destroy(RavaCallFrame_t *frame) {
if (!frame) return;
free(frame->locals);
rava_stack_destroy(frame->operand_stack);
free(frame);
}
RavaCallStack_t* rava_call_stack_create(void) {
RavaCallStack_t *stack = malloc(sizeof(RavaCallStack_t));
if (!stack) return NULL;
stack->capacity = 256;
stack->frames = malloc(sizeof(RavaCallFrame_t*) * stack->capacity);
if (!stack->frames) {
free(stack);
return NULL;
}
stack->count = 0;
return stack;
}
void rava_call_stack_destroy(RavaCallStack_t *stack) {
if (!stack) return;
for (size_t i = 0; i < stack->count; i++) {
rava_call_frame_destroy(stack->frames[i]);
}
free(stack->frames);
free(stack);
}
#define RAVA_MAX_CALL_STACK_DEPTH 10000
bool rava_call_stack_push(RavaCallStack_t *stack, RavaCallFrame_t *frame) {
if (stack->count >= RAVA_MAX_CALL_STACK_DEPTH) {
return false;
}
if (stack->count >= stack->capacity) {
stack->capacity *= 2;
RavaCallFrame_t **new_frames = rava_safe_realloc(stack->frames, sizeof(RavaCallFrame_t*) * stack->capacity);
if (!new_frames) return false;
stack->frames = new_frames;
}
stack->frames[stack->count++] = frame;
return true;
}
RavaCallFrame_t* rava_call_stack_pop(RavaCallStack_t *stack) {
if (stack->count == 0) return NULL;
RavaCallFrame_t *frame = stack->frames[--stack->count];
return frame;
}
RavaCallFrame_t* rava_call_stack_current(RavaCallStack_t *stack) {
if (stack->count == 0) return NULL;
return stack->frames[stack->count - 1];
}
-85
View File
@@ -1,85 +0,0 @@
#include "runtime_internal.h"
RavaStaticFieldTable_t* rava_static_field_table_create(void) {
RavaStaticFieldTable_t *table = malloc(sizeof(RavaStaticFieldTable_t));
if (!table) return NULL;
table->capacity = 16;
table->fields = calloc(table->capacity, sizeof(RavaStaticField_t));
if (!table->fields) {
free(table);
return NULL;
}
table->count = 0;
for (int i = 0; i < RAVA_STATIC_HASH_SIZE; i++) {
table->hash_table[i] = -1;
}
return table;
}
void rava_static_field_table_destroy(RavaStaticFieldTable_t *table) {
if (!table) return;
for (size_t i = 0; i < table->count; i++) {
free(table->fields[i].class_name);
free(table->fields[i].field_name);
}
free(table->fields);
free(table);
}
RavaValue_t* rava_static_field_table_get(RavaStaticFieldTable_t *table,
const char *class_name,
const char *field_name) {
uint32_t hash = _rava_static_hash(class_name, field_name);
for (size_t probe = 0; probe < RAVA_STATIC_HASH_SIZE; probe++) {
uint32_t slot = (hash + probe) & (RAVA_STATIC_HASH_SIZE - 1);
int idx = table->hash_table[slot];
if (idx == -1) {
return NULL;
}
if ((size_t)idx < table->count &&
strcmp(table->fields[idx].class_name, class_name) == 0 &&
strcmp(table->fields[idx].field_name, field_name) == 0) {
return &table->fields[idx].value;
}
}
return NULL;
}
void rava_static_field_table_set(RavaStaticFieldTable_t *table,
const char *class_name,
const char *field_name,
RavaValue_t value) {
uint32_t hash = _rava_static_hash(class_name, field_name);
for (size_t probe = 0; probe < RAVA_STATIC_HASH_SIZE; probe++) {
uint32_t slot = (hash + probe) & (RAVA_STATIC_HASH_SIZE - 1);
int idx = table->hash_table[slot];
if (idx == -1) {
if (table->count >= table->capacity) {
size_t new_cap = table->capacity * 2;
RavaStaticField_t *new_fields = rava_safe_realloc(table->fields, sizeof(RavaStaticField_t) * new_cap);
if (!new_fields) return;
table->fields = new_fields;
table->capacity = new_cap;
}
table->fields[table->count].class_name = strdup(class_name);
table->fields[table->count].field_name = strdup(field_name);
table->fields[table->count].value = value;
table->hash_table[slot] = (int)table->count;
table->count++;
return;
}
if ((size_t)idx < table->count &&
strcmp(table->fields[idx].class_name, class_name) == 0 &&
strcmp(table->fields[idx].field_name, field_name) == 0) {
table->fields[idx].value = value;
return;
}
}
}
-97
View File
@@ -1,97 +0,0 @@
#include "runtime_internal.h"
RavaValue_t rava_value_string(const char *str) {
RavaValue_t val;
val.type = RAVA_VAL_STRING;
val.data.string_val = str ? strdup(str) : NULL;
return val;
}
const char* rava_value_as_string(RavaValue_t value) {
if (value.type == RAVA_VAL_STRING) {
return value.data.string_val ? value.data.string_val : "";
}
return "";
}
char* _rava_get_string_buffer(RavaVM_t *vm, size_t needed) {
if (needed >= RAVA_STRING_BUFFER_SIZE) {
return malloc(needed);
}
char *buf = vm->string_pool.buffers[vm->string_pool.current];
vm->string_pool.current = (vm->string_pool.current + 1) % RAVA_STRING_BUFFER_COUNT;
return buf;
}
void _rava_object_set_field_vm(RavaObject_t *obj, const char *name, RavaValue_t value, RavaVM_t *vm) {
if (!obj || !name) return;
uint32_t hash = _rava_field_hash(name);
for (size_t probe = 0; probe < RAVA_OBJECT_HASH_SIZE; probe++) {
uint32_t idx = (hash + probe) & (RAVA_OBJECT_HASH_SIZE - 1);
int field_idx = obj->field_hash[idx];
if (field_idx == -1) {
if (obj->field_count >= obj->field_capacity) {
size_t new_cap = obj->field_capacity * 2;
char **new_names = rava_safe_realloc(obj->field_names, new_cap * sizeof(char*));
RavaValue_t *new_values = rava_safe_realloc(obj->field_values, new_cap * sizeof(RavaValue_t));
if (!new_names || !new_values) return;
obj->field_names = new_names;
obj->field_values = new_values;
obj->field_capacity = new_cap;
}
obj->field_names[obj->field_count] = (char*)(vm ? _rava_intern_string(vm, name) : strdup(name));
obj->field_values[obj->field_count] = value;
obj->field_hash[idx] = (int)obj->field_count;
obj->field_count++;
return;
}
if ((size_t)field_idx < obj->field_count &&
strcmp(obj->field_names[field_idx], name) == 0) {
obj->field_values[field_idx] = value;
return;
}
}
}
int64_t rava_value_as_int(RavaValue_t value) {
switch (value.type) {
case RAVA_VAL_INT: return value.data.int_val;
case RAVA_VAL_LONG: return value.data.long_val;
case RAVA_VAL_FLOAT: return (int64_t)value.data.float_val;
case RAVA_VAL_DOUBLE: return (int64_t)value.data.double_val;
case RAVA_VAL_BOOLEAN: return value.data.bool_val ? 1 : 0;
case RAVA_VAL_CHAR: return value.data.char_val;
default: return 0;
}
}
int64_t rava_value_as_long(RavaValue_t value) {
switch (value.type) {
case RAVA_VAL_INT: return value.data.int_val;
case RAVA_VAL_LONG: return value.data.long_val;
case RAVA_VAL_FLOAT: return (int64_t)value.data.float_val;
case RAVA_VAL_DOUBLE: return (int64_t)value.data.double_val;
default: return 0;
}
}
double rava_value_as_double(RavaValue_t value) {
switch (value.type) {
case RAVA_VAL_INT: return value.data.int_val;
case RAVA_VAL_LONG: return (double)value.data.long_val;
case RAVA_VAL_FLOAT: return value.data.float_val;
case RAVA_VAL_DOUBLE: return value.data.double_val;
default: return 0.0;
}
}
bool rava_value_as_boolean(RavaValue_t value) {
if (value.type == RAVA_VAL_BOOLEAN) {
return value.data.bool_val;
}
return rava_value_as_int(value) != 0;
}
-6
View File
@@ -269,11 +269,6 @@ static void optimize_inline_calls(RavaInstruction_t *instrs, size_t count) {
} }
} }
static void optimize_array_cmp_swap(RavaInstruction_t *instrs, size_t count) {
(void)instrs;
(void)count;
}
void rava_optimize_superinstructions(RavaMethod_t* method) { void rava_optimize_superinstructions(RavaMethod_t* method) {
if (!method || !method->instructions) return; if (!method || !method->instructions) return;
@@ -283,7 +278,6 @@ void rava_optimize_superinstructions(RavaMethod_t* method) {
optimize_constant_folding(instrs, count); optimize_constant_folding(instrs, count);
optimize_inline_calls(instrs, count); optimize_inline_calls(instrs, count);
optimize_strength_reduction(instrs, count); optimize_strength_reduction(instrs, count);
optimize_array_cmp_swap(instrs, count);
optimize_add_local_to_local(instrs, count); optimize_add_local_to_local(instrs, count);
optimize_local_lt_local_jump(instrs, count); optimize_local_lt_local_jump(instrs, count);
optimize_inc_dec_local(instrs, count); optimize_inc_dec_local(instrs, count);
+3 -81
View File
@@ -123,34 +123,14 @@ static bool _rava_semantic_analyze_method(RavaSemanticAnalyzer_t *analyzer, Rava
char *method_name = method_node->data.method_decl.name; char *method_name = method_node->data.method_decl.name;
RavaType_t *return_type = _rava_semantic_resolve_type(analyzer, method_node->data.method_decl.return_type); RavaType_t *return_type = _rava_semantic_resolve_type(analyzer, method_node->data.method_decl.return_type);
size_t param_count = 0;
for (size_t i = 0; i < method_node->children_count; i++) {
if (method_node->children[i]->type == RAVA_AST_PARAM_DECL) {
param_count++;
}
}
RavaSymbol_t *method_symbol = rava_symbol_create(RAVA_SYMBOL_METHOD, method_name, return_type); RavaSymbol_t *method_symbol = rava_symbol_create(RAVA_SYMBOL_METHOD, method_name, return_type);
method_symbol->modifiers = method_node->data.method_decl.modifiers; method_symbol->modifiers = method_node->data.method_decl.modifiers;
method_symbol->modifiers_count = method_node->data.method_decl.modifiers_count; method_symbol->modifiers_count = method_node->data.method_decl.modifiers_count;
method_symbol->declaration = method_node; method_symbol->declaration = method_node;
method_symbol->param_count = param_count;
if (param_count > 0) {
method_symbol->param_types = calloc(param_count, sizeof(RavaType_t*));
size_t param_index = 0;
for (size_t i = 0; i < method_node->children_count; i++) {
RavaASTNode_t *child = method_node->children[i];
if (child->type == RAVA_AST_PARAM_DECL) {
RavaType_t *param_type = _rava_semantic_resolve_type(analyzer, child->data.var_decl.type);
method_symbol->param_types[param_index++] = rava_type_copy(param_type);
}
}
}
if (!rava_symbol_table_define(analyzer->symbol_table, method_symbol)) { if (!rava_symbol_table_define(analyzer->symbol_table, method_symbol)) {
char error_msg[256]; char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Method '%s' with this signature already defined", method_name); snprintf(error_msg, sizeof(error_msg), "Method '%s' already defined", method_name);
_rava_semantic_error(analyzer, error_msg, method_node->line, method_node->column); _rava_semantic_error(analyzer, error_msg, method_node->line, method_node->column);
rava_symbol_destroy(method_symbol); rava_symbol_destroy(method_symbol);
return false; return false;
@@ -290,9 +270,6 @@ static RavaType_t* _rava_semantic_check_expression(RavaSemanticAnalyzer_t *analy
if (strcmp(name, "Math") == 0) { if (strcmp(name, "Math") == 0) {
return rava_type_from_name("Math"); return rava_type_from_name("Math");
} }
if (strcmp(name, "InetAddress") == 0) {
return rava_type_from_name("InetAddress");
}
RavaSymbol_t *symbol = rava_symbol_table_resolve(analyzer->symbol_table, name); RavaSymbol_t *symbol = rava_symbol_table_resolve(analyzer->symbol_table, name);
if (!symbol) { if (!symbol) {
@@ -351,14 +328,6 @@ static RavaType_t* _rava_semantic_check_expression(RavaSemanticAnalyzer_t *analy
for (size_t i = 0; i < expr->data.call.arguments_count; i++) { for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
_rava_semantic_check_expression(analyzer, expr->data.call.arguments[i]); _rava_semantic_check_expression(analyzer, expr->data.call.arguments[i]);
} }
if (expr->data.call.callee->type == RAVA_AST_IDENTIFIER_EXPR) {
const char *func_name = expr->data.call.callee->data.identifier.name;
if (strcmp(func_name, "readLine") == 0) {
return rava_type_create_class("String");
} else if (strcmp(func_name, "sendResponse") == 0 || strcmp(func_name, "handleRequest") == 0) {
return rava_type_create_primitive(RAVA_TYPE_VOID);
}
}
if (expr->data.call.callee->type == RAVA_AST_MEMBER_ACCESS_EXPR) { if (expr->data.call.callee->type == RAVA_AST_MEMBER_ACCESS_EXPR) {
RavaASTNode_t *member = expr->data.call.callee; RavaASTNode_t *member = expr->data.call.callee;
const char *method = member->data.member_access.member; const char *method = member->data.member_access.member;
@@ -391,60 +360,13 @@ static RavaType_t* _rava_semantic_check_expression(RavaSemanticAnalyzer_t *analy
return rava_type_create_primitive(RAVA_TYPE_DOUBLE); return rava_type_create_primitive(RAVA_TYPE_DOUBLE);
} }
} }
if (member->data.member_access.object->type == RAVA_AST_IDENTIFIER_EXPR &&
strcmp(member->data.member_access.object->data.identifier.name, "InetAddress") == 0) {
if (strcmp(method, "getByName") == 0 || strcmp(method, "getLocalHost") == 0 ||
strcmp(method, "getLoopbackAddress") == 0) {
return rava_type_create_class("InetAddress");
}
}
if (strcmp(method, "getHostName") == 0 || strcmp(method, "getHostAddress") == 0) {
return rava_type_create_class("String");
}
if (strcmp(method, "isLoopbackAddress") == 0 || strcmp(method, "isAnyLocalAddress") == 0) {
return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
}
if (strcmp(method, "getLocalPort") == 0 || strcmp(method, "getPort") == 0) {
return rava_type_create_primitive(RAVA_TYPE_INT);
}
if (strcmp(method, "isBound") == 0 || strcmp(method, "isClosed") == 0) {
return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
}
if (strcmp(method, "getInetAddress") == 0 || strcmp(method, "getLocalAddress") == 0) {
return rava_type_create_class("InetAddress");
}
if (strcmp(method, "accept") == 0) {
return rava_type_create_class("Socket");
}
if (strcmp(method, "getInputStream") == 0) {
return rava_type_create_class("InputStream");
}
if (strcmp(method, "getOutputStream") == 0) {
return rava_type_create_class("OutputStream");
}
if (strcmp(method, "getSoTimeout") == 0 || strcmp(method, "getReceiveBufferSize") == 0 ||
strcmp(method, "getSendBufferSize") == 0) {
return rava_type_create_primitive(RAVA_TYPE_INT);
}
if (strcmp(method, "getTcpNoDelay") == 0 || strcmp(method, "getKeepAlive") == 0 ||
strcmp(method, "getReuseAddress") == 0 || strcmp(method, "isConnected") == 0 ||
strcmp(method, "isMulticastAddress") == 0 || strcmp(method, "isReachable") == 0) {
return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
}
if (strcmp(method, "read") == 0 || strcmp(method, "skip") == 0) {
return rava_type_create_primitive(RAVA_TYPE_INT);
}
if (strcmp(method, "length") == 0) { if (strcmp(method, "length") == 0) {
return rava_type_create_primitive(RAVA_TYPE_INT); return rava_type_create_primitive(RAVA_TYPE_INT);
} else if (strcmp(method, "charAt") == 0) { } else if (strcmp(method, "charAt") == 0) {
return rava_type_create_primitive(RAVA_TYPE_CHAR); return rava_type_create_primitive(RAVA_TYPE_CHAR);
} else if (strcmp(method, "substring") == 0 || strcmp(method, "toLowerCase") == 0 || } else if (strcmp(method, "equals") == 0) {
strcmp(method, "toUpperCase") == 0 || strcmp(method, "trim") == 0) {
return rava_type_create_class("String");
} else if (strcmp(method, "equals") == 0 || strcmp(method, "contains") == 0 ||
strcmp(method, "startsWith") == 0 || strcmp(method, "endsWith") == 0) {
return rava_type_create_primitive(RAVA_TYPE_BOOLEAN); return rava_type_create_primitive(RAVA_TYPE_BOOLEAN);
} else if (strcmp(method, "compareTo") == 0 || strcmp(method, "indexOf") == 0) { } else if (strcmp(method, "compareTo") == 0) {
return rava_type_create_primitive(RAVA_TYPE_INT); return rava_type_create_primitive(RAVA_TYPE_INT);
} else if (strcmp(method, "size") == 0) { } else if (strcmp(method, "size") == 0) {
return rava_type_create_primitive(RAVA_TYPE_INT); return rava_type_create_primitive(RAVA_TYPE_INT);
+2 -66
View File
@@ -92,43 +92,14 @@ void rava_symbol_destroy(RavaSymbol_t *symbol) {
if (!symbol) return; if (!symbol) return;
free(symbol->name); free(symbol->name);
rava_type_destroy(symbol->type); rava_type_destroy(symbol->type);
if (symbol->param_types) {
for (size_t i = 0; i < symbol->param_count; i++) {
rava_type_destroy(symbol->param_types[i]);
}
free(symbol->param_types);
}
free(symbol); free(symbol);
} }
bool rava_symbol_table_define(RavaSymbolTable_t *table, RavaSymbol_t *symbol) { bool rava_symbol_table_define(RavaSymbolTable_t *table, RavaSymbol_t *symbol) {
if (!table || !symbol) return false; if (!table || !symbol) return false;
if (symbol->kind == RAVA_SYMBOL_METHOD) { if (rava_symbol_table_resolve_in_scope(table->current_scope, symbol->name)) {
uint32_t h = _rava_symbol_hash(symbol->name); return false;
RavaSymbol_t *existing = table->current_scope->hash_table[h];
while (existing) {
if (strcmp(existing->name, symbol->name) == 0 &&
existing->kind == RAVA_SYMBOL_METHOD) {
if (existing->param_count == symbol->param_count) {
bool same_signature = true;
for (size_t i = 0; i < symbol->param_count; i++) {
if (!rava_type_equals(existing->param_types[i], symbol->param_types[i])) {
same_signature = false;
break;
}
}
if (same_signature) {
return false;
}
}
}
existing = existing->hash_next;
}
} else {
if (rava_symbol_table_resolve_in_scope(table->current_scope, symbol->name)) {
return false;
}
} }
symbol->next = table->current_scope->symbols; symbol->next = table->current_scope->symbols;
@@ -180,38 +151,3 @@ bool rava_symbol_has_modifier(RavaSymbol_t *symbol, RavaModifier_e modifier) {
return false; return false;
} }
bool rava_symbol_signature_matches(RavaSymbol_t *method, RavaType_t **arg_types, size_t arg_count) {
if (!method || method->kind != RAVA_SYMBOL_METHOD) return false;
if (method->param_count != arg_count) return false;
for (size_t i = 0; i < arg_count; i++) {
if (!rava_type_is_assignable_to(arg_types[i], method->param_types[i])) {
return false;
}
}
return true;
}
RavaSymbol_t* rava_symbol_table_resolve_method(RavaSymbolTable_t *table, const char *name, RavaType_t **arg_types, size_t arg_count) {
if (!table || !name) return NULL;
RavaScope_t *scope = table->current_scope;
while (scope) {
uint32_t h = _rava_symbol_hash(name);
RavaSymbol_t *symbol = scope->hash_table[h];
while (symbol) {
if (strcmp(symbol->name, name) == 0 &&
symbol->kind == RAVA_SYMBOL_METHOD &&
rava_symbol_signature_matches(symbol, arg_types, arg_count)) {
return symbol;
}
symbol = symbol->hash_next;
}
scope = scope->parent;
}
return NULL;
}
-5
View File
@@ -26,9 +26,6 @@ typedef struct RavaSymbol_t {
RavaASTNode_t *declaration; RavaASTNode_t *declaration;
size_t local_index; size_t local_index;
RavaType_t **param_types;
size_t param_count;
struct RavaSymbol_t *next; struct RavaSymbol_t *next;
struct RavaSymbol_t *hash_next; struct RavaSymbol_t *hash_next;
} RavaSymbol_t; } RavaSymbol_t;
@@ -63,9 +60,7 @@ void rava_symbol_destroy(RavaSymbol_t *symbol);
bool rava_symbol_table_define(RavaSymbolTable_t *table, RavaSymbol_t *symbol); bool rava_symbol_table_define(RavaSymbolTable_t *table, RavaSymbol_t *symbol);
RavaSymbol_t* rava_symbol_table_resolve(RavaSymbolTable_t *table, const char *name); RavaSymbol_t* rava_symbol_table_resolve(RavaSymbolTable_t *table, const char *name);
RavaSymbol_t* rava_symbol_table_resolve_in_scope(RavaScope_t *scope, const char *name); RavaSymbol_t* rava_symbol_table_resolve_in_scope(RavaScope_t *scope, const char *name);
RavaSymbol_t* rava_symbol_table_resolve_method(RavaSymbolTable_t *table, const char *name, RavaType_t **arg_types, size_t arg_count);
bool rava_symbol_has_modifier(RavaSymbol_t *symbol, RavaModifier_e modifier); bool rava_symbol_has_modifier(RavaSymbol_t *symbol, RavaModifier_e modifier);
bool rava_symbol_signature_matches(RavaSymbol_t *method, RavaType_t **arg_types, size_t arg_count);
#endif #endif
+84
View File
@@ -0,0 +1,84 @@
#include "../lexer/lexer.h"
#include "../parser/parser.h"
#include "../semantic/semantic.h"
#include "../ir/ir.h"
#include "../ir/ir_gen.h"
#include "../runtime/runtime.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
static char* read_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (!file) return NULL;
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
char *content = malloc(size + 1);
size_t read_bytes = fread(content, 1, size, file); (void)read_bytes;
content[size] = '\0';
fclose(file);
return content;
}
static bool run_example(const char *filename, const char *class_name) {
printf("\n========================================\n");
printf("Running: %s\n", filename);
printf("========================================\n");
char *source = read_file(filename);
if (!source) return false;
RavaLexer_t *lexer = rava_lexer_create(source);
RavaParser_t *parser = rava_parser_create(lexer);
RavaASTNode_t *ast = rava_parser_parse(parser);
if (parser->had_error) {
free(source);
return false;
}
RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create();
if (!rava_semantic_analyze(analyzer, ast)) {
free(source);
return false;
}
RavaIRGenerator_t *ir_gen = rava_ir_generator_create(analyzer);
RavaProgram_t *program = rava_ir_generate(ir_gen, ast);
if (!program) {
free(source);
return false;
}
RavaVM_t *vm = rava_vm_create(program);
printf("\nOutput:\n");
if (!rava_vm_execute(vm, class_name, "main")) {
printf("\nRuntime error: %s\n", vm->error_message);
rava_vm_destroy(vm);
free(source);
return false;
}
printf("\nâś… Execution completed successfully!\n");
rava_vm_destroy(vm);
rava_program_destroy(program);
rava_ir_generator_destroy(ir_gen);
rava_semantic_analyzer_destroy(analyzer);
rava_ast_node_destroy(ast);
rava_parser_destroy(parser);
rava_lexer_destroy(lexer);
free(source);
return true;
}
int main() {
run_example("examples/07_CollatzConjecture.java", "CollatzConjecture");
run_example("examples/08_PascalTriangle.java", "PascalTriangle");
return 0;
}
+110
View File
@@ -0,0 +1,110 @@
#include "../lexer/lexer.h"
#include "../parser/parser.h"
#include "../semantic/semantic.h"
#include "../ir/ir.h"
#include "../ir/ir_gen.h"
#include "../runtime/runtime.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
static char* read_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (!file) return NULL;
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
char *content = malloc(size + 1);
size_t read_bytes = fread(content, 1, size, file); (void)read_bytes;
content[size] = '\0';
fclose(file);
return content;
}
static bool run_example(const char *filename, const char *class_name) {
printf("\n========================================\n");
printf("Running: %s\n", filename);
printf("========================================\n");
fflush(stdout);
char *source = read_file(filename);
if (!source) return false;
RavaLexer_t *lexer = rava_lexer_create(source);
RavaParser_t *parser = rava_parser_create(lexer);
RavaASTNode_t *ast = rava_parser_parse(parser);
if (parser->had_error) {
free(source);
return false;
}
RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create();
if (!rava_semantic_analyze(analyzer, ast)) {
free(source);
return false;
}
RavaIRGenerator_t *ir_gen = rava_ir_generator_create(analyzer);
RavaProgram_t *program = rava_ir_generate(ir_gen, ast);
if (!program) {
free(source);
return false;
}
RavaVM_t *vm = rava_vm_create(program);
printf("\nOutput:\n");
fflush(stdout);
if (!rava_vm_execute(vm, class_name, "main")) {
printf("\nRuntime error: %s\n", vm->error_message);
rava_vm_destroy(vm);
free(source);
return false;
}
printf("\nâś… Execution completed successfully!\n");
fflush(stdout);
rava_vm_destroy(vm);
rava_program_destroy(program);
rava_ir_generator_destroy(ir_gen);
rava_semantic_analyzer_destroy(analyzer);
rava_ast_node_destroy(ast);
rava_parser_destroy(parser);
rava_lexer_destroy(lexer);
free(source);
return true;
}
int main() {
const char *examples[][2] = {
{"examples/01_Fibonacci.java", "Fibonacci"},
{"examples/02_PrimeNumbers.java", "PrimeNumbers"},
{"examples/03_FactorialVariations.java", "FactorialVariations"},
{"examples/04_GCD_LCM.java", "GCD_LCM"},
{"examples/05_PowerFunction.java", "PowerFunction"},
{"examples/06_BubbleSort.java", "BubbleSort"},
{"examples/07_CollatzConjecture.java", "CollatzConjecture"},
{"examples/08_PascalTriangle.java", "PascalTriangle"},
{"examples/09_TowerOfHanoi.java", "TowerOfHanoi"},
{"examples/10_AckermannFunction.java", "AckermannFunction"},
};
int passed = 0;
for (size_t i = 0; i < 10; i++) {
printf("\n[%zu/10]\n", i+1);
fflush(stdout);
if (run_example(examples[i][0], examples[i][1])) {
passed++;
}
}
printf("\n========================================\n");
printf("SUMMARY: %d/10 passed\n", passed);
printf("========================================\n");
return (passed == 10) ? 0 : 1;
}
Binary file not shown.
+30
View File
@@ -0,0 +1,30 @@
#include "../lexer/lexer.h"
#include "../parser/parser.h"
#include <stdio.h>
#include <stdlib.h>
int main() {
const char *source =
"public class ArrayTest {\n"
" public static int main() {\n"
" int[] numbers = new int[5];\n"
" numbers[0] = 10;\n"
" numbers[1] = 20;\n"
" int result = numbers[0] + numbers[1];\n"
" System.out.println(result);\n"
" return 0;\n"
" }\n"
"}\n";
RavaLexer_t *lexer = rava_lexer_create(source);
RavaParser_t *parser = rava_parser_create(lexer);
rava_parser_parse(parser);
if (parser->had_error) {
printf("Parse error: %s\n", parser->error_message);
return 1;
}
printf("Parsed successfully!\n");
return 0;
}
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.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4 -414
View File
@@ -1,355 +1,5 @@
#include "test_utils.h" #include "test_utils.h"
UnittestTestResult_t* test_simple_object_creation(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_simple_object_creation");
const char *source =
"class Point { int x; int y; }\n"
"public class Test {\n"
" public static int main() {\n"
" Point p = new Point();\n"
" p.x = 10;\n"
" p.y = 20;\n"
" return p.x + p.y;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 30,
"Object creation and field access should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_multiple_objects(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_multiple_objects");
const char *source =
"class Point { int x; int y; }\n"
"public class Test {\n"
" public static int main() {\n"
" Point p1 = new Point();\n"
" Point p2 = new Point();\n"
" p1.x = 5;\n"
" p1.y = 10;\n"
" p2.x = 15;\n"
" p2.y = 20;\n"
" return p1.x + p1.y + p2.x + p2.y;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 50,
"Multiple objects should have independent fields");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_field_update(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_field_update");
const char *source =
"class Counter { int value; }\n"
"public class Test {\n"
" public static int main() {\n"
" Counter c = new Counter();\n"
" c.value = 0;\n"
" c.value = c.value + 1;\n"
" c.value = c.value + 1;\n"
" c.value = c.value + 1;\n"
" return c.value;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 3,
"Object field updates should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_constructor_basic(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_constructor_basic");
const char *source =
"class Box {\n"
" int width;\n"
" int height;\n"
" Box(int w, int h) {\n"
" this.width = w;\n"
" this.height = h;\n"
" }\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Box b = new Box(5, 10);\n"
" return b.width * b.height;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 50,
"Constructor with parameters should initialize fields");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_constructor_chained_operations(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_constructor_chained_operations");
const char *source =
"class Rectangle {\n"
" int width;\n"
" int height;\n"
" int area;\n"
" Rectangle(int w, int h) {\n"
" this.width = w;\n"
" this.height = h;\n"
" this.area = w * h;\n"
" }\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Rectangle r = new Rectangle(6, 7);\n"
" return r.area;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 42,
"Constructor should compute derived values");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_instance_method_on_main_class(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_instance_method_on_main_class");
const char *source =
"public class Test {\n"
" int value;\n"
" Test(int v) { this.value = v; }\n"
" int getValue() { return this.value; }\n"
" void setValue(int v) { this.value = v; }\n"
" public static int main() {\n"
" Test obj = new Test(42);\n"
" int v1 = obj.getValue();\n"
" obj.setValue(100);\n"
" int v2 = obj.getValue();\n"
" return v1 + v2;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 142,
"Instance methods on main class should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_single_instance_method(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_single_instance_method");
const char *source =
"class Counter {\n"
" int value;\n"
" int getValue() { return this.value; }\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Counter c = new Counter();\n"
" c.value = 42;\n"
" return c.getValue();\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 42,
"Single instance method should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_this_keyword_explicit(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_this_keyword_explicit");
const char *source =
"public class Test {\n"
" int x;\n"
" void setX(int x) { this.x = x; }\n"
" int getX() { return this.x; }\n"
" public static int main() {\n"
" Test v = new Test();\n"
" v.setX(99);\n"
" return v.getX();\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 99,
"this keyword should disambiguate field from parameter");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_passed_to_method(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_passed_to_method");
const char *source =
"class Point { int x; int y; }\n"
"public class Test {\n"
" public static int sumPoint(Point p) {\n"
" return p.x + p.y;\n"
" }\n"
" public static int main() {\n"
" Point p = new Point();\n"
" p.x = 15;\n"
" p.y = 25;\n"
" return sumPoint(p);\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 40,
"Objects should be passable to static methods");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_modified_by_method(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_modified_by_method");
const char *source =
"class Point { int x; int y; }\n"
"public class Test {\n"
" public static void doublePoint(Point p) {\n"
" p.x = p.x * 2;\n"
" p.y = p.y * 2;\n"
" }\n"
" public static int main() {\n"
" Point p = new Point();\n"
" p.x = 5;\n"
" p.y = 10;\n"
" doublePoint(p);\n"
" return p.x + p.y;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 30,
"Objects should be modifiable by methods (pass by reference)");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inheritance_field_access(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_inheritance_field_access");
const char *source =
"class Animal { int age; }\n"
"class Dog extends Animal { int barkCount; }\n"
"public class Test {\n"
" public static int main() {\n"
" Dog d = new Dog();\n"
" d.age = 5;\n"
" d.barkCount = 10;\n"
" return d.age + d.barkCount;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 15,
"Subclass should access inherited fields");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inheritance_method_override(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_inheritance_method_override");
const char *source =
"class Animal {\n"
" int speak() { return 1; }\n"
"}\n"
"class Dog extends Animal {\n"
" int speak() { return 2; }\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Dog d = new Dog();\n"
" return d.speak();\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 2,
"Subclass should override parent methods");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_multiple_int_fields(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_multiple_int_fields");
const char *source =
"class Tuple {\n"
" int a;\n"
" int b;\n"
" int c;\n"
" int d;\n"
"}\n"
"public class Test {\n"
" public static int main() {\n"
" Tuple t = new Tuple();\n"
" t.a = 1;\n"
" t.b = 2;\n"
" t.c = 3;\n"
" t.d = 4;\n"
" return t.a + t.b + t.c + t.d;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 10,
"Objects with multiple int fields should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_in_loop(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_in_loop");
const char *source =
"class Counter { int value; }\n"
"public class Test {\n"
" public static int main() {\n"
" Counter c = new Counter();\n"
" c.value = 0;\n"
" for (int i = 0; i < 10; i = i + 1) {\n"
" c.value = c.value + i;\n"
" }\n"
" return c.value;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 45,
"Object fields should be modifiable in loops");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_object_in_conditional(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_object_in_conditional");
const char *source =
"class Value { int x; }\n"
"public class Test {\n"
" public static int main() {\n"
" Value v = new Value();\n"
" v.x = 50;\n"
" int result = 0;\n"
" if (v.x > 25) {\n"
" result = v.x * 2;\n"
" } else {\n"
" result = v.x;\n"
" }\n"
" return result;\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Test", "main", 100,
"Object fields should work in conditionals");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_simple_object_example(void) { UnittestTestResult_t* test_simple_object_example(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_simple_object_example"); UNITTEST_BEGIN_TEST("TestObjects", "test_simple_object_example");
@@ -361,28 +11,6 @@ UnittestTestResult_t* test_simple_object_example(void) {
UNITTEST_END_TEST(); UNITTEST_END_TEST();
} }
UnittestTestResult_t* test_instance_methods_example(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_instance_methods_example");
RAVA_TEST_FILE_EXECUTES(_unittest_result,
"examples/14_InstanceMethods.java",
"InstanceMethods", "main",
"14_InstanceMethods.java should execute successfully");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inheritance_example(void) {
UNITTEST_BEGIN_TEST("TestObjects", "test_inheritance_example");
RAVA_TEST_FILE_EXECUTES(_unittest_result,
"examples/17_Inheritance.java",
"Inheritance", "main",
"17_Inheritance.java should execute successfully");
UNITTEST_END_TEST();
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
UnittestConfig_t *config = unittest_config_create(); UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2; config->verbosity = 2;
@@ -392,49 +20,11 @@ int main(int argc, char **argv) {
config->use_colors = false; config->use_colors = false;
} }
UnittestTestSuite_t *suite = unittest_test_suite_create("Object Tests"); UnittestTestSuite_t *suite = unittest_test_suite_create("Object Example Tests");
UnittestTestCase_t *tc_basic = unittest_test_case_create("TestObjectBasics"); UnittestTestCase_t *tc = unittest_test_case_create("TestObjects");
unittest_test_case_add_result(tc_basic, test_simple_object_creation()); unittest_test_case_add_result(tc, test_simple_object_example());
unittest_test_case_add_result(tc_basic, test_multiple_objects()); unittest_test_suite_add_test_case(suite, tc);
unittest_test_case_add_result(tc_basic, test_object_field_update());
unittest_test_suite_add_test_case(suite, tc_basic);
UnittestTestCase_t *tc_constructor = unittest_test_case_create("TestConstructors");
unittest_test_case_add_result(tc_constructor, test_constructor_basic());
unittest_test_case_add_result(tc_constructor, test_constructor_chained_operations());
unittest_test_suite_add_test_case(suite, tc_constructor);
UnittestTestCase_t *tc_methods = unittest_test_case_create("TestInstanceMethods");
unittest_test_case_add_result(tc_methods, test_instance_method_on_main_class());
unittest_test_case_add_result(tc_methods, test_single_instance_method());
unittest_test_case_add_result(tc_methods, test_this_keyword_explicit());
unittest_test_suite_add_test_case(suite, tc_methods);
UnittestTestCase_t *tc_passing = unittest_test_case_create("TestObjectPassing");
unittest_test_case_add_result(tc_passing, test_object_passed_to_method());
unittest_test_case_add_result(tc_passing, test_object_modified_by_method());
unittest_test_suite_add_test_case(suite, tc_passing);
UnittestTestCase_t *tc_inheritance = unittest_test_case_create("TestInheritance");
unittest_test_case_add_result(tc_inheritance, test_inheritance_field_access());
unittest_test_case_add_result(tc_inheritance, test_inheritance_method_override());
unittest_test_suite_add_test_case(suite, tc_inheritance);
UnittestTestCase_t *tc_types = unittest_test_case_create("TestObjectTypes");
unittest_test_case_add_result(tc_types, test_multiple_int_fields());
unittest_test_suite_add_test_case(suite, tc_types);
UnittestTestCase_t *tc_advanced = unittest_test_case_create("TestAdvancedObjects");
unittest_test_case_add_result(tc_advanced, test_object_in_loop());
unittest_test_case_add_result(tc_advanced, test_object_in_conditional());
unittest_test_suite_add_test_case(suite, tc_advanced);
UnittestTestCase_t *tc_examples = unittest_test_case_create("TestExamples");
unittest_test_case_add_result(tc_examples, test_simple_object_example());
unittest_test_case_add_result(tc_examples, test_instance_methods_example());
unittest_test_case_add_result(tc_examples, test_inheritance_example());
unittest_test_suite_add_test_case(suite, tc_examples);
unittest_generate_report(suite, config); unittest_generate_report(suite, config);
Binary file not shown.
+17
View File
@@ -0,0 +1,17 @@
#include <stdio.h>
#include "../ir/ir.h"
int main(void) {
printf("RAVA_OP_NOP = %d\n", RAVA_OP_NOP);
printf("RAVA_OP_LOAD_CONST = %d\n", RAVA_OP_LOAD_CONST);
printf("RAVA_OP_CALL = %d\n", RAVA_OP_CALL);
printf("RAVA_OP_CALL_STATIC = %d\n", RAVA_OP_CALL_STATIC);
printf("RAVA_OP_CALL_RECURSIVE = %d\n", RAVA_OP_CALL_RECURSIVE);
printf("RAVA_OP_CALL_VIRTUAL = %d\n", RAVA_OP_CALL_VIRTUAL);
printf("RAVA_OP_CALL_SUPER = %d\n", RAVA_OP_CALL_SUPER);
printf("RAVA_OP_CALL_NATIVE = %d\n", RAVA_OP_CALL_NATIVE);
printf("RAVA_OP_RETURN = %d\n", RAVA_OP_RETURN);
printf("RAVA_OP_MATH_RANDOM = %d\n", RAVA_OP_MATH_RANDOM);
printf("Total opcodes: %d\n", RAVA_OP_MATH_RANDOM + 1);
return 0;
}
-171
View File
@@ -1,171 +0,0 @@
#include "unittest.h"
#include "../lexer/lexer.h"
#include "../parser/parser.h"
#include "../semantic/semantic.h"
#include "../ir/ir_gen.h"
#include "../runtime/runtime.h"
UnittestTestResult_t* test_overloading_different_param_count(void) {
UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_different_param_count");
const char* source =
"public class Calculator {\n"
" public static int add(int a, int b) {\n"
" return a + b;\n"
" }\n"
"\n"
" public static int add(int a, int b, int c) {\n"
" return a + b + c;\n"
" }\n"
"}\n";
RavaLexer_t* lexer = rava_lexer_create(source);
UNITTEST_ASSERT_NOT_NULL(_unittest_result, lexer, "lexer should be created");
RavaParser_t* parser = rava_parser_create(lexer);
UNITTEST_ASSERT_NOT_NULL(_unittest_result, parser, "parser should be created");
RavaASTNode_t* ast = rava_parser_parse(parser);
UNITTEST_ASSERT_NOT_NULL(_unittest_result, ast, "AST should be created");
RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create();
UNITTEST_ASSERT_NOT_NULL(_unittest_result, semantic, "semantic analyzer should be created");
bool success = rava_semantic_analyze(semantic, ast);
UNITTEST_ASSERT_TRUE(_unittest_result, success, "semantic analysis should accept overloaded methods with different param counts");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_overloading_different_param_types(void) {
UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_different_param_types");
const char* source =
"public class Calculator {\n"
" public static int add(int a, int b) {\n"
" return a + b;\n"
" }\n"
"\n"
" public static double add(double a, double b) {\n"
" return a + b;\n"
" }\n"
"}\n";
RavaLexer_t* lexer = rava_lexer_create(source);
RavaParser_t* parser = rava_parser_create(lexer);
RavaASTNode_t* ast = rava_parser_parse(parser);
RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create();
bool success = rava_semantic_analyze(semantic, ast);
UNITTEST_ASSERT_TRUE(_unittest_result, success, "semantic analysis should accept overloaded methods with different param types");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_overloading_reject_duplicate_signature(void) {
UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_reject_duplicate_signature");
const char* source =
"public class Calculator {\n"
" public static int add(int a, int b) {\n"
" return a + b;\n"
" }\n"
"\n"
" public static int add(int x, int y) {\n"
" return x + y;\n"
" }\n"
"}\n";
RavaLexer_t* lexer = rava_lexer_create(source);
RavaParser_t* parser = rava_parser_create(lexer);
RavaASTNode_t* ast = rava_parser_parse(parser);
RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create();
bool success = rava_semantic_analyze(semantic, ast);
UNITTEST_ASSERT_FALSE(_unittest_result, success, "semantic analysis should reject duplicate method signatures");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_overloading_mixed_param_types(void) {
UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_mixed_param_types");
const char* source =
"public class Calculator {\n"
" public static int add(int a, double b) {\n"
" return a + (int)b;\n"
" }\n"
"\n"
" public static double add(double a, int b) {\n"
" return a + (double)b;\n"
" }\n"
"}\n";
RavaLexer_t* lexer = rava_lexer_create(source);
RavaParser_t* parser = rava_parser_create(lexer);
RavaASTNode_t* ast = rava_parser_parse(parser);
RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create();
bool success = rava_semantic_analyze(semantic, ast);
UNITTEST_ASSERT_TRUE(_unittest_result, success, "semantic analysis should accept overloaded methods with mixed param types");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_overloading_three_overloads(void) {
UNITTEST_BEGIN_TEST("TestMethodOverloading", "test_three_overloads");
const char* source =
"public class Math {\n"
" public static int max(int a, int b) {\n"
" return a > b ? a : b;\n"
" }\n"
"\n"
" public static double max(double a, double b) {\n"
" return a > b ? a : b;\n"
" }\n"
"\n"
" public static int max(int a, int b, int c) {\n"
" return a > b ? (a > c ? a : c) : (b > c ? b : c);\n"
" }\n"
"}\n";
RavaLexer_t* lexer = rava_lexer_create(source);
RavaParser_t* parser = rava_parser_create(lexer);
RavaASTNode_t* ast = rava_parser_parse(parser);
RavaSemanticAnalyzer_t* semantic = rava_semantic_analyzer_create();
bool success = rava_semantic_analyze(semantic, ast);
UNITTEST_ASSERT_TRUE(_unittest_result, success, "semantic analysis should accept three overloads of max()");
UNITTEST_END_TEST();
}
int main(int argc, char **argv) {
UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
config->track_execution_time = true;
if (argc > 1 && strcmp(argv[1], "--json") == 0) {
config->output_format = UNITTEST_FORMAT_JSON;
config->use_colors = false;
}
UnittestTestSuite_t *suite = unittest_test_suite_create("Method Overloading Tests");
UnittestTestCase_t *tc = unittest_test_case_create("TestMethodOverloading");
unittest_test_case_add_result(tc, test_overloading_different_param_count());
unittest_test_case_add_result(tc, test_overloading_different_param_types());
unittest_test_case_add_result(tc, test_overloading_reject_duplicate_signature());
unittest_test_case_add_result(tc, test_overloading_mixed_param_types());
unittest_test_case_add_result(tc, test_overloading_three_overloads());
unittest_test_suite_add_test_case(suite, tc);
unittest_generate_report(suite, config);
int failures = suite->total_failed + suite->total_errors;
unittest_test_suite_destroy(suite);
unittest_config_destroy(config);
return failures > 0 ? 1 : 0;
}
-100
View File
@@ -1,100 +0,0 @@
#include "test_utils.h"
UnittestTestResult_t* test_overloading_call_two_params(void) {
UNITTEST_BEGIN_TEST("TestOverloadingRuntime", "test_call_two_params");
const char* source =
"public class Calculator {\n"
" public static int add(int a, int b) {\n"
" return a + b;\n"
" }\n"
"\n"
" public static int add(int a, int b, int c) {\n"
" return a + b + c;\n"
" }\n"
"\n"
" public static int main() {\n"
" return add(10, 20);\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Calculator", "main", 30,
"add(10, 20) should return 30");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_overloading_call_three_params(void) {
UNITTEST_BEGIN_TEST("TestOverloadingRuntime", "test_call_three_params");
const char* source =
"public class Calculator {\n"
" public static int add(int a, int b) {\n"
" return a + b;\n"
" }\n"
"\n"
" public static int add(int a, int b, int c) {\n"
" return a + b + c;\n"
" }\n"
"\n"
" public static int main() {\n"
" return add(10, 20, 30);\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Calculator", "main", 60,
"add(10, 20, 30) should return 60");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_overloading_different_types(void) {
UNITTEST_BEGIN_TEST("TestOverloadingRuntime", "test_different_types");
const char* source =
"public class Math {\n"
" public static int max(int a, int b) {\n"
" return a > b ? a : b;\n"
" }\n"
"\n"
" public static double max(double a, double b) {\n"
" return a > b ? a : b;\n"
" }\n"
"\n"
" public static int main() {\n"
" return max(15, 25);\n"
" }\n"
"}\n";
RAVA_TEST_RUN(_unittest_result, source, "Math", "main", 25,
"max(15, 25) should return 25");
UNITTEST_END_TEST();
}
int main(int argc, char **argv) {
UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
config->track_execution_time = true;
if (argc > 1 && strcmp(argv[1], "--json") == 0) {
config->output_format = UNITTEST_FORMAT_JSON;
config->use_colors = false;
}
UnittestTestSuite_t *suite = unittest_test_suite_create("Method Overloading Runtime Tests");
UnittestTestCase_t *tc = unittest_test_case_create("TestOverloadingRuntime");
unittest_test_case_add_result(tc, test_overloading_call_two_params());
unittest_test_case_add_result(tc, test_overloading_call_three_params());
unittest_test_case_add_result(tc, test_overloading_different_types());
unittest_test_suite_add_test_case(suite, tc);
unittest_generate_report(suite, config);
int failures = suite->total_failed + suite->total_errors;
unittest_test_suite_destroy(suite);
unittest_config_destroy(config);
return failures > 0 ? 1 : 0;
}
Binary file not shown.
+91
View File
@@ -0,0 +1,91 @@
#include "../lexer/lexer.h"
#include "../parser/parser.h"
#include "../semantic/semantic.h"
#include "../ir/ir.h"
#include "../ir/ir_gen.h"
#include "../runtime/runtime.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char* read_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (!file) return NULL;
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
char *content = malloc(size + 1);
size_t read_bytes = fread(content, 1, size, file); (void)read_bytes;
content[size] = '\0';
fclose(file);
return content;
}
int main() {
char *source = read_file("examples/08_PascalTriangle.java");
if (!source) return 1;
RavaLexer_t *lexer = rava_lexer_create(source);
RavaParser_t *parser = rava_parser_create(lexer);
RavaASTNode_t *ast = rava_parser_parse(parser);
if (parser->had_error) {
free(source);
return 1;
}
RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create();
if (!rava_semantic_analyze(analyzer, ast)) {
free(source);
return 1;
}
RavaIRGenerator_t *ir_gen = rava_ir_generator_create(analyzer);
RavaProgram_t *program = rava_ir_generate(ir_gen, ast);
if (!program) {
free(source);
return 1;
}
RavaVM_t *vm = rava_vm_create(program);
if (!rava_vm_execute(vm, "PascalTriangle", "main")) {
printf("Runtime error\n");
rava_vm_destroy(vm);
free(source);
return 1;
}
printf("\nCleaning up VM...\n");
fflush(stdout);
rava_vm_destroy(vm);
printf("Cleaning up program...\n");
fflush(stdout);
rava_program_destroy(program);
printf("Cleaning up IR generator...\n");
fflush(stdout);
rava_ir_generator_destroy(ir_gen);
printf("Cleaning up analyzer...\n");
fflush(stdout);
rava_semantic_analyzer_destroy(analyzer);
printf("Cleaning up AST...\n");
fflush(stdout);
rava_ast_node_destroy(ast);
printf("Cleaning up parser...\n");
fflush(stdout);
rava_parser_destroy(parser);
printf("Cleaning up lexer...\n");
fflush(stdout);
rava_lexer_destroy(lexer);
printf("Freeing source...\n");
fflush(stdout);
free(source);
printf("Done!\n");
return 0;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
-331
View File
@@ -34,320 +34,6 @@ UnittestTestResult_t* test_socket_create_multiple(void) {
UNITTEST_END_TEST(); UNITTEST_END_TEST();
} }
UnittestTestResult_t* test_inetaddress_loopback(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_loopback");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" InetAddress addr = InetAddress.getLoopbackAddress();\n"
" System.out.println(addr.getHostAddress());\n"
" return 1;\n"
" }\n"
"}\n",
"Test", "main", 1, "Loopback address should have IP address");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inetaddress_localhost(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_localhost");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" InetAddress addr = InetAddress.getLocalHost();\n"
" System.out.println(addr.getHostAddress());\n"
" return 1;\n"
" }\n"
"}\n",
"Test", "main", 1, "Local host should have an IP address");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inetaddress_getbyname(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_getbyname");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" InetAddress addr = InetAddress.getByName(\"localhost\");\n"
" System.out.println(addr.getHostAddress());\n"
" return 1;\n"
" }\n"
"}\n",
"Test", "main", 1, "localhost should resolve to IP");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_server_socket_local_port(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_server_socket_local_port");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" ServerSocket server = new ServerSocket(9995);\n"
" int port = server.getLocalPort();\n"
" server.close();\n"
" return port;\n"
" }\n"
"}\n",
"Test", "main", 9995, "ServerSocket should report correct local port");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_socket_bind(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_bind");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" Socket sock = new Socket();\n"
" sock.bind(\"127.0.0.1\", 9994);\n"
" int result = sock.isBound() ? 1 : 0;\n"
" sock.close();\n"
" return result;\n"
" }\n"
"}\n",
"Test", "main", 1, "Socket should be bound after bind()");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_socket_is_connected(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_is_connected");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" ServerSocket server = new ServerSocket(9993);\n"
" Socket client = new Socket();\n"
" int before = client.isConnected() ? 1 : 0;\n"
" InetAddress addr = InetAddress.getLoopbackAddress();\n"
" client.connect(addr, 9993);\n"
" int after = client.isConnected() ? 1 : 0;\n"
" client.close();\n"
" server.close();\n"
" return before * 10 + after;\n"
" }\n"
"}\n",
"Test", "main", 1, "Socket should report connected state");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_socket_is_closed(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_is_closed");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" Socket sock = new Socket();\n"
" int before = sock.isClosed() ? 1 : 0;\n"
" sock.close();\n"
" int after = sock.isClosed() ? 1 : 0;\n"
" return before * 10 + after;\n"
" }\n"
"}\n",
"Test", "main", 1, "Socket should report closed state");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_socket_shutdown_input(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_shutdown_input");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" ServerSocket server = new ServerSocket(9992);\n"
" Socket client = new Socket();\n"
" InetAddress addr = InetAddress.getLoopbackAddress();\n"
" client.connect(addr, 9992);\n"
" int before = client.isInputShutdown() ? 1 : 0;\n"
" client.shutdownInput();\n"
" int after = client.isInputShutdown() ? 1 : 0;\n"
" client.close();\n"
" server.close();\n"
" return before * 10 + after;\n"
" }\n"
"}\n",
"Test", "main", 1, "Socket should report input shutdown state");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_socket_shutdown_output(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_shutdown_output");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" ServerSocket server = new ServerSocket(9991);\n"
" Socket client = new Socket();\n"
" InetAddress addr = InetAddress.getLoopbackAddress();\n"
" client.connect(addr, 9991);\n"
" int before = client.isOutputShutdown() ? 1 : 0;\n"
" client.shutdownOutput();\n"
" int after = client.isOutputShutdown() ? 1 : 0;\n"
" client.close();\n"
" server.close();\n"
" return before * 10 + after;\n"
" }\n"
"}\n",
"Test", "main", 1, "Socket should report output shutdown state");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_socket_is_bound(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_is_bound");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" ServerSocket server = new ServerSocket(9990);\n"
" int result = server.isBound() ? 1 : 0;\n"
" server.close();\n"
" return result;\n"
" }\n"
"}\n",
"Test", "main", 1, "ServerSocket should be bound after creation");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_socket_buffer_sizes(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_buffer_sizes");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" Socket sock = new Socket();\n"
" sock.setSendBufferSize(16384);\n"
" sock.setReceiveBufferSize(16384);\n"
" int sendSize = sock.getSendBufferSize();\n"
" int recvSize = sock.getReceiveBufferSize();\n"
" sock.close();\n"
" return (sendSize > 0 && recvSize > 0) ? 1 : 0;\n"
" }\n"
"}\n",
"Test", "main", 1, "Socket buffer sizes should be retrievable");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_socket_keep_alive_reuse_address(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_socket_keep_alive_reuse_address");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" Socket sock = new Socket();\n"
" sock.setKeepAlive(true);\n"
" int keepAlive = sock.getKeepAlive() ? 1 : 0;\n"
" sock.setKeepAlive(false);\n"
" int keepAlive2 = sock.getKeepAlive() ? 1 : 0;\n"
" sock.setReuseAddress(true);\n"
" int reuse = sock.getReuseAddress() ? 1 : 0;\n"
" sock.setReuseAddress(false);\n"
" int reuse2 = sock.getReuseAddress() ? 1 : 0;\n"
" sock.close();\n"
" return (keepAlive == 1 && keepAlive2 == 0 && reuse == 1 && reuse2 == 0) ? 1 : 0;\n"
" }\n"
"}\n",
"Test", "main", 1, "Socket KeepAlive and ReuseAddress options should work");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inetaddress_get_address(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_get_address");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" InetAddress addr = InetAddress.getByName(\"127.0.0.1\");\n"
" addr.getAddress();\n"
" return 1;\n"
" }\n"
"}\n",
"Test", "main", 1, "InetAddress.getAddress() should execute");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inetaddress_is_multicast(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_is_multicast");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" InetAddress addr = InetAddress.getByName(\"127.0.0.1\");\n"
" int multicast = addr.isMulticastAddress() ? 1 : 0;\n"
" return (multicast == 0) ? 1 : 0;\n"
" }\n"
"}\n",
"Test", "main", 1, "InetAddress.isMulticastAddress() should return false for loopback");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inetaddress_is_reachable(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_is_reachable");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" InetAddress addr = InetAddress.getByName(\"127.0.0.1\");\n"
" int reachable = addr.isReachable(1000) ? 1 : 0;\n"
" return 1;\n"
" }\n"
"}\n",
"Test", "main", 1, "InetAddress.isReachable() should execute without error");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_inetaddress_get_all_by_name(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_inetaddress_get_all_by_name");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" InetAddress.getAllByName(\"localhost\");\n"
" return 1;\n"
" }\n"
"}\n",
"Test", "main", 1, "InetAddress.getAllByName() should execute");
UNITTEST_END_TEST();
}
UnittestTestResult_t* test_server_socket_options(void) {
UNITTEST_BEGIN_TEST("TestSockets", "test_server_socket_options");
RAVA_TEST_RUN(_unittest_result,
"public class Test {\n"
" public static int main() {\n"
" ServerSocket server = new ServerSocket(0);\n"
" server.setReceiveBufferSize(16384);\n"
" int bufSize = server.getReceiveBufferSize();\n"
" server.setReuseAddress(true);\n"
" int reuse = server.getReuseAddress() ? 1 : 0;\n"
" server.setReuseAddress(false);\n"
" int reuse2 = server.getReuseAddress() ? 1 : 0;\n"
" return (bufSize > 0 && reuse == 1 && reuse2 == 0) ? 1 : 0;\n"
" }\n"
"}\n",
"Test", "main", 1, "ServerSocket buffer and reuse address options should work");
UNITTEST_END_TEST();
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
UnittestConfig_t *config = unittest_config_create(); UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2; config->verbosity = 2;
@@ -362,23 +48,6 @@ int main(int argc, char **argv) {
UnittestTestCase_t *tc = unittest_test_case_create("TestSockets"); UnittestTestCase_t *tc = unittest_test_case_create("TestSockets");
unittest_test_case_add_result(tc, test_socket_create_server()); unittest_test_case_add_result(tc, test_socket_create_server());
unittest_test_case_add_result(tc, test_socket_create_multiple()); unittest_test_case_add_result(tc, test_socket_create_multiple());
unittest_test_case_add_result(tc, test_inetaddress_loopback());
unittest_test_case_add_result(tc, test_inetaddress_localhost());
unittest_test_case_add_result(tc, test_inetaddress_getbyname());
unittest_test_case_add_result(tc, test_server_socket_local_port());
unittest_test_case_add_result(tc, test_socket_bind());
unittest_test_case_add_result(tc, test_socket_is_connected());
unittest_test_case_add_result(tc, test_socket_is_closed());
unittest_test_case_add_result(tc, test_socket_shutdown_input());
unittest_test_case_add_result(tc, test_socket_shutdown_output());
unittest_test_case_add_result(tc, test_socket_is_bound());
unittest_test_case_add_result(tc, test_socket_buffer_sizes());
unittest_test_case_add_result(tc, test_socket_keep_alive_reuse_address());
unittest_test_case_add_result(tc, test_inetaddress_get_address());
unittest_test_case_add_result(tc, test_inetaddress_is_multicast());
unittest_test_case_add_result(tc, test_inetaddress_is_reachable());
unittest_test_case_add_result(tc, test_inetaddress_get_all_by_name());
unittest_test_case_add_result(tc, test_server_socket_options());
unittest_test_suite_add_test_case(suite, tc); unittest_test_suite_add_test_case(suite, tc);
unittest_generate_report(suite, config); unittest_generate_report(suite, config);
Binary file not shown.
+40
View File
@@ -0,0 +1,40 @@
#include "../lexer/lexer.h"
#include "../parser/parser.h"
#include <stdio.h>
#include <stdlib.h>
static char* read_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (!file) return NULL;
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
char *content = malloc(size + 1);
size_t read_bytes = fread(content, 1, size, file); (void)read_bytes;
content[size] = '\0';
fclose(file);
return content;
}
int main() {
char *source = read_file("examples/11_TowerOfHanoiStatic.java");
if (!source) {
printf("Failed to read file\n");
return 1;
}
RavaLexer_t *lexer = rava_lexer_create(source);
RavaParser_t *parser = rava_parser_create(lexer);
rava_parser_parse(parser);
if (parser->had_error) {
printf("Parse error: %s\n", parser->error_message);
free(source);
return 1;
}
printf("Parsed successfully!\n");
free(source);
return 0;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+56
View File
@@ -0,0 +1,56 @@
#include "../lexer/lexer.h"
#include "../parser/parser.h"
#include "../semantic/semantic.h"
#include "../ir/ir.h"
#include "../ir/ir_gen.h"
#include <stdio.h>
#include <stdlib.h>
static char* read_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (!file) return NULL;
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
char *content = malloc(size + 1);
size_t read_bytes = fread(content, 1, size, file); (void)read_bytes;
content[size] = '\0';
fclose(file);
return content;
}
int main() {
char *source = read_file("examples/09_TowerOfHanoi.java");
if (!source) return 1;
RavaLexer_t *lexer = rava_lexer_create(source);
RavaParser_t *parser = rava_parser_create(lexer);
RavaASTNode_t *ast = rava_parser_parse(parser);
if (parser->had_error) {
printf("Parse error: %s\n", parser->error_message);
free(source);
return 1;
}
RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create();
if (!rava_semantic_analyze(analyzer, ast)) {
printf("Semantic error: %s\n", analyzer->error_message);
free(source);
return 1;
}
RavaIRGenerator_t *ir_gen = rava_ir_generator_create(analyzer);
RavaProgram_t *program = rava_ir_generate(ir_gen, ast);
if (!program) {
printf("IR generation failed\n");
free(source);
return 1;
}
rava_program_print(program);
free(source);
return 0;
}
-22
View File
@@ -68,28 +68,6 @@ RavaType_t* rava_type_create_array(RavaType_t *element_type, int dimensions) {
return type; return type;
} }
RavaType_t* rava_type_copy(RavaType_t *type) {
if (!type) return NULL;
if (_is_pooled_type(type)) {
return type;
}
if (type->kind == RAVA_TYPE_ARRAY) {
return rava_type_create_array(
rava_type_copy(type->data.array.element_type),
type->data.array.dimensions
);
} else if (type->kind == RAVA_TYPE_CLASS) {
return rava_type_create_class(type->data.class_type.class_name);
}
RavaType_t *copy = calloc(1, sizeof(RavaType_t));
copy->kind = type->kind;
copy->name = strdup(type->name);
return copy;
}
void rava_type_destroy(RavaType_t *type) { void rava_type_destroy(RavaType_t *type) {
if (!type || _is_pooled_type(type)) return; if (!type || _is_pooled_type(type)) return;
-1
View File
@@ -42,7 +42,6 @@ struct RavaType_t {
RavaType_t* rava_type_create_primitive(RavaTypeKind_e kind); RavaType_t* rava_type_create_primitive(RavaTypeKind_e kind);
RavaType_t* rava_type_create_class(const char *class_name); RavaType_t* rava_type_create_class(const char *class_name);
RavaType_t* rava_type_create_array(RavaType_t *element_type, int dimensions); RavaType_t* rava_type_create_array(RavaType_t *element_type, int dimensions);
RavaType_t* rava_type_copy(RavaType_t *type);
void rava_type_destroy(RavaType_t *type); void rava_type_destroy(RavaType_t *type);
RavaType_t* rava_type_from_name(const char *type_name); RavaType_t* rava_type_from_name(const char *type_name);
+10
View File
@@ -19,4 +19,14 @@ static inline void* rava_safe_realloc(void *ptr, size_t size) {
return new_ptr; return new_ptr;
} }
static inline void* rava_safe_malloc(size_t size) {
if (size == 0) return NULL;
return malloc(size);
}
static inline void* rava_safe_calloc(size_t count, size_t size) {
if (count == 0 || size == 0) return NULL;
return calloc(count, size);
}
#endif #endif