]> Nishi Git Mirror - gwion.git/commitdiff
:art: Parse fptr template flag
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Tue, 15 Sep 2020 20:18:23 +0000 (22:18 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Tue, 15 Sep 2020 20:18:23 +0000 (22:18 +0200)
ast
include/env/env.h
include/import/special.h
include/pass.h
src/compile.c
src/env/env.c
src/gwiondata.c
src/import/import_special.c
src/parse/check.c
src/parse/template.c
src/pass.c

diff --git a/ast b/ast
index 95aeae8c6dae2652dc092dd36bc0d9caa12a20a7..0b64428ec56f99521ef33990cd0c725573b8418b 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 95aeae8c6dae2652dc092dd36bc0d9caa12a20a7
+Subproject commit 0b64428ec56f99521ef33990cd0c725573b8418b
index 172008a1339355944cadf09f0fbabbe6b6d86fb0..b07f2f87ac84980077a5b414a15907479d287a70 100644 (file)
@@ -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);
index afb9654db3864900664baf9c1323569dfc31aa13..4d7e5f8386e880680185d21137bb7ccf24a8965b 100644 (file)
@@ -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);
index ef72d5e0714945e43adc60dc04e63230819c9ecc..b0c50efd52899c1b5dcc51abc5b0031e8862ccdb 100644 (file)
@@ -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
index b4faf42f4e776b1c5820352d45da4fd1dad028b9..b646f22ffb7eeab290acb1a3b1cae314ec14b892 100644 (file)
@@ -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;
 }
 
index 4d051660323d461112e6d77d3aa6e1090c855d81..c232a6b7737b19204c2d0cc3efcfce1012cd5391 100644 (file)
@@ -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)
index 533496a9346603812cb64148284b162672bc0e88..5f74b69726626c07f160fba06a0bdd01ecf31ed6 100644 (file)
@@ -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);
index 33d01cf728af099765b42376c96200bca3809590..f4f2e4144ceb4bc176864c2c169283ee5123c36a 100644 (file)
@@ -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);
 }
 
index bfe46b8ca9995d01310220357b385cdad6f53840..634d5b1ca4b61b7d92d6c440f73d9f2eb8fda346 100644 (file)
@@ -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;
   }
index 857cf8ad2f313f7dbe54fa8bd47d29e3dafd1bd3..7c7e0ced367ddf8fbfbf0f92b0621a5ffd9c17cb 100644 (file)
@@ -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 };
index b48ba6a167ffe7af0ab754950adc7b7ab48b919f..30c5b2926c8d570512fc36990c5b79deab208517 100644 (file)
@@ -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);
 }