return str2tl(env, c, &depth);
}
+ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_Def fdef) {
+ CHECK_BB(traverse_func_def(emit->env, fdef))
+ return emit_func_def(emit, fdef);
+}
+
ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
- 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(!dt->def->base->func && traverse_func_def(emit->env, dt->def) > 0)
- ret = emit_func_def(emit, dt->def);
+ const m_uint scope = emit_push(emit, dt->owner_class, dt->owner);
+ const m_bool ret = traverse_emit_func_def(emit, dt->def);
emit_pop(emit, scope);
return ret;
}
static inline m_bool push_func_code(const Emitter emit, const Func f) {
+ if(!vector_size(&emit->code->instr))
+ return GW_OK;
const Instr instr = (Instr)vector_back(&emit->code->instr);
- if(GET_FLAG(f, template) && f->value_ref->owner_class) {
-// assert(instr->opcode == eDotTmplVal);
+ if(instr->opcode == eDotTmplVal) {
size_t len = strlen(f->name);
size_t sz = len - strlen(f->value_ref->owner_class->name);
char c[sz + 1];
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;
- }
+ instr->opcode = eRegPushImm;
+ instr->m_val = (m_uint)f->code;
return GW_OK;
}
CHECK_BB(traverse_class_def(emit->env, f->value_ref->owner_class->e->def))
const Value v = f->value_ref;
size_t scope = emit_push(emit, v->owner_class, v->owner);
- CHECK_BB(emit_func_def(emit, f->def))
+ const m_bool ret = emit_func_def(emit, f->def);
emit_pop(emit, scope);
- return push_func_code(emit, f);
+ return ret > 0 ? push_func_code(emit, f) : GW_ERROR;
}
ANN static Instr get_prelude(const Emitter emit, const Func f) {
emit_union_offset(stmt->l, stmt->o);
if(stmt->xid || stmt->type_xid || global)
emit_pop(emit, scope);
+ SET_FLAG(stmt->xid ? stmt->value->type : stmt->type, emit);
return GW_OK;
}
func_i->m_val = (m_uint)(func->code ?: (VM_Code)func);
return GW_OK;
}
-// if(func->def->base->tmpl)
- if(GET_FLAG(func->def, template))
+ if(func->def->base->tmpl)
emit_add_instr(emit, DotTmplVal);
else {
const Instr instr = emit_add_instr(emit, GET_FLAG(func, member) ? DotFunc : DotStaticFunc);
const Type parent = cdef->base.type->e->parent;
const Type base = parent->e->d.base_type;
if(base && !GET_FLAG(base, emit))
-// if(parent && (!GET_FLAG(parent, emit) || GET_FLAG(parent, template)))
- CHECK_BB(scanx_parent(base, emit_parent_inner, emit))
- return !GET_FLAG(parent, emit) ? GW_OK : scanx_parent(parent, emit_parent_inner, emit);
+ CHECK_BB(emit_parent_inner(emit, base->e->def))
+ return !GET_FLAG(parent, emit) ? emit_parent_inner(emit, parent->e->def) : GW_OK;
}
ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
INSTR(DTOR_EOC) {
const M_Object o = *(M_Object*)MEM(0);
o->type_ref = o->type_ref->e->parent;
- __release(o, shred);
+ _release(o, shred);
shred->info->me->ref = 1;
vm_shred_exit(shred);
}
free_object(shred->info->mp, tmp);
}
-ANN static Func_Def from_base(const Env env, const struct dottmpl_ *dt, const Nspc nspc) {
+ANN static Func_Def from_base(const Env env, struct dottmpl_ *const 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);
- DECL_OO(const Value, v, = nspc_lookup_value1(nspc, sym))
+ DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym))
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, 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));
+ fdef->base->args), base->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);
+ def->base->tmpl->call = dt->tl;
+ dt->def = def;
+ dt->owner = v->owner;
+ dt->owner_class = v->owner_class;
SET_FLAG(def, template);
return def;
}
if(base) {
free_mstr(emit->gwion->mp, tmpl_name);
assert(base->code);
- if(GET_FLAG(base->def, static))
- shred->reg -= SZ_INT;
*(VM_Code*)(shred->reg -SZ_INT) = base->code;
return;
}
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(f, member)) // TODO: CHECK ME
- shred->reg += SZ_INT; else
- if(GET_FLAG(def, static))
- shred->reg -= SZ_INT;
+ if(traverse_dot_tmpl(emit, dt) > 0)
*(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code;
- return;
- } else
+ else
Except(shred, "TemplateException");
}
strcpy(str + instr->m_val2, t->name);
const Func f = nspc_lookup_func1(t->nspc, insert_symbol(emit->env->gwion->st, str));
if(f) {
- if(!f->code) {
- dt->def = f->def;//
- dt->owner_class = t; //
- if(traverse_dot_tmpl(emit, dt) < 0)
- continue;
- }
- if(GET_FLAG(f->def, static))
- shred->reg -= SZ_INT;
*(VM_Code*)shred->reg = f->code;
shred->reg += SZ_INT;
return;
const Func_Def def = from_base(emit->env, dt, t->nspc);
if(!def)
continue;
- dt->def = def; //
- dt->owner_class = t; //
if(traverse_dot_tmpl(emit, dt) > 0) {
- if(GET_FLAG(def, static))
- shred->reg -= SZ_INT;
*(VM_Code*)shred->reg = def->base->func->code;
shred->reg += SZ_INT;
return;
ANN void __release(const M_Object o, const VM_Shred shred) {
MemPool p = shred->info->mp;
Type t = o->type_ref;
- while(t->e->parent) {
+ do {
struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
Value v;
while(scope_iter(&iter, &v) > 0) {
isa(v->type, t_object) > 0)
release(*(M_Object*)(o->data + v->offset), shred);
}
- if(GET_FLAG(t, dtor)) {
+ if(GET_FLAG(t, dtor) && t->nspc->dtor) {
if(GET_FLAG(t->nspc->dtor, builtin))
((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
else {
+ o->type_ref = t;
handle_dtor(o, shred);
return;
}
}
- t = t->e->parent;
- }
+ } while((t = t->e->parent));
free_object(p, o);
}
}
if(!decl->type) // TODO: remove when scan passes are complete
ERR_O(td_pos(decl->td), _("can't infer type."));
- if(GET_FLAG(decl->type , template)) {
- /*if(!GET_FLAG(decl->type, checked))*/
- if(!GET_FLAG(decl->type, scan2))
- CHECK_BO(traverse_cdef(env, decl->type->e->def))
- }
+ if(GET_FLAG(decl->type , template) && !GET_FLAG(decl->type, check))
+ 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);
do {
}
if(e1->type == t_undefined ||
(func->def->base->tmpl && is_fptr(func->value_ref->type) > 0)) {
- if(func->value_ref->owner_class)
+ if(SAFE_FLAG(func->value_ref->owner_class, template))
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)
+ if(SAFE_FLAG(func->value_ref->owner_class, template))
nspc_pop_type(env->gwion->mp, env->curr);
}
if(func_match_inner(env, e, e1->type, implicit, specific) < 0)
}
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);
if(td->array)
CHECK_BB(check_exp_array_subscripts(env, td->array->exp))
if(parent->e->def && (!GET_FLAG(parent, check) || GET_FLAG(parent, template)))
- CHECK_BB(scanx_parent(parent, traverse_class_def, env))
+ CHECK_BB(scanx_parent(parent, traverse_cdef, env))
if(GET_FLAG(parent, typedef))
SET_FLAG(cdef->base.type, typedef);
return GW_OK;
ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
Nspc nspc = get_nspc(emit->gwion->st, opi);
+ Type l = opi->lhs;
do {
- Type l = opi->lhs;
+ Type r = opi->rhs;
do {
- 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
+ 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)));
return GW_ERROR;
}
stmt->value->owner = env->curr;
stmt->value->owner_class = env->class_def;
fptr_def(env, stmt);
+ if(env->class_def)
+ fptr_assign(env, stmt);
SET_FLAG(stmt->value, func);
add_type(env, t->e->owner, t);
return GW_OK;
ANN m_bool scan1_stmt_type(const Env env, const Stmt_Type stmt) {
if(!stmt->type)
CHECK_BB(scan0_stmt_type(env, stmt))
- return stmt->type->e->def ? scan1_class_def(env, stmt->type->e->def) : GW_OK;
+ return stmt->type->e->def ? scan1_cdef(env, stmt->type->e->def) : GW_OK;
}
ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) {
if(isa(parent, t_object) < 0)
ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
if(parent->e->def && (!GET_FLAG(parent, scan1) || GET_FLAG(parent, template)))
- CHECK_BB(scanx_parent(parent, scan1_class_def, env))
+ CHECK_BB(scanx_parent(parent, scan1_cdef, env))
if(type_ref(parent))
ERR_B(pos, _("can't use ref type in class extend"))
return GW_OK;
return f->value_ref = v;
}
+
+ANN void fptr_assign(const Env env, const Stmt_Fptr ptr) {
+ const Func_Def def = ptr->type->e->d.func->def;
+ if(GET_FLAG(ptr->base->td, global)) {
+ SET_FLAG(ptr->value, global);
+ SET_FLAG(ptr->base->func, global);
+ SET_FLAG(def, global);
+ } else if(!GET_FLAG(ptr->base->td, static)) {
+ SET_FLAG(ptr->value, member);
+ SET_FLAG(ptr->base->func, member);
+ SET_FLAG(def, member);
+ def->stack_depth += SZ_INT;
+ } else {
+ SET_FLAG(ptr->value, static);
+ SET_FLAG(ptr->base->func, static);
+ SET_FLAG(def, static);
+ }
+ if(GET_FLAG(def, variadic))
+ def->stack_depth += SZ_INT;
+ ptr->value->owner_class = env->class_def;
+}
+
ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr ptr) {
const Func_Def def = ptr->type->e->d.func->def;
if(!ptr->base->tmpl) {
def->base->ret_type = ptr->base->ret_type;
if(ptr->base->args)
CHECK_BB(scan2_args(env, def))
- }
- if(env->class_def) {
- if(GET_FLAG(ptr->base->td, global)) {
- SET_FLAG(ptr->value, global);
- SET_FLAG(ptr->base->func, global);
- } else if(!GET_FLAG(ptr->base->td, static)) {
- SET_FLAG(ptr->value, member);
- SET_FLAG(ptr->base->func, member);
- def->stack_depth += SZ_INT;
- } else {
- SET_FLAG(ptr->value, static);
- SET_FLAG(ptr->base->func, static);
- }
- ptr->value->owner_class = env->class_def;
- }
- if(ptr->base->tmpl)
+ } else
SET_FLAG(ptr->type, func);
// nspc_add_value(env->curr, ptr->base->xid, ptr->value);
nspc_add_func(ptr->type->e->owner, ptr->base->xid, ptr->base->func);
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;
}
if(a->base.type)
return a->base.type;
a->base.tmpl = mk_tmpl(env, t, t->e->def->base.tmpl, type->types);
- if(isa(t, t_union) < 0) {
+ if(t->e->parent != t_union) {
CHECK_BO(scan0_class_def(env, a))
map_set(&t->e->owner->info->type->map, (vtype)a->base.xid, (vtype)a->base.type);
map_set((Map)vector_front((Vector)&t->e->owner->info->type->ptr), (vtype)a->base.xid, (vtype)a->base.type);
nspc_add_type(env->curr, sym, ret);
const Func_Def def = new_func_def(env->gwion->mp,
new_func_base(env->gwion->mp, t->e->d.func->def->base->td, sym, t->e->d.func->def->base->args),
- NULL, type->flag, loc_cpy(env->gwion->mp, td_pos(type)));
+ NULL, t->e->d.func->def->flag, loc_cpy(env->gwion->mp, td_pos(type)));
const Func func = ret->e->d.func = new_func(env->gwion->mp, s_name(sym), def);
const Value value = new_value(env->gwion->mp, ret, s_name(sym));
+ func->flag = def->flag;
value->d.func_ref = func;
value->owner = t->e->owner;
value->owner_class = t->e->d.func->value_ref->owner_class;
#ifdef DEBUG_STACK
#define VM_INFO \
- if(s->curr) \
- gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", \
- shred->tick->xid, \
- mem - ((m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG), reg - ((m_bit*)shred + sizeof(struct VM_Shred_)));
+ gw_err("shred[%" UINT_F "] mem[%" INT_F"] reg[%" INT_F"]\n", \
+ shred->tick->xid, \
+ mem - ((m_bit*)shred + sizeof(struct VM_Shred_) + SIZEOF_REG), reg - ((m_bit*)shred + sizeof(struct VM_Shred_)));
#else
#define VM_INFO
#endif
--- /dev/null
+class C {
+ fun void test<~A~>(A a) { <<< a >>>; }
+}
+
+class D extends C {
+}
+
+D d;
+d.test(1);
+d.test(2.3);
--- /dev/null
+class <~A~>C {
+ dtor { <<< __func__ >>>; }
+}
+class <~A~>D extends <~A~>C {
+ dtor { <<< __func__ >>>; }
+}
+class E extends <~int~>D {
+ dtor { <<< __func__ >>>; }
+}
+
+E e;
--- /dev/null
+union <~A~>U {
+ A a;
+ int i;
+};
+
+#!<~float~>U u;
+#!<<< u.i >>>;
+class <~A~>C extends <~A~>U {
+ fun void test() { <<< this >>>; }
+ dtor { <<< __func__ >>>; }
+}
+
+<~float~>C c;
+<<< c >>>;
+<<< c.test() >>>;
+<<< c.i >>>;
+
+class <~A,B~>D extends <~float~>C {
+
+}
+
+<~int,int~>D d;
+class <~A,B~>E extends <~float,B~>D {
+
+}
+<~int,int~>E e;
--- /dev/null
+`1` i;
+<<< i >>>;
--- /dev/null
+new Object @=> Object ! @ o;
--- /dev/null
+class global C {
+ fun static void t<~A~>() { <<< __func__ >>>; }
+}
+class D extends C {
+
+}
+
+fun void test(C c) {
+ C.t<~int~>();
+}
+
+#!D d;
+#!d.t<~int~>();
+#!d => test;
--- /dev/null
+#!C.t<~float~>();
+#!C.t<~Object~>();
+class D extends C {
+
+}
+#!<<< "here" >>>;
+D d;
+<<< d >>>;
+#!<<< d.t() >>>;
+<<< d.t<~int~>() >>>;
+#!d.t<~Object~>();
--- /dev/null
+class C {
+ fun int test<~A~>(A a) { <<< " A ", a >>>; }
+ fun int test<~A~>(A a, int i) { <<< " A ", a, " ", __func__ >>>; }
+ fun int test<~A~>(A a, int i, int j) { <<< a >>>; }
+}
+class D extends C {
+ fun int test<~A~>(A a, int i) { <<< this, " extent ", a, __func__ >>>; }
+}
+class E extends D {
+ fun int test<~A~>(A a, int i) { <<< this, " Extent ", a, __func__ >>>; }
+}
+
+
+<<< E e >>>;
+
+e.test(123,3);
--- /dev/null
+class C {
+ typedef static void func_t<~A~>(A a);
+ fun static void myfunc<~A~>(A a) { <<< a >>>; }
+ myfunc @=> static func_t ptr;
+ ptr(1);
+}
+
+C c;
--- /dev/null
+class C {
+ typedef void t_ptr();
+
+ t_ptr iptr;
+
+ fun void test() {
+ <<< this, " ", __func__ >>>;
+ }
+
+ test @=> iptr;
+ <<< iptr() >>>;
+ <<< iptr() >>>;
+}
+<<<C c>>>;
+ <<< c.iptr >>>;
+ <<< c.iptr() >>>;
+ <<< c.iptr() >>>;
--- /dev/null
+class C {
+ typedef void t_ptr(...);
+
+ t_ptr iptr;
+
+ fun void test(...) {
+ <<< this, " ", __func__ >>>;
+ vararg.start;
+ <<< vararg.i >>>;
+ vararg.end;
+ }
+
+ test @=> iptr;
+ <<< iptr() >>>;
+ <<< iptr() >>>;
+}
+<<<C c>>>;
+ <<< c.iptr >>>;
+ <<< c.iptr(1) >>>;
+ <<< c.iptr(1,2) >>>;
--- /dev/null
+class C {
+ typedef void t_ptr<~A~>();
+
+ <~int~>t_ptr iptr;
+
+ fun void test<~A~>() {
+ <<< this, " ", __func__ >>>;
+ }
+
+ test @=> iptr;
+ <<< iptr() >>>;
+ <<< iptr() >>>;
+}
+<<<C c>>>;
+ <<< c.iptr >>>;
+ <<< c.iptr() >>>;
+ <<< c.iptr() >>>;
--- /dev/null
+class C {
+ typedef static void t_ptr<~A~>();
+
+ <~int~>t_ptr iptr;
+
+ fun static void test<~A~>() {
+ <<< __func__ >>>;
+ }
+
+ test @=> iptr;
+#! test<~int~>();
+ <<< iptr() >>>;
+ <<< iptr() >>>;
+}
+<<<C c>>>;
+#! <<< c.iptr >>>;
+#! <<< c.iptr() >>>;
+#! <<< c.iptr() >>>;