diff --git a/.travis.yml b/.travis.yml index bddfa7230..37a1e0e6e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: c #sudo: required os: - linux -# - windows - osx + - windows addons: # coverity_scan: @@ -33,8 +33,8 @@ env: matrix: allow_failures: - - compiler: clang -# - os: windows +# - compiler: clang + - os: windows compiler: - gcc @@ -47,7 +47,7 @@ install: export BUILD_ON_WINDOWS=1; export VALGRIND="NO_VALGRIND"; export SEVERITY=1; - export LDFLAGS="$LDLAGS -lpsapi -shared -fPIC -Wl,--export-all -Wl,--enable-auto-import -Wl,--out-implib,libgwion.a"; + export LDFLAGS="$LDLAGS -lpsapi -shared -fPIC -Wl,--export-all -Wl,--enable-auto-import"; export LIBS="$LIBS -lpsapi -shared -fPIC"; fi; @@ -59,7 +59,12 @@ before_script: script: - if [ $(uname) = "Linux" ] || [ $(uname) = "Darwin" ]; then make && make test; - else make.exe && make.exe test; + else { + if [ "$CC" = "clang" ]; + then export CFLAGS+=" -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -Dssize_t=SSIZE_T"; + fi; + make.exe && make.exe test; + } fi; git: diff --git a/ast b/ast index 2f8759c59..63cdc3025 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 2f8759c59db171ce3d4737c7912b3b57d1d6dec6 +Subproject commit 63cdc302579f7e86ddeb6b498e1336b933499700 diff --git a/examples/binary_tmpl.gw b/examples/binary_tmpl.gw index 34b11cc1c..9b2a9107a 100644 --- a/examples/binary_tmpl.gw +++ b/examples/binary_tmpl.gw @@ -1,4 +1,4 @@ -fun<~A~> void test(A a) { <<>>; } +fun void test<~A~>(A a) { <<>>; } 1 => test; 1.3 => test; test(1); diff --git a/examples/class_func_pointer.gw b/examples/class_func_pointer.gw index 5e79ffb4b..937ba7ea1 100644 --- a/examples/class_func_pointer.gw +++ b/examples/class_func_pointer.gw @@ -1,13 +1,13 @@ -function void test() { <<<"member function.">>>; } +fun void test() { <<<"member function.">>>; } class C { typedef void func_t(); // typedef static void s_func_t(); func_t func_p; // static fun c_t s_func_p; // static s_func_t s_ptr; - function void test() { <<<"member function.">>>; } - function void test2() { <<<"member function variant.">>>; } -// fun static void s_test() { <<<"member function.">>>; } + fun void test() { <<<"member function.">>>; } + fun void test2() { <<<"member function variant.">>>; } +// fun static void s_test() { <<<"member fun.">>>; } // test @=> func_p; // test @=> s_ptr; diff --git a/examples/class_spork_func.gw b/examples/class_spork_func.gw index e375e598a..180fd4f18 100644 --- a/examples/class_spork_func.gw +++ b/examples/class_spork_func.gw @@ -1,6 +1,6 @@ class C { - function void test() { + fun void test() { <<<"here">>>; samp => now; <<<"and now">>>; diff --git a/examples/func.gw b/examples/func.gw index d8b70aa23..74f319f13 100644 --- a/examples/func.gw +++ b/examples/func.gw @@ -1,4 +1,4 @@ -function float testf(){ return 1.1; } -function float testf(float f){ return f; } +fun float testf(){ return 1.1; } +fun float testf(float f){ return f; } <<>>; <<>>; diff --git a/examples/func_pointer.gw b/examples/func_pointer.gw index 49600abc6..6eb9d8f55 100644 --- a/examples/func_pointer.gw +++ b/examples/func_pointer.gw @@ -1,7 +1,7 @@ typedef void func_t(); func_t func_p; -function void test1() { <<<"test1">>>; } -function void test2() { <<<"test2">>>; } +fun void test1() { <<<"test1">>>; } +fun void test2() { <<<"test2">>>; } test1 @=> func_p; func_p(); func_p(); diff --git a/examples/func_ptr.gw b/examples/func_ptr.gw index a98de761d..c0cb1da26 100644 --- a/examples/func_ptr.gw +++ b/examples/func_ptr.gw @@ -1,15 +1,15 @@ -// define a function pointer type +// define a fun pointer type typedef void Test() -// define a few functions -function void test1(){ <<<"test">>>; }; -function void test2(){ <<<"another test">>>; }; -function void test3(){ <<<"yet another test">>>; }; +// define a few funs +fun void test1(){ <<<"test">>>; }; +fun void test2(){ <<<"another test">>>; }; +fun void test3(){ <<<"yet another test">>>; }; -// create a function pointer instance +// create a fun pointer instance Test test; -// assign it a function +// assign it a fun test1 @=> test; // test it test(); diff --git a/examples/in_class_class.gw b/examples/in_class_class.gw index 3ef4deee7..724b12964 100644 --- a/examples/in_class_class.gw +++ b/examples/in_class_class.gw @@ -1,5 +1,5 @@ class C { - function<~a~> void test(a var){ <<>>; } + fun void test<~a~>(a var){ <<>>; } class D { int i;} } diff --git a/examples/member.gw b/examples/member.gw index 8759dd050..f4be65650 100644 --- a/examples/member.gw +++ b/examples/member.gw @@ -7,19 +7,19 @@ class C Vec4 w; Object o; - function int m_i() { return i; } - function float m_f() { return f; } - function complex m_c() { return c; } - function Vec3 m_v() { return v; } - function Vec4 m_w() { return w; } - function Object m_o() { return o; } + fun int m_i() { return i; } + fun float m_f() { return f; } + fun complex m_c() { return c; } + fun Vec3 m_v() { return v; } + fun Vec4 m_w() { return w; } + fun Object m_o() { return o; } } C c; // read members <<< c.i, c.c, c.f, c.v, c.w, c.o >>>; -// call function members +// call fun members <<< c.m_i(), " ", c.m_f(), " ", c.m_c(), " ", c.m_v(), " ", c.m_w(), " ", c.m_o()>>>; diff --git a/examples/member_func.gw b/examples/member_func.gw index 05742d145..b56ed704e 100644 --- a/examples/member_func.gw +++ b/examples/member_func.gw @@ -1,9 +1,9 @@ class C { - function float testf() { + fun float testf() { return 1.1; } - function float testf(float f) { + fun float testf(float f) { return f; } } diff --git a/examples/ptr_assign_class.gw b/examples/ptr_assign_class.gw index 05a6f23c7..b49465fad 100644 --- a/examples/ptr_assign_class.gw +++ b/examples/ptr_assign_class.gw @@ -1,7 +1,7 @@ class C { typedef void Test(); - function void test1(){}; + fun void test1(){}; Test test0; << test0>>>; } diff --git a/examples/sinosc_extend.gw b/examples/sinosc_extend.gw index 3a4aa80f7..8c7f7aebf 100644 --- a/examples/sinosc_extend.gw +++ b/examples/sinosc_extend.gw @@ -1,6 +1,6 @@ class Sine extends SinOsc { - function float freq(float f) { (2 * f) => (this $ SinOsc).freq; } + fun float freq(float f) { (2 * f) => (this $ SinOsc).freq; } } Sine s => dac; diff --git a/examples/spork_func.gw b/examples/spork_func.gw index 14252342e..ed40d747d 100644 --- a/examples/spork_func.gw +++ b/examples/spork_func.gw @@ -1,6 +1,6 @@ class C { - function void test(int i) { + fun void test(int i) { <<<"here => ", i>>>; samp => now; <<<"and now">>>; diff --git a/examples/static.gw b/examples/static.gw index 6877968dc..a1fec3bb0 100644 --- a/examples/static.gw +++ b/examples/static.gw @@ -7,12 +7,12 @@ class C static Vec4 w; static Object o; - function int m_i() { return i; } - function float m_f() { return f; } - function complex m_c() { return c; } - function Vec3 m_v() { return v; } - function Vec4 m_w() { return w; } - function Object m_o() { return o; } + fun int m_i() { return i; } + fun float m_f() { return f; } + fun complex m_c() { return c; } + fun Vec3 m_v() { return v; } + fun Vec4 m_w() { return w; } + fun Object m_o() { return o; } fun static int _i() { return i; } fun static float _f() { return f; } @@ -25,7 +25,7 @@ class C // read members <<< C.i, C.c, C.f, C.v, C.w, C.o >>>; -// call function members +// call fun members <<< C._i(), " ", C._f(), " ", C._c(), " ", C._v(), " ", C._w(), " ", C._o()>>>; // write members diff --git a/examples/switch.gw b/examples/switch.gw index 9b576f356..c34fb47d5 100644 --- a/examples/switch.gw +++ b/examples/switch.gw @@ -1,6 +1,6 @@ int i; -function void test(int i) { +fun void test(int i) { switch(i) { case 1: <<<"'i' is 1">>>; diff --git a/examples/template.gw b/examples/template.gw index d4d2dfc48..32323111a 100644 --- a/examples/template.gw +++ b/examples/template.gw @@ -1,4 +1,4 @@ -function<~A~> void test (A var){ <<< var>>>; } -function<~A,B~> void test (A var, B var2){ <<< var>>>; } +fun void test<~A~> (A var){ <<< var>>>; } +fun void test<~A,B~> (A var, B var2){ <<< var>>>; } test<~int~>(1); test<~float, float~>(3, 1.4); diff --git a/examples/template_dyn.gw b/examples/template_dyn.gw index 793907a52..aa64a7174 100644 --- a/examples/template_dyn.gw +++ b/examples/template_dyn.gw @@ -4,15 +4,15 @@ fun void test(C cc, int i) { <<<1>>>; <<>>; } class C { - fun<~A~> int test(A a) { <<<" A ", a>>>; } - fun<~A~> int test(A a, int i) { <<<" ", a >>>; } - fun<~A~> int test(A a, int i, int j) { <<>>; } + fun int test<~A~>(A a) { <<<" A ", a>>>; } + fun int test<~A~>(A a, int i) { <<<" ", a >>>; } + fun int test<~A~>(A a, int i, int j) { <<>>; } } class D extends C { - fun<~A~> int test(A a, int i) { <<>>; } + fun int test<~A~>(A a, int i) { <<>>; } } class E extends D { - fun<~A~> int test(A a, int i) { <<>>; } + fun int test<~A~>(A a, int i) { <<>>; } } diff --git a/examples/template_guess.gw b/examples/template_guess.gw index 26dadbcb5..40202949e 100644 --- a/examples/template_guess.gw +++ b/examples/template_guess.gw @@ -1,4 +1,4 @@ -function <~A,B~> void test(A a, B b){<<>>;} +fun void test<~A,B~>(A a, B b){<<>>;} test(1, 2.1); test(1.1, 2.1); test(1.2, 2); diff --git a/examples/template_vararg.gw b/examples/template_vararg.gw index 77ad4f945..d2d52b6fb 100644 --- a/examples/template_vararg.gw +++ b/examples/template_vararg.gw @@ -1,4 +1,4 @@ -fun<~A~> void test(...) { +fun void test<~A~>(...) { vararg.start; <<>>; vararg.end; diff --git a/include/instr.h b/include/instr.h index f311e2b50..a84f8d4a4 100644 --- a/include/instr.h +++ b/include/instr.h @@ -61,13 +61,15 @@ INSTR(VecMember); INSTR(PopArrayClass); INSTR(DotTmpl); +INSTR(GTmpl); struct dottmpl_ { size_t len; m_str name; Func_Def base, def; - Type owner; - size_t overload; // => vtindex ? + Type owner_class; + Nspc owner; + size_t vt_index; Type_List tl; }; ANN void free_dottmpl(struct dottmpl_*); diff --git a/include/parse.h b/include/parse.h index 42dbcd68f..0eee67712 100644 --- a/include/parse.h +++ b/include/parse.h @@ -79,4 +79,18 @@ static inline ANN m_bool env_ext(const Env env, const Class_Def cdef, const _exp ANN m_bool scanx_parent(const Type t, const _exp_func f, void *d); #define scanx_parent(a,b,c) scanx_parent(a, (_exp_func)b, c) + + +ANN m_bool scanx_cdef(const Env, void *,const Class_Def, + const _exp_func f_cdef, const _exp_func f_union); + +#define xxx_cdef(prefix) \ +static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \ + return scanx_cdef(env, env, cdef, \ + (_exp_func)prefix##_class_def, (_exp_func)prefix##_stmt_union); \ +} +xxx_cdef(scan1) +xxx_cdef(scan2) +xxx_cdef(check) +xxx_cdef(traverse) #endif diff --git a/include/type.h b/include/type.h index f286ca8d2..e9cc2a349 100644 --- a/include/type.h +++ b/include/type.h @@ -1,15 +1,16 @@ #ifndef __TYPE #define __TYPE - struct TypeInfo_ { - Type parent; - Nspc owner; - Class_Def def; - union type_data { - Func func; - Type base_type; - } d; - }; +struct TypeInfo_ { + Type parent; + Nspc owner; + Class_Def def; + union type_data { + Func func; + Type base_type; + } d; + struct Vector_ contains; +}; struct Type_ { m_str name; diff --git a/src/emit/emit.c b/src/emit/emit.c index c2dcb5147..641f2da3e 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -305,7 +305,7 @@ ANN static inline Exp dot_static_exp(const Emitter emit, const Exp_Primary* prim ANN static m_bool emit_symbol_owned(const Emitter emit, const Exp_Primary* prim) { const Value v = prim->value; const Exp dot = (!GET_FLAG(v, static) ? dot_this_exp : dot_static_exp)(emit, prim, v->owner_class); - dot->type = v->type; + dot->type = exp_self(prim)->type; dot->emit_var = exp_self(prim)->emit_var; const m_bool ret = emit_exp_dot(emit, &dot->d.exp_dot); free_exp(emit->gwion->mp, dot); @@ -349,6 +349,8 @@ ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) { const m_uint size = v->type->size; const Instr instr = emit_kind(emit, size, exp_self(prim)->emit_var, !GET_FLAG(v, global) ? regpushmem : regpushbase); instr->m_val = v->offset; + if(isa(v->type, t_function) > 0 && isa(v->type, t_fptr) < 0) + instr->m_val = exp_self(prim)->type->e->d.func->value_ref->offset; return GW_OK; } @@ -607,10 +609,11 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Var_Decl var_de } ANN static m_bool emit_class_def(const Emitter, const Class_Def); +ANN static m_bool emit_cdef(const Emitter, const Class_Def); ANN static m_bool emit_parent_inner(const Emitter emit, const Class_Def cdef) { - CHECK_BB(traverse_class_def(emit->env, cdef)) - return emit_class_def(emit, cdef); + CHECK_BB(traverse_cdef(emit->env, cdef)) + return emit_cdef(emit, cdef); } ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) { @@ -683,6 +686,9 @@ ANN static m_bool prepare_call(const Emitter emit, const Exp_Call* exp_call) { ANN static inline m_int push_tmpl_func(const Emitter emit, const Func f) { const Value v = f->value_ref; + if(isa(v->type, t_class) > 0 && + isa(actual_type(v->type), t_fptr) > 0) + return emit->env->scope->depth; const m_uint scope = emit_push(emit, v->owner_class, v->owner); CHECK_BB(traverse_func_template(emit->env, f->def)) return (m_int)scope; @@ -750,10 +756,11 @@ ANN static Type_List tmpl_tl(const Env env, const m_str name) { } ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) { - const m_uint scope = emit_push_type(emit, dt->owner); + const m_uint scope = dt->owner_class ? + emit_push_type(emit, dt->owner_class) : emit_push(emit, NULL, dt->owner); m_bool ret = GW_ERROR; dt->def->base->tmpl->call = dt->tl;// in INSTR - if(traverse_func_template(emit->env, dt->def) > 0) { + if(!dt->def->base->func &&traverse_func_template(emit->env, dt->def) > 0) { ret = emit_func_def(emit, dt->def); nspc_pop_type(emit->gwion->mp, emit->env->curr); } @@ -764,7 +771,7 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) { static inline m_bool push_func_code(const Emitter emit, const Func f) { if(GET_FLAG(f, template) && f->value_ref->owner_class) { const Instr instr = (Instr)vector_back(&emit->code->instr); - assert(instr->opcode == eDotTmplVal); + assert(instr->opcode == eDotTmplVal); size_t len = strlen(f->name); size_t sz = len - strlen(f->value_ref->owner_class->name); char c[sz + 1]; @@ -772,7 +779,7 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) { c[sz] = '\0'; struct dottmpl_ *dt = mp_calloc(emit->gwion->mp, dottmpl); dt->name = s_name(insert_symbol(c)); - dt->overload = f->def->base->tmpl->base; + dt->vt_index = f->def->base->tmpl->base; dt->tl = tmpl_tl(emit->env, c); dt->base = f->def; instr->opcode = eOP_MAX; @@ -781,11 +788,11 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) { instr->execute = DotTmpl; return GW_OK; } -if(vector_size(&emit->code->instr)) { - const Instr instr = (Instr)vector_back(&emit->code->instr); - instr->opcode = eRegPushImm; - instr->m_val = (m_uint)f->code; -} + if(vector_size(&emit->code->instr)) { + const Instr instr = (Instr)vector_back(&emit->code->instr); + instr->opcode = eRegPushImm; + instr->m_val = (m_uint)f->code; + } return GW_OK; } @@ -806,6 +813,23 @@ ANN static Instr get_prelude(const Emitter emit, const Func f) { instr = emit_add_instr(emit, !GET_FLAG(f, builtin) ? FuncUsr : SetCode); else { emit_add_instr(emit, GWOP_EXCEPT); + if(f->def->base->tmpl) { // TODO: put in func + struct dottmpl_ *dt = (struct dottmpl_*)mp_calloc(emit->gwion->mp, dottmpl); + size_t len = strlen(f->name); + size_t sz = len - strlen(f->value_ref->owner->name); + char c[sz + 1]; + memcpy(c, f->name, sz); + c[sz] = '\0'; + dt->tl = tmpl_tl(emit->env, c); + dt->name = s_name(insert_symbol(c)); + dt->vt_index = f->def->base->tmpl->base; + dt->base = f->def; + dt->owner = f->value_ref->owner; + dt->owner_class = f->value_ref->owner_class; + const Instr gtmpl = emit_add_instr(emit, GTmpl); + gtmpl->m_val = (m_uint)dt; + gtmpl->m_val2 = strlen(c); + } instr = emit_add_instr(emit, FuncPtr); } instr->m_val2 = 1; @@ -841,7 +865,8 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) { if(GET_FLAG(f, template) && emit->env->func != f) CHECK_BB(emit_template_code(emit, f)) } else if((f->value_ref->owner_class && is_special(f->value_ref->owner_class) > 0) || - !f->value_ref->owner_class || GET_FLAG(f, template)) + !f->value_ref->owner_class || (GET_FLAG(f, template) && + isa(f->value_ref->type, t_fptr) < 0)) push_func_code(emit, f); else if(vector_size(&emit->code->instr)){ const Instr back = (Instr)vector_back(&emit->code->instr); @@ -974,8 +999,9 @@ ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) { } ANN static m_bool emit_implicit_cast(const Emitter emit, - const restrict Type from, const restrict Type to) { - struct Op_Import opi = { .op=op_impl, .lhs=from, .rhs=to, .data=(m_uint)from }; + const restrict Exp from, const restrict Type to) { + const struct Implicit imp = { from, to }; + struct Op_Import opi = { .op=op_impl, .lhs=from->type, .rhs=to, .data=(m_uint)&imp }; return op_emit(emit, &opi); } @@ -1023,7 +1049,7 @@ ANN2(1) static m_bool emit_exp(const Emitter emit, Exp exp, const m_bool ref) { do { CHECK_BB(exp_func[exp->exp_type](emit, &exp->d)) if(exp->cast_to) - CHECK_BB(emit_implicit_cast(emit, exp->type, exp->cast_to)) + CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to)) if(ref && isa(exp->type, t_object) > 0 && isa(exp->type, t_shred) < 0 ) { // beware fork const Instr instr = emit_add_instr(emit, RegAddRef); instr->m_val = exp->emit_var; @@ -1378,6 +1404,8 @@ ANN static inline void union_allocdata(MemPool mp, const Stmt_Union stmt) { } ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { + if(stmt->tmpl) + return GW_OK; Decl_List l = stmt->l; m_uint scope = emit->env->scope->depth; const m_bool global = GET_FLAG(stmt, global); @@ -1507,7 +1535,7 @@ ANN static inline Instr get_variadic(const Emitter emit) { } ANN static void emit_vararg_end(const Emitter emit, const m_uint offset) { - const Instr instr = emit_add_instr(emit, VarargEnd), + const Instr instr = emit_add_instr(emit, VarargEnd), variadic = get_variadic(emit); instr->m_val = offset; instr->m_val2 = variadic->m_val2; @@ -1560,7 +1588,7 @@ ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, co emit_add_instr(emit, DotTmplVal); else { const Instr instr = emit_add_instr(emit, GET_FLAG(func, member) ? DotFunc : DotStaticFunc); - instr->m_val = func->vt_index; + instr->m_val = exp_self(member)->type->e->d.func->vt_index; } return GW_OK; } @@ -1615,8 +1643,8 @@ ANN static void emit_func_def_args(const Emitter emit, Arg_List a) { } while((a = a->next)); } -ANN static void emit_func_def_ensure(const Emitter emit, const Func_Def func_def) { - const m_uint size = func_def->base->ret_type->size; +ANN static void emit_func_def_ensure(const Emitter emit, const Func_Def fdef) { + const m_uint size = fdef->base->ret_type->size; if(size) { const Instr instr = emit_kind(emit, size, 0, regpushimm); instr->m_val2 = size; @@ -1648,31 +1676,42 @@ ANN static void emit_func_def_code(const Emitter emit, const Func func) { instr->m_val = (m_uint)emit->gwion->mp; ADD_REF(func->code) } + // TODO: find why we need this + func->def->stack_depth = func->code->stack_depth; } -ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def func_def) { - if(func_def->base->args) - emit_func_def_args(emit, func_def->base->args); - if(GET_FLAG(func_def, variadic)) +ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) { + if(fdef->base->args) + emit_func_def_args(emit, fdef->base->args); + if(GET_FLAG(fdef, variadic)) stack_alloc(emit); - if(func_def->d.code->d.stmt_code.stmt_list) - CHECK_BB(emit_stmt_code(emit, &func_def->d.code->d.stmt_code)) - emit_func_def_ensure(emit, func_def); + if(fdef->d.code) + CHECK_BB(emit_stmt_code(emit, &fdef->d.code->d.stmt_code)) + emit_func_def_ensure(emit, fdef); return GW_OK; } -ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { - const Func func = get_func(emit->env, func_def); +ANN static m_bool tmpl_rettype(const Emitter emit, const Func_Def fdef) { + CHECK_BB(template_push_types(emit->env, fdef->base->tmpl)) + const m_bool ret = emit_parent_inner(emit, fdef->base->ret_type->e->def); + nspc_pop_type(emit->gwion->mp, emit->env->curr); + return ret; +} + +ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) { + const Func func = get_func(emit->env, fdef); const Func former = emit->env->func; if(func->code) return GW_OK; - if(tmpl_base(func_def->base->tmpl)) { - UNSET_FLAG(func_def, template); + if(tmpl_base(fdef->base->tmpl)) { + UNSET_FLAG(fdef, template); return GW_OK; } + if(GET_FLAG(fdef->base->ret_type, template) && !GET_FLAG(fdef->base->ret_type, emit)) + CHECK_BB(tmpl_rettype(emit, fdef)) if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template)) return GW_OK; - if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->base->tmpl && !emit->env->scope->depth) + if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl && !emit->env->scope->depth) func->value_ref->offset = emit_local(emit, SZ_INT, 0); emit_func_def_init(emit, func); if(GET_FLAG(func, member)) @@ -1680,21 +1719,21 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { emit_push_scope(emit); emit->env->func = func; vector_add(&emit->variadic, 0); - CHECK_BB(emit_func_def_body(emit, func_def)) - if(GET_FLAG(func_def, variadic)) { + CHECK_BB(emit_func_def_body(emit, fdef)) + if(GET_FLAG(fdef, variadic)) { if(!get_variadic(emit)) - ERR_B(func_def->pos, "invalid variadic use") + ERR_B(fdef->pos, "invalid variadic use") if(!GET_FLAG(func, empty)) - ERR_B(func_def->pos, "invalid variadic use") + ERR_B(fdef->pos, "invalid variadic use") } vector_pop(&emit->variadic); emit_func_def_return(emit); emit_func_def_code(emit, func); emit->env->func = former; emit_pop_code(emit); - if(GET_FLAG(func_def, op)) + if(GET_FLAG(fdef, op)) SET_FLAG(func->code, op); - if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->base->tmpl) + if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl) emit_func_def_global(emit, func->value_ref); if(emit->memoize && GET_FLAG(func, pure)) func->code->memoize = memoize_ini(emit, func, @@ -1724,6 +1763,11 @@ ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) { return scanx_parent(parent, emit_parent_inner, emit); } +ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) { + return scanx_cdef(emit->env, emit, cdef, + (_exp_func)emit_class_def, (_exp_func)emit_stmt_union); +} + ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { const Type type = cdef->base.type; const Nspc nspc = type->nspc; diff --git a/src/lib/func.c b/src/lib/func.c index a757862cc..ca08dcdb3 100644 --- a/src/lib/func.c +++ b/src/lib/func.c @@ -36,30 +36,113 @@ static OP_CHECK(opck_func_call) { return check_exp_call1(env, &e->d.exp_call) ?: t_null; } +static inline void fptr_instr(const Emitter emit, const Func f, const m_uint i) { + const Instr set = emit_add_instr(emit, RegSetImm); + set->m_val = (m_uint)f; + set->m_val2 = -SZ_INT*i; +} + static OP_EMIT(opem_func_assign) { Exp_Binary* bin = (Exp_Binary*)data; + if(bin->rhs->type->e->d.func->def->base->tmpl) + fptr_instr(emit, bin->lhs->type->e->d.func, 2); emit_add_instr(emit, int_r_assign); - if((bin->lhs->type != t_lambda && isa(bin->lhs->type, t_fptr) < 0) && GET_FLAG(bin->rhs->type->e->d.func, member)) { + if((bin->lhs->type != t_lambda && isa(bin->lhs->type, t_fptr) < 0) && + GET_FLAG(bin->rhs->type->e->d.func, member)) { const Instr instr = emit_add_instr(emit, LambdaAssign); instr->m_val = SZ_INT; } return GW_OK; } -ANN static Type fptr_type(const Env env, Exp_Binary* bin) { - const Func l_func = bin->lhs->type->e->d.func; - const Func r_func = bin->rhs->type->e->d.func; - const Nspc nspc = l_func->value_ref->owner; - const m_str c = s_name(l_func->def->base->xid); - const Value v = l_func->value_ref; - for(m_uint i = 0; i <= v->offset; ++i) { - const Symbol sym = func_symbol(env, nspc->name, c, NULL, i); - const Func f = nspc_lookup_func1(nspc, sym); // was lookup2 - CHECK_OO(f) - if(compat_func(r_func->def, f->def) > 0) - return r_func->value_ref->type->e->d.base_type; +struct FptrInfo { + Func lhs; + const Func rhs; + const Exp exp; + const loc_t pos; +}; + +ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) { + if(!info->rhs->def->base->tmpl) + return GW_OK; + ID_List t0 = info->lhs->def->base->tmpl->list, + t1 = info->rhs->def->base->tmpl->list; + nspc_push_type(env->gwion->mp, env->curr); + while(t0) { + CHECK_OB(t1) + nspc_add_type(env->curr, t0->xid, t_undefined); + nspc_add_type(env->curr, t1->xid, t_undefined); + t0 = t0->next; + t1 = t1->next; } - return NULL; + return GW_OK; +} + +ANN static m_bool fptr_args(const Env env, struct Func_Base_ *base[2]) { + Arg_List arg0 = base[0]->args, arg1 = base[1]->args; + while(arg0) { + CHECK_OB(arg1) + const Type t0 = known_type(env, base[0]->td); + CHECK_OB(t0) + const Type t1 = known_type(env, base[1]->td); + CHECK_OB(t1) + CHECK_BB(isa(t0, t1)) + arg0 = arg0->next; + arg1 = arg1->next; + } + return !arg1 ? GW_OK : GW_ERROR; +} + +ANN static m_bool fptr_check(const Env env, struct FptrInfo *info) { + const Type l_type = info->lhs->value_ref->owner_class; + const Type r_type = info->rhs->value_ref->owner_class; + if(!r_type && l_type) + ERR_B(info->pos, "can't assign member function to non member function pointer") + else if(!l_type && r_type) { + if(!GET_FLAG(info->rhs, global)) + ERR_B(info->pos, "can't assign non member function to member function pointer") + } else if(l_type && isa(r_type, l_type) < 0) + ERR_B(info->pos, "can't assign member function to a pointer of an other class") + if(GET_FLAG(info->rhs, member)) { + if(!GET_FLAG(info->lhs, member)) + ERR_B(info->pos, "can't assign static function to member function pointer") + } else if(GET_FLAG(info->lhs, member)) + ERR_B(info->pos, "can't assign member function to static function pointer") + return GW_OK; +} + +ANN static m_bool fptr_rettype(const Env env, struct FptrInfo *info) { + const Type t0 = known_type(env, info->lhs->def->base->td); + CHECK_OB(t0) + const Type t1 = known_type(env, info->rhs->def->base->td); + CHECK_OB(t1) + return isa(t0, t1); +} + +ANN static inline m_bool fptr_arity(struct FptrInfo *info) { + return GET_FLAG(info->lhs->def, variadic) == + GET_FLAG(info->rhs->def, variadic); +} + +ANN static Type fptr_type(const Env env, struct FptrInfo *info) { + const Value v = info->lhs->value_ref; + const Nspc nspc = v->owner; + const m_str c = s_name(info->lhs->def->base->xid), + stmpl = !info->rhs->def->base->tmpl ? NULL : "template"; + Type type = NULL; + for(m_uint i = 0; i <= v->offset && !type; ++i) { + const Symbol sym = (!info->lhs->def->base->tmpl || i != 0) ? + func_symbol(env, nspc->name, c, stmpl, i) : info->lhs->def->base->xid; + info->lhs = nspc_lookup_func1(nspc, sym); + assert(info->lhs); + struct Func_Base_ *base[2] = { info->lhs->def->base, info->rhs->def->base }; + if(fptr_tmpl_push(env, info) > 0 && fptr_rettype(env, info) > 0 && + fptr_arity(info) && fptr_args(env, base) > 0) + type = info->lhs->value_ref->type; + if(info->rhs->def->base->tmpl) + nspc_pop_type(env->gwion->mp, env->curr); + } + return type; } ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner, @@ -74,8 +157,9 @@ ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner, } if(base || arg) ERR_B(exp_self(l)->pos, "argument number does not match for lambda") - l->def = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, def->base->td, l->name, l->args), l->code, def->flag, - loc_cpy(env->gwion->mp, def->pos)); + l->def = new_func_def(env->gwion->mp, + new_func_base(env->gwion->mp, def->base->td, l->name, l->args), + l->code, def->flag, loc_cpy(env->gwion->mp, def->pos)); CHECK_BB(traverse_func_def(env, l->def)) arg = l->args; while(arg) { @@ -87,63 +171,44 @@ ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner, return GW_OK; } +ANN static m_bool fptr_lambda(const Env env, struct FptrInfo *info) { + Exp_Lambda *l = &info->exp->d.exp_lambda; + const Type owner = info->rhs->value_ref->owner_class; + return check_lambda(env, owner, l, info->rhs->def); +} + +ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) { + if(isa(info->exp->type, t_lambda) < 0) { + CHECK_BB(fptr_check(env, info)) + return (info->exp->type = fptr_type(env, info)) ? GW_OK : GW_ERROR; + } + return fptr_lambda(env, info); +} + static OP_CHECK(opck_fptr_at) { Exp_Binary* bin = (Exp_Binary*)data; + struct FptrInfo info = { bin->lhs->type->e->d.func, bin->rhs->type->e->d.func, + bin->lhs, exp_self(bin)->pos }; + CHECK_BO(fptr_do(env, &info)) bin->rhs->emit_var = 1; - if(isa(bin->lhs->type, t_lambda) > 0) { - Exp_Lambda *l = &bin->lhs->d.exp_lambda; - const Type owner = nspc_lookup_type1(bin->rhs->type->e->owner->parent, - insert_symbol(bin->rhs->type->e->owner->name)); - CHECK_BO(check_lambda(env, owner, l, bin->rhs->type->e->d.func->def)) - return bin->rhs->type; - } - const Func l_func = bin->lhs->type->e->d.func; - const Func_Def l_fdef = l_func->def; - const Type l_type = l_func->value_ref->owner_class; - const Func r_func = bin->rhs->type->e->d.func; - const Func_Def r_fdef = r_func->def; - const Type r_type = r_func->value_ref->owner_class; - if(!r_type && l_type) - ERR_N(exp_self(bin)->pos, "can't assign member function to non member function pointer") - else if(r_type && !l_type) { - if(!GET_FLAG(r_func, global)) - ERR_N(exp_self(bin)->pos, "can't assign non member function to member function pointer") - } else if(r_type && isa(r_type, l_type) < 0) - ERR_N(exp_self(bin)->pos, "can't assign member function to member function pointer" - " of an other class") - if(GET_FLAG(r_func, member)) { - if(!GET_FLAG(l_func, member)) - ERR_N(exp_self(bin)->pos, "can't assign static function to member function pointer") - } else if(GET_FLAG(l_func, member)) - ERR_N(exp_self(bin)->pos, "can't assign member function to static function pointer") - if(isa(r_fdef->base->ret_type, l_fdef->base->ret_type) < 0) - ERR_N(exp_self(bin)->pos, "return type '%s' does not match '%s'\n\t... in pointer assignement", - r_fdef->base->ret_type->name, l_fdef->base->ret_type->name) - if(GET_FLAG(l_fdef, variadic) != GET_FLAG(r_fdef, variadic)) - ERR_N(exp_self(bin)->pos, "function must be of same argument kind.", - r_fdef->base->ret_type->name, l_fdef->base->ret_type->name) - if(isa(bin->lhs->type, t_fptr) > 0 && isa(bin->lhs->type, bin->rhs->type) > 0) - return bin->rhs->type; - return fptr_type(env, bin); + return bin->rhs->type; } static OP_CHECK(opck_fptr_cast) { Exp_Cast* cast = (Exp_Cast*)data; const Type t = exp_self(cast)->type; - const Value v = nspc_lookup_value1(env->curr, cast->exp->d.exp_primary.d.var); - CHECK_OO(v) - const Func f = isa(v->type, t_fptr) > 0 ? - v->type->e->d.func : - nspc_lookup_func1(env->curr, insert_symbol(v->name)); - CHECK_OO(f) - CHECK_BO(compat_func(t->e->d.func->def, f->def)) - cast->func = f; + struct FptrInfo info = { cast->exp->type->e->d.func, t->e->d.func, + cast->exp, exp_self(cast)->pos }; + CHECK_BO(fptr_do(env, &info)) + cast->func = cast->exp->type->e->d.func; return t; } static OP_EMIT(opem_fptr_cast) { CHECK_BB(opem_basic_cast(emit, data)) Exp_Cast* cast = (Exp_Cast*)data; + if(exp_self(cast)->type->e->d.func->def->base->tmpl) + fptr_instr(emit, cast->exp->type->e->d.func, 1); if(GET_FLAG(cast->exp->type->e->d.func, member)) { const Instr instr = emit_add_instr(emit, RegPop); instr->m_val = SZ_INT*2; @@ -153,6 +218,25 @@ static OP_EMIT(opem_fptr_cast) { return GW_OK; } +static OP_CHECK(opck_fptr_impl) { + struct Implicit *impl = (struct Implicit*)data; + struct FptrInfo info = { ((Exp)impl->e)->type->e->d.func, impl->t->e->d.func, + (Exp)impl->e, ((Exp)impl->e)->pos }; + CHECK_BO(fptr_do(env, &info)) + return ((Exp)impl->e)->cast_to = impl->t; +} + +static OP_EMIT(opem_fptr_impl) { + struct Implicit *impl = (struct Implicit*)data; + if(GET_FLAG(impl->t->e->d.func, member)) { + const Instr pop = emit_add_instr(emit, RegPop); + pop->m_val = SZ_INT; + } + if(impl->t->e->d.func->def->base->tmpl) + fptr_instr(emit, ((Exp)impl->e)->type->e->d.func, 1); + return GW_OK; +} + ANN Type check_exp_unary_spork(const Env env, const Stmt code); static OP_CHECK(opck_spork) { @@ -163,10 +247,10 @@ static OP_CHECK(opck_spork) { if(unary->exp && unary->exp->exp_type == ae_exp_call) return unary->op == op_spork ? t_shred : t_fork; else if(unary->code) { - ++env->scope->depth; \ - nspc_push_value(env->gwion->mp, env->curr); \ + ++env->scope->depth; + nspc_push_value(env->gwion->mp, env->curr); const m_bool ret = check_stmt(env, unary->code); - nspc_pop_value(env->gwion->mp, env->curr); \ + nspc_pop_value(env->gwion->mp, env->curr); --env->scope->depth; CHECK_BO(ret) return unary->op == op_spork ? t_shred : t_fork; @@ -202,6 +286,9 @@ GWION_IMPORT(func) { CHECK_BB(gwi_oper_add(gwi, opck_fptr_cast)) CHECK_BB(gwi_oper_emi(gwi, opem_fptr_cast)) CHECK_BB(gwi_oper_end(gwi, op_cast, NULL)) + CHECK_BB(gwi_oper_add(gwi, opck_fptr_impl)) + CHECK_BB(gwi_oper_emi(gwi, opem_fptr_impl)) + CHECK_BB(gwi_oper_end(gwi, op_impl, NULL)) CHECK_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL)) CHECK_BB(gwi_oper_add(gwi, opck_spork)) CHECK_BB(gwi_oper_emi(gwi, opem_spork)) diff --git a/src/lib/gack.c b/src/lib/gack.c index 71be9ccd2..775a0a09a 100644 --- a/src/lib/gack.c +++ b/src/lib/gack.c @@ -15,7 +15,7 @@ static void print_type(const Type type) { const m_bool is_func = isa(type, t_function) > 0 && isa(type, t_fptr) < 0; const m_str name = is_func ? strdup("@function") : strdup(type->name); gw_out("(%s) ", name); - free(name); + xfree(name); if(GET_FLAG(type, typedef)) { gw_out(" aka "); print_type(type->e->parent); @@ -53,7 +53,7 @@ static inline void print_polar(const m_complex c) { ANN static inline void print_vec(const m_bit* f, const m_uint size) { gw_out("@("); for(m_uint i = 0; i < size; i++) { - print_float(creal(*(m_float*)(f + i * SZ_FLOAT))); + print_float(*(m_float*)(f + i * SZ_FLOAT)); if(i < size - 1) gw_out(", "); } @@ -76,12 +76,14 @@ ANN2(1) static inline void print_object(const Type type, const M_Object obj) { } ANN static inline void print_func(const Type type, const m_bit* stack) { - if(type->e->d.func) { - const VM_Code code = isa(type, t_fptr) > 0 ? - *(VM_Code*)stack : type->e->d.func->code; - gw_out("%s %s %p", type->name, (void*)code ? code->name : NULL, code); - } else - gw_out("%s %p", type->name, NULL); + if(isa(type, t_fptr) > 0 && type->e->d.func->def->base->tmpl) { + const Func f = *(Func*)stack; + gw_out("%s", f ? f->name : "(nil)"); + return; + } + const VM_Code code = isa(type, t_fptr) > 0 ? + *(VM_Code*)stack : type->e->d.func->code; + gw_out("%s %s %p", type->name, (void*)code ? code->name : NULL, code); } ANN static void print_prim(const Type type, const m_bit* stack) { diff --git a/src/lib/instr.c b/src/lib/instr.c index 8529b8cdf..cac9c0403 100644 --- a/src/lib/instr.c +++ b/src/lib/instr.c @@ -58,21 +58,58 @@ INSTR(PopArrayClass) { ADD_REF(obj->type_ref) // add ref to typedef array type } -ANN static Func_Def from_base(const Env env, const struct dottmpl_ *dt, const Type t) { - const Symbol sym = func_symbol(env, t->name, s_name(dt->base->base->xid), - "template", dt->overload); - const Value v = nspc_lookup_value1(t->nspc, sym); +ANN static Func_Def from_base(const Env env, const struct dottmpl_ *dt, const Nspc nspc) { + const Func_Def fdef = dt->def ?: dt->base; + const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid), + "template", dt->vt_index); + const Value v = nspc_lookup_value1(nspc, sym); CHECK_OO(v) const Func_Def base = v->d.func_ref->def; - const Func_Def def = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(env->gwion->st, v->name), - base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->mp, base->pos)); - def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, dt->overload); + const Func_Def def = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, fdef->base->td, insert_symbol(env->gwion->st, v->name), + fdef->base->args), fdef->d.code, fdef->flag, loc_cpy(env->gwion->mp, base->pos)); + def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, dt->vt_index); SET_FLAG(def, template); return def; } +INSTR(GTmpl) { + struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val; + const Func f = *(Func*)REG(-SZ_INT); + const m_str name = f->name; + const Emitter emit = shred->info->vm->gwion->emit; + emit->env->name = "runtime"; + m_str tmpl_name = tl2str(emit->env, dt->tl); + for(m_uint i = 0 ; i <= f->value_ref->offset; ++i) { + const Symbol sym = func_symbol(emit->env, f->value_ref->owner->name, + name, tmpl_name, i); + const Func base = nspc_lookup_func1(f->value_ref->owner, sym); + if(base) { + xfree(tmpl_name); + assert(base->code); + if(GET_FLAG(base->def, static)) + shred->reg -= SZ_INT; + *(VM_Code*)(shred->reg -SZ_INT) = base->code; + return; + } + } + xfree(tmpl_name); + dt->def = f->def; + const Func_Def def = from_base(emit->env, dt, f->value_ref->owner); + if(!def) + Except(shred, "MissigTmplPtrException[internal]"); + dt->def = def; + dt->owner = f->value_ref->owner; + dt->owner_class = f->value_ref->owner_class; + if(traverse_dot_tmpl(emit, dt) > 0) { + if(GET_FLAG(def, static)) + shred->reg -= SZ_INT; + *(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code; + return; + } +} + INSTR(DotTmpl) { - struct dottmpl_ * dt = (struct dottmpl_*)instr->m_val; + struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val; const m_str name = dt->name; const M_Object o = *(M_Object*)REG(-SZ_INT); Type t = o->type_ref; @@ -86,7 +123,7 @@ INSTR(DotTmpl) { if(f) { if(!f->code) { dt->def = f->def;// - dt->owner = t; // + dt->owner_class = t; // if(traverse_dot_tmpl(emit, dt) < 0) continue; } @@ -96,11 +133,11 @@ INSTR(DotTmpl) { shred->reg += SZ_INT; return; } else { - const Func_Def def = from_base(emit->env, dt, t); + const Func_Def def = from_base(emit->env, dt, t->nspc); if(!def) continue; dt->def = def; // - dt->owner = t; // + dt->owner_class = t; // if(traverse_dot_tmpl(emit, dt) > 0) { if(GET_FLAG(def, static)) shred->reg -= SZ_INT; diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index 9d02745fc..b186ea720 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -65,7 +65,8 @@ OP_CHECK(opck_unary_meta2_uniq) { const Exp_Unary* unary = (Exp_Unary*)data; CHECK_OO(opck_unary_meta2(env, data)) if(unary->exp->next) - ERR_N(exp_self(unary)->pos, "fuck!!") + ERR_N(exp_self(unary)->pos, + "'%s' must be applied to a unique expression", op2str(unary->op)) return t_int; } diff --git a/src/lib/prim.c b/src/lib/prim.c index 629c75e1d..e33e05c08 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -12,6 +12,7 @@ #include "emit.h" #include "operator.h" #include "driver.h" +#include "traverse.h" #include "parse.h" #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func) diff --git a/src/main.c b/src/main.c index 4bae78890..af1af971d 100644 --- a/src/main.c +++ b/src/main.c @@ -31,7 +31,7 @@ int main(int argc, char** argv) { Arg arg = { .argc=argc, .argv=argv, .loop=-1 }; signal(SIGINT, sig); signal(SIGTERM, sig); - struct Gwion_ gwion = {}; + struct Gwion_ gwion = { .plug=NULL }; const m_bool ini = gwion_ini(&gwion, &arg); arg_release(&arg); if(/*setjmp(jmp) == 0 && */ini > 0) diff --git a/src/oo/context.c b/src/oo/context.c index a92308501..45695dfc6 100644 --- a/src/oo/context.c +++ b/src/oo/context.c @@ -1,4 +1,5 @@ #include +#include #include "gwion_util.h" #include "gwion_ast.h" #include "oo.h" @@ -10,14 +11,15 @@ ANN static void free_context(const Context a, Gwion gwion) { REM_REF(a->nspc, gwion) + xfree(a->name); mp_free(gwion->mp, Context, a); } ANN2(2) Context new_context(MemPool p, const Ast ast, const m_str str) { const Context context = mp_calloc(p, Context); - context->nspc = new_nspc(p, str); + context->name = strdup(str); + context->nspc = new_nspc(p, context->name); context->tree = ast; - context->name = str; context->ref = new_refcount(p, free_context); return context; } diff --git a/src/oo/switch.c b/src/oo/switch.c index 11a5485c9..888f12a0e 100644 --- a/src/oo/switch.c +++ b/src/oo/switch.c @@ -11,6 +11,7 @@ #include "type.h" #include "context.h" #include "nspc.h" +#include "traverse.h" #include "parse.h" #include "switch.h" diff --git a/src/oo/type.c b/src/oo/type.c index 2c6b0b281..419267147 100644 --- a/src/oo/type.c +++ b/src/oo/type.c @@ -6,14 +6,27 @@ #include "type.h" #include "nspc.h" #include "vm.h" +#include "traverse.h" #include "parse.h" #include "gwion.h" ANN static void free_type(Type a, Gwion gwion) { - if(GET_FLAG(a, template)) + if(GET_FLAG(a, template)) { + if(GET_FLAG(a, union)) { + if(a->e->def->stmt && !GET_FLAG(a, pure)) { // <=> decl_list + UNSET_FLAG(&a->e->def->stmt->d.stmt_union, global); + free_stmt(gwion->mp, a->e->def->stmt); + } + a->e->def->stmt = NULL; + } free_class_def(gwion->mp, a->e->def); + } if(a->nspc) REM_REF(a->nspc, gwion); + if(a->e->contains.ptr) + vector_release(&a->e->contains); +// TODO: commenting this should not happen +// mp_free(gwion->mp, TypeInfo, a->e); mp_free(gwion->mp, Type, a); } diff --git a/src/parse/check.c b/src/parse/check.c index 0c57604ef..118a5924c 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -105,7 +105,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { ERR_O(td_pos(decl->td), "can't infer type."); if(GET_FLAG(decl->type , template)) { if(!GET_FLAG(decl->type, check)) - CHECK_BO(traverse_class_def(env, decl->type->e->def)) + CHECK_BO(traverse_cdef(env, decl->type->e->def)) } const m_bool global = GET_FLAG(decl->td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); @@ -367,6 +367,13 @@ ANN2(1,2) static Func find_func_match_actual(const Env env, Func func, const Exp CHECK_OO(func->next); return find_func_match_actual(env, func->next, args, implicit, specific); } + if(e1->type == t_undefined) { + if(func->value_ref->owner_class) + CHECK_BO(template_push_types(env, func->value_ref->owner_class->e->def->base.tmpl)) + e1->type = known_type(env, e1->td); + if(func->value_ref->owner_class) + nspc_pop_type(env->gwion->mp, env->curr); + } if(func_match_inner(env, e, e1->type, implicit, specific) < 0) break; e = e->next; @@ -394,7 +401,7 @@ ANN static m_bool check_call(const Env env, const Exp_Call* exp) { if(et != ae_exp_primary && et != ae_exp_dot && et != ae_exp_cast) ERR_B(exp->func->pos, "invalid expression for function call.") CHECK_OB(check_exp(env, exp->func)) - return exp->args ? !!check_exp(env, exp->args) : -1; + return exp->args ? !!check_exp(env, exp->args) : GW_OK; } ANN static inline Value template_get_ready(const Env env, const Value v, const m_str tmpl, const m_uint i) { @@ -403,69 +410,111 @@ ANN static inline Value template_get_ready(const Env env, const Value v, const m nspc_lookup_value1(v->owner, sym); } +static Func ensure_tmpl(const Env env, const Func f, const Exp_Call *exp) { + nspc_pop_type(env->gwion->mp, env->curr); + if(check_call(env, exp) > 0) { + const Func next = f->next; + f->next = NULL; + const Func func = find_func_match(env, f, exp->args); + f->next = next; + if(func) { + SET_FLAG(func, checked | ae_flag_template); + return func; + } + } + return NULL; +} +ANN static m_bool check_func_args(const Env env, Arg_List arg_list) { + do { + const Var_Decl decl = arg_list->var_decl; + const Value v = decl->value; + if(arg_list->td && !arg_list->td->xid) + arg_list->type = v->type = check_td(env, arg_list->td); + if(isa(v->type, t_object) > 0 || isa(v->type, t_function) > 0) + UNSET_FLAG(env->func, pure); + CHECK_BB(already_defined(env, decl->xid, decl->pos)) + SET_FLAG(v, checked); + nspc_add_value(env->curr, decl->xid, v); + } while((arg_list = arg_list->next)); + return GW_OK; +} + ANN static Func _find_template_match(const Env env, const Value v, const Exp_Call* exp) { - const Exp args = exp->args; const Type_List types = exp->tmpl->call; - Func m_func = exp->m_func, former = env->func; -if(types->td->types)exit(12); + Func m_func = NULL, former = env->func; const m_str tmpl_name = tl2str(env, types); - const m_uint sz = vector_size((Vector)env->curr->info->type); const m_uint scope = env_push(env, v->owner_class, v->owner); + if(isa(actual_type(v->type), t_fptr) > 0) { + const Symbol sym = func_symbol(env, v->owner->name, v->name, tmpl_name, 0); + const Value value = nspc_lookup_value1(v->owner, sym); + Func_Def base = v->d.func_ref->def; + struct Func_Base_ *fbase = /*value ? value->type->e->d.func->def :*/ + new_func_base(env->gwion->mp, base->base->td, sym, base->base->args); + fbase->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, 0); + fbase->tmpl->call = types; + CHECK_BO(template_push_types(env, fbase->tmpl)) + const Stmt stmt = new_stmt_fptr(env->gwion->mp, fbase, base->flag); + if(value) { + stmt->d.stmt_fptr.type = actual_type(value->type); + stmt->d.stmt_fptr.value = value; + } + CHECK_BO(traverse_stmt_fptr(env, &stmt->d.stmt_fptr)) + free_stmt(env->gwion->mp, stmt); + CHECK_OO((base->base->ret_type = known_type(env, base->base->td))) + if(exp->args) + CHECK_OO(check_exp(env, exp->args)) + const Func func = find_func_match(env, fbase->func, exp->args); + // nspc_pop_type(env->gwion->mp, env->curr); + // env_pop(env, scope); + if(!value) + map_set(&v->owner->info->type->map, (vtype)sym, (vtype)actual_type(func->value_ref->type)); + xfree(tmpl_name); + env->func = former; + return func; + } for(m_uint i = 0; i < v->offset + 1; ++i) { - Func_Def def = NULL; + Func_Def fdef = NULL; Func_Def base = NULL; Value value = template_get_ready(env, v, tmpl_name, i); if(value) { if(env->func == value->d.func_ref) { - free(tmpl_name); CHECK_BO(check_call(env, exp)) - return env->func; + m_func = env->func; + break; } - base = def = value->d.func_ref->def; - if(!def->base->tmpl) { + base = fdef = value->d.func_ref->def; + if(!fdef->base->tmpl) { if(!(value = template_get_ready(env, v, "template", i))) continue; base = value->d.func_ref->def; - def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); + fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); } } else { if(!(value = template_get_ready(env, v, "template", i))) continue; base = value->d.func_ref->def; - def = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(v->name), + fdef = new_func_def(env->gwion->mp, new_func_base(env->gwion->mp, base->base->td, insert_symbol(v->name), base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->mp, base->pos)); - def->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); - SET_FLAG(def, template); + fdef->base->tmpl = new_tmpl(env->gwion->mp, base->base->tmpl->list, (m_int)i); + SET_FLAG(fdef, template); } - def->base->tmpl->call = types; - if(traverse_func_template(env, def) > 0) { - nspc_pop_type(env->gwion->mp, env->curr); - if(check_call(env, exp) > 0) { - const Func next = def->base->func->next; - def->base->func->next = NULL; - m_func = find_func_match(env, def->base->func, args); - def->base->func->next = next; - if(m_func) { - SET_FLAG(m_func, checked | ae_flag_template); - goto end; - } - } - } - if(sz != vector_size((Vector)env->curr->info->type)) - nspc_pop_type(env->gwion->mp, env->curr); - SET_FLAG(base, template); + fdef->base->tmpl->call = types; + if(traverse_func_template(env, fdef) > 0 && + (m_func = ensure_tmpl(env, fdef->base->func, exp))) + break; } -end: - free(tmpl_name); + xfree(tmpl_name); env_pop(env, scope); env->func = former; return m_func; } + ANN Func find_template_match(const Env env, const Value value, const Exp_Call* exp) { Type t = value->owner_class; const Func f = _find_template_match(env, value, exp); - if(f) + if(f) { return f; + } while(t) { Value v = nspc_lookup_value1(t->nspc, value->d.func_ref->def->base->xid); if(!v) @@ -943,6 +992,8 @@ ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) { } ANN m_bool check_stmt_union(const Env env, const Stmt_Union stmt) { + if(stmt->tmpl) + return GW_OK; if(stmt->xid) { if(env->class_def) (!GET_FLAG(stmt, static) ? decl_member : decl_static)(env->curr, stmt->value); @@ -959,8 +1010,9 @@ ANN m_bool check_stmt_union(const Env env, const Stmt_Union stmt) { do { CHECK_OB(check_exp(env, l->self)) if(isa(l->self->type, t_object) > 0) { - if(!GET_FLAG(l->self->d.exp_decl.td, ref)) + if(!GET_FLAG(l->self->d.exp_decl.td, ref) && !GET_FLAG(stmt->type, template)) ERR_B(l->self->pos, "In union, Objects must be declared as reference (use '@')") +// SET_FLAG(l->self->d.exp_decl.td, ref); Var_Decl_List list = l->self->d.exp_decl.list; do SET_FLAG(list->self->value, pure); while((list = list->next)); @@ -995,29 +1047,29 @@ ANN static m_bool check_stmt_list(const Env env, Stmt_List l) { return GW_OK; } -ANN static m_bool check_signature_match(const Env env, const Func_Def f, const Func parent) { - if(GET_FLAG(parent->def, static) != GET_FLAG(f, static)) { - const m_str c_name = f->base->func->value_ref->owner_class->name; +ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) { + if(GET_FLAG(parent->def, static) != GET_FLAG(fdef, static)) { + const m_str c_name = fdef->base->func->value_ref->owner_class->name; const m_str p_name = parent->value_ref->owner_class->name; - const m_str f_name = s_name(f->base->xid); - ERR_B(td_pos(f->base->td), + const m_str f_name = s_name(fdef->base->xid); + ERR_B(td_pos(fdef->base->td), "function '%s.%s' ressembles '%s.%s' but cannot override...\n" "\t...(reason: '%s.%s' is declared as 'static')", c_name, f_name, p_name, c_name, - GET_FLAG(f, static) ? c_name : p_name, f_name) + GET_FLAG(fdef, static) ? c_name : p_name, f_name) } - return !f->base->tmpl ? isa(f->base->ret_type, parent->def->base->ret_type) : GW_OK; + return !fdef->base->tmpl ? isa(fdef->base->ret_type, parent->def->base->ret_type) : GW_OK; } -ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f, +ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def fdef, const restrict Func func) { Func parent_func = func; do { - if(compat_func(f, parent_func->def) > 0) { - CHECK_BB(check_signature_match(env, f, parent_func)) - if(!f->base->tmpl) { - f->base->func->vt_index = parent_func->vt_index; - vector_set(&env->curr->info->vtable, f->base->func->vt_index, (vtype)f->base->func); + if(compat_func(fdef, parent_func->def) > 0) { + CHECK_BB(check_signature_match(env, fdef, parent_func)) + if(!fdef->base->tmpl) { + fdef->base->func->vt_index = parent_func->vt_index; + vector_set(&env->curr->info->vtable, fdef->base->func->vt_index, (vtype)fdef->base->func); } return GW_OK; } @@ -1025,13 +1077,13 @@ ANN static m_bool parent_match_actual(const Env env, const restrict Func_Def f, return 0; } -ANN static m_bool check_parent_match(const Env env, const Func_Def f) { - const Func func = f->base->func; +ANN static m_bool check_parent_match(const Env env, const Func_Def fdef) { + const Func func = fdef->base->func; const Type parent = env->class_def->e->parent; if(parent) { - const Value v = find_value(parent, f->base->xid); + const Value v = find_value(parent, fdef->base->xid); if(v && isa(v->type, t_function) > 0) { - const m_bool match = parent_match_actual(env, f, v->d.func_ref); + const m_bool match = parent_match_actual(env, fdef, v->d.func_ref); if(match) return match; } @@ -1043,52 +1095,37 @@ ANN static m_bool check_parent_match(const Env env, const Func_Def f) { return GW_OK; } -ANN static m_bool check_func_args(const Env env, Arg_List arg_list) { - do { - const Var_Decl decl = arg_list->var_decl; - const Value v = decl->value; - if(arg_list->td && !arg_list->td->xid) - arg_list->type = v->type = check_td(env, arg_list->td); - if(isa(v->type, t_object) > 0 || isa(v->type, t_function) > 0) - UNSET_FLAG(env->func, pure); - CHECK_BB(already_defined(env, decl->xid, decl->pos)) - SET_FLAG(v, checked); - nspc_add_value(env->curr, decl->xid, v); - } while((arg_list = arg_list->next)); - return GW_OK; -} - -ANN static inline Func get_overload(const Env env, const Func_Def def, const m_uint i) { - const Symbol sym = func_symbol(env, env->curr->name, s_name(def->base->xid), NULL, i); +ANN static inline Func get_overload(const Env env, const Func_Def fdef, const m_uint i) { + const Symbol sym = func_symbol(env, env->curr->name, s_name(fdef->base->xid), NULL, i); return nspc_lookup_func1(env->curr, sym); } -ANN static m_bool check_func_overload(const Env env, const Func_Def f) { - const Value v = f->base->func->value_ref; +ANN static m_bool check_func_overload(const Env env, const Func_Def fdef) { + const Value v = fdef->base->func->value_ref; for(m_uint i = 0; i <= v->offset; ++i) { - const Func f1 = get_overload(env, f, i); + const Func f1 = get_overload(env, fdef, i); for(m_uint j = i + 1; f1 && j <= v->offset; ++j) { - const Func f2 = get_overload(env, f, j); + const Func f2 = get_overload(env, fdef, j); if(f2 && compat_func(f1->def, f2->def) > 0) ERR_B(td_pos(f2->def->base->td), "global function '%s' already defined" - " for those arguments", s_name(f->base->xid)) + " for those arguments", s_name(fdef->base->xid)) } } return GW_OK; } -ANN static m_bool check_func_def_override(const Env env, const Func_Def f) { - const Func func = f->base->func; +ANN static m_bool check_func_def_override(const Env env, const Func_Def fdef) { + const Func func = fdef->base->func; if(env->class_def && env->class_def->e->parent) { - const Value override = find_value(env->class_def->e->parent, f->base->xid); + const Value override = find_value(env->class_def->e->parent, fdef->base->xid); if(override && override->owner_class && isa(override->type, t_function) < 0) - ERR_B(f->pos, + ERR_B(fdef->pos, "function name '%s' conflicts with previously defined value...\n" "\tfrom super class '%s'...", - s_name(f->base->xid), override->owner_class->name) + s_name(fdef->base->xid), override->owner_class->name) } - if(func->value_ref->offset && (!f->base->tmpl || !f->base->tmpl->base)) - CHECK_BB(check_func_overload(env, f)) + if(func->value_ref->offset && (!fdef->base->tmpl || !fdef->base->tmpl->base)) + CHECK_BB(check_func_overload(env, fdef)) return GW_OK; } @@ -1109,43 +1146,44 @@ ANN static void operator_func(const Func f) { operator_set_func(&opi); } -ANN m_bool check_func_def(const Env env, const Func_Def f) { - const Func func = get_func(env, f); +ANN m_bool check_func_def(const Env env, const Func_Def fdef) { + const Func func = get_func(env, fdef); m_bool ret = GW_OK; - if(tmpl_base(f->base->tmpl)) - return env->class_def ? check_parent_match(env, f) : 1; - if(f->base->td && !f->base->td->xid) { - f->base->ret_type = check_td(env, f->base->td); - return traverse_func_def(env, f); + if(tmpl_base(fdef->base->tmpl)) + return env->class_def ? check_parent_match(env, fdef) : 1; + if(fdef->base->td && !fdef->base->td->xid) { + fdef->base->ret_type = check_td(env, fdef->base->td); + return traverse_func_def(env, fdef); } - CHECK_BB(check_func_def_override(env, f)) + CHECK_BB(check_func_def_override(env, fdef)) if(env->class_def) - CHECK_BB(check_parent_match(env, f)) - else if(GET_FLAG(f, global)) + CHECK_BB(check_parent_match(env, fdef)) + else if(GET_FLAG(fdef, global)) env_push_global(env); const Func former = env->func; env->func = func; ++env->scope->depth; nspc_push_value(env->gwion->mp, env->curr); - if(!f->base->args) - UNSET_FLAG(f->base->func, pure); + if(!fdef->base->args) + UNSET_FLAG(fdef->base->func, pure); else - ret = check_func_args(env, f->base->args); + ret = check_func_args(env, fdef->base->args); if(ret > 0) { - const Value variadic = GET_FLAG(f, variadic) ? set_variadic(env) : NULL; - if(!GET_FLAG(f, builtin) && check_stmt_code(env, &f->d.code->d.stmt_code) < 0) + const Value variadic = GET_FLAG(fdef, variadic) ? set_variadic(env) : NULL; + if(!GET_FLAG(fdef, builtin) && fdef->d.code && + check_stmt_code(env, &fdef->d.code->d.stmt_code) < 0) ret = GW_ERROR; if(variadic) REM_REF(variadic, env->gwion) - if(GET_FLAG(f, builtin)) - func->code->stack_depth = f->stack_depth; - else if(GET_FLAG(f, op)) + if(GET_FLAG(fdef, builtin)) + func->code->stack_depth = fdef->stack_depth; + else if(GET_FLAG(fdef, op)) operator_func(func); } nspc_pop_value(env->gwion->mp, env->curr); --env->scope->depth; env->func = former; - if(GET_FLAG(f, global)) + if(GET_FLAG(fdef, global)) env_push_global(env); return ret; } @@ -1157,7 +1195,8 @@ ANN static m_bool check_class_parent(const Env env, const Class_Def cdef) { const Type_Decl *td = cdef->base.ext; if(td->array) CHECK_BB(check_exp_array_subscripts(env, td->array->exp)) - CHECK_BB(scanx_parent(parent, traverse_class_def, env)) + if(parent->e->def) + CHECK_BB(scanx_parent(parent, traverse_class_def, env)) if(GET_FLAG(parent, typedef)) SET_FLAG(cdef->base.type, typedef); return GW_OK; @@ -1176,7 +1215,7 @@ ANN m_bool check_class_def(const Env env, const Class_Def cdef) { const Type type = cdef->base.type; if(type->e->parent == t_undefined) { type->e->parent = check_td(env, cdef->base.ext); - return traverse_class_def(env, cdef); + return traverse_cdef(env, cdef); } if(cdef->base.ext) CHECK_BB(env_ext(env, cdef, check_class_parent)) diff --git a/src/parse/operator.c b/src/parse/operator.c index a29062bbc..f765fcf1b 100644 --- a/src/parse/operator.c +++ b/src/parse/operator.c @@ -211,22 +211,24 @@ ANN static Nspc get_nspc(const struct Op_Import* opi) { } ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) { - const Nspc nspc = get_nspc(opi); - Type l = opi->lhs; + Nspc nspc = get_nspc(opi); do { - Type r = opi->rhs; + Type l = opi->lhs; do { - if(!nspc->info->op_map.ptr) - continue; - const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op); - const M_Operator* mo = operator_find(v, l, r); - if(mo) { - if(mo->em) - return mo->em(emit, (void*)opi->data); - return handle_instr(emit, mo); - } - } while(r && (r = op_parent(emit->env, r))); - } while(l && (l = op_parent(emit->env, l))); + Type r = opi->rhs; + do { + if(!nspc->info->op_map.ptr) + continue; + const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op); + const M_Operator* mo = operator_find(v, l, r); + if(mo) { + if(mo->em) + return mo->em(emit, (void*)opi->data); + return handle_instr(emit, mo); + } + } while(r && (r = op_parent(emit->env, r))); + } while(l && (l = op_parent(emit->env, l))); + } while((nspc = nspc->parent)); // probably deserves err_msg here return GW_ERROR; } diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 10ac80694..fc56c533c 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -8,9 +8,9 @@ #include "func.h" #include "nspc.h" #include "vm.h" -#include "parse.h" #include "traverse.h" #include "template.h" +#include "parse.h" ANN static Value mk_class(const Env env, const Type base) { const Type t = type_copy(env->gwion->mp, t_class); @@ -113,6 +113,8 @@ ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { CHECK_BB(env_storage(env, stmt->flag, stmt_self(stmt)->pos)) + const m_uint scope = !GET_FLAG(stmt, global) ? env->scope->depth : + env_push_global(env); if(stmt->xid) { CHECK_BB(scan0_defined(env, stmt->xid, stmt_self(stmt)->pos)) const Nspc nspc = !GET_FLAG(stmt, global) ? @@ -131,6 +133,7 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { if(!stmt->type_xid) SET_FLAG(t, op); } else if(stmt->type_xid) { + CHECK_BB(scan0_defined(env, stmt->type_xid, stmt_self(stmt)->pos)) const Nspc nspc = !GET_FLAG(stmt, global) ? env->curr : env->global_nspc; stmt->type = union_type(env, nspc, stmt->type_xid, 1); @@ -144,8 +147,23 @@ ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { stmt->value->owner = nspc; nspc_add_value(nspc, stmt->xid, stmt->value); SET_FLAG(stmt->value, checked | stmt->flag); - } + if(stmt->tmpl) { + if(tmpl_base(stmt->tmpl)) { + const Class_Def cdef = new_class_def(env->gwion->mp, stmt->flag, stmt->type_xid, + NULL, (Class_Body)stmt->l, stmt_self(stmt)->pos); + stmt->type->e->def = cdef; + cdef->base.tmpl = stmt->tmpl; + cdef->base.type = stmt->type; + cdef->list = stmt->l; + SET_FLAG(stmt->type, pure); + SET_FLAG(stmt, template); + SET_FLAG(stmt->type, template); + } + SET_FLAG(stmt->type, union); + } + if(GET_FLAG(stmt, global)) + env_pop(env, scope); return GW_OK; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 88ae8fca8..106390d07 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -5,11 +5,11 @@ #include "type.h" #include "nspc.h" #include "value.h" -#include "optim.h" +#include "func.h" #include "vm.h" -#include "parse.h" #include "traverse.h" #include "template.h" +#include "parse.h" ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list); ANN static m_bool scan1_stmt(const Env env, Stmt stmt); @@ -22,28 +22,51 @@ ANN static Type void_type(const Env env, const Type_Decl* td) { ERR_O(td_pos(td), "cannot declare variables of size '0' (i.e. 'void')...") } + +ANN static inline Type get_base_type(const Env env, const Type t) { + const m_str decl_name = get_type_name(env, t->name, 0); + return nspc_lookup_type1(env->curr, insert_symbol(decl_name)); +} + +ANN static m_bool type_recursive(const Env env, Exp_Decl* decl, const Type t) { + const Type decl_base = get_base_type(env, t); + const Type base = get_base_type(env, env->class_def); + if(decl_base && base) { + if(!base->e->contains.ptr) + vector_init(&base->e->contains); + vector_add(&base->e->contains, (vtype)decl_base); + if(decl_base->e->contains.ptr) { + for(m_uint i = 0; i < vector_size(&decl_base->e->contains); ++i) { + if(base == (Type)vector_at(&decl_base->e->contains, i) && !GET_FLAG(decl->td, ref)) + ERR_B(exp_self(decl)->pos, "%s declared inside %s\n. (make it a ref ?)", + decl_base->name, decl_base == base ? "itself" : base->name); + } + } + } + return GW_OK; +} + ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) { const Type t = void_type(env, decl->td); CHECK_OO(t); if(decl->td->xid && decl->td->xid->xid == insert_symbol("auto") && decl->type) return decl->type; + if(!env->scope->depth && env->class_def) { + if(isa(t, t_object) > 0) + CHECK_BO(type_recursive(env, decl, t)) + if(!GET_FLAG(decl->td, static)) + SET_FLAG(decl->td, member); + } if(GET_FLAG(t, abstract) && !GET_FLAG(decl->td, ref)) ERR_O(exp_self(decl)->pos, "Type '%s' is abstract, declare as ref. (use @)", t->name) if(GET_FLAG(t, private) && t->e->owner != env->curr) ERR_O(exp_self(decl)->pos, "can't use private type %s", t->name) if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0)) ERR_O(exp_self(decl)->pos, "can't use protected type %s", t->name) - if(env->class_def) { - if(!env->scope->depth) { - if(!env->func && !GET_FLAG(decl->td, static)) - SET_FLAG(decl->td, member); - if(!GET_FLAG(decl->td, ref) && t == env->class_def) - ERR_O(exp_self(decl)->pos, "...(note: object of type '%s' declared inside itself)", t->name) - } - } decl->base = t->e->def; return decl->type = t; } + ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos)) Var_Decl_List list = decl->list; @@ -53,10 +76,10 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { const m_uint scope = !global ? env->scope->depth : env_push_global(env); const Nspc nspc = !global ? env->curr : env->global_nspc; do { - Type t = decl->type; const Var_Decl var = list->self; - const Value former = nspc_lookup_value0(env->curr, var->xid); CHECK_BB(isres(env, var->xid, exp_self(decl)->pos)) + Type t = decl->type; + const Value former = nspc_lookup_value0(env->curr, var->xid); if(former && !decl->td->exp && (!env->class_def || !(GET_FLAG(env->class_def, template) || GET_FLAG(env->class_def, scan1)))) ERR_B(var->pos, "variable %s has already been defined in the same scope...", @@ -65,17 +88,17 @@ ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { if(var->array->exp) { if(GET_FLAG(decl->td, ref)) ERR_B(td_pos(decl->td), "ref array must not have array expression.\n" - "e.g: int @my_array[];\nnot: int my_array[2];") + "e.g: int @my_array[];\nnot: @int my_array[2];") CHECK_BB(scan1_exp(env, var->array->exp)) } t = array_type(env, decl->type, var->array->depth); } - const Value v = var->value = former ? former : new_value(env->gwion->mp, t, s_name(var->xid)); + const Value v = var->value = former ?: new_value(env->gwion->mp, t, s_name(var->xid)); nspc_add_value(nspc, var->xid, v); v->flag = decl->td->flag; if(var->array && !var->array->exp) SET_FLAG(v, ref); - if(!env->func && !env->scope->depth && !env->class_def) + if(!env->scope->depth && !env->class_def) SET_FLAG(v, global); v->type = t; v->d.ptr = var->addr; @@ -137,9 +160,8 @@ ANN static m_bool scan1_exp_if(const Env env, const Exp_If* exp_if) { } ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) { - if((unary->op == op_spork || unary->op == op_fork) && unary->code) { - RET_NSPC(scan1_stmt(env, unary->code)) - } + if((unary->op == op_spork || unary->op == op_fork) && unary->code) + { RET_NSPC(scan1_stmt(env, unary->code)) } return unary->exp ? scan1_exp(env, unary->exp) : GW_OK; } @@ -168,9 +190,8 @@ describe_ret_nspc(if, Stmt_If,, !(scan1_exp(env, stmt->cond) < 0 || (stmt->else_body && scan1_stmt(env, stmt->else_body) < 0)) ? 1 : -1) ANN static inline m_bool scan1_stmt_code(const Env env, const Stmt_Code stmt) { - if(stmt->stmt_list) { - RET_NSPC(scan1_stmt_list(env, stmt->stmt_list)) - } + if(stmt->stmt_list) + { RET_NSPC(scan1_stmt_list(env, stmt->stmt_list)) } return GW_OK; } @@ -201,7 +222,7 @@ ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) { } while((list = list->next)); return GW_OK; } -#include "func.h" + ANN static m_bool scan1_args(const Env env, Arg_List list) { do { const Var_Decl var = list->var_decl; @@ -227,6 +248,8 @@ ANN m_bool scan1_stmt_type(const Env env, const Stmt_Type stmt) { } ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) { + if(stmt->tmpl) + return GW_OK; if(!stmt->value) CHECK_BB(scan0_stmt_union(env, stmt)) Decl_List l = stmt->l; @@ -288,19 +311,19 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td))) if(tmpl_base(fdef->base->tmpl)) return GW_OK; + if(GET_FLAG(fdef, dtor) && !env->class_def) + ERR_B(td_pos(fdef->base->td), "dtor must be in class def!!") + if(GET_FLAG(fdef, op) && env->class_def) + SET_FLAG(fdef, static); struct Func_ fake = { .name=s_name(fdef->base->xid) }, *const former = env->func; env->func = &fake; ++env->scope->depth; - if(GET_FLAG(fdef, dtor) && !env->class_def) - ERR_B(td_pos(fdef->base->td), "dtor must be in class def!!") if(fdef->base->td) CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td))) if(fdef->base->args) CHECK_BB(scan1_args(env, fdef->base->args)) - if(!GET_FLAG(fdef, builtin)) + if(!GET_FLAG(fdef, builtin) && fdef->d.code) CHECK_BB(scan1_stmt_code(env, &fdef->d.code->d.stmt_code)) - if(GET_FLAG(fdef, op) && env->class_def) - SET_FLAG(fdef, static); env->func = former; --env->scope->depth; return GW_OK; @@ -315,14 +338,14 @@ ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) { const Type parent = cdef->base.type->e->parent = known_type(env, cdef->base.ext); CHECK_OB(parent) Type t = parent; - while(t) { + do { if(cdef->base.type == t) ERR_B(pos, "recursive (%s <= %s) class declaration.", cdef->base.type->name, t->name); - t = t->e->parent; - } + } while((t = t->e->parent)); if(isa(parent, t_object) < 0) ERR_B(pos, "cannot extend primitive type '%s'", parent->name) - CHECK_BB(scanx_parent(parent, scan1_class_def, env)) + if(parent->e->def) + CHECK_BB(scanx_parent(parent, scan1_class_def, env)) if(type_ref(parent)) ERR_B(pos, "can't use ref type in class extend") return GW_OK; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 254967f1b..7fba103e1 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -8,35 +8,33 @@ #include "value.h" #include "func.h" #include "template.h" +#include "traverse.h" #include "optim.h" #include "parse.h" #include "nspc.h" #include "operator.h" -ANN /* static */ m_bool scan2_exp(const Env, const Exp); +//ANN /* static */ m_bool scan2_exp(const Env, const Exp); ANN static m_bool scan2_stmt(const Env, const Stmt); ANN static m_bool scan2_stmt_list(const Env, Stmt_List); -extern ANN m_bool scan1_class_def(const Env, const Class_Def); -ANN m_bool scan2_class_def(const Env, const Class_Def); ANN static m_bool scan2_exp_decl_template(const Env env, const Exp_Decl* decl) { - CHECK_BB(scan1_class_def(env, decl->type->e->def)) - CHECK_BB(scan2_class_def(env, decl->type->e->def)) - return GW_OK; + CHECK_BB(scan1_cdef(env, decl->type->e->def)) + return scan2_cdef(env, decl->type->e->def); } ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { - Var_Decl_List list = decl->list; + const m_bool global = GET_FLAG(decl->td, global); + const m_uint scope = !global ? env->scope->depth : env_push_global(env); const Type type = decl->type; if(GET_FLAG(type, template) && !GET_FLAG(type, scan2)) CHECK_BB(scan2_exp_decl_template(env, decl)) - const m_bool global = GET_FLAG(decl->td, global); - const m_uint scope = !global ? env->scope->depth : env_push_global(env); + Var_Decl_List list = decl->list; do { const Var_Decl var = list->self; - const Array_Sub array = var->array; - if(array && array->exp) - CHECK_BB(scan2_exp(env, array->exp)) + const Exp array = var->array ? var->array->exp : NULL; + if(array) + CHECK_BB(scan2_exp(env, array)) nspc_add_value(env->curr, var->xid, var->value); } while((list = list->next)); if(global) @@ -93,6 +91,7 @@ ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr ptr) { ptr->value->d.func_ref = ptr->base->func; ptr->base->func->value_ref = ptr->value; ptr->type->e->d.func = ptr->base->func; + def->base->tmpl = ptr->base->tmpl; SET_FLAG(ptr->value, func | ae_flag_checked); if(ptr->base->args) CHECK_BB(scan2_args(env, def)) @@ -270,6 +269,8 @@ ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) { } ANN m_bool scan2_stmt_union(const Env env, const Stmt_Union stmt) { + if(stmt->tmpl) + return GW_OK; const m_uint scope = union_push(env, stmt); Decl_List l = stmt->l; do CHECK_BB(scan2_exp(env, l->self)) @@ -300,8 +301,10 @@ ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) { ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) { const m_bool base = tmpl_base(f->base->tmpl); const m_bool tmpl = GET_FLAG(overload, template); - if(isa(overload->type, t_function) < 0 || isa(overload->type, t_fptr) > 0) + if(isa(overload->type, t_function) < 0 || isa(overload->type, t_fptr) > 0) { + if(isa(actual_type(overload->type), t_function) < 0) ERR_B(f->pos, "function name '%s' is already used by another value", overload->name) +} if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f, template))) ERR_B(f->pos, "must overload template function with template") return GW_OK; @@ -386,6 +389,7 @@ ANN2(1, 2) static m_bool scan2_func_def_template(const Env env, const Func_Def f func->vt_index = i; ADD_REF(value) nspc_add_value(env->curr, f->base->xid, value); + nspc_add_func(env->curr, f->base->xid, func); } else func->vt_index = ++overload->offset; return GW_OK; @@ -450,7 +454,7 @@ ANN static m_str func_tmpl_name(const Env env, const Func_Def f) { vector_add(&v, (vtype)t); tlen += strlen(t->name); } while((id = id->next) && ++tlen); - char tmpl_name[tlen + 1]; + char tmpl_name[tlen + 2]; m_str str = tmpl_name; for(m_uint i = 0; i < vector_size(&v); ++i) { const m_str s = ((Type)vector_at(&v, i))->name; @@ -466,7 +470,7 @@ ANN static m_str func_tmpl_name(const Env env, const Func_Def f) { } -ANN2(1,2,4) static Value func_create(const Env env, const Func_Def f, +ANN2(1,2,4) /*static */Value func_create(const Env env, const Func_Def f, const Value overload, const m_str name) { const Func func = scan_new_func(env, f, name); nspc_add_func(env->curr, insert_symbol(func->name), func); @@ -530,7 +534,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) { // body if(f->base->args) CHECK_BB(scan2_args(env, f)) - if(!GET_FLAG(f, builtin) && f->d.code->d.stmt_code.stmt_list) + if(!GET_FLAG(f, builtin) && f->d.code) CHECK_BB(scan2_func_def_code(env, f)) // gpop if(GET_FLAG(f, global)) @@ -548,7 +552,8 @@ DECL_SECTION_FUNC(scan2) ANN static m_bool scan2_class_parent(const Env env, const Class_Def cdef) { const Type parent = cdef->base.type->e->parent; - CHECK_BB(scanx_parent(parent, scan2_class_def, env)) + if(parent->e->def) + CHECK_BB(scanx_parent(parent, scan2_cdef, env)) if(cdef->base.ext->array) CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp)) return GW_OK; diff --git a/src/parse/scanx.c b/src/parse/scanx.c index e722b0869..492478faf 100644 --- a/src/parse/scanx.c +++ b/src/parse/scanx.c @@ -6,8 +6,9 @@ #include "type.h" #include "nspc.h" #include "vm.h" -#include "parse.h" #include "template.h" +#include "traverse.h" +#include "parse.h" ANN static inline m_bool _body(const Env e, Class_Body b, const _exp_func f) { do CHECK_BB(f(e, b->section)) @@ -24,10 +25,10 @@ ANN static inline m_bool tmpl_push(const Env env, const Tmpl* tmpl) { } ANN static inline m_int _push(const Env env, const Class_Def c) { - const m_uint scope = env_push_type(env, c->base.type); - if(c->base.tmpl && !tmpl_push(env, c->base.tmpl)) - return GW_ERROR; - return scope; + const m_int scope = env_push_type(env, c->base.type); + CHECK_BB(scope) + return (!c->base.tmpl || tmpl_push(env, c->base.tmpl)) ? + scope : GW_ERROR; } ANN static inline void _pop(const Env e, const Class_Def c, const m_uint s) { @@ -36,6 +37,7 @@ ANN static inline void _pop(const Env e, const Class_Def c, const m_uint s) { env_pop(e, s); } +// TODO: 'v' should be 2° argument ANN m_bool scanx_body(const Env e, const Class_Def c, const _exp_func f, void* d) { const m_int scope = _push(e, c); @@ -67,27 +69,18 @@ static inline Class_Def get_type_def(const Type t) { ANN m_bool scanx_parent(const Type t, const _exp_func f, void* d) { + if(t->e->parent == t_union) + return GW_OK; const Class_Def def = get_type_def(t); return def ? f(d, def) : GW_OK; } -/* -struct Parent_ { - void* ptr; - const Type t; - m_bool (*f)(void*, void*); - const ae_flag flag; -}; -ANN m_bool scanx_parent_actual(void* ptr, const Type t, m_bool (*f)(void*, void*), const ae_flag flag) { - if(t->e->def && (t->flag & flag) != flag) - return f(ptr, t->e->def); - return GW_OK; -} -ANN m_bool scanx_parent(void* ptr, const Type t, m_bool (*f)(void*, void*), const ae_flag flag) { - if(t->array_depth) - CHECK_BB(f(ptr, array_base(t))) - else - CHECK_BB(f(ptr, t)) - return GW_OK; +ANN m_bool scanx_cdef(const Env env, void* opt, const Class_Def cdef, + const _exp_func f_cdef, const _exp_func f_union) { + if(cdef->base.type->e->parent != t_union) + return f_cdef(opt, cdef); + CHECK_BB(template_push_types(env, cdef->base.tmpl)) + const m_bool ret = f_union(opt, &cdef->stmt->d.stmt_union); + nspc_pop_type(env->gwion->mp, env->curr); + return ret; } -*/ diff --git a/src/parse/template.c b/src/parse/template.c index f2511a586..081a4bd65 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -6,6 +6,7 @@ #include "env.h" #include "type.h" #include "nspc.h" +#include "traverse.h" #include "template.h" #include "vm.h" #include "parse.h" @@ -70,9 +71,13 @@ ANN static inline size_t tmpl_set(struct tmpl_info* info, const Type t) { ANN static size_t template_size(const Env env, struct tmpl_info* info) { ID_List base = info->cdef->base.tmpl->list; + Type_List call = info->call; size_t size = tmpl_set(info, info->cdef->base.type); - do size += tmpl_set(info, type_decl_resolve(env, info->call->td)); - while((info->call = info->call->next) && (base = base->next) && ++size); + do { + const Type t = type_decl_resolve(env, call->td); + CHECK_OB(t) + size += tmpl_set(info, t); + } while((call = call->next) && (base = base->next) && ++size); return size + 16 + 3; } @@ -82,7 +87,7 @@ ANN static inline m_str tmpl_get(struct tmpl_info* info, m_str str) { return str += vector_at(&info->size, info->index); } -ANN static void template_name(const Env env, struct tmpl_info* info, m_str s) { +ANN static void template_name(struct tmpl_info* info, m_str s) { m_str str = s; str = tmpl_get(info, str); *str++ = '<'; @@ -91,10 +96,7 @@ ANN static void template_name(const Env env, struct tmpl_info* info, m_str s) { str = tmpl_get(info, str); *str++ = (info->index < size - 1) ? ',' : '>'; } - if(info->cdef->base.type->e->owner == env->global_nspc) - sprintf(str, "%p", (void*)env->curr); - else - *str = '\0'; + *str = '\0'; } ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) { @@ -102,7 +104,7 @@ ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_ vector_init(&info.type); vector_init(&info.size); char name[template_size(env, &info)]; - template_name(env, &info, name); + template_name(&info, name); vector_release(&info.type); vector_release(&info.size); return insert_symbol(name); @@ -115,6 +117,8 @@ ANN m_bool template_match(ID_List base, Type_List call) { ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) { const Symbol name = template_id(env, def, call); + if(env->class_def && name == insert_symbol(env->class_def->name)) + return env->class_def->e->def; const Type t = nspc_lookup_type1(env->curr, name); return t ? t->e->def : new_class_def(env->gwion->mp, def->flag, name, def->base.ext, def->body, loc_cpy(env->gwion->mp, def->pos)); @@ -158,19 +162,28 @@ ANN Type scan_type(const Env env, const Type t, const Type_Decl* type) { return a->base.type; a->base.tmpl = new_tmpl(env->gwion->mp, get_total_type_list(env, t), 0); a->base.tmpl->call = type->types; - - CHECK_BO(scan0_class_def(env, a)) + if(isa(t, t_union) < 0) { + CHECK_BO(scan0_class_def(env, a)) + map_set(&t->e->owner->info->type->map, (vtype)insert_symbol(a->base.type->name), + (vtype)a->base.type); + } else { + a->stmt = new_stmt_union(env->gwion->mp, (Decl_List)a->body, t->e->def->pos); + a->stmt->d.stmt_union.type_xid = a->base.xid; + CHECK_BO(scan0_stmt_union(env, &a->stmt->d.stmt_union)) + a->base.type = a->stmt->d.stmt_union.type; + a->base.type->e->def = a; + SET_FLAG(a, union); + } SET_FLAG(a->base.type, template | ae_flag_ref); a->base.type->e->owner = t->e->owner; if(GET_FLAG(t, builtin)) SET_FLAG(a->base.type, builtin); - CHECK_BO(scan1_class_def(env, a)) + CHECK_BO(scan1_cdef(env, a)) if(t->nspc->dtor) { a->base.type->nspc->dtor = t->nspc->dtor; SET_FLAG(a->base.type, dtor); ADD_REF(t->nspc->dtor) } - nspc_add_type(t->e->owner, insert_symbol(a->base.type->name), a->base.type); return a->base.type; } else if(type->types) ERR_O(type->xid->pos, diff --git a/src/parse/traverse.c b/src/parse/traverse.c index 637d93e3b..00ee4ce5b 100644 --- a/src/parse/traverse.c +++ b/src/parse/traverse.c @@ -40,7 +40,7 @@ ANN m_bool traverse_stmt_enum(const Env env, const Stmt_Enum def) { } ANN m_bool traverse_stmt_fptr(const Env env, const Stmt_Fptr def) { - CHECK_BB(scan0_stmt_fptr(env, def)) +// CHECK_BB(scan0_stmt_fptr(env, def)) CHECK_BB(scan1_stmt_fptr(env, def)) return scan2_stmt_fptr(env, def); // CHECK_BB(check_stmt_fptr(env, def)) diff --git a/src/parse/traverse_template.c b/src/parse/traverse_template.c index 8b32476fe..1a49596a1 100644 --- a/src/parse/traverse_template.c +++ b/src/parse/traverse_template.c @@ -10,5 +10,8 @@ ANN m_bool traverse_func_template(const Env env, const Func_Def def) { CHECK_BB(template_push_types(env, def->base->tmpl)) - return traverse_func_def(env, def); + if(traverse_func_def(env, def) > 0) + return GW_OK; + nspc_pop_type(env->gwion->mp, env->curr); + return GW_ERROR; } diff --git a/src/parse/type_decl.c b/src/parse/type_decl.c index b320346d4..bc1d4d9db 100644 --- a/src/parse/type_decl.c +++ b/src/parse/type_decl.c @@ -7,6 +7,7 @@ #include "nspc.h" #include "type.h" #include "vm.h" +#include "traverse.h" #include "parse.h" ANN Type type_decl_resolve(const Env env, const Type_Decl* td) { diff --git a/src/parse/type_utils.c b/src/parse/type_utils.c index d0aa6b3e6..d27414a8d 100644 --- a/src/parse/type_utils.c +++ b/src/parse/type_utils.c @@ -7,6 +7,7 @@ #include "value.h" #include "type.h" #include "vm.h" +#include "traverse.h" #include "parse.h" ANN m_bool isres(const Env env, const Symbol xid, const loc_t pos) { diff --git a/src/vm/vm.c b/src/vm/vm.c index 512375397..11610db16 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -301,7 +301,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] do { register Instr instr; DISPATCH(); regsetimm: - *(m_uint*)reg = instr->m_val; + *(m_uint*)(reg + (m_int)instr->m_val2) = instr->m_val; DISPATCH(); regpushimm: *(m_uint*)reg = instr->m_val; diff --git a/tests/bug/Tester.gw b/tests/bug/Tester.gw index 73a675d78..d7a633dc4 100644 --- a/tests/bug/Tester.gw +++ b/tests/bug/Tester.gw @@ -1,7 +1,7 @@ class Tester { - function<~A~> int assert_equal(string description, A a, A b){ if(a == b) return 0; return 1; } - function<~A~> int assert_not_equal(string description, A a, A b){ if(a != b) return 0; return 1; } + fun int assert<~A~>_equal(string description, A a, A b){ if(a == b) return 0; return 1; } + fun int assert<~A~>_not_equal(string description, A a, A b){ if(a != b) return 0; return 1; } } Tester t; diff --git a/tests/bug/class_doc.gw b/tests/bug/class_doc.gw index 17d094a6b..c20e5b00a 100644 --- a/tests/bug/class_doc.gw +++ b/tests/bug/class_doc.gw @@ -3,8 +3,8 @@ class C { //! has an int int i; - //! a function - function void test() {} + //! a fun + fun void test() {} //! operator operator => void(C c, C d){ <<>>; diff --git a/tests/bug/template_no_guess.gw b/tests/bug/template_no_guess.gw index c160b6f28..822f852e8 100644 --- a/tests/bug/template_no_guess.gw +++ b/tests/bug/template_no_guess.gw @@ -1,2 +1,2 @@ -function void test(){} +fun void test(){} test([1], 2.3); diff --git a/tests/error/arg_prim_ref.gw b/tests/error/arg_prim_ref.gw index cd27414d3..2e78acc6e 100644 --- a/tests/error/arg_prim_ref.gw +++ b/tests/error/arg_prim_ref.gw @@ -1,2 +1,2 @@ // [contains] primitive types cannot be used as reference -function void test(int @i){} +fun void test(int @i){} diff --git a/tests/error/arg_res.gw b/tests/error/arg_res.gw index b3aee8e46..a94baa562 100644 --- a/tests/error/arg_res.gw +++ b/tests/error/arg_res.gw @@ -1,2 +1,2 @@ // [contains] this is reserved -function void test(int this){} +fun void test(int this){} diff --git a/tests/error/conflict_super.gw b/tests/error/conflict_super.gw index da190c9c9..c9fbeecb7 100644 --- a/tests/error/conflict_super.gw +++ b/tests/error/conflict_super.gw @@ -3,5 +3,5 @@ class C { int test; } class D extends C { - function void test(){} + fun void test(){} } diff --git a/tests/error/func_arg_array_empty.gw b/tests/error/func_arg_array_empty.gw index a15fd2328..70d28d36d 100644 --- a/tests/error/func_arg_array_empty.gw +++ b/tests/error/func_arg_array_empty.gw @@ -1,2 +1,2 @@ // [contains] must be defined with empty -function int[] my_func(int i[2]){} +fun int[] my_func(int i[2]){} diff --git a/tests/error/func_arg_defined.gw b/tests/error/func_arg_defined.gw index 8aebbb25f..3b5fbf85a 100644 --- a/tests/error/func_arg_defined.gw +++ b/tests/error/func_arg_defined.gw @@ -1,2 +1,2 @@ // [contains] already declared -function void test(int i, int i){} +fun void test(int i, int i){} diff --git a/tests/error/func_arg_unknown.gw b/tests/error/func_arg_unknown.gw index cc803901d..c64c738e5 100644 --- a/tests/error/func_arg_unknown.gw +++ b/tests/error/func_arg_unknown.gw @@ -1,2 +1,2 @@ // [contains] unknown type - function void my_func(unknown_type unknown_arg){} + fun void my_func(unknown_type unknown_arg){} diff --git a/tests/error/func_code_error.gw b/tests/error/func_code_error.gw index 81c1df2e3..cb6a91aa0 100644 --- a/tests/error/func_code_error.gw +++ b/tests/error/func_code_error.gw @@ -1,2 +1,2 @@ // [contains] in function: -function void test() { <<>>; } +fun void test() { <<>>; } diff --git a/tests/error/func_error_scan2.gw b/tests/error/func_error_scan2.gw index 1ff25d4b9..5909dd8b8 100644 --- a/tests/error/func_error_scan2.gw +++ b/tests/error/func_error_scan2.gw @@ -1,2 +1,2 @@ // [contains] unknown type -function void test() { skfuv sd; } +fun void test() { skfuv sd; } diff --git a/tests/error/func_no_match.gw b/tests/error/func_no_match.gw index ca53f52e0..b59e3c4b0 100644 --- a/tests/error/func_no_match.gw +++ b/tests/error/func_no_match.gw @@ -1,4 +1,4 @@ -// [contains] argument type(s) do not match for function -function void test(){} -function void test(int i[], int j[]){} +// [contains] argument type(s) do not match for fun +fun void test(){} +fun void test(int i[], int j[]){} test(1,2); diff --git a/tests/error/func_ret_array_empty.gw b/tests/error/func_ret_array_empty.gw index e45efd3bc..7ff64da71 100644 --- a/tests/error/func_ret_array_empty.gw +++ b/tests/error/func_ret_array_empty.gw @@ -1,2 +1,2 @@ // [contains] must be defined with empty - function int[1] my_func(int i[]){} + fun int[1] my_func(int i[]){} diff --git a/tests/error/func_unknown_ret.gw b/tests/error/func_unknown_ret.gw index ee15a0eb0..70fc88b69 100644 --- a/tests/error/func_unknown_ret.gw +++ b/tests/error/func_unknown_ret.gw @@ -1,2 +1,2 @@ // [contains] unknown type - function unknwon_type my_function(){} + fun unknwon_type my_function(){} diff --git a/tests/error/function_arg_no_size.gw b/tests/error/function_arg_no_size.gw index a85b12beb..daca37ab1 100644 --- a/tests/error/function_arg_no_size.gw +++ b/tests/error/function_arg_no_size.gw @@ -1,2 +1,2 @@ // [contains] cannot declare variables of size - function void test(void v){} + fun void test(void v){} diff --git a/tests/error/function_nested.gw b/tests/error/function_nested.gw index 96176466f..4c7f35aa7 100644 --- a/tests/error/function_nested.gw +++ b/tests/error/function_nested.gw @@ -1,5 +1,5 @@ // [contains] - function void test() + fun void test() { - function void nested(){} + fun void nested(){} } diff --git a/tests/error/function_ret_ref_prim.gw b/tests/error/function_ret_ref_prim.gw index 1b5d56d1a..df1013573 100644 --- a/tests/error/function_ret_ref_prim.gw +++ b/tests/error/function_ret_ref_prim.gw @@ -1,2 +1,2 @@ // [contains] primitive types cannot be used as reference -function int@ test(){} +fun int@ test(){} diff --git a/tests/error/function_used.gw b/tests/error/function_used.gw index bae0d6b92..9e2e417eb 100644 --- a/tests/error/function_used.gw +++ b/tests/error/function_used.gw @@ -1,3 +1,3 @@ // [contains] is already used by another value int i; -function void i(){} +fun void i(){} diff --git a/tests/error/global_func_already_defined.gw b/tests/error/global_func_already_defined.gw index 8c865c6db..7678ce188 100644 --- a/tests/error/global_func_already_defined.gw +++ b/tests/error/global_func_already_defined.gw @@ -1,3 +1,3 @@ // [contains] global function 'test' already defined for those arguments -function void test(){} -function void test(){} +fun void test(){} +fun void test(){} diff --git a/tests/error/invalid_return.gw b/tests/error/invalid_return.gw index 0a05d8f30..03ebbf66d 100644 --- a/tests/error/invalid_return.gw +++ b/tests/error/invalid_return.gw @@ -1,2 +1,2 @@ // [contains] invalid return type -function void test() { return 1; } +fun void test() { return 1; } diff --git a/tests/error/name_conflict.gw b/tests/error/name_conflict.gw index f6726bbd7..48a252fe4 100644 --- a/tests/error/name_conflict.gw +++ b/tests/error/name_conflict.gw @@ -4,5 +4,5 @@ class C { } class D extends C { - function int test() {} + fun int test() {} } diff --git a/tests/error/override_confict.gw b/tests/error/override_confict.gw index f1f8b1d8a..0f05c7146 100644 --- a/tests/error/override_confict.gw +++ b/tests/error/override_confict.gw @@ -6,7 +6,7 @@ class C class D extends C { - function void test() {} + fun void test() {} } C c; diff --git a/tests/error/override_static.gw b/tests/error/override_static.gw index a14b2fb7c..47fa35f09 100644 --- a/tests/error/override_static.gw +++ b/tests/error/override_static.gw @@ -6,5 +6,5 @@ class C class D extends C { - function void test() {} + fun void test() {} } diff --git a/tests/error/override_static2.gw b/tests/error/override_static2.gw index 6127e2436..4b326b83c 100644 --- a/tests/error/override_static2.gw +++ b/tests/error/override_static2.gw @@ -1,7 +1,7 @@ // [contains] but cannot override class C { - function void test() {} + fun void test() {} } class D extends C diff --git a/tests/error/pointer_outside_class.gw b/tests/error/pointer_outside_class.gw index e957a4431..51c099c8b 100644 --- a/tests/error/pointer_outside_class.gw +++ b/tests/error/pointer_outside_class.gw @@ -1,2 +1,2 @@ // [contains] can only be used at class scope -typedef static void my_function(){} +typedef static void my_fun(){} diff --git a/tests/error/pointer_unknown.gw b/tests/error/pointer_unknown.gw index 7d54e1049..d53fc486c 100644 --- a/tests/error/pointer_unknown.gw +++ b/tests/error/pointer_unknown.gw @@ -1,2 +1,2 @@ // [contains] unknown type - typedef unknown_type my_function(){} + typedef unknown_type my_fun(){} diff --git a/tests/error/ptr_assign_global.gw b/tests/error/ptr_assign_global.gw index 9ba840d94..17038c96e 100644 --- a/tests/error/ptr_assign_global.gw +++ b/tests/error/ptr_assign_global.gw @@ -4,6 +4,6 @@ class C { Test test; } -function void test(){} +fun void test(){} C c; test @=> c.test; diff --git a/tests/error/ptr_assign_member.gw b/tests/error/ptr_assign_member.gw index 47212ef74..fa68cf449 100644 --- a/tests/error/ptr_assign_member.gw +++ b/tests/error/ptr_assign_member.gw @@ -2,7 +2,7 @@ typedef void Test(); Test test; class D { - function void test(){} + fun void test(){} } D d; diff --git a/tests/error/ptr_assign_other.gw b/tests/error/ptr_assign_other.gw index 51560b6a4..7f18d51a2 100644 --- a/tests/error/ptr_assign_other.gw +++ b/tests/error/ptr_assign_other.gw @@ -1,11 +1,11 @@ -// [contains] can't assign member function to member function pointer of an other class +// [contains] can't assign member function to a pointer of an other class class C { typedef void Test(); Test test; } class D { - function void test(){} + fun void test(){} } C c; diff --git a/tests/error/ptr_no_match.gw b/tests/error/ptr_no_match.gw index 10ca6d1cd..0dc5b75d4 100644 --- a/tests/error/ptr_no_match.gw +++ b/tests/error/ptr_no_match.gw @@ -1,6 +1,6 @@ // [contains] no match found -function void test(int i){} -function void test(float f){} +fun void test(int i){} +fun void test(float f){} typedef void Test(); Test t; diff --git a/tests/error/template_enough.gw b/tests/error/template_enough.gw index 6261d0840..af3391acd 100644 --- a/tests/error/template_enough.gw +++ b/tests/error/template_enough.gw @@ -1,3 +1,3 @@ // [contains] -function<~A,B~> void test(){} +fun void test<~A,B~>(){} test(); diff --git a/tests/error/template_n_mismatch.gw b/tests/error/template_n_mismatch.gw index a5892457e..c912840ce 100644 --- a/tests/error/template_n_mismatch.gw +++ b/tests/error/template_n_mismatch.gw @@ -1,6 +1,6 @@ // [contains] arguments do not match for template call -function<~A~> void test(){ <<<"func">>>;} -function<~A~> void test(int i){<<<"other func">>>;} +fun void test<~A~>(){ <<<"func">>>;} +fun void test<~A~>(int i){<<<"other func">>>;} test<~int, float, int~>(); //test<~int~>(); diff --git a/tests/error/template_no_match.gw b/tests/error/template_no_match.gw index 08586135c..0868e24a8 100644 --- a/tests/error/template_no_match.gw +++ b/tests/error/template_no_match.gw @@ -1,7 +1,7 @@ // [contains] arguments do not match for template call class C { - function<~A~> void test(float f) {} - function<~A~> void test() {} + fun void test<~A~>(float f) {} + fun void test<~A~>() {} } C c; //c.test<~int~>(); diff --git a/tests/error/template_ternary.gw b/tests/error/template_ternary.gw index 86318b6ad..6b99bf58c 100644 --- a/tests/error/template_ternary.gw +++ b/tests/error/template_ternary.gw @@ -1,4 +1,4 @@ // [contains] invalid expression for function call -function<~A~> void test(A a){} +fun void test<~A~>(A a){} (maybe ? test : test)(1); diff --git a/tests/error/template_unknown.gw b/tests/error/template_unknown.gw index 503d7a3e1..85e15132f 100644 --- a/tests/error/template_unknown.gw +++ b/tests/error/template_unknown.gw @@ -1,4 +1,4 @@ // [contains] unknown type -function<~A~> void my_function() { <<<"test">>>; } +fun void my_function<~A~>() { <<<"test">>>; } my_function<~unknown_type~>(); diff --git a/tests/error/type_path_test.gw b/tests/error/type_path_test.gw index c604e5d77..1e255e092 100644 --- a/tests/error/type_path_test.gw +++ b/tests/error/type_path_test.gw @@ -1,2 +1,2 @@ // [contains] unknown type -function void test(B->C a){} +fun void test(B->C a){} diff --git a/tests/import/variadic.gw b/tests/import/variadic.gw index c315163f2..fe54f6f1c 100644 --- a/tests/import/variadic.gw +++ b/tests/import/variadic.gw @@ -1,4 +1,4 @@ -<<<"test builtin variadic function">>>; +<<<"test builtin variadic fun">>>; Variadic v; "iiii" => string format; <<>>; diff --git a/tests/new/spork_in_func.gw b/tests/new/spork_in_func.gw index a6835f18f..e5bfe2562 100644 --- a/tests/new/spork_in_func.gw +++ b/tests/new/spork_in_func.gw @@ -1,4 +1,4 @@ -function void test() { +fun void test() { // <<<1>>>; //spork \{<<<2>>>;}(); } diff --git a/tests/tree/arg_array.gw b/tests/tree/arg_array.gw index b4aa8c6a0..b834990f9 100644 --- a/tests/tree/arg_array.gw +++ b/tests/tree/arg_array.gw @@ -1 +1 @@ -function void test(int i[]){} +fun void test(int i[]){} diff --git a/tests/tree/array_test.gw b/tests/tree/array_test.gw index c17c86052..82abecbcf 100644 --- a/tests/tree/array_test.gw +++ b/tests/tree/array_test.gw @@ -1,4 +1,4 @@ -function void print_array(int a[]){ +fun void print_array(int a[]){ for(int i; i < a.size(); i++) <<>>; } diff --git a/tests/tree/assign_member_ptr.gw b/tests/tree/assign_member_ptr.gw index 00f3144b1..2da5caa07 100644 --- a/tests/tree/assign_member_ptr.gw +++ b/tests/tree/assign_member_ptr.gw @@ -2,7 +2,7 @@ class C { typedef void Test(); Test test; - function void func(){} + fun void func(){} } C c; c.func @=> c.test; diff --git a/tests/tree/balance.gw b/tests/tree/balance.gw index 49f997714..50c654793 100644 --- a/tests/tree/balance.gw +++ b/tests/tree/balance.gw @@ -1,13 +1,13 @@ -function float test() {} -function float test(int i) {} -function float test(float f) {} -function float test(complex c) {} -function float test(Vec3 v) {} -function float test(Vec4 w) {} - -function complex ctest(){} -function Vec3 vtest(){} -function Vec4 wtest(){} +fun float test() {} +fun float test(int i) {} +fun float test(float f) {} +fun float test(complex c) {} +fun float test(Vec3 v) {} +fun float test(Vec4 w) {} + +fun complex ctest(){} +fun Vec3 vtest(){} +fun Vec4 wtest(){} ctest(); vtest(); wtest(); @@ -31,12 +31,12 @@ test(@(1.2, 2.3, 3.4, 4.5)); class C { - function float test() {} - function float test(int i) {} - function float test(float f) {} - function float test(complex c) {} - function float test(Vec3 v) {} - function float test(Vec4 w) {} + fun float test() {} + fun float test(int i) {} + fun float test(float f) {} + fun float test(complex c) {} + fun float test(Vec3 v) {} + fun float test(Vec4 w) {} fun static float s_test() {} fun static float s_test(int i) {} diff --git a/tests/tree/class_template.gw b/tests/tree/class_template.gw index fc23b0294..ed4694266 100644 --- a/tests/tree/class_template.gw +++ b/tests/tree/class_template.gw @@ -4,7 +4,7 @@ class<~A,B~> C { fun A test() { <<<"lol">>>; } - fun<~C~> void test2(C c) { + fun void test2<~C~>(C c) { <<>>; } } diff --git a/tests/tree/f2i_cast.gw b/tests/tree/f2i_cast.gw index b6cfc7cc6..ddb179e47 100644 --- a/tests/tree/f2i_cast.gw +++ b/tests/tree/f2i_cast.gw @@ -1,5 +1,5 @@ <<<"test">>>; <<< 2.3 $ int >>>; 1 => float f; -function void test(float f){} +fun void test(float f){} 1 => test; diff --git a/tests/tree/func_extend_error.gw b/tests/tree/func_extend_error.gw index 18d01393d..dd39ee3b3 100644 --- a/tests/tree/func_extend_error.gw +++ b/tests/tree/func_extend_error.gw @@ -1,6 +1,6 @@ class Sine extends SinOsc { - function int freq(float f) { + fun int freq(float f) { (2 * f) => (this $ SinOsc).freq; } } diff --git a/tests/tree/func_ret_void.gw b/tests/tree/func_ret_void.gw index 25531a97f..88eb7a5d5 100644 --- a/tests/tree/func_ret_void.gw +++ b/tests/tree/func_ret_void.gw @@ -1,2 +1,2 @@ -function void test() { <<<"test">>>; return; <<<"this won't print. ever.">>>; } +fun void test() { <<<"test">>>; return; <<<"this won't print. ever.">>>; } test(); diff --git a/tests/tree/func_return_coverage.gw b/tests/tree/func_return_coverage.gw index 5886e7481..490211fed 100644 --- a/tests/tree/func_return_coverage.gw +++ b/tests/tree/func_return_coverage.gw @@ -1,6 +1,6 @@ -function complex testc() {}; -function Vec3 testv3() {}; -function Vec4 testv4() {}; +fun complex testc() {}; +fun Vec3 testv3() {}; +fun Vec4 testv4() {}; testc(); testv3(); testv4(); diff --git a/tests/tree/func_sig_differ.gw b/tests/tree/func_sig_differ.gw index 595c36348..607fddf79 100644 --- a/tests/tree/func_sig_differ.gw +++ b/tests/tree/func_sig_differ.gw @@ -1,4 +1,4 @@ -function void test(int i){} -function int test(){} +fun void test(int i){} +fun int test(){} <<>>; <<>>; diff --git a/tests/tree/member_op.gw b/tests/tree/member_op.gw index 2c9da3717..27ab7e607 100644 --- a/tests/tree/member_op.gw +++ b/tests/tree/member_op.gw @@ -2,7 +2,7 @@ class C { operator => void(C c, int i){<<>>;} // this => this; -//function void test_op(C c){ this => c; } +//fun void test_op(C c){ this => c; } this => int i; } C c; diff --git a/tests/tree/object_func.gw b/tests/tree/object_func.gw index 9a0ac9340..ab3df0375 100644 --- a/tests/tree/object_func.gw +++ b/tests/tree/object_func.gw @@ -1,2 +1,2 @@ -function Object test(){ Object o; <<>>; return new Object; } +fun Object test(){ Object o; <<>>; return new Object; } test(); diff --git a/tests/tree/ptr_decl_assign.gw b/tests/tree/ptr_decl_assign.gw index 7c511541d..6edb9197d 100644 --- a/tests/tree/ptr_decl_assign.gw +++ b/tests/tree/ptr_decl_assign.gw @@ -1,4 +1,4 @@ typedef void Test(); -function void t(){<<<"lol">>>;} +fun void t(){<<<"lol">>>;} t @=> Test test; test(); diff --git a/tests/tree/ptr_test.gw b/tests/tree/ptr_test.gw index 642a35ab2..e44119a47 100644 --- a/tests/tree/ptr_test.gw +++ b/tests/tree/ptr_test.gw @@ -1,4 +1,4 @@ typedef void Test(); -function void t0(){} +fun void t0(){} t0 @=> Test test; test(); diff --git a/tests/tree/push_mem.gw b/tests/tree/push_mem.gw index 05d0e0b35..85b3961bc 100644 --- a/tests/tree/push_mem.gw +++ b/tests/tree/push_mem.gw @@ -1,2 +1,2 @@ -function void test() { complex c; c; Vec3 v; v; Vec4 w; w; } +fun void test() { complex c; c; Vec3 v; v; Vec4 w; w; } test(); diff --git a/tests/tree/return_void.gw b/tests/tree/return_void.gw index 441273387..d23fe4442 100644 --- a/tests/tree/return_void.gw +++ b/tests/tree/return_void.gw @@ -1,7 +1,7 @@ // define a simple variable: 'i'. int i; -// define a functions that returns 1 if 'i' is non zero, and 0 othervise. -function int test() { return i ? 1 : 0; } +// define a funs that returns 1 if 'i' is non zero, and 0 othervise. +fun int test() { return i ? 1 : 0; } <<>>; 1 => i; <<>>; diff --git a/tests/tree/spork_arg.gw b/tests/tree/spork_arg.gw index bdbae8fd8..8ffaa84eb 100644 --- a/tests/tree/spork_arg.gw +++ b/tests/tree/spork_arg.gw @@ -1,2 +1,2 @@ -function void test(int i, int j){} +fun void test(int i, int j){} spork test(1,2); diff --git a/tests/tree/spork_in_func.gw b/tests/tree/spork_in_func.gw index 250380d2e..72b710826 100644 --- a/tests/tree/spork_in_func.gw +++ b/tests/tree/spork_in_func.gw @@ -1,4 +1,4 @@ -function void test() { +fun void test() { spork { <<<2>>>; }; } //spork { <<<1>>>; }; diff --git a/tests/tree/spork_member.gw b/tests/tree/spork_member.gw index 29c2e97f6..192ba5db3 100644 --- a/tests/tree/spork_member.gw +++ b/tests/tree/spork_member.gw @@ -1,6 +1,6 @@ class C { - function void test(int i){ + fun void test(int i){ <<>>; spork { <<<"test2">>>; diff --git a/tests/tree/this.gw b/tests/tree/this.gw index a741751a7..890fa20d8 100644 --- a/tests/tree/this.gw +++ b/tests/tree/this.gw @@ -1,6 +1,6 @@ class C { - function C test() { + fun C test() { return this; } } diff --git a/tests/tree/this_valid.gw b/tests/tree/this_valid.gw index aebba4f3e..a526f2204 100644 --- a/tests/tree/this_valid.gw +++ b/tests/tree/this_valid.gw @@ -1,6 +1,6 @@ class C { - function void test() { + fun void test() { <<>>; } } diff --git a/tests/tree/uncalled_functions.gw b/tests/tree/uncalled_functions.gw index 0c5ec6700..79c3ebfed 100644 --- a/tests/tree/uncalled_functions.gw +++ b/tests/tree/uncalled_functions.gw @@ -1,4 +1,4 @@ -// just to check uncalled function to not push the stack +// just to check uncalled fun to not push the stack class C { fun void test(){} fun static void stest() {}} C c; diff --git a/util b/util index 6e10d0bd6..f2e8f3377 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 6e10d0bd6a9e6731e35cc01d44562e0271755676 +Subproject commit f2e8f337708be41cac47fb85862766b801d1bda6