ANN Type check_array_access(const Env env, const Array_Sub array);
ANN m_bool emit_array_access(const Emitter emit,
struct ArrayAccessInfo *const info);
+ANN2(1,2) m_bool check_array_instance(const Env env, Type_Decl *td, const Exp args);
#endif
.lhs = info->array.exp->type,
.rhs = info->array.type,
.data = (uintptr_t)info};
+/*
if (!info->is_var &&
(GET_FLAG(info->array.type, abstract) || type_ref(info->array.type)))
emit_fast_except(emit, NULL, info->array.exp->pos);
+*/
return op_emit(emit, &opi);
}
return emit_array_shift(emit, ArrayConcatRight);
emit_regmove(emit, -SZ_INT);
if (tflag(bin->lhs->type, tflag_compound))
- emit_compound_addref(emit, bin->lhs->type, -SZ_INT*2, false);
+ emit_compound_addref(emit, bin->lhs->type, -SZ_INT - bin->lhs->type->size, false);
(void)emit_add_instr(emit, ArrayAppendFront);
return GW_OK;
}
if (shift_match(bin->rhs->type, bin->lhs->type))
return emit_array_shift(emit, ArrayConcatLeft);
if (tflag(bin->rhs->type, tflag_compound))
- emit_compound_addref(emit, bin->rhs->type, -SZ_INT, false);
+ emit_compound_addref(emit, bin->rhs->type, -bin->rhs->type->size, false);
emit_regmove(emit, -bin->rhs->type->size);
emit_add_instr(emit, ArrayAppend);
return GW_OK;
*(m_uint *)REG(-SZ_INT) = num_obj;
}
}
+
+ANN static bool last_is_zero(Exp e) {
+ while(e->next) e = e->next;
+ return exp_is_zero(e);
+}
+
+ANN2(1,2) m_bool check_array_instance(const Env env, Type_Decl *td, const Exp args) {
+ if (!last_is_zero(td->array->exp)) {
+ if (!args)
+ ERR_B(td->pos, "declaration of abstract type arrays needs lambda");
+ } else {
+ if(args)
+ gwerr_warn("array is empty", "no need to provide a lambda",
+ NULL, env->name, td->array->exp->pos);
+ }
+ return GW_OK;
+}
static OP_CHECK(opck_fptr_call) {
Exp_Binary *bin = (Exp_Binary *)data;
const Type t = mk_call(env, exp_self(bin), bin->rhs, bin->lhs);
- if (t == env->gwion->type[et_error]) {
- gwerr_basic("no matching argument of funptr call", "invalid call", "did you mean to use {+}:=>{0}", env->name, exp_self(bin)->pos, 0);
- env->context->error = true;
- return env->gwion->type[et_error];
- }
+ if (t == env->gwion->type[et_error])
+ gw_err("{-}did you mean to use {0}{+}:=>{0}{-}?{0}\n");
return t;
}
#include "parse.h"
#include "operator.h"
#include "import.h"
+#include "array.h"
OP_CHECK(opck_basic_cast) {
const Exp_Cast *cast = (Exp_Cast *)data;
DECL_ON(const Type, t, = known_type(env, unary->ctor.td));
if(array && !unary->ctor.exp) {
const Type base = array_base(t);
- if(GET_FLAG(base, abstract)) CHECK_BN(abstract_array(env, array));
+ if(GET_FLAG(base, abstract))
+ CHECK_BN(abstract_array(env, array));
+ if(GET_FLAG(base, abstract))
+ CHECK_BN(check_array_instance(env, unary->ctor.td, unary->ctor.exp));
}
CHECK_BN(ensure_traverse(env, t));
if (type_ref(t))
if (tflag(t, tflag_infer))
ERR_N(unary->ctor.td->pos, _("can't use 'new' on '%s'\n"),
t->name);
- if (array) CHECK_BN(check_subscripts(env, array, 1));
+ if (array) {
+ CHECK_BN(check_subscripts(env, array, 1));
+ }
if(unary->ctor.exp) {
const Exp self = exp_self(unary);
const Exp args = cpy_exp(env->gwion->mp, unary->ctor.exp);
#include "tmp_resolve.h"
#include "partial.h"
#include "spread.h"
+#include "array.h"
ANN m_bool check_stmt_list(const Env env, Stmt_List list);
ANN m_bool check_class_def(const Env env, const Class_Def class_def);
const Var_Decl *vd = &decl->vd;
CHECK_BB(check_var(env, vd));
CHECK_BB(check_var_td(env, vd, decl->td));
- if(decl->td->array && decl->td->array->exp) {
+ if (decl->td->array && decl->td->array->exp) {
CHECK_BB(check_subscripts(env, decl->td->array, true));
- if(!decl->args && GET_FLAG(array_base(decl->type), abstract))
- ERR_B(decl->td->pos, "declaration of abstract type arrays needs lambda");
+ if (GET_FLAG(array_base(decl->type), abstract))
+ CHECK_BB(check_array_instance(env, decl->td, decl->args));
}
valid_value(env, vd->xid, vd->value);
// set_vflag(var->value, vflag_used));
return;
gwerr_basic("Argument type mismatch", "call site",
"valid alternatives:", env->name, pos, 0);
- Func up = isa(t, env->gwion->type[et_closure]) < 0
+ const bool is_closure = isa(t, env->gwion->type[et_closure]) < 0;
+ Func up = is_closure
? t->info->func : closure_def(t)->base->func;
do print_signature(up);
while ((up = up->next));
if(t) return t;
}
}
- if(is_func(env->gwion, exp->func->type))
- function_alternative(env, exp->func->type, exp->args, exp->func->pos);
+ function_alternative(env, exp->func->type, exp->args, exp->func->pos);
return NULL;
}
#include "import.h"
ANN static Type _option(const Env env, Type_Decl *td, const uint8_t n) {
+ const Array_Sub array = td->array;
+ td->array = NULL;
Type_List tl = new_mp_vector(env->gwion->mp, Type_Decl*, 1);
mp_vector_set(tl, Type_Decl*, 0, td);
Type_Decl tmp = {
.xid = insert_symbol("Option"), .types = tl, .pos = td->pos};
const Type t = !(n - 1) ? known_type(env, &tmp) : _option(env, &tmp, n - 1);
free_mp_vector(env->gwion->mp, Type_Decl*, tl);
+ td->array = array;
return t;
}