mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 11:09:54 +00:00
Add parser/clone. (#120)
This commit is contained in:
parent
802a2d6b71
commit
43520ac67d
@ -634,6 +634,51 @@ void janet_parser_deinit(JanetParser *parser) {
|
|||||||
free(parser->states);
|
free(parser->states);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void janet_parser_clone(JanetParser *src, JanetParser *dest) {
|
||||||
|
/* Misc fields */
|
||||||
|
dest->flag = src->flag;
|
||||||
|
dest->pending = src->pending;
|
||||||
|
dest->lookback = src->lookback;
|
||||||
|
dest->offset = src->offset;
|
||||||
|
dest->error = src->error;
|
||||||
|
|
||||||
|
/* Keep counts */
|
||||||
|
dest->argcount = src->argcount;
|
||||||
|
dest->bufcount = src->bufcount;
|
||||||
|
dest->statecount = src->statecount;
|
||||||
|
|
||||||
|
/* Capacities are equal to counts */
|
||||||
|
dest->bufcap = dest->bufcount;
|
||||||
|
dest->statecap = dest->statecount;
|
||||||
|
dest->argcap = dest->argcount;
|
||||||
|
|
||||||
|
/* Deep cloned fields */
|
||||||
|
dest->args = NULL;
|
||||||
|
dest->states = NULL;
|
||||||
|
dest->buf = NULL;
|
||||||
|
if (dest->bufcap) {
|
||||||
|
dest->buf = malloc(dest->bufcap);
|
||||||
|
if (!dest->buf) goto nomem;
|
||||||
|
}
|
||||||
|
if (dest->argcap) {
|
||||||
|
dest->args = malloc(sizeof(Janet) * dest->argcap);
|
||||||
|
if (!dest->args) goto nomem;
|
||||||
|
}
|
||||||
|
if (dest->statecap) {
|
||||||
|
dest->states = malloc(sizeof(JanetParseState) * dest->statecap);
|
||||||
|
if (!dest->states) goto nomem;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dest->buf, src->buf, dest->bufcap);
|
||||||
|
memcpy(dest->args, src->args, dest->argcap * sizeof(Janet));
|
||||||
|
memcpy(dest->states, src->states, dest->statecap * sizeof(JanetParseState));
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
nomem:
|
||||||
|
JANET_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
int janet_parser_has_more(JanetParser *parser) {
|
int janet_parser_has_more(JanetParser *parser) {
|
||||||
return !!parser->pending;
|
return !!parser->pending;
|
||||||
}
|
}
|
||||||
@ -841,9 +886,19 @@ static Janet cfun_parse_state(int32_t argc, Janet *argv) {
|
|||||||
return janet_wrap_string(str);
|
return janet_wrap_string(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Janet cfun_parse_clone(int32_t argc, Janet *argv) {
|
||||||
|
janet_fixarity(argc, 1);
|
||||||
|
JanetParser *src = janet_getabstract(argv, 0, &janet_parse_parsertype);
|
||||||
|
JanetParser *dest = janet_abstract(&janet_parse_parsertype, sizeof(JanetParser));
|
||||||
|
janet_parser_clone(src, dest);
|
||||||
|
return janet_wrap_abstract(dest);
|
||||||
|
}
|
||||||
|
|
||||||
static const JanetMethod parser_methods[] = {
|
static const JanetMethod parser_methods[] = {
|
||||||
{"byte", cfun_parse_byte},
|
{"byte", cfun_parse_byte},
|
||||||
|
{"clone", cfun_parse_clone},
|
||||||
{"consume", cfun_parse_consume},
|
{"consume", cfun_parse_consume},
|
||||||
|
{"eof", cfun_parse_eof},
|
||||||
{"error", cfun_parse_error},
|
{"error", cfun_parse_error},
|
||||||
{"flush", cfun_parse_flush},
|
{"flush", cfun_parse_flush},
|
||||||
{"has-more", cfun_parse_has_more},
|
{"has-more", cfun_parse_has_more},
|
||||||
@ -852,7 +907,6 @@ static const JanetMethod parser_methods[] = {
|
|||||||
{"state", cfun_parse_state},
|
{"state", cfun_parse_state},
|
||||||
{"status", cfun_parse_status},
|
{"status", cfun_parse_status},
|
||||||
{"where", cfun_parse_where},
|
{"where", cfun_parse_where},
|
||||||
{"eof", cfun_parse_eof},
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -869,6 +923,13 @@ static const JanetReg parse_cfuns[] = {
|
|||||||
"Creates and returns a new parser object. Parsers are state machines "
|
"Creates and returns a new parser object. Parsers are state machines "
|
||||||
"that can receive bytes, and generate a stream of janet values.")
|
"that can receive bytes, and generate a stream of janet values.")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"parser/clone", cfun_parse_clone,
|
||||||
|
JDOC("(parser/clone p)\n\n"
|
||||||
|
"Creates a deep clone of a parser that is identical to the input parser. "
|
||||||
|
"This cloned parser can be used to continue parsing from a good checkpoint "
|
||||||
|
"if parsing later fails. Returns a new parser.")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"parser/has-more", cfun_parse_has_more,
|
"parser/has-more", cfun_parse_has_more,
|
||||||
JDOC("(parser/has-more parser)\n\n"
|
JDOC("(parser/has-more parser)\n\n"
|
||||||
|
@ -109,4 +109,13 @@
|
|||||||
(comment 1 2 3)
|
(comment 1 2 3)
|
||||||
(comment 1 2 3 4)
|
(comment 1 2 3 4)
|
||||||
|
|
||||||
|
# Parser clone
|
||||||
|
(def p (parser/new))
|
||||||
|
(assert (= 7 (parser/consume p "(1 2 3 ")) "parser 1")
|
||||||
|
(def p2 (parser/clone p))
|
||||||
|
(parser/consume p2 ") 1 ")
|
||||||
|
(parser/consume p ") 1 ")
|
||||||
|
(assert (deep= (parser/status p) (parser/status p2)) "parser 2")
|
||||||
|
(assert (deep= (parser/state p) (parser/state p2)) "parser 3")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
Loading…
Reference in New Issue
Block a user