diff --git a/src/compiler.c b/src/compiler.c index 59c1ea8..1857e75 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -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); diff --git a/src/cstatic.c b/src/cstatic.c index 73b21a1..e219d0c 100644 --- a/src/cstatic.c +++ b/src/cstatic.c @@ -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 @@ -224,6 +251,23 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size) 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) { diff --git a/src/opcodes.h b/src/opcodes.h index 9d4c289..c62f31d 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -30,7 +30,8 @@ G(OP_SMUL), \ G(OP_MKARRAY), \ G(OP_ADEREF), \ - G(OP_ACAT) + G(OP_ACAT), \ + G(OP_AMUL) enum Opcodes { OPCODES(GEN_ENUM) diff --git a/src/vm.c b/src/vm.c index 3b4c682..60cf931 100644 --- a/src/vm.c +++ b/src/vm.c @@ -72,6 +72,7 @@ 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", @@ -645,6 +646,38 @@ void vm_acat(vm* self) 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; jchildren.size; i++) + { + array_push(&result_arr, arr->children.data[i]); + } + } + + value* result = malloc(sizeof(value)); value_init_array(result, &result_arr, lhs->lineno); diff --git a/src/vm.h b/src/vm.h index 4eae76d..f819d5b 100644 --- a/src/vm.h +++ b/src/vm.h @@ -56,5 +56,6 @@ void vm_mkarray(vm* self, int param); void vm_aderef(vm* self); void vm_acat(vm* self); +void vm_amul(vm* self); #endif diff --git a/tests/err_ty_array.wuz b/tests/err_ty_array.wuz index 862288a..8d28356 100644 --- a/tests/err_ty_array.wuz +++ b/tests/err_ty_array.wuz @@ -8,3 +8,5 @@ [1, 2, 3][0, 0] [1] + 1 [[1, 2]] + [1] +[1] * 2.3 +2.3 * [4.2] diff --git a/tests/test_array.wuz b/tests/test_array.wuz index cd90d22..4d4ef43 100644 --- a/tests/test_array.wuz +++ b/tests/test_array.wuz @@ -20,3 +20,9 @@ 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] + +