2023-12-09 17:24:41 +00:00
|
|
|
#include "compiler.h"
|
|
|
|
#include "lib/commons.h"
|
|
|
|
|
|
|
|
void compiler_init(compiler_t* compiler, mod_t* mod, tysy_t* tysy, err_t* err)
|
|
|
|
{
|
|
|
|
assert(compiler);
|
|
|
|
assert(err);
|
|
|
|
|
|
|
|
compiler->mod = mod;
|
|
|
|
compiler->tysy = tysy;
|
|
|
|
compiler->err = err;
|
|
|
|
}
|
|
|
|
|
|
|
|
void compiler_free(compiler_t* compiler)
|
|
|
|
{
|
|
|
|
assert(compiler);
|
|
|
|
}
|
|
|
|
|
|
|
|
void compiler_run(compiler_t* compiler, node_t* node)
|
|
|
|
{
|
|
|
|
assert(compiler);
|
|
|
|
assert(node);
|
|
|
|
|
|
|
|
switch (node->type)
|
|
|
|
{
|
|
|
|
case NODE_MOD: {
|
|
|
|
for (size_t i=0; i<node->children.size; i++)
|
|
|
|
{
|
|
|
|
compiler_run(compiler, (node_t*) node->children.data[i]);
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case NODE_NUM: {
|
|
|
|
double value = atof(node->value.data);
|
2023-12-11 17:01:22 +00:00
|
|
|
value_t* val = tysy_new_num(compiler->tysy, value, node->line);
|
2023-12-09 17:24:41 +00:00
|
|
|
Opcode op = OP_PUSH;
|
|
|
|
param_t param = (param_t) mod_push_new_value(compiler->mod, val);
|
|
|
|
|
|
|
|
mod_push_instr(compiler->mod, op, param);
|
|
|
|
|
|
|
|
} break;
|
|
|
|
|
2023-12-09 21:59:24 +00:00
|
|
|
case NODE_BOOL: {
|
|
|
|
int value = strcmp(node->value.data, "true") == 0;
|
2023-12-11 17:01:22 +00:00
|
|
|
value_t* val = tysy_new_bool(compiler->tysy, value, node->line);
|
2023-12-09 21:59:24 +00:00
|
|
|
Opcode op = OP_PUSH;
|
|
|
|
param_t param = (param_t) mod_push_new_value(compiler->mod, val);
|
|
|
|
|
|
|
|
mod_push_instr(compiler->mod, op, param);
|
|
|
|
} break;
|
|
|
|
|
2023-12-10 03:49:28 +00:00
|
|
|
case NODE_STR: {
|
|
|
|
char* value = node->value.data;
|
2023-12-11 17:01:22 +00:00
|
|
|
value_t* val = tysy_new_str(compiler->tysy, value, node->line);
|
2023-12-10 03:49:28 +00:00
|
|
|
Opcode op = OP_PUSH;
|
|
|
|
param_t param = (param_t) mod_push_new_value(compiler->mod, val);
|
|
|
|
|
|
|
|
mod_push_instr(compiler->mod, op, param);
|
|
|
|
} break;
|
|
|
|
|
2023-12-11 17:01:22 +00:00
|
|
|
case NODE_ASSERT: {
|
|
|
|
assert(node->children.size == 1);
|
|
|
|
compiler_run(compiler, node_child(node, 0));
|
|
|
|
mod_push_instr(compiler->mod, OP_ASSERT, RZ_NO_PARAM);
|
|
|
|
} break;
|
|
|
|
|
2023-12-15 18:30:20 +00:00
|
|
|
case NODE_NE:
|
|
|
|
case NODE_EQ: {
|
|
|
|
assert(node->children.size == 2);
|
|
|
|
|
|
|
|
for (size_t i=0; i<node->children.size; i++)
|
|
|
|
{
|
|
|
|
compiler_run(compiler, node_child(node, i));
|
|
|
|
}
|
|
|
|
|
|
|
|
mod_push_instr(compiler->mod,
|
|
|
|
node->type == NODE_EQ ? OP_EQ : OP_NE, RZ_NO_PARAM);
|
|
|
|
} break;
|
|
|
|
|
2023-12-15 20:32:17 +00:00
|
|
|
case NODE_LT:
|
|
|
|
case NODE_LE:
|
|
|
|
case NODE_GT:
|
|
|
|
case NODE_GE:{
|
|
|
|
assert(node->children.size == 2);
|
|
|
|
|
|
|
|
for (size_t i=0; i<node->children.size; i++)
|
|
|
|
{
|
|
|
|
compiler_run(compiler, node_child(node, i));
|
|
|
|
}
|
|
|
|
|
|
|
|
Opcode op;
|
|
|
|
switch (node->type)
|
|
|
|
{
|
|
|
|
case NODE_LT: op = OP_LT; break;
|
|
|
|
case NODE_LE: op = OP_LE; break;
|
|
|
|
case NODE_GT: op = OP_GT; break;
|
|
|
|
case NODE_GE: op = OP_GE; break;
|
|
|
|
default: assert(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
mod_push_instr(compiler->mod, op, RZ_NO_PARAM);
|
|
|
|
|
|
|
|
} break;
|
|
|
|
|
2023-12-09 17:24:41 +00:00
|
|
|
default: {
|
2023-12-11 17:01:22 +00:00
|
|
|
fprintf(stderr, "Cannot compile unknown node '%s'",
|
|
|
|
NodeTypeStr[node->type]);
|
|
|
|
abort();
|
2023-12-09 17:24:41 +00:00
|
|
|
} break;
|
|
|
|
}
|
|
|
|
}
|