Update, finaly an interpreter.
This commit is contained in:
parent
faec0e0d9e
commit
f7df28e897
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ merge.py
|
||||
/test_*
|
||||
*.o
|
||||
run_examples
|
||||
rava
|
||||
|
||||
16
Makefile
16
Makefile
@ -302,6 +302,18 @@ benchmark: test_benchmark
|
||||
@python3 examples/benchmark.py
|
||||
@echo ""
|
||||
|
||||
rava: rava.o $(LEXER_OBJECTS) $(PARSER_OBJECTS) $(TYPES_OBJECTS) $(SEMANTIC_OBJECTS) $(IR_OBJECTS) $(RUNTIME_OBJECTS) $(LOADER_OBJECTS)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
examples: rava
|
||||
@echo "=== Running All Examples ==="
|
||||
@for f in examples/*.java; do \
|
||||
echo "--- $$f ---"; \
|
||||
./rava "$$f" || true; \
|
||||
echo ""; \
|
||||
done
|
||||
@echo "=== Examples Complete ==="
|
||||
|
||||
test_nanbox: tests/test_nanbox.c runtime/nanbox.h $(UNITTEST_OBJECTS)
|
||||
$(CC) $(CFLAGS) -o $@ tests/test_nanbox.c $(UNITTEST_OBJECTS) $(LDFLAGS)
|
||||
|
||||
@ -347,9 +359,9 @@ clean:
|
||||
$(TEST_STRINGS_OBJECTS) $(TEST_ARRAYS_OBJECTS) $(TEST_OBJECTS_OBJECTS) $(TEST_INSTANCE_OBJECTS) $(TEST_FILEIO_OBJECTS) \
|
||||
$(TEST_DOWHILE_OBJECTS) $(TEST_SWITCH_OBJECTS) $(TEST_MATH_OBJECTS) $(TEST_STRING_METHODS_OBJECTS) $(TEST_STATIC_OBJECTS) $(TEST_INTERFACES_OBJECTS) $(TEST_EXCEPTIONS_OBJECTS) $(TEST_TERNARY_OBJECTS) $(TEST_BITWISE_OBJECTS) $(TEST_ENHANCED_FOR_OBJECTS) $(TEST_ARRAY_INIT_OBJECTS) $(TEST_INSTANCEOF_OBJECTS) $(TEST_SHORTCIRCUIT_OBJECTS) $(TEST_MULTIDIM_ARRAYS_OBJECTS) $(TEST_STATIC_INIT_OBJECTS) $(TEST_NEGATIVE_OBJECTS) $(TEST_ENUMS_OBJECTS) $(TEST_COLLECTIONS_OBJECTS) $(TEST_SUPER_OBJECTS) $(TEST_INHERITANCE_OBJECTS) $(TEST_BREAK_OBJECTS) $(TEST_ELSEIF_OBJECTS) $(TEST_FORLOOP_OBJECTS) $(TEST_PRINTLN_OBJECTS) $(TEST_LOADER_OBJECTS) $(TEST_OBJECT_METHODS_OBJECTS) $(TEST_AUTOBOX_OBJECTS) $(TEST_SOCKETS_OBJECTS) $(TEST_METHOD_REF_OBJECTS) $(TEST_GC_OBJECTS) $(TEST_BENCHMARK_OBJECTS) \
|
||||
test_lexer test_parser test_semantic test_ir test_runtime test_strings test_arrays test_objects test_instance_methods test_fileio test_dowhile test_switch test_math test_string_methods test_static test_interfaces test_exceptions test_ternary test_bitwise test_enhanced_for test_array_init test_instanceof test_shortcircuit test_multidim_arrays test_static_init test_negative test_enums test_collections test_super test_inheritance test_break test_elseif test_forloop test_println test_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 *.gcda */*.gcda
|
||||
test_nanbox test_fastframe test_labeltable test_methodcache test_benchmark_pgo test_unittest_demo rava rava.o *.gcda */*.gcda
|
||||
|
||||
.PHONY: all clean benchmark test_phase0 pgo test_benchmark_pgo_gen pgo_run test_benchmark_pgo test
|
||||
.PHONY: all clean benchmark test_phase0 pgo test_benchmark_pgo_gen pgo_run test_benchmark_pgo test examples
|
||||
|
||||
test: all
|
||||
@echo "=== Running All Tests ==="
|
||||
|
||||
112
rava.c
Normal file
112
rava.c
Normal file
@ -0,0 +1,112 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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"
|
||||
|
||||
static char* read_file(const char *filename) {
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
fseek(file, 0, SEEK_END);
|
||||
long size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
char *content = malloc(size + 1);
|
||||
if (!content) {
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
size_t read_bytes = fread(content, 1, size, file);
|
||||
content[read_bytes] = '\0';
|
||||
fclose(file);
|
||||
return content;
|
||||
}
|
||||
|
||||
static const char* find_main_class(const char *source) {
|
||||
static char class_name[256];
|
||||
const char *p = strstr(source, "public static");
|
||||
if (!p) p = strstr(source, "static public");
|
||||
if (!p) return "Main";
|
||||
|
||||
while (p > source) {
|
||||
p--;
|
||||
if (strncmp(p, "class ", 6) == 0) {
|
||||
p += 6;
|
||||
while (*p == ' ') p++;
|
||||
int i = 0;
|
||||
while (*p && *p != ' ' && *p != '{' && *p != '\n' && i < 255) {
|
||||
class_name[i++] = *p++;
|
||||
}
|
||||
class_name[i] = '\0';
|
||||
return class_name;
|
||||
}
|
||||
}
|
||||
return "Main";
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <file.java> [class] [method]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *source = read_file(argv[1]);
|
||||
if (!source) return 1;
|
||||
|
||||
const char *class_name = argc > 2 ? argv[2] : find_main_class(source);
|
||||
const char *method_name = argc > 3 ? argv[3] : "main";
|
||||
|
||||
RavaLexer_t *lexer = rava_lexer_create(source);
|
||||
RavaParser_t *parser = rava_parser_create(lexer);
|
||||
RavaASTNode_t *ast = rava_parser_parse(parser);
|
||||
|
||||
if (!ast || parser->had_error) {
|
||||
fprintf(stderr, "Parse error: %s\n", parser->error_message ? parser->error_message : "unknown");
|
||||
free(source);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RavaSemanticAnalyzer_t *analyzer = rava_semantic_analyzer_create();
|
||||
if (!rava_semantic_analyze(analyzer, ast)) {
|
||||
fprintf(stderr, "Semantic error: %s\n", analyzer->error_message ? analyzer->error_message : "unknown");
|
||||
free(source);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RavaIRGenerator_t *ir_gen = rava_ir_generator_create(analyzer);
|
||||
RavaProgram_t *program = rava_ir_generate(ir_gen, ast);
|
||||
if (!program) {
|
||||
fprintf(stderr, "IR generation failed\n");
|
||||
free(source);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RavaVM_t *vm = rava_vm_create(program);
|
||||
if (!rava_vm_execute(vm, class_name, method_name)) {
|
||||
fprintf(stderr, "Runtime error: %s\n", vm->error_message ? vm->error_message : "unknown");
|
||||
free(source);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RavaValue_t result = rava_vm_get_result(vm);
|
||||
if (result.type == RAVA_VAL_INT) {
|
||||
return (int)result.data.int_val;
|
||||
}
|
||||
|
||||
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 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user