From 9a5550cfa25f98ad412c44b3557c8d695538fd54 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Tue, 15 Sep 2020 22:18:23 +0200 Subject: [PATCH] :art: Parse fptr template flag --- ast | 2 +- include/env/env.h | 1 + include/import/special.h | 2 +- include/pass.h | 11 ++++++++--- src/compile.c | 16 ++++++++++------ src/env/env.c | 7 ++++++- src/gwiondata.c | 2 +- src/import/import_special.c | 2 +- src/parse/check.c | 6 +++--- src/parse/template.c | 2 +- src/pass.c | 14 +++++++++++--- 11 files changed, 44 insertions(+), 21 deletions(-) diff --git a/ast b/ast index 95aeae8c..0b64428e 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 95aeae8c6dae2652dc092dd36bc0d9caa12a20a7 +Subproject commit 0b64428ec56f99521ef33990cd0c725573b8418b diff --git a/include/env/env.h b/include/env/env.h index 172008a1..b07f2f87 100644 --- a/include/env/env.h +++ b/include/env/env.h @@ -51,6 +51,7 @@ ANN void env_add_type(const Env, const Type); ANN Type find_type(const Env, Type_Decl*); ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos); ANN m_bool type_engine_check_prog(const Env, const Ast); +ANN m_bool type_engine_clean_prog(const Env, const m_bool*); ANN m_bool traverse_func_template(const Env, const Func_Def); ANN2(1,3) void env_err(const Env, const loc_t pos, const m_str fmt, ...); ANN Value global_string(const Env env, const m_str str); diff --git a/include/import/special.h b/include/import/special.h index afb9654d..4d7e5f83 100644 --- a/include/import/special.h +++ b/include/import/special.h @@ -6,7 +6,7 @@ #define FREEARG(a) ANN void a(Instr instr NUSED, void *gwion NUSED) typedef void (*f_freearg)(Instr, void*); ANN void gwi_register_freearg(const Gwi, const f_instr, const f_freearg); -ANN void gwi_register_pass(const Gwi, const m_str, const compilation_pass); +ANN void gwi_register_pass(const Gwi, const m_str, const compilation_pass[2]); ANN void gwi_reserve(const Gwi, const m_str); typedef struct SpecialId_* SpecialId; ANN void gwi_specialid(const Gwi gwi, const m_str id, const SpecialId); diff --git a/include/pass.h b/include/pass.h index ef72d5e0..b0c50efd 100644 --- a/include/pass.h +++ b/include/pass.h @@ -1,16 +1,21 @@ #ifndef __GWIONPASS #define __GWIONPASS +typedef union __attribute__((__transparent_union__)) { + struct Ast_ *ast; + m_bool *ret; +} PassArg; + struct Passes_ { struct Map_ map; struct Vector_ vec; }; // change this to gwion ? -typedef m_bool (*compilation_pass)(Env, Ast); +typedef m_bool (*compilation_pass)(Env, PassArg); ANEW ANN struct Passes_* new_passes(MemPool mp); -ANN void free_passes(struct Passes_*); -ANN void pass_register(const Gwion, const m_str, const compilation_pass); +ANN void free_passes(MemPool mp, struct Passes_*); +ANN void pass_register(const Gwion, const m_str, const compilation_pass[2]); ANN void pass_default(const Gwion); ANN m_bool pass_set(const Gwion, const Vector); #endif diff --git a/src/compile.c b/src/compile.c index b4faf42f..b646f22f 100644 --- a/src/compile.c +++ b/src/compile.c @@ -46,14 +46,12 @@ ANN static inline void compiler_error(MemPool p, const struct Compiler* c) { } } -ANN static void compiler_clean(const Gwion gwion, const struct Compiler* c) { +ANN static void compiler_clean(const struct Compiler* c) { if(c->name) xfree(c->name); /* test c->type because COMPILE_FILE does not own file */ if(c->type != COMPILE_FILE && c->file) fclose(c->file); - if(c->ast) - ast_cleaner(gwion, c->ast); } ANN static m_bool _compiler_open(struct Compiler* c) { @@ -106,9 +104,15 @@ ANN static inline m_bool _check(struct Gwion_* gwion, struct Compiler* c) { CHECK_OB((c->ast = parse(&arg))) gwion->env->name = c->name; for(m_uint i = 0; i < vector_size(&gwion->data->passes->vec); ++i) { - const compilation_pass pass = (compilation_pass)vector_at(&gwion->data->passes->vec, i); - CHECK_BB(pass(gwion->env, c->ast)) + const compilation_pass *pass = (compilation_pass*)vector_at(&gwion->data->passes->vec, i); + const m_bool ret = pass[0](gwion->env, c->ast); + if(ret < 0) + ast_cleaner(gwion, c->ast); + if(pass[1]) + CHECK_BB(pass[1](gwion->env, (Ast)(m_uint)ret)) + CHECK_BB(ret) } + ast_cleaner(gwion, c->ast); return GW_OK; } @@ -135,7 +139,7 @@ ANN static m_uint compile(struct Gwion_* gwion, struct Compiler* c) { MUTEX_LOCK(gwion->data->mutex); const m_uint ret = _compile(gwion, c); MUTEX_UNLOCK(gwion->data->mutex); - compiler_clean(gwion, c); + compiler_clean(c); return ret; } diff --git a/src/env/env.c b/src/env/env.c index 4d051660..c232a6b7 100644 --- a/src/env/env.c +++ b/src/env/env.c @@ -97,7 +97,12 @@ ANN m_bool type_engine_check_prog(const Env env, const Ast ast) { const Context ctx = new_context(env->gwion->mp, ast, env->name); env_reset(env); load_context(ctx, env); - const m_bool ret = traverse_ast(env, ast); + return traverse_ast(env, ast); +} + +ANN m_bool type_engine_clean_prog(const Env env, const m_bool *r) { + const m_bool ret = (m_bool)r; + const Context ctx = env->context; if(ret > 0) //{ nspc_commit(env->curr); if(ret > 0 || env->context->global) diff --git a/src/gwiondata.c b/src/gwiondata.c index 533496a9..5f74b697 100644 --- a/src/gwiondata.c +++ b/src/gwiondata.c @@ -47,7 +47,7 @@ ANN void free_gwiondata(const struct Gwion_ *gwion) { mp_free(gwion->mp, SpecialId, (struct SpecialId_*)map_at(&data->id, i)); map_release(&data->id); vector_release(&data->reserved); - free_passes(data->passes); + free_passes(gwion->mp, data->passes); if(data->plug) free_plug(gwion); free_gwiondata_cpy(gwion->mp, data); diff --git a/src/import/import_special.c b/src/import/import_special.c index 33d01cf7..f4f2e414 100644 --- a/src/import/import_special.c +++ b/src/import/import_special.c @@ -22,7 +22,7 @@ ANN void gwi_register_freearg(const Gwi gwi, const f_instr _exec, const f_freear map_set(&gwi->gwion->data->freearg, (vtype)_exec, (vtype)_free); } -ANN void gwi_register_pass(const Gwi gwi, const m_str name, const compilation_pass pass) { +ANN void gwi_register_pass(const Gwi gwi, const m_str name, const compilation_pass pass[2]) { pass_register(gwi->gwion, name, pass); } diff --git a/src/parse/check.c b/src/parse/check.c index bfe46b8c..634d5b1c 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -870,10 +870,9 @@ ANN static Type check_exp_call(const Env env, Exp_Call* exp) { if(exp->tmpl) { CHECK_OO(check_exp(env, exp->func)) const Type t = actual_type(env->gwion, unflag_type(exp->func->info->type)); - const Value v = type_value(env->gwion, t) ?: t->e->d.func->value_ref; - if(!GET_FLAG(v, func) && !GET_FLAG(exp->func->info->type, func) ) + if(isa(t, env->gwion->type[et_function]) < 0) ERR_O(exp_self(exp)->pos, _("template call of non-function value.")) - if(!v->d.func_ref || !v->d.func_ref->def->base->tmpl) + if(!t->e->d.func->def->base->tmpl) ERR_O(exp_self(exp)->pos, _("template call of non-template function.")) if(t->e->d.func->def->base->tmpl->call) { if(env->func == t->e->d.func) { @@ -884,6 +883,7 @@ ANN static Type check_exp_call(const Env env, Exp_Call* exp) { } else CHECK_BO(predefined_call(env, t, exp_self(exp)->pos)) } + const Value v = type_value(env->gwion, t); CHECK_OO((exp->m_func = find_template_match(env, v, exp))) return exp->m_func->def->base->ret_type; } diff --git a/src/parse/template.c b/src/parse/template.c index 857cf8ad..7c7e0ced 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -93,7 +93,7 @@ static ANN Type maybe_func(const Env env, const Type t, const Type_Decl* td) { } ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) { - if(GET_FLAG(t, template)) { + if(GET_FLAG(t, template) && isa(t, env->gwion->type[et_function]) < 0) { if(GET_FLAG(t, ref) || (GET_FLAG(t, unary) && !td->types)) return t; struct TemplateScan ts = { .t=t, .td=td }; diff --git a/src/pass.c b/src/pass.c index b48ba6a1..30c5b292 100644 --- a/src/pass.c +++ b/src/pass.c @@ -8,12 +8,16 @@ #include "pass.h" static const m_str default_passes_name[] = { "check", "emit" }; -static const compilation_pass default_passes[] = { type_engine_check_prog, emit_ast }; +static const compilation_pass default_passes[][2] = { { type_engine_check_prog, type_engine_clean_prog }, { emit_ast, NULL } }; #define NPASS sizeof(default_passes)/sizeof(default_passes[0]) -ANN void pass_register(const Gwion gwion, const m_str name, const compilation_pass pass) { +ANN void pass_register(const Gwion gwion, const m_str name, const compilation_pass pass[2]) { + compilation_pass *passes = mp_malloc2(gwion->mp, sizeof(compilation_pass)*2); + passes[0] = pass[0]; + passes[1] = pass[1]; const Symbol sym = insert_symbol(gwion->st, name); map_set(&gwion->data->passes->map, (vtype)sym, (vtype)pass); + map_set(&gwion->data->passes->map, (vtype)sym, (vtype)passes); } ANN m_bool pass_set(const Gwion gwion, const Vector passes) { @@ -52,7 +56,11 @@ ANEW ANN struct Passes_* new_passes(MemPool mp) { return a; } -ANN void free_passes(struct Passes_ *a) { +ANN void free_passes(const MemPool mp, struct Passes_ *a) { map_release(&a->map); + for(m_uint i = 0; i < vector_size(&a->vec); ++i) { + compilation_pass *passes = (compilation_pass *)vector_at(&a->vec, i); + mp_free2(mp, sizeof(compilation_pass)*2, passes); + } vector_release(&a->vec); } -- 2.43.0