From: fennecdjay Date: Thu, 7 Nov 2024 10:14:53 +0000 (+0100) Subject: :fire: named parameters X-Git-Tag: nightly~2 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=25b37f8e086f4c68a1edcd29c872ee6a239b957f;p=gwion.git :fire: named parameters --- diff --git a/ast b/ast index 4a237db7..bf2ac162 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 4a237db7d547d5b132ffcdb4489ed67126e67e69 +Subproject commit bf2ac162a45d024461ed046fb4af500566a10f54 diff --git a/include/parse.h b/include/parse.h index 4d2a2529..c321a1e3 100644 --- a/include/parse.h +++ b/include/parse.h @@ -169,7 +169,7 @@ ANN bool abstract_array(const Env env, const Array_Sub array); ANN static inline bool is_static_call(const Gwion gwion, Exp* e) { if (e->exp_type != ae_exp_dot) return true; const Exp_Dot *member = &e->d.exp_dot; - if(unlikely(!strcmp(s_name(member->xid), "new"))) return true; + if(unlikely(!strcmp(s_name(member->tag.sym), "new"))) return true; return GET_FLAG(e->type, final) || GET_FLAG(member->base->type, final) || is_class(gwion, member->base->type) || diff --git a/src/clean.c b/src/clean.c index e66ea2e6..85cfa780 100644 --- a/src/clean.c +++ b/src/clean.c @@ -132,6 +132,10 @@ ANN static void clean_exp_td(Clean *a, Type_Decl **b) { clean_type_decl(a, *b); } +ANN static void clean_exp_named(Clean *a, Exp_Named *b) { + clean_exp(a, b->exp); +} + DECL_EXP_FUNC(clean, void, Clean *) ANN static void clean_exp(Clean *a, Exp* b) { clean_exp_func[b->exp_type](a, &b->d); diff --git a/src/emit/emit.c b/src/emit/emit.c index 20678f40..72146263 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -18,7 +18,6 @@ #include "match.h" #include "specialid.h" #include "looper.h" -#include "shreduler_private.h" #undef insert_symbol #define insert_symbol(a) insert_symbol(emit->gwion->st, (a)) @@ -1909,9 +1908,13 @@ ANN static bool emit_exp_td(const Emitter emit, Type_Decl *td) { return true; } +ANN static bool emit_exp_named(const Emitter emit, Exp_Named *exp) { +// gw_out("these should be changed in verify pass"); + return emit_exp(emit, exp->exp); +} DECL_EXP_FUNC(emit, bool, Emitter) -ANN2(1) /*static */ bool emit_exp(const Emitter emit, /* const */ Exp* e) { +ANN2(1) bool emit_exp(const Emitter emit, /* const */ Exp* e) { Exp* exp = e; do { if (emit->info->debug){ diff --git a/src/import/import_checker.c b/src/import/import_checker.c index 9ea38f16..b3ac3acd 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -320,7 +320,7 @@ 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); + base = new_exp_dot(mp, base, next->tag, td->tag.loc); next = next->next; } return base; @@ -358,7 +358,7 @@ ANEW ANN m_str type2str(const Gwion gwion, const Type t, ANEW ANN m_str tl2str(const Gwion gwion, const TmplArg_List tl, const loc_t loc NUSED) { - struct GwfmtState ls = {.minimize=true, .ppa = gwion->ppa}; + struct GwfmtState ls = {.minimize=true, .ppa = gwion->ppa, .color=false}; gwfmt_state_init(&ls); text_init(&ls.text, gwion->mp); Gwfmt gwfmter = {.mp = gwion->mp, .st = gwion->st, .ls = &ls, .line = 1, .last = cht_nl }; diff --git a/src/import/import_oper.c b/src/import/import_oper.c index 1f6e1afb..33ed1811 100644 --- a/src/import/import_oper.c +++ b/src/import/import_oper.c @@ -1,6 +1,3 @@ -#include -#include -#include #include "gwion_util.h" #include "gwion_ast.h" #include "gwion_env.h" @@ -13,8 +10,6 @@ #include "operator.h" #include "import.h" #include "gwi.h" -#include "mpool.h" -#include "specialid.h" ANN static Type _get_type(const Gwi gwi, const m_str s) { if (s == (m_str)OP_ANY_TYPE) return OP_ANY_TYPE; @@ -30,7 +25,8 @@ static bool import_op(const Gwi gwi, struct OperCK *const op, const f_instr f) { const Type lhs = gwi_get_type(gwi, op->lhs), rhs = gwi_get_type(gwi, op->rhs), ret = gwi_get_type(gwi, op->ret); const struct Op_Func opfunc = { - .ck = op->ck, .em = op->em, .effect = {.ptr = op->effect.ptr}}; + .ck = op->ck, .em = op->em, + .effect = {.ptr = op->effect.ptr}}; const struct Op_Import opi = {.lhs = lhs, .rhs = rhs, .ret = ret, @@ -52,7 +48,7 @@ bool gwi_oper_ini(const Gwi gwi, const restrict m_str l, return true; } -ANN bool gwi_oper_add(const Gwi gwi, Type (*ck)(Env, void *)) { +ANN bool gwi_oper_add(const Gwi gwi, const opck ck) { gwi->oper->ck = ck; return true; } diff --git a/src/lib/deep_equal.c b/src/lib/deep_equal.c index f442dd0b..f6538275 100644 --- a/src/lib/deep_equal.c +++ b/src/lib/deep_equal.c @@ -69,17 +69,20 @@ ANN static inline void check_deep_equal_exp(const Env env, Exp* e, const Vector exp_setvar(e, true); } -#define MK_DOT(_data, _exp, _value) \ - { \ - .d = { \ - .exp_dot = { \ - .base = _exp, \ - .xid = insert_symbol(_data->gwion->st, _value->name) \ - } \ - }, \ - .type = _value->type, \ - .exp_type = ae_exp_dot, \ - .loc = _exp->loc \ +#define MK_DOT(_data, _exp, _value) \ + { \ + .d = { \ + .exp_dot = { \ + .base = _exp, \ + .tag = { \ + .sym = insert_symbol(_data->gwion->st, _value->name), \ + .loc = _exp->loc \ + } \ + } \ + }, \ + .type = _value->type, \ + .exp_type = ae_exp_dot, \ + .loc = _exp->loc \ } #define MK_BIN(_lhs, _rhs, _bin) \ diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 99a591fb..41a94896 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -173,13 +173,13 @@ ANN static inline void emit_struct_data(const Emitter emit, const Value v, ANN static inline Value get_value(const Env env, const Exp_Dot *member, const Type t) { - const Value value = find_value(t, member->xid); + const Value value = find_value(t, member->tag.sym); if (value) return value; if (env->func && env->func->def->base->values) - return upvalues_lookup(env->func->def->base->values, member->xid); + return upvalues_lookup(env->func->def->base->values, member->tag.sym); if(t->info->values) - return (Value)scope_lookup1(t->info->values, (m_uint)member->xid); + return (Value)scope_lookup1(t->info->values, (m_uint)member->tag.sym); return NULL; } @@ -200,20 +200,20 @@ ANN static bool member_access(const Env env, Exp* exp, const Value value) { OP_CHECK(opck_object_dot) { Exp_Dot *const member = (Exp_Dot *)data; Exp* self = exp_self(member); - const m_str str = s_name(member->xid); + const m_str str = s_name(member->tag.sym); const bool base_static = is_class(env->gwion, member->base->type); const Type the_base = base_static ? _class_base(member->base->type) : member->base->type; const Value value = get_value(env, member, the_base); if (!value) { - const Value v = nspc_lookup_value1(env->curr, member->xid); + const Value v = nspc_lookup_value1(env->curr, member->tag.sym); if(v) { if (self->is_call) { if (is_func(env->gwion, v->type) && (!v->from->owner_class || isa(the_base, v->from->owner_class))) // is_callable needs type return v->type; } } - env_err(env, self->loc, _("class '%s' has no member '%s'"), + env_err(env, member->tag.loc, _("class '%s' has no member '%s'"), the_base->name, str); if (member->base->type->nspc) did_you_mean_type(the_base, str); return env->gwion->type[et_error]; @@ -237,7 +237,7 @@ ANN static Type member_type(const Gwion gwion, const Type base) { OP_EMIT(opem_object_dot) { const Exp_Dot *member = (Exp_Dot *)data; const Type t_base = member_type(emit->gwion, member->base->type); - const Value value = find_value(t_base, member->xid); + const Value value = find_value(t_base, member->tag.sym); if (is_class(emit->gwion, value->type)) { emit_pushimm(emit, (m_uint)value->type); return true; diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 794ca80b..0c22f150 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -73,7 +73,7 @@ OP_CHECK(opck_rassign) { const Exp_Binary *bin = (Exp_Binary *)data; if (opck_const_rhs(env, data) == env->gwion->type[et_error]) return env->gwion->type[et_error]; - exp_setvar(bin->rhs, 1); + exp_setvar(bin->rhs, true); return bin->rhs->type; } @@ -140,7 +140,7 @@ OP_CHECK(opck_new) { Exp* args = cpy_exp(env->gwion->mp, unary->ctor.exp); Exp* base = new_exp_unary2(env->gwion->mp, unary->op, unary->ctor.td, unary->ctor.exp, self->loc); base->type = t; - Exp* func = new_exp_dot(env->gwion->mp, base, insert_symbol("new"), self->loc); + Exp* func = new_exp_dot(env->gwion->mp, base, MK_TAG(insert_symbol("new"), self->loc), self->loc); self->d.exp_call.func = func; self->d.exp_call.args = args; self->d.exp_call.tmpl = NULL; diff --git a/src/lib/prim.c b/src/lib/prim.c index ebb41be3..1a3144eb 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -497,7 +497,7 @@ static inline int is_now(const Env env, Exp* exp) { static OP_CHECK(opck_now) { const Exp_Binary *bin = (Exp_Binary *)data; if (!is_now(env, bin->rhs)) CHECK_NN(opck_const_rhs(env, data)); - exp_setvar(bin->rhs, 1); + exp_setvar(bin->rhs, true); return bin->rhs->type; } diff --git a/src/lib/sift.c b/src/lib/sift.c index f64ce856..fefff660 100644 --- a/src/lib/sift.c +++ b/src/lib/sift.c @@ -37,7 +37,7 @@ static OP_CHECK(opck_ctrl) { Exp* exp = exp_self(data); Exp* func = cpy_exp(mp, exp); - Exp* dot = new_exp_dot(mp, func->d.exp_binary.lhs, insert_symbol(env->gwion->st, "last"), func->loc); + Exp* dot = new_exp_dot(mp, func->d.exp_binary.lhs, MK_TAG(insert_symbol(env->gwion->st, "last"), func->loc), func->loc); Exp* call = new_exp_call(mp, dot, NULL, func->loc); func->d.exp_binary.lhs = call; func->d.exp_binary.op = chuck; diff --git a/src/lib/union.c b/src/lib/union.c index d9284898..a2b8d9ad 100644 --- a/src/lib/union.c +++ b/src/lib/union.c @@ -31,22 +31,105 @@ static INSTR(UnionIndex) { // probs exosts already *(m_uint*)REG(-SZ_INT) = **(m_uint**)REG(-SZ_INT); } + +static bool needs_reset(const Env env, const Exp *base) { + return base->cast_to +// && isa(base->cast_t + && strcmp(*(m_str*)base->cast_to->nspc->class_data, env->curr->name); +} + +// TODO: put in header, check other uses +OP_CHECK(opck_object_dot); + +OP_EMIT(opem_setunion_implicit) { exit(19);} + +OP_CHECK(opck_setunion_class) { + struct TemplateScan *ts = (struct TemplateScan *)data; + const Type base = known_type(env, mp_vector_at(ts->td->types, TmplArg, 0)->d.td); + const m_str name = mp_vector_at(ts->td->types, TmplArg, 1)->d.exp->d.prim.d.string.data; + char buf[256]; + snprintf(buf, 256, "FlowType:[%s,\"%s\",\"%s\"]", + base->name, name, env->curr->name); // vector_at 1 + const Type t = type_copy(env->gwion->mp, base); + t->name = s_name(insert_symbol(env->gwion->st, buf)); + t->info->parent = ts->t; // check if not set by copy + t->info->base_type = base; + t->nspc = new_nspc(env->gwion->mp, t->name); + t->nspc->class_data_size = 16; + nspc_allocdata(env->gwion->mp, t->nspc); + *(m_str*)t->nspc->class_data = s_name(insert_symbol(env->gwion->st, name)); + *(m_str*)(t->nspc->class_data+SZ_INT) = s_name(insert_symbol(env->gwion->st, env->name)); + return t; +} + +OP_CHECK(opck_setunion_implicit) { + exit(87); +} + +static Value find_dot_value(const Env env, const Exp *exp) { +// if(exp->exp_type == ae_exp_dot) +// return find_dot_value( + if(exp->exp_type == ae_exp_primary && exp->d.prim.prim_type == ae_prim_id) + return nspc_lookup_value1(env->curr, exp->d.prim.d.var); + return NULL; +} + +static OP_CHECK(opck_setunion_dot) { + const Exp_Dot *member = (Exp_Dot *)data; + const Type set_t = member->base->type; + const Type t = member->base->type->info->base_type; + member->base->type = t; + const Type ret = opck_object_dot(env, data); + member->base->type = set_t; + return ret; +} + +static OP_CHECK(opck_setunion_dot2) { + puts(__func__); + const Exp_Dot *member = (Exp_Dot *)data; + puts(member->base->type->name); + const m_str name = *(m_str*)member->base->type->nspc->class_data; + if(!exp_getvar(exp_self(member)) && strcmp(s_name(member->tag.sym), name)) { + // change member->base->loc to member->tag.loc + char buf[256]; + sprintf(buf, "expected {G}%s{0}", name); + gwlog_error("invalid union access", buf, env->name, member->base->loc, 0); + return env->gwion->type[et_error]; + } + member->base->type = member->base->type->info->base_type; + return exp_self(member)->type; +} + +static OP_CHECK(opck_union_dot) { + const Exp_Dot *member = (Exp_Dot *)data; + find_dot_value(env, member->base); + DECL_NN(const Type, ret, = opck_object_dot(env, data)); +/* + char buf[256]; + snprintf(buf, 256, "FlowType:[%s,\"%s\",\"%s\"]", + member->base->type->name, s_name(member->xid), env->curr->name); + const Value v = find_dot_value(env, member->base); + if(v) + v->type = str2type(env->gwion, buf, member->base->loc); +*/ + return ret; +} + static OP_EMIT(opem_union_dot) { const Exp_Dot *member = (Exp_Dot *)data; - const Map map = &member->base->type->nspc->info->value->map; exp_setvar(member->base, true); CHECK_B(emit_exp(emit, member->base)); if (is_func(emit->gwion, exp_self(member)->type)) { // is_callable? can only be a func emit_pushimm(emit, (m_uint)exp_self(member)->type->info->func->code); return true; } - if (!strcmp(s_name(member->xid), "index")) { - //emit_add_instr(emit, DotMember); + if (!strcmp(s_name(member->tag.sym), "index")) { emit_add_instr(emit, UnionIndex); return true; } + const Map map = &member->base->type->nspc->info->value->map; for (m_uint i = 0; i < map_size(map); ++i) { - if (VKEY(map, i) == (m_uint)member->xid) { + if (VKEY(map, i) == (m_uint)member->tag.sym) { const Value v = (Value)VVAL(map, i); const uint emit_addr = exp_getvar(exp_self(member)); emit_unionmember(emit, i, v->type->size, emit_addr); @@ -88,7 +171,7 @@ static OP_CHECK(opck_union_is) { Exp* exp_args = call->args; e->exp_type = ae_exp_binary; e->d.exp_binary.lhs = cpy_exp(env->gwion->mp, exp_func); - e->d.exp_binary.lhs->d.exp_dot.xid = + e->d.exp_binary.lhs->d.exp_dot.tag.sym = insert_symbol(env->gwion->st, "index"); // e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i+1, e->loc); e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i, e->loc); diff --git a/src/parse/check.c b/src/parse/check.c index 8bfa07ff..8af1b75a 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -378,7 +378,7 @@ ANN static Type prim_owned(const Env env, const Symbol *data) { exp->d.exp_dot.base = base; base->d.prim.value = v->from->owner_class->info->value; // base->type = v->from->owner_class; - exp->d.exp_dot.xid = *data; + exp->d.exp_dot.tag.sym = *data; return check_exp(env, exp); } @@ -410,7 +410,7 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) { exp->exp_type = ae_exp_dot; Type_Decl *td = cpy_type_decl(env->gwion->mp, using->d.td); exp->d.exp_dot.base = new_exp_td(env->gwion->mp, td, exp->loc); - exp->d.exp_dot.xid = insert_symbol(value->name); + exp->d.exp_dot.tag.sym = insert_symbol(value->name); return check_exp(env, exp); } } else if(sym == using->tag.sym) { @@ -643,7 +643,7 @@ ANN static Func call2ufcs(const Env env, Exp_Call *call, const Value v) { call->args = this; call->func->type = v->type; call->func->d.prim.value = v; - call->func->d.prim.d.var = call->func->d.exp_dot.xid; + call->func->d.prim.d.var = call->func->d.exp_dot.tag.sym; call->func->exp_type = ae_exp_primary; call->func->d.prim.prim_type = ae_prim_id; CHECK_O(check_exp_call(env, call)); @@ -657,7 +657,7 @@ ANN static Func ufcs(const Env env, const Func up, Exp_Call *const call) { return NULL; } -ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) { +static ANN Func find_func_match_normal(const Env env, const Func up, Exp_Call *const call) { Func func; Exp* exp = call->args; Exp* args = @@ -672,6 +672,110 @@ ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) { : NULL; } +ANN bool call_has_named_args(Exp_Call *call, uint32_t *nargs) { + Exp *exp = call->args; + bool ret = false; + do { + if(exp->exp_type == ae_exp_named) + ret = true; + (*nargs)++; + } while ((exp = exp->next)); + return ret; +} + +struct NamedChecker { + MP_Vector *call_list; + MP_Vector *named; + MP_Vector *unnamed; + uint32_t nargs; +}; + +static ANN Func __find_func_match_named(const Env env, const Func up, Exp_Call *const call, const struct NamedChecker *nc) { + const MP_Vector *args = up->def->base->args; + if(!args || nc->nargs != args->len) { + return NULL; + } + + uint32_t nnamed = 0; + uint32_t nunnamed = 0; + for(uint32_t i = 0; i < args->len; i++) { + bool found = false; + Arg *arg = mp_vector_at(args, Arg, i); + for(uint32_t j = 0; j < nc->named->len; j++) { + Exp *exp = *mp_vector_at(nc->named, Exp*, j); + if(arg->var.vd.tag.sym == exp->d.exp_named.tag.sym) { + mp_vector_set(nc->call_list, Exp*, i, exp); + nnamed++; + found = true; + break; + } + } + if(!found && nunnamed < nc->unnamed->len) + mp_vector_set(nc->call_list, Exp*, i, *mp_vector_at(nc->unnamed, Exp*,nunnamed++)); + } + if((nunnamed + nnamed) != nc->nargs) return NULL; + for(uint32_t i = 1; i < nc->call_list->len; i++) { + (*mp_vector_at(nc->call_list, Exp*, i-1))->next = + *mp_vector_at(nc->call_list, Exp*, i); + } + (*mp_vector_at(nc->call_list, Exp*, nc->call_list->len-1))->next = NULL; + call->args = *mp_vector_at(nc->call_list, Exp*, 0); + return find_func_match_normal(env, up, call); +} + +static ANN Func _find_func_match_named(const Env env, const Func up, Exp_Call *const call, const struct NamedChecker *nc) { + Func ret = __find_func_match_named(env, up, call, nc); + if(ret) return ret; + if(!up->next) return NULL; + return _find_func_match_named(env, up->next, call, nc); +} + +static ANN Func find_func_match_named(const Env env, const Func up, Exp_Call *const call, const uint32_t nargs) { + struct NamedChecker nc = { + .call_list = new_mp_vector(env->gwion->mp, Exp*, nargs), + .named = new_mp_vector(env->gwion->mp, Exp*, 0), + .unnamed = new_mp_vector(env->gwion->mp, Exp*, 0), + .nargs = nargs, + }; + MP_Vector *arg_list = new_mp_vector(env->gwion->mp, Exp*, nargs); + Exp *exp = call->args; + uint32_t i = 0; + do { + mp_vector_set(arg_list, Exp*, i, exp); + if(exp->exp_type == ae_exp_named) { + exp->d.exp_named.is_arg = true; + mp_vector_add(env->gwion->mp, &nc.named, Exp*, exp); + } else + mp_vector_add(env->gwion->mp, &nc.unnamed, Exp*, exp); + i++; + } while((exp = exp->next)); + + const Func ret = _find_func_match_named(env, up, call, &nc); + + if(!ret) { + for(uint32_t i = 1; i < arg_list->len; i++) { + (*mp_vector_at(arg_list, Exp*, i-1))->next = + *mp_vector_at(arg_list, Exp*, i); + } + (*mp_vector_at(arg_list, Exp*, arg_list->len-1))->next = NULL; + call->args = (*mp_vector_at(arg_list, Exp*, 0)); + } + + free_mp_vector(env->gwion->mp, Exp*, arg_list); + free_mp_vector(env->gwion->mp, Exp*, nc.call_list); + free_mp_vector(env->gwion->mp, Exp*, nc.named); + free_mp_vector(env->gwion->mp, Exp*, nc.unnamed); + + return ret; +} + +ANN Func find_func_match(const Env env, const Func up, Exp_Call *const call) { + uint32_t nargs = 0; + if(!call->args || !call_has_named_args(call, &nargs)) + return find_func_match_normal(env, up, call); + return find_func_match_named(env, up, call, nargs); +} + ANN bool check_traverse_fdef(const Env env, const Func_Def fdef) { struct Vector_ v = {}; const m_uint scope = env->scope->depth; @@ -713,8 +817,11 @@ ANN static inline Exp* next_arg_exp(const Exp *e) { } ANN static void print_current_args(Exp* e) { - do gw_err(" {G}%s{0}", e->type ? e->type->name : ""); - while ((e = next_arg_exp(e))); + do { + if (e->exp_type == ae_exp_named) + gw_err(" {B}%s{0} =", s_name(e->d.exp_named.tag.sym)); + gw_err(" {G}%s{0}", e->type ? e->type->name : ""); + } while ((e = next_arg_exp(e))); gw_err("\n"); } @@ -1045,7 +1152,7 @@ ANN static Type call_return(const Env env, Exp_Call *const exp, return NULL; } -ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) { +static ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) { DECL_O(const Type, t, = call_type(env, exp)); if (t == env->gwion->type[et_op]) return check_op_call(env, exp); if (!t->info->func) // TODO: effects? @@ -1109,6 +1216,7 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) { bin->rhs->d.exp_decl.type == env->gwion->type[et_auto]; if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type; // allow foo => new C to mean new C(foo) + // do we actually still need that? if(bin->op == insert_symbol("=>") && bin->rhs->exp_type == ae_exp_unary && bin->rhs->d.exp_unary.unary_type == unary_td && !bin->rhs->d.exp_unary.ctor.td->array && @@ -1368,6 +1476,9 @@ ANN static Type check_exp_td(const Env env, Type_Decl **td) { return t; } +ANN static Type check_exp_named(const Env env, Exp_Named *exp_named) { + return check_exp(env, exp_named->exp); +} DECL_EXP_FUNC(check, Type, Env) ANN Type check_exp(const Env env, Exp* exp) { diff --git a/src/parse/operator.c b/src/parse/operator.c index c1ac396e..256c52c3 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -172,9 +172,6 @@ ANN bool add_op(const Gwion gwion, const struct Op_Import *opi) { CHECK_B(op_exist(&ock, n)); } } while ((n = n->parent)); - // Nspc nspc = gwion->env->context - // ? gwion->env->context->nspc - // : gwion->env->curr; const Nspc nspc = get_nspc(gwion->env); if (!nspc->operators) nspc->operators = mp_calloc(gwion->mp, NspcOp); @@ -208,7 +205,7 @@ ANN static Type op_check_inner(const Env env, struct OpChecker *ock, ock->opi->lhs, r) : operator_find((Vector)&VVAL(ock->map, idx), ock->opi->lhs, r))) { - if ((mo->ck && (t = mo->ck(ock->env, (void *)ock->opi->data)))) { + if ((mo->ck && (t = mo->ck(ock->env, (void *)ock->opi->data)))) { ock->effect.ptr = mo->effect.ptr; return t; } else @@ -296,6 +293,7 @@ ANN static Type op_check_tmpl(const Env env, struct Op_Import *opi) { return NULL; } +// TODO: maybe should return M_Operator*? ANN void* op_get(const Env env, struct Op_Import *opi) { for (int i = 0; i < 2; ++i) { Nspc nspc = env->curr; @@ -395,8 +393,6 @@ ANN Type op_check(const Env env, struct Op_Import *opi) { } ANN bool operator_set_func(const Env env, const struct Op_Import *opi) { - //const Nspc nspc = ((Func)opi->data)->value_ref->from->owner; - //const Nspc nspc = ((Func)opi->data)->value_ref->from->ctx->nspc; const Nspc nspc = get_nspc(env); const m_int idx = map_index(&nspc->operators->map, (vtype)opi->op); const Vector v = (Vector)&VVAL(&nspc->operators->map, idx); diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 67309333..d9d69c30 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -280,6 +280,7 @@ ANN static void union_tmpl(const Env env, const Union_Def udef) { ANN bool scan0_union_def(const Env env, const Union_Def udef) { bool global = false; + bool ok = true; CHECK_B(scan0_global(env, udef->flag, udef->tag.loc, &global)); CHECK_B(scan0_defined(env, udef->tag)); udef->type = union_type(env, udef->tag.sym, udef->tag.loc); @@ -287,7 +288,7 @@ ANN bool scan0_union_def(const Env env, const Union_Def udef) { if (udef->tmpl) union_tmpl(env, udef); if (global) env_pop(env, 0); set_tflag(udef->type, tflag_scan0); - return true; + return ok; } ANN static inline void cdef_flag(const Class_Def cdef, const Type t) { diff --git a/src/parse/scan1.c b/src/parse/scan1.c index e84225ba..ac2388d9 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -144,7 +144,7 @@ ANN static bool scan1_decl(const Env env, Exp_Decl *const decl) { SET_FLAG(v, global); else if(env->context) set_vflag(v, vflag_fglobal); // file global - } else if (GET_FLAG(decl->var.td, global)) + } else if (GET_FLAG(decl->var.td, global)) // wait we can have globals in a scope ? SET_FLAG(v, global); nspc_add_value(env->curr, vd->tag.sym, v); ((Exp_Decl *)decl)->type = decl->var.vd.value->type; @@ -250,6 +250,11 @@ ANN static inline bool scan1_exp_unary(const restrict Env env, #define scan1_exp_lambda dummy_func #define scan1_exp_td dummy_func + +ANN static bool scan1_exp_named(const Env env, Exp_Named *named) { + return scan1_exp(env, named->exp); +} + HANDLE_EXP_FUNC(scan1, bool, Env) ANN static inline bool _scan1_stmt_match_case(const restrict Env env, @@ -410,6 +415,19 @@ ANN static inline bool scan1_stmt_exp(const Env env, const Stmt_Exp stmt) { return stmt->val ? scan1_exp(env, stmt->val) : 1; } +ANN static void enum_value(const Env env, const Enum_Def edef, + const Tag tag, const m_int value, m_int *last) { + const Value v = new_value(env, edef->type, tag); + v->d.num = value; + *last = v->d.num + 1; + valuefrom(env, v->from); + nspc_add_value(env->curr, tag.sym, v); + SET_FLAG(v, static | ae_flag_const); + SET_ACCESS(edef, v) + SET_ACCESS(edef, edef->type) + set_vflag(v, vflag_builtin); +} + ANN bool scan1_enum_def(const Env env, const Enum_Def edef) { const Type t = edef->type; t->nspc = new_nspc(env->gwion->mp, t->name); @@ -418,15 +436,11 @@ ANN 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, ev.tag); - v->d.num = (ev.set ? ev.gwint.num : last); - last = v->d.num + 1; - valuefrom(env, v->from); - nspc_add_value(env->curr, ev.tag.sym, v); - SET_FLAG(v, static | ae_flag_const); - SET_ACCESS(edef, v) - SET_ACCESS(edef, t) - set_vflag(v, vflag_builtin); + CHECK_B(can_define(env, ev.tag.sym, ev.tag.loc)); + const m_int value = !ev.set + ? last + : ev.gwint.num; + enum_value(env, edef, ev.tag, value, &last); } env_pop(env, scope); return true; @@ -550,17 +564,13 @@ ANN bool scan1_type_def(const Env env, const Type_Def tdef) { ANN static inline bool scan1_union_def_inner_loop(const Env env, Union_Def udef) { - nspc_allocdata(env->gwion->mp, udef->type->nspc); - Variable_List l = udef->l; m_uint sz = 0; - const Symbol sym = insert_symbol("@index"); - const Value v = new_value(env, env->gwion->type[et_int], MK_TAG(sym, udef->tag.loc)); - nspc_add_value_front(env->curr, sym, v); - valuefrom(env, v->from); bool ok = true; + Variable_List l = udef->l; for(uint32_t i = 0; i < l->len; i++) { Variable *um = mp_vector_at(l, Variable, i); if (nspc_lookup_value0(env->curr, um->vd.tag.sym)) { + // TODO: use already_declared ERR_OK(ok, um->vd.tag.loc, _("'%s' already declared in union"), s_name(um->vd.tag.sym)); continue; } @@ -885,8 +895,8 @@ ANN static bool scan1_class_def_body(const Env env, const Class_Def cdef) { } // return // check for previous errors? -cdef->base.type->error = !env_body(env, cdef, scan1_section); -return true; + cdef->base.type->error = !env_body(env, cdef, scan1_section); + return true; } ANN static bool scan1_class_tmpl(const Env env, const Class_Def c) { diff --git a/src/parse/scan2.c b/src/parse/scan2.c index f2986281..74659e0d 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -210,6 +210,10 @@ ANN static inline bool scan2_stmt_match(const restrict Env env, RET_NSPC(_scan2_stmt_match(env, stmt)) } +ANN static bool scan2_exp_named(const Env env, Exp_Named *named) { + return scan2_exp(env, named->exp); +} + #define scan2_exp_lambda dummy_func #define scan2_exp_td dummy_func HANDLE_EXP_FUNC(scan2, bool, Env) diff --git a/src/parse/template.c b/src/parse/template.c index bbe51d68..00e7772a 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -202,7 +202,7 @@ ANN2(1,2) bool check_tmpl(const Env env, const TmplArg_List tl, const Specialize if(t) { targ->type = tmplarg_exp; Exp* e = new_exp_td(env->gwion->mp, base, base->tag.loc); - targ->d.exp = new_exp_dot(env->gwion->mp, e, last->tag.sym, base->tag.loc); + targ->d.exp = new_exp_dot(env->gwion->mp, e, last->tag, base->tag.loc); free_type_decl(env->gwion->mp, last); i--; continue; diff --git a/src/parse/validate.c b/src/parse/validate.c index 7ccf6cfd..72dd24a1 100644 --- a/src/parse/validate.c +++ b/src/parse/validate.c @@ -228,6 +228,14 @@ ANN static bool validate_exp_td(Validate *a, Type_Decl *b) { return validate_type_decl(a, b); } +ANN static bool validate_exp_named(Validate *a, Exp_Named *b) { + if(!b->is_arg) { + env_err(a->env, exp_self(b)->loc, "named expression not in a function call"); + return false; + } + return validate_exp(a, b->exp); +} + DECL_EXP_FUNC(validate, bool, Validate*) ANN static bool validate_exp(Validate *a, Exp* b) { bool ret = true; diff --git a/src/sema/default_arg.c b/src/sema/default_arg.c index 338bec92..b159c69f 100644 --- a/src/sema/default_arg.c +++ b/src/sema/default_arg.c @@ -51,7 +51,7 @@ ANN static Stmt_List new_code(const Sema *sema, Func_Base *base, const uint32_t SymTable *st = sema->st; Exp* dbase = new_prim_id(p, insert_symbol(st, "this"), base->tag.loc); const Symbol sym = insert_symbol(st, "new"); - Exp* func = new_exp_dot(p, dbase, sym, base->tag.loc); + Exp* func = new_exp_dot(p, dbase, MK_TAG(sym, base->tag.loc), base->tag.loc); return code(p, func, base->args, max, ae_stmt_exp); } diff --git a/src/sema/sema.c b/src/sema/sema.c index c1d96a36..004c57d5 100644 --- a/src/sema/sema.c +++ b/src/sema/sema.c @@ -250,6 +250,10 @@ ANN static bool sema_exp_td(Sema *a, Type_Decl *b) { return type_decl_array_empty(a, b, "in `type declaration` expression"); } +ANN static bool sema_exp_named(Sema *a, Exp_Named *b) { + return sema_exp(a, b->exp); +} + DECL_EXP_FUNC(sema, bool, Sema*) ANN static bool sema_exp(Sema *a, Exp* b) { bool ok = sema_exp_func[b->exp_type](a, &b->d); @@ -542,7 +546,7 @@ ANN static bool sema_stmt_spread(Sema *a, Spread_Def b) { MP_Vector *result = new_mp_vector(a->mp, Stmt, base->len + stmt_list->len - 1); // store the first part of the list in it // TODO: use memcpy - // or berrer, use the above function to just start at part two + // or better, use the above function to just start at part two for(uint32_t i = 0; i < index; i++) { Stmt stmt = *mp_vector_at(base, Stmt, i); mp_vector_set(result, Stmt, i, stmt); @@ -767,6 +771,11 @@ ANN static bool sema_enum_def(Sema *a, Enum_Def b) { // TODO: rename l ANN static bool sema_union_def(Sema *a, Union_Def b) { + if(!b->l->len) { + gwlog_error(_("unions can't be empty"), NULL, + a->filename, b->tag.loc, 0); + return false; + } bool ok = true; for(uint32_t i = 0; i < b->l->len; i++) { Variable *c = mp_vector_at(b->l, Variable, i);