Compare commits

..
33 Commits
Author SHA1 Message Date
retoor ca544088d6 Performance upgrade.
CI / Optimization Infrastructure Tests (push) Successful in 14s
CI / Unit Tests (push) Successful in 43s
CI / Integration Tests (push) Successful in 21s
CI / Performance Benchmark (push) Successful in 1m29s
2025-12-08 07:15:25 +01:00
retoor 7b69ff62f6 WOrking benchmark. 2025-12-08 03:13:33 +01:00
retoor 668e6b8b34 Huge performance upgrade. 2025-12-08 02:48:35 +01:00
retoor d22e4b0611 Update.
CI / Unit Tests (push) Successful in 27s
CI / Optimization Infrastructure Tests (push) Successful in 27s
CI / Integration Tests (push) Successful in 1m15s
CI / Performance Benchmark (push) Successful in 52s
2025-12-07 22:57:06 +01:00
retoor f2f7dbbddc Update. 2025-12-07 16:31:49 +01:00
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
35 changed files with 485 additions and 2269 deletions
+6 -3
View File
@@ -124,7 +124,10 @@ jobs:
- name: Install dependencies
run: |
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
run: make benchmark
- name: Build 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 \
-o test_benchmark_pgo \
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 \
semantic/symbol_table.c semantic/semantic.c \
ir/ir.c ir/ir_gen.c \
-4
View File
@@ -6,7 +6,3 @@ merge.py
*.o
run_examples
rava
*.gcno
*.gcda
coverage_report
*.info
+3 -147
View File
@@ -5,7 +5,7 @@ LDFLAGS = -ldl -lm
LEXER_SOURCES = lexer/lexer_tokenizer.c lexer/lexer_keywords.c lexer/lexer_literals.c
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)
TYPES_SOURCES = types/types.c
@@ -57,12 +57,6 @@ TEST_ARRAYS_OBJECTS = $(TEST_ARRAYS_SOURCES:.c=.o)
TEST_OBJECTS_SOURCES = tests/test_objects.c
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_OBJECTS = $(TEST_INSTANCE_SOURCES:.c=.o)
@@ -165,7 +159,7 @@ UNITTEST_OBJECTS = $(UNITTEST_SOURCES:.c=.o)
TEST_UNITTEST_DEMO_SOURCES = tests/test_unittest_demo.c
TEST_UNITTEST_DEMO_OBJECTS = $(TEST_UNITTEST_DEMO_SOURCES:.c=.o)
all: 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)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
@@ -191,12 +185,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)
$(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)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
@@ -317,20 +305,6 @@ benchmark: test_benchmark
@echo "========================================"
@python3 examples/benchmark.py
@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)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lreadline
@@ -391,125 +365,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_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
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"
.PHONY: all clean benchmark test_phase0 pgo test_benchmark_pgo_gen pgo_run test_benchmark_pgo test test_repl examples
test: all
@echo "=== Running All Tests ==="
+7 -84
View File
@@ -147,92 +147,15 @@ make test_repl
## 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 |
|-----------|------|--------|--------|---------|
| 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)
Started at 1402ms for Fibonacci. After 9 optimization phases: 257ms. That is 5.5x faster.
## Structure
+3 -175
View File
@@ -1,4 +1,4 @@
class Benchmark {
public class Benchmark {
public static int fibonacci(int n) {
if (n <= 1) {
return n;
@@ -187,120 +187,7 @@ class Benchmark {
return arr[0];
}
public static int quickSortPartition(int[] arr, int low, int high) {
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) {
public static int main() {
System.out.println("=== Rava Comprehensive Benchmark Suite ===");
long start = System.nanoTime();
@@ -453,66 +340,7 @@ class Benchmark {
System.out.print(bubbleTime);
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 ===");
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;
}
}
-124
View File
@@ -1,8 +1,5 @@
#!/usr/bin/env python3
import time
import sys
sys.setrecursionlimit(10000)
def fibonacci(n):
if n <= 1:
@@ -139,85 +136,6 @@ def bubble_sort(size):
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():
print("=== Python Comprehensive Benchmark Suite ===")
@@ -326,48 +244,6 @@ def main():
print(f"Bubble sort (5000 elements) = {bubble}")
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 ===")
if __name__ == "__main__":
-1
View File
@@ -338,7 +338,6 @@ static const char* _rava_opcode_name(RavaOpCode_e opcode) {
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_INVOKE: return "METHOD_REF_INVOKE";
case RAVA_OP_ARRAY_CMP_SWAP_INT: return "ARRAY_CMP_SWAP_INT";
default: return "UNKNOWN";
}
}
-5
View File
@@ -113,7 +113,6 @@ typedef enum {
RAVA_OP_LOAD_TWO_LOCALS,
RAVA_OP_ADD_LOCAL_TO_LOCAL,
RAVA_OP_LOAD_LOCAL_LT_LOCAL_JUMPFALSE,
RAVA_OP_ARRAY_CMP_SWAP_INT,
RAVA_OP_MATH_ABS,
RAVA_OP_MATH_SQRT,
@@ -264,10 +263,6 @@ typedef union {
bool is_constructor;
bool is_static;
} method_ref;
struct {
int array_local;
int index_local;
} array_cmp_swap;
} RavaOperand_u;
typedef struct {
+2 -25
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) {
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;
}
}
}
@@ -334,24 +323,12 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
bool use_unchecked = false;
if (gen->loop_context && gen->loop_context->has_bounds_check) {
RavaASTNode_t *index_node = expr->data.array_access.index;
if (index_node->type == RAVA_AST_IDENTIFIER_EXPR) {
const char *index_name = index_node->data.identifier.name;
if (expr->data.array_access.index->type == RAVA_AST_IDENTIFIER_EXPR) {
const char *index_name = expr->data.array_access.index->data.identifier.name;
if (gen->loop_context->loop_var_name &&
strcmp(index_name, gen->loop_context->loop_var_name) == 0) {
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;
}
}
}
-3
View File
@@ -31,7 +31,6 @@ RavaMethod_t* rava_methodcache_lookup(MethodCache_t* cache,
slot->method_hash == method_hash &&
slot->method != NULL) {
entry->lru = (uint8_t)i;
slot->hit_count++;
return slot->method;
}
}
@@ -56,7 +55,6 @@ void rava_methodcache_insert(MethodCache_t* cache,
entry->slots[i].class_hash = class_hash;
entry->slots[i].method_hash = method_hash;
entry->slots[i].method = method;
entry->slots[i].hit_count = 0;
entry->lru = (uint8_t)i;
return;
}
@@ -66,7 +64,6 @@ void rava_methodcache_insert(MethodCache_t* cache,
entry->slots[evict].class_hash = class_hash;
entry->slots[evict].method_hash = method_hash;
entry->slots[evict].method = method;
entry->slots[evict].hit_count = 0;
entry->lru = (uint8_t)evict;
}
-1
View File
@@ -13,7 +13,6 @@ typedef struct {
uint32_t class_hash;
uint32_t method_hash;
RavaMethod_t* method;
uint64_t hit_count;
} MethodCacheSlot_t;
typedef struct {
+18 -77
View File
@@ -325,23 +325,9 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
break;
case RAVA_OP_CALL_STATIC: {
int arg_count = instr->operand.call.arg_count;
RavaMethod_t *method = (RavaMethod_t*)instr->operand.call.cached_method;
if (!method) {
RavaValue_t *args = arg_count > 0 ? &stack->values[stack->top - arg_count] : NULL;
method = _rava_vm_find_method_overload(vm,
instr->operand.call.class_name,
instr->operand.call.method_name,
args, (size_t)arg_count);
if (!method) {
method = _rava_vm_find_method_cached(vm,
RavaMethod_t *method = _rava_vm_find_method_cached(vm,
instr->operand.call.class_name,
instr->operand.call.method_name);
}
if (method) {
instr->operand.call.cached_method = method;
}
}
if (!method) {
vm->had_error = true;
vm->error_message = malloc(RAVA_ERROR_BUFFER_SIZE);
@@ -353,7 +339,7 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
RavaCallFrame_t *new_frame = rava_call_frame_create(method);
for (int i = arg_count - 1; i >= 0; i--) {
for (int i = instr->operand.call.arg_count - 1; i >= 0; i--) {
new_frame->locals[i] = rava_stack_pop(stack);
}
@@ -401,11 +387,7 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
class_name = obj_val.data.object_val->class_name;
}
RavaMethod_t *method = _rava_vm_find_method_overload(vm, class_name, instr->operand.call.method_name,
args, (size_t)instr->operand.call.arg_count);
if (!method) {
method = _rava_vm_find_method_cached(vm, class_name, instr->operand.call.method_name);
}
RavaMethod_t *method = _rava_vm_find_method_cached(vm, class_name, instr->operand.call.method_name);
if (!method) {
if (strcmp(instr->operand.call.method_name, "<init>") == 0 && instr->operand.call.arg_count == 0) {
break;
@@ -485,11 +467,7 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
RavaValue_t obj_val = rava_stack_pop(stack);
const char *super_class = instr->operand.call.class_name;
RavaMethod_t *method = _rava_vm_find_method_overload(vm, super_class, instr->operand.call.method_name,
args, (size_t)instr->operand.call.arg_count);
if (!method) {
method = _rava_vm_find_method_cached(vm, super_class, instr->operand.call.method_name);
}
RavaMethod_t *method = _rava_vm_find_method_cached(vm, super_class, instr->operand.call.method_name);
if (!method) {
vm->had_error = true;
vm->error_message = malloc(RAVA_ERROR_BUFFER_SIZE);
@@ -2730,7 +2708,7 @@ op_instanceof: {
RavaValue_t val = STACK_POP(stack);
bool result = false;
if (val.type == RAVA_VAL_OBJECT && val.data.object_val) {
result = _rava_vm_instanceof(vm, val.data.object_val->class_name, instr->operand.string_value);
result = strcmp(val.data.object_val->class_name, instr->operand.string_value) == 0;
}
STACK_PUSH(stack, rava_value_boolean(result));
DISPATCH();
@@ -3343,7 +3321,6 @@ bool _rava_vm_execute_ultrafast(RavaVM_t *vm, RavaMethod_t *entry_method) {
&&uf_load_local_const_add, &&uf_load_local_const_lt_jumpfalse,
&&uf_load_local_const_le_jumpfalse, &&uf_load_two_locals,
&&uf_add_local_to_local, &&uf_load_local_lt_local_jumpfalse,
&&uf_array_cmp_swap_int,
&&uf_math_abs, &&uf_math_sqrt, &&uf_math_pow, &&uf_math_min, &&uf_math_max,
&&uf_math_floor, &&uf_math_ceil, &&uf_math_round,
&&uf_math_sin, &&uf_math_cos, &&uf_math_tan, &&uf_math_log, &&uf_math_exp,
@@ -3662,23 +3639,8 @@ uf_label:
uf_call:
uf_call_static: {
RavaNanboxValue_t args[16];
for (int i = instr->operand.call.arg_count - 1; i >= 0; i--) {
args[i] = UF_POP();
}
RavaMethod_t *target = (RavaMethod_t*)instr->operand.call.cached_method;
if (!target) {
target = _rava_vm_find_method_overload_nb(vm,
instr->operand.call.class_name, instr->operand.call.method_name,
args, (size_t)instr->operand.call.arg_count);
if (!target) {
target = _rava_vm_find_method_cached(vm,
instr->operand.call.class_name, instr->operand.call.method_name);
}
if (target) {
instr->operand.call.cached_method = target;
}
}
RavaMethod_t *target = _rava_vm_find_method_cached(vm,
instr->operand.call.class_name, instr->operand.call.method_name);
if (!target) {
vm->had_error = true;
goto uf_done;
@@ -3687,6 +3649,10 @@ uf_call_static: {
rava_optimize_superinstructions(target);
target->label_table = rava_labeltable_create(target->instructions);
}
RavaNanboxValue_t args[16];
for (int i = instr->operand.call.arg_count - 1; i >= 0; i--) {
args[i] = UF_POP();
}
frame->pc = pc;
FastFrame_t *new_frame = rava_fastframe_push(target, target->local_count);
if (!new_frame) {
@@ -3800,11 +3766,7 @@ uf_call_virtual: {
}
RavaObject_t *obj = rava_nanbox_as_object(obj_val);
const char *class_name = obj->class_name;
RavaMethod_t *target = _rava_vm_find_method_overload_nb(vm, class_name, instr->operand.call.method_name,
args, (size_t)arg_count);
if (!target) {
target = _rava_vm_find_method_cached(vm, class_name, instr->operand.call.method_name);
}
RavaMethod_t *target = _rava_vm_find_method_cached(vm, class_name, instr->operand.call.method_name);
if (!target) {
if (strcmp(mname, "<init>") == 0 && arg_count == 0) {
UF_DISPATCH();
@@ -3861,11 +3823,7 @@ uf_call_super: {
}
RavaNanboxValue_t obj_val = UF_POP();
const char *super_class = instr->operand.call.class_name;
RavaMethod_t *target = _rava_vm_find_method_overload_nb(vm, super_class, instr->operand.call.method_name,
args, (size_t)arg_count);
if (!target) {
target = _rava_vm_find_method_cached(vm, super_class, instr->operand.call.method_name);
}
RavaMethod_t *target = _rava_vm_find_method_cached(vm, super_class, instr->operand.call.method_name);
if (!target) {
vm->had_error = true;
goto uf_done;
@@ -3977,10 +3935,10 @@ uf_load_array_unchecked: {
RavaArray_t *arr = rava_nanbox_as_array(arr_val);
size_t i = (size_t)rava_nanbox_to_int(idx);
if (arr->element_type == RAVA_VAL_ARRAY || arr->element_type == RAVA_VAL_OBJECT) {
RavaValue_t v = ((RavaValue_t*)arr->data)[i];
RavaValue_t v = rava_array_get_value(arr, i);
UF_PUSH(rava_value_to_nanbox(v));
} else {
int64_t val = ((int64_t*)arr->data)[i];
int64_t val = rava_array_get_int(arr, i);
UF_PUSH(rava_nanbox_int(val));
}
UF_DISPATCH();
@@ -4009,9 +3967,9 @@ uf_store_array_unchecked: {
RavaArray_t *arr = rava_nanbox_as_array(arr_val);
size_t i = (size_t)rava_nanbox_to_int(idx);
if (arr->element_type == RAVA_VAL_ARRAY || arr->element_type == RAVA_VAL_OBJECT) {
((RavaValue_t*)arr->data)[i] = rava_nanbox_to_value(val);
rava_array_set_value(arr, i, rava_nanbox_to_value(val));
} else {
((int64_t*)arr->data)[i] = rava_nanbox_to_int(val);
rava_array_set_int(arr, i, rava_nanbox_to_int(val));
}
UF_DISPATCH();
}
@@ -4364,7 +4322,7 @@ uf_instanceof: {
if (rava_nanbox_is_object(val)) {
RavaObject_t *obj = rava_nanbox_as_object(val);
if (obj) {
result = _rava_vm_instanceof(vm, obj->class_name, instr->operand.string_value);
result = strcmp(obj->class_name, instr->operand.string_value) == 0;
}
}
UF_PUSH(rava_nanbox_bool(result));
@@ -4521,23 +4479,6 @@ uf_load_local_lt_local_jumpfalse: {
UF_DISPATCH();
}
uf_array_cmp_swap_int: {
int array_local = instr->operand.array_cmp_swap.array_local;
int index_local = instr->operand.array_cmp_swap.index_local;
RavaNanboxValue_t arr_val = frame->locals[array_local];
RavaNanboxValue_t idx_val = frame->locals[index_local];
RavaArray_t *arr = rava_nanbox_as_array(arr_val);
size_t i = (size_t)rava_nanbox_to_int(idx_val);
int64_t *data = (int64_t*)arr->data;
int64_t v1 = data[i];
int64_t v2 = data[i + 1];
if (v1 > v2) {
data[i] = v2;
data[i + 1] = v1;
}
UF_DISPATCH();
}
uf_math_abs: {
RavaNanboxValue_t val = UF_POP();
if (rava_nanbox_is_double(val)) {
-16
View File
@@ -101,19 +101,3 @@ size_t rava_array_length(RavaArray_t *array) {
if (!array) return 0;
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];
}
-3
View File
@@ -151,11 +151,8 @@ 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);
-93
View File
@@ -19,66 +19,6 @@ RavaClass_t* _rava_vm_find_class(RavaVM_t *vm, const char *class_name) {
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) {
@@ -101,27 +41,6 @@ RavaMethod_t* _rava_vm_find_method(RavaVM_t *vm, const char *class_name, const c
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);
@@ -132,15 +51,3 @@ RavaMethod_t* _rava_vm_find_method_cached(RavaVM_t *vm, const char *class_name,
}
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);
}
-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) {
if (!method || !method->instructions) return;
@@ -283,7 +278,6 @@ void rava_optimize_superinstructions(RavaMethod_t* method) {
optimize_constant_folding(instrs, count);
optimize_inline_calls(instrs, count);
optimize_strength_reduction(instrs, count);
optimize_array_cmp_swap(instrs, count);
optimize_add_local_to_local(instrs, count);
optimize_local_lt_local_jump(instrs, count);
optimize_inc_dec_local(instrs, count);
+1 -21
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;
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);
method_symbol->modifiers = method_node->data.method_decl.modifiers;
method_symbol->modifiers_count = method_node->data.method_decl.modifiers_count;
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)) {
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_symbol_destroy(method_symbol);
return false;
+2 -66
View File
@@ -92,43 +92,14 @@ void rava_symbol_destroy(RavaSymbol_t *symbol) {
if (!symbol) return;
free(symbol->name);
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);
}
bool rava_symbol_table_define(RavaSymbolTable_t *table, RavaSymbol_t *symbol) {
if (!table || !symbol) return false;
if (symbol->kind == RAVA_SYMBOL_METHOD) {
uint32_t h = _rava_symbol_hash(symbol->name);
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;
}
if (rava_symbol_table_resolve_in_scope(table->current_scope, symbol->name)) {
return false;
}
symbol->next = table->current_scope->symbols;
@@ -180,38 +151,3 @@ bool rava_symbol_has_modifier(RavaSymbol_t *symbol, RavaModifier_e modifier) {
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;
size_t local_index;
RavaType_t **param_types;
size_t param_count;
struct RavaSymbol_t *next;
struct RavaSymbol_t *hash_next;
} RavaSymbol_t;
@@ -63,9 +60,7 @@ void rava_symbol_destroy(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_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_signature_matches(RavaSymbol_t *method, RavaType_t **arg_types, size_t arg_count);
#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;
}
+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;
}
+4 -414
View File
@@ -1,355 +1,5 @@
#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) {
UNITTEST_BEGIN_TEST("TestObjects", "test_simple_object_example");
@@ -361,28 +11,6 @@ UnittestTestResult_t* test_simple_object_example(void) {
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) {
UnittestConfig_t *config = unittest_config_create();
config->verbosity = 2;
@@ -392,49 +20,11 @@ int main(int argc, char **argv) {
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");
unittest_test_case_add_result(tc_basic, test_simple_object_creation());
unittest_test_case_add_result(tc_basic, test_multiple_objects());
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);
UnittestTestCase_t *tc = unittest_test_case_create("TestObjects");
unittest_test_case_add_result(tc, test_simple_object_example());
unittest_test_suite_add_test_case(suite, tc);
unittest_generate_report(suite, config);
+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;
}
+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;
}
+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;
}
+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;
}
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) {
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_class(const char *class_name);
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);
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;
}
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