Module

Tramaj.Parser

Package
purescript-tramaj-purs
Repository
lucasdicioccio/purescript-tramaj-purs

Surface syntax to core AST. Everything the surface offers beyond Tramaj.Ast's constructors is desugared here rather than represented:

  • @name=expr binding lines become nested Lets;
  • string interpolation becomes Concat over the str builtin;
  • branch(fallback, p1, v1, ...) becomes nested Branch;
  • object shorthand {foo} becomes {"foo": $foo};
  • escape sequences are resolved into the StringLit they denote.

The grammar keeps three leader characters from v1: . introduces a document, $ reads a binding, @ defines one. What changed is that there is now a single expression grammar — v1's separate template-phase productions (node, nodeArg, childArg, templateSpecialForm, pathOrCallChild) are gone, because documents are expressions.

A fourth character is lexical rather than grammatical: -- begins a comment that runs to the end of the line. It is discarded by skipSpaces along with whitespace, so it never reaches the AST and there is nothing to desugar.

Two conventions are load-bearing and carried over deliberately:

  • A special form's try covers name recognition only. Once import or map has matched, its shape is parsed without backtracking, so a malformed one is a hard parse error instead of silently falling through to a meaningless Call that would only fail much later at eval time.
  • A field-access suffix is parsed with no whitespace skipped before it, so f().rendered is a field access while f() followed by a newline and .div(...) is two separate things.

Kept in lockstep with ../tramaj-hs/src/Tramaj/Parser.hs.

#parseProgram Source

parseProgram :: String -> Either ParseError Program

A program is a sequence of statements and a root expression. Which kind of program it is follows from the root's own form — a document root is exactly one written as a document — so there is no mode to declare and no separate entry point to pick.