-Subproject commit cc3a1b18354ea5f3d06bfec3eb747ed3cec4a141
+Subproject commit b631a0ecbc6687ff9b38ad417f0f250f68fdb17f
--- /dev/null
+#ifndef __CLEAN
+#define __CLEAN
+
+void ast_cleaner(const Gwion, Ast);
+void func_def_cleaner(const Gwion, Func_Def);
+#ifdef __CLEAN_IMPL
+typedef struct {
+ m_uint scope;
+ Gwion gwion;
+} Clean;
+
+ANN static void clean_array_sub(Clean *a, Array_Sub b);
+ANN static void clean_id_list(Clean *a, ID_List b);
+ANN static void clean_type_list(Clean *a, Type_List b);
+ANN static void clean_tmpl(Clean *a, Tmpl *b);
+ANN static void clean_range(Clean *a, Range *b);
+ANN static void clean_type_decl(Clean *a, Type_Decl *b);
+ANN static void clean_prim(Clean *a, Exp_Primary *b);
+ANN static void clean_var_decl(Clean *a, Var_Decl b);
+ANN static void clean_var_decl_list(Clean *a, Var_Decl_List b);
+ANN static void clean_exp_decl(Clean *a, Exp_Decl *b);
+ANN static void clean_exp_binary(Clean *a, Exp_Binary *b);
+ANN static void clean_exp_unary(Clean *a, Exp_Unary *b);
+ANN static void clean_exp_cast(Clean *a, Exp_Cast *b);
+ANN static void clean_exp_post(Clean *a, Exp_Postfix *b);
+ANN static void clean_exp_call(Clean *a, Exp_Call *b);
+ANN static void clean_exp_array(Clean *a, Exp_Array *b);
+ANN static void clean_exp_slice(Clean *a, Exp_Slice *b);
+ANN static void clean_exp_if(Clean *a, Exp_If *b);
+ANN static void clean_exp_dot(Clean *a, Exp_Dot *b);
+ANN static void clean_exp_lambda(Clean *a, Exp_Lambda *b);
+ANN static void clean_exp(Clean *a, Exp b);
+ANN static void clean_stmt_exp(Clean *a, Stmt_Exp b);
+ANN static void clean_stmt_for(Clean *a, Stmt_For b);
+ANN static void clean_stmt_auto(Clean *a, Stmt_Auto b);
+ANN static void clean_stmt_loop(Clean *a, Stmt_Loop b);
+ANN static void clean_stmt_if(Clean *a, Stmt_If b);
+ANN static void clean_stmt_code(Clean *a, Stmt_Code b);
+ANN static void clean_stmt_varloop(Clean *a, Stmt_VarLoop b);
+ANN static void clean_stmt_return(Clean *a, Stmt_Exp b);
+ANN static void clean_case_list(Clean *a, Stmt_List b);
+ANN static void clean_stmt_match(Clean *a, Stmt_Match b);
+ANN static void clean_stmt_case(Clean *a, Stmt_Match b);
+ANN static void clean_stmt(Clean *a, Stmt b);
+ANN static void clean_arg_list(Clean *a, Arg_List b);
+ANN static void clean_decl_list(Clean *a, Decl_List b);
+ANN static void clean_stmt_list(Clean *a, Stmt_List b);
+ANN static void clean_func_base(Clean *a, Func_Base *b);
+ANN static void clean_func_def(Clean *a, Func_Def b);
+ANN static void clean_class_def(Clean *a, Class_Def b);
+ANN static void clean_enum_def(Clean *a, Enum_Def b);
+ANN static void clean_union_def(Clean *a, Union_Def b);
+ANN static void clean_fptr_def(Clean *a, Fptr_Def b);
+ANN static void clean_type_def(Clean *a, Type_Def b);
+ANN static void clean_section(Clean *a, Section *b);
+ANN static void clean_ast(Clean *a, Ast b);
+
+#endif
+
+#endif
keyword_fork="fork"
keyword_union="union"
keyword_class="class"
+keyword_struct="struct"
keyword_dtor="dtor"
keyword_operator="operator"
keyword_extends="extends"
keyword_protect="protect"
keyword_private="private"
keyword_const="const"
+keyword_ref="ref"
+keyword_nonnull="nonnull"
keyword_if="if"
keyword_else="else"
keyword_break="break"
symbol_gack1="<<<"
-symbol_gack2=">>>"
\ No newline at end of file
+symbol_gack2=">>>"
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "gwion.h"
+#define __CLEAN_IMPL
+#include "clean.h"
+
+ANN static void clean_array_sub(Clean *a, Array_Sub b) {
+ if(b->exp)
+ clean_exp(a, b->exp);
+}
+
+ANN static void clean_id_list(Clean *a, ID_List b) {
+ if(b->next)
+ clean_id_list(a, b->next);
+}
+
+ANN static void clean_type_list(Clean *a, Type_List b) {
+ clean_type_decl(a, b->td);
+ if(b->next)
+ clean_type_list(a, b->next);
+}
+
+ANN static void clean_tmpl(Clean *a, Tmpl *b) {
+ if(b->list)
+ clean_id_list(a, b->list);
+ if(b->call)
+ clean_type_list(a, b->call);
+}
+
+ANN static void clean_range(Clean *a, Range *b) {
+ if(b->start)
+ clean_exp(a, b->start);
+ if(b->end)
+ clean_exp(a, b->end);
+}
+
+ANN static void clean_type_decl(Clean *a, Type_Decl *b) {
+ if(b->exp)
+ clean_exp(a, b->exp);
+ if(b->array)
+ clean_array_sub(a, b->array);
+ if(b->types)
+ clean_type_list(a, b->types);
+ if(b->next)
+ clean_type_decl(a, b->next);
+}
+
+ANN static void clean_prim(Clean *a, Exp_Primary *b) {
+ if(b->prim_type == ae_prim_hack ||
+ b->prim_type == ae_prim_typeof ||
+ b->prim_type == ae_prim_interp)
+ clean_exp(a, b->d.exp);
+ else if(b->prim_type == ae_prim_array)
+ clean_array_sub(a, b->d.array);
+ else if(b->prim_type == ae_prim_range)
+ clean_range(a, b->d.range);
+}
+
+ANN static void clean_var_decl(Clean *a, Var_Decl b) {
+ if(b->array)
+ clean_array_sub(a, b->array);
+ if(a->scope && b->value)
+ REM_REF(b->value, a->gwion)
+}
+
+ANN static void clean_var_decl_list(Clean *a, Var_Decl_List b) {
+ clean_var_decl(a, b->self);
+ if(b->next)
+ clean_var_decl_list(a, b->next);
+}
+
+ANN static void clean_exp_decl(Clean *a, Exp_Decl *b) {
+ if(b->td)
+ clean_type_decl(a, b->td);
+ clean_var_decl_list(a, b->list);
+}
+
+ANN static void clean_exp_binary(Clean *a, Exp_Binary *b) {
+ clean_exp(a, b->lhs);
+ clean_exp(a, b->rhs);
+}
+
+ANN static void clean_exp_unary(Clean *a, Exp_Unary *b) {
+ if(b->exp)
+ clean_exp(a, b->exp);
+ if(b->td)
+ clean_type_decl(a, b->td);
+ if(b->code)
+ clean_stmt(a, b->code);
+}
+
+ANN static void clean_exp_cast(Clean *a, Exp_Cast *b) {
+ clean_type_decl(a, b->td);
+ clean_exp(a, b->exp);
+}
+
+ANN static void clean_exp_post(Clean *a, Exp_Postfix *b) {
+ clean_exp(a, b->exp);
+}
+
+ANN static void clean_exp_call(Clean *a, Exp_Call *b) {
+ clean_exp(a, b->func);
+ if(b->args)
+ clean_exp(a, b->args);
+ if(b->tmpl)
+ clean_tmpl(a, b->tmpl);
+}
+
+ANN static void clean_exp_array(Clean *a, Exp_Array *b) {
+ clean_exp(a, b->base);
+ clean_array_sub(a, b->array);
+}
+
+ANN static void clean_exp_slice(Clean *a, Exp_Slice *b) {
+ clean_exp(a, b->base);
+ clean_range(a, b->range);
+}
+
+ANN static void clean_exp_if(Clean *a, Exp_If *b) {
+ clean_exp(a, b->cond);
+ if(b->if_exp)
+ clean_exp(a, b->if_exp);
+ clean_exp(a, b->else_exp);
+}
+
+ANN static void clean_exp_dot(Clean *a, Exp_Dot *b) {
+ clean_exp(a, b->base);
+}
+
+ANN static void clean_exp_lambda(Clean *a, Exp_Lambda *b) {
+ clean_func_def(a, b->def);
+}
+
+DECL_EXP_FUNC(clean, void, Clean*)
+ANN static void clean_exp(Clean *a, Exp b) {
+ clean_exp_func[b->exp_type](a, &b->d);
+ if(b->next)
+ clean_exp(a, b->next);
+}
+
+ANN static void clean_stmt_exp(Clean *a, Stmt_Exp b) {
+ if(b->val)
+ clean_exp(a, b->val);
+}
+
+ANN static void clean_stmt_flow(Clean *a, Stmt_Flow b) {
+ ++a->scope;
+ clean_exp(a, b->cond);
+ clean_stmt(a, b->body);
+ --a->scope;
+}
+
+#define clean_stmt_while clean_stmt_flow
+#define clean_stmt_until clean_stmt_flow
+
+ANN static void clean_stmt_for(Clean *a, Stmt_For b) {
+ ++a->scope;
+ clean_stmt(a, b->c1);
+ if(b->c2)
+ clean_stmt(a, b->c2);
+ if(b->c3)
+ clean_exp(a, b->c3);
+ clean_stmt(a, b->body);
+ --a->scope;
+}
+
+ANN static void clean_stmt_auto(Clean *a, Stmt_Auto b) {
+ ++a->scope;
+ clean_exp(a, b->exp);
+ clean_stmt(a, b->body);
+ --a->scope;
+}
+
+ANN static void clean_stmt_loop(Clean *a, Stmt_Loop b) {
+ ++a->scope;
+ clean_exp(a, b->cond);
+ clean_stmt(a, b->body);
+ --a->scope;
+}
+
+ANN static void clean_stmt_if(Clean *a, Stmt_If b) {
+ ++a->scope;
+ clean_exp(a, b->cond);
+ clean_stmt(a, b->if_body);
+ if(b->else_body)
+ clean_stmt(a, b->else_body);
+ --a->scope;
+}
+
+ANN static void clean_stmt_code(Clean *a, Stmt_Code b) {
+ ++a->scope;
+ if(b->stmt_list)
+ clean_stmt_list(a, b->stmt_list);
+ --a->scope;
+}
+
+ANN static void clean_stmt_varloop(Clean *a, Stmt_VarLoop b) {
+ ++a->scope;
+ clean_exp(a, b->exp);
+ clean_stmt(a, b->body);
+ --a->scope;
+}
+
+ANN static void clean_stmt_return(Clean *a, Stmt_Exp b) {
+ if(b->val)
+ clean_exp(a, b->val);
+}
+
+ANN static void clean_case_list(Clean *a, Stmt_List b) {
+ clean_stmt_case(a, &b->stmt->d.stmt_match);
+ if(b->next)
+ clean_case_list(a, b->next);
+}
+
+ANN static void clean_stmt_match(Clean *a, Stmt_Match b) {
+ ++a->scope;
+ clean_exp(a, b->cond);
+ clean_case_list(a, b->list);
+ if(b->where)
+ clean_stmt(a, b->where);
+ --a->scope;
+}
+
+ANN static void clean_stmt_case(Clean *a, Stmt_Match b) {
+ ++a->scope;
+ clean_exp(a, b->cond);
+ clean_stmt_list(a, b->list);
+ if(b->when)
+ clean_exp(a, b->when);
+ --a->scope;
+}
+
+
+ANN static void clean_dummy(Clean *a NUSED, void *b NUSED) {}
+#define clean_stmt_jump clean_dummy
+#define clean_stmt_pp clean_dummy
+#define clean_stmt_break clean_dummy
+#define clean_stmt_continue clean_dummy
+
+DECL_STMT_FUNC(clean, void, Clean*)
+ANN static void clean_stmt(Clean *a, Stmt b) {
+ clean_stmt_func[b->stmt_type](a, &b->d);
+}
+
+ANN static void clean_arg_list(Clean *a, Arg_List b) {
+ if(b->td)
+ clean_type_decl(a, b->td);
+ clean_var_decl(a, b->var_decl);
+ if(b->next)
+ clean_arg_list(a, b->next);
+}
+
+ANN static void clean_decl_list(Clean *a, Decl_List b) {
+ clean_exp(a, b->self);
+ if(b->next)
+ clean_decl_list(a, b->next);
+}
+
+ANN static void clean_stmt_list(Clean *a, Stmt_List b) {
+ clean_stmt(a, b->stmt);
+ if(b->next)
+ clean_stmt_list(a, b->next);
+}
+
+ANN static void clean_func_base(Clean *a, Func_Base *b) {
+ if(b->td)
+ clean_type_decl(a, b->td);
+ if(b->args)
+ clean_arg_list(a, b->args);
+ if(b->tmpl)
+ clean_tmpl(a, b->tmpl);
+}
+
+ANN static void clean_func_def(Clean *a, Func_Def b) {
+ ++a->scope;
+ clean_func_base(a, b->base);
+ if(b->d.code && !GET_FLAG(b, builtin))
+ clean_stmt(a, b->d.code);
+ --a->scope;
+}
+
+ANN void func_def_cleaner(const Gwion gwion, Func_Def b) {
+ Clean a = { .gwion=gwion };
+ clean_func_def(&a, b);
+ if(GET_FLAG(b, builtin))
+ b->d.code = NULL;
+ free_func_def(gwion->mp, b);
+}
+
+ANN static void clean_class_def(Clean *a, Class_Def b) {
+ clean_type_def(a, &b->base);
+ if(b->body)
+ clean_ast(a, b->body);
+}
+
+ANN static void clean_enum_def(Clean *a, Enum_Def b) {
+ clean_id_list(a, b->list);
+}
+
+ANN static void clean_union_def(Clean *a, Union_Def b) {
+ clean_decl_list(a, b->l);
+ if(b->tmpl)
+ clean_tmpl(a, b->tmpl);
+}
+
+ANN static void clean_fptr_def(Clean *a, Fptr_Def b) {
+ clean_func_base(a, b->base);
+}
+
+ANN static void clean_type_def(Clean *a, Type_Def b) {
+ if(b->ext)
+ clean_type_decl(a, b->ext);
+ if(b->tmpl)
+ clean_tmpl(a, b->tmpl);
+}
+
+DECL_SECTION_FUNC(clean, void, Clean*)
+
+ANN static inline void clean_section(Clean *a, Section *b) {
+ clean_section_func[b->section_type](a, *(void**)&b->d);
+}
+
+ANN static void clean_ast(Clean *a, Ast b) {
+ clean_section(a, b->section);
+ if(b->next)
+ clean_ast(a, b->next);
+}
+
+ANN void ast_cleaner(const Gwion gwion, Ast b) {
+ Clean a = { .gwion=gwion };
+ clean_ast(&a, b);
+ free_ast(gwion->mp, b);
+}
#include "compile.h"
#include "gwion.h"
#include "pass.h"
+#include "clean.h"
enum compile_type {
COMPILE_NAME,
}
}
-ANN static void compiler_clean(MemPool p, const struct Compiler* c) {
+ANN static void compiler_clean(const Gwion gwion, 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)
- free_ast(p, c->ast);
+ ast_cleaner(gwion, c->ast);
}
ANN static m_bool _compiler_open(struct Compiler* c) {
ANN static inline m_bool compiler_open(MemPool p, struct Compiler* c) {
char name[strlen(c->name) + 1];
strcpy(name, c->name);
+#ifdef __AFL_HAVE_MANUAL_CONTROL
+ if(strcmp(name, "afl"))
+#endif
if(c->type == COMPILE_FILE && !is_reg(name)) {
gw_err(_("'%s': is a not a regular file\n"), name);
return GW_ERROR;
MUTEX_LOCK(gwion->data->mutex);
const m_uint ret = _compile(gwion, c);
MUTEX_UNLOCK(gwion->data->mutex);
- compiler_clean(gwion->mp, c);
+ compiler_clean(gwion, c);
return ret;
}
#define emit_prim_nil (void*)dummy_func
+ANN static m_bool emit_prim_typeof(const Emitter emit, const Exp *exp) {
+ const Exp e = *exp;
+ if(!e->info->type->array_depth)
+ regpushi(emit, (m_uint)(actual_type(emit->gwion, e->info->type)));
+ else
+ regpushi(emit, (m_uint)e->info->type);
+ return GW_OK;
+}
+
ANN static inline void struct_interp(const Emitter emit, const Exp e) {
if(GET_FLAG(e->info->type, struct) && !GET_FLAG(e->info->type, builtin)) {
exp_setvar(e, 1);
return GW_OK;
}
+ANN static m_bool emit_prim_interp(const Emitter emit, const Exp *exp) {
+ const Exp e = *exp;
+ CHECK_BB(emit_interp(emit, e))
+ const Instr instr = emit_add_instr(emit, GackEnd);
+ instr->m_val = 1;
+ return GW_OK;
+}
+
DECL_PRIM_FUNC(emit, m_bool , Emitter);
ANN static m_bool emit_prim(const Emitter emit, Exp_Primary *const prim) {
return emit_prim_func[prim->prim_type](emit, &prim->d);
return ret;
}
-ANN static m_bool emit_exp_typeof(const Emitter emit, const Exp_Typeof *exp) {
- if(!exp->exp->info->type->array_depth)
- regpushi(emit, (m_uint)(actual_type(emit->gwion, exp->exp->info->type)));
- else
- regpushi(emit, (m_uint)exp->exp->info->type);
- return GW_OK;
-}
-
-ANN static m_bool emit_exp_interp(const Emitter emit, const Exp_Interp *exp) {
- CHECK_BB(emit_interp(emit, exp->exp))
- const Instr instr = emit_add_instr(emit, GackEnd);
- instr->m_val = 1;
- return GW_OK;
-}
-
DECL_EXP_FUNC(emit, m_bool, Emitter)
ANN static Type class_type(const Env env, const Type base) {
- const Type t = type_copy(env->gwion->mp, env->gwion->type[et_class]);
+ const Type t_class = env->gwion->type[et_class];
+ const Type t = type_copy(env->gwion->mp, t_class);
+ t->e->parent = t_class;
t->e->ctx = base->e->ctx;
t->e->d.base_type = base;
return t;
ANN static m_bool import_core_libs(const Gwi gwi) {
const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
+ GWI_BB(gwi_gack(gwi, t_class, gack_class)) // not working yet
GWI_BB(gwi_add_type(gwi, t_class))
GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_object_dot))
GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
GWI_BB(gwi_oper_end(gwi, "@dot", NULL))
- GWI_BB(gwi_gack(gwi, gwi->gwion->type[et_class], gack_class)) // not working yet
const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
#ifdef __AFL_HAVE_MANUAL_CONTROL
-#define BUFSIZE 4
-
static void afl_run(const Gwion gwion) {
__AFL_INIT();
- char buf[BUFSIZE];
- struct GwText_ text = { .mp=gwion->mp };
while (__AFL_LOOP(256)) {
- ssize_t sz;
- while((sz = read(0, buf, BUFSIZE-1)) > 0) {
-buf[sz] = '\0';
- text_add(&text, buf);
- }
- if(compile_string(gwion, "afl", text.str)) {
- push_global(gwion, "[afl]");
+ FILE* f = fdopen(0, "r");
+ push_global(gwion, "[afl]");
+ if(compile_file(gwion, "afl", f))
gwion_run(gwion);
- pop_global(gwion);
- }
- text_reset(&text);
+ pop_global(gwion);
}
- text_release(&text);
}
+
#define gwion_run(a) { afl_run(a); return 0; }
#endif
return env->gwion->type[et_gack];
}
+ANN static Type check_prim_typeof(const Env env, const Exp *exp) {
+ const Exp e = *exp;
+ DECL_OO(const Type, t, = check_exp(env, e))
+ DECL_OO(Value, v, = nspc_lookup_value1(t->e->owner, insert_symbol(t->name)))
+ return v->type;
+}
+
+ANN static Type check_prim_interp(const Env env, const Exp* exp) {
+ CHECK_OO(check_exp(env, *exp))
+ return env->gwion->type[et_string];
+}
+
+
+
#define describe_prim_xxx(name, type) \
ANN static Type check##_prim_##name(const Env env NUSED, const union prim_data* data NUSED) {\
return type; \
ANN static Type check_exp_lambda(const Env env,
const Exp_If* exp_if NUSED) { return env->gwion->type[et_lambda]; }
-ANN static Type check_exp_typeof(const Env env, const Exp_Typeof *exp) {
- DECL_OO(const Type, t, = check_exp(env, exp->exp))
- DECL_OO(Value, v, = nspc_lookup_value1(t->e->owner, insert_symbol(t->name)))
- return v->type;
-}
-
-ANN static Type check_exp_interp(const Env env, const Exp_Interp* exp) {
- CHECK_OO(check_exp(env, exp->exp))
- return env->gwion->type[et_string];
-}
-
DECL_EXP_FUNC(check, Type, Env)
ANN Type check_exp(const Env env, const Exp exp) {
#include "gwion_env.h"
#include "vm.h"
#include "gwion.h"
+#include "clean.h"
ANN static void free_func(Func a, Gwion gwion) {
-// if(GET_FLAG(a, template) && !GET_FLAG(a, builtin)/* && a->def->d.code*/)
if(GET_FLAG(a, template))
- free_func_def(gwion->mp, a->def);
+ func_def_cleaner(gwion, a->def);
if(a->code)
REM_REF(a->code, gwion);
mp_free(gwion->mp, Func, a);
}
ANN static inline m_bool scan1_prim(const Env env, const Exp_Primary* prim) {
- if(prim->prim_type == ae_prim_hack)
+ if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
+ prim->prim_type == ae_prim_interp)
return scan1_exp(env, prim->d.exp);
if(prim->prim_type == ae_prim_array && prim->d.array->exp)
return scan1_exp(env, prim->d.array->exp);
return unary->exp ? scan1_exp(env, unary->exp) : GW_OK;
}
-ANN static inline m_bool scan1_exp_typeof(const restrict Env env, const Exp_Typeof *exp) {
- return scan1_exp(env, exp->exp);
-}
-
-ANN static inline m_bool scan1_exp_interp(const restrict Env env, const Exp_Interp *exp) {
- return scan1_exp(env, exp->exp);
-}
-
#define scan1_exp_lambda dummy_func
HANDLE_EXP_FUNC(scan1, m_bool, Env)
}
ANN static inline m_bool scan2_prim(const Env env, const Exp_Primary* prim) {
- if(prim->prim_type == ae_prim_hack)
+ if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
+ prim->prim_type == ae_prim_interp)
CHECK_BB(scan2_exp(env, prim->d.exp))
else if(prim->prim_type == ae_prim_id) {
const Value v = prim_value(env, prim->d.var);
return GW_OK;
}
-ANN static inline m_bool scan2_exp_typeof(const restrict Env env, const Exp_Typeof *exp) {
- return scan2_exp(env, exp->exp);
-}
-
-ANN static inline m_bool scan2_exp_interp(const restrict Env env, const Exp_Interp *exp) {
- return scan2_exp(env, exp->exp);
-}
-
ANN static inline m_bool _scan2_stmt_match_case(const restrict Env env, const Stmt_Match stmt) {
CHECK_BB(scan2_exp(env, stmt->cond))
if(stmt->when)