#define __SPECIALID
typedef Type (*idck)(const Env, const Exp_Primary *);
-typedef struct Instr_ *(*idem)(const Emitter, const Exp_Primary *);
+typedef m_bool (*idem)(const Emitter, const Exp_Primary *);
struct SpecialId_ {
Type type;
#define ID_CHECK(a) \
ANN Type a(const Env env NUSED, const Exp_Primary *prim NUSED)
#define ID_EMIT(a) \
- ANN Instr a(const Emitter emit NUSED, const Exp_Primary *prim NUSED)
+ ANN m_bool a(const Emitter emit NUSED, const Exp_Primary *prim NUSED)
ANN static inline Type specialid_type(const Env env, struct SpecialId_ *spid,
const Exp_Primary *prim) {
return GW_OK;
}
-ANN static inline Instr specialid_instr(const Emitter emit,
+ANN static m_bool 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);
+ if(spid->exec) emit_add_instr(emit, spid->exec);
+ else if (spid->em) spid->em(emit, prim);
+ return GW_OK;
}
-ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) {
- const Exp_Primary *prim = prim_self(data);
+ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) {
struct SpecialId_ *spid = specialid_get(emit->gwion, *data);
if (unlikely(spid))
- return specialid_instr(emit, spid, prim_self(data)) ? GW_OK : GW_ERROR;
- if(vflag(prim->value, vflag_fglobal)) exp_self(prim)->acquire = 1;
+ return specialid_instr(emit, spid, prim_self(data));
return emit_symbol(emit, prim_self(data));
}
tflag(exp_self(prim)->type, tflag_struct)) {
const Instr instr = emit_add_instr(emit, RegPushMemDeref);
instr->m_val2 = emit->env->class_def->size;
- return (Instr)GW_OK;
+ return GW_OK;
}
const Instr instr = emit_add_instr(emit, RegPushMem);
instr->m_val = emit->status.this_offset;
- return instr;
+ return GW_OK;
+}
+
+static ID_CHECK(opck_super) {
+ const Exp self = exp_self(prim);
+ if(!env->func)
+ ERR_O(self->pos, "can't use 'super' outside of constructor");
+// move in emit?
+// if(!self->is_call)
+// ERR_O(self->pos, "'super' can only be used as a call");
+ const Type parent = env->class_def->info->parent;
+ DECL_OO(const Value, v, = find_value(parent, insert_symbol("new")));
+ SET_FLAG(env->func, const);
+ return v->type;
+}
+
+static ID_EMIT(opem_super) {
+ emit_regpushmem(emit, 0, SZ_INT, false);
+ emit_pushimm(emit, (m_uint)exp_self(prim)->type);
+ return GW_OK;
}
GWION_IMPORT(object) {
gwi_set_global_type(gwi, t_object, et_object);
set_tflag(t_object, tflag_compound);
t_object->nspc = new_nspc(gwi->gwion->mp, "Object");
- struct SpecialId_ spid = {.ck = opck_this, .em = opem_this, .is_const = 1};
- gwi_specialid(gwi, "this", &spid);
+ struct SpecialId_ spid_this = {.ck = opck_this, .em = opem_this, .is_const = 1};
+ gwi_specialid(gwi, "this", &spid_this);
+ struct SpecialId_ spid_super = {.ck = opck_super, .em = opem_super, .is_const = 1};
+ gwi_specialid(gwi, "super", &spid_super);
return GW_OK;
}