From: fennecdjay Date: Wed, 2 Oct 2019 21:59:21 +0000 (+0200) Subject: :art: Check internal usr operators X-Git-Tag: nightly~2198^2~169 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=12eda37b49eda31b38107ca2903099a2450b020e;p=gwion.git :art: Check internal usr operators --- diff --git a/ast b/ast index 03bc1aa5..52b685d2 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 03bc1aa5abcd342240fd41ad0c46e2f824940b2f +Subproject commit 52b685d2b39fa1cdee9220d9a2f2eff18bb82424 diff --git a/src/emit/emit.c b/src/emit/emit.c index 744195ba..58b0460f 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1754,14 +1754,21 @@ ANN static void emit_func_def_return(const Emitter emit) { emit_add_instr(emit, MemoizeStore); } -ANN static void emit_func_def_code(const Emitter emit, const Func func) { - const m_bool is_dtor = func->def->base->xid == insert_symbol("@dtor");// could be get flag - func->code = finalyze(emit, !is_dtor ? FuncReturn : DTOR_EOC); - if(is_dtor) { - emit->env->class_def->nspc->dtor = func->code; - ADD_REF(func->code) - } else if(func->def->base->xid == insert_symbol("@gack")) - emit->env->class_def->e->gack = func->code; +ANN static VM_Code emit_internal(const Emitter emit, const Func f) { + if(f->def->base->xid == insert_symbol("@dtor")) { + emit->env->class_def->nspc->dtor = f->code = finalyze(emit, DTOR_EOC); + ADD_REF(f->code) + return f->code; + } else if(f->def->base->xid == insert_symbol("@gack")) + emit->env->class_def->e->gack = f->code; + return finalyze(emit, FuncReturn); +} + +ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) { + if(GET_FLAG(func->def, typedef)) + return emit_internal(emit, func); + else + return finalyze(emit, FuncReturn); } ANN static m_bool _fdef_body(const Emitter emit, const Func_Def fdef) { @@ -1820,7 +1827,7 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def fdef) { if(fdef->base->tmpl) emit_pop_type(emit); if(ret > 0) { - emit_func_def_code(emit, func); + func->code = emit_func_def_code(emit, func); emit->env->func = former; if(!emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl) emit_func_def_global(emit, func->value_ref); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 056f0a8c..e96957ff 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -346,9 +346,50 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List l) { return GW_OK; } +ANN static m_bool class_internal(const Env env, const Func_Base *base) { + if(!env->class_def) + ERR_B(td_pos(base->td), _("'%s' must be in class def!!"), s_name(base->xid)) + if(base->args) + ERR_B(td_pos(base->td), _("'%s' must not have args"), s_name(base->xid)) + if(base->ret_type != env->gwion->type[et_void]) + ERR_B(td_pos(base->td), _("'%s' must return 'void'"), s_name(base->xid)) + return GW_OK; +} + +ANN static inline m_bool scan_internal_arg(const Env env, const Func_Base *base) { + if(base->args && !base->args->next) + return GW_OK; + ERR_B(td_pos(base->td), _("'%s' must have one (and only one) argument"), base->xid) +} + +ANN static inline m_bool scan_internal_int(const Env env, const Func_Base *base) { + CHECK_BB(scan_internal_arg(env, base)) + if(isa(base->ret_type, env->gwion->type[et_int]) > 0) + return GW_OK; + ERR_B(td_pos(base->td), _("'%s' must must return 'int'"), base->xid) +} + +ANN static m_bool scan_internal(const Env env, const Func_Base *base) { + const Symbol op = base->xid; + if(op == insert_symbol("@dtor") || op == insert_symbol("@gack")) + return class_internal(env, base); + if(op == insert_symbol("@implicit")) + return scan_internal_arg(env, base); + if(op == insert_symbol("@access") || + op == insert_symbol("@repeat") || + op == insert_symbol("@conditionnal") || + op == insert_symbol("@unconditionnal")) + return scan_internal_int(env, base); + return GW_ERROR; +} + 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)) + CHECK_BB(scan_internal(env, fdef->base)) + else if(GET_FLAG(fdef, op) && env->class_def) + SET_FLAG(fdef, static); if(fdef->base->args) CHECK_BB(scan1_args(env, fdef->base->args)) if(!GET_FLAG(fdef, builtin) && fdef->d.code) @@ -361,14 +402,6 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { 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, op)) { - if(fdef->base->xid == insert_symbol("@dtor") || fdef->base->xid == insert_symbol("@gack")) { - if(!env->class_def) - ERR_B(td_pos(fdef->base->td), _("'%s' must be in class def!!"), s_name(fdef->base->xid)) - if(fdef->base->args)exit(3); - } else if(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;