preparing to handle instance/class variables in a new style
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
hyung-hwan 2024-07-06 14:29:07 +09:00
parent 6407d3c175
commit cd67f4b337

View File

@ -1394,6 +1394,65 @@ static HCL_INLINE hcl_cframe_t* find_cframe_from_top (hcl_t* hcl, int opcode)
/* ========================================================================= */
static int collect_vardcl_for_class (hcl_t* hcl, hcl_cnode_t* obj, hcl_cnode_t** nextobj, hcl_oow_t tv_dup_check_start, hcl_oow_t* nvardcls, const hcl_bch_t* desc)
{
hcl_oow_t ndcls = 0;
hcl_oow_t old_wcount = hcl->c->tv.wcount;
hcl_cnode_t* dcl;
hcl_cnode_t* var;
int coloned = 0;
dcl = HCL_CNODE_CONS_CAR(obj);
HCL_ASSERT (hcl, HCL_CNODE_IS_CONS_CONCODED(dcl, HCL_CONCODE_XLIST));
do
{
var = HCL_CNODE_CONS_CAR(dcl);
if (HCL_CNODE_IS_COLON(var))
{
if (coloned) goto synerr_varname;
coloned = 1;
goto next;
}
if (!HCL_CNODE_IS_SYMBOL_PLAIN(var))
{
synerr_varname:
hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARNAME, HCL_CNODE_GET_LOC(var), HCL_CNODE_GET_TOK(var), "not variable name");
return -1;
}
if (add_temporary_variable(hcl, HCL_CNODE_GET_TOK(var), tv_dup_check_start) <= -1)
{
if (hcl->errnum == HCL_EEXIST)
{
hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGNAMEDUP, HCL_CNODE_GET_LOC(var), HCL_CNODE_GET_TOK(var), "duplicate %hs variable", desc);
}
return -1;
}
ndcls++;
next:
dcl = HCL_CNODE_CONS_CDR(dcl);
if (!dcl) break;
if (!HCL_CNODE_IS_CONS(dcl))
{
hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_CNODE_GET_LOC(dcl), HCL_CNODE_GET_TOK(dcl), "redundant cdr in %hs variable list", desc);
return -1;
}
}
while (1);
HCL_ASSERT (hcl, ndcls == hcl->c->tv.wcount - old_wcount);
*nextobj = HCL_CNODE_CONS_CDR(obj);
*nvardcls = ndcls;
return 0;
}
static int collect_vardcl (hcl_t* hcl, hcl_cnode_t* obj, hcl_cnode_t** nextobj, hcl_oow_t tv_dup_check_start, hcl_oow_t* nvardcls, const hcl_bch_t* desc)
{
/* process a single variable declaration list */
@ -2533,7 +2592,30 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl)
)
*/
tmp = HCL_CNODE_CONS_CAR(obj);
if (/*HCL_CNODE_IS_COLON(tmp)|| */ HCL_CNODE_IS_DBLCOLONS(tmp))
if (HCL_CNODE_IS_CONS_CONCODED(tmp, HCL_CONCODE_XLIST))
{
/* instance variables */
hcl_oow_t checkpoint;
checkpoint = hcl->c->tv.s.len;
if (collect_vardcl_for_class(hcl, obj, &obj, tv_dup_check_start, &dclcount, "instance") <= -1) return -1;
nivars += dclcount;
if (ivar_len <= 0) ivar_start = (cvar_len <= 0)? checkpoint: cvar_start;
ivar_len += hcl->c->tv.s.len - checkpoint;
if (cvar_len > 0)
{
/* place the instance variables before the class variables
* if class variables "a b" has been collected before instance variables "cc dd ee"
* the rotation below manipulates the buffer to contain "cc dd ee a b".
*/
hcl_rotate_oochars (&hcl->c->tv.s.ptr[cvar_start], hcl->c->tv.s.len - cvar_start, -1, cvar_len);
cvar_start += hcl->c->tv.s.len - checkpoint;
}
}
else if (/*HCL_CNODE_IS_COLON(tmp)|| */ HCL_CNODE_IS_DBLCOLONS(tmp))
{
/* class variables */
hcl_oow_t checkpoint;
@ -2555,6 +2637,7 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl)
checkpoint = hcl->c->tv.s.len;
if (collect_vardcl(hcl, obj, &obj, tv_dup_check_start, &dclcount, "class") <= -1) return -1;
ncvars += dclcount;
if (cvar_len <= 0) cvar_start = checkpoint;
cvar_len += hcl->c->tv.s.len - checkpoint;
}