ccm/lib/compiler.c

117 lines
3.0 KiB
C

#include "compiler.h"
void compiler_init(compiler_t* self, module_t* module)
{
assert(self);
err_init(&self->err);
self->module = module;
}
void compiler_free(compiler_t* self)
{
assert(self);
err_free(&self->err);
}
void compiler_compile(compiler_t* self,
node_t* node,
prog_t* prog)
{
assert(self);
assert(node);
assert(prog);
if (!err_is_ok(&self->err))
{
return;
}
switch (node->kind)
{
case NODE_ASSERT_EQ: {
compiler_compile(self, node->children.data[0], prog);
prog_add_instr(prog, OP_ASSERT_EQ, CCM_NO_PARAM);
} break;
case NODE_ASSERT_NE: {
compiler_compile(self, node->children.data[0], prog);
prog_add_instr(prog, OP_ASSERT_NE, CCM_NO_PARAM);
} break;
case NODE_MODULE: {
for (size_t i=0; i<node->children.size; i++)
{
compiler_compile(self,
node->children.data[i],
prog);
}
} break;
case NODE_NUM: {
size_t id = prog_add_new_constant(
prog,
ccm_to_num(&self->module->ccm,
atof(node->value),
node->line)
);
prog_add_instr(prog, OP_PUSH, id);
} break;
case NODE_TUPLE: {
for (size_t i=0; i<node->children.size; i++)
{
size_t k = node->children.size - 1 - i;
compiler_compile(self,
node->children.data[k],
prog);
}
prog_add_instr(prog, OP_MK_TUPLE, node->children.size);
} break;
case NODE_SUB: {
compiler_compile(self, node->children.data[0], prog);
if (node->children.size == 2)
{
compiler_compile(self, node->children.data[1], prog);
prog_add_instr(prog, OP_SUB, CCM_NO_PARAM);
}
else
{
prog_add_instr(prog, OP_USUB, CCM_NO_PARAM);
}
} break;
case NODE_ADD:
case NODE_MUL:
case NODE_DIV:
case NODE_MOD:
case NODE_POW: {
compiler_compile(self, node->children.data[0], prog);
compiler_compile(self, node->children.data[1], prog);
Opcode op;
switch (node->kind)
{
case NODE_ADD: op = OP_ADD; break;
case NODE_MUL: op = OP_MUL; break;
case NODE_DIV: op = OP_DIV; break;
case NODE_MOD: op = OP_MOD; break;
case NODE_POW: op = OP_POW; break;
default: abort();
}
prog_add_instr(prog, op, CCM_NO_PARAM);
} break;
default: {
fprintf(stderr, "cannot compile node %s\n",
NodeKindStr[node->kind]);
abort();
}
}
}