mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-30 23:23:07 +00:00 
			
		
		
		
	Complete adding parser to scripting.
This commit is contained in:
		| @@ -39,6 +39,7 @@ int debug_compile_and_run(Gst *vm, GstValue ast, GstValue env) { | |||||||
|     gst_compiler(&c, vm); |     gst_compiler(&c, vm); | ||||||
|     gst_compiler_usemodule(&c, "std"); |     gst_compiler_usemodule(&c, "std"); | ||||||
|     gst_compiler_usemodule(&c, "std.io"); |     gst_compiler_usemodule(&c, "std.io"); | ||||||
|  |     gst_compiler_usemodule(&c, "std.parse"); | ||||||
|     gst_compiler_globals(&c, env); |     gst_compiler_globals(&c, env); | ||||||
|     func = gst_wrap_function(gst_compiler_compile(&c, ast)); |     func = gst_wrap_function(gst_compiler_compile(&c, ast)); | ||||||
|     /* Check for compilation errors */ |     /* Check for compilation errors */ | ||||||
| @@ -145,6 +146,7 @@ int main(int argc, const char **argv) { | |||||||
|  |  | ||||||
|     gst_init(&vm); |     gst_init(&vm); | ||||||
|     gst_stl_load(&vm); |     gst_stl_load(&vm); | ||||||
|  |     gst_parse_load(&vm); | ||||||
|     if (argc > 1) { |     if (argc > 1) { | ||||||
|         const char *filename; |         const char *filename; | ||||||
|         FILE *f; |         FILE *f; | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								core/gc.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								core/gc.c
									
									
									
									
									
								
							| @@ -34,6 +34,11 @@ struct GCMemoryHeader { | |||||||
|     uint32_t tags : 31; |     uint32_t tags : 31; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /* Mark a chunk of memory as reachable for the gc */ | ||||||
|  | void gst_mark_mem(Gst *vm, void *mem) { | ||||||
|  | 	gc_header(mem)->color = vm->black; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Helper to mark function environments */ | /* Helper to mark function environments */ | ||||||
| static void gst_mark_funcenv(Gst *vm, GstFuncEnv *env) { | static void gst_mark_funcenv(Gst *vm, GstFuncEnv *env) { | ||||||
|     if (gc_header(env)->color != vm->black) { |     if (gc_header(env)->color != vm->black) { | ||||||
| @@ -172,8 +177,10 @@ void gst_mark(Gst *vm, GstValueUnion x, GstType type) { | |||||||
|  |  | ||||||
|         case GST_USERDATA: |         case GST_USERDATA: | ||||||
|             if (gc_header(x.string - sizeof(GstUserdataHeader))->color != vm->black) { |             if (gc_header(x.string - sizeof(GstUserdataHeader))->color != vm->black) { | ||||||
|                 GstUserdataHeader *userHeader = (GstUserdataHeader *)x.string - 1; |                 GstUserdataHeader *h = (GstUserdataHeader *)x.pointer - 1; | ||||||
|                 gc_header(userHeader)->color = vm->black; |                 gc_header(h)->color = vm->black; | ||||||
|  |                 if (h->type->gcmark) | ||||||
|  |                     h->type->gcmark(vm, x.pointer, h->size); | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										125
									
								
								core/parse.c
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								core/parse.c
									
									
									
									
									
								
							| @@ -42,11 +42,6 @@ struct GstParseState { | |||||||
|             uint8_t endDelimiter; |             uint8_t endDelimiter; | ||||||
|             GstArray *array; |             GstArray *array; | ||||||
|         } form; |         } form; | ||||||
|         struct { |  | ||||||
|             GstValue key; |  | ||||||
|             int keyFound; |  | ||||||
|             GstTable *table; |  | ||||||
|         } table; |  | ||||||
|         struct { |         struct { | ||||||
|             GstBuffer *buffer; |             GstBuffer *buffer; | ||||||
|             uint32_t count; |             uint32_t count; | ||||||
| @@ -540,3 +535,123 @@ void gst_parser(GstParser *p, Gst *vm) { | |||||||
|     p->flags = GST_PARSER_FLAG_EXPECTING_COMMENT; |     p->flags = GST_PARSER_FLAG_EXPECTING_COMMENT; | ||||||
|     parser_push(p, PTYPE_ROOT, ' '); |     parser_push(p, PTYPE_ROOT, ' '); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* CG finalize a parser */ | ||||||
|  | static void gst_stl_parser_finalize(Gst *vm, void *data, uint32_t len) { | ||||||
|  | 	/* printf("Finalizing parser: %p, %d\n", data, len); */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* GC mark a parser */ | ||||||
|  | static void gst_stl_parser_mark(Gst *vm, void *data, uint32_t len) { | ||||||
|  |     uint32_t i; | ||||||
|  |     GstParser *p = (GstParser *) data; | ||||||
|  |     gst_mark_mem(vm, p->data); | ||||||
|  |     gst_mark_value(vm, p->value); | ||||||
|  |     for (i = 0; i < p->count; ++i) { | ||||||
|  | 		GstParseState *ps = p->data + i; | ||||||
|  | 		switch (ps->type) { | ||||||
|  |     		case PTYPE_ROOT: | ||||||
|  |     			break; | ||||||
|  | 			case PTYPE_FORM: | ||||||
|  |     			gst_mark_value(vm, gst_wrap_array(ps->buf.form.array)); | ||||||
|  |     			break; | ||||||
|  |     		case PTYPE_STRING: | ||||||
|  |         	case PTYPE_TOKEN: | ||||||
|  |             	gst_mark_value(vm, gst_wrap_buffer(ps->buf.string.buffer)); | ||||||
|  |             	break; | ||||||
|  | 		} | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /***/ | ||||||
|  | /* Stl functions */ | ||||||
|  | /***/ | ||||||
|  |  | ||||||
|  | /* Parse filetype */ | ||||||
|  | static const GstUserType gst_stl_parsetype = { | ||||||
|  | 	"std.parser", | ||||||
|  | 	NULL, | ||||||
|  | 	NULL, | ||||||
|  | 	&gst_stl_parser_finalize, | ||||||
|  | 	&gst_stl_parser_mark | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* Create a parser */ | ||||||
|  | int gst_stl_parser(Gst *vm) { | ||||||
|  | 	GstParser *p = gst_userdata(vm, sizeof(GstParser), &gst_stl_parsetype); | ||||||
|  | 	gst_parser(p, vm); | ||||||
|  | 	gst_c_return(vm, gst_wrap_userdata(p)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Consume a value from the parser */ | ||||||
|  | int gst_stl_parser_consume(Gst *vm) { | ||||||
|  | 	GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype); | ||||||
|  | 	if (p == NULL) | ||||||
|  |     	gst_c_throwc(vm, "expected parser"); | ||||||
|  |     if (!gst_parse_hasvalue(p)) | ||||||
|  |         gst_c_throwc(vm, "parser has no pending value"); | ||||||
|  | 	gst_c_return(vm, gst_parse_consume(p)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Check if the parser has a value to consume */ | ||||||
|  | int gst_stl_parser_hasvalue(Gst *vm) { | ||||||
|  | 	GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype); | ||||||
|  | 	if (p == NULL) | ||||||
|  |     	gst_c_throwc(vm, "expected parser"); | ||||||
|  | 	gst_c_return(vm, gst_wrap_boolean(gst_parse_hasvalue(p))); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Parse a single byte. Returns if the byte was successfully parsed. */ | ||||||
|  | int gst_stl_parser_byte(Gst *vm) { | ||||||
|  |     GstInteger b; | ||||||
|  | 	GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype); | ||||||
|  | 	if (p == NULL) | ||||||
|  |     	gst_c_throwc(vm, "expected parser"); | ||||||
|  | 	if (!gst_check_integer(vm, 1, &b)) | ||||||
|  |     	gst_c_throwc(vm, "expected integer"); | ||||||
|  |     if (p->status == GST_PARSER_PENDING || p->status == GST_PARSER_ROOT) { | ||||||
|  |         dispatch_char(p, b); | ||||||
|  |         gst_c_return(vm, gst_wrap_boolean(1)); | ||||||
|  |     } else { | ||||||
|  |         gst_c_return(vm, gst_wrap_boolean(0)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Parse a string or buffer. Returns nil if the entire char array is parsed, | ||||||
|  | * otherwise returns the remainder of what could not be parsed. */ | ||||||
|  | int gst_stl_parser_charseq(Gst *vm) { | ||||||
|  |     uint32_t i; | ||||||
|  | 	uint32_t len; | ||||||
|  | 	const uint8_t *data; | ||||||
|  | 	GstParser *p = gst_check_userdata(vm, 0, &gst_stl_parsetype); | ||||||
|  | 	if (p == NULL) | ||||||
|  |     	gst_c_throwc(vm, "expected parser"); | ||||||
|  |     if (!gst_chararray_view(gst_arg(vm, 1), &data, &len)) | ||||||
|  |         gst_c_throwc(vm, "expected string/buffer"); | ||||||
|  |     for (i = 0; i < len; ++i) { | ||||||
|  |         if (p->status != GST_PARSER_PENDING && p->status != GST_PARSER_ROOT) break; | ||||||
|  |         dispatch_char(p, data[i]); | ||||||
|  |     } | ||||||
|  |     if (i == len) { | ||||||
|  | 		/* No remainder */ | ||||||
|  | 		gst_c_return(vm, gst_wrap_nil()); | ||||||
|  |     } else { | ||||||
|  | 		/* We have remaining characters */ | ||||||
|  | 		gst_c_return(vm, gst_wrap_string(gst_string_b(vm, data + i, len - i))); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* The module */ | ||||||
|  | static const GstModuleItem gst_parser_module[] = { | ||||||
|  | 	{"parser", gst_stl_parser}, | ||||||
|  | 	{"parse-byte", gst_stl_parser_byte}, | ||||||
|  | 	{"parse-consume", gst_stl_parser_consume}, | ||||||
|  | 	{"parse-hasvalue", gst_stl_parser_hasvalue}, | ||||||
|  | 	{"parse-charseq", gst_stl_parser_charseq}, | ||||||
|  | 	{NULL, NULL} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* Load the module */ | ||||||
|  | void gst_parse_load(Gst *vm) { | ||||||
|  | 	gst_module_put(vm, "std.parse", gst_cmodule_struct(vm, gst_parser_module)); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -524,6 +524,7 @@ static GstUserType gst_stl_filetype = { | |||||||
|     "io.file", |     "io.file", | ||||||
|     NULL, |     NULL, | ||||||
|     NULL,  |     NULL,  | ||||||
|  |     NULL, | ||||||
|     NULL |     NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -646,6 +647,12 @@ int gst_stl_dasm(Gst *vm) { | |||||||
|     return GST_RETURN_OK; |     return GST_RETURN_OK; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Force garbage collection */ | ||||||
|  | int gst_stl_gcollect(Gst *vm) { | ||||||
|  | 	gst_collect(vm); | ||||||
|  | 	return GST_RETURN_OK; | ||||||
|  | } | ||||||
|  |  | ||||||
| /****/ | /****/ | ||||||
| /* Bootstraping */ | /* Bootstraping */ | ||||||
| /****/ | /****/ | ||||||
| @@ -693,6 +700,7 @@ static const GstModuleItem const std_module[] = { | |||||||
|     {"write", gst_stl_write}, |     {"write", gst_stl_write}, | ||||||
|     {"close", gst_stl_close}, |     {"close", gst_stl_close}, | ||||||
|     {"dasm", gst_stl_dasm}, |     {"dasm", gst_stl_dasm}, | ||||||
|  |     {"gcollect", gst_stl_gcollect}, | ||||||
|     {NULL, NULL} |     {NULL, NULL} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -191,7 +191,7 @@ GstInteger gst_real_to_integer(GstReal x) { | |||||||
| } | } | ||||||
|  |  | ||||||
| GstInteger gst_startrange(GstInteger raw, uint32_t len) { | GstInteger gst_startrange(GstInteger raw, uint32_t len) { | ||||||
|     if (raw > len) |     if (raw >= len) | ||||||
|         return -1; |         return -1; | ||||||
|     if (raw < 0) |     if (raw < 0) | ||||||
|         return len + raw; |         return len + raw; | ||||||
|   | |||||||
| @@ -264,6 +264,7 @@ struct GstUserType { | |||||||
|     GstValue (*serialize)(Gst *vm, void *data, uint32_t len); |     GstValue (*serialize)(Gst *vm, void *data, uint32_t len); | ||||||
|     GstValue (*deserialize)(Gst *vm, GstValue in); |     GstValue (*deserialize)(Gst *vm, GstValue in); | ||||||
|     void (*finalize)(Gst *vm, void *data, uint32_t len); |     void (*finalize)(Gst *vm, void *data, uint32_t len); | ||||||
|  |     void (*gcmark)(Gst *vm, void *data, uint32_t len); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* Contains information about userdata */ | /* Contains information about userdata */ | ||||||
| @@ -462,6 +463,7 @@ void gst_mem_tag(void *mem, uint32_t tags); | |||||||
| void gst_collect(Gst *vm); | void gst_collect(Gst *vm); | ||||||
| void gst_maybe_collect(Gst *vm); | void gst_maybe_collect(Gst *vm); | ||||||
| void gst_clear_memory(Gst *vm); | void gst_clear_memory(Gst *vm); | ||||||
|  | void gst_mark_mem(Gst *vm, void *mem); | ||||||
|  |  | ||||||
| /****/ | /****/ | ||||||
| /* VM */ | /* VM */ | ||||||
|   | |||||||
| @@ -68,4 +68,7 @@ int gst_parse_hasvalue(GstParser *p); | |||||||
| /* Gets a value from the parser */ | /* Gets a value from the parser */ | ||||||
| GstValue gst_parse_consume(GstParser *p); | GstValue gst_parse_consume(GstParser *p); | ||||||
|  |  | ||||||
|  | /* Load the parsing library */ | ||||||
|  | void gst_parse_load(Gst *vm); | ||||||
|  |  | ||||||
| #endif /* end of include guard: PARSE_H_ONYWMADW */ | #endif /* end of include guard: PARSE_H_ONYWMADW */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose