Snowball.Analyser (snowball v0.1.1)

Copy Markdown View Source

Parses a Snowball token stream into a typed AST with a symbol table.

Accepts the output of Snowball.Lexer.tokenize/1 and returns a program/0 map that the code generator consumes.

AST node shapes

All nodes are plain maps with at least a :kind atom and a :line integer. The primary node kinds are:

  • %{kind: :program, symbols: symbol_table, defs: [node]} — top-level.

  • %{kind: :define_routine, name: binary, body: node, line: n}.

  • %{kind: :define_grouping, name: binary, strings: [binary], line: n}.

  • Command nodes — see node/0.

Summary

Types

An AST node (map with at least :kind and :line).

The top-level program node.

A symbol table entry.

The symbol table — map from name string to symbol.

Symbol types that names can be declared as.

t()

Functions

Analyse a token list produced by Snowball.Lexer.tokenize/1.

Types

ast_node()

@type ast_node() :: map()

An AST node (map with at least :kind and :line).

program()

@type program() :: %{kind: :program, symbols: symbol_table(), defs: [ast_node()]}

The top-level program node.

symbol()

@type symbol() :: %{type: symbol_type(), mode: :unknown | :forward | :backward}

A symbol table entry.

symbol_table()

@type symbol_table() :: %{optional(binary()) => symbol()}

The symbol table — map from name string to symbol.

symbol_type()

@type symbol_type() ::
  :integer | :boolean | :string | :grouping | :routine | :external

Symbol types that names can be declared as.

t()

@type t() :: %Snowball.Analyser{
  errors: [{binary(), pos_integer()}],
  mode: :forward | :backward,
  symbols: symbol_table(),
  tokens: [Snowball.Lexer.token()]
}

Functions

analyse(tokens)

@spec analyse([Snowball.Lexer.token()]) ::
  {:ok, program()} | {:error, [{binary(), non_neg_integer()}]}

Analyse a token list produced by Snowball.Lexer.tokenize/1.

Arguments

Returns

  • {:ok, program} — the program AST.

  • {:error, [{reason, line}]} — one or more parse errors.

Examples

iex> {:ok, tokens} = Snowball.Lexer.tokenize("integers ( p1 )")
iex> {:ok, prog} = Snowball.Analyser.analyse(tokens)
iex> prog.kind
:program