Skip to content

SyntaxParser

Dr. Ernie Prabhakar edited this page Apr 2, 2017 · 2 revisions

HC uses a version of applicative-parsing, which is similar to monadic parsing. The core idea is to define a generic combinator that consumes and aggregates elements that get chained together to form the Abstract Syntax Tree (AST). Of course, since Frame is fully homoiconic, the AST is simply a tree of Frames, including FrameExpr's that can be directly evaluated to product a result.

Syntax Combinator

The core class is SyntaxCombinator.

Terminals

We initialize them as an array, since we can extract the key from an instantiated object.

export const terminals = [
  SyntaxNest(FrameGroup),
  SyntaxNest(FrameArray),
  SyntaxNest(FrameLazyGroup),
  SyntaxFinish(FrameExpr, ","),
  SyntaxFinish(FrameStatement, ";"),
  SyntaxEnd(Frame.kEND)
];

Those methods all return factory functions which instantiate those classes using the current Array<Frame> state.

Tokens

Tokens operate similarly, but each item constructed from a string (at this level, every Frame is a character represented as FrameSymbol, so Array<FrameSymbol> can be concatenated into a JavaScript string).

export const tokens = [
  SyntaxQuote(FrameString),
  SyntaxQuote(FrameComment),
  SyntaxQuote(FrameBlob),
  SyntaxItem(FrameSymbol),
  SyntaxItem(FrameName),
  SyntaxItem(FrameNumber),
  SyntaxItem(FrameReference),
  SyntaxItem(FrameControl)
];

Pipeline

Those are used to create a lexer, which feeds into the pipeline. const lex_pipe = make_lexer(tokens, terminals);

export const evaluate = (input: string, context = Void): Frame => {
  const result = new FrameArray([], context); // store the result
  const evaluator = new EvalPipe(result); // evaluate lists into results
  const grouper = new GroupPipe(evaluator); // group expressions into lists
  const parser = new ParsePipe(grouper); // parse tokens into expressions
  const lexer = lex_pipe(parser); // lex characters into tokens

  lexer.lex_string(input);
  return result;
};

Syntax

Clone this wiki locally