From: Jérémie Astor Date: Sun, 8 Mar 2020 16:44:50 +0000 (+0100) Subject: :art: Refactor op operations X-Git-Tag: nightly~1726^2~43 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=4aa86b704f6994c81de606ca1def29d27af69edd;p=gwion.git :art: Refactor op operations --- diff --git a/examples/vec4.gw b/examples/vec4.gw index 4dc23d48..3415180c 100644 --- a/examples/vec4.gw +++ b/examples/vec4.gw @@ -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) >>>; diff --git a/include/array.h b/include/array.h index 7d4eb41d..24060901 100644 --- a/include/array.h +++ b/include/array.h @@ -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 diff --git a/include/emit.h b/include/emit.h index 8a8cb71e..2c2c7569 100644 --- a/include/emit.h +++ b/include/emit.h @@ -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 diff --git a/include/env/type.h b/include/env/type.h index 3f3086ee..89fbb445 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -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 diff --git a/include/parse.h b/include/parse.h index 09f955a0..43ffc4cc 100644 --- a/include/parse.h +++ b/include/parse.h @@ -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 diff --git a/src/emit/emit.c b/src/emit/emit.c index 97312a7d..d4f1baff 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -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) { diff --git a/src/lib/array.c b/src/lib/array.c index 5f9a9157..b27651e7 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -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; diff --git a/src/lib/complex.c b/src/lib/complex.c index b1f57ef0..4a3c176c 100644 --- a/src/lib/complex.c +++ b/src/lib/complex.c @@ -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; } diff --git a/src/lib/engine.c b/src/lib/engine.c index 5cef63a1..30ecede5 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -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); diff --git a/src/lib/object.c b/src/lib/object.c index b94a6536..ffd8539b 100644 --- a/src/lib/object.c +++ b/src/lib/object.c @@ -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; +} diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index d5e72a10..8a443967 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -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; } diff --git a/src/lib/prim.c b/src/lib/prim.c index 2846045d..dcc518c4 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -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; } diff --git a/src/lib/shred.c b/src/lib/shred.c index 07a20e71..a247efbe 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -13,11 +13,10 @@ #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)) diff --git a/src/lib/tuple.c b/src/lib/tuple.c index 8dd269ae..f905a406 100644 --- a/src/lib/tuple.c +++ b/src/lib/tuple.c @@ -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; -} diff --git a/src/lib/vararg.c b/src/lib/vararg.c index 129fa43b..e57026c6 100644 --- a/src/lib/vararg.c +++ b/src/lib/vararg.c @@ -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)) diff --git a/src/lib/vec.c b/src/lib/vec.c index 2c6b2e90..5273103a 100644 --- a/src/lib/vec.c +++ b/src/lib/vec.c @@ -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)) diff --git a/src/parse/check.c b/src/parse/check.c index 567a98b6..c1ca2097 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -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)) diff --git a/src/parse/operator.c b/src/parse/operator.c index 0f8e3240..46bd2b19 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -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) diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 35c7b289..3fa4ebaa 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -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; diff --git a/tests/error/non_public_typedef_global_scope.gw b/tests/error/non_public_typedef_global_scope.gw index df46f923..c8504e82 100644 --- a/tests/error/non_public_typedef_global_scope.gw +++ b/tests/error/non_public_typedef_global_scope.gw @@ -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(); diff --git a/tests/internal_op/internal_not_int.gw b/tests/internal_op/internal_not_int.gw index 57bb4223..ef41b380 100644 --- a/tests/internal_op/internal_not_int.gw +++ b/tests/internal_op/internal_not_int.gw @@ -1,2 +1,2 @@ #! [contains] must return -operator @access Object (int i) {} +operator @conditionnal Object (int i) {} diff --git a/tests/match/internal_multi.gw b/tests/match/internal_multi.gw index cabafc9c..c45e141b 100644 --- a/tests/match/internal_multi.gw +++ b/tests/match/internal_multi.gw @@ -1,2 +1,2 @@ #! [contains] must have one -operator @access int(Vec3 v, int i) {} +operator @implicit int(Vec3 v, int i) {} diff --git a/tests/tree/for_break_continue.gw b/tests/tree/for_break_continue.gw index a46b3be1..f9b9b900 100644 --- a/tests/tree/for_break_continue.gw +++ b/tests/tree/for_break_continue.gw @@ -1,5 +1,4 @@ -int i; -for(i=0; i< 3; i++) { +for(int i; i< 3; i++) { if(maybe) break; else continue;