1
0

Write docs

This commit is contained in:
Jeff 2024-02-15 04:16:34 -05:00
parent d9f065fbb6
commit 933ab3900b

View File

@ -2,7 +2,7 @@
//! //!
//! This module has three tools to run Dust code. //! This module has three tools to run Dust code.
//! //!
//! - [interpret] is the simples way to run Dust code inside of an application or library //! - [interpret] is the simplest way to run Dust code inside of an application or library
//! - [interpret_with_context] allows you to set variables on the execution context //! - [interpret_with_context] allows you to set variables on the execution context
//! - [Interpreter] is an advanced tool that can parse, verify, run and format Dust code //! - [Interpreter] is an advanced tool that can parse, verify, run and format Dust code
//! //!
@ -22,11 +22,11 @@
//! //!
//! ```rust //! ```rust
//! # use dust_lang::*; //! # use dust_lang::*;
//! let context = Map::new(); //! let context = Context::new();
//! //!
//! context.set("one".into(), 1.into()); //! context.set_value("one".into(), 1.into()).unwrap();
//! context.set("two".into(), 2.into()); //! context.set_value("two".into(), 2.into()).unwrap();
//! context.set("three".into(), 3.into()); //! context.set_value("three".into(), 3.into()).unwrap();
//! //!
//! let dust_code = "four = 4; one + two + three + four"; //! let dust_code = "four = 4; one + two + three + four";
//! //!
@ -66,16 +66,27 @@ pub fn interpret_with_context(source: &str, context: Context) -> Result<Value, E
/// A source code interpreter for the Dust language. /// A source code interpreter for the Dust language.
/// ///
/// The interpreter's most important functions are used to parse dust source code, verify it is safe /// The interpreter's most important functions are used to parse dust source
/// and run it and they are written in a way that forces them to be used safely. Each step in this /// code, verify it is safe and run it. They are written in a way that forces
/// process contains the prior steps, meaning that the same code is always used to create the syntax /// tree, abstract tree and final evaluation. This avoids a critical logic error. /// them to be used safely: each step in this process contains the prior
/// steps, meaning that the same code is always used to create the syntax tree,
/// abstract tree and final evaluation. This avoids a critical logic error.
///
/// ```
/// # use dust_lang::*;
/// let context = Context::new();
/// let mut interpreter = Interpreter::new(context);
/// let result = interpreter.run("2 + 2");
///
/// assert_eq!(result, Ok(Value::Integer(4)));
/// ```
pub struct Interpreter { pub struct Interpreter {
parser: Parser, parser: Parser,
context: Context, context: Context,
} }
impl Interpreter { impl Interpreter {
/// Creates a new interpreter with the given variable context. /// Create a new interpreter with the given context.
pub fn new(context: Context) -> Self { pub fn new(context: Context) -> Self {
let mut parser = Parser::new(); let mut parser = Parser::new();
@ -90,11 +101,12 @@ impl Interpreter {
Interpreter { parser, context } Interpreter { parser, context }
} }
/// Generates a syntax tree from the source. Returns an error if the the parser is cancelled for /// Generate a syntax tree from the source. Returns an error if the the
/// taking too long. The syntax tree may contain error nodes, which represent syntax errors. /// parser is cancelled for taking too long. The syntax tree may contain
/// error nodes, which represent syntax errors.
/// ///
/// Tree sitter is designed to be run on every keystroke, so this is generally a lightweight /// Tree sitter is designed to be run on every keystroke, so this is
/// function to call. /// generally a lightweight function to call.
pub fn parse(&mut self, source: &str) -> Result<SyntaxTree, Error> { pub fn parse(&mut self, source: &str) -> Result<SyntaxTree, Error> {
if let Some(tree) = self.parser.parse(source, None) { if let Some(tree) = self.parser.parse(source, None) {
Ok(tree) Ok(tree)
@ -103,7 +115,7 @@ impl Interpreter {
} }
} }
/// Checks the source for errors and generates an abstract tree. /// Check the source for errors and generate an abstract tree.
/// ///
/// The order in which this function works is: /// The order in which this function works is:
/// ///
@ -111,7 +123,7 @@ impl Interpreter {
/// - check the syntax tree for errors /// - check the syntax tree for errors
/// - generate an abstract tree from the source and syntax tree /// - generate an abstract tree from the source and syntax tree
/// - check the abstract tree for type errors /// - check the abstract tree for type errors
pub fn verify(&mut self, source: &str) -> Result<Root, Error> { pub fn validate(&mut self, source: &str) -> Result<Root, Error> {
fn check_for_error( fn check_for_error(
node: SyntaxNode, node: SyntaxNode,
source: &str, source: &str,
@ -144,31 +156,32 @@ impl Interpreter {
Ok(abstract_tree) Ok(abstract_tree)
} }
/// Runs the source, returning the final statement's value or first error. /// Run the source, returning the final statement's value or first error.
/// ///
/// This function [parses][Self::parse], [verifies][Self::verify] and [runs][Root::run] using /// This function [parses][Self::parse], [validates][Self::validate] and
/// the same source code. /// [runs][Root::run] using the same source code.
pub fn run(&mut self, source: &str) -> Result<Value, Error> { pub fn run(&mut self, source: &str) -> Result<Value, Error> {
self.verify(source)? self.validate(source)?
.run(source, &self.context) .run(source, &self.context)
.map_err(|error| Error::Runtime(error)) .map_err(|error| Error::Runtime(error))
} }
/// Return an s-expression displaying a syntax tree of the source, or the ParserCancelled error /// Return an s-expression displaying a syntax tree of the source, or the
/// if the parser takes too long. /// ParserCancelled error if the parser takes too long.
pub fn syntax_tree(&mut self, source: &str) -> Result<String, Error> { pub fn syntax_tree(&mut self, source: &str) -> Result<String, Error> {
Ok(self.parse(source)?.root_node().to_sexp()) Ok(self.parse(source)?.root_node().to_sexp())
} }
/// Return formatted Dust code generated from the current abstract tree, or None if no source /// Return formatted Dust code generated from the current abstract tree, or
/// code has been run successfully. /// None if no source code has been run successfully.
/// ///
/// You should call [verify][Interpreter::verify] before calling this function. You can only /// You should call [verify][Interpreter::verify] before calling this
/// create formatted source from a valid abstract tree. /// function. You can only create formatted source from a valid abstract
/// tree.
pub fn format(&mut self, source: &str) -> Result<String, Error> { pub fn format(&mut self, source: &str) -> Result<String, Error> {
let mut formatted_output = String::new(); let mut formatted_output = String::new();
self.verify(source)?.format(&mut formatted_output, 0); self.validate(source)?.format(&mut formatted_output, 0);
Ok(formatted_output) Ok(formatted_output)
} }