Compare commits

..

2 Commits

Author SHA1 Message Date
bog 1a2edd01f1 ADD: array integer multiplication. 2023-08-24 19:52:33 +02:00
bog 85a5475fb4 ADD: array additions. 2023-08-24 19:30:31 +02:00
7 changed files with 166 additions and 13 deletions

View File

@ -44,6 +44,18 @@ void compile_node(compiler* self, node* root, program* prog)
compile_node(self, root->children.data[0], prog);
program_add_instr(prog, OP_SMUL, NO_PARAM);
}
else if (lhs == TY_ARRAY && rhs == TY_INTEGER)
{
compile_node(self, root->children.data[0], prog);
compile_node(self, root->children.data[1], prog);
program_add_instr(prog, OP_AMUL, NO_PARAM);
}
else if (rhs == TY_ARRAY && lhs == TY_INTEGER)
{
compile_node(self, root->children.data[1], prog);
compile_node(self, root->children.data[0], prog);
program_add_instr(prog, OP_AMUL, NO_PARAM);
}
else
{
compile_number(self, root, prog, OP_IMUL, OP_FMUL);
@ -64,6 +76,11 @@ void compile_node(compiler* self, node* root, program* prog)
compile_children(self, root, prog);
program_add_instr(prog, OP_CAT, NO_PARAM);
}
else if (lhs == rhs && lhs == TY_ARRAY)
{
compile_children(self, root, prog);
program_add_instr(prog, OP_ACAT, NO_PARAM);
}
else
{
compile_number(self, root, prog, OP_IADD, OP_FADD);

View File

@ -46,6 +46,33 @@ type* cstatic_resolve_new(cstatic* self, node* ast)
}
}
if (ast->type == NODE_MUL)
{
type* lhs = cstatic_resolve_new(self, ast->children.data[0]);
type* rhs = cstatic_resolve_new(self, ast->children.data[1]);
if (lhs->base_type == TY_INTEGER
&& rhs->base_type == TY_ARRAY)
{
type_free(lhs);
free(lhs);
return rhs;
}
if (lhs->base_type == TY_ARRAY
&& rhs->base_type == TY_INTEGER)
{
type_free(rhs);
free(rhs);
return lhs;
}
type_free(lhs);
free(lhs);
type_free(rhs);
free(rhs);
}
if (ast->type == NODE_INDEX)
{
// find inner type using first array element
@ -70,15 +97,7 @@ type* cstatic_resolve_new(cstatic* self, node* ast)
else if (ast->type == NODE_ADD)
{
int lhs = cstatic_resolve_base_type(self, ast->children.data[0]);
int rhs = cstatic_resolve_base_type(self, ast->children.data[1]);
if (lhs == TY_STRING && rhs == TY_STRING)
{
return cstatic_new_type(self, TY_STRING);
}
return cstatic_new_type(self, lhs);
return cstatic_resolve_new(self, ast->children.data[0]);
}
else if (ast->type == NODE_STRING)
@ -213,6 +232,41 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
return 1;
}
// Array Operations
if (ast->type == NODE_ADD)
{
type* lhs = cstatic_resolve_new(self, ast->children.data[0]);
type* rhs = cstatic_resolve_new(self, ast->children.data[1]);
if (lhs->base_type == TY_ARRAY
&& type_equals(lhs, rhs))
{
type_free(lhs); free(lhs);
type_free(rhs); free(rhs);
return 1;
}
type_free(lhs); free(lhs);
type_free(rhs); free(rhs);
}
if (ast->type == NODE_MUL)
{
type* lhs = cstatic_resolve_new(self, ast->children.data[0]);
type* rhs = cstatic_resolve_new(self, ast->children.data[1]);
if ( (lhs->base_type == TY_ARRAY && rhs->base_type == TY_INTEGER)
|| (lhs->base_type == TY_INTEGER && rhs->base_type == TY_ARRAY))
{
type_free(lhs); free(lhs);
type_free(rhs); free(rhs);
return 1;
}
type_free(lhs); free(lhs);
type_free(rhs); free(rhs);
}
// String Operations
if (ast->type == NODE_ADD)

View File

@ -29,7 +29,9 @@
G(OP_CAT), \
G(OP_SMUL), \
G(OP_MKARRAY), \
G(OP_ADEREF)
G(OP_ADEREF), \
G(OP_ACAT), \
G(OP_AMUL)
enum Opcodes {
OPCODES(GEN_ENUM)

View File

@ -71,6 +71,8 @@ void vm_exec(vm* self, program* prog)
case OP_MKARRAY: vm_mkarray(self, param); break;
case OP_ADEREF: vm_aderef(self); break;
case OP_ACAT: vm_acat(self); break;
case OP_AMUL: vm_amul(self); break;
default: {
fprintf(stderr, "unknown opcode %s\n",
@ -620,3 +622,70 @@ void vm_aderef(vm* self)
self->pc++;
}
void vm_acat(vm* self)
{
assert(self);
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
array* lhs_arr = lhs->val.array_val;
array* rhs_arr = rhs->val.array_val;
array result_arr;
array_init(&result_arr, lhs->type->array_type);
for (size_t i=0; i<lhs_arr->children.size; i++)
{
array_push(&result_arr, lhs_arr->children.data[i]);
}
for (size_t i=0; i<rhs_arr->children.size; i++)
{
array_push(&result_arr, rhs_arr->children.data[i]);
}
value* result = malloc(sizeof(value));
value_init_array(result, &result_arr, lhs->lineno);
array_free(&result_arr);
value_free(lhs); free(lhs);
value_free(rhs); free(rhs);
vm_push_value(self, result);
self->pc++;
}
void vm_amul(vm* self)
{
assert(self);
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
array* arr = lhs->val.array_val;
int count = rhs->val.integer;
array result_arr;
array_init(&result_arr, lhs->type->array_type);
for (int j=0; j<count; j++)
{
for (size_t i=0; i<arr->children.size; i++)
{
array_push(&result_arr, arr->children.data[i]);
}
}
value* result = malloc(sizeof(value));
value_init_array(result, &result_arr, lhs->lineno);
array_free(&result_arr);
value_free(lhs); free(lhs);
value_free(rhs); free(rhs);
vm_push_value(self, result);
self->pc++;
}

View File

@ -55,5 +55,7 @@ void vm_cat(vm* self);
void vm_mkarray(vm* self, int param);
void vm_aderef(vm* self);
void vm_acat(vm* self);
void vm_amul(vm* self);
#endif

View File

@ -6,3 +6,7 @@
[1, 2, 3][3.14]
[1, 2, 3][ [0, 1] ]
[1, 2, 3][0, 0]
[1] + 1
[[1, 2]] + [1]
[1] * 2.3
2.3 * [4.2]

View File

@ -16,8 +16,13 @@ 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] == [1] + [2]
assert [3, 4, 5, 6] == [3] + [4] + [5, 6]
assert [[2, 4], [6, 8]] == [[2, 4]] + [[6, 8]]
assert [0, 1, 0, 1, 0, 1, 2] == [0, 1] * 3 + [2]
assert [0, 1, 0, 1, 0, 1] == 3 * [0, 1]
assert [0, 0, 0, 0, 0, 0, 1] == 2 * (3 * [0]) + [1]