diff --git a/src/core/peg.c b/src/core/peg.c index 904befa0..30133cab 100644 --- a/src/core/peg.c +++ b/src/core/peg.c @@ -402,9 +402,6 @@ tail: s->mode = oldmode; if (!result) return NULL; - /* Add matched text */ - pushcap(s, janet_stringv(text, (int32_t)(result - text)), text, result); - /* Now check captures with provided function */ int32_t argc = s->captures->count - cs.cap; Janet *argv = s->captures->data + cs.cap; @@ -417,11 +414,12 @@ tail: cap = cfun(argc, argv); } + cap_load(s, cs); + /* Capture failed */ - if (janet_checktype(cap, JANET_NIL)) return NULL; + if (!janet_truthy(cap)) return NULL; /* Capture worked, so use new capture */ - cap_load(s, cs); pushcap(s, cap, text, result); return result; @@ -698,9 +696,9 @@ static void spec_reference(Builder *b, int32_t argc, const Janet *argv) { Reserve r = reserve(b, 2); int32_t index = peg_getinteger(b, argv[0]); if (index < 0) { - emit_1(r, RULE_BACKINDEX, -index); + emit_1(r, RULE_REPINDEX, -index - 1); } else { - emit_1(r, RULE_REPINDEX, index); + emit_1(r, RULE_BACKINDEX, index); } } diff --git a/test/suite3.janet b/test/suite3.janet index 985c568e..fd012dc2 100644 --- a/test/suite3.janet +++ b/test/suite3.janet @@ -182,6 +182,7 @@ (check-match '(* (some (range "az" "AZ")) -1) "hello" true) (check-match '(* (some (range "az" "AZ")) -1) "hello world" false) (check-match '(* (some (range "az" "AZ")) -1) "1he11o" false) +(check-match '(* (some (range "az" "AZ")) -1) "" false) # Pre compile @@ -271,7 +272,7 @@ # Matchtime capture -(def scanner (peg/compile ~(cmt (some 1) ,scan-number))) +(def scanner (peg/compile ~(cmt (capture (some 1)) ,scan-number))) (check-deep scanner "123" @[123]) (check-deep scanner "0x86" @[0x86]) @@ -287,4 +288,35 @@ (check-match g "aacbb" true) (check-match g "aadbb" false) +# Back reference + +(def wrapped-string + ~{:pad (any "=") + :open (* "[" (capture :pad) "[") + :close (* "]" (cmt (* (backref 0) (capture :pad)) ,=) "]") + :main (* :open (any (if-not 1 :close)) :close -1)}) + +(check-match wrapped-string "[[]]" true) +(check-match wrapped-string "[==[a]==]" true) +(check-match wrapped-string "[==[]===]" false) +(check-match wrapped-string "[[blark]]" true) +(check-match wrapped-string "[[bl[ark]]" true) +(check-match wrapped-string "[[bl]rk]]" true) +(check-match wrapped-string "[[bl]rk]] " false) +(check-match wrapped-string "[=[bl]]rk]=] " false) +(check-match wrapped-string "[=[bl]==]rk]=] " false) + +(def janet-longstring + ~{:open (capture (some "`")) + :close (cmt (* (backref 0) :open) ,=) + :main (* :open (any (if-not 1 :close)) (not (> -1 "`")) :close -1)}) + +(check-match janet-longstring "`john" false) +(check-match janet-longstring "abc" false) +(check-match janet-longstring "` `" true) +(check-match janet-longstring "` `" true) +(check-match janet-longstring "`` ``" true) +(check-match janet-longstring "``` `` ```" true) +(check-match janet-longstring "`` ```" false) + (end-suite)