]> Nishi Git Mirror - gwion.git/commitdiff
:art: Use compilation passes
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 22 Sep 2019 22:27:45 +0000 (00:27 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 22 Sep 2019 22:27:45 +0000 (00:27 +0200)
13 files changed:
include/arg.h
include/emit.h
include/gwiondata.h
include/pass.h [new file with mode: 0644]
src/arg.c
src/compile.c
src/emit/emit.c
src/emit/emitter.c
src/gwion.c
src/gwiondata.c
src/pass.c [new file with mode: 0644]
src/plug.c
tests/sh/opt.sh

index 336cfdc62c7f7d1d22a90b2c0f05bdf5e603213c..f80ac7e447fa4ca522a890418c48bf5fe66f209e 100644 (file)
@@ -14,5 +14,5 @@ typedef struct Arg_ {
 } Arg;
 
 ANN void arg_release(Arg*);
-ANN void arg_parse(Arg*);
+ANN void arg_parse(const Gwion, Arg*);
 #endif
index e08bc23a0e413b7bd20d5ffcf561777d804a4568..8c7012149b663d057b438feb7d87ee8ed556ebac 100644 (file)
@@ -35,7 +35,6 @@ struct Emitter_ {
 
 ANEW ANN Emitter new_emitter(MemPool);
 ANN void free_emitter(MemPool, Emitter);
-ANEW ANN VM_Code emit_code(const Emitter);
 ANN m_bool emit_ast(const Env env, Ast ast);
 ANN Instr emit_exp_call1(const Emitter, const Func);
 ANN2(1) Instr emit_add_instr(const Emitter, const f_instr) __attribute__((returns_nonnull));
index 5136b21c8fab236892711b4d45646dc0fbb5f6c0..5624a6b706f0f921444372a481642e723b132182 100644 (file)
@@ -1,11 +1,14 @@
 #ifndef __GWIONDATA
 #define __GWIONDATA
-
+typedef struct Env_* Env;
+typedef m_bool (*compilation_pass)(Env, Ast);
 typedef struct GwionData_ {
   struct Map_ freearg;
   MUTEX_TYPE mutex;
   struct Vector_ child;
   struct Vector_ reserved;
+  struct Map_ pass_map;
+  struct Vector_ pass;
 } GwionData;
 
 ANN GwionData* new_gwiondata(MemPool);
diff --git a/include/pass.h b/include/pass.h
new file mode 100644 (file)
index 0000000..b8bc7e6
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __GWIONPASS
+#define __GWIONPASS
+typedef m_bool (*compilation_pass)(Env, Ast);
+
+ANN void pass_register(const Gwion, const m_str, const compilation_pass);
+ANN void pass_default(const Gwion);
+ANN m_bool pass_set(const Gwion, const Vector);
+#endif
index 4a06f7d2a0e4e72b193014503234d93cf9080581..9f26475bd75690cee4ae9acac1f8e314033d0900 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -1,7 +1,13 @@
 #include <string.h>
 #include "gwion_util.h"
-#include "arg.h"
+#include "gwion_ast.h"
 #include "soundinfo.h"
+#include "oo.h"
+#include "vm.h"
+#include "gwion.h"
+#include "arg.h"
+#include "pass.h"
+
 #define GWIONRC ".gwionrc"
 
 /* use before MemPool allocation */
@@ -30,7 +36,6 @@ ANN static void arg_init(Arg* arg) {
   vector_init(&arg->lib);
   vector_init(&arg->mod);
   vector_init(&arg->config);
-//  vector_add(&arg->lib, (vtype)GWPLUG_DIR);
   vector_add(&arg->lib, (vtype)plug_dir());
 }
 
@@ -53,22 +58,34 @@ static const char usage[] =
 "  -i    <number>  : set input channel number\n"
 "  -o    <number>  : set output channel number\n"
 "  -d    <number>  : set driver (and arguments)\n"
+"  -l    <number>  : set loop mode\n"
 "  -z    <number>  : set memoization limit\n"
-"  -m   <mod:args> : load module (and arguments)\n";
+"  -m   <mod:args> : load module (and arguments)\n"
+"  -g   <mod:args> : set Gwion compiler passes order\n";
 
-ANN static void config_parse(Arg* arg, const m_str name);
+ANN static void config_parse(const Gwion, Arg*, const m_str);
 
 #define CASE(a,b) case a: (b) ; break;
 #define get_arg(a) (a[i][2] == '\0' ? arg->argv[++i] : a[i] + 2)
 #define ARG2INT(a) strtol(get_arg(a), NULL, 10)
 
-ANN void _arg_parse(Arg* arg) {
+ANN2(1) static inline void arg_set_pass(const Gwion gwion, const m_str str) {
+  if(!str)
+    gw_err(_("needs arguments"));
+  const Vector v = split_args(gwion->mp, str);
+  pass_set(gwion, v);
+  for(m_uint i = 0; i < vector_size(v); ++i)
+    free_mstr(gwion->mp, (m_str)vector_at(v, i));
+  free_vector(gwion->mp, v);
+}
+
+ANN void _arg_parse(const Gwion gwion, Arg* arg) {
   for(int i = 1; i < arg->argc; ++i) {
     if(arg->argv[i][0] == '-') {
       switch(arg->argv[i][1]) {
         CASE('h', gw_err(usage))
         CASE('k', gw_err("CFLAGS: %s\nLDFLAGS: %s\n", CFLAGS, LDFLAGS))
-        CASE('c', config_parse(arg, get_arg(arg->argv)))
+        CASE('c', config_parse(gwion, arg, get_arg(arg->argv)))
         CASE('p', vector_add(&arg->lib, (vtype)get_arg(arg->argv)))
         CASE('m', vector_add(&arg->mod, (vtype)get_arg(arg->argv)))
         CASE('l', arg->loop = (m_bool)ARG2INT(arg->argv) > 0 ? 1 : -1)
@@ -77,6 +94,7 @@ ANN void _arg_parse(Arg* arg) {
         CASE('o', arg->si->out = (uint8_t)ARG2INT(arg->argv))
         CASE('s', arg->si->sr = (uint32_t)ARG2INT(arg->argv))
         CASE('d', arg->si->arg = get_arg(arg->argv))
+        CASE('g', arg_set_pass(gwion, get_arg(arg->argv)))
       }
     } else
       vector_add(&arg->add, (vtype)arg->argv[i]);
@@ -113,29 +131,29 @@ ANN static Vector get_config(const m_str name) {
   return v;
 }
 
-ANN static void config_parse(Arg* arg, const m_str name) {
+ANN static void config_parse(const Gwion gwion, Arg* arg, const m_str name) {
   const Vector v = get_config(name);
   if(v) {
     int argc = arg->argc;
     char** argv = arg->argv;
     arg->argc = vector_size(v);
     arg->argv =  (m_str*)(v->ptr + OFFSET);
-    _arg_parse(arg);
+    _arg_parse(gwion, arg);
     arg->argc = argc;
     arg->argv = argv;
     vector_add(&arg->config, (vtype)v);
   }
 }
 
-ANN static void config_default(Arg* arg) {
+ANN static void config_default(const Gwion gwion , Arg* arg) {
   char* home = getenv("HOME");
   char c[strlen(home) + strlen(GWIONRC) + 2];
   sprintf(c, "%s/%s", home, GWIONRC);
-  config_parse(arg, c);
+  config_parse(gwion, arg, c);
 }
 
-ANN void arg_parse(Arg* a) {
+ANN void arg_parse(const Gwion gwion, Arg* a) {
   arg_init(a);
-  config_default(a);
-  _arg_parse(a);
+  config_default(gwion, a);
+  _arg_parse(gwion, a);
 }
index fd8ad67fe08f666205a7372cef3e3d802bcdd07c..baadc5a557e8579b962cf0285b1751e9b1a039c5 100644 (file)
@@ -84,19 +84,16 @@ static inline m_bool _check(struct Gwion_* gwion, struct Compiler* c) {
   struct ScannerArg_ arg = { c->name, c->file, gwion->st };
   CHECK_OB((c->ast = parse(&arg)))
   gwion->env->name = c->name;
-  return type_engine_check_prog(gwion->env, c->ast);
-}
-/*
-static m_bool check(struct Gwion_* gwion, struct Compiler* c) {
-  MUTEX_LOCK(gwion->data->mutex);
-  const m_bool ret = _check(gwion, c);
-  MUTEX_UNLOCK(gwion->data->mutex);
-  return ret;
+  for(m_uint i = 0; i < vector_size(&gwion->data->pass); ++i) {
+    const compilation_pass pass = (compilation_pass)vector_at(&gwion->data->pass, i);
+    CHECK_BB(pass(gwion->env, c->ast))
+  }
+  return GW_OK;
 }
-*/
+
 static m_uint _compile(struct Gwion_* gwion, struct Compiler* c) {
   CHECK_BB(compiler_open(gwion->mp, c))
-  if(_check(gwion, c) < 0 || emit_ast(gwion->env, c->ast) < 0) {
+  if(_check(gwion, c) < 0) {
     gw_err(_("while compiling file '%s'\n"), c->base);
     return 0;
   }
@@ -116,26 +113,6 @@ static m_uint compile(struct Gwion_* gwion, struct Compiler* c) {
   return ret;
 }
 
-/*
-m_bool check_filename(struct Gwion_* vm, const m_str filename) {
-  struct Compiler c = { .base=filename, .type=COMPILE_NAME };
-  CHECK_BB(compiler_open(gwion->mp, c))
-  return check(&c, vm);
-}
-
-m_bool check_string(struct Gwion_* vm, const m_str filename, const m_str data) {
-  struct Compiler c = { .base=filename, .type=COMPILE_MSTR, .data=data };
-  CHECK_BB(compiler_open(gwion->mp, c))
-  return check(&c, vm);
-}
-
-m_bool check_file(struct Gwion_* vm, const m_str filename, FILE* file) {
-  struct Compiler c = { .base=filename, .type=COMPILE_FILE, .file = file};
-  CHECK_BB(compiler_open(gwion->mp, c))
-  return check(&c, vm);
-}
-*/
-//m_uint compile_filename(struct Gwion_* vm, const m_str filename) {
 m_uint compile_filename(struct Gwion_* gwion, const m_str filename) {
   struct Compiler c = { .base=filename, .type=COMPILE_NAME };
   return compile(gwion, &c);
index 6c126c6ffeab39685b7f1407ad65d1a7b8b6ed03..38681317d6ec89ebebcd4ae30d994888796282e5 100644 (file)
@@ -362,17 +362,10 @@ ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) {
   return GW_OK;
 }
 
-ANEW ANN VM_Code emit_code(const Emitter emit) {
-  Code* c = emit->code;
-  const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth,
-      c->flag, c->name);
-  free_code(emit->gwion->mp, c);
-  return code;
-}
-
 ANN static VM_Code finalyze(const Emitter emit, const f_instr exec) {
   emit_add_instr(emit, exec);
-  const VM_Code code = emit_code(emit);
+  const VM_Code code = emit->info->emit_code(emit);
+  free_code(emit->gwion->mp, emit->code);
   emit->code = (Code*)vector_pop(&emit->stack);
   return code;
 }
index 71c8df69b60a49806f4fc186e4e001490b695b8f..060b18ec6f027ff59eea6cdf3056d501ecbe79dd 100644 (file)
 #include "emit.h"
 #include "escape.h"
 
+static ANEW ANN VM_Code emit_code(const Emitter emit) {
+  Code* const c = emit->code;
+  const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth,
+      c->flag, c->name);
+  return code;
+}
+
 ANEW Emitter new_emitter(MemPool p) {
   Emitter emit = (Emitter)mp_calloc(p, Emitter);
   vector_init(&emit->stack);
@@ -18,6 +25,7 @@ ANEW Emitter new_emitter(MemPool p) {
   vector_init(&emit->info->pure);
   vector_init(&emit->info->variadic);
   emit->info->escape = escape_table(p);
+  emit->info->emit_code = emit_code;
   emit->info->finalyzer = EOC;
   return emit;
 }
index c28493a6fe57380c1171de701b8b6f3158ed8d07..edb8c2222e003886eda528def9680a319dff4ed3 100644 (file)
 #include "emit.h"
 #include "engine.h"
 #include "driver.h"
-#include "arg.h"
 #include "gwion.h"
+#include "arg.h"
 #include "compile.h"
 #include "object.h" // fork_clean
+#include "pass.h" // fork_clean
 
 ANN m_bool gwion_audio(const Gwion gwion) {
   Driver* di = gwion->vm->bbq;
@@ -69,11 +70,16 @@ ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
   gwion->vm->gwion = gwion;
   gwion->env->gwion = gwion;
   gwion->vm->bbq->si = new_soundinfo(gwion->mp);
+  gwion->data = new_gwiondata(gwion->mp);
+  pass_default(gwion);
   arg->si = gwion->vm->bbq->si;
-  arg_parse(arg);
+  arg_parse(gwion, arg);
   gwion->emit->info->memoize = arg->memoize;
   gwion->plug = new_plug(gwion->mp, &arg->lib);
-  gwion->data = new_gwiondata(gwion->mp);
+//  map_set(&gwion->data->pass_map, (vtype)"check", (vtype)type_engine_check_prog);
+//  map_set(&gwion->data->pass_map, (vtype)"emit", (vtype)emit_ast);
+//  vector_add(&gwion->data->pass, (vtype)type_engine_check_prog);
+//  vector_add(&gwion->data->pass, (vtype)emit_ast);
   shreduler_set_loop(gwion->vm->shreduler, arg->loop);
   if(gwion_audio(gwion) > 0 && gwion_engine(gwion)) {
     gwion_compile(gwion, &arg->add);
index 8d31b0536745a45806dd4a991c919d2a7fa81ab9..92645bf2eb82a9576392fe68bf24bea1173933e2 100644 (file)
@@ -1,10 +1,13 @@
 #include "gwion_util.h"
+#include "gwion_ast.h"
 #include "gwiondata.h"
 
 ANN GwionData* new_gwiondata(MemPool mp) {
   struct GwionData_ *data = mp_calloc(mp, GwionData);
   map_init(&data->freearg);
   vector_init(&data->reserved);
+  map_init(&data->pass_map);
+  vector_init(&data->pass);
   MUTEX_SETUP(data->mutex);
   return data;
 }
@@ -12,6 +15,8 @@ ANN GwionData* new_gwiondata(MemPool mp) {
 ANN void free_gwiondata(MemPool mp, GwionData *data) {
   map_release(&data->freearg);
   vector_release(&data->reserved);
+  map_release(&data->pass_map);
+  vector_release(&data->pass);
   MUTEX_CLEANUP(data->mutex);
   mp_free(mp, GwionData, data);
 }
diff --git a/src/pass.c b/src/pass.c
new file mode 100644 (file)
index 0000000..9a2434c
--- /dev/null
@@ -0,0 +1,46 @@
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "oo.h"
+#include "vm.h"
+#include "env.h"
+#include "instr.h"
+#include "emit.h"
+#include "gwion.h"
+#include "pass.h"
+
+static const m_str default_passes_name[] = { "check", "emit" };
+static const compilation_pass default_passes[] = { type_engine_check_prog, emit_ast };
+#define NPASS sizeof(default_passes)/sizeof(default_passes[0])
+
+ANN void pass_register(const Gwion gwion, const m_str name, const compilation_pass pass) {
+  const Symbol sym = insert_symbol(gwion->st, name);
+  map_set(&gwion->data->pass_map, (vtype)sym, (vtype)pass);
+}
+
+ANN m_bool pass_set(const Gwion gwion, const Vector passes) {
+  const Vector v = &gwion->data->pass;
+  vector_clear(v);
+  for(m_uint i = 0; i < vector_size(passes); ++i) {
+    const m_str name = (m_str)vector_at(passes, i);
+    const Symbol sym = insert_symbol(gwion->st, name);
+    const compilation_pass pass = (compilation_pass)map_get(&gwion->data->pass_map, (vtype)sym);
+    if(!pass) {
+      gw_err("Failed to set compilation passes, back to default");
+      pass_default(gwion);
+      return GW_ERROR;
+    }
+    vector_add(v, (vtype)pass);
+  }
+  return GW_OK;
+}
+
+ANN void pass_default(const Gwion gwion) {
+  struct Vector_ v;
+  vector_init(&v);
+  for(m_uint i = 0; i < NPASS; ++i) {
+    vector_add(&v, (vtype)default_passes_name[i]);
+    pass_register(gwion, default_passes_name[i], default_passes[i]);
+  }
+  pass_set(gwion, &v);
+  vector_release(&v);
+}
index 281906b953db26cc2412e14ff0cf9af5fcf19972..e3611a15d41fc66ebfbb50cfa79af5d7a6d63847 100644 (file)
@@ -117,13 +117,10 @@ void free_plug(const Gwion gwion) {
 }
 
 ANN Vector split_args(MemPool p, const m_str str) {
-  const m_str arg = strchr(str, '=');
-  if(!arg)
-    return NULL;
   const Vector args = new_vector(p);
-  m_str d = strdup(arg+1);
-  while(d)
-    vector_add(args, (vtype)mstrdup(p, strsep(&d, ",")));
+  m_str d = strdup(str), e = d;
+  while(e)
+    vector_add(args, (vtype)mstrdup(p, strsep(&e, ",")));
   xfree(d);
   return args;
 }
@@ -134,7 +131,8 @@ ANN static Vector get_arg(MemPool p, const m_str name, const Vector v) {
     const m_str str = (m_str)vector_at(v, i - 1);
     if(!strncmp(name, str, len)) {
       vector_rem(v, i-1);
-      return split_args(p, str);
+      const m_str arg = strchr(str, '=');
+      return arg ? split_args(p, str) : NULL;
     }
   }
   return NULL;
index 9b733534f7f0af6027c8dc7f8442c9ce8aa4498a..65c18796e020831b45dfb11653ab9260fd278976 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-# [test] #15
+# [test] #16
 n=0
 [ "$1" ] && n="$1"
 [ "$n" -eq 0 ] && n=1
@@ -68,6 +68,10 @@ run "$n" "module argument" "-mfake:test" "file"
 n=$((n+1))
 run "$n" "Kompile time Konfig" "-k" "file"
 
+# set compilation passes
+n=$((n+1))
+run "$n" "just check" "-g check" "file"
+
 # test signal
 ./gwion -l1 &
 PID=$!