From c5606262b909057a5564820626d8ebc0c2187431 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 13 Jan 2024 14:37:59 +0900 Subject: [PATCH] WIP - multi-vars assignment --- lib/comp.c | 7 +++--- lib/read.c | 66 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/lib/comp.c b/lib/comp.c index bb5b3b7..8efdd52 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -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) || 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_ALIST)*/) + HCL_CNODE_IS_CONS_CONCODED(car, HCL_CONCODE_MLIST) /* || + 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 * ( ...) */ @@ -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) { /* instance variable? or instance method? */ -HCL_DEBUG1 (hcl, ">>>> instance variable or method %js\n", sep + 1); name.ptr = (hcl_ooch_t*)(sep + 1); name.len -= 5; x = find_variable_backward_with_word(hcl, &name, HCL_CNODE_GET_LOC(obj), 1, &vi); @@ -4483,7 +4482,7 @@ redo: case HCL_CONCODE_MLIST: if (compile_cons_mlist_expression(hcl, oprnd, 0) <= -1) return -1; break; - /* TODO: + /* TODO: case HCL_CONCODE_ALIST: break; */ diff --git a/lib/read.c b/lib/read.c index 16b2663..33ed288 100644 --- a/lib/read.c +++ b/lib/read.c @@ -56,10 +56,11 @@ static struct voca_t { 5, { 's','u','p','e','r' } }, { 3, { 's','e','t' } }, + { 5, { 's','e','t','-','r' } }, { 3, { '(',' ',')' /* XLIST */ } }, { 4, { '(',':',' ',')' /* MLIST */ } }, - { 3, { '(',':','=',')' } }, + { 3, { '(',':','=',')' /* ALIST */ } }, { 3, { '{',' ','}' /* BLOCK */ } }, { 3, { '[',' ',']' /* ARRAY */ } }, { 4, { '#','[',' ',']' } }, @@ -94,10 +95,11 @@ enum voca_id_t VOCA_KW_SUPER, VOCA_SYM_SET, + VOCA_SYM_SET_R, VOCA_XLIST, VOCA_MLIST, - VOCA_ALIST, + VOCA_ALIST, /* assignment list */ VOCA_BLOCK, VOCA_ARRAY, 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) { /* 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; - fake_tok.ptr = vocas[VOCA_SYM_SET].str; - fake_tok.len = vocas[VOCA_SYM_SET].len; - fake_tok_ptr = &fake_tok; + rval = HCL_CNODE_CONS_CAR(head); + if (rval && HCL_CNODE_IS_CONS(rval) && HCL_CNODE_CONS_CONCODE(rval) == HCL_CONCODE_ARRAY) + { + 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??? */ 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; } + newhead = hcl_makecnodecons(hcl, 0, &loc, fake_tok_ptr, sym, head); 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) { hcl_rstl_t* rstl; + hcl_concode_t cc; HCL_ASSERT (hcl, hcl->c->r.st != HCL_NULL); 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; 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; } - else if (LIST_FLAG_GET_CONCODE(rstl->flagv) != HCL_CONCODE_ARRAY && - LIST_FLAG_GET_CONCODE(rstl->flagv) != HCL_CONCODE_BYTEARRAY) + else if (cc != HCL_CONCODE_ARRAY && cc != HCL_CONCODE_BYTEARRAY) { 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 */ /* 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); - if (cc == HCL_CONCODE_XLIST) { if (rstl->count > 1) return 0; @@ -716,10 +754,7 @@ static HCL_INLINE int can_coloneq_list (hcl_t* hcl) /* assignment only in XLIST */ if (cc != HCL_CONCODE_XLIST) return 0; - /* TODO: some transformation is required... */ - LIST_FLAG_SET_CONCODE(rstl->flagv, HCL_CONCODE_ALIST); - rstl->flagv |= COLONEQED; 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"); goto oops; #else + /* allow redundant semicolons without not balanced with preceding expression */ goto ok; #endif }