80 lines
3.5 KiB
Rust
80 lines
3.5 KiB
Rust
//! # NGR (No Good Reason) Compiler
|
|
//!
|
|
//! This is the top-level module for the NGR compiler; a compiler written
|
|
//! in Rust for no good reason. I may eventually try to turn this into a
|
|
//! basic guide for writing compilers, but for now it's a fairly silly
|
|
//! (although complete) language and implementation, featuring:
|
|
//!
|
|
//! * Variable binding with basic arithmetic operators.
|
|
//! * The ability to print variable values.
|
|
//!
|
|
//! I'll be extending this list into the future, with the eventual goal of
|
|
//! being able to implement basic programming tasks with it. For example,
|
|
//! I have a goal of eventually writing reasonably-clear
|
|
//! [Advent of Code](https://adventofcode.com/) implementations with it.
|
|
//!
|
|
//! Users of this as a library will want to choose their adventure based
|
|
//! on how much they want to customize their experience; I've defaulted
|
|
//! to providing the ability to see internals, rather than masking them,
|
|
//! so folks can play with things as they see fit.
|
|
//!
|
|
//! ## Easy Mode - Just Running a REPL or Compiler
|
|
//!
|
|
//! For easiest use, you will want to use either the [`Compiler`] object
|
|
//! or the [`REPL`] object.
|
|
//!
|
|
//! As you might expect, the [`Compiler`] object builds a compiler, which
|
|
//! can be re-used to compile as many files as you'd like. Right now,
|
|
//! that's all it does. (TODO: Add a linker function to it.)
|
|
//!
|
|
//! The [`REPL`] object implements the core of what you'll need to
|
|
//! implement a just-in-time compiled read-eval-print loop. It will
|
|
//! maintain variable state and make sure that variables are linked
|
|
//! appropriately as the loop progresses.
|
|
//!
|
|
//! ## Hard Mode - Looking at the individual passes
|
|
//!
|
|
//! This compiler is broken into three core parts:
|
|
//!
|
|
//! 1. The front-end / syntax engine. This portion of the compiler is
|
|
//! responsible for turning basic strings (or files) into a machine-
|
|
//! friendly abstract syntax tree. See the [`syntax`] module for
|
|
//! more information.
|
|
//! 2. The IR. This portion of the compiler will be responsible for
|
|
//! high-level code analysis and transformation ... although for
|
|
//! now, it doesn't do much at all. See the [`ir`] module for more
|
|
//! information.
|
|
//! 3. The Backend implementation. This portion of the compiler turns
|
|
//! the IR from the previous section into Cranelift structures, and
|
|
//! helps with either compiling them via JIT or statically compiling
|
|
//! them into a file. The [`backend`] module also contains information
|
|
//! about the runtime functions made available to the user.
|
|
//!
|
|
//! ## Testing
|
|
//!
|
|
//! Testing is a key focus of this effort. To that end, both the syntax
|
|
//! tree used in the syntax module and the IR used in the middle of the
|
|
//! compiler both implement `Arbitrary`, and are subject to property-based
|
|
//! testing to make sure that various passes work properly.
|
|
//!
|
|
//! In addition, to support basic equivalence testing, we include support
|
|
//! for evaluating all expressions. The [`eval`] module provides some
|
|
//! utility support for this work.
|
|
//!
|
|
/// The front-end of the compiler: lexing, parsing, validation
|
|
pub mod syntax;
|
|
/// The middle of the compiler: analysis, simplification, optimization
|
|
pub mod ir;
|
|
/// The backend of the compiler: transformation to Cranelift, runtime
|
|
pub mod backend;
|
|
/// Helpful functions for evaluating NGR programs
|
|
pub mod eval;
|
|
|
|
/// Implementation module for the high-level compiler
|
|
mod compiler;
|
|
/// Implementation module for the high-level REPL
|
|
mod repl;
|
|
|
|
pub use crate::compiler::Compiler;
|
|
pub use crate::repl::REPL;
|