Skip to content

Commit

Permalink
Merge pull request #148 from fennecdjay/CompilationStages
Browse files Browse the repository at this point in the history
Compilation stages
  • Loading branch information
fennecdjay committed Sep 24, 2019
2 parents 4592a65 + ceedc0d commit 213c57c
Show file tree
Hide file tree
Showing 36 changed files with 471 additions and 10,131 deletions.
2 changes: 1 addition & 1 deletion include/arg.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ typedef struct Arg_ {
} Arg;

ANN void arg_release(Arg*);
ANN void arg_parse(Arg*);
ANN m_bool arg_parse(const Gwion, Arg*);
#endif
20 changes: 13 additions & 7 deletions include/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,27 @@ typedef struct Code_ {
ae_flag flag;
} Code;

struct EmitterInfo_ {
struct Vector_ pure;
struct Vector_ variadic;
char *escape;
f_instr finalyzer;
VM_Code (*emit_code)(const Emitter);
VM_Code code;
m_bool memoize;
};

struct Emitter_ {
Env env;
Code* code;
struct Gwion_ *gwion;
struct Vector_ stack;
struct Vector_ pure;
struct Vector_ variadic;
char *escape;
m_bool memoize;
struct EmitterInfo_ *info;
struct Vector_ stack;
};

ANEW ANN Emitter new_emitter(MemPool);
ANN void free_emitter(MemPool, Emitter);
ANEW ANN VM_Code emit_code(const Emitter);
ANN VM_Code emit_ast(const Emitter emit, Ast ast);
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));
ANN Code* emit_class_code(const Emitter, const m_str);
Expand Down
4 changes: 3 additions & 1 deletion include/gwiondata.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#ifndef __GWIONDATA
#define __GWIONDATA

typedef struct GwionData_ {
struct Map_ freearg;
struct Map_ id;
MUTEX_TYPE mutex;
struct Vector_ child;
struct Vector_ reserved;
struct Map_ pass_map;
struct Vector_ pass;
} GwionData;

ANN GwionData* new_gwiondata(MemPool);
Expand Down
3 changes: 2 additions & 1 deletion include/import.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,6 @@ ANN Type_List str2tl(const Env env, const m_str s, m_uint *depth);
typedef void (*f_freearg)(Instr, void*);
ANN void register_freearg(const Gwi, const f_instr, const f_freearg);
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);
#endif
3 changes: 3 additions & 0 deletions include/nspc.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ describe_lookup1(A, b) \
static inline ANN void nspc_add_##b(const Nspc n, const Symbol s, const A a) { \
scope_add(n->info->b, (vtype)s, (vtype)a); \
} \
static inline ANN void nspc_add_##b##_front(const Nspc n, const Symbol s, const A a) { \
map_set(&n->info->b->map, (vtype)s, (vtype)a); \
} \
ANN static inline void nspc_push_##b(MemPool p, const Nspc n) { scope_push(p, n->info->b); }\
ANN static inline void nspc_pop_##b (MemPool p, const Nspc n) { scope_pop (p, n->info->b); }\
describe_lookups(A, b)
Expand Down
8 changes: 8 additions & 0 deletions include/pass.h
Original file line number Diff line number Diff line change
@@ -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
33 changes: 33 additions & 0 deletions include/specialid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef __SPECIALID
#define __SPECIALID

//typedef struct SpecialId_* SpecialId;
struct SpecialId_;
typedef Type (*idck)(const Env, const Exp_Primary*);
typedef Instr (*idem)(const Emitter, const Exp_Primary*);

struct SpecialId_ {
Type type;
idck ck;
f_instr exec;
idem em;
m_bool is_const;
};

#define ID_CHECK(a) ANN Type a(const Env env NUSED, const Exp_Primary* prim NUSED)
#define ID_EMIT(a) ANN Instr a(const Emitter emit NUSED, const Exp_Primary* prim NUSED)

ANN static inline Type specialid_type(const Env env,
struct SpecialId_ *spid, const Exp_Primary* prim) {
if(spid->is_const)
exp_self(prim)->meta = ae_meta_value;
return spid->type ?: spid->ck(env, prim);
}

ANN static inline Instr specialid_instr(const Emitter emit,
struct SpecialId_ *spid, const Exp_Primary* prim) {
return spid->exec ? emit_add_instr(emit, spid->exec) : spid->em(emit, prim);
}

ANN struct SpecialId_* specialid_get(const Gwion, const Symbol);
#endif
113 changes: 87 additions & 26 deletions src/arg.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
#include <string.h>
#include "gwion_util.h"
#include "arg.h"
#include "gwion_ast.h"
#include "soundinfo.h"
#include "oo.h"
#include "env.h"
#include "vm.h"
#include "gwion.h"
#include "arg.h"
#include "pass.h"

#define GWIONRC ".gwionrc"

/* use before MemPool allocation */
Expand Down Expand Up @@ -30,7 +37,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());
}

Expand All @@ -53,34 +59,89 @@ 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)
#define ARG2INT(a) strtol(a, NULL, 10)

