]> Nishi Git Mirror - gwion.git/commitdiff
:art: Refactor op operations
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Sun, 8 Mar 2020 16:44:50 +0000 (17:44 +0100)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Sun, 8 Mar 2020 16:44:50 +0000 (17:44 +0100)
23 files changed:
examples/vec4.gw
include/array.h
include/emit.h
include/env/type.h
include/parse.h
src/emit/emit.c
src/lib/array.c
src/lib/complex.c
src/lib/engine.c
src/lib/object.c
src/lib/opfunc.c
src/lib/prim.c
src/lib/shred.c
src/lib/tuple.c
src/lib/vararg.c
src/lib/vec.c
src/parse/check.c
src/parse/operator.c
src/parse/scan1.c
tests/error/non_public_typedef_global_scope.gw
tests/internal_op/internal_not_int.gw
tests/match/internal_multi.gw
tests/tree/for_break_continue.gw

index 4dc23d48cab37f442ce26fb30ad57da384e7b668..3415180c19d9370e046a89b44a12119cc82ac83d 100644 (file)
@@ -23,7 +23,7 @@ Vec4 v, w;
 <<<  1 => v.y  >>>;
 <<<  1 => v.z  >>>;
 <<<  1 => v.w  >>>;
-<<<  Vec3(.1, .2, .4, .5) => v  >>>;
+<<<  Vec4(.1, .2, .4, .5) => v  >>>;
 
 <<<  "set ",      v.set(1,2,3,4)  >>>;
 <<<  "setAll ",    v.setAll(1.2)  >>>;
index 7d4eb41dffd092da340e2d4ea9aa3b22bf322029..2406090179996f833bc16bbe909bc1fa2d6bc790 100644 (file)
@@ -1,5 +1,12 @@
 #ifndef __ARRAY
 #define __ARRAY
+
+struct ArrayAccessInfo {
+  struct Array_Sub_ array;
+  const Type type;
+  const m_bool is_var;
+};
+
 typedef struct M_Vector_  * M_Vector;
 typedef struct ArrayInfo_ {
   m_int depth;
@@ -22,4 +29,6 @@ ANN m_bit* m_vector_addr(const M_Vector, const m_uint);
 ANN void m_vector_rem(const M_Vector,  const m_uint);
 ANEW M_Vector new_m_vector(MemPool, const m_uint size, const m_uint len);
 ANN void free_m_vector(MemPool, M_Vector);
+ANN Type check_array_access(const Env env, const Array_Sub array);
+ANN m_bool emit_array_access(const Emitter emit, struct ArrayAccessInfo *const info);
 #endif
index 8a8cb71eec1d55054b02e2b364883c2c45d41f9d..2c2c7569f80430535bcec869c51efb038482afeb 100644 (file)
@@ -51,5 +51,4 @@ ANN m_bool emit_exp(const Emitter, const Exp, const m_bool add_ref);
 ANN static inline void emit_except(const Emitter emit, const Type t) {
   emit_add_instr(emit, !GET_FLAG(t, nonnull) ? GWOP_EXCEPT : SetObj);
 }
-
 #endif
index 3f3086ee21721a8621396bb2caac2ba485093854..89fbb445779960c77cdecbaacd650291634a477b 100644 (file)
@@ -47,9 +47,9 @@ ANN m_bool is_class(const struct Gwion_*, const Type t);
 ANN m_uint get_depth(const Type type);
 
 typedef enum {
-  et_void, et_int, et_bool, et_char, et_float, et_complex, et_polar, et_vec3, et_vec4,
+  et_void, et_int, et_bool, et_char, et_float,
   et_null, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack,
-  et_function, et_fptr, et_varloop, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto, et_tuple,
+  et_function, et_fptr, et_varloop, et_vararg, et_lambda, et_class, et_union, et_undefined, et_auto,
   MAX_TYPE
 } type_enum;
 #endif
index 09f955a053264103ad311c9e7b7c40abf3c28654..43ffc4cc112d524332131bff4e2df7f36483116b 100644 (file)
@@ -85,5 +85,6 @@ ANN m_bool scanx_fdef(const Env, void *, const Func_Def, const _exp_func);
 
 __attribute__((returns_nonnull))
 ANN Type get_type(const Type t);
-ANN m_bool check_subscripts(const Env, const Array_Sub);
+ANN m_bool check_subscripts(const Env, const Array_Sub, const m_bool is_decl);
+ANN m_bool check_implicit(const Env env, const Exp e, const Type t);
 #endif
index 97312a7d16f372a9a72259aa051fdf90bf2caf59..d4f1baff050a434274cc851a582013d0dff5718c 100644 (file)
@@ -274,7 +274,7 @@ static inline enum Kind kindof(const m_uint size, const uint emit_var) {
   return size == SZ_INT ? KIND_INT : size == SZ_FLOAT ? KIND_FLOAT : KIND_OTHER;
 }
 
-ANN static Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]) {
+ANN /*static */Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]) {
   const enum Kind kind = kindof(size, addr);
   const Instr instr = emit_add_instr(emit, func[kind]);
   instr->m_val2 = size;
@@ -285,39 +285,13 @@ static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegP
 static const f_instr regpushmem[] = { RegPushMem, RegPushMem2, RegPushMem3, RegPushMem4 };
 static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, RegPushBase4 };
 static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
-static const f_instr dotmember[]  = { DotMember, DotMember2, DotMember3, DotMember4 };
 static const f_instr allocmember[]  = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 };
 static const f_instr allocword[]  = { AllocWord, AllocWord2, AllocWord3, RegPushMem4 };
 
