117 lines
2.8 KiB
C
117 lines
2.8 KiB
C
#include "exec.h"
|
|
#include "status.h"
|
|
|
|
void exec_init(struct exec* self)
|
|
{
|
|
assert(self);
|
|
self->pc = 0;
|
|
}
|
|
|
|
void exec_free(struct exec* self)
|
|
{
|
|
assert(self);
|
|
}
|
|
|
|
void exec_prog(struct exec* self,
|
|
struct moka* moka,
|
|
struct prog* prog)
|
|
{
|
|
assert(self); assert(moka); assert(prog);
|
|
self->pc = 0;
|
|
|
|
while (self->pc < prog->instructions.size)
|
|
{
|
|
exec_instr(self,
|
|
moka,
|
|
prog,
|
|
prog->instructions.data[self->pc]);
|
|
|
|
if (!status_is_ok(moka->status))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void exec_instr(struct exec* self,
|
|
struct moka* moka,
|
|
struct prog* prog,
|
|
struct instruction* instr)
|
|
{
|
|
assert(self); assert(moka); assert(instr);
|
|
int param = instr->param;
|
|
|
|
switch (instr->opcode)
|
|
{
|
|
case OP_MAKE_ARRAY: {
|
|
moka_make_array(moka, param);
|
|
self->pc++;
|
|
} break;
|
|
|
|
case OP_CALL: {
|
|
moka_call(moka, param);
|
|
if (!status_is_ok(moka->status))
|
|
{
|
|
return;
|
|
}
|
|
|
|
self->pc++;
|
|
} break;
|
|
|
|
case OP_GLOBAL_LOAD: {
|
|
moka_push_ref(moka, param, 0);
|
|
self->pc++;
|
|
} break;
|
|
|
|
case OP_LOCAL_LOAD: {
|
|
moka_push(moka, param);
|
|
self->pc++;
|
|
} break;
|
|
|
|
case OP_PUSH: {
|
|
struct value* value = prog->values.data[param];
|
|
switch (value->type)
|
|
{
|
|
case TY_INT: {
|
|
moka_push_int(moka, value->data.integer, value->line);
|
|
} break;
|
|
|
|
case TY_FLOAT: {
|
|
moka_push_float(moka, value->data.real, value->line);
|
|
} break;
|
|
|
|
case TY_BOOL: {
|
|
moka_push_bool(moka, value->data.boolean, value->line);
|
|
} break;
|
|
|
|
case TY_STRING: {
|
|
moka_push_string(moka, value->data.str, value->line);
|
|
} break;
|
|
|
|
case TY_SYMBOL: {
|
|
moka_push_symbol(moka, value->data.sym, value->line);
|
|
} break;
|
|
|
|
case TY_LAZY: {
|
|
moka_push_lazy(moka, value->data.lazy, value->line);
|
|
} break;
|
|
default: {
|
|
fprintf(stderr,
|
|
"cannot push value of type <%s>\n",
|
|
TypeKindStr[value->type]
|
|
);
|
|
|
|
abort();
|
|
} break;
|
|
}
|
|
self->pc++;
|
|
} break;
|
|
|
|
default: {
|
|
fprintf(stderr, "cannot execute opcode <%s>\n",
|
|
OpcodeKindStr[instr->opcode]);
|
|
abort();
|
|
} break;
|
|
}
|
|
}
|