1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-26 00:10:27 +00:00

Complete adding parser to scripting.

This commit is contained in:
Calvin Rose 2017-05-03 19:57:06 -04:00
parent 631bb0cb63
commit c6e9f24f82
7 changed files with 145 additions and 8 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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));
}

View File

@ -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}
}; };

View File

@ -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;

View File

@ -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 */

View File

@ -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 */