implemented simple binary operator handling in the reader code
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
0455d6cdb3
commit
b86eb13fb1
38
lib/read.c
38
lib/read.c
@ -120,10 +120,12 @@ enum list_flag_t
|
|||||||
{
|
{
|
||||||
QUOTED = (1 << 0),
|
QUOTED = (1 << 0),
|
||||||
DOTTED = (1 << 1),
|
DOTTED = (1 << 1),
|
||||||
|
|
||||||
COMMAED = (1 << 2),
|
COMMAED = (1 << 2),
|
||||||
COLONED = (1 << 3),
|
COLONED = (1 << 3),
|
||||||
COLONEQED = (1 << 4),
|
COLONEQED = (1 << 4),
|
||||||
BINOPED = (1 << 5),
|
BINOPED = (1 << 5),
|
||||||
|
|
||||||
CLOSED = (1 << 6),
|
CLOSED = (1 << 6),
|
||||||
JSON = (1 << 7),
|
JSON = (1 << 7),
|
||||||
DATA_LIST = (1 << 8),
|
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 */
|
/* HACK */
|
||||||
if (concode == HCL_CONCODE_ALIST)
|
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_cnode_t* sym, * newhead, * lval;
|
||||||
hcl_oocs_t fake_tok, * fake_tok_ptr = HCL_NULL;
|
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;
|
fake_tok_ptr = &fake_tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HCL_ASSERT (hcl, count >= 2); /* the missing rvalue check has been done above */
|
HCL_ASSERT (hcl, count >= 2); /* the missing rvalue check has been done above */
|
||||||
if (count != 2)
|
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;
|
return HCL_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* create a new head joined with set or set-r */
|
/* create a new head joined with set or set-r */
|
||||||
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))
|
||||||
@ -675,6 +675,36 @@ static HCL_INLINE hcl_cnode_t* leave_list (hcl_t* hcl, hcl_loc_t* list_loc, int*
|
|||||||
head = newhead;
|
head = newhead;
|
||||||
concode = HCL_CONCODE_XLIST; /* switch back to XLIST */
|
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 */
|
/* END HACK */
|
||||||
|
|
||||||
HCL_CNODE_CONS_CONCODE(head) = concode;
|
HCL_CNODE_CONS_CONCODE(head) = concode;
|
||||||
@ -1339,7 +1369,7 @@ static int feed_process_token (hcl_t* hcl)
|
|||||||
int can = 0;
|
int can = 0;
|
||||||
if (frd->level <= 0 || !(can = can_binop_list(hcl)))
|
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;
|
goto oops;
|
||||||
}
|
}
|
||||||
if (can == 1) goto ident; /* if binop is the first in the list */
|
if (can == 1) goto ident; /* if binop is the first in the list */
|
||||||
|
@ -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..
|
## you can't have another colon before the method..
|
||||||
(obj: :method) ##ERROR: syntax error - : disallowed
|
(obj: :method) ##ERROR: syntax error - : disallowed
|
||||||
|
|
||||||
|
@ -34,24 +34,24 @@ defclass B :: A | d e f | {
|
|||||||
};
|
};
|
||||||
|
|
||||||
a := ((B:newInstance 1 2 3):sum);
|
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; };
|
else { printf "OK %d\n" a; };
|
||||||
|
|
||||||
b := (B:newInstance 2 3 4);
|
b := (B:newInstance 2 3 4);
|
||||||
a := (b:get-a);
|
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 };
|
else { printf "OK %d\n" a };
|
||||||
|
|
||||||
a := (b:get-b);
|
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 };
|
else { printf "OK %d\n" a };
|
||||||
|
|
||||||
a := (b:get-c);
|
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 };
|
else {printf "OK %d\n" a };
|
||||||
|
|
||||||
a := (b:sum);
|
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 };
|
else { printf "OK %d\n" a };
|
||||||
|
|
||||||
## super is equivalent to self unless a message is sent to it.
|
## super is equivalent to self unless a message is sent to it.
|
||||||
|
Loading…
Reference in New Issue
Block a user