Compare commits
48
Commits
fa831d3b5f
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84ae385f2c | ||
|
|
d3122c98de | ||
|
|
f1cd4c11ef | ||
|
|
4e47d1d875 | ||
|
|
758399397a | ||
|
|
f30f58044c | ||
|
|
4ac83652a1 | ||
|
|
c678289045 | ||
|
|
827aacb5bb | ||
|
|
28c2ed7ed5 | ||
|
|
70819b2fad | ||
|
|
8d41fedf64 | ||
|
|
c07b6ce236 | ||
|
|
3269e63a90 | ||
|
|
5136a27601 | ||
|
|
1387088c8b | ||
|
|
639fe0b07c | ||
|
|
1287b7cc24 | ||
|
|
170a3832ea | ||
|
|
36f84fba17 | ||
|
|
8c0c82335e | ||
|
|
89f511d439 | ||
|
|
90c12006de | ||
|
|
7b240ff598 | ||
|
|
605c2bf8d3 | ||
|
|
18dd9eef8f | ||
|
|
0a368ed1c3 | ||
|
|
915e097a52 | ||
|
|
c880ff6b3f | ||
|
|
3247d6c40b | ||
|
|
ff9d95345c | ||
|
|
dfa37a2ee4 | ||
|
|
d86535ef5f | ||
|
|
b0bbbf1c53 | ||
|
|
d31a269819 | ||
|
|
e8fe2f8ff1 | ||
|
|
ce7624e693 | ||
|
|
ed69521892 | ||
|
|
e768ed066c | ||
|
|
f83de7abcd | ||
|
|
29c8b6d063 | ||
|
|
43103e7120 | ||
|
|
6dfbe4a4d0 | ||
|
|
d259e7a5b1 | ||
|
|
c09a0a41be | ||
|
|
0216064cf1 | ||
|
|
1e76fb7cc4 | ||
|
|
f9c7a0fa78 |
@@ -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_printer.c \
|
||||
parser/parser.c parser/parser_expressions.c parser/parser_statements.c parser/parser_declarations.c \
|
||||
types/types.c \
|
||||
semantic/symbol_table.c semantic/semantic.c \
|
||||
ir/ir.c ir/ir_gen.c \
|
||||
|
||||
@@ -6,3 +6,7 @@ merge.py
|
||||
*.o
|
||||
run_examples
|
||||
rava
|
||||
*.gcno
|
||||
*.gcda
|
||||
coverage_report
|
||||
*.info
|
||||
|
||||
@@ -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/parser_printer.c
|
||||
PARSER_SOURCES = parser/parser.c parser/parser_expressions.c parser/parser_statements.c parser/parser_declarations.c
|
||||
PARSER_OBJECTS = $(PARSER_SOURCES:.c=.o)
|
||||
|
||||
TYPES_SOURCES = types/types.c
|
||||
@@ -391,7 +391,125 @@ 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
|
||||
.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"
|
||||
|
||||
test: all
|
||||
@echo "=== Running All Tests ==="
|
||||
|
||||
@@ -0,0 +1,701 @@
|
||||
class Point {
|
||||
int x;
|
||||
int y;
|
||||
}
|
||||
|
||||
class Rectangle {
|
||||
int width;
|
||||
int height;
|
||||
int area;
|
||||
|
||||
Rectangle(int w, int h) {
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
this.area = w * h;
|
||||
}
|
||||
}
|
||||
|
||||
class Counter {
|
||||
int count;
|
||||
|
||||
Counter() {
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
void increment() {
|
||||
this.count = this.count + 1;
|
||||
}
|
||||
|
||||
int getCount() {
|
||||
return this.count;
|
||||
}
|
||||
}
|
||||
|
||||
class MathUtils {
|
||||
int x;
|
||||
}
|
||||
|
||||
class Animal {
|
||||
int name;
|
||||
|
||||
int speak() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
class Dog extends Animal {
|
||||
int breed;
|
||||
|
||||
int speak() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
class Cat extends Animal {
|
||||
int indoor;
|
||||
|
||||
int speak() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
interface Shape {
|
||||
int getArea();
|
||||
}
|
||||
|
||||
class Circle implements Shape {
|
||||
int radius;
|
||||
|
||||
Circle(int r) {
|
||||
this.radius = r;
|
||||
}
|
||||
|
||||
int getArea() {
|
||||
return (int)(3.14159 * this.radius * this.radius);
|
||||
}
|
||||
}
|
||||
|
||||
class Square implements Shape {
|
||||
int side;
|
||||
|
||||
Square(int s) {
|
||||
this.side = s;
|
||||
}
|
||||
|
||||
int getArea() {
|
||||
return this.side * this.side;
|
||||
}
|
||||
}
|
||||
|
||||
public class JavaKungFu {
|
||||
|
||||
static int staticCounter = 0;
|
||||
static int fibCalls = 0;
|
||||
|
||||
int instanceValue;
|
||||
|
||||
JavaKungFu() {
|
||||
this.instanceValue = 100;
|
||||
}
|
||||
|
||||
JavaKungFu(int val) {
|
||||
this.instanceValue = val;
|
||||
}
|
||||
|
||||
int getValue() {
|
||||
return this.instanceValue;
|
||||
}
|
||||
|
||||
void setValue(int v) {
|
||||
this.instanceValue = v;
|
||||
}
|
||||
|
||||
int add(int x) {
|
||||
return this.instanceValue + x;
|
||||
}
|
||||
|
||||
public static int square(int x) {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
public static int cube(int x) {
|
||||
return x * x * x;
|
||||
}
|
||||
|
||||
public static int fibonacci(int n) {
|
||||
JavaKungFu.fibCalls = JavaKungFu.fibCalls + 1;
|
||||
if (n <= 1) return n;
|
||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||
}
|
||||
|
||||
public static int factorial(int n) {
|
||||
if (n <= 1) return 1;
|
||||
return n * factorial(n - 1);
|
||||
}
|
||||
|
||||
public static int gcd(int a, int b) {
|
||||
if (b == 0) return a;
|
||||
return gcd(b, a % b);
|
||||
}
|
||||
|
||||
public static boolean isPrime(int n) {
|
||||
if (n <= 1) return false;
|
||||
if (n <= 3) return true;
|
||||
if (n % 2 == 0 || n % 3 == 0) return false;
|
||||
int i = 5;
|
||||
while (i * i <= n) {
|
||||
if (n % i == 0 || n % (i + 2) == 0) return false;
|
||||
i = i + 6;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void bubbleSort(int[] arr) {
|
||||
int n = arr.length;
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
for (int j = 0; j < n - i - 1; j++) {
|
||||
if (arr[j] > arr[j + 1]) {
|
||||
int temp = arr[j];
|
||||
arr[j] = arr[j + 1];
|
||||
arr[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int binarySearch(int[] arr, int target) {
|
||||
int left = 0;
|
||||
int right = arr.length - 1;
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
if (arr[mid] == target) return mid;
|
||||
if (arr[mid] < target) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean testPrimitiveTypes() {
|
||||
int i = 42;
|
||||
long l = 9876543210L;
|
||||
double d = 3.14159;
|
||||
boolean b = true;
|
||||
char c = 'A';
|
||||
if (i != 42) return false;
|
||||
if (l != 9876543210L) return false;
|
||||
if (d < 3.14 || d > 3.15) return false;
|
||||
if (b != true) return false;
|
||||
if (c != 'A') return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testArithmeticOperators() {
|
||||
int a = 20;
|
||||
int b = 6;
|
||||
if (a + b != 26) return false;
|
||||
if (a - b != 14) return false;
|
||||
if (a * b != 120) return false;
|
||||
if (a / b != 3) return false;
|
||||
if (a % b != 2) return false;
|
||||
if (-a != -20) return false;
|
||||
int x = 10;
|
||||
x += 5;
|
||||
if (x != 15) return false;
|
||||
x -= 3;
|
||||
if (x != 12) return false;
|
||||
x *= 2;
|
||||
if (x != 24) return false;
|
||||
x /= 4;
|
||||
if (x != 6) return false;
|
||||
int y = 5;
|
||||
if (++y != 6) return false;
|
||||
if (--y != 5) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testBitwiseOperators() {
|
||||
int a = 12;
|
||||
int b = 10;
|
||||
if ((a & b) != 8) return false;
|
||||
if ((a | b) != 14) return false;
|
||||
if ((a ^ b) != 6) return false;
|
||||
int c = 1;
|
||||
if ((c << 4) != 16) return false;
|
||||
if ((16 >> 2) != 4) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testComparisonOperators() {
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
int c = 10;
|
||||
if ((a == c) != true) return false;
|
||||
if ((a != b) != true) return false;
|
||||
if ((a < b) != true) return false;
|
||||
if ((a <= c) != true) return false;
|
||||
if ((b > a) != true) return false;
|
||||
if ((b >= a) != true) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testLogicalOperators() {
|
||||
boolean t = true;
|
||||
boolean f = false;
|
||||
if ((t && t) != true) return false;
|
||||
if ((t && f) != false) return false;
|
||||
if ((t || f) != true) return false;
|
||||
if ((f || f) != false) return false;
|
||||
if ((!t) != false) return false;
|
||||
if ((!f) != true) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testTernaryOperator() {
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
int max = a > b ? a : b;
|
||||
if (max != 20) return false;
|
||||
int min = a < b ? a : b;
|
||||
if (min != 10) return false;
|
||||
int nested = a > 5 ? (a > 15 ? 2 : 1) : 0;
|
||||
if (nested != 1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testIfElse() {
|
||||
int x = 15;
|
||||
int result = 0;
|
||||
if (x > 20) {
|
||||
result = 1;
|
||||
} else if (x > 10) {
|
||||
result = 2;
|
||||
} else if (x > 5) {
|
||||
result = 3;
|
||||
} else {
|
||||
result = 4;
|
||||
}
|
||||
if (result != 2) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testWhileLoop() {
|
||||
int sum = 0;
|
||||
int i = 1;
|
||||
while (i <= 10) {
|
||||
sum = sum + i;
|
||||
i = i + 1;
|
||||
}
|
||||
if (sum != 55) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testDoWhileLoop() {
|
||||
int count = 0;
|
||||
do {
|
||||
count = count + 1;
|
||||
} while (count < 5);
|
||||
if (count != 5) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testForLoop() {
|
||||
int sum = 0;
|
||||
for (int a = 0; a < 10; a++) {
|
||||
sum = sum + a;
|
||||
}
|
||||
if (sum != 45) return false;
|
||||
int nested = 0;
|
||||
for (int b = 0; b < 3; b++) {
|
||||
for (int c = 0; c < 3; c++) {
|
||||
nested = nested + 1;
|
||||
}
|
||||
}
|
||||
if (nested != 9) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testBreakContinue() {
|
||||
int sum = 0;
|
||||
for (int a = 0; a < 100; a++) {
|
||||
if (a >= 10) break;
|
||||
sum = sum + a;
|
||||
}
|
||||
if (sum != 45) return false;
|
||||
sum = 0;
|
||||
for (int b = 0; b < 10; b++) {
|
||||
if (b % 2 == 0) continue;
|
||||
sum = sum + b;
|
||||
}
|
||||
if (sum != 25) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testSwitchStatement() {
|
||||
int day = 3;
|
||||
int result = 0;
|
||||
switch (day) {
|
||||
case 1: result = 10; break;
|
||||
case 2: result = 20; break;
|
||||
case 3: result = 30; break;
|
||||
default: result = -1;
|
||||
}
|
||||
if (result != 30) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testArrays() {
|
||||
int[] arr = new int[5];
|
||||
arr[0] = 10;
|
||||
arr[1] = 20;
|
||||
arr[2] = 30;
|
||||
arr[3] = 40;
|
||||
arr[4] = 50;
|
||||
if (arr.length != 5) return false;
|
||||
if (arr[2] != 30) return false;
|
||||
int sum = 0;
|
||||
for (int a = 0; a < arr.length; a++) {
|
||||
sum = sum + arr[a];
|
||||
}
|
||||
if (sum != 150) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testEnhancedFor() {
|
||||
int[] numbers = {1, 2, 3, 4, 5};
|
||||
int sum = 0;
|
||||
for (int n : numbers) {
|
||||
sum = sum + n;
|
||||
}
|
||||
if (sum != 15) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testMultiDimArrays() {
|
||||
int[][] matrix = new int[3][3];
|
||||
for (int a = 0; a < 3; a++) {
|
||||
for (int b = 0; b < 3; b++) {
|
||||
matrix[a][b] = a * 3 + b;
|
||||
}
|
||||
}
|
||||
if (matrix[0][0] != 0) return false;
|
||||
if (matrix[1][1] != 4) return false;
|
||||
if (matrix[2][2] != 8) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testObjectCreation() {
|
||||
Point p1 = new Point();
|
||||
p1.x = 10;
|
||||
p1.y = 20;
|
||||
if (p1.x != 10) return false;
|
||||
if (p1.y != 20) return false;
|
||||
Rectangle r = new Rectangle(4, 5);
|
||||
if (r.width != 4) return false;
|
||||
if (r.height != 5) return false;
|
||||
if (r.area != 20) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testInstanceMethods() {
|
||||
Rectangle r = new Rectangle(10, 5);
|
||||
if (r.area != 50) return false;
|
||||
if (r.width != 10) return false;
|
||||
if (r.height != 5) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testStaticMembers() {
|
||||
JavaKungFu.staticCounter = 0;
|
||||
JavaKungFu.staticCounter = JavaKungFu.staticCounter + 1;
|
||||
JavaKungFu.staticCounter = JavaKungFu.staticCounter + 1;
|
||||
if (JavaKungFu.staticCounter != 2) return false;
|
||||
int result = square(5);
|
||||
if (result != 25) return false;
|
||||
result = cube(3);
|
||||
if (result != 27) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testInheritance() {
|
||||
Dog dog = new Dog();
|
||||
dog.name = 42;
|
||||
dog.breed = 7;
|
||||
if (dog.name != 42) return false;
|
||||
if (dog.breed != 7) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testMethodOverride() {
|
||||
Animal animal = new Animal();
|
||||
if (animal.speak() != 0) return false;
|
||||
Dog dog = new Dog();
|
||||
if (dog.speak() != 1) return false;
|
||||
Cat cat = new Cat();
|
||||
if (cat.speak() != 2) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testInterfaces() {
|
||||
Circle circle = new Circle(5);
|
||||
int area = circle.getArea();
|
||||
if (area < 75 || area > 79) return false;
|
||||
Square square = new Square(4);
|
||||
if (square.getArea() != 16) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testInstanceOf() {
|
||||
Dog dog = new Dog();
|
||||
boolean dogIsAnimal = dog instanceof Animal;
|
||||
boolean dogIsDog = dog instanceof Dog;
|
||||
if (dogIsAnimal != true) return false;
|
||||
if (dogIsDog != true) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testRecursion() {
|
||||
int fib10 = fibonacci(10);
|
||||
if (fib10 != 55) return false;
|
||||
int fact5 = factorial(5);
|
||||
if (fact5 != 120) return false;
|
||||
int gcdVal = gcd(48, 18);
|
||||
if (gcdVal != 6) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testMathLibrary() {
|
||||
if (Math.abs(-42) != 42) return false;
|
||||
if (Math.min(10, 20) != 10) return false;
|
||||
if (Math.max(10, 20) != 20) return false;
|
||||
double sqrt = Math.sqrt(16.0);
|
||||
if (sqrt < 3.99 || sqrt > 4.01) return false;
|
||||
double pow = Math.pow(2.0, 10.0);
|
||||
if (pow < 1023.0 || pow > 1025.0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testStringOperations() {
|
||||
String s = "Hello World";
|
||||
if (s.length() != 11) return false;
|
||||
if (s.charAt(0) != 'H') return false;
|
||||
String sub = s.substring(0, 5);
|
||||
if (sub.equals("Hello") == false) return false;
|
||||
if (s.indexOf("World") != 6) return false;
|
||||
if (s.contains("World") != true) return false;
|
||||
if (s.startsWith("Hello") != true) return false;
|
||||
if (s.endsWith("World") != true) return false;
|
||||
String upper = s.toUpperCase();
|
||||
if (upper.equals("HELLO WORLD") == false) return false;
|
||||
String concat = "Hello" + " " + "World";
|
||||
if (concat.equals("Hello World") == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testArrayList() {
|
||||
ArrayList list = new ArrayList();
|
||||
if (list.isEmpty() != true) return false;
|
||||
list.add(10);
|
||||
list.add(20);
|
||||
list.add(30);
|
||||
if (list.size() != 3) return false;
|
||||
if ((int)list.get(0) != 10) return false;
|
||||
if ((int)list.get(1) != 20) return false;
|
||||
list.set(1, 25);
|
||||
if ((int)list.get(1) != 25) return false;
|
||||
list.clear();
|
||||
if (list.size() != 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testHashMap() {
|
||||
HashMap map = new HashMap();
|
||||
map.put("one", 1);
|
||||
map.put("two", 2);
|
||||
map.put("three", 3);
|
||||
if (map.size() != 3) return false;
|
||||
if ((int)map.get("one") != 1) return false;
|
||||
if ((int)map.get("two") != 2) return false;
|
||||
if (map.containsKey("one") != true) return false;
|
||||
if (map.containsKey("four") != false) return false;
|
||||
map.put("two", 22);
|
||||
if ((int)map.get("two") != 22) return false;
|
||||
map.clear();
|
||||
if (map.size() != 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testExceptions() {
|
||||
int result = 0;
|
||||
try {
|
||||
throw 42;
|
||||
} catch (Exception e) {
|
||||
result = e;
|
||||
}
|
||||
if (result != 42) return false;
|
||||
result = 0;
|
||||
try {
|
||||
result = 1;
|
||||
} catch (Exception e) {
|
||||
result = -1;
|
||||
}
|
||||
if (result != 1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean testAlgorithms() {
|
||||
int[] arr = {64, 34, 25, 12, 22, 11, 90};
|
||||
bubbleSort(arr);
|
||||
for (int a = 0; a < arr.length - 1; a++) {
|
||||
if (arr[a] > arr[a + 1]) return false;
|
||||
}
|
||||
int[] sorted = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
|
||||
int idx = binarySearch(sorted, 11);
|
||||
if (idx != 5) return false;
|
||||
idx = binarySearch(sorted, 10);
|
||||
if (idx != -1) return false;
|
||||
if (isPrime(17) == false) return false;
|
||||
if (isPrime(18) == true) return false;
|
||||
if (isPrime(2) == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int main() {
|
||||
System.out.println("=== JAVA KUNG-FU DEMONSTRATION ===");
|
||||
System.out.println("");
|
||||
|
||||
int totalTests = 0;
|
||||
int passedTests = 0;
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testPrimitiveTypes() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Primitive Types"); }
|
||||
else { System.out.println("[FAIL] Primitive Types"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testArithmeticOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Arithmetic Operators"); }
|
||||
else { System.out.println("[FAIL] Arithmetic Operators"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testBitwiseOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Bitwise Operators"); }
|
||||
else { System.out.println("[FAIL] Bitwise Operators"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testComparisonOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Comparison Operators"); }
|
||||
else { System.out.println("[FAIL] Comparison Operators"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testLogicalOperators() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Logical Operators"); }
|
||||
else { System.out.println("[FAIL] Logical Operators"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testTernaryOperator() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Ternary Operator"); }
|
||||
else { System.out.println("[FAIL] Ternary Operator"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testIfElse() == true) { passedTests = passedTests + 1; System.out.println("[PASS] If-Else Statements"); }
|
||||
else { System.out.println("[FAIL] If-Else Statements"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testWhileLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] While Loop"); }
|
||||
else { System.out.println("[FAIL] While Loop"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testDoWhileLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Do-While Loop"); }
|
||||
else { System.out.println("[FAIL] Do-While Loop"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testForLoop() == true) { passedTests = passedTests + 1; System.out.println("[PASS] For Loop"); }
|
||||
else { System.out.println("[FAIL] For Loop"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testBreakContinue() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Break/Continue"); }
|
||||
else { System.out.println("[FAIL] Break/Continue"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testSwitchStatement() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Switch Statement"); }
|
||||
else { System.out.println("[FAIL] Switch Statement"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testArrays() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Arrays"); }
|
||||
else { System.out.println("[FAIL] Arrays"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testEnhancedFor() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Enhanced For Loop"); }
|
||||
else { System.out.println("[FAIL] Enhanced For Loop"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testMultiDimArrays() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Multi-Dimensional Arrays"); }
|
||||
else { System.out.println("[FAIL] Multi-Dimensional Arrays"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testObjectCreation() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Object Creation"); }
|
||||
else { System.out.println("[FAIL] Object Creation"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testInstanceMethods() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Instance Methods"); }
|
||||
else { System.out.println("[FAIL] Instance Methods"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testStaticMembers() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Static Members"); }
|
||||
else { System.out.println("[FAIL] Static Members"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testInheritance() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Inheritance"); }
|
||||
else { System.out.println("[FAIL] Inheritance"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testMethodOverride() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Method Override"); }
|
||||
else { System.out.println("[FAIL] Method Override"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testInterfaces() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Interfaces"); }
|
||||
else { System.out.println("[FAIL] Interfaces"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testInstanceOf() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Instanceof"); }
|
||||
else { System.out.println("[FAIL] Instanceof"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testRecursion() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Recursion"); }
|
||||
else { System.out.println("[FAIL] Recursion"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testMathLibrary() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Math Library"); }
|
||||
else { System.out.println("[FAIL] Math Library"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testStringOperations() == true) { passedTests = passedTests + 1; System.out.println("[PASS] String Operations"); }
|
||||
else { System.out.println("[FAIL] String Operations"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testArrayList() == true) { passedTests = passedTests + 1; System.out.println("[PASS] ArrayList"); }
|
||||
else { System.out.println("[FAIL] ArrayList"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testHashMap() == true) { passedTests = passedTests + 1; System.out.println("[PASS] HashMap"); }
|
||||
else { System.out.println("[FAIL] HashMap"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testExceptions() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Exceptions"); }
|
||||
else { System.out.println("[FAIL] Exceptions"); }
|
||||
|
||||
totalTests = totalTests + 1;
|
||||
if (testAlgorithms() == true) { passedTests = passedTests + 1; System.out.println("[PASS] Algorithms"); }
|
||||
else { System.out.println("[FAIL] Algorithms"); }
|
||||
|
||||
System.out.println("");
|
||||
System.out.println("=== RESULTS ===");
|
||||
System.out.print("Passed: ");
|
||||
System.out.print(passedTests);
|
||||
System.out.print(" / ");
|
||||
System.out.println(totalTests);
|
||||
|
||||
if (passedTests == totalTests) {
|
||||
System.out.println("ALL TESTS PASSED!");
|
||||
}
|
||||
|
||||
return passedTests == totalTests ? 0 : 1;
|
||||
}
|
||||
}
|
||||
+54
-13
@@ -325,9 +325,23 @@ static bool _rava_vm_execute_instruction(RavaVM_t *vm, RavaCallFrame_t *frame, R
|
||||
break;
|
||||
|
||||
case RAVA_OP_CALL_STATIC: {
|
||||
RavaMethod_t *method = _rava_vm_find_method_cached(vm,
|
||||
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,
|
||||
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);
|
||||
@@ -339,7 +353,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 = instr->operand.call.arg_count - 1; i >= 0; i--) {
|
||||
for (int i = arg_count - 1; i >= 0; i--) {
|
||||
new_frame->locals[i] = rava_stack_pop(stack);
|
||||
}
|
||||
|
||||
@@ -387,7 +401,11 @@ 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_cached(vm, class_name, instr->operand.call.method_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);
|
||||
}
|
||||
if (!method) {
|
||||
if (strcmp(instr->operand.call.method_name, "<init>") == 0 && instr->operand.call.arg_count == 0) {
|
||||
break;
|
||||
@@ -467,7 +485,11 @@ 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_cached(vm, super_class, instr->operand.call.method_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);
|
||||
}
|
||||
if (!method) {
|
||||
vm->had_error = true;
|
||||
vm->error_message = malloc(RAVA_ERROR_BUFFER_SIZE);
|
||||
@@ -2708,7 +2730,7 @@ op_instanceof: {
|
||||
RavaValue_t val = STACK_POP(stack);
|
||||
bool result = false;
|
||||
if (val.type == RAVA_VAL_OBJECT && val.data.object_val) {
|
||||
result = strcmp(val.data.object_val->class_name, instr->operand.string_value) == 0;
|
||||
result = _rava_vm_instanceof(vm, val.data.object_val->class_name, instr->operand.string_value);
|
||||
}
|
||||
STACK_PUSH(stack, rava_value_boolean(result));
|
||||
DISPATCH();
|
||||
@@ -3640,8 +3662,23 @@ uf_label:
|
||||
|
||||
uf_call:
|
||||
uf_call_static: {
|
||||
RavaMethod_t *target = _rava_vm_find_method_cached(vm,
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (!target) {
|
||||
vm->had_error = true;
|
||||
goto uf_done;
|
||||
@@ -3650,10 +3687,6 @@ 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) {
|
||||
@@ -3767,7 +3800,11 @@ 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_cached(vm, class_name, instr->operand.call.method_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);
|
||||
}
|
||||
if (!target) {
|
||||
if (strcmp(mname, "<init>") == 0 && arg_count == 0) {
|
||||
UF_DISPATCH();
|
||||
@@ -3824,7 +3861,11 @@ 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_cached(vm, super_class, instr->operand.call.method_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);
|
||||
}
|
||||
if (!target) {
|
||||
vm->had_error = true;
|
||||
goto uf_done;
|
||||
@@ -4323,7 +4364,7 @@ uf_instanceof: {
|
||||
if (rava_nanbox_is_object(val)) {
|
||||
RavaObject_t *obj = rava_nanbox_as_object(val);
|
||||
if (obj) {
|
||||
result = strcmp(obj->class_name, instr->operand.string_value) == 0;
|
||||
result = _rava_vm_instanceof(vm, obj->class_name, instr->operand.string_value);
|
||||
}
|
||||
}
|
||||
UF_PUSH(rava_nanbox_bool(result));
|
||||
|
||||
@@ -151,9 +151,11 @@ 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);
|
||||
|
||||
@@ -19,6 +19,19 @@ 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;
|
||||
@@ -119,3 +132,15 @@ 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);
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
+414
-4
@@ -1,5 +1,355 @@
|
||||
#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");
|
||||
|
||||
@@ -11,6 +361,28 @@ 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;
|
||||
@@ -20,11 +392,49 @@ int main(int argc, char **argv) {
|
||||
config->use_colors = false;
|
||||
}
|
||||
|
||||
UnittestTestSuite_t *suite = unittest_test_suite_create("Object Example Tests");
|
||||
UnittestTestSuite_t *suite = unittest_test_suite_create("Object Tests");
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
unittest_generate_report(suite, config);
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -19,14 +19,4 @@ 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
|
||||
|
||||
Reference in New Issue
Block a user