mirror of
https://github.com/janet-lang/janet
synced 2025-12-03 07:08:09 +00:00
Update PEG documentation and peg syntax.
Disable tail calls in the root scope for better stacktraces, as the root scope may contain a single call to a failing function, as in the case of the test suite.
This commit is contained in:
@@ -403,7 +403,9 @@ static JanetSlot janetc_call(JanetFopts opts, JanetSlot *slots, JanetSlot fun) {
|
||||
}
|
||||
if (!specialized) {
|
||||
janetc_pushslots(c, slots);
|
||||
if (opts.flags & JANET_FOPTS_TAIL) {
|
||||
if ((opts.flags & JANET_FOPTS_TAIL) &&
|
||||
/* Prevent top level tail calls for better errors */
|
||||
!(c->scope->flags & JANET_SCOPE_TOP)) {
|
||||
janetc_emit_s(c, JOP_TAILCALL, fun, 0);
|
||||
retslot = janetc_cslot(janet_wrap_nil());
|
||||
retslot.flags = JANET_SLOT_RETURNED;
|
||||
@@ -553,7 +555,7 @@ JanetSlot janetc_value(JanetFopts opts, Janet x) {
|
||||
}
|
||||
break;
|
||||
case JANET_SYMBOL:
|
||||
ret = janetc_resolve(opts.compiler, janet_unwrap_symbol(x));
|
||||
ret = janetc_resolve(c, janet_unwrap_symbol(x));
|
||||
break;
|
||||
case JANET_ARRAY:
|
||||
ret = janetc_array(opts, x);
|
||||
@@ -576,13 +578,13 @@ JanetSlot janetc_value(JanetFopts opts, Janet x) {
|
||||
if (c->result.status == JANET_COMPILE_ERROR)
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
if (opts.flags & JANET_FOPTS_TAIL)
|
||||
ret = janetc_return(opts.compiler, ret);
|
||||
ret = janetc_return(c, ret);
|
||||
if (opts.flags & JANET_FOPTS_HINT) {
|
||||
janetc_copy(opts.compiler, opts.hint, ret);
|
||||
janetc_copy(c, opts.hint, ret);
|
||||
ret = opts.hint;
|
||||
}
|
||||
c->current_mapping = last_mapping;
|
||||
opts.compiler->recursion_guard++;
|
||||
c->recursion_guard++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ typedef enum {
|
||||
RULE_LOOK, /* [offset, rule] */
|
||||
RULE_CHOICE, /* [len, rules...] */
|
||||
RULE_SEQUENCE, /* [len, rules...] */
|
||||
RULE_IFNOT, /* [rule_a, rule_b (a if not b)] */
|
||||
RULE_IF, /* [rule_a, rule_b (b if a)] */
|
||||
RULE_IFNOT, /* [rule_a, rule_b (b if not a)] */
|
||||
RULE_NOT, /* [rule] */
|
||||
RULE_BETWEEN, /* [lo, hi, rule] */
|
||||
RULE_CAPTURE, /* [rule] */
|
||||
@@ -207,6 +208,7 @@ tail:
|
||||
rule = s->bytecode + args[len - 1];
|
||||
goto tail;
|
||||
}
|
||||
case RULE_IF:
|
||||
case RULE_IFNOT:
|
||||
{
|
||||
const uint32_t *rule_a = s->bytecode + rule[1];
|
||||
@@ -214,11 +216,11 @@ tail:
|
||||
int oldmode = s->mode;
|
||||
s->mode = PEG_MODE_NOCAPTURE;
|
||||
down1(s);
|
||||
const uint8_t *result = peg_rule(s, rule_b, text);
|
||||
const uint8_t *result = peg_rule(s, rule_a, text);
|
||||
up1(s);
|
||||
s->mode = oldmode;
|
||||
if (result) return NULL;
|
||||
rule = rule_a;
|
||||
if (rule[0] == RULE_IF ? !result : !!result) return NULL;
|
||||
rule = rule_b;
|
||||
goto tail;
|
||||
}
|
||||
case RULE_NOT:
|
||||
@@ -356,29 +358,23 @@ tail:
|
||||
|
||||
} else { /* RULE_REPLACE */
|
||||
Janet constant = s->constants[rule[2]];
|
||||
int32_t nbytes = (int32_t)(result - text);
|
||||
switch (janet_type(constant)) {
|
||||
default:
|
||||
cap = constant;
|
||||
break;
|
||||
case JANET_STRUCT:
|
||||
cap = janet_struct_get(janet_unwrap_struct(constant),
|
||||
janet_stringv(text, nbytes));
|
||||
s->captures->data[s->captures->count - 1]);
|
||||
break;
|
||||
case JANET_TABLE:
|
||||
cap = janet_table_get(janet_unwrap_table(constant),
|
||||
janet_stringv(text, nbytes));
|
||||
s->captures->data[s->captures->count - 1]);
|
||||
break;
|
||||
case JANET_CFUNCTION:
|
||||
janet_array_push(s->captures,
|
||||
janet_stringv(text, nbytes));
|
||||
JanetCFunction cfunc = janet_unwrap_cfunction(constant);
|
||||
cap = cfunc(s->captures->count - cs.cap,
|
||||
cap = janet_unwrap_cfunction(constant)(s->captures->count - cs.cap,
|
||||
s->captures->data + cs.cap);
|
||||
break;
|
||||
case JANET_FUNCTION:
|
||||
janet_array_push(s->captures,
|
||||
janet_stringv(text, nbytes));
|
||||
cap = janet_call(janet_unwrap_function(constant),
|
||||
s->captures->count - cs.cap,
|
||||
s->captures->data + cs.cap);
|
||||
@@ -634,12 +630,20 @@ static void spec_sequence(Builder *b, int32_t argc, const Janet *argv) {
|
||||
spec_variadic(b, argc, argv, RULE_SEQUENCE);
|
||||
}
|
||||
|
||||
static void spec_ifnot(Builder *b, int32_t argc, const Janet *argv) {
|
||||
/* For (if a b) and (if-not a b) */
|
||||
static void spec_branch(Builder *b, int32_t argc, const Janet *argv, uint32_t rule) {
|
||||
peg_fixarity(b, argc, 2);
|
||||
Reserve r = reserve(b, 3);
|
||||
uint32_t rule_a = compile1(b, argv[0]);
|
||||
uint32_t rule_b = compile1(b, argv[1]);
|
||||
emit_2(r, RULE_IFNOT, rule_a, rule_b);
|
||||
emit_2(r, rule, rule_a, rule_b);
|
||||
}
|
||||
|
||||
static void spec_if(Builder *b, int32_t argc, const Janet *argv) {
|
||||
spec_branch(b, argc, argv, RULE_IF);
|
||||
}
|
||||
static void spec_ifnot(Builder *b, int32_t argc, const Janet *argv) {
|
||||
spec_branch(b, argc, argv, RULE_IFNOT);
|
||||
}
|
||||
|
||||
/* Rule of the form [rule] */
|
||||
@@ -663,18 +667,6 @@ static void spec_group(Builder *b, int32_t argc, const Janet *argv) {
|
||||
spec_onerule(b, argc, argv, RULE_GROUP);
|
||||
}
|
||||
|
||||
static void spec_exponent(Builder *b, int32_t argc, const Janet *argv) {
|
||||
peg_fixarity(b, argc, 2);
|
||||
Reserve r = reserve(b, 4);
|
||||
int32_t n = peg_getinteger(b, argv[1]);
|
||||
uint32_t subrule = compile1(b, argv[0]);
|
||||
if (n < 0) {
|
||||
emit_3(r, RULE_BETWEEN, 0, -n, subrule);
|
||||
} else {
|
||||
emit_3(r, RULE_BETWEEN, n, UINT32_MAX, subrule);
|
||||
}
|
||||
}
|
||||
|
||||
static void spec_between(Builder *b, int32_t argc, const Janet *argv) {
|
||||
peg_fixarity(b, argc, 3);
|
||||
Reserve r = reserve(b, 4);
|
||||
@@ -778,10 +770,9 @@ static const SpecialPair specials[] = {
|
||||
{"!", spec_not},
|
||||
{"*", spec_sequence},
|
||||
{"+", spec_choice},
|
||||
{"-", spec_ifnot},
|
||||
{"/", spec_replace},
|
||||
{"<-", spec_capture},
|
||||
{">", spec_look},
|
||||
{"^", spec_exponent},
|
||||
{"any", spec_any},
|
||||
{"argument", spec_argument},
|
||||
{"at-least", spec_atleast},
|
||||
@@ -793,6 +784,7 @@ static const SpecialPair specials[] = {
|
||||
{"cmt", spec_matchtime},
|
||||
{"constant", spec_constant},
|
||||
{"group", spec_group},
|
||||
{"if", spec_if},
|
||||
{"if-not", spec_ifnot},
|
||||
{"look", spec_look},
|
||||
{"not", spec_not},
|
||||
|
||||
Reference in New Issue
Block a user