diff --git a/lib/comp.c b/lib/comp.c index 7e3b213..a2d7720 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -1259,6 +1259,7 @@ enum COP_COMPILE_CLASS_P3, COP_EMIT_PUSH_NIL, + COP_EMIT_PUSH_SYMBOL, COP_EMIT_CALL, COP_EMIT_SEND, @@ -2190,7 +2191,7 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl) if (HCL_UNLIKELY(!tmp)) goto oops; if (emit_push_literal(hcl, tmp, &cf->u._class.start_loc) <= -1) goto oops; } - + if (ncvars > 0) { hcl_oop_t tmp; @@ -3500,10 +3501,15 @@ static int compile_cons_mlist_expression (hcl_t* hcl, hcl_cnode_t* obj, int nret return -1; } car = HCL_CNODE_CONS_CAR(cdr); -/* TODO: if car is a normal symbol, it is a method name of the receiver's class. - * don't evalutate it. - * however, if it's enclosed in another () or (:), evaluate it... */ - PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, car); + if (HCL_CNODE_IS_SYMBOL_PLAIN(car)) + { + PUSH_CFRAME (hcl, COP_EMIT_PUSH_SYMBOL, car); + } + else + { +/* TODO: more sanity check on what can be used as a method */ + PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, car); + } /* compile ... etc */ cdr = HCL_CNODE_CONS_CDR(cdr); @@ -3958,7 +3964,6 @@ redo: hcl_setsynerrbfmt (hcl, HCL_SYNERR_TRPCOLONSBANNED, HCL_CNODE_GET_LOC(oprnd), HCL_CNODE_GET_TOK(oprnd), "triple colons disallowed in this context", HCL_CNODE_GET_TYPE(oprnd)); return -1; - default: hcl_setsynerrbfmt (hcl, HCL_SYNERR_INTERN, HCL_CNODE_GET_LOC(oprnd), HCL_CNODE_GET_TOK(oprnd), "internal error - unexpected object type %d", HCL_CNODE_GET_TYPE(oprnd)); return -1; @@ -4531,6 +4536,23 @@ static HCL_INLINE int emit_push_nil (hcl_t* hcl) return n; } +static HCL_INLINE int emit_push_symbol (hcl_t* hcl) +{ + hcl_cframe_t* cf; + hcl_oop_t lit; + + cf = GET_TOP_CFRAME(hcl); + HCL_ASSERT (hcl, cf->opcode == COP_EMIT_PUSH_SYMBOL); + HCL_ASSERT (hcl, cf->operand != HCL_NULL); + + lit = hcl_makesymbol(hcl, HCL_CNODE_GET_TOKPTR(cf->operand), HCL_CNODE_GET_TOKLEN(cf->operand)); + if (HCL_UNLIKELY(!lit)) return -1; + if (emit_push_literal(hcl, lit, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; + + POP_CFRAME (hcl); + return 0; +} + static HCL_INLINE int emit_send (hcl_t* hcl) { hcl_cframe_t* cf; @@ -5063,6 +5085,10 @@ int hcl_compile (hcl_t* hcl, hcl_cnode_t* obj, int flags) if (emit_push_nil(hcl) <= -1) goto oops; break; + case COP_EMIT_PUSH_SYMBOL: + if (emit_push_symbol(hcl) <= -1) goto oops; + break; + case COP_EMIT_SEND: if (emit_send(hcl) <= -1) goto oops; break; diff --git a/lib/exec.c b/lib/exec.c index b3909a7..77f9a51 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -1900,8 +1900,8 @@ static int prepare_new_context (hcl_t* hcl, hcl_oop_block_t rcv_blk, hcl_ooi_t n tmpr_mask = HCL_OOP_TO_SMOOI(rcv_blk->tmpr_mask); - fblk_nrvars = GET_BLKTMPR_MASK_NRVARS(tmpr_mask); - fblk_nlvars = GET_BLKTMPR_MASK_NLVARS(tmpr_mask); + fblk_nrvars = GET_BLKTMPR_MASK_NRVARS(tmpr_mask); + fblk_nlvars = GET_BLKTMPR_MASK_NLVARS(tmpr_mask); fixed_nargs = GET_BLKTMPR_MASK_NARGS(tmpr_mask); actual_nargs = nargs - nargs_offset; excess_nargs = actual_nargs - fixed_nargs; @@ -2021,8 +2021,8 @@ static int __activate_function (hcl_t* hcl, hcl_oop_function_t rcv_func, hcl_ooi HCL_ASSERT (hcl, HCL_IS_FUNCTION(hcl, rcv_func)); tmpr_mask = HCL_OOP_TO_SMOOI(rcv_func->tmpr_mask); - nrvars = GET_BLKTMPR_MASK_NRVARS(tmpr_mask); - nlvars = GET_BLKTMPR_MASK_NLVARS(tmpr_mask); + nrvars = GET_BLKTMPR_MASK_NRVARS(tmpr_mask); + nlvars = GET_BLKTMPR_MASK_NLVARS(tmpr_mask); fixed_nargs = GET_BLKTMPR_MASK_NARGS(tmpr_mask); actual_nargs = nargs - nargs_offset; excess_nargs = actual_nargs - fixed_nargs; @@ -2108,6 +2108,16 @@ static HCL_INLINE int call_primitive (hcl_t* hcl, hcl_ooi_t nargs) return ((hcl_pfimpl_t)rcv->impl)(hcl, (hcl_mod_t*)rcv->mod, nargs); } +/* ------------------------------------------------------------------------- */ +static HCL_INLINE int send_message (hcl_t* hcl, hcl_oop_t rcv, hcl_oop_t op, int to_super, hcl_ooi_t nargs) +{ + HCL_ASSERT (hcl, HCL_IS_INSTANCE(hcl, rcv)); + HCL_ASSERT (hcl, HCL_IS_SYMBOL(hcl, op)); + + + return 0; +} + /* ------------------------------------------------------------------------- */ static HCL_INLINE int do_throw (hcl_t* hcl, hcl_oop_t val, hcl_ooi_t ip) @@ -3667,32 +3677,9 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) rcv = HCL_STACK_GETRCV(hcl, b1); op = HCL_STACK_GETOP(hcl, b1); - if (HCL_OOP_IS_POINTER(op)) + if (HCL_IS_INSTANCE(hcl, rcv) && HCL_IS_SYMBOL(hcl, op)) { - switch (HCL_OBJ_GET_FLAGS_BRAND(op)) - { - case HCL_BRAND_FUNCTION: - if (activate_function(hcl, b1) <= -1) goto call_failed; - break; - - case HCL_BRAND_BLOCK: - if (activate_block(hcl, b1, 0) <= -1) goto call_failed; - break; - - case HCL_BRAND_PRIM: - if (call_primitive(hcl, b1) <= -1) - { -/* -TODO: translate a certain primitive failure to a catchable exception. this seems to work . i need to capture the throw value instead of hcl->_nil . -if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) -*/ - goto call_failed; - } - break; - - default: - goto cannot_send; - } + if (send_message(hcl, rcv, op, ((bcode >> 2) & 1), b1) <= -1) goto send_failed; } else {