added a new identifier - self
This commit is contained in:
parent
d1c12bc543
commit
495cea5704
@ -67,6 +67,11 @@ hcl_cnode_t* hcl_makecnodefalse (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_
|
||||
return make_cnode(hcl, HCL_CNODE_FALSE, loc, tok);
|
||||
}
|
||||
|
||||
hcl_cnode_t* hcl_makecnodeself (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok)
|
||||
{
|
||||
return make_cnode(hcl, HCL_CNODE_SELF, 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);
|
||||
|
14
lib/comp.c
14
lib/comp.c
@ -1983,14 +1983,13 @@ static int check_if_plain_cnode (hcl_t* hcl, hcl_cnode_t* obj, hcl_cnode_t* prev
|
||||
/*
|
||||
(defclass A
|
||||
| x y | ; instance variables
|
||||
| ::: x y z | ; class variables <--- how to initialize the class variables???
|
||||
::: | x y z | ; class variables <--- how to initialize the class variables???
|
||||
|
||||
; everything inside defclass after the variable declarations are normal expressions.
|
||||
; however, the resolution of some variables will fall under the enclosing class.
|
||||
(set x 20)
|
||||
(printf "normal statement ....\n");
|
||||
|
||||
|
||||
(defun new (a b c)
|
||||
(printf "%O\n" self) ; self is A
|
||||
(set obj super.new)
|
||||
@ -2990,7 +2989,6 @@ static HCL_INLINE int compile_catch (hcl_t* hcl)
|
||||
vi.index_in_ctx = hcl->c->tv.wcount - par_tmprcnt;
|
||||
if (add_temporary_variable(hcl, HCL_CNODE_GET_TOK(exarg), hcl->c->tv.s.len) <= -1) return -1;
|
||||
|
||||
|
||||
fbi = &hcl->c->fnblk.info[hcl->c->fnblk.depth];
|
||||
HCL_ASSERT (hcl, fbi->tmprlen == hcl->c->tv.s.len - HCL_CNODE_GET_TOKLEN(exarg) - 1);
|
||||
HCL_ASSERT (hcl, fbi->tmprcnt == vi.index_in_ctx + par_tmprcnt);
|
||||
@ -3630,6 +3628,8 @@ static HCL_INLINE int compile_dsymbol (hcl_t* hcl, hcl_cnode_t* obj)
|
||||
* must differentiate module access and dictioary member access...
|
||||
* must implementate dictionary member access syntax... */
|
||||
|
||||
#if 0
|
||||
the dot notation collides with car/cdr separator???
|
||||
{ /* HACK FOR NOW */
|
||||
const hcl_ooch_t* sep;
|
||||
|
||||
@ -3642,6 +3642,7 @@ HCL_DEBUG1 (hcl, ">>>> instance variable or method %js\n", sep + 1);
|
||||
}
|
||||
/* TODO: super? */
|
||||
}
|
||||
#endif
|
||||
|
||||
sym = hcl_makesymbol(hcl, HCL_CNODE_GET_TOKPTR(obj), HCL_CNODE_GET_TOKLEN(obj));
|
||||
if (HCL_UNLIKELY(!sym)) return -1;
|
||||
@ -3832,6 +3833,12 @@ redo:
|
||||
if (emit_byte_instruction(hcl, HCL_CODE_PUSH_FALSE, HCL_CNODE_GET_LOC(oprnd)) <= -1) return -1;
|
||||
goto done;
|
||||
|
||||
case HCL_CNODE_SELF:
|
||||
if (emit_byte_instruction(hcl, HCL_CODE_PUSH_RECEIVER, HCL_CNODE_GET_LOC(oprnd)) <= -1) return -1;
|
||||
goto done;
|
||||
|
||||
/* TODO: super, this-context */
|
||||
|
||||
case HCL_CNODE_CHARLIT:
|
||||
lit = HCL_CHAR_TO_OOP(oprnd->u.charlit.v);
|
||||
goto literal;
|
||||
@ -4919,7 +4926,6 @@ static HCL_INLINE int emit_class_mstore (hcl_t* hcl)
|
||||
if (add_literal(hcl, lit, &index) <= -1) return -1;
|
||||
if (emit_single_param_instruction(hcl, HCL_CODE_CLASS_MSTORE, index, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1;
|
||||
|
||||
|
||||
POP_CFRAME (hcl);
|
||||
return 0;
|
||||
}
|
||||
|
104
lib/exec.c
104
lib/exec.c
@ -88,6 +88,8 @@ static hcl_ooch_t oocstr_dash[] = { '-', '\0' };
|
||||
#define LOAD_ACTIVE_SP(hcl) LOAD_SP(hcl, (hcl)->processor->active)
|
||||
#define STORE_ACTIVE_SP(hcl) STORE_SP(hcl, (hcl)->processor->active)
|
||||
|
||||
#if 0
|
||||
// THIS PART IS TO BE REMOVED
|
||||
#define SWITCH_ACTIVE_CONTEXT(hcl,v_ctx) \
|
||||
do \
|
||||
{ \
|
||||
@ -98,6 +100,18 @@ static hcl_ooch_t oocstr_dash[] = { '-', '\0' };
|
||||
LOAD_ACTIVE_IP (hcl); \
|
||||
(hcl)->processor->active->current_context = (hcl)->active_context; \
|
||||
} while (0)
|
||||
#else
|
||||
#define SWITCH_ACTIVE_CONTEXT(hcl,v_ctx) \
|
||||
do \
|
||||
{ \
|
||||
STORE_ACTIVE_IP (hcl); \
|
||||
(hcl)->active_context = (v_ctx); \
|
||||
(hcl)->active_function = (hcl)->active_context->base; \
|
||||
(hcl)->active_code = HCL_FUNCTION_GET_CODE_BYTE((hcl)->active_function); \
|
||||
LOAD_ACTIVE_IP (hcl); \
|
||||
(hcl)->processor->active->current_context = (hcl)->active_context; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*#define FETCH_BYTE_CODE(hcl) ((hcl)->code.bc.arr->slot[(hcl)->ip++])*/
|
||||
#define FETCH_BYTE_CODE(hcl) ((hcl)->active_code[(hcl)->ip++])
|
||||
@ -1940,11 +1954,20 @@ static int prepare_new_context (hcl_t* hcl, hcl_oop_block_t op_blk, hcl_ooi_t na
|
||||
blkctx->ip = op_blk->ip;
|
||||
blkctx->req_nrets = HCL_SMOOI_TO_OOP(req_nrvars);
|
||||
blkctx->tmpr_mask = op_blk->tmpr_mask;
|
||||
blkctx->base = (hcl_oop_t)op_blk;
|
||||
blkctx->home = op_blk->home;
|
||||
/* blkctx->origin = op_blk->origin; */
|
||||
//blkctx->base = (hcl_oop_t)op_blk;
|
||||
blkctx->base = op_blk->home->base;
|
||||
blkctx->origin = op_blk->home->origin;
|
||||
blkctx->receiver = is_msgsend? HCL_STACK_GETRCV(hcl, nargs): op_blk->home->receiver;
|
||||
|
||||
if (is_msgsend)
|
||||
{
|
||||
blkctx->home = blkctx; /* itself */
|
||||
blkctx->receiver = HCL_STACK_GETRCV(hcl, nargs);
|
||||
}
|
||||
else
|
||||
{
|
||||
blkctx->home = op_blk->home;
|
||||
blkctx->receiver = op_blk->home->receiver;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (HCL_LIKELY(copy_args))
|
||||
@ -2014,9 +2037,7 @@ static HCL_INLINE int activate_block (hcl_t* hcl, hcl_ooi_t nargs, hcl_ooi_t nrv
|
||||
|
||||
static int __activate_function (hcl_t* hcl, hcl_oop_function_t op_func, hcl_ooi_t nargs, hcl_oop_context_t* pnewctx)
|
||||
{
|
||||
/* prepare a new block context for activation.
|
||||
* the receiver must be a block context which becomes the base
|
||||
* for a new block context. */
|
||||
/* prepare a new block context for activation */
|
||||
|
||||
hcl_oop_context_t functx;
|
||||
hcl_ooi_t i, j;
|
||||
@ -2031,7 +2052,6 @@ static int __activate_function (hcl_t* hcl, hcl_oop_function_t op_func, hcl_ooi_
|
||||
(printf ">>>> %d\n" (sum 10))
|
||||
*/
|
||||
|
||||
/* the receiver must be a function */
|
||||
HCL_ASSERT (hcl, HCL_IS_FUNCTION(hcl, op_func));
|
||||
|
||||
tmpr_mask = HCL_OOP_TO_SMOOI(op_func->tmpr_mask);
|
||||
@ -2059,7 +2079,7 @@ static int __activate_function (hcl_t* hcl, hcl_oop_function_t op_func, hcl_ooi_
|
||||
functx->ip = HCL_SMOOI_TO_OOP(0);
|
||||
functx->req_nrets = HCL_SMOOI_TO_OOP(1);
|
||||
functx->tmpr_mask = op_func->tmpr_mask;
|
||||
functx->base = (hcl_oop_t)op_func;
|
||||
functx->base = op_func;
|
||||
functx->home = op_func->home;
|
||||
functx->origin = functx; /* the origin of the context over a function should be itself */
|
||||
functx->receiver = HCL_STACK_GETRCV(hcl, nargs);
|
||||
@ -2088,13 +2108,13 @@ static int __activate_function (hcl_t* hcl, hcl_oop_function_t op_func, hcl_ooi_
|
||||
static HCL_INLINE int activate_function (hcl_t* hcl, hcl_ooi_t nargs)
|
||||
{
|
||||
int x;
|
||||
hcl_oop_function_t op;
|
||||
hcl_oop_function_t op_func;
|
||||
hcl_oop_context_t newctx;
|
||||
|
||||
op = (hcl_oop_function_t)HCL_STACK_GETOP(hcl, nargs);
|
||||
HCL_ASSERT (hcl, HCL_IS_FUNCTION(hcl, op));
|
||||
op_func = (hcl_oop_function_t)HCL_STACK_GETOP(hcl, nargs);
|
||||
HCL_ASSERT (hcl, HCL_IS_FUNCTION(hcl, op_func));
|
||||
|
||||
x = __activate_function(hcl, op, nargs, &newctx);
|
||||
x = __activate_function(hcl, op_func, nargs, &newctx);
|
||||
if (HCL_UNLIKELY(x <= -1)) return -1;
|
||||
|
||||
SWITCH_ACTIVE_CONTEXT (hcl, newctx);
|
||||
@ -3029,7 +3049,7 @@ static int execute (hcl_t* hcl)
|
||||
b1 = bcode & 0x7; /* low 3 bits */
|
||||
push_instvar:
|
||||
LOG_INST_1 (hcl, "push_instvar %zu", b1);
|
||||
HCL_ASSERT (hcl, HCL_OBJ_GET_FLAGS_TYPE(hcl->active_context->origin->receiver) == HCL_OBJ_TYPE_OOP);
|
||||
HCL_ASSERT (hcl, HCL_OBJ_GET_FLAGS_TYPE(hcl->active_context->receiver) == HCL_OBJ_TYPE_OOP);
|
||||
/* TODO: FIX TO OFFSET THE INHERTED PART... */
|
||||
//HCL_STACK_PUSH (hcl, ((hcl_oop_oop_t)hcl->active_context->origin->receiver)->slot[b1]);
|
||||
HCL_STACK_PUSH (hcl, ((hcl_oop_oop_t)hcl->active_context->receiver)->slot[b1]);
|
||||
@ -3052,7 +3072,8 @@ static int execute (hcl_t* hcl)
|
||||
store_instvar:
|
||||
LOG_INST_1 (hcl, "store_into_instvar %zu", b1);
|
||||
HCL_ASSERT (hcl, HCL_OBJ_GET_FLAGS_TYPE(hcl->active_context->receiver) == HCL_OBJ_TYPE_OOP);
|
||||
((hcl_oop_oop_t)hcl->active_context->origin->receiver)->slot[b1] = HCL_STACK_GETTOP(hcl);
|
||||
//((hcl_oop_oop_t)hcl->active_context->origin->receiver)->slot[b1] = HCL_STACK_GETTOP(hcl);
|
||||
((hcl_oop_oop_t)hcl->active_context->receiver)->slot[b1] = HCL_STACK_GETTOP(hcl);
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
@ -3071,17 +3092,20 @@ static int execute (hcl_t* hcl)
|
||||
pop_into_instvar:
|
||||
LOG_INST_1 (hcl, "pop_into_instvar %zu", b1);
|
||||
HCL_ASSERT (hcl, HCL_OBJ_GET_FLAGS_TYPE(hcl->active_context->receiver) == HCL_OBJ_TYPE_OOP);
|
||||
((hcl_oop_oop_t)hcl->active_context->origin->receiver)->slot[b1] = HCL_STACK_GETTOP(hcl);
|
||||
//((hcl_oop_oop_t)hcl->active_context->origin->receiver)->slot[b1] = HCL_STACK_GETTOP(hcl);
|
||||
((hcl_oop_oop_t)hcl->active_context->receiver)->slot[b1] = HCL_STACK_GETTOP(hcl);
|
||||
HCL_STACK_POP (hcl);
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
#if 0
|
||||
// the compiler never emits these instructions. reuse these instructions for other purposes
|
||||
case HCL_CODE_PUSH_TEMPVAR_X:
|
||||
case HCL_CODE_STORE_INTO_TEMPVAR_X:
|
||||
case HCL_CODE_POP_INTO_TEMPVAR_X:
|
||||
FETCH_PARAM_CODE_TO (hcl, b1);
|
||||
goto handle_tempvar;
|
||||
|
||||
|
||||
case HCL_CODE_PUSH_TEMPVAR_0:
|
||||
case HCL_CODE_PUSH_TEMPVAR_1:
|
||||
case HCL_CODE_PUSH_TEMPVAR_2:
|
||||
@ -3147,6 +3171,7 @@ static int execute (hcl_t* hcl)
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
case HCL_CODE_PUSH_LITERAL_X2:
|
||||
@ -3776,6 +3801,9 @@ HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1]
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
/* access the class variables in the initialization context.
|
||||
* the class object is at the class stack top */
|
||||
case HCL_CODE_PUSH_CLSVAR_I_X:
|
||||
{
|
||||
hcl_oop_class_t t;
|
||||
@ -3821,13 +3849,15 @@ HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1]
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
|
||||
/* access the class variables in the instance method context.
|
||||
* the receiver's class is accessed. */
|
||||
case HCL_CODE_PUSH_CLSVAR_M_X:
|
||||
{
|
||||
hcl_oop_class_t t;
|
||||
FETCH_PARAM_CODE_TO (hcl, b1);
|
||||
LOG_INST_1 (hcl, "push_clsvar_m %zu", b1);
|
||||
/* TODO: finish implementing CLSVAR_M_X instructions ....*/
|
||||
t = (hcl_oop_oop_t)hcl->active_context->origin->receiver;
|
||||
//t = (hcl_oop_oop_t)hcl->active_context->origin->receiver;
|
||||
t = (hcl_oop_oop_t)hcl->active_context->receiver;
|
||||
if (!HCL_IS_INSTANCE(hcl, t))
|
||||
{
|
||||
hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "non-instance receiver");
|
||||
@ -3844,7 +3874,8 @@ HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1]
|
||||
hcl_oop_class_t t;
|
||||
FETCH_PARAM_CODE_TO (hcl, b1);
|
||||
LOG_INST_1 (hcl, "store_into_clsvar_m %zu", b1);
|
||||
t = (hcl_oop_oop_t)hcl->active_context->origin->receiver;
|
||||
//t = (hcl_oop_oop_t)hcl->active_context->origin->receiver;
|
||||
t = (hcl_oop_oop_t)hcl->active_context->receiver;
|
||||
if (!HCL_IS_INSTANCE(hcl, t))
|
||||
{
|
||||
hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "non-instance receiver");
|
||||
@ -3861,7 +3892,8 @@ HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1]
|
||||
hcl_oop_class_t t;
|
||||
FETCH_PARAM_CODE_TO (hcl, b1);
|
||||
LOG_INST_1 (hcl, "pop_into_clsvar_m %zu", b1);
|
||||
t = (hcl_oop_oop_t)hcl->active_context->origin->receiver;
|
||||
//t = (hcl_oop_oop_t)hcl->active_context->origin->receiver;
|
||||
t = (hcl_oop_oop_t)hcl->active_context->receiver;
|
||||
if (!HCL_IS_INSTANCE(hcl, t))
|
||||
{
|
||||
hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "non-instance receiver");
|
||||
@ -3877,7 +3909,8 @@ HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1]
|
||||
|
||||
case HCL_CODE_PUSH_RECEIVER: /* push self or super */
|
||||
LOG_INST_0 (hcl, "push_receiver");
|
||||
HCL_STACK_PUSH (hcl, hcl->active_context->origin->receiver);
|
||||
//HCL_STACK_PUSH (hcl, hcl->active_context->origin->receiver);
|
||||
HCL_STACK_PUSH (hcl, hcl->active_context->receiver);
|
||||
break;
|
||||
|
||||
case HCL_CODE_PUSH_NIL:
|
||||
@ -4204,7 +4237,8 @@ HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1]
|
||||
|
||||
case HCL_CODE_RETURN_RECEIVER:
|
||||
LOG_INST_0 (hcl, "return_receiver");
|
||||
return_value = hcl->active_context->origin->receiver;
|
||||
//return_value = hcl->active_context->origin->receiver;
|
||||
return_value = hcl->active_context->receiver;
|
||||
|
||||
handle_return:
|
||||
hcl->last_retv = return_value;
|
||||
@ -4222,7 +4256,7 @@ HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1]
|
||||
|
||||
case HCL_CODE_MAKE_FUNCTION:
|
||||
{
|
||||
hcl_oop_function_t func;
|
||||
hcl_oop_function_t funcobj;
|
||||
hcl_oow_t b3, b4;
|
||||
hcl_oow_t joff;
|
||||
|
||||
@ -4256,16 +4290,16 @@ HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1]
|
||||
|
||||
/* copy the byte codes from the active context to the new context */
|
||||
#if (HCL_CODE_LONG_PARAM_SIZE == 2)
|
||||
func = make_function(hcl, b4, &hcl->active_code[hcl->ip + 3], joff, HCL_NULL);
|
||||
funcobj = make_function(hcl, b4, &hcl->active_code[hcl->ip + 3], joff, HCL_NULL);
|
||||
#else
|
||||
func = make_function(hcl, b4, &hcl->active_code[hcl->ip + 2], joff, HCL_NULL);
|
||||
funcobj = make_function(hcl, b4, &hcl->active_code[hcl->ip + 2], joff, HCL_NULL);
|
||||
#endif
|
||||
if (HCL_UNLIKELY(!func)) goto oops;
|
||||
if (HCL_UNLIKELY(!funcobj)) goto oops;
|
||||
|
||||
fill_function_data (hcl, func, b1, hcl->active_context, &hcl->active_function->literal_frame[b3], b4);
|
||||
fill_function_data (hcl, funcobj, b1, hcl->active_context, &hcl->active_function->literal_frame[b3], b4);
|
||||
|
||||
/* push the new function to the stack of the active context */
|
||||
HCL_STACK_PUSH (hcl, (hcl_oop_t)func);
|
||||
HCL_STACK_PUSH (hcl, (hcl_oop_t)funcobj);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4338,7 +4372,7 @@ oops:
|
||||
|
||||
hcl_oop_t hcl_execute (hcl_t* hcl)
|
||||
{
|
||||
hcl_oop_function_t func;
|
||||
hcl_oop_function_t funcobj;
|
||||
int n;
|
||||
hcl_bitmask_t log_default_type_mask;
|
||||
|
||||
@ -4369,13 +4403,13 @@ hcl_oop_t hcl_execute (hcl_t* hcl)
|
||||
}
|
||||
|
||||
/* create a virtual function object that hold the bytes codes generated plus the literal frame */
|
||||
func = make_function(hcl, hcl->code.lit.len, hcl->code.bc.ptr, hcl->code.bc.len, hcl->code.dbgi);
|
||||
if (HCL_UNLIKELY(!func)) return HCL_NULL;
|
||||
funcobj = make_function(hcl, hcl->code.lit.len, hcl->code.bc.ptr, hcl->code.bc.len, hcl->code.dbgi);
|
||||
if (HCL_UNLIKELY(!funcobj)) return HCL_NULL;
|
||||
|
||||
/* pass nil for the home context of the initial function */
|
||||
fill_function_data (hcl, func, ENCODE_BLKTMPR_MASK(0,0,0,hcl->code.ngtmprs), (hcl_oop_context_t)hcl->_nil, hcl->code.lit.arr->slot, hcl->code.lit.len);
|
||||
fill_function_data (hcl, funcobj, ENCODE_BLKTMPR_MASK(0,0,0,hcl->code.ngtmprs), (hcl_oop_context_t)hcl->_nil, hcl->code.lit.arr->slot, hcl->code.lit.len);
|
||||
|
||||
hcl->initial_function = func; /* the initial function is ready */
|
||||
hcl->initial_function = funcobj; /* the initial function is ready */
|
||||
|
||||
#if 0
|
||||
/* unless the system is buggy, hcl->proc_map_used should be 0.
|
||||
@ -4478,7 +4512,7 @@ hcl_pfrc_t hcl_pf_process_fork (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs)
|
||||
if (HCL_UNLIKELY(x <= -1)) return HCL_PF_FAILURE;
|
||||
|
||||
HCL_ASSERT (hcl, (hcl_oop_t)newctx->sender == hcl->_nil);
|
||||
newctx->home = hcl->_nil; /* the new context is the initial context in the new process. so reset it to nil */
|
||||
newctx->home = (hcl_oop_context_t)hcl->_nil; /* the new context is the initial context in the new process. so reset it to nil */
|
||||
|
||||
hcl_pushvolat (hcl, (hcl_oop_t*)&newctx);
|
||||
newprc = make_process(hcl, newctx);
|
||||
|
6
lib/gc.c
6
lib/gc.c
@ -55,9 +55,9 @@ static struct
|
||||
{ 16, { 'r','e','t','u','r','n','-','f','r','o','m','-','h','o','m','e'},
|
||||
HCL_SYNCODE_RETURN_FROM_HOME, HCL_OFFSETOF(hcl_t,_return_from_home) },
|
||||
{ 3, { 's','e','t' }, HCL_SYNCODE_SET, HCL_OFFSETOF(hcl_t,_set) },
|
||||
{ 5, { 's','e','t','-','r' }, HCL_SYNCODE_SET_R, HCL_OFFSETOF(hcl_t,_set_r) },
|
||||
{ 5, { 't','h','r','o','w' }, HCL_SYNCODE_THROW, HCL_OFFSETOF(hcl_t,_throw) },
|
||||
{ 3, { 't','r','y' }, HCL_SYNCODE_TRY, HCL_OFFSETOF(hcl_t,_try) },
|
||||
{ 5, { 's','e','t','-','r' }, HCL_SYNCODE_SET_R, HCL_OFFSETOF(hcl_t,_set_r) },
|
||||
{ 5, { 't','h','r','o','w' }, HCL_SYNCODE_THROW, HCL_OFFSETOF(hcl_t,_throw) },
|
||||
{ 3, { 't','r','y' }, HCL_SYNCODE_TRY, HCL_OFFSETOF(hcl_t,_try) },
|
||||
{ 5, { 'u','n','t','i','l' }, HCL_SYNCODE_UNTIL, HCL_OFFSETOF(hcl_t,_until) },
|
||||
{ 5, { 'w','h','i','l','e' }, HCL_SYNCODE_WHILE, HCL_OFFSETOF(hcl_t,_while) }
|
||||
};
|
||||
|
@ -144,6 +144,7 @@ enum hcl_iotok_type_t
|
||||
HCL_IOTOK_NIL,
|
||||
HCL_IOTOK_TRUE,
|
||||
HCL_IOTOK_FALSE,
|
||||
HCL_IOTOK_SELF,
|
||||
|
||||
HCL_IOTOK_IDENT,
|
||||
HCL_IOTOK_IDENT_DOTTED,
|
||||
@ -198,6 +199,7 @@ enum hcl_cnode_type_t
|
||||
HCL_CNODE_NIL,
|
||||
HCL_CNODE_TRUE,
|
||||
HCL_CNODE_FALSE,
|
||||
HCL_CNODE_SELF,
|
||||
HCL_CNODE_ELLIPSIS,
|
||||
HCL_CNODE_TRPCOLONS,
|
||||
|
||||
@ -1501,6 +1503,7 @@ int hcl_emitbyteinstruction (
|
||||
hcl_cnode_t* hcl_makecnodenil (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok);
|
||||
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_makecnodeellipsis (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);
|
||||
hcl_cnode_t* hcl_makecnodesymbol (hcl_t* hcl, const hcl_ioloc_t* loc, const hcl_oocs_t* tok);
|
||||
|
51
lib/hcl.h
51
lib/hcl.h
@ -376,7 +376,7 @@ typedef enum hcl_obj_type_t hcl_obj_type_t;
|
||||
#define HCL_OBJ_FLAGS_MOVED_BITS 2
|
||||
#define HCL_OBJ_FLAGS_NGC_BITS 1
|
||||
#define HCL_OBJ_FLAGS_TRAILER_BITS 1
|
||||
#define HCL_OBJ_FLAGS_SYNCODE_BITS 4
|
||||
#define HCL_OBJ_FLAGS_SYNCODE_BITS 5
|
||||
#define HCL_OBJ_FLAGS_BRAND_BITS 6
|
||||
|
||||
|
||||
@ -624,7 +624,31 @@ struct hcl_context_t
|
||||
/* SmallInteger, instruction pointer */
|
||||
hcl_oop_t ip;
|
||||
|
||||
hcl_oop_t base; /* either a block or a function */
|
||||
/* the initial context is created with the initial function object in this field.
|
||||
* a function-based context is created with the activating function object.
|
||||
* a block-based context is created with the function object that the base field of
|
||||
* the home context of the activating block context points to. */
|
||||
hcl_oop_function_t base; /* function */
|
||||
|
||||
/* TODO: get rid of origin. or rename base to origin??? with the base pointing to
|
||||
* the originating function object and a separate receiver pointer,
|
||||
* the originating function context isn't that useful.... */
|
||||
/* a function context is created with itself in this field. The function
|
||||
* context creation is based on a function object(initial or lambda/defun).
|
||||
*
|
||||
* a block context is created over a block object. it stores
|
||||
* a function context that points to itself in this field. a block context
|
||||
* points to the function context where it is created. another block context
|
||||
* created within the block context also points to the same function context.
|
||||
*
|
||||
* take note of the following points:
|
||||
* ctx->origin: function context
|
||||
* ctx->origin->base: actual function containing byte codes pertaining to ctx.
|
||||
*
|
||||
* a base of a block context is a block object but ctx->origin is guaranteed to be
|
||||
* a function context. so its base is also a function object all the time.
|
||||
*/
|
||||
hcl_oop_context_t origin;
|
||||
|
||||
/* it points to the active context at the moment when
|
||||
* this context object has been activated. a new method context
|
||||
@ -643,24 +667,8 @@ struct hcl_context_t
|
||||
* moment the block context was created. that is, it points to
|
||||
* a method context where the base block has been defined.
|
||||
* an activated block context copies this field from the base block context. */
|
||||
hcl_oop_context_t home; /* context or nil */
|
||||
hcl_oop_context_t home; /* context or nil */
|
||||
|
||||
/* a function context is created with itself in this field. The function
|
||||
* context creation is based on a function object(initial or lambda/defun).
|
||||
*
|
||||
* a block context is created over a block object. it stores
|
||||
* a function context that points to itself in this field. a block context
|
||||
* points to the function context where it is created. another block context
|
||||
* created within the block context also points to the same function context.
|
||||
*
|
||||
* take note of the following points:
|
||||
* ctx->origin: function context
|
||||
* ctx->origin->base: actual function containing byte codes pertaining to ctx.
|
||||
*
|
||||
* a base of a block context is a block object but ctx->origin is guaranteed to be
|
||||
* a function context. so its base is also a function object all the time.
|
||||
*/
|
||||
hcl_oop_context_t origin;
|
||||
|
||||
/* variable indexed part */
|
||||
hcl_oop_t slot[1]; /* arguments, return variables, local variables, other arguments, etc */
|
||||
@ -1528,7 +1536,7 @@ struct hcl_t
|
||||
|
||||
hcl_oop_t _and; /* symbol */
|
||||
hcl_oop_t _break; /* symbol */
|
||||
hcl_oop_t _catch; /* symbol */
|
||||
hcl_oop_t _catch; /* symbol */
|
||||
hcl_oop_t _continue; /* symbol */
|
||||
hcl_oop_t _defclass; /* symbol */
|
||||
hcl_oop_t _defun; /* symbol */
|
||||
@ -1842,7 +1850,8 @@ enum hcl_syncode_t
|
||||
HCL_SYNCODE_THROW,
|
||||
HCL_SYNCODE_TRY,
|
||||
HCL_SYNCODE_UNTIL,
|
||||
HCL_SYNCODE_WHILE
|
||||
HCL_SYNCODE_WHILE,
|
||||
|
||||
};
|
||||
typedef enum hcl_syncode_t hcl_syncode_t;
|
||||
|
||||
|
@ -992,7 +992,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 }
|
||||
{ 5, { 'f','a','l','s','e' }, HCL_IOTOK_FALSE },
|
||||
{ 4, { 's','e','l','f' }, HCL_IOTOK_SELF }
|
||||
};
|
||||
|
||||
for (i = 0; i < HCL_COUNTOF(tab); i++)
|
||||
@ -1990,6 +1991,10 @@ static hcl_cnode_t* read_object (hcl_t* hcl)
|
||||
obj = hcl_makecnodefalse(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||
break;
|
||||
|
||||
case HCL_IOTOK_SELF:
|
||||
obj = hcl_makecnodeself(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||
break;
|
||||
|
||||
case HCL_IOTOK_ELLIPSIS:
|
||||
obj = hcl_makecnodeellipsis(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user