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