From fe4fdc53d62be3c82953afdd161289f94edf947b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Tue, 22 Dec 2020 00:39:56 +0100 Subject: [PATCH] :art: Few fixes --- src/emit/emit.c | 20 +++++++++++--------- src/lib/array.c | 2 +- src/lib/engine.c | 4 ++-- src/lib/lib_func.c | 13 +++++++------ src/lib/object_op.c | 2 +- src/lib/ptr.c | 4 ++-- src/lib/union.c | 7 +++---- src/parse/operator.c | 38 +++++++++++++++++++++----------------- src/parse/scan0.c | 4 +++- src/parse/scan1.c | 6 ++++-- 10 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index a0969d8e..c7025c75 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -418,6 +418,10 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) { const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !vflag(v, vflag_fglobal) ? regpushmem : regpushbase); instr->m_val = v->from->offset; + if(GET_FLAG(v, late) && !exp_getvar(prim_exp(data)) && isa(v->type, emit->gwion->type[et_object]) > 0) { + const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); + instr->m_val = -SZ_INT; + } return GW_OK; } @@ -1774,7 +1778,6 @@ ANN static m_bool emit_case_body(const Emitter emit, const struct Stmt_Match_* s ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) { const Value v = e->d.prim.value; -printf("base->type %s\n", base->type->name); v->from->offset = emit_local(emit, base->type); const Instr instr = emit_add_instr(emit, Reg2Mem4); instr->m_val = v->from->offset; @@ -1837,10 +1840,11 @@ ANN static Symbol case_op(const Emitter emit, const Exp base, const Exp e, const CHECK_BO(op_emit(emit, &opi)) const Instr instr = emit_add_instr(emit, BranchEqInt); vector_add(vec, (vtype)instr); + return CASE_PASS; } ANN static m_bool _emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt, - const Vector v, struct Match_ *const match) { + const Vector v) { Exp e = stmt->cond; const Map map = &emit->env->scope->match->map; for(m_uint i = 0; i < map_size(map) && e; e = e->next, ++i) { @@ -1848,18 +1852,16 @@ ANN static m_bool _emit_stmt_match_case(const Emitter emit, const struct Stmt_Ma const Symbol op = case_op(emit, base, e, v, 0); if(op != CASE_PASS) CHECK_BB(emit_case_head(emit, base, e, op, v)) -else puts("pass"); } CHECK_BB(emit_case_body(emit, stmt)) return GW_OK; } -ANN static m_bool emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt, - struct Match_ *match) { +ANN static m_bool emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt) { emit_push_scope(emit); struct Vector_ v; vector_init(&v); - const m_bool ret = _emit_stmt_match_case(emit, stmt, &v, match); + const m_bool ret = _emit_stmt_match_case(emit, stmt, &v); emit_pop_scope(emit); for(m_uint i = 0; i < vector_size(&v); ++i) { const Instr instr = (Instr)vector_at(&v, i); @@ -1878,8 +1880,8 @@ ANN static inline void match_unvec(struct Match_ *const match, const m_uint pc) vector_release(vec); } -ANN static m_bool emit_stmt_cases(const Emitter emit, Stmt_List list, struct Match_ *match) { - do CHECK_BB(emit_stmt_match_case(emit, &list->stmt->d.stmt_match, match)) +ANN static m_bool emit_stmt_cases(const Emitter emit, Stmt_List list) { + do CHECK_BB(emit_stmt_match_case(emit, &list->stmt->d.stmt_match)) while((list = list->next)); return GW_OK; } @@ -1889,7 +1891,7 @@ ANN static m_bool emit_match(const Emitter emit, const struct Stmt_Match_* stmt) CHECK_BB(emit_stmt(emit, stmt->where, 1)) MATCH_INI(emit->env->scope) vector_init(&m.vec); - const m_bool ret = emit_stmt_cases(emit, stmt->list, &m); + const m_bool ret = emit_stmt_cases(emit, stmt->list); match_unvec(&m, emit_code_size(emit)); MATCH_END(emit->env->scope) return ret; diff --git a/src/lib/array.c b/src/lib/array.c index b68dda40..dd824abc 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -321,7 +321,7 @@ static OP_CHECK(opck_array) { const Array_Sub array = (Array_Sub)data; const Type t_int = env->gwion->type[et_int]; Exp e = array->exp; - do CHECK_BO(check_implicit(env, e, t_int)) + do CHECK_BN(check_implicit(env, e, t_int)) while((e = e->next)); const Type t = array->type->array_depth ? array->type : typedef_base(array->type); if(t->array_depth >= array->depth) diff --git a/src/lib/engine.c b/src/lib/engine.c index 69a526b5..a073b049 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -155,11 +155,11 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(gwi_oper_end(gwi, ">", instr_class_gt)) GWI_BB(gwi_oper_end(gwi, "<=", instr_class_le)) GWI_BB(gwi_oper_end(gwi, "<", instr_class_lt)) -/* + GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL)) GWI_BB(gwi_oper_add(gwi, opck_basic_ctor)) GWI_BB(gwi_oper_end(gwi, "@ctor", NULL)) -*/ + GWI_BB(gwi_oper_ini(gwi, "@Compound", (m_str)OP_ANY_TYPE, NULL)) GWI_BB(gwi_oper_add(gwi, opck_object_dot)) GWI_BB(gwi_oper_emi(gwi, opem_object_dot)) diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 450c9c4f..6e893764 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -176,7 +176,8 @@ ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) { ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) { if(isa(info->exp->type, env->gwion->type[et_lambda]) < 0) { CHECK_BB(fptr_check(env, info)) - CHECK_OB((info->exp->type = fptr_type(env, info))) + if(!(info->exp->type = fptr_type(env, info))) + ERR_B(info->lhs->def->pos, _("no match found")) return GW_OK; } Exp_Lambda *l = &info->exp->d.exp_lambda; @@ -213,13 +214,13 @@ static OP_CHECK(opck_fptr_at) { bin->rhs->type->info->func->def->base->tmpl->call) { struct FptrInfo info = { bin->lhs->type->info->func, bin->rhs->type->info->parent->info->func, bin->lhs, exp_self(bin)->pos }; - CHECK_BO(fptr_do(env, &info)) + CHECK_BN(fptr_do(env, &info)) exp_setvar(bin->rhs, 1); return bin->rhs->type; } struct FptrInfo info = { bin->lhs->type->info->func, bin->rhs->type->info->func, bin->lhs, exp_self(bin)->pos }; - CHECK_BO(fptr_do(env, &info)) + CHECK_BN(fptr_do(env, &info)) exp_setvar(bin->rhs, 1); return bin->rhs->type; } @@ -229,7 +230,7 @@ static OP_CHECK(opck_fptr_cast) { const Type t = exp_self(cast)->type; struct FptrInfo info = { cast->exp->type->info->func, t->info->func, cast->exp, exp_self(cast)->pos }; - CHECK_BO(fptr_do(env, &info)) + CHECK_BN(fptr_do(env, &info)) return t; } @@ -257,7 +258,7 @@ static OP_CHECK(opck_fptr_impl) { struct Implicit *impl = (struct Implicit*)data; struct FptrInfo info = { impl->e->type->info->func, impl->t->info->func, impl->e, impl->e->pos }; - CHECK_BO(fptr_do(env, &info)) + CHECK_BN(fptr_do(env, &info)) return impl->t; } @@ -313,7 +314,7 @@ static OP_CHECK(opck_spork) { const m_bool ret = check_stmt(env, unary->code); nspc_pop_value(env->gwion->mp, env->curr); --env->scope->depth; - CHECK_BO(ret) + CHECK_BN(ret) return env->gwion->type[unary->op == insert_symbol("spork") ? et_shred : et_fork]; } ERR_O(exp_self(unary)->pos, _("only function calls can be sporked...")) diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 02e307ec..932f87a3 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -36,7 +36,7 @@ static OP_CHECK(at_object) { if(bin->rhs->exp_type == ae_exp_decl) SET_FLAG(bin->rhs->d.exp_decl.td, late); // ??? exp_setvar(bin->rhs, 1); - CHECK_BO(isa(bin->lhs->type , bin->rhs->type)) + CHECK_BN(isa(bin->lhs->type , bin->rhs->type)) return bin->rhs->type; } diff --git a/src/lib/ptr.c b/src/lib/ptr.c index 616e7bf6..98e146b9 100644 --- a/src/lib/ptr.c +++ b/src/lib/ptr.c @@ -28,8 +28,8 @@ ANN static inline Type ptr_base(const Env env, const Type t) { static OP_CHECK(opck_ptr_assign) { const Exp_Binary* bin = (Exp_Binary*)data; - CHECK_BO(ptr_access(env, bin->lhs)) - CHECK_BO(ptr_access(env, bin->rhs)) + CHECK_BN(ptr_access(env, bin->lhs)) + CHECK_BN(ptr_access(env, bin->rhs)) exp_setvar(bin->lhs, 1); exp_setvar(bin->rhs, 1); Type t = bin->lhs->type; diff --git a/src/lib/union.c b/src/lib/union.c index fff775c1..5f68019d 100644 --- a/src/lib/union.c +++ b/src/lib/union.c @@ -94,7 +94,7 @@ static OP_CHECK(opck_union_is) { free_exp(env->gwion->mp, exp_func); free_exp(env->gwion->mp, exp_args); e->d.exp_binary.op = insert_symbol(env->gwion->st, "=="); - CHECK_OO(check_exp(env, e)) + CHECK_ON(check_exp(env, e)) return e->type; } } @@ -111,7 +111,7 @@ static OP_CHECK(opck_union_ctor) { if(!name || !name->next || name->next->next) ERR_N(name->pos, "Union constructor takes two arguments, " "'id' and 'value'") - if(name->exp_type != ae_exp_primary || + if(name->exp_type != ae_exp_primary || name->d.prim.prim_type != ae_prim_id) return NULL; const Exp val = name->next; @@ -137,7 +137,6 @@ static OP_CHECK(opck_union_ctor) { static INSTR(UnionCtor) { POP_REG(shred, instr->m_val2); POP_REG(shred, SZ_INT); - const Type t = *(Type*)REG(-SZ_INT*2); const m_uint index = *(m_uint*)REG(-SZ_INT); const M_Object o = *(M_Object*)REG(-SZ_INT) = new_object(shred->info->vm->gwion->mp, NULL, (Type)instr->m_val); *(m_uint*)o->data = index;// + 1; @@ -148,7 +147,7 @@ static OP_EMIT(opem_union_ctor) { Exp_Call *call = (Exp_Call*)data; const Type base = actual_type(emit->gwion, call->func->type); const Instr instr = emit_add_instr(emit, UnionCtor); - instr->m_val = base; + instr->m_val = (m_uint)base; instr->m_val2 = call->args->next->type->size; return GW_OK; } diff --git a/src/parse/operator.c b/src/parse/operator.c index 479dc5bb..2a7133a0 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -58,7 +58,7 @@ ANN2(1) static M_Operator* operator_find(const Vector v, const restrict Type lhs ANN2(1) static M_Operator* operator_find2(const Vector v, const restrict Type lhs, const restrict Type rhs) { for(m_uint i = vector_size(v) + 1; --i;) { M_Operator* mo = (M_Operator*)vector_at(v, i - 1); - if(lhs == mo->lhs && rhs == mo->rhs) + if(mo && lhs == mo->lhs && rhs == mo->rhs) return mo; } return NULL; @@ -134,12 +134,12 @@ ANN m_bool add_op(const Gwion gwion, const struct Op_Import* opi) { return GW_OK; } -ANN static Type op_check_inner(struct OpChecker* ock) { +ANN static Type op_check_inner(struct OpChecker* ock, const uint i) { Type t, r = ock->opi->rhs; do { const M_Operator* mo; const Vector v = (Vector)map_get(ock->map, (vtype)ock->opi->op); - if(v && (mo = operator_find(v, ock->opi->lhs, r))) { + if(v && (mo = !i ? operator_find2(v, ock->opi->lhs, r) : operator_find(v, ock->opi->lhs, r))) { if((mo->ck && (t = mo->ck(ock->env, (void*)ock->opi->data)))) return t; else @@ -150,22 +150,24 @@ ANN static Type op_check_inner(struct OpChecker* ock) { } ANN Type op_check(const Env env, struct Op_Import* opi) { +for(int i = 0; i < 2; ++i) { Nspc nspc = env->curr; do { - if(nspc->info->op_map.ptr) { - Type l = opi->lhs; - do { - struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data, .op_type=opi->op_type }; - struct OpChecker ock = { env, &nspc->info->op_map, &opi2 }; - const Type ret = op_check_inner(&ock); - if(ret) { - if(ret == env->gwion->type[et_error]) - return NULL; - return ret; - } - } while(l && (l = l->info->parent)); - } + if(!nspc->info->op_map.ptr) + continue; + Type l = opi->lhs; + do { + struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data, .op_type=opi->op_type }; + struct OpChecker ock = { env, &nspc->info->op_map, &opi2 }; + const Type ret = op_check_inner(&ock, i); + if(ret) { + if(ret == env->gwion->type[et_error]) + return NULL; + return ret; + } + } while(l && (l = l->info->parent)); } while((nspc = nspc->parent)); +} if(opi->op == insert_symbol(env->gwion->st, "$") && opi->rhs == opi->lhs) return opi->rhs; if(opi->op == insert_symbol(env->gwion->st, "@func_check")) @@ -200,6 +202,7 @@ ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) { } ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) { + for(int i = 0; i < 2; ++i) { Nspc nspc = emit->env->class_def ? emit->env->curr : emit->env->context->nspc; do { if(!nspc->info->op_map.ptr)continue; @@ -210,7 +213,7 @@ ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) { const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op); if(!v) continue; - const M_Operator* mo = operator_find(v, l, r); + const M_Operator* mo = !i ? operator_find2(v, l, r) :operator_find(v, l, r); if(mo) { if(mo->em) { const m_bool ret = mo->em(emit, (void*)opi->data); @@ -222,5 +225,6 @@ ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) { } while(r && (r = r->info->parent)); } while(l && (l = l->info->parent)); } while((nspc = nspc->parent)); + } return GW_ERROR; } diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 291dc8fe..c333eb71 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -218,7 +218,9 @@ ANN static Type union_type(const Env env, const Symbol s) { t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ??? add_type(env, env->curr, t); mk_class(env, t); - SET_FLAG(t, final | ae_flag_abstract); + SET_FLAG(t, final); + if(strncmp(t->name, "Option", 6)) + SET_FLAG(t, abstract); return t; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 0835087a..0789d086 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -85,8 +85,10 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) { if(var->array->exp) CHECK_BB(scan1_exp(env, var->array->exp)) t = array_type(env, decl->type, var->array->depth); - } else if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late)) - SET_FLAG(decl->td, late); + } else if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, late)) { + ERR_B(var->pos, "Type '%s' is abstract, use late") + // SET_FLAG(decl->td, late); + } const Value v = var->value = var->value ?: new_value(env->gwion->mp, t, s_name(var->xid)); // rewrite logic if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static)) -- 2.43.0