#define __TRAVERSE
ANN m_bool traverse_ast(const Env, const Ast);
ANN m_bool traverse_class_def(const Env, const Class_Def);
-ANN m_bool traverse_template(const Env, const Class_Def);
ANN m_bool traverse_func_def(const Env, const Func_Def);
ANN m_bool traverse_stmt_union(const Env, const Stmt_Union);
ANN m_bool traverse_stmt_enum(const Env, const Stmt_Enum);
ANN static inline m_bool emit_exp_decl_template(const Emitter emit, const Exp_Decl* decl) {
const Type t = typedef_base(decl->type);
+ CHECK_BB(traverse_class_def(emit->env, t->e->def))
return !GET_FLAG(t, emit) ? emit_class_def(emit, t->e->def) : GW_OK;
}
CHECK_BB(emit_exp_decl_static(emit, list->self, r, var))
else if(!global)
CHECK_BB(emit_exp_decl_non_static(emit, list->self, r, var))
-else
+ else
CHECK_BB(emit_exp_decl_global(emit, list->self, r, var))
} while((list = list->next));
if(global)
ANN static m_bool emit_template_code(const Emitter emit, const Func f) {
if(GET_FLAG(f, ref))
- CHECK_BB(traverse_template(emit->env, f->value_ref->owner_class->e->def))
+ 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))
emit_pop_code(emit);
}
-ANN static m_bool emit_class_def(const Emitter emit, const Class_Def class_def) {
- const Type type = class_def->base.type;
+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;
- if(tmpl_class_base(class_def->tmpl))
+ if(tmpl_class_base(cdef->tmpl))
return GW_OK;
- if(class_def->base.ext && ((/*!GET_FLAG(type->e->parent, emit) &&*/
- GET_FLAG(class_def->base.ext, typedef)) || class_def->base.ext->types)) {
- const Type base = class_def->base.ext->array ?
+ if(cdef->base.ext && ((/*!GET_FLAG(type->e->parent, emit) &&*/
+ GET_FLAG(cdef->base.ext, typedef)) || cdef->base.ext->types)) {
+ const Type base = cdef->base.ext->array ?
array_base(type->e->parent) : type->e->parent;
if(!base->nspc->pre_ctor)
CHECK_BB(emit_class_def(emit, base->e->def))
nspc->info->class_data = (m_bit*)xcalloc(1, nspc->info->class_data_size);
emit_class_push(emit, type);
emit_class_code(emit, type->name);
- if(class_def->base.ext && class_def->base.ext->array)
- CHECK_BB(emit_array_extend(emit, type->e->parent, class_def->base.ext->array->exp))
- if(class_def->body) {
- Class_Body body = class_def->body;
+ if(cdef->base.ext && cdef->base.ext->array)
+ CHECK_BB(emit_array_extend(emit, type->e->parent, cdef->base.ext->array->exp))
+ if(cdef->body) {
+ const m_uint scope = env_push_type(emit->env, cdef->base.type);
+ if(cdef->tmpl)
+ template_push_types(emit->env, cdef->tmpl->list.list, cdef->tmpl->base);
+ Class_Body body = cdef->body;
do CHECK_BB(emit_section(emit, body->section))
while((body = body->next));
+ if(cdef->tmpl)
+ nspc_pop_type(emit->env->gwion->mp, emit->env->curr);
+ env_pop(emit->env, scope);
}
emit_class_finish(emit, nspc);
- SET_FLAG(class_def->base.type->nspc->pre_ctor, ctor);
+ SET_FLAG(cdef->base.type->nspc->pre_ctor, ctor);
emit_class_pop(emit);
SET_FLAG(type, emit);
return GW_OK;
ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos) {
const Value v = nspc_lookup_value0(env->curr, s);
- if(!v)
+ if(!v || isa(v->type, t_class) > 0)
return GW_OK;
env_err(env, pos,
"'%s' already declared as variable of type '%s'.", s_name(s), v->type->name);
if(GET_FLAG(decl->type , template)) {
const Type t = typedef_base(decl->type);
if(!GET_FLAG(t, check))
- CHECK_BO(traverse_template(env, t->e->def))
+ CHECK_BO(traverse_class_def(env, t->e->def))
}
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
return check_lambda_call(env, exp);
if(GET_FLAG(exp->func->type->e->d.func, ref)) {
const Value value = exp->func->type->e->d.func->value_ref;
- CHECK_BO(traverse_template(env, value->owner_class->e->def))
+ CHECK_BO(traverse_class_def(env, value->owner_class->e->def))
}
if(exp->args)
CHECK_OO(check_exp(env, exp->args))
if(td->types) {
const Type t = parent->array_depth ? array_base(parent) : parent;
if(!GET_FLAG(t, checked))
- CHECK_BB(traverse_template(env, t->e->def))
+ CHECK_BB(traverse_class_def(env, t->e->def))
}
if(!GET_FLAG(parent, checked))
CHECK_BB(check_class_def(env, parent->e->def))
ANN static m_bool check_class_body(const Env env, const Class_Def cdef) {
const m_uint scope = env_push_type(env, cdef->base.type);
Class_Body body = cdef->body;
+ if(cdef->tmpl)
+ template_push_types(env, cdef->tmpl->list.list, cdef->tmpl->base);
do CHECK_BB(check_section(env, body->section))
while((body = body->next));
+ if(cdef->tmpl)
+ nspc_pop_type(env->gwion->mp, env->curr);
env_pop(env, scope);
return GW_OK;
}
#include "vm.h"
#include "parse.h"
#include "traverse.h"
+#include "template.h"
ANN static Value mk_class(const Env env, const Type base) {
const Type t = type_copy(env->gwion->mp, t_class);
if(cdef->body) {
Class_Body body = cdef->body;
const m_uint scope = env_push_type(env, cdef->base.type);
+ if(cdef->tmpl)
+ template_push_types(env, cdef->tmpl->list.list, cdef->tmpl->base);
do CHECK_BB(scan0_section(env, body->section))
while((body = body->next));
+ if(cdef->tmpl)
+ nspc_pop_type(env->gwion->mp, env->curr);
env_pop(env, scope);
}
(void)mk_class(env, cdef->base.type);
ANN static m_bool scan1_class_body(const Env env, const Class_Def cdef) {
const m_uint scope = env_push_type(env, cdef->base.type);
Class_Body body = cdef->body;
+ if(cdef->tmpl)
+ template_push_types(env, cdef->tmpl->list.list, cdef->tmpl->base);
do CHECK_BB(scan1_section(env, body->section))
while((body = body->next));
+ if(cdef->tmpl)
+ nspc_pop_type(env->gwion->mp, env->curr);
env_pop(env, scope);
return GW_OK;
}
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(template_push_types(env, decl->base->tmpl->list.list, decl->td->types));
CHECK_BB(scan1_class_def(env, decl->type->e->def))
CHECK_BB(scan2_class_def(env, decl->type->e->def))
- nspc_pop_type(env->gwion->mp, env->curr);
return GW_OK;
}
ANN static m_bool scan2_class_body(const Env env, const Class_Def cdef) {
const m_uint scope = env_push_type(env, cdef->base.type);
Class_Body body = cdef->body;
+ if(cdef->tmpl)
+ template_push_types(env, cdef->tmpl->list.list, cdef->tmpl->base);
do CHECK_BB(scan2_section(env, body->section))
while((body = body->next));
+ if(cdef->tmpl)
+ nspc_pop_type(env->gwion->mp, env->curr);
env_pop(env, scope);
return GW_OK;
}
"you must provide template types for type '%s'", t->name)
if(template_match(t->e->def->tmpl->list.list, type->types) < 0)
ERR_O(type->xid->pos, "invalid template types number")
- CHECK_BO(template_push_types(env, t->e->def->tmpl->list.list, type->types))
const Class_Def a = template_class(env, t->e->def, type->types);
SET_FLAG(a, ref);
if(a->base.type)
- POP_RET(a->base.type);
+ return a->base.type;
+ a->tmpl = new_tmpl_class(env->gwion->mp, get_total_type_list(env, t), 0);
+ a->tmpl->base = type->types;
+
CHECK_BO(scan0_class_def(env, a))
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))
- nspc_pop_type(env->gwion->mp, env->curr);
if(t->nspc->dtor) {
a->base.type->nspc->dtor = t->nspc->dtor;
SET_FLAG(a->base.type, dtor);
ADD_REF(t->nspc->dtor)
}
- a->tmpl = new_tmpl_class(env->gwion->mp, get_total_type_list(env, t), 0);
- a->tmpl->base = type->types;
nspc_add_type(t->e->owner, insert_symbol(a->base.type->name), a->base.type);
return a->base.type;
} else if(type->types)
#include "vm.h"
#include "gwion.h"
-ANN m_bool traverse_template(const Env env, const Class_Def def) {
- CHECK_BB(template_push_types(env, def->tmpl->list.list, def->tmpl->base))
- CHECK_BB(traverse_class_def(env, def))
- POP_RET(1);
-}
-
ANN m_bool traverse_func_template(const Env env, const Func_Def def, const Type_List types) {
CHECK_BB(template_push_types(env, def->tmpl->list, types))
return traverse_func_def(env, def);
-template<~A, B~>
-class C {
+class<~A,B~> C {
A a;
B b;
fun A test() {