janet-lang / spork

Various Janet utility modules - the official "Contrib" library.
MIT License
122 stars 35 forks source link

`fmt/` removes code for some cases #14

Closed pepe closed 3 years ago

pepe commented 3 years ago

Easy repro:

➜ janet -l spork/fmt
Janet 1.13.2-dev-local linux/x64 - '(doc)' for help
repl:1:> (def c "(def a 1)\n(def b 2)\ndef c (+ a b))\n(print c)")
"(def a 1)\n(def b 2)\ndef c (+ a b))\n(print c)"
repl:2:> (format-print c)
(def a 1)
(def b 2)
def c (+ a b)
nil
repl:3:>

As could be seen, the format-print unexpectedly removes the last line and paren on the line before. I think error would be better here.

sogaiu commented 3 years ago

FWIW, it looks like it's not necessarily just the last line:

$ janet -l spork/fmt
Janet 1.13.2-dev-local linux/x64 - '(doc)' for help
repl:1:> (def c "(def a 1)\n(def b 2)\ndef c (+ a b))\n(print c)\n(print c)")
"(def a 1)\n(def b 2)\ndef c (+ a b))\n(print c)\n(print c)"
repl:2:> (format-print c)
(def a 1)
(def b 2)
def c (+ a b)
nil
repl:3:>

Is it possible to use the new flycheck function from boot.janet usefully in this context before trying to format?

On a side note, for judge-gen, I've been thinking about whether to run code through a linter (e.g. janet -k) before trying to process incoming source code. Processing broken code can produce strange results.

bakpakin commented 3 years ago

Using flycheck is much too heavy-handed here. We could just adapt the peg to either fail if it doesn't make it to the end of the string, or capture and emit the rest of the input verbatim from where the match failed.

pepe commented 3 years ago

I want to take a stab at this, but I would like to ask about the best way you see here @bakpakin. I still have a problem grasping your PEGs, yet I still have the desire to get to this level of thought. And every help with it is appreciated.

pepe commented 3 years ago

In #21, I propose a fix with the first solution: fail when peg does not make it to the end.