kadena-io / pact

The Pact Smart Contract Language
https://docs.kadena.io/build/pact
BSD 3-Clause "New" or "Revised" License
581 stars 99 forks source link

Generalized parsing of conditional expressions #1300

Closed 0xd34df00d closed 11 months ago

0xd34df00d commented 1 year ago

This allows parsing some corner cases of the cond expression default values, in particular #1118.

The current condForm greedily parses the list of branches as, roughly speaking, valueLevel >> valueLevel (I'm omitting handling their results for brevity), and the default/fallback clause of the form (a b) gets consumed by this as well, so the final default clause parser doesn't see it and errors out.

To generalize, the problem is that we need to parse a list of ps followed by a single q, where p recognizes a (proper) subset of strings from q. The current parser effectively does some p >> q, which fails if that last element is in p (where, un-generalizing back to our problem, p is the branches parser, and q is the default clause parser).

Looks like the only solution (besides some post-processing and reshuffling of parsed terms, which is probably not something we'd like to do) is to do some lookahead. The way it's done here is as follows:

  1. We first try to parse q ensuring it's not followed by another q. If it isn't followed, then it must be the final q and we're good.
  2. If it is, then it must really be the (non-final) p, so we backtrack and parse with p.

As a side note, this parser now also accepts a cond with a single default clause and no branches — it makes the implementation a tad simpler and more readable in what's already a somewhat non-trivial code, without sacrificing correctness. If somebody wants an effectively no-op cond, shall we let them?


PR checklist:

Additionally, please justify why you should or should not do the following:

0xd34df00d commented 11 months ago

Closing this without merging since getting corner cases ironed out in the type checker proves to be harder than expected. It seems to be more reasonable to delay this until type checker gets overhauled.