]> Nishi Git Mirror - gwion.git/commitdiff
:art: Fixes
authorJérémie Astor <fennecdjay@gmail.com>
Sat, 19 Jun 2021 20:31:37 +0000 (22:31 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Sat, 19 Jun 2021 20:31:37 +0000 (22:31 +0200)
24 files changed:
ast
include/emit.h
include/env/env.h
include/env/func.h
include/env/nspc.h
include/env/value.h
include/instr.h
include/parse.h
include/vm.h
src/emit/emit.c
src/import/import_checker.c
src/lib/array.c
src/lib/engine.c
src/lib/lib_func.c
src/lib/object_op.c
src/lib/prim.c
src/lib/shred.c
src/lib/string.c
src/lib/ugen.c
src/main.c
src/parse/check.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/template.c

diff --git a/ast b/ast
index 5796cf89170539636d4f1405c59bc938e055acb0..476773eed83abcd74bf28cccebc59cf9eccca8bb 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 5796cf89170539636d4f1405c59bc938e055acb0
+Subproject commit 476773eed83abcd74bf28cccebc59cf9eccca8bb
index 2d6a777095375c3ee799b0a87b700147e8771c90..56837bcfcd017b59954fdd2ecd7d802eea2de53b 100644 (file)
@@ -11,7 +11,7 @@ typedef struct Frame_ {
 } Frame;
 
 typedef struct VMValue_ {
-  Type t;
+  Type     t;
   uint16_t offset;
   uint16_t start;
   uint16_t end;
@@ -87,11 +87,13 @@ ANN static inline bool is_static_call(const Emitter emit, const Exp e) {
   if (e->exp_type != ae_exp_dot) return true;
   const Exp_Dot *member = &e->d.exp_dot;
   return GET_FLAG(member->base->type, final) ||
+         !vflag(exp_self(member)->type->info->value, vflag_member) ||
          is_class(emit->gwion, member->base->type) ||
          member->base->exp_type == ae_exp_cast;
 }
 
-ANN Instr emit_kind(Emitter, const m_uint size, const bool addr, const f_instr func[]);
+ANN Instr emit_kind(Emitter, const m_uint size, const bool addr,
+                    const f_instr func[]);
 ANN Instr emit_regpushimm(Emitter, const m_uint, const bool);
 ANN Instr emit_regpushmem(Emitter, const m_uint, const bool);
 ANN Instr emit_regpushbase(Emitter, const m_uint, const bool);
index 7ece02a5b252f78086a149d3f3e16b272882fbea..822956c47c7c16fe792bf0c77e239c5cd868fef4 100644 (file)
@@ -25,6 +25,7 @@ struct Env_Scope_ {
   uint16_t       depth;
   bool           in_try;
   bool           in_loop;
+  bool           allow_curry;
 };
 
 typedef struct Env_ {
index f2a5d96851f83f1a708247bbd6856fd7baf94bb3..d567a548e5684200eb3b636ea33e1efc875b1940 100644 (file)
@@ -7,8 +7,9 @@ enum fflag {
   fflag_ftmpl  = 1 << 2,
   fflag_tmpl   = 1 << 3,
   fflag_valid  = 1 << 4,
-  fflag_return = 1 << 5,
-  fflag_recurs = 1 << 6,
+  fflag_emit   = 1 << 5,
+  fflag_return = 1 << 6,
+  fflag_recurs = 1 << 7,
 } __attribute__((packed));
 
 struct Func_ {
index a988f25379ff87de0f0aab1b401e51e1fa605acb..53624c66ed82746dc99253f8be8febd4f7834d72 100644 (file)
@@ -1,14 +1,15 @@
 #ifndef __NSPC
 #define __NSPC
 struct NspcInfo_ {
-  m_bit *     class_data;
-  struct Map_ op_map;
-  Scope       value;
-  Scope       type;
-  Scope       func;
-  Scope       trait;
-  size_t      offset;
-  size_t      class_data_size;
+  m_bit *        class_data;
+  struct Map_    op_map;
+  Scope          value;
+  Scope          type;
+  Scope          func;
+  Scope          trait;
+  struct Vector_ op_map_tmpl;
+  uint16_t       offset;
+  uint16_t       class_data_size;
 };
 
 struct Nspc_ {
index c4c70097b207c05d27b9fa9368d177d8c3b88c3a..67879b7b3d83cad28b3d8a2b2e5cea79f2b84360 100644 (file)
@@ -46,6 +46,7 @@ ANEW ANN Value new_value(MemPool p, const Type type, const m_str name);
 ANN void       valuefrom(const Env, struct ValueFrom_ *, const loc_t loc);
 
 ANN static inline void defined_here(const Value v) {
-  gwerr_secondary(_("defined here"), v->from->filename, v->from->loc);
+  if (v->from->filename) // TODO: check why is that from check
+    gwerr_secondary(_("defined here"), v->from->filename, v->from->loc);
 }
 #endif
index b2887574b0de5719c0416c735179ab79299777e6..82bf384f2c4950ecd797f7a081153971b500b830 100644 (file)
@@ -11,7 +11,7 @@
   __attribute__((hot)) ANN2(1) void a(const VM_Shred shred NUSED,              \
                                       const Instr instr    NUSED)
 
-//enum Kind { KIND_INT, KIND_FLOAT, KIND_OTHER, KIND_ADDR };
+// enum Kind { KIND_INT, KIND_FLOAT, KIND_OTHER, KIND_ADDR };
 
 typedef struct Instr_ *Instr;
 typedef void (*f_instr)(const VM_Shred, const Instr);
index 4de09fd6de8121472133c2bfb4c82be6e9db69be..0bd829e9381e7f483400321ff9b23b29740d5eb1 100644 (file)
@@ -101,10 +101,9 @@ ANN static inline void env_inline_mult(const Env env, const float mult) {
 
 ANN static inline bool is_hole(const Env env, const Exp exp) {
   const Symbol hole = insert_symbol("_");
-  if(exp->exp_type == ae_exp_primary) {
-    if(exp->d.prim.prim_type == ae_prim_id) {
-      if(exp->d.prim.d.var == hole)
-        return true;
+  if (exp->exp_type == ae_exp_primary) {
+    if (exp->d.prim.prim_type == ae_prim_id) {
+      if (exp->d.prim.d.var == hole) return true;
     }
   }
   return false;
index 1735c550199f091e7f428d786a0959a82c979321..777e33ee90a178cf51b25f84dac6bb0edeb30f55 100644 (file)
@@ -16,19 +16,19 @@ struct VM_Code_ {
     struct Vector_ instr;
     m_uint         native_func;
   };
-  Type   ret_type; // could be `struct Vector_ tmpl_types;`
+  Type ret_type; // could be `struct Vector_ tmpl_types;`
   union {
     void *   memoize;
     Closure *closure;
   };
-  m_str       name;
-  struct Map_ handlers;
+  m_str            name;
+  struct Map_      handlers;
   struct M_Vector_ live_values;
-  uint16_t    stack_depth;
-  uint16_t    ref;
-  bool        builtin;
-  bool        callback;
-  bool        is_memoize;
+  uint16_t         stack_depth;
+  uint16_t         ref;
+  bool             builtin;
+  bool             callback;
+  bool             is_memoize;
 };
 
 typedef struct frame_t {
@@ -97,9 +97,10 @@ struct VM_Shred_ {
   struct ShredInfo_ *info;
 };
 REF_FUNC(VM_Code, vmcode)
-ANN2(1,4)
-ANEW VM_Code new_vmcode(MemPool p, const Vector instr, const M_Vector live_values, const m_str name,
-                        const uint16_t stack_depth, const bool builtin);
+ANN2(1, 4)
+ANEW VM_Code     new_vmcode(MemPool p, const Vector instr,
+                            const M_Vector live_values, const m_str name,
+                            const uint16_t stack_depth, const bool builtin);
 ANN ANEW VM_Code vmcode_callback(MemPool p, const VM_Code code);
 
 ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
index 480c408169511ff4ebe3fcaf2fb632ee95866433..64d871204081336a1a0c786e490a0dc39cedf533 100644 (file)
@@ -498,7 +498,8 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
            : emit_regpushbase(emit, size, exp_getvar(prim_exp(data)));
   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 || is_fptr(emit->gwion,  v->type))) {
+      (isa(v->type, emit->gwion->type[et_object]) > 0 ||
+       is_fptr(emit->gwion, v->type))) {
     const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
     instr->m_val      = -SZ_INT;
   }
@@ -506,6 +507,8 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
 }
 
 ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary *prim) {
+  if (!prim->value) // assume it's an operator
+    ERR_B(exp_self(prim)->pos, "missing value for operator");
   return _emit_symbol(emit, &prim->d.var);
 }
 
@@ -1137,8 +1140,8 @@ ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call *exp_call) {
   // skip when recursing
   const Type t = actual_type(emit->gwion, exp_call->func->type);
   const Func f = t->info->func;
-  if (is_fptr(emit->gwion, t) || f != emit->env->func ||
-      f->value_ref->from->owner_class || strstr(emit->code->name, "ork~"))
+  if (is_fptr(emit->gwion, t) || strstr(emit->code->name, "ork~") ||
+      (f != emit->env->func || f->value_ref->from->owner_class))
     CHECK_BB(prepare_call(emit, exp_call));
   else
     CHECK_BB(emit_func_args(emit, exp_call));
@@ -1180,10 +1183,11 @@ ANN static m_uint get_decl_size(Var_Decl_List a, bool emit_addr) {
 ANN static m_uint pop_exp_size(Exp e) {
   const bool emit_addr = exp_getvar(e);
   m_uint     size      = 0;
-  do { // account for emit_var ?
+  do {
     size += (e->exp_type == ae_exp_decl
                  ? get_decl_size(e->d.exp_decl.list, emit_addr)
-                 : e->type->size);
+             : !emit_addr ? e->type->size
+                          : SZ_INT);
   } while ((e = e->next));
   return size;
 }
@@ -1435,12 +1439,12 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f,
       }
     } else if (emit->env->func != f && !f->value_ref->from->owner_class &&
                !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
+      // ensure env?
+      CHECK_BB(emit_func_def(emit, f->def));
       if (fbflag(f->def->base, fbflag_op)) {
         const Instr back = (Instr)vector_back(&emit->code->instr);
         back->m_val      = (m_uint)f;
       } else {
-        // ensure env?
-        CHECK_BB(emit_func_def(emit, f->def));
         const Instr instr = emit_add_instr(emit, RegSetImm);
         instr->m_val      = (m_uint)f->code;
         instr->m_val2     = -SZ_INT;
@@ -1457,14 +1461,13 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f,
   }
   if (vector_size(&emit->code->instr) && vflag(f->value_ref, vflag_member) &&
       is_fptr(emit->gwion, f->value_ref->type)) {
-    const Instr back = (Instr)vector_back(&emit->code->instr);
-    const bool is_except = back->opcode == eGWOP_EXCEPT;
-    const Instr base = !is_except
-            ? back
-            : (Instr)vector_at(&emit->code->instr,
-                               vector_size(&emit->code->instr) - 2);
-    if(is_except)
-      vector_pop(&emit->code->instr);
+    const Instr back      = (Instr)vector_back(&emit->code->instr);
+    const bool  is_except = back->opcode == eGWOP_EXCEPT;
+    const Instr base =
+        !is_except ? back
+                   : (Instr)vector_at(&emit->code->instr,
+                                      vector_size(&emit->code->instr) - 2);
+    if (is_except) vector_pop(&emit->code->instr);
     const m_bit  exec = base->opcode;
     const m_uint val  = base->m_val;
     const m_uint val2 = base->m_val2;
@@ -1474,9 +1477,9 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f,
     const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
     instr->m_val      = val;
     instr->m_val2     = val2;
-    if(is_except) {
-       vector_add(&emit->code->instr, (m_uint)back);
-       back->m_val = -SZ_INT;
+    if (is_except) {
+      vector_add(&emit->code->instr, (m_uint)back);
+      back->m_val = -SZ_INT;
     }
   } else if (f != emit->env->func && !f->code &&
              !is_fptr(emit->gwion, f->value_ref->type)) {
@@ -1696,7 +1699,7 @@ ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If *exp_if) {
     exp_setvar(exp_if->else_exp, 1);
   }
   DECL_OB(const Instr, op, = emit_flow(emit, exp_if->cond));
-  CHECK_BB(emit_exp_pop_next(emit, exp_if->if_exp ?: exp_if->cond));
+  CHECK_BB(emit_exp_pop_next(emit, e));
   const Instr op2  = emit_add_instr(emit, Goto);
   op->m_val        = emit_code_size(emit);
   const m_bool ret = emit_exp_pop_next(emit, exp_if->else_exp);
@@ -1775,7 +1778,9 @@ ANN static m_bool emit_exp_lambda(const Emitter     emit,
 }
 
 ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl *td) {
-  regpushi(emit, (m_uint)_class_base(exp_self(td)->type));
+  const Type base = exp_self(td)->type;
+  const Type t    = _class_base(base) ?: base;
+  regpushi(emit, (m_uint)t);
   return GW_OK;
 }
 
@@ -2649,7 +2654,9 @@ ANN m_bool emit_func_def(const Emitter emit, const Func_Def f) {
   const Func     func   = f->base->func;
   const Func_Def fdef   = func->def;
   const Func     former = emit->env->func;
-  if (func->code || tmpl_base(fdef->base->tmpl)) return GW_OK;
+  if (func->code || tmpl_base(fdef->base->tmpl) || fflag(func, fflag_emit))
+    return GW_OK;
+  set_fflag(func, fflag_emit);
   if (vflag(func->value_ref, vflag_builtin) &&
       safe_tflag(emit->env->class_def, tflag_tmpl)) {
     const Func base =
@@ -2731,7 +2738,7 @@ ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
 
 ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
   if (tmpl_base(cdef->base.tmpl)) return GW_OK;
-  const Type t = cdef->base.type;
+  const Type      t = cdef->base.type;
   const Class_Def c = t->info->cdef;
   if (tflag(t, tflag_emit)) return GW_OK;
   set_tflag(t, tflag_emit);
index c855a5861e528cd71dfcb530cffd25313d5f1cec..ae7c1fce1bae462fe475b99367ba56b0669e3baf 100644 (file)
@@ -209,7 +209,7 @@ ANN Type_Decl *str2td(const Gwion gwion, const m_str str, const loc_t pos) {
   DECL_OO(Type_Decl *, td, = _str2td(gwion, &tdc));
   if (*tdc.str) {
     free_type_decl(gwion->mp, td);
-    GWION_ERR_O(pos, "excedental character '%c'", *tdc.str);
+    GWION_ERR_O(pos, "excedental character '%c' in '%s'", *tdc.str, str);
   }
   return td;
 }
index 042dc9286171c6898a11049b11fd2936777e442c..c3c38f895053042102e77c7cf1e5c5c9a605c7cb 100644 (file)
@@ -634,6 +634,12 @@ static OP_CHECK(opck_array_scan) {
   const Class_Def      c       = t_array->info->cdef;
   DECL_ON(const Type, base,
           = ts->t != t_array ? ts->t : known_type(env, ts->td->types->td));
+  if (base->size == 0) {
+    gwerr_basic("Can't use type of size 0 as array base", NULL, NULL,
+                "/dev/null", (loc_t) {}, 0);
+    env->context->error = true;
+    return env->gwion->type[et_error];
+  }
   if (!strncmp(base->name, "Ref:[", 5)) {
     gwerr_basic("Can't use ref types as array base", NULL, NULL, "/dev/null",
                 (loc_t) {}, 0);
@@ -660,10 +666,11 @@ static OP_CHECK(opck_array_scan) {
   const m_uint scope = env_push(env, base->info->value->from->owner_class,
                                 base->info->value->from->owner);
   (void)scan0_class_def(env, cdef);
-  const Type t = cdef->base.type;
-  (void)traverse_cdef(env, t);
+  const Type   t   = cdef->base.type;
+  const m_bool ret = traverse_cdef(env, t);
   env_pop(env, scope);
   env->context = ctx;
+  if (ret == GW_ERROR) return NULL;
   if (GET_FLAG(base, abstract))
     SET_FLAG(t, abstract);
   else
index 3d88d5071b266116b2f0a5a68c9b8d33f8ca388a..4f08b734050e2c97b7111a93b442b588ba56b00a 100644 (file)
@@ -157,7 +157,6 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   const Type t_curry = gwi_mk_type(gwi, "@Curry", 0, NULL);
   GWI_BB(gwi_set_global_type(gwi, t_curry, et_curry))
 
-
   gwidoc(gwi, "type for internal pointer data.");
   GWI_BB(gwi_typedef_ini(gwi, "int", "@internal"))
   GWI_BB(gwi_typedef_end(gwi, ae_flag_none))
index 3eabfa43bf7f85addfe12d169ef46aeec9f48475..2cdec9e390c18e2577f045c8facfc89ae723a1df 100644 (file)
@@ -23,12 +23,12 @@ static OP_CHECK(opck_func_call) {
 }
 
 ANN static inline Exp cpy_nonext(const Env env, const Exp e) {
-  const MemPool mp = env->gwion->mp;
-  const Exp next = e->next;
-  e->next = NULL;
-  const Exp ret = cpy_exp(mp, e);
-  e->next = next;
-  if(!check_exp(env, ret)) {
+  const MemPool mp   = env->gwion->mp;
+  const Exp     next = e->next;
+  e->next            = NULL;
+  const Exp ret      = cpy_exp(mp, e);
+  e->next            = next;
+  if (!check_exp(env, ret)) {
     free_exp(mp, ret);
     return NULL;
   }
@@ -36,29 +36,28 @@ ANN static inline Exp cpy_nonext(const Env env, const Exp e) {
 }
 
 ANN static Exp order_curry(const Env env, Exp fn, Exp arg) {
-  const MemPool mp = env->gwion->mp;
-  Exp base   = NULL;
-  Exp next   = NULL;
+  const MemPool mp   = env->gwion->mp;
+  Exp           base = NULL;
+  Exp           next = NULL;
   do {
     const bool hole = is_hole(env, fn);
-    const Exp curr = !hole ? fn : arg;
-    if(hole) {
-      if(!arg) {
-        if(base)
-          free_exp(mp, base);
+    const Exp  curr = !hole ? fn : arg;
+    if (hole) {
+      if (!arg) {
+        if (base) free_exp(mp, base);
         ERR_O(fn->pos, "no enough arguments for holes");
       }
       arg = arg->next;
     }
-    if(!base)
+    if (!base)
       base = next = cpy_nonext(env, curr);
     else {
       next->next = cpy_nonext(env, curr);
-      next = next->next;
+      next       = next->next;
     }
   } while ((fn = fn->next));
   assert(base);
-  if(arg) {
+  if (arg) {
     free_exp(mp, base);
     ERR_O(arg->pos, "too many arguments for holes");
   }
@@ -69,15 +68,16 @@ static OP_CHECK(opck_curry) {
   Exp_Binary *bin  = (Exp_Binary *)data;
   Exp         lhs  = bin->lhs;
   Exp_Call    base = bin->rhs->d.exp_call;
-  DECL_OO(const Exp,   args, = order_curry(env, base.args, lhs));
-  Exp_Call    call = {.func = base.func, .args = args};
-  Exp         e    = exp_self(bin);
-  e->exp_type      = ae_exp_call;
-  e->type          = NULL;
+  DECL_ON(const Exp, args, = order_curry(env, base.args, lhs));
+  Exp_Call call = {.func = base.func, .args = args};
+  Exp      e    = exp_self(bin);
+  e->exp_type   = ae_exp_call;
+  e->type       = NULL;
   memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
   const MemPool mp = env->gwion->mp;
   free_exp(mp, base.args);
   free_exp(mp, lhs);
+  env->scope->allow_curry = true;
   return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
 }
 
@@ -94,7 +94,8 @@ static OP_EMIT(opem_func_assign) {
     fptr_instr(emit, bin->lhs->type->info->func, 2);
   (void)emit_add_instr(emit, int_r_assign);
   if (!is_fptr(emit->gwion, bin->lhs->type) &&
-      vflag(bin->rhs->type->info->func->value_ref, vflag_member)) {
+      vflag(bin->rhs->type->info->func->value_ref, vflag_member)/*&&
+      bin->lhs->exp_type != ae_exp_td*/) {
     const Instr pop = emit_add_instr(emit, RegMove);
     pop->m_val      = -SZ_INT;
     const Instr cpy = emit_add_instr(emit, Reg2Reg);
@@ -341,6 +342,9 @@ static OP_CHECK(opck_fptr_at) {
   Exp_Binary *bin = (Exp_Binary *)data;
   if (bin->rhs->exp_type == ae_exp_decl)
     UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
+  if (bin->lhs->exp_type == ae_exp_td)
+    ERR_N(bin->lhs->pos, "can't use type_decl expression");
+  //    UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
   if (bin->rhs->type->info->func->def->base->tmpl &&
       bin->rhs->type->info->func->def->base->tmpl->call) {
     struct FptrInfo info = {bin->lhs->type->info->func,
@@ -357,7 +361,7 @@ static OP_CHECK(opck_fptr_at) {
   exp_setvar(bin->rhs, 1);
   return bin->rhs->type;
 }
-
+/*
 static OP_CHECK(opck_fptr_cast) {
   Exp_Cast *      cast = (Exp_Cast *)data;
   const Type      t    = exp_self(cast)->type;
@@ -366,7 +370,7 @@ static OP_CHECK(opck_fptr_cast) {
   CHECK_BN(fptr_do(env, &info));
   return t;
 }
-
+*/
 static void member_fptr(const Emitter emit) {
   const Instr instr = emit_add_instr(emit, RegMove);
   instr->m_val      = -SZ_INT;
@@ -377,7 +381,7 @@ static void member_fptr(const Emitter emit) {
 static inline int is_member(const Type from) {
   return vflag(from->info->func->value_ref, vflag_member);
 }
-
+/*
 static OP_EMIT(opem_fptr_cast) {
   const Exp_Cast *cast = (Exp_Cast *)data;
   if (is_member(cast->exp->type)) member_fptr(emit);
@@ -385,7 +389,7 @@ static OP_EMIT(opem_fptr_cast) {
     fptr_instr(emit, cast->exp->type->info->func, 1);
   return GW_OK;
 }
-
+*/
 static OP_CHECK(opck_fptr_impl) {
   struct Implicit *impl = (struct Implicit *)data;
   struct FptrInfo  info = {impl->e->type->info->func, impl->t->info->func,
@@ -657,9 +661,9 @@ GWION_IMPORT(func) {
   GWI_BB(gwi_oper_add(gwi, opck_fptr_at))
   GWI_BB(gwi_oper_emi(gwi, opem_func_assign))
   GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_fptr_cast))
-  GWI_BB(gwi_oper_emi(gwi, opem_fptr_cast))
-  GWI_BB(gwi_oper_end(gwi, "$", NULL))
+  //  GWI_BB(gwi_oper_add(gwi, opck_fptr_cast))
+  //  GWI_BB(gwi_oper_emi(gwi, opem_fptr_cast))
+  //  GWI_BB(gwi_oper_end(gwi, "$", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_fptr_impl))
   GWI_BB(gwi_oper_emi(gwi, opem_fptr_impl))
   GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
index 92aead951bcd9e48c3d3ebb96f828e0373559800..906284e4b2e8520a9b163b682f2b124a1253ca12 100644 (file)
@@ -70,6 +70,7 @@ static Type opck_object_scan(const Env env, const struct TemplateScan *ts) {
 
 static OP_CHECK(opck_struct_scan) {
   struct TemplateScan *ts = (struct TemplateScan *)data;
+  CHECK_OO(ts->td);
   return opck_object_scan(env, ts);
 }
 
@@ -128,7 +129,6 @@ ANN static inline void emit_member(const Emitter emit, const Value v,
   const m_uint size  = v->type->size;
   const Instr  instr = emit_dotmember(emit, size, emit_addr);
   instr->m_val       = v->from->offset;
-  instr->m_val2      = size;
 }
 
 ANN static inline void emit_struct_data(const Emitter emit, const Value v,
@@ -199,11 +199,17 @@ OP_EMIT(opem_object_dot) {
   const Exp_Dot *member = (Exp_Dot *)data;
   const Type     t_base = actual_type(emit->gwion, member->base->type);
   const Value    value  = find_value(t_base, member->xid);
+  if (is_class(emit->gwion, value->type)) {
+    const Instr instr = emit_add_instr(emit, RegPushImm);
+    instr->m_val      = (m_uint)value->type;
+    return GW_OK;
+  }
   if (!is_class(emit->gwion, member->base->type) &&
       (vflag(value, vflag_member) ||
        (isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 &&
         !is_fptr(emit->gwion, exp_self(member)->type)))) {
-    if (!tflag(t_base, tflag_struct)) CHECK_BB(emit_exp(emit, member->base));
+    if (!tflag(t_base, tflag_struct) && vflag(value, vflag_member))
+      CHECK_BB(emit_exp(emit, member->base));
   }
   if (isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 &&
       !is_fptr(emit->gwion, exp_self(member)->type))
index 5d73847c1f8522c35cb986b5a1cbdbf188583e1b..0f67c3f5e332cc3a45559ff197be76952161ab55 100644 (file)
@@ -173,8 +173,8 @@ static OP_EMIT(opem_int_range) {
   static OP_CHECK(opck_##ntype##_##name) {                                     \
     /*const*/ Exp_Unary *unary = (Exp_Unary *)data;                            \
     const Type           t     = env->gwion->type[TYPE];                       \
-    if (!exp_self(unary)->pos.first.line || !func(unary->exp)) return t;       \
     CHECK_NN(opck_unary_meta(env, data));                                      \
+    if (!func(unary->exp)) return t;                                           \
     const ctype num                   = OP unary->exp->d.prim.d.member;        \
     exp_self(unary)->exp_type         = ae_exp_primary;                        \
     exp_self(unary)->d.prim.prim_type = exptype;                               \
@@ -255,7 +255,7 @@ static OP_CHECK(opck_implicit_i2f) { return env->gwion->type[et_float]; }
               is_prim_float, m_float, ae_prim_float, num, fnum, fnum)
 #define BINARY_INT_FLOAT_FOLD2(name, TYPE, OP, pre, post)                      \
   BINARY_FOLD(int_float, name, TYPE, OP, pre, post, is_prim_int,               \
-              is_prim_float, m_float, ae_prim_float, num, fnum, num)
+              is_prim_float, m_float, ae_prim_num, num, fnum, num)
 
 BINARY_INT_FLOAT_FOLD(add, et_float, +, , )
 BINARY_INT_FLOAT_FOLD(sub, et_float, -, , )
index 31b875fc178117ea3125e51a09e60543b4e05ea8..b570e8ef2bbf72d4841a736f4a47c5189e708bff 100644 (file)
@@ -93,7 +93,7 @@ static SFUN(vm_shred_from_id) {
       }
     }
   }
-  *(m_uint *)RETURN = 0;
+  handle(shred, "InvalidShredRequest");
 }
 
 static MFUN(shred_args) {
@@ -108,7 +108,7 @@ static MFUN(shred_arg) {
     const m_str str = (m_str)vector_at(&s->info->args, *(m_uint *)MEM(SZ_INT));
     *(M_Object *)RETURN = str ? new_string(shred->info->mp, shred, str) : NULL;
   } else
-    *(m_uint *)RETURN = 0;
+    handle(shred, "InvalidShredArgumentRequest");
 }
 
 #ifndef BUILD_ON_WINDOWS
index dd6c827a376ee20074714d62180f52dc40983bcc..68ff08d33e4023c1f86bd0eadc7699b48cb37b31 100644 (file)
@@ -153,7 +153,7 @@ static MFUN(string_trim) {
       break;
   }
   if (len - start - end <= 0) {
-    *(m_uint *)RETURN = 0;
+    handle(shred, "InvalidStringTrimRequest");
     return;
   }
   char c[len - start - end + 1];
@@ -191,12 +191,7 @@ static MFUN(string_insert) {
   strcpy(str, STRING(o));
   m_int          i, len_insert = 0, index = *(m_int *)MEM(SZ_INT);
   const M_Object arg = *(M_Object *)MEM(SZ_INT * 2);
-
-  if (!arg) {
-    *(M_Object *)RETURN = NULL;
-    return;
-  }
-  char insert[strlen(STRING(arg)) + 1];
+  char           insert[strlen(STRING(arg)) + 1];
   strcpy(insert, STRING(arg));
   const m_uint len = strlen(str);
   len_insert       = strlen(insert);
@@ -223,7 +218,7 @@ static MFUN(string_replace) {
   const m_uint len = strlen(str);
   len_insert       = strlen(insert);
   if (index >= (m_int)len || index < 0 || (index + len_insert + 1) <= 0) {
-    *(M_Object *)RETURN = NULL;
+    handle(shred, "InvalidStringReplace");
     return;
   }
   char c[index + len_insert + 1];
@@ -242,7 +237,7 @@ static MFUN(string_replaceN) {
   const m_int    _len = *(m_int *)MEM(SZ_INT * 2);
   if (!arg || index > (m_int)strlen(STRING(o)) ||
       _len > (m_int)strlen(STRING(arg))) {
-    *(M_Object *)RETURN = NULL;
+    handle(shred, "InvalidStringReplace");
     return;
   }
   char         insert[strlen(STRING(arg)) + 1];
@@ -358,7 +353,7 @@ static MFUN(string_erase) {
   const m_int len   = strlen(str);
   const m_int size  = len - rem + 1;
   if (start >= len || size <= 0) {
-    *(M_Object *)RETURN = NULL;
+    handle(shred, "InvalidStringErase");
     return;
   }
   char c[size];
index 1dff2c77fe3d99b9b8c6ce528a739f572bc32fff..742b42dfff8d905d04d7a8995a3726cbbf5d4f17 100644 (file)
@@ -323,10 +323,10 @@ static MFUN(ugen_channel) {
   const m_int i = *(m_int *)MEM(SZ_INT);
   if (!UGEN(o)->multi)
     *(M_Object *)RETURN = !i ? o : NULL;
-  else if (i < 0 || (m_uint)i >= UGEN(o)->connect.multi->n_chan)
-    *(M_Object *)RETURN = NULL;
-  else
+  else if (i > 0 || (m_uint)i < UGEN(o)->connect.multi->n_chan)
     *(M_Object *)RETURN = UGEN(o)->connect.multi->channel[i];
+  else
+    handle(shred, "InvalidChannelRequest");
 }
 
 static MFUN(ugen_get_op) { *(m_uint *)RETURN = UGEN(o)->op + 1; }
index 864cb9dc32688a46f6b8f1cfdcde5a1af91a5efb..bdf756b98b1e294b39d9a4b55f46651c31fdb45c 100644 (file)
@@ -17,6 +17,8 @@ static void sig(int unused NUSED) {
 
 #ifdef __AFL_HAVE_MANUAL_CONTROL
 
+#include "compile.h"
+
 static void afl_run(const Gwion gwion) {
   gw_seed(gwion->vm->rand, 0);
   __AFL_INIT();
index 1337c3251349364810a95c588a840eb2181408f1..85b4ee2dc9d65aba0f884772b94edd2d13ad572b 100644 (file)
@@ -888,17 +888,15 @@ ANN static m_bool predefined_call(const Env env, const Type t,
 }
 
 ANN2(1) static inline bool curried(const Env env, Exp exp) {
-  while(exp) {
-    if (is_hole(env, exp))
-      return true;
+  while (exp) {
+    if (is_hole(env, exp)) return true;
     exp = exp->next;
   }
   return false;
 }
 
 ANN static Type check_exp_call(const Env env, Exp_Call *exp) {
-  if(curried(env, exp->args))
-    return env->gwion->type[et_curry];
+  if (curried(env, exp->args)) return env->gwion->type[et_curry];
   if (exp->tmpl) {
     DECL_BO(const m_bool, ret, = func_check(env, exp));
     if (!ret) return exp_self(exp)->type;
@@ -952,7 +950,7 @@ ANN static Type _flow(const Env env, const Exp e, const m_bool b) {
 #define check_flow(emit, b) _flow(emit, b, 1)
 
 ANN static Type check_exp_if(const Env env, Exp_If *const exp_if) {
-  if(!exp_if->if_exp) {
+  if (!exp_if->if_exp) {
     const Exp e = exp_if->if_exp = cpy_exp(env->gwion->mp, exp_if->cond);
     scan1_exp(env, e);
     scan2_exp(env, e);
@@ -961,7 +959,8 @@ ANN static Type check_exp_if(const Env env, Exp_If *const exp_if) {
   DECL_OO(const Type, if_exp, = check_exp(env, exp_if->if_exp));
   DECL_OO(const Type, else_exp, = check_exp(env, exp_if->else_exp));
 
-  const uint meta = exp_getmeta(exp_if->if_exp) || exp_getmeta(exp_if->else_exp);
+  const uint meta =
+      exp_getmeta(exp_if->if_exp) || exp_getmeta(exp_if->else_exp);
   exp_setmeta(exp_self(exp_if), meta);
   const Type ret = find_common_anc(if_exp, else_exp);
   if (!ret)
@@ -1056,7 +1055,7 @@ ANN static Type check_exp_lambda(const Env env, const Exp_If *exp_if NUSED) {
 
 ANN static Type check_exp_td(const Env env, Type_Decl **td) {
   DECL_OO(const Type, t, = known_type(env, *td));
-  if(isa(t, env->gwion->type[et_function]) > 0 && !is_fptr(env->gwion, t))
+  if (isa(t, env->gwion->type[et_function]) > 0 && !is_fptr(env->gwion, t))
     return type_class(env->gwion, t);
   return t;
 }
index 4a812bb1453b5cd40f5db3e3f4440f095c4f59a4..de04f4bf394977a323941010cdf62cdd0b09d7e9 100644 (file)
@@ -365,7 +365,7 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) {
   ID_List list = edef->list;
   do {
     CHECK_BB(already_defined(env, list->xid, edef->pos));
-    if(nspc_lookup_value1(edef->t->info->value->from->owner, list->xid))
+    if (nspc_lookup_value1(edef->t->info->value->from->owner, list->xid))
       ERR_B(edef->pos, "'%s' already defined", s_name(list->xid));
     const Value v = new_value(env->gwion->mp, edef->t, s_name(list->xid));
     valuefrom(env, v->from, edef->pos);
@@ -687,7 +687,7 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
 
 ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
   if (tmpl_base(cdef->base.tmpl)) return GW_OK;
-  const Type t = cdef->base.type;
+  const Type      t = cdef->base.type;
   const Class_Def c = t->info->cdef;
   if (tflag(t, tflag_scan1)) return GW_OK;
   set_tflag(t, tflag_scan1);
index 1e0e648cfd26628bb2b6ecea69e1e572a2ab8ec0..e65ca1950395f5383cd71f23df7aa13f81e2cb37 100644 (file)
@@ -329,10 +329,10 @@ ANN static void func_no_overload(const Env env, const Func f, const Value v) {
   value_addref(v);
   nspc_add_value_front(env->curr, f->def->base->xid, v);
 
-  const Type newt    = type_copy(env->gwion->mp, t);
-  t->info->parent = newt;
-  newt->name         = s_name(f->def->base->xid);
-  newt->info->func   = f;
+  const Type newt  = type_copy(env->gwion->mp, t);
+  t->info->parent  = newt;
+  newt->name       = s_name(f->def->base->xid);
+  newt->info->func = f;
   nspc_add_type_front(env->curr, f->def->base->xid, newt);
   newt->info->value = v;
 }
@@ -591,7 +591,7 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) {
 
 ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
   if (tmpl_base(cdef->base.tmpl)) return GW_OK;
-  const Type t = cdef->base.type;
+  const Type      t = cdef->base.type;
   const Class_Def c = t->info->cdef;
   if (tflag(t, tflag_scan2)) return GW_OK;
   if (t->info->value->from->owner_class)
index 5691dd9b31ef86ea41205a2cd47fc0ac0ce48e86..03395c4c8097d881b2613c8b1fb77131180d1c2b 100644 (file)
 #include "object.h"
 #include "import.h"
 
-ANN static m_bool push_types(const Env env, const Tmpl *tmpl) {
+ANN static m_bool _push_types(const Env env, const Nspc nspc,
+                              const Tmpl *tmpl) {
   Specialized_List list = tmpl->list;
   Type_List        call = tmpl->call;
   do {
     if (!call) break;
     const Type t = known_type(env, call->td);
-    if (!t) return 1;
-    nspc_add_type(env->curr, list->xid, t);
+    if (!t) return GW_OK;
+    nspc_add_type(nspc, list->xid, t);
     call = call->next;
   } while ((list = list->next));
-  return !call;
+  return !call ? GW_OK : GW_ERROR;
+}
+
+ANN static m_bool push_types(const Env env, const Nspc nspc, const Tmpl *tmpl) {
+  if (nspc->parent) env->curr = env->curr->parent;
+  const Type t = env->class_def;
+  if (t) env->class_def = t->info->value->from->owner_class;
+  const m_bool ret = _push_types(env, nspc, tmpl);
+  if (nspc->parent) env->curr = nspc;
+  env->class_def = t;
+  return ret;
 }
 
 ANN static m_bool _template_push(const Env env, const Type t) {
   if (t->info->value->from->owner_class)
     CHECK_BB(template_push(env, t->info->value->from->owner_class));
   if (tflag(t, tflag_tmpl))
-    return push_types(env, t->info->cdef->base.tmpl); // incorrect
+    return push_types(env, t->nspc, t->info->cdef->base.tmpl); // incorrect
   return GW_OK;
 }
 
@@ -40,7 +51,7 @@ ANN m_bool template_push(const Env env, const Type t) {
 
 ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) {
   nspc_push_type(env->gwion->mp, env->curr);
-  if (push_types(env, tmpl)) return GW_OK;
+  if (push_types(env, env->curr, tmpl) > 0) return GW_OK;
   POP_RET(GW_ERROR);
 }