ANN void _arg_parse(Arg* arg) {
ANN2(1) static inline void arg_set_pass(const Gwion gwion, const m_str str) {
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 static inline m_str _get_arg(Arg* arg, int *i) {
const char key = arg->argv[*i][1];
const m_str str = (arg->argv[*i][2] == '\0' ? arg->argv[++(*i)] : arg->argv[*i] + 2);
if(!str)
gw_err(_("option '-%c' needs arguments\n"), key);
return str;
}
ANN m_bool _arg_parse(const Gwion gwion, Arg* arg) {
for(int i = 1; i < arg->argc; ++i) {
if(arg->argv[i][0] == '-') {
m_str tmp;
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('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)
CASE('z', arg->memoize = (uint32_t)ARG2INT(arg->argv))
CASE('i', arg->si->in = (uint8_t)ARG2INT(arg->argv))
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 'h':
gw_err(usage);
break;
case 'k':
gw_err("CFLAGS: %s\nLDFLAGS: %s\n", CFLAGS, LDFLAGS);
break;
case 'c':
CHECK_OB((tmp = _get_arg(arg, &i)))
config_parse(gwion, arg, tmp);
break;
case 'p':
CHECK_OB((tmp = _get_arg(arg, &i)))
vector_add(&arg->lib, (vtype)tmp);
break;
case 'm':
CHECK_OB((tmp = _get_arg(arg, &i)))
vector_add(&arg->mod, (vtype)tmp);
break;
case 'l':
CHECK_OB((tmp = _get_arg(arg, &i)))
arg->loop = (m_bool)ARG2INT(tmp) > 0 ? 1 : -1;
break;
case 'z':
CHECK_OB((tmp = _get_arg(arg, &i)))
arg->memoize = (uint32_t)ARG2INT(tmp);
break;
case 'i':
CHECK_OB((tmp = _get_arg(arg, &i)))
arg->si->in = (uint8_t)ARG2INT(tmp);
break;
case 'o':
CHECK_OB((tmp = _get_arg(arg, &i)))
arg->si->out = (uint8_t)ARG2INT(tmp);
break;
case 's':
CHECK_OB((tmp = _get_arg(arg, &i)))
arg->si->sr = (uint32_t)ARG2INT(tmp);
break;
case 'd':
CHECK_OB((tmp = _get_arg(arg, &i)))
arg->si->arg = tmp;
break;
case 'g':
CHECK_OB((tmp = _get_arg(arg, &i)))
arg_set_pass(gwion, tmp);
break;
default:
gw_err(_("invalid arguments"));
return GW_ERROR;
}
} else
vector_add(&arg->add, (vtype)arg->argv[i]);
}
return GW_OK;
}

ANN static void split_line(const m_str line, const Vector v) {
Expand Down Expand Up @@ -113,29 +174,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 m_bool arg_parse(const Gwion gwion, Arg* a) {
arg_init(a);
config_default(a);
_arg_parse(a);
config_default(gwion, a);
return _arg_parse(gwion, a);
}
59 changes: 25 additions & 34 deletions src/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "emit.h"
#include "compile.h"
#include "gwion.h"
#include "pass.h"

enum compile_type {
COMPILE_NAME,
Expand Down Expand Up @@ -80,63 +81,53 @@ static inline m_bool compiler_open(MemPool p, struct Compiler* c) {
return GW_OK;
}

static m_bool check(struct Gwion_* gwion, struct Compiler* c) {
static inline m_bool _check(struct Gwion_* gwion, struct Compiler* c) {
struct ScannerArg_ arg = { c->name, c->file, gwion->st };
MUTEX_LOCK(gwion->data->mutex);
CHECK_OB((c->ast = parse(&arg)))
gwion->env->name = c->name;
const m_bool ret = type_engine_check_prog(gwion->env, c->ast);
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) {
VM_Shred shred = NULL;
VM_Code code;
compiler_name(gwion->mp, c);
MUTEX_LOCK(gwion->data->mutex);
static m_uint _compile(struct Gwion_* gwion, struct Compiler* c) {
CHECK_BB(compiler_open(gwion->mp, c))
if(check(gwion, c) < 0 || !(code = emit_ast(gwion->emit, c->ast)))
if(_check(gwion, c) < 0) {
gw_err(_("while compiling file '%s'\n"), c->base);
else {
const VM_Shred shred = new_vm_shred(gwion->mp, code);
return 0;
}
if(gwion->emit->info->code) {
const VM_Shred shred = new_vm_shred(gwion->mp, gwion->emit->info->code);
shred->info->args = c->args;
vm_add_shred(gwion->vm, shred);
gwion->emit->info->code = NULL;
return shred->tick->xid;
}
MUTEX_UNLOCK(gwion->data->mutex);
compiler_clean(gwion->mp, c);
return shred ? shred->tick->xid : 0;
}
/*
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);
return GW_OK;
}

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);
static m_uint compile(struct Gwion_* gwion, struct Compiler* c) {
compiler_name(gwion->mp, c);
MUTEX_LOCK(gwion->data->mutex);
const m_uint ret = _compile(gwion, c);
MUTEX_UNLOCK(gwion->data->mutex);
compiler_clean(gwion->mp, c);
return ret;
}

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);
}
/*

m_uint compile_string(struct Gwion_* vm, const m_str filename, const m_str data) {
struct Compiler c = { .base=filename, .type=COMPILE_MSTR, .data=data };
return compile(vm, &c);
}

/*
m_uint compile_file(struct Gwion_* vm, const m_str filename, FILE* file) {
struct Compiler c = { .base=filename, .type=COMPILE_MSTR, .file=file };
return compile(vm, &c);
Expand Down

0 comments on commit 213c57c

Please sign in to comment.