janet icon indicating copy to clipboard operation
janet copied to clipboard

peg/replace should accept functions for replacement

Open Techcable opened this issue 2 years ago • 2 comments

I would expect the following code to work:

(defn escape-string [target]
   (defn escaper [bad] (string/format "\\%s" bad))
   (def escaped (peg/replace-all '(set ``\\\"\n\t\0``) escaper target))
   (string/format ``"%s"`` escaped))

(print (escape-string "foo\nbar"))

However, this code currently fails with the following error:

error: bad slot #1, expected string|symbol|keyword|buffer, got <function 0x6000037A84A0>
  in peg/replace-all [src/core/peg.c] on line 1733
  in escape-string [repl] on line 2, column 17
  in _thunk [repl] (tailcall) on line 4, column 1

I would say we should support "replacement functions" in addition to literal replacements. These functions would be called each time the pattern matches, and we should support one or two argument variants (if possible) [matchedText &opt patternCaptures]

The return result of that function call would then be expected to be a string literal. Supporting functions would be much more flexible overall (especially when combined with full pattern capabilities) and consistent with the regex capabilities of other languages.

I think it would be possible to emulate this in Janet boot.janet?....

Techcable avatar Aug 18 '22 22:08 Techcable

Just to be clear, peg/match can be used for replacements as well, and can do function replacements - peg/replace is just a convenience function.

I would be open to adding this though if it is easy to add.

bakpakin avatar Aug 18 '22 23:08 bakpakin

It would also be useful if peg/replace-all had this feature too!

autumnull avatar Sep 12 '22 21:09 autumnull