-ANN static inline Exp this_exp(const Emitter emit, const Type t, const loc_t pos) {
-  const Exp exp = new_prim_id(emit->gwion->mp, insert_symbol("this"),
-    loc_cpy(emit->gwion->mp, pos));
-  exp->type = t;
-  return exp;
-}
-
-ANN static inline Exp dot_this_exp(const Emitter emit, const Symbol *data, const Type t) {
-  const Exp exp = this_exp(emit, t, prim_pos(data));
-  const Exp dot = new_exp_dot(emit->gwion->mp, exp, *data);
-  dot->d.exp_dot.t_base = t;
-  return dot;
-}
-
-ANN static inline Exp dot_static_exp(const Emitter emit, const Symbol *data, const Type t) {
-  const Symbol s = insert_symbol(t->name);
-  const Exp    e = new_prim_id(emit->gwion->mp, s,
-    loc_cpy(emit->gwion->mp, prim_pos(data)));
-  const Value  val = nspc_lookup_value1(t->nspc->parent, s);
-  const Exp dot = new_exp_dot(emit->gwion->mp, e, *data);
-  dot->d.exp_dot.t_base = val->type;
-  return dot;
-}
-
+ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data);
 ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) {
-  const Value v = prim_self(data)->value;
-  const Exp dot = (!GET_FLAG(v, static) ? dot_this_exp : dot_static_exp)(emit, data, v->from->owner_class);
-  dot->type = prim_exp(data)->type;
-  dot->emit_var = prim_exp(data)->emit_var;
+  const Exp dot = symbol_owned_exp(emit->gwion, data);
+  dot->nspc = prim_exp(data)->nspc;
   const m_bool ret = emit_exp_dot(emit, &dot->d.exp_dot);
   free_exp(emit->gwion->mp, dot);
   return ret;
@@ -417,111 +391,20 @@ ANN static m_bool emit_prim_range(const Emitter emit, Range **data) {
   return GW_OK;
 }
 
-ANN static void array_loop(const Emitter emit, const m_uint depth) {
-  regpop(emit, depth * SZ_INT);
-  emit_add_instr(emit, GWOP_EXCEPT);
-  for(m_uint i = 0; i < depth - 1; ++i) {
-    const Instr access = emit_add_instr(emit, ArrayAccess);
-    access->m_val = i;
-    const Instr get = emit_add_instr(emit, ArrayGet);
-    get->m_val = i;
-    get->m_val2 = -SZ_INT;
-    emit_add_instr(emit, GWOP_EXCEPT);
-  }
-  regpop(emit, SZ_INT);
-  const Instr access = emit_add_instr(emit, ArrayAccess);
-  access->m_val = depth;
-}
-
-ANN static void array_finish(const Emitter emit, const m_uint depth,
-               const m_uint size, const m_bool is_var) {
-  const Instr get = emit_add_instr(emit, is_var ? ArrayAddr : ArrayGet);
-  get->m_val = depth;
-  const Instr push = emit_add_instr(emit, ArrayValid);
-  push->m_val = is_var ? SZ_INT : size;
-}
-
-ANN static inline m_bool array_do(const  Emitter emit, const Array_Sub array, const m_bool is_var) {
-  emit_add_instr(emit, GcAdd);
-  CHECK_BB(emit_exp(emit, array->exp, 0))
-  array_loop(emit, array->depth);
-  array_finish(emit, array->depth, array->type->size, is_var);
-  return GW_OK;
-}
-
-ANN static inline void tuple_access(const  Emitter emit, const m_uint idx,
-        const m_bool is_var) {
-  const Instr instr = emit_add_instr(emit, TupleMember);
-  instr->m_val = idx;
-  instr->m_val2 = is_var;
-  emit_add_instr(emit, DotMember); // just a place holder.
-}
-
-struct ArrayAccessInfo {
-  struct Array_Sub_ array;
-  const Type type;
-  const m_bool is_var;
-};
-
-ANN static inline m_bool _emit_indexes(const Emitter emit, struct ArrayAccessInfo *const info);
-
-ANN void emit_except(const Emitter emit, const Type t) {
-  if(!GET_FLAG(t, nonnull))
-    emit_add_instr(emit, GWOP_EXCEPT);
-  else
-    emit_add_instr(emit, SetObj);
-}
-
-ANN static inline m_bool tuple_index(const Emitter emit, struct ArrayAccessInfo *const info) {
-  assert(isa(info->array.type, emit->gwion->type[et_tuple]) > 0);
-  const m_uint idx = info->array.exp->d.prim.d.num;
-  emit_except(emit, info->array.type);
-  tuple_access(emit, info->array.exp->d.prim.d.num, (info->array.depth -1)? 0 : info->is_var);
-  if(!info->array.exp->next)
-    return GW_OK;
-  const Type type = (Type)vector_at(&info->array.type->e->tuple->types, idx);
-  struct Array_Sub_ next = { info->array.exp->next, type, info->array.depth - 1 };
-  info->array = next;
-  return _emit_indexes(emit, info);
-}
-
-ANN static inline Exp emit_n_exp(const Emitter emit,  struct ArrayAccessInfo *const info) {
-  const Exp e = take_exp(info->array.exp, info->array.depth);
-  const Exp next = e->next;
-  e->next = NULL;
-  struct Array_Sub_ partial = { info->array.exp, info->array.type, info->array.depth };
-  const m_bool ret = array_do(emit, &partial, 0);
-  e->next = next;
-  return ret > 0 ? next : NULL;
-}
-
-ANN static inline m_bool emit_partial_indexes(const Emitter emit, struct ArrayAccessInfo *const info) {
-  struct Array_Sub_ partial = { info->array.exp, info->array.type, info->array.type->array_depth };
-  struct Array_Sub_ next = { info->array.exp, array_base(info->array.type), info->array.depth - info->array.type->array_depth };
-  info->array = partial;
-  DECL_OB(const Exp, exp, = emit_n_exp(emit, info))
-  next.exp = exp;
-  info->array = next;
-  return _emit_indexes(emit, info);
-}
-
-ANN static inline m_bool _emit_indexes(const Emitter emit, struct ArrayAccessInfo *const info) {
+ANN m_bool emit_array_access(const Emitter emit, struct ArrayAccessInfo *const info) {
   if(GET_FLAG(info->array.type, typedef)) {
     info->array.type = info->array.type->e->parent;
-    return _emit_indexes(emit, info);
+    return emit_array_access(emit, info);
   }
-  if(info->array.type->array_depth >= info->array.depth) {
-    struct Array_Sub_ next = { info->array.exp, info->type, info->array.depth };
-    return array_do(emit, &next, info->is_var);
-  }
-  return (info->array.type->array_depth ? emit_partial_indexes : tuple_index)(emit, info);
+  struct Op_Import opi = { .op=insert_symbol("@array"), .lhs=info->array.exp->type, .rhs=info->array.type, .data=(uintptr_t)info };
+  return op_emit(emit, &opi) != (Instr)GW_ERROR ? GW_OK : GW_ERROR;
 }
 
 ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) {
   CHECK_BB(emit_exp(emit, array->base, 0))
   const Exp e = exp_self(array);
   struct ArrayAccessInfo info = { *array->array, e->type, e->emit_var };
-  return _emit_indexes(emit, &info);
+  return emit_array_access(emit, &info);
 }
 
 ANN static m_bool emit_exp_slice(const Emitter emit, const Exp_Slice* range) {
@@ -583,8 +466,6 @@ ANN static m_bool emit_prim_str(const Emitter emit, const m_str *str) {
   return GW_OK;
 }
 
-#define emit_prim_complex emit_prim_vec
-#define emit_prim_polar   emit_prim_vec
 #define emit_prim_nil     (void*)dummy_func
 
 ANN static m_bool emit_interp(const Emitter emit, const Exp exp) {
@@ -1667,125 +1548,11 @@ ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List l) {
   return GW_OK;
 }
 
-ANN static m_bool emit_dot_static_import_data(const Emitter emit, const Value v, const uint emit_addr) {
-  if(v->d.ptr && GET_FLAG(v, builtin) && GET_FLAG(v, const)) {
-    const m_uint size = v->type->size;
-    const Instr instr = emit_kind(emit, size, emit_addr, regpushimm);
-    instr->m_val = (m_uint)v->d.ptr;
-    instr->m_val2 = size;
-    return GW_OK;
-  }
-  return emit_dot_static_data(emit, v, emit_addr);
-}
-
-ANN static m_bool emit_complex_member(const Emitter emit, const Exp_Dot* member) {
-  const Exp base = member->base;
-  base->emit_var = 1;
-  CHECK_BB(emit_exp(emit, base, 0))
-  const m_bool is_complex = !strcmp((isa(base->type, emit->gwion->type[et_complex]) > 0  ? "re" : "phase") ,
-        s_name(member->xid));
-  if(is_complex && exp_self(member)->emit_var)
-    return GW_OK;
-  const Instr instr = emit_add_instr(emit, is_complex ? ComplexReal : ComplexImag);
-  instr->m_val = exp_self(member)->emit_var;
-  return GW_OK;
-}
-
-ANN static m_bool emit_VecMember(const Emitter emit, const Exp_Dot* member) {
-  member->base->emit_var = 1;
-  CHECK_BB(emit_exp(emit, member->base, 0))
-  const Value v = find_value(member->base->type, member->xid);
-  if(GET_FLAG(v, func)) {
-    regpushi(emit, (m_uint)v->d.func_ref->code);
-    return GW_OK;
-  }
-  if(!v->from->offset && exp_self(member)->emit_var)
-    return GW_OK;
-  const Instr instr = emit_add_instr(emit, VecMember);
-  instr->m_val2 = v->from->offset;
-  instr->m_val = exp_self(member)->emit_var;
-  return GW_OK;
-}
-
-ANN static m_bool emit_vararg_start(const Emitter emit, const m_uint offset) {
-  const Instr instr = emit_add_instr(emit, VarargTop);
-  instr->m_val = offset;
-  instr->m_val2 = emit_code_size(emit);
-  vector_set(&emit->info->variadic, vector_size(&emit->info->variadic) -1, (vtype)instr);
-  return GW_OK;
-}
-
 ANN static inline Instr get_variadic(const Emitter emit) {
   return (Instr)vector_back(&emit->info->variadic);
 }
 
-ANN static void emit_vararg_end(const Emitter emit, const m_uint offset) {
-  const Instr instr = emit_add_instr(emit, VarargEnd),
-    variadic = get_variadic(emit);
-  instr->m_val = offset;
-  instr->m_val2 = variadic->m_val2;
-  variadic->m_val2 = emit_code_size(emit);
-  SET_FLAG(emit->env->func, empty);// mark vararg func as complete
-}
-
-ANN static m_bool emit_vararg(const Emitter emit, const Exp_Dot* member) {
-  m_uint offset = emit->env->class_def ? SZ_INT : 0;
-  Arg_List l = emit->env->func->def->base->args;
-  const m_str str = s_name(member->xid);
-  while(l) {
-    offset += l->type->size;
-    l = l->next;
-  }
-  if(!strcmp(str, "start")) {
-    if(get_variadic(emit))
-      ERR_B(exp_self(member)->pos, _("vararg.start already used"))
-    emit_vararg_start(emit, offset);
-    return GW_OK;
-  }
-  if(!strcmp(str, "end")) {
-    if(!get_variadic(emit))
-      ERR_B(exp_self(member)->pos, _("vararg.start not used before vararg.end"))
-    emit_vararg_end(emit, offset);
-    return GW_OK;
-  }
-// should not be reached now
-  return GW_ERROR;
-}
-
-ANN static m_bool emit_exp_dot_special(const Emitter emit, const Exp_Dot* member) {
-  const Type t = member->t_base;
-  if(isa(t, emit->gwion->type[et_complex]) > 0 || isa(t, emit->gwion->type[et_polar]) > 0)
-    return emit_complex_member(emit, member);
-  else if(isa(t, emit->gwion->type[et_vec3]) > 0 || isa(t, emit->gwion->type[et_vec4]) > 0)
-    return emit_VecMember(emit, member);
-  return emit_vararg(emit, member);
-}
-
-ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member) {
-  const Func f = exp_self(member)->type->e->d.func;
-  if(is_class(emit->gwion, member->t_base) || GET_FLAG(member->base->type, force)) {
-    const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : PushStaticCode);
-    func_i->m_val = (m_uint)f->code;
-    return GW_OK;
-  }
-  if(f->def->base->tmpl)
-    emit_add_instr(emit, DotTmplVal);
-  else {
-    const Instr instr = emit_add_instr(emit, GET_FLAG(f, member) ? DotFunc : DotStaticFunc);
-    instr->m_val = f->vt_index;
-  }
-  return GW_OK;
-}
-
-ANN static inline m_bool emit_member(const Emitter emit, const Value v, const uint emit_addr) {
-  const m_uint size = v->type->size;
-  const Instr instr = emit_kind(emit, size, emit_addr, dotmember);
-  instr->m_val = v->from->offset;
-  instr->m_val2 = size;
-  return GW_OK;
-}
-
-ANN static m_bool ensure_emit(const Emitter emit, const Type type) {
+ANN static inline m_bool ensure_emit(const Emitter emit, const Type type) {
   const Type t = actual_type(emit->gwion, type) ?: type;
   if(!GET_FLAG(t, emit) && t->e->def)
     CHECK_BB(emit_class_def(emit, t->e->def))
@@ -1794,18 +1561,9 @@ ANN static m_bool ensure_emit(const Emitter emit, const Type type) {
 
 ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) {
   CHECK_BB(ensure_emit(emit, member->t_base))
-  if(is_special(emit, member->t_base) > 0)
-    return emit_exp_dot_special(emit, member);
-  const Value value = find_value(actual_type(emit->gwion, member->t_base), member->xid);
-  if(!is_class(emit->gwion, member->t_base) && (GET_FLAG(value, member) ||
-       (isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 &&
-       !is_fptr(emit->gwion, exp_self(member)->type)))) {
-    CHECK_BB(emit_exp(emit, member->base, 0))
-    emit_except(emit, member->t_base);
-  }
-  if(isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->type))
-    return emit_member_func(emit, member);
-  return (GET_FLAG(value, member) ? emit_member : emit_dot_static_import_data) (emit, value, exp_self(member)->emit_var);
+  struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->t_base,
+  .rhs=exp_self(member)->type, .data=(uintptr_t)member, .pos=exp_self(member)->pos };
+  return op_emit_bool(emit, &opi);
 }
 
 ANN static inline void emit_func_def_global(const Emitter emit, const Value value) {
index 5f9a9157c055ea1effbf8882372c3e969c339933..b27651e70f279e7e4262e1efeac647efa2abb336 100644 (file)
@@ -229,22 +229,83 @@ static FREEARG(freearg_array) {
   mp_free(((Gwion)gwion)->mp, ArrayInfo, info);
 }
 
-ANN Type at_depth(const Env env, const Array_Sub array);
-ANN static Type partial_depth(const Env env, const Array_Sub array) {
-  const Exp curr = take_exp(array->exp, array->type->array_depth);
-  struct Array_Sub_ next = { curr->next, array_base(array->type), array->depth - array->type->array_depth };
-  return at_depth(env, &next);
-}
-
 static OP_CHECK(opck_not_array) {
   const Array_Sub array = (Array_Sub)data;
     ERR_O(array->exp->pos, _("array subscripts (%"UINT_F") exceeds defined dimension (%"UINT_F")"),
         array->depth, get_depth(array->type))
 }
 
+ANN Type check_array_access(const Env env, const Array_Sub array);
+
 static OP_CHECK(opck_array) {
   const Array_Sub array = (Array_Sub)data;
-  return partial_depth(env, array);
+  const Type t_int = env->gwion->type[et_int];
+  Exp e = array->exp;
+  do CHECK_BO(check_implicit(env, e, t_int))
+  while((e = e->next));
+  const Type t = array->type;
+  if(t->array_depth >= array->depth)
+    return array_type(env, array_base(t), t->array_depth - array->depth);
+  const Exp curr = take_exp(array->exp, array->type->array_depth);
+  struct Array_Sub_ next = { curr->next, array_base(array->type), array->depth - array->type->array_depth };
+  return check_array_access(env, &next);
+}
+
+ANN static void array_loop(const Emitter emit, const m_uint depth) {
+  const Instr pre_pop = emit_add_instr(emit, RegPop);
+  pre_pop->m_val = depth * SZ_INT;
+  emit_add_instr(emit, GWOP_EXCEPT);
+  for(m_uint i = 0; i < depth - 1; ++i) {
+    const Instr access = emit_add_instr(emit, ArrayAccess);
+    access->m_val = i;
+    const Instr get = emit_add_instr(emit, ArrayGet);
+    get->m_val = i;
+    get->m_val2 = -SZ_INT;
+    emit_add_instr(emit, GWOP_EXCEPT);
+  }
+  const Instr post_pop = emit_add_instr(emit, RegPop);
+  post_pop->m_val = SZ_INT;
+  const Instr access = emit_add_instr(emit, ArrayAccess);
+  access->m_val = depth;
+}
+
+ANN static void array_finish(const Emitter emit, const m_uint depth,
+               const m_uint size, const m_bool is_var) {
+  const Instr get = emit_add_instr(emit, is_var ? ArrayAddr : ArrayGet);
+  get->m_val = depth;
+  const Instr push = emit_add_instr(emit, ArrayValid);
+  push->m_val = is_var ? SZ_INT : size;
+}
+
+ANN static inline m_bool array_do(const  Emitter emit, const Array_Sub array, const m_bool is_var) {
+  emit_add_instr(emit, GcAdd);
+  CHECK_BB(emit_exp(emit, array->exp, 0))
+  array_loop(emit, array->depth);
+  array_finish(emit, array->depth, array->type->size, is_var);
+  return GW_OK;
+}
+ANN static inline Exp emit_n_exp(const Emitter emit,  struct ArrayAccessInfo *const info) {
+  const Exp e = take_exp(info->array.exp, info->array.depth);
+  const Exp next = e->next;
+  e->next = NULL;
+  struct Array_Sub_ partial = { info->array.exp, info->array.type, info->array.depth };
+  const m_bool ret = array_do(emit, &partial, 0);
+  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) {
+    struct Array_Sub_ next = { .exp=info->array.exp, .type=info->type, .depth=info->array.depth };
+    return (Instr)(m_uint)array_do(emit, &next, info->is_var);
+  }
+  struct Array_Sub_ partial = { info->array.exp, info->array.type, info->array.type->array_depth };
+  struct Array_Sub_ next = { info->array.exp, array_base(info->array.type), info->array.depth - info->array.type->array_depth };
+  info->array = partial;
+  const Exp exp = emit_n_exp(emit, info);
+  next.exp = exp;
+  info->array = next;
+  return (Instr)(m_uint)(exp ? emit_array_access(emit, info) : GW_ERROR);
 }
 
 GWION_IMPORT(array) {
@@ -287,6 +348,7 @@ GWION_IMPORT(array) {
   GWI_BB(gwi_oper_end(gwi, "@array", NULL))
   GWI_BB(gwi_oper_ini(gwi, "int", "@Array", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_array))
+  GWI_BB(gwi_oper_emi(gwi, opem_array_access))
   GWI_BB(gwi_oper_end(gwi, "@array", NULL))
   gwi_register_freearg(gwi, ArrayAlloc, freearg_array);
   return GW_OK;
index b1f57ef0ff1dbec6899e1606a5f8d883b2698d4c..4a3c176c680cdd9e60ac9f6520fc8ea789aa5456 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "gwi.h"
 #include "gack.h"
+#include "emit.h"
 
 #define describe(name, op) \
 static INSTR(Complex##name) {\
@@ -123,20 +124,33 @@ static GACK(gack_polar) {
 }
 
 EQUALITY_OPER(complex, SZ_COMPLEX)
-OP_CHECK(vecx_ck);
+OP_CHECK(opck_vecx_ctor);
+
+#define opem(type, first_name) static OP_EMIT(opem_##type##_dot) {               \
+  const Exp_Dot *dot = (Exp_Dot*)data;                                           \
+  const Exp base = dot->base;                                                    \
+  base->emit_var = 1;                                                            \
+  if(emit_exp(emit, base, 0) < 0) return (Instr)GW_OK;                           \
+  const m_bool is_first = !strcmp(#first_name, s_name(dot->xid));                \
+  if(is_first && exp_self(dot)->emit_var)                                        \
+    return (Instr)GW_OK;                                                         \
+  const Instr instr = emit_add_instr(emit, is_first ? ComplexReal : ComplexImag);\
+  instr->m_val = exp_self(dot)->emit_var;                                        \
+  return (Instr)GW_OK;                                                           \
+}
+opem(complex, re)
+opem(polar, mod)
+
+OP_CHECK(opck_object_dot);
 GWION_IMPORT(complex) {
-// should be special
   const Type t_complex = gwi_class_spe(gwi, "complex", SZ_COMPLEX);
   GWI_BB(gwi_gack(gwi, t_complex, gack_complex))
-  gwi->gwion->type[et_complex] = t_complex; // use func
        gwi_item_ini(gwi, "float", "re");
   GWI_BB(gwi_item_end(gwi,   ae_flag_member, NULL))
        gwi_item_ini(gwi, "float", "im");
   GWI_BB(gwi_item_end(gwi,   ae_flag_member, NULL))
   GWI_BB(gwi_class_end(gwi))
-// should be special
   const Type t_polar   = gwi_class_spe(gwi, "polar", SZ_COMPLEX);
-  gwi->gwion->type[et_polar] = t_polar;
   GWI_BB(gwi_gack(gwi, t_polar, gack_polar))
   GWI_BB(gwi_item_ini(gwi, "float", "mod"))
   GWI_BB(gwi_item_end(gwi,   ae_flag_member, NULL))
@@ -145,10 +159,10 @@ GWION_IMPORT(complex) {
   GWI_BB(gwi_class_end(gwi))
 
   GWI_BB(gwi_oper_ini(gwi, "complex", NULL, NULL))
-  GWI_BB(gwi_oper_add(gwi, vecx_ck))
+  GWI_BB(gwi_oper_add(gwi, opck_vecx_ctor))
   GWI_BB(gwi_oper_end(gwi, "@ctor",   NULL))
   GWI_BB(gwi_oper_ini(gwi, "polar", NULL, NULL))
-  GWI_BB(gwi_oper_add(gwi, vecx_ck))
+  GWI_BB(gwi_oper_add(gwi, opck_vecx_ctor))
   GWI_BB(gwi_oper_end(gwi, "@ctor",   NULL))
   GWI_BB(gwi_oper_ini(gwi, "complex", "complex", "bool"))
   GWI_BB(gwi_oper_end(gwi, "==",          complex_eq))
@@ -186,5 +200,13 @@ GWION_IMPORT(complex) {
   GWI_BB(gwi_oper_end(gwi, "*=>",   PolarRMul))
   GWI_BB(gwi_oper_add(gwi, opck_rassign))
   GWI_BB(gwi_oper_end(gwi, "/=>",  PolarRDiv))
+  GWI_BB(gwi_oper_ini(gwi, "complex", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_object_dot))
+  GWI_BB(gwi_oper_emi(gwi, opem_complex_dot))
+  GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
+  GWI_BB(gwi_oper_ini(gwi, "polar", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_object_dot))
+  GWI_BB(gwi_oper_emi(gwi, opem_polar_dot))
+  GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
   return GW_OK;
 }
index 5cef63a1250267e6694b972d9b1e4341d461ba43..30ecede52148b9c3aad147318afba24a2e263911 100644 (file)
@@ -62,10 +62,16 @@ mk_class_instr(gt, l, r, && l != r)
 mk_class_instr(le, r, l)
 mk_class_instr(lt, r, l, && l != r)
 
+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_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))
+  GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
+  GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
   GWI_BB(gwi_gack(gwi, gwi->gwion->type[et_class], gack_class)) // not working yet
   gwi->gwion->type[et_class] = t_class;
   const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
index b94a6536fa79bd630b1c7046e10964ab03b2618a..ffd8539b211704c0553c09ba06ddbb4dc5818f2e 100644 (file)
@@ -68,7 +68,7 @@ ANN void __release(const M_Object o, const VM_Shred shred) {
     if(GET_FLAG(t, nonnull))
       t = t->e->parent;
     if(!t->nspc)
-      continue; // return ?
+      continue;
     struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
     Value v;
     while(scope_iter(&iter, &v) > 0) {
@@ -121,8 +121,6 @@ static inline Type check_nonnull(const Env env, const Type l, const Type r,
       ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
     return r->e->parent;
   }
-/*  if(nonnull_check(l, r))
-    ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name); */
   if(l != env->gwion->type[et_null] && isa(l, r) < 0)
     ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
   return r;
@@ -235,6 +233,71 @@ static OP_CHECK(opck_object_scan) {
   ERR_O(td_pos(ts->td), _("you must provide template types for type '%s'"), ts->t->name)
 }
 
+static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
+ANN Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]);
+ANN static void emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) {
+  const m_uint size = v->type->size;
+  const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
+  instr->m_val = (m_uint)(v->from->owner->info->class_data + v->from->offset);
+  instr->m_val2 = size;
+}
+
+static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
+ANN static void emit_dot_static_import_data(const Emitter emit, const Value v, const uint emit_addr) {
+  if(v->d.ptr && GET_FLAG(v, builtin) && GET_FLAG(v, const)) {
+    const m_uint size = v->type->size;
+    const Instr instr = emit_kind(emit, size, emit_addr, regpushimm);
+    instr->m_val = (m_uint)v->d.ptr;
+    instr->m_val2 = size;
+  } else
+    emit_dot_static_data(emit, v, emit_addr);
+}
+static const f_instr dotmember[]  = { DotMember, DotMember2, DotMember3, DotMember4 };
+
+ANN static void emit_member_func(const Emitter emit, const Exp_Dot* member) {
+  const Func f = exp_self(member)->type->e->d.func;
+  if(is_class(emit->gwion, member->t_base) || GET_FLAG(member->base->type, force)) {
+    const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : PushStaticCode);
+    func_i->m_val = (m_uint)f->code;
+    return;
+  }
+  if(f->def->base->tmpl)
+    emit_add_instr(emit, DotTmplVal);
+  else {
+    const Instr instr = emit_add_instr(emit, GET_FLAG(f, member) ? DotFunc : DotStaticFunc);
+    instr->m_val = f->vt_index;
+  }
+  return;
+}
+
+ANN static inline void emit_member(const Emitter emit, const Value v, const uint emit_addr) {
+  const m_uint size = v->type->size;
+  const Instr instr = emit_kind(emit, size, emit_addr, dotmember);
+  instr->m_val = v->from->offset;
+  instr->m_val2 = size;
+}
+
+OP_CHECK(opck_object_dot) {
+  const Exp_Dot *member = (Exp_Dot*)data;
+  const Value value = find_value(actual_type(env->gwion, member->t_base), member->xid);
+  return value->type;
+}
+
+OP_EMIT(opem_object_dot) {
+  const Exp_Dot *member = (Exp_Dot*)data;
+  const Value value = find_value(actual_type(emit->gwion, member->t_base), member->xid);
+  if(!is_class(emit->gwion, member->t_base) && (GET_FLAG(value, member) ||
+       (isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 &&
+       !is_fptr(emit->gwion, exp_self(member)->type)))) {
+    CHECK_BO(emit_exp(emit, member->base, 0))
+    emit_except(emit, member->t_base);
+  }
+  if(isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->type))
+         emit_member_func(emit, member);
+  else (GET_FLAG(value, member) ? emit_member : emit_dot_static_import_data)(emit, value, exp_self(member)->emit_var);
+  return (Instr)GW_OK;
+}
+
 GWION_IMPORT(object) {
   const Type t_object  = gwi_mk_type(gwi, "Object", SZ_INT, NULL);
   gwi_add_type(gwi, t_object);
@@ -246,9 +309,6 @@ GWION_IMPORT(object) {
   gwi->gwion->type[et_null] = t_null;
   GWI_BB(gwi_set_global_type(gwi, t_null, et_null))
   GWI_BB(gwi_oper_cond(gwi, "Object", BranchEqInt, BranchNeqInt))
-  GWI_BB(gwi_oper_ini(gwi, "@null", "Object", "Object"))
-  GWI_BB(gwi_oper_add(gwi, at_object))
-  GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
   GWI_BB(gwi_oper_ini(gwi, "Object", "Object", NULL))
   GWI_BB(gwi_oper_add(gwi, at_object))
   GWI_BB(gwi_oper_emi(gwi, opem_at_object))
@@ -263,19 +323,8 @@ GWION_IMPORT(object) {
   GWI_BB(gwi_oper_emi(gwi, opem_implicit_null2obj))
   GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
   GWI_BB(gwi_oper_ini(gwi, "@null", "Object", "int"))
-  GWI_BB(gwi_oper_end(gwi, "==",  EqObject))
-  GWI_BB(gwi_oper_end(gwi, "!=", NeqObject))
-  GWI_BB(gwi_oper_add(gwi, opck_object_cast))
-  GWI_BB(gwi_oper_emi(gwi, opem_object_cast))
-  GWI_BB(gwi_oper_end(gwi, "$", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_implicit_null2obj))
   GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "Object", "@null", "int"))
-//  GWI_BB(gwi_oper_add(gwi, opck_object_cast))
-//  GWI_BB(gwi_oper_emi(gwi, opem_object_cast))
-//  GWI_BB(gwi_oper_end(gwi, "$", NULL))
-  GWI_BB(gwi_oper_end(gwi, "==", EqObject))
-  GWI_BB(gwi_oper_end(gwi, "!=", NeqObject))
   GWI_BB(gwi_oper_ini(gwi, NULL, "Object", "bool"))
   GWI_BB(gwi_oper_add(gwi, opck_unary_meta2))
   GWI_BB(gwi_oper_end(gwi, "!", IntNot))
@@ -403,3 +452,26 @@ ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td) {
   CHECK_BO(scan1_cdef(env, a))
   return a->base.type;
 }
