This document describes the high-level architecture of ErgoScript compiler and ErgoTree interpreter.
ErgoScript compiler pass consists of the following phases:
Converts a source code into a list of tokens. Uses Logos under the hood.
Crate: ergoscript-compiler
Module: lexer
Produces an AST by going through list of tokens. Uses Rowan CST (Concrete Syntax Trees) under the hood. AST nodes wrap Rowan's trees (CST) and expose node-specific details via methods (e.g. BinaryExpr::lhs()).
Crate: ergoscript-compiler
Modules: parser, ast
Created by "lowering" from AST produced by the parser. Each node(hir::Expr) has a kind(enum), span(source code reference) and an optional type.
Crate: ergoscript-compiler
Module: hir
Rewrites HIR tree swapping identifiers (e.g. HEIGHT), some predefined functions (e.g. min/max) and variables from environment (ScriptEnv) with their HIR nodes.
Crate: ergoscript-compiler
Module: binder
Traverses the HIR tree and assigns a type to every node.
Crate: ergoscript-compiler
Module: type_infer
Created by "lowering" from HIR. "Final" IR, used in the interpreter and serialization.
Crate: ergotree-ir
Module: mir
Traverses the MIR tree and check that node's ancestors types correspond to node's type.
Crate: ergotree-ir
Module: type_check
All phases are run in compiler::compile() which is the entry point for the compiler.
Tests are comparing produced tree to the expected data(snapshot testing) using expect_test crate.
To update test data, run cargo test with UPDATE_EXPECT variable:
env UPDATE_EXPECT=1 cargo testEvaluates MIR nodes by calling Evaluable::eval() on the tree root. Each node implements trait Evaluable::eval() method.
Crate: ergotree-interpreter
Each MIR node implements SigmaSerializable trait with sigma_parse() and sigma_serialize().
Crate: ergotree-ir
Module: serialization