blue matrix

Parsing in Js after all

Oh... kay... I've been a little optimistic there. 😅

I needed to move on, so I decided to switch back to good old Javascript. I used PEGGYjs, which is the properly maintained child of PEGjs. A few hours later, when I look at the sheer size of the grammar, I don't regret my decision. It wasn't exactly trivial to setup in Javascript, so doing it in Go would have been next to impossible for me.

One potential benefit will be the ability to include Javascript lines of code directly in the tables, for example. But that will require an additional syntactic device that is not invented yet. So for now, I'll stick to the original plan. Having Hup Javascript-based shouldn't make it overly slow.

Anyway every code sample shown in the previous posts is now correctly parsed by the parser, and turned into a JSON object.

[
    older than 50
    = [detailed family]
        % #genre( #name age(#age) ) &( #age > 50 )
        : #name( #genre #age years old )
    | Pedro( man 66 years old )
    | Alma( woman 62 years old )
]

This results in the following structure.

[
  {
    TableName: 'older than 50',
    TableFormula: [
      {
        Operator: 'PRODUCE',
        Shaped: false,
        Operands: [
          {
            T: 'Reference',
            V: 'detailed family'
          }
        ]
      },
      {
        Operator: 'EXTRACT',
        Shaped: false,
        Operands: [
          {
            T: 'Compound',
            V: {
              Functor: {
                T: 'Variable',
                V: '#genre'
              },
              Arguments: [
                {
                  Operator: 'PRODUCE',
                  Shaped: false,
                  Operands: [
                    {
                      T: 'Variable',
                      V: '#name'
                    },
                    {
                      T: 'Compound',
                      V: {
                        Functor: {
                          T: 'Atom',
                          V: 'age'
                        },
                        Arguments: [
                          {
                            Operator: 'PRODUCE',
                            Shaped: false,
                            Operands: [
                              {
                                T: 'Variable',
                                V: '#age'
                              }
                            ]
                          }
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          }
        ]
      },
      {
        Operator: 'COPY',
        Shaped: false,
        Operands: [
          {
            T: 'Formula',
            V: [
              {
                Operator: 'PRODUCE',
                Shaped: false,
                Operands: [
                  {
                    T: 'Variable',
                    V: '#age'
                  }
                ]
              },
              {
                Operator: 'GT',
                Shaped: false,
                Operands: [
                  {
                    T: 'Number',
                    V: 50
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        Operator: 'PRODUCE',
        Shaped: false,
        Operands: [
          {
            T: 'Compound',
            V: {
              Functor: {
                T: 'Variable',
                V: '#name'
              },
              Arguments: [
                {
                  Operator: 'PRODUCE',
                  Shaped: false,
                  Operands: [
                    {
                      T: 'Variable',
                      V: '#genre'
                    },
                    {
                      T: 'Variable',
                      V: '#age'
                    },
                    {
                      T: 'Atom',
                      V: 'years'
                    },
                    {
                      T: 'Atom',
                      V: 'old'
                    }
                  ]
                }
              ]
            }
          }
        ]
      }
    ],
    TableValues: [
      [
        {
          T: 'Compound',
          V: {
            Functor: {
              T: 'Atom',
              V: 'Pedro'
            },
            Arguments: [
              {
                Operator: 'PRODUCE',
                Shaped: false,
                Operands: [
                  {
                    T: 'Atom',
                    V: 'man'
                  },
                  {
                    T: 'Number',
                    V: 66
                  },
                  {
                    T: 'Atom',
                    V: 'years'
                  },
                  {
                    T: 'Atom',
                    V: 'old'
                  }
                ]
              }
            ]
          }
        }
      ],
      [
        {
          T: 'Compound',
          V: {
            Functor: {
              T: 'Atom',
              V: 'Alma'
            },
            Arguments: [
              {
                Operator: 'PRODUCE',
                Shaped: false,
                Operands: [
                  {
                    T: 'Atom',
                    V: 'woman'
                  },
                  {
                    T: 'Number',
                    V: 62
                  },
                  {
                    T: 'Atom',
                    V: 'years'
                  },
                  {
                    T: 'Atom',
                    V: 'old'
                  }
                ]
              }
            ]
          }
        }
      ]
    ]
  }
]

Notice how the first part of a formula gets turned into a Produce operation.

The platform is still Wails, but the target is now Javascript - probably in a Web Worker to keep the UI perfectly reactive. With everything in place, I'm now ready to start the part that I love: implementing the interpreter itself!


I'm adding a new Merge operator ", the purpose of which is to join tables on a per value basis.

[ c | 1 | 2 | 3 | 3 | 4 ]
[ d | 5 | bar | moo mew ]

[
  merging c and d
    = c " d
    | 1 5
    | 2 bar
    | 3 moo mew
    | 3
    | 4
]

Now I believe the list of operators should be complete.