return !GET_FLAG(t, emit) ? emit_cdef(emit, t->e->def) : GW_OK;
}
-ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
- Var_Decl_List list = decl->list;
- const uint ref = GET_FLAG(decl->td, ref) || type_ref(decl->type);
- const uint var = exp_self(decl)->emit_var;
- if(GET_FLAG(decl->type, template))
- CHECK_BB(emit_exp_decl_template(emit, decl))
+ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
const m_bool global = GET_FLAG(decl->td, global);
- const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
+ const uint var = exp_self(decl)->emit_var;
+ const uint ref = GET_FLAG(decl->td, ref) || type_ref(decl->type);
+ Var_Decl_List list = decl->list;
do {
const uint r = (list->self->array && list->self->array->exp && ref) ? 0 : (uint)(GET_FLAG(list->self->value, ref) + ref);
-// if(!GET_FLAG(list->self->value, used))
-// continue;
if(GET_FLAG(decl->td, static))
CHECK_BB(emit_exp_decl_static(emit, list->self, r, var))
else if(!global)
if(GET_FLAG(list->self->value->type, nonnull))
emit_add_instr(emit, GWOP_EXCEPT);
} while((list = list->next));
+ return GW_OK;
+}
+
+ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
+ if(GET_FLAG(decl->type, template))
+ CHECK_BB(emit_exp_decl_template(emit, decl))
+ const m_bool global = GET_FLAG(decl->td, global);
+ const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
+ const m_bool ret = emit_decl(emit, decl);
if(global)
emit_pop(emit, scope);
- return GW_OK;
+ return ret;
}
ANN static m_uint vararg_size(const Exp_Call* exp_call, const Vector kinds) {
return ret;
}
+ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda * lambda) {
+ CHECK_BB(emit_func_def(emit, lambda->def))
+ if(GET_FLAG(lambda->def, member))
+ emit_add_instr(emit, RegPushMem);
+ regpushi(emit, (m_uint)lambda->def->base->func->code);
+ return GW_OK;
+}
+
ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda) {
if(lambda->def) {
const m_uint scope = !lambda->owner ?
emit->env->scope->depth : emit_push_type(emit, lambda->owner);
- CHECK_BB(emit_func_def(emit, lambda->def))
- if(GET_FLAG(lambda->def, member))
- emit_add_instr(emit, RegPushMem);
- regpushi(emit, (m_uint)lambda->def->base->func->code);
+ const m_bool ret = emit_lambda(emit, lambda);
if(lambda->owner)
emit_pop(emit, scope);
+ return ret;
} else
emit_add_instr(emit, RegPushImm);
return GW_OK;
return GW_OK;
}
-ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) {
- emit_push_scope(emit);
+ANN static m_bool emit_if(const Emitter emit, const Stmt_If stmt) {
DECL_OB(const Instr, op, = emit_flow(emit, stmt->cond))
CHECK_BB(scoped_stmt(emit, stmt->if_body, 1))
const Instr op2 = emit_add_instr(emit, Goto);
if(stmt->else_body)
CHECK_BB(scoped_stmt(emit, stmt->else_body, 1))
op2->m_val = emit_code_size(emit);
- emit_pop_scope(emit);
return GW_OK;
}
+ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) {
+ emit_push_scope(emit);
+ const m_bool ret = emit_if(emit, stmt);
+ emit_pop_scope(emit);
+ return ret;
+}
+
ANN static m_bool emit_stmt_code(const Emitter emit, const Stmt_Code stmt) {
++emit->env->scope->depth;
const m_bool ret = stmt->stmt_list ? emit_stmt_list(emit, stmt->stmt_list) : 1;
emit_union_offset(udef->l, udef->o);
if(udef->xid || udef->type_xid || global)
emit_pop(emit, scope);
-puts(emit->env->name);
-// SET_FLAG(udef->xid ? udef->value->type : udef->type, emit);
return GW_OK;
}
return decl->type;
}
-ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
+ANN static m_bool check_var(const Env env, const Var_Decl var) {
+ if(env->class_def && !env->scope->depth && env->class_def->e->parent)
+ CHECK_BB(check_exp_decl_parent(env, var))
+ if(var->array && var->array->exp)
+ return check_subscripts(env, var->array);
+ return GW_OK;
+}
+
+ANN static m_bool check_var_td(const Env env, const Var_Decl var, Type_Decl *const td) {
+ const Value v = var->value;
+ if(env->class_def) {
+ if(GET_FLAG(td, member)) {
+ decl_member(env, v);
+ if(isa(env->class_def, env->gwion->type[et_object]) > 0)
+ tuple_info(env, td, var);
+ } else if(GET_FLAG(td, static))
+ decl_static(env, v);
+ } else if(GET_FLAG(td, global) || (env->func && GET_FLAG(env->func->def, global)))
+ SET_FLAG(v, abstract);
+ return GW_OK;
+}
+
+ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
Var_Decl_List list = decl->list;
+ do {
+ const Var_Decl var = list->self;
+ CHECK_BB(check_var(env, var))
+ CHECK_BB(check_var_td(env, var, decl->td))
+ if(is_fptr(env->gwion, decl->type))
+ CHECK_BB(check_fptr_decl(env, var))
+ SET_FLAG(var->value, checked | ae_flag_used);
+ nspc_add_value(env->curr, var->xid, var->value);
+ } while((list = list->next));
+ return GW_OK;
+}
+
+ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) {
if(!decl->td->xid)
return no_xid(env, decl);
if(decl->td->xid->xid == insert_symbol("auto")) { // should be better
clear_decl(env, decl);
CHECK_BO(scan1_exp(env, exp_self(decl)))
CHECK_BO(scan2_exp(env, exp_self(decl)))
+ const Type t_auto = env->gwion->type[et_auto];
if(is_class(env->gwion, decl->type)) {
- do {
- list->self->value->type = env->gwion->type[et_auto];
- } while((list = list->next));
- ((Exp_Decl*)decl)->type = env->gwion->type[et_auto];
+ Var_Decl_List list = decl->list;
+ do list->self->value->type = t_auto;
+ while((list = list->next));
+ ((Exp_Decl*)decl)->type = t_auto;
}
- if(decl->type == env->gwion->type[et_auto])
+ if(decl->type == t_auto)
ERR_O(td_pos(decl->td), _("can't infer type."));
}
if(!decl->type)
}
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
- do {
- const Var_Decl var = list->self;
- const Value v = var->value;
- if(env->class_def && !env->scope->depth && env->class_def->e->parent)
- CHECK_BO(check_exp_decl_parent(env, var))
- if(var->array && var->array->exp)
- CHECK_BO(check_subscripts(env, var->array))
- if(env->class_def) {
- if(GET_FLAG(decl->td, member)) {
- decl_member(env, v);
- if(isa(env->class_def, env->gwion->type[et_object]) > 0)
- tuple_info(env, decl->td, var);
- } else if(GET_FLAG(decl->td, static))
- decl_static(env, v);
- }
- else if(global || (env->func && GET_FLAG(env->func->def, global)))
- SET_FLAG(v, abstract);
- if(is_fptr(env->gwion, decl->type))
- CHECK_BO(check_fptr_decl(env, var))
- SET_FLAG(v, checked | ae_flag_used);
- nspc_add_value(env->curr, var->xid, v);
- } while((list = list->next));
+ const m_bool ret = check_decl(env, decl);
if(global)
env_pop(env, scope);
- return decl->type;
+ return ret > 0 ? decl->type : NULL;
}
const Value exists = template_get_ready(env, v, tmpl_name, i);
if(exists) {
if(env->func == exists->d.func_ref) {
- if(check_call(env, exp) < 0)
+ if(check_call(env, exp) < 0 ||
+ find_func_match(env, env->func, exp->args))
continue;
- CHECK_OO(find_func_match(env, env->func, exp->args))
m_func = env->func;
break;
}
DECL_OO(const Func, func, = value->d.func_ref ?: predefined_func(env, value, exp, tm))
if(!func->def->base->ret_type) { // template fptr
const m_uint scope = env_push(env, value->from->owner_class, value->from->owner);
- CHECK_BO(traverse_func_def(env, func->def))
+ const m_bool ret = traverse_func_def(env, func->def);
env_pop(env, scope);
+ CHECK_BO(ret)
}
exp->m_func = func;
return func->def->base->ret_type;
ANN m_bool check_func_def(const Env env, const Func_Def fdef) {
const Func func = fdef->base->func;
assert(func == fdef->base->func);
+ if(env->class_def) // tmpl ?
+ CHECK_BB(check_parent_match(env, fdef))
if(tmpl_base(fdef->base->tmpl))
- return env->class_def ? check_parent_match(env, fdef) : 1;
+ return GW_OK;
if(fdef->base->td && !fdef->base->td->xid) { // tmpl ?
fdef->base->ret_type = check_td(env, fdef->base->td);
return traverse_func_def(env, fdef);
}
CHECK_BB(check_func_def_override(env, fdef))
DECL_BB(const m_int, scope, = GET_FLAG(fdef, global) ? env_push_global(env) : env->scope->depth)
- if(env->class_def) // tmpl ?
- CHECK_BB(check_parent_match(env, fdef))
const Func former = env->func;
env->func = func;
++env->scope->depth;
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))
+ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
Var_Decl_List list = decl->list;
- ((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
- CHECK_OB(decl->type)
- const m_bool global = GET_FLAG(decl->td, global);
- if(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;
- const m_uint scope = !global ? env->scope->depth : env_push_global(env);
- const Nspc nspc = !global ? env->curr : env->global_nspc;
do {
const Var_Decl var = list->self;
CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
if(var->array) {
if(var->array->exp) {
if(GET_FLAG(decl->td, ref))
- ERR_B(td_pos(decl->td), _("ref array must not have array expression.\n"
+ ERR_B(var->array->exp->pos, _("ref array must not have array expression.\n"
"e.g: int @my_array[];\nnot: int @my_array[2];"))
CHECK_BB(scan1_exp(env, var->array->exp))
}
if(env->class_def)
type_contains(env->class_def, t);
const Value v = var->value = former ?: new_value(env->gwion->mp, t, s_name(var->xid));
- nspc_add_value(nspc, var->xid, v);
+ nspc_add_value(env->curr, var->xid, v);
v->flag = decl->td->flag;
v->type = t;
if(var->array && !var->array->exp)
valuefrom(env, v->from);
} while((list = list->next));
((Exp_Decl*)decl)->type = decl->list->self->value->type;
+ return GW_OK;
+}
+
+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);
+ CHECK_OB(decl->type)
+ const m_bool global = GET_FLAG(decl->td, global);
+ if(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;
+ const m_uint scope = !global ? env->scope->depth : env_push_global(env);
+ const m_bool ret = scan1_decl(env, decl);
if(global)
env_pop(env, scope);
- return GW_OK;
+ return ret;
}
ANN static inline m_bool scan1_exp_binary(const Env env, const Exp_Binary* bin) {
ANN static m_bool scan2_stmt(const Env, const Stmt);
ANN static m_bool scan2_stmt_list(const Env, Stmt_List);
-ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) {
- const m_bool global = GET_FLAG(decl->td, global);
- const m_uint scope = !global ? env->scope->depth : env_push_global(env);
-{
+ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
const Type t = get_type(decl->type);
if(GET_FLAG(t, template) && !GET_FLAG(t, scan2))
CHECK_BB(scan2_cdef(env, t->e->def))
-}
Var_Decl_List list = decl->list;
do {
const Var_Decl var = list->self;
CHECK_BB(scan2_exp(env, array))
nspc_add_value(env->curr, var->xid, var->value);
} while((list = list->next));
+ return GW_OK;
+}
+
+ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) {
+ const m_bool global = GET_FLAG(decl->td, global);
+ const m_uint scope = !global ? env->scope->depth : env_push_global(env);
+ const m_bool ret = scan2_decl(env, decl);
if(global)
env_pop(env, scope);
- return GW_OK;
+ return ret;
}
ANN static Value arg_value(MemPool p, const Arg_List list) {
return GW_OK;
}
+ANN static m_bool scan2_union_decl(const Env env, const Decl_List list) {
+ Decl_List l = list;
+ do CHECK_BB(scan2_exp_decl(env, &l->self->d.exp_decl))
+ while((l = l->next));
+ return GW_OK;
+}
+
ANN m_bool scan2_union_def(const Env env, const Union_Def udef) {
if(tmpl_base(udef->tmpl))
return GW_OK;
const m_uint scope = union_push(env, udef);
- Decl_List l = udef->l;
- do CHECK_BB(scan2_exp(env, l->self))
- while((l = l->next));
+ const m_bool ret = scan2_union_decl(env, udef->l);
union_pop(env, udef, scope);
- return GW_OK;
+ return ret;
}
static const _exp_func stmt_func[] = {