-Subproject commit db6a920ab506312eabe2835f41ca8b02ecec153f
+Subproject commit 50ab3bf5f4dbbbc493e382d0a74cd8a9cd6f2b7b
OP_CHECK(opck_rassign);
OP_CHECK(opck_rhs_emit_var);
OP_CHECK(opck_basic_cast);
-OP_CHECK(opck_simple_cast);
OP_CHECK(opck_usr_implicit);
OP_CHECK(opck_new);
OP_EMIT(opem_new);
ANN m_uint union_push(const Env, const Union_Def);
ANN void union_pop(const Env, const Union_Def, const m_uint);
+ANN void union_flag(const Union_Def, const ae_flag);
ANN m_bool check_stmt(const Env env, const Stmt stmt);
typedef m_bool (*_exp_func)(const void*, const void*);
emit_section(emit, section) : GW_OK;
}
-ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
- if(tmpl_base(cdef->base.tmpl))
+ANN static m_bool emit_class_def(const Emitter emit, const Class_Def c) {
+ if(tmpl_base(c->base.tmpl))
return GW_OK;
+ const Class_Def cdef = c->base.type->e->def;
if(GET_FLAG(cdef->base.type, emit))
return GW_OK;
const Type type = cdef->base.type;
#include "gwion.h"
ANN static inline m_bool freeable(const Type a) {
- return !GET_FLAG(a, nonnull) &&
- (GET_FLAG(a, template) || GET_FLAG(a, global));
+ return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
}
ANN static void free_type(Type a, Gwion gwion) {
if(freeable(a)) {
if(GET_FLAG(a, union)) {
if(a->e->def->union_def) {
- if(!GET_FLAG(a, pure)) { // <=> decl_list
- UNSET_FLAG(a->e->def->union_def, global);
+ if(!GET_FLAG(a, pure))
free_union_def(gwion->mp, a->e->def->union_def);
- } else
+ else
free_decl_list(gwion->mp, a->e->def->list);
}
a->e->def->union_def = NULL;
- } else if(a->e->def) {
- if(!(a->e->ctx && a->e->ctx->error)) {
- UNSET_FLAG(a->e->def, template);
- UNSET_FLAG(a->e->def, global);
- free_class_def(gwion->mp, a->e->def);
- }
}
+ if(a->e->def)
+ free_class_def(gwion->mp, a->e->def);
}
if(a->nspc)
REM_REF(a->nspc, gwion);
struct TemplateScan *ts = (struct TemplateScan*)data;
if(ts->td->types)
return scan_class(env, ts->t, ts->td);
- if(GET_FLAG(ts->t, unary))
+ if(!GET_FLAG(ts->t, template) || GET_FLAG(ts->t, unary))
return ts->t;
ERR_O(td_pos(ts->td), _("you must provide template types for type '%s'"), ts->t->name)
}
a->union_def = new_union_def(env->gwion->mp, a->list,
loc_cpy(env->gwion->mp, t->e->def->pos));
a->union_def->type_xid = a->base.xid;
+ if(GET_FLAG(t, global))
+ SET_FLAG(a->union_def, global);
CHECK_BB(scan0_union_def(env, a->union_def))
SET_FLAG(a, scan0);
a->base.type = a->union_def->type;
a->base.type->e->def = a;
+ a->union_def->tmpl = cpy_tmpl(env->gwion->mp, a->base.tmpl);
return GW_OK;
}
exp_self(cast)->info->type : env->gwion->type[et_null];
}
-OP_CHECK(opck_simple_cast) {
- const Exp_Cast* cast = (Exp_Cast*)data;
- return cast->exp->info->cast_to = exp_self(cast)->info->type;
-}
-
OP_CHECK(opck_usr_implicit) {
struct Implicit* imp = (struct Implicit*)data;
imp->e->info->cast_to = imp->t;
return GW_OK;
}
+static OP_CHECK(opck_cast_f2i) {
+ return env->gwion->type[et_int];
+}
+
static OP_CHECK(opck_implicit_f2i) {
return env->gwion->type[et_null];
}
+static OP_CHECK(opck_cast_i2f) {
+ return env->gwion->type[et_float];
+}
+
static OP_CHECK(opck_implicit_i2f) {
struct Implicit* imp = (struct Implicit*)data;
return imp->e->info->cast_to = env->gwion->type[et_float];
CHECK_IF("-=>", rassign, r_minus)
CHECK_IF("*=>", rassign, r_mul)
CHECK_IF("/=>", rassign, r_div)
- _CHECK_OP("$", simple_cast, CastI2F)
+ _CHECK_OP("$", cast_i2f, CastI2F)
_CHECK_OP("@implicit", implicit_i2f, CastI2F)
return GW_OK;
}
CHECK_FI("-=>", rassign, r_minus)
CHECK_FI("*=>", rassign, r_mul)
CHECK_FI("/=>", rassign, r_div)
- _CHECK_OP("$", simple_cast, CastF2I)
+ _CHECK_OP("$", cast_f2i, CastF2I)
_CHECK_OP("@implicit", implicit_f2i, CastF2I)
return GW_OK;
}
ANN static Func get_template_func(const Env env, const Exp_Call* func, const Value v) {
const Func f = find_template_match(env, v, func);
if(f) {
+// copy that tmpl->call?
Tmpl* tmpl = new_tmpl_call(env->gwion->mp, func->tmpl->call);
tmpl->list = v->d.func_ref ? v->d.func_ref->def->base->tmpl->list : func->func->info->type->e->d.func->def->base->tmpl->list;
((Exp_Call*)func)->tmpl = tmpl;
CHECK_OO((exp_self(cast)->info->type = cast->td->xid ? known_type(env, cast->td) : check_td(env, cast->td)))
struct Op_Import opi = { .op=insert_symbol("$"), .lhs=t, .rhs=exp_self(cast)->info->type,
.data=(uintptr_t)cast, .pos=exp_self(cast)->pos, .op_type=op_cast };
- return op_check(env, &opi);
+// return op_check(env, &opi);
+ const Type ret = op_check(env, &opi);
+printf("[%s] %p\n", __func__, t);
+ return ret;
}
ANN static Type check_exp_post(const Env env, const Exp_Postfix* post) {
if(!udef->xid && !udef->type_xid && env->class_def && !GET_FLAG(udef, static))
env->class_def->nspc->info->offset = udef->o + udef->s;
union_pop(env, udef, scope);
+ union_flag(udef, ae_flag_check);
+ union_flag(udef, ae_flag_checked);
return ret;
}
return ret;
}
-ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
- if(tmpl_base(cdef->base.tmpl))
+ANN m_bool check_class_def(const Env env, const Class_Def c) {
+ if(tmpl_base(c->base.tmpl))
return GW_OK;
-if(GET_FLAG(cdef->base.type, checked))return GW_OK;
+ const Class_Def cdef = c->base.type->e->def;
+ if(GET_FLAG(cdef->base.type, checked))return GW_OK;
const Type type = cdef->base.type;
SET_FLAG(type, check);
if(cdef->base.ext)
loc_cpy(env->gwion->mp, td_pos(tdef->ext)));
CHECK_BB(scan0_class_def(env, cdef))
tdef->type = cdef->base.type;
- cdef->base.tmpl = tdef->tmpl;
+ cdef->base.tmpl = tdef->tmpl;// check cpy
return GW_OK;
}
const Class_Def cdef = new_class_def(env->gwion->mp, udef->flag, udef->type_xid,
NULL, (Ast)udef->l, loc_cpy(env->gwion->mp, udef->pos));
udef->type->e->def = cdef;
- cdef->base.tmpl = udef->tmpl;
+ cdef->base.tmpl = cpy_tmpl(env->gwion->mp, udef->tmpl);
cdef->base.type = udef->type;
cdef->list = cpy_decl_list(env->gwion->mp, udef->l);
SET_FLAG(cdef, union);
SET_FLAG(udef, template);
SET_FLAG(udef->type, template);
}
+ if(GET_FLAG(udef, global))
+ SET_FLAG(udef->type, global);
SET_FLAG(udef->type, union);
}
inherit_tmpl(env, cdef);
set_template(t, cdef);
} else if(SAFE_FLAG(env->class_def, template)) {
- cdef->base.tmpl = new_tmpl_base(env->gwion->mp, env->class_def->e->def->base.tmpl->list);
+ cdef->base.tmpl = new_tmpl_base(env->gwion->mp, cpy_id_list(env->gwion->mp, env->class_def->e->def->base.tmpl->list));
+// cdef->base.tmpl = cpy_tmpl(env->gwion->mp, env->class_def->e->def->base.tmpl);
set_template(t, cdef);
}
if(cdef->base.ext && cdef->base.ext->array)
scan0_class_def_inner(env, cdef) : GW_ERROR;
if(GET_FLAG(cdef, global))
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
- return ret;
+ CHECK_BB(ret)
+ if(cdef->base.tmpl && !cdef->base.tmpl->call) {
+ const Class_Def c = cpy_class_def(env->gwion->mp, cdef);
+ c->base.type = cdef->base.type;
+ c->base.type->e->def = c;
+ }
+ return GW_OK;
}
ANN m_bool scan0_ast(const Env env, Ast ast) {
return GW_OK;
}
+ANN int is_global(const Nspc nspc, Nspc global) {
+ do if(nspc == global)
+ return 1;
+ while((global = global->parent));
+ return 0;
+}
+
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))
((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
exp_setmeta(exp_self(decl), 1);
// SET_FLAG(decl->td, const);
const m_bool global = GET_FLAG(decl->td, global);
- if(global && decl->type->e->owner != env->global_nspc)
+ if(global && !is_global(decl->type->e->owner, env->global_nspc))
ERR_B(exp_self(decl)->pos, _("type '%s' is not global"), decl->type->name)
if(env->context)
env->context->global = 1;
SET_FLAG(decl.td, member);
else if(GET_FLAG(udef, static))
SET_FLAG(decl.td, static);
- CHECK_BB(scan1_exp(env, l->self))
-Var_Decl_List list = decl.list;
-do ADD_REF(list->self->value)
-while((list = list->next));
+ if(udef->tmpl && udef->tmpl->call)
+ CHECK_BB(template_push_types(env, udef->tmpl))
+ const m_bool ret = scan1_exp(env, l->self);
+ if(udef->tmpl && udef->tmpl->call)
+ nspc_pop_type(env->gwion->mp, env->curr);
+ CHECK_BB(ret)
+ Var_Decl_List list = decl.list;
+ do ADD_REF(list->self->value)
+ while((list = list->next));
if(global)
SET_FLAG(decl.td, global);
+ union_flag(udef, ae_flag_scan1);
return GW_OK;
}
Decl_List l = udef->l;
do CHECK_BB(scan1_union_def_action(env, udef, l))
while((l = l->next));
- return GW_OK;
+ return GW_OK;
}
ANN m_bool scan1_union_def(const Env env, const Union_Def udef) {
}
const m_bool ret = scan1_union_def_inner(env, udef);
union_pop(env, udef, scope);
- SET_FLAG(udef, scan1);
+ const Type type = udef->xid || udef->type_xid ? udef->value->type : udef->type;
+ SET_FLAG(type, scan1);
return ret;
}
return ret;
}
-ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
- if(tmpl_base(cdef->base.tmpl))
+ANN m_bool scan1_class_def(const Env env, const Class_Def c) {
+ if(tmpl_base(c->base.tmpl))
return GW_OK;
+ const Class_Def cdef = c->base.type->e->def;
if(GET_FLAG(cdef->base.type, scan1))return GW_OK;
SET_FLAG(cdef->base.type, scan1);
if(cdef->base.ext)
const m_uint scope = union_push(env, udef);
const m_bool ret = scan2_union_decl(env, udef->l);
union_pop(env, udef, scope);
+ SET_FLAG(udef, scan2);
+ union_flag(udef, ae_flag_scan2);
return ret;
}
return ret;
}
-ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) {
- if(tmpl_base(cdef->base.tmpl))
+ANN m_bool scan2_class_def(const Env env, const Class_Def c) {
+ if(tmpl_base(c->base.tmpl))
return GW_OK;
+ const Class_Def cdef = c->base.type->e->def;
if(GET_FLAG(cdef->base.type, scan2))return GW_OK;
SET_FLAG(cdef->base.type, scan2);
if(cdef->base.ext)
if(udef->xid || udef->type_xid || GET_FLAG(udef, global))
env_pop(env, scope);
}
+
+ANN void union_flag(const Union_Def udef, const ae_flag flag) {
+ const Type type = udef->xid || !udef->type_xid ?
+ udef->value->type : udef->type;
+ type->flag |= flag;
+}
class C {
- 1 $ float;
+ <<< 1 $ float >>>;
}
-
+C c;
#!C c;
<<< c.a >>>;
<<< d.a >>>;
-<<< e.a >>>;
<<< c.test() >>>;
<<< d.test() >>>;
-<<< e.test() >>>;
-<<< f.test() >>>;
<<< g.test() >>>;
c.test2(2);