diff --git a/lib/cnode.c b/lib/cnode.c index 586c34d..4686bf2 100644 --- a/lib/cnode.c +++ b/lib/cnode.c @@ -72,6 +72,11 @@ hcl_cnode_t* hcl_makecnodeself (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_o return make_cnode(hcl, HCL_CNODE_SELF, loc, tok); } +hcl_cnode_t* hcl_makecnodesuper (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok) +{ + return make_cnode(hcl, HCL_CNODE_SUPER, loc, tok); +} + hcl_cnode_t* hcl_makecnodeellipsis (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok) { return make_cnode(hcl, HCL_CNODE_ELLIPSIS, loc, tok); diff --git a/lib/comp.c b/lib/comp.c index 6599369..e91dff8 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -3856,10 +3856,11 @@ redo: goto done; case HCL_CNODE_SELF: + case HCL_CNODE_SUPER: if (emit_byte_instruction(hcl, HCL_CODE_PUSH_RECEIVER, HCL_CNODE_GET_LOC(oprnd)) <= -1) return -1; goto done; - /* TODO: super, this-context */ + /* TODO: this-context */ case HCL_CNODE_CHARLIT: lit = HCL_CHAR_TO_OOP(oprnd->u.charlit.v); diff --git a/lib/exec.c b/lib/exec.c index 4591892..9888a78 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -2131,7 +2131,7 @@ static HCL_INLINE int call_primitive (hcl_t* hcl, hcl_ooi_t nargs) /* ------------------------------------------------------------------------- */ -static hcl_oop_block_t find_cmethod_noseterr (hcl_t* hcl, hcl_oop_class_t class_, hcl_oop_t op_name, hcl_oop_class_t* owner) +static hcl_oop_block_t find_cmethod_noseterr (hcl_t* hcl, hcl_oop_class_t class_, hcl_oop_t op_name, int to_super, hcl_oop_class_t* owner) { hcl_oocs_t name; @@ -2142,10 +2142,17 @@ static hcl_oop_block_t find_cmethod_noseterr (hcl_t* hcl, hcl_oop_class_t class_ name.ptr = HCL_OBJ_GET_CHAR_SLOT(op_name); name.len = HCL_OBJ_GET_SIZE(op_name); + if (to_super) + { + class_ = (hcl_oop_class_t)class_->superclass; + if (!HCL_IS_CLASS(hcl, class_)) return HCL_NULL; + } + do { hcl_oop_t dic; + dic = class_->cdic; HCL_ASSERT (hcl, HCL_IS_NIL(hcl, dic) || HCL_IS_DIC(hcl, dic)); @@ -2172,7 +2179,7 @@ static hcl_oop_block_t find_cmethod_noseterr (hcl_t* hcl, hcl_oop_class_t class_ return HCL_NULL; } -static hcl_oop_block_t find_imethod_noseterr (hcl_t* hcl, hcl_oop_class_t class_, hcl_oop_t op, hcl_ooi_t* ivaroff, hcl_oop_class_t* owner) +static hcl_oop_block_t find_imethod_noseterr (hcl_t* hcl, hcl_oop_class_t class_, hcl_oop_t op, int to_super, hcl_ooi_t* ivaroff, hcl_oop_class_t* owner) { hcl_oocs_t name; @@ -2182,6 +2189,12 @@ static hcl_oop_block_t find_imethod_noseterr (hcl_t* hcl, hcl_oop_class_t class_ name.ptr = HCL_OBJ_GET_CHAR_SLOT(op); name.len = HCL_OBJ_GET_SIZE(op); + if (to_super) + { + class_ = (hcl_oop_class_t)class_->superclass; + if (!HCL_IS_CLASS(hcl, class_)) return HCL_NULL; + } + do { hcl_oop_t dic; @@ -2229,14 +2242,14 @@ static HCL_INLINE int send_message (hcl_t* hcl, hcl_oop_t rcv, hcl_oop_t msg, in if (HCL_IS_CLASS(hcl, rcv)) { class_ = (hcl_oop_class_t)rcv; - mth_blk = find_cmethod_noseterr(hcl, class_, msg, &owner); + mth_blk = find_cmethod_noseterr(hcl, class_, msg, to_super, &owner); } else { HCL_ASSERT (hcl, HCL_IS_INSTANCE(hcl, rcv)); HCL_ASSERT (hcl, HCL_IS_CLASS(hcl, rcv->_class)); class_ = (hcl_oop_class_t)rcv->_class; - mth_blk = find_imethod_noseterr(hcl, class_, msg, &ivaroff, &owner); + mth_blk = find_imethod_noseterr(hcl, class_, msg, to_super, &ivaroff, &owner); } if (!mth_blk) { @@ -3822,16 +3835,8 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) case HCL_CODE_SEND_X: case HCL_CODE_SEND_TO_SUPER_X: - #if 0 - /* b1 -> number of arguments - * b2 -> selector index stored in the literal frame */ - FETCH_PARAM_CODE_TO (hcl, b1); - FETCH_PARAM_CODE_TO (hcl, b2); - goto handle_send_message; - #else FETCH_PARAM_CODE_TO (hcl, b1); goto handle_send; - #endif case HCL_CODE_SEND_0: case HCL_CODE_SEND_1: diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index ff71196..544a173 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -145,6 +145,7 @@ enum hcl_iotok_type_t HCL_IOTOK_TRUE, HCL_IOTOK_FALSE, HCL_IOTOK_SELF, + HCL_IOTOK_SUPER, HCL_IOTOK_IDENT, HCL_IOTOK_IDENT_DOTTED, @@ -200,6 +201,7 @@ enum hcl_cnode_type_t HCL_CNODE_TRUE, HCL_CNODE_FALSE, HCL_CNODE_SELF, + HCL_CNODE_SUPER, HCL_CNODE_ELLIPSIS, HCL_CNODE_TRPCOLONS, @@ -1506,6 +1508,7 @@ hcl_cnode_t* hcl_makecnodenil (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_ooc hcl_cnode_t* hcl_makecnodetrue (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok); hcl_cnode_t* hcl_makecnodefalse (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok); hcl_cnode_t* hcl_makecnodeself (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok); +hcl_cnode_t* hcl_makecnodesuper (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok); hcl_cnode_t* hcl_makecnodeellipsis (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok); hcl_cnode_t* hcl_makecnodetrpcolons (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok); hcl_cnode_t* hcl_makecnodecharlit (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok, const hcl_ooch_t v); diff --git a/lib/read.c b/lib/read.c index 34c4091..b569e81 100644 --- a/lib/read.c +++ b/lib/read.c @@ -993,7 +993,8 @@ static hcl_iotok_type_t classify_ident_token (hcl_t* hcl, const hcl_oocs_t* v) { 4, { 'n','u','l','l' }, HCL_IOTOK_NIL }, { 4, { 't','r','u','e' }, HCL_IOTOK_TRUE }, { 5, { 'f','a','l','s','e' }, HCL_IOTOK_FALSE }, - { 4, { 's','e','l','f' }, HCL_IOTOK_SELF } + { 4, { 's','e','l','f' }, HCL_IOTOK_SELF }, + { 5, { 's','u','p','e','r' }, HCL_IOTOK_SUPER } }; for (i = 0; i < HCL_COUNTOF(tab); i++) @@ -1995,6 +1996,10 @@ static hcl_cnode_t* read_object (hcl_t* hcl) obj = hcl_makecnodeself(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); break; + case HCL_IOTOK_SUPER: + obj = hcl_makecnodesuper(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); + break; + case HCL_IOTOK_ELLIPSIS: obj = hcl_makecnodeellipsis(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); break;