#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;
}