roza/lib/fun.c

110 lines
2.3 KiB
C
Raw Normal View History

2023-12-20 19:54:58 +00:00
#include "fun.h"
#include "sym.h"
2023-12-23 20:17:12 +00:00
#include "locals.h"
#include "value.h"
2023-12-20 19:54:58 +00:00
void fun_init(fun_t* fun, struct tysy* tysy, err_t* err)
{
assert(fun);
program_init(&fun->program);
2023-12-23 20:17:12 +00:00
fun->err = err;
2023-12-20 19:54:58 +00:00
fun->sym = malloc(sizeof(sym_t));
sym_init((sym_t*) fun->sym, (tysy_t*) tysy, err);
2023-12-23 20:17:12 +00:00
fun->locals = malloc(sizeof(locals_t));
locals_init((locals_t*) fun->locals);
fun->base = 0;
fun->closure.size = 0;
fun->closure.cap = 0;
fun->closure.data = NULL;
}
fun_t* fun_new_clone(fun_t* fun)
{
assert(fun);
fun_t* clone = malloc(sizeof(fun_t));
fun_init(clone, fun->tysy, fun->err);
locals_free((locals_t*) clone->locals);
free(clone->locals);
clone->locals = (struct locals*) locals_new_clone((locals_t*) fun->locals);
clone->base = fun->base;
clone->arg_base = fun->arg_base;
for (size_t i=0; i<fun->closure.size; i++)
{
fun_capture(clone,
fun->closure.data[i]->id,
fun->closure.data[i]->value);
}
return clone;
2023-12-20 19:54:58 +00:00
}
void fun_free(fun_t* fun)
{
assert(fun);
program_free(&fun->program);
sym_free((sym_t*) fun->sym);
free(fun->sym);
2023-12-23 20:17:12 +00:00
locals_free((locals_t*) fun->locals);
free(fun->locals);
for (size_t i=0; i<fun->closure.size; i++)
{
value_free((value_t*) fun->closure.data[i]->value);
free(fun->closure.data[i]->value);
free(fun->closure.data[i]);
}
free(fun->closure.data);
fun->closure.data = NULL;
}
void fun_capture(fun_t* fun, int id, struct value* value)
{
assert(fun);
assert(value);
if (fun->closure.data == NULL)
{
fun->closure.cap = 2;
fun->closure.data = malloc(sizeof(closure_entry_t*) * fun->closure.cap);
}
if (fun->closure.size >= fun->closure.cap)
{
fun->closure.cap *= 2;
fun->closure.data = realloc(fun->closure.data,
sizeof(closure_entry_t*) * fun->closure.cap);
}
fun->closure.data[fun->closure.size] = malloc(sizeof(closure_entry_t));
fun->closure.data[fun->closure.size]->id = id;
fun->closure.data[fun->closure.size]->value = value_new_clone(value);
fun->closure.size++;
}
closure_entry_t* fun_try_find_closure(fun_t* fun, int id)
{
assert(fun);
for (size_t i=0; i<fun->closure.size; i++)
{
if (fun->closure.data[i]->id == id)
{
return fun->closure.data[i];
}
}
return NULL;
2023-12-20 19:54:58 +00:00
}