diff --git a/src/backend.rs b/src/backend.rs index 6e10075..f97e88c 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -1,4 +1,4 @@ -//! # The compiler backend! +//! # The compiler backend: generation of machine code, both static and JIT. //! //! This module is responsible for taking our intermediate representation from //! [`crate::ir`] and turning it into Cranelift and then into object code that @@ -15,19 +15,16 @@ //! they share a lot of behaviors. However, you'll want to use different variants //! based on your goals: //! -//! * Use `Backend`, constructed via -//! [`Backend::object_file`](self::backend::Backend::object_file), if you -//! want to compile to an object file on disk, which you're then going to -//! link to later. -//! * Use `Backend`, constructed via -//! [`Backend::jit`](self::backend::Backend::jit), if you want to do -//! just-in-time compilation and are just going to run things immediately. +//! * Use `Backend`, constructed via [`Backend::object_file`], +//! if you want to compile to an object file on disk, which you're then going +//! to link to later. +//! * Use `Backend`, constructed via [`Backend::jit`], if you want +//! to do just-in-time compilation and are just going to run things immediately. //! //! ## Working with Runtime Functions //! //! For now, runtime functions are pretty easy to describe, because there's -//! only one. In the future, though, the -//! [`RuntimeFunctions`](self::backend::RuntimeFunctions) object is there to +//! only one. In the future, though, the [`RuntimeFunctions`] object is there to //! help provide a clean interface to them all. mod error; mod eval; diff --git a/src/eval.rs b/src/eval.rs index b764eb5..017c9b6 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -1,3 +1,4 @@ +//! Helpful functions for evaluating NGR programs. mod env; mod primop; mod value; diff --git a/src/ir.rs b/src/ir.rs index b7cd9cf..5c2458b 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -1,3 +1,17 @@ +//! The middle of the compiler: analysis, simplification, optimization. +//! +//! For the moment, this module doesn't do much besides define an intermediate +//! representation for NGR programs that is a little easier to work with then +//! the structures we've built from the actual user syntax. For example, in the +//! IR syntax, function calls are simplified so that all their arguments are +//! either variables or constants, which can make reasoning about programs +//! (and implicit temporary variables) quite a bit easier. +//! +//! For the foreseeable future, this module will likely remain mostly empty +//! besides definitions, as we'll likely want to focus on just processing / +//! validating syntax, and then figuring out how to turn it into Cranelift +//! and object code. After that point, however, this will be the module to +//! come to for analysis and optimization work. mod ast; mod eval; mod from_syntax; diff --git a/src/ir/from_syntax.rs b/src/ir/from_syntax.rs index e5eea0e..9caa1ff 100644 --- a/src/ir/from_syntax.rs +++ b/src/ir/from_syntax.rs @@ -1,7 +1,7 @@ use internment::ArcIntern; use crate::ir::ast as ir; -use crate::syntax::ast as syntax; +use crate::syntax as syntax; impl From for ir::Program { fn from(mut value: syntax::Program) -> Self { diff --git a/src/lib.rs b/src/lib.rs index 88057b3..df9cf15 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -61,18 +61,14 @@ //! 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 +/// Implementation module for the high-level compiler. mod compiler; -/// Implementation module for the high-level REPL +/// Implementation module for the high-level REPL. mod repl; pub use crate::compiler::Compiler; diff --git a/src/syntax.rs b/src/syntax.rs index cbadf0c..8356999 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -1,20 +1,47 @@ +//! NGR Parsing: Reading input, turning it into sense (or errors). +//! +//! This module implement the front end of the compiler, which is responsible for +//! reading in NGR syntax as a string, turning it into a series of reasonable Rust +//! structures for us to manipulate, and doing some validation while it's at it. +//! +//! The core flow for this work is: +//! +//! * Turning the string into a series of language-specific [`Token`]s. +//! * Taking those tokens, and computing a basic syntax tree from them, +//! using our [`parser`]. +//! * Validating the tree we have parsed, using the [`validate`] module, +//! returning any warnings or errors we have found. +//! * Simplifying the tree we have parsed, using the [`simplify`] module, +//! into something that's more easily turned into our [compiler internal +//! representation](super::ir). +//! +//! In addition to all of this, we make sure that the structures defined in this +//! module are all: +//! +//! * Instances of [`Pretty`](::pretty::Pretty), so that you can print stuff back +//! out that can be read by a human. +//! * Instances of [`Arbitrary`](proptest::prelude::Arbitrary), so they can be +//! used in `proptest`-based property testing. There are built-in tests in +//! the library, for example, to make sure that the pretty-printing round-trips. +//! * Can be evaluated using an `eval` function, for comparison with later +//! versions of the function downstream. use codespan_reporting::{diagnostic::Diagnostic, files::SimpleFiles}; use lalrpop_util::lalrpop_mod; use logos::Logos; mod arbitrary; -pub mod ast; +mod ast; mod eval; mod location; -mod simplify; +pub mod simplify; mod tokens; lalrpop_mod!( #[allow(clippy::just_underscores_and_digits, clippy::clone_on_copy)] - parser, + pub parser, "/syntax/parser.rs" ); mod pretty; -mod validate; +pub mod validate; pub use crate::syntax::ast::*; pub use crate::syntax::location::Location;