ox

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

commit e024c6033408b15d36e341c61d4e1a3b2a9faded
parent 5cb4fd6849f05d0ef70be767716fd0dc1d3a9094
Author: citbl <citbl@citbl.org>
Date:   Sun, 16 Nov 2025 14:47:37 +1000

basic func call with args handled

Diffstat:
Mex-call-args.ox | 15++++++++++++++-
Msrc/gen/gen.c | 84++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/types.h | 1+
3 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/ex-call-args.ox b/ex-call-args.ox @@ -1,8 +1,21 @@ void callee_test(string message) { + print("message was:"); print(message); } +void callee_test2(int age) { + print("with age:"); + print(age); +} + +void callee_test3(string message2, int age2) { + print("summarized:"); + print(message2); + print(age2); +} + void main() { callee_test("hello, there"); + callee_test2(42); + callee_test3("Jack", 26); } - diff --git a/src/gen/gen.c b/src/gen/gen.c @@ -18,6 +18,9 @@ static gcc_jit_type* type_cstr; static gcc_jit_type* type_char; static gcc_jit_type* type_voidp; +static const char* type_func = "function"; +static const char* type_var = "variable"; + #define MAXARGS 16 static gcc_jit_location* @@ -542,16 +545,16 @@ handle_func_call(Gen* gen, Node* node) } /* - When generating the identifier expression message in the AST: - Lookup env["message"] -> you get a gcc_jit_param* or gcc_jit_lvalue*. - Use gcc_jit_param_as_rvalue / gcc_jit_lvalue_as_rvalue. + When generating the identifier expression message in the AST: + Lookup env["message"] -> you get a gcc_jit_param* or gcc_jit_lvalue*. + Use gcc_jit_param_as_rvalue / gcc_jit_lvalue_as_rvalue. - gcc_jit_rvalue *msg = gcc_jit_param_as_rvalue(callee_param); + gcc_jit_rvalue *msg = gcc_jit_param_as_rvalue(callee_param); - gcc_jit_rvalue *args[1] = { msg }; - gcc_jit_block_add_eval( - b, loc, - gcc_jit_context_new_call(ctx, loc, print_fn, 1, args)); + gcc_jit_rvalue *args[1] = { msg }; + gcc_jit_block_add_eval( + b, loc, + gcc_jit_context_new_call(ctx, loc, print_fn, 1, args)); */ return gcc_jit_context_new_call(gen->ctx, loc, callee, argc, args); @@ -648,6 +651,16 @@ add_symbol(Gen* gen, Symbol* sym) printf("we now have %zu symbols.\n", gen->scope->len); } +static void +print_symbols_here(Gen* gen) +{ + for (size_t i = 0; i < gen->scope->len; i++) { + Symbol* sym = gen->scope->symbols[i]; + const char* name = span_str(gen->src, sym->name, (char[IDENTSZ]) { 0 }); + printf("[%zu/%zu] symbol: %s (%s)\n", i + 1, gen->scope->len, name, sym->english_type); + } +} + static bool build_block(Gen*, Node*); static bool build_statement(Gen*, Node*); @@ -838,6 +851,7 @@ build_var_decl_statement(Gen* gen, Node* node) sym->decl = node; sym->ctype = declared_type; sym->d.lvalue = var_decl; + sym->english_type = type_var; add_symbol(gen, sym); return false; } @@ -992,21 +1006,30 @@ build_func_decl(Gen* gen, Node* node) gcc_jit_location* loc = loc_from_node(gen, node); size_t argc = node->data.function_decl.p_len; + + gcc_jit_param** params = calloc(argc, sizeof(gcc_jit_param*)); + + // 1) Create ONE gcc_jit_param per AST param for (size_t i = 0; i < argc; i++) { - // make a bunch of gcc params stored in the symbols table of the func scope - } + Node* pnode = node->data.function_decl.params[i]; + const char* pname = span_str(gen->src, pnode->data.param.name, (char[IDENTSZ]) { 0 }); - // TODO create the gcc_jit_param* for the function - // Put each parameter into a symbol table/scope. + gcc_jit_type* declared_type = ox_type_to_c_type(gen, pnode->data.param.type); + gcc_jit_param* p = gcc_jit_context_new_param(gen->ctx, loc, declared_type, strdup(pname)); + + params[i] = p; + } + + // 2) Create the function with those params gcc_jit_function* func = gcc_jit_context_new_function(gen->ctx, loc, - GCC_JIT_FUNCTION_EXPORTED, // declared - ret_type, // ret - strdup(func_name), // name - 0, // num params // TODO @next we need to pass the params here as per AST definition - NULL, // params - 0); // is variadic + GCC_JIT_FUNCTION_EXPORTED, + ret_type, + strdup(func_name), + argc, + params, // <-- these are now owned by 'func' + 0); gcc_jit_block* block = gcc_jit_function_new_block(func, "entry"); @@ -1015,16 +1038,37 @@ build_func_decl(Gen* gen, Node* node) gen->curr_block = block; gen->curr_func = func; + // 3) Add the function symbol to the current (enclosing) scope Symbol* sym = (Symbol*)calloc(1, sizeof(Symbol)); sym->name = node->data.function_decl.name; sym->decl = node; - sym->ctype = type_voidp; + sym->ctype = type_voidp; // whatever you use for function type metadata sym->d.funcvalue = func; + sym->english_type = type_func; add_symbol(gen, sym); + // 4) Add parameter symbols to the FUNCTION scope, reusing the same gcc_jit_param* + for (size_t i = 0; i < argc; i++) { + Node* pnode = node->data.function_decl.params[i]; + + gcc_jit_param* p = params[i]; // <-- reuse, DO NOT new_param again + + gcc_jit_type* declared_type = ox_type_to_c_type(gen, pnode->data.param.type); + + Symbol* ps = (Symbol*)calloc(1, sizeof(Symbol)); + ps->name = pnode->data.param.name; // param identifier span + ps->decl = pnode; + ps->ctype = declared_type; + ps->d.param = p; // <-- this is associated with 'func' + ps->english_type = type_var; // or type_param if you distinguish + add_symbol(gen, ps); + } + + print_symbols_here(gen); + build_block(gen, node->data.function_decl.body); - if (gen->curr_block && ret_type == type_int) { // TODO handle more return types in function declarations + if (gen->curr_block && ret_type == type_int) { 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) { diff --git a/src/types.h b/src/types.h @@ -276,6 +276,7 @@ typedef struct Symbol { TypeInfo* type; // todo print all found in gen gcc_jit_type* ctype; + const char* english_type; union { gcc_jit_function* funcvalue; gcc_jit_lvalue* lvalue;