-Subproject commit 95aeae8c6dae2652dc092dd36bc0d9caa12a20a7
+Subproject commit 0b64428ec56f99521ef33990cd0c725573b8418b
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);
#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);
#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
}
}
-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) {
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;
}
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;
}
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)
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);
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);
}
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) {
} 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;
}
}
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 };
#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) {
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);
}