]> Nishi Git Mirror - gwion.git/commitdiff
:art: Fix envset, improve array and VM
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Fri, 8 May 2020 18:45:14 +0000 (20:45 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Fri, 8 May 2020 18:45:14 +0000 (20:45 +0200)
src/env/envset.c
src/gwion.c
src/lib/array.c
src/lib/engine.c
src/lib/object_op.c
src/main.c
src/parse/check.c
src/parse/template.c
src/vm/vm.c

index de3917a564efec1e4e5145879ea724a1652e0c61..cfa938c9a81cbf3cc890993e820e7ccc3d5826b2 100644 (file)
@@ -8,7 +8,7 @@
 ANN static void check(struct EnvSet *es, const Type t) {
   const Vector v = &es->env->scope->class_stack;
   Type owner = t->e->owner_class;
-  for(vtype i = vector_size(v); owner && --i;) {
+  for(vtype i = vector_size(v) + 1; owner && --i;) {
     if(owner != (Type)vector_at(v, i - 1)) {
       es->run = 1;
       return;
@@ -54,7 +54,8 @@ ANN m_bool envset_run(struct EnvSet *es, const Type t) {
   check(es, t);
   if(es->run)
     CHECK_BB(push(es, t->e->owner_class))
-  const m_bool ret = es->func(es->data, t->e->def);
+  const m_bool ret = !(t->flag & es->flag) ?
+    es->func(es->data, t->e->def) : GW_OK;
   if(es->run)
     envset_pop(es, t->e->owner_class);
   return ret;
index 97d42f06a323d792393a444f87025007b1057759..d1f0e336c6e70df29088407046d085a8c263d1cd 100644 (file)
@@ -184,5 +184,5 @@ ANN void push_global(struct Gwion_ *gwion, const m_str name) {
 ANN Nspc pop_global(struct Gwion_ *gwion) {
   const Nspc nspc = gwion->env->global_nspc->parent;
   REM_REF(gwion->env->global_nspc, gwion)
-  return gwion->env->global_nspc = nspc;
+  return gwion->env->curr = gwion->env->global_nspc = nspc;
 }
index c9b3b23904d1a491ee0b3e16acdb9ec610c43c31..81a3ebe55079b483e70c3848d4a9b573782f2176 100644 (file)
@@ -138,18 +138,20 @@ ANN static Type get_array_type(Type t) {
 }
 
 #define ARRAY_OPCK                                        \
-  const Exp_Binary* bin = (Exp_Binary*)data;              \
   const Type l = get_array_type(bin->lhs->info->type);    \
   const Type r = get_array_type(bin->rhs->info->type);    \
   if(isa(l, r) < 0)                                       \
     ERR_N(exp_self(bin)->pos, _("array types do not match."))
 
 static OP_CHECK(opck_array_at) {
-  ARRAY_OPCK
+  const Exp_Binary* bin = (Exp_Binary*)data;
   if(opck_const_rhs(env, data, mut) == env->gwion->type[et_null])
     return env->gwion->type[et_null];
-  if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth)
-    ERR_N(exp_self(bin)->pos, _("array depths do not match."))
+  if(bin->lhs->info->type != env->gwion->type[et_null]) {
+    ARRAY_OPCK
+    if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth)
+      ERR_N(exp_self(bin)->pos, _("array depths do not match."))
+  }
   if(bin->rhs->exp_type == ae_exp_decl) {
     if(bin->rhs->d.exp_decl.list->self->array &&
           bin->rhs->d.exp_decl.list->self->array->exp)
@@ -160,6 +162,10 @@ static OP_CHECK(opck_array_at) {
 }
 
 static OP_CHECK(opck_array_shift) {
+  const Exp_Binary* bin = (Exp_Binary*)data;
+  if(bin->rhs->info->type == env->gwion->type[et_null] &&
+      bin->lhs->info->type->array_depth > 1)
+    return bin->lhs->info->type;
   ARRAY_OPCK
   if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth + 1)
     ERR_N(exp_self(bin)->pos, "array depths do not match for '<<'.");
@@ -294,6 +300,7 @@ ANN static inline Exp emit_n_exp(const Emitter emit,  struct ArrayAccessInfo *co
   e->next = next;
   return ret > 0 ? next : NULL;
 }
+
 static OP_EMIT(opem_array_access) {
   struct ArrayAccessInfo *const info = (struct ArrayAccessInfo*)data;
   if(info->array.type->array_depth >= info->array.depth) {
@@ -329,7 +336,7 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_func_end(gwi, vm_vector_rem, ae_flag_none))
 
   GWI_BB(gwi_class_end(gwi))
-  GWI_BB(gwi_oper_ini(gwi, "@Array", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array_at))
   GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
   GWI_BB(gwi_oper_ini(gwi, "nonnull @Array", (m_str)OP_ANY_TYPE, NULL))
index 688f27212bf511ad3f11e51453a72fbb28646557..b920d6b3558d43a2475a8d5082c75ea176b49781 100644 (file)
@@ -67,7 +67,7 @@ OP_CHECK(opck_object_dot);
 OP_EMIT(opem_object_dot);
 ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
-  gwi->gwion->type[et_class] = t_class;
+  GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
   GWI_BB(gwi_add_type(gwi, t_class))
   GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_object_dot))
@@ -77,8 +77,9 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
   const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
+  SET_FLAG(t_auto, infer);
   GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
-  SET_FLAG(t_class, abstract);
+  SET_FLAG(t_class, infer);
   const Type t_void  = gwi_mk_type(gwi, "void", 0, NULL);
   GWI_BB(gwi_gack(gwi, t_void, gack_void))
   GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
@@ -113,11 +114,12 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr))
   GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr))
   const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, "@function");
+  SET_FLAG(t_lambda, infer);
   GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda))
