]> Nishi Git Mirror - gwion.git/commitdiff
:bug: various bugfixes
authorfennecdjay <astor.jeremie@wanadoo.fr>
Mon, 2 Sep 2019 23:28:03 +0000 (01:28 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Mon, 2 Sep 2019 23:28:03 +0000 (01:28 +0200)
include/env.h
src/emit/emit.c
src/lib/array.c
src/oo/switch.c
src/parse/scan1.c
src/parse/traverse.c

index 9ba10888d40efecbf9992a485761ab5f2ca1ae5a..c45805cc7c0779def91b5ab650d5b9f70c4ca71a 100644 (file)
@@ -12,6 +12,7 @@ struct Switch_ {
   vtype iter;
   size_t default_case_index;
   size_t depth;
+  struct SwInfo_ *info;
   uint ok;
 };
 
index ada3abb7382341d15128d9f3c1c538c3ca3194ab..8e73c0e0cfa90152767431cc5bfc28e8ee3eb216 100644 (file)
@@ -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);
index ea9f47bf779a427f097d6c5ca8fdc728194b7f83..974425b4d470a184df15dea92d5556b62096598e 100644 (file)
@@ -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;
 }
index 89375fc7fd74adf7131834d83a967137f928e19e..768f5fdbc2f14f82c0504fa64dbb3762046db297 100644 (file)
@@ -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;
 }
index 39332129c7bb592bcb7167bd1a60c376b3728d50..7580124cf0a5a62a6d77e83ef9150bdfe7cd7938 100644 (file)
@@ -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;
 }
 
index 6f8a8507f513a1fc107af33f634e72c5bb5dbe3f..9442b6a555fdb7a3cb24014ccea9b209be84e91c 100644 (file)
@@ -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) {