moka/lib/moka.c

417 lines
10 KiB
C
Raw Normal View History

2024-03-26 18:31:33 +00:00
#include "moka.h"
#include "node.h"
#include "compiler.h"
#include "prog.h"
#include "exec.h"
2024-03-27 19:53:06 +00:00
#include "module.h"
void moka_mod_init(struct moka_mod* self,
char* name,
struct module* new_module)
{
assert(self);
self->name = strdup(name);
self->module = new_module;
}
void moka_mod_free(struct moka_mod* self)
{
free(self->name);
module_free(self->module);
free(self->module);
}
2024-03-26 18:31:33 +00:00
void moka_init(struct moka* self, struct status* status)
2024-03-26 18:31:33 +00:00
{
assert(self);
self->status = status;
symtable_init(&self->symtable);
2024-03-26 18:31:33 +00:00
vec_init(&self->frame_stack);
vec_init(&self->global_values);
2024-03-27 19:53:06 +00:00
vec_init(&self->modules);
2024-03-26 18:31:33 +00:00
struct frame* frame = malloc(sizeof(struct frame));
frame_init(frame);
vec_push(&self->frame_stack, frame);
}
void frame_init(struct frame* self)
{
vec_init(&self->local_values);
vec_init(&self->stack);
}
void frame_free(struct frame* self)
{
assert(self);
vec_free_elements(&self->local_values, (void*)value_free);
vec_free(&self->local_values);
vec_free(&self->stack);
}
void moka_free(struct moka* self)
{
assert(self);
symtable_free(&self->symtable);
2024-03-26 18:31:33 +00:00
vec_free_elements(&self->frame_stack, (void*) frame_free);
vec_free(&self->frame_stack);
2024-03-27 19:53:06 +00:00
vec_free_elements(&self->modules, (void*) moka_mod_free);
vec_free(&self->modules);
vec_free_elements(&self->global_values, (void*) value_free);
2024-03-26 18:31:33 +00:00
vec_free(&self->global_values);
}
void moka_decl_native(struct moka* self,
char* name,
native_fun_t fun)
{
struct native* native = malloc(sizeof(struct native));
native_init(native, fun);
struct value* value = malloc(sizeof(struct value));
value_init_native(value, native, 0);
vec_push(&self->global_values, value);
size_t addr = self->global_values.size - 1;
symtable_declare(&self->symtable, name, addr, false);
}
2024-03-26 18:31:33 +00:00
struct frame* moka_frame(struct moka* self)
{
assert(self);
assert(self->frame_stack.size > 0);
return self->frame_stack.data[
self->frame_stack.size - 1
];
}
bool moka_has_top(struct moka* self)
{
assert(self);
struct frame* frame = moka_frame(self);
return frame->stack.size > 0;
}
MOKA moka_top(struct moka* self)
{
assert(self);
struct frame* frame = moka_frame(self);
assert(frame->stack.size > 0);
MOKA val = (MOKA) frame->stack.data[frame->stack.size - 1];
return val;
}
MOKA moka_pop(struct moka* self)
{
assert(self);
struct frame* frame = moka_frame(self);
assert(frame->stack.size > 0);
MOKA val = (MOKA) frame->stack.data[frame->stack.size - 1];
vec_pop(&frame->stack);
return val;
}
2024-03-26 18:31:33 +00:00
bool moka_is(struct moka* self, MOKA value, TypeKind type)
{
return moka_type_of(self, value) == type;
}
TypeKind moka_type_of(struct moka* self, MOKA value)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value const* val = frame->local_values.data[value];
return val->type;
}
void moka_dump(struct moka* self, MOKA value)
{
if (moka_is(self, value, TY_REF))
{
printf("&%zu", moka_get_ref(self, value));
return;
}
2024-03-26 18:31:33 +00:00
if (moka_is(self, value, TY_INT))
{
printf("%d", moka_get_int(self, value));
return;
}
if (moka_is(self, value, TY_FLOAT))
{
printf("%f", moka_get_float(self, value));
return;
}
if (moka_is(self, value, TY_BOOL))
{
printf("%s", moka_get_bool(self, value) ? "true" : "false");
return;
}
if (moka_is(self, value, TY_STRING))
{
printf("%s", moka_get_string(self, value));
return;
}
if (moka_is(self, value, TY_SYMBOL))
{
printf("'%s", moka_get_symbol(self, value));
return;
}
fprintf(stderr, "cannot dump value of type <%s>\n",
TypeKindStr[moka_type_of(self, value)]
);
abort();
}
MOKA moka_call(struct moka* self, int arg_count)
{
MOKA fun = moka_pop(self);
struct vec args;
vec_init(&args);
for (ssize_t i=0; i<arg_count; i++)
{
MOKA arg = moka_pop(self);
vec_push(&args, (void*) arg);
}
struct value* val = self->global_values.data[
moka_get_ref(self, fun)
];
assert(val->type == TY_NATIVE);
struct native* native = val->data.native;
(native->fun)(self, &args);
vec_free(&args);
return moka_top(self);
}
2024-03-26 18:31:33 +00:00
MOKA moka_push_int(struct moka* self, int value, int line)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = malloc(sizeof(struct value));
value_init_int(val, value, line);
vec_push(&frame->local_values, val);
size_t addr = frame->local_values.size - 1;
vec_push(&frame->stack, (void*) addr);
return addr;
}
int moka_get_int(struct moka* self, MOKA value)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = frame->local_values.data[value];
assert(val->type == TY_INT);
return val->data.integer;
}
MOKA moka_push_float(struct moka* self, float value, int line)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = malloc(sizeof(struct value));
value_init_float(val, value, line);
vec_push(&frame->local_values, val);
size_t addr = frame->local_values.size - 1;
vec_push(&frame->stack, (void*) addr);
return addr;
}
float moka_get_float(struct moka* self, MOKA value)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = frame->local_values.data[value];
assert(val->type == TY_FLOAT);
return val->data.real;
}
MOKA moka_push_bool(struct moka* self, bool value, int line)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = malloc(sizeof(struct value));
value_init_bool(val, value, line);
vec_push(&frame->local_values, val);
size_t addr = frame->local_values.size - 1;
vec_push(&frame->stack, (void*) addr);
return addr;
}
float moka_get_bool(struct moka* self, MOKA value)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = frame->local_values.data[value];
assert(val->type == TY_BOOL);
return val->data.boolean;
}
MOKA moka_push_string(struct moka* self, char const* value, int line)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = malloc(sizeof(struct value));
value_init_string(val, value, line);
vec_push(&frame->local_values, val);
size_t addr = frame->local_values.size - 1;
vec_push(&frame->stack, (void*) addr);
return addr;
}
char* moka_get_string(struct moka* self, MOKA value)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = frame->local_values.data[value];
assert(val->type == TY_STRING);
return val->data.str;
}
MOKA moka_push_symbol(struct moka* self, char const* value, int line)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = malloc(sizeof(struct value));
value_init_symbol(val, value, line);
vec_push(&frame->local_values, val);
size_t addr = frame->local_values.size - 1;
vec_push(&frame->stack, (void*) addr);
return addr;
}
char* moka_get_symbol(struct moka* self, MOKA value)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = frame->local_values.data[value];
assert(val->type == TY_SYMBOL);
return val->data.sym;
}
MOKA moka_push_ref(struct moka* self, size_t value, int line)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = malloc(sizeof(struct value));
value_init_ref(val, value, line);
vec_push(&frame->local_values, val);
size_t addr = frame->local_values.size - 1;
vec_push(&frame->stack, (void*) addr);
return addr;
}
size_t moka_get_ref(struct moka* self, MOKA value)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = frame->local_values.data[value];
assert(val->type == TY_REF);
return val->data.ref;
}
MOKA moka_push_native(struct moka* self, native_fun_t value, int line)
{
assert(self);
assert(value);
struct native* native = malloc(sizeof(struct native));
native_init(native, value);
struct value* val = malloc(sizeof(struct value));
value_init_native(val, native, line);
vec_push(&self->global_values, val);
size_t addr = self->global_values.size - 1;
return moka_push_ref(self, addr, line);
}
native_fun_t moka_get_native(struct moka* self, MOKA value)
{
assert(self);
size_t addr = moka_get_ref(self, value);
struct value const* val = self->global_values.data[addr];
struct native const* native = val->data.native;
return native->fun;
}
MOKA moka_eval_lazy(struct moka* self, MOKA lazy_value)
{
assert(self);
if (!moka_is(self, lazy_value, TY_LAZY))
{
return lazy_value;
}
struct node* node = moka_get_lazy(self, lazy_value);
struct compiler compiler;
compiler_init(&compiler, self->status);
struct prog prog;
prog_init(&prog);
compiler_compile(
&compiler,
node,
&prog,
&self->symtable);
if (!status_is_ok(self->status))
{
status_dump(self->status);
moka_push_int(self, 0, 0);
goto free_prog;
}
struct exec exec;
exec_init(&exec);
exec_prog(&exec, self, &prog);
exec_free(&exec);
free_prog:
prog_free(&prog);
compiler_free(&compiler);
return moka_pop(self);
}
MOKA moka_push_lazy(struct moka* self, struct node* value, int line)
{
assert(self);
assert(value);
struct value* val = malloc(sizeof(struct value));
value_init_lazy(val, value, line);
struct frame* frame = moka_frame(self);
vec_push(&frame->local_values, val);
size_t addr = frame->local_values.size - 1;
vec_push(&frame->stack, (void*) addr);
return addr;
}
struct node* moka_get_lazy(struct moka* self, MOKA value)
{
assert(self);
struct frame* frame = moka_frame(self);
struct value* val = frame->local_values.data[value];
assert(val->type == TY_LAZY);
return val->data.lazy;
}