WIP - multi-vars assignment

This commit is contained in:
hyung-hwan 2024-01-13 14:37:59 +09:00
parent f70a087525
commit c5606262b9
2 changed files with 54 additions and 19 deletions

View File

@ -3843,8 +3843,8 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_cnode_t* obj, int nret
} }
else if (HCL_CNODE_IS_SYMBOL(car) || HCL_CNODE_IS_DSYMBOL(car) || else if (HCL_CNODE_IS_SYMBOL(car) || HCL_CNODE_IS_DSYMBOL(car) ||
HCL_CNODE_IS_CONS_CONCODED(car, HCL_CONCODE_XLIST) || HCL_CNODE_IS_CONS_CONCODED(car, HCL_CONCODE_XLIST) ||
HCL_CNODE_IS_CONS_CONCODED(car, HCL_CONCODE_MLIST) /*TODO|| HCL_CNODE_IS_CONS_CONCODED(car, HCL_CONCODE_MLIST) /* ||
HCL_CNODE_IS_CONS_CONCODED(car, HCL_CONCODE_ALIST)*/) HCL_CNODE_IS_CONS_CONCODED(car, HCL_CONCODE_ALIST)*/) /* NOTE: ALIST is only used in read.c and the reader transforms it to the set expression */
{ {
/* normal function call /* normal function call
* (<operator> <operand1> ...) */ * (<operator> <operand1> ...) */
@ -4130,7 +4130,6 @@ static HCL_INLINE int compile_dsymbol (hcl_t* hcl, hcl_cnode_t* obj)
if (hcl_comp_oochars_bcstr(name.ptr, (sep - (const hcl_ooch_t*)name.ptr), "self") == 0) if (hcl_comp_oochars_bcstr(name.ptr, (sep - (const hcl_ooch_t*)name.ptr), "self") == 0)
{ {
/* instance variable? or instance method? */ /* instance variable? or instance method? */
HCL_DEBUG1 (hcl, ">>>> instance variable or method %js\n", sep + 1);
name.ptr = (hcl_ooch_t*)(sep + 1); name.ptr = (hcl_ooch_t*)(sep + 1);
name.len -= 5; name.len -= 5;
x = find_variable_backward_with_word(hcl, &name, HCL_CNODE_GET_LOC(obj), 1, &vi); x = find_variable_backward_with_word(hcl, &name, HCL_CNODE_GET_LOC(obj), 1, &vi);
@ -4483,7 +4482,7 @@ redo:
case HCL_CONCODE_MLIST: case HCL_CONCODE_MLIST:
if (compile_cons_mlist_expression(hcl, oprnd, 0) <= -1) return -1; if (compile_cons_mlist_expression(hcl, oprnd, 0) <= -1) return -1;
break; break;
/* TODO: /* TODO:
case HCL_CONCODE_ALIST: case HCL_CONCODE_ALIST:
break; break;
*/ */

View File

@ -56,10 +56,11 @@ static struct voca_t
{ 5, { 's','u','p','e','r' } }, { 5, { 's','u','p','e','r' } },
{ 3, { 's','e','t' } }, { 3, { 's','e','t' } },
{ 5, { 's','e','t','-','r' } },
{ 3, { '(',' ',')' /* XLIST */ } }, { 3, { '(',' ',')' /* XLIST */ } },
{ 4, { '(',':',' ',')' /* MLIST */ } }, { 4, { '(',':',' ',')' /* MLIST */ } },
{ 3, { '(',':','=',')' } }, { 3, { '(',':','=',')' /* ALIST */ } },
{ 3, { '{',' ','}' /* BLOCK */ } }, { 3, { '{',' ','}' /* BLOCK */ } },
{ 3, { '[',' ',']' /* ARRAY */ } }, { 3, { '[',' ',']' /* ARRAY */ } },
{ 4, { '#','[',' ',']' } }, { 4, { '#','[',' ',']' } },
@ -94,10 +95,11 @@ enum voca_id_t
VOCA_KW_SUPER, VOCA_KW_SUPER,
VOCA_SYM_SET, VOCA_SYM_SET,
VOCA_SYM_SET_R,
VOCA_XLIST, VOCA_XLIST,
VOCA_MLIST, VOCA_MLIST,
VOCA_ALIST, VOCA_ALIST, /* assignment list */
VOCA_BLOCK, VOCA_BLOCK,
VOCA_ARRAY, VOCA_ARRAY,
VOCA_BYTEARRAY, VOCA_BYTEARRAY,
@ -570,12 +572,43 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
if (concode == HCL_CONCODE_ALIST) if (concode == HCL_CONCODE_ALIST)
{ {
/* tranform (var := val) to (set var val) */ /* tranform (var := val) to (set var val) */
hcl_cnode_t* sym, * newhead; hcl_cnode_t* sym, * newhead, * rval;
hcl_oocs_t fake_tok, * fake_tok_ptr = HCL_NULL; hcl_oocs_t fake_tok, * fake_tok_ptr = HCL_NULL;
fake_tok.ptr = vocas[VOCA_SYM_SET].str; rval = HCL_CNODE_CONS_CAR(head);
fake_tok.len = vocas[VOCA_SYM_SET].len; if (rval && HCL_CNODE_IS_CONS(rval) && HCL_CNODE_CONS_CONCODE(rval) == HCL_CONCODE_ARRAY)
fake_tok_ptr = &fake_tok; {
hcl_cnode_t* tmp, * lval;
fake_tok.ptr = vocas[VOCA_SYM_SET_R].str;
fake_tok.len = vocas[VOCA_SYM_SET_R].len;
fake_tok_ptr = &fake_tok;
/* move the array item up to the main list */
/* TODO: check ELIST separately??? */
lval = HCL_CNODE_CONS_CDR(lval);
HCL_CNODE_CONS_CAR(head) = HCL_CNODE_CONS_CAR(rval);
hcl_dumpcnode(hcl, tmp, 1);
hcl_dumpcnode(hcl, rval, 1);
for (tmp = rval; tmp && HCL_CNODE_IS_CONS(tmp); tmp = HCL_CNODE_CONS_CDR(tmp))
{
if (!HCL_CNODE_CONS_CDR(tmp))
{
// HCL_CNODE_CONS_CDR(tmp) = lval;
break;
}
}
hcl_dumpcnode(hcl, rval, 1);
hcl_freesinglecnode (hcl, rval);
hcl_dumpcnode(hcl, head, 1);
}
else
{
fake_tok.ptr = vocas[VOCA_SYM_SET].str;
fake_tok.len = vocas[VOCA_SYM_SET].len;
fake_tok_ptr = &fake_tok;
}
/* TODO: check the number of argumetns in advance??? */ /* TODO: check the number of argumetns in advance??? */
sym = hcl_makecnodesymbol(hcl, 0, &loc, fake_tok_ptr); sym = hcl_makecnodesymbol(hcl, 0, &loc, fake_tok_ptr);
@ -587,6 +620,7 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
return HCL_NULL; return HCL_NULL;
} }
newhead = hcl_makecnodecons(hcl, 0, &loc, fake_tok_ptr, sym, head); newhead = hcl_makecnodecons(hcl, 0, &loc, fake_tok_ptr, sym, head);
if (HCL_UNLIKELY(!newhead)) if (HCL_UNLIKELY(!newhead))
{ {
@ -637,6 +671,7 @@ static HCL_INLINE int can_dot_list (hcl_t* hcl)
static HCL_INLINE int can_comma_list (hcl_t* hcl) static HCL_INLINE int can_comma_list (hcl_t* hcl)
{ {
hcl_rstl_t* rstl; hcl_rstl_t* rstl;
hcl_concode_t cc;
HCL_ASSERT (hcl, hcl->c->r.st != HCL_NULL); HCL_ASSERT (hcl, hcl->c->r.st != HCL_NULL);
rstl = hcl->c->r.st; rstl = hcl->c->r.st;
@ -646,14 +681,18 @@ static HCL_INLINE int can_comma_list (hcl_t* hcl)
if (rstl->count == 1) rstl->flagv |= JSON; if (rstl->count == 1) rstl->flagv |= JSON;
else if (!(rstl->flagv & JSON)) return 0; else if (!(rstl->flagv & JSON)) return 0;
if (rstl->flagv & (COMMAED | COLONED)) return 0; if (rstl->flagv & (COMMAED | COLONED | COLONEQED)) return 0;
if (LIST_FLAG_GET_CONCODE(rstl->flagv) == HCL_CONCODE_DIC) cc = LIST_FLAG_GET_CONCODE(rstl->flagv);
if (cc == HCL_CONCODE_XLIST)
{
LIST_FLAG_SET_CONCODE(rstl->flagv, HCL_CONCODE_ALIST);
}
else if (cc == HCL_CONCODE_DIC)
{ {
if (rstl->count & 1) return 0; if (rstl->count & 1) return 0;
} }
else if (LIST_FLAG_GET_CONCODE(rstl->flagv) != HCL_CONCODE_ARRAY && else if (cc != HCL_CONCODE_ARRAY && cc != HCL_CONCODE_BYTEARRAY)
LIST_FLAG_GET_CONCODE(rstl->flagv) != HCL_CONCODE_BYTEARRAY)
{ {
return 0; return 0;
} }
@ -677,10 +716,9 @@ static HCL_INLINE int can_colon_list (hcl_t* hcl)
else if (!(rstl->flagv & JSON)) return 0; /* the first key is not colon-delimited. so not allowed to colon-delimit other keys */ else if (!(rstl->flagv & JSON)) return 0; /* the first key is not colon-delimited. so not allowed to colon-delimit other keys */
/* multiple single-colons - e.g. #{ "abc": : 20 } */ /* multiple single-colons - e.g. #{ "abc": : 20 } */
if (rstl->flagv & (COMMAED | COLONED)) return 0; if (rstl->flagv & (COMMAED | COLONED | COLONEQED)) return 0;
cc = LIST_FLAG_GET_CONCODE(rstl->flagv); cc = LIST_FLAG_GET_CONCODE(rstl->flagv);
if (cc == HCL_CONCODE_XLIST) if (cc == HCL_CONCODE_XLIST)
{ {
if (rstl->count > 1) return 0; if (rstl->count > 1) return 0;
@ -716,10 +754,7 @@ static HCL_INLINE int can_coloneq_list (hcl_t* hcl)
/* assignment only in XLIST */ /* assignment only in XLIST */
if (cc != HCL_CONCODE_XLIST) return 0; if (cc != HCL_CONCODE_XLIST) return 0;
/* TODO: some transformation is required... */
LIST_FLAG_SET_CONCODE(rstl->flagv, HCL_CONCODE_ALIST); LIST_FLAG_SET_CONCODE(rstl->flagv, HCL_CONCODE_ALIST);
rstl->flagv |= COLONEQED; rstl->flagv |= COLONEQED;
return 1; return 1;
} }
@ -1205,6 +1240,7 @@ static int feed_process_token (hcl_t* hcl)
hcl_setsynerrbfmt (hcl, HCL_SYNERR_SEMICOLON, TOKEN_LOC(hcl), TOKEN_NAME(hcl), "unexpected semicolon"); hcl_setsynerrbfmt (hcl, HCL_SYNERR_SEMICOLON, TOKEN_LOC(hcl), TOKEN_NAME(hcl), "unexpected semicolon");
goto oops; goto oops;
#else #else
/* allow redundant semicolons without not balanced with preceding expression */
goto ok; goto ok;
#endif #endif
} }