ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

commit 52d5fb89bc8d20bdc529ed2c8cd34f19bc11e95d
parent 0bda74cf854d0753b794290063322b35a8d2bb6a
Author: citbl <citbl@citbl.org>
Date:   Sat, 25 Oct 2025 13:46:34 +1000

wip

Diffstat:
M.zed/debug.json | 2+-
Aex-assignment-1.ox | 4++++
Aex-for-simple1.ox | 6++++++
Msrc/gen/gen.c | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/parser/parser.c | 15++++++++++++++-
5 files changed, 93 insertions(+), 6 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/ex3.ox"], + "args": ["$ZED_WORKTREE_ROOT/ex123.ox"], "request": "launch", "adapter": "CodeLLDB" } diff --git a/ex-assignment-1.ox b/ex-assignment-1.ox @@ -0,0 +1,4 @@ +void main() { + int i = 0; + i = 5; +} diff --git a/ex-for-simple1.ox b/ex-for-simple1.ox @@ -0,0 +1,6 @@ +void main() { + int i; + for(i = 0; i < 5; i++) { + print("bozo!"); + } +} diff --git a/src/gen/gen.c b/src/gen/gen.c @@ -299,12 +299,71 @@ add_symbol(Gen* gen, Symbol* sym) gen->scope->symbols[gen->scope->len++] = sym; } -static bool build_block(Gen* gen, Node* body); -static int block_counter = 0; +static bool build_block(Gen*, Node*); +static bool build_statement(Gen*, Node*); + +static int block_counter = 0, loop_counter = 0; + +static bool +build_for_statement(Gen* gen, Node* node) +{ + /* + entry → (init) → [head: cond?] ──T──> (body) ──continue──> (step) ──┐ + └──F───────────────────> (end) → next + ^ + └── back to [head] + */ + + // gcc_jit_location* loc = loc_from_node(gen, node); + + // Node* init = node->data.for_statement.init; + // Node* cond = node->data.for_statement.cond; + // Node* step = node->data.for_statement.increment; + // Node* body = node->data.for_statement.body; + + // loop_counter++; + + // char label_cond[64], label_body[64], label_step[64], label_end[64]; + // snprintf(label_cond, 64, "for.cond%d", loop_counter); + // snprintf(label_body, 64, "for.body%d", loop_counter); + // snprintf(label_step, 64, "for.step%d", loop_counter); + // snprintf(label_end, 64, "for.end%d", loop_counter); + + // gcc_jit_block* cond_block = gcc_jit_function_new_block(gen->curr_func, label_cond); + // gcc_jit_block* body_block = gcc_jit_function_new_block(gen->curr_func, label_body); + // gcc_jit_block* step_block = gcc_jit_function_new_block(gen->curr_func, label_step); + // gcc_jit_block* end_block = gcc_jit_function_new_block(gen->curr_func, label_end); + + // // header, e.g. for(int = 0 <- + // if (init) { build_statement(gen, init); } + + // // jump to cond e.g. ; i < 5 <- + // gcc_jit_block_end_with_jump(gen->curr_block, loc, cond_block); + + // // cond: evaluate + // gen->curr_block = cond_block; + // gcc_jit_rvalue* cnd = NULL; + + // if (cond != NULL) { + // // cnd = build_bool_rvalue(gen, cond); + // // TODO our parsing needs to handle the int i = 0; + // // need to handle binary_expr like if + // // or check if it's already a bool + // // or check if it's numbers(?) + // } + + return false; +} static bool build_if_statement(Gen* gen, Node* node) { + /* + pre → [cond?] ──T──> (then) ─────┐ + └──F──> (else) ─────┐ │ + (merge) → next + */ + gcc_jit_location* loc = loc_from_node(gen, node); // build the condition @@ -455,6 +514,8 @@ build_statement(Gen* gen, Node* node) } case NODE_IF: return build_if_statement(gen, node); + case NODE_FOR: + return build_for_statement(gen, node); default: printf("build_statement unhandled, %s\n", node_type_str(node->type)); break; @@ -479,7 +540,8 @@ build_func_decl(Gen* gen, Node* node) { const char* func_name = span_str(gen->src, node->data.function_decl.name, (char[IDENTSZ]) { 0 }); - gcc_jit_type* ret_type = ox_type_to_c_type(gen, node->data.function_decl.return_type); + Node* return_type = node->data.function_decl.return_type; + gcc_jit_type* ret_type = ox_type_to_c_type(gen, return_type); gcc_jit_location* loc = loc_from_node(gen, node); gcc_jit_function* func = gcc_jit_context_new_function(gen->ctx, @@ -503,8 +565,10 @@ build_func_decl(Gen* gen, Node* node) if (gen->curr_block && ret_type == type_int) { // TODO handle more return types 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 if (gen->curr_block && ret_type == type_void) { + gcc_jit_block_end_with_void_return(gen->curr_block, loc); } else { - printf("build_func_decl unhandled return type, %s\n", node_type_str(node->type)); + printf("build_func_decl unhandled return type in func: %s - defaulting to void\n", func_name); gcc_jit_block_end_with_void_return(gen->curr_block, loc); } diff --git a/src/parser/parser.c b/src/parser/parser.c @@ -172,10 +172,23 @@ parse_equality(Parser* par) return node; } +static Node* +parse_assignment_expr(Parser* par) +{ + Node* left = parse_equality(par); + + if (match(par, TOKEN_EQUAL)) { + Node* right = parse_assignment_expr(par); // right-associative + if (left->type != NODE_IDENT) panic("invalid assignment target"); + return make_binary_node(OP_ASSIGN, left, right); + } + return left; +} + Node* parse_expression(Parser* par) { - return parse_equality(par); + return parse_assignment_expr(par); } Node*