implemented simple binary operator handling in the reader code
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
hyung-hwan 2024-02-10 12:23:34 +09:00
parent 0455d6cdb3
commit b86eb13fb1
3 changed files with 58 additions and 9 deletions

View File

@ -120,10 +120,12 @@ enum list_flag_t
{
QUOTED = (1 << 0),
DOTTED = (1 << 1),
COMMAED = (1 << 2),
COLONED = (1 << 3),
COLONEQED = (1 << 4),
BINOPED = (1 << 5),
CLOSED = (1 << 6),
JSON = (1 << 7),
DATA_LIST = (1 << 8),
@ -594,7 +596,7 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
/* HACK */
if (concode == HCL_CONCODE_ALIST)
{
/* tranform (var := val) to (set var val) */
/* tranform (var := val) to (set var val) - note ALIST doesn't contain the := symbol */
hcl_cnode_t* sym, * newhead, * lval;
hcl_oocs_t fake_tok, * fake_tok_ptr = HCL_NULL;
@ -637,7 +639,6 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
fake_tok_ptr = &fake_tok;
}
HCL_ASSERT (hcl, count >= 2); /* the missing rvalue check has been done above */
if (count != 2)
{
@ -660,7 +661,6 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
return HCL_NULL;
}
/* create a new head joined with set or set-r */
newhead = hcl_makecnodecons(hcl, 0, &loc, fake_tok_ptr, sym, head);
if (HCL_UNLIKELY(!newhead))
@ -675,6 +675,36 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
head = newhead;
concode = HCL_CONCODE_XLIST; /* switch back to XLIST */
}
else if (concode == HCL_CONCODE_BLIST)
{
/* x binop y -> binop x y - BLIST contains BINOP in it */
hcl_cnode_t* x, * binop;
x = HCL_CNODE_CONS_CAR(head);
if (x && HCL_CNODE_IS_ELIST(x))
{
hcl_setsynerr (hcl, HCL_SYNERR_LVALUE, HCL_CNODE_GET_LOC(x), HCL_CNODE_GET_TOK(x));
if (head) hcl_freecnode (hcl, head);
return HCL_NULL;
}
/* swap x and binop */
binop = HCL_CNODE_CONS_CDR(head);
if (!binop || !HCL_CNODE_IS_CONS(binop) || !HCL_CNODE_CONS_CDR(binop) || !HCL_CNODE_IS_CONS(HCL_CNODE_CONS_CDR(binop)))
{
hcl_setsynerrbfmt (hcl, HCL_SYNERR_NOVALUE, HCL_CNODE_GET_LOC(x), HCL_CNODE_GET_TOK(x), "no operand after binary operator");
if (head) hcl_freecnode (hcl, head);
return HCL_NULL;
}
/* TODO: support multiple operators and operands .. like 1 + 2 - 3.. -> currently can_binop_list() disallows more operators */
HCL_ASSERT (hcl, count == 3);
HCL_CNODE_CONS_CDR(head) = HCL_CNODE_CONS_CDR(binop);
HCL_CNODE_CONS_CDR(binop) = head;
head = binop;
concode = HCL_CONCODE_XLIST;
}
/* END HACK */
HCL_CNODE_CONS_CONCODE(head) = concode;
@ -1339,7 +1369,7 @@ static int feed_process_token (hcl_t* hcl)
int can = 0;
if (frd->level <= 0 || !(can = can_binop_list(hcl)))
{
hcl_setsynerr (hcl, HCL_SYNERR_BANNED, TOKEN_LOC(hcl), HCL_NULL);
hcl_setsynerrbfmt (hcl, HCL_SYNERR_BANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl), "prohibited binary operator");
goto oops;
}
if (can == 1) goto ident; /* if binop is the first in the list */

View File

@ -1,3 +1,22 @@
##
x := (+ 10 20) "aaaa"; ##ERROR: syntax error - too many rvalues
---
##
x := (10 +); ##ERROR: syntax error - no operand after binary operator
---
##
x := (10 + 20 * 4); ##ERROR: syntax error - prohibited binary operator
---
## you can't have another colon before the method..
(obj: :method) ##ERROR: syntax error - : disallowed

View File

@ -34,24 +34,24 @@ defclass B :: A | d e f | {
};
a := ((B:newInstance 1 2 3):sum);
if (/= a 18) { printf "ERROR: a must be 18\n"; } \
if (a /= 18) { printf "ERROR: a must be 18\n"; } \
else { printf "OK %d\n" a; };
b := (B:newInstance 2 3 4);
a := (b:get-a);
if (/= a 4) {printf "ERROR: a must be 4\n" } \
if (a /= 4) {printf "ERROR: a must be 4\n" } \
else { printf "OK %d\n" a };
a := (b:get-b);
if (/= a 6) { printf "ERROR: a must be 6\n" } \
if (a /= 6) { printf "ERROR: a must be 6\n" } \
else { printf "OK %d\n" a };
a := (b:get-c);
if (/= a 8) { printf "ERROR: a must be 8\n" } \
if (a /= 8) { printf "ERROR: a must be 8\n" } \
else {printf "OK %d\n" a };
a := (b:sum);
if (/= a 27) { printf "ERROR: a must be 27\n" } \
if (a /= 27) { printf "ERROR: a must be 27\n" } \
else { printf "OK %d\n" a };
## super is equivalent to self unless a message is sent to it.