+
   GWI_BB(gwi_typedef_ini(gwi, "int", "@internal"))
   GWI_BB(gwi_typedef_end(gwi, ae_flag_none))
 
-
   GWI_BB(import_object_op(gwi))
   GWI_BB(import_values(gwi))
 
index 86e6986236a1901cdb1267e74cd8a81cbd6e47e1..3b6f05c72a9c9d8967f4b36b6f0899a9bca9f923 100644 (file)
@@ -406,7 +406,7 @@ ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td) {
     return a->base.type;
   struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
     .scope=env->scope->depth, .flag=ae_flag_scan0 };
-  CHECK_BO(envset_push(&es, t->e->owner_class, t->e->owner))
+  CHECK_BO(envset_push(&es, t->e->owner_class, env->context->nspc))
   a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, td->types);
   const m_bool ret = _scan_class(env, t, a);
   if(es.run)
index 597130d27acc47c4ac0e8ec97c052362867ff01d..156e85fc080c2d245ceeed418edb0e99776f1ba3 100644 (file)
@@ -17,12 +17,13 @@ static void sig(int unused NUSED) {
 
 #ifdef __AFL_HAVE_MANUAL_CONTROL
 
-#define BUFSIZE 256
+#define BUFSIZE 128
 
 static void afl_run(const Gwion gwion) {
+  __AFL_INIT();
   char buf[BUFSIZE];
   struct GwText_ text = { .mp=gwion->mp };
-  while (__AFL_LOOP(128)) {
+  while (__AFL_LOOP(256)) {
     ssize_t sz;
     memset(buf, 0, BUFSIZE);
     while((sz = read(0, buf, BUFSIZE)) > 0) {
@@ -33,12 +34,12 @@ static void afl_run(const Gwion gwion) {
       push_global(gwion, "[afl]");
       gwion_run(gwion);
       pop_global(gwion);
-    }
+   }
     text_reset(&text);
   }
   text_release(&text);
 }
-#define gwion_run(a) afl_run(a)
+#define gwion_run(a) { afl_run(a); return; }
 #endif
 
 int main(int argc, char** argv) {
index a1147bda1a6079a93307cbce680c2e67a7633c31..8e7b7f5bd2420c0b9e9520aa9efbf2fd542ec51c 100644 (file)
@@ -159,8 +159,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
     clear_decl(env, decl);
     CHECK_BO(scan1_exp(env, exp_self(decl)))
     CHECK_BO(scan2_exp(env, exp_self(decl)))
-    const Type t_auto = env->gwion->type[et_auto];
-    if(decl->type == t_auto)
+    if(GET_FLAG(decl->type, infer))
       ERR_O(td_pos(decl->td), _("can't infer type."));
   }
   if(!decl->type)
@@ -175,7 +174,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
   const m_bool ret = check_decl(env, decl);
   if(global)
     env_pop(env, scope);
-  return ret > 0 ? decl->type : NULL;
+  return ret > 0 ? decl->list->self->value->type : NULL;
 }
 
 
@@ -980,8 +979,11 @@ ANN static m_bool do_stmt_auto(const Env env, const Stmt_Auto stmt) {
       td.array = &array;
     }
     ptr = known_type(env, &td);
-    if(!GET_FLAG(ptr, checked) && ptr->e->def)
-      CHECK_BB(ensure_check(env, ptr))
+    if(!GET_FLAG(ptr, checked) && ptr->e->def) {
+      struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef,
+        .scope=env->scope->depth, .flag=ae_flag_check };
+      CHECK_BB(envset_run(&es, get_type(ptr)))
+    }
   }
   t = depth ? array_type(env, ptr, depth) : ptr;
   stmt->v = new_value(env->gwion->mp, t, s_name(stmt->sym));
