#define __GWIONDATA
typedef struct GwionData_ {
struct Map_ freearg;
+ struct Map_ id;
MUTEX_TYPE mutex;
struct Vector_ child;
struct Vector_ reserved;
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
--- /dev/null
+#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
#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))
}
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;
#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;
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;
+}
#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);
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);
#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; }
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);
+}
#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);
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))
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;
}
#include "driver.h"
#include "traverse.h"
#include "parse.h"
+#include "specialid.h"
#define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func)
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;
}
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;
}
/*
#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;
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)))
#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));
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))
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;
}
#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);
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)
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];
}
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;