+
+ANN static inline Symbol dot_symbol(SymTable *st, const Value v) {
+  const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name;
+  return insert_symbol(st, name);
+}
+
+ANN static inline Type dot_type(SymTable *st, const Value v) {
+  const Type t = v->from->owner_class;
+  if(!GET_FLAG(v, static))
+    return t;
+  const Value  val = nspc_lookup_value1(t->nspc->parent, insert_symbol(st, t->name));
+  return val->type;
+}
+
+ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data) {
+  const Value v = prim_self(data)->value;
+  const Exp base = new_prim_id(gwion->mp, dot_symbol(gwion->st, v), loc_cpy(gwion->mp, prim_pos(data)));
+  const Exp dot = new_exp_dot(gwion->mp, base, *data);
+  dot->d.exp_dot.t_base = dot->d.exp_dot.base->type = dot_type(gwion->st, v);
+  dot->type = prim_exp(data)->type;
+  dot->emit_var = prim_exp(data)->emit_var;
+  return dot;
+}
index d5e72a101f7f7cf184e281a653923ae3eddc66ef..8a443967f45bd6e3d672d2c902df040ca3b4f586 100644 (file)
@@ -99,7 +99,7 @@ OP_CHECK(opck_new) {
     ERR_N(td_pos(unary->td), _("can't use 'new' on abstract type '%s'\n"), t->name)
   UNSET_FLAG(unary->td, ref);
   if(unary->td->array)
-    CHECK_BN(check_subscripts(env, unary->td->array))
+    CHECK_BN(check_subscripts(env, unary->td->array, 1))
   return t;
 }
 
