mirror of
https://github.com/janet-lang/janet
synced 2024-12-25 07:50:27 +00:00
Complete adding parser to scripting.
This commit is contained in:
parent
631bb0cb63
commit
c6e9f24f82
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user