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:
		
							
								
								
									
										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. | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user