]> Nishi Git Mirror - gwion.git/commitdiff
:art: Introduce SpecialId
authorfennecdjay <astor.jeremie@wanadoo.fr>
Mon, 23 Sep 2019 14:16:43 +0000 (16:16 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Mon, 23 Sep 2019 14:16:43 +0000 (16:16 +0200)
12 files changed:
include/gwiondata.h
include/import.h
include/specialid.h [new file with mode: 0644]
src/emit/emit.c
src/gwion.c
src/gwiondata.c
src/lib/import.c
src/lib/object.c
src/lib/prim.c
src/lib/shred.c
src/lib/string.c
src/parse/check.c

index f0e31285dec801c7c814ab88b9da25779ae61dd4..c21a27ac5cc52f712add1e968f1e241ba4065b1d 100644 (file)
@@ -2,6 +2,7 @@
 #define __GWIONDATA
 typedef struct GwionData_ {
   struct Map_ freearg;
+  struct Map_ id;
   MUTEX_TYPE mutex;
   struct Vector_ child;
   struct Vector_ reserved;
index d8bd808def35175edf5000ee87b2eceb3f99a027..3122f6ff06b85c60399c22d5ff6dc94b5885c43e 100644 (file)
@@ -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
diff --git a/include/specialid.h b/include/specialid.h
new file mode 100644 (file)
index 0000000..13fe0e5
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __SPECIALID
+#define __SPECIALID
+
+//typedef struct SpecialId_* SpecialId;
+struct SpecialId_;
+typedef Type (*idck)(const Env, Exp_Primary*);
+typedef Instr (*idem)(const Emitter, 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, Exp_Primary* prim NUSED)
+#define ID_EMIT(a)  ANN Instr a(const Emitter emit NUSED, 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
index 38681317d6ec89ebebcd4ae30d994888796282e5..abaca1d6cff2409ae1efc0410ba6b4bd3a08b881 100644 (file)
@@ -24,6 +24,7 @@
 #include "match.h"
 #include "parser.h"
 #include "tuple.h"
+#include "specialid.h"
 
 #undef insert_symbol
 #define insert_symbol(a) insert_symbol(emit->gwion->st, (a))
@@ -512,14 +513,9 @@ ANN static m_bool prim_vec(const Emitter emit, const Exp_Primary * primary) {
 }
 
 ANN static m_bool prim_id(const Emitter emit, const Exp_Primary* prim) {
-  if(prim->d.var == insert_symbol("this"))
-    emit_add_instr(emit, RegPushMem);
-  else if(prim->d.var == insert_symbol("me"))
-    emit_add_instr(emit, RegPushMe);
-  else if(prim->d.var == insert_symbol("now"))
-    emit_add_instr(emit, RegPushNow);
-  else if(prim->d.var == insert_symbol("maybe"))
-    emit_add_instr(emit, RegPushMaybe);
+  struct SpecialId_ * spid = specialid_get(emit->gwion, prim->d.var);
+  if(spid)
+    return specialid_instr(emit, spid, prim) ? GW_OK : GW_ERROR;
   else
     emit_symbol(emit, prim);
   return GW_OK;
index edb8c2222e003886eda528def9680a319dff4ed3..f80bb4dce2ec90174c36bd770f46354df753034a 100644 (file)
@@ -17,6 +17,7 @@
 #include "compile.h"
 #include "object.h" // fork_clean
 #include "pass.h" // fork_clean
+#include "specialid.h" // fork_clean
 
 ANN m_bool gwion_audio(const Gwion gwion) {
   Driver* di = gwion->vm->bbq;
@@ -129,3 +130,12 @@ ANN void env_err(const Env env, const struct YYLTYPE* pos, const m_str fmt, ...)
   if(env->context)
     env->context->error = 1;
 }
+
+ANN struct SpecialId_* specialid_get(const Gwion gwion, const Symbol sym) {
+  const Map map = &gwion->data->id;
+  for(m_uint i = 0; i < map_size(map); ++i) {
+    if(sym == (Symbol)VKEY(map, i))
+      return (struct SpecialId_*)VVAL(map, i);
+  }
+  return NULL;
+}
index 92645bf2eb82a9576392fe68bf24bea1173933e2..11306a6393e931dbb49f57413169749bb55d6f57 100644 (file)
@@ -1,10 +1,17 @@
 #include "gwion_util.h"
 #include "gwion_ast.h"
 #include "gwiondata.h"
+#include "oo.h"
+#include "env.h"
+#include "vm.h"
+#include "instr.h"
+#include "gwion.h"
+#include "specialid.h"
 
 ANN GwionData* new_gwiondata(MemPool mp) {
   struct GwionData_ *data = mp_calloc(mp, GwionData);
   map_init(&data->freearg);
+  map_init(&data->id);
   vector_init(&data->reserved);
   map_init(&data->pass_map);
   vector_init(&data->pass);
@@ -14,6 +21,9 @@ ANN GwionData* new_gwiondata(MemPool mp) {
 
 ANN void free_gwiondata(MemPool mp, GwionData *data) {
   map_release(&data->freearg);
+  for(m_uint i = 0; i < map_size(&data->id); ++i)
+    mp_free(mp, SpecialId, (struct SpecialId_*)map_at(&data->id, i));
+  map_release(&data->id);
   vector_release(&data->reserved);
   map_release(&data->pass_map);
   vector_release(&data->pass);
index 10103aa287f05d17d3679c3ef8b010d67fa9406a..6391fce571c786761a8fa9dcac4c49dece19f262 100644 (file)
@@ -19,6 +19,7 @@
 #include "import.h"
 #include "gwi.h"
 #include "mpool.h"
+#include "specialid.h"
 
 #define GWI_ERR_B(a,...) { env_err(gwi->gwion->env, gwi->loc, (a), ## __VA_ARGS__); return GW_ERROR; }
 #define GWI_ERR_O(a,...) { env_err(gwi->gwion->env, gwi->loc, (a), ## __VA_ARGS__); return NULL; }
@@ -679,3 +680,12 @@ ANN void register_freearg(const Gwi gwi, const f_instr _exec, const f_freearg _f
 ANN void gwi_reserve(const Gwi gwi, const m_str str) {
   vector_add(&gwi->gwion->data->reserved, (vtype)insert_symbol(gwi->gwion->st, str));
 }
+
+ANN void gwi_specialid(const Gwi gwi, const m_str id, const SpecialId spid) {
+  struct SpecialId_ *a = mp_calloc(gwi->gwion->mp, SpecialId);
+  a->type = spid->type;
+  a->ck = spid->ck;
+  a->exec = spid->exec;
+  a->em = spid->em;
+  map_set(&gwi->gwion->data->id, (vtype)insert_symbol(gwi->gwion->st, id), (vtype)a);
+}
index 482f66afe588312f14aa3de6d947c465356ecc2c..fc5cad828335b8e3520f126f805fef83c014e084 100644 (file)
 #include "operator.h"
 #include "import.h"
 #include "emit.h"
+#include "traverse.h"
+#include "parse.h"
+#include "func.h"
+#include "specialid.h"
 
+#include "gwi.h"
+
+#undef insert_symbol
 ANN void exception(const VM_Shred shred, const m_str c) {
   gw_err("%s: shred[id=%" UINT_F ":%s], PC=[%" UINT_F "]\n",
           c, shred->tick->xid, shred->info->name, shred->pc - 1);
@@ -206,6 +213,14 @@ static OP_EMIT(opem_implicit_null2obj) {
   return (Instr)GW_OK;
 }
 
+static ID_CHECK(check_this) {
+  if(!env->class_def)
+    ERR_O(exp_self(prim)->pos, _("keyword 'this' can be used only inside class definition..."))
+  if(env->func && !GET_FLAG(env->func, member))
+    ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions..."))
+  return env->class_def;
+}
+
 GWION_IMPORT(object) {
   t_object  = gwi_mk_type(gwi, "Object", SZ_INT, NULL);
   GWI_BB(gwi_class_ini(gwi, t_object, NULL, NULL))
@@ -244,5 +259,7 @@ GWION_IMPORT(object) {
   gwi_item_ini(gwi, "@null", "null");
   gwi_item_end(gwi, 0, NULL);
   gwi_reserve(gwi, "this");
+  struct SpecialId_ spid = { .ck=check_this, .exec=RegPushMem, .is_const=1 };
+  gwi_specialid(gwi, "this", &spid);
   return GW_OK;
 }
index 8a4048c9798ef6a42dfeecf4fa4ffa60d9b4569c..295e6809fd66d72b7ff11a491ef0ae98d0487dc6 100644 (file)
@@ -14,6 +14,7 @@
 #include "driver.h"
 #include "traverse.h"
 #include "parse.h"
+#include "specialid.h"
 
 #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func)
 
@@ -78,9 +79,11 @@ static GWION_IMPORT(int_values) {
   GWI_BB(gwi_enum_add(gwi, "false", 0))
   GWI_BB(gwi_enum_add(gwi, "true", 1))
   t_bool = gwi_enum_end(gwi);
-  GWI_BB(gwi_item_ini(gwi, "bool", "maybe"))
-  GWI_BB(gwi_item_end(gwi, 0, NULL))
+//  GWI_BB(gwi_item_ini(gwi, "bool", "maybe"))
+//  GWI_BB(gwi_item_end(gwi, 0, NULL))
   gwi_reserve(gwi, "maybe");
+  struct SpecialId_ spid = { .type=t_bool, .exec=RegPushMaybe, .is_const=1 };
+  gwi_specialid(gwi, "maybe", &spid);
   return GW_OK;
 }
 
@@ -126,6 +129,8 @@ static GWION_IMPORT(values) {
   gwi_item_ini(gwi, "@now", "now");
   gwi_item_end(gwi, ae_flag_const, NULL);
   gwi_reserve(gwi, "now");
+  struct SpecialId_ spid = { .type=t_now, .exec=RegPushNow, .is_const=1 };
+  gwi_specialid(gwi, "now", &spid);
   return GW_OK;
 }
 /*
index a727e08a8f1a9bc6fb7611b00229747f7f0101fa..da411adf10eb66760355e0b3e13a96470c5e36b4 100644 (file)
@@ -12,6 +12,7 @@
 #include "gwion.h"
 #include "operator.h"
 #include "import.h"
+#include "specialid.h"
 
 static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_retval, 
   o_fork_orig;
@@ -291,8 +292,10 @@ GWION_IMPORT(shred) {
   GWI_BB(gwi_func_end(gwi, 0))
   GWI_BB(gwi_class_end(gwi))
 
-  gwi_item_ini(gwi, "Shred", "me");
-  gwi_item_end(gwi, ae_flag_const, NULL);
+  gwi_reserve(gwi, "me");
+  struct SpecialId_ spid = { .type=t_shred, .exec=RegPushMe, .is_const=1 };
+  gwi_specialid(gwi, "me", &spid);
+
   SET_FLAG((t_shred), abstract);
 
   GWI_OB((t_fork = gwi_mk_type(gwi, "Fork", SZ_INT, t_shred)))
index d323bbce26e620d2385046381d107b9dd79a08fd..fbb3ecbae6550ae5500ad94fba285b32c18f1d6b 100644 (file)
@@ -13,6 +13,8 @@
 #include "gwion.h"
 #include "operator.h"
 #include "import.h"
+#include "specialid.h"
+#include "func.h"
 
 ANN static void push_string(const VM_Shred shred, const M_Object obj, const m_str c) {
   STRING(obj) = s_name(insert_symbol(shred->info->vm->gwion->st, c));
@@ -169,6 +171,14 @@ static CTOR(string_ctor) {
   STRING(o) = "";
 }
 
+ANN Type prim_str(const Env, Exp_Primary *const);
+ID_CHECK(check_funcpp) {
+  prim->primary_type = ae_primary_str;
+  prim->d.str = env->func ? env->func->name : env->class_def ?
+    env->class_def->name : env->name;
+  return prim_str(env, prim);
+}
+
 GWION_IMPORT(string) {
   t_string = gwi_mk_type(gwi, "string", SZ_INT, t_object);
   GWI_BB(gwi_class_ini(gwi,  t_string, string_ctor, NULL))
@@ -244,8 +254,12 @@ GWION_IMPORT(string) {
   GWI_BB(gwi_oper_add(gwi, opck_const_rhs))
   GWI_BB(gwi_oper_end(gwi, "+=>", Object_String_Plus))
 
-  gwi_item_ini(gwi, "string", "__func__");
-  gwi_item_end(gwi, ae_flag_const, NULL);
+//  gwi_item_ini(gwi, "string", "__func__");
+//  gwi_item_end(gwi, ae_flag_const, NULL);
+//  gwi_reserve(gwi, "__func__");
+
   gwi_reserve(gwi, "__func__");
+  struct SpecialId_ spid = { .ck=check_funcpp, .exec=RegPushMe, .is_const=1 };
+  gwi_specialid(gwi, "__func__", &spid);
   return GW_OK;
 }
index 52897ff1a762da33ab064a003af9ca2606615145..9c8881bca0620bb8fe80db0c456b326a14a054be 100644 (file)
@@ -20,6 +20,7 @@
 #include "match.h"
 #include "cpy_ast.h"
 #include "tuple.h"
+#include "specialid.h"
 
 ANN static Type   check_exp(const Env env, Exp exp);
 ANN static m_bool check_stmt_list(const Env env, Stmt_List list);
@@ -237,16 +238,6 @@ ANN static Type prim_id_non_res(const Env env, const Exp_Primary* primary) {
   return v->type;
 }
 
-ANN static Type check_exp_prim_this(const Env env, const Exp_Primary* primary) {
-  if(!env->class_def)
-    ERR_O(exp_self(primary)->pos, _("keyword 'this' can be used only inside class definition..."))
-  if(env->func && !GET_FLAG(env->func, member))
-    ERR_O(exp_self(primary)->pos, _("keyword 'this' cannot be used inside static functions..."))
-  exp_self(primary)->meta = ae_meta_value;
-  return env->class_def;
-}
-
-
 ANN static inline Value prim_str_value(const Env env, const Symbol sym) {
   const Value v = nspc_lookup_value0(env->global_nspc, sym);
   if(v)
@@ -256,7 +247,7 @@ ANN static inline Value prim_str_value(const Env env, const Symbol sym) {
   return value;
 }
 
-ANN static Type prim_str(const Env env, Exp_Primary *const prim) {
+ANN Type prim_str(const Env env, Exp_Primary *const prim) {
   if(!prim->value) {
     const m_str str = prim->d.str;
     char c[strlen(str) + 8];
@@ -267,10 +258,11 @@ ANN static Type prim_str(const Env env, Exp_Primary *const prim) {
 }
 
 ANN static Type prim_id(const Env env, Exp_Primary* primary) {
+  struct SpecialId_ * spid = specialid_get(env->gwion, primary->d.var);
+  if(spid)
+    return specialid_type(env, spid, primary);
   const m_str str = s_name(primary->d.var);
-  if(!strcmp(str, "this"))
-    return check_exp_prim_this(env, primary);
-  else if(!strcmp(str, "__func__")) {
+  if(!strcmp(str, "__func__")) {
     primary->primary_type = ae_primary_str;
     primary->d.str = env->func ? env->func->name : env->class_def ?
       env->class_def->name : env->name;