Compare commits

..

No commits in common. "d1286c008bf6a147d20b2d0af7a280244eee35ae" and "85875d2d946b8c139d5a7b78242cf91cbe0c997f" have entirely different histories.

24 changed files with 85 additions and 641 deletions

View File

@ -17,14 +17,13 @@ LEXPR ::=
| continue | continue
| return EXPR? | return EXPR?
| FUN | FUN
| new EXPR
| free EXPR
BEXPR ::= BEXPR ::=
| BLOCK | BLOCK
| IF | IF
| WHILE | WHILE
IF ::= IF ::=
| if EXPR BLOCK | if EXPR BLOCK
| if EXPR BLOCK else BLOCK | if EXPR BLOCK else BLOCK
@ -35,7 +34,7 @@ WHILE ::= while EXPR BLOCK
FUN ::= fun PARAMS (rarrow TYPE) BLOCK FUN ::= fun PARAMS (rarrow TYPE) BLOCK
PARAMS ::= 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 BLOCK ::= obrace INSTR* cbrace
VARDECL ::= var ident colon TYPE? assign EXPR VARDECL ::= var ident colon TYPE? assign EXPR
@ -68,4 +67,3 @@ BUILTIN ::= bool | int | float | string
TYPE ::= TYPE ::=
| type | type
| opar TYPE+ rarrow TYPE+ cpar | opar TYPE+ rarrow TYPE+ cpar
| rawptr TYPE

View File

