commit 2f61c2b50ac165f96b91096ab1471b6c46effe43
parent 92e1639b07afa8e67e225e020ddb157de0637c83
Author: citbl <citbl@citbl.org>
Date: Mon, 13 Oct 2025 21:10:06 +1000
handle ret void
Diffstat:
| M | src/gen/gen.c | | | 145 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 78 insertions(+), 67 deletions(-)
diff --git a/src/gen/gen.c b/src/gen/gen.c
@@ -8,27 +8,27 @@
#include <string.h>
#include <sys/param.h>
-static gcc_jit_type *type_int;
-static gcc_jit_type *type_uint;
-static gcc_jit_type *type_double;
-static gcc_jit_type *type_void;
-static gcc_jit_type *type_cstr;
+static gcc_jit_type* type_int;
+static gcc_jit_type* type_uint;
+static gcc_jit_type* type_double;
+static gcc_jit_type* type_void;
+static gcc_jit_type* type_cstr;
#define MAXARGS 16
-static gcc_jit_location *
-loc_from_node(Gen *gen, Node *node)
+static gcc_jit_location*
+loc_from_node(Gen* gen, Node* node)
{
if (node->filename == NULL) return NULL;
return gcc_jit_context_new_location(gen->ctx, node->filename, node->line, node->col);
}
Gen
-gen_init(Scope *scope, const char *src, Node *node, bool quiet)
+gen_init(Scope* scope, const char* src, Node* node, bool quiet)
{
if (scope == NULL || src == NULL) { panic("gen_init: no Scope or AST provided"); }
- gcc_jit_context *ctx;
+ gcc_jit_context* ctx;
ctx = gcc_jit_context_acquire();
@@ -37,6 +37,9 @@ gen_init(Scope *scope, const char *src, Node *node, bool quiet)
// needs loc* to work
// gcc_jit_context_set_bool_option(ctx, GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
// high level
+
+ gcc_jit_context_set_bool_option(ctx, GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
+
if (quiet == false) { gcc_jit_context_set_bool_option(ctx, GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE, 1); }
// gcc_jit_context_set_bool_option(ctx, GCC_JIT_BOOL_OPTION_DUMP_SUMMARY, 1);
@@ -55,13 +58,13 @@ gen_init(Scope *scope, const char *src, Node *node, bool quiet)
type_void = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_VOID);
type_cstr = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_CONST_CHAR_PTR);
- gcc_jit_location *loc = gcc_jit_context_new_location(ctx, node->filename, 0, 0);
+ gcc_jit_location* loc = gcc_jit_context_new_location(ctx, node->filename, 0, 0);
- gcc_jit_param *pm_puts[] = { gcc_jit_context_new_param(ctx, loc, type_cstr, "s") };
- gcc_jit_function *fn_puts = gcc_jit_context_new_function(ctx, loc, GCC_JIT_FUNCTION_IMPORTED, type_int, "puts", 1, pm_puts, 0);
+ gcc_jit_param* pm_puts[] = { gcc_jit_context_new_param(ctx, loc, type_cstr, "s") };
+ gcc_jit_function* fn_puts = gcc_jit_context_new_function(ctx, loc, GCC_JIT_FUNCTION_IMPORTED, type_int, "puts", 1, pm_puts, 0);
- gcc_jit_param *pm_printf[] = { gcc_jit_context_new_param(ctx, loc, type_cstr, "fmt") };
- gcc_jit_function *fn_printf = gcc_jit_context_new_function(ctx,
+ gcc_jit_param* pm_printf[] = { gcc_jit_context_new_param(ctx, loc, type_cstr, "fmt") };
+ gcc_jit_function* fn_printf = gcc_jit_context_new_function(ctx,
loc,
GCC_JIT_FUNCTION_IMPORTED,
type_int,
@@ -83,16 +86,16 @@ gen_init(Scope *scope, const char *src, Node *node, bool quiet)
};
}
-static gcc_jit_rvalue *
-handle_ident_call(Gen *gen, Node *node)
+static gcc_jit_rvalue*
+handle_ident_call(Gen* gen, Node* node)
{
// Look up the symbol in the current scope
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 });
+ 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);
- const char *ident_name = span_str(gen->src, node->data.ident.name, (char[IDENTSZ]) { 0 });
+ const char* ident_name = span_str(gen->src, node->data.ident.name, (char[IDENTSZ]) { 0 });
printf("ident %s\n", ident_name);
printf("comparing: %s vs. %s\n", sym_name, ident_name);
@@ -121,33 +124,33 @@ handle_ident_call(Gen *gen, Node *node)
return NULL;
}
-static gcc_jit_rvalue *handle_expr(Gen *, Node *);
+static gcc_jit_rvalue* handle_expr(Gen*, Node*);
-static gcc_jit_rvalue *
-emit_literal_string(Gen *gen, Node *node)
+static gcc_jit_rvalue*
+emit_literal_string(Gen* gen, Node* node)
{
size_t len = node->data.string.value.end - node->data.string.value.start;
- char *str = calloc(len + 1, sizeof(char));
+ char* str = calloc(len + 1, sizeof(char));
if (str == NULL) panic("emit_literal_string: could not alloc");
memcpy(str, gen->src + node->data.string.value.start, len);
str[len] = '\0';
return gcc_jit_context_new_string_literal(gen->ctx, str);
}
-static gcc_jit_rvalue *
-emit_literal_int(Gen *gen, Node *node)
+static gcc_jit_rvalue*
+emit_literal_int(Gen* gen, Node* node)
{
return gcc_jit_context_new_rvalue_from_int(gen->ctx, type_int, (int)node->data.number.value);
}
-static gcc_jit_rvalue *
-emit_literal_float(Gen *gen, Node *node)
+static gcc_jit_rvalue*
+emit_literal_float(Gen* gen, Node* node)
{
return gcc_jit_context_new_rvalue_from_double(gen->ctx, type_double, node->data.number.value);
}
static void
-build_program(Gen *gen, Node *node)
+build_program(Gen* gen, Node* node)
{
size_t cnt = node->data.program.len;
for (size_t i = 0; i < cnt; i++) {
@@ -155,17 +158,17 @@ build_program(Gen *gen, Node *node)
}
}
-static gcc_jit_rvalue *
-lower_builtin_print(Gen *gen, Node *node)
+static gcc_jit_rvalue*
+lower_builtin_print(Gen* gen, Node* node)
{
size_t argc = node->data.call_expr.len;
// 1-arg, treat as puts(arg)
if (argc == 1) {
- gcc_jit_rvalue *arg = handle_expr(gen, node->data.call_expr.args[0]); // TODO [0] when many
+ gcc_jit_rvalue* arg = handle_expr(gen, node->data.call_expr.args[0]); // TODO [0] when many
// cast common cases to const char*
// if (gcc_jit_rvalue_get_type(arg) != type_cstr) arg = gcc_jit_context_new_cast(gen->ctx, loc_from_node(gen, node), arg, type_cstr);
- gcc_jit_rvalue *args[] = { arg };
+ gcc_jit_rvalue* args[] = { arg };
return gcc_jit_context_new_call(gen->ctx, loc_from_node(gen, node), gen->puts_fn, 1, args);
}
@@ -183,12 +186,12 @@ lower_builtin_print(Gen *gen, Node *node)
// to a struct. Do we say [[struct]] or do we have some automatic unwrap and display of
// struct data... probably, yes.
- gcc_jit_rvalue **args = (gcc_jit_rvalue **)calloc(MAXARGS, sizeof(gcc_jit_rvalue *));
+ gcc_jit_rvalue** args = (gcc_jit_rvalue**)calloc(MAXARGS, sizeof(gcc_jit_rvalue*));
if (argc > MAXARGS) { softpanic("we do not currently support more than 16 args to a print call"); }
for (size_t i = 0; i < argc; i++) {
- gcc_jit_rvalue *arg = handle_expr(gen, node->data.call_expr.args[i]);
+ gcc_jit_rvalue* arg = handle_expr(gen, node->data.call_expr.args[i]);
if (i == 0) {
if (gcc_jit_rvalue_get_type(arg) != type_cstr) {
// note this is probably not going to work as limited cast supported
@@ -199,7 +202,7 @@ lower_builtin_print(Gen *gen, Node *node)
//
// simple widening for common scalar types
//
- gcc_jit_type *ty = gcc_jit_rvalue_get_type(arg);
+ gcc_jit_type* ty = gcc_jit_rvalue_get_type(arg);
if (ty == type_int) {
arg = gcc_jit_context_new_cast(gen->ctx, loc_from_node(gen, node), arg, type_cstr);
} else if (ty == type_double) {
@@ -225,11 +228,11 @@ lower_builtin_print(Gen *gen, Node *node)
// // TODO see todo below about linked list parameters...
// }
-static gcc_jit_rvalue *
-handle_func_call(Gen *gen, Node *node)
+static gcc_jit_rvalue*
+handle_func_call(Gen* gen, Node* node)
{
- Node *fcallee = node->data.call_expr.callee;
- const char *func_name = span_str(gen->src, fcallee->data.ident.name, (char[IDENTSZ]) { 0 });
+ Node* fcallee = node->data.call_expr.callee;
+ const char* func_name = span_str(gen->src, fcallee->data.ident.name, (char[IDENTSZ]) { 0 });
if (strcmp(func_name, "print") == 0) return lower_builtin_print(gen, node);
softpanic("unhandled func call named: %s", func_name);
@@ -248,8 +251,8 @@ handle_func_call(Gen *gen, Node *node)
// return NULL;
}
-static gcc_jit_rvalue *
-handle_expr(Gen *gen, Node *node)
+static gcc_jit_rvalue*
+handle_expr(Gen* gen, Node* node)
{
switch (node->type) {
case NODE_INT_LITERAL:
@@ -277,10 +280,10 @@ handle_expr(Gen *gen, Node *node)
return NULL;
}
-static gcc_jit_type *
-ox_type_to_c_type(Gen *gen, Node *node)
+static gcc_jit_type*
+ox_type_to_c_type(Gen* gen, Node* node)
{
- const char *type_name = span_str(gen->src, node->data.ident.name, (char[IDENTSZ]) { 0 });
+ const char* type_name = span_str(gen->src, node->data.ident.name, (char[IDENTSZ]) { 0 });
if (strcmp(type_name, "int") == 0) {
return type_int;
@@ -299,7 +302,7 @@ ox_type_to_c_type(Gen *gen, Node *node)
}
static void
-build_statement(Gen *gen, Node *node)
+build_statement(Gen* gen, Node* node)
{
switch (node->type) {
case NODE_BLOCK:
@@ -307,12 +310,12 @@ build_statement(Gen *gen, Node *node)
case NODE_RETURN:
break;
case NODE_VAR_DECL: {
- 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_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);
+ 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));
@@ -326,7 +329,7 @@ build_statement(Gen *gen, Node *node)
printf("adding 1 symbol: %s\n", span_str(gen->src, node->data.var_decl.name, (char[IDENTSZ]) { 0 }));
- Symbol *sym = (Symbol *)calloc(1, sizeof(Symbol));
+ Symbol* sym = (Symbol*)calloc(1, sizeof(Symbol));
sym->name = node->data.var_decl.name;
sym->decl = node;
sym->ctype = declared_type;
@@ -334,13 +337,13 @@ build_statement(Gen *gen, Node *node)
if (gen->scope->len == gen->scope->cap) {
gen->scope->cap *= 2;
- gen->scope->symbols = (Symbol **)realloc(gen->scope->symbols, sizeof(Symbol *) * gen->scope->cap);
+ gen->scope->symbols = (Symbol**)realloc(gen->scope->symbols, sizeof(Symbol*) * gen->scope->cap);
}
gen->scope->symbols[gen->scope->len++] = sym;
} break;
case NODE_EXPR_STATEMENT: {
- gcc_jit_rvalue *rv = handle_expr(gen, node->data.expr_statement.expr);
+ gcc_jit_rvalue* rv = handle_expr(gen, node->data.expr_statement.expr);
if (rv) gcc_jit_block_add_eval(gen->curr_block, loc_from_node(gen, node), rv);
} break;
default:
@@ -350,7 +353,7 @@ build_statement(Gen *gen, Node *node)
}
static void
-build_block(Gen *gen, Node *body)
+build_block(Gen* gen, Node* body)
{
for (size_t i = 0; i < body->data.block.len; i++) {
build_statement(gen, body->data.block.stmts[i]);
@@ -358,38 +361,46 @@ build_block(Gen *gen, Node *body)
}
static void
-build_func_decl(Gen *gen, Node *node)
+build_func_decl(Gen* gen, Node* node)
{
- gcc_jit_function *func = gcc_jit_context_new_function(gen->ctx,
- loc_from_node(gen, node),
+ const char* func_name = span_str(gen->src, node->data.function_decl.name, (char[IDENTSZ]) { 0 });
+
+ auto ret_type = ox_type_to_c_type(gen, node->data.function_decl.return_type);
+ auto loc = loc_from_node(gen, node);
+
+ gcc_jit_function* func = gcc_jit_context_new_function(gen->ctx,
+ loc,
GCC_JIT_FUNCTION_EXPORTED, // declared
- type_int, // ret
- "main", // name
+ ret_type, // ret
+ strdup(func_name), // name
0, // num params
NULL, // params
0); // is variadic
- gcc_jit_block *block = gcc_jit_function_new_block(func, "entry");
+ gcc_jit_block* block = gcc_jit_function_new_block(func, "entry");
- gcc_jit_function *prev_func = gen->curr_func;
- gcc_jit_block *prev_block = gen->curr_block;
+ gcc_jit_function* prev_func = gen->curr_func;
+ gcc_jit_block* prev_block = gen->curr_block;
gen->curr_block = block;
gen->curr_func = func;
build_block(gen, node->data.function_decl.body);
- if (gen->curr_block) {
- 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_from_node(gen, node), ret_value);
- gen->curr_block = NULL;
+ if (gen->curr_block && ret_type == type_int) {
+ auto 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 {
+ 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;
}
void
-gen_next(Gen *gen, Node *node)
+gen_next(Gen* gen, Node* node)
{
// printf("gen_next, %s\n", node_type_str(node->type));