1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-01 04:19:55 +00:00

Merge pull request #1028 from autumnull/master

Made peg 'not' and 'if-not' drop their captures on success
This commit is contained in:
Calvin Rose 2022-09-13 15:20:10 -05:00 committed by GitHub
commit dfc0aefd87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 5 deletions

View File

@ -261,24 +261,46 @@ tail:
goto tail; goto tail;
} }
case RULE_IF: case RULE_IF: {
case RULE_IFNOT: {
const uint32_t *rule_a = s->bytecode + rule[1]; const uint32_t *rule_a = s->bytecode + rule[1];
const uint32_t *rule_b = s->bytecode + rule[2]; const uint32_t *rule_b = s->bytecode + rule[2];
down1(s); down1(s);
const uint8_t *result = peg_rule(s, rule_a, text); const uint8_t *result = peg_rule(s, rule_a, text);
up1(s); up1(s);
if (rule[0] == RULE_IF ? !result : !!result) return NULL; if (!result) return NULL;
rule = rule_b; rule = rule_b;
goto tail; goto tail;
} }
case RULE_IFNOT: {
const uint32_t *rule_a = s->bytecode + rule[1];
const uint32_t *rule_b = s->bytecode + rule[2];
down1(s);
CapState cs = cap_save(s);
const uint8_t *result = peg_rule(s, rule_a, text);
if (!!result) {
up1(s);
return NULL;
} else {
cap_load(s, cs);
up1(s);
rule = rule_b;
goto tail;
}
}
case RULE_NOT: { case RULE_NOT: {
const uint32_t *rule_a = s->bytecode + rule[1]; const uint32_t *rule_a = s->bytecode + rule[1];
down1(s); down1(s);
CapState cs = cap_save(s);
const uint8_t *result = peg_rule(s, rule_a, text); const uint8_t *result = peg_rule(s, rule_a, text);
if (result) {
up1(s); up1(s);
return (result) ? NULL : text; return NULL;
} else {
cap_load(s, cs);
up1(s);
return text;
}
} }
case RULE_THRU: case RULE_THRU:

20
test/suite0014.janet Normal file
View File

@ -0,0 +1,20 @@
(import ./helper :prefix "" :exit true)
(start-suite 14)
(assert (deep=
(peg/match '(not (* (constant 7) "a")) "hello")
@[]) "peg not")
(assert (deep=
(peg/match '(if-not (* (constant 7) "a") "hello") "hello")
@[]) "peg if-not")
(assert (deep=
(peg/match '(if-not (drop (* (constant 7) "a")) "hello") "hello")
@[]) "peg if-not drop")
(assert (deep=
(peg/match '(if (not (* (constant 7) "a")) "hello") "hello")
@[]) "peg if not")
(end-suite)