fixed the vlist reading in the feed-based reader
This commit is contained in:
		| @ -850,7 +850,6 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int cflags, int verbose) | |||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| oops: | oops: | ||||||
| 	hcl_endfeed (hcl); |  | ||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -630,9 +630,10 @@ typedef struct hcl_frd_t hcl_frd_t; | |||||||
| struct hcl_frd_t | struct hcl_frd_t | ||||||
| { | { | ||||||
| 	int level; | 	int level; | ||||||
| 	int array_level; | 	int data_list_level; | ||||||
| 	int flagv; | 	int flagv; | ||||||
| 	int expect_include_file; | 	int expect_include_file; | ||||||
|  | 	int expect_vlist_item; | ||||||
| 	int do_include_file; | 	int do_include_file; | ||||||
| 	hcl_cnode_t* obj; | 	hcl_cnode_t* obj; | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										92
									
								
								lib/read.c
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								lib/read.c
									
									
									
									
									
								
							| @ -90,7 +90,8 @@ enum list_flag_t | |||||||
| 	COMMAED    = (1 << 2), | 	COMMAED    = (1 << 2), | ||||||
| 	COLONED    = (1 << 3), | 	COLONED    = (1 << 3), | ||||||
| 	CLOSED     = (1 << 4), | 	CLOSED     = (1 << 4), | ||||||
| 	JSON       = (1 << 5) | 	JSON       = (1 << 5), | ||||||
|  | 	DATA_LIST  = (1 << 6) | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define LIST_FLAG_GET_CONCODE(x) (((x) >> 8) & 0xFF) | #define LIST_FLAG_GET_CONCODE(x) (((x) >> 8) & 0xFF) | ||||||
| @ -1842,7 +1843,7 @@ static hcl_cnode_t* read_object (hcl_t* hcl) | |||||||
| 	/* this function read an s-expression non-recursively | 	/* this function read an s-expression non-recursively | ||||||
| 	 * by manipulating its own stack. */ | 	 * by manipulating its own stack. */ | ||||||
|  |  | ||||||
| 	int level = 0, array_level = 0, flagv = 0; | 	int level = 0, data_list_level = 0, flagv = 0; | ||||||
| 	hcl_cnode_t* obj = HCL_NULL; | 	hcl_cnode_t* obj = HCL_NULL; | ||||||
|  |  | ||||||
| 	while (1) | 	while (1) | ||||||
| @ -1871,22 +1872,22 @@ static hcl_cnode_t* read_object (hcl_t* hcl) | |||||||
| 				goto redo; | 				goto redo; | ||||||
|  |  | ||||||
| 			case HCL_IOTOK_LBRACK: /* [] */ | 			case HCL_IOTOK_LBRACK: /* [] */ | ||||||
| 				flagv = 0; | 				flagv = DATA_LIST; | ||||||
| 				LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_ARRAY); | 				LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_ARRAY); | ||||||
| 				goto start_list; | 				goto start_list; | ||||||
|  |  | ||||||
| 			case HCL_IOTOK_BAPAREN: /* #[ */ | 			case HCL_IOTOK_BAPAREN: /* #[ */ | ||||||
| 				flagv = 0; | 				flagv = DATA_LIST; | ||||||
| 				LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_BYTEARRAY); | 				LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_BYTEARRAY); | ||||||
| 				goto start_list; | 				goto start_list; | ||||||
|  |  | ||||||
| 			case HCL_IOTOK_LBRACE: /* { */ | 			case HCL_IOTOK_LBRACE: /* { */ | ||||||
| 				flagv = 0; | 				flagv = DATA_LIST; | ||||||
| 				LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_DIC); | 				LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_DIC); | ||||||
| 				goto start_list; | 				goto start_list; | ||||||
|  |  | ||||||
| 			case HCL_IOTOK_QLPAREN: /* #( */ | 			case HCL_IOTOK_QLPAREN: /* #( */ | ||||||
| 				flagv = 0; | 				flagv = DATA_LIST; | ||||||
| 				LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_QLIST); | 				LIST_FLAG_SET_CONCODE (flagv, HCL_CONCODE_QLIST); | ||||||
| 				goto start_list; | 				goto start_list; | ||||||
|  |  | ||||||
| @ -1910,7 +1911,7 @@ static hcl_cnode_t* read_object (hcl_t* hcl) | |||||||
| 				 * a list literal or an array literal */ | 				 * a list literal or an array literal */ | ||||||
| 				if (enter_list(hcl, TOKEN_LOC(hcl), flagv) <= -1) goto oops; | 				if (enter_list(hcl, TOKEN_LOC(hcl), flagv) <= -1) goto oops; | ||||||
| 				level++; | 				level++; | ||||||
| 				if (LIST_FLAG_GET_CONCODE(flagv) == HCL_CONCODE_ARRAY) array_level++; | 				if (flagv & DATA_LIST) data_list_level++; | ||||||
|  |  | ||||||
| 				/* read the next token */ | 				/* read the next token */ | ||||||
| 				GET_TOKEN_WITH_GOTO (hcl, oops); | 				GET_TOKEN_WITH_GOTO (hcl, oops); | ||||||
| @ -2012,14 +2013,14 @@ static hcl_cnode_t* read_object (hcl_t* hcl) | |||||||
| 				obj = leave_list(hcl, &flagv, &oldflagv); | 				obj = leave_list(hcl, &flagv, &oldflagv); | ||||||
|  |  | ||||||
| 				level--; | 				level--; | ||||||
| 				if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--; | 				if (oldflagv & DATA_LIST) data_list_level--; | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			case HCL_IOTOK_VBAR: | 			case HCL_IOTOK_VBAR: | ||||||
| /* TODO: think wheter to allow | | inside a quoted list... */ | /* TODO: think wheter to allow | | inside a quoted list... */ | ||||||
| /* TODO: revise this part ... */ | /* TODO: revise this part ... */ | ||||||
| 				if (array_level > 0) /* TODO: this check is wrong... i think .. */ | 				if (data_list_level > 0) /* TODO: this check is wrong... i think .. */ | ||||||
| 				{ | 				{ | ||||||
| 					hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | 					hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | ||||||
| 					goto oops; | 					goto oops; | ||||||
| @ -2158,7 +2159,7 @@ static hcl_cnode_t* read_object (hcl_t* hcl) | |||||||
| 			/* one level up toward the top */ | 			/* one level up toward the top */ | ||||||
| 			level--; | 			level--; | ||||||
|  |  | ||||||
| 			if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) array_level--; | 			if (oldflagv & DATA_LIST) data_list_level--; | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @ -2182,7 +2183,7 @@ static hcl_cnode_t* read_object (hcl_t* hcl) | |||||||
|  |  | ||||||
| 	/* upon exit, we must be at the top level */ | 	/* upon exit, we must be at the top level */ | ||||||
| 	HCL_ASSERT (hcl, level == 0); | 	HCL_ASSERT (hcl, level == 0); | ||||||
| 	HCL_ASSERT (hcl, array_level == 0); | 	HCL_ASSERT (hcl, data_list_level == 0); | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, hcl->c->r.st == HCL_NULL); | 	HCL_ASSERT (hcl, hcl->c->r.st == HCL_NULL); | ||||||
| 	HCL_ASSERT (hcl, obj != HCL_NULL); | 	HCL_ASSERT (hcl, obj != HCL_NULL); | ||||||
| @ -2343,9 +2344,12 @@ static int feed_process_token (hcl_t* hcl) | |||||||
| 	/* this function composes an s-expression non-recursively | 	/* this function composes an s-expression non-recursively | ||||||
| 	 * by manipulating its own stack. */ | 	 * by manipulating its own stack. */ | ||||||
|  |  | ||||||
| /*hcl_logbfmt (hcl, HCL_LOG_STDERR, "TOKEN => [%.*js] type=%d\n", TOKEN_NAME_LEN(hcl), TOKEN_NAME_PTR(hcl), TOKEN_TYPE(hcl));*/ | /*hcl_logbfmt (hcl, HCL_LOG_STDERR, "TOKEN => [%.*js] type=%d LOC=%d.%d\n", TOKEN_NAME_LEN(hcl), TOKEN_NAME_PTR(hcl), TOKEN_TYPE(hcl), TOKEN_LOC(hcl)->line, TOKEN_LOC(hcl)->colm);*/ | ||||||
| 	if (frd->expect_include_file) | 	if (frd->expect_include_file) | ||||||
| 	{ | 	{ | ||||||
|  | 		/* the #include directive is an exception to the general expression rule. | ||||||
|  | 		 * use this exceptional code block to divert the major token processing */ | ||||||
|  |  | ||||||
| 		if (TOKEN_TYPE(hcl) != HCL_IOTOK_STRLIT) | 		if (TOKEN_TYPE(hcl) != HCL_IOTOK_STRLIT) | ||||||
| 		{ | 		{ | ||||||
| 			hcl_setsynerr (hcl, HCL_SYNERR_STRING, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | 			hcl_setsynerr (hcl, HCL_SYNERR_STRING, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | ||||||
| @ -2362,6 +2366,13 @@ static int feed_process_token (hcl_t* hcl) | |||||||
| 		goto ok; | 		goto ok; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (frd->expect_vlist_item && TOKEN_TYPE(hcl) != HCL_IOTOK_IDENT && TOKEN_TYPE(hcl) != HCL_IOTOK_VBAR) | ||||||
|  | 	{ | ||||||
|  | 		/* vlist also has special requirement that it can only contain variable names. */ | ||||||
|  | 		hcl_setsynerr (hcl, HCL_SYNERR_VARNAME, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | ||||||
|  | 		goto oops; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	switch (TOKEN_TYPE(hcl)) | 	switch (TOKEN_TYPE(hcl)) | ||||||
| 	{ | 	{ | ||||||
| 		default: | 		default: | ||||||
| @ -2369,7 +2380,6 @@ static int feed_process_token (hcl_t* hcl) | |||||||
| 			goto oops; | 			goto oops; | ||||||
|  |  | ||||||
| 		case HCL_IOTOK_EOF: | 		case HCL_IOTOK_EOF: | ||||||
| 		/* TODO: change the code. not an error? */ |  | ||||||
| 			hcl_setsynerr (hcl, HCL_SYNERR_EOF, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | 			hcl_setsynerr (hcl, HCL_SYNERR_EOF, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | ||||||
| 			goto oops; | 			goto oops; | ||||||
|  |  | ||||||
| @ -2379,23 +2389,56 @@ static int feed_process_token (hcl_t* hcl) | |||||||
| 			frd->expect_include_file = 1; | 			frd->expect_include_file = 1; | ||||||
| 			goto ok; | 			goto ok; | ||||||
|  |  | ||||||
| 		case HCL_IOTOK_LBRACK: /* [] */ | 		case HCL_IOTOK_VBAR: | ||||||
|  | 			if (frd->expect_vlist_item) | ||||||
|  | 			{ | ||||||
|  | 				/* closer */ | ||||||
|  | 				int oldflagv; | ||||||
|  | 				frd->expect_vlist_item = 0; | ||||||
|  | 				frd->obj = leave_list(hcl, &frd->flagv, &oldflagv); | ||||||
|  | 				frd->level--; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				/* opener */ | ||||||
|  |  | ||||||
|  | 				/* the vlist is different from other lists in that | ||||||
|  | 				 *   it uses the same opener and the closer | ||||||
|  | 				 *   it allows only variable names. | ||||||
|  | 				 *   it prohibits nesting of other lists | ||||||
|  | 				 */ | ||||||
|  | 				if (frd->data_list_level > 0) /* TODO: this check is wrong... i think .. */ | ||||||
|  | 				{ | ||||||
|  | 					hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | ||||||
|  | 					goto oops; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				/* neither a data list nor an executable list. handle this specially using | ||||||
|  | 				 * a dedicated frd->expect_vlist_item variable */ | ||||||
| 				frd->flagv = 0;  | 				frd->flagv = 0;  | ||||||
|  | 				LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_VLIST); | ||||||
|  | 				frd->expect_vlist_item = 1; | ||||||
|  | 				goto start_list; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 		case HCL_IOTOK_LBRACK: /* [ */ | ||||||
|  | 			frd->flagv = DATA_LIST; | ||||||
| 			LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_ARRAY); | 			LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_ARRAY); | ||||||
| 			goto start_list; | 			goto start_list; | ||||||
|  |  | ||||||
| 		case HCL_IOTOK_BAPAREN: /* #[ */ | 		case HCL_IOTOK_BAPAREN: /* #[ */ | ||||||
| 			frd->flagv = 0; | 			frd->flagv = DATA_LIST; | ||||||
| 			LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_BYTEARRAY); | 			LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_BYTEARRAY); | ||||||
| 			goto start_list; | 			goto start_list; | ||||||
|  |  | ||||||
| 		case HCL_IOTOK_LBRACE: /* { */ | 		case HCL_IOTOK_LBRACE: /* { */ | ||||||
| 			frd->flagv = 0; | 			frd->flagv = DATA_LIST; | ||||||
| 			LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_DIC); | 			LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_DIC); | ||||||
| 			goto start_list; | 			goto start_list; | ||||||
|  |  | ||||||
| 		case HCL_IOTOK_QLPAREN: /* #( */ | 		case HCL_IOTOK_QLPAREN: /* #( */ | ||||||
| 			frd->flagv = 0; | 			frd->flagv = DATA_LIST; | ||||||
| 			LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_QLIST); | 			LIST_FLAG_SET_CONCODE (frd->flagv, HCL_CONCODE_QLIST); | ||||||
| 			goto start_list; | 			goto start_list; | ||||||
|  |  | ||||||
| @ -2410,7 +2453,7 @@ static int feed_process_token (hcl_t* hcl) | |||||||
| 		start_list: | 		start_list: | ||||||
| 			if (frd->level >= HCL_TYPE_MAX(int)) | 			if (frd->level >= HCL_TYPE_MAX(int)) | ||||||
| 			{ | 			{ | ||||||
| 				/* the nesting frd->level has become too deep */ | 				/* the nesting level has become too deep */ | ||||||
| 				hcl_setsynerr (hcl, HCL_SYNERR_NESTING, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | 				hcl_setsynerr (hcl, HCL_SYNERR_NESTING, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | ||||||
| 				goto oops; | 				goto oops; | ||||||
| 			} | 			} | ||||||
| @ -2419,7 +2462,7 @@ static int feed_process_token (hcl_t* hcl) | |||||||
| 			 * a list literal or an array literal */ | 			 * a list literal or an array literal */ | ||||||
| 			if (enter_list(hcl, TOKEN_LOC(hcl), frd->flagv) <= -1) goto oops; | 			if (enter_list(hcl, TOKEN_LOC(hcl), frd->flagv) <= -1) goto oops; | ||||||
| 			frd->level++; | 			frd->level++; | ||||||
| 			if (LIST_FLAG_GET_CONCODE(frd->flagv) == HCL_CONCODE_ARRAY) frd->array_level++; | 			if (frd->flagv & DATA_LIST) frd->data_list_level++; | ||||||
|  |  | ||||||
| 			/* read the next token */ | 			/* read the next token */ | ||||||
| 			goto ok; | 			goto ok; | ||||||
| @ -2515,22 +2558,23 @@ static int feed_process_token (hcl_t* hcl) | |||||||
| 			} | 			} | ||||||
| #endif | #endif | ||||||
| 			frd->obj = leave_list(hcl, &frd->flagv, &oldflagv); | 			frd->obj = leave_list(hcl, &frd->flagv, &oldflagv); | ||||||
|  |  | ||||||
| 			frd->level--; | 			frd->level--; | ||||||
| 			if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) frd->array_level--; | 			if (oldflagv & DATA_LIST) frd->data_list_level--; | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| 		case HCL_IOTOK_VBAR: | 		case HCL_IOTOK_VBAR: | ||||||
| /* TODO: think wheter to allow | | inside a quoted list... */ | /* TODO: think wheter to allow | | inside a quoted list... */ | ||||||
| /* TODO: revise this part ... */ | /* TODO: revise this part ... */ | ||||||
| 			if (frd->array_level > 0) /* TODO: this check is wrong... i think .. */ | 			if (frd->data_list_level > 0) /* TODO: this check is wrong... i think .. */ | ||||||
| 			{ | 			{ | ||||||
| 				hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | 				hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | ||||||
| 				goto oops; | 				goto oops; | ||||||
| 			} | 			} | ||||||
| 			frd->obj = read_vlist(hcl); | 			frd->obj = read_vlist(hcl); | ||||||
| 			break; | 			break; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 		case HCL_IOTOK_NIL: | 		case HCL_IOTOK_NIL: | ||||||
| 			frd->obj = hcl_makecnodenil(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | 			frd->obj = hcl_makecnodenil(hcl, TOKEN_LOC(hcl), TOKEN_NAME(hcl)); | ||||||
| @ -2662,7 +2706,7 @@ static int feed_process_token (hcl_t* hcl) | |||||||
| 		/* one frd->level up toward the top */ | 		/* one frd->level up toward the top */ | ||||||
| 		frd->level--; | 		frd->level--; | ||||||
|  |  | ||||||
| 		if (LIST_FLAG_GET_CONCODE(oldflagv) == HCL_CONCODE_ARRAY) frd->array_level--; | 		if (oldflagv & DATA_LIST) frd->data_list_level--; | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @ -2674,7 +2718,7 @@ static int feed_process_token (hcl_t* hcl) | |||||||
|  |  | ||||||
| 		/* upon exit, we must be at the top level */ | 		/* upon exit, we must be at the top level */ | ||||||
| 		HCL_ASSERT (hcl, frd->level == 0); | 		HCL_ASSERT (hcl, frd->level == 0); | ||||||
| 		HCL_ASSERT (hcl, frd->array_level == 0); | 		HCL_ASSERT (hcl, frd->data_list_level == 0); | ||||||
|  |  | ||||||
| 		HCL_ASSERT (hcl, hcl->c->r.st == HCL_NULL); | 		HCL_ASSERT (hcl, hcl->c->r.st == HCL_NULL); | ||||||
| 		HCL_ASSERT (hcl, frd->obj != HCL_NULL); | 		HCL_ASSERT (hcl, frd->obj != HCL_NULL); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user