index 2846045d49578ba92cca4f4eb6836c6155b3595b..dcc518c4b6480c805daf06c8ae60f28e9a9a788d 100644 (file)
@@ -24,9 +24,7 @@ GWION_IMPORT(int_op) {
   GWI_BB(gwi_oper_end(gwi, "-", int_minus))
   GWI_BB(gwi_oper_end(gwi, "*", int_mul))
   GWI_BB(gwi_oper_end(gwi, "/", int_div))
-  GWI_BB(gwi_oper_end(gwi, "%", int_modulo))
-  GWI_BB(gwi_oper_end(gwi, "@access", NULL))
-  return gwi_oper_end(gwi, "@repeat", NULL);
+  return gwi_oper_end(gwi, "%", int_modulo);
 }
 
 static GWION_IMPORT(int_logical) {
@@ -170,11 +168,6 @@ static OP_CHECK(opck_implicit_f2i) {
   return env->gwion->type[et_null];
 }
 
-static OP_CHECK(opck_repeat_f2i) {
-  struct Implicit* imp = (struct Implicit*)data;
-  return imp->e->cast_to = env->gwion->type[et_int];
-}
-
 static OP_CHECK(opck_implicit_i2f) {
   struct Implicit* imp = (struct Implicit*)data;
   return imp->e->cast_to = env->gwion->type[et_float];
@@ -231,7 +224,6 @@ static GWION_IMPORT(floatint) {
   CHECK_FI("/=>", rassign, r_div)
   _CHECK_OP("$", basic_cast, CastF2I)
   _CHECK_OP("@implicit", implicit_f2i, CastF2I)
-  _CHECK_OP("@repeat", repeat_f2i, CastF2I)
   return GW_OK;
 }
 
index 07a20e71244b39a66e68311b0ef4c6f5798f5892..a247efbe1fb47fa8c9e570e7fd3bfdb19c439fd7 100644 (file)
 #include "specialid.h"
 #include "gwi.h"
 
-static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_retval;
+static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize;
 
 #define FORK_THREAD(o) *(THREAD_TYPE*)(o->data + o_fork_thread)
 #define FORK_RETSIZE(o) *(m_int*)(o->data + o_fork_retsize)
-#define FORK_RETVAL(o) (o->data + o_fork_retval)
 
 VM_Shred new_shred_base(const VM_Shred shred, const VM_Code code) {
   const VM_Shred sh = new_vm_shred(shred->info->mp, code);
@@ -207,11 +206,6 @@ static MFUN(shred_test_cancel) {
   MUTEX_UNLOCK(ME(o)->tick->shreduler->mutex);
 }
 
-void fork_retval(const M_Object o) {
-  const m_uint sz = FORK_RETSIZE(o);
-  memcpy(FORK_RETVAL(o), ME(o)->reg - sz, sz);
-}
-
 static ANN void* fork_run(void* data) {
   VM *vm = (VM*)data;
   const M_Object me = vm->shreduler->list->self->info->me;
@@ -221,7 +215,6 @@ static ANN void* fork_run(void* data) {
   }
   vm_lock(vm->parent);
   if(vm_running(vm->parent)) {
-    fork_retval(me);
     *(m_int*)(me->data + o_fork_done) = 1;
     broadcast(*(M_Object*)(me->data + o_fork_ev));
   } else if(me->ref > 1)
@@ -335,14 +328,6 @@ GWION_IMPORT(shred) {
   GWI_BB((o_fork_ev = gwi_item_end(gwi, ae_flag_const, NULL)))
   gwi_item_ini(gwi, "int", "retsize");
   GWI_BB((o_fork_retsize = gwi_item_end(gwi, ae_flag_const, NULL)))
-  o_fork_retval = t_fork->nspc->info->offset;
-  GWI_BB(gwi_union_ini(gwi, NULL, NULL))
-  GWI_BB(gwi_union_add(gwi, "int", "i"))
-  GWI_BB(gwi_union_add(gwi, "float", "f"))
-  GWI_BB(gwi_union_add(gwi, "Vec3", "v"))
-  GWI_BB(gwi_union_add(gwi, "Vec4", "w"))
-  GWI_BB(gwi_union_add(gwi, "VarObject", "o"))
-  GWI_OB(gwi_union_end(gwi, ae_flag_const))
   gwi_func_ini(gwi, "void", "join");
   GWI_BB(gwi_func_end(gwi, fork_join, ae_flag_none))
   GWI_BB(gwi_class_end(gwi))
index 8dd269aee1d2b40c15be1691383e417dff489083..f905a40644c34cbb71286b308cc8da218f3ee8ed 100644 (file)
@@ -16,6 +16,7 @@
 #include "tuple.h"
 #include "array.h"
 
+#define TUPLE_NAME "Tuple"
 struct TupleEmit {
   Exp e;
   Vector v;
@@ -102,7 +103,7 @@ ANN void emit_unpack_instr(const Emitter emit, struct TupleEmit *te) {
   unpack_instr_decl(emit, te);
   if(te->sz)
     emit_unpack_instr_inner(emit, te);
-  if(te->e && (te->e = te->e->next)) // antepenultimate ?
+  if(te->e && (te->e = te->e->next))
     emit_unpack_instr(emit, te);
 }
 
@@ -157,26 +158,21 @@ static INSTR(Tuple2Object) {
     Except(shred, _("can't cast\n"));
 }
 
-  // TODO: do not emit Tuple2Object if full match
-#define mk_opem_tuple2object(name, type, rhs)             \
-static OP_EMIT(opem_##name##_tuple_object) {              \
-  const type exp = (type)data;                            \
-  const Instr instr = emit_add_instr(emit, Tuple2Object); \
-  instr->m_val = (m_uint)rhs;                             \
-  instr->m_val2 = SZ_INT;                                 \
-  return instr;                                           \
+// TODO: do not emit Tuple2Object if full match
+static OP_EMIT(opem_cast_tuple_object) {
+  const Exp_Cast* exp = (Exp_Cast*)data;
+  const Instr instr = emit_add_instr(emit, Tuple2Object);
+  instr->m_val = (m_uint)exp_self(exp)->type;
+  instr->m_val2 = SZ_INT;
+  return instr;
 }
-static OP_EMIT(opem_at_tuple_object) {                     \
-  const Exp_Binary *bin = (Exp_Binary*)data;               \
-  const Instr instr = emit_add_instr(emit, Tuple2Object);  \
-  instr->m_val = (m_uint)bin->rhs->type;                   \
-  instr->m_val2 = SZ_INT*2;                                \
-
-  const Instr assign = emit_add_instr(emit, ObjectAssign); \
-
-return assign;
+static OP_EMIT(opem_at_tuple_object) {
+  const Exp_Binary *bin = (Exp_Binary*)data;
+  const Instr instr = emit_add_instr(emit, Tuple2Object);
+  instr->m_val = (m_uint)bin->rhs->type;
+  instr->m_val2 = SZ_INT*2;
+  return emit_add_instr(emit, ObjectAssign);
 }
-mk_opem_tuple2object(cast, Exp_Cast *, exp_self(exp)->type)
 
 static OP_CHECK(opck_cast_tuple) {
   const Exp_Cast *cast = (Exp_Cast*)data;
@@ -218,7 +214,7 @@ INSTR(TupleCtor) {
 
 ANN static Symbol tuple_sym(const Env env, const Vector v) {
   GwText text = { .mp=env->gwion->mp };
-  text_add(&text, env->gwion->type[et_tuple]->name);
+  text_add(&text, TUPLE_NAME);
   text_add(&text, "<~");
   for(m_uint i = 0; i < vector_size(v); ++i) {
     const Type t = (Type)vector_at(v, i);
@@ -267,7 +263,7 @@ ANN Type tuple_type(const Env env, const Vector v, const loc_t pos) {
   }
   Section * section = new_section_stmt_list(env->gwion->mp, base);
   Ast body = new_ast(env->gwion->mp, section, NULL);
-  const ID_List ilist = new_id_list(env->gwion->mp, insert_symbol(env->gwion->type[et_tuple]->name),
+  const ID_List ilist = new_id_list(env->gwion->mp, insert_symbol(TUPLE_NAME),
       loc_cpy(env->gwion->mp, pos));
   Type_Decl *td = new_type_decl(env->gwion->mp, ilist);
   Class_Def cdef = new_class_def(env->gwion->mp, ae_flag_template,
@@ -298,7 +294,8 @@ ANN void free_tupleform(MemPool p, const TupleForm tuple) {
     free_type_list(p, tuple->list);
 }
 
-ANN /*static*/ Type at_depth(const Env env, const Array_Sub array);
+ANN Type check_array_access(const Env env, const Array_Sub array);
+
 static OP_CHECK(opck_tuple) {
   const Array_Sub array = (Array_Sub)data;
   const Vector v = &array->type->e->tuple->types;
@@ -315,10 +312,10 @@ static OP_CHECK(opck_tuple) {
   if(!exp->next)
     return type;
   struct Array_Sub_ next = { exp->next, type, array->depth - 1 };
-  return at_depth(env, &next);
+  return check_array_access(env, &next);
 }
 
-static OP_CHECK(tuple_ck) {
+static OP_CHECK(opck_tuple_ctor) {
   const Exp_Call *call = (Exp_Call*)data;
   const Exp exp = call->args;
   if(exp)
@@ -333,7 +330,7 @@ static OP_CHECK(tuple_ck) {
   return ret;
 }
 
-static OP_EMIT(tuple_em) {
+static OP_EMIT(opem_tuple_ctor) {
   const Exp_Call *call = (Exp_Call*)data;
   const Instr instr = emit_add_instr(emit, TupleCtor);
   instr->m_val = (m_uint)exp_self(call)->type;
@@ -377,6 +374,15 @@ static OP_EMIT(unpack_em) {
   return NULL;
 }
 
+static void parents(const Env env, const Type t, const Vector v) {
+  const Nspc parent = t->e->owner;
+  if(parent->parent && parent != env->context->nspc && parent != env->global_nspc) {
+    const Type older = nspc_lookup_type1(parent->parent, insert_symbol(parent->name));
+    parents(env, older, v);
+  }
+  vector_add(v, (vtype)insert_symbol(t->name));
+}
+
 static OP_CHECK(opck_at_unpack) {
   const Exp_Binary *bin = (Exp_Binary*)data;
   Exp e = bin->rhs->d.exp_call.args;
@@ -384,7 +390,14 @@ static OP_CHECK(opck_at_unpack) {
   while(e) {
     if(e->exp_type == ae_exp_decl) {
       DECL_OO(const Type, t, = (Type)VPTR(&bin->lhs->type->e->tuple->types, i))
-      e->d.exp_decl.td->xid->xid = insert_symbol(t->name);
+      struct Vector_ v; // hoist?
+      vector_init(&v);
+      parents(env, t, &v);
+      ID_List id = e->d.exp_decl.td->xid;
+      id->xid = (Symbol)vector_front(&v);
+      for(m_uint i = 1; i < vector_size(&v); ++i)
+        id = (id->next = new_id_list(env->gwion->mp, (Symbol)vector_at(&v, i), loc_cpy(env->gwion->mp, e->pos)));
+      vector_release(&v);
       const Exp next = e->next;
       e->d.exp_decl.type = NULL;
       e->next = NULL;
@@ -417,32 +430,70 @@ static OP_EMIT(opem_at_unpack) {
   return (Instr)GW_OK;
 }
 
-ANN static Type scan_tuple(const Env env, const Type_Decl *td);
+static ANN Type scan_tuple(const Env env, const Type_Decl *td) {
+  struct Vector_ v;
+  vector_init(&v);
+  Type_List tl = td->types;
+  do {
+    const Type t = tl->td->xid->xid != insert_symbol("_") ?
+       known_type(env, tl->td) : (Type)1;
+    if(t)
+      vector_add(&v, (m_uint)t);
+    else {
+      vector_release(&v);
+      return env->gwion->type[et_null];
+    }
+  } while((tl = tl->next));
+  const Type ret = tuple_type(env, &v, td_pos(td));
+  vector_release(&v);
+  return ret;
+}
+
 static OP_CHECK(opck_tuple_scan) {
   struct TemplateScan *ts = (struct TemplateScan*)data;
   return ts->td->types ? scan_tuple(env, ts->td) : ts->t;
 }
 
+ANN static void tuple_access(const  Emitter emit, const m_uint idx,
+        const m_bool is_var) {
+  const Instr instr = emit_add_instr(emit, TupleMember);
+  instr->m_val = idx;
+  instr->m_val2 = is_var;
+  emit_add_instr(emit, DotMember); // just a place holder.
+}
+
+static OP_EMIT(opem_tuple_access) {
+  struct ArrayAccessInfo *info = (struct ArrayAccessInfo*)data;
+  const m_uint idx = info->array.exp->d.prim.d.num;
+  emit_except(emit, info->array.type);
+  tuple_access(emit, info->array.exp->d.prim.d.num, (info->array.depth -1)? 0 : info->is_var);
+  if(!info->array.exp->next)
+    return (Instr)GW_OK;
+  const Type type = (Type)vector_at(&info->array.type->e->tuple->types, idx);
+  struct Array_Sub_ next = { info->array.exp->next, type, info->array.depth - 1 };
+  info->array = next;
+  return (Instr)(m_uint)emit_array_access(emit, info);
+}
+
 GWION_IMPORT(tuple) {
-  const Type t_tuple = gwi_mk_type(gwi, "Tuple", SZ_INT, "Object");
+  const Type t_tuple = gwi_mk_type(gwi, TUPLE_NAME, SZ_INT, "Object");
   gwi_add_type(gwi, t_tuple);
   SET_FLAG(t_tuple, checked | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
-  gwi->gwion->type[et_tuple] = t_tuple;
   SET_FLAG(t_tuple, abstract | ae_flag_template);
-  GWI_BB(gwi_oper_ini(gwi, "Tuple", NULL, NULL))
-  GWI_BB(gwi_oper_add(gwi, tuple_ck))
-  GWI_BB(gwi_oper_emi(gwi, tuple_em))
+  GWI_BB(gwi_oper_ini(gwi, TUPLE_NAME, NULL, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_tuple_ctor))
+  GWI_BB(gwi_oper_emi(gwi, opem_tuple_ctor))
   GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_tuple_scan))
   GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "Object", "Tuple", NULL))
+  GWI_BB(gwi_oper_ini(gwi, "Object", TUPLE_NAME, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_at_object_tuple))
   GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
   GWI_BB(gwi_oper_add(gwi, opck_cast_tuple))
   GWI_BB(gwi_oper_end(gwi, "$", NoOp))
   GWI_BB(gwi_oper_add(gwi, opck_impl_tuple))
   GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "Tuple", "Object", NULL))
+  GWI_BB(gwi_oper_ini(gwi, TUPLE_NAME, "Object", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_at_tuple_object))
   GWI_BB(gwi_oper_emi(gwi, opem_at_tuple_object))
   GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
@@ -451,19 +502,18 @@ GWION_IMPORT(tuple) {
   GWI_BB(gwi_oper_end(gwi, "$", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_impl_tuple))
   GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "Tuple", "Tuple", NULL))
+  GWI_BB(gwi_oper_ini(gwi, TUPLE_NAME, "Tuple", NULL))
   GWI_BB(gwi_oper_add(gwi, opck_at_object_tuple))
   GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign))
-  GWI_BB(gwi_oper_ini(gwi, "int", "Tuple", NULL))
+  GWI_BB(gwi_oper_ini(gwi, "int", TUPLE_NAME, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_tuple))
-//  GWI_BB(gwi_oper_emi(gwi, opem_at_tuple))
+  GWI_BB(gwi_oper_emi(gwi, opem_tuple_access))
   GWI_BB(gwi_oper_end(gwi, "@array", NULL))
   gwi_register_freearg(gwi, TupleUnpack, freearg_tuple_at);
 
   const Type t_unpack = gwi_mk_type(gwi, "Unpack", 0, NULL);
   gwi_add_type(gwi, t_unpack);
   SET_FLAG(t_unpack, checked | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
-//  SET_FLAG(t_unpack, abstract | ae_flag_template);
   GWI_BB(gwi_oper_ini(gwi, "Unpack", NULL, NULL))
   GWI_BB(gwi_oper_add(gwi, unpack_ck))
   GWI_BB(gwi_oper_emi(gwi, unpack_em))
@@ -475,31 +525,5 @@ GWION_IMPORT(tuple) {
   GWI_BB(gwi_oper_add(gwi, opck_at_unpack))
   GWI_BB(gwi_oper_emi(gwi, opem_at_unpack))
   GWI_BB(gwi_oper_end(gwi, "==", NULL))
-  GWI_BB(gwi_oper_ini(gwi, "Tuple", "Unpack", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_at_unpack))
-  GWI_BB(gwi_oper_emi(gwi, opem_at_unpack))
-  GWI_BB(gwi_oper_end(gwi, "@=>", NULL))
-  GWI_BB(gwi_oper_add(gwi, opck_at_unpack))
-  GWI_BB(gwi_oper_emi(gwi, opem_at_unpack))
-  GWI_BB(gwi_oper_end(gwi, "==", NULL))
   return GW_OK;
 }
-
-static ANN Type scan_tuple(const Env env, const Type_Decl *td) {
-  struct Vector_ v;
-  vector_init(&v);
-  Type_List tl = td->types;
-  do {
-    const Type t = tl->td->xid->xid != insert_symbol("_") ?
-       known_type(env, tl->td) : (Type)1;
-    if(t)
-      vector_add(&v, (m_uint)t);
-    else {
-      vector_release(&v);
-      return env->gwion->type[et_null];
-    }
-  } while((tl = tl->next));
-  const Type ret = tuple_type(env, &v, td_pos(td));
-  vector_release(&v);
-  return ret;
-}
index 129fa43b8dfd680e82fbad12fd5e6e8c21ac7bd7..e57026c6e82f277d76ce7e8cbc96fd057c675c53 100644 (file)
@@ -61,9 +61,7 @@ INSTR(VarargEnd) {
 
 static OP_CHECK(opck_vararg_cast) {
   const Exp_Cast* cast = (Exp_Cast*)data;
-  const Type t = known_type(env, cast->td);
-//puts(t->name);
-  return t;
+  return known_type(env, cast->td);
 }
 
 static INSTR(VarargCast) {
@@ -73,7 +71,6 @@ static INSTR(VarargCast) {
          free_vararg(shred->info->mp, arg);
          Except(shred, "InvalidVariadicAccess");
   }
-//  POP_REG(shred, SZ_INT);
   for(m_uint i = 0; i < t->size; i += SZ_INT)
     *(m_uint*)REG(i - SZ_INT) = *(m_uint*)(arg->d + arg->o + i);
   PUSH_REG(shred, t->size - SZ_INT);
@@ -96,23 +93,11 @@ static OP_EMIT(opem_vararg_cast) {
   const Exp_Cast* cast = (Exp_Cast*)data;
   CHECK_BO(variadic_check(emit, cast->exp->pos))
   const Instr instr = emit_add_instr(emit, VarargCast);
-  const Instr variadic = (Instr)vector_back(&emit->info->variadic);
-  instr->m_val = variadic->m_val;
-  const Type t = known_type(emit->env, cast->td);
-  instr->m_val2 = (m_uint)t;
+  instr->m_val = get_variadic(emit)->m_val;
+  instr->m_val2 = (m_uint)exp_self(cast)->type;
   return instr;
 }
 
-static OP_CHECK(at_varobj) {
-  const Exp_Binary* bin = (Exp_Binary*)data;
-  return bin->rhs->type;
-}
-
-static INSTR(VarargAssign) {
-  POP_REG(shred, SZ_INT);
-  *(M_Object**)REG(0) = &*(M_Object*)REG(-SZ_INT);
-}
-
 static FREEARG(freearg_vararg) {
   if(instr->m_val2)
     free_vector(((Gwion)gwion)->mp, (Vector)instr->m_val2);
@@ -128,11 +113,52 @@ static GACK(gack_vararg) {
   INTERP_PRINTF("%p\n", *(M_Object*)VALUE);
 }
 
+ANN static inline m_uint emit_code_size(const Emitter emit) {
+  return vector_size(&emit->code->instr);
+}
+ANN static m_bool emit_vararg_start(const Emitter emit, const m_uint offset) {
+  const Instr instr = emit_add_instr(emit, VarargTop);
+  instr->m_val = offset;
+  instr->m_val2 = emit_code_size(emit);
+  vector_set(&emit->info->variadic, vector_size(&emit->info->variadic) -1, (vtype)instr);
+  return GW_OK;
+}
+
+ANN static void emit_vararg_end(const Emitter emit, const m_uint offset) {
+  const Instr instr = emit_add_instr(emit, VarargEnd),
+    variadic = get_variadic(emit);
+  instr->m_val = offset;
+  instr->m_val2 = variadic->m_val2;
+  variadic->m_val2 = emit_code_size(emit);
+  SET_FLAG(emit->env->func, empty);// mark vararg func as complete
+}
+
+static OP_EMIT(opem_vararg_dot) {
+  const Env env = emit->env;
+  const Exp_Dot *member = (Exp_Dot*)data;
+  m_uint offset = emit->env->class_def ? SZ_INT : 0;
+  Arg_List l = emit->env->func->def->base->args;
+  const m_str str = s_name(member->xid);
+  while(l) {
+    offset += l->type->size;
+    l = l->next;
+  }
+  if(!strcmp(str, "start")) {
+    if(get_variadic(emit))
+      ERR_O(exp_self(member)->pos, _("vararg.start already used"))
+    emit_vararg_start(emit, offset);
+    return (Instr)GW_OK;
+  }
+  assert(!strcmp(str, "end"));
+  if(!get_variadic(emit))
+    ERR_O(exp_self(member)->pos, _("vararg.start not used before vararg.end"))
+  emit_vararg_end(emit, offset);
+  return (Instr)GW_OK;
+}
+OP_CHECK(opck_object_dot);
+
 GWION_IMPORT(vararg) {
-  const Type t_varobj  = gwi_mk_type(gwi, "VarObject", SZ_INT, "Object");
-  SET_FLAG(t_varobj, abstract);
   const Type t_varloop = gwi_mk_type(gwi, "@VarLoop",  SZ_INT, NULL);
-  GWI_BB(gwi_add_type(gwi,  t_varobj))
   GWI_BB(gwi_set_global_type(gwi, t_varloop, et_varloop))
   const Type t_vararg  = gwi_class_spe(gwi, "@Vararg", 0);
   gwi_gack(gwi, t_vararg, gack_vararg);
@@ -142,12 +168,10 @@ GWION_IMPORT(vararg) {
   GWI_BB(gwi_union_add(gwi, "@VarLoop",  "end"))
   GWI_OB(gwi_union_end(gwi, ae_flag_const))
   GWI_BB(gwi_class_end(gwi))
-  GWI_BB(gwi_oper_ini(gwi, "VarObject", "Object", NULL))
-  GWI_BB(gwi_oper_add(gwi, at_varobj))
-  GWI_BB(gwi_oper_end(gwi, "@=>", VarargAssign))
-  GWI_BB(gwi_oper_ini(gwi, "Object", "VarObject", NULL))
-  GWI_BB(gwi_oper_add(gwi, at_varobj))
-  GWI_BB(gwi_oper_end(gwi, "@=>", VarargAssign))
+  GWI_BB(gwi_oper_ini(gwi, "@Vararg", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_object_dot))
+  GWI_BB(gwi_oper_emi(gwi, opem_vararg_dot))
+  GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
   GWI_BB(gwi_oper_ini(gwi, "@Vararg", (m_str)OP_ANY_TYPE, NULL))
   GWI_BB(gwi_oper_add(gwi, opck_vararg_cast))
   GWI_BB(gwi_oper_emi(gwi, opem_vararg_cast))
index 2c6b2e90b21d78ed89d50cf179f821d0c9725e30..5273103ae6aaba7f4bf4c8ffe8822fd3c56c782a 100644 (file)
@@ -12,6 +12,7 @@
 #include "driver.h"
 #include "gwi.h"
 #include "gack.h"
+#include "emit.h"
 
 INSTR(VecCpy) {
   POP_REG(shred, instr->m_val2);
@@ -165,7 +166,7 @@ static GACK(gack_vec3) {
 
 EQUALITY_OPER(vec3, SZ_VEC3);
 
-OP_CHECK(vecx_ck) {
+OP_CHECK(opck_vecx_ctor) {
   Exp_Call *call = (Exp_Call*)data;
   Exp e = call->args, last = NULL;
   if(call->args)
@@ -195,10 +196,29 @@ OP_CHECK(vecx_ck) {
   }
   return t;
 }
+OP_CHECK(opck_object_dot);
+
+static OP_EMIT(opem_vec_dot) {
+  Exp_Dot *member = (Exp_Dot*)data;
+  member->base->emit_var = 1;
+  CHECK_BO(emit_exp(emit, member->base, 0))
+  const Value v = find_value(member->base->type, member->xid);
+  if(GET_FLAG(v, func)) {
+         /*regpushi(emit, (m_uint)v->d.func_ref->code);*/
+    const Instr instr = emit_add_instr(emit, RegPushImm);
+    instr->m_val = (m_uint)v->d.func_ref->code;
+    return instr;
+  }
+  if(!v->from->offset && exp_self(member)->emit_var)
+    return (Instr)GW_OK;
+  const Instr instr = emit_add_instr(emit, VecMember);
+  instr->m_val2 = v->from->offset;
+  instr->m_val = exp_self(member)->emit_var;
+  return instr;
+}
 
 GWION_IMPORT(vec3) {
   const Type t_vec3 = gwi_class_spe(gwi, "Vec3", SZ_VEC3);
-  gwi->gwion->type[et_vec3] = t_vec3;
   GWI_BB(gwi_gack(gwi, t_vec3, gack_vec3))
   vecx_base(gwi);
   gwi_func_ini(gwi, "void", "set");
@@ -238,9 +258,14 @@ GWION_IMPORT(vec3) {
   GWI_BB(gwi_class_end(gwi))
 
   GWI_BB(gwi_oper_ini(gwi, "Vec3", NULL, NULL))
-  GWI_BB(gwi_oper_add(gwi, vecx_ck))
+  GWI_BB(gwi_oper_add(gwi, opck_vecx_ctor))
   GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
 
+  GWI_BB(gwi_oper_ini(gwi, "Vec3", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_object_dot))
+  GWI_BB(gwi_oper_emi(gwi, opem_vec_dot))
+  GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
+
   GWI_BB(gwi_oper_ini(gwi, "Vec3", "Vec3", "bool"))
   GWI_BB(gwi_oper_end(gwi, "==",          vec3_eq))
   GWI_BB(gwi_oper_end(gwi, "!=",          vec3_ne))
@@ -355,7 +380,6 @@ EQUALITY_OPER(vec4, SZ_VEC4);
 
 GWION_IMPORT(vec4) {
   const Type t_vec4 = gwi_class_spe(gwi, "Vec4", SZ_VEC4);
-  gwi->gwion->type[et_vec4] = t_vec4;
   GWI_BB(gwi_gack(gwi, t_vec4, gack_vec4))
   vecx_base(gwi);
        gwi_item_ini(gwi, "float", "w");
@@ -376,9 +400,14 @@ GWION_IMPORT(vec4) {
   CHECK_BB(gwi_class_end(gwi))
 
   GWI_BB(gwi_oper_ini(gwi, "Vec4", NULL, NULL))
-  GWI_BB(gwi_oper_add(gwi, vecx_ck))
+  GWI_BB(gwi_oper_add(gwi, opck_vecx_ctor))
   GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
 
+  GWI_BB(gwi_oper_ini(gwi, "Vec4", (m_str)OP_ANY_TYPE, NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_object_dot))
+  GWI_BB(gwi_oper_emi(gwi, opem_vec_dot))
+  GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
+
   GWI_BB(gwi_oper_ini(gwi, "Vec4", "Vec4", "bool"))
   GWI_BB(gwi_oper_end(gwi, "==",          vec4_eq))
   GWI_BB(gwi_oper_end(gwi, "!=",          vec4_ne))
index 567a98b62f9921a51653ace36977b06e6e1f1675..c1ca209705caf251f3f6ba0ac96786722b69338d 100644 (file)
@@ -28,18 +28,20 @@ ANN static m_bool check_internal(const Env env, const Symbol sym,
   return GW_OK;
 }
 
-ANN /*static inline */m_bool check_implicit(const Env env, const Exp e, const Type t) {
+ANN m_bool check_implicit(const Env env, const Exp e, const Type t) {
+  if(e->type == t)
+    return GW_OK;
   const Symbol sym = insert_symbol("@implicit");
   return check_internal(env, sym, e, t);
 }
 
-ANN m_bool check_subscripts(Env env, const Array_Sub array) {
+ANN m_bool check_subscripts(Env env, const Array_Sub array, const m_bool is_decl) {
   CHECK_OB(check_exp(env, array->exp))
   m_uint depth = 0;
   Exp e = array->exp;
-  const Symbol sym = insert_symbol("@access");
-  do CHECK_BB(check_internal(env, sym, e, env->gwion->type[et_int]))
-  while(++(depth) && (e = e->next));
+  do if(is_decl)
+    CHECK_BB(check_implicit(env, e, env->gwion->type[et_int]))
+  while(++depth && (e = e->next));
   if(depth != array->depth)
     ERR_B(array->exp->pos, _("invalid array acces expression."))
   return GW_OK;
@@ -77,7 +79,8 @@ ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
   if(!env->class_def) {
     if(!type || GET_FLAG(func, global))
       return GW_OK;
-    ERR_B(var->pos, _("can't use non public typedef at global scope."))
+return GW_OK;
+//    ERR_B(var->pos, _("can't use non public typedef at global scope."))
   }
   if(type && isa(type, env->class_def) < 0 && !GET_FLAG(func, global))
     ERR_B(var->pos, _("can't use non global fptr of other class."))
@@ -118,7 +121,7 @@ ANN static m_bool check_var(const Env env, const Var_Decl var) {
   if(env->class_def && !env->scope->depth && env->class_def->e->parent)
     CHECK_BB(check_exp_decl_parent(env, var))
   if(var->array && var->array->exp)
-    return check_subscripts(env, var->array);
+    return check_subscripts(env, var->array, 1);
   return GW_OK;
 }
 
@@ -260,6 +263,14 @@ ANN static Value check_non_res_value(const Env env, const Symbol *data) {
   return value;
 }
 
+ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data);
+
+ANN static Type check_dot(const Env env, const Value v, const Exp_Dot *member) {
+  struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->t_base,
+         .rhs=v->type, .data=(uintptr_t)member, .pos=exp_self(member)->pos };
+  return op_check(env, &opi);
+}
+
 ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
   const Symbol var = *data;
   const Value v = check_non_res_value(env, data);
@@ -273,8 +284,15 @@ ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
     UNSET_FLAG(env->func, pure);
   SET_FLAG(v, used);
   prim_self(data)->value = v;
-  if(GET_FLAG(v, const) || !strcmp(s_name(var), "maybe"))
+  if(GET_FLAG(v, const))
     prim_exp(data)->meta = ae_meta_value;
+  if(v->from->owner_class) {
+    const Exp exp  = symbol_owned_exp(env->gwion, data);
+    const Type ret = check_dot(env, v, &exp->d.exp_dot);
+    prim_exp(data)->nspc = exp->nspc;
+    free_exp(env->gwion->mp, exp);
+    CHECK_OO(ret);
+  }
   return v->type;
 }
 
@@ -316,25 +334,16 @@ ANN static Type check_prim(const Env env, Exp_Primary *prim) {
   return exp_self(prim)->type = check_prim_func[prim->prim_type](env, &prim->d);
 }
 
-ANN Type at_depth(const Env env, const Array_Sub array) {
-  const Type t = array->type;
-  const m_uint depth = array->depth;
-  if(GET_FLAG(t, typedef)) {
-    struct Array_Sub_ next = { array->exp, t->e->parent, depth };
-    return at_depth(env, &next);
-  }
-  if(t->array_depth >= depth)
-    return array_type(env, array_base(array->type), t->array_depth - depth);
+ANN Type check_array_access(const Env env, const Array_Sub array) {
   const Symbol sym = insert_symbol("@array");
   struct Op_Import opi = { .op=sym, .lhs=array->exp->type, .rhs=array->type, .pos=array->exp->pos, .data=(uintptr_t)array };
-  const Type ret = op_check(env, &opi);
-  return ret;
+  return op_check(env, &opi);
 }
 
 static ANN Type check_exp_array(const Env env, const Exp_Array* array) {
   CHECK_OO((array->array->type = check_exp(env, array->base)))
-  CHECK_BO(check_subscripts(env, array->array))
-  return at_depth(env, array->array);
+  CHECK_BO(check_subscripts(env, array->array, 0))
+  return check_array_access(env, array->array);
 }
 
 static ANN Type check_exp_slice(const Env env, const Exp_Slice* range) {
@@ -874,6 +883,8 @@ ANN static Type check_exp_dot(const Env env, Exp_Dot* member) {
           the_base->name, str)
   if(GET_FLAG(value, const) || GET_FLAG(value, enum))
     exp_self(member)->meta = ae_meta_value;
+//  prim_self(member)->value = value;
+  CHECK_OO(check_dot(env, value, member))
   return value->type;
 }
 
@@ -995,9 +1006,8 @@ ANN static m_bool do_stmt_auto(const Env env, const Stmt_Auto stmt) {
 }
 
 ANN static inline m_bool cond_type(const Env env, const Exp e) {
-  const Symbol sym = insert_symbol("@repeat");
   const Type t_int = env->gwion->type[et_int];
-  return check_internal(env, sym, e, t_int);
+  return check_implicit(env, e, t_int);
 }
 
 #define stmt_func_xxx(name, type, prolog, exp) describe_stmt_func(check, name, type, prolog, exp)
@@ -1343,7 +1353,7 @@ ANN static m_bool check_parent(const Env env, const Class_Def cdef) {
   const Type parent = cdef->base.type->e->parent;
   const Type_Decl *td = cdef->base.ext;
   if(td->array)
-    CHECK_BB(check_subscripts(env, td->array))
+    CHECK_BB(check_subscripts(env, td->array, 1))
   if(parent->e->def && !GET_FLAG(parent, check))
     CHECK_BB(scanx_parent(parent, traverse_cdef, env))
   if(GET_FLAG(parent, typedef))
index 0f8e3240c7d24f213949953ace4a581cdc5f4d03..46bd2b19c6330af73d5bda0b486fed098cb2e00f 100644 (file)
@@ -146,16 +146,13 @@ ANN m_bool add_op(const Gwion gwion, const struct Op_Import* opi) {
 }
 
 ANN static void set_nspc(struct OpChecker* ock, const Nspc nspc) {
-printf("here %s\n", nspc->name);
   if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@array")) {
     Array_Sub array = (Array_Sub)ock->opi->data;
     array->exp->nspc = nspc;
     return;
 
   }
-  if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@implicit") ||
-     ock->opi->op == insert_symbol(ock->env->gwion->st, "@access") ||
-     ock->opi->op == insert_symbol(ock->env->gwion->st, "@repeat")) {
+  if(ock->opi->op == insert_symbol(ock->env->gwion->st, "@implicit")) {
     struct Implicit* imp = (struct Implicit*)ock->opi->data;
     imp->e->nspc = nspc;
     return;
@@ -237,6 +234,10 @@ ANN static Instr handle_instr(const Emitter emit, const M_Operator* mo) {
 }
 
 ANN static Nspc get_nspc(SymTable *st, const struct Op_Import* opi) {
+  if(opi->op == insert_symbol(st, "@array")) {
+    struct ArrayAccessInfo *info = (struct ArrayAccessInfo*)opi->data;
+    return info->array.exp->nspc;
+  }
   if(opi->op == insert_symbol(st, "@implicit")) {
     struct Implicit* imp = (struct Implicit*)opi->data;
     return imp->e->nspc;
@@ -263,8 +264,7 @@ ANN Instr op_emit(const Emitter emit, const struct Op_Import* opi) {
     Type r = opi->rhs;
     do {
       const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
-if(!v)continue;
-assert(v);
+      if(!v)continue;
       const M_Operator* mo = operator_find(v, l, r);
       if(mo) {
         if(mo->em)
index 35c7b289983db7f296b982e026f11fb9c48abbf4..3fa4ebaa92b50fa41c599428dfc3df1b15c4a2c0 100644 (file)
@@ -394,9 +394,7 @@ ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
     return class_internal(env, base);
   if(op == insert_symbol("@implicit"))
     return scan_internal_arg(env, base);
-  if(op == insert_symbol("@access")       ||
-     op == insert_symbol("@repeat")       ||
-     op == insert_symbol("@conditionnal") ||
+  if(op == insert_symbol("@conditionnal") ||
      op == insert_symbol("@unconditionnal"))
     return scan_internal_int(env, base);
   return GW_OK;
index df46f923acf6b2b44accc1bd0d2255787c1f9d9b..c8504e82aaa005003f4673a0469d3b9eb697658b 100644 (file)
@@ -1,5 +1,6 @@
-#! [contains] can't use non public typedef at global scope
+#! [contains] NullPtrException
 class C {
   typedef void t_ptr();
 }
 C->t_ptr ptr;
+ptr();
index 57bb422315203407dfe14098cb0d6636e2ece7a8..ef41b3800aa58120623b60098c000bf275449f82 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] must return
-operator @access Object (int i) {}
+operator @conditionnal Object (int i) {}
index cabafc9cf3d589173353a723e960d7b347b6113f..c45e141b69012d2a92dbed805bf564ed87123f99 100644 (file)
@@ -1,2 +1,2 @@
 #! [contains] must have one
-operator @access int(Vec3 v, int i) {}
+operator @implicit int(Vec3 v, int i) {}
index a46b3be1af32b5677bbcc55360f846a246cd56e9..f9b9b900c22eccd2ae087b7daeac7e3474dc7065 100644 (file)
@@ -1,5 +1,4 @@
-int i;
-for(i=0; i< 3; i++) {
+for(int i; i< 3; i++) {
   if(maybe)
     break;
   else continue;