Creating callbacks for the Ohm-js parser

I’m working on porting a pet language project from TS to Rescript. All going well, apart from the bindings to the Ohm parser generator.

Ohm associates actions with parse rules using callbacks. The name of the parse rule is used as a key into a JS object. The values are functions that are passed one or more nodes, each node corresponding; to an element on the RHS of the rule. So, given:

      = QualifiedName "("  CallParameters ")" -- with_parens
      | QualifiedName  CallParameters -- no_parens

I’d handle the callbacks with a JS object that looks something like the following (N is a type alias for the Ohm node type).

const TreeMaker = {
  FunctionCall_no_parens(fn: N, params: N) {
    return functionNode(this, fn, params)

  FunctionCall_with_parens(fn: N, _1: N, params: N, _2: N) {
    return functionNode(this, fn, params)

 . . .

I’d really like to have the callbacks in Rescript, because they are generating an AST, and that’s just begging for variant types.

I think I have two problems. The first is that I need to be able to create a type for the set of functions that take 1 or more Ohm nodes as parameters, but I can’t see a way of doing that. I can’t use an array, because the callback API is fixed by Ohm.

The second is that some callback function names must start with an uppercase letter, and other must start with lowercase.

I’m probably missing something obvious… but what?

TIA for reading


I might not be quite following what you’re after, but I wonder if using object syntax would be helpful for you?

For example:

type node

type treeMaker = {
  "FunctionCall_no_parens": (node, node) => unit,
  "FunctionCall_with_parens": (node, node, node, node) => unit,

let callbacks: treeMaker = {
  "FunctionCall_no_parens": (_fn, _params) => {
  "FunctionCall_with_parens": (_fn, _1, _params, _2) => {

Well, color me a fool :slight_smile: I should have thought of doing that. I got stuck initially on the signature for the Ohm function I called, and what I should be using to represent the treeMaker parameter, but suddenly realized I don’t care: it’s just a pass through, so 't is all I need.

Many thanks!