@@ -1138,9 +1140,11 @@ ANN static Symbol case_op(const Env env, const Exp e, const m_uint i) {
 }
 
 ANN static m_bool match_case_exp(const Env env, Exp e) {
+  Exp last = e;
   for(m_uint i = 0; i < map_size(&env->scope->match->map); e = e->next, ++i) {
     if(!e)
-    ERR_B(e->pos, _("no enough to match"))
+      ERR_B(last->pos, _("no enough to match"))
+    last = e;
     const Symbol op = case_op(env, e, i);
     if(op) {
       const Exp base = (Exp)VKEY(&env->scope->match->map, i);
index a0a52c6f25d9870c1e932da5425f3654bbf7c5e4..932c63a14e7cc39445073f1427744f10b711fbf6 100644 (file)
@@ -113,15 +113,14 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl* td) {
     CHECK_OO(owner)
     if(!owner->nspc)
       ERR_O(td_pos(td), "type '%s' has no namespace", owner->name)
-    const Tmpl *tmpl = GET_FLAG(owner, template) ?
-      owner->e->def->base.tmpl : NULL;
-    if(tmpl)
-      CHECK_BO(template_push_types(env, tmpl))
-    const m_uint scope = env_push(env, owner, owner->nspc);
+    struct EnvSet es = { .env=env, .data=env,
+      .scope=env->scope->depth, .flag=ae_flag_none };
+    envset_push(&es, owner, owner->nspc);
+    (void)env_push(env, owner, owner->nspc);
     const Type ret = scan_type(env, t, td->next);
-    env_pop(env, scope);
-    if(tmpl)
-      nspc_pop_type(env->gwion->mp, env->curr);
+    env_pop(env, es.scope);
+    if(es.run)
+      envset_pop(&es, owner);
     return ret;
   }
   return _scan_type(env, t, td);
index 248d56e0c55d846897c0380d2df108a2336b826e..008a8425111a193b328f21cd2abacead96cde1f3 100644 (file)
@@ -705,16 +705,19 @@ branchnefloat:
   reg -= SZ_FLOAT;
   BRANCH_DISPATCH(*(m_float*)reg);
 arrayappend:
-  m_vector_add(ARRAY(a.obj), reg);
-  release(a.obj, shred);
+  m_vector_add(ARRAY(*(M_Object*)(reg-SZ_INT)), reg);
+  release(*(M_Object*)(reg-SZ_INT), shred);
   DISPATCH()
 autoloop:
-  m_vector_get(ARRAY(a.obj), *(m_uint*)(mem + VAL), mem + VAL + SZ_INT);
+//  m_vector_get(ARRAY(a.obj), *(m_uint*)(mem + VAL), mem + VAL + SZ_INT);
+  m_vector_get(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL), mem + VAL + SZ_INT);
   goto autoloopcount;
 autoloopptr:
-  *(m_bit**)(*(M_Object*)(mem + VAL + SZ_INT))->data = m_vector_addr(ARRAY(a.obj), *(m_uint*)(mem + VAL));
+  *(m_bit**)(*(M_Object*)(mem + VAL + SZ_INT))->data = m_vector_addr(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL));
+//  *(m_bit**)(*(M_Object*)(mem + VAL + SZ_INT))->data = m_vector_addr(ARRAY(a.obj), *(m_uint*)(mem + VAL));
 autoloopcount:
-  *(m_uint*)reg = m_vector_size(ARRAY(a.obj)) - (*(m_uint*)(mem + VAL))++;
+  *(m_uint*)reg = m_vector_size(ARRAY(*(M_Object*)(reg-SZ_INT))) - (*(m_uint*)(mem + VAL))++;
+//  *(m_uint*)reg = m_vector_size(ARRAY(a.obj)) - (*(m_uint*)(mem + VAL))++;
   reg += SZ_INT;
   DISPATCH()
 arraytop:
@@ -726,6 +729,7 @@ arrayaccess:
 {
   register const m_int idx = *(m_int*)(reg + SZ_INT * VAL);
   if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) {
+//  if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(*(M_Object*)(reg-SZ_INT)))) {
     gw_err(_("  ... at index [%" INT_F "]\n"), idx);
     gw_err(_("  ... at dimension [%" INT_F "]\n"), VAL);
     VM_OUT
@@ -766,9 +770,6 @@ objassign:
   }
 assign:
   reg -= SZ_INT;
-//  a.obj = *(M_Object*)(reg-SZ_INT);
-//  **(M_Object**)reg = a.obj;
-//  a.obj = 
   **(M_Object**)reg = *(M_Object*)(reg-SZ_INT);
   DISPATCH()
 remref: