ADD: array integer multiplication.
parent
85a5475fb4
commit
1a2edd01f1
|
@ -44,6 +44,18 @@ void compile_node(compiler* self, node* root, program* prog)
|
||||||
compile_node(self, root->children.data[0], prog);
|
compile_node(self, root->children.data[0], prog);
|
||||||
program_add_instr(prog, OP_SMUL, NO_PARAM);
|
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
|
else
|
||||||
{
|
{
|
||||||
compile_number(self, root, prog, OP_IMUL, OP_FMUL);
|
compile_number(self, root, prog, OP_IMUL, OP_FMUL);
|
||||||
|
|
|
@ -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)
|
if (ast->type == NODE_INDEX)
|
||||||
{
|
{
|
||||||
// find inner type using first array element
|
// find inner type using first array element
|
||||||
|
@ -224,6 +251,23 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
|
||||||
type_free(rhs); free(rhs);
|
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
|
// String Operations
|
||||||
if (ast->type == NODE_ADD)
|
if (ast->type == NODE_ADD)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
G(OP_SMUL), \
|
G(OP_SMUL), \
|
||||||
G(OP_MKARRAY), \
|
G(OP_MKARRAY), \
|
||||||
G(OP_ADEREF), \
|
G(OP_ADEREF), \
|
||||||
G(OP_ACAT)
|
G(OP_ACAT), \
|
||||||
|
G(OP_AMUL)
|
||||||
|
|
||||||
enum Opcodes {
|
enum Opcodes {
|
||||||
OPCODES(GEN_ENUM)
|
OPCODES(GEN_ENUM)
|
||||||
|
|
33
src/vm.c
33
src/vm.c
|
@ -72,6 +72,7 @@ void vm_exec(vm* self, program* prog)
|
||||||
case OP_MKARRAY: vm_mkarray(self, param); break;
|
case OP_MKARRAY: vm_mkarray(self, param); break;
|
||||||
case OP_ADEREF: vm_aderef(self); break;
|
case OP_ADEREF: vm_aderef(self); break;
|
||||||
case OP_ACAT: vm_acat(self); break;
|
case OP_ACAT: vm_acat(self); break;
|
||||||
|
case OP_AMUL: vm_amul(self); break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
fprintf(stderr, "unknown opcode %s\n",
|
fprintf(stderr, "unknown opcode %s\n",
|
||||||
|
@ -645,6 +646,38 @@ void vm_acat(vm* self)
|
||||||
array_push(&result_arr, rhs_arr->children.data[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* result = malloc(sizeof(value));
|
||||||
value_init_array(result, &result_arr, lhs->lineno);
|
value_init_array(result, &result_arr, lhs->lineno);
|
||||||
|
|
||||||
|
|
1
src/vm.h
1
src/vm.h
|
@ -56,5 +56,6 @@ void vm_mkarray(vm* self, int param);
|
||||||
|
|
||||||
void vm_aderef(vm* self);
|
void vm_aderef(vm* self);
|
||||||
void vm_acat(vm* self);
|
void vm_acat(vm* self);
|
||||||
|
void vm_amul(vm* self);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,3 +8,5 @@
|
||||||
[1, 2, 3][0, 0]
|
[1, 2, 3][0, 0]
|
||||||
[1] + 1
|
[1] + 1
|
||||||
[[1, 2]] + [1]
|
[[1, 2]] + [1]
|
||||||
|
[1] * 2.3
|
||||||
|
2.3 * [4.2]
|
||||||
|
|
|
@ -20,3 +20,9 @@ assert [1, 2] == [1] + [2]
|
||||||
assert [3, 4, 5, 6] == [3] + [4] + [5, 6]
|
assert [3, 4, 5, 6] == [3] + [4] + [5, 6]
|
||||||
assert [[2, 4], [6, 8]] == [[2, 4]] + [[6, 8]]
|
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]
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue