From 89314842a28db6fde139ef050cf3b963855e0ee9 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Mon, 29 Jan 2024 20:24:26 +0100 Subject: [PATCH] :art: function const generics :tada: --- ast | 2 +- const-generic.gw | 22 +++ examples/Gain.gw | 3 + include/env/func.h | 2 +- include/env/type.h | 2 +- include/gwion.h | 7 +- include/import/checker.h | 2 +- include/operator.h | 2 +- include/parse.h | 2 +- include/spread.h | 2 +- include/template.h | 18 +++ include/tmp_resolve.h | 1 + src/clean.c | 15 +- src/emit/emit.c | 128 ++++++++++----- src/env/context.c | 2 +- src/env/env_utils.c | 18 +-- src/env/envset.c | 7 +- src/env/func.c | 2 +- src/gwion.c | 7 +- src/import/import_cdef.c | 6 +- src/import/import_checker.c | 62 +++++--- src/import/import_enum.c | 2 +- src/import/import_fdef.c | 2 +- src/import/import_item.c | 4 +- src/import/import_prim.c | 8 +- src/import/import_udef.c | 12 +- src/lib/array.c | 18 +-- src/lib/closure.c | 83 +++++----- src/lib/dict.c | 12 +- src/lib/engine.c | 6 + src/lib/instr.c | 4 +- src/lib/object.c | 2 +- src/lib/object_op.c | 22 +-- src/lib/opfunc.c | 6 +- src/lib/ref.c | 2 +- src/lib/tmpl_info.c | 6 +- src/lib/xork.c | 6 +- src/parse/check.c | 265 +++++++++++++++++++------------- src/parse/check_traits.c | 18 +-- src/parse/default_arg.c | 10 +- src/parse/func_operator.c | 10 +- src/parse/func_resolve_tmpl.c | 33 ++-- src/parse/operator.c | 16 +- src/parse/partial.c | 8 +- src/parse/scan0.c | 105 +++++++------ src/parse/scan1.c | 196 +++++++++++------------ src/parse/scan2.c | 52 +++---- src/parse/spread.c | 8 +- src/parse/template.c | 147 +++++++++--------- src/parse/type_decl.c | 21 ++- tests/driver/simple_driver.c | 2 - tests/error/template_unknown.gw | 2 +- tests/union/union_ref.gw | 1 + tests/usr_op/op_tmpl.gw | 2 +- 54 files changed, 805 insertions(+), 598 deletions(-) create mode 100644 const-generic.gw diff --git a/ast b/ast index 7c1340d7..6477df11 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 7c1340d71a2c83dfad0c1d933732e7d223beab59 +Subproject commit 6477df1118c1c7b011583f14cae9e7d185f2cbeb diff --git a/const-generic.gw b/const-generic.gw new file mode 100644 index 00000000..451f7af9 --- /dev/null +++ b/const-generic.gw @@ -0,0 +1,22 @@ +#!enum Enum { +#! bar, +#! foo +#!} +#!class C:[const int N] { +#!class C:[const Enum N] { +#! N :=> var auto n; +#! <<< "N:${N} n:${n}" >>>; +#!} + +fun void foo:[T, const float N]() { +#! <<< __func__ >>>; + <<< N >>>; +#! <<< "heyo">>>; +} +#!const int i; +#!new C:[Enum.foo]; +#!new C:[2]; +#!r +#!foo:[int, Enum.foo](); +foo:[int, .2](); +#!foo:[int, 2](); diff --git a/examples/Gain.gw b/examples/Gain.gw index 099e9fb1..7210dda3 100644 --- a/examples/Gain.gw +++ b/examples/Gain.gw @@ -1,10 +1,13 @@ adc ~> var Gain g ~> dac; g.chan(0); + spork { while(true) { (g.gain() == .2 ? .2 : .1) => g.gain; .15::second => now; }}; + for(var int i; i < 5; i++) { <<< g.op() >>>; i => g.op; <<< g.op() >>>; 2::second => now; } + 1 => adc.op; diff --git a/include/env/func.h b/include/env/func.h index 4c45038e..cd90ee93 100644 --- a/include/env/func.h +++ b/include/env/func.h @@ -49,6 +49,6 @@ ANN static inline m_uint captures_sz(const Capture_List captures) { } ANN static inline bool is_ctor(const Func_Def fdef) { - return !strcmp(s_name(fdef->base->xid), "@ctor"); + return !strcmp(s_name(fdef->base->tag.sym), "@ctor"); } #endif diff --git a/include/env/type.h b/include/env/type.h index 32278ef1..a5cd0f3a 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -67,7 +67,7 @@ ANN2(1, 2) ANEW Type new_type(MemPool, const m_str name, const Type); ANEW ANN Type type_copy(MemPool, const Type type); ANN Value find_value(const Type, const Symbol); ANN m_bool isa(const Type, const Type) __attribute__((pure)); -ANN m_bool isres(const Env, const Symbol, const loc_t pos); +ANN m_bool isres(const Env, const Tag); ANN Type array_type(const Env, const Type, const m_uint); ANN Type find_common_anc(const Type, const Type) __attribute__((pure)); ANN Type array_base(Type) __attribute__((pure)); diff --git a/include/gwion.h b/include/gwion.h index 7e6ec227..5f1e8b37 100644 --- a/include/gwion.h +++ b/include/gwion.h @@ -1,7 +1,6 @@ #ifndef __GWION #define __GWION -// typedef struct Gwion_* Gwion; #include "arg.h" #include "plug.h" #include "driver.h" @@ -49,5 +48,11 @@ ANN static inline void shred_pool_run(const VM_Shred shred, void (*fun)(void*), threadpool_add(shred->info->vm->gwion->data->tpool, fun, arg); } +typedef struct { + VM_Shred shred; + m_bit *mem; + m_bit *RETURN; + MemPool mp; +} TpShredInfo; #endif diff --git a/include/import/checker.h b/include/import/checker.h index f81de9ff..7f229d22 100644 --- a/include/import/checker.h +++ b/include/import/checker.h @@ -16,7 +16,7 @@ typedef struct ImportCK { // name_checker ? f_xfun addr; }; union { - Union_List list; // union + Variable_List list; // union struct Vector_ v; MP_Vector *mpv; // ID_List curr;// enum diff --git a/include/operator.h b/include/operator.h index 72483037..54c1ed42 100644 --- a/include/operator.h +++ b/include/operator.h @@ -93,7 +93,7 @@ ANN static inline void operator_resume(struct Op_Import *opi) { ANN static inline void set_decl_ref(const Exp e) { if (e->exp_type == ae_exp_decl) - SET_FLAG(e->d.exp_decl.vd.value, late); + SET_FLAG(e->d.exp_decl.var.vd.value, late); } ANN void func_operator(const Func_Def fdef, struct Op_Import *opi); diff --git a/include/parse.h b/include/parse.h index 9cfed325..14fd446b 100644 --- a/include/parse.h +++ b/include/parse.h @@ -135,5 +135,5 @@ ANN static inline bool is_static_call(const Gwion gwion, const Exp e) { member->base->exp_type == ae_exp_cast; } -#define is_new(a) !strcmp(s_name((a)->base->xid), "new") +#define is_new(a) !strcmp(s_name((a)->base->tag.sym), "new") #endif diff --git a/include/spread.h b/include/spread.h index cf1d45c1..b95d4428 100644 --- a/include/spread.h +++ b/include/spread.h @@ -3,7 +3,7 @@ ANN static inline bool is_spread_tmpl(const Tmpl *tmpl) { const Specialized *spec = mp_vector_at(tmpl->list, Specialized, tmpl->list->len - 1); - return !strcmp(s_name(spec->xid), "..."); + return !strcmp(s_name(spec->tag.sym), "..."); } ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl); diff --git a/include/template.h b/include/template.h index a91f5be6..47f2d20a 100644 --- a/include/template.h +++ b/include/template.h @@ -3,6 +3,24 @@ ANN m_bool template_push_types(const Env, const Tmpl *); ANN m_bool template_push(const Env env, const Type t); ANN Tmpl *mk_tmpl(const Env, const Tmpl *, const Type_List); +/* +//! returns the Tmpl of a class or enum def +ANN static inline Tmpl* get_tmpl(const Type t) { + return tflag(t, tflag_cdef) + ? t->info->cdef->base.tmpl +// : tflag(t, tflag_udef) + : t->info->udef->tmpl; +// : NULL; +} +*/ +ANN static inline Tmpl* get_tmpl(const Type t) { + return tflag(t, tflag_udef) + ? t->info->udef->tmpl + : t->info->cdef->base.tmpl; +// : tflag(t, tflag_udef) +// : NULL; +} + #define POP_RET(a) \ { \ nspc_pop_type(env->gwion->mp, env->curr); \ diff --git a/include/tmp_resolve.h b/include/tmp_resolve.h index fe9729be..113566f1 100644 --- a/include/tmp_resolve.h +++ b/include/tmp_resolve.h @@ -3,4 +3,5 @@ ANN Func find_template_match(const Env env, const Value value, Exp_Call *const exp); ANN Func find_func_match(const Env env, const Func up, Exp_Call *const exp); +ANN2(1,2) m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread); #endif diff --git a/src/clean.c b/src/clean.c index aa7d57df..0a232814 100644 --- a/src/clean.c +++ b/src/clean.c @@ -53,11 +53,15 @@ ANN static void clean_var_decl(Clean *a, Var_Decl *b) { if (a->scope && b->value) value_remref(b->value, a->gwion); } -ANN static void clean_exp_decl(Clean *a, Exp_Decl *b) { +ANN static void clean_variable(Clean *a, Variable *b) { if (b->td) clean_type_decl(a, b->td); clean_var_decl(a, &b->vd); } +ANN static void clean_exp_decl(Clean *a, Exp_Decl *b) { + clean_variable(a, &b->var); +} + ANN static void clean_exp_binary(Clean *a, Exp_Binary *b) { clean_exp(a, b->lhs); clean_exp(a, b->rhs); @@ -254,8 +258,7 @@ ANN static void clean_stmt(Clean *a, Stmt b) { ANN static void clean_arg_list(Clean *a, Arg_List b) { for(uint32_t i = 0; i < b->len; i++) { Arg *arg = mp_vector_at(b, Arg, i); - if (arg->td) clean_type_decl(a, arg->td); - clean_var_decl(a, &arg->var_decl); + clean_variable(a, &arg->var); } } @@ -307,16 +310,16 @@ ANN void class_def_cleaner(const Gwion gwion, Class_Def b) { } #define clean_enum_def clean_dummy -ANN static void clean_union_list(Clean *a, Union_List b) { +ANN static void clean_variable_list(Clean *a, Variable_List b) { for(uint32_t i = 0; i < b->len; i++) { - Union_Member *tgt = mp_vector_at(b, Union_Member, i); + Variable *tgt = mp_vector_at(b, Variable, i); clean_type_decl(a, tgt->td); clean_var_decl(a, &tgt->vd); } } ANN static void clean_union_def(Clean *a, Union_Def b) { - clean_union_list(a, b->l); + clean_variable_list(a, b->l); if (b->tmpl) clean_tmpl(a, b->tmpl); } diff --git a/src/emit/emit.c b/src/emit/emit.c index 52d37347..eb09a332 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -824,7 +824,7 @@ ANN /*static*/ m_bool emit_interp(const Emitter emit, const Exp exp) { ANN static m_bool emit_prim_hack(const Emitter emit, const Exp *exp) { CHECK_BB(emit_interp(emit, *exp)); if (!(emit->env->func && - emit->env->func->def->base->xid == insert_symbol("@gack"))) + emit->env->func->def->base->tag.sym == insert_symbol("@gack"))) emit_add_instr(emit, GackEnd); else emit_regtomem(emit, SZ_INT, -SZ_INT); return GW_OK; @@ -893,7 +893,7 @@ ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, ANN static m_bool _decl_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl *var_decl, const uint is_ref) { const Value v = var_decl->value; - if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, v->type, decl->td, is_ref)); + if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, v->type, decl->var.td, is_ref)); else CHECK_BB(emit_exp(emit, decl->args)); CHECK_BB(emit_dot_static_data(emit, v, 1)); emit_add_instr(emit, Assign); @@ -932,7 +932,7 @@ ANN static m_uint decl_non_static_offset(const Emitter emit, const Exp_Decl *dec ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) { const Type t = decl->type; const bool emit_addr = exp_getvar(exp_self(decl)); - if(GET_FLAG(decl->vd.value, late) || GET_FLAG(decl->td, late)) { + if(GET_FLAG(decl->var.vd.value, late) || GET_FLAG(decl->var.td, late)) { if(!emit_addr) decl_expand(emit, t); return GW_OK; @@ -1028,7 +1028,7 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0; const bool emit_addr = (!is_obj || is_ref) ? emit_var : true; if (is_obj && !is_ref && !exp_self(decl)->ref) { - if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref)); + if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->var.td, is_ref)); else CHECK_BB(emit_exp(emit, decl->args)); } f_instr *exec = (f_instr *)allocmember; @@ -1067,7 +1067,7 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0; const bool emit_addr = (!is_obj || is_ref) ? emit_var : true; if (is_obj && !is_ref) { - if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref)); + if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->var.td, is_ref)); else CHECK_BB(emit_exp(emit, decl->args)); } if (type->size > SZ_INT) @@ -1089,7 +1089,7 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, ANN static void set_late(const Exp_Decl *decl, const Var_Decl *var) { const Value v = var->value; if (!exp_getvar(exp_self(decl)) && - (GET_FLAG(array_base_simple(v->type), abstract) || GET_FLAG(decl->td, late))) + (GET_FLAG(array_base_simple(v->type), abstract) || GET_FLAG(decl->var.td, late))) SET_FLAG(v, late); else UNSET_FLAG(v, late); } @@ -1099,13 +1099,13 @@ static inline bool late_array(const Type_Decl* td) { } ANN static m_bool emit_decl(const Emitter emit, Exp_Decl *const decl) { - const m_bool global = GET_FLAG(decl->td, global); + const m_bool global = GET_FLAG(decl->var.td, global); const uint var = exp_getvar(exp_self(decl)); - const uint ref = GET_FLAG(decl->td, late) || type_ref(decl->type); - Var_Decl *vd = &decl->vd; + const uint ref = GET_FLAG(decl->var.td, late) || type_ref(decl->type); + Var_Decl *vd = &decl->var.vd; const Value v = vd->value; const uint r = ref || GET_FLAG(v, late); - if (GET_FLAG(decl->td, static)) + if (GET_FLAG(decl->var.td, static)) CHECK_BB(emit_exp_decl_static(emit, decl, vd, r, var)); else if (!global) CHECK_BB(emit_exp_decl_non_static(emit, decl, vd, r, var)); @@ -1120,11 +1120,11 @@ ANN static m_bool emit_decl(const Emitter emit, Exp_Decl *const decl) { CHECK_BB(op_emit(emit, &opi)); } set_late(decl, vd); - if (!decl->args && !exp_getvar(exp_self(decl)) && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->td, late) && - GET_FLAG(v, late) && late_array(decl->td) + if (!decl->args && !exp_getvar(exp_self(decl)) && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->var.td, late) && + GET_FLAG(v, late) && late_array(decl->var.td) && GET_FLAG(v->type, abstract)) { - env_err(emit->env, decl->td->pos, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"), - v->type->name, !GET_FLAG(decl->td, const) ? "var" : "const"); + env_err(emit->env, decl->var.td->tag.loc, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"), + v->type->name, !GET_FLAG(decl->var.td, const) ? "var" : "const"); if(v->type->nspc->vtable.ptr) { const Vector vec = &v->type->nspc->vtable; for(m_uint i = 0; i < vector_size(vec); i++) { @@ -1147,12 +1147,12 @@ ANN /*static */ m_bool emit_exp_decl(const Emitter emit, Exp_Decl *const decl) { if(decl->args && !strncmp(decl->args->type->name, "partial:", 8)) ERR_B(decl->args->pos, "unresolved partial"); CHECK_BB(ensure_emit(emit, t)); - const m_bool global = GET_FLAG(decl->td, global); + const m_bool global = GET_FLAG(decl->var.td, global); const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit); const m_bool ret = emit_decl(emit, decl); if (global) emit_pop(emit, scope); - if(emit->status.in_return && GET_FLAG(decl->vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0) + if(emit->status.in_return && GET_FLAG(decl->var.vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0) emit_add_instr(emit, GWOP_EXCEPT); return ret; } @@ -1502,7 +1502,7 @@ ANN static m_bool emit_template_code(const Emitter emit, const Func f) { ANN static void tmpl_prelude(const Emitter emit, const Func f) { const Instr gtmpl = emit_add_instr(emit, GTmpl); gtmpl->m_val = (m_uint)f->def; - gtmpl->m_val2 = (m_uint)tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->pos); + gtmpl->m_val2 = (m_uint)tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->tag.loc); } ANN static Instr get_prelude(const Emitter emit, const Func f, @@ -1541,7 +1541,7 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) { struct Exp_ lhs = { .exp_type = ae_exp_primary, .type = arg->type, - .pos = arg->td->pos, + .pos = arg->var.td->tag.loc, .d = { .prim = { .prim_type = ae_prim_id } } @@ -1549,7 +1549,7 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) { struct Exp_ rhs = { .exp_type = ae_exp_primary, .type = me->emit->gwion->type[et_bool], - .pos = arg->td->pos, + .pos = arg->var.td->tag.loc, .d = { .prim = { .prim_type = ae_prim_id } } @@ -1557,7 +1557,7 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) { struct Exp_ bin = { .exp_type = ae_exp_binary, .type = arg->type, - .pos = arg->td->pos, + .pos = arg->var.td->tag.loc, .d = { .exp_binary = { .lhs = &lhs, @@ -1569,7 +1569,7 @@ static m_bool me_cmp(MemoizeEmitter *me, const Arg *arg) { struct Op_Import opi = {.op = sym, .lhs = arg->type, .rhs = arg->type, - .pos = me->fdef->base->pos, + .pos = me->fdef->base->tag.loc, .data = (uintptr_t)&bin.d}; CHECK_BB(op_emit(emit, &opi)); const Instr instr = emit_add_instr(emit, BranchEqInt); @@ -1782,7 +1782,7 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary *unary) { const Value v = cap->orig; struct Exp_ exp = { .d = { .prim = { - .d = { .var = cap->xid }, + .d = { .var = cap->tag.sym }, .value = v, .prim_type = ae_prim_id }}, @@ -1972,10 +1972,10 @@ ANN2(1) /*static */ m_bool emit_exp(const Emitter emit, /* const */ Exp e) { if (exp->cast_to) CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to)); if (isa(e->type, emit->gwion->type[et_object]) > 0 && (e->cast_to ? isa(e->cast_to, emit->gwion->type[et_object]) > 0 : 1) && - e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.td, late) && + e->exp_type == ae_exp_decl && GET_FLAG(e->d.exp_decl.var.td, late) && exp_getuse(e) && !exp_getvar(e) && - GET_FLAG(e->d.exp_decl.vd.value, late)) - emit_fast_except(emit, e->d.exp_decl.vd.value->from, e->pos); + GET_FLAG(e->d.exp_decl.var.vd.value, late)) + emit_fast_except(emit, e->d.exp_decl.var.vd.value->from, e->pos); } while ((exp = exp->next)); return GW_OK; } @@ -2255,11 +2255,11 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, emit_memsetimm(emit, key_offset, -1); stmt->v->from->offset = val_offset; //value_addref(stmt->v); -_nspc_add_value(emit->env->curr, stmt->sym, stmt->v); +_nspc_add_value(emit->env->curr, stmt->tag.sym, stmt->v); emit_debug(emit, stmt->v); if (stmt->idx) { stmt->idx->v->from->offset = key_offset; -_nspc_add_value(emit->env->curr, stmt->idx->sym, stmt->idx->v); +_nspc_add_value(emit->env->curr, stmt->idx->tag.sym, stmt->idx->v); //value_addref(stmt->idx->v); emit_debug(emit, stmt->idx->v); } @@ -2405,7 +2405,7 @@ ANN static inline m_bool emit_handler_list(const restrict Emitter emit, Handler *handler = mp_vector_at(handlers, Handler, i); const Instr instr = emit_add_instr(emit, HandleEffect); instr->m_val = emit->status.effect = offset; - instr->m_val2 = (m_uint)handler->xid; + instr->m_val2 = (m_uint)handler->tag.sym; CHECK_BB(scoped_stmt(emit, handler->stmt)); emit_try_goto(emit, v); instr->m_val = emit_code_size(emit); @@ -2663,11 +2663,11 @@ ANN static inline void emit_func_def_init(const Emitter emit, const Func func) { ANN static void emit_func_def_args(const Emitter emit, Arg_List args) { for(uint32_t i = 0; i < args->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); - const Type type = arg->var_decl.value->type; + const Type type = arg->var.vd.value->type; emit->code->stack_depth += type->size; - arg->var_decl.value->from->offset = emit_localn(emit, type); - emit_debug(emit, arg->var_decl.value); - _nspc_add_value(emit->env->curr, insert_symbol(arg->var_decl.value->name), arg->var_decl.value); + arg->var.vd.value->from->offset = emit_localn(emit, type); + emit_debug(emit, arg->var.vd.value); + _nspc_add_value(emit->env->curr, insert_symbol(arg->var.vd.value->name), arg->var.vd.value); } } @@ -2685,9 +2685,9 @@ ANN static m_bool emit_func_def_return(const Emitter emit) { } ANN static VM_Code emit_internal(const Emitter emit, const Func f) { - if (f->def->base->xid == insert_symbol("@dtor")) + if (f->def->base->tag.sym == insert_symbol("@dtor")) return emit->env->class_def->nspc->dtor = finalyze(emit, DTOR_EOC); - else if (f->def->base->xid == insert_symbol("@gack")) { + else if (f->def->base->tag.sym == insert_symbol("@gack")) { emit_regmove(emit, -SZ_INT - f->value_ref->from->owner_class->size); const Instr instr = emit_add_instr(emit, RegPushMem); instr->m_val = SZ_INT; @@ -2721,7 +2721,7 @@ ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) { } ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) { - if (fdef->base->xid == insert_symbol("@dtor")) emit_local(emit, emit->gwion->type[et_int]); + if (fdef->base->tag.sym == insert_symbol("@dtor")) emit_local(emit, emit->gwion->type[et_int]); if (fdef->base->args) emit_func_def_args(emit, fdef->base->args); if (fdef->d.code) { if(!fdef->builtin) { @@ -2819,6 +2819,11 @@ ANN static void emit_lambda_capture(const Emitter emit, const Func_Def fdef) { emit_regtomem4(emit, fdef->stack_depth, offset); } +static INSTR(ConstGenericEOC) { + shred->reg -= instr->m_val; + memcpy((void*)instr->m_val2, shred->reg, instr->m_val); +//a exit(12); +} ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) { if (tmpl_base(f->base->tmpl) && fbflag(f->base, fbflag_op)) return GW_OK; const Func func = f->base->func; @@ -2835,18 +2840,63 @@ ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) { if ((vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl)) || (fdef->base->tmpl && is_new(f))) { const Func base = - nspc_lookup_func1(func->value_ref->from->owner, f->base->xid); + nspc_lookup_func1(func->value_ref->from->owner, f->base->tag.sym); builtin_func(emit->gwion, func, (f_xfun)base->code->native_func); return GW_OK; } const uint global = GET_FLAG(f->base, global); const m_uint scope = !global ? emit->env->scope->depth : env_push_global(emit->env); + if(fdef->base->tmpl) { // check is call? + if(tmplarg_ntypes(fdef->base->tmpl->call) != fdef->base->tmpl->call->len) { +emit_push_code(emit, "const-generic"); // better name? +uint32_t size = 0; +// create new code here + for(uint32_t i = 0; i < fdef->base->tmpl->call->len; i++) { + TmplArg *targ = mp_vector_at(fdef->base->tmpl->call, TmplArg, i); + if(targ->type == tmplarg_td)continue; + // spec could be null cause of spread ops + Specialized *spec = mp_vector_at(fdef->base->tmpl->list, Specialized, i); + if(!spec) break; +CHECK_BB(emit_exp(emit, targ->d.exp)); +//oemit_regmove(emit, -targ->d.exp->type->size); +//emit_regmove(emit, -SZ_INT); +//pop_exp(emit, targ->d.exp); +size += targ->d.exp->type->size; + } +// set variables values +// and remove code +//emit_regmove(emit, -size); +fdef->base->func->value_ref->type->nspc->class_data_size = size; +fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size); +const Instr instr = emit_add_instr(emit, ConstGenericEOC); +instr->m_val = size; +instr->m_val2 = (m_uint)fdef->base->func->value_ref->type->nspc->class_data; +const VM_Code code = finalyze(emit, EOC); +//const VM_Code code = finalyze(emit, ConstGenericEOC); +const VM_Shred shred = new_vm_shred(emit->gwion->mp, code); +vm_add_shred(emit->gwion->vm, shred); +//shred->info->me->ref++; +//vm_run(emit->gwion->vm); +//emit->gwion->vm-> +const bool loop = emit->gwion->vm->shreduler->loop; +vm_run(emit->gwion->vm); +// alloc space +//fdef->base->func->value_ref->type->nspc->class_data_size = size; +//fdef->base->func->value_ref->type->nspc->class_data = _mp_malloc(emit->gwion->mp, size); +//memcpy(fdef->base->func->value_ref->type->nspc->class_data, shred->reg, size); +// => copy data +emit->gwion->vm->bbq->is_running = true; +emit->gwion->vm->shreduler->loop = loop; +//release(shred->info->me, emit->gwion->vm->cleaner_shred); +//} + } + } emit_func_def_init(emit, func); if (vflag(func->value_ref, vflag_member)) stack_alloc(emit); emit->env->func = func; emit_push_scope(emit); - if (!strcmp(s_name(fdef->base->xid), "@gack")) { + if (!strcmp(s_name(fdef->base->tag.sym), "@gack")) { emit_local(emit, emit->gwion->type[et_int]); emit_memsetimm(emit, SZ_INT, 0); } else if(fdef->captures) emit_lambda_capture(emit, fdef); @@ -2921,13 +2971,13 @@ static INSTR(set) { 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"); + emit_push_code(emit, "tmpl"); // make better name 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); + const Value v = nspc_lookup_value1(nspc, spec.tag.sym); emit_pushimm(emit, (m_uint)v); const Instr instr = emit_add_instr(emit, set); instr->m_val2 = targ.d.exp->type->size; diff --git a/src/env/context.c b/src/env/context.c index e5f5639e..421683e6 100644 --- a/src/env/context.c +++ b/src/env/context.c @@ -44,7 +44,7 @@ ANN static void clean(const Nspc nspc, const Env env) { ANN void unload_context(const Context ctx, const Env env) { const Nspc global = ctx->nspc->parent; - if(global != env->global_nspc) exit(53); + assert(global == env->global_nspc); 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); diff --git a/src/env/env_utils.c b/src/env/env_utils.c index f163ddd5..c9926064 100644 --- a/src/env/env_utils.c +++ b/src/env/env_utils.c @@ -54,13 +54,13 @@ ANN Type find_initial(const Env env, const Symbol xid) { } #undef RETURN_TYPE -ANN Type find_type(const Env env, Type_Decl *path) { - DECL_OO(Type, type, = find_initial(env, path->xid)); - while ((path = path->next) && type && type->nspc) { +ANN Type find_type(const Env env, Type_Decl *td) { + DECL_OO(Type, type, = find_initial(env, td->tag.sym)); + while ((td = td->next) && type && type->nspc) { const Nspc nspc = type->nspc; - if(!(type = find_in_parent(type, path->xid))) - ERR_O(path->pos, _("...(cannot find class '%s' in nspc '%s')"), - s_name(path->xid), nspc->name) + if(!(type = find_in_parent(type, td->tag.sym))) + ERR_O(td->tag.loc, _("...(cannot find class '%s' in nspc '%s')"), + s_name(td->tag.sym), nspc->name) } return type; } @@ -107,11 +107,11 @@ ANN Value global_string(const Env env, const m_str str, const loc_t loc) { return value; } -ANN m_bool isres(const Env env, const Symbol xid, const loc_t pos) { +ANN m_bool isres(const Env env, const Tag tag) { const Map map = &env->gwion->data->id; for (m_uint i = 0; i < map_size(map); i++) { - if (xid == (Symbol)VKEY(map, i)) - ERR_B(pos, _("%s is reserved."), s_name(xid)); + if (tag.sym == (Symbol)VKEY(map, i)) + ERR_B(tag.loc, _("%s is reserved."), s_name(tag.sym)); } return GW_OK; } diff --git a/src/env/envset.c b/src/env/envset.c index 699c4d08..5f11cbb6 100644 --- a/src/env/envset.c +++ b/src/env/envset.c @@ -29,9 +29,10 @@ ANN static m_bool push(struct EnvSet *es, const Type t) { t->info->value->from->ctx ? t->info->value->from->ctx->nspc : es->env->curr); env_push_type((void *)es->env, t); // do not push if is a function? - if (tflag(t, tflag_tmpl)) - CHECK_BB(template_push_types( - es->env, t->info->cdef->base.tmpl)); // incorrect templates? + if (tflag(t, tflag_tmpl)) { + const Tmpl *tmpl = get_tmpl(t); + CHECK_BB(template_push_types(es->env, tmpl)); + } return GW_OK; } diff --git a/src/env/func.c b/src/env/func.c index d06873dd..b7840aa8 100644 --- a/src/env/func.c +++ b/src/env/func.c @@ -44,7 +44,7 @@ ANN void builtin_func(const Gwion gwion, const Func f, void *func_ptr) { 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), "...")) { + if(!strcmp(s_name(spec->tag.sym), "...")) { const uint32_t len = tmplarg_ntypes(tl); f->code->types = new_mp_vector(gwion->mp, Type, len); uint32_t n = 0; diff --git a/src/gwion.c b/src/gwion.c index b685f967..487e7699 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -181,14 +181,15 @@ ANN void env_error_footer(const Env env) { bool ctor = false; if (env->func && env->func->def) { if(!is_ctor(env->func->def)) - gwerr_secondary("in function", env->name, env->func->def->base->pos); + gwerr_secondary("in function", env->name, env->func->def->base->tag.loc); else { - gwerr_secondary("in class pre constructor", env->name, env->class_def->info->cdef->pos); + gwerr_secondary("in class pre constructor", env->name, + env->class_def->info->cdef->base.tag.loc); ctor = true; } } if (!ctor && env->class_def && tflag(env->class_def, tflag_cdef)) - gwerr_secondary("in class", env->name, env->class_def->info->cdef->pos); + gwerr_secondary("in class", env->name, env->class_def->info->cdef->base.tag.loc); } ANN static void env_xxx(const Env env, const loc_t pos, const m_str fmt, diff --git a/src/import/import_cdef.c b/src/import/import_cdef.c index 9473972e..be1871a7 100644 --- a/src/import/import_cdef.c +++ b/src/import/import_cdef.c @@ -33,10 +33,10 @@ ANN2(1, 2) static void import_class_ini(const Env env, const Type t) { ANN2(1) void add_template(const Env env, const Type t) { nspc_push_type(env->gwion->mp, env->curr); // - Specialized_List sl = t->info->cdef->base.tmpl->list; + Specialized_List sl = get_tmpl(t)->list; for(uint32_t i = 0; i < sl->len; i++) { Specialized *spec = mp_vector_at(sl, Specialized, i); - nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]); + nspc_add_type(env->curr, spec->tag.sym, env->gwion->type[et_auto]); } } @@ -60,7 +60,7 @@ ANN static Type type_finish(const Gwi gwi, const Type t) { tflag(t, tflag_compound); gwi_add_type(gwi, t); import_class_ini(gwi->gwion->env, t); - if (t->info->cdef && t->info->cdef->base.tmpl) { + if (t->info->cdef && get_tmpl(t)) { gwi->tmpls++; add_template(gwi->gwion->env, t); set_tflag(t, tflag_cdef); diff --git a/src/import/import_checker.c b/src/import/import_checker.c index 68203126..abb3ff85 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -75,9 +75,8 @@ ANN m_bool str2var(const Gwion gwion, Var_Decl *vd, const m_str path, const loc_ DECL_OB(const Symbol, sym, = __str2sym(gwion, &tdc)); struct AC ac = {.str = tdc.str, .pos = pos}; CHECK_BB(ac_run(gwion, &ac)); - vd->xid = sym; + vd->tag = MK_TAG(sym, pos); vd->value = NULL; - vd->pos = pos; return GW_OK; } @@ -86,19 +85,13 @@ ANN static bool _tmpl_list(const Gwion gwion, struct td_checker *tdc, Specialized_List *sl) { if(unlikely(!strncmp(tdc->str, "...", 3))) { tdc->str += 3; - Specialized spec = { - .xid = insert_symbol(gwion->st, "..."), - .pos = tdc->pos - }; + Specialized spec = { .tag = MK_TAG(insert_symbol(gwion->st, "..."), tdc->pos) }; mp_vector_add(gwion->mp, sl, Specialized, spec); return true; } DECL_OO(const Symbol, sym, = __str2sym(gwion, tdc)); // TODO: handle traits? - Specialized spec = { - .xid = sym, - .pos = tdc->pos - }; + Specialized spec = { .tag = MK_TAG(sym, tdc->pos) }; mp_vector_add(gwion->mp, sl, Specialized, spec); if (*tdc->str == ',') { ++tdc->str; @@ -133,6 +126,7 @@ ANN m_bool check_typename_def(const Gwi gwi, ImportCK *ck) { 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) { + // we probably need smth better if(isalpha(*tdc->str)) { TmplArg targ = { .type = tmplarg_td, @@ -145,7 +139,7 @@ ANN bool str2tl(const Gwion gwion, struct td_checker *tdc, Type_List *tl) { if (!str2tl(gwion, tdc, tl)) return false; } - } else exit(6); + } else GWION_ERR_B(tdc->pos, "invalid character in template list"); return true; } @@ -190,7 +184,7 @@ ANN static Arg_List fptr_args(const Gwion gwion, struct td_checker *tdc) { free_arg_list(gwion->mp, args); return (Arg_List)GW_ERROR; } - mp_vector_add(gwion->mp, &args, Arg, (Arg){ .td = td }); + mp_vector_add(gwion->mp, &args, Arg, (Arg){ .var = {.td = td }}); } while(*tdc->str == ',' && tdc->str++); return args; } @@ -298,22 +292,54 @@ ANN static void td_fullname(const Env env, GwText *text, const Type t) { text_add(text, t->name); } +ANN Exp td2exp(const MemPool mp, const Type_Decl *td) { + Exp base = new_prim_id(mp, td->tag.sym, td->tag.loc); + Type_Decl *next = td->next; + while(next) { + base = new_exp_dot(mp, base, next->tag.sym, td->tag.loc); + next = next->next; + } + return base; +} + ANN static m_bool td_info_run(const Env env, struct td_info *info) { + const Gwion gwion = env->gwion; Type_List tl = info->tl; for(uint32_t i = 0; i < tl->len; i++) { 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); + TmplArg *targ = mp_vector_at(tl, TmplArg, i); + if(targ->type == tmplarg_td) { + // we may need to stop errors + if(env->context) env->context->error = true; + const Type t = known_type(env, targ->d.td); + if(env->context) env->context->error = false; + if(t) + td_fullname(env, &info->fmt->ls->text, t); + else { + const Exp exp = td2exp(gwion->mp, targ->d.td); + if(traverse_exp(env, exp) > 0) { + if(is_class(gwion, exp->type)) { + td_fullname(env, &info->fmt->ls->text, exp->type); + free_exp(gwion->mp, exp); + } else gwfmt_exp(info->fmt, exp); + } else GWION_ERR_B(targ->d.td->tag.loc, "invalid template argument"); + } + } else { + Exp exp = targ->d.exp; + if(check_exp(env, targ->d.exp)) { + if(!is_class(gwion, exp->type)) + gwfmt_exp(info->fmt, exp); + else + td_fullname(env, &info->fmt->ls->text, targ->d.exp->type); + } + } } return GW_OK; } ANEW ANN m_str type2str(const Gwion gwion, const Type t, const loc_t pos NUSED) { - GwText text; + GwText text; text_init(&text, gwion->mp); td_fullname(gwion->env, &text, t); return text.str; diff --git a/src/import/import_enum.c b/src/import/import_enum.c index 7d6adf9a..d05b4687 100644 --- a/src/import/import_enum.c +++ b/src/import/import_enum.c @@ -32,7 +32,7 @@ ANN m_int gwi_enum_ini(const Gwi gwi, const m_str type) { ANN m_int gwi_enum_add(const Gwi gwi, const m_str name, const m_uint i) { CHECK_BB(ck_ok(gwi, ck_edef)); DECL_OB(const Symbol, xid, = gwi_str2sym(gwi, name)); - const EnumValue ev = { .xid = xid, .gwint = { .num = i }, .set = true}; + const EnumValue ev = { .tag = MK_TAG(xid, gwi->loc), .gwint = { .num = i }, .set = true}; mp_vector_add(gwi->gwion->mp, &gwi->ck->tmpl, EnumValue, ev); return GW_OK; } diff --git a/src/import/import_fdef.c b/src/import/import_fdef.c index d12d2095..89779089 100644 --- a/src/import/import_fdef.c +++ b/src/import/import_fdef.c @@ -101,7 +101,7 @@ ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, DECL_OB(Type_Decl *, td, = gwi_str2td(gwi, t)); struct Var_Decl_ var; if(gwi_str2var(gwi, &var, n) > 0) { - Arg arg = { .td = td, .var_decl = var }; + Arg arg = { .var = MK_VAR(td, var) }; mp_vector_add(gwi->gwion->mp, &gwi->ck->mpv, Arg, arg); return GW_OK; } diff --git a/src/import/import_item.c b/src/import/import_item.c index dc18be6d..882e351a 100644 --- a/src/import/import_item.c +++ b/src/import/import_item.c @@ -42,7 +42,7 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, union value_data addr) { CHECK_BB(ck_ok(gwi, ck_item)); const Env env = gwi->gwion->env; - gwi->ck->exp->d.exp_decl.td->flag = flag; + gwi->ck->exp->d.exp_decl.var.td->flag = flag; if (gwi->gwion->data->cdoc) { gwfmt_indent(gwi->gwfmt); gwfmt_exp(gwi->gwfmt, gwi->ck->exp); @@ -52,7 +52,7 @@ m_int gwi_item_end(const Gwi gwi, const ae_flag flag, union value_data addr) { if (env->class_def && tflag(env->class_def, tflag_tmpl)) return gwi_item_tmpl(gwi); CHECK_BB(traverse_exp(env, gwi->ck->exp)); - const Value value = gwi->ck->exp->d.exp_decl.vd.value; + const Value value = gwi->ck->exp->d.exp_decl.var.vd.value; value->d = addr; set_vflag(value, vflag_builtin); if (!env->class_def) SET_FLAG(value, global); diff --git a/src/import/import_prim.c b/src/import/import_prim.c index e648492d..9376770d 100644 --- a/src/import/import_prim.c +++ b/src/import/import_prim.c @@ -193,6 +193,11 @@ ANN static void prim_implicit(const Env env, const Type t){ add_op(env->gwion, &opi); } +static OP_CHECK(opck_prim_cast) { + Exp_Cast *cast = data; + return known_type(env, cast->td); +} + ANN Type mk_primitive(const Env env, const m_str name, const m_uint size) { m_uint sz = SZ_INT; while(sz < size) sz += SZ_INT; @@ -204,7 +209,8 @@ ANN Type mk_primitive(const Env env, const m_str name, const m_uint size) { scan_prim_op2(env, t); if(size < SZ_INT) { prim_op(env, t, ":=>", opck_rassign, opem_bitset); - prim_op(env, t, "$", NULL, opem_bitcast); +// prim_op(env, t, "$", NULL, opem_bitcast); + prim_op(env, t, "$", opck_prim_cast, opem_bitcast); prim_implicit(env, t); } else if(size == SZ_INT) { prim_op(env, t, ":=>", opck_rassign, (opem)dummy_func); diff --git a/src/import/import_udef.c b/src/import/import_udef.c index 1da63f56..ac958b7e 100644 --- a/src/import/import_udef.c +++ b/src/import/import_udef.c @@ -29,7 +29,7 @@ ANN m_int gwi_union_ini(const Gwi gwi, const m_str name) { CHECK_BB(ck_ini(gwi, ck_udef)); gwi->ck->name = name; CHECK_BB(check_typename_def(gwi, gwi->ck)); - gwi->ck->mpv = new_mp_vector(gwi->gwion->mp, Union_Member, 0); + gwi->ck->mpv = new_mp_vector(gwi->gwion->mp, Variable, 0); return GW_OK; } @@ -38,9 +38,9 @@ ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, CHECK_BB(ck_ok(gwi, ck_udef)); DECL_OB(Type_Decl *, td, = str2td(gwi->gwion, type, gwi->loc)); DECL_OB(const Symbol, xid, = str2sym(gwi->gwion, name, gwi->loc)); - Union_Member um = { .td = td, .vd = { .xid = xid, .pos = gwi->loc } }; - mp_vector_add(gwi->gwion->mp, &gwi->ck->list, Union_Member, um); -// const Union_List l = new_union_list(gwi->gwion->mp, td, xid, gwi->loc); + Variable um = { .td = td, .vd = { .tag = MK_TAG(xid, gwi->loc) } }; + mp_vector_add(gwi->gwion->mp, &gwi->ck->list, Variable, um); +// const Variable_List l = new_variable_list(gwi->gwion->mp, td, xid, gwi->loc); // l->next = gwi->ck->list; // gwi->ck->list = l; return GW_OK; @@ -70,7 +70,7 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) { const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->ck->mpv, gwi->loc); gwi->ck->list = NULL; udef->flag = flag; - udef->xid = gwi->ck->sym; + udef->tag.sym = gwi->ck->sym; if (gwi->ck->tmpl) { udef->tmpl = gwi_tmpl(gwi); gwi->ck->tmpl = NULL; @@ -82,6 +82,6 @@ ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) { } ANN void ck_clean_udef(MemPool mp, ImportCK *ck) { - if (ck->mpv) free_mp_vector(mp, Union_Member, ck->mpv); + if (ck->mpv) free_mp_vector(mp, Variable, ck->mpv); if (ck->tmpl) free_id_list(mp, ck->tmpl); } diff --git a/src/lib/array.c b/src/lib/array.c index 8b0f0a69..589d12a3 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -144,11 +144,11 @@ static OP_CHECK(opck_array_at) { ERR_N(exp_self(bin)->pos, _("array depths do not match.")); } if (bin->rhs->exp_type == ae_exp_decl) { - Type_Decl *td = bin->rhs->d.exp_decl.td; + Type_Decl *td = bin->rhs->d.exp_decl.var.td; if (td->array && td->array->exp) ERR_N(exp_self(bin)->pos, _("do not provide array for 'xxx => declaration'.")); - SET_FLAG(bin->rhs->d.exp_decl.vd.value, late); + SET_FLAG(bin->rhs->d.exp_decl.var.vd.value, late); } bin->rhs->ref = bin->lhs; // bin->rhs->data = bin->lhs; @@ -264,7 +264,7 @@ static OP_CHECK(opck_array_cast) { Type parent = t; while(parent) { if (tflag(parent, tflag_cdef) && parent->info->cdef->base.ext && parent->info->cdef->base.ext->array) { - ERR_N(cast->td->pos, "can only cast to simple array types"); + ERR_N(cast->td->tag.loc, "can only cast to simple array types"); } parent = parent->info->parent; } @@ -816,10 +816,10 @@ static OP_CHECK(opck_array_scan) { const Type type = nspc_lookup_type1(base->info->value->from->owner, sym); if (type) return type; 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.ext = type2td(env->gwion, t_array, (loc_t){}); + cdef->base.tag.sym = sym; 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) {})} }; + 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; @@ -840,8 +840,8 @@ static OP_CHECK(opck_array_scan) { t->array_depth = base->array_depth + 1; t->info->base_type = array_base(base); set_tflag(t, tflag_cdef | tflag_tmpl); - - builtin_func(env->gwion, (Func)vector_at(&t->nspc->vtable, 0), get_rem(t)); + + builtin_func(env->gwion, (Func)vector_at(&t->nspc->vtable, 0), get_rem(t)); array_func(env, t, "insert", get_insert(t)); array_func(env, t, "size", vm_vector_size); array_func(env, t, "depth", vm_vector_depth); @@ -1193,7 +1193,7 @@ ANN static bool last_is_zero(Exp 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"); + ERR_B(td->tag.loc, "declaration of abstract type arrays needs lambda"); } else { if(args) gwerr_warn("array is empty", "no need to provide a lambda", diff --git a/src/lib/closure.c b/src/lib/closure.c index 2c1754a1..53b275a1 100644 --- a/src/lib/closure.c +++ b/src/lib/closure.c @@ -77,13 +77,13 @@ static OP_CHECK(opck_fptr_call) { } ANN Type upvalue_type(const Env env, Capture *cap) { - const Value v = nspc_lookup_value1(env->curr, cap->xid); - if(!v) ERR_O(cap->pos, _("non existing value")); // did_you_mean + const Value v = nspc_lookup_value1(env->curr, cap->tag.sym); + if(!v) ERR_O(cap->tag.loc, _("non existing value")); // did_you_mean if(cap->is_ref && not_upvalue(env, v)) - ERR_O(cap->pos, _("can't take ref of a scoped value")); + ERR_O(cap->tag.loc, _("can't take ref of a scoped value")); cap->orig = v; const Type base_type = !tflag(v->type, tflag_ref) ? v->type : (Type)vector_front(&v->type->info->tuple->contains); - return !cap->is_ref ? base_type : ref_type(env->gwion, base_type, cap->pos); + return !cap->is_ref ? base_type : ref_type(env->gwion, base_type, cap->tag.loc); } ANN void free_captures(const VM_Shred shred, m_bit *const caps) { @@ -119,17 +119,17 @@ static INSTR(fptr_assign) { ANN static m_bool emit_fptr_assign(const Emitter emit, const Type lhs, const Type rhs) { const Instr instr = emit_add_instr(emit, fptr_assign); - if(rhs->info->cdef && rhs->info->cdef->base.tmpl) + if(rhs->info->cdef && get_tmpl(rhs)) instr->m_val = SZ_INT * 2; if(!lhs->info->func) { const Func_Def fdef = lhs->info->func->def; const Capture_List captures = fdef->captures; if(captures) { uint32_t offset = 0; - Exp e = new_prim_id(emit->gwion->mp, fdef->base->xid, fdef->base->pos); // free me + Exp e = new_prim_id(emit->gwion->mp, fdef->base->tag.sym, fdef->base->tag.loc); // free me for(uint32_t i = 0; i < captures->len; i++) { Capture *const cap = mp_vector_at(captures, Capture, i); - e->d.prim.d.var = cap->xid; + e->d.prim.d.var = cap->tag.sym; e->d.prim.value = cap->orig; e->type = cap->orig->type; exp_setvar(e, cap->is_ref); @@ -171,7 +171,7 @@ ANN static void _fptr_tmpl_push(const Env env, const Func f) { 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); + nspc_add_type(env->curr, spec->tag.sym, t); } } @@ -205,7 +205,7 @@ ANN static m_bool fptr_args(const Env env, Func_Base *base[2]) { if (arg0->type && arg1->type) CHECK_BB(isa(arg0->type, arg1->type)); else if(!tmpl_base(base[0]->tmpl) && !tmpl_base(base[1]->tmpl)){ - Type_Decl *td[2] = {arg0->td, arg1->td}; + Type_Decl *td[2] = {arg0->var.td, arg1->var.td}; CHECK_BB(td_match(env, td)); } } @@ -246,12 +246,12 @@ ANN static inline m_bool fptr_rettype(const Env env, struct FptrInfo *info) { ANN static Type fptr_type(const Env env, struct FptrInfo *info) { const Value v = info->lhs->value_ref; const Nspc nspc = v->from->owner; - const m_str c = s_name(info->lhs->def->base->xid), + const m_str c = s_name(info->lhs->def->base->tag.sym), stmpl = !info->rhs->def->base->tmpl ? NULL : "template"; for (m_uint i = 0; i <= v->from->offset; ++i) { const Symbol sym = (!info->lhs->def->base->tmpl || i != 0) ? func_symbol(env, nspc->name, c, stmpl, i) - : info->lhs->def->base->xid; + : info->lhs->def->base->tag.sym; if (!is_class(env->gwion, info->lhs->value_ref->type)) { if (!(info->lhs = nspc_lookup_func1(nspc, sym))) { const Value v = nspc_lookup_value1(nspc, insert_symbol(c)); @@ -260,7 +260,7 @@ ANN static Type fptr_type(const Env env, struct FptrInfo *info) { } } else { DECL_OO(const Type, t, - = nspc_lookup_type1(nspc, info->lhs->def->base->xid)); + = nspc_lookup_type1(nspc, info->lhs->def->base->tag.sym)); info->lhs = actual_type(env->gwion, t)->info->func; } Type type = NULL; @@ -287,10 +287,10 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, // here move to arguments for(uint32_t i = 0; i < l->def->captures->len; i++) { Capture *cap = mp_vector_at(l->def->captures, Capture, i); - const Value v = nspc_lookup_value1(env->curr, cap->xid); - if(!v) ERR_B(cap->pos, _("unknown value in capture")); + const Value v = nspc_lookup_value1(env->curr, cap->tag.sym); + if(!v) ERR_B(cap->tag.loc, _("unknown value in capture")); DECL_OB(const Type, t, = upvalue_type(env, cap)); - cap->temp = new_value(env, t, s_name(cap->xid), cap->pos); + cap->temp = new_value(env, t, s_name(cap->tag.sym), cap->tag.loc); cap->orig = v; } } @@ -303,16 +303,17 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, .flag = tflag_scan0}; CHECK_BB(envset_pushv(&es, owner->info->value)); while(owner) { - if(owner->info->cdef->base.tmpl) - template_push_types(env, owner->info->cdef->base.tmpl); + const Tmpl *tmpl = get_tmpl(owner); + if(tmpl) + template_push_types(env, tmpl); owner = owner->info->value->from->owner_class; } if(bases) { for(uint32_t i = 0; i < bases->len; i++) { Arg *base = mp_vector_at(bases, Arg, i); Arg *arg = mp_vector_at(args, Arg, i); - DECL_OB(const Type, arg_type, = known_type(env, base->td)); - arg->td = type2td(env->gwion, arg_type, exp_self(l)->pos); + DECL_OB(const Type, arg_type, = known_type(env, base->var.td)); + arg->var.td = type2td(env->gwion, arg_type, exp_self(l)->pos); } } DECL_OB(const Type, ret_type, = known_type(env, fdef->base->td)); @@ -341,7 +342,7 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, } /*Type*/ owner = fdef->base->func->value_ref->from->owner_class->info->value->from->owner_class; while(owner) { - if(owner->info->cdef->base.tmpl) + if(get_tmpl(owner)) nspc_pop_type(env->gwion->mp, env->curr); owner = owner->info->value->from->owner_class; } @@ -350,8 +351,8 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, if(args) { for(uint32_t i = 0; i < bases->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); - free_value(arg->var_decl.value, env->gwion); - arg->var_decl.value = NULL; + free_value(arg->var.vd.value, env->gwion); + arg->var.vd.value = NULL; } } } @@ -383,7 +384,7 @@ ANN static Type partial2auto(const Env env, const Exp_Binary *bin) { set_fbflag(fdef->base, fbflag_lambda); const Type actual = fdef->base->func->value_ref->type; set_fbflag(fdef->base, fbflag_lambda); - Var_Decl vd = bin->rhs->d.exp_decl.vd; + Var_Decl vd = bin->rhs->d.exp_decl.var.vd; exp_setvar(bin->rhs, true); return vd.value->type = bin->rhs->type = bin->rhs->d.exp_decl.type = actual; } @@ -392,7 +393,7 @@ static OP_CHECK(opck_auto_fptr) { const Exp_Binary *bin = (Exp_Binary *)data; // we'll only deal with auto fptr declaration if (bin->rhs->exp_type != ae_exp_decl && - bin->rhs->d.exp_decl.td->xid != insert_symbol("auto")) + bin->rhs->d.exp_decl.var.td->tag.sym != insert_symbol("auto")) ERR_N(bin->lhs->pos, "invalid {G+}function{0} {+}:=>{0} {+G}function{0} assignment"); if (bin->lhs->exp_type == ae_exp_td) ERR_N(bin->lhs->pos, "can't use {/}type decl expressions{0} in auto function pointer declarations"); @@ -411,11 +412,11 @@ static OP_CHECK(opck_auto_fptr) { num_digit(bin->rhs->pos.first.column)]; sprintf(name, "generated@%s@%u:%u", env->curr->name, bin->rhs->pos.first.line, bin->rhs->pos.first.column); - fptr_def->base->xid = insert_symbol(name); + fptr_def->base->tag.sym = insert_symbol(name); const m_bool ret = traverse_fptr_def(env, fptr_def); const Type t = fptr_def->cdef->base.type; free_fptr_def(env->gwion->mp, fptr_def); - Var_Decl vd = bin->rhs->d.exp_decl.vd; + Var_Decl vd = bin->rhs->d.exp_decl.var.vd; vd.value->type = bin->rhs->type = bin->rhs->d.exp_decl.type = t; return ret > 0 ? t : env->gwion->type[et_error]; @@ -443,7 +444,7 @@ static OP_CHECK(opck_fptr_impl) { static OP_EMIT(opem_fptr_impl) { struct Implicit *impl = (struct Implicit *)data; - if(!impl->e->type->info->func->def->base->tmpl && impl->t->info->cdef->base.tmpl) { + if(!impl->e->type->info->func->def->base->tmpl && get_tmpl(impl->t)) { const Instr instr = (Instr)vector_back(&emit->code->instr); instr->opcode = eRegPushImm; instr->m_val = (m_uint)impl->e->type->info->func; @@ -510,14 +511,14 @@ static inline void op_impl_ensure_types(const Env env, const Func func) { safe_tflag(func->value_ref->from->owner_class, tflag_tmpl); if (owner_tmpl) template_push_types( - env, func->value_ref->from->owner_class->info->cdef->base.tmpl); + env, get_tmpl(func->value_ref->from->owner_class)); const bool func_tmpl = fflag(func, fflag_tmpl); if (func_tmpl) template_push_types(env, func->def->base->tmpl); Arg_List args = func->def->base->args; for(uint32_t i = 0; i < args->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); - if (!arg->type) arg->type = known_type(env, arg->td); + if (!arg->type) arg->type = known_type(env, arg->var.td); } if (!func->def->base->ret_type) func->def->base->ret_type = known_type(env, func->def->base->td); @@ -546,12 +547,12 @@ static OP_CHECK(opck_op_impl) { .d = {.prim = {.d = {.var = lhs_sym}, .prim_type = ae_prim_id}}, .exp_type = ae_exp_primary, .type = arg0->type, - .pos = arg0->td->pos}; + .pos = arg0->var.td->tag.loc}; struct Exp_ _rhs = { .d = {.prim = {.d = {.var = rhs_sym}, .prim_type = ae_prim_id}}, .exp_type = ae_exp_primary, .type = arg1->type, - .pos = arg1->td->pos}; + .pos = arg1->var.td->tag.loc}; struct Exp_ self = {.pos = impl->e->pos}; self.d.exp_binary.lhs = &_lhs; self.d.exp_binary.rhs = &_rhs; @@ -586,10 +587,10 @@ static OP_CHECK(opck_op_impl) { } } const Arg_List args = cpy_arg_list(env->gwion->mp, func->def->base->args); - Arg *larg0 = (Arg*)(args->ptr); - Arg *larg1 = (Arg*)(args->ptr + sizeof(Arg)); - larg0->var_decl.xid = lhs_sym; - larg1->var_decl.xid = rhs_sym; + Arg *larg0 = mp_vector_at(args, Arg, 0); + Arg *larg1 = mp_vector_at(args, Arg, 1); + larg0->var.vd.tag.sym = lhs_sym; + larg1->var.vd.tag.sym = rhs_sym; Func_Base *base = new_func_base(env->gwion->mp, type2td(env->gwion, t, impl->e->pos), impl->e->d.prim.d.var, args, ae_flag_none, impl->e->pos); @@ -601,9 +602,9 @@ static OP_CHECK(opck_op_impl) { free_mp_vector(env->gwion->mp, struct ScopeEffect, eff); } const Exp lhs = - new_prim_id(env->gwion->mp, larg0->var_decl.xid, impl->e->pos); + new_prim_id(env->gwion->mp, larg0->var.vd.tag.sym, impl->e->pos); const Exp rhs = - new_prim_id(env->gwion->mp, larg1->var_decl.xid, impl->e->pos); + new_prim_id(env->gwion->mp, larg1->var.vd.tag.sym, impl->e->pos); const Exp bin = new_exp_binary(env->gwion->mp, lhs, impl->e->d.prim.d.var, rhs, impl->e->pos); Stmt_List code = new_mp_vector(env->gwion->mp, struct Stmt_, 1); @@ -613,7 +614,7 @@ static OP_CHECK(opck_op_impl) { .pos = impl->e->pos })); const Func_Def def = new_func_def(env->gwion->mp, base, code); - def->base->xid = impl->e->d.prim.d.var; + def->base->tag.sym = impl->e->d.prim.d.var; // use envset // or better, some function with envset and traverse const m_uint scope = env_push(env, NULL, opi.nspc); @@ -673,17 +674,17 @@ ANN static bool is_base(const Env env, const Type_List tl) { static OP_CHECK(opck_closure_scan) { struct TemplateScan *ts = (struct TemplateScan *)data; struct tmpl_info info = { - .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list}; + .base = ts->t, .td = ts->td, .list = get_tmpl(ts->t)->list}; const Type exists = tmpl_exists(env, &info); if (exists) return exists != env->gwion->type[et_error] ? exists : NULL; const Func_Base *base = closure_def(ts->t)->base; const Arg_List args = base->args ? cpy_arg_list(env->gwion->mp, base->args) : NULL; - Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, base->td), info.name, args, ae_flag_none, base->pos); + Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, base->td), info.name, args, ae_flag_none, base->tag.loc); fbase->tmpl = cpy_tmpl(env->gwion->mp, base->tmpl); if(!is_base(env, ts->td->types)) fbase->tmpl->call = cpy_type_list(env->gwion->mp, ts->td->types); const Fptr_Def fdef = new_fptr_def(env->gwion->mp, cpy_func_base(env->gwion->mp, fbase)); - fdef->base->xid = info.name; + fdef->base->tag.sym = info.name; struct EnvSet es = {.env = env, .data = env, .func = (_exp_func)traverse_cdef, diff --git a/src/lib/dict.c b/src/lib/dict.c index d8e9f250..6875581e 100644 --- a/src/lib/dict.c +++ b/src/lib/dict.c @@ -17,6 +17,7 @@ #include "array.h" #include "looper.h" #include "dict.h" +#include "template.h" #define HMAP_MIN_CAP 32 #define HMAP_MAX_LOAD 0.75 @@ -554,19 +555,20 @@ static OP_CHECK(opck_dict_each_val) { static OP_CHECK(opck_dict_scan) { struct TemplateScan *ts = (struct TemplateScan *)data; - if(ts->t->info->cdef->base.tmpl->call) return ts->t; + const Tmpl *tmpl = get_tmpl(ts->t); + if(tmpl->call) return ts->t; struct tmpl_info info = { - .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list}; + .base = ts->t, .td = ts->td, .list = tmpl->list}; 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, 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"); + ERR_N(ts->td->tag.loc, "can't use Ref:[] in dicts"); const Class_Def cdef = cpy_class_def(env->gwion->mp, env->gwion->type[et_dict]->info->cdef); - cdef->base.ext = type2td(env->gwion, env->gwion->type[et_dict], (loc_t) {}); - cdef->base.xid = info.name; + cdef->base.ext = type2td(env->gwion, env->gwion->type[et_dict], (loc_t){}); + cdef->base.tag.sym = info.name; cdef->base.tmpl->call = cpy_type_list(env->gwion->mp, info.td->types); const bool is_global = tmpl_global(env, ts->td->types); diff --git a/src/lib/engine.c b/src/lib/engine.c index 8148b7ac..0345d290 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -138,6 +138,12 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(gwi_oper_emi(gwi, opem_object_dot)) GWI_BB(gwi_oper_end(gwi, ".", NULL)) + // allow const generics in functions + GWI_BB(gwi_oper_ini(gwi, "function", (m_str)OP_ANY_TYPE, NULL)) + GWI_BB(gwi_oper_add(gwi, opck_object_dot)) + GWI_BB(gwi_oper_emi(gwi, opem_object_dot)) + GWI_BB(gwi_oper_end(gwi, ".", NULL)) + GWI_BB(gwimport_class(gwi)) gwidoc(gwi, "allow static access."); diff --git a/src/lib/instr.c b/src/lib/instr.c index 2b9e4009..de050607 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -16,10 +16,10 @@ ANN static Func_Def traverse_tmpl(const Emitter emit, Func_Def fdef, Func_Def fbase, const Nspc nspc) { const Env env = emit->env; - const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid), + const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->tag.sym), "template", fbase->vt_index); DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) - ?: nspc_lookup_value0(nspc, fdef->base->xid)); + ?: nspc_lookup_value0(nspc, fdef->base->tag.sym)); const f_xfun xfun = v->d.func_ref->def->d.dl_func_ptr; if (vflag(v, vflag_builtin)) v->d.func_ref->def->d.dl_func_ptr = NULL; // why diff --git a/src/lib/object.c b/src/lib/object.c index 77cb458e..fa892fc6 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -101,7 +101,7 @@ static ID_CHECK(opck_this) { ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions...")) if (!exp_getuse(exp_self(prim)) && - !strcmp(s_name(env->func->def->base->xid), "@gack")) + !strcmp(s_name(env->func->def->base->tag.sym), "@gack")) return get_gack(env->class_def->info->parent); // get_gack ? } return env->class_def; diff --git a/src/lib/object_op.c b/src/lib/object_op.c index f2fcc5b4..a359f0e6 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -1,4 +1,3 @@ - #include "gwion_util.h" #include "gwion_ast.h" #include "gwion_env.h" @@ -32,7 +31,7 @@ static OP_CHECK(opck_object_at) { if (opck_rassign(env, data) == env->gwion->type[et_error]) return env->gwion->type[et_error]; if (bin->rhs->exp_type == ae_exp_decl) { - Var_Decl vd = bin->rhs->d.exp_decl.vd; + Var_Decl vd = bin->rhs->d.exp_decl.var.vd; SET_FLAG(vd.value, late); } exp_setvar(bin->rhs, 1); @@ -46,14 +45,14 @@ static OP_CHECK(opck_object_instance) { Exp rhs = bin->rhs; if (rhs->exp_type != ae_exp_decl) return NULL; - if (rhs->d.exp_decl.td->array) + if (rhs->d.exp_decl.var.td->array) return NULL; Exp lhs = bin->lhs; Exp e = exp_self(bin); Exp_Decl *const decl = &e->d.exp_decl; e->exp_type = ae_exp_decl; - decl->td = cpy_type_decl(env->gwion->mp, rhs->d.exp_decl.td); - decl->vd = rhs->d.exp_decl.vd; + decl->var.td = cpy_type_decl(env->gwion->mp, rhs->d.exp_decl.var.td); + decl->var.vd = rhs->d.exp_decl.var.vd; decl->type = rhs->type; decl->args = lhs; free_exp(env->gwion->mp, rhs); @@ -94,7 +93,8 @@ ANN /*static*/ Type scan_class(const Env env, const Type t, static OP_CHECK(opck_struct_scan) { struct TemplateScan *ts = (struct TemplateScan *)data; - if(ts->t->info->cdef->base.tmpl->call) return ts->t; + const Tmpl *tmpl = get_tmpl(ts->t); + if(tmpl->call) return ts->t; return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_error]; } @@ -119,7 +119,7 @@ ANN static void emit_dottmpl(const Emitter emit, const Func f) { struct dottmpl_ *dt = mp_malloc(emit->gwion->mp, dottmpl); dt->nspc = emit->env->curr; dt->type = emit->env->class_def; - dt->tmpl_name = tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->pos); + dt->tmpl_name = tl2str(emit->gwion, f->def->base->tmpl->call, f->def->base->tag.loc); instr->m_val2 = (m_uint)dt; } @@ -279,7 +279,7 @@ ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) { const Class_Def cdef = new_class_def( env->gwion->mp, c->flag, info->name, c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL, - NULL, c->pos); + NULL, c->base.tag.loc); if(c->body) cdef->body = cpy_ast(env->gwion->mp, c->body); cdef->cflag = c->cflag; cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->td->types); @@ -295,8 +295,8 @@ ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) { ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) { const Union_Def u = info->base->info->udef; const Union_Def udef = new_union_def( - env->gwion->mp, cpy_union_list(env->gwion->mp, u->l), u->pos); - udef->xid = info->name; + env->gwion->mp, cpy_variable_list(env->gwion->mp, u->l), u->tag.loc); + udef->tag.sym = info->name; udef->tmpl = mk_tmpl(env, u->tmpl, info->td->types); // resolve the template here if (GET_FLAG(info->base, global)) SET_FLAG(udef, global); @@ -320,7 +320,7 @@ ANN static Type _scan_class(const Env env, struct tmpl_info *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}; + .base = t, .td = td, .list = get_tmpl(t)->list}; const Type exists = tmpl_exists(env, &info); if (exists) return exists != env->gwion->type[et_error] ? exists : NULL; struct EnvSet es = {.env = env, diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 67fdd2ff..7c869ebb 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -128,9 +128,9 @@ OP_CHECK(opck_new) { } CHECK_BN(ensure_traverse(env, t)); if (type_ref(t)) - ERR_N(unary->ctor.td->pos, _("can't use 'new' on ref type '%s'\n"), t->name); + ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on ref type '%s'\n"), t->name); if (tflag(t, tflag_infer)) - ERR_N(unary->ctor.td->pos, _("can't use 'new' on '%s'\n"), + ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on '%s'\n"), t->name); if (array) { CHECK_BN(check_subscripts(env, array, 1)); @@ -150,7 +150,7 @@ OP_CHECK(opck_new) { } if (GET_FLAG(t, abstract) && (!array || (array->exp && exp_is_zero(array->exp)))) - ERR_N(unary->ctor.td->pos, _("can't use 'new' on abstract type '%s'\n"), + ERR_N(unary->ctor.td->tag.loc, _("can't use 'new' on abstract type '%s'\n"), t->name); if (isa(t, env->gwion->type[et_object]) < 0) ERR_N(exp_self(unary)->pos, _("can't use 'new' on non-object types...\n")); diff --git a/src/lib/ref.c b/src/lib/ref.c index 3a0b8076..8b6f7c2a 100644 --- a/src/lib/ref.c +++ b/src/lib/ref.c @@ -146,7 +146,7 @@ ANN static void ref2ref(Env env, const Type lhs, const Type rhs) { static OP_CHECK(opck_ref_scan) { struct TemplateScan *ts = (struct TemplateScan *)data; struct tmpl_info info = { - .base = ts->t, .td = ts->td, .list = ts->t->info->cdef->base.tmpl->list}; + .base = ts->t, .td = ts->td, .list = get_tmpl(ts->t)->list}; const Type exists = tmpl_exists(env, &info); if (exists) return exists != env->gwion->type[et_error] ? exists : NULL; const TmplArg arg = *mp_vector_at(ts->td->types, TmplArg, 0); diff --git a/src/lib/tmpl_info.c b/src/lib/tmpl_info.c index 3033d5c3..a1d387a6 100644 --- a/src/lib/tmpl_info.c +++ b/src/lib/tmpl_info.c @@ -43,11 +43,11 @@ ANN static inline size_t tmpl_set(struct tmpl_info *info, const m_str str) { ANN static ssize_t template_size(const Env env, struct tmpl_info *info) { DECL_OB(const m_str, str, - = tl2str(env->gwion, info->td->types, info->td->pos)); + = tl2str(env->gwion, info->td->types, info->td->tag.loc)); const size_t tmpl_sz = tmpl_set(info, str); const m_str base = !is_func(env->gwion, info->base) ? mstrdup(env->gwion->mp, info->base->name) - : type2str(env->gwion, info->base, info->td->pos); + : type2str(env->gwion, info->base, info->td->tag.loc); return tmpl_sz + tmpl_set(info, base) + 4; } @@ -91,7 +91,7 @@ ANN static Type _tmpl_exists(const Env env, const Symbol name) { ANN Type tmpl_exists(const Env env, struct tmpl_info *const info) { if (template_match(info->list, info->td->types) < 0) // invalid template - ERR_N(info->td->pos, _("invalid template types number")); + ERR_N(info->td->tag.loc, _("invalid template types number")); if (!info->name) info->name = template_id(env, info); return _tmpl_exists(env, info->name); diff --git a/src/lib/xork.c b/src/lib/xork.c index b65ed401..c02f8b94 100644 --- a/src/lib/xork.c +++ b/src/lib/xork.c @@ -42,7 +42,7 @@ static OP_CHECK(opck_spork) { for(uint32_t i = 0; i < unary->captures->len; i++) { Capture *const cap = mp_vector_at(unary->captures, Capture, i); DECL_OO(const Type, t, = upvalue_type(env, cap)); - cap->temp = new_value(env, t, s_name(cap->xid), cap->pos); + cap->temp = new_value(env, t, s_name(cap->tag.sym), cap->tag.loc); cap->temp->from->offset = offset; offset += cap->temp->type->size; } @@ -55,14 +55,14 @@ static OP_CHECK(opck_spork) { if(unary->captures) { for(uint32_t i = 0; i < unary->captures->len; i++) { Capture *const cap = mp_vector_at(unary->captures, Capture, i); - valid_value(env, cap->xid, cap->temp); + valid_value(env, cap->tag.sym, cap->temp); } } const Func f = env->func; struct Value_ value = { .type = env->gwion->type[et_function]}; if(env->class_def) set_vflag(&value, vflag_member); - struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = &upvalues, .fbflag = fbflag_lambda, .pos = exp_self(unary)->pos}; + struct Func_Base_ fbase = { .tag=MK_TAG(insert_symbol("in spork"), exp_self(unary)->pos), .values = &upvalues, .fbflag = fbflag_lambda}; struct Func_Def_ fdef = { .base = &fbase}; struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value}; env->func = &func; diff --git a/src/parse/check.c b/src/parse/check.c index 3a35d7e1..79858f7f 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -57,9 +57,9 @@ ANN m_bool check_subscripts(Env env, const Array_Sub array, ANN static inline m_bool check_exp_decl_parent(const Env env, const Var_Decl *var) { - const Value value = find_value(env->class_def->info->parent, var->xid); + const Value value = find_value(env->class_def->info->parent, var->tag.sym); if (value) { - env_err(env, var->pos, _("Value defined in parent class")); + env_err(env, var->tag.loc, _("Value defined in parent class")); defined_here(value); return GW_ERROR; } @@ -99,7 +99,7 @@ ANN static void var_effects(const Env env, const Type t, const Symbol sym, const ANN static m_bool check_var(const Env env, const Var_Decl *var) { if (env->class_def && !env->scope->depth && env->class_def->info->parent) CHECK_BB(check_exp_decl_parent(env, var)); - var_effects(env, var->value->type, insert_symbol("@ctor"), var->pos); + var_effects(env, var->value->type, insert_symbol("@ctor"), var->tag.loc); return GW_OK; } @@ -117,15 +117,15 @@ ANN static m_bool check_var_td(const Env env, const Var_Decl *var, } ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) { - const Var_Decl *vd = &decl->vd; + const Var_Decl *vd = &decl->var.vd; CHECK_BB(check_var(env, vd)); - CHECK_BB(check_var_td(env, vd, decl->td)); - if (decl->td->array && decl->td->array->exp) { - CHECK_BB(check_subscripts(env, decl->td->array, true)); + CHECK_BB(check_var_td(env, vd, decl->var.td)); + if (decl->var.td->array && decl->var.td->array->exp) { + CHECK_BB(check_subscripts(env, decl->var.td->array, true)); if (GET_FLAG(array_base(decl->type), abstract)) - CHECK_BB(check_array_instance(env, decl->td, decl->args)); + CHECK_BB(check_array_instance(env, decl->var.td, decl->args)); } - valid_value(env, vd->xid, vd->value); + valid_value(env, vd->tag.sym, vd->value); // set_vflag(var->value, vflag_used)); return GW_OK; } @@ -161,36 +161,36 @@ ANN static inline m_bool inferable(const Env env, const Type t, } ANN Type check_exp_decl(const Env env, Exp_Decl *const decl) { - if (decl->td->array && decl->td->array->exp) - CHECK_OO(check_exp(env, decl->td->array->exp)); + if (decl->var.td->array && decl->var.td->array->exp) + CHECK_OO(check_exp(env, decl->var.td->array->exp)); if (decl->args) { - const Exp e = new_exp_unary2(env->gwion->mp, insert_symbol("new"), cpy_type_decl(env->gwion->mp, decl->td), decl->args, decl->td->pos); + const Exp e = new_exp_unary2(env->gwion->mp, insert_symbol("new"), cpy_type_decl(env->gwion->mp, decl->var.td), decl->args, decl->var.td->tag.loc); CHECK_OO(check_exp(env, e)); decl->args = e; e->ref = exp_self(decl); } - if (decl->td->xid == insert_symbol("auto")) { // should be better + if (decl->var.td->tag.sym == insert_symbol("auto")) { // should be better CHECK_BO(scan1_exp(env, exp_self(decl))); CHECK_BO(scan2_exp(env, exp_self(decl))); } - if (!decl->type) ERR_O(decl->td->pos, _("can't find type")); + if (!decl->type) ERR_O(decl->var.td->tag.loc, _("can't find type")); { CHECK_BO(ensure_check(env, decl->type)); - if(inferable(env, decl->type, decl->td->pos) < 0) { + if(inferable(env, decl->type, decl->var.td->tag.loc) < 0) { if(!tflag(decl->type, tflag_check) && decl->type->ref > 1 && env->class_def && !env->scope->depth) type_remref(decl->type, env->gwion); return NULL; } } - const m_bool global = GET_FLAG(decl->td, global); + const m_bool global = GET_FLAG(decl->var.td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); const m_bool ret = check_decl(env, decl); if (global) { env_pop(env, scope); - set_vflag(decl->vd.value, vflag_direct); + set_vflag(decl->var.vd.value, vflag_direct); } env_weight(env, 1 + isa(decl->type, env->gwion->type[et_object]) > 0); - return ret > 0 ? decl->vd.value->type : NULL; + return ret > 0 ? decl->var.vd.value->type : NULL; } ANN static m_bool check_collection(const Env env, Type type, const Exp e, @@ -287,6 +287,18 @@ ANN m_bool not_from_owner_class(const Env env, const Type t, const Value v, ANN static inline Value get_value(const Env env, const Symbol sym) { const Value value = nspc_lookup_value1(env->curr, sym); if(value) { +if(value->from->owner_class && is_func(env->gwion, value->from->owner_class)) { +/* + +set_tflag(value->from->owner_class, tflag_check); +set_tflag(value->from->owner_class, tflag_scan0); +set_tflag(value->from->owner_class, tflag_scan1); +set_tflag(value->from->owner_class, tflag_scan2); +set_tflag(value->from->owner_class, tflag_check); +*/ +return value; +} + if (!value->from->owner_class || isa(env->class_def, value->from->owner_class) > 0) return value; if(env->class_def) { @@ -364,6 +376,8 @@ ANN static Type prim_owned(const Env env, const Symbol *data) { const Value v = exp->d.prim.value; if(is_class(env->gwion, v->type) && env->class_def == v->type->info->base_type) // write it better return v->type->info->base_type; +// if(v->from->owner_class && is_func(env->gwion, v->from->owner_class)) +// return v->type; const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name; const Exp base = new_prim_id(env->gwion->mp, insert_symbol(name), prim_pos(data)); @@ -529,7 +543,7 @@ static ANN Type check_exp_slice(const Env env, const Exp_Slice *range) { // without the mangling ANN static inline Type type_list_base_func(const Type type) { const Nspc owner = type->info->value->from->owner; - const Symbol xid = type->info->func->def->base->xid; + const Symbol xid = type->info->func->def->base->tag.sym; return nspc_lookup_type0(owner, xid); } @@ -545,8 +559,9 @@ ANN static Type_Decl* mk_td(const Env env, Type_Decl *td, return type2td(env->gwion, t, pos); } -ANN static Type tmpl_arg_match(const Env env, const Symbol xid, const Symbol tgt, const Type t) { +ANN static Type tmplarg_match(const Env env, const Symbol xid, const Symbol tgt, const Type t) { if (xid == tgt) return t; +// Tmpl *tmpl = get_tmpl(t);//tflag(t, tflag_cdef) ? t->info->cdef->base.tmpl Tmpl *tmpl = tflag(t, tflag_cdef) ? t->info->cdef->base.tmpl : tflag(t, tflag_udef) ? t->info->udef->tmpl : NULL; @@ -554,8 +569,8 @@ ANN static Type tmpl_arg_match(const Env env, const Symbol xid, const Symbol tgt const uint32_t len = mp_vector_len(tmpl->list); for(uint32_t i = 0; i < len; i++) { Specialized *spec = mp_vector_at(tmpl->list, Specialized, i); - const Type base = nspc_lookup_type1(t->nspc, spec->xid); - const Type t = tmpl_arg_match(env, xid, spec->xid, base); + const Type base = nspc_lookup_type1(t->nspc, spec->tag.sym); + const Type t = tmplarg_match(env, xid, spec->tag.sym, base); if(t) return t; } return NULL; @@ -587,7 +602,7 @@ static Func find_func_match_actual(const Env env, const Func f, const Exp exp, if (arg->type == env->gwion->type[et_auto]) { const Type owner = func->value_ref->from->owner_class; if (owner) CHECK_BO(template_push(env, owner)); - arg->type = known_type(env, arg->td); + arg->type = known_type(env, arg->var.td); if (owner) nspc_pop_type(env->gwion->mp, env->curr); CHECK_OO(arg->type); } @@ -616,7 +631,7 @@ ANN static Func call2ufcs(const Env env, Exp_Call *call, const Value v) { } ANN static Func ufcs(const Env env, const Func up, Exp_Call *const call) { - const Value v = nspc_lookup_value1(env->curr, up->def->base->xid); + const Value v = nspc_lookup_value1(env->curr, up->def->base->tag.sym); if (v && is_func(env->gwion, v->type) && !v->from->owner_class) // is_callable return call2ufcs(env, call, v); return NULL; @@ -657,10 +672,10 @@ ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) { ANN static m_bool check_func_args(const Env env, Arg_List args) { for(uint32_t i = 0; i < args->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); - const Var_Decl *decl = &arg->var_decl; + const Var_Decl *decl = &arg->var.vd; const Value v = decl->value; - if(decl->xid) CHECK_BB(already_defined(env, decl->xid, decl->pos)); - valid_value(env, decl->xid, v); + if(decl->tag.sym) CHECK_BB(already_defined(env, decl->tag.sym, decl->tag.loc)); + valid_value(env, decl->tag.sym, v); } return GW_OK; } @@ -753,16 +768,17 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp, const uint32_t len = sl->len - spread; Type_List tl = new_mp_vector(env->gwion->mp, TmplArg, len); m_uint args_number = 0; - +// infer template types from args +// should not work with const generic if(exp->other) { for(uint32_t i = 0; i < len; i++) { Specialized *spec = mp_vector_at(sl, Specialized, i); - if (tmpl_arg_match(env, spec->xid, fdef->base->td->xid, fdef->base->ret_type)) { + if (tmplarg_match(env, spec->tag.sym, fdef->base->td->tag.sym, fdef->base->ret_type)) { CHECK_OO(check_exp(env, exp->other)); if(!is_func(env->gwion, exp->other->type)) { TmplArg targ = { .type = tmplarg_td, - .d = { .td = type2td(env->gwion, exp->other->type, fdef->base->td->pos) } + .d = { .td = type2td(env->gwion, exp->other->type, fdef->base->td->tag.loc) } }; mp_vector_set(tl, TmplArg, 0, targ); } else { @@ -772,7 +788,7 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp, Arg *arg = mp_vector_at(func->def->base->args, Arg, 0); TmplArg targ = { .type = tmplarg_td, - .d = { .td = cpy_type_decl(env->gwion->mp, arg->td) } + .d = { .td = cpy_type_decl(env->gwion->mp, arg->var.td) } }; mp_vector_set(tl, TmplArg, 0, targ); break; @@ -792,10 +808,10 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp, uint32_t count = 0; 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)) { + if (tmplarg_match(env, spec->tag.sym, arg->var.td->tag.sym, template_arg->type)) { TmplArg targ = { .type = tmplarg_td, - .d = { .td = mk_td(env, arg->td, template_arg->type, fdef->base->pos) } + .d = { .td = mk_td(env, arg->var.td, template_arg->type, fdef->base->tag.loc) } }; mp_vector_set(tl, TmplArg, args_number, targ); ++args_number; @@ -875,12 +891,12 @@ ANN static Exp check_lambda_captures(const Env env, const Func_Def fdef) { if(args) free_exp(env->gwion->mp, args); return NULL; } - Arg arg = { - .td = type2td(env->gwion, t, cap->pos), - .var_decl = { .xid = cap->xid } - }; + Arg arg = { .var = MK_VAR( + type2td(env->gwion, t, cap->tag.loc), + (Var_Decl){ .tag = MK_TAG(cap->tag.sym, cap->tag.loc) } + )}; mp_vector_add(env->gwion->mp, &fdef->base->args, Arg, arg); - const Exp exp = new_prim_id(env->gwion->mp, cap->xid, cap->pos); + const Exp exp = new_prim_id(env->gwion->mp, cap->tag.sym, cap->tag.loc); if(args) tmp = tmp->next = exp; else args = tmp = exp; } @@ -1078,7 +1094,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) { CHECK_OO(check_exp(env, bin->rhs)); if (is_auto) { assert(bin->rhs->type == bin->lhs->type); - set_vflag(bin->rhs->d.exp_decl.vd.value, vflag_assigned); + set_vflag(bin->rhs->d.exp_decl.var.vd.value, vflag_assigned); } struct Op_Import opi = {.op = bin->op, .lhs = bin->lhs->type, @@ -1089,7 +1105,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) { exp_setuse(bin->rhs, 1); const Type ret = op_check(env, &opi); if (!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary) - bin->rhs->d.exp_decl.vd.value->type = env->gwion->type[et_auto]; + bin->rhs->d.exp_decl.var.vd.value->type = env->gwion->type[et_auto]; return ret; } @@ -1126,7 +1142,7 @@ ANN static m_bool predefined_call(const Env env, const Type t, free_mstr(env->gwion->mp, str); if (tflag(t, tflag_typedef)) { gwerr_secondary("from definition:", env->name, - t->info->func->def->base->pos); + t->info->func->def->base->tag.loc); } return GW_ERROR; } @@ -1259,13 +1275,13 @@ ANN static Type check_exp_dot(const Env env, Exp_Dot *member) { ANN m_bool check_type_def(const Env env, const Type_Def tdef) { if (tdef->when) { set_tflag(tdef->type, tflag_contract); - struct Var_Decl_ decl = { .xid = insert_symbol("self"), .pos = tdef->when->pos }; + struct Var_Decl_ decl = { .tag = MK_TAG(insert_symbol("self"), tdef->when->pos) }; Type_Decl *td = cpy_type_decl(env->gwion->mp, tdef->ext); Arg_List args = new_mp_vector(env->gwion->mp, Arg, 1); - mp_vector_set(args, Arg, 0, ((Arg) { .td = td, .var_decl = decl })); + mp_vector_set(args, Arg, 0, ((Arg) { .var = MK_VAR(td, decl)})); Func_Base *fb = new_func_base( - env->gwion->mp, type2td(env->gwion, tdef->type, tdef->pos), - insert_symbol("@implicit"), args, ae_flag_none, tdef->pos); + env->gwion->mp, type2td(env->gwion, tdef->type, tdef->tag.loc), + insert_symbol("@implicit"), args, ae_flag_none, tdef->tag.loc); set_fbflag(fb, fbflag_op); const Exp helper = new_prim_id(env->gwion->mp, insert_symbol("@predicate"), tdef->when->pos); @@ -1293,14 +1309,14 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) { "use `{/+}bool{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); + gwerr_secondary(from, env->name, tdef->tag.loc); env_set_error(env, true); return GW_ERROR; } // 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"), when->pos); - ret_id->d.prim.value = new_value(env, tdef->type, "self", tdef->pos); + ret_id->d.prim.value = new_value(env, tdef->type, "self", tdef->tag.loc); struct Stmt_ ret = { .stmt_type = ae_stmt_return, .d = { .stmt_exp = { .val = ret_id }}, .pos = when->pos @@ -1348,7 +1364,7 @@ ANN m_bool check_enum_def(const Env env, const Enum_Def edef) { ID_List list = edef->list; for(uint32_t i = 0; i < list->len; i++) { EnumValue ev= *mp_vector_at(list, EnumValue, i); - decl_static(env, nspc_lookup_value0(env->curr, ev.xid)); + decl_static(env, nspc_lookup_value0(env->curr, ev.tag.sym)); } env_pop(env, scope); return GW_OK; @@ -1386,8 +1402,8 @@ ANN static inline m_bool for_empty(const Env env, const Stmt_For stmt) { } ANN static void check_idx(const Env env, const Type base, struct EachIdx_ *const idx) { - idx->v = new_value(env, base, s_name(idx->sym), idx->pos); - valid_value(env, idx->sym, idx->v); + idx->v = new_value(env, base, s_name(idx->tag.sym), idx->tag.loc); + valid_value(env, idx->tag.sym, idx->v); SET_FLAG(idx->v, const); } @@ -1398,7 +1414,7 @@ ANN static m_bool check_each_idx(const Env env, const Exp exp, struct EachIdx_ * .lhs = exp->type, .op = insert_symbol("@each_idx"), .data = (m_uint)exp, - .pos = idx->pos + .pos = idx->tag.loc }; DECL_OB(const Type, t, = op_check(env, &opi)); check_idx(env, t, idx); @@ -1422,8 +1438,8 @@ ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) { if (stmt->idx) CHECK_BB(check_each_idx(env, stmt->exp, stmt->idx)); DECL_OB(const Type, ret, = check_each_val(env, stmt->exp)); - stmt->v = new_value(env, ret, s_name(stmt->sym), stmt->vpos); - valid_value(env, stmt->sym, stmt->v); + stmt->v = new_value(env, ret, s_name(stmt->tag.sym), stmt->tag.loc); + valid_value(env, stmt->tag.sym, stmt->v); return check_conts(env, stmt_self(stmt), stmt->body); } @@ -1487,7 +1503,7 @@ ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) { ret_type->name); if (stmt->val) { Arg *arg = mp_vector_at(env->func->def->base->args, Arg, 0); - if (env->func->def->base->xid == insert_symbol("@implicit") && + if (env->func->def->base->tag.sym == insert_symbol("@implicit") && ret_type == arg->type) ERR_B(stmt_self(stmt)->pos, _("can't use implicit casting while defining it")) @@ -1522,7 +1538,7 @@ ANN static m_bool check_stmt_exp(const Env env, const Stmt_Exp stmt) { if(stmt->val) { CHECK_OB(check_exp(env, stmt->val)); if(stmt->val->exp_type == ae_exp_lambda) { - const loc_t loc = stmt->val->d.exp_lambda.def->base->pos; + const loc_t loc = stmt->val->d.exp_lambda.def->base->tag.loc; env_warn(env, loc, _("Partial application not used")); } } @@ -1640,8 +1656,8 @@ ANN static inline m_bool check_handler_list(const restrict Env env, ANN static inline bool find_handler(const Handler_List handlers, const Symbol xid) { for(uint32_t i = 0; i < handlers->len; i++) { Handler *handler = mp_vector_at(handlers, Handler, i); - if(xid == handler->xid) return true; - if(!handler->xid) return true; + if(xid == handler->tag.sym) return true; + if(!handler->tag.sym) return true; } return false; } @@ -1729,13 +1745,13 @@ ANN m_bool check_stmt_list(const Env env, Stmt_List l) { ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) { if (GET_FLAG(parent->def->base, final)) - ERR_B(fdef->base->td->pos, _("can't override final function '%s'\n"), + ERR_B(fdef->base->td->tag.loc, _("can't override final function '%s'\n"), parent->name) if (GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) { const m_str c_name = fdef->base->func->value_ref->from->owner_class->name; const m_str p_name = parent->value_ref->from->owner_class->name; - const m_str f_name = s_name(fdef->base->xid); - ERR_B(fdef->base->td->pos, + const m_str f_name = s_name(fdef->base->tag.sym); + ERR_B(fdef->base->td->tag.loc, _("function '%s.%s' ressembles '%s.%s' but cannot override...\n" " ...(reason: '%s.%s' is declared as 'static')"), c_name, f_name, p_name, c_name, @@ -1772,7 +1788,7 @@ ANN static m_bool check_parent_match(const Env env, const Func_Def fdef) { const Type parent = env->class_def->info->parent; if (!env->curr->vtable.ptr) vector_init(&env->curr->vtable); if (parent) { - const Value v = find_value(parent, fdef->base->xid); + const Value v = find_value(parent, fdef->base->tag.sym); if (v && is_func(env->gwion, v->type)) { const m_bool match = parent_match_actual(env, fdef, v->d.func_ref); if (match) return match; @@ -1786,7 +1802,7 @@ ANN static m_bool check_parent_match(const Env env, const Func_Def fdef) { ANN static inline Func get_overload(const Env env, const Func_Def fdef, const m_uint i) { const Symbol sym = - func_symbol(env, env->curr->name, s_name(fdef->base->xid), NULL, i); + func_symbol(env, env->curr->name, s_name(fdef->base->tag.sym), NULL, i); return nspc_lookup_func1(env->curr, sym); } @@ -1803,10 +1819,10 @@ ANN static m_bool check_func_overload(const Env env, const Func_Def fdef) { fbflag(f2->def->base, fbflag_unary) && fbflag(f1->def->base, fbflag_postfix) == fbflag(f2->def->base, fbflag_postfix)) - ERR_B(f2->def->base->pos, + ERR_B(f2->def->base->tag.loc, _("global function '%s' already defined" " for those arguments"), - s_name(fdef->base->xid)) + s_name(fdef->base->tag.sym)) } } return GW_OK; @@ -1827,13 +1843,13 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef, const Func func = fdef->base->func; if (env->class_def && env->class_def->info->parent) { const Value override = - find_value(env->class_def->info->parent, fdef->base->xid); + find_value(env->class_def->info->parent, fdef->base->tag.sym); if (override && override->from->owner_class && !is_func(env->gwion, override->type)) - ERR_B(fdef->base->pos, + ERR_B(fdef->base->tag.loc, _("function name '%s' conflicts with previously defined value...\n" " from super class '%s'..."), - s_name(fdef->base->xid), override->from->owner_class->name) + s_name(fdef->base->tag.sym), override->from->owner_class->name) *ov = override; } if (func->value_ref->from->offset && @@ -1845,8 +1861,8 @@ ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef, ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) { MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects); if (v) { - if (fdef->base->xid == insert_symbol("@dtor")) - ERR_B(fdef->base->pos, _("can't use effects in destructors")); + if (fdef->base->tag.sym == insert_symbol("@dtor")) + ERR_B(fdef->base->tag.loc, _("can't use effects in destructors")); const Vector base = &fdef->base->effects; if (!base->ptr) vector_init(base); for (uint32_t i = 0; i < v->len; i++) { @@ -1859,23 +1875,69 @@ ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) { return GW_OK; } +ANN static void fdef_const_generic_value(const Env env, const Type owner, const Type t, const Tag tag) { + const Value v = new_value(env, t, s_name(tag.sym), tag.loc); + SET_FLAG(v, static|ae_flag_const); + valid_value(env, tag.sym, v); + nspc_add_value_front(owner->nspc, tag.sym, v); + v->from->owner = owner->nspc; + v->from->owner_class = owner; +} + +ANN static m_bool fdef_const_generic_typecheck(const Env env, const Specialized *spec, const TmplArg *targ) { + CHECK_OB(check_exp(env, targ->d.exp)); + // check implicits? + const Type target = known_type(env, spec->td); + if(isa(targ->d.exp->type, target) < 0) { + char msg[256]; + tcol_snprintf(msg, 255, "expected {G+}%s{0}", target->name); + gwerr_basic("invalid type for const generic argument", msg, NULL, env->name, spec->tag.loc, 0); + tcol_snprintf(msg, 255, "got {G+}%s{0}", targ->d.exp->type->name); + gwerr_secondary(msg, env->name, targ->d.exp->pos); + return GW_ERROR; + } + return GW_OK; +} + +ANN static m_bool check_fdef_const_generic(const Env env, const Func_Def fdef) { + const Tmpl *tmpl = fdef->base->tmpl; + if(tmplarg_ntypes(tmpl->call) == tmpl->call->len) return GW_OK; + const Type t = fdef->base->func->value_ref->type; + assert(!t->nspc); + t->nspc = new_nspc(env->gwion->mp, t->name); + + for(uint32_t i = 0; i < fdef->base->tmpl->call->len; i++) { + const TmplArg *targ = mp_vector_at(fdef->base->tmpl->call, TmplArg, i); + if(targ->type == tmplarg_td)continue; + // spec could be null cause of spread ops + const Specialized *spec = mp_vector_at(fdef->base->tmpl->list, Specialized, i); + if(!spec) break; + CHECK_BB(fdef_const_generic_typecheck(env, spec, targ)); + fdef_const_generic_value(env, t, targ->d.exp->type, spec->tag); + } + return GW_OK; +} + +ANN static m_bool check_fdef_code(const Env env, const Func_Def fdef) { + const bool ctor = is_ctor(fdef); + if(!ctor) { + nspc_push_value(env->gwion->mp, env->curr); + env->scope->depth++; + } + const m_bool ret = check_stmt_list(env, fdef->d.code); + if(!ctor) { + env->scope->depth--; + nspc_pop_value(env->gwion->mp, env->curr); + } + CHECK_BB(check_fdef_effects(env, fdef)); + return ret; +} + ANN m_bool check_fdef(const Env env, const Func_Def fdef) { if (fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args)); - if(fdef->builtin) return GW_OK; - if (fdef->d.code && fdef->d.code) { - const bool ctor = is_ctor(fdef); - if(!ctor) { - env->scope->depth++; - nspc_push_value(env->gwion->mp, env->curr); - } - const m_bool ret = check_stmt_list(env, fdef->d.code); - if(!ctor) { - nspc_pop_value(env->gwion->mp, env->curr); - env->scope->depth--; - } - CHECK_BB(check_fdef_effects(env, fdef)); - return ret; - } + if (fdef->base->tmpl) CHECK_BB(check_fdef_const_generic(env, fdef)); + if (fdef->builtin) return GW_OK; + if (fdef->d.code) CHECK_BB(check_fdef_code(env, fdef)); return GW_OK; } @@ -1888,10 +1950,9 @@ ANN static m_bool check_ctor(const Env env, const Func func) { const Type parent = env->class_def->info->parent; const Value v = nspc_lookup_value0(parent->nspc, insert_symbol("new")); if(v && !GET_FLAG(v->d.func_ref->def->base, abstract)) - ERR_B(func->def->base->pos, "missing call to parent constructor"); + ERR_B(func->def->base->tag.loc, "missing call to parent constructor"); } } - return GW_OK; } @@ -1913,6 +1974,7 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) { const Func former = env->func; env->func = func; nspc_push_value(env->gwion->mp, env->curr); +// env->scope->depth++; struct Op_Import opi = {}; if (fbflag(fdef->base, fbflag_op)) { func_operator(f, &opi); @@ -1922,7 +1984,7 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) { uint32_t offset = fdef->stack_depth; for(uint32_t i = 0; i < fdef->captures->len; i++) { Capture *cap = mp_vector_at(fdef->captures, Capture, i); - valid_value(env, cap->xid, cap->temp); + valid_value(env, cap->tag.sym, cap->temp); cap->temp->from->offset = offset; offset += cap->temp->type->size; } @@ -1932,13 +1994,14 @@ ANN m_bool _check_func_def(const Env env, const Func_Def f) { vector_pop(&env->scope->effects); if (fbflag(fdef->base, fbflag_op)) operator_resume(&opi); nspc_pop_value(env->gwion->mp, env->curr); +// env->scope->depth--; env->func = former; if (ret > 0) { if (env->class_def && fdef->base->effects.ptr && (override && !check_effect_overload(&fdef->base->effects, override->d.func_ref))) - ERR_B(fdef->base->pos, _("too much effects in override."), - s_name(fdef->base->xid)) + ERR_B(fdef->base->tag.loc, _("too much effects in override."), + s_name(fdef->base->tag.sym)) if(is_new(f) && !tflag(env->class_def, tflag_struct)) CHECK_BB(check_ctor(env, func)); } @@ -1961,7 +2024,7 @@ ANN m_bool check_func_def(const Env env, const Func_Def fdef) { ANN bool check_trait_requests(const Env env, const Type t, const ID_List list, const ValueFrom *from); ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) { const Type t = xdef->type; - ValueFrom from = { .filename = env->name, .loc=xdef->td->pos, .ctx=env->context, + ValueFrom from = { .filename = env->name, .loc=xdef->td->tag.loc, .ctx=env->context, .owner = env->curr, .owner_class = env->class_def }; const bool ret = check_trait_requests(env, t, xdef->traits, &from); @@ -1984,7 +2047,7 @@ ANN static m_bool check_extend_def(const Env env, const Extend_Def xdef) { } ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) { - const Trait trait = nspc_lookup_trait1(env->curr, pdef->xid); + const Trait trait = nspc_lookup_trait1(env->curr, pdef->tag.sym); Ast ast = pdef->body; if(!ast) return GW_OK; for(m_uint i = 0; i < ast->len; i++) { @@ -1996,7 +2059,7 @@ ANN static m_bool _check_trait_def(const Env env, const Trait_Def pdef) { const Stmt stmt = mp_vector_at(l, struct Stmt_, i); if (stmt->stmt_type == ae_stmt_exp) { CHECK_BB(traverse_exp(env, stmt->d.stmt_exp.val)); - Var_Decl vd = stmt->d.stmt_exp.val->d.exp_decl.vd; + Var_Decl vd = stmt->d.stmt_exp.val->d.exp_decl.var.vd; const Value value = vd.value; valuefrom(env, value->from); if (!trait->var) @@ -2053,7 +2116,7 @@ ANN m_bool check_abstract(const Env env, const Class_Def cdef) { gwerr_basic(_("missing function definition"), _("must be declared 'abstract'"), _("provide an implementation for the following:"), - env->name, cdef->pos, 0); + env->name, cdef->base.tag.loc, 0); } ValueFrom *from = f->value_ref->from; gwerr_secondary_from("implementation missing", from); @@ -2067,7 +2130,7 @@ ANN static bool class_def_has_body(Ast ast) { const Section *section = mp_vector_at(ast, Section, 0); if(section->section_type != ae_section_func) return false; Func_Def f = section->d.func_def; - if(strcmp(s_name(f->base->xid), "@ctor"))return false; + if(strcmp(s_name(f->base->tag.sym), "@ctor"))return false; Stmt_List l = f->d.code; for(m_uint i = 0; i < l->len; i++) { const Stmt stmt = mp_vector_at(l, struct Stmt_, i); @@ -2076,8 +2139,8 @@ ANN static bool class_def_has_body(Ast ast) { const Exp exp = stmt->d.stmt_exp.val; if (!exp) continue; if (exp->exp_type != ae_exp_decl) return true; - if (GET_FLAG(exp->d.exp_decl.td, late)) continue; - Var_Decl vd = exp->d.exp_decl.vd; + if (GET_FLAG(exp->d.exp_decl.var.td, late)) continue; + Var_Decl vd = exp->d.exp_decl.var.vd; if (GET_FLAG(vd.value, late)) continue; if (tflag(vd.value->type, tflag_compound)) return true; @@ -2097,7 +2160,7 @@ ANN static bool recursive_value(const Env env, const Type t, const Value v) { if(type_is_recurs(t, tgt)) { env_err(env, v->from->loc, _("recursive type")); env_set_error(env, false); - gwerr_secondary("in class", t->name, t->info->cdef->base.pos); + gwerr_secondary("in class", t->name, t->info->cdef->base.tag.loc); const Type first = tgt->info->value->from->loc.first.line < t->info->value->from->loc.first.line ? v->type : t; @@ -2169,17 +2232,13 @@ ANN static m_bool check_class_tmpl(const Env env, const Tmpl *tmpl, const Nspc n 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); + const Value v = new_value(env, targ.d.exp->type, s_name(spec.tag.sym), 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); + nspc_add_value(nspc, spec.tag.sym, v); SET_FLAG(v, const| ae_flag_static); set_vflag(v, vflag_builtin); - - // set value type } } return GW_OK; diff --git a/src/parse/check_traits.c b/src/parse/check_traits.c index e06d08ba..91063e6a 100644 --- a/src/parse/check_traits.c +++ b/src/parse/check_traits.c @@ -52,7 +52,7 @@ ANN static bool check_trait_variables(const Env env, const Type t, } ANN static bool trait_inherit(const Env env, const Type t, const Func_Def req) { - const bool global = type_global(env, t) || !!nspc_lookup_value1(env->curr->parent, req->base->xid); + const bool global = type_global(env, t) || !!nspc_lookup_value1(env->curr->parent, req->base->tag.sym); nspc_push_type(env->gwion->mp, env->curr); nspc_add_type(env->curr, insert_symbol("Self"), t); const Func_Def cpy = cpy_func_def(env->gwion->mp, req); @@ -70,12 +70,12 @@ ANN static bool check_trait_args(const Env env, const Func f, const Func_Base *r if (mp_vector_len(f->def->base->args) + m != mp_vector_len(req->args)) return false; if(m) { const Arg *r = mp_vector_at(req->args, Arg, 0); - if(strcmp(s_name(r->td->xid), "Self")) + if(strcmp(s_name(r->var.td->tag.sym), "Self")) return false; } for(m_uint i = m; i < req->args->len; i++) { const Arg *r = mp_vector_at(req->args, Arg, i + m); - const Type t = known_type(env, r->td); + const Type t = known_type(env, r->var.td); const Arg *arg = mp_vector_at(f->def->base->args, Arg, i); if(arg->type != t) return false; } @@ -84,7 +84,7 @@ ANN static bool check_trait_args(const Env env, const Func f, const Func_Base *r ANN static bool request_found(const Env env, const Type t, const Func_Def request) { - const Value v = nspc_lookup_value0(t->nspc, request->base->xid); + const Value v = nspc_lookup_value0(t->nspc, request->base->tag.sym); if (!v) return false; if (!is_func(env->gwion, v->type)) { gwerr_basic_from("is not a function", NULL, NULL, v->from, 0); @@ -124,7 +124,7 @@ ANN static bool ufcs_match(const Env env, const Value v, ANN static bool trait_ufcs(const Env env, const Type t, const Func_Def request) { - const Value v = nspc_lookup_value1(env->curr, request->base->xid); + const Value v = nspc_lookup_value1(env->curr, request->base->tag.sym); if(v) { const bool global = type_global(env, t) || from_global_nspc(env, v->from->owner); nspc_push_type(env->gwion->mp, env->curr); @@ -142,16 +142,16 @@ ANN static bool request_fun(const Env env, const Type t, if (trait_ufcs(env, t, request)) return true; if (!GET_FLAG(request->base, abstract)) return trait_inherit(env, t, request); - const Value parent = nspc_lookup_value1(env->global_nspc, request->base->xid); + const Value parent = nspc_lookup_value1(env->global_nspc, request->base->tag.sym); if(parent) { - const Value v = nspc_lookup_value1(env->curr, request->base->xid); + const Value v = nspc_lookup_value1(env->curr, request->base->tag.sym); if(!env->context->error) { gwerr_basic_from("is missing {+G}global{0}", NULL, NULL, v->from, 0); - gwerr_secondary("from requested func", env->name, request->base->pos); + gwerr_secondary("from requested func", env->name, request->base->tag.loc); env_set_error(env, true); } } else gwerr_basic("missing requested function", NULL, NULL, env->name, - request->base->pos, 0); + request->base->tag.loc, 0); return false; } diff --git a/src/parse/default_arg.c b/src/parse/default_arg.c index 68264436..aa74c15f 100644 --- a/src/parse/default_arg.c +++ b/src/parse/default_arg.c @@ -8,7 +8,7 @@ ANN2(1,2) static Exp base_args(const MemPool p, const Arg_List args, Exp next, const uint32_t min) { for(uint32_t i = min; i--;) { Arg *arg = mp_vector_at(args, Arg, i); - const Exp exp = new_prim_id(p, arg->var_decl.xid, arg->var_decl.pos); + const Exp exp = new_prim_id(p, arg->var.vd.tag.sym, arg->var.vd.tag.loc); exp->next = next; next = exp; } @@ -46,23 +46,23 @@ ANN static Stmt_List code(const MemPool p, const Exp func, const Arg_List lst, ANN static Stmt_List std_code(const Env env, Func_Base *base, const uint32_t max) { const MemPool p = env->gwion->mp; - const Exp func = new_prim_id(p, base->xid, base->pos); + const Exp func = new_prim_id(p, base->tag.sym, base->tag.loc); return code(p, func, base->args, max, ae_stmt_return); } ANN static Stmt_List new_code(const Env env, Func_Base *base, const uint32_t max) { const MemPool p = env->gwion->mp; SymTable *st = env->gwion->st; - const Exp dbase = new_prim_id(p, insert_symbol(st, "this"), base->pos); + const Exp dbase = new_prim_id(p, insert_symbol(st, "this"), base->tag.loc); const Symbol sym = insert_symbol(st, "new"); - const Exp func = new_exp_dot(p, dbase, sym, base->pos); + const Exp func = new_exp_dot(p, dbase, sym, base->tag.loc); return code(p, func, base->args, max, ae_stmt_exp); } ANN Func_Def default_args(const Env env, Func_Base *fb, Ast *acc, uint32_t max) { Func_Base *const base = cpy_func_base(env->gwion->mp, fb); - Stmt_List code = strcmp(s_name(base->xid), "new") + Stmt_List code = strcmp(s_name(base->tag.sym), "new") ? std_code(env, fb, max) : new_code(env, fb, max); const Func_Def fdef = new_func_def(env->gwion->mp, base, code); diff --git a/src/parse/func_operator.c b/src/parse/func_operator.c index a9984d9b..a3bc20d1 100644 --- a/src/parse/func_operator.c +++ b/src/parse/func_operator.c @@ -8,19 +8,19 @@ #include "operator.h" ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) { - opi->op = fdef->base->xid; - const m_str str = s_name(fdef->base->xid); + opi->op = fdef->base->tag.sym; + const m_str str = s_name(fdef->base->tag.sym); const uint is_unary = fbflag(fdef->base, fbflag_unary) + (!strcmp(str, "@conditional") || !strcmp(str, "@unconditional")); const Arg_List args = fdef->base->args; Arg *arg0 = args ? mp_vector_at(args, Arg, 0) : NULL; Arg *arg1 = (args && args->len >= 2) ? mp_vector_at(args, Arg, 1) : NULL; - opi->lhs = is_unary ? NULL : args ? arg0->var_decl.value->type : NULL; + opi->lhs = is_unary ? NULL : args ? arg0->var.vd.value->type : NULL; if (strcmp(str, "@implicit")) // opi->rhs = args ? is_unary ? arg0->var_decl->value->type - opi->rhs = args ? is_unary ? (arg0 ? arg0->var_decl.value->type : NULL) - : (arg1 ? arg1->var_decl.value->type : NULL) + opi->rhs = args ? is_unary ? (arg0 ? arg0->var.vd.value->type : NULL) + : (arg1 ? arg1->var.vd.value->type : NULL) : NULL; else opi->rhs = fdef->base->ret_type; diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index f2ef19cb..4aa3f346 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -77,7 +77,7 @@ ANN static Func fptr_match(const Env env, struct ResolverArgs *ra) { const Tmpl tmpl = {.list = base->base->tmpl->list, .call = ra->types}; CHECK_BO(template_push_types(env, &tmpl)); Func_Base *const fbase = cpy_func_base(env->gwion->mp, base->base); - fbase->xid = sym; + fbase->tag.sym = sym; fbase->tmpl->call = cpy_type_list(env->gwion->mp, ra->types); const Fptr_Def fptr = new_fptr_def(env->gwion->mp, fbase); const Func m_func = ensure_fptr(env, ra, fptr); @@ -110,12 +110,11 @@ ANN static Func create_tmpl(const Env env, struct ResolverArgs *ra, char c[256]; sprintf(c, "arg%u", idx); 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*/ }}; + Arg arg = { .var = MK_VAR(cpy_type_decl(env->gwion->mp, targ.d.td), (Var_Decl){ .tag = MK_TAG(insert_symbol(c), fdef->base->tag.loc)})}; mp_vector_add(env->gwion->mp, &args, Arg, arg); } fdef->base->args = args; } - const Func func = ensure_tmpl(env, fdef, ra->e, ra->v->from->filename); if (func && func->def->builtin) { builtin_func(env->gwion, func, (void*)ra->v->d.func_ref->code->native_func); @@ -151,14 +150,14 @@ ANN static Func find_tmpl(const Env env, const Value v, Exp_Call *const exp, .v = v, .e = exp, .tmpl_name = tmpl_name, .types = types}; CHECK_BO(envset_pushv(&es, v)); (void)env_push(env, v->from->owner_class, v->from->owner); - const bool in_tmpl = v->from->owner_class && v->from->owner_class->info->cdef && - v->from->owner_class->info->cdef->base.tmpl; - if(in_tmpl) - (void)template_push_types(env, v->from->owner_class->info->cdef->base.tmpl); + const Tmpl *tmpl = v->from->owner_class && v->from->owner_class->info->cdef ? + get_tmpl(v->from->owner_class) : NULL; + if(tmpl) + (void)template_push_types(env, tmpl); const bool is_clos = isa(exp->func->type, env->gwion->type[et_closure]) > 0; const Func m_func = !is_clos ? func_match(env, &ra) : fptr_match(env, &ra); - if(in_tmpl) + if(tmpl) nspc_pop_type(env->gwion->mp, env->curr); env_pop(env, scope); envset_pop(&es, v->from->owner_class); @@ -184,13 +183,21 @@ ANN static Func _find_template_match(const Env env, const Value v, 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 + if(unlikely(arg.type == tmplarg_td)) + ERR_O(exp_self(exp)->pos, "expected contant, not type"); + // check argument in call exp continue; + } else { + if(unlikely(arg.type == tmplarg_exp)) { + ERR_O(exp_self(exp)->pos, "expected type, not constant"); + // 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; } - DECL_OO(const Type, t, = known_type(env, arg.d.td)); - if(t->info->traits && miss_traits(t, spec)) - return NULL; } return f; } @@ -211,7 +218,7 @@ ANN Func find_template_match(const Env env, const Value value, while (t && t->nspc) { const Func_Def fdef = value->d.func_ref ? value->d.func_ref->def : value->type->info->func->def; - const Value v = nspc_lookup_value0(t->nspc, fdef->base->xid); + const Value v = nspc_lookup_value0(t->nspc, fdef->base->tag.sym); if (v) { const Func f = _find_template_match(env, v, exp); if (f) return f; diff --git a/src/parse/operator.c b/src/parse/operator.c index 022ac4c9..feb57286 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -194,7 +194,7 @@ ANN static Type op_check_inner(const Env env, struct OpChecker *ock, ANN static bool op_template_type(const Symbol xid, const Specialized_List sl) { for(uint32_t i = 0; i < sl->len; i++) { Specialized *spec = mp_vector_at(sl, Specialized, i); - if (xid == spec->xid) return true; + if (xid == spec->tag.sym) return true; } return false; } @@ -202,7 +202,7 @@ ANN static bool op_template_type(const Symbol xid, const Specialized_List sl) { //! check if type matches for template operator ANN2(1,2,3) bool _tmpl_match(const Env env, const Type t, Type_Decl *const td, Specialized_List sl) { - if (!td->next && !td->types && op_template_type(td->xid, sl)) + if (!td->next && !td->types && op_template_type(td->tag.sym, sl)) return true; const Type base = known_type(env, td); return base ? isa(t, base) > 0 : false; @@ -216,14 +216,14 @@ ANN bool tmpl_match(const Env env, const struct Op_Import *opi, Arg *arg0 = mp_vector_at(args, Arg, 0); Arg *arg1 = args->len > 1 ? mp_vector_at(args, Arg, 1) : NULL; if (opi->lhs) { - if (!_tmpl_match(env, opi->lhs, arg0->td, sl)) return false; + if (!_tmpl_match(env, opi->lhs, arg0->var.td, sl)) return false; if (fbflag(base, fbflag_postfix)) return !!opi->rhs; if (!fbflag(base, fbflag_unary)) { if (!opi->rhs) return false; - if (!_tmpl_match(env, opi->rhs, arg1->td, sl)) return false; + if (!_tmpl_match(env, opi->rhs, arg1->var.td, sl)) return false; } else if (opi->rhs) return false; } else if (!fbflag(base, fbflag_unary) || - !_tmpl_match(env, opi->rhs, arg0->td, sl)) + !_tmpl_match(env, opi->rhs, arg0->var.td, sl)) return false; return true; } @@ -261,7 +261,7 @@ ANN static Type op_check_tmpl(const Env env, struct Op_Import *opi) { const Vector v = &nspc->operators->tmpl; for (m_uint i = vector_size(v) + 1; --i;) { const Func_Def fdef = (Func_Def)vector_at(v, i - 1); - if (opi->op != fdef->base->xid) continue; + if (opi->op != fdef->base->tag.sym) continue; if (!tmpl_match(env, opi, fdef->base)) continue; return op_def(env, opi, fdef); } @@ -380,10 +380,10 @@ ANN static m_bool handle_instr(const Emitter emit, const M_Operator *mo) { emit_pushfunc(emit, mo->func); CHECK_BB(emit_exp_call1(emit, mo->func, mo->func->def->base->ret_type->size, true)); - if (mo->func->def->base->xid == + if (mo->func->def->base->tag.sym == insert_symbol(emit->gwion->st, "@conditional")) emit_add_instr(emit, BranchEqInt); - else if (mo->func->def->base->xid == + else if (mo->func->def->base->tag.sym == insert_symbol(emit->gwion->st, "@unconditional")) emit_add_instr(emit, BranchNeqInt); return GW_OK; diff --git a/src/parse/partial.c b/src/parse/partial.c index 158e1f05..f4ee2a99 100644 --- a/src/parse/partial.c +++ b/src/parse/partial.c @@ -22,8 +22,8 @@ ANN static Arg_List partial_arg_list(const Env env, const Arg_List base, const E char c[256]; sprintf(c, "@%u", args->len); const Arg *src = mp_vector_at(base, Arg, i); - Type_Decl *td = src->td ? cpy_type_decl(env->gwion->mp, src->td) : NULL; - Arg arg = { .td = td, .var_decl = { .xid = insert_symbol(c) }}; + Type_Decl *td = src->var.td ? cpy_type_decl(env->gwion->mp, src->var.td) : NULL; + Arg arg = { .var = MK_VAR(td, (Var_Decl){ .tag = MK_TAG(insert_symbol(c), src->var.vd.tag.loc)})}; mp_vector_add(env->gwion->mp, &args, Arg, arg); } i++; @@ -49,7 +49,7 @@ ANN static Exp partial_exp(const Env env, Arg_List args, Exp e, const uint i) { char c[256]; sprintf(c, "@%u", i); const Exp exp = new_prim_id(env->gwion->mp, insert_symbol(c), e->pos); - exp->type = known_type(env, mp_vector_at(args, Arg, i)->td); + exp->type = known_type(env, mp_vector_at(args, Arg, i)->var.td); exp->d.prim.value = new_value(env, exp->type, c, e->pos); valid_value(env, insert_symbol(c), exp->d.prim.value); return exp; @@ -117,7 +117,7 @@ ANN static void print_arg(Arg_List args) { for(uint32_t i = 0; i < args->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); gw_err("{G}%s{0} {/}%s{0}", arg->type ? arg->type->name : NULL, - arg->var_decl.xid ? s_name(arg->var_decl.xid) : ""); + arg->var.vd.tag.sym ? s_name(arg->var.vd.tag.sym) : ""); if(i < args->len - 1) gw_err(", "); } } diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 9f8e18b4..9626183e 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -17,22 +17,21 @@ static inline void add_type(const Env env, const Nspc nspc, const Type t) { nspc_add_type_front(nspc, insert_symbol(t->name), t); } -ANN static inline m_bool scan0_defined(const Env env, const Symbol s, - const loc_t pos) { - if (nspc_lookup_type1(env->curr, s)) - ERR_B(pos, _("type '%s' already defined"), s_name(s)); - return already_defined(env, s, pos); +ANN static inline m_bool scan0_defined(const Env env, const Tag tag) { + if (nspc_lookup_type1(env->curr, tag.sym)) + ERR_B(tag.loc, _("type '%s' already defined"), s_name(tag.sym)); + return already_defined(env, tag.sym, tag.loc); } ANN static Arg_List fptr_arg_list(const Env env, const Fptr_Def fptr) { if(env->class_def && !GET_FLAG(fptr->base, static)) { - Arg arg = { .td = type2td(env->gwion, env->class_def, fptr->base->td->pos) }; + Arg arg = { .var = {.td = type2td(env->gwion, env->class_def, fptr->base->td->tag.loc)}}; const uint32_t len = mp_vector_len(fptr->base->args); Arg_List args = new_mp_vector(env->gwion->mp, Arg, len + 1); mp_vector_set(args, Arg, 0, arg); for(uint32_t i = 0; i < len; i++) { Arg *base = mp_vector_at(fptr->base->args, Arg, i); - Arg arg = { .td = cpy_type_decl(env->gwion->mp, base->td) }; + Arg arg = { .var = {.td = cpy_type_decl(env->gwion->mp, base->var.td)}}; mp_vector_set(args, Arg, i+1, arg); } return args; @@ -55,9 +54,9 @@ ANN static inline m_bool scan0_global(const Env env, const ae_flag flag, } ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) { - const loc_t loc = fptr->base->td->pos; + const loc_t loc = fptr->base->td->tag.loc; CHECK_BB(env_access(env, fptr->base->flag, loc)); - CHECK_BB(scan0_defined(env, fptr->base->xid, loc)); + CHECK_BB(scan0_defined(env, fptr->base->tag)); const Arg_List args = fptr_arg_list(env, fptr); Func_Base *const fbase = new_func_base(env->gwion->mp, cpy_type_decl(env->gwion->mp, fptr->base->td), insert_symbol("func"), args, ae_flag_static | ae_flag_private, loc); @@ -65,7 +64,7 @@ ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) { Ast body = new_mp_vector(env->gwion->mp, Section, 1); mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef)); Type_Decl* td = new_type_decl(env->gwion->mp, insert_symbol(env->gwion->type[et_closure]->name), loc); - const Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_final, fptr->base->xid, td, body, loc); + const Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_final, fptr->base->tag.sym, td, body, loc); if(GET_FLAG(fptr->base, global)) { SET_FLAG(cdef, global); UNSET_FLAG(fptr->base, global); @@ -126,7 +125,7 @@ ANN static void scan0_explicit_distinct(const Env env, const Type lhs, ANN static void typedef_simple(const Env env, const Type_Def tdef, const Type base) { - const Type t = new_type(env->gwion->mp, s_name(tdef->xid), base); + const Type t = new_type(env->gwion->mp, s_name(tdef->tag.sym), base); t->size = base->size; const Nspc nspc = (!env->class_def && GET_FLAG(tdef->ext, global)) ? env->global_nspc @@ -148,9 +147,9 @@ ANN static void typedef_simple(const Env env, const Type_Def tdef, ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) { const ae_flag flag = base->info->cdef ? base->info->cdef->flag : 0; - const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid, + const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->tag.sym, cpy_type_decl(env->gwion->mp, tdef->ext), - NULL, tdef->ext->pos); + NULL, tdef->ext->tag.loc); const bool final = GET_FLAG(base, final); if(final) UNSET_FLAG(base, final); CHECK_BB(scan0_class_def(env, cdef)); @@ -162,14 +161,14 @@ ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, } ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) { - CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->pos)); + CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->tag.loc)); DECL_OB(const Type, base, = known_type(env, tdef->ext)); - CHECK_BB(scan0_defined(env, tdef->xid, tdef->ext->pos)); - DECL_BB(const m_bool, global, = scan0_global(env, tdef->ext->flag, tdef->ext->pos)); + CHECK_BB(scan0_defined(env, tdef->tag)); + DECL_BB(const m_bool, global, = scan0_global(env, tdef->ext->flag, tdef->ext->tag.loc)); if (!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp)) typedef_simple(env, tdef, base); else CHECK_BB(typedef_complex(env, tdef, base)); - mk_class(env, tdef->type, tdef->pos); + mk_class(env, tdef->type, tdef->tag.loc); if (tdef->when) set_tflag(tdef->type, tflag_contract); if (tdef->type != base && !tdef->distinct && !tdef->when) scan0_implicit_similar(env, base, tdef->type); @@ -192,16 +191,16 @@ ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) { ANN static Type enum_type(const Env env, const Enum_Def edef) { const Type t = type_copy(env->gwion->mp, env->gwion->type[et_enum]); - t->name = s_name(edef->xid); + t->name = s_name(edef->tag.sym); t->info->parent = env->gwion->type[et_enum]; add_type(env, env->curr, t); - mk_class(env, t, edef->pos); + mk_class(env, t, edef->tag.loc); return t; } ANN m_bool scan0_enum_def(const Env env, const Enum_Def edef) { - CHECK_BB(scan0_defined(env, edef->xid, edef->pos)); - DECL_BB(const m_bool, global, = scan0_global(env, edef->flag, edef->pos)); + CHECK_BB(scan0_defined(env, edef->tag)); + DECL_BB(const m_bool, global, = scan0_global(env, edef->flag, edef->tag.loc)); edef->type = enum_type(env, edef); if (global) env_pop(env, 0); return GW_OK; @@ -280,9 +279,9 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) { } ANN m_bool scan0_union_def(const Env env, const Union_Def udef) { - DECL_BB(const m_bool, global, = scan0_global(env, udef->flag, udef->pos)); - CHECK_BB(scan0_defined(env, udef->xid, udef->pos)); - udef->type = union_type(env, udef->xid, udef->pos); + DECL_BB(const m_bool, global, = scan0_global(env, udef->flag, udef->tag.loc)); + CHECK_BB(scan0_defined(env, udef->tag)); + udef->type = union_type(env, udef->tag.sym, udef->tag.loc); SET_ACCESS(udef, udef->type); if (udef->tmpl) union_tmpl(env, udef); if (global) env_pop(env, 0); @@ -300,7 +299,7 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) { Type owner = env->class_def; while (owner) { if (t == owner) - ERR_O(td->pos, _("'%s' as parent inside itself\n."), owner->name); + ERR_O(td->tag.loc, _("'%s' as parent inside itself\n."), owner->name); owner = owner->info->value->from->owner_class; } return t; @@ -308,7 +307,7 @@ ANN static Type get_parent_base(const Env env, Type_Decl *td) { ANN static inline Type scan0_final(const Env env, Type_Decl *td) { const Type t = known_type(env, td); - if(!t) ERR_O(td->pos, _("can't find parent class %s\n."), s_name(td->xid)); + if(!t) ERR_O(td->tag.loc, _("can't find parent class %s\n."), s_name(td->tag.sym)); return t; } @@ -343,16 +342,16 @@ ANN static m_bool find_traits(const Env env, ID_List traits, const loc_t pos) { } ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { - CHECK_BO(scan0_defined(env, cdef->base.xid, cdef->pos)); + CHECK_BO(scan0_defined(env, cdef->base.tag)); DECL_OO(const Type, parent, = cdef_parent(env, cdef)); if(GET_FLAG(cdef, global) && isa(parent, env->gwion->type[et_closure]) < 0 && !type_global(env, parent)) { - gwerr_basic(_("parent type is not global"), NULL, NULL, env->name, cdef->base.ext ? cdef->base.ext->pos : cdef->base.pos, 0); + gwerr_basic(_("parent type is not global"), NULL, NULL, env->name, cdef->base.ext ? cdef->base.ext->tag.loc : cdef->base.tag.loc, 0); declared_here(parent->info->value); env_set_error(env, true); return NULL; } - if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->pos)); - const Type t = new_type(env->gwion->mp, s_name(cdef->base.xid), parent); + if (cdef->traits) CHECK_BO(find_traits(env, cdef->traits, cdef->base.tag.loc)); + const Type t = new_type(env->gwion->mp, s_name(cdef->base.tag.sym), parent); if (cflag(cdef, cflag_struct)) { t->size = 0; set_tflag(t, tflag_struct); @@ -371,7 +370,7 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) { ANN static m_bool _spread_tmpl(const Env env, const Type t, const Spread_Def spread) { if(t->info->value->from->owner_class) CHECK_BB(_spread_tmpl(env, t->info->value->from->owner_class, spread)); - const Tmpl *tmpl = t->info->cdef->base.tmpl; + const Tmpl *tmpl = get_tmpl(t); if(!tmpl || !tmpl->call) return GW_OK; if(is_spread_tmpl(tmpl)) CHECK_BB(spread_ast(env, spread, tmpl)); @@ -394,7 +393,7 @@ ANN static bool spreadable(const Env env) { return true; Type t = env->class_def; while(t) { - const Tmpl *tmpl = t->info->cdef->base.tmpl; + const Tmpl *tmpl = get_tmpl(t); if(tmpl && is_spread_tmpl(tmpl)) return true; t = t->info->value->from->owner_class; @@ -426,7 +425,7 @@ ANN m_bool scan0_func_def(const Env env, const Func_Def fdef) { if(!fdef->base->tmpl || !fdef->base->tmpl->call) return GW_OK; if(env->context) { if(fdef->base->tmpl && fdef->base->tmpl->call && is_spread_tmpl(fdef->base->tmpl)) { - struct Func_ fake = {.name = s_name(fdef->base->xid), .def = fdef }, *const former = + struct Func_ fake = {.name = s_name(fdef->base->tag.sym), .def = fdef }, *const former = env->func; env->func = &fake; if(!fdef->builtin && fdef->d.code) @@ -448,7 +447,7 @@ ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) { if(!global) { const Trait trait = nspc_lookup_trait1(env->curr, xid); gwerr_basic("trait should be declared global", NULL, NULL, trait->filename, trait->loc, 0); - gwerr_secondary("from the request ", env->name, xdef->td->pos); + gwerr_secondary("from the request ", env->name, xdef->td->tag.loc); env_set_error(env, true); } } @@ -458,13 +457,13 @@ ANN static m_bool scan0_extend_def(const Env env, const Extend_Def xdef) { } ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) { - CHECK_BB(scan0_defined(env, pdef->xid, pdef->pos)); - DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, pdef->pos)); - const Trait trait = new_trait(env->gwion->mp, pdef->pos); - trait->loc = pdef->pos; - trait->name = s_name(pdef->xid); + CHECK_BB(scan0_defined(env, pdef->tag)); + DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, pdef->tag.loc)); + const Trait trait = new_trait(env->gwion->mp, pdef->tag.loc); + trait->loc = pdef->tag.loc; + trait->name = s_name(pdef->tag.sym); trait->filename = env->name; - nspc_add_trait(env->curr, pdef->xid, trait); + nspc_add_trait(env->curr, pdef->tag.sym, trait); if(global) env_pop(env, 0); Ast ast = pdef->body; if(!ast) return GW_OK; // ??? @@ -474,7 +473,7 @@ ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) { const Func_Def fdef = section->d.func_def; if (fdef->base->flag != ae_flag_none && fdef->base->flag != (ae_flag_none | ae_flag_abstract)) - ERR_B(fdef->base->pos, "Trait function must be declared without qualifiers"); + ERR_B(fdef->base->tag.loc, "Trait function must be declared without qualifiers"); if (!trait->fun) trait->fun = new_mp_vector(env->gwion->mp, Func_Def, 0); mp_vector_add(env->gwion->mp, &trait->fun, Func_Def, fdef); } else if (section->section_type == ae_section_stmt) { @@ -485,33 +484,33 @@ ANN static m_bool _scan0_trait_def(const Env env, const Trait_Def pdef) { ERR_B(stmt->pos, "trait can only contains variable requests and functions"); } } else - ERR_B(pdef->pos, "invalid section for trait definition"); + ERR_B(pdef->tag.loc, "invalid section for trait definition"); } return GW_OK; } ANN static m_bool scan0_trait_def(const Env env, const Trait_Def pdef) { - const Symbol s = pdef->xid; + const Symbol s = pdef->tag.sym; const Trait exists = nspc_lookup_trait1(env->curr, s); if (exists) { - gwerr_basic("trait already defined", NULL, NULL, env->name, pdef->pos, 0); + gwerr_basic("trait already defined", NULL, NULL, env->name, pdef->tag.loc, 0); gwerr_secondary("defined here", env->name, exists->loc); env_set_error(env, true); - return already_defined(env, s, pdef->pos); + return already_defined(env, s, pdef->tag.loc); } - if (pdef->traits) CHECK_BB(find_traits(env, pdef->traits, pdef->pos)); + if (pdef->traits) CHECK_BB(find_traits(env, pdef->traits, pdef->tag.loc)); _scan0_trait_def(env, pdef); return GW_OK; } ANN m_bool scan0_prim_def(const Env env, const Prim_Def pdef) { - const loc_t loc = pdef->loc; + const loc_t loc = pdef->tag.loc; CHECK_BB(env_access(env, pdef->flag, loc)); - CHECK_BB(scan0_defined(env, pdef->name, loc)); + CHECK_BB(scan0_defined(env, pdef->tag)); DECL_BB(const m_bool, global, = scan0_global(env, pdef->flag, loc)); - const Type t = mk_primitive(env, s_name(pdef->name), pdef->size); + const Type t = mk_primitive(env, s_name(pdef->tag.sym), pdef->size); add_type(env, env->curr, t); - mk_class(env, t, pdef->loc); + mk_class(env, t, pdef->tag.loc); t->flag = pdef->flag; if(global) env_pop(env, 0); return GW_OK; @@ -520,11 +519,11 @@ ANN m_bool scan0_prim_def(const Env env, const Prim_Def pdef) { HANDLE_SECTION_FUNC(scan0, m_bool, Env) ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) { - CHECK_BB(isres(env, cdef->base.xid, cdef->pos)); + CHECK_BB(isres(env, cdef->base.tag)); CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef))); cdef->base.type->info->traits = cdef->traits; // should we copy the traits? set_tflag(cdef->base.type, tflag_scan0); - (void)mk_class(env, cdef->base.type, cdef->pos); + (void)mk_class(env, cdef->base.type, cdef->base.tag.loc); add_type(env, cdef->base.type->info->value->from->owner, cdef->base.type); const m_bool ret = cdef->body ? env_body(env, cdef, scan0_section) : GW_OK; return ret; @@ -533,7 +532,7 @@ ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) { ANN Ast spread_class(const Env env, const Ast body); ANN m_bool scan0_class_def(const Env env, const Class_Def c) { - DECL_BB(const m_bool, global, = scan0_global(env, c->flag, c->pos)); + DECL_BB(const m_bool, global, = scan0_global(env, c->flag, c->base.tag.loc)); const Ast old_extend = env->context ? env->context->extend : NULL; const int cpy = tmpl_base(c->base.tmpl) || GET_FLAG(c, global); const Class_Def cdef = !cpy ? c : cpy_class_def(env->gwion->mp, c); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 2eab1fe2..a3a3bd4b 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -20,14 +20,15 @@ ANN static inline m_bool type_cyclic(const Env env, const Type t, Type parent = t; do { if (parent == owner) - ERR_B(td->pos, _("%s declared inside %s"), t->name, owner->name); + ERR_B(td->tag.loc, _("%s declared inside %s"), t->name, owner->name); } while ((parent = parent->info->parent)); } while ((owner = owner->info->value->from->owner_class)); return GW_OK; } ANN static inline m_bool ensure_scan1(const Env env, const Type t) { - if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef))) +// if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef))) + if (tflag(t, tflag_scan1) || !(tflag(t, tflag_cdef) || tflag(t, tflag_union))) return GW_OK; struct EnvSet es = {.env = env, .data = env, @@ -64,15 +65,15 @@ ANN static Type scan1_type(const Env env, Type_Decl *td) { ANN static Type void_type(const Env env, Type_Decl *td) { DECL_OO(const Type, type, = scan1_type(env, td)); if (type->size) return type; - ERR_O(td->pos, _("cannot declare variables of size '0' (i.e. 'void')...")) + ERR_O(td->tag.loc, _("cannot declare variables of size '0' (i.e. 'void')...")) } ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl *decl) { if (decl->type) return decl->type; - DECL_OO(const Type, t, = void_type(env, decl->td)); - if(env->class_def && type_global(env, env->class_def) && !check_global(env, t, decl->td->pos)) + DECL_OO(const Type, t, = void_type(env, decl->var.td)); + if(env->class_def && type_global(env, env->class_def) && !check_global(env, t, decl->var.td->tag.loc)) return NULL; - if (decl->td->xid == insert_symbol("auto") && decl->type) return decl->type; + if (decl->var.td->tag.sym == insert_symbol("auto") && decl->type) return decl->type; if (GET_FLAG(t, private) && t->info->value->from->owner != env->curr) ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name) if (GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0)) @@ -86,11 +87,11 @@ static inline m_bool scan1_defined(const Env env, const Var_Decl *var) { const Value v = ((!env->class_def || !GET_FLAG(env->class_def, final) || env->scope->depth) ? nspc_lookup_value1 - : nspc_lookup_value2)(env->curr, var->xid); + : nspc_lookup_value2)(env->curr, var->tag.sym); if(v && (!v->from->owner_class || isa(env->class_def, v->from->owner_class) > 0)) - ERR_B(var->pos, + ERR_B(var->tag.loc, _("variable %s has already been defined in the same scope..."), - s_name(var->xid)) + s_name(var->tag.sym)) return GW_OK; } @@ -105,30 +106,30 @@ ANN m_bool abstract_array(const Env env, const Array_Sub array) { } ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) { - const bool decl_ref = decl->td->array && !decl->td->array->exp; - Var_Decl *const vd = &decl->vd; - CHECK_BB(isres(env, vd->xid, exp_self(decl)->pos)); + const bool decl_ref = decl->var.td->array && !decl->var.td->array->exp; + Var_Decl *const vd = &decl->var.vd; + CHECK_BB(isres(env, vd->tag)); Type t = decl->type; CHECK_BB(scan1_defined(env, vd)); const Type base = array_base_simple(t); - if(decl->td->array) { - if (!GET_FLAG(decl->td, late) && !decl->td->array->exp) - ERR_B(decl->td->pos, _("arrays with no expressions should be declared `late`")); - if (GET_FLAG(decl->td, late) && decl->td->array->exp) - ERR_B(decl->td->array->exp->pos, _("late array should have no size")); - if (!decl->args && GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->td->array)); + if(decl->var.td->array) { + if (!GET_FLAG(decl->var.td, late) && !decl->var.td->array->exp) + ERR_B(decl->var.td->tag.loc, _("arrays with no expressions should be declared `late`")); + if (GET_FLAG(decl->var.td, late) && decl->var.td->array->exp) + ERR_B(decl->var.td->array->exp->pos, _("late array should have no size")); + if (!decl->args && GET_FLAG(base, abstract)) CHECK_BB(abstract_array(env, decl->var.td->array)); } const Value v = vd->value = - vd->value ?: new_value(env, t, s_name(vd->xid), vd->pos); - if (GET_FLAG(t, abstract) && !decl->args && !GET_FLAG(decl->td, late)) SET_FLAG(v, late); + vd->value ?: new_value(env, t, s_name(vd->tag.sym), vd->tag.loc); + if (GET_FLAG(t, abstract) && !decl->args && !GET_FLAG(decl->var.td, late)) SET_FLAG(v, late); v->type = t; if (decl_ref) SET_FLAG(v, late); - v->flag |= decl->td->flag; + v->flag |= decl->var.td->flag; if (!env->scope->depth) { valuefrom(env, v->from); if (env->class_def) { if (env->class_def->info->tuple) tuple_contains(env, v); - if (!GET_FLAG(decl->td, static)) { + if (!GET_FLAG(decl->var.td, static)) { set_vflag(v, vflag_member); if(tflag(t, tflag_release)) set_tflag(env->class_def, tflag_release); @@ -139,23 +140,23 @@ ANN static m_bool scan1_decl(const Env env, Exp_Decl *const decl) { env->class_def->size += t->size; } } - } else if (GET_FLAG(decl->td, global)) + } else if (GET_FLAG(decl->var.td, global)) SET_FLAG(v, global); else if(env->context) set_vflag(v, vflag_fglobal); // file global - } else if (GET_FLAG(decl->td, global)) + } else if (GET_FLAG(decl->var.td, global)) SET_FLAG(v, global); - nspc_add_value(env->curr, vd->xid, v); - ((Exp_Decl *)decl)->type = decl->vd.value->type; + nspc_add_value(env->curr, vd->tag.sym, v); + ((Exp_Decl *)decl)->type = decl->var.vd.value->type; return GW_OK; } ANN m_bool scan1_exp_decl(const Env env, Exp_Decl *const decl) { - CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos)); + CHECK_BB(env_storage(env, decl->var.td->flag, exp_self(decl)->pos)); ((Exp_Decl *)decl)->type = scan1_exp_decl_type(env, (Exp_Decl *)decl); CHECK_OB(decl->type); if(decl->args) CHECK_BB(scan1_exp(env, decl->args)); - const bool global = GET_FLAG(decl->td, global); + const bool global = GET_FLAG(decl->var.td, global); if (global) { if (env->context) env->context->global = true; if (!type_global(env, decl->type)) @@ -301,12 +302,12 @@ ANN static inline m_bool scan1_stmt_try(const restrict Env env, ANN static inline m_bool stmt_each_defined(const restrict Env env, const Stmt_Each stmt) { - if (nspc_lookup_value1(env->curr, stmt->sym)) + if (nspc_lookup_value1(env->curr, stmt->tag.sym)) ERR_B(stmt_self(stmt)->pos, _("foreach value '%s' is already defined"), - s_name(stmt->sym)) - if (stmt->idx && nspc_lookup_value1(env->curr, stmt->idx->sym)) - ERR_B(stmt->idx->pos, _("foreach index '%s' is already defined"), - s_name(stmt->idx->sym)) + s_name(stmt->tag.sym)) + if (stmt->idx && nspc_lookup_value1(env->curr, stmt->idx->tag.sym)) + ERR_B(stmt->idx->tag.loc, _("foreach index '%s' is already defined"), + s_name(stmt->idx->tag.sym)) return GW_OK; } @@ -320,25 +321,23 @@ ANN static inline m_bool shadow_err(const Env env, const Value v, return GW_ERROR; } -ANN static inline m_bool shadow_arg(const Env env, const Symbol sym, - const loc_t loc) { +ANN static inline m_bool shadow_arg(const Env env, const Tag tag) { Nspc nspc = env->curr; do { - const Value v = nspc_lookup_value0(nspc, sym); + const Value v = nspc_lookup_value0(nspc, tag.sym); if (v && !env->func->def->builtin) { const Type owner = v->from->owner_class; if (owner && env->class_def && isa(env->class_def, owner) < 0) continue; - return shadow_err(env, v, loc); + return shadow_err(env, v, tag.loc); } } while ((nspc = nspc->parent)); return GW_OK; } -ANN static inline m_bool shadow_var(const Env env, const Symbol sym, - const loc_t loc) { - const Value v = nspc_lookup_value1(env->curr, sym); - return !v ? GW_OK : shadow_err(env, v, loc); +ANN static inline m_bool shadow_var(const Env env, const Tag tag){ + const Value v = nspc_lookup_value1(env->curr, tag.sym); + return !v ? GW_OK : shadow_err(env, v, tag.loc); } #define describe_ret_nspc(name, type, prolog, exp) \ @@ -351,7 +350,7 @@ describe_ret_nspc(for, Stmt_For,, !(scan1_stmt(env, stmt->c1) < 0 || scan1_stmt(env, stmt->body) < 0) ? 1 : -1) describe_ret_nspc(each, Stmt_Each,, !(stmt_each_defined(env, stmt) < 0 || scan1_exp(env, stmt->exp) < 0 || scan1_stmt(env, stmt->body) < 0) ? 1 : -1) -describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->sym, stmt->idx->pos)) < 0 || +describe_ret_nspc(loop, Stmt_Loop,, !( (!stmt->idx ? GW_OK : shadow_var(env, stmt->idx->tag)) < 0 || scan1_exp(env, stmt->cond) < 0 || scan1_stmt(env, stmt->body) < 0) ? 1 : -1) @@ -400,11 +399,11 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) { m_int last = 0; for(uint32_t i = 0; i < list->len; i++) { EnumValue ev = *mp_vector_at(list, EnumValue, i); - const Value v = new_value(env, t, s_name(ev.xid), edef->pos); + const Value v = new_value(env, t, s_name(ev.tag.sym), ev.tag.loc); v->d.num = (ev.set ? ev.gwint.num : last); last = v->d.num + 1; valuefrom(env, v->from); - nspc_add_value(env->curr, ev.xid, v); + nspc_add_value(env->curr, ev.tag.sym, v); SET_FLAG(v, static | ae_flag_const); SET_ACCESS(edef, v) SET_ACCESS(edef, t) @@ -415,28 +414,28 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) { } ANN static Value arg_value(const Env env, Arg *const arg) { - const Var_Decl *vd = &arg->var_decl; + const Var_Decl *vd = &arg->var.vd; const Value v = new_value(env, arg->type, - vd->xid ? s_name(vd->xid) : (m_str) __func__, arg->var_decl.pos); - if (arg->td) - v->flag = arg->td->flag; + vd->tag.sym ? s_name(vd->tag.sym) : (m_str) __func__, arg->var.vd.tag.loc); + if (arg->var.td) + v->flag = arg->var.td->flag; return v; } ANN static m_bool scan1_args(const Env env, Arg_List args) { for(uint32_t i = 0; i < args->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); - Var_Decl *const vd = &arg->var_decl; - if (vd->xid) CHECK_BB(isres(env, vd->xid, vd->pos)); - if (arg->td) { - SET_FLAG(arg->td, late); - CHECK_OB((arg->type = void_type(env, arg->td))); + Var_Decl *const vd = &arg->var.vd; + if (vd->tag.sym) CHECK_BB(isres(env, vd->tag)); + if (arg->var.td) { + SET_FLAG(arg->var.td, late); + CHECK_OB((arg->type = void_type(env, arg->var.td))); if (GET_FLAG(env->func->def->base, global) && !type_global(env, arg->type)) - ERR_B(arg->td->pos, "is not global"); - UNSET_FLAG(arg->td, late); + ERR_B(arg->var.td->tag.loc, "is not global"); + UNSET_FLAG(arg->var.td, late); } vd->value = arg_value(env, arg); - if (vd->xid) nspc_add_value(env->curr, vd->xid, vd->value); + if (vd->tag.sym) nspc_add_value(env->curr, vd->tag.sym, vd->value); } return GW_OK; } @@ -445,14 +444,14 @@ ANN static Type scan1_noret(const Env env, const Func_Base *base) { assert(base->td); DECL_OO(const Type, t, = known_type(env, base->td)); if (!tflag(t, tflag_noret)) return t; - ERR_O(base->pos, _("Can't use type `{+G}%s{0}` for return"), t->name); + ERR_O(base->tag.loc, _("Can't use type `{+G}%s{0}` for return"), t->name); } ANN static m_bool _scan1_fbase_tmpl(const Env env, Func_Base *base) { Specialized_List sl = base->tmpl->list; for(uint32_t i = 0; i < sl->len; i++) { Specialized *spec = mp_vector_at(sl, Specialized, i); - nspc_add_type(env->curr, spec->xid, env->gwion->type[et_auto]); + nspc_add_type(env->curr, spec->tag.sym, env->gwion->type[et_auto]); } CHECK_OB((base->ret_type = scan1_noret(env, base))); return GW_OK; @@ -477,7 +476,7 @@ ANN static bool spec_acc_has(const MemPool mp, MP_Vector **acc, const Symbol xid ANN static bool find_op_template_type(const MemPool mp, const Symbol xid, const Specialized_List sl, MP_Vector **acc) { for(uint32_t i = 0; i < sl->len; i++) { Specialized *spec = mp_vector_at(sl, Specialized, i); - if (xid == spec->xid) { + if (xid == spec->tag.sym) { spec_acc_has(mp, acc, xid); return true; } @@ -493,13 +492,13 @@ ANN static m_bool scan1_fdef_base_tmpl(const Env env, const Func_Def fdef) { MP_Vector *acc = new_mp_vector(env->gwion->mp, Symbol, 0); for(uint32_t i = 0; i < args->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); - if (!arg->td->next) { - find_op_template_type(env->gwion->mp, arg->td->xid, sl, &acc); + if (!arg->var.td->next) { + find_op_template_type(env->gwion->mp, arg->var.td->tag.sym, sl, &acc); } } const uint32_t len = acc->len; free_mp_vector(env->gwion->mp, Symbol, acc); - if (len < sl->len) ERR_B(base->pos, "too many template types for operator"); + if (len < sl->len) ERR_B(base->tag.loc, "too many template types for operator"); if (!env->curr->operators) env->curr->operators = mp_calloc(env->gwion->mp, NspcOp); const Vector v = &env->curr->operators->tmpl; @@ -519,7 +518,7 @@ ANN m_bool scan1_fptr_def(const Env env, const Fptr_Def fptr) { ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) { if (tdef->when) CHECK_BB(scan1_exp(env, tdef->when)); if(tflag(tdef->type->info->parent, tflag_ref)) - ERR_B(tdef->pos, "can't typedef a reference type"); + ERR_B(tdef->tag.loc, "can't typedef a reference type"); if (tflag(tdef->type, tflag_cdef)) return scan1_class_def(env, tdef->type->info->cdef); return tdef->type->info->cdef ? scan1_cdef(env, tdef->type) : GW_OK; @@ -528,22 +527,22 @@ ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) { ANN static inline m_bool scan1_union_def_inner_loop(const Env env, Union_Def udef) { nspc_allocdata(env->gwion->mp, udef->type->nspc); - Union_List l = udef->l; + Variable_List l = udef->l; m_uint sz = 0; - const Value v = new_value(env, env->gwion->type[et_int], "@index", udef->pos); + const Value v = new_value(env, env->gwion->type[et_int], "@index", udef->tag.loc); nspc_add_value_front(env->curr, insert_symbol("@index"), v); valuefrom(env, v->from); for(uint32_t i = 0; i < l->len; i++) { - Union_Member *um = mp_vector_at(l, Union_Member, i); + Variable *um = mp_vector_at(l, Variable, i); DECL_OB(const Type, t, = known_type(env, um->td)); - if (nspc_lookup_value0(env->curr, um->vd.xid)) - ERR_B(um->vd.pos, _("'%s' already declared in union"), s_name(um->vd.xid)) + if (nspc_lookup_value0(env->curr, um->vd.tag.sym)) + ERR_B(um->vd.tag.loc, _("'%s' already declared in union"), s_name(um->vd.tag.sym)) if(tflag(t, tflag_ref)) - ERR_B(um->vd.pos, _("can't declare ref type in union")); - const Value v = new_value(env, t, s_name(um->vd.xid), um->vd.pos); + ERR_B(um->vd.tag.loc, _("can't declare ref type in union")); + const Value v = new_value(env, t, s_name(um->vd.tag.sym), um->vd.tag.loc); tuple_contains(env, v); valuefrom(env, v->from); - nspc_add_value_front(env->curr, um->vd.xid, v); + nspc_add_value_front(env->curr, um->vd.tag.sym, v); if (t->size > sz) sz = t->size; } udef->type->nspc->offset = SZ_INT + sz; @@ -635,11 +634,11 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) { ANN static m_bool class_internal(const Env env, const Func_Base *base) { assert(base->td); if (!env->class_def) - ERR_B(base->td->pos, _("'%s' must be in class def!!"), s_name(base->xid)) + ERR_B(base->td->tag.loc, _("'%s' must be in class def!!"), s_name(base->tag.sym)) if (base->args) - ERR_B(base->td->pos, _("'%s' must not have args"), s_name(base->xid)) + ERR_B(base->td->tag.loc, _("'%s' must not have args"), s_name(base->tag.sym)) if (base->ret_type != env->gwion->type[et_void]) - ERR_B(base->td->pos, _("'%s' must return 'void'"), s_name(base->xid)) + ERR_B(base->td->tag.loc, _("'%s' must return 'void'"), s_name(base->tag.sym)) return GW_OK; } @@ -647,8 +646,8 @@ ANN static inline m_bool scan_internal_arg(const Env env, const Func_Base *base) { if (mp_vector_len(base->args) == 1) return GW_OK; assert(base->td); - ERR_B(base->td->pos, _("'%s' must have one (and only one) argument"), - s_name(base->xid)) + ERR_B(base->td->tag.loc, _("'%s' must have one (and only one) argument"), + s_name(base->tag.sym)) } ANN static inline m_bool scan_internal_int(const Env env, @@ -656,14 +655,14 @@ ANN static inline m_bool scan_internal_int(const Env env, assert(base->td); CHECK_BB(scan_internal_arg(env, base)); if (isa(base->ret_type, env->gwion->type[et_int]) > 0) return GW_OK; - ERR_B(base->td->pos, _("'%s' must return 'int'"), s_name(base->xid)) + ERR_B(base->td->tag.loc, _("'%s' must return 'int'"), s_name(base->tag.sym)) } ANN static m_bool scan_internal(const Env env, const Func_Base *base) { - const Symbol op = base->xid; + const Symbol op = base->tag.sym; if (op == insert_symbol("@dtor")) { if(safe_tflag(env->class_def, tflag_struct)) - ERR_B(base->pos, "can't use '@dtor' for structures"); + ERR_B(base->tag.loc, "can't use '@dtor' for structures"); return class_internal(env, base); } if (op == insert_symbol("@gack")) @@ -678,14 +677,14 @@ ANN static m_bool scan_internal(const Env env, const Func_Base *base) { op == insert_symbol("@each_init") || op == insert_symbol("@each_val") || op == insert_symbol("@partial")) - ERR_B(base->pos, "operator '%s' not allowed", s_name(op)); + ERR_B(base->tag.loc, "operator '%s' not allowed", s_name(op)); return GW_OK; } ANN static m_bool scan1_fdef_args(const Env env, Arg_List args) { for(uint32_t i = 0; i < args->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); - CHECK_BB(shadow_arg(env, arg->var_decl.xid, arg->var_decl.pos)); + CHECK_BB(shadow_arg(env, arg->var.vd.tag)); } return GW_OK; } @@ -716,40 +715,40 @@ ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) { ANN static inline m_bool scan1_fdef_defined(const Env env, const Func_Def fdef) { - const Value v = nspc_lookup_value1(env->curr, fdef->base->xid); + const Value v = nspc_lookup_value1(env->curr, fdef->base->tag.sym); if (!v) return GW_OK; if (is_func(env->gwion, actual_type(env->gwion, v->type))) return GW_OK; // is_callable if(fdef->builtin) return GW_OK; if ((!env->class_def || !GET_FLAG(env->class_def, final)) && - !nspc_lookup_value0(env->curr, fdef->base->xid)) - ERR_B(fdef->base->pos, + !nspc_lookup_value0(env->curr, fdef->base->tag.sym)) + ERR_B(fdef->base->tag.loc, _("function '%s' has already been defined in the same scope..."), - s_name(fdef->base->xid)) + s_name(fdef->base->tag.sym)); return GW_OK; } ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) { if(GET_FLAG(fdef->base, abstract) && !env->class_def) - ERR_B(fdef->base->pos, "file scope function can't be abstract"); - CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->pos)); + ERR_B(fdef->base->tag.loc, "file scope function can't be abstract"); + CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->tag.loc)); CHECK_BB(scan1_fdef_defined(env, fdef)); const bool global = GET_FLAG(fdef->base, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); if (tmpl_base(fdef->base->tmpl)) return scan1_fdef_base_tmpl(env, fdef); - struct Func_ fake = {.name = s_name(fdef->base->xid), .def = fdef }, *const former = + struct Func_ fake = {.name = s_name(fdef->base->tag.sym), .def = fdef }, *const former = env->func; env->func = &fake; const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)scan1_fdef); env->func = former; if (global) env_pop(env, scope); - if ((strcmp(s_name(fdef->base->xid), "@implicit") || fbflag(fdef->base, fbflag_internal)) && !fdef->builtin && fdef->base->ret_type && + if ((strcmp(s_name(fdef->base->tag.sym), "@implicit") || fbflag(fdef->base, fbflag_internal)) && !fdef->builtin && fdef->base->ret_type && fdef->base->ret_type != env->gwion->type[et_void] && fdef->d.code && !fake.memoize) - ERR_B(fdef->base->td->pos, + ERR_B(fdef->base->td->tag.loc, _("missing return statement in a non void function")); - if (fdef->base->xid == insert_symbol("@gack") && !fake.weight) { + if (fdef->base->tag.sym == insert_symbol("@gack") && !fake.weight) { gwerr_basic(_("`@gack` operator does not print anything"), NULL, - _("use `<<<` `>>>` in the function"), env->name, fdef->base->pos, 0); + _("use `<<<` `>>>` in the function"), env->name, fdef->base->tag.loc, 0); env_set_error(env, true); return GW_ERROR; } @@ -774,19 +773,20 @@ ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) { Type t = parent; do if (tdef->type == t) - ERR_O(tdef->ext->pos, _("recursive (%s <= %s) class declaration."), + ERR_O(tdef->ext->tag.loc, _("recursive (%s <= %s) class declaration."), tdef->type->name, t->name) while ((t = t->info->parent)); return parent; } ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { - const loc_t pos = cdef->base.ext->pos; + const loc_t pos = cdef->base.ext->tag.loc; if (cdef->base.ext->array && cdef->base.ext->array->exp) CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp)); DECL_OB(const Type, parent, = scan1_get_parent(env, &cdef->base)); if (isa(parent, env->gwion->type[et_object]) < 0 && - !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_udef))) +// !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_udef))) + !(tflag(cdef->base.type, tflag_cdef) || tflag(cdef->base.type, tflag_union))) ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name) if (type_ref(parent)) ERR_B(pos, _("can't use ref type in class extend")) return GW_OK; @@ -795,7 +795,7 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { ANN static inline Type scan1_final(const Env env, Type_Decl *td, const bool tdef) { DECL_OO(const Type, t, = known_type(env, td)); if (!GET_FLAG(t, final) || tdef) return t; - ERR_O(td->pos, _("can't inherit from final parent class '%s'\n."), t->name); + ERR_O(td->tag.loc, _("can't inherit from final parent class '%s'\n."), t->name); } ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { @@ -824,9 +824,9 @@ ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) { } } else mp_vector_add(mp, &body, Section, section); } - Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.pos); + Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.tag.loc); Symbol sym = insert_symbol("@ctor"); - Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.pos); + Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.tag.loc); Func_Def fdef = new_func_def(mp, fb, ctor); mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef)); free_mp_vector(mp, Section, base); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 6d473406..74bbffe5 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -31,14 +31,14 @@ ANN static inline m_bool ensure_scan2(const Env env, const Type t) { ANN static m_bool scan2_decl(const Env env, const Exp_Decl *decl) { const Type t = decl->type; CHECK_BB(ensure_scan2(env, t)); - const Var_Decl vd = decl->vd; - nspc_add_value(env->curr, vd.xid, vd.value); + const Var_Decl vd = decl->var.vd; + nspc_add_value(env->curr, vd.tag.sym, vd.value); return GW_OK; } ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl *decl) { if(decl->args) CHECK_BB(scan2_exp(env, decl->args)); - const bool global = GET_FLAG(decl->td, global); + const bool global = GET_FLAG(decl->var.td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); const m_bool ret = scan2_decl(env, decl); if (global) env_pop(env, scope); @@ -49,7 +49,7 @@ ANN static m_bool scan2_args(const Func_Def f) { Arg_List args = f->base->args; for(uint32_t i = 0; i < args->len; i++) { Arg *arg = mp_vector_at(args, Arg, i); - const Value v = arg->var_decl.value; + const Value v = arg->var.vd.value; v->from->offset = f->stack_depth; f->stack_depth += v->type->size; set_vflag(v, vflag_arg); @@ -278,22 +278,22 @@ ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) { if (!is_func(env->gwion, overload->type)) { if (!fbflag(f->base, fbflag_internal)) - ERR_B(f->base->pos, + ERR_B(f->base->tag.loc, _("function name '%s' is already used by another value"), overload->name) } const Func obase = overload->d.func_ref; if (GET_FLAG(obase->def->base, final) && (!env->class_def || (obase->value_ref->from->owner_class != env->class_def))) { - env_err(env, f->base->pos, _("can't overload final function `{G}%s{0}`"), s_name(f->base->xid)); + env_err(env, f->base->tag.loc, _("can't overload final function `{G}%s{0}`"), s_name(f->base->tag.sym)); declared_here(obase->value_ref); return GW_ERROR; } const m_bool base = tmpl_base(f->base->tmpl); const m_bool tmpl = fflag(obase, fflag_tmpl); if ((!tmpl && base) || (tmpl && !base && !f->base->tmpl)) - ERR_B(f->base->pos, _("must overload template function with template")) + ERR_B(f->base->tag.loc, _("must overload template function with template")) if (GET_FLAG(f->base, global) != GET_FLAG(obase->def->base, global)) - ERR_B(f->base->pos, _("function is declared global")) // improve me + ERR_B(f->base->tag.loc, _("function is declared global")) // improve me return GW_OK; } @@ -321,20 +321,20 @@ ANN static Type func_type(const Env env, const Func func) { ANN static void func_no_overload(const Env env, const Func f, const Value v) { const Type t = v->type; value_addref(v); - nspc_add_value_front(env->curr, f->def->base->xid, v); + nspc_add_value_front(env->curr, f->def->base->tag.sym, v); const Type newt = type_copy(env->gwion->mp, t); t->info->parent = newt; - newt->name = s_name(f->def->base->xid); + newt->name = s_name(f->def->base->tag.sym); newt->info->func = f; - nspc_add_type_front(env->curr, f->def->base->xid, newt); + nspc_add_type_front(env->curr, f->def->base->tag.sym, newt); newt->info->value = v; } ANN2(1, 2) static Value func_value(const Env env, const Func f, const Value overload) { const Type t = func_type(env, f); - const Value v = t->info->value = new_value(env, t, t->name, f->def->base->pos); + const Value v = t->info->value = new_value(env, t, t->name, f->def->base->tag.loc); valuefrom(env, v->from); CHECK_OO(scan2_func_assign(env, f->def, f, v)); if (!overload) @@ -351,7 +351,7 @@ static Value func_value(const Env env, const Func f, const Value overload) { ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Value overload) { - const m_str name = s_name(f->base->xid); + const m_str name = s_name(f->base->tag.sym); const Func func = scan_new_func(env, f, name); const Value value = func_value(env, func, overload); set_fflag(func, fflag_tmpl); @@ -362,7 +362,7 @@ static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, Nspc nspc = env->curr; uint i = 0; do { - const Value v = nspc_lookup_value0(nspc, f->base->xid); + const Value v = nspc_lookup_value0(nspc, f->base->tag.sym); if (v) { Func ff = v->d.func_ref; if (!ff) continue; @@ -373,14 +373,14 @@ static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, } if (compat_func(ff->def, f) > 0) { if (ff->value_ref->from->owner == env->curr) - ERR_B(f->base->pos, + ERR_B(f->base->tag.loc, "template function '%s' already defined with those arguments " "in this namespace", name) const Symbol sym = func_symbol(env, env->curr->name, name, "template", ff->def->vt_index); nspc_add_value(env->curr, sym, value); - if (!overload) nspc_add_value(env->curr, f->base->xid, value); + if (!overload) nspc_add_value(env->curr, f->base->tag.sym, value); nspc_add_func(env->curr, sym, func); func->def->vt_index = ff->def->vt_index; return GW_OK; @@ -392,17 +392,17 @@ static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Symbol sym = func_symbol(env, env->curr->name, name, "template", i); nspc_add_value(env->curr, sym, value); nspc_add_func(env->curr, sym, func); - if (!overload) nspc_add_value(env->curr, f->base->xid, value); + if (!overload) nspc_add_value(env->curr, f->base->tag.sym, value); else func->def->vt_index = ++overload->from->offset; 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 m_str str = s_name(f->base->tag.sym); struct Op_Func opfunc = {.ck = strcmp(str, "@implicit") ? 0 : opck_usr_implicit}; struct Op_Import opi = {.ret = f->base->ret_type, - .pos = f->base->pos, + .pos = f->base->tag.loc, .data = (uintptr_t)f->base->func, .func = &opfunc}; func_operator(f, &opi); @@ -430,14 +430,14 @@ ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) { ANN static void scan2_func_def_flag(const Env env, const Func_Def f) { set_fflag(f->base->func, fflag_pure); - if (f->base->xid == insert_symbol("@dtor")) + if (f->base->tag.sym == insert_symbol("@dtor")) set_tflag(env->class_def, tflag_dtor); } ANN static m_str func_tmpl_name(const Env env, const Func_Def f) { - const m_str name = s_name(f->base->xid); - m_str tmpl_name = tl2str(env->gwion, f->base->tmpl->call, f->base->pos); + const m_str name = s_name(f->base->tag.sym); + m_str tmpl_name = tl2str(env->gwion, f->base->tmpl->call, f->base->tag.loc); const Symbol sym = func_symbol(env, env->curr->name, name, tmpl_name, (m_uint)f->vt_index); return s_name(sym); @@ -457,7 +457,7 @@ static Value func_create(const Env env, const Func_Def f, const Value overload, ANN2(1, 2) static m_str func_name(const Env env, const Func_Def f, const Value v) { if (!f->base->tmpl) { - const Symbol sym = func_symbol(env, env->curr->name, s_name(f->base->xid), + const Symbol sym = func_symbol(env, env->curr->name, s_name(f->base->tag.sym), NULL, v ? ++v->from->offset : 0); return s_name(sym); } @@ -483,7 +483,7 @@ m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value overload) { //! use function from parent class as next. ANN static void upfunction(const Env env, const Func_Base *fb) { - const Value v = find_value(env->class_def->info->parent, fb->xid); + const Value v = find_value(env->class_def->info->parent, fb->tag.sym); if (!v) return; Func func = fb->func; while (func->next && func->next->value_ref->from->owner == env->curr) @@ -492,7 +492,7 @@ ANN static void upfunction(const Env env, const Func_Base *fb) { } ANN m_bool scan2_fdef(const Env env, const Func_Def fdef) { - const Value overload = nspc_lookup_value2(env->curr, fdef->base->xid); + const Value overload = nspc_lookup_value2(env->curr, fdef->base->tag.sym); if (overload) CHECK_BB(scan2_func_def_overload(env, fdef, overload)); CHECK_BB((!tmpl_base(fdef->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)( env, fdef, overload)); @@ -519,7 +519,7 @@ ANN m_bool _scan2_func_def(const Env env, const Func_Def fdef) { return GW_OK; if(is_new(fdef)) { if(!env->class_def) - ERR_B(fdef->base->pos, _("{G+}new{0} operator must be set inside {C+}class{0}")); + ERR_B(fdef->base->tag.loc, _("{G+}new{0} operator must be set inside {C+}class{0}")); SET_FLAG(env->class_def, abstract); if(!fdef->base->ret_type) // fdef->base->ret_type = env->class_def; diff --git a/src/parse/spread.c b/src/parse/spread.c index 923efdf3..7e232196 100644 --- a/src/parse/spread.c +++ b/src/parse/spread.c @@ -22,8 +22,8 @@ ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl) // 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, targ.d.td->pos); - sprintf(c, "%s=%s", s_name(spread->xid), type); + const m_str type = type2str(env->gwion, t, targ.d.td->tag.loc); + sprintf(c, "%s=%s", s_name(spread->tag.sym), type); free_mstr(env->gwion->mp, type); pparg_add(env->gwion->ppa, c); for(uint32_t j = 0; j < spread->list->len; j++) { @@ -32,8 +32,8 @@ ANN m_bool spread_ast(const Env env, const Spread_Def spread, const Tmpl *tmpl) sprintf(c, "%s=%s%u", name, name, i); pparg_add(env->gwion->ppa, c); } - Ast ast = parse_pos(&arg, spread->pos); - pparg_rem(env->gwion->ppa, s_name(spread->xid)); + Ast ast = parse_pos(&arg, spread->tag.loc.first); + pparg_rem(env->gwion->ppa, s_name(spread->tag.sym)); for(uint32_t j = 0; j < spread->list->len;j++) { const Symbol sym = *mp_vector_at(spread->list, Symbol, j); m_str name = s_name(sym); diff --git a/src/parse/template.c b/src/parse/template.c index c44a7977..bea9160a 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -4,6 +4,7 @@ #include "vm.h" #include "traverse.h" #include "template.h" +#include "tmp_resolve.h" #include "vm.h" #include "parse.h" #include "gwion.h" @@ -19,7 +20,7 @@ ANN static m_bool _push_types(const Env env, const Nspc nspc, Type_List tl = tmpl->call; Specialized *spec = mp_vector_at(sl, Specialized, sl->len - 1); - const uint32_t len = strcmp(s_name(spec->xid), "...") ? sl->len : sl->len-1; + const uint32_t len = strcmp(s_name(spec->tag.sym), "...") ? sl->len : sl->len-1; if(!tl) return GW_OK; for(uint32_t i = 0; i < len; i++) { if (i >= tl->len) return GW_OK; @@ -27,7 +28,7 @@ ANN static m_bool _push_types(const Env env, const Nspc nspc, 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); + nspc_add_type(nspc, spec->tag.sym, t); }; if(len != sl->len) return GW_OK; return tl->len == sl->len ? GW_OK : GW_ERROR; @@ -50,9 +51,9 @@ ANN static m_bool push_types(const Env env, const Nspc nspc, const Tmpl *tmpl) { ANN static m_bool _template_push(const Env env, const Type t) { if (t->info->value->from->owner_class) CHECK_BB(template_push(env, t->info->value->from->owner_class)); - if (tflag(t, tflag_tmpl)) - return push_types(env, t->nspc, t->info->cdef->base.tmpl); // incorrect - return GW_OK; + return tflag(t, tflag_tmpl) + ? push_types(env, t->nspc, get_tmpl(t)) + : GW_OK; } ANN m_bool template_push(const Env env, const Type t) { @@ -61,24 +62,37 @@ ANN m_bool template_push(const Env env, const Type t) { } #include +ANN Exp td2exp(const MemPool mp, const Type_Decl *td); ANN void check_call(const Env env, const Tmpl *tmpl) { for(uint32_t i = 0; i < tmpl->call->len; i++) { 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"); +//if(targ->type != tmplarg_td) exit(16); +if(targ->type == tmplarg_td) { + if(spec && strcmp(s_name(spec->tag.sym), "...")) { +if(unlikely(spec->td)) { +if(targ->type == tmplarg_td) { +targ->type = tmplarg_exp; +const Exp exp = td2exp(env->gwion->mp, targ->d.td); +targ->d.exp = exp; + +} +} +else if(spec->tag.sym == targ->d.td->tag.sym) { + if (!nspc_lookup_type1(env->curr, spec->tag.sym)) + targ->d.td->tag.sym = 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); + const Type t = nspc_lookup_type1(env->curr, spec->tag.sym); + Type_Decl *td = type2td(env->gwion, t, targ->d.td->tag.loc); free_type_decl(env->gwion->mp, targ->d.td); targ->d.td = td; } - } + } else { // normal case?r +//exit(11 + !!spec->xid); + } +} } else { //if(targ->type == tmplarg_td) // targ->d.td->xid = insert_symbol("auto"); @@ -101,7 +115,7 @@ ANN Tmpl *mk_tmpl(const Env env, const Tmpl *tm, const Type_List types) { } static ANN Type scan_func(const Env env, const Type t, const Type_Decl *td) { - DECL_OO(const m_str, tl_name, = tl2str(env->gwion, td->types, td->pos)); + DECL_OO(const m_str, tl_name, = tl2str(env->gwion, td->types, td->tag.loc)); const Symbol sym = func_symbol(env, t->info->value->from->owner->name, t->info->func->name, tl_name, 0); free_mstr(env->gwion->mp, tl_name); @@ -119,7 +133,7 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl *td) { const Func_Def def = cpy_func_def(env->gwion->mp, t->info->func->def); const Func func = ret->info->func = new_func(env->gwion->mp, s_name(sym), def); - const Value value = new_value(env, ret, s_name(sym), def->base->pos); + const Value value = new_value(env, ret, s_name(sym), def->base->tag.loc); func->flag = def->base->flag; if (vflag(t->info->func->value_ref, vflag_member)) set_vflag(value, vflag_member); @@ -141,7 +155,7 @@ static ANN Type scan_func(const Env env, const Type t, const Type_Decl *td) { static ANN Type maybe_func(const Env env, const Type t, const Type_Decl *td) { if (is_func(env->gwion, t) && t->info->func->def->base->tmpl) // is_callable needs type return scan_func(env, t, td); - ERR_O(td->pos, + ERR_O(td->tag.loc, _("type '%s' is not template. You should not provide template types"), t->name) } @@ -149,51 +163,40 @@ static ANN Type maybe_func(const Env env, const Type t, const Type_Decl *td) { static ANN bool is_single_variadic(const MP_Vector *v) { if(v->len != 1) return false; const Specialized *spec = mp_vector_at(v, Specialized, 0); - return !strcmp(s_name(spec->xid), "..."); + return !strcmp(s_name(spec->tag.sym), "..."); } -ANN2(1,2) static m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread) { +ANN2(1,2) m_bool check_tmpl(const Env env, const Type_List tl, const Specialized_List sl, const loc_t pos, const bool is_spread) { 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++) { TmplArg *arg = mp_vector_at(tl, TmplArg, i); Specialized *spec = mp_vector_at(sl, Specialized, i); 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"); + 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); + if(t) { + arg->type = tmplarg_exp; + Exp e = new_exp_td(env->gwion->mp, base, base->tag.loc); + arg->d.exp = new_exp_dot(env->gwion->mp, e, last->tag.sym, base->tag.loc); + free_type_decl(env->gwion->mp, last); + i--; + continue; + } + next->next = last; + } + ERR_B(pos, "template type argument mismatch. expected %s", + spec->td ? "constant" : "type"); } DECL_OB(const Type, t, = known_type(env, arg->d.td)); @@ -205,20 +208,15 @@ i--;continue; } } } else { - if(!spec->td) { - ERR_B(pos, "template const argument mismatch. expected %s", - spec->td ? "constant" : "type"); + 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"); + CHECK_OB(check_exp(env, arg->d.exp)); + 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); } } return GW_OK; @@ -227,15 +225,16 @@ if(isa(arg->d.exp->type,t) < 0) ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) { if (tflag(t, tflag_tmpl) && !is_func(env->gwion, t)) { // is_callable if (tflag(t, tflag_ntmpl) && !td->types) return t; - const bool single_variadic = is_single_variadic(t->info->cdef->base.tmpl->list); + Tmpl *tmpl = get_tmpl(t); + const bool single_variadic = is_single_variadic(tmpl->list); if(!td->types) { - const Type new_type = nspc_lookup_type1(env->curr, td->xid); - Type_Decl *new_td = type2td(env->gwion, new_type, td->pos); + const Type new_type = nspc_lookup_type1(env->curr, td->tag.sym); + Type_Decl *new_td = type2td(env->gwion, new_type, td->tag.loc); Type_Decl *d = new_td; while(d->next) d = d->next; if(!d->types) { if(!single_variadic) - ERR_O(td->pos, _("you must provide template types for type '%s'"), t->name); + ERR_O(td->tag.loc, _("you must provide template types for type '%s'"), t->name); d->types = new_mp_vector(env->gwion->mp, TmplArg, 0); } const Type ret = _scan_type(env, t, d); @@ -244,14 +243,14 @@ ANN static Type _scan_type(const Env env, const Type t, Type_Decl *td) { } struct TemplateScan ts = {.t = t, .td = td}; Type_List tl = td->types; - Specialized_List sl = t->info->cdef->base.tmpl - ? t->info->cdef->base.tmpl->list : NULL; - const bool is_spread = is_spread_tmpl(t->info->cdef->base.tmpl); - if(!single_variadic) CHECK_BO(check_tmpl(env, tl, sl, td->pos, is_spread)); + Specialized_List sl = tmpl + ? tmpl->list : NULL; + const bool is_spread = is_spread_tmpl(tmpl); + if(!single_variadic) CHECK_BO(check_tmpl(env, tl, sl, td->tag.loc, is_spread)); struct Op_Import opi = {.op = insert_symbol("class"), .lhs = t, .data = (uintptr_t)&ts, - .pos = td->pos}; + .pos = td->tag.loc}; return op_check(env, &opi); } else if (td->types) return maybe_func(env, t, td); @@ -266,7 +265,7 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl *td) { const Type owner = array_base_simple(maybe_array); td->next = next; CHECK_OO(owner); - if (!owner->nspc) ERR_O(td->pos, "type '%s' has no namespace", owner->name) + if (!owner->nspc) ERR_O(td->tag.loc, "type '%s' has no namespace", owner->name) struct EnvSet es = {.env = env, .data = env, .scope = env->scope->depth, diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index a95f1ed3..c2435988 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -15,8 +15,7 @@ ANN static Type _option(const Env env, Type_Decl *td, const uint8_t n) { 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}; + Type_Decl tmp = { .tag = MK_TAG(insert_symbol("Option"), td->tag.loc), .types = tl }; const Type t = !(n - 1) ? known_type(env, &tmp) : _option(env, &tmp, n - 1); free_mp_vector(env->gwion->mp, TmplArg, tl); td->array = array; @@ -35,7 +34,7 @@ ANN static Type _ref(const Env env, Type_Decl *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}; + Type_Decl tmp = {.tag = MK_TAG(insert_symbol("Ref"), td->tag.loc), .types = tl}; const Type t = known_type(env, &tmp); free_mp_vector(env->gwion->mp, TmplArg, tl); return t; @@ -53,7 +52,7 @@ ANN static Symbol symname(const Env env, Func_Base *const base, bool *global) { text_init(&text, env->gwion->mp); text_add(&text, "("); DECL_OO(const Type, t, = known_type(env, base->td)); - DECL_OO(const m_str, name, = type2str(env->gwion, t, base->td->pos)); + DECL_OO(const m_str, name, = type2str(env->gwion, t, base->td->tag.loc)); text_add(&text, name); free_mstr(env->gwion->mp, name); text_add(&text, "("); @@ -62,8 +61,8 @@ ANN static Symbol symname(const Env env, Func_Base *const base, bool *global) { for(uint32_t i = 0; i < base->args->len; i++) { if(i) text_add(&text, ","); Arg *arg = mp_vector_at(base->args, Arg, i); - DECL_OO(const Type, t, = known_type(env, arg->td)); - DECL_OO(const m_str, name, = type2str(env->gwion, t, arg->td->pos)); + DECL_OO(const Type, t, = known_type(env, arg->var.td)); + DECL_OO(const m_str, name, = type2str(env->gwion, t, arg->var.td->tag.loc)); text_add(&text, name); free_mstr(env->gwion->mp, name); if(*global) @@ -72,15 +71,15 @@ ANN static Symbol symname(const Env env, Func_Base *const base, bool *global) { } text_add(&text, ")"); text_add(&text, ")"); - base->xid = insert_symbol(text.str); + base->tag.sym = insert_symbol(text.str); text_release(&text); - return base->xid; + return base->tag.sym; } ANN static inline Type find(const Env env, Type_Decl *td) { if (!td->fptr) return find_type(env, td); bool global = false; - CHECK_OO((td->xid = symname(env, td->fptr->base, &global))); + CHECK_OO((td->tag.sym = symname(env, td->fptr->base, &global))); const Fptr_Def fptr = td->fptr; td->fptr = NULL; const Type exists = find_type(env, td); @@ -109,7 +108,7 @@ ANN static Type resolve(const Env env, Type_Decl *td) { while (last->next) last = last->next; DECL_OO(const Type, base, = find(env, td)); const Context ctx = base->info->value->from->ctx; - if (ctx && ctx->error) ERR_O(td->pos, _("type '%s' is invalid"), base->name) + if (ctx && ctx->error) ERR_O(td->tag.loc, _("type '%s' is invalid"), base->name) DECL_OO(const Type, type, = find1(env, base, td)); DECL_OO(const Type, t, = !td->ref ? type : ref(env, td)); DECL_OO(const Type, ret, = !td->option ? t : option(env, td)); @@ -118,7 +117,7 @@ ANN static Type resolve(const Env env, Type_Decl *td) { } ANN static inline void *type_unknown(const Env env, const Type_Decl *td) { - env_err(env, td->pos, _("unknown type '%s'"), s_name(td->xid)); + env_err(env, td->tag.loc, _("unknown type '%s'"), s_name(td->tag.sym)); return NULL; } diff --git a/tests/driver/simple_driver.c b/tests/driver/simple_driver.c index 78a22594..7bcede9c 100644 --- a/tests/driver/simple_driver.c +++ b/tests/driver/simple_driver.c @@ -2,8 +2,6 @@ #include "gwion_ast.h" #include "gwion_env.h" #include "vm.h" -#include "plug.h" -#include "driver.h" #include "gwion.h" static DRVRUN(simple_driver_run) { diff --git a/tests/error/template_unknown.gw b/tests/error/template_unknown.gw index d3b6ca2f..64b3d840 100644 --- a/tests/error/template_unknown.gw +++ b/tests/error/template_unknown.gw @@ -1,4 +1,4 @@ -#! [contains] unknown type +#! [contains] Invalid variable unknown_type fun void my_function:[A]() { <<< "test" >>>; } my_function:[unknown_type](); diff --git a/tests/union/union_ref.gw b/tests/union/union_ref.gw index c560ebdc..93e64609 100644 --- a/tests/union/union_ref.gw +++ b/tests/union/union_ref.gw @@ -1,3 +1,4 @@ +#! [contains] can't declare ref type in union union U { &int i; } diff --git a/tests/usr_op/op_tmpl.gw b/tests/usr_op/op_tmpl.gw index 032cd6b8..0ce3d07d 100644 --- a/tests/usr_op/op_tmpl.gw +++ b/tests/usr_op/op_tmpl.gw @@ -1,3 +1,3 @@ -operator int --- :[A,C] (A i, C j) { return i;} +operator int --- :[A,C] (A i, C j) { var C c; return i;} <<< 1 --- 2 >>>; <<< 2 --- 2 >>>; -- 2.43.0