279 lines
8.4 KiB
C
279 lines
8.4 KiB
C
|
|
#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 int test_count = 0;
|
||
|
|
static int pass_count = 0;
|
||
|
|
|
||
|
|
static int run_test(const char *name, const char *source, int expected) {
|
||
|
|
test_count++;
|
||
|
|
|
||
|
|
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("FAIL: %s (parse error)\n", name);
|
||
|
|
rava_parser_destroy(parser);
|
||
|
|
rava_lexer_destroy(lexer);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create();
|
||
|
|
if (!rava_semantic_analyze(analyzer, ast)) {
|
||
|
|
printf("FAIL: %s (semantic error)\n", name);
|
||
|
|
rava_semantic_analyzer_destroy(analyzer);
|
||
|
|
rava_ast_node_destroy(ast);
|
||
|
|
rava_parser_destroy(parser);
|
||
|
|
rava_lexer_destroy(lexer);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
RavaIRGenerator_t *ir_gen = rava_ir_generator_create(analyzer);
|
||
|
|
RavaProgram_t *program = rava_ir_generate(ir_gen, ast);
|
||
|
|
|
||
|
|
if (!program) {
|
||
|
|
printf("FAIL: %s (IR error)\n", name);
|
||
|
|
rava_ir_generator_destroy(ir_gen);
|
||
|
|
rava_semantic_analyzer_destroy(analyzer);
|
||
|
|
rava_ast_node_destroy(ast);
|
||
|
|
rava_parser_destroy(parser);
|
||
|
|
rava_lexer_destroy(lexer);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
RavaVM_t *vm = rava_vm_create(program);
|
||
|
|
|
||
|
|
if (!rava_vm_execute(vm, "Test", "main")) {
|
||
|
|
printf("FAIL: %s (runtime error)\n", name);
|
||
|
|
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);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
RavaValue_t result = rava_vm_get_result(vm);
|
||
|
|
int actual = rava_value_as_int(result);
|
||
|
|
|
||
|
|
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);
|
||
|
|
|
||
|
|
if (actual == expected) {
|
||
|
|
printf("PASS: %s\n", name);
|
||
|
|
pass_count++;
|
||
|
|
return 1;
|
||
|
|
} else {
|
||
|
|
printf("FAIL: %s (expected %d, got %d)\n", name, expected, actual);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(void) {
|
||
|
|
printf("=== ArrayList Tests ===\n");
|
||
|
|
|
||
|
|
run_test("ArrayList create and size",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" return list.size();\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 0);
|
||
|
|
|
||
|
|
run_test("ArrayList add and size",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" list.add(10);\n"
|
||
|
|
" list.add(20);\n"
|
||
|
|
" list.add(30);\n"
|
||
|
|
" return list.size();\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 3);
|
||
|
|
|
||
|
|
run_test("ArrayList add and get",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" list.add(42);\n"
|
||
|
|
" return list.get(0);\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 42);
|
||
|
|
|
||
|
|
run_test("ArrayList set",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" list.add(10);\n"
|
||
|
|
" list.set(0, 99);\n"
|
||
|
|
" return list.get(0);\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 99);
|
||
|
|
|
||
|
|
run_test("ArrayList isEmpty true",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" if (list.isEmpty()) {\n"
|
||
|
|
" return 1;\n"
|
||
|
|
" }\n"
|
||
|
|
" return 0;\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 1);
|
||
|
|
|
||
|
|
run_test("ArrayList isEmpty false",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" list.add(1);\n"
|
||
|
|
" if (list.isEmpty()) {\n"
|
||
|
|
" return 1;\n"
|
||
|
|
" }\n"
|
||
|
|
" return 0;\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 0);
|
||
|
|
|
||
|
|
run_test("ArrayList clear",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" list.add(1);\n"
|
||
|
|
" list.add(2);\n"
|
||
|
|
" list.clear();\n"
|
||
|
|
" return list.size();\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 0);
|
||
|
|
|
||
|
|
run_test("ArrayList remove",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" list.add(10);\n"
|
||
|
|
" list.add(20);\n"
|
||
|
|
" list.add(30);\n"
|
||
|
|
" int removed = list.remove(1);\n"
|
||
|
|
" return removed;\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 20);
|
||
|
|
|
||
|
|
run_test("ArrayList sum elements",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" ArrayList list = new ArrayList();\n"
|
||
|
|
" list.add(1);\n"
|
||
|
|
" list.add(2);\n"
|
||
|
|
" list.add(3);\n"
|
||
|
|
" list.add(4);\n"
|
||
|
|
" int sum = 0;\n"
|
||
|
|
" for (int i = 0; i < list.size(); i = i + 1) {\n"
|
||
|
|
" sum = sum + list.get(i);\n"
|
||
|
|
" }\n"
|
||
|
|
" return sum;\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 10);
|
||
|
|
|
||
|
|
printf("\n=== HashMap Tests ===\n");
|
||
|
|
|
||
|
|
run_test("HashMap create and size",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" HashMap map = new HashMap();\n"
|
||
|
|
" return map.size();\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 0);
|
||
|
|
|
||
|
|
run_test("HashMap put and size",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" HashMap map = new HashMap();\n"
|
||
|
|
" map.put(\"a\", 1);\n"
|
||
|
|
" map.put(\"b\", 2);\n"
|
||
|
|
" return map.size();\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 2);
|
||
|
|
|
||
|
|
run_test("HashMap put and get",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" HashMap map = new HashMap();\n"
|
||
|
|
" map.put(\"key\", 42);\n"
|
||
|
|
" return map.get(\"key\");\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 42);
|
||
|
|
|
||
|
|
run_test("HashMap containsKey true",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" HashMap map = new HashMap();\n"
|
||
|
|
" map.put(\"test\", 99);\n"
|
||
|
|
" if (map.containsKey(\"test\")) {\n"
|
||
|
|
" return 1;\n"
|
||
|
|
" }\n"
|
||
|
|
" return 0;\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 1);
|
||
|
|
|
||
|
|
run_test("HashMap containsKey false",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" HashMap map = new HashMap();\n"
|
||
|
|
" map.put(\"test\", 99);\n"
|
||
|
|
" if (map.containsKey(\"other\")) {\n"
|
||
|
|
" return 1;\n"
|
||
|
|
" }\n"
|
||
|
|
" return 0;\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 0);
|
||
|
|
|
||
|
|
run_test("HashMap remove",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" HashMap map = new HashMap();\n"
|
||
|
|
" map.put(\"a\", 10);\n"
|
||
|
|
" map.put(\"b\", 20);\n"
|
||
|
|
" int removed = map.remove(\"a\");\n"
|
||
|
|
" return removed + map.size();\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 11);
|
||
|
|
|
||
|
|
run_test("HashMap clear",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" HashMap map = new HashMap();\n"
|
||
|
|
" map.put(\"x\", 1);\n"
|
||
|
|
" map.put(\"y\", 2);\n"
|
||
|
|
" map.clear();\n"
|
||
|
|
" return map.size();\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 0);
|
||
|
|
|
||
|
|
run_test("HashMap update value",
|
||
|
|
"public class Test {\n"
|
||
|
|
" public static int main() {\n"
|
||
|
|
" HashMap map = new HashMap();\n"
|
||
|
|
" map.put(\"key\", 10);\n"
|
||
|
|
" map.put(\"key\", 20);\n"
|
||
|
|
" return map.get(\"key\");\n"
|
||
|
|
" }\n"
|
||
|
|
"}\n", 20);
|
||
|
|
|
||
|
|
printf("\n=== Results ===\n");
|
||
|
|
printf("Passed: %d/%d\n", pass_count, test_count);
|
||
|
|
|
||
|
|
return (pass_count == test_count) ? 0 : 1;
|
||
|
|
}
|