ANN static void clean_type_list(Clean *a, Type_List b) {
for(uint32_t i = 0; i < b->len; i++) {
- Type_Decl *td = *mp_vector_at(b, Type_Decl*, i);
- clean_type_decl(a, td);
+ TmplArg arg = *mp_vector_at(b, TmplArg, i);
+ if(arg.type == tmplarg_td)
+ clean_type_decl(a, arg.d.td);
+ else if(arg.type == tmplarg_exp)
+ clean_exp(a, arg.d.exp);
}
}
return ret;
}
+static INSTR(set) {
+ Value v = *(Value*)(shred->reg + -SZ_INT);
+ shred->reg -= instr->m_val;
+ memcpy(&v->d.ptr, shred->reg, instr->m_val2);
+}
+
+ANN static m_bool emit_class_tmpl(const Emitter emit, const Tmpl *tmpl, const Nspc nspc) {
+ if(tmplarg_ntypes(tmpl->list) != tmpl->list->len) {
+ emit_push_code(emit, "tmpl");
+ for(uint32_t i = 0; i < tmpl->list->len; i++) {
+ const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
+ if(likely(targ.type == tmplarg_td)) continue;
+ CHECK_BB(emit_exp(emit, targ.d.exp));
+ const Specialized spec = *mp_vector_at(tmpl->list, Specialized, i);
+ const Value v = nspc_lookup_value1(nspc, spec.xid);
+ emit_pushimm(emit, (m_uint)v);
+ const Instr instr = emit_add_instr(emit, set);
+ instr->m_val2 = targ.d.exp->type->size;
+ instr->m_val = instr->m_val2 + SZ_INT;
+ }
+ VM_Code code = finalyze(emit, EOC);
+ VM_Shred shred = new_vm_shred(emit->gwion->mp, code);
+ vm_add_shred(emit->gwion->vm, shred);
+ const bool loop = emit->gwion->vm->shreduler->loop;
+ vm_run(emit->gwion->vm);
+ emit->gwion->vm->bbq->is_running = true;
+ emit->gwion->vm->shreduler->loop = loop;
+ }
+ return GW_OK;
+}
+
ANN static m_bool _emit_class_def(const Emitter emit, const Class_Def cdef) {
const Type t = cdef->base.type;
set_tflag(t, tflag_emit);
if (c->base.ext && t->info->parent->info->cdef &&
!tflag(t->info->parent, tflag_emit)) // ?????
CHECK_BB(cdef_parent(emit, c));
+ if (c->base.tmpl) CHECK_BB(emit_class_tmpl(emit, c->base.tmpl, c->base.type->nspc));
if (c->body)
return scanx_body(emit->env, c, (_exp_func)emit_section, emit);
return GW_OK;
ANN void unload_context(const Context ctx, const Env env) {
const Nspc global = ctx->nspc->parent;
- if(global != env->global_nspc) exit(3);
+ if(global != env->global_nspc) exit(53);
context_remref(ctx, env->gwion);
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
const Nspc user = (Nspc)vector_at(&env->scope->nspc_stack, 1);
f->code = new_vmcode(gwion->mp, NULL, NULL, f->name, f->def->stack_depth, true, false);
f->code->native_func = (m_uint)func_ptr;
f->code->ret_type = f->def->base->ret_type;
- if(f->def->base->tmpl && f->def->base->tmpl->call) {
+ if(f->def->base->tmpl) {
+ const Type_List tl = f->def->base->tmpl->call;
+ if(!tl) return;
const Specialized *spec = mp_vector_at(f->def->base->tmpl->list, Specialized, f->def->base->tmpl->list->len - 1);
if(!strcmp(s_name(spec->xid), "...")) {
- f->code->types = new_mp_vector(gwion->mp, Type_Decl*, f->def->base->tmpl->call->len);
- for(uint32_t i = 0; i < f->def->base->tmpl->call->len; i++) {
- Type_Decl *const td = *mp_vector_at(f->def->base->tmpl->call, Type_Decl*, i);
- mp_vector_set(f->code->types, Type, i, known_type(gwion->env, td));
+ const uint32_t len = tmplarg_ntypes(tl);
+ f->code->types = new_mp_vector(gwion->mp, Type, len);
+ uint32_t n = 0;
+ for(uint32_t i = 0; i < tl->len; i++) {
+ const TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+ if(likely(arg.type == tmplarg_td))
+ mp_vector_set(f->code->types, Type, n++, known_type(gwion->env, arg.d.td));
}
+// f->code->types->len = n;
}
}
}
ANN static Type_Decl *_str2td(const Gwion gwion, struct td_checker *tdc);
ANN bool str2tl(const Gwion gwion, struct td_checker *tdc, Type_List *tl) {
- Type_Decl *td = _str2td(gwion, tdc);
- if (!td) GWION_ERR_B(tdc->pos, "invalid types");
- mp_vector_add(gwion->mp, tl, Type_Decl*, td);
- if (*tdc->str == ',') {
- ++tdc->str;
- if (!str2tl(gwion, tdc, tl))
- return false;
- }
+ if(isalpha(*tdc->str)) {
+ TmplArg targ = {
+ .type = tmplarg_td,
+ .d = { .td = _str2td(gwion, tdc) }
+ };
+ if (!targ.d.td) GWION_ERR_B(tdc->pos, "invalid types");
+ mp_vector_add(gwion->mp, tl, TmplArg, targ);
+ if (*tdc->str == ',') {
+ ++tdc->str;
+ if (!str2tl(gwion, tdc, tl))
+ return false;
+ }
+ } else exit(6);
return true;
}
return (Type_List)GW_ERROR;
}
++tdc->str;
- Type_List tl = new_mp_vector(gwion->mp, Type_Decl*, 0);
+ Type_List tl = new_mp_vector(gwion->mp, TmplArg, 0);
if (!str2tl(gwion, tdc, &tl)) {
free_type_list(gwion->mp, tl);
return (Type_List)GW_ERROR;
struct td_info {
Type_List tl;
- GwText text;
+ Gwfmt *fmt;
};
ANN static void td_fullname(const Env env, GwText *text, const Type t) {
ANN static m_bool td_info_run(const Env env, struct td_info *info) {
Type_List tl = info->tl;
- if(unlikely(!tl->len)) {
- text_add(&info->text, "");
- return GW_OK;
- }
for(uint32_t i = 0; i < tl->len; i++) {
- if (i) text_add(&info->text, ",");
- DECL_OB(Type_Decl *, td, = *mp_vector_at(tl, Type_Decl*, i));
- DECL_OB(const Type, t, = known_type(env, td));
- td_fullname(env, &info->text, t);
+ if (i) text_add(&info->fmt->ls->text, ",");
+ TmplArg targ = *mp_vector_at(tl, TmplArg, i);
+ if(targ.type == tmplarg_td) {
+ DECL_OB(const Type, t, = known_type(env, targ.d.td));
+ td_fullname(env, &info->fmt->ls->text, t);
+ } else gwfmt_exp(info->fmt, targ.d.exp);
}
return GW_OK;
}
ANEW ANN m_str tl2str(const Gwion gwion, const Type_List tl,
const loc_t pos NUSED) {
- struct td_info info = {.tl = tl};
- text_init(&info.text, gwion->mp);
+ struct GwfmtState ls = {.minimize=true, .ppa = gwion->ppa};
+ text_init(&ls.text, gwion->mp);
+ Gwfmt l = {.mp = gwion->mp, .st = gwion->st, .ls = &ls, .line = 1, .last = cht_nl };
+ struct td_info info = {.tl = tl, .fmt = &l };
CHECK_BO(td_info_run(gwion->env, &info));
- return info.text.str;
+ return ls.text.str;
}
ANN static inline m_bool ac_finish(const Gwion gwion, const struct AC *ac) {
const Type t_array = env->gwion->type[et_array];
const Class_Def c = t_array->info->cdef;
DECL_ON(const Type, base,
- = ts->t != t_array ? ts->t : known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0)));
+ = ts->t != t_array ? ts->t : known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td));
if (base->size == 0) {
gwerr_basic("Can't use type of size 0 as array base", NULL, NULL,
"/dev/null", (loc_t) {}, 0);
const Class_Def cdef = cpy_class_def(env->gwion->mp, c);
cdef->base.ext = type2td(env->gwion, t_array, (loc_t) {});
cdef->base.xid = sym;
- cdef->base.tmpl->call = new_mp_vector(env->gwion->mp, Type_Decl*, 1);
- mp_vector_set(cdef->base.tmpl->call, Type_Decl*, 0, type2td(env->gwion, base, (loc_t) {}));
+ cdef->base.tmpl->call = new_mp_vector(env->gwion->mp, TmplArg, 1);
+ TmplArg arg = {.type = tmplarg_td, .d = {.td = type2td(env->gwion, base, (loc_t) {})} };
+ mp_vector_set(cdef->base.tmpl->call, TmplArg, 0, arg);
const Context ctx = env->context;
env->context = base->info->value->from->ctx;
const m_uint scope = env_push(env, base->info->value->from->owner_class,
Specialized_List sl = tmpl->list;
for(uint32_t i = 0; i < sl->len; i++) {
Specialized *spec = mp_vector_at(sl, Specialized, i);
- Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
- const Type t = known_type(env, td);
+ // can it be called with consts?
+ if(spec->td) continue;
+ TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+ const Type t = known_type(env, arg.d.td);
nspc_add_type(env->curr, spec->xid, t);
}
}
ANN static bool is_base(const Env env, const Type_List tl) {
for(uint32_t i = 0; i < tl->len; i++) {
- Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
- if(known_type(env, td) == env->gwion->type[et_auto])
+ // can call with const happen?
+ TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+ if(unlikely(arg.type == tmplarg_exp)) continue;
+ if(known_type(env, arg.d.td) == env->gwion->type[et_auto])
return true;
}
return false;
const Type exists = tmpl_exists(env, &info);
if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
if(!ts->td->types || ts->td->types->len != 2) return env->gwion->type[et_error];
- DECL_ON(const Type, key, = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0)));
- DECL_ON(const Type, val, = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 1)));
+ DECL_ON(const Type, key, = known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td));
+ DECL_ON(const Type, val, = known_type(env, mp_vector_at(ts->td->types, TmplArg, 1)->d.td));
if(tflag(key, tflag_ref) || tflag(val, tflag_ref))
ERR_N(ts->td->pos, "can't use Ref:[] in dicts");
const Class_Def cdef = cpy_class_def(env->gwion->mp, env->gwion->type[et_dict]->info->cdef);
.base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list};
const Type exists = tmpl_exists(env, &info);
if (exists) return exists != env->gwion->type[et_error] ? exists : NULL;
- const Type base = known_type(env, *mp_vector_at(ts->td->types, Type_Decl*, 0));
+ const TmplArg arg = *mp_vector_at(ts->td->types, TmplArg, 0);
+ const Type base = known_type(env, arg.d.td);
const Type t = new_type(env->gwion->mp, s_name(info.name), base);
t->size = SZ_INT;
SET_FLAG(t, abstract | ae_flag_final);
ANN bool tmpl_global(const Env env, Type_List tl) {
for(uint32_t i = 0; i < tl->len; i++) {
- Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
- const Type t = known_type(env, td);
+ TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+ if(unlikely(arg.type == tmplarg_exp)) continue;
+ const Type t = known_type(env, arg.d.td);
if(!t || !type_global(env, t))
return false;
}
GWI_BB(gwi_func_arg(gwi, "int", "id"))
GWI_BB(gwi_func_arg(gwi, "T", "value"))
GWI_BB(gwi_func_end(gwi, union_new, ae_flag_none))
-
+
GWI_BB(gwi_class_end(gwi))
- const Func f = (Func)vector_at(&t_union->nspc->vtable, 0);
- const struct Op_Func opfunc = {.ck = opck_union_is};
- const struct Op_Import opi = {
- .rhs = f->value_ref->type,
- .func = &opfunc,
- .data = (uintptr_t)f,
- .pos = gwi->loc,
- .op = insert_symbol(gwi->gwion->st, "@func_check")};
- CHECK_BB(add_op(gwi->gwion, &opi));
-
- const Func f1 = (Func)vector_at(&t_union->nspc->vtable, 1);
+ const struct Op_Func opfunc0 = {.ck = opck_union_is};
+ GWI_BB(add_op_func_check(gwi->gwion->env, t_union, &opfunc0, 0));
+
const struct Op_Func opfunc1 = {.ck = opck_union_new};
- const struct Op_Import opi1 = {
- .rhs = f1->value_ref->type,
- .func = &opfunc1,
- .data = (uintptr_t)f1,
- .pos = gwi->loc,
- .op = insert_symbol(gwi->gwion->st, "@func_check")};
- CHECK_BB(add_op(gwi->gwion, &opi1));
+ GWI_BB(add_op_func_check(gwi->gwion->env, t_union, &opfunc1, 1));
GWI_BB(gwi_oper_ini(gwi, "union", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_emi(gwi, opem_union_dot))
Specialized_List sl = tm->list;
const bool spread = is_spread_tmpl(fdef->base->tmpl);
const uint32_t len = sl->len - spread;
- Type_List tl = new_mp_vector(env->gwion->mp, Type_Decl*, len);
+ Type_List tl = new_mp_vector(env->gwion->mp, TmplArg, len);
m_uint args_number = 0;
if(exp->other) {
if (tmpl_arg_match(env, spec->xid, fdef->base->td->xid, fdef->base->ret_type)) {
CHECK_OO(check_exp(env, exp->other));
if(!is_func(env->gwion, exp->other->type)) {
- Type_Decl *td = type2td(env->gwion, exp->other->type, fdef->base->td->pos);
- mp_vector_set(tl, Type_Decl*, 0, td);
+ TmplArg targ = {
+ .type = tmplarg_td,
+ .d = { .td = type2td(env->gwion, exp->other->type, fdef->base->td->pos) }
+ };
+ mp_vector_set(tl, TmplArg, 0, targ);
} else {
Func func = exp->other->type->info->func;
do {
if(mp_vector_len(func->def->base->args) == 1) {
Arg *arg = mp_vector_at(func->def->base->args, Arg, 0);
- Type_Decl *td = cpy_type_decl(env->gwion->mp, arg->td);
- mp_vector_set(tl, Type_Decl*, 0, td);
+ TmplArg targ = {
+ .type = tmplarg_td,
+ .d = { .td = cpy_type_decl(env->gwion->mp, arg->td) }
+ };
+ mp_vector_set(tl, TmplArg, 0, targ);
break;
}
} while((func = func->next));
while (count < args_len && template_arg) {
Arg *arg = mp_vector_at(args, Arg, count);
if (tmpl_arg_match(env, spec->xid, arg->td->xid, template_arg->type)) {
- mp_vector_set(tl, Type_Decl*, args_number,
- mk_td(env, arg->td, template_arg->type, fdef->base->pos));
+ TmplArg targ = {
+ .type = tmplarg_td,
+ .d = { .td = mk_td(env, arg->td, template_arg->type, fdef->base->pos) }
+ };
+ mp_vector_set(tl, TmplArg, args_number, targ);
++args_number;
break;
}
if(fdef->base->args)
for(uint32_t i = 0; i < fdef->base->args->len && e; i++) e = e->next;
while(e) {
- mp_vector_add(env->gwion->mp, &tl, Type_Decl*, type2td(env->gwion, e->type, e->pos));
+ TmplArg targ = {
+ .type = tmplarg_td,
+ .d = { .td = type2td(env->gwion, e->type, e->pos) }
+ };
+ mp_vector_add(env->gwion->mp, &tl, TmplArg, targ);
e = e->next;
}
}
ANN static bool tl_match(const Env env, const Type_List tl0, const Type_List tl1) {
if (tl0->len != tl1->len) return false;
for(uint32_t i = 0; i < tl0->len; i++) {
- Type_Decl *td0 = *mp_vector_at(tl0, Type_Decl*, i);
- Type_Decl *td1 = *mp_vector_at(tl1, Type_Decl*, i);
- if(known_type(env, td0) != known_type(env, td1))
+ TmplArg targ0 = *mp_vector_at(tl0, TmplArg, i);
+ TmplArg targ1 = *mp_vector_at(tl1, TmplArg, i);
+ if (targ0.type != targ1.type) return false;
+ if(targ0.type == tmplarg_td && known_type(env, targ0.d.td) != known_type(env, targ1.d.td))
return false;
+ // how do we check exps???
}
return true;
}
}
return !err ? GW_OK : GW_ERROR;
}
-/*
-ANN static inline void ctor_effects(const Env env) {
- const Vector v = &env->scope->effects;
- MP_Vector *const w = (MP_Vector*)vector_back(v);
- if (!w) return;
- vector_init(&env->class_def->effects);
- for (uint32_t j = 0; j < w->len; j++) {
- struct ScopeEffect *eff = mp_vector_at(w, struct ScopeEffect, j);
- vector_add(&env->class_def->effects, (m_uint)eff->sym);
- }
- free_mp_vector(env->gwion->mp, struct ScopeEffect, w);
- vector_pop(v);
-}
-*/
-ANN static m_bool check_body(const Env env, Section *const section) {
- const m_bool ret = check_section(env, section);
-// ctor_effects(env);
- return ret;
-}
ANN static bool class_def_has_body(Ast ast) {
const Section *section = mp_vector_at(ast, Section, 0);
}
ANN bool check_trait_requests(const Env env, const Type t, const ID_List list, const ValueFrom *from);
+
+ANN static m_bool check_class_tmpl(const Env env, const Tmpl *tmpl, const Nspc nspc) {
+ if(tmplarg_ntypes(tmpl->list) != tmpl->list->len) {
+ for(uint32_t i = 0; i < tmpl->list->len; i++) {
+ const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
+ if(likely(targ.type == tmplarg_td)) continue;
+ CHECK_OB(check_exp(env, targ.d.exp));
+// if(isa(targ.d.exp->type, known_type(env, spec)
+ const Specialized spec = *mp_vector_at(tmpl->list, Specialized, i);
+ const Value v = new_value(env, targ.d.exp->type, s_name(spec.xid), targ.d.exp->pos);
+ valuefrom(env, v->from);
+ set_vflag(v, vflag_valid);
+ nspc_add_value(nspc, spec.xid, v);
+// valid_value(env, spec.xid, v);
+ SET_FLAG(v, const| ae_flag_static);
+ set_vflag(v, vflag_builtin);
+
+ // set value type
+ }
+ }
+ return GW_OK;
+}
+
ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) {
const Type t = cdef->base.type;
if (cdef->base.ext) CHECK_BB(cdef_parent(env, cdef));
if (!tflag(t, tflag_struct)) inherit(t);
+ if(cdef->base.tmpl) CHECK_BB(check_class_tmpl(env, cdef->base.tmpl, cdef->base.type->nspc));
if (cdef->body) {
- CHECK_BB(env_body(env, cdef, check_body));
+ CHECK_BB(env_body(env, cdef, check_section));
if (cflag(cdef, cflag_struct) || class_def_has_body(cdef->body))
// if (class_def_has_body(cdef->body))
set_tflag(t, tflag_ctor);
for(uint32_t idx = 0; idx < ra->types->len; idx++) {
char c[256];
sprintf(c, "arg%u", idx);
- Type_Decl *td = *mp_vector_at(ra->types, Type_Decl*, idx);
- Arg arg = { .td = cpy_type_decl(env->gwion->mp, td), .var_decl = {.xid = insert_symbol(c), /*.value = v*/ }};
+ TmplArg targ = *mp_vector_at(ra->types, TmplArg, idx);
+ Arg arg = { .td = cpy_type_decl(env->gwion->mp, targ.d.td), .var_decl = {.xid = insert_symbol(c), /*.value = v*/ }};
mp_vector_add(env->gwion->mp, &args, Arg, arg);
}
fdef->base->args = args;
Type_List tl = exp->tmpl->call;
Specialized_List sl = f->def->base->tmpl->list;
for(uint32_t i = 0; i < tl->len; i++) {
- Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
- DECL_OO(const Type, t, = known_type(env, td));
- if(t->info->traits) {
- Specialized * spec = mp_vector_at(sl, Specialized, i);
- if (miss_traits(t, spec)) return NULL;
+ Specialized * spec = mp_vector_at(sl, Specialized, i);
+ TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+ if(unlikely(spec->td)) {
+// check argument in call exp
+ continue;
+
}
+ DECL_OO(const Type, t, = known_type(env, arg.d.td));
+ if(t->info->traits && miss_traits(t, spec))
+ return NULL;
}
return f;
}
return true;
}
+ANN static void op_tmpl_set(const Gwion gwion, Type_List tl,
+ const Type t, const loc_t pos, const uint32_t idx) {
+ TmplArg arg = {.type = tmplarg_td, .d = { .td = type2td(gwion, t, pos)}};
+ mp_vector_set(tl, TmplArg, idx, arg);
+}
+
//! make template operator Func_def
ANN static Type op_def(const Env env, struct Op_Import *const opi,
const Func_Def fdef) {
const Func_Def tmpl_fdef = cpy_func_def(env->gwion->mp, fdef);
tmpl_fdef->base->tmpl->call = new_mp_vector(env->gwion->mp,
- Type_Decl*, fdef->base->tmpl->list->len);
+ TmplArg, fdef->base->tmpl->list->len); // we need to check op def for type, maybe
if (opi->lhs) {
- uint32_t idx = 0;
- const Type lhs = find_type(env, mp_vector_at(fdef->base->args, Arg, 0)->td);
- if(!lhs)
- mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, idx++, type2td(env->gwion, opi->lhs, opi->pos));
- const Type rhs = find_type(env, mp_vector_at(fdef->base->args, Arg, 1)->td);
- if(!rhs)
- mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, idx, type2td(env->gwion, opi->rhs, opi->pos));
+ op_tmpl_set(env->gwion, tmpl_fdef->base->tmpl->call, opi->lhs, opi->pos, 0);
+ if(opi->rhs)
+ op_tmpl_set(env->gwion, tmpl_fdef->base->tmpl->call, opi->rhs, opi->pos, 1);
} else
- mp_vector_set(tmpl_fdef->base->tmpl->call, Type_Decl*, 0, type2td(env->gwion, opi->rhs, opi->pos));
+ op_tmpl_set(env->gwion, tmpl_fdef->base->tmpl->call, opi->rhs, opi->pos, 0);
if (traverse_func_def(env, tmpl_fdef) < 0) {
if (!tmpl_fdef->base->func) func_def_cleaner(env->gwion, tmpl_fdef);
return NULL;
op_visit(env->gwion->mp, env->curr, opi, &visited);
vector_release(&visited);
}
+
+ANN m_bool add_op_func_check(const Env env, const Type t, const struct Op_Func *opfunc, const m_uint idx) {
+ const Func f = (Func)vector_at(&t->nspc->vtable, idx);
+ const struct Op_Import opi = {
+ .rhs = f->value_ref->type,
+ .func = opfunc,
+ .data = (uintptr_t)f,
+ .op = insert_symbol(env->gwion->st, "@func_check")};
+ return add_op(env->gwion, &opi);
+}
return env_body(env, cdef, scan1_section);
}
+ANN static m_bool scan1_class_tmpl(const Env env, const Class_Def c) {
+ Specialized_List sl = c->base.tmpl->list;
+ Type_List tl = c->base.tmpl->call;
+ env_push_type(env, c->base.type);
+ m_bool ret = GW_OK;
+// check len
+ for(uint32_t i = 0; i < sl->len; i++) {
+ const TmplArg targ = *mp_vector_at(tl, TmplArg, i);
+// const Specialized spec = *mp_vector_at(sl, Specialized, i);
+ if (targ.type == tmplarg_td) continue;
+ if(scan1_exp(env, targ.d.exp) < 0) {
+ ret = GW_ERROR;
+ break;
+ }
+/*
+ const Value v = new_value(env, env->gwion->type[et_int], s_name(spec.xid), targ.d.exp->pos);
+ valuefrom(env, v->from);
+ valid_value(env, spec.xid, v);
+ SET_FLAG(v, const| ae_flag_static);
+ set_vflag(v, vflag_builtin);
+ v->d.num = targ.d.exp->d.prim.d.gwint.num;
+*/
+ }
+ env_pop(env, 0);
+ return ret;
+}
+
ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
if (tmpl_base(cdef->base.tmpl)) return GW_OK;
const Type t = cdef->base.type;
const Class_Def c = t->info->cdef;
if (c->base.ext) CHECK_BB(cdef_parent(env, c));
if (c->body) CHECK_BB(scan1_class_def_body(env, c));
+ if (c->base.tmpl) CHECK_BB(scan1_class_tmpl(env, c));
return GW_OK;
}
return ret;
}
+ANN m_bool scan2_class_body(const Env env, const Class_Def c) {
+ const Tmpl *tmpl = c->base.tmpl;
+ if(tmpl && tmplarg_ntypes(tmpl->list) != tmpl->list->len) {
+ for(uint32_t i = 0; i < tmpl->list->len; i++) {
+ const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
+ if(unlikely(targ.type != tmplarg_td))
+ CHECK_BB(scan2_exp(env, targ.d.exp));
+ }
+ }
+ return scan2_ast(env, &c->body);
+}
+
ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
if (tmpl_base(cdef->base.tmpl)) return GW_OK;
const Type t = cdef->base.type;
const Tmpl *tmpl = cdef->base.tmpl;
if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
template_push_types(env, tmpl);
- const m_bool ret = scan2_ast(env, &c->body);
+ const m_bool ret = scan2_class_body(env, c);
if(tmpl && tmpl->call && tmpl->call != (Type_List)1 && tmpl->list)
nspc_pop_type(env->gwion->mp, env->curr);
env_pop(env, scope);
DECL_OB(FILE *,f, = fmemopen(data, strlen(data), "r"));
for(uint32_t i = tmpl->list->len - 1; i < tmpl->call->len; i++) {
fseek(f, 0, SEEK_SET);
- Type_Decl* td = *mp_vector_at(tmpl->call, Type_Decl*, i);
- DECL_OB(const Type, t, = known_type(env, td));
+ const TmplArg targ = *mp_vector_at(tmpl->call, TmplArg, i);
+ // skip or error on const?
+ // or do smth else?
+ DECL_OB(const Type, t, = known_type(env, targ.d.td));
struct AstGetter_ arg = {env->name, f, env->gwion->st, .ppa = env->gwion->ppa};
- const m_str type = type2str(env->gwion, t, td->pos);
+ const m_str type = type2str(env->gwion, t, targ.d.td->pos);
sprintf(c, "%s=%s", s_name(spread->xid), type);
free_mstr(env->gwion->mp, type);
pparg_add(env->gwion->ppa, c);
if(!tl) return GW_OK;
for(uint32_t i = 0; i < len; i++) {
if (i >= tl->len) return GW_OK;
- Type_Decl *td = *mp_vector_at(tl, Type_Decl*, i);
- const Type t = known_type(env, td);
+ TmplArg arg = *mp_vector_at(tl, TmplArg, i);
+ if(unlikely(arg.type == tmplarg_exp)) continue;
+ const Type t = known_type(env, arg.d.td);
Specialized *spec = mp_vector_at(sl, Specialized, i);
nspc_add_type(nspc, spec->xid, t);
};
-if(len != sl->len) return GW_OK;
+ if(len != sl->len) return GW_OK;
return tl->len == sl->len ? GW_OK : GW_ERROR;
}
return _template_push(env, t);
}
+#include <ctype.h>
ANN void check_call(const Env env, const Tmpl *tmpl) {
for(uint32_t i = 0; i < tmpl->call->len; i++) {
- Specialized *spec = mp_vector_at(tmpl->list, Specialized, i);
- Type_Decl *call = *mp_vector_at(tmpl->call, Type_Decl*, i);
- if(spec->xid == call->xid) {
- if (!nspc_lookup_type1(env->curr, spec->xid))
- call->xid = insert_symbol("auto");
- else {
- const Type t = nspc_lookup_type1(env->curr, spec->xid);
- Type_Decl *td = type2td(env->gwion, t, call->pos);
- free_type_decl(env->gwion->mp, call);
- mp_vector_set(tmpl->call, Type_Decl*, i, td);
+ Specialized *spec = i < tmpl->list->len
+ ? mp_vector_at(tmpl->list, Specialized, i)
+ : NULL;
+ TmplArg *targ = mp_vector_at(tmpl->call, TmplArg, i);
+ if(spec && strcmp(s_name(spec->xid), "...")) {
+ //spec->is_const) exit(12);
+ if(spec->xid == targ->d.td->xid) {
+ if (!nspc_lookup_type1(env->curr, spec->xid))
+ targ->d.td->xid = insert_symbol("auto");
+ else {
+ const Type t = nspc_lookup_type1(env->curr, spec->xid);
+ Type_Decl *td = type2td(env->gwion, t, targ->d.td->pos);
+ free_type_decl(env->gwion->mp, targ->d.td);
+ targ->d.td = td;
+ }
}
+ } else {
+ //if(targ->type == tmplarg_td)
+ // targ->d.td->xid = insert_symbol("auto");
+ //else what
}
}
}
+
ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) {
nspc_push_type(env->gwion->mp, env->curr);
if (tmpl->call) check_call(env, tmpl);
if (!sl || sl->len > tl->len || (tl->len != sl->len && !is_spread))
ERR_B(pos, "invalid template type number");
for (uint32_t i = 0; i < sl->len; i++) {
- Type_Decl *tmp = *mp_vector_at(tl, Type_Decl*, i);
- DECL_OB(const Type, t, = known_type(env, tmp));
+ TmplArg *arg = mp_vector_at(tl, TmplArg, i);
Specialized *spec = mp_vector_at(sl, Specialized, i);
- if(spec->traits) {
- Symbol missing = miss_traits(t, spec);
- if (missing) {
- ERR_B(pos, "does not implement requested trait '{/}%s{0}'",
+ if(arg->type == tmplarg_td) {
+
+ // could be an enum or smth
+ if(spec->td) {
+
+Type_Decl *base = arg->d.td;
+Type_Decl *next = base;
+Type_Decl *last = next->next;
+while(next && last) {
+ if(!last->next) break;
+ last = last->next;
+ next = next->next;
+}
+
+if(last) {
+ next->next = NULL;
+const Type t = known_type(env, base);
+// check no array?
+// no template?
+if(t) {
+ arg->type = tmplarg_exp;
+ Exp e = new_exp_td(env->gwion->mp, base, base->pos);
+ arg->d.exp = new_exp_dot(env->gwion->mp, e, last->xid, base->pos);
+free_type_decl(env->gwion->mp, last);
+// arg->d
+
+//turn into an exp;
+i--;continue;
+}
+ next->next = last;
+
+}
+
+//exit(3);
+ ERR_B(pos, "template type argument mismatch. expected %s",
+ spec->td ? "constant" : "type");
+ }
+
+ DECL_OB(const Type, t, = known_type(env, arg->d.td));
+ if(spec->traits) {
+ Symbol missing = miss_traits(t, spec);
+ if (missing) {
+ ERR_B(pos, "does not implement requested trait '{/}%s{0}'",
s_name(missing));
+ }
+ }
+ } else {
+ if(!spec->td) {
+ ERR_B(pos, "template const argument mismatch. expected %s",
+ spec->td ? "constant" : "type");
}
+
+ DECL_OB(const Type, t, = known_type(env, spec->td));
+CHECK_OB(check_exp(env, arg->d.exp));
+// DECL_OB(const Type, t, = nspc_lookup_valueh);
+if(isa(arg->d.exp->type,t) < 0)
+ ERR_B(pos, "invalid type %s for template argument. expected %s",
+ arg->d.exp->type->name, t->name);
+
+// exit(13);
+//puts("we could check here");
}
}
return GW_OK;
if(!d->types) {
if(!single_variadic)
ERR_O(td->pos, _("you must provide template types for type '%s'"), t->name);
- d->types = new_mp_vector(env->gwion->mp, Type_Decl*, 0);
+ d->types = new_mp_vector(env->gwion->mp, TmplArg, 0);
}
const Type ret = _scan_type(env, t, d);
free_type_decl(env->gwion->mp, new_td);
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_List tl = new_mp_vector(env->gwion->mp, TmplArg, 1);
+ TmplArg arg = { .type = tmplarg_td, .d = { .td = td } };
+ mp_vector_set(tl, TmplArg, 0, arg);
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);
+ free_mp_vector(env->gwion->mp, TmplArg, tl);
td->array = array;
return t;
}
}
ANN static Type _ref(const Env env, Type_Decl *td) {
- Type_List tl = new_mp_vector(env->gwion->mp, Type_Decl*, 1);
- mp_vector_set(tl, Type_Decl*, 0, td);
+ Type_List tl = new_mp_vector(env->gwion->mp, TmplArg, 1);
+ TmplArg arg = { .type = tmplarg_td, .d = { .td = td } };
+ mp_vector_set(tl, TmplArg, 0, arg);
Type_Decl tmp = {.xid = insert_symbol("Ref"), .types = tl, .pos = td->pos};
const Type t = known_type(env, &tmp);
- free_mp_vector(env->gwion->mp, Type_Decl*, tl);
+ free_mp_vector(env->gwion->mp, TmplArg, tl);
return t;
}