Compare commits

..

No commits in common. "7f5b5486c023322a3e703c3324b70462722cc09f" and "c2e9880c996165432a9b3a360035d2f7fe1f4620" have entirely different histories.

17 changed files with 85 additions and 415 deletions

View File

@ -30,12 +30,6 @@ void array_free(array* self)
free(self->type); self->type = NULL; free(self->type); self->type = NULL;
} }
struct value* array_deref_copy(array* self, size_t index)
{
assert(index < self->children.size);
return (struct value*) value_new_clone((value*)self->children.data[index]);
}
void array_push(array* self, struct value* element) void array_push(array* self, struct value* element)
{ {
assert(self); assert(self);

View File

@ -18,7 +18,6 @@ typedef struct {
void array_init(array* self, type* elements_type); void array_init(array* self, type* elements_type);
void array_free(array* self); void array_free(array* self);
struct value* array_deref_copy(array* self, size_t index);
void array_push(array* self, struct value* element); void array_push(array* self, struct value* element);
size_t array_str(array* self, char* buffer, size_t size); size_t array_str(array* self, char* buffer, size_t size);

View File

@ -17,18 +17,13 @@ void compile_node(compiler* self, node* root, program* prog)
assert(root); assert(root);
assert(prog); assert(prog);
if (root->type == NODE_INDEX) if (root->type == NODE_MUL)
{
compile_children(self, root, prog);
program_add_instr(prog, OP_ADEREF, NO_PARAM);
}
else if (root->type == NODE_MUL)
{ {
cstatic cs; cstatic cs;
cstatic_init(&cs); cstatic_init(&cs);
int lhs = cstatic_resolve_base_type(&cs, root->children.data[0]); int lhs = cstatic_resolve(&cs, root->children.data[0]);
int rhs = cstatic_resolve_base_type(&cs, root->children.data[1]); int rhs = cstatic_resolve(&cs, root->children.data[1]);
cstatic_free(&cs); cstatic_free(&cs);
@ -54,8 +49,8 @@ void compile_node(compiler* self, node* root, program* prog)
cstatic cs; cstatic cs;
cstatic_init(&cs); cstatic_init(&cs);
int lhs = cstatic_resolve_base_type(&cs, root->children.data[0]); int lhs = cstatic_resolve(&cs, root->children.data[0]);
int rhs = cstatic_resolve_base_type(&cs, root->children.data[1]); int rhs = cstatic_resolve(&cs, root->children.data[1]);
cstatic_free(&cs); cstatic_free(&cs);
@ -200,7 +195,7 @@ void compile_number(compiler* self, node* root, program* prog,
cstatic cs; cstatic cs;
cstatic_init(&cs); cstatic_init(&cs);
int ty = cstatic_resolve_base_type(&cs, root); int ty = cstatic_resolve(&cs, root);
switch (ty) switch (ty)
{ {

View File

@ -11,115 +11,74 @@ void cstatic_free(cstatic* self)
assert(self); assert(self);
} }
type* cstatic_new_type(cstatic* self, int base_type) int cstatic_resolve(cstatic* self, node* ast)
{
assert(self);
type* ty = malloc(sizeof(type));
type_init(ty, base_type);
return ty;
}
int cstatic_resolve_base_type(cstatic* self, node* ast)
{
assert(self);
type* ty = cstatic_resolve_new(self, ast);
int res = ty->base_type;
type_free(ty);
free(ty);
return res;
}
type* cstatic_resolve_new(cstatic* self, node* ast)
{ {
assert(self); assert(self);
assert(ast); assert(ast);
if (ast->type == NODE_MUL) if (ast->type == NODE_MUL)
{ {
int lhs = cstatic_resolve_base_type(self, ast->children.data[0]); int lhs = cstatic_resolve(self, ast->children.data[0]);
int rhs = cstatic_resolve_base_type(self, ast->children.data[1]); int rhs = cstatic_resolve(self, ast->children.data[1]);
if (lhs == TY_STRING || rhs == TY_STRING) if (lhs == TY_STRING || rhs == TY_STRING)
{ {
return cstatic_new_type(self, TY_STRING); return TY_STRING;
} }
} }
if (ast->type == NODE_INDEX) if (ast->type == NODE_INTEGER)
{ {
// find inner type using first array element return TY_INTEGER;
size_t dim = ast->children.data[1]->children.size;
node* iter = ast->children.data[0];
for (size_t i=0; i<dim; i++)
{
iter = iter->children.data[0];
}
return cstatic_resolve_new(self, iter);
}
else if (ast->type == NODE_INTEGER)
{
return cstatic_new_type(self, TY_INTEGER);
} }
else if (ast->type == NODE_FLOAT) else if (ast->type == NODE_FLOAT)
{ {
return cstatic_new_type(self, TY_FLOAT); return TY_FLOAT;
} }
else if (ast->type == NODE_ADD) else if (ast->type == NODE_ADD)
{ {
int lhs = cstatic_resolve_base_type(self, ast->children.data[0]); int lhs = cstatic_resolve(self, ast->children.data[0]);
int rhs = cstatic_resolve_base_type(self, ast->children.data[1]); int rhs = cstatic_resolve(self, ast->children.data[1]);
if (lhs == TY_STRING && rhs == TY_STRING) if (lhs == TY_STRING && rhs == TY_STRING)
{ {
return cstatic_new_type(self, TY_STRING); return TY_STRING;
} }
return cstatic_new_type(self, lhs); return lhs;
} }
else if (ast->type == NODE_STRING) else if (ast->type == NODE_STRING)
{ {
return cstatic_new_type(self, TY_STRING); return TY_STRING;
} }
else if (ast->type == NODE_ARRAY) else if (ast->type == NODE_ARRAY)
{ {
assert(ast->children.size > 0); return TY_ARRAY;
type* child = cstatic_resolve_new(self, ast->children.data[0]);
type* ty = malloc(sizeof(type));
type_init_array(ty, child);
type_free(child);
free(child);
return ty;
} }
else if (ast->type == NODE_BOOLEAN else if (ast->type == NODE_BOOLEAN
|| ast->type == NODE_EQ || ast->type == NODE_EQ
|| ast->type == NODE_NE) || ast->type == NODE_NE)
{ {
return cstatic_new_type(self, TY_BOOLEAN); return TY_BOOLEAN;
} }
else else
{ {
for (size_t i=0; i<ast->children.size; i++) for (size_t i=0; i<ast->children.size; i++)
{ {
type* ty = cstatic_resolve_new(self, ast->children.data[i]); int ty = cstatic_resolve(self, ast->children.data[i]);
if (ty != NULL) if (ty != TY_NIL)
{ {
return ty; return ty;
} }
} }
} }
return NULL; return TY_NIL;
} }
int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
@ -139,55 +98,11 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
} }
} }
// Arrays // Arrays
if (ast->type == NODE_INDEX) if (ast->type == NODE_ARRAY)
{
// check dimension
size_t dim = ast->children.data[1]->children.size;
size_t real_dim = 0;
node* iter = ast->children.data[0];
while (iter->type == NODE_ARRAY)
{
iter = iter->children.data[0];
real_dim++;
}
if (real_dim != dim)
{
snprintf(msg, size,
"E: array dimension mismatch:"
" expected '%ld', got '%ld'.",
real_dim, dim);
return 0;
}
// check that all indexes are integers
for (size_t i=0; i<dim; i++)
{
int status = cstatic_check_type_base(
self,
ast->children.data[1]->children.data[i],
msg,
size,
TY_INTEGER,
TYPE_END
);
if (!status)
{
return 0;
}
}
return 1;
}
else if (ast->type == NODE_ARRAY)
{ {
assert(ast->children.size > 0); assert(ast->children.size > 0);
type* ty = cstatic_resolve_new(self, ast->children.data[0]); int ty = cstatic_resolve(self, ast->children.data[0]);
for (size_t i=1; i<ast->children.size; i++) for (size_t i=1; i<ast->children.size; i++)
{ {
@ -197,28 +112,23 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
msg, msg,
size, size,
ty, ty,
NULL TYPE_END
); );
if (!status) if (!status)
{ {
type_free(ty);
free(ty);
return status; return status;
} }
} }
type_free(ty);
free(ty);
return 1; return 1;
} }
// String Operations // String Operations
if (ast->type == NODE_ADD) if (ast->type == NODE_ADD)
{ {
int lhs = cstatic_resolve_base_type(self, ast->children.data[0]); int lhs = cstatic_resolve(self, ast->children.data[0]);
int rhs = cstatic_resolve_base_type(self, ast->children.data[1]); int rhs = cstatic_resolve(self, ast->children.data[1]);
if (lhs == rhs && lhs == TY_STRING) if (lhs == rhs && lhs == TY_STRING)
@ -229,8 +139,8 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
if (ast->type == NODE_MUL) if (ast->type == NODE_MUL)
{ {
int lhs = cstatic_resolve_base_type(self, ast->children.data[0]); int lhs = cstatic_resolve(self, ast->children.data[0]);
int rhs = cstatic_resolve_base_type(self, ast->children.data[1]); int rhs = cstatic_resolve(self, ast->children.data[1]);
if ((lhs == TY_STRING && rhs == TY_INTEGER) if ((lhs == TY_STRING && rhs == TY_INTEGER)
|| (lhs == TY_INTEGER && rhs == TY_STRING)) || (lhs == TY_INTEGER && rhs == TY_STRING))
@ -259,7 +169,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
else if (ast->type == NODE_ASSERT else if (ast->type == NODE_ASSERT
|| ast->type == NODE_NOT) || ast->type == NODE_NOT)
{ {
int status = cstatic_check_type_base(self, int status = cstatic_check_type(self,
ast->children.data[0], ast->children.data[0],
msg, msg,
size, size,
@ -287,7 +197,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
return status; return status;
} }
status = cstatic_check_type_base(self, status = cstatic_check_type(self,
ast->children.data[0], ast->children.data[0],
msg, msg,
size, size,
@ -303,7 +213,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
else if (ast->type == NODE_UADD else if (ast->type == NODE_UADD
|| ast->type == NODE_USUB) || ast->type == NODE_USUB)
{ {
int status = cstatic_check_type_base(self, int status = cstatic_check_type(self,
ast->children.data[0], ast->children.data[0],
msg, msg,
size, size,
@ -335,7 +245,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
return status; return status;
} }
status = cstatic_check_type_base(self, status = cstatic_check_type(self,
ast->children.data[0], ast->children.data[0],
msg, msg,
size, size,
@ -352,68 +262,7 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
} }
int cstatic_check_type(cstatic* self, node* lhs, int cstatic_check_type(cstatic* self, node* lhs,
char* msg, size_t size, type* types, ...) char* msg, size_t size, int types, ...)
{
assert(self);
assert(lhs);
char aze[512];
node_str(lhs, aze, 512);
va_list args;
va_start(args, types);
type* rhs = types;
type* left = cstatic_resolve_new(self, lhs);
type* all_types[TY_TYPE_COUNT];
for (int i=0; i<TY_TYPE_COUNT; i++)
{
all_types[i] = NULL;
}
size_t i = 0;
while (rhs != NULL)
{
all_types[i] = rhs;
if (type_equals(left, rhs))
{
va_end(args);
type_free(left);
free(left);
return 1;
}
rhs = va_arg(args, type*);
i++;
}
va_end(args);
size_t sz = snprintf(msg, size, "E(%d): type mismatch, got '", lhs->lineno);
sz += type_str(left, msg + sz, size - sz);
sz += snprintf(msg + sz, size - sz, "', expected: \n");
size_t j = 0;
while (all_types[j] != NULL)
{
sz += snprintf(msg + sz, size - sz, "\t - ");
sz += type_str(all_types[j], msg + sz, size - sz);
sz += snprintf(msg + sz, size - sz, "\n");
j++;
}
type_free(left);
free(left);
return 0;
}
int cstatic_check_type_base(cstatic* self, node* lhs,
char* msg, size_t size, int types, ...)
{ {
assert(self); assert(self);
assert(lhs); assert(lhs);
@ -424,7 +273,7 @@ int cstatic_check_type_base(cstatic* self, node* lhs,
va_start(args, types); va_start(args, types);
int rhs = types; int rhs = types;
int left = cstatic_resolve_base_type(self, lhs); int left = cstatic_resolve(self, lhs);
int all_types[TY_TYPE_COUNT]; int all_types[TY_TYPE_COUNT];
memset(all_types, TYPE_END, TY_TYPE_COUNT * sizeof(int)); memset(all_types, TYPE_END, TY_TYPE_COUNT * sizeof(int));
@ -448,7 +297,7 @@ int cstatic_check_type_base(cstatic* self, node* lhs,
size_t sz = snprintf(msg, size, "E(%d): type mismatch, got '%s', ", size_t sz = snprintf(msg, size, "E(%d): type mismatch, got '%s', ",
lhs->lineno, lhs->lineno,
TypesStr[left] + strlen("TY_")); TypesStr[left]);
sz += snprintf(msg + sz, size - sz, "expected: \n"); sz += snprintf(msg + sz, size - sz, "expected: \n");
@ -457,7 +306,7 @@ int cstatic_check_type_base(cstatic* self, node* lhs,
while (all_types[j] != TYPE_END) while (all_types[j] != TYPE_END)
{ {
sz += snprintf(msg + sz, size - sz, "\t '%s'\n", sz += snprintf(msg + sz, size - sz, "\t '%s'\n",
TypesStr[all_types[j]] + strlen("TY_")); TypesStr[all_types[j]]);
j++; j++;
} }
@ -471,27 +320,17 @@ int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs,
assert(lhs); assert(lhs);
assert(rhs); assert(rhs);
type* left = cstatic_resolve_new(self, lhs); int left = cstatic_resolve(self, lhs);
type* right = cstatic_resolve_new(self, rhs); int right = cstatic_resolve(self, rhs);
if (!type_equals(left, right)) if (left != right)
{ {
size_t sz = 0; snprintf(msg, size, "E(%d): expected '%s', got '%s'.",
lhs->lineno,
sz += snprintf(msg + sz, size - sz, "E(%d): expected '", lhs->lineno); TypesStr[left],
sz += type_str(left, msg + sz, size - sz); TypesStr[right]);
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 0;
} }
type_free(left); free(left);
type_free(right); free(right);
return 1; return 1;
} }

View File

@ -3,7 +3,6 @@
#include "commons.h" #include "commons.h"
#include "node.h" #include "node.h"
#include "type.h"
#define TYPE_END (-1) #define TYPE_END (-1)
@ -14,17 +13,11 @@ typedef struct {
void cstatic_init(cstatic* self); void cstatic_init(cstatic* self);
void cstatic_free(cstatic* self); void cstatic_free(cstatic* self);
type* cstatic_new_type(cstatic* self, int base_type); int cstatic_resolve(cstatic* self, node* ast);
int cstatic_resolve_base_type(cstatic* self, node* ast);
type* cstatic_resolve_new(cstatic* self, node* ast);
int cstatic_check(cstatic* self, node* ast, char* msg, size_t size); int cstatic_check(cstatic* self, node* ast, char* msg, size_t size);
int cstatic_check_type(cstatic* self, node* lhs, int cstatic_check_type(cstatic* self, node* lhs,
char* msg, size_t size, type* types, ...); char* msg, size_t size, int types, ...);
int cstatic_check_type_base(cstatic* self, node* lhs,
char* msg, size_t size, int types, ...);
int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs,
char* msg, size_t size); char* msg, size_t size);

View File

@ -20,7 +20,6 @@ STRING \"[^"]*\"
{WHITESPACES} {} {WHITESPACES} {}
"assert" { return ASSERT; } "assert" { return ASSERT; }
"," { return COMMA; }
"+" { return ADD; } "+" { return ADD; }
"-" { return SUB; } "-" { return SUB; }
"*" { return MUL; } "*" { return MUL; }

View File

@ -60,15 +60,13 @@ int main(int argc, char** argv)
{ {
size_t const BUF = 1024; size_t const BUF = 1024;
char buffer[BUF]; char buffer[BUF];
memset(buffer, 0, BUF);
node_str(ast, buffer, BUF); node_str(ast, buffer, BUF);
printf("-- ast ---\n%s\n\n", buffer); printf("-- ast ---\n%s\n\n", buffer);
memset(buffer, 0, BUF);
program_str(&prog, buffer, BUF); program_str(&prog, buffer, BUF);
printf("--- program ---\n%s\n", buffer); printf("--- program ---\n%s\n", buffer);
memset(buffer, 0, BUF);
vm_str(&v, buffer, BUF); vm_str(&v, buffer, BUF);
printf("--- stack ---\n%s\n", buffer); printf("--- stack ---\n%s\n", buffer);
} }

View File

@ -10,7 +10,7 @@
G(NODE_ASSERT), \ G(NODE_ASSERT), \
G(NODE_UADD), G(NODE_USUB), G(NODE_ADD), G(NODE_SUB), \ 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_MUL), G(NODE_DIV), G(NODE_MOD), G(NODE_POW), \
G(NODE_ARRAY), G(NODE_INDEX) G(NODE_ARRAY)
#include "mutils.h" #include "mutils.h"

View File

@ -28,8 +28,7 @@
G(OP_FUSUB), \ G(OP_FUSUB), \
G(OP_CAT), \ G(OP_CAT), \
G(OP_SMUL), \ G(OP_SMUL), \
G(OP_MKARRAY), \ G(OP_MKARRAY)
G(OP_ADEREF)
enum Opcodes { enum Opcodes {
OPCODES(GEN_ENUM) OPCODES(GEN_ENUM)

View File

@ -23,8 +23,7 @@
%left ASSERT %left ASSERT
%token <str> BOOLEAN INTEGER FLOAT STRING %token <str> BOOLEAN INTEGER FLOAT STRING
%type <n_children> expr exprs prog array arrays builtins %type <n_children> expr exprs prog;
%type <n_children> expr_list
%left EQ NE %left EQ NE
%left AND %left AND
%left OR %left OR
@ -32,7 +31,7 @@
%left MUL DIV MOD %left MUL DIV MOD
%left POW %left POW
%left NOT %left NOT
%token OPAR CPAR OSQUARE CSQUARE COMMA %token OPAR CPAR OSQUARE CSQUARE
%% %%
@ -67,36 +66,7 @@ exprs:
expr: expr:
// INDEX ASSERT expr {
array array {
node *n = malloc(sizeof(node));
node_init(n, NODE_INDEX, "", line);
size_t const SZ = $1 + $2;
node* all[SZ];
for (size_t i=0; i<SZ; i++)
{
all[i] = stack_pop();
}
for (size_t i=0; i<SZ; i++)
{
node_add_child(n, all[SZ - 1 - i]);
}
stack_push(n);
$$ = 1;
}
// EXPRESSIONS
| array {
$$ = 1;
}
| builtins {
$$ = $1;
}
| ASSERT expr {
node *n = malloc(sizeof(node)); node *n = malloc(sizeof(node));
node_init(n, NODE_ASSERT, "", line); node_init(n, NODE_ASSERT, "", line);
node_add_child(n, stack_pop()); node_add_child(n, stack_pop());
@ -243,12 +213,27 @@ expr:
$$ = $2; $$ = $2;
} }
| OSQUARE exprs CSQUARE {
; node *n = malloc(sizeof(node));
node_init(n, NODE_ARRAY, "", line);
node* elements[$2];
builtins: for (size_t i=0; i<$2; i++)
{
elements[i] = stack_pop();
}
for (size_t i=0; i<$2; i++)
{
node_add_child(n, elements[$2 - 1 - i]);
}
stack_push(n);
$$ = 1;
}
STRING { | STRING {
node* n = malloc(sizeof(node)); node* n = malloc(sizeof(node));
size_t const SZ = strlen($1); size_t const SZ = strlen($1);
char str[SZ - 2]; char str[SZ - 2];
@ -282,34 +267,6 @@ builtins:
} }
; ;
expr_list:
expr { $$ = $1; }
| expr_list COMMA expr { $$ = $1 + $3; }
;
array:
OSQUARE expr_list CSQUARE {
node *n = malloc(sizeof(node));
node_init(n, NODE_ARRAY, "", line);
node* elements[$2];
for (size_t i=0; i<$2; i++)
{
elements[i] = stack_pop();
}
for (size_t i=0; i<$2; i++)
{
node_add_child(n, elements[$2 - 1 - i]);
}
stack_push(n);
$$ = 1;
}
;
%% %%
void yyerror(char const* msg) void yyerror(char const* msg)

View File

@ -6,26 +6,11 @@ void type_init(type* self, int base_type)
{ {
assert(self); assert(self);
self->base_type = base_type; self->base_type = base_type;
self->array_type = NULL;
}
void type_init_array(type* self, type* array_type)
{
assert(self);
assert(array_type);
type_init(self, TY_ARRAY);
self->array_type = type_new_clone(array_type);
} }
void type_free(type* self) void type_free(type* self)
{ {
assert(self); assert(self);
if (self->array_type != NULL)
{
type_free(self->array_type);
free(self->array_type);
}
} }
type* type_new_clone(type* self) type* type_new_clone(type* self)
@ -35,11 +20,6 @@ type* type_new_clone(type* self)
type* clone = malloc(sizeof(type)); type* clone = malloc(sizeof(type));
type_init(clone, self->base_type); type_init(clone, self->base_type);
if (self->array_type)
{
clone->array_type = type_new_clone(self->array_type);
}
return clone; return clone;
} }
@ -47,35 +27,12 @@ int type_equals(type* self, type* rhs)
{ {
assert(self); assert(self);
assert(rhs); assert(rhs);
if (self->base_type != rhs->base_type)
{
return 0;
}
if (self->base_type == TY_ARRAY)
{
assert(self->array_type);
assert(rhs->array_type);
return type_equals(self->array_type, rhs->array_type);
}
return 1;
return self->base_type == rhs->base_type;
} }
size_t type_str(type* self, char* buffer, size_t size) size_t type_str(type* self, char* buffer, size_t size)
{ {
assert(self); assert(self);
size_t sz = snprintf(buffer, size, "%s", return snprintf(buffer, size, "%s", TypesStr[self->base_type]);
TypesStr[self->base_type] + strlen("TY_"));
if (self->base_type == TY_ARRAY)
{
sz += snprintf(buffer + sz, size - sz, "<");
sz += type_str(self->array_type, buffer + sz, size - sz);
sz += snprintf(buffer + sz, size - sz, ">");
}
return sz;
} }

View File

@ -20,11 +20,9 @@ extern char const* TypesStr[];
typedef struct type { typedef struct type {
int base_type; int base_type;
struct type* array_type;
} type; } type;
void type_init(type* self, int base_type); void type_init(type* self, int base_type);
void type_init_array(type* self, type* array_type);
void type_free(type* self); void type_free(type* self);
type* type_new_clone(type* self); type* type_new_clone(type* self);

View File

@ -51,9 +51,8 @@ void value_init_array(value* self, array* arr, int lineno)
self->val.array_val = array_new_clone(arr); self->val.array_val = array_new_clone(arr);
self->lineno = lineno; self->lineno = lineno;
self->type = malloc(sizeof(type)); self->type = malloc(sizeof(type));
type_init_array(self->type, arr->type); type_init(self->type, TY_ARRAY);
} }
void value_free(value* self) void value_free(value* self)

View File

@ -70,7 +70,6 @@ void vm_exec(vm* self, program* prog)
case OP_CAT: vm_cat(self); break; case OP_CAT: vm_cat(self); break;
case OP_MKARRAY: vm_mkarray(self, param); break; case OP_MKARRAY: vm_mkarray(self, param); break;
case OP_ADEREF: vm_aderef(self); break;
default: { default: {
fprintf(stderr, "unknown opcode %s\n", fprintf(stderr, "unknown opcode %s\n",
@ -569,8 +568,8 @@ void vm_mkarray(vm* self, int param)
array_push(arr, (struct value*) elements[i]); array_push(arr, (struct value*) elements[i]);
} }
value_init_array(arr_val, arr, elements[0]->lineno);
value_init_array(arr_val, arr, elements[0]->lineno);
vm_push_value(self, arr_val); vm_push_value(self, arr_val);
for (int i=0; i<param; i++) for (int i=0; i<param; i++)
@ -584,39 +583,3 @@ void vm_mkarray(vm* self, int param)
self->pc++; self->pc++;
} }
void vm_aderef(vm* self)
{
assert(self);
value* idx = vm_pop_value(self);
value* arr = vm_pop_value(self);
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_copy(
arr->val.array_val,
index);
if (val->type->base_type == TY_ARRAY)
{
value_free(arr);
free(arr);
arr = val;
}
}
assert(val);
vm_push_value(self, val);
value_free(idx); free(idx);
value_free(arr); free(arr);
self->pc++;
}

View File

@ -54,6 +54,4 @@ void vm_smul(vm* self);
void vm_cat(vm* self); void vm_cat(vm* self);
void vm_mkarray(vm* self, int param); void vm_mkarray(vm* self, int param);
void vm_aderef(vm* self);
#endif #endif

View File

@ -1,8 +1,2 @@
[] []
[1, 2, 3, "4"] [1 2 3 "4"]
[ [0, 1], ["0", "1"] ]
[1, 2, 3]["a"]
[1, 2, 3][false]
[1, 2, 3][3.14]
[1, 2, 3][ [0, 1] ]
[1, 2, 3][0, 0]

View File

@ -1,23 +1,11 @@
assert [1, 2, 3] == [1, 2, 3] assert [1 - 2 3] == [-1 3]
assert ["a", "b", "c"] == ["a", "b", "c"] assert [1 -2 3] == [1 -2 3]
assert [1, 2, 3] != [7, 2, 3]
assert [1, 2, 3] != [1, 2, 3, 4]
assert ["a", "b", "c"] != ["ac", "b", "c"]
assert ["a", "b", "c"] != ["a", "b", "c", "d"]
assert 3 == [3, 8, 9][0]
assert 8 == [3, 8, 9][1]
assert 9 == [3, 8, 9][2]
assert "8" == ["3", "8", "9"][2 - 1]
assert 7 == [[4, 6], [9, 2, 7], [3, 3, 2]][1, 2]
assert 9 == [[4, 6], [9, 2, 7], [3, 3, 2]][[2, 9, 1][2], 0]
assert [1 2 3] == [1 2 3]
assert ["a" "b" "c"] == ["a" "b" "c"]
assert [1 2 3] != [7 2 3]
assert [1 2 3] != [1 2 3 4]
assert ["a" "b" "c"] != ["ac" "b" "c"]
assert ["a" "b" "c"] != ["a" "b" "c" "d"]