ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def);
ANN Type known_type(const Env env, Type_Decl*);
ANN Type type_nonnull(const Env env, const Type base);
+ANN Type force_type(const Env env, const Type t);
ANN Type prim_ref(const Env env, const Type t, const Type_Decl* td);
ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos);
ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos);
ANN m_bool operator_set_func(const struct Op_Import*);
ANN void free_op_map(Map map, struct Gwion_* gwion);
+
+ANN void operator_suspend(const Nspc, struct Op_Import*);
+ANN static inline void operator_resume(struct Op_Import *opi) {
+ *(uintptr_t*)opi->ret = opi->data;
+}
+
ANN static inline void set_decl_ref(const Exp e) {
if(e->exp_type == ae_exp_decl) {
SET_FLAG(e->d.exp_decl.td, ref);
SET_FLAG(e->d.exp_decl.list->self->value, ref);
}
}
+
+
+ANN void func_operator(const Func_Def fdef, struct Op_Import *opi);
#endif
if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack") &&
GET_FLAG(env->class_def, struct))
ERR_O(exp_self(prim)->pos, _("can't use 'this' in struct @gack"))
+ if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack"))
+ return force_type(env, env->class_def->e->parent);
return env->class_def;
}
return emit_add_instr(emit, ObjectAssign);
}
-#define STR_FORCE ":force"
-#define STRLEN_FORCE strlen(STR_FORCE)
-
-static inline Type new_force_type(MemPool p, const Type t, const Symbol sym) {
- const Type ret = type_copy(p, t);
- if(ret->nspc)
- ADD_REF(ret->nspc)
- ret->name = s_name(sym);
- ret->flag = t->flag | ae_flag_force;
- nspc_add_type_front(t->e->owner, sym, ret);
- return ret;
- }
-
-static Type get_force_type(const Env env, const Type t) {
- const size_t len = strlen(t->name);
- char name[len + STRLEN_FORCE + 2];
- strcpy(name, t->name);
- strcpy(name + len, STR_FORCE);
- const Symbol sym = insert_symbol(env->gwion->st, name);
- return nspc_lookup_type1(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym);
-}
-
static OP_CHECK(opck_object_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
const Type l = cast->exp->info->type;
const Type r = exp_self(cast)->info->type;
if(check_nonnull(env, l, r, "cast", exp_self(cast)->pos) == env->gwion->type[et_null])
return env->gwion->type[et_null];
- return get_force_type(env, r);
+ return force_type(env, r);
}
static OP_EMIT(opem_object_cast) {
env->func = func;
++env->scope->depth;
nspc_push_value(env->gwion->mp, env->curr);
+ struct Op_Import opi = { };
+ if(GET_FLAG(fdef, op)) {
+ func_operator(f, &opi);
+ operator_suspend(env->curr, &opi);
+ }
const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
+ if(GET_FLAG(fdef, op))
+ operator_resume(&opi);
nspc_pop_value(env->gwion->mp, env->curr);
--env->scope->depth;
env->func = former;
ANN2(1) static M_Operator* operator_find(const Vector v, const restrict Type lhs, const restrict Type rhs) {
for(m_uint i = vector_size(v) + 1; --i;) {
M_Operator* mo = (M_Operator*)vector_at(v, i - 1);
+ if(!mo)
+ continue;
if(op_match(lhs, mo->lhs) && op_match(rhs, mo->rhs))
return mo;
}
return NULL;
}
+ANN void operator_suspend(const Nspc n, struct Op_Import *opi) {
+ const Vector v = (Vector)map_get(&n->info->op_map, (vtype)opi->op);
+ for(m_uint i = vector_size(v) + 1; --i;) {
+ M_Operator* mo = (M_Operator*)vector_at(v, i - 1);
+ if(op_match2(opi->lhs, mo->lhs) && op_match2(opi->rhs, mo->rhs)) {
+ opi->data = (uintptr_t)mo;
+ opi->ret = (Type)&VPTR(v, i-1);
+ VPTR(v, i-1) = 0;
+ break;
+ }
+ }
+}
ANN static M_Operator* new_mo(MemPool p, const struct Op_Import* opi) {
M_Operator* mo = mp_calloc(p, M_Operator);
fptr_assign(env, fptr);
SET_FLAG(fptr->value, func);
add_type(env, t->e->owner, t);
+ mk_class(env, t);
return GW_OK;
}
ANN static m_bool scan2_func_def_op(const Env env, const Func_Def f) {
const m_str str = s_name(f->base->xid);
- const uint is_unary = GET_FLAG(f, unary) + (!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
- const Type l = is_unary ? NULL :
- f->base->args ? f->base->args->var_decl->value->type : NULL;
- const Type r = f->base->args ? is_unary ? f->base->args->var_decl->value->type :
- f->base->args->next ? f->base->args->next->var_decl->value->type :
- f->base->ret_type : NULL;
struct Op_Func opfunc = { .ck=strcmp(str, "@implicit") ? 0 : opck_usr_implicit };
- struct Op_Import opi = { .op=f->base->xid, .lhs=l, .rhs=r, .ret=f->base->ret_type,
- .pos=f->pos, .data=(uintptr_t)f->base->func, .func=&opfunc };
+ struct Op_Import opi = { .ret=f->base->ret_type, .pos=f->pos,
+ .data=(uintptr_t)f->base->func, .func=&opfunc };
+ func_operator(f, &opi);
CHECK_BB(add_op(env->gwion, &opi))
operator_set_func(&opi);
return GW_OK;
if(t->nspc)
ADD_REF(t->nspc)
t->name = s_name(sym);
- t->flag = base->flag;
- SET_FLAG(t, nonnull);
+ t->flag = base->flag | ae_flag_nonnull;
nspc_add_type_front(t->e->owner, sym, t);
- mk_class(env, t);
return t;
}
+#define STR_FORCE ":force"
+#define STRLEN_FORCE strlen(STR_FORCE)
+
+ANN static inline Type new_force_type(MemPool p, const Type t, const Symbol sym) {
+ const Type ret = type_copy(p, t);
+ if(ret->nspc)
+ ADD_REF(ret->nspc)
+ ret->name = s_name(sym);
+ ret->flag = t->flag | ae_flag_force;
+ nspc_add_type_front(t->e->owner, sym, ret);
+ return ret;
+ }
+
+ANN Type force_type(const Env env, const Type t) {
+ const size_t len = strlen(t->name);
+ char name[len + STRLEN_FORCE + 2];
+ strcpy(name, t->name);
+ strcpy(name + len, STR_FORCE);
+ const Symbol sym = insert_symbol(name);
+ return nspc_lookup_type1(t->e->owner, sym) ?: new_force_type(env->gwion->mp, t, sym);
+}
+
ANN Type type_decl_resolve(const Env env, Type_Decl* td) {
DECL_OO(const Type, base, = find_type(env, td))
if(base->e->ctx && base->e->ctx->error)