chore: remove trailing whitespace from README.md line 42
This commit is contained in:
@@ -265,6 +265,21 @@ static const char* _rava_opcode_name(RavaOpCode_e opcode) {
|
||||
case RAVA_OP_DUP: return "DUP";
|
||||
case RAVA_OP_PRINT: return "PRINT";
|
||||
case RAVA_OP_PRINTLN: return "PRINTLN";
|
||||
case RAVA_OP_ARRAYLIST_NEW: return "ARRAYLIST_NEW";
|
||||
case RAVA_OP_ARRAYLIST_ADD: return "ARRAYLIST_ADD";
|
||||
case RAVA_OP_ARRAYLIST_GET: return "ARRAYLIST_GET";
|
||||
case RAVA_OP_ARRAYLIST_SET: return "ARRAYLIST_SET";
|
||||
case RAVA_OP_ARRAYLIST_SIZE: return "ARRAYLIST_SIZE";
|
||||
case RAVA_OP_ARRAYLIST_REMOVE: return "ARRAYLIST_REMOVE";
|
||||
case RAVA_OP_ARRAYLIST_CLEAR: return "ARRAYLIST_CLEAR";
|
||||
case RAVA_OP_ARRAYLIST_ISEMPTY: return "ARRAYLIST_ISEMPTY";
|
||||
case RAVA_OP_HASHMAP_NEW: return "HASHMAP_NEW";
|
||||
case RAVA_OP_HASHMAP_PUT: return "HASHMAP_PUT";
|
||||
case RAVA_OP_HASHMAP_GET: return "HASHMAP_GET";
|
||||
case RAVA_OP_HASHMAP_REMOVE: return "HASHMAP_REMOVE";
|
||||
case RAVA_OP_HASHMAP_SIZE: return "HASHMAP_SIZE";
|
||||
case RAVA_OP_HASHMAP_CONTAINSKEY: return "HASHMAP_CONTAINSKEY";
|
||||
case RAVA_OP_HASHMAP_CLEAR: return "HASHMAP_CLEAR";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,24 @@ typedef enum {
|
||||
RAVA_OP_MATH_TAN,
|
||||
RAVA_OP_MATH_LOG,
|
||||
RAVA_OP_MATH_EXP,
|
||||
RAVA_OP_MATH_RANDOM
|
||||
RAVA_OP_MATH_RANDOM,
|
||||
|
||||
RAVA_OP_ARRAYLIST_NEW,
|
||||
RAVA_OP_ARRAYLIST_ADD,
|
||||
RAVA_OP_ARRAYLIST_GET,
|
||||
RAVA_OP_ARRAYLIST_SET,
|
||||
RAVA_OP_ARRAYLIST_SIZE,
|
||||
RAVA_OP_ARRAYLIST_REMOVE,
|
||||
RAVA_OP_ARRAYLIST_CLEAR,
|
||||
RAVA_OP_ARRAYLIST_ISEMPTY,
|
||||
|
||||
RAVA_OP_HASHMAP_NEW,
|
||||
RAVA_OP_HASHMAP_PUT,
|
||||
RAVA_OP_HASHMAP_GET,
|
||||
RAVA_OP_HASHMAP_REMOVE,
|
||||
RAVA_OP_HASHMAP_SIZE,
|
||||
RAVA_OP_HASHMAP_CONTAINSKEY,
|
||||
RAVA_OP_HASHMAP_CLEAR
|
||||
} RavaOpCode_e;
|
||||
|
||||
typedef union {
|
||||
@@ -212,6 +229,7 @@ typedef struct {
|
||||
size_t method_count;
|
||||
size_t method_capacity;
|
||||
int method_hash[RAVA_METHOD_HASH_SIZE];
|
||||
bool is_enum;
|
||||
} RavaClass_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
+151
-11
@@ -426,18 +426,27 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
_rava_ir_emit(gen, instr);
|
||||
}
|
||||
} else if (expr->data.new_expr.type) {
|
||||
instr.opcode = RAVA_OP_NEW;
|
||||
instr.operand.call.class_name = strdup(expr->data.new_expr.type->data.type.type_name);
|
||||
instr.operand.call.arg_count = expr->data.new_expr.arguments_count;
|
||||
_rava_ir_emit(gen, instr);
|
||||
instr.opcode = RAVA_OP_DUP;
|
||||
_rava_ir_emit(gen, instr);
|
||||
for (size_t i = 0; i < expr->data.new_expr.arguments_count; i++) {
|
||||
_rava_ir_gen_expression(gen, expr->data.new_expr.arguments[i]);
|
||||
const char *type_name = expr->data.new_expr.type->data.type.type_name;
|
||||
if (strcmp(type_name, "ArrayList") == 0) {
|
||||
instr.opcode = RAVA_OP_ARRAYLIST_NEW;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (strcmp(type_name, "HashMap") == 0) {
|
||||
instr.opcode = RAVA_OP_HASHMAP_NEW;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else {
|
||||
instr.opcode = RAVA_OP_NEW;
|
||||
instr.operand.call.class_name = strdup(type_name);
|
||||
instr.operand.call.arg_count = expr->data.new_expr.arguments_count;
|
||||
_rava_ir_emit(gen, instr);
|
||||
instr.opcode = RAVA_OP_DUP;
|
||||
_rava_ir_emit(gen, instr);
|
||||
for (size_t i = 0; i < expr->data.new_expr.arguments_count; i++) {
|
||||
_rava_ir_gen_expression(gen, expr->data.new_expr.arguments[i]);
|
||||
}
|
||||
instr.opcode = RAVA_OP_CALL_VIRTUAL;
|
||||
instr.operand.call.method_name = strdup("<init>");
|
||||
_rava_ir_emit(gen, instr);
|
||||
}
|
||||
instr.opcode = RAVA_OP_CALL_VIRTUAL;
|
||||
instr.operand.call.method_name = strdup("<init>");
|
||||
_rava_ir_emit(gen, instr);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -476,7 +485,17 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
bool is_math_log = false;
|
||||
bool is_math_exp = false;
|
||||
bool is_math_random = false;
|
||||
bool is_arraylist_add = false;
|
||||
bool is_arraylist_get = false;
|
||||
bool is_arraylist_set = false;
|
||||
bool is_arraylist_size = false;
|
||||
bool is_arraylist_remove = false;
|
||||
bool is_arraylist_clear = false;
|
||||
bool is_arraylist_isempty = false;
|
||||
bool is_hashmap_put = false;
|
||||
bool is_hashmap_containskey = false;
|
||||
RavaASTNode_t *string_object = NULL;
|
||||
RavaASTNode_t *collection_object = NULL;
|
||||
|
||||
if (expr->data.call.callee->type == RAVA_AST_MEMBER_ACCESS_EXPR) {
|
||||
RavaASTNode_t *member = expr->data.call.callee;
|
||||
@@ -581,6 +600,33 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
} else if (strcmp(member->data.member_access.member, "trim") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_string_trim = true;
|
||||
string_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "add") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_arraylist_add = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "get") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_arraylist_get = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "set") == 0 && expr->data.call.arguments_count == 2) {
|
||||
is_arraylist_set = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "size") == 0 && expr->data.call.arguments_count == 0 && !is_string_length) {
|
||||
is_arraylist_size = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "remove") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_arraylist_remove = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "clear") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_arraylist_clear = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "isEmpty") == 0 && expr->data.call.arguments_count == 0) {
|
||||
is_arraylist_isempty = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "put") == 0 && expr->data.call.arguments_count == 2) {
|
||||
is_hashmap_put = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
} else if (strcmp(member->data.member_access.member, "containsKey") == 0 && expr->data.call.arguments_count == 1) {
|
||||
is_hashmap_containskey = true;
|
||||
collection_object = member->data.member_access.object;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -722,6 +768,50 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
|
||||
} else if (is_math_random) {
|
||||
instr.opcode = RAVA_OP_MATH_RANDOM;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_arraylist_add) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_ARRAYLIST_ADD;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_arraylist_get) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_ARRAYLIST_GET;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_arraylist_set) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[1]);
|
||||
instr.opcode = RAVA_OP_ARRAYLIST_SET;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_arraylist_size) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
instr.opcode = RAVA_OP_ARRAYLIST_SIZE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_arraylist_remove) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_ARRAYLIST_REMOVE;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_arraylist_clear) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
instr.opcode = RAVA_OP_ARRAYLIST_CLEAR;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_arraylist_isempty) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
instr.opcode = RAVA_OP_ARRAYLIST_ISEMPTY;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_hashmap_put) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[1]);
|
||||
instr.opcode = RAVA_OP_HASHMAP_PUT;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_hashmap_containskey) {
|
||||
_rava_ir_gen_expression(gen, collection_object);
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
|
||||
instr.opcode = RAVA_OP_HASHMAP_CONTAINSKEY;
|
||||
_rava_ir_emit(gen, instr);
|
||||
} else if (is_println || is_print) {
|
||||
for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
|
||||
_rava_ir_gen_expression(gen, expr->data.call.arguments[i]);
|
||||
@@ -1488,6 +1578,54 @@ static void _rava_ir_gen_class(RavaIRGenerator_t *gen, RavaASTNode_t *class_node
|
||||
gen->current_class = NULL;
|
||||
}
|
||||
|
||||
static void _rava_ir_gen_enum(RavaIRGenerator_t *gen, RavaASTNode_t *enum_node) {
|
||||
if (enum_node->type != RAVA_AST_ENUM_DECL) return;
|
||||
|
||||
RavaClass_t *class = rava_class_create(enum_node->data.enum_decl.name);
|
||||
class->is_enum = true;
|
||||
gen->current_class = class;
|
||||
|
||||
rava_symbol_table_enter_scope(gen->analyzer->symbol_table, enum_node->data.enum_decl.name);
|
||||
|
||||
if (enum_node->data.enum_decl.constants_count > 0) {
|
||||
RavaMethod_t *clinit = rava_method_create("<clinit>", NULL);
|
||||
gen->current_method = clinit;
|
||||
gen->next_local = 0;
|
||||
_rava_ir_clear_locals(gen);
|
||||
|
||||
RavaInstruction_t instr = {0};
|
||||
for (size_t i = 0; i < enum_node->data.enum_decl.constants_count; i++) {
|
||||
instr.opcode = RAVA_OP_LOAD_CONST;
|
||||
instr.operand.int_value = (int32_t)i;
|
||||
_rava_ir_emit(gen, instr);
|
||||
|
||||
instr.opcode = RAVA_OP_STORE_STATIC;
|
||||
instr.operand.field.class_name = strdup(enum_node->data.enum_decl.name);
|
||||
instr.operand.field.field_name = strdup(enum_node->data.enum_decl.constants[i]);
|
||||
_rava_ir_emit(gen, instr);
|
||||
}
|
||||
|
||||
instr.opcode = RAVA_OP_RETURN_VOID;
|
||||
_rava_ir_emit(gen, instr);
|
||||
clinit->local_count = gen->next_local;
|
||||
rava_class_add_method(gen->current_class, clinit);
|
||||
gen->current_method = NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < enum_node->children_count; i++) {
|
||||
RavaASTNode_t *child = enum_node->children[i];
|
||||
|
||||
if (child->type == RAVA_AST_METHOD_DECL) {
|
||||
_rava_ir_gen_method(gen, child);
|
||||
}
|
||||
}
|
||||
|
||||
rava_symbol_table_exit_scope(gen->analyzer->symbol_table);
|
||||
|
||||
rava_program_add_class(gen->program, class);
|
||||
gen->current_class = NULL;
|
||||
}
|
||||
|
||||
RavaProgram_t* rava_ir_generate(RavaIRGenerator_t *generator, RavaASTNode_t *root) {
|
||||
if (!generator || !root) return NULL;
|
||||
|
||||
@@ -1496,6 +1634,8 @@ RavaProgram_t* rava_ir_generate(RavaIRGenerator_t *generator, RavaASTNode_t *roo
|
||||
RavaASTNode_t *child = root->children[i];
|
||||
if (child->type == RAVA_AST_CLASS_DECL) {
|
||||
_rava_ir_gen_class(generator, child);
|
||||
} else if (child->type == RAVA_AST_ENUM_DECL) {
|
||||
_rava_ir_gen_enum(generator, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user