ANN Type tmpl_exists(const Env env, struct tmpl_info *const info);
ANN Type scan_class(const Env env, const Type t, const Type_Decl *td) {
- struct tmpl_info info = { .base=t, .td=td, .list=t->info->cdef->base.tmpl->list };
+ struct tmpl_info info = { .base=t, .td=td, .list=t->info->cdef->base.tmpl->list };
const Type exists = tmpl_exists(env, &info);
if(exists)
return exists != env->gwion->type[et_error] ? exists : NULL;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
.scope=env->scope->depth, .flag=tflag_scan0 };
- CHECK_BO(envset_push(&es, t->info->owner_class, t->info->ctx ? t->info->ctx->nspc : env->curr))
+ const Type _t = known_type(env, td->types->td);
+ CHECK_BO(envset_push(&es, _t->info->owner_class, _t->info->owner))
const Type ret = _scan_class(env, &info);
if(es.run)
- envset_pop(&es, t->info->owner_class);
+ envset_pop(&es, _t->info->owner_class);
return ret;
}
OP_CHECK(opck_usr_implicit) {
struct Implicit* imp = (struct Implicit*)data;
+/*
+// in use for refinement types
+ const Value v = nspc_lookup_value1(imp->t->info->owner, insert_symbol("@implicit"));
+ if(v) {
+ Func f = v->d.func_ref;
+ while(f) {
+ if(f->def->base->ret_type == imp->t)
+ break;
+ f = f->next;
+ }
+ if(f) {
+ // TODO: add call exp
+ struct Exp_ call = { .exp_type=ae_exp_call, .d={.exp_call={.args=imp->e}}, .pos=imp->e->pos,
+ .type=f->value_ref->type };
+ struct Op_Import opi = { .op=insert_symbol("@func_check"),
+ .rhs=f->value_ref->type, .pos=imp->e->pos, .data=(uintptr_t)&call };
+ CHECK_NN(op_check(env, &opi))
+ }
+ }
+*/
return imp->t;
}
return check_dot(env, member);
}
+/*
+// enable static checking
+ANN static OP_CHECK(opck_predicate) {
+ const Exp_Call *call = (Exp_Call*)data;
+ const Exp predicate = call->args;
+const Func f = exp_self(call)->type->info->func;
+//f->def->d.code->d.stmt_code.stmt_list->stmt->d.stmt_exp.val;
+ if(predicate->exp_type != ae_exp_primary ||
+ predicate->d.prim.prim_type != ae_prim_num ||
+ !predicate->d.prim.d.num) exit(12);
+}
+*/
+
ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
if(tdef->when) {
const Var_Decl decl = new_var_decl(env->gwion->mp, insert_symbol("self"), NULL, tdef->when->pos);
insert_symbol("@implicit"), args, ae_flag_none, tdef->pos);
set_fbflag(fb, fbflag_op);
const Exp helper = new_prim_id(env->gwion->mp, insert_symbol("@predicate"), tdef->when->pos);
- tdef->when->next = helper;
- const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, cpy_exp(env->gwion->mp, tdef->when), tdef->when->pos);// copy exp
+ const Exp when = cpy_exp(env->gwion->mp, tdef->when);
+ when->next = helper;
+ const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, when, when->pos);
const Stmt_List body = new_stmt_list(env->gwion->mp, stmt, NULL);//ret_list);
- const Stmt code = new_stmt_code(env->gwion->mp, body, tdef->when->pos);
+ const Stmt code = new_stmt_code(env->gwion->mp, body, when->pos);
const Func_Def fdef = new_func_def(env->gwion->mp, fb, code);
CHECK_BB(traverse_func_def(env, fdef))
const Exp predicate = stmt->d.stmt_exp.val;
char explain[strlen(predicate->type->name) + 7];
sprintf(explain, "found `{/+}%s{0}`", predicate->type->name);
gwerr_basic("Invalid `{/+}when{0}` predicate expression type", explain, "use `{/+}bool{0}`",
- env->name, tdef->when->pos, 0);
+ env->name, when->pos, 0);
char from[strlen(tdef->type->name) + 39];
sprintf(from, "in `{/+}%s{0}` definition", tdef->type->name);
gwerr_secondary(from, env->name, tdef->pos);
env->context->error++;
return GW_ERROR;
}
+/*
+ // enable static checking
+ const Func f = fdef->base->func;
+ const struct Op_Func opfunc = { .ck=opck_predicate };
+ const struct Op_Import opi = { .rhs=f->value_ref->type,
+ .func=&opfunc, .data=(uintptr_t)f, .pos=tdef->pos, .op=insert_symbol("@func_check") };
+ CHECK_BB(add_op(env->gwion, &opi))
+*/
// we handle the return after, so that we don't get *cant' use implicit casting while defining it*
- const Exp ret_id = new_prim_id(env->gwion->mp, insert_symbol("self"), tdef->when->pos);
+ const Exp ret_id = new_prim_id(env->gwion->mp, insert_symbol("self"), when->pos);
ret_id->d.prim.value = new_value(env->gwion->mp, tdef->type, "self");
- const Stmt ret = new_stmt_exp(env->gwion->mp, ae_stmt_return, ret_id, tdef->when->pos);
+ const Stmt ret = new_stmt_exp(env->gwion->mp, ae_stmt_return, ret_id, when->pos);
const Stmt_List ret_list = new_stmt_list(env->gwion->mp, ret, NULL);
ret_id->type = tdef->type;
body->next = ret_list;