Compare commits
No commits in common. "502a31d5c9a00f326018c07334dc3995aa3d1e1c" and "d8f1af99a6167faacd59c7da030bf84669b2eaca" have entirely different histories.
502a31d5c9
...
d8f1af99a6
|
@ -30,12 +30,6 @@ void array_free(array* self)
|
|||
free(self->type); self->type = NULL;
|
||||
}
|
||||
|
||||
struct value* array_deref(array* self, size_t index)
|
||||
{
|
||||
assert(index < self->children.size);
|
||||
return (struct value*) self->children.data[index];
|
||||
}
|
||||
|
||||
struct value* array_deref_copy(array* self, size_t index)
|
||||
{
|
||||
assert(index < self->children.size);
|
||||
|
|
|
@ -19,7 +19,6 @@ void array_init(array* self, type* elements_type);
|
|||
void array_free(array* self);
|
||||
|
||||
struct value* array_deref_copy(array* self, size_t index);
|
||||
struct value* array_deref(array* self, size_t index);
|
||||
void array_push(array* self, struct value* element);
|
||||
|
||||
size_t array_str(array* self, char* buffer, size_t size);
|
||||
|
|
|
@ -30,29 +30,6 @@ void compile_node(compiler* self, node* root, program* prog)
|
|||
program_add_instr(prog, OP_ADEREF, NO_PARAM);
|
||||
}
|
||||
// Variables stuff
|
||||
else if (root->type == NODE_CONSTDECL)
|
||||
{
|
||||
cstatic cs;
|
||||
cstatic_init(&cs);
|
||||
|
||||
type* ty = cstatic_resolve_new(&cs,
|
||||
self->sym,
|
||||
root->children.data[1]);
|
||||
|
||||
size_t id = symtable_declare(
|
||||
self->sym,
|
||||
root->children.data[0]->value,
|
||||
ty,
|
||||
root->children.data[1]
|
||||
);
|
||||
|
||||
compile_node(self, root->children.data[1], prog);
|
||||
program_add_instr(prog, OP_STORE, id);
|
||||
|
||||
type_free(ty);
|
||||
free(ty);
|
||||
cstatic_free(&cs);
|
||||
}
|
||||
else if (root->type == NODE_VARDECL)
|
||||
{
|
||||
cstatic cs;
|
||||
|
@ -65,8 +42,7 @@ void compile_node(compiler* self, node* root, program* prog)
|
|||
size_t id = symtable_declare(
|
||||
self->sym,
|
||||
root->children.data[0]->value,
|
||||
ty,
|
||||
root->children.data[1]
|
||||
ty
|
||||
);
|
||||
|
||||
compile_node(self, root->children.data[1], prog);
|
||||
|
@ -76,35 +52,6 @@ void compile_node(compiler* self, node* root, program* prog)
|
|||
free(ty);
|
||||
cstatic_free(&cs);
|
||||
}
|
||||
else if (root->type == NODE_ASSIGN)
|
||||
{
|
||||
node* ident_node = root->children.data[0];
|
||||
|
||||
symentry* entry = symtable_find(
|
||||
self->sym,
|
||||
ident_node->value
|
||||
);
|
||||
|
||||
assert(entry);
|
||||
|
||||
if (root->children.size == 3)
|
||||
{
|
||||
node* array_node = root->children.data[1];
|
||||
node* expr_node = root->children.data[2];
|
||||
|
||||
compile_node(self, array_node, prog);
|
||||
compile_node(self, expr_node, prog);
|
||||
|
||||
program_add_instr(prog, OP_ASTORE, entry->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
node* expr_node = root->children.data[1];
|
||||
|
||||
compile_node(self, expr_node, prog);
|
||||
program_add_instr(prog, OP_STORE, entry->id);
|
||||
}
|
||||
}
|
||||
else if (root->type == NODE_IDENT)
|
||||
{
|
||||
symentry* entry = symtable_find(self->sym, root->value);
|
||||
|
|
159
src/cstatic.c
159
src/cstatic.c
|
@ -51,21 +51,6 @@ type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast)
|
|||
return ty;
|
||||
}
|
||||
|
||||
if (ast->type == NODE_ASSIGN)
|
||||
{
|
||||
size_t i = 1;
|
||||
|
||||
if (ast->children.size == 3)
|
||||
{
|
||||
i = 2;
|
||||
}
|
||||
|
||||
type* ty = cstatic_resolve_new(self,
|
||||
sym,
|
||||
ast->children.data[i]);
|
||||
return ty;
|
||||
}
|
||||
|
||||
if (ast->type == NODE_ADD)
|
||||
{
|
||||
type* lhs = cstatic_resolve_new(self, sym, ast->children.data[0]);
|
||||
|
@ -135,13 +120,6 @@ type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast)
|
|||
size_t dim = ast->children.data[1]->children.size;
|
||||
node* iter = ast->children.data[0];
|
||||
|
||||
if (iter->type == NODE_IDENT)
|
||||
{
|
||||
symentry* entry = symtable_find(sym,
|
||||
iter->value);
|
||||
iter = entry->sym_node;
|
||||
}
|
||||
|
||||
for (size_t i=0; i<dim; i++)
|
||||
{
|
||||
iter = iter->children.data[0];
|
||||
|
@ -242,21 +220,13 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
size_t real_dim = 0;
|
||||
|
||||
node* iter = ast->children.data[0];
|
||||
|
||||
if (iter->type == NODE_IDENT)
|
||||
{
|
||||
symentry* entry = symtable_find(sym,
|
||||
iter->value);
|
||||
iter = entry->sym_node;
|
||||
}
|
||||
|
||||
while (iter->type == NODE_ARRAY)
|
||||
{
|
||||
iter = iter->children.data[0];
|
||||
real_dim++;
|
||||
}
|
||||
|
||||
if (real_dim < dim)
|
||||
if (real_dim != dim)
|
||||
{
|
||||
snprintf(msg, size,
|
||||
"E: array dimension mismatch:"
|
||||
|
@ -324,97 +294,7 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (ast->type == NODE_ASSIGN)
|
||||
{
|
||||
char const* name = ast->children.data[0]->value;
|
||||
|
||||
if (!symtable_find(sym, name))
|
||||
{
|
||||
fprintf(stderr, "E(%d): '%s' is undefined.\n",
|
||||
ast->lineno,
|
||||
name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
symentry* entry = symtable_find(sym, name);
|
||||
|
||||
if (!entry->is_mut)
|
||||
{
|
||||
fprintf(stderr, "E(%d): '%s' is not mutable.\n",
|
||||
ast->lineno,
|
||||
name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (ast->children.size == 3)
|
||||
{
|
||||
type* expr_ty = cstatic_resolve_new(self,
|
||||
sym,
|
||||
ast->children.data[2]
|
||||
);
|
||||
|
||||
type* array_ty = cstatic_resolve_new(self,
|
||||
sym,
|
||||
ast->children.data[0]
|
||||
);
|
||||
|
||||
size_t dim = ast->children.data[1]->children.size;
|
||||
|
||||
type* iter = array_ty;
|
||||
|
||||
for (size_t i=0; i<dim; i++)
|
||||
{
|
||||
if (iter->sub_types.size == 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"E(%d): array assignement "
|
||||
"wrong dimension, expected"
|
||||
" '%ld', got '%ld'.\n", ast->lineno,
|
||||
i, dim);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
iter = iter->sub_types.data[0];
|
||||
}
|
||||
|
||||
int status =
|
||||
cstatic_check_same_type_ptr(self,
|
||||
ast->children.data[0],
|
||||
iter,
|
||||
expr_ty, sym,
|
||||
msg, size);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
type_free(array_ty); free(array_ty);
|
||||
type_free(expr_ty); free(expr_ty);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int status = cstatic_check_same_type(
|
||||
self,
|
||||
ast->children.data[0],
|
||||
ast->children.data[1],
|
||||
sym,
|
||||
msg,
|
||||
size
|
||||
);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (ast->type == NODE_VARDECL
|
||||
|| ast->type == NODE_CONSTDECL)
|
||||
if (ast->type == NODE_VARDECL)
|
||||
{
|
||||
char const* name = ast->children.data[0]->value;
|
||||
|
||||
|
@ -428,16 +308,7 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
|
||||
type* ty = cstatic_resolve_new(self, sym, ast->children.data[1]);
|
||||
assert(ty);
|
||||
|
||||
if (ast->type == NODE_VARDECL)
|
||||
{
|
||||
symtable_declare_mut(sym, name, ty, ast->children.data[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
symtable_declare(sym, name, ty, ast->children.data[1]);
|
||||
}
|
||||
|
||||
symtable_declare(sym, name, ty);
|
||||
type_free(ty);
|
||||
free(ty);
|
||||
return 1;
|
||||
|
@ -799,30 +670,6 @@ int cstatic_check_type_base(cstatic* self, node* lhs, symtable* sym,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cstatic_check_same_type_ptr(cstatic* self, node* lhs,
|
||||
type* left, type* right, symtable* sym, char* msg, size_t size)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
if (!type_equals(left, right))
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
||||
sz += snprintf(msg + sz, size - sz, "E(%d): expected '", lhs->lineno);
|
||||
sz += type_str(left, msg + sz, size - sz);
|
||||
sz += snprintf(msg + sz, size - sz, "', got '");
|
||||
sz += type_str(right, msg + sz, size - sz);
|
||||
sz += snprintf(msg + sz, size - sz, "'");
|
||||
|
||||
type_free(left); free(left);
|
||||
type_free(right); free(right);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, symtable* sym,
|
||||
char* msg, size_t size)
|
||||
{
|
||||
|
|
|
@ -26,10 +26,6 @@ int cstatic_check_type(cstatic* self, node* lhs, symtable* sym,
|
|||
int cstatic_check_type_base(cstatic* self, node* lhs, symtable* sym,
|
||||
char* msg, size_t size, int types, ...);
|
||||
|
||||
int cstatic_check_same_type_ptr(cstatic* self,
|
||||
node* lhs, type* left, type* right, symtable* sym,
|
||||
char* msg, size_t size);
|
||||
|
||||
int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, symtable* sym,
|
||||
char* msg, size_t size);
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ IDENT [_A-Za-z][_A-Za-z0-9]*
|
|||
return TYPE;
|
||||
}
|
||||
|
||||
"let!" { return LET_MUT; }
|
||||
"let" { return LET; }
|
||||
"assert" { return ASSERT; }
|
||||
"<=" { return LE; }
|
||||
|
|
13
src/node.c
13
src/node.c
|
@ -36,19 +36,6 @@ void node_free(node* self)
|
|||
self->children.capacity = 0;
|
||||
}
|
||||
|
||||
node* node_new_clone(node* self)
|
||||
{
|
||||
assert(self);
|
||||
node* clone = malloc(sizeof(node));
|
||||
node_init(clone, self->type, self->value, self->lineno);
|
||||
|
||||
for (size_t i=0; i<self->children.size; i++)
|
||||
{
|
||||
node_add_child(clone, node_new_clone(self->children.data[i]));
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
void node_add_child(node* self, node* child)
|
||||
{
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
G(NODE_UADD), G(NODE_USUB), G(NODE_ADD), G(NODE_SUB), \
|
||||
G(NODE_MUL), G(NODE_DIV), G(NODE_MOD), G(NODE_POW), \
|
||||
G(NODE_ARRAY), G(NODE_INDEX), G(NODE_LT), G(NODE_LE), \
|
||||
G(NODE_GT), G(NODE_GE), G(NODE_VARDECL), G(NODE_IDENT), \
|
||||
G(NODE_CONSTDECL), G(NODE_ASSIGN)
|
||||
G(NODE_GT), G(NODE_GE), G(NODE_VARDECL), G(NODE_IDENT)
|
||||
|
||||
|
||||
#include "mutils.h"
|
||||
|
@ -39,8 +38,6 @@ typedef struct node {
|
|||
void node_init(node* self, int type, char const* value, int lineno);
|
||||
void node_free(node* self);
|
||||
|
||||
node* node_new_clone(node* self);
|
||||
|
||||
void node_add_child(node* self, node* child);
|
||||
|
||||
size_t node_str(node* self, char* buffer, size_t size);
|
||||
|
|
|
@ -43,9 +43,7 @@
|
|||
G(OP_FGT), \
|
||||
G(OP_FGE), \
|
||||
G(OP_STORE), \
|
||||
G(OP_LOAD), \
|
||||
G(OP_ASTORE)
|
||||
|
||||
G(OP_LOAD)
|
||||
|
||||
enum Opcodes {
|
||||
OPCODES(GEN_ENUM)
|
||||
|
|
54
src/parser.y
54
src/parser.y
|
@ -35,7 +35,7 @@
|
|||
%left NOT
|
||||
%token OPAR CPAR
|
||||
%token OSQUARE CSQUARE COMMA
|
||||
%token LET LET_MUT ASSIGN
|
||||
%token LET ASSIGN
|
||||
%type <n_children> expr_unop
|
||||
|
||||
%%
|
||||
|
@ -79,24 +79,7 @@ exprs:
|
|||
|
||||
expr:
|
||||
// INDEX
|
||||
expr array ASSIGN expr {
|
||||
node* n = malloc(sizeof(node));
|
||||
node_init(n, NODE_ASSIGN, "", line);
|
||||
|
||||
node* expr_node = stack_pop();
|
||||
node* array_node = stack_pop();
|
||||
node* ident_node = stack_pop();
|
||||
|
||||
node_add_child(n, ident_node);
|
||||
node_add_child(n, array_node);
|
||||
node_add_child(n, expr_node);
|
||||
|
||||
stack_push(n);
|
||||
|
||||
$$ = 1;
|
||||
}
|
||||
|
||||
| expr array {
|
||||
array array {
|
||||
node *n = malloc(sizeof(node));
|
||||
node_init(n, NODE_INDEX, "", line);
|
||||
size_t const SZ = $1 + $2;
|
||||
|
@ -119,39 +102,9 @@ expr:
|
|||
| ident {
|
||||
}
|
||||
|
||||
| LET_MUT ident ASSIGN expr {
|
||||
node* n = malloc(sizeof(node));
|
||||
node_init(n, NODE_VARDECL, "", line);
|
||||
|
||||
node* rhs = stack_pop();
|
||||
node* lhs = stack_pop();
|
||||
|
||||
node_add_child(n, lhs);
|
||||
node_add_child(n, rhs);
|
||||
|
||||
stack_push(n);
|
||||
|
||||
$$ = 1;
|
||||
}
|
||||
|
||||
| LET ident ASSIGN expr {
|
||||
node* n = malloc(sizeof(node));
|
||||
node_init(n, NODE_CONSTDECL, "", line);
|
||||
|
||||
node* rhs = stack_pop();
|
||||
node* lhs = stack_pop();
|
||||
|
||||
node_add_child(n, lhs);
|
||||
node_add_child(n, rhs);
|
||||
|
||||
stack_push(n);
|
||||
|
||||
$$ = 1;
|
||||
}
|
||||
|
||||
| ident ASSIGN expr {
|
||||
node* n = malloc(sizeof(node));
|
||||
node_init(n, NODE_ASSIGN, "", line);
|
||||
node_init(n, NODE_VARDECL, "", line);
|
||||
|
||||
node* rhs = stack_pop();
|
||||
node* lhs = stack_pop();
|
||||
|
@ -183,6 +136,7 @@ expr:
|
|||
}
|
||||
|
||||
|
||||
|
||||
| expr LT expr {
|
||||
node *n = malloc(sizeof(node));
|
||||
node_init(n, NODE_LT, "", line);
|
||||
|
|
|
@ -17,10 +17,6 @@ void symtable_free(symtable* self)
|
|||
|
||||
for (size_t i=0; i<self->entries.size; i++)
|
||||
{
|
||||
node_free(self->entries.data[i]->sym_node);
|
||||
free(self->entries.data[i]->sym_node);
|
||||
self->entries.data[i]->sym_node = NULL;
|
||||
|
||||
free(self->entries.data[i]->name);
|
||||
type_free(self->entries.data[i]->ty);
|
||||
free(self->entries.data[i]->ty);
|
||||
|
@ -34,17 +30,7 @@ void symtable_free(symtable* self)
|
|||
self->entries.data = NULL;
|
||||
}
|
||||
|
||||
size_t symtable_declare_mut(symtable* self, char const* name, type* ty, node* sym_node)
|
||||
{
|
||||
assert(self);
|
||||
size_t id = symtable_declare(self, name, ty, sym_node);
|
||||
|
||||
self->entries.data[id]->is_mut = 1;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
size_t symtable_declare(symtable* self, char const* name, type* ty, node* sym_node)
|
||||
size_t symtable_declare(symtable* self, char const* name, type* ty)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
|
@ -66,8 +52,6 @@ size_t symtable_declare(symtable* self, char const* name, type* ty, node* sym_no
|
|||
self->entries.data[self->entries.size]->name = str_new(name);
|
||||
self->entries.data[self->entries.size]->ty = type_new_clone(ty);
|
||||
self->entries.data[self->entries.size]->id = self->id;
|
||||
self->entries.data[self->entries.size]->is_mut = 0;
|
||||
self->entries.data[self->entries.size]->sym_node = node_new_clone(sym_node);
|
||||
self->entries.size++;
|
||||
|
||||
return self->id++;
|
||||
|
|
|
@ -3,14 +3,11 @@
|
|||
|
||||
#include "commons.h"
|
||||
#include "type.h"
|
||||
#include "node.h"
|
||||
|
||||
typedef struct {
|
||||
size_t id;
|
||||
int is_mut;
|
||||
char* name;
|
||||
type* ty;
|
||||
node* sym_node;
|
||||
} symentry;
|
||||
|
||||
typedef struct {
|
||||
|
@ -26,8 +23,7 @@ typedef struct {
|
|||
void symtable_init(symtable* self);
|
||||
void symtable_free(symtable* self);
|
||||
|
||||
size_t symtable_declare(symtable* self, char const* name, type* ty, node* sym_node);
|
||||
size_t symtable_declare_mut(symtable* self, char const* name, type* ty, node* sym_node);
|
||||
size_t symtable_declare(symtable* self, char const* name, type* ty);
|
||||
symentry* symtable_find(symtable* self, char const* name);
|
||||
|
||||
#endif
|
||||
|
|
118
src/vm.c
118
src/vm.c
|
@ -102,7 +102,6 @@ void vm_exec(vm* self, program* prog)
|
|||
|
||||
case OP_LOAD: vm_load(self, param); break;
|
||||
case OP_STORE: vm_store(self, param); break;
|
||||
case OP_ASTORE: vm_astore(self, param); break;
|
||||
|
||||
default: {
|
||||
fprintf(stderr, "unknown opcode %s\n",
|
||||
|
@ -168,17 +167,7 @@ void vm_set(vm* self, size_t addr, value* val)
|
|||
assert(self);
|
||||
assert(val);
|
||||
|
||||
if (vm_exists(self, addr))
|
||||
{
|
||||
size_t id = vm_find(self, addr);
|
||||
value_free(self->vars.data[id]->val);
|
||||
free(self->vars.data[id]->val);
|
||||
|
||||
self->vars.data[id]->val = value_new_clone(val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->vars.size >= self->vars.capacity)
|
||||
if (self->vars.size > self->vars.capacity)
|
||||
{
|
||||
self->vars.capacity *= 2;
|
||||
self->vars.data = realloc(
|
||||
|
@ -190,42 +179,9 @@ void vm_set(vm* self, size_t addr, value* val)
|
|||
self->vars.data[self->vars.size] = malloc(sizeof(var));
|
||||
self->vars.data[self->vars.size]->addr = addr;
|
||||
self->vars.data[self->vars.size]->val = value_new_clone(val);
|
||||
|
||||
self->vars.size++;
|
||||
}
|
||||
|
||||
int vm_exists(vm* self, size_t addr)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
for (size_t i=0; i<self->vars.size; i++)
|
||||
{
|
||||
if (self->vars.data[i]->addr == addr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t vm_find(vm* self, size_t addr)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
for (size_t i=0; i<self->vars.size; i++)
|
||||
{
|
||||
if (self->vars.data[i]->addr == addr)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
value* vm_get(vm* self, size_t addr)
|
||||
{
|
||||
assert(self);
|
||||
|
@ -241,38 +197,6 @@ value* vm_get(vm* self, size_t addr)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
value* vm_array_deref(vm* self, value* array_val, value* index_val)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
value* idx = index_val;
|
||||
value* arr = array_val;
|
||||
|
||||
array* idx_array = idx->val.array_val;
|
||||
|
||||
value* val = NULL;
|
||||
|
||||
for (size_t i=0; i<idx_array->children.size; i++)
|
||||
{
|
||||
size_t index = ((value*) idx_array->children.data[i])->val.integer;
|
||||
|
||||
val = (value*) array_deref(
|
||||
arr->val.array_val,
|
||||
index);
|
||||
|
||||
if (val->type->base_type == TY_ARRAY)
|
||||
{
|
||||
value_free(arr);
|
||||
free(arr);
|
||||
arr = val;
|
||||
}
|
||||
}
|
||||
|
||||
value_free(idx); free(idx);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void vm_push(vm* self, int param)
|
||||
{
|
||||
assert(self);
|
||||
|
@ -753,17 +677,12 @@ void vm_aderef(vm* self)
|
|||
arr = val;
|
||||
}
|
||||
}
|
||||
|
||||
assert(val);
|
||||
|
||||
vm_push_value(self, val);
|
||||
|
||||
value_free(idx); free(idx);
|
||||
|
||||
if (arr != val)
|
||||
{
|
||||
value_free(arr); free(arr);
|
||||
}
|
||||
|
||||
self->pc++;
|
||||
}
|
||||
|
@ -1041,6 +960,7 @@ void vm_store(vm* self, int param)
|
|||
assert(self);
|
||||
|
||||
value* val = vm_pop_value(self);
|
||||
|
||||
vm_set(self, param, val);
|
||||
|
||||
value_free(val);
|
||||
|
@ -1059,37 +979,3 @@ void vm_load(vm* self, int param)
|
|||
|
||||
self->pc++;
|
||||
}
|
||||
|
||||
void vm_astore(vm* self, int param)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
value* expr_val = vm_pop_value(self);
|
||||
value* index_val = vm_pop_value(self);
|
||||
|
||||
size_t id = vm_find(self, param);
|
||||
value* array_val = self->vars.data[id]->val;
|
||||
|
||||
value* val = array_val;
|
||||
|
||||
for (size_t i=0; i<index_val->val.array_val->children.size - 1; i++)
|
||||
{
|
||||
value* v = (value*) index_val->val.array_val->children.data[i];
|
||||
size_t index = v->val.integer;
|
||||
val = (value*) val->val.array_val->children.data[index];
|
||||
}
|
||||
|
||||
size_t last_i = index_val->val.array_val->children.size - 1;
|
||||
value* v = (value*) index_val->val.array_val->children.data[last_i];
|
||||
size_t index = v->val.integer;
|
||||
|
||||
value_free((value*) val->val.array_val->children.data[index]);
|
||||
free(val->val.array_val->children.data[index]);
|
||||
|
||||
val->val.array_val->children.data[index] = (struct value*) expr_val;
|
||||
|
||||
value_free(index_val); free(index_val);
|
||||
|
||||
self->pc++;
|
||||
}
|
||||
|
||||
|
|
3
src/vm.h
3
src/vm.h
|
@ -36,8 +36,6 @@ value* vm_pop_value(vm* self);
|
|||
size_t vm_str(vm* self, char* buffer, size_t size);
|
||||
|
||||
void vm_set(vm* self, size_t addr, value* val);
|
||||
size_t vm_find(vm* self, size_t addr);
|
||||
int vm_exists(vm* self, size_t addr);
|
||||
value* vm_get(vm* self, size_t addr);
|
||||
|
||||
void vm_push(vm* self, int param);
|
||||
|
@ -88,6 +86,5 @@ void vm_fge(vm* self);
|
|||
|
||||
void vm_store(vm* self, int param);
|
||||
void vm_load(vm* self, int param);
|
||||
void vm_astore(vm* self, int param);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
let x = 0 x + 1.2
|
||||
let x = false x + "false"
|
||||
let x=0 let x=7
|
||||
let x=[1, 2] x[7, 9]
|
||||
let x = 0 x = 3.2
|
||||
let x = 0 x = 7
|
||||
let x=[1, 2] x[0] = 3.2
|
||||
let x=[3, 4] x[0] = 7
|
||||
|
|
|
@ -25,5 +25,4 @@ assert [0, 1, 0, 1, 0, 1] == 3 * [0, 1]
|
|||
|
||||
assert [0, 0, 0, 0, 0, 0, 1] == 2 * (3 * [0]) + [1]
|
||||
|
||||
assert [2, 4] == [[2, 4], [7, 9]][0]
|
||||
assert [7, 9] == [[2, 4], [7, 9]][1]
|
||||
|
||||
|
|
|
@ -3,33 +3,3 @@ let b = 7
|
|||
let c = a * b + 1
|
||||
|
||||
assert 29 == c
|
||||
|
||||
let d = [[2, 4], [6, 8]]
|
||||
assert 6 == d[1, 0]
|
||||
assert [2, 4] == d[0]
|
||||
assert [6, 8] == d[1]
|
||||
|
||||
let e = 0
|
||||
let f = 1
|
||||
assert [2, 4] == d[e]
|
||||
assert [6, 8] == d[f]
|
||||
|
||||
let! g = 4
|
||||
let! h = 7
|
||||
let i = 3
|
||||
|
||||
h = h + i
|
||||
|
||||
assert 10 == h
|
||||
|
||||
let! j = [1, 2, 3]
|
||||
j[0] = 12
|
||||
j[1] = j[0] + 1
|
||||
assert [12, 13, 3] == j
|
||||
|
||||
let! k = [[2, 4], [6, 8]]
|
||||
k[1, 0] = 12
|
||||
assert [[2, 4], [12, 8]] == k
|
||||
|
||||
k[1] = k[1] + [3]
|
||||
assert [[2, 4], [12, 8, 3]] == k
|
||||
|
|
Loading…
Reference in New Issue