clear blocks.

main
bog 2024-02-13 03:53:19 +01:00
parent 75987d9780
commit bb300a1a93
6 changed files with 116 additions and 37 deletions

View File

@ -2,6 +2,7 @@
#include "commons.h"
#include "node.h"
#include "opcodes.h"
#include "program.h"
#include "syms.h"
#include "value.h"
#include "vec.h"
@ -11,6 +12,7 @@ void compiler_init(struct compiler* self, struct syms* syms)
assert(self);
self->syms = syms;
memset(self->error_msg, 0, GUX_STR_SIZE);
self->stack_size = 0;
}
void compiler_free(struct compiler* self)
@ -28,6 +30,26 @@ int compiler_compile(struct compiler* self,
switch (node->type)
{
case NODE_BLOCK: {
int stack_base = self->stack_size;
for (size_t i=0; i<node->children.size; i++)
{
if (compiler_compile(self, node->children.data[i], program) != 0)
{
return 1;
}
}
int top = self->stack_size - stack_base;
for (int i=0; i<top; i++)
{
compiler_gen_instr(self, program, OP_POP, NO_PARAM);
}
} break;
case NODE_ASSIGN: {
struct node* ident = node->children.data[0];
struct node* expr = node->children.data[1];
@ -40,7 +62,7 @@ int compiler_compile(struct compiler* self,
return 1;
}
program_push_instr(program, OP_STORE, entry->addr);
compiler_gen_instr(self, program, OP_STORE, entry->addr);
} break;
case NODE_IDENT: {
@ -56,7 +78,7 @@ int compiler_compile(struct compiler* self,
return 1;
}
program_push_instr(program, OP_LOAD, entry->addr);
compiler_gen_instr(self, program, OP_LOAD, entry->addr);
} break;
case NODE_CONSTDECL:
@ -76,7 +98,7 @@ int compiler_compile(struct compiler* self,
node);
assert(entry);
program_push_instr(program, OP_STORE, entry->addr);
compiler_gen_instr(self, program, OP_STORE, entry->addr);
} break;
case NODE_BOOL: {
struct value* val = malloc(sizeof(struct value));
@ -84,28 +106,28 @@ int compiler_compile(struct compiler* self,
strcmp(node->value, "true") == 0 ? 1 : 0,
node->line);
size_t addr = program_push_constant(program, val);
program_push_instr(program, OP_PUSH, addr);
compiler_gen_instr(self, program, OP_PUSH, addr);
} break;
case NODE_INT: {
struct value* val = malloc(sizeof(struct value));
value_init_int(val, atoi(node->value), node->line);
size_t addr = program_push_constant(program, val);
program_push_instr(program, OP_PUSH, addr);
compiler_gen_instr(self, program, OP_PUSH, addr);
} break;
case NODE_FLOAT: {
struct value* val = malloc(sizeof(struct value));
value_init_float(val, atof(node->value), node->line);
size_t addr = program_push_constant(program, val);
program_push_instr(program, OP_PUSH, addr);
compiler_gen_instr(self, program, OP_PUSH, addr);
} break;
case NODE_STRING: {
struct value* val = malloc(sizeof(struct value));
value_init_string(val, node->value, node->line);
size_t addr = program_push_constant(program, val);
program_push_instr(program, OP_PUSH, addr);
compiler_gen_instr(self, program, OP_PUSH, addr);
} break;
case NODE_ASSERT: {
@ -114,21 +136,21 @@ int compiler_compile(struct compiler* self,
return 1;
}
size_t brt = program_push_instr(program, OP_BRT, NO_PARAM);
program_push_instr(program, OP_PUSH, GUX_RET_ASSERT);
size_t halt = program_push_instr(program, OP_HALT, node->line);
size_t brt = compiler_gen_instr(self, program, OP_BRT, NO_PARAM);
compiler_gen_instr(self, program, OP_PUSH, GUX_RET_ASSERT);
size_t halt = compiler_gen_instr(self, program, OP_HALT, node->line);
struct instruction* instr = program->instructions.data[brt];
instr->param = halt + 1;
if (halt + 1 >= program->instructions.size)
{
program_push_instr(program, OP_NOP, NO_PARAM);
compiler_gen_instr(self, program, OP_NOP, NO_PARAM);
}
struct value* value = malloc(sizeof(struct value));
value_init_bool(value, VAL_TRUE, node->line);
program_push_instr(program, OP_PUSH,
compiler_gen_instr(self, program, OP_PUSH,
program_push_constant(program, value));
} break;
@ -140,7 +162,7 @@ int compiler_compile(struct compiler* self,
{
return 1;
}
program_push_instr(program, OP_EQ, NO_PARAM);
compiler_gen_instr(self, program, OP_EQ, NO_PARAM);
} break;
case NODE_NE: {
@ -152,8 +174,8 @@ int compiler_compile(struct compiler* self,
return 1;
}
program_push_instr(program, OP_EQ, NO_PARAM);
program_push_instr(program, OP_NOT, NO_PARAM);
compiler_gen_instr(self, program, OP_EQ, NO_PARAM);
compiler_gen_instr(self, program, OP_NOT, NO_PARAM);
} break;
case NODE_NOT: {
@ -162,7 +184,7 @@ int compiler_compile(struct compiler* self,
return 1;
}
program_push_instr(program, OP_NOT, NO_PARAM);
compiler_gen_instr(self, program, OP_NOT, NO_PARAM);
} break;
case NODE_AND: {
@ -177,17 +199,17 @@ int compiler_compile(struct compiler* self,
}
size_t* addr = malloc(sizeof(size_t));
*addr = program_push_instr(program, OP_BRF, NO_PARAM); // to pivot
*addr = compiler_gen_instr(self, program, OP_BRF, NO_PARAM); // to pivot
vec_push(&to_pivot, addr);
}
// true case
struct value* true_val = malloc(sizeof(struct value));
value_init_bool(true_val, VAL_TRUE, node->line);
program_push_instr(program, OP_PUSH,
compiler_gen_instr(self, program, OP_PUSH,
program_push_constant(program, true_val));
size_t to_end = program_push_instr(program, OP_BR, NO_PARAM); // to end
size_t to_end = compiler_gen_instr(self, program, OP_BR, NO_PARAM); // to end
// pivot
size_t pivot_point = program->instructions.size;
@ -195,7 +217,7 @@ int compiler_compile(struct compiler* self,
// false case
struct value* false_val = malloc(sizeof(struct value));
value_init_bool(false_val, VAL_FALSE, node->line);
program_push_instr(program, OP_PUSH,
compiler_gen_instr(self, program, OP_PUSH,
program_push_constant(program, false_val));
// end
@ -229,17 +251,17 @@ int compiler_compile(struct compiler* self,
}
size_t* addr = malloc(sizeof(size_t));
*addr = program_push_instr(program, OP_BRT, NO_PARAM); // to pivot
*addr = compiler_gen_instr(self, program, OP_BRT, NO_PARAM); // to pivot
vec_push(&to_pivot, addr);
}
// false case
struct value* false_val = malloc(sizeof(struct value));
value_init_bool(false_val, VAL_FALSE, node->line);
program_push_instr(program, OP_PUSH,
compiler_gen_instr(self, program, OP_PUSH,
program_push_constant(program, false_val));
size_t to_end = program_push_instr(program, OP_BR, NO_PARAM); // to end
size_t to_end = compiler_gen_instr(self, program, OP_BR, NO_PARAM); // to end
// pivot
size_t pivot_point = program->instructions.size;
@ -247,7 +269,7 @@ int compiler_compile(struct compiler* self,
// false case
struct value* true_val = malloc(sizeof(struct value));
value_init_bool(true_val, VAL_TRUE, node->line);
program_push_instr(program, OP_PUSH,
compiler_gen_instr(self, program, OP_PUSH,
program_push_constant(program, true_val));
// end
@ -291,16 +313,16 @@ int compiler_compile(struct compiler* self,
switch (node->type)
{
case NODE_ADD: program_push_instr(program, OP_ADD, NO_PARAM); break;
case NODE_SUB: program_push_instr(program, OP_SUB, NO_PARAM); break;
case NODE_MUL: program_push_instr(program, OP_MUL, NO_PARAM); break;
case NODE_DIV: program_push_instr(program, OP_DIV, NO_PARAM); break;
case NODE_MOD: program_push_instr(program, OP_MOD, NO_PARAM); break;
case NODE_POW: program_push_instr(program, OP_POW, NO_PARAM); break;
case NODE_LT: program_push_instr(program, OP_LT, NO_PARAM); break;
case NODE_LE: program_push_instr(program, OP_LE, NO_PARAM); break;
case NODE_GT: program_push_instr(program, OP_GT, NO_PARAM); break;
case NODE_GE: program_push_instr(program, OP_GE, NO_PARAM); break;
case NODE_ADD: compiler_gen_instr(self, program, OP_ADD, NO_PARAM); break;
case NODE_SUB: compiler_gen_instr(self, program, OP_SUB, NO_PARAM); break;
case NODE_MUL: compiler_gen_instr(self, program, OP_MUL, NO_PARAM); break;
case NODE_DIV: compiler_gen_instr(self, program, OP_DIV, NO_PARAM); break;
case NODE_MOD: compiler_gen_instr(self, program, OP_MOD, NO_PARAM); break;
case NODE_POW: compiler_gen_instr(self, program, OP_POW, NO_PARAM); break;
case NODE_LT: compiler_gen_instr(self, program, OP_LT, NO_PARAM); break;
case NODE_LE: compiler_gen_instr(self, program, OP_LE, NO_PARAM); break;
case NODE_GT: compiler_gen_instr(self, program, OP_GT, NO_PARAM); break;
case NODE_GE: compiler_gen_instr(self, program, OP_GE, NO_PARAM); break;
default: break;
}
@ -320,3 +342,45 @@ int compiler_compile(struct compiler* self,
return 0;
}
size_t compiler_gen_instr(struct compiler* self,
struct program* program,
enum Opcodes op,
int param)
{
assert(self);
assert(program);
size_t addr = program_push_instr(program, op, param);
switch (op)
{
case OP_LOAD:
case OP_PUSH: self->stack_size += 1; break;
case OP_LT:
case OP_LE:
case OP_GT:
case OP_GE:
case OP_ADD:
case OP_SUB:
case OP_MUL:
case OP_DIV:
case OP_MOD:
case OP_POW:
case OP_EQ:
case OP_POP:
case OP_HALT:
case OP_BRF:
case OP_BRT:
self->stack_size -= 1; break;
case OP_SWAP:
case OP_BR:
case OP_NOT:
case OP_NOP:
case OP_STORE: break;
}
return addr;
}

View File

@ -10,6 +10,7 @@ struct compiler {
char error_msg[GUX_STR_SIZE];
struct syms* syms;
int error_line;
int stack_size;
};
void compiler_init(struct compiler* self, struct syms* syms);
@ -19,4 +20,9 @@ int compiler_compile(struct compiler* self,
struct node* node,
struct program* program);
size_t compiler_gen_instr(struct compiler* self,
struct program* program,
enum Opcodes op,
int param);
#endif

View File

@ -5,7 +5,8 @@
G(OP_PUSH), G(OP_POP), G(OP_BRF), G(OP_BR), G(OP_HALT), \
G(OP_BRT), G(OP_NOP), G(OP_NOT), G(OP_EQ), \
G(OP_ADD), G(OP_SUB), G(OP_MUL), G(OP_DIV), G(OP_MOD), G(OP_POW), \
G(OP_LT), G(OP_LE), G(OP_GT),G(OP_GE), G(OP_LOAD), G(OP_STORE)
G(OP_LT), G(OP_LE), G(OP_GT),G(OP_GE), G(OP_LOAD), G(OP_STORE),\
G(OP_SWAP)
#include <commons.h>

View File

@ -53,7 +53,7 @@ int type_resolver_resolve(struct type_resolver* self,
case NODE_IDENT: {
struct syms_entry* entry = syms_try_get(self->syms,
node->value,
node_depth(node));
node);
if (!entry)
{

View File

@ -9,7 +9,7 @@
#include <ctype.h>
#include <stdarg.h>
#define GUX_STR_SIZE 256
#define GUX_STR_SIZE 512
#define GUX_ENUM_IDENT(X) X
#define GUX_ENUM_STR(X) #X
#define GUX_ENUM_H(Prefix, Types) \

View File

@ -124,6 +124,14 @@ int vm_exec(struct vm* self, struct program* program)
switch (opcode)
{
case OP_SWAP: {
assert(frame->sp > 1);
int tmp = frame->stack[frame->sp - 1];
frame->stack[frame->sp - 1] = frame->stack[frame->sp - 2];
frame->stack[frame->sp - 2] = tmp;
self->pc++;
} break;
case OP_LOAD: {
int stack_addr = vm_load(self, param);
struct frame* myframe = self->stack[self->fp - 1];