commit b1397ecf38cef8fd371d4fb51b45a273b230b2c0
parent 2fba18d005233ab3a053baf6a8da086a27c40f87
Author: citbl <citbl@citbl.org>
Date: Thu, 23 Oct 2025 21:53:05 +1000
refac
Diffstat:
| M | src/gen/gen.c | | | 216 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 115 insertions(+), 101 deletions(-)
diff --git a/src/gen/gen.c b/src/gen/gen.c
@@ -303,6 +303,118 @@ static bool build_block(Gen* gen, Node* body);
static int block_counter = 0;
static bool
+build_if_statement(Gen* gen, Node* node)
+{
+ gcc_jit_location* loc = loc_from_node(gen, node);
+ // build the condition
+
+ OpType op = node->data.if_statement.cond->data.binary_expr.op;
+ Node* lhs = node->data.if_statement.cond->data.binary_expr.lhs;
+ Node* rhs = node->data.if_statement.cond->data.binary_expr.rhs;
+
+ Node* then_body = node->data.if_statement.then_body;
+ Node* else_body = node->data.if_statement.else_body;
+
+ enum gcc_jit_comparison cmp;
+ switch (op) {
+ case OP_EQUALITY:
+ cmp = GCC_JIT_COMPARISON_EQ;
+ break;
+ case OP_INEQUALITY:
+ cmp = GCC_JIT_COMPARISON_NE;
+ break;
+ default:
+ printf("build_statement NODE_IF unhandled, %d\n", op);
+ cmp = GCC_JIT_COMPARISON_EQ;
+ }
+
+ gcc_jit_rvalue* lhs_val = handle_expr(gen, lhs);
+ gcc_jit_rvalue* rhs_val = handle_expr(gen, rhs);
+
+ gcc_jit_rvalue* cond = gcc_jit_context_new_comparison(gen->ctx, loc, cmp, lhs_val, rhs_val);
+
+ // create the BLOCKS
+
+ // labels
+ block_counter++;
+ char label_then[64], label_else[64], label_end[64];
+ snprintf(label_then, 64, "if.then%d", block_counter);
+ snprintf(label_else, 64, "if.else%d", block_counter);
+ snprintf(label_end, 64, "if.end%d", block_counter);
+
+ // blocks
+ gcc_jit_block* then_bb = gcc_jit_function_new_block(gen->curr_func, label_then);
+ gcc_jit_block* else_bb = else_body ? gcc_jit_function_new_block(gen->curr_func, label_else) : NULL;
+ gcc_jit_block* merge_bb = NULL;
+
+ if (!else_bb) {
+ // no else: need merge now for the false edge
+ merge_bb = gcc_jit_function_new_block(gen->curr_func, label_end);
+ gcc_jit_block_end_with_conditional(gen->curr_block, loc, cond, then_bb, merge_bb);
+ } else {
+ // with else: branch to then/else; decide on merge later
+ gcc_jit_block_end_with_conditional(gen->curr_block, loc, cond, then_bb, else_bb);
+ }
+
+ // THEN
+ gen->curr_block = then_bb;
+ bool then_ended = build_block(gen, then_body);
+ gcc_jit_block* then_open = gen->curr_block; // last open block in THEN (may differ from then_bb)
+
+ // ELSE
+ bool else_ended = false;
+ gcc_jit_block* else_open = NULL;
+ if (else_bb) {
+ gen->curr_block = else_bb;
+ else_ended = build_block(gen, else_body);
+ else_open = gen->curr_block; // last open block in ELSE
+ }
+
+ // If both branches ended, no merge needed, we notify we have ended as well
+ if (else_bb && then_ended && else_ended) return true;
+
+ // Ensure we have a merge if any branch continues.
+ if (!merge_bb) merge_bb = gcc_jit_function_new_block(gen->curr_func, label_end);
+
+ if (!then_ended) gcc_jit_block_end_with_jump(then_open, loc, merge_bb);
+ if (else_bb && !else_ended) gcc_jit_block_end_with_jump(else_open, loc, merge_bb);
+
+ gen->curr_block = merge_bb;
+ return false;
+}
+
+static bool
+build_var_decl_statement(Gen* gen, Node* node)
+{
+ gcc_jit_location* loc = loc_from_node(gen, node);
+ const char* var_name = span_str(gen->src, node->data.var_decl.name, (char[IDENTSZ]) { 0 });
+ gcc_jit_type* declared_type = ox_type_to_c_type(gen, node->data.var_decl.type);
+
+ gcc_jit_lvalue* var_decl = NULL;
+ gcc_jit_rvalue* rvalue = handle_expr(gen, node->data.var_decl.init);
+
+ if (gen->curr_func == NULL && gen->curr_block == NULL) {
+ var_decl = gcc_jit_context_new_global(gen->ctx, loc, GCC_JIT_GLOBAL_INTERNAL, declared_type, strdup(var_name));
+ gcc_jit_global_set_initializer_rvalue(var_decl, rvalue);
+ } else {
+ var_decl = gcc_jit_function_new_local(gen->curr_func, loc, declared_type, strdup(var_name));
+ gcc_jit_block_add_assignment(gen->curr_block, loc, var_decl, rvalue);
+ }
+
+ if (node->data.var_decl.init == NULL) { panic("could not instanciate gcc jit new local"); }
+
+ printf("adding 1 symbol: %s\n", var_name);
+
+ Symbol* sym = (Symbol*)calloc(1, sizeof(Symbol));
+ sym->name = node->data.var_decl.name;
+ sym->decl = node;
+ sym->ctype = declared_type;
+ sym->d.lvalue = var_decl;
+ add_symbol(gen, sym);
+ return false;
+}
+
+static bool
build_statement(Gen* gen, Node* node)
{
gcc_jit_location* loc = loc_from_node(gen, node);
@@ -316,31 +428,7 @@ build_statement(Gen* gen, Node* node)
return true; // we end the block here
}
case NODE_VAR_DECL: {
- const char* var_name = span_str(gen->src, node->data.var_decl.name, (char[IDENTSZ]) { 0 });
- gcc_jit_type* declared_type = ox_type_to_c_type(gen, node->data.var_decl.type);
-
- gcc_jit_lvalue* var_decl = NULL;
- gcc_jit_rvalue* rvalue = handle_expr(gen, node->data.var_decl.init);
-
- if (gen->curr_func == NULL && gen->curr_block == NULL) {
- var_decl = gcc_jit_context_new_global(gen->ctx, loc, GCC_JIT_GLOBAL_INTERNAL, declared_type, strdup(var_name));
- gcc_jit_global_set_initializer_rvalue(var_decl, rvalue);
- } else {
- var_decl = gcc_jit_function_new_local(gen->curr_func, loc, declared_type, strdup(var_name));
- gcc_jit_block_add_assignment(gen->curr_block, loc, var_decl, rvalue);
- }
-
- if (node->data.var_decl.init == NULL) { panic("could not instanciate gcc jit new local"); }
-
- printf("adding 1 symbol: %s\n", var_name);
-
- Symbol* sym = (Symbol*)calloc(1, sizeof(Symbol));
- sym->name = node->data.var_decl.name;
- sym->decl = node;
- sym->ctype = declared_type;
- sym->d.lvalue = var_decl;
- add_symbol(gen, sym);
- break;
+ return build_var_decl_statement(gen, node);
}
case NODE_VAR_ASSIGN: {
gcc_jit_rvalue* rvalue = handle_expr(gen, node->data.var_assign.rhs);
@@ -365,82 +453,8 @@ build_statement(Gen* gen, Node* node)
if (rv) gcc_jit_block_add_eval(gen->curr_block, loc_from_node(gen, node), rv);
break;
}
- case NODE_IF: {
- // build the condition
-
- OpType op = node->data.if_statement.cond->data.binary_expr.op;
- Node* lhs = node->data.if_statement.cond->data.binary_expr.lhs;
- Node* rhs = node->data.if_statement.cond->data.binary_expr.rhs;
-
- Node* then_body = node->data.if_statement.then_body;
- Node* else_body = node->data.if_statement.else_body;
-
- enum gcc_jit_comparison cmp;
- switch (op) {
- case OP_EQUALITY:
- cmp = GCC_JIT_COMPARISON_EQ;
- break;
- case OP_INEQUALITY:
- cmp = GCC_JIT_COMPARISON_NE;
- break;
- default:
- printf("build_statement NODE_IF unhandled, %d\n", op);
- cmp = GCC_JIT_COMPARISON_EQ;
- }
-
- gcc_jit_rvalue* lhs_val = handle_expr(gen, lhs);
- gcc_jit_rvalue* rhs_val = handle_expr(gen, rhs);
- gcc_jit_rvalue* cond = gcc_jit_context_new_comparison(gen->ctx, loc, cmp, lhs_val, rhs_val);
-
- // create the BLOCKS
-
- // labels
- block_counter++;
- char label_then[64], label_else[64], label_end[64];
- snprintf(label_then, 64, "if.then%d", block_counter);
- snprintf(label_else, 64, "if.else%d", block_counter);
- snprintf(label_end, 64, "if.end%d", block_counter);
-
- // blocks
- gcc_jit_block* then_bb = gcc_jit_function_new_block(gen->curr_func, label_then);
- gcc_jit_block* else_bb = else_body ? gcc_jit_function_new_block(gen->curr_func, label_else) : NULL;
- gcc_jit_block* merge_bb = NULL;
-
- if (!else_bb) {
- // no else: need merge now for the false edge
- merge_bb = gcc_jit_function_new_block(gen->curr_func, label_end);
- gcc_jit_block_end_with_conditional(gen->curr_block, loc, cond, then_bb, merge_bb);
- } else {
- // with else: branch to then/else; decide on merge later
- gcc_jit_block_end_with_conditional(gen->curr_block, loc, cond, then_bb, else_bb);
- }
-
- // THEN
- gen->curr_block = then_bb;
- bool then_ended = build_block(gen, then_body);
- gcc_jit_block* then_open = gen->curr_block; // last open block in THEN (may differ from then_bb)
-
- // ELSE
- bool else_ended = false;
- gcc_jit_block* else_open = NULL;
- if (else_bb) {
- gen->curr_block = else_bb;
- else_ended = build_block(gen, else_body);
- else_open = gen->curr_block; // last open block in ELSE
- }
-
- // If both branches ended, no merge needed, we notify we have ended as well
- if (else_bb && then_ended && else_ended) return true;
-
- // Ensure we have a merge if any branch continues.
- if (!merge_bb) merge_bb = gcc_jit_function_new_block(gen->curr_func, label_end);
-
- if (!then_ended) gcc_jit_block_end_with_jump(then_open, loc, merge_bb);
- if (else_bb && !else_ended) gcc_jit_block_end_with_jump(else_open, loc, merge_bb);
-
- gen->curr_block = merge_bb;
- return false;
- }
+ case NODE_IF:
+ return build_if_statement(gen, node);
default:
printf("build_statement unhandled, %s\n", node_type_str(node->type));
break;