-Subproject commit 2f8759c59db171ce3d4737c7912b3b57d1d6dec6
+Subproject commit 8072d3e7711680521b71fee4f8a9d41363a9f1ce
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
}
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) {
}
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);
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;
#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)
#include "type.h"
#include "context.h"
#include "nspc.h"
+#include "traverse.h"
#include "parse.h"
#include "switch.h"
#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) {
+ if(GET_FLAG(a, pure))
+ free_decl_list(gwion->mp, a->e->def->list);
+ else {
+ 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);
mp_free(gwion->mp, Type, a);
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);
}
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);
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));
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;
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))
#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);
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) ?
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);
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;
}
#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);
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)
+ if(!GET_FLAG(decl->td, static))
+ SET_FLAG(decl->td, member);
}
}
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;
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...",
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;
}
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;
}
(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;
}
} 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;
}
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;
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))
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;
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;
#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))
+ CHECK_BB(scan1_cdef(env, decl->type->e->def))
+ CHECK_BB(scan2_cdef(env, decl->type->e->def))
return GW_OK;
}
}
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))
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;
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;
#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))
}
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) {
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);
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;
}
-*/
#include "env.h"
#include "type.h"
#include "nspc.h"
+#include "traverse.h"
#include "template.h"
#include "vm.h"
#include "parse.h"
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 size += tmpl_set(info, type_decl_resolve(env, call->td));
+ while((call = call->next) && (base = base->next) && ++size);
return size + 16 + 3;
}
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++ = '<';
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) {
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);
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))
+ 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);
#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) {
#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) {
-Subproject commit 6e10d0bd6a9e6731e35cc01d44562e0271755676
+Subproject commit e2cb40dfde5fe6200e3d14954aec316de1883136