From 7328467e6474b50e1033dc2717fb60ab21428680 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 7 Aug 2024 11:38:08 -0400 Subject: [PATCH] Add analysis step to run function --- dust-lang/src/abstract_tree.rs | 7 +- dust-lang/src/analyzer.rs | 71 ++++---- dust-lang/src/lib.rs | 2 +- dust-lang/src/parse.rs | 294 ++++++++++++++++++--------------- dust-lang/src/type.rs | 2 +- dust-lang/src/vm.rs | 24 ++- 6 files changed, 224 insertions(+), 176 deletions(-) diff --git a/dust-lang/src/abstract_tree.rs b/dust-lang/src/abstract_tree.rs index 36a155b..f27709f 100644 --- a/dust-lang/src/abstract_tree.rs +++ b/dust-lang/src/abstract_tree.rs @@ -1,5 +1,5 @@ use std::{ - collections::HashMap, + collections::{HashMap, VecDeque}, fmt::{self, Display, Formatter}, }; @@ -7,6 +7,11 @@ use serde::{Deserialize, Serialize}; use crate::{Identifier, ReservedIdentifier, Span, Type, Value}; +#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct AbstractSyntaxTree { + pub nodes: VecDeque, +} + #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct Node { pub statement: Statement, diff --git a/dust-lang/src/analyzer.rs b/dust-lang/src/analyzer.rs index 4eca964..9662f9f 100644 --- a/dust-lang/src/analyzer.rs +++ b/dust-lang/src/analyzer.rs @@ -1,22 +1,22 @@ -use crate::{Node, Statement}; +use crate::{AbstractSyntaxTree, Node, Statement}; -pub fn analyze(abstract_tree: Vec) -> Result<(), AnalyzerError> { +pub fn analyze(abstract_tree: &AbstractSyntaxTree) -> Result<(), AnalyzerError> { let analyzer = Analyzer::new(abstract_tree); analyzer.analyze() } -pub struct Analyzer { - abstract_tree: Vec, +pub struct Analyzer<'a> { + abstract_tree: &'a AbstractSyntaxTree, } -impl Analyzer { - pub fn new(abstract_tree: Vec) -> Self { +impl<'a> Analyzer<'a> { + pub fn new(abstract_tree: &'a AbstractSyntaxTree) -> Self { Analyzer { abstract_tree } } pub fn analyze(&self) -> Result<(), AnalyzerError> { - for node in &self.abstract_tree { + for node in &self.abstract_tree.nodes { self.analyze_node(node)?; } @@ -90,15 +90,18 @@ mod tests { #[test] fn assignment_expect_identifier() { - let abstract_tree = vec![Node::new( - Statement::Assign( - Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - Box::new(Node::new(Statement::Constant(Value::integer(2)), (1, 2))), - ), - (0, 2), - )]; + let abstract_tree = AbstractSyntaxTree { + nodes: [Node::new( + Statement::Assign( + Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), + Box::new(Node::new(Statement::Constant(Value::integer(2)), (1, 2))), + ), + (0, 2), + )] + .into(), + }; - let analyzer = Analyzer::new(abstract_tree); + let analyzer = Analyzer::new(&abstract_tree); assert_eq!( analyzer.analyze(), @@ -110,12 +113,15 @@ mod tests { #[test] fn unexpected_identifier_simple() { - let abstract_tree = vec![Node::new( - Statement::Identifier(Identifier::new("x")), - (0, 1), - )]; + let abstract_tree = AbstractSyntaxTree { + nodes: [Node::new( + Statement::Identifier(Identifier::new("x")), + (0, 1), + )] + .into(), + }; - let analyzer = Analyzer::new(abstract_tree); + let analyzer = Analyzer::new(&abstract_tree); assert_eq!( analyzer.analyze(), @@ -127,18 +133,21 @@ mod tests { #[test] fn unexpected_identifier_nested() { - let abstract_tree = vec![Node::new( - Statement::Add( - Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - Box::new(Node::new( - Statement::Identifier(Identifier::new("x")), - (1, 2), - )), - ), - (0, 1), - )]; + let abstract_tree = AbstractSyntaxTree { + nodes: [Node::new( + Statement::Add( + Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), + Box::new(Node::new( + Statement::Identifier(Identifier::new("x")), + (1, 2), + )), + ), + (0, 1), + )] + .into(), + }; - let analyzer = Analyzer::new(abstract_tree); + let analyzer = Analyzer::new(&abstract_tree); assert_eq!( analyzer.analyze(), diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index f54bedd..97f61f7 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -15,7 +15,7 @@ pub mod r#type; pub mod value; pub mod vm; -pub use abstract_tree::{Node, Statement}; +pub use abstract_tree::{AbstractSyntaxTree, Node, Statement}; pub use analyzer::{analyze, Analyzer, AnalyzerError}; pub use identifier::Identifier; pub use lex::{lex, LexError, Lexer}; diff --git a/dust-lang/src/parse.rs b/dust-lang/src/parse.rs index a0840e8..bfe33a2 100644 --- a/dust-lang/src/parse.rs +++ b/dust-lang/src/parse.rs @@ -1,11 +1,8 @@ use std::collections::VecDeque; -use crate::{ - lex::{LexError, Lexer}, - Node, Span, Statement, Token, Value, -}; +use crate::{AbstractSyntaxTree, LexError, Lexer, Node, Span, Statement, Token, Value}; -pub fn parse(input: &str) -> Result, ParseError> { +pub fn parse(input: &str) -> Result { let lexer = Lexer::new(input); let mut parser = Parser::new(lexer); let mut nodes = VecDeque::new(); @@ -20,7 +17,7 @@ pub fn parse(input: &str) -> Result, ParseError> { } } - Ok(nodes) + Ok(AbstractSyntaxTree { nodes }) } pub struct Parser<'src> { @@ -227,7 +224,9 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new(Statement::Constant(Value::boolean(true)), (0, 4))].into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new(Statement::Constant(Value::boolean(true)), (0, 4))].into() + }) ); } @@ -237,21 +236,23 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new( - Statement::PropertyAccess( - Box::new(Node::new( - Statement::List(vec![ - Node::new(Statement::Constant(Value::integer(1)), (1, 2)), - Node::new(Statement::Constant(Value::integer(2)), (4, 5)), - Node::new(Statement::Constant(Value::integer(3)), (7, 8)), - ]), - (0, 9) - )), - Box::new(Node::new(Statement::Constant(Value::integer(0)), (10, 11))), - ), - (0, 11), - )] - .into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new( + Statement::PropertyAccess( + Box::new(Node::new( + Statement::List(vec![ + Node::new(Statement::Constant(Value::integer(1)), (1, 2)), + Node::new(Statement::Constant(Value::integer(2)), (4, 5)), + Node::new(Statement::Constant(Value::integer(3)), (7, 8)), + ]), + (0, 9) + )), + Box::new(Node::new(Statement::Constant(Value::integer(0)), (10, 11))), + ), + (0, 11), + )] + .into() + }) ); } @@ -261,20 +262,22 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new( - Statement::PropertyAccess( - Box::new(Node::new( - Statement::Identifier(Identifier::new("a")), - (0, 1) - )), - Box::new(Node::new( - Statement::Identifier(Identifier::new("b")), - (2, 3) - )), - ), - (0, 3), - )] - .into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new( + Statement::PropertyAccess( + Box::new(Node::new( + Statement::Identifier(Identifier::new("a")), + (0, 1) + )), + Box::new(Node::new( + Statement::Identifier(Identifier::new("b")), + (2, 3) + )), + ), + (0, 3), + )] + .into() + }) ); } @@ -284,39 +287,44 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new( - Statement::List(vec![ - Node::new(Statement::Constant(Value::integer(1)), (1, 2)), - Node::new( - Statement::Add( - Box::new(Node::new(Statement::Constant(Value::integer(1)), (4, 5))), - Box::new(Node::new(Statement::Constant(Value::integer(1)), (8, 9))), + Ok(AbstractSyntaxTree { + nodes: [Node::new( + Statement::List(vec![ + Node::new(Statement::Constant(Value::integer(1)), (1, 2)), + Node::new( + Statement::Add( + Box::new(Node::new(Statement::Constant(Value::integer(1)), (4, 5))), + Box::new(Node::new(Statement::Constant(Value::integer(1)), (8, 9))), + ), + (4, 9), ), - (4, 9), - ), - Node::new( - Statement::Add( - Box::new(Node::new(Statement::Constant(Value::integer(2)), (11, 12))), - Box::new(Node::new( - Statement::Multiply( - Box::new(Node::new( - Statement::Constant(Value::integer(4)), - (16, 17) - )), - Box::new(Node::new( - Statement::Constant(Value::integer(10)), - (20, 22) - )), - ), - (15, 23), - ),), + Node::new( + Statement::Add( + Box::new(Node::new( + Statement::Constant(Value::integer(2)), + (11, 12) + )), + Box::new(Node::new( + Statement::Multiply( + Box::new(Node::new( + Statement::Constant(Value::integer(4)), + (16, 17) + )), + Box::new(Node::new( + Statement::Constant(Value::integer(10)), + (20, 22) + )), + ), + (15, 23), + ),), + ), + (11, 23), ), - (11, 23), - ), - ]), - (0, 24), - )] - .into()) + ]), + (0, 24), + )] + .into() + }) ); } @@ -326,14 +334,16 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new( - Statement::List(vec![ - Node::new(Statement::Constant(Value::integer(1)), (1, 2)), - Node::new(Statement::Constant(Value::integer(2)), (4, 5)), - ]), - (0, 6), - )] - .into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new( + Statement::List(vec![ + Node::new(Statement::Constant(Value::integer(1)), (1, 2)), + Node::new(Statement::Constant(Value::integer(2)), (4, 5)), + ]), + (0, 6), + )] + .into() + }) ); } @@ -343,7 +353,9 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new(Statement::List(vec![]), (0, 2))].into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new(Statement::List(vec![]), (0, 2))].into() + }) ); } @@ -353,7 +365,9 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new(Statement::Constant(Value::float(42.0)), (0, 4))].into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new(Statement::Constant(Value::float(42.0)), (0, 4))].into() + }) ); } @@ -363,14 +377,16 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new( - Statement::Add( - Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5))), - ), - (0, 5), - )] - .into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new( + Statement::Add( + Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), + Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5))), + ), + (0, 5), + )] + .into() + }) ); } @@ -380,14 +396,16 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new( - Statement::Multiply( - Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5))), - ), - (0, 5), - )] - .into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new( + Statement::Multiply( + Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), + Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5))), + ), + (0, 5), + )] + .into() + }) ); } @@ -397,20 +415,22 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new( - Statement::Add( - Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - Box::new(Node::new( - Statement::Multiply( - Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5))), - Box::new(Node::new(Statement::Constant(Value::integer(3)), (8, 9))), - ), - (4, 9), - )), - ), - (0, 9), - )] - .into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new( + Statement::Add( + Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), + Box::new(Node::new( + Statement::Multiply( + Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5))), + Box::new(Node::new(Statement::Constant(Value::integer(3)), (8, 9))), + ), + (4, 9), + )), + ), + (0, 9), + )] + .into() + }) ); } @@ -420,35 +440,37 @@ mod tests { assert_eq!( parse(input), - Ok([Node::new( - Statement::Assign( - Box::new(Node::new( - Statement::Identifier(Identifier::new("a")), - (0, 1) - )), - Box::new(Node::new( - Statement::Add( - Box::new(Node::new(Statement::Constant(Value::integer(1)), (4, 5))), - Box::new(Node::new( - Statement::Multiply( - Box::new(Node::new( - Statement::Constant(Value::integer(2)), - (8, 9) - )), - Box::new(Node::new( - Statement::Constant(Value::integer(3)), - (12, 13) - )), - ), - (8, 13), - )), - ), - (4, 13), - )), - ), - (0, 13), - )] - .into()) + Ok(AbstractSyntaxTree { + nodes: [Node::new( + Statement::Assign( + Box::new(Node::new( + Statement::Identifier(Identifier::new("a")), + (0, 1) + )), + Box::new(Node::new( + Statement::Add( + Box::new(Node::new(Statement::Constant(Value::integer(1)), (4, 5))), + Box::new(Node::new( + Statement::Multiply( + Box::new(Node::new( + Statement::Constant(Value::integer(2)), + (8, 9) + )), + Box::new(Node::new( + Statement::Constant(Value::integer(3)), + (12, 13) + )), + ), + (8, 13), + )), + ), + (4, 13), + )), + ), + (0, 13), + )] + .into() + }) ); } } diff --git a/dust-lang/src/type.rs b/dust-lang/src/type.rs index c7acf40..bbc811c 100644 --- a/dust-lang/src/type.rs +++ b/dust-lang/src/type.rs @@ -18,7 +18,7 @@ use std::{ use serde::{Deserialize, Serialize}; -use crate::identifier::Identifier; +use crate::Identifier; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct TypeConflict { diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index d7d611c..eabd933 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -1,7 +1,8 @@ -use std::collections::{HashMap, VecDeque}; +use std::collections::HashMap; use crate::{ - parse, Identifier, Node, ParseError, ReservedIdentifier, Span, Statement, Value, ValueError, + parse, AbstractSyntaxTree, Analyzer, AnalyzerError, Identifier, Node, ParseError, + ReservedIdentifier, Span, Statement, Value, ValueError, }; pub fn run( @@ -9,18 +10,22 @@ pub fn run( variables: &mut HashMap, ) -> Result, VmError> { let abstract_syntax_tree = parse(input)?; + let analyzer = Analyzer::new(&abstract_syntax_tree); + + analyzer.analyze()?; + let mut vm = Vm::new(abstract_syntax_tree); vm.run(variables) } pub struct Vm { - statement_nodes: VecDeque, + abstract_tree: AbstractSyntaxTree, } impl Vm { - pub fn new(statement_nodes: VecDeque) -> Self { - Vm { statement_nodes } + pub fn new(abstract_tree: AbstractSyntaxTree) -> Self { + Self { abstract_tree } } pub fn run( @@ -29,7 +34,7 @@ impl Vm { ) -> Result, VmError> { let mut previous_value = None; - while let Some(node) = self.statement_nodes.pop_front() { + while let Some(node) = self.abstract_tree.nodes.pop_front() { previous_value = self.run_node(node, variables)?; } @@ -166,6 +171,7 @@ impl Vm { #[derive(Clone, Debug, PartialEq)] pub enum VmError { + AnaylyzerError(AnalyzerError), ParseError(ParseError), ValueError(ValueError), @@ -178,6 +184,12 @@ pub enum VmError { ExpectedValue { position: Span }, } +impl From for VmError { + fn from(error: AnalyzerError) -> Self { + Self::AnaylyzerError(error) + } +} + impl From for VmError { fn from(error: ParseError) -> Self { Self::ParseError(error)