Parsing task, help making the code look more like ReScript

I have code that looks like that to parse text:

let st = ref({lnum: 0, syms: list{}})
while st.contents.lnum < lines->Array.length &&
    switch consumeLine(st.contents, predicate) {
      | {lnum: next, syms: newsyms} =>
        if st.contents.lnum == next {
          st := {...st.contents, lnum: next + 1} // reached block end
          false
        }
        else {
          st := {lnum: next, syms: newsyms}
          true
        }
    }
{
  ()	// empty while body
}

Do you have suggestions to get rid of that ugly “while”? (even better if I can do it without “ref”.)

Playground:
https://rescript-lang.org/try?code=PYBwpgdgBAQmA2AXAUM+ZFUWAHpgvFAAYCSU8wAbmFAE5gDOAxrQJYgoC03yDYTwCABNyrCGDQBDBpnhiwRVOlnyGUQtjycAfACkGAOgDKiNhADmBhiDmIAFACIAOhAcBKVIgCe4KDMnY6lAA3shQ5BAArgC2AFxQYogANGF+XtEM8XIyADwyZubayAC+ShhQAhAMMWAAMvJBdkyRtPQQyVCQQmBCbupFAJAMAO6siEwAFqLiDADaza2QiAbwUdEAuiGp4eEAPlBGwNFgdnLiffhFOzsDrABmUHZdPafybn2h118VLW0o3+FSgDOvA+FtgeF9CtgOZXudtgDggZkQs-kkIjF4qilis1lAANRQACMQIBpOu+wAcoIaJcEeEBlCKLCHAAjSQiaLAABWwHc9KgAyRKN+S3Rq0xxIADDKZeSoKU0OUQPQhKwmAFaQkICBIgRtI8xLqCIQHNxOPylZgZEF6Hc7MEJXEoFL0Qx0plRDJgsVih5hhNWOg-MtKth2oYnVActNGDoAIKtSReFaQcyIKYAMkzyCGo3GU0q1WO9XEdhkBjDSwY6JVPXVmo+Av2jrW8XEeDdHvbYGG7oyxX6AtuDwrVYjuJi6kIHcwnwhNtihGFVlDgnDiBrGOds4JxMHAHoD3QwJJJj0oKyKEwANadYQC653SSgiTfAbyhkIMHz4GL5dOj2nZpBkPZ9h6n5fKYkRvmSYQfsg852G4AxHp00QcF4UABkGNCssAQheCUyBAA

Hi Jido,

I need to take some more time to think about what you are actually trying to achieve.
But from a very first glimpse I think this would be an application for fold_left or Belt.Array.reduce.

st would probably be your accumulator.

The only possible “issue” I see is, that reduce will go over every item of the array without any possibility for an “early exit”.

Could you give a short description of what your code should be doing in prosa text, please?

Kind regards

Yes exactly, the issue is with early exit.

The task: think of parsing a markup language with blocks of varying boundaries. While it is possible to keep track of the nesting level and boundary stack, I am trying to do it with recursion instead.

Is that a good application of async/await? (It’s basically a task for a generator).

If you are ultimately targeting node and this is supposed to be more than just a quick sketch, I’d use node streams.

They are quite performant AFAIK and would support arbitary file sizes without holding everything in memory.
There is a package called rescript-node which is maintained by a long-time community member (@spyder), which should give you a kickstart.

You’d probably want to split up parsing and detection of elements from acting on them.
The former would be done by emitting custom events, while the latter would be achieved by subscribing event-handlers to them.

1 Like