From b6e09da15099ce7e7aa1406c494f60f481caaaba Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 3 Sep 2019 01:28:03 +0200 Subject: [PATCH] :bug: various bugfixes --- include/env.h | 1 + src/emit/emit.c | 5 +++-- src/lib/array.c | 6 ++++-- src/oo/switch.c | 34 +++++++++++++++++----------------- src/parse/scan1.c | 12 ++++++++++-- src/parse/traverse.c | 7 +++---- 6 files changed, 38 insertions(+), 27 deletions(-) diff --git a/include/env.h b/include/env.h index 9ba10888..c45805cc 100644 --- a/include/env.h +++ b/include/env.h @@ -12,6 +12,7 @@ struct Switch_ { vtype iter; size_t default_case_index; size_t depth; + struct SwInfo_ *info; uint ok; }; diff --git a/src/emit/emit.c b/src/emit/emit.c index ada3abb7..8e73c0e0 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1425,7 +1425,7 @@ ANN static m_bool emit_stmt_case(const Emitter emit, const Stmt_Exp stmt) { m_int value = 0; const Value v = case_value(stmt->val); if((!v && prim_value(stmt->val, &value)) || value_value(v, &value)) { - CHECK_BB(switch_dup(emit->env, value, stmt->val->pos)) + CHECK_BB(switch_dup(emit->env, value, stmt_self(stmt)->pos)) switch_dynpc(emit->env, value, emit_code_size(emit)); } else switch_pc(emit->env, emit_code_size(emit)); @@ -1679,7 +1679,8 @@ ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) { (isa(exp_self(member)->type, t_function) > 0 && isa(exp_self(member)->type, t_fptr) < 0)) ) { CHECK_BB(emit_exp(emit, member->base, 0)) - emit_except(emit, member->t_base); +// emit_except(emit, member->t_base); + emit_add_instr(emit, GWOP_EXCEPT); } if(isa(exp_self(member)->type, t_function) > 0 && isa(exp_self(member)->type, t_fptr) < 0) return emit_member_func(emit, member, value->d.func_ref); diff --git a/src/lib/array.c b/src/lib/array.c index ea9f47bf..974425b4 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -48,7 +48,8 @@ void free_m_vector(MemPool p, M_Vector a) { } static DTOR(array_dtor) { - const Type t = o->type_ref; + const Type t = !GET_FLAG(o->type_ref, nonnull) ? + o->type_ref : o->type_ref->e->parent; const Type base = array_base(t); struct M_Vector_* a = ARRAY(o); if(t->array_depth > 1 || isa(base, t_object) > 0) @@ -164,7 +165,8 @@ static OP_EMIT(opem_array_shift) { const Type type = bin->rhs->type; const Instr pop = emit_add_instr(emit, RegPop); pop->m_val = type->size; - emit_add_instr(emit, GWOP_EXCEPT); + if(!GET_FLAG(bin->lhs->type, nonnull)) + emit_add_instr(emit, GWOP_EXCEPT); emit_add_instr(emit, ArrayAppend); return GW_OK; } diff --git a/src/oo/switch.c b/src/oo/switch.c index 89375fc7..768f5fdb 100644 --- a/src/oo/switch.c +++ b/src/oo/switch.c @@ -28,20 +28,21 @@ static Switch new_switch(MemPool p) { return sw; } +struct SwInfo_ { + Stmt_Switch s; + Type t; + Func f; +}; + ANN static void free_switch(MemPool p, const Switch sw) { if(!sw->ok) free_map(p, sw->cases); free_vector(p, sw->vec); // only for dynamic vector_release(&sw->exp); + mp_free(p, SwInfo, sw->info); mp_free(p, Switch, sw); } -struct SwInfo_ { - Stmt_Switch s; - Type t; - Func f; -}; - ANN static Switch new_swinfo(const Env env, const Stmt_Switch stmt) { struct SwInfo_ *info = mp_calloc(env->gwion->mp, SwInfo); info->s = stmt; @@ -50,6 +51,7 @@ ANN static Switch new_swinfo(const Env env, const Stmt_Switch stmt) { const Switch sw = new_switch(env->gwion->mp); map_set(&env->scope->swi->map, (vtype)info, (vtype)sw); sw->depth = env->scope->depth + 2; + sw->info = info; return sw; } @@ -60,8 +62,9 @@ ANN static inline m_bool swinfo_cmp(const struct SwInfo_ *i1, const struct SwInf ANN Switch swinfo_get(const Env env, const struct SwInfo_ *info) { for(m_uint i = 0; i < VLEN(&env->scope->swi->map); ++i) { const struct SwInfo_ *key = (const struct SwInfo_*)VKEY(&env->scope->swi->map, i); - if(swinfo_cmp(key, info)) + if(swinfo_cmp(key, info)) { return (Switch)VVAL(&env->scope->swi->map, i); + } } return NULL; } @@ -89,9 +92,7 @@ ANN void switch_get(const Env env, const Stmt_Switch stmt) { void switch_reset(const Env env) { for(m_uint i = VLEN(&env->scope->swi->map) + 1; --i;) { - struct SwInfo_ *info = (struct SwInfo_ *)VKEY(&env->scope->swi->map, i - 1); - mp_free(env->gwion->mp, SwInfo, info); - Switch sw = (Switch)VVAL(&env->scope->swi->map, i - 1); + const Switch sw = (Switch)VVAL(&env->scope->swi->map, i - 1); free_switch(env->gwion->mp, sw); } _scope_clear(env->scope->swi); @@ -118,6 +119,7 @@ ANN m_bool switch_inside(const Env env, const loc_t pos) { ERR_B(pos, _("case found outside switch statement.")) return GW_OK; } + ANN m_bool switch_dup(const Env env, const m_int value, const loc_t pos) { const Switch sw = (Switch)_scope_back(env->scope->swi); if(map_get(sw->cases, (vtype)value)) @@ -167,19 +169,17 @@ ANN m_uint switch_idx(const Env env) { } ANN m_bool switch_pop(const Env env) { - const Switch sw = (Switch)_scope_back(env->scope->swi); + const Switch sw = (Switch)_scope_pop(env->scope->swi); sw->ok = 1; - _scope_pop(env->scope->swi); return GW_OK; } ANN m_bool switch_end(const Env env, const loc_t pos) { const Switch sw = (Switch)_scope_pop(env->scope->swi); - const vtype index = VKEY(&env->scope->swi->map, VLEN(&env->scope->swi->map) - 1); -// sw->ok = 1; - if(!VLEN(sw->cases) && !VLEN(&sw->exp)) - ERR_B(pos, _("switch statement with no cases.")) - map_remove(&env->scope->swi->map, index); + map_remove(&env->scope->swi->map, sw->info); + const m_bool empty = !VLEN(sw->cases) && !VLEN(&sw->exp); free_switch(env->gwion->mp, sw); + if(empty) + ERR_B(pos, _("switch statement with no cases.")) return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 39332129..7580124c 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -176,6 +176,12 @@ ANN static inline m_bool scan1_exp_typeof(const restrict Env env, const Exp_Type #define scan1_exp_lambda dummy_func HANDLE_EXP_FUNC(scan1, m_bool, 1) +ANN static inline m_bool scan1_stmt_switch(const restrict Env env, const Stmt_Switch stmt) { + CHECK_BB(scan1_exp(env, stmt->val)) + CHECK_BB(scan1_stmt(env, stmt->stmt)) + return GW_OK; +} + #define describe_ret_nspc(name, type, prolog, exp) describe_stmt_func(scan1, name, type, prolog, exp) describe_ret_nspc(flow, Stmt_Flow,, !(scan1_exp(env, stmt->cond) < 0 || scan1_stmt(env, stmt->body) < 0) ? 1 : -1) @@ -187,8 +193,8 @@ describe_ret_nspc(auto, Stmt_Auto,, !(scan1_exp(env, stmt->exp) < 0 || scan1_stmt(env, stmt->body) < 0) ? 1 : -1) describe_ret_nspc(loop, Stmt_Loop,, !(scan1_exp(env, stmt->cond) < 0 || scan1_stmt(env, stmt->body) < 0) ? 1 : -1) -describe_ret_nspc(switch, Stmt_Switch,, !(scan1_exp(env, stmt->val) < 0 || - scan1_stmt(env, stmt->stmt) < 0) ? 1 : -1) +//describe_ret_nspc(switch, Stmt_Switch,, !(scan1_exp(env, stmt->val) < 0 || +// scan1_stmt(env, stmt->stmt) < 0) ? 1 : -1) describe_ret_nspc(if, Stmt_If,, !(scan1_exp(env, stmt->cond) < 0 || scan1_stmt(env, stmt->if_body) < 0 || (stmt->else_body && scan1_stmt(env, stmt->else_body) < 0)) ? 1 : -1) @@ -373,6 +379,8 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { CHECK_BB(scanx_parent(parent, scan1_cdef, env)) if(type_ref(parent)) ERR_B(pos, _("can't use ref type in class extend")) + if(GET_FLAG(parent, nonnull)) + ERR_B(pos, _("can't use nonnull type in class extend")) return GW_OK; } diff --git a/src/parse/traverse.c b/src/parse/traverse.c index 6f8a8507..9442b6a5 100644 --- a/src/parse/traverse.c +++ b/src/parse/traverse.c @@ -19,12 +19,11 @@ ANN m_bool traverse_decl(const Env env, const Exp_Decl* decl) { ANN m_bool traverse_func_def(const Env env, const Func_Def def) { const Func former = env->func; - if(scan1_func_def(env, def) > 0 && + const m_bool ret = scan1_func_def(env, def) > 0 && scan2_func_def(env, def) > 0 && - check_func_def(env, def) > 0) - return GW_OK; + check_func_def(env, def) > 0; env->func = former; - return GW_ERROR; + return ret ? GW_OK : GW_ERROR; } ANN m_bool traverse_union_def(const Env env, const Union_Def def) { -- 2.43.0