enhanced the binop expression check in leave_list() in read.c
All checks were successful
continuous-integration/drone/push Build is passing

fixed the issue of the lost line terminator after the comment text which caused the next line to be treated as the same line
This commit is contained in:
hyung-hwan 2024-03-09 17:10:51 +09:00
parent 081c6d1874
commit 8345e2f949
7 changed files with 50 additions and 23 deletions

View File

@ -541,7 +541,7 @@ static HCL_INLINE int enter_list (hcl_t* hcl, const hcl_loc_t* loc, int flagv)
static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int* flagv, int* oldflagv) static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int* flagv, int* oldflagv)
{ {
hcl_rstl_t* rstl; hcl_rstl_t* rstl;
hcl_cnode_t* head; hcl_cnode_t* head, * tail;
hcl_oow_t count; hcl_oow_t count;
hcl_loc_t loc; hcl_loc_t loc;
int fv, concode; int fv, concode;
@ -551,6 +551,7 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
rstl = hcl->c->r.st; /* get the stack top */ rstl = hcl->c->r.st; /* get the stack top */
head = rstl->head; head = rstl->head;
tail = rstl->tail;
count = rstl->count; count = rstl->count;
fv = rstl->flagv; fv = rstl->flagv;
loc = rstl->loc; loc = rstl->loc;
@ -707,8 +708,21 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
return HCL_NULL; return HCL_NULL;
} }
/* TODO: support multiple operators and operands .. like 1 + 2 - 3.. -> currently can_binop_list() disallows more operators */ /* TODO: support multiple operators and operands .. like 1 + 2 - 3
HCL_ASSERT (hcl, count == 3); currently can_binop_list() disallows more operators.
but the check isn't complemete if more operands are added without an operator e.g. (1 + 2 3)
*/
/*HCL_ASSERT (hcl, count == 3);*/
if (count != 3)
{
/* Currently, the implementation supports two operands and a single binop in an expression.
* If the implementation is enhanced to support more than one binop and more operands,
* this check must be removed. */
/* TODO: support more than two operands */
hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGFLOOD, HCL_CNODE_GET_LOC(tail), HCL_CNODE_GET_TOK(tail), "too many operands");
if (head) hcl_freecnode (hcl, head);
return HCL_NULL;
}
HCL_CNODE_CONS_CDR(head) = HCL_CNODE_CONS_CDR(binop); HCL_CNODE_CONS_CDR(head) = HCL_CNODE_CONS_CDR(binop);
HCL_CNODE_CONS_CDR(binop) = head; HCL_CNODE_CONS_CDR(binop) = head;
@ -1542,9 +1556,12 @@ static int feed_process_token (hcl_t* hcl)
} }
#endif #endif
frd->obj = leave_list(hcl, &frd->list_loc, &frd->flagv, &oldflagv); frd->obj = leave_list(hcl, &frd->list_loc, &frd->flagv, &oldflagv);
frd->level--; if (HCL_LIKELY(frd->obj))
frd->flagv |= AT_BEGINNING; {
list_loc = &frd->list_loc; frd->level--;
frd->flagv |= AT_BEGINNING;
list_loc = &frd->list_loc;
}
break; break;
} }
@ -2104,7 +2121,16 @@ static int flx_backslashed (hcl_t* hcl, hcl_ooci_t c)
static int flx_comment (hcl_t* hcl, hcl_ooci_t c) static int flx_comment (hcl_t* hcl, hcl_ooci_t c)
{ {
if (is_linebreak(c)) FEED_CONTINUE (hcl, HCL_FLX_START); if (is_linebreak(c))
{
FEED_CONTINUE (hcl, HCL_FLX_START);
/* don't consume the line break together with the comment text
* if a comment text is located at the back of the line in the
* LANG_ENABLE_EOL mode.
* TODO: Consider removing this check because not consuming it
* in another mode doesn't cause a problem. */
if ((hcl->option.trait & HCL_TRAIT_LANG_ENABLE_EOL)) return 0; /* not consumed */
}
return 1; /* consumed */ return 1; /* consumed */
} }

View File

@ -14,7 +14,6 @@ check_ERRORS = \
call-5001.err \ call-5001.err \
class-5001.err \ class-5001.err \
do-5001.err \ do-5001.err \
do-5002.err \
feed-5001.err \ feed-5001.err \
mlist-5001.err \ mlist-5001.err \
var-5001.err \ var-5001.err \

View File

@ -486,7 +486,6 @@ check_ERRORS = \
call-5001.err \ call-5001.err \
class-5001.err \ class-5001.err \
do-5001.err \ do-5001.err \
do-5002.err \
feed-5001.err \ feed-5001.err \
mlist-5001.err \ mlist-5001.err \
var-5001.err \ var-5001.err \

View File

@ -1,3 +1,13 @@
## if `do` is not enclosed in `( )`, variable declaration is prohibited ## if `do` is not enclosed in `( )`, variable declaration is prohibited
do { | k | set k 10 }; do { | k | set k 10 };
do | k | {set k 10;}; ##ERROR: syntax error - variable declaration disallowed do | k | {set k 10;}; ##ERROR: syntax error - variable declaration disallowed
---
## if `do` is not enclosed in `( )`, it supports only the limited number of expressions.
do ; ## this is ok
do 1; ## this is ok
do { set k 10; printf "k=%d\n" k; } { set k 20; printf "k=%d\n" k; }; ##ERROR: syntax error - more than one expression after do

View File

@ -1,8 +0,0 @@
## if `do` is not enclosed in `( )`, it supports only the limited number of expressions.
do ; ## this is ok
do 1; ## this is ok
do { set k 10; printf "k=%d\n" k; } ##ERROR: syntax error - more than one expression after do
{ set k 20; printf "k=%d\n" k; };

View File

@ -86,3 +86,7 @@ defun :: fun1() { ##ERROR: syntax error - function name not symbol in defun
defun :* fun1() { ##ERROR: syntax error - function name not symbol in defun defun :* fun1() { ##ERROR: syntax error - function name not symbol in defun
return 10; return 10;
}; };
---
(10 + 20 30) ##ERROR: syntax error - too many operands

View File

@ -23,8 +23,7 @@ defun mkfun(t) {
defun mkfund(t) { defun mkfund(t) {
return {fun(c) { return {fun(c) {
return (fun(d) { return (fun(d) {
##return (d + c t) ## this causes assertion failure. return (+ d c t)
return (d + c t)
}) })
}} }}
} }
@ -47,10 +46,8 @@ if (k = 50) {
}; };
k := { k := {
## the return value of this expression is ignored (mkfun 20) 30 ## the return value of this expression is ignored
(mkfun 20) 30 ## having comment here cause an issue... (mkfun 20) 40 ## the return value of this expression is the return value of the block expression
## the return value of this expression is the return value of the block expression
(mkfun 20) 40
} }
if (k = 60) { if (k = 60) {
printf "OK - %d\n" k printf "OK - %d\n" k