@ -173,7 +173,7 @@ int main(int argc, char** argv)
if (type_checker_check(&checker, ast) != 0) if (type_checker_check(&checker, ast) != 0)
{ {
fprintf(stderr, "[%s:%d] type check error, %s\n", fprintf(stderr, "[%s:%d] %s\n",
path, path,
checker.error_line, checker.error_line,
checker.error_msg); checker.error_msg);
@ -215,7 +215,7 @@ int main(int argc, char** argv)
if (compiler_compile(&compiler, ast, &program) != 0) if (compiler_compile(&compiler, ast, &program) != 0)
{ {
fprintf(stderr, "[%s:%d] compile error, %s\n", fprintf(stderr, "[%s:%d] %s\n",
path, path,
compiler.error_line, compiler.error_line,
compiler.error_msg); compiler.error_msg);

View File

@ -18,7 +18,6 @@ void compiler_init(struct compiler* self, struct sym_table* global)
memset(self->error_msg, 0, GUX_STR_SIZE); memset(self->error_msg, 0, GUX_STR_SIZE);
self->stack_size = 0; self->stack_size = 0;
vec_init(&self->loops, 1); vec_init(&self->loops, 1);
self->heap_addr_counter = 1000;
} }
void compiler_free(struct compiler* self) void compiler_free(struct compiler* self)
@ -39,21 +38,6 @@ int compiler_compile(struct compiler* self,
switch (node->type) 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: { case NODE_RETURN: {
if (node->children.size > 0) if (node->children.size > 0)
{ {
@ -81,11 +65,7 @@ int compiler_compile(struct compiler* self,
{ {
struct node* param = params->children.data[i]; struct node* param = params->children.data[i];
if (param->type == NODE_VAR) if (param->type != NODE_TYPE)
{
continue;
}
else if (param->type != NODE_TYPE)
{ {
vec_push(&idents, param); vec_push(&idents, param);
} }
@ -96,7 +76,8 @@ int compiler_compile(struct compiler* self,
struct node* ident = idents.data[j]; struct node* ident = idents.data[j];
struct type* ty = malloc(sizeof(struct type)); 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, sym_table_declare_const(&compiler.sym_table,
ident->value, ident->value,
@ -274,32 +255,13 @@ int compiler_compile(struct compiler* self,
struct node* ident = node->children.data[0]; struct node* ident = node->children.data[0];
struct node* expr = node->children.data[1]; 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; struct type type;
type_init(&type, TYPE_VOID); type_init(&type, TYPE_VOID);
compiler_get_type(self, expr, &type); compiler_get_type(self, expr, &type);
struct sym* entry; struct sym* entry = sym_table_fetch(&self->sym_table,
ident->value,
if (is_ptr) &type);
{
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);
type_free(&type); type_free(&type);
assert(entry); assert(entry);
@ -309,8 +271,7 @@ int compiler_compile(struct compiler* self,
return 1; return 1;
} }
compiler_gen_instr(self, program, is_ptr ? OP_REFSTORE : OP_STORE, compiler_gen_instr(self, program, OP_STORE, entry->addr);
entry->addr);
} break; } break;
case NODE_IDENT: { case NODE_IDENT: {
@ -338,11 +299,11 @@ int compiler_compile(struct compiler* self,
case NODE_CONSTDECL: case NODE_CONSTDECL:
case NODE_VARDECL: { 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) if (err != 0)
{ {
@ -351,7 +312,7 @@ int compiler_compile(struct compiler* self,
struct type* ty = malloc(sizeof(struct type)); struct type* ty = malloc(sizeof(struct type));
type_init(ty, TYPE_VOID); 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, sym_table_declare(&self->sym_table, node->value, ty,
node->type == NODE_VARDECL); node->type == NODE_VARDECL);
@ -359,10 +320,10 @@ int compiler_compile(struct compiler* self,
struct sym* entry = sym_table_fetch(&self->sym_table, struct sym* entry = sym_table_fetch(&self->sym_table,
node->value, node->value,
ty); ty);
assert(entry); assert(entry);
compiler_gen_instr(self, program, OP_STORE, entry->addr); compiler_gen_instr(self, program, OP_STORE, entry->addr);
} break; } break;
case NODE_BOOL: { case NODE_BOOL: {
struct value* val = malloc(sizeof(struct value)); struct value* val = malloc(sizeof(struct value));
@ -676,7 +637,6 @@ size_t compiler_gen_instr(struct compiler* self,
case OP_GLOAD: case OP_GLOAD:
case OP_PUSH: self->stack_size += 1; break; case OP_PUSH: self->stack_size += 1; break;
case OP_FREE:
case OP_LT: case OP_LT:
case OP_LE: case OP_LE:
case OP_GT: case OP_GT:
@ -694,17 +654,12 @@ size_t compiler_gen_instr(struct compiler* self,
case OP_BRT: case OP_BRT:
self->stack_size -= 1; break; self->stack_size -= 1; break;
case OP_DEREF:
case OP_NEW:
case OP_RET: case OP_RET:
case OP_SWAP: case OP_SWAP:
case OP_BR: case OP_BR:
case OP_NOT: case OP_NOT:
case OP_NOP: case OP_NOP:
case OP_STORE: case OP_STORE: break;
case OP_REFSTORE:break;
default: assert(0);
} }
return addr; return addr;

View File

@ -17,7 +17,6 @@ struct compiler {
int error_line; int error_line;
int stack_size; int stack_size;
struct vec loops; struct vec loops;
int heap_addr_counter;
}; };
void compiler_init(struct compiler* self, struct sym_table* global); void compiler_init(struct compiler* self, struct sym_table* global);

View File

@ -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, "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, "int", NODE_TYPE, "int", 1);
lexer_add_tok(self, "float", NODE_TYPE, "float", 1); lexer_add_tok(self, "float", NODE_TYPE, "float", 1);
lexer_add_tok(self, "bool", NODE_TYPE, "bool", 1); lexer_add_tok(self, "bool", NODE_TYPE, "bool", 1);
lexer_add_tok(self, "string", NODE_TYPE, "string", 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_COMMA, "", 0);
lexer_add_tok(self, "{", NODE_OBRACE, "", 0); lexer_add_tok(self, "{", NODE_OBRACE, "", 0);
lexer_add_tok(self, "}", NODE_CBRACE, "", 0); lexer_add_tok(self, "}", NODE_CBRACE, "", 0);

View File

@ -18,7 +18,7 @@
G(NODE_IF), G(NODE_ELSE), G(NODE_COND), G(NODE_WHILE), G(NODE_FOR), \ 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_CONTINUE), G(NODE_BREAK), G(NODE_RARROW), G(NODE_FUN), \
G(NODE_RETURN), G(NODE_PARAMS), G(NODE_COMMA), G(NODE_CALL), \ 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); GUX_ENUM_H(NodeType, NODE_TYPE);

View File

@ -6,8 +6,7 @@
G(OP_BRT), G(OP_NOP), G(OP_NOT), G(OP_EQ), \ 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_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), G(OP_CALL), G(OP_RET), G(OP_GLOAD), G(OP_NEW), \ G(OP_SWAP), G(OP_CALL), G(OP_RET), G(OP_GLOAD)
G(OP_FREE), G(OP_DEREF), G(OP_REFSTORE)
#include <commons.h> #include <commons.h>

View File

@ -149,8 +149,7 @@ int parser_start_type(struct parser* self)
struct node* tok = self->tokens.data[self->cursor]; struct node* tok = self->tokens.data[self->cursor];
return tok->type == NODE_OPAR return tok->type == NODE_OPAR
|| tok->type == NODE_TYPE || tok->type == NODE_TYPE;
|| tok->type == NODE_PTR;
} }
struct node* parser_try_new_root(struct parser* self, char const* source) 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); 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)) if (parser_type_is(self, NODE_FUN, 0))
{ {
return parser_try_new_fun(self); 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) if (parser_try_consume(self, NODE_RETURN) == 0)
{ {
struct node* node = malloc(sizeof(struct node)); struct node* node = malloc(sizeof(struct node));
@ -444,8 +425,7 @@ struct node* parser_try_new_params(struct parser* self)
while (1) while (1)
{ {
if (!parser_type_is(self, NODE_IDENT, 0) if (!parser_type_is(self, NODE_IDENT, 0))
&& !parser_type_is(self, NODE_VAR, 0))
{ {
vec_free_elements(&types); vec_free_elements(&types);
vec_free(&types); vec_free(&types);
@ -454,14 +434,6 @@ struct node* parser_try_new_params(struct parser* self)
return NULL; 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 // ident
struct node* current = self->tokens.data[self->cursor]; struct node* current = self->tokens.data[self->cursor];
struct node* ident = malloc(sizeof(struct node)); struct node* ident = malloc(sizeof(struct node));
@ -592,9 +564,14 @@ struct node* parser_try_new_vardecl(struct parser* self)
return NULL; return NULL;
} }
if (parser_type_is(self, NODE_TYPE, 0) if (parser_type_is(self, NODE_TYPE, 0))
|| parser_type_is(self, NODE_PTR, 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)); node_add_child(node, parser_try_new_type(self));
} }
@ -976,14 +953,6 @@ struct node* parser_try_new_type(struct parser* self)
{ {
assert(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)) if (parser_type_is(self, NODE_OPAR, 0))
{ {
self->cursor++; // opar self->cursor++; // opar

View File

@ -14,13 +14,10 @@ void program_free(struct program* self)
for (size_t i=0; i<self->constant_pool.size; i++) 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]);
{
value_free(self->constant_pool.data[i]);
free(self->constant_pool.data[i]);
}
} }
vec_free_elements(&self->constant_pool);
vec_free(&self->constant_pool); vec_free(&self->constant_pool);
vec_free_elements(&self->instructions); vec_free_elements(&self->instructions);

View File

@ -12,12 +12,6 @@ void sym_table_init(struct sym_table* self, struct sym_table* prev)
self->addr_counter = 0; self->addr_counter = 0;
self->prev = prev; 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) void sym_table_free(struct sym_table* self)
@ -102,7 +96,7 @@ struct sym* sym_table_fetch(struct sym_table* self,
if (self->prev) if (self->prev)
{ {
return sym_table_fetch(self->prev, name, type); return sym_table_fetch(self->prev, name, NULL);
} }
return NULL; return NULL;
@ -115,15 +109,8 @@ struct sym* sym_table_fetch_fun(struct sym_table* self,
struct vec args_ty; struct vec args_ty;
vec_init(&args_ty, 1); vec_init(&args_ty, 1);
struct sym_table* itr = self;
while (itr->next)
{
itr = itr->next;
}
struct type_resolver resolver; struct type_resolver resolver;
type_resolver_init(&resolver, itr); type_resolver_init(&resolver, self);
for (size_t i=0; i < args->children.size; i++) 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_init(arg_type, TYPE_VOID);
type_resolver_resolve(&resolver, child, arg_type); type_resolver_resolve(&resolver, child, arg_type);
vec_push(&args_ty, 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) if (self->prev)
{ {
return sym_table_fetch_fun(self->prev, name, args); return sym_table_fetch(self->prev, name, NULL);
} }
return NULL; return NULL;
@ -219,7 +205,7 @@ int sym_table_declare(struct sym_table* self,
assert(self); assert(self);
assert(strcmp(name, "") != 0); 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 if (s && s->parent == self->root
&& type_equals(s->type, new_type)) && type_equals(s->type, new_type))
@ -233,7 +219,7 @@ int sym_table_declare(struct sym_table* self,
sym->type = new_type; sym->type = new_type;
sym->parent = self->root; sym->parent = self->root;
sym->is_global = 0; sym->is_global = 0;
sym->type->is_var = is_var; sym->is_var = is_var;
sym->addr = self->addr_counter; sym->addr = self->addr_counter;
vec_push(&table->syms, sym); vec_push(&table->syms, sym);
@ -250,7 +236,7 @@ int sym_table_declare_global(struct sym_table* self,
assert(self); assert(self);
assert(strcmp(name, "") != 0); 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 if (s && s->parent == self->root && s->is_global
&& type_equals(s->type, new_type)) && type_equals(s->type, new_type))
@ -264,7 +250,7 @@ int sym_table_declare_global(struct sym_table* self,
sym->type = new_type; sym->type = new_type;
sym->parent = self->root; sym->parent = self->root;
sym->is_global = 1; sym->is_global = 1;
sym->type->is_var = 0; sym->is_var = 0;
sym->addr = addr; sym->addr = addr;
vec_push(&table->syms, sym); vec_push(&table->syms, sym);

View File

@ -8,7 +8,7 @@
struct sym { struct sym {
struct table* parent; struct table* parent;
char* name; char* name;
//int is_var; int is_var;
int is_global; int is_global;
int addr; int addr;
struct type* type; struct type* type;
@ -20,7 +20,6 @@ struct table {
}; };
struct sym_table { struct sym_table {
struct sym_table* next;
struct sym_table* prev; struct sym_table* prev;
struct table* root; struct table* root;
int addr_counter; int addr_counter;

View File

@ -8,7 +8,6 @@ void type_init(struct type* self, enum TypeKind kind)
{ {
assert(self); assert(self);
self->kind = kind; self->kind = kind;
self->is_var = 0;
vec_init(&self->subtypes, 1); vec_init(&self->subtypes, 1);
} }
@ -16,17 +15,9 @@ void type_init_from_node(struct type* self, struct node* node)
{ {
assert(self); assert(self);
self->is_var = 0;
vec_init(&self->subtypes, 1); vec_init(&self->subtypes, 1);
if (node->type == NODE_TYPE && strcmp(node->value, "rawptr") == 0) if (node->type == NODE_TYPE && strcmp(node->value, "fun") == 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)
{ {
self->kind = TYPE_FUN; self->kind = TYPE_FUN;
int input = 1; 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); type_init_from_node(ret_ty, ret);
vec_push(&self->subtypes, ret_ty); vec_push(&self->subtypes, ret_ty);
int is_var = 0;
for (size_t i=0; i<params->children.size; i++) for (size_t i=0; i<params->children.size; i++)
{ {
struct node* child = params->children.data[i]; struct node* child = params->children.data[i];
if (child->type == NODE_VAR)
{
is_var = 1;
}
if (child->type == NODE_TYPE) if (child->type == NODE_TYPE)
{ {
struct type* param_ty = malloc(sizeof(struct type)); struct type* param_ty = malloc(sizeof(struct type));
type_init_from_node(param_ty, child); type_init_from_node(param_ty, child);
param_ty->is_var = is_var;
is_var = 0;
vec_push(&self->subtypes, param_ty); vec_push(&self->subtypes, param_ty);
} }
} }
@ -112,8 +94,6 @@ void type_copy(struct type* self, struct type* dest)
type_free(dest); type_free(dest);
type_init(dest, self->kind); type_init(dest, self->kind);
dest->is_var = self->is_var;
for (size_t i=0; i<self->subtypes.size; i++) for (size_t i=0; i<self->subtypes.size; i++)
{ {
type_add_subtype(dest, TYPE_VOID); type_add_subtype(dest, TYPE_VOID);
@ -169,25 +149,6 @@ int type_equals(struct type* self, struct type* rhs)
return 1; 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) void type_add_subtype(struct type* self, enum TypeKind kind)
{ {
assert(self); assert(self);
@ -203,11 +164,6 @@ size_t type_str(struct type* self, char* buffer, size_t size)
assert(buffer); assert(buffer);
size_t sz = 0; size_t sz = 0;
if (0 && self->is_var)
{
sz += snprintf(buffer + sz, size - sz, "VAR_");
}
sz += snprintf(buffer + sz, size - sz, "%s", sz += snprintf(buffer + sz, size - sz, "%s",
TypeKindStr[self->kind] + strlen("TYPE_")); TypeKindStr[self->kind] + strlen("TYPE_"));

View File

@ -7,15 +7,13 @@
#define TYPE_KIND(G) \ #define TYPE_KIND(G) \
G(TYPE_VOID), G(TYPE_BOOL), G(TYPE_INT), \ G(TYPE_VOID), G(TYPE_BOOL), G(TYPE_INT), \
G(TYPE_FLOAT), G(TYPE_STRING), G(TYPE_FUN), \ G(TYPE_FLOAT), G(TYPE_STRING), G(TYPE_FUN)
G(TYPE_RAW_PTR)
GUX_ENUM_H(TypeKind, TYPE_KIND); GUX_ENUM_H(TypeKind, TYPE_KIND);
struct type { struct type {
enum TypeKind kind; enum TypeKind kind;
struct vec subtypes; struct vec subtypes;
int is_var;
}; };
void type_init(struct type* self, enum TypeKind kind); 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); void type_clear(struct type* self);
int type_equals(struct type* self, struct type* rhs); 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); void type_add_subtype(struct type* self, enum TypeKind kind);
size_t type_str(struct type* self, char* buffer, size_t size); size_t type_str(struct type* self, char* buffer, size_t size);
int type_is(struct type* self, char const* repr); int type_is(struct type* self, char const* repr);

View File

@ -44,7 +44,7 @@ int type_checker_check(struct type_checker* self,
return 1; 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); 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 node* args = node->children.data[1];
struct sym* entry = sym_table_fetch_fun(&self->sym_table, struct sym* entry = sym_table_fetch_fun(&self->sym_table,
target->value, target->value,
args); args);
if (!entry) if (!entry)
{ {
@ -118,30 +118,13 @@ int type_checker_check(struct type_checker* self,
return 1; return 1;
} }
if (type_checker_check(self, sub_node) != 0) if (!type_equals(&t, sub))
{
self->error_line = sub_node->line;
type_free(&t);
return 1;
}
if (!type_equiv(&t, sub))
{ {
type_checker_error_msg(self, sub_node, sub, &t); type_checker_error_msg(self, sub_node, sub, &t);
type_free(&t); type_free(&t);
return 1; 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); type_free(&t);
} }
@ -157,9 +140,6 @@ int type_checker_check(struct type_checker* self,
struct vec names; struct vec names;
vec_init(&names, 1); vec_init(&names, 1);
struct vec vars;
vec_init(&vars, 1);
for (size_t i=0; i<params->children.size; i++) for (size_t i=0; i<params->children.size; i++)
{ {
struct node* param = params->children.data[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)); struct type* ty = malloc(sizeof(struct type));
type_init_from_node(ty, param); type_init_from_node(ty, param);
int* var = vars.data[j]; sym_table_declare_const(&self->sym_table,
ty->is_var = *var; n->value,
ty);
sym_table_declare(&self->sym_table,
n->value,
ty,
*var);
} }
vec_free(&names); vec_free(&names);
vec_init(&names, 1); 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); vec_push(&names, param);
} }
} }
@ -249,8 +211,6 @@ int type_checker_check(struct type_checker* self,
type_free(&ret_ty); type_free(&ret_ty);
vec_free(&ret_instrs); vec_free(&ret_instrs);
vec_free(&names); vec_free(&names);
vec_free_elements(&vars);
vec_free(&vars);
sym_table_pop_table(&self->sym_table); sym_table_pop_table(&self->sym_table);
} }
@ -266,7 +226,7 @@ int type_checker_check(struct type_checker* self,
struct type want; struct type want;
type_init(&want, TYPE_BOOL); type_init(&want, TYPE_BOOL);
if (!type_equiv(&have, &want)) if (!type_equals(&have, &want))
{ {
type_checker_error_msg(self, node, &want, &have); type_checker_error_msg(self, node, &want, &have);
type_free(&have); type_free(&have);
@ -332,7 +292,7 @@ int type_checker_check(struct type_checker* self,
return 1; return 1;
} }
if (!entry->type->is_var) if (!entry->is_var)
{ {
snprintf(self->error_msg, GUX_STR_SIZE, "<%s> is not mutable", snprintf(self->error_msg, GUX_STR_SIZE, "<%s> is not mutable",
ident->value); ident->value);
@ -348,7 +308,7 @@ int type_checker_check(struct type_checker* self,
type_resolver_resolve(&self->resolver, expr, &expr_type); 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_checker_error_msg(self, node, var_type, &expr_type);
type_free(&expr_type); type_free(&expr_type);
@ -362,8 +322,8 @@ int type_checker_check(struct type_checker* self,
case NODE_CONSTDECL:{ case NODE_CONSTDECL:{
struct type type; struct type type;
type_init(&type, TYPE_VOID); 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, struct sym* entry = sym_table_fetch(&self->sym_table,
node->value, node->value,
@ -401,11 +361,6 @@ int type_checker_check(struct type_checker* self,
if (type_resolver_resolve(&self->resolver, expr, ty) != 0) 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); type_free(ty);
free(ty); free(ty);
return 1; return 1;
@ -515,7 +470,7 @@ int type_checker_check(struct type_checker* self,
lhs_msg); lhs_msg);
} }
} }
else if (!type_equiv(&lhs_type, &rhs_type)) else if (!type_equals(&lhs_type, &rhs_type))
{ {
snprintf(self->error_msg, MSG_SZ, snprintf(self->error_msg, MSG_SZ,
"type mismatch (<%s>, <%s>)", "type mismatch (<%s>, <%s>)",
@ -525,7 +480,7 @@ int type_checker_check(struct type_checker* self,
if (solve_lhs != 0 if (solve_lhs != 0
|| solve_rhs != 0 || solve_rhs != 0
|| !type_equiv(&lhs_type, &rhs_type) || !type_equals(&lhs_type, &rhs_type)
|| lhs_type.subtypes.size > 0 || lhs_type.subtypes.size > 0
|| rhs_type.subtypes.size > 0 || rhs_type.subtypes.size > 0
|| (lhs_type.kind != TYPE_INT && lhs_type.kind != TYPE_FLOAT) || (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->children.data[i],
&node_type); &node_type);
if (!type_equiv(&type, &node_type)) if (!type_equals(&type, &node_type))
{ {
self->error_line = node->line; self->error_line = node->line;
snprintf(self->error_msg, snprintf(self->error_msg,

View File

@ -1,7 +1,5 @@
#include "type_resolver.h" #include "type_resolver.h"
#include "commons.h"
#include "node.h" #include "node.h"
#include "sym_table.h"
#include "type.h" #include "type.h"
void type_resolver_init(struct type_resolver* self, void type_resolver_init(struct type_resolver* self,
@ -28,14 +26,6 @@ int type_resolver_resolve(struct type_resolver* self,
switch (node->type) 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: { case NODE_RETURN: {
if (node->children.size == 0) if (node->children.size == 0)
{ {
@ -50,22 +40,9 @@ int type_resolver_resolve(struct type_resolver* self,
}; };
case NODE_CALL: { 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; struct type call_type;
type_init(&call_type, TYPE_VOID); type_init(&call_type, TYPE_VOID);
if (type_resolver_resolve(self, node->children.data[0], &call_type) == 0 if (type_resolver_resolve(self, node->children.data[0], &call_type) == 0
&& call_type.subtypes.size > 0) && call_type.subtypes.size > 0)
{ {
@ -108,8 +85,8 @@ int type_resolver_resolve(struct type_resolver* self,
type_copy(ty, type); type_copy(ty, type);
type_free(ty); //sym_table_declare(self->sym_table, node->value, ty,
free(ty); // node->type == NODE_VARDECL);
} return 0; } return 0;
@ -176,7 +153,7 @@ int type_resolver_resolve(struct type_resolver* self,
type_init(&rhs, TYPE_VOID); type_init(&rhs, TYPE_VOID);
type_resolver_resolve(self, node->children.data[1], &rhs); 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) if (type_is(&lhs, "INT") && equals)
{ {
@ -200,16 +177,6 @@ int type_resolver_resolve(struct type_resolver* self,
{ {
type->kind = TYPE_STRING; 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 else
{ {
type_free(&lhs); type_free(&lhs);

View File

@ -1,5 +1,4 @@
#include "value.h" #include "value.h"
#include "commons.h"
#include "native.h" #include "native.h"
#include "type.h" #include "type.h"
#include "fun.h" #include "fun.h"
@ -67,18 +66,6 @@ void value_init_new_native(struct value* self, native_fun_t native,
self->is_native = 1; 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) void value_free(struct value* self)
{ {
assert(self); assert(self);
@ -127,13 +114,6 @@ size_t value_str(struct value* self, char* buffer, size_t size)
size_t sz = 0; 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) if (self->type.kind == TYPE_FUN)
{ {
sz += snprintf(buffer + sz, size - sz, "<function>"); sz += snprintf(buffer + sz, size - sz, "<function>");

View File

@ -13,7 +13,6 @@ union value_data {
char* s; char* s;
float f; float f;
int i; int i;
int addr;
struct fun* fun; struct fun* fun;
native_fun_t native; 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_fun(struct value* self, struct fun* value, int line);
void value_init_new_native(struct value* self, native_fun_t native, void value_init_new_native(struct value* self, native_fun_t native,
struct type* type, int line); 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); void value_free(struct value* self);

View File

@ -127,10 +127,8 @@ Test(lexer, ident) {
} }
Test(lexer, var_types) { Test(lexer, var_types) {
test_lexer("int float bool string ^", 5, test_lexer("int float bool string", 4,
"TYPE[int]", "TYPE[float]", "TYPE[int]", "TYPE[float]", "TYPE[bool]", "TYPE[string]");
"TYPE[bool]", "TYPE[string]",
"PTR");
} }
Test(lexer, blocks) { Test(lexer, blocks) {
@ -145,7 +143,3 @@ Test(lexer, flow_control) {
Test(lexer, fun) { Test(lexer, fun) {
test_lexer("-> fun return,", 4, "RARROW", "FUN", "RETURN", "COMMA"); test_lexer("-> fun return,", 4, "RARROW", "FUN", "RETURN", "COMMA");
} }
Test(lexer, mem) {
test_lexer("new free", 2, "NEW", "FREE");
}

View File

@ -174,9 +174,6 @@ Test(parser, types) {
test_parser("ROOT(CONSTDECL[x](" test_parser("ROOT(CONSTDECL[x]("
"TYPE[fun](TYPE[int],TYPE[int],RARROW,TYPE[float]),INT[0]))", "TYPE[fun](TYPE[int],TYPE[int],RARROW,TYPE[float]),INT[0]))",
"x : (int int -> float) = 0;"); "x : (int int -> float) = 0;");
test_parser("ROOT(CONSTDECL[x](TYPE[rawptr](TYPE[float]),INT[0]))",
"x : ^float = 0;");
} }
Test(parser, fun_call) { Test(parser, fun_call) {
@ -197,15 +194,6 @@ Test(parser, fun_decl) {
test_parser("ROOT(CONSTDECL[hello](FUN(PARAMS(IDENT[n],TYPE[int])," test_parser("ROOT(CONSTDECL[hello](FUN(PARAMS(IDENT[n],TYPE[int]),"
"TYPE[int],BLOCK(RETURN(IDENT[n])))))", "TYPE[int],BLOCK(RETURN(IDENT[n])))))",
"fun hello (n: int) -> int { return 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) { Test(parser, param_sugar) {
@ -214,11 +202,3 @@ Test(parser, param_sugar) {
"TYPE[int],BLOCK(RETURN(IDENT[n])))))", "TYPE[int],BLOCK(RETURN(IDENT[n])))))",
"fun hello (n, m, k: int) -> int { return 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;");
}

View File

@ -44,20 +44,6 @@ void* vec_pop(struct vec* self)
return element; 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) void vec_free_elements(struct vec* self)
{ {
assert(self); assert(self);

View File

@ -14,7 +14,6 @@ void vec_free(struct vec* self);
void vec_push(struct vec* self, void* element); void vec_push(struct vec* self, void* element);
void* vec_pop(struct vec* self); void* vec_pop(struct vec* self);
void* vec_remove(struct vec* self, size_t index);
void vec_free_elements(struct vec* self); void vec_free_elements(struct vec* self);

View File

@ -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;

View File

@ -17,7 +17,6 @@ void vm_init(struct vm* self, struct vec* natives)
memset(self->error_msg, 0, GUX_STR_SIZE); memset(self->error_msg, 0, GUX_STR_SIZE);
vm_add_frame(self); vm_add_frame(self);
vec_init(&self->heap, 1);
} }
void vm_free(struct vm* self) void vm_free(struct vm* self)
@ -32,16 +31,6 @@ void vm_free(struct vm* self)
} }
self->fp = 0; 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) void vm_add_frame(struct vm* self)
@ -142,99 +131,6 @@ int vm_exec(struct vm* self, struct program* program)
switch (opcode) 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: { case OP_CALL: {
int fun_addr = vm_pop(self); int fun_addr = vm_pop(self);
struct value* fun_val = program->constant_pool.data[fun_addr]; 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; size_t ret_addr = self->pc;
self->pc = 0; self->pc = 0;
if (vm_exec(self, &fun->program) != 0) vm_exec(self, &fun->program);
{
vec_free_elements(&args);
vec_free(&args);
return 1;
}
vec_free_elements(&args); vec_free_elements(&args);
vec_free(&args); vec_free(&args);
@ -436,11 +327,8 @@ int vm_exec(struct vm* self, struct program* program)
int rhs = vm_pop(self); int rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val = struct value* lhs_val = program->constant_pool.data[lhs];
vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val =
vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = malloc(sizeof(struct value)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val = struct value* lhs_val = program->constant_pool.data[lhs];
vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val =
vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_add(lhs_val, rhs_val); struct value* res = value_try_new_add(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val = struct value* lhs_val = program->constant_pool.data[lhs];
vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val =
vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_sub(lhs_val, rhs_val); struct value* res = value_try_new_sub(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val struct value* lhs_val = program->constant_pool.data[lhs];
= vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val
= vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_mul(lhs_val, rhs_val); struct value* res = value_try_new_mul(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val struct value* lhs_val = program->constant_pool.data[lhs];
= vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val
= vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_div(lhs_val, rhs_val); struct value* res = value_try_new_div(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val struct value* lhs_val = program->constant_pool.data[lhs];
= vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val
= vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_mod(lhs_val, rhs_val); struct value* res = value_try_new_mod(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val struct value* lhs_val = program->constant_pool.data[lhs];
= vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val
= vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_pow(lhs_val, rhs_val); struct value* res = value_try_new_pow(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val struct value* lhs_val = program->constant_pool.data[lhs];
= vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val
= vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_lt(lhs_val, rhs_val); struct value* res = value_try_new_lt(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val struct value* lhs_val = program->constant_pool.data[lhs];
= vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val
= vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_le(lhs_val, rhs_val); struct value* res = value_try_new_le(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val struct value* lhs_val = program->constant_pool.data[lhs];
= vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val
= vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_gt(lhs_val, rhs_val); struct value* res = value_try_new_gt(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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 rhs = vm_pop(self);
int lhs = vm_pop(self); int lhs = vm_pop(self);
struct value* lhs_val struct value* lhs_val = program->constant_pool.data[lhs];
= vm_try_get_val(self, program->constant_pool.data[lhs]); struct value* rhs_val = program->constant_pool.data[rhs];
struct value* rhs_val
= vm_try_get_val(self, program->constant_pool.data[rhs]);
struct value* res = value_try_new_ge(lhs_val, rhs_val); struct value* res = value_try_new_ge(lhs_val, rhs_val);
vm_push(self, program_push_constant(program, res)); 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; size_t sz = 0;
sz += snprintf(buffer + sz, size - sz, "--- STACKS ---\n");
for (size_t i=0; i<self->fp; i++) for (size_t i=0; i<self->fp; i++)
{ {
struct frame* frame = self->stack[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; 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;
}
}

View File

@ -12,11 +12,6 @@ struct local {
int stack_addr; int stack_addr;
}; };
struct heap_item {
int addr;
struct value* value;
};
struct frame { struct frame {
int stack[STACK_DEPTH]; int stack[STACK_DEPTH];
size_t sp; size_t sp;
@ -31,7 +26,6 @@ struct vm {
size_t fp; size_t fp;
struct frame* stack[FRAME_DEPTH]; struct frame* stack[FRAME_DEPTH];
struct vec* natives; struct vec* natives;
struct vec heap;
}; };
void vm_init(struct vm* self, struct vec* natives); 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, size_t vm_str(struct vm* self, struct program* program,
char* buffer, size_t size); 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 #endif