commit ecc6a44d87f87542ed5b3da1fb88fad2e32132b6
parent a30c84cfa89fefe405d9727ff9c6fbb3823c4f31
Author: citbl <citbl@citbl.org>
Date: Thu, 23 Oct 2025 20:28:05 +1000
wip if nested
Diffstat:
6 files changed, 123 insertions(+), 13 deletions(-)
diff --git a/.zed/debug.json b/.zed/debug.json
@@ -11,7 +11,7 @@
"cwd": "$ZED_WORKTREE_ROOT"
},
"program": "$ZED_WORKTREE_ROOT/oxc",
- "args": ["$ZED_WORKTREE_ROOT/ex12.ox"],
+ "args": ["$ZED_WORKTREE_ROOT/ex3.ox"],
"request": "launch",
"adapter": "CodeLLDB"
}
diff --git a/ex3.ox b/ex3.ox
@@ -1,7 +1,15 @@
// conditional to be handled
void main() {
- if (a == true) {
- print("conditional test passed");
+ print("did it work?");
+ string password = "123";
+ if (password == "1234") {
+ print("it worked!");
+ } else {
+ if(password == "123") {
+ print("the else worked!");
+ } else {
+ print("booboo");
+ }
}
}
diff --git a/src/gen.h b/src/gen.h
@@ -16,6 +16,7 @@ typedef struct {
// gcc_jit_type *type_kind; need type too?
Scope* scope;
const char* src;
+ bool block_terminated;
} Gen;
Gen gen_init(Scope*, const char*, Node*, bool);
diff --git a/src/gen/gen.c b/src/gen/gen.c
@@ -95,12 +95,11 @@ handle_ident_call(Gen* gen, Node* node)
for (size_t i = 0; i < gen->scope->len; i++) {
Symbol* sym = gen->scope->symbols[i];
const char* sym_name = span_str(gen->src, sym->name, (char[IDENTSZ]) { 0 });
- printf("symbol %s\n", sym_name);
+ // printf("symbol %s\n", sym_name);
const char* ident_name = span_str(gen->src, node->data.ident.name, (char[IDENTSZ]) { 0 });
- printf("ident %s\n", ident_name);
+ // printf("ident %s\n", ident_name);
- printf("comparing: %s vs. %s\n", sym_name, ident_name);
if (strncmp(sym_name, ident_name, strlen(sym_name)) == 0) {
printf("found %s\n", sym_name);
return gcc_jit_lvalue_as_rvalue(sym->d.lvalue);
@@ -301,6 +300,18 @@ add_symbol(Gen* gen, Symbol* sym)
}
static void
+end_jump_if_needed(Gen* gen, gcc_jit_location* loc, gcc_jit_block* target)
+{
+ if (!gen->block_terminated && gen->curr_block) {
+ gcc_jit_block_end_with_jump(gen->curr_block, loc, target);
+ gen->block_terminated = true;
+ }
+}
+
+static void build_block(Gen* gen, Node* body);
+static int block_counter = 0;
+
+static void
build_statement(Gen* gen, Node* node)
{
switch (node->type) {
@@ -349,9 +360,7 @@ build_statement(Gen* gen, Node* node)
// check the type of lvalue matches the rvalue
gcc_jit_type* ltype = sym->ctype;
gcc_jit_type* rtype = gcc_jit_rvalue_get_type(rvalue);
- if (rtype != ltype) {
- panic_at(node, "right hand side of assigment doesn't match the type of the left hand side");
- }
+ if (rtype != ltype) { panic_at(node, "right hand side of assigment doesn't match the type of the left hand side"); }
if (lvalue) gcc_jit_block_add_assignment(gen->curr_block, loc, lvalue, rvalue);
}
}
@@ -362,6 +371,75 @@ 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: {
+ 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_block = gcc_jit_function_new_block(gen->curr_func, label_then);
+ gcc_jit_block* merge_block = gcc_jit_function_new_block(gen->curr_func, label_else);
+ gcc_jit_block* else_block = else_body ? gcc_jit_function_new_block(gen->curr_func, label_else) : NULL;
+
+ // rig the jumps
+
+ gcc_jit_block_end_with_conditional(gen->curr_block, loc, cond, then_block, else_body ? else_block : merge_block);
+
+ // build THEN
+
+ gen->curr_block = then_block;
+ gen->block_terminated = false;
+ build_block(gen, then_body);
+ end_jump_if_needed(gen, loc, merge_block);
+
+ // build ELSE block (optional)
+ if (else_block != NULL) {
+ gen->curr_block = else_block;
+ gen->block_terminated = false;
+ build_block(gen, else_body);
+ end_jump_if_needed(gen, loc, merge_block);
+ }
+
+ // continue after if, note that the original block is terminated.
+ gen->curr_block = merge_block;
+ gen->block_terminated = false;
+
+ break;
+ }
default:
printf("build_statement unhandled, %s\n", node_type_str(node->type));
break;
@@ -406,11 +484,10 @@ build_func_decl(Gen* gen, Node* node)
gcc_jit_rvalue* ret_value = gcc_jit_context_new_rvalue_from_int(gen->ctx, type_int, 0);
gcc_jit_block_end_with_return(gen->curr_block, loc, ret_value);
} else {
+ printf("build_func_decl unhandled return type, %s\n", node_type_str(node->type));
gcc_jit_block_end_with_void_return(gen->curr_block, loc);
}
- gen->curr_block = NULL;
-
gen->curr_func = prev_func;
gen->curr_block = prev_block;
}
diff --git a/src/parser/parser.c b/src/parser/parser.c
@@ -135,6 +135,28 @@ static Node*
parse_equality(Parser* par)
{
Node* node = parse_relational(par);
+
+ // TODO handle all enum gcc_jit_comparison
+ // {
+ // /* (EXPR_A) == (EXPR_B). */
+ // GCC_JIT_COMPARISON_EQ,
+
+ // /* (EXPR_A) != (EXPR_B). */
+ // GCC_JIT_COMPARISON_NE,
+
+ // /* (EXPR_A) < (EXPR_B). */
+ // GCC_JIT_COMPARISON_LT,
+
+ // /* (EXPR_A) <=(EXPR_B). */
+ // GCC_JIT_COMPARISON_LE,
+
+ // /* (EXPR_A) > (EXPR_B). */
+ // GCC_JIT_COMPARISON_GT,
+
+ // /* (EXPR_A) >= (EXPR_B). */
+ // GCC_JIT_COMPARISON_GE
+ // };
+
for (;;) {
if (match(par, TOKEN_EQUALITY)) { // "=="
Node* rhs = parse_relational(par);
@@ -142,8 +164,10 @@ parse_equality(Parser* par)
} else if (match(par, TOKEN_INEQUALITY)) { // "!="
Node* rhs = parse_relational(par);
node = make_binary_node(OP_INEQUALITY, node, rhs);
- } else
+ } else {
+ perror("unhandled parse_equality token");
break;
+ }
}
return node;
}
diff --git a/src/types.h b/src/types.h
@@ -115,7 +115,7 @@ typedef enum {
*/
typedef enum {
- OP_PLUS = 23,
+ OP_PLUS = 300,
OP_MINUS,
OP_MUL,
OP_DIV,