-Subproject commit 4f6d18f266ba8c3fc3a8714e3abf043010f1afb6
+Subproject commit bfa25ccbd71243abe8d89b3615e43395c5493e30
ANN static void clean_func_def(Clean *a, Func_Def b) {
clean_func_base(a, b->base);
++a->scope;
- if(b->d.code && !GET_FLAG(b, builtin))
+ if(b->d.code && !GET_FLAG(b->base, builtin))
clean_stmt(a, b->d.code);
+ else
+ b->d.code = NULL;
--a->scope;
}
ANN void func_def_cleaner(const Gwion gwion, Func_Def b) {
Clean a = { .gwion=gwion };
clean_func_def(&a, b);
- if(GET_FLAG(b, builtin))
- b->d.code = NULL;
free_func_def(gwion->mp, b);
}
CHECK_BB(emit_exp(emit, exp_call->args))
emit_exp_addref(emit, exp_call->args, -exp_totalsize(exp_call->args));
}
- if(exp_call->m_func && GET_FLAG(exp_call->m_func->def, variadic))
+ if(exp_call->m_func && GET_FLAG(exp_call->m_func->def->base, variadic))
emit_func_arg_vararg(emit, exp_call);
return GW_OK;
}
back->m_val = 0;
}
} else if(emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
- if(GET_FLAG(f->def, op)) {
+ if(GET_FLAG(f->def->base, op)) {
const Instr back = (Instr)vector_back(&emit->code->instr);
back->m_val = (m_uint)f;
} else {
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) && !exp_getvar(exp_self(lambda)))
+ if(GET_FLAG(lambda->def->base, member) && !exp_getvar(exp_self(lambda)))
emit_add_instr(emit, RegPushMem);
regpushi(emit, (m_uint)lambda->def->base->func->code);
return GW_OK;
}
ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
- if(GET_FLAG(func->def, typedef))
+ if(GET_FLAG(func->def->base, typedef))
return emit_internal(emit, func);
else
return finalyze(emit, FuncReturn);
ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
if(fdef->base->args)
emit_func_def_args(emit, fdef->base->args);
- if(GET_FLAG(fdef, variadic))
+ if(GET_FLAG(fdef->base, variadic))
stack_alloc(emit);
if(fdef->d.code)
CHECK_BB(scoped_stmt(emit, fdef->d.code, 1))
static ANN int fdef_is_file_global(const Emitter emit, const Func_Def fdef) {
return isa(fdef->base->func->value_ref->type, emit->gwion->type[et_lambda]) < 0 &&
- !emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl &&
+ !emit->env->class_def && !GET_FLAG(fdef->base, global) && !fdef->base->tmpl &&
!emit->env->scope->depth;
}
ANEW ANN static Func_Base* gwi_func_base(const Gwi gwi, ImportCK *ck) {
const Arg_List arg_list = make_dll_arg_list(&gwi->ck->v);
- Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag);
+ Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag | ae_flag_builtin);
ck->td = NULL;
if(ck->tmpl) {
base->tmpl = gwi_tmpl(gwi);
ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) {
Func_Base* base = gwi_func_base(gwi, ck);
- const Func_Def fdef = new_func_def(gwi->gwion->mp, base,
- NULL, ck->flag | ae_flag_builtin, loc(gwi));
+ const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL, loc(gwi));
fdef->d.dl_func_ptr = (void*)(m_uint)ck->addr;
if(base->tmpl)
- SET_FLAG(fdef, template);
+ SET_FLAG(fdef->base, template);
return fdef;
}
dt->def = def;
dt->owner = v->from->owner;
dt->owner_class = v->from->owner_class;
- SET_FLAG(def, template);
+ SET_FLAG(def->base, template);
return def;
}
}
ANN static inline m_bool fptr_arity(struct FptrInfo *info) {
- return GET_FLAG(info->lhs->def, variadic) ==
- GET_FLAG(info->rhs->def, variadic);
+ return GET_FLAG(info->lhs->def->base, variadic) ==
+ GET_FLAG(info->rhs->def->base, variadic);
}
ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
}
if(base || arg)
ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
- l->def->flag = def->flag;
+ l->def->base->flag = def->base->flag;
l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td);
- SET_FLAG(l->def, abstract); // mark as non immediate lambda
+ SET_FLAG(l->def->base, abstract); // mark as non immediate lambda
map_set(&env->curr->info->func->map, (m_uint)l->def->base, env->scope->depth);
const m_bool ret = check_traverse_fdef(env, l->def);
map_remove(&env->curr->info->func->map, (m_uint)l->def->base);
// create a matching signature
// TODO: we could check first if there a matching existing one
Func_Base *const fbase = cpy_func_base(env->gwion->mp, bin->lhs->info->type->e->d.func->def->base);
- const Fptr_Def fptr_def = new_fptr_def(env->gwion->mp, fbase, bin->lhs->info->type->e->d.func->def->flag);
+ const Fptr_Def fptr_def = new_fptr_def(env->gwion->mp, fbase, bin->lhs->info->type->e->d.func->def->base->flag);
char name[13 + strlen(env->curr->name) +
num_digit(bin->rhs->pos->first.line) + num_digit(bin->rhs->pos->first.column)];
sprintf(name, "generated@%s@%u:%u", env->curr->name, bin->rhs->pos->first.line, bin->rhs->pos->first.column);
// emit_add_instr(emit, DotTmplVal);
else {
if(GET_FLAG(member->t_base, struct)) {
- if(!GET_FLAG(f->def, static)) {
+ if(!GET_FLAG(f->def->base, static)) {
exp_setvar(member->base, 1);
emit_exp(emit, member->base);
}
}
static ID_CHECK(idck_vararg) {
- if(env->func && GET_FLAG(env->func->def, variadic))
+ if(env->func && GET_FLAG(env->func->def->base, variadic))
return nonnul_type(env, exp_self(prim)->info->type);
ERR_O(exp_self(prim)->pos, _("'vararg' must be used inside variadic function"))
}
CHECK_BO(not_from_owner_class(env, env->class_def, value, prim_pos(data)))
const Value v = value ?: find_value(env->class_def, var);
if(v) {
- if(env->func && GET_FLAG(env->func->def, static) && GET_FLAG(v, member))
+ if(env->func && GET_FLAG(env->func->def->base, static) && GET_FLAG(v, member))
ERR_O(prim_pos(data),
_("non-static member '%s' used from static function."), s_name(var))
}
return v;
- } else if(SAFE_FLAG(env->class_def, global) || (env->func && GET_FLAG(env->func->def, global))) {
+ } else if(SAFE_FLAG(env->class_def, global) || (env->func && GET_FLAG(env->func->def->base, global))) {
if(!SAFE_FLAG(value, abstract))
ERR_O(prim_pos(data),
_("non-global variable '%s' used from global function/class."), s_name(var))
}
prim_self(data)->value = v;
if(env->func) {
- if(GET_FLAG(env->func->def, abstract))
+ if(GET_FLAG(env->func->def->base, abstract))
CHECK_BO(lambda_valid(env, prim_self(data)))
if(env->func && !GET_FLAG(v, const) && v->from->owner)
UNSET_FLAG(env->func, pure);
Arg_List e1 = func->def->base->args;
while(e) {
if(!e1) {
- if(GET_FLAG(func->def, variadic))
+ if(GET_FLAG(func->def->base, variadic))
return func;
CHECK_OO(func->next);
return find_func_match_actual(env, func->next, args, implicit, specific);
}
ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) {
- const m_bool ret = GET_FLAG(fdef, valid) || check_traverse_fdef(env, fdef) > 0;
+ const m_bool ret = GET_FLAG(fdef->base, valid) || check_traverse_fdef(env, fdef) > 0;
if(ret) {
const Func f = fdef->base->func;
const Func next = f->next;
fbase->tmpl->base = 0;
fbase->tmpl->call = cpy_type_list(env->gwion->mp, types);
if(template_push_types(env, fbase->tmpl) > 0) {
- const Fptr_Def fptr = new_fptr_def(env->gwion->mp, fbase, base->flag);
+ const Fptr_Def fptr = new_fptr_def(env->gwion->mp, fbase, base->base->flag);
if(traverse_fptr_def(env, fptr) > 0 &&
(base->base->ret_type = known_type(env, base->base->td)) &&
(!exp->args || !!check_exp(env, exp->args))) {
SET_FLAG(value->d.func_ref, builtin);
}
const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
- SET_FLAG(fdef, template);
+ SET_FLAG(fdef->base, template);
fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types);
fdef->base->tmpl->base = i;
if((m_func = ensure_tmpl(env, fdef, exp)))
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
.scope=env->scope->depth, .flag=ae_flag_check };
CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
- SET_FLAG(func->def, typedef);
+ SET_FLAG(func->def->base, typedef);
const m_bool ret = check_traverse_fdef(env, func->def);
if(es.run)
envset_pop(&es, v->from->owner_class);
ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
CHECK_BO(check_traverse_fdef(env, l->def))
if(env->class_def)
- SET_FLAG(l->def, member);
+ SET_FLAG(l->def->base, member);
((Exp_Call*)exp)->m_func = l->def->base->func;
return l->def->base->ret_type ?: (l->def->base->ret_type = env->gwion->type[et_void]);
}
}
ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) {
- if(GET_FLAG(parent->def, static) != GET_FLAG(fdef, static)) {
+ if(GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) {
const m_str c_name = fdef->base->func->value_ref->from->owner_class->name;
const m_str p_name = parent->value_ref->from->owner_class->name;
const m_str f_name = s_name(fdef->base->xid);
_("function '%s.%s' ressembles '%s.%s' but cannot override...\n"
" ...(reason: '%s.%s' is declared as 'static')"),
c_name, f_name, p_name, c_name,
- GET_FLAG(fdef, static) ? c_name : p_name, f_name)
+ GET_FLAG(fdef->base, static) ? c_name : p_name, f_name)
}
return !fdef->base->tmpl ? isa(fdef->base->ret_type, parent->def->base->ret_type) : GW_OK;
}
ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
if(fdef->base->args)
CHECK_BB(check_func_args(env, fdef->base->args))
- if(!GET_FLAG(fdef, builtin)) {
+ if(!GET_FLAG(fdef->base, builtin)) {
if(fdef->d.code)
CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
} else
return check_traverse_fdef(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)
+ DECL_BB(const m_int, scope, = GET_FLAG(fdef->base, global) ? env_push_global(env) : env->scope->depth)
const Func former = env->func;
env->func = func;
++env->scope->depth;
nspc_push_value(env->gwion->mp, env->curr);
struct Op_Import opi = { };
- if(GET_FLAG(fdef, op)) {
+ if(GET_FLAG(fdef->base, op)) {
func_operator(f, &opi);
operator_suspend(env->curr, &opi);
}
const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
- if(GET_FLAG(fdef, op))
+ if(GET_FLAG(fdef->base, op))
operator_resume(&opi);
nspc_pop_value(env->gwion->mp, env->curr);
--env->scope->depth;
env->func = former;
if(ret > 0)
- SET_FLAG(fdef, valid);
- if(GET_FLAG(fdef, global))
+ SET_FLAG(fdef->base, valid);
+ if(GET_FLAG(fdef->base, global))
env_pop(env,scope);
return ret;
}
ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) {
opi->op =fdef->base->xid;
const m_str str = s_name(fdef->base->xid);
- const uint is_unary = GET_FLAG(fdef, unary) +
+ const uint is_unary = GET_FLAG(fdef->base, unary) +
(!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
const Arg_List args = fdef->base->args;
opi->lhs = is_unary ? NULL :
context_global(env);
SET_FLAG(fptr->value, global);
SET_FLAG(fptr->base->func, global);
- SET_FLAG(def, global);
+ SET_FLAG(def->base, global);
} else if(!GET_FLAG(fptr->base, static)) {
SET_FLAG(fptr->value, member);
SET_FLAG(fptr->base->func, member);
- SET_FLAG(def, member);
+ SET_FLAG(def->base, member);
def->stack_depth += SZ_INT;
} else {
SET_FLAG(fptr->value, static);
SET_FLAG(fptr->base->func, static);
- SET_FLAG(def, static);
+ SET_FLAG(def->base, static);
}
- if(GET_FLAG(def, variadic))
+ if(GET_FLAG(def->base, variadic))
def->stack_depth += SZ_INT;
fptr->value->from->owner_class = env->class_def;
}
static void fptr_def(const Env env, const Fptr_Def fptr) {
const Func_Def def = new_func_def(env->gwion->mp,
cpy_func_base(env->gwion->mp, fptr->base),
- NULL, fptr->base->flag, loc_cpy(env->gwion->mp, td_pos(fptr->base->td)));
+ NULL, loc_cpy(env->gwion->mp, td_pos(fptr->base->td)));
fptr->base->func = new_func(env->gwion->mp, s_name(fptr->base->xid), def);
fptr->value->d.func_ref = fptr->base->func;
fptr->base->func->value_ref = fptr->value;
ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
if(fdef->base->args) {
- if(!GET_FLAG(fdef, builtin))
+ if(!GET_FLAG(fdef->base, builtin))
CHECK_BB(scan1_fdef_args(env, fdef->base->args))
CHECK_BB(scan1_args(env, fdef->base->args))
}
- if(!GET_FLAG(fdef, builtin) && fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
+ if(!GET_FLAG(fdef->base, builtin) && fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
CHECK_BB(scan1_stmt_list(env, fdef->d.code->d.stmt_code.stmt_list))
return GW_OK;
}
ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
if(fdef->base->td)
CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
- if(GET_FLAG(fdef, typedef))
+ if(GET_FLAG(fdef->base, typedef))
CHECK_BB(scan_internal(env, fdef->base))
- else if(GET_FLAG(fdef, op) && env->class_def)
- SET_FLAG(fdef, static);
+ else if(GET_FLAG(fdef->base, op) && env->class_def)
+ SET_FLAG(fdef->base, static);
RET_NSPC(scan1_fbody(env, fdef))
return GW_OK;
}
ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) {
if(fdef->base->td)
- CHECK_BB(env_storage(env, fdef->flag, td_pos(fdef->base->td)))
+ CHECK_BB(env_storage(env, fdef->base->flag, td_pos(fdef->base->td)))
CHECK_BB(scan1_fdef_defined(env, fdef))
if(tmpl_base(fdef->base->tmpl))
return scan1_fdef_base_tmpl(env, fdef->base);
if(GET_FLAG(f, member))
SET_FLAG(v, member);
else SET_FLAG(v, static);
- SET_ACCESS(d, v)
+ SET_ACCESS(d->base, v)
}
d->base->func = v->d.func_ref = f;
return f->value_ref = v;
const m_bool base = tmpl_base(f->base->tmpl);
const m_bool tmpl = GET_FLAG(overload, template);
if(isa(overload->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, overload->type)) {
- if(!GET_FLAG(f, typedef))
+ if(!GET_FLAG(f->base, typedef))
ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
}
- if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f, template)))
+ if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f->base, template)))
ERR_B(f->pos, _("must overload template function with template"))
return GW_OK;
}
if(env->class_def) {
if(GET_FLAG(env->class_def, template))
SET_FLAG(func, ref);
- if(!GET_FLAG(f, static))
+ if(!GET_FLAG(f->base, static))
SET_FLAG(func, member);
}
return func;
nspc_add_func(env->curr, f->base->xid, func);
} else
func->vt_index = ++overload->from->offset;
- if(GET_FLAG(f, builtin)) {
+ if(GET_FLAG(f->base, builtin)) {
CHECK_BB(scan2_func_def_builtin(env->gwion->mp, func, func->name))
SET_FLAG(func, builtin);
SET_FLAG(value, builtin);
}
ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
- if(!GET_FLAG(f, builtin))
+ if(!GET_FLAG(f->base, builtin))
SET_FLAG(f->base->func, pure);
if(f->base->xid == insert_symbol("@dtor"))
SET_FLAG(env->class_def, dtor);
nspc_add_func(env->curr, insert_symbol(func->name), func);
const Value v = func_value(env, func, overload);
scan2_func_def_flag(env, f);
- if(GET_FLAG(f, builtin))
+ if(GET_FLAG(f->base, builtin))
CHECK_BO(scan2_func_def_builtin(env->gwion->mp, func, func->name))
nspc_add_value(env->curr, insert_symbol(func->name), v);
return v;
f->base->func = base;
if(f->base->args)
CHECK_BB(scan2_args(f))
- if(!GET_FLAG(f, builtin) && f->d.code)
+ if(!GET_FLAG(f->base, builtin) && f->d.code)
CHECK_BB(scan2_func_def_code(env, f))
if(!base) {
- if(GET_FLAG(f, op))
+ if(GET_FLAG(f->base, op))
CHECK_BB(scan2_func_def_op(env, f))
SET_FLAG(f->base->func->value_ref, valid);
}
}
static inline int is_cpy(const Func_Def fdef) {
- return GET_FLAG(fdef, global) ||
+ return GET_FLAG(fdef->base, global) ||
(fdef->base->tmpl && !fdef->base->tmpl->call);
}
ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) {
- if(GET_FLAG(fdef, global))
+ if(GET_FLAG(fdef->base, global))
env->context->global = 1;
const Func_Def f = !is_cpy(fdef) ?
fdef : scan2_cpy_fdef(env, fdef);
- const m_uint scope = !GET_FLAG(f, global) ? env->scope->depth : env_push_global(env);
- f->stack_depth = (env->class_def && !GET_FLAG(f, static) && !GET_FLAG(f, global)) ? SZ_INT : 0;
- if(GET_FLAG(f, variadic))
+ const m_uint scope = !GET_FLAG(f->base, global) ? env->scope->depth : env_push_global(env);
+ f->stack_depth = (env->class_def && !GET_FLAG(f->base, static) && !GET_FLAG(f->base, global)) ? SZ_INT : 0;
+ if(GET_FLAG(f->base, variadic))
f->stack_depth += SZ_INT;
const m_bool ret = scanx_fdef(env, env, f, (_exp_func)scan2_fdef);
- if(GET_FLAG(f, global))
+ if(GET_FLAG(f->base, global))
env_pop(env, scope);
CHECK_BB(ret)
fdef->base->func = f->base->func; // only needed if 'is_cpy()'
const Func_Def def = cpy_func_def(env->gwion->mp, t->e->d.func->def);
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;
+ func->flag = def->base->flag;
value->d.func_ref = func;
value->from->owner = t->e->owner;
value->from->owner_class = t->e->owner_class;