}
if(nonnull_check(l, r))
ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
+ if(l != t_null && isa(l, r) < 0)
+ ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
return r;
}
return t_null;
if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.td, ref);
- const Type t = check_nonnull(env, l, r, "assign", exp_self(bin)->pos);
- if(t == t_null)
- return t_null;
- if(l != t_null && isa(l, t) < 0)
- ERR_N(exp_self(bin)->pos, _("'%s' @=> '%s': not allowed"), l->name, r->name);
+ CHECK_OO(check_nonnull(env, l, r, "assign", exp_self(bin)->pos))
bin->rhs->emit_var = 1;
return r;
}
const Type r = exp_self(cast)->type;
if(check_nonnull(env, l, r, "cast", exp_self(cast)->pos) == t_null)
return t_null;
- return isa(l, r) > 0 ? get_force_type(env, r) : t_null;
+ return get_force_type(env, r);
}
static OP_EMIT(opem_object_cast) {
const Vector v = (Vector)map_get(&n->info->op_map, (vtype)ock->opi->op);
if(!v || !operator_find(v, ock->opi->lhs, ock->opi->rhs))
return GW_OK;
-// TODO: get me back
-// env_err(ock->env, ock->opi->pos, _("operator '%s', for type '%s' and '%s' already imported"),
-// s_name(ock->opi->op), ock->opi->lhs ? ock->opi->lhs->name : NULL,
-// ock->opi->rhs ? ock->opi->rhs->name : NULL);
+ env_err(ock->env, ock->opi->pos, _("operator '%s', for type '%s' and '%s' already imported"),
+ s_name(ock->opi->op), ock->opi->lhs ? ock->opi->lhs->name : NULL,
+ ock->opi->rhs ? ock->opi->rhs->name : NULL);
return GW_ERROR;
}
}
ANN Type op_check(const Env env, struct Op_Import* opi) {
- Type ret = NULL;
Nspc nspc = env->curr;
do {
if(nspc->info->op_map.ptr) {
do {
struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data };
struct OpChecker ock = { env, &nspc->info->op_map, &opi2, 0 };
- ret = op_check_inner(&ock);
+ const Type ret = op_check_inner(&ock);
if(ret) {
if(ret == t_null)
break;
if(!ock.mut)
- set_nspc(&ock, nspc);// TODO check me
+ set_nspc(&ock, nspc);
return ret;
}
} while(l && (l = op_parent(env, l)));
}
- nspc = nspc->parent;
- } while(nspc);
- if(opi->op == insert_symbol(env->gwion->st, "$") ||
- (ret != t_null && opi->op != insert_symbol(env->gwion->st, "@implicit")))
+ } while((nspc = nspc->parent));
+ if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs)
+ return opi->rhs;
+ if(opi->op != insert_symbol(env->gwion->st, "@implicit"))
env_err(env, opi->pos, _("%s %s %s: no match found for operator"),
type_name(opi->lhs), s_name(opi->op), type_name(opi->rhs));
return NULL;
ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
Nspc nspc = get_nspc(emit->gwion->st, opi);
+ if(!nspc || !nspc->info->op_map.ptr)
+ return GW_OK;
Type l = opi->lhs;
do {
Type r = opi->rhs;
do {
- if(!nspc->info->op_map.ptr)
- continue;
const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
const M_Operator* mo = operator_find(v, l, r);
if(mo) {