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:
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;