]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve AFL
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Sat, 9 May 2020 14:48:06 +0000 (16:48 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Sat, 9 May 2020 14:48:06 +0000 (16:48 +0200)
13 files changed:
ast
include/clean.h [new file with mode: 0644]
scripts/afl-dict/sum
src/clean.c [new file with mode: 0644]
src/compile.c
src/emit/emit.c
src/env/env_utils.c
src/lib/engine.c
src/main.c
src/parse/check.c
src/parse/func.c
src/parse/scan1.c
src/parse/scan2.c

diff --git a/ast b/ast
index cc3a1b18354ea5f3d06bfec3eb747ed3cec4a141..b631a0ecbc6687ff9b38ad417f0f250f68fdb17f 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit cc3a1b18354ea5f3d06bfec3eb747ed3cec4a141
+Subproject commit b631a0ecbc6687ff9b38ad417f0f250f68fdb17f
diff --git a/include/clean.h b/include/clean.h
new file mode 100644 (file)
index 0000000..5e64850
--- /dev/null
@@ -0,0 +1,60 @@
+#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
index 3e0e6b2eda4db6867e9b7428db3b712d9539b5f9..27fb3e10ef3db1fae5e9c1842fa941858683b63d 100644 (file)
@@ -6,6 +6,7 @@ keyword_spork="spork"
 keyword_fork="fork"
 keyword_union="union"
 keyword_class="class"
+keyword_struct="struct"
 keyword_dtor="dtor"
 keyword_operator="operator"
 keyword_extends="extends"
@@ -14,6 +15,8 @@ keyword_static="static"
 keyword_protect="protect"
 keyword_private="private"
 keyword_const="const"
+keyword_ref="ref"
+keyword_nonnull="nonnull"
 keyword_if="if"
 keyword_else="else"
 keyword_break="break"
@@ -57,4 +60,4 @@ symbol_colon=":"
 
 
 symbol_gack1="<<<"
-symbol_gack2=">>>"
\ No newline at end of file
+symbol_gack2=">>>"
diff --git a/src/clean.c b/src/clean.c
new file mode 100644 (file)
index 0000000..9b04359
--- /dev/null
@@ -0,0 +1,335 @@
+#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);
+}
index 2f9cca9f1b2f207216094d98f2b4f7ca5fb7ec34..8621b0a1f1a7977c015f7e84e654b8e62db13648 100644 (file)
@@ -7,6 +7,7 @@
 #include "compile.h"
 #include "gwion.h"
 #include "pass.h"
+#include "clean.h"
 
 enum compile_type {
   COMPILE_NAME,
@@ -45,14 +46,14 @@ ANN static inline void compiler_error(MemPool p, const struct Compiler* c) {
   }
 }
 
-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) {
@@ -86,6 +87,9 @@ ANN static m_bool is_reg(const m_str path) {
 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;
@@ -132,7 +136,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->mp, c);
+  compiler_clean(gwion, c);
   return ret;
 }
 
index 806efee2f15352ae8070d45ccf81940312236d8b..8c21a47c2950b0aae64fdab42858937325ec47aa 100644 (file)
@@ -484,6 +484,15 @@ ANN static m_bool emit_prim_str(const Emitter emit, const m_str *str) {
 
 #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);
@@ -531,6 +540,14 @@ ANN static m_bool emit_prim_hack(const Emitter emit, const Exp *exp) {
   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);
@@ -1220,21 +1237,6 @@ ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda)
   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)
 
 
index 9fa3959644109582143a7fa08c758b955f4a1ba4..8ee418158408d32a5b8f1a694e564119af14f783 100644 (file)
@@ -75,7 +75,9 @@ ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos) {
 
 
 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;
index b920d6b3558d43a2475a8d5082c75ea176b49781..5e3c40f6e5cd8c09a5036939ac996055ee8b9371 100644 (file)
@@ -68,12 +68,12 @@ OP_EMIT(opem_object_dot);
 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);
index 3229e3b5958c3fad5bfe6bdd29dbe01dbf846fd7..5f2fba6aeac62d704628b1e7f9e1d75f5bef657c 100644 (file)
@@ -17,27 +17,17 @@ static void sig(int unused NUSED) {
 
 #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
 
index 8e7b7f5bd2420c0b9e9520aa9efbf2fd542ec51c..1d6131fbf959ad25cd034415e5d9b2c02dbadbec 100644 (file)
@@ -318,6 +318,20 @@ ANN static Type check_prim_hack(const Env env, const Exp *data) {
   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; \
@@ -876,17 +890,6 @@ ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
 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) {
index 6c78802cddf5438981431f9017a82b6804579048..053033068a98c3cb6d080fad7104d211ca3ad86d 100644 (file)
@@ -3,11 +3,11 @@
 #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);
index a78ae058e65b5f59c3129cd4b4b0432d3f29e1c4..c3325ba2daab9e18fd2cb5ee62601f516f00e69b 100644 (file)
@@ -155,7 +155,8 @@ ANN static m_bool scan1_range(const Env env, Range *range) {
 }
 
 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);
@@ -214,14 +215,6 @@ ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary
   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)
 
index c52c5fd9a8bc8450482d9226dbefe9d220a78fb3..74e0031df26915ea7e560276a745fe5a202a47ac 100644 (file)
@@ -101,7 +101,8 @@ ANN static m_bool scan2_range(const Env env, Range *range) {
 }
 
 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);
@@ -174,14 +175,6 @@ ANN static m_bool scan2_exp_unary(const Env env, const Exp_Unary * unary) {
   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)