Compare commits
No commits in common. "d1286c008bf6a147d20b2d0af7a280244eee35ae" and "85875d2d946b8c139d5a7b78242cf91cbe0c997f" have entirely different histories.
d1286c008b
...
85875d2d94
|
@ -17,14 +17,13 @@ LEXPR ::=
|
|||
| continue
|
||||
| return EXPR?
|
||||
| FUN
|
||||
| new EXPR
|
||||
| free EXPR
|
||||
|
||||
BEXPR ::=
|
||||
| BLOCK
|
||||
| IF
|
||||
| WHILE
|
||||
|
||||
|
||||
IF ::=
|
||||
| if EXPR BLOCK
|
||||
| if EXPR BLOCK else BLOCK
|
||||
|
@ -35,7 +34,7 @@ WHILE ::= while EXPR BLOCK
|
|||
FUN ::= fun PARAMS (rarrow TYPE) BLOCK
|
||||
|
||||
PARAMS ::=
|
||||
| opar var? ident colon TYPE (comma var? ident colon type)* cpar
|
||||
| opar ident colon TYPE (comma ident colon type)* cpar
|
||||
|
||||
BLOCK ::= obrace INSTR* cbrace
|
||||
VARDECL ::= var ident colon TYPE? assign EXPR
|
||||
|
@ -68,4 +67,3 @@ BUILTIN ::= bool | int | float | string
|
|||
TYPE ::=
|
||||
| type
|
||||
| opar TYPE+ rarrow TYPE+ cpar
|
||||
| rawptr TYPE
|
||||
|
|
|
@ -173,7 +173,7 @@ int main(int argc, char** argv)
|
|||
|
||||
if (type_checker_check(&checker, ast) != 0)
|
||||
{
|
||||
fprintf(stderr, "[%s:%d] type check error, %s\n",
|
||||
fprintf(stderr, "[%s:%d] %s\n",
|
||||
path,
|
||||
checker.error_line,
|
||||
checker.error_msg);
|
||||
|
@ -215,7 +215,7 @@ int main(int argc, char** argv)
|
|||
|
||||
if (compiler_compile(&compiler, ast, &program) != 0)
|
||||
{
|
||||
fprintf(stderr, "[%s:%d] compile error, %s\n",
|
||||
fprintf(stderr, "[%s:%d] %s\n",
|
||||
path,
|
||||
compiler.error_line,
|
||||
compiler.error_msg);
|
||||
|
|
|
@ -18,7 +18,6 @@ void compiler_init(struct compiler* self, struct sym_table* global)
|
|||
memset(self->error_msg, 0, GUX_STR_SIZE);
|
||||
self->stack_size = 0;
|
||||
vec_init(&self->loops, 1);
|
||||
self->heap_addr_counter = 1000;
|
||||
}
|
||||
|
||||
void compiler_free(struct compiler* self)
|
||||
|
@ -39,21 +38,6 @@ int compiler_compile(struct compiler* self,
|
|||
|
||||
switch (node->type)
|
||||
{
|
||||
case NODE_NEW: {
|
||||
compiler_compile(self, node->children.data[0], program);
|
||||
compiler_gen_instr(self, program, OP_NEW, self->heap_addr_counter++);
|
||||
} break;
|
||||
|
||||
case NODE_FREE: {
|
||||
struct node* ident = node->children.data[0];
|
||||
|
||||
struct sym* entry = sym_table_fetch(&self->sym_table,
|
||||
ident->value,
|
||||
NULL);
|
||||
|
||||
compiler_gen_instr(self, program, OP_FREE, entry->addr);
|
||||
} break;
|
||||
|
||||
case NODE_RETURN: {
|
||||
if (node->children.size > 0)
|
||||
{
|
||||
|
@ -81,11 +65,7 @@ int compiler_compile(struct compiler* self,
|
|||
{
|
||||
struct node* param = params->children.data[i];
|
||||
|
||||
if (param->type == NODE_VAR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (param->type != NODE_TYPE)
|
||||
if (param->type != NODE_TYPE)
|
||||
{
|
||||
vec_push(&idents, param);
|
||||
}
|
||||
|
@ -96,7 +76,8 @@ int compiler_compile(struct compiler* self,
|
|||
struct node* ident = idents.data[j];
|
||||
|
||||
struct type* ty = malloc(sizeof(struct type));
|
||||
type_init_from_node(ty, param);
|
||||
type_init(ty, TYPE_VOID);
|
||||
compiler_get_type(self, param, ty);
|
||||
|
||||
sym_table_declare_const(&compiler.sym_table,
|
||||
ident->value,
|
||||
|
@ -274,32 +255,13 @@ int compiler_compile(struct compiler* self,
|
|||
struct node* ident = node->children.data[0];
|
||||
struct node* expr = node->children.data[1];
|
||||
|
||||
struct type lhs_ty;
|
||||
type_init(&lhs_ty, TYPE_VOID);
|
||||
compiler_get_type(self, ident, &lhs_ty);
|
||||
|
||||
int is_ptr = lhs_ty.kind == TYPE_RAW_PTR;
|
||||
|
||||
struct type type;
|
||||
type_init(&type, TYPE_VOID);
|
||||
compiler_get_type(self, expr, &type);
|
||||
|
||||
struct sym* entry;
|
||||
|
||||
if (is_ptr)
|
||||
{
|
||||
entry = sym_table_fetch(&self->sym_table,
|
||||
ident->value,
|
||||
&lhs_ty);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry = sym_table_fetch(&self->sym_table,
|
||||
ident->value,
|
||||
&type);
|
||||
}
|
||||
|
||||
type_free(&lhs_ty);
|
||||
struct sym* entry = sym_table_fetch(&self->sym_table,
|
||||
ident->value,
|
||||
&type);
|
||||
type_free(&type);
|
||||
|
||||
assert(entry);
|
||||
|
@ -309,8 +271,7 @@ int compiler_compile(struct compiler* self,
|
|||
return 1;
|
||||
}
|
||||
|
||||
compiler_gen_instr(self, program, is_ptr ? OP_REFSTORE : OP_STORE,
|
||||
entry->addr);
|
||||
compiler_gen_instr(self, program, OP_STORE, entry->addr);
|
||||
} break;
|
||||
|
||||
case NODE_IDENT: {
|
||||
|
@ -338,11 +299,11 @@ int compiler_compile(struct compiler* self,
|
|||
|
||||
case NODE_CONSTDECL:
|
||||
case NODE_VARDECL: {
|
||||
struct node* rhs = node->children.size == 1
|
||||
? node->children.data[0]
|
||||
: node->children.data[1];
|
||||
|
||||
int err = compiler_compile(self, rhs, program);
|
||||
int err = compiler_compile(self, node->children.size == 1
|
||||
? node->children.data[0]
|
||||
: node->children.data[1],
|
||||
program);
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
|
@ -351,7 +312,7 @@ int compiler_compile(struct compiler* self,
|
|||
|
||||
struct type* ty = malloc(sizeof(struct type));
|
||||
type_init(ty, TYPE_VOID);
|
||||
compiler_get_type(self, rhs, ty);
|
||||
compiler_get_type(self, node->children.data[0], ty);
|
||||
|
||||
sym_table_declare(&self->sym_table, node->value, ty,
|
||||
node->type == NODE_VARDECL);
|
||||
|
@ -359,10 +320,10 @@ int compiler_compile(struct compiler* self,
|
|||
struct sym* entry = sym_table_fetch(&self->sym_table,
|
||||
node->value,
|
||||
ty);
|
||||
|
||||
assert(entry);
|
||||
|
||||
compiler_gen_instr(self, program, OP_STORE, entry->addr);
|
||||
|
||||
} break;
|
||||
case NODE_BOOL: {
|
||||
struct value* val = malloc(sizeof(struct value));
|
||||
|
@ -676,7 +637,6 @@ size_t compiler_gen_instr(struct compiler* self,
|
|||
case OP_GLOAD:
|
||||
case OP_PUSH: self->stack_size += 1; break;
|
||||
|
||||
case OP_FREE:
|
||||
case OP_LT:
|
||||
case OP_LE:
|
||||
case OP_GT:
|
||||
|
@ -694,17 +654,12 @@ size_t compiler_gen_instr(struct compiler* self,
|
|||
case OP_BRT:
|
||||
self->stack_size -= 1; break;
|
||||
|
||||
case OP_DEREF:
|
||||
case OP_NEW:
|
||||
case OP_RET:
|
||||
case OP_SWAP:
|
||||
case OP_BR:
|
||||
case OP_NOT:
|
||||
case OP_NOP:
|
||||
case OP_STORE:
|
||||
case OP_REFSTORE:break;
|
||||
|
||||
default: assert(0);
|
||||
case OP_STORE: break;
|
||||
}
|
||||
|
||||
return addr;
|
||||
|
|
|
@ -17,7 +17,6 @@ struct compiler {
|
|||
int error_line;
|
||||
int stack_size;
|
||||
struct vec loops;
|
||||
int heap_addr_counter;
|
||||
};
|
||||
|
||||
void compiler_init(struct compiler* self, struct sym_table* global);
|
||||
|
|
|
@ -26,14 +26,11 @@ void lexer_init(struct lexer* self, char const* source)
|
|||
|
||||
lexer_add_tok(self, "var", NODE_VAR, "", 1);
|
||||
|
||||
lexer_add_tok(self, "new", NODE_NEW, "", 1);
|
||||
lexer_add_tok(self, "free", NODE_FREE, "", 1);
|
||||
lexer_add_tok(self, "int", NODE_TYPE, "int", 1);
|
||||
lexer_add_tok(self, "float", NODE_TYPE, "float", 1);
|
||||
lexer_add_tok(self, "bool", NODE_TYPE, "bool", 1);
|
||||
lexer_add_tok(self, "string", NODE_TYPE, "string", 1);
|
||||
|
||||
lexer_add_tok(self, "^", NODE_PTR, "", 0);
|
||||
lexer_add_tok(self, ",", NODE_COMMA, "", 0);
|
||||
lexer_add_tok(self, "{", NODE_OBRACE, "", 0);
|
||||
lexer_add_tok(self, "}", NODE_CBRACE, "", 0);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
G(NODE_IF), G(NODE_ELSE), G(NODE_COND), G(NODE_WHILE), G(NODE_FOR), \
|
||||
G(NODE_CONTINUE), G(NODE_BREAK), G(NODE_RARROW), G(NODE_FUN), \
|
||||
G(NODE_RETURN), G(NODE_PARAMS), G(NODE_COMMA), G(NODE_CALL), \
|
||||
G(NODE_ARGS), G(NODE_RAWPTR), G(NODE_PTR), G(NODE_FREE), G(NODE_NEW)
|
||||
G(NODE_ARGS)
|
||||
|
||||
|
||||
GUX_ENUM_H(NodeType, NODE_TYPE);
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
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_SWAP), G(OP_CALL), G(OP_RET), G(OP_GLOAD), G(OP_NEW), \
|
||||
G(OP_FREE), G(OP_DEREF), G(OP_REFSTORE)
|
||||
G(OP_SWAP), G(OP_CALL), G(OP_RET), G(OP_GLOAD)
|
||||
|
||||
#include <commons.h>
|
||||
|
||||
|
|
|
@ -149,8 +149,7 @@ int parser_start_type(struct parser* self)
|
|||
struct node* tok = self->tokens.data[self->cursor];
|
||||
|
||||
return tok->type == NODE_OPAR
|
||||
|| tok->type == NODE_TYPE
|
||||
|| tok->type == NODE_PTR;
|
||||
|| tok->type == NODE_TYPE;
|
||||
}
|
||||
|
||||
struct node* parser_try_new_root(struct parser* self, char const* source)
|
||||
|
@ -233,29 +232,11 @@ struct node* parser_try_new_lexpr(struct parser* self)
|
|||
{
|
||||
assert(self);
|
||||
|
||||
if (parser_try_consume(self, NODE_FREE) == 0)
|
||||
{
|
||||
struct node* node = malloc(sizeof(struct node));
|
||||
node_init(node, NODE_FREE, "", parser_current_line(self));
|
||||
node_add_child(node, parser_try_new_expr(self));
|
||||
return node;
|
||||
}
|
||||
|
||||
if (parser_type_is(self, NODE_FUN, 0))
|
||||
{
|
||||
return parser_try_new_fun(self);
|
||||
}
|
||||
|
||||
if (parser_try_consume(self, NODE_NEW) == 0)
|
||||
{
|
||||
struct node* node = malloc(sizeof(struct node));
|
||||
node_init(node, NODE_NEW, "", parser_current_line(self));
|
||||
|
||||
node_add_child(node, parser_try_new_expr(self));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
if (parser_try_consume(self, NODE_RETURN) == 0)
|
||||
{
|
||||
struct node* node = malloc(sizeof(struct node));
|
||||
|
@ -444,8 +425,7 @@ struct node* parser_try_new_params(struct parser* self)
|
|||
|
||||
while (1)
|
||||
{
|
||||
if (!parser_type_is(self, NODE_IDENT, 0)
|
||||
&& !parser_type_is(self, NODE_VAR, 0))
|
||||
if (!parser_type_is(self, NODE_IDENT, 0))
|
||||
{
|
||||
vec_free_elements(&types);
|
||||
vec_free(&types);
|
||||
|
@ -454,14 +434,6 @@ struct node* parser_try_new_params(struct parser* self)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (parser_try_consume(self, NODE_VAR) == 0)
|
||||
{
|
||||
struct node* var = malloc(sizeof(struct node));
|
||||
node_init(var, NODE_VAR, "",
|
||||
parser_current_line(self));
|
||||
node_add_child(node, var);
|
||||
}
|
||||
|
||||
// ident
|
||||
struct node* current = self->tokens.data[self->cursor];
|
||||
struct node* ident = malloc(sizeof(struct node));
|
||||
|
@ -592,9 +564,14 @@ struct node* parser_try_new_vardecl(struct parser* self)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (parser_type_is(self, NODE_TYPE, 0)
|
||||
|| parser_type_is(self, NODE_PTR, 0))
|
||||
if (parser_type_is(self, NODE_TYPE, 0))
|
||||
{
|
||||
/*current = self->tokens.data[self->cursor];
|
||||
struct node* ty = malloc(sizeof(struct node));
|
||||
node_init(ty, NODE_TYPE, current->value, parser_current_line(self));
|
||||
|
||||
node_add_child(node, ty);
|
||||
self->cursor++;*/
|
||||
node_add_child(node, parser_try_new_type(self));
|
||||
}
|
||||
|
||||
|
@ -976,14 +953,6 @@ struct node* parser_try_new_type(struct parser* self)
|
|||
{
|
||||
assert(self);
|
||||
|
||||
if (parser_try_consume(self, NODE_PTR) == 0)
|
||||
{
|
||||
struct node* node = malloc(sizeof(struct node));
|
||||
node_init(node, NODE_TYPE, "rawptr", parser_current_line(self));
|
||||
node_add_child(node, parser_try_new_type(self));
|
||||
return node;
|
||||
}
|
||||
|
||||
if (parser_type_is(self, NODE_OPAR, 0))
|
||||
{
|
||||
self->cursor++; // opar
|
||||
|
|
|
@ -14,13 +14,10 @@ void program_free(struct program* self)
|
|||
|
||||
for (size_t i=0; i<self->constant_pool.size; i++)
|
||||
{
|
||||
if (self->constant_pool.data[i] != NULL)
|
||||
{
|
||||
value_free(self->constant_pool.data[i]);
|
||||
free(self->constant_pool.data[i]);
|
||||
}
|
||||
value_free(self->constant_pool.data[i]);
|
||||
}
|
||||
|
||||
vec_free_elements(&self->constant_pool);
|
||||
vec_free(&self->constant_pool);
|
||||
|
||||
vec_free_elements(&self->instructions);
|
||||
|
|
|
@ -12,12 +12,6 @@ void sym_table_init(struct sym_table* self, struct sym_table* prev)
|
|||
self->addr_counter = 0;
|
||||
|
||||
self->prev = prev;
|
||||
self->next = NULL;
|
||||
|
||||
if (self->prev && self->prev->next == NULL)
|
||||
{
|
||||
self->prev->next = self;
|
||||
}
|
||||
}
|
||||
|
||||
void sym_table_free(struct sym_table* self)
|
||||
|
@ -102,7 +96,7 @@ struct sym* sym_table_fetch(struct sym_table* self,
|
|||
|
||||
if (self->prev)
|
||||
{
|
||||
return sym_table_fetch(self->prev, name, type);
|
||||
return sym_table_fetch(self->prev, name, NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -115,15 +109,8 @@ struct sym* sym_table_fetch_fun(struct sym_table* self,
|
|||
struct vec args_ty;
|
||||
vec_init(&args_ty, 1);
|
||||
|
||||
struct sym_table* itr = self;
|
||||
|
||||
while (itr->next)
|
||||
{
|
||||
itr = itr->next;
|
||||
}
|
||||
|
||||
struct type_resolver resolver;
|
||||
type_resolver_init(&resolver, itr);
|
||||
type_resolver_init(&resolver, self);
|
||||
|
||||
for (size_t i=0; i < args->children.size; i++)
|
||||
{
|
||||
|
@ -132,7 +119,6 @@ struct sym* sym_table_fetch_fun(struct sym_table* self,
|
|||
type_init(arg_type, TYPE_VOID);
|
||||
|
||||
type_resolver_resolve(&resolver, child, arg_type);
|
||||
|
||||
vec_push(&args_ty, arg_type);
|
||||
}
|
||||
|
||||
|
@ -191,7 +177,7 @@ struct sym* sym_table_fetch_fun(struct sym_table* self,
|
|||
|
||||
if (self->prev)
|
||||
{
|
||||
return sym_table_fetch_fun(self->prev, name, args);
|
||||
return sym_table_fetch(self->prev, name, NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -219,7 +205,7 @@ int sym_table_declare(struct sym_table* self,
|
|||
assert(self);
|
||||
assert(strcmp(name, "") != 0);
|
||||
|
||||
struct sym* s = sym_table_fetch(self, name, new_type);
|
||||
struct sym* s = sym_table_fetch(self, name, NULL);
|
||||
|
||||
if (s && s->parent == self->root
|
||||
&& type_equals(s->type, new_type))
|
||||
|
@ -233,7 +219,7 @@ int sym_table_declare(struct sym_table* self,
|
|||
sym->type = new_type;
|
||||
sym->parent = self->root;
|
||||
sym->is_global = 0;
|
||||
sym->type->is_var = is_var;
|
||||
sym->is_var = is_var;
|
||||
sym->addr = self->addr_counter;
|
||||
vec_push(&table->syms, sym);
|
||||
|
||||
|
@ -250,7 +236,7 @@ int sym_table_declare_global(struct sym_table* self,
|
|||
assert(self);
|
||||
assert(strcmp(name, "") != 0);
|
||||
|
||||
struct sym* s = sym_table_fetch(self, name, new_type);
|
||||
struct sym* s = sym_table_fetch(self, name, NULL);
|
||||
|
||||
if (s && s->parent == self->root && s->is_global
|
||||
&& type_equals(s->type, new_type))
|
||||
|
@ -264,7 +250,7 @@ int sym_table_declare_global(struct sym_table* self,
|
|||
sym->type = new_type;
|
||||
sym->parent = self->root;
|
||||
sym->is_global = 1;
|
||||
sym->type->is_var = 0;
|
||||
sym->is_var = 0;
|
||||
sym->addr = addr;
|
||||
vec_push(&table->syms, sym);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
struct sym {
|
||||
struct table* parent;
|
||||
char* name;
|
||||
//int is_var;
|
||||
int is_var;
|
||||
int is_global;
|
||||
int addr;
|
||||
struct type* type;
|
||||
|
@ -20,7 +20,6 @@ struct table {
|
|||
};
|
||||
|
||||
struct sym_table {
|
||||
struct sym_table* next;
|
||||
struct sym_table* prev;
|
||||
struct table* root;
|
||||
int addr_counter;
|
||||
|
|
|
@ -8,7 +8,6 @@ void type_init(struct type* self, enum TypeKind kind)
|
|||
{
|
||||
assert(self);
|
||||
self->kind = kind;
|
||||
self->is_var = 0;
|
||||
vec_init(&self->subtypes, 1);
|
||||
}
|
||||
|
||||
|
@ -16,17 +15,9 @@ void type_init_from_node(struct type* self, struct node* node)
|
|||
{
|
||||
assert(self);
|
||||
|
||||
self->is_var = 0;
|
||||
vec_init(&self->subtypes, 1);
|
||||
|
||||
if (node->type == NODE_TYPE && strcmp(node->value, "rawptr") == 0)
|
||||
{
|
||||
self->kind = TYPE_RAW_PTR;
|
||||
type_add_subtype(self, TYPE_VOID);
|
||||
type_free(self->subtypes.data[0]);
|
||||
type_init_from_node(self->subtypes.data[0], node->children.data[0]);
|
||||
}
|
||||
else if (node->type == NODE_TYPE && strcmp(node->value, "fun") == 0)
|
||||
if (node->type == NODE_TYPE && strcmp(node->value, "fun") == 0)
|
||||
{
|
||||
self->kind = TYPE_FUN;
|
||||
int input = 1;
|
||||
|
@ -77,23 +68,14 @@ void type_init_from_node(struct type* self, struct node* node)
|
|||
type_init_from_node(ret_ty, ret);
|
||||
vec_push(&self->subtypes, ret_ty);
|
||||
|
||||
int is_var = 0;
|
||||
|
||||
for (size_t i=0; i<params->children.size; i++)
|
||||
{
|
||||
struct node* child = params->children.data[i];
|
||||
|
||||
if (child->type == NODE_VAR)
|
||||
{
|
||||
is_var = 1;
|
||||
}
|
||||
|
||||
if (child->type == NODE_TYPE)
|
||||
{
|
||||
struct type* param_ty = malloc(sizeof(struct type));
|
||||
type_init_from_node(param_ty, child);
|
||||
param_ty->is_var = is_var;
|
||||
is_var = 0;
|
||||
vec_push(&self->subtypes, param_ty);
|
||||
}
|
||||
}
|
||||
|
@ -112,8 +94,6 @@ void type_copy(struct type* self, struct type* dest)
|
|||
type_free(dest);
|
||||
type_init(dest, self->kind);
|
||||
|
||||
dest->is_var = self->is_var;
|
||||
|
||||
for (size_t i=0; i<self->subtypes.size; i++)
|
||||
{
|
||||
type_add_subtype(dest, TYPE_VOID);
|
||||
|
@ -169,25 +149,6 @@ int type_equals(struct type* self, struct type* rhs)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int type_equiv(struct type* self, struct type* rhs)
|
||||
{
|
||||
assert(self);
|
||||
assert(rhs);
|
||||
|
||||
if (type_equals(self, rhs))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (self->kind == TYPE_RAW_PTR
|
||||
&& type_equals(self->subtypes.data[0], rhs))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void type_add_subtype(struct type* self, enum TypeKind kind)
|
||||
{
|
||||
assert(self);
|
||||
|
@ -203,11 +164,6 @@ size_t type_str(struct type* self, char* buffer, size_t size)
|
|||
assert(buffer);
|
||||
size_t sz = 0;
|
||||
|
||||
if (0 && self->is_var)
|
||||
{
|
||||
sz += snprintf(buffer + sz, size - sz, "VAR_");
|
||||
}
|
||||
|
||||
sz += snprintf(buffer + sz, size - sz, "%s",
|
||||
TypeKindStr[self->kind] + strlen("TYPE_"));
|
||||
|
||||
|
|
|
@ -7,15 +7,13 @@
|
|||
|
||||
#define TYPE_KIND(G) \
|
||||
G(TYPE_VOID), G(TYPE_BOOL), G(TYPE_INT), \
|
||||
G(TYPE_FLOAT), G(TYPE_STRING), G(TYPE_FUN), \
|
||||
G(TYPE_RAW_PTR)
|
||||
G(TYPE_FLOAT), G(TYPE_STRING), G(TYPE_FUN)
|
||||
|
||||
GUX_ENUM_H(TypeKind, TYPE_KIND);
|
||||
|
||||
struct type {
|
||||
enum TypeKind kind;
|
||||
struct vec subtypes;
|
||||
int is_var;
|
||||
};
|
||||
|
||||
void type_init(struct type* self, enum TypeKind kind);
|
||||
|
@ -26,8 +24,6 @@ void type_copy(struct type* self, struct type* dest);
|
|||
void type_clear(struct type* self);
|
||||
|
||||
int type_equals(struct type* self, struct type* rhs);
|
||||
int type_equiv(struct type* self, struct type* rhs);
|
||||
|
||||
void type_add_subtype(struct type* self, enum TypeKind kind);
|
||||
size_t type_str(struct type* self, char* buffer, size_t size);
|
||||
int type_is(struct type* self, char const* repr);
|
||||
|
|
|
@ -44,7 +44,7 @@ int type_checker_check(struct type_checker* self,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!type_equiv(&fun_ty, &ret_ty))
|
||||
if (!type_equals(&fun_ty, &ret_ty))
|
||||
{
|
||||
type_checker_error_msg(self, node, &fun_ty, &ret_ty);
|
||||
|
||||
|
@ -83,8 +83,8 @@ int type_checker_check(struct type_checker* self,
|
|||
struct node* args = node->children.data[1];
|
||||
|
||||
struct sym* entry = sym_table_fetch_fun(&self->sym_table,
|
||||
target->value,
|
||||
args);
|
||||
target->value,
|
||||
args);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
|
@ -118,30 +118,13 @@ int type_checker_check(struct type_checker* self,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (type_checker_check(self, sub_node) != 0)
|
||||
{
|
||||
self->error_line = sub_node->line;
|
||||
|
||||
type_free(&t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!type_equiv(&t, sub))
|
||||
if (!type_equals(&t, sub))
|
||||
{
|
||||
type_checker_error_msg(self, sub_node, sub, &t);
|
||||
type_free(&t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!t.is_var && sub->is_var)
|
||||
{
|
||||
snprintf(self->error_msg, GUX_STR_SIZE,
|
||||
"<%s> is not mutable", sub_node->value);
|
||||
self->error_line = sub_node->line;
|
||||
type_free(&t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
type_free(&t);
|
||||
}
|
||||
|
||||
|
@ -157,9 +140,6 @@ int type_checker_check(struct type_checker* self,
|
|||
struct vec names;
|
||||
vec_init(&names, 1);
|
||||
|
||||
struct vec vars;
|
||||
vec_init(&vars, 1);
|
||||
|
||||
for (size_t i=0; i<params->children.size; i++)
|
||||
{
|
||||
struct node* param = params->children.data[i];
|
||||
|
@ -172,34 +152,16 @@ int type_checker_check(struct type_checker* self,
|
|||
struct type* ty = malloc(sizeof(struct type));
|
||||
type_init_from_node(ty, param);
|
||||
|
||||
int* var = vars.data[j];
|
||||
ty->is_var = *var;
|
||||
|
||||
sym_table_declare(&self->sym_table,
|
||||
n->value,
|
||||
ty,
|
||||
*var);
|
||||
sym_table_declare_const(&self->sym_table,
|
||||
n->value,
|
||||
ty);
|
||||
}
|
||||
|
||||
vec_free(&names);
|
||||
vec_init(&names, 1);
|
||||
vec_free_elements(&vars);
|
||||
vec_free(&vars);
|
||||
vec_init(&vars, 1);
|
||||
}
|
||||
else if (param->type == NODE_VAR)
|
||||
else
|
||||
{
|
||||
int* var = malloc(sizeof(int));
|
||||
*var = 1;
|
||||
vec_push(&vars, var);
|
||||
vec_push(&names, params->children.data[i + 1]);
|
||||
i++;
|
||||
}
|
||||
else if (param->type == NODE_IDENT)
|
||||
{
|
||||
int* var = malloc(sizeof(int));
|
||||
*var = 0;
|
||||
vec_push(&vars, var);
|
||||
vec_push(&names, param);
|
||||
}
|
||||
}
|
||||
|
@ -249,8 +211,6 @@ int type_checker_check(struct type_checker* self,
|
|||
type_free(&ret_ty);
|
||||
vec_free(&ret_instrs);
|
||||
vec_free(&names);
|
||||
vec_free_elements(&vars);
|
||||
vec_free(&vars);
|
||||
|
||||
sym_table_pop_table(&self->sym_table);
|
||||
}
|
||||
|
@ -266,7 +226,7 @@ int type_checker_check(struct type_checker* self,
|
|||
struct type want;
|
||||
type_init(&want, TYPE_BOOL);
|
||||
|
||||
if (!type_equiv(&have, &want))
|
||||
if (!type_equals(&have, &want))
|
||||
{
|
||||
type_checker_error_msg(self, node, &want, &have);
|
||||
type_free(&have);
|
||||
|
@ -332,7 +292,7 @@ int type_checker_check(struct type_checker* self,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!entry->type->is_var)
|
||||
if (!entry->is_var)
|
||||
{
|
||||
snprintf(self->error_msg, GUX_STR_SIZE, "<%s> is not mutable",
|
||||
ident->value);
|
||||
|
@ -348,7 +308,7 @@ int type_checker_check(struct type_checker* self,
|
|||
|
||||
type_resolver_resolve(&self->resolver, expr, &expr_type);
|
||||
|
||||
if (!type_equiv(var_type, &expr_type))
|
||||
if (!type_equals(var_type, &expr_type))
|
||||
{
|
||||
type_checker_error_msg(self, node, var_type, &expr_type);
|
||||
type_free(&expr_type);
|
||||
|
@ -362,8 +322,8 @@ int type_checker_check(struct type_checker* self,
|
|||
case NODE_CONSTDECL:{
|
||||
struct type type;
|
||||
type_init(&type, TYPE_VOID);
|
||||
type_resolver_resolve(&self->resolver,
|
||||
node->children.data[0], &type);
|
||||
|
||||
type_resolver_resolve(&self->resolver, node->children.data[0], &type);
|
||||
|
||||
struct sym* entry = sym_table_fetch(&self->sym_table,
|
||||
node->value,
|
||||
|
@ -401,11 +361,6 @@ int type_checker_check(struct type_checker* self,
|
|||
|
||||
if (type_resolver_resolve(&self->resolver, expr, ty) != 0)
|
||||
{
|
||||
char expr_str[GUX_STR_SIZE];
|
||||
node_str(expr, expr_str, GUX_STR_SIZE);
|
||||
snprintf(self->error_msg, GUX_STR_SIZE * 2,
|
||||
"cannot find type of <%s>.", expr_str);
|
||||
self->error_line = expr->line;
|
||||
type_free(ty);
|
||||
free(ty);
|
||||
return 1;
|
||||
|
@ -515,7 +470,7 @@ int type_checker_check(struct type_checker* self,
|
|||
lhs_msg);
|
||||
}
|
||||
}
|
||||
else if (!type_equiv(&lhs_type, &rhs_type))
|
||||
else if (!type_equals(&lhs_type, &rhs_type))
|
||||
{
|
||||
snprintf(self->error_msg, MSG_SZ,
|
||||
"type mismatch (<%s>, <%s>)",
|
||||
|
@ -525,7 +480,7 @@ int type_checker_check(struct type_checker* self,
|
|||
|
||||
if (solve_lhs != 0
|
||||
|| solve_rhs != 0
|
||||
|| !type_equiv(&lhs_type, &rhs_type)
|
||||
|| !type_equals(&lhs_type, &rhs_type)
|
||||
|| lhs_type.subtypes.size > 0
|
||||
|| rhs_type.subtypes.size > 0
|
||||
|| (lhs_type.kind != TYPE_INT && lhs_type.kind != TYPE_FLOAT)
|
||||
|
@ -585,7 +540,7 @@ int type_checker_check(struct type_checker* self,
|
|||
node->children.data[i],
|
||||
&node_type);
|
||||
|
||||
if (!type_equiv(&type, &node_type))
|
||||
if (!type_equals(&type, &node_type))
|
||||
{
|
||||
self->error_line = node->line;
|
||||
snprintf(self->error_msg,
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "type_resolver.h"
|
||||
#include "commons.h"
|
||||
#include "node.h"
|
||||
#include "sym_table.h"
|
||||
#include "type.h"
|
||||
|
||||
void type_resolver_init(struct type_resolver* self,
|
||||
|
@ -28,14 +26,6 @@ int type_resolver_resolve(struct type_resolver* self,
|
|||
|
||||
switch (node->type)
|
||||
{
|
||||
case NODE_NEW: {
|
||||
type->kind = TYPE_RAW_PTR;
|
||||
type_add_subtype(type, TYPE_VOID);
|
||||
type_resolver_resolve(self, node->children.data[0],
|
||||
type->subtypes.data[0]);
|
||||
|
||||
} return 0;
|
||||
|
||||
case NODE_RETURN: {
|
||||
if (node->children.size == 0)
|
||||
{
|
||||
|
@ -50,22 +40,9 @@ int type_resolver_resolve(struct type_resolver* self,
|
|||
};
|
||||
|
||||
case NODE_CALL: {
|
||||
struct node* target = node->children.data[0];
|
||||
struct node* args = node->children.data[1];
|
||||
struct sym* entry = sym_table_fetch_fun(self->sym_table,
|
||||
target->value,
|
||||
args);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
type_copy(entry->type->subtypes.data[0], type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct type call_type;
|
||||
type_init(&call_type, TYPE_VOID);
|
||||
|
||||
|
||||
if (type_resolver_resolve(self, node->children.data[0], &call_type) == 0
|
||||
&& call_type.subtypes.size > 0)
|
||||
{
|
||||
|
@ -108,8 +85,8 @@ int type_resolver_resolve(struct type_resolver* self,
|
|||
|
||||
type_copy(ty, type);
|
||||
|
||||
type_free(ty);
|
||||
free(ty);
|
||||
//sym_table_declare(self->sym_table, node->value, ty,
|
||||
// node->type == NODE_VARDECL);
|
||||
|
||||
} return 0;
|
||||
|
||||
|
@ -176,7 +153,7 @@ int type_resolver_resolve(struct type_resolver* self,
|
|||
type_init(&rhs, TYPE_VOID);
|
||||
type_resolver_resolve(self, node->children.data[1], &rhs);
|
||||
|
||||
int equals = type_equiv(&lhs, &rhs);
|
||||
int equals = type_equals(&lhs, &rhs);
|
||||
|
||||
if (type_is(&lhs, "INT") && equals)
|
||||
{
|
||||
|
@ -200,16 +177,6 @@ int type_resolver_resolve(struct type_resolver* self,
|
|||
{
|
||||
type->kind = TYPE_STRING;
|
||||
}
|
||||
else if (lhs.kind == TYPE_RAW_PTR)
|
||||
{
|
||||
struct type* sub = lhs.subtypes.data[0];
|
||||
type->kind = sub->kind;
|
||||
}
|
||||
else if (rhs.kind == TYPE_RAW_PTR)
|
||||
{
|
||||
struct type* sub = rhs.subtypes.data[0];
|
||||
type->kind = sub->kind;
|
||||
}
|
||||
else
|
||||
{
|
||||
type_free(&lhs);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "value.h"
|
||||
#include "commons.h"
|
||||
#include "native.h"
|
||||
#include "type.h"
|
||||
#include "fun.h"
|
||||
|
@ -67,18 +66,6 @@ void value_init_new_native(struct value* self, native_fun_t native,
|
|||
self->is_native = 1;
|
||||
}
|
||||
|
||||
void value_init_new_rawptr(struct value* self, int addr,
|
||||
struct type* type, int line)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
type_init(&self->type, TYPE_VOID);
|
||||
type_copy(type, &self->type);
|
||||
self->data.addr = addr;
|
||||
self->line = line;
|
||||
self->is_native = 0;
|
||||
}
|
||||
|
||||
void value_free(struct value* self)
|
||||
{
|
||||
assert(self);
|
||||
|
@ -127,13 +114,6 @@ size_t value_str(struct value* self, char* buffer, size_t size)
|
|||
|
||||
size_t sz = 0;
|
||||
|
||||
if (self->type.kind == TYPE_RAW_PTR)
|
||||
{
|
||||
sz += snprintf(buffer + sz, size - sz, "<raw ptr: %d>",
|
||||
self->data.addr);
|
||||
return sz;
|
||||
}
|
||||
|
||||
if (self->type.kind == TYPE_FUN)
|
||||
{
|
||||
sz += snprintf(buffer + sz, size - sz, "<function>");
|
||||
|
|
|
@ -13,7 +13,6 @@ union value_data {
|
|||
char* s;
|
||||
float f;
|
||||
int i;
|
||||
int addr;
|
||||
struct fun* fun;
|
||||
native_fun_t native;
|
||||
};
|
||||
|
@ -32,8 +31,6 @@ void value_init_string(struct value* self, char* value, int line);
|
|||
void value_init_new_fun(struct value* self, struct fun* value, int line);
|
||||
void value_init_new_native(struct value* self, native_fun_t native,
|
||||
struct type* type, int line);
|
||||
void value_init_new_rawptr(struct value* self, int addr,
|
||||
struct type* type, int line);
|
||||
|
||||
void value_free(struct value* self);
|
||||
|
||||
|
|
|
@ -127,10 +127,8 @@ Test(lexer, ident) {
|
|||
}
|
||||
|
||||
Test(lexer, var_types) {
|
||||
test_lexer("int float bool string ^", 5,
|
||||
"TYPE[int]", "TYPE[float]",
|
||||
"TYPE[bool]", "TYPE[string]",
|
||||
"PTR");
|
||||
test_lexer("int float bool string", 4,
|
||||
"TYPE[int]", "TYPE[float]", "TYPE[bool]", "TYPE[string]");
|
||||
}
|
||||
|
||||
Test(lexer, blocks) {
|
||||
|
@ -145,7 +143,3 @@ Test(lexer, flow_control) {
|
|||
Test(lexer, fun) {
|
||||
test_lexer("-> fun return,", 4, "RARROW", "FUN", "RETURN", "COMMA");
|
||||
}
|
||||
|
||||
Test(lexer, mem) {
|
||||
test_lexer("new free", 2, "NEW", "FREE");
|
||||
}
|
||||
|
|
|
@ -174,9 +174,6 @@ Test(parser, types) {
|
|||
test_parser("ROOT(CONSTDECL[x]("
|
||||
"TYPE[fun](TYPE[int],TYPE[int],RARROW,TYPE[float]),INT[0]))",
|
||||
"x : (int int -> float) = 0;");
|
||||
|
||||
test_parser("ROOT(CONSTDECL[x](TYPE[rawptr](TYPE[float]),INT[0]))",
|
||||
"x : ^float = 0;");
|
||||
}
|
||||
|
||||
Test(parser, fun_call) {
|
||||
|
@ -197,15 +194,6 @@ Test(parser, fun_decl) {
|
|||
test_parser("ROOT(CONSTDECL[hello](FUN(PARAMS(IDENT[n],TYPE[int]),"
|
||||
"TYPE[int],BLOCK(RETURN(IDENT[n])))))",
|
||||
"fun hello (n: int) -> int { return n; }");
|
||||
|
||||
test_parser("ROOT(CONSTDECL[hello](FUN(PARAMS(VAR,IDENT[n],TYPE[int]),"
|
||||
"TYPE[int],BLOCK(RETURN(IDENT[n])))))",
|
||||
"fun hello (var n: int) -> int { return n; }");
|
||||
|
||||
test_parser("ROOT(CONSTDECL[hello](FUN(PARAMS(IDENT[m],TYPE[float],"
|
||||
"VAR,IDENT[n],TYPE[int]),"
|
||||
"TYPE[int],BLOCK(RETURN(IDENT[n])))))",
|
||||
"fun hello (m: float, var n: int) -> int { return n; }");
|
||||
}
|
||||
|
||||
Test(parser, param_sugar) {
|
||||
|
@ -214,11 +202,3 @@ Test(parser, param_sugar) {
|
|||
"TYPE[int],BLOCK(RETURN(IDENT[n])))))",
|
||||
"fun hello (n, m, k: int) -> int { return n; }");
|
||||
}
|
||||
|
||||
Test(parser, mem) {
|
||||
test_parser("ROOT(CONSTDECL[x](NEW(INT[32])))",
|
||||
"x := new 32;");
|
||||
|
||||
test_parser("ROOT(FREE(IDENT[hello]))",
|
||||
"free hello;");
|
||||
}
|
||||
|
|
|
@ -44,20 +44,6 @@ void* vec_pop(struct vec* self)
|
|||
return element;
|
||||
}
|
||||
|
||||
void* vec_remove(struct vec* self, size_t index)
|
||||
{
|
||||
assert(index < self->size);
|
||||
void* to_remove = self->data[index];
|
||||
void* tmp = self->data[self->size - 1];
|
||||
|
||||
self->data[self->size - 1] = to_remove;
|
||||
to_remove = tmp;
|
||||
|
||||
vec_pop(self);
|
||||
|
||||
return to_remove;
|
||||
}
|
||||
|
||||
void vec_free_elements(struct vec* self)
|
||||
{
|
||||
assert(self);
|
||||
|
|
|
@ -14,7 +14,6 @@ void vec_free(struct vec* self);
|
|||
|
||||
void vec_push(struct vec* self, void* element);
|
||||
void* vec_pop(struct vec* self);
|
||||
void* vec_remove(struct vec* self, size_t index);
|
||||
|
||||
void vec_free_elements(struct vec* self);
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
fun incr(var n: ^int) {
|
||||
n = n + 1;
|
||||
n = n * 2;
|
||||
}
|
||||
|
||||
var a : ^int = new 43;
|
||||
|
||||
assert a == 43;
|
||||
|
||||
incr(a);
|
||||
a = a + 1;
|
||||
|
||||
assert a == 89;
|
||||
|
||||
free a;
|
284
vm/src/vm.c
284
vm/src/vm.c
|
@ -17,7 +17,6 @@ void vm_init(struct vm* self, struct vec* natives)
|
|||
memset(self->error_msg, 0, GUX_STR_SIZE);
|
||||
|
||||
vm_add_frame(self);
|
||||
vec_init(&self->heap, 1);
|
||||
}
|
||||
|
||||
void vm_free(struct vm* self)
|
||||
|
@ -32,16 +31,6 @@ void vm_free(struct vm* self)
|
|||
}
|
||||
|
||||
self->fp = 0;
|
||||
|
||||
for (size_t i=0; i<self->heap.size; i++)
|
||||
{
|
||||
struct heap_item* item = self->heap.data[i];
|
||||
value_free(item->value);
|
||||
free(item->value);
|
||||
}
|
||||
|
||||
vec_free_elements(&self->heap);
|
||||
vec_free(&self->heap);
|
||||
}
|
||||
|
||||
void vm_add_frame(struct vm* self)
|
||||
|
@ -142,99 +131,6 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
|
||||
switch (opcode)
|
||||
{
|
||||
case OP_FREE: {
|
||||
int ref_val = vm_load(self, param);
|
||||
int stack_addr = frame->stack[ref_val];
|
||||
|
||||
struct value* ref = program->constant_pool.data[stack_addr];
|
||||
int addr = ref->data.addr;
|
||||
|
||||
ssize_t value_idx = vm_heap_try_find(self, addr);
|
||||
|
||||
if (value_idx == -1)
|
||||
{
|
||||
snprintf(self->error_msg, GUX_STR_SIZE, "wrong address");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int stack_val = vm_pop(self);
|
||||
struct value* stack = program->constant_pool.data[stack_val];
|
||||
assert(stack);
|
||||
|
||||
struct heap_item* item = vec_remove(&self->heap, value_idx);
|
||||
|
||||
value_free(item->value);
|
||||
free(item->value);
|
||||
free(item);
|
||||
|
||||
self->pc++;
|
||||
} break;
|
||||
|
||||
case OP_REFSTORE: {
|
||||
int ref_val = vm_load(self, param);
|
||||
int stack_addr = frame->stack[ref_val];
|
||||
|
||||
struct value* ref = program->constant_pool.data[stack_addr];
|
||||
|
||||
int addr = ref->data.addr;
|
||||
|
||||
ssize_t value_idx = vm_heap_try_find(self, addr);
|
||||
|
||||
if (value_idx == -1)
|
||||
{
|
||||
snprintf(self->error_msg, GUX_STR_SIZE, "wrong address");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int stack_val = vm_pop(self);
|
||||
struct value* stack = program->constant_pool.data[stack_val];
|
||||
assert(stack);
|
||||
|
||||
struct heap_item* item = self->heap.data[value_idx];
|
||||
|
||||
value_free(item->value);
|
||||
free(item->value);
|
||||
item->value = value_new_clone(stack);
|
||||
|
||||
self->pc++;
|
||||
} break;
|
||||
|
||||
case OP_DEREF: {
|
||||
int val = vm_pop(self);
|
||||
struct value* ref = program->constant_pool.data[val];
|
||||
|
||||
struct value* value = value_new_clone
|
||||
(vm_heap_try_load(self, ref->data.addr));
|
||||
assert(value);
|
||||
|
||||
vm_push(self,
|
||||
program_push_constant(program, value));
|
||||
|
||||
self->pc++;
|
||||
} break;
|
||||
|
||||
case OP_NEW: {
|
||||
int val = vm_pop(self);
|
||||
struct value* value =
|
||||
value_new_clone(program->constant_pool.data[val]);
|
||||
|
||||
vm_heap_store_new(self, param, value);
|
||||
|
||||
struct type type;
|
||||
type_init(&type, TYPE_RAW_PTR);
|
||||
type_add_subtype(&type, TYPE_VOID);
|
||||
type_copy(&value->type, type.subtypes.data[0]);
|
||||
|
||||
struct value* ref = malloc(sizeof(struct value));
|
||||
value_init_new_rawptr(ref, param, &type, value->line);
|
||||
type_free(&type);
|
||||
|
||||
vm_push(self,
|
||||
program_push_constant(program, ref));
|
||||
|
||||
self->pc++;
|
||||
} break;
|
||||
|
||||
case OP_CALL: {
|
||||
int fun_addr = vm_pop(self);
|
||||
struct value* fun_val = program->constant_pool.data[fun_addr];
|
||||
|
@ -306,12 +202,7 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
size_t ret_addr = self->pc;
|
||||
self->pc = 0;
|
||||
|
||||
if (vm_exec(self, &fun->program) != 0)
|
||||
{
|
||||
vec_free_elements(&args);
|
||||
vec_free(&args);
|
||||
return 1;
|
||||
}
|
||||
vm_exec(self, &fun->program);
|
||||
|
||||
vec_free_elements(&args);
|
||||
vec_free(&args);
|
||||
|
@ -436,11 +327,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val =
|
||||
vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
|
||||
struct value* rhs_val =
|
||||
vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = malloc(sizeof(struct value));
|
||||
|
||||
|
@ -483,11 +371,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val =
|
||||
vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
|
||||
struct value* rhs_val =
|
||||
vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_add(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -499,10 +384,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val =
|
||||
vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val =
|
||||
vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_sub(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -514,10 +397,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_mul(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -529,10 +410,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_div(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -544,10 +423,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_mod(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -559,10 +436,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_pow(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -574,10 +449,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_lt(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -589,10 +462,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_le(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -604,10 +475,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_gt(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -619,10 +488,8 @@ int vm_exec(struct vm* self, struct program* program)
|
|||
int rhs = vm_pop(self);
|
||||
int lhs = vm_pop(self);
|
||||
|
||||
struct value* lhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[lhs]);
|
||||
struct value* rhs_val
|
||||
= vm_try_get_val(self, program->constant_pool.data[rhs]);
|
||||
struct value* lhs_val = program->constant_pool.data[lhs];
|
||||
struct value* rhs_val = program->constant_pool.data[rhs];
|
||||
|
||||
struct value* res = value_try_new_ge(lhs_val, rhs_val);
|
||||
vm_push(self, program_push_constant(program, res));
|
||||
|
@ -645,8 +512,6 @@ size_t vm_str(struct vm* self, struct program* program,
|
|||
|
||||
size_t sz = 0;
|
||||
|
||||
sz += snprintf(buffer + sz, size - sz, "--- STACKS ---\n");
|
||||
|
||||
for (size_t i=0; i<self->fp; i++)
|
||||
{
|
||||
struct frame* frame = self->stack[i];
|
||||
|
@ -664,108 +529,5 @@ size_t vm_str(struct vm* self, struct program* program,
|
|||
}
|
||||
}
|
||||
|
||||
sz += snprintf(buffer + sz, size - sz, "--- HEAP ---\n");
|
||||
|
||||
for (size_t i=0; i<self->heap.size; i++)
|
||||
{
|
||||
struct heap_item* item = self->heap.data[i];
|
||||
char val_str[GUX_STR_SIZE];
|
||||
value_str(item->value, val_str, GUX_STR_SIZE);
|
||||
|
||||
sz += snprintf(buffer + sz, size - sz, "%i %s\n",
|
||||
item->addr,
|
||||
val_str);
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
void vm_heap_store_new(struct vm* self, int addr, struct value* value)
|
||||
{
|
||||
assert(self);
|
||||
struct heap_item* item = malloc(sizeof(struct heap_item));
|
||||
item->addr = addr;
|
||||
item->value = value;
|
||||
vec_push(&self->heap, item);
|
||||
}
|
||||
|
||||
struct value* vm_heap_try_load(struct vm* self, int addr)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
for (size_t i=0; i<self->heap.size; i++)
|
||||
{
|
||||
struct heap_item* item = self->heap.data[i];
|
||||
|
||||
if (item->addr == addr)
|
||||
{
|
||||
return item->value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t vm_heap_try_find(struct vm* self, int addr)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
for (size_t i=0; i<self->heap.size; i++)
|
||||
{
|
||||
struct heap_item* item = self->heap.data[i];
|
||||
|
||||
if (item->addr == addr)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int vm_heap_free(struct vm* self, int addr)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
size_t idx = 0;
|
||||
int found = 0;
|
||||
|
||||
for (size_t i=0; i<self->heap.size; i++)
|
||||
{
|
||||
struct heap_item* item = self->heap.data[i];
|
||||
|
||||
if (item->addr == addr)
|
||||
{
|
||||
found = 1;
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) { return 1; }
|
||||
|
||||
struct heap_item* tmp = self->heap.data[self->heap.size - 1];
|
||||
self->heap.data[self->heap.size - 1] = self->heap.data[idx];
|
||||
self->heap.data[idx] = tmp;
|
||||
|
||||
vec_pop(&self->heap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct value* vm_try_get_val(struct vm* self, struct value* value)
|
||||
{
|
||||
assert(self);
|
||||
assert(value);
|
||||
|
||||
if (value->type.kind == TYPE_RAW_PTR)
|
||||
{
|
||||
struct value* v = vm_heap_try_load(self, value->data.addr);
|
||||
assert(v);
|
||||
return v;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
12
vm/src/vm.h
12
vm/src/vm.h
|
@ -12,11 +12,6 @@ struct local {
|
|||
int stack_addr;
|
||||
};
|
||||
|
||||
struct heap_item {
|
||||
int addr;
|
||||
struct value* value;
|
||||
};
|
||||
|
||||
struct frame {
|
||||
int stack[STACK_DEPTH];
|
||||
size_t sp;
|
||||
|
@ -31,7 +26,6 @@ struct vm {
|
|||
size_t fp;
|
||||
struct frame* stack[FRAME_DEPTH];
|
||||
struct vec* natives;
|
||||
struct vec heap;
|
||||
};
|
||||
|
||||
void vm_init(struct vm* self, struct vec* natives);
|
||||
|
@ -50,10 +44,4 @@ int vm_exec(struct vm* self, struct program* program);
|
|||
size_t vm_str(struct vm* self, struct program* program,
|
||||
char* buffer, size_t size);
|
||||
|
||||
void vm_heap_store_new(struct vm* self, int addr, struct value* value);
|
||||
struct value* vm_heap_try_load(struct vm* self, int addr);
|
||||
ssize_t vm_heap_try_find(struct vm* self, int addr);
|
||||
int vm_heap_free(struct vm* self, int addr);
|
||||
struct value* vm_try_get_val(struct vm* self, struct value* value);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue