Add some top-level documentation.

This commit is contained in:
2023-04-23 20:08:13 -07:00
parent 9e3cce5076
commit 9b72fb7827
3 changed files with 137 additions and 7 deletions

View File

@@ -9,6 +9,17 @@ use cranelift_module::ModuleError;
use pretty::termcolor::{ColorChoice, StandardStream};
use std::collections::HashMap;
/// A high-level REPL helper for NGR.
///
/// This object holds most of the state required to implement some
/// form of interactive compiler for NGR; all you need to do is provide
/// the actual user IO.
///
/// For most console-based used cases, the [`Default`] implementation
/// should be sufficient; it prints any warnings or errors to `stdout`,
/// using a default color scheme that should work based on the terminal
/// type. For more complex interactions, though, you may want to use
/// the `REPL::new` function to provide your own print substrate.
pub struct REPL {
file_database: SimpleFiles<String, String>,
jitter: Backend<JITModule>,
@@ -50,6 +61,12 @@ impl From<REPLError> for Diagnostic<usize> {
}
impl REPL {
/// Construct a new REPL helper, using the given stream implementation and console configuration.
///
/// For most users, the [`Default::default`] implementation will be sufficient;
/// it will use `stdout` and a default console configuration. But if you need to
/// be more specific, this will help you provide more guidance to the REPL as it
/// evaluates things.
pub fn new(console: StandardStream, console_config: Config) -> Result<Self, BackendError> {
Ok(REPL {
file_database: SimpleFiles::new(),
@@ -61,6 +78,10 @@ impl REPL {
})
}
/// Emit a diagnostic to the configured console.
///
/// This is just a convenience function; there's a lot of boilerplate in printing
/// diagnostics, and it was nice to pull it out into its own function.
fn emit_diagnostic(
&mut self,
diagnostic: Diagnostic<usize>,
@@ -73,6 +94,17 @@ impl REPL {
)
}
/// Process a line of input, printing any problems or the results.
///
/// The line number argument is just for a modicum of source information, to
/// provide to the user if some parsing or validation step fails. It can be
/// changed to be any value you like that provides some insight into what
/// failed, although it is probably a good idea for it to be different for
/// every invocation of this function. (Not critical, but a good idea.)
///
/// Any warnings or errors generated in processing this command will be
/// printed to the configured console. If there are no problems, the
/// command will be compiled and then executed.
pub fn process_input(&mut self, line_no: usize, command: String) {
if let Err(err) = self.process(line_no, command) {
if let Err(e) = self.emit_diagnostic(Diagnostic::from(err)) {
@@ -84,6 +116,12 @@ impl REPL {
}
}
/// The internal implementation, with a handy `Result` type.
///
/// All information from the documentation of `REPL::process_input` applies here,
/// as well; this is the internal implementation of that function, which is
/// differentiated by returning a `Result` type that is hidden from the user
/// in the case of `REPL::process_input`.
fn process(&mut self, line_no: usize, command: String) -> Result<(), REPLError> {
let entry = self.file_database.add("entry".to_string(), command);
let source = self