From fdf324c866d1080ff5353d48a97d87de9894e4d4 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 14 Aug 2024 15:52:04 -0400 Subject: [PATCH] Continue AST overhaul --- dust-lang/src/abstract_tree/expression.rs | 23 +- dust-lang/src/abstract_tree/mod.rs | 6 +- dust-lang/src/analyzer.rs | 273 +--- dust-lang/src/lib.rs | 5 +- dust-lang/src/parser.rs | 1539 ++++----------------- dust-lang/src/vm.rs | 653 +-------- 6 files changed, 328 insertions(+), 2171 deletions(-) diff --git a/dust-lang/src/abstract_tree/expression.rs b/dust-lang/src/abstract_tree/expression.rs index bd378db..6fc0ae8 100644 --- a/dust-lang/src/abstract_tree/expression.rs +++ b/dust-lang/src/abstract_tree/expression.rs @@ -16,7 +16,7 @@ pub enum Expression { } impl Expression { - pub fn call_expression(call_expression: CallExpression, position: Span) -> Self { + pub fn call(call_expression: CallExpression, position: Span) -> Self { Expression::WithoutBlock(Node::new( Box::new(ExpressionWithoutBlock::Call(call_expression)), position, @@ -30,7 +30,7 @@ impl Expression { )) } - pub fn operator_expression(operator_expression: OperatorExpression, position: Span) -> Self { + pub fn operator(operator_expression: OperatorExpression, position: Span) -> Self { Expression::WithoutBlock(Node::new( Box::new(ExpressionWithoutBlock::Operator(operator_expression)), position, @@ -58,14 +58,14 @@ impl Expression { )) } - pub fn struct_expression(struct_expression: StructExpression, position: Span) -> Self { + pub fn r#struct(struct_expression: StructExpression, position: Span) -> Self { Expression::WithoutBlock(Node::new( Box::new(ExpressionWithoutBlock::Struct(struct_expression)), position, )) } - pub fn identifier_expression(identifier: Identifier, position: Span) -> Self { + pub fn identifier(identifier: Identifier, position: Span) -> Self { Expression::WithoutBlock(Node::new( Box::new(ExpressionWithoutBlock::Identifier(identifier)), position, @@ -97,13 +97,6 @@ impl Expression { )) } - pub fn identifier(identifier: Identifier, position: Span) -> Self { - Expression::WithoutBlock(Node::new( - Box::new(ExpressionWithoutBlock::Identifier(identifier)), - position, - )) - } - pub fn position(&self) -> Span { match self { Expression::WithBlock(expression_node) => expression_node.position, @@ -248,7 +241,7 @@ impl Display for ListExpression { } } -#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum LiteralExpression { Boolean(bool), Float(f64), @@ -273,6 +266,12 @@ impl Display for LiteralExpression { impl Eq for LiteralExpression {} +impl PartialOrd for LiteralExpression { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + impl Ord for LiteralExpression { fn cmp(&self, other: &Self) -> Ordering { match (self, other) { diff --git a/dust-lang/src/abstract_tree/mod.rs b/dust-lang/src/abstract_tree/mod.rs index ab8311d..599aad0 100644 --- a/dust-lang/src/abstract_tree/mod.rs +++ b/dust-lang/src/abstract_tree/mod.rs @@ -10,7 +10,7 @@ use std::{ use serde::{Deserialize, Serialize}; -use crate::{BuiltInFunction, Context, Identifier, Span, Type, Value}; +use crate::{Identifier, Span, Type}; /// In-memory representation of a Dust program. #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] @@ -59,6 +59,10 @@ pub enum Statement { } impl Statement { + pub fn struct_definition(struct_definition: StructDefinition, position: Span) -> Self { + Statement::StructDefinition(Node::new(struct_definition, position)) + } + pub fn position(&self) -> Span { match self { Statement::Expression(expression) => expression.position(), diff --git a/dust-lang/src/analyzer.rs b/dust-lang/src/analyzer.rs index 2b1da5d..cd3f1af 100644 --- a/dust-lang/src/analyzer.rs +++ b/dust-lang/src/analyzer.rs @@ -10,9 +10,8 @@ use std::{ }; use crate::{ - abstract_tree::{BinaryOperator, UnaryOperator}, - parse, AbstractSyntaxTree, Context, DustError, Identifier, Node, Span, Statement, - StructDefinition, StructType, Type, + abstract_tree::{AbstractSyntaxTree, Node, Statement}, + parse, Context, DustError, Identifier, Span, Type, }; /// Analyzes the abstract syntax tree for errors. @@ -73,7 +72,7 @@ impl<'a> Analyzer<'a> { Ok(()) } - fn analyze_statement(&mut self, _: &Node) -> Result<(), AnalyzerError> { + fn analyze_statement(&mut self, _: &Statement) -> Result<(), AnalyzerError> { Ok(()) } } @@ -81,25 +80,25 @@ impl<'a> Analyzer<'a> { #[derive(Clone, Debug, PartialEq)] pub enum AnalyzerError { ExpectedBoolean { - actual: Node, + actual: Statement, }, ExpectedIdentifier { - actual: Node, + actual: Statement, }, ExpectedIdentifierOrString { - actual: Node, + actual: Statement, }, ExpectedIntegerOrRange { - actual: Node, + actual: Statement, }, ExpectedList { - actual: Node, + actual: Statement, }, ExpectedMap { - actual: Node, + actual: Statement, }, ExpectedValue { - actual: Node, + actual: Statement, }, ExpectedValueArgumentCount { expected: usize, @@ -107,56 +106,54 @@ pub enum AnalyzerError { position: Span, }, IndexOutOfBounds { - list: Node, - index: Node, + list: Statement, + index: Statement, index_value: usize, length: usize, }, TypeConflict { - actual_statement: Node, + actual_statement: Statement, actual_type: Type, expected: Type, }, UndefinedField { - identifier: Node, - statement: Node, + identifier: Statement, + statement: Statement, }, UndefinedType { identifier: Node, }, UnexpectedIdentifier { - identifier: Node, + identifier: Statement, }, UnexectedString { - actual: Node, + actual: Statement, }, UndefinedVariable { - identifier: Node, + identifier: Statement, }, } impl AnalyzerError { pub fn position(&self) -> Span { match self { - AnalyzerError::ExpectedBoolean { actual, .. } => actual.position, - AnalyzerError::ExpectedIdentifier { actual, .. } => actual.position, - AnalyzerError::ExpectedIdentifierOrString { actual } => actual.position, - AnalyzerError::ExpectedIntegerOrRange { actual, .. } => actual.position, - AnalyzerError::ExpectedList { actual } => actual.position, - AnalyzerError::ExpectedMap { actual } => actual.position, - AnalyzerError::ExpectedValue { actual } => actual.position, + AnalyzerError::ExpectedBoolean { actual } => actual.position(), + AnalyzerError::ExpectedIdentifier { actual } => actual.position(), + AnalyzerError::ExpectedIdentifierOrString { actual } => actual.position(), + AnalyzerError::ExpectedIntegerOrRange { actual } => actual.position(), + AnalyzerError::ExpectedList { actual } => actual.position(), + AnalyzerError::ExpectedMap { actual } => actual.position(), + AnalyzerError::ExpectedValue { actual } => actual.position(), AnalyzerError::ExpectedValueArgumentCount { position, .. } => *position, - AnalyzerError::IndexOutOfBounds { list, index, .. } => { - (list.position.0, index.position.1) - } + AnalyzerError::IndexOutOfBounds { index, .. } => index.position(), AnalyzerError::TypeConflict { actual_statement, .. - } => actual_statement.position, - AnalyzerError::UndefinedField { identifier, .. } => identifier.position, + } => actual_statement.position(), + AnalyzerError::UndefinedField { identifier, .. } => identifier.position(), AnalyzerError::UndefinedType { identifier } => identifier.position, - AnalyzerError::UndefinedVariable { identifier } => identifier.position, - AnalyzerError::UnexpectedIdentifier { identifier } => identifier.position, - AnalyzerError::UnexectedString { actual } => actual.position, + AnalyzerError::UndefinedVariable { identifier } => identifier.position(), + AnalyzerError::UnexpectedIdentifier { identifier } => identifier.position(), + AnalyzerError::UnexectedString { actual } => actual.position(), } } } @@ -231,7 +228,7 @@ impl Display for AnalyzerError { #[cfg(test)] mod tests { - use crate::{AssignmentOperator, Identifier, Value}; + use crate::{Identifier, Value}; use super::*; @@ -242,27 +239,7 @@ mod tests { a += 1.0 "; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::TypeConflict { - actual_statement: Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("a"), (31, 32)), - operator: Node::new(AssignmentOperator::AddAssign, (33, 35)), - value: Box::new(Node::new( - Statement::Constant(Value::float(1.0)), - (38, 41) - )) - }, - (31, 32) - ), - actual_type: Type::Integer, - expected: Type::Float - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] @@ -272,27 +249,7 @@ mod tests { a -= 1.0 "; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::TypeConflict { - actual_statement: Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("a"), (31, 32)), - operator: Node::new(AssignmentOperator::SubtractAssign, (33, 37)), - value: Box::new(Node::new( - Statement::Constant(Value::float(1.0)), - (40, 43) - )) - }, - (31, 32) - ), - actual_type: Type::Integer, - expected: Type::Float - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] @@ -302,221 +259,83 @@ mod tests { Foo(1, 2) "; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::TypeConflict { - actual_statement: Node::new(Statement::Constant(Value::integer(2)), (55, 56)), - actual_type: Type::Integer, - expected: Type::Float - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn constant_list_index_out_of_bounds() { let source = "[1, 2, 3][3]"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::IndexOutOfBounds { - list: 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) - ), - index: Node::new(Statement::Constant(Value::integer(3)), (10, 11)), - index_value: 3, - length: 3 - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn nonexistant_field_identifier() { let source = "{ x = 1 }.y"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::UndefinedField { - identifier: Node::new(Statement::Identifier(Identifier::new("y")), (10, 11)), - statement: Node::new( - Statement::Map(vec![( - Node::new(Identifier::new("x"), (2, 3)), - Node::new(Statement::Constant(Value::integer(1)), (6, 7)) - )]), - (0, 9) - ) - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn nonexistant_field_string() { let source = "{ x = 1 }.'y'"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::UndefinedField { - identifier: Node::new(Statement::Constant(Value::string("y")), (10, 13)), - statement: Node::new( - Statement::Map(vec![( - Node::new(Identifier::new("x"), (2, 3)), - Node::new(Statement::Constant(Value::integer(1)), (6, 7)) - )]), - (0, 9) - ) - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn malformed_list_index() { let source = "[1, 2, 3]['foo']"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::ExpectedIntegerOrRange { - actual: Node::new(Statement::Constant(Value::string("foo")), (10, 15)), - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn malformed_field_access() { let source = "{ x = 1 }.0"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::ExpectedIdentifierOrString { - actual: Node::new(Statement::Constant(Value::integer(0)), (10, 11)), - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn length_no_arguments() { let source = "length()"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::ExpectedValueArgumentCount { - expected: 1, - actual: 0, - position: (0, 6) - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn float_plus_integer() { let source = "42.0 + 2"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::TypeConflict { - actual_statement: Node::new(Statement::Constant(Value::integer(2)), (7, 8)), - actual_type: Type::Integer, - expected: Type::Float, - }, - source - }) - ) + assert_eq!(analyze(source), todo!()); } #[test] fn integer_plus_boolean() { let source = "42 + true"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::TypeConflict { - actual_statement: Node::new(Statement::Constant(Value::boolean(true)), (5, 9)), - actual_type: Type::Boolean, - expected: Type::Integer, - }, - source - }) - ) + assert_eq!(analyze(source), todo!()); } #[test] fn is_even_expects_number() { let source = "is_even('hello')"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::TypeConflict { - actual_statement: Node::new( - Statement::Constant(Value::string("hello")), - (8, 15) - ), - actual_type: Type::String, - expected: Type::Number, - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn is_odd_expects_number() { let source = "is_odd('hello')"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::TypeConflict { - actual_statement: Node::new( - Statement::Constant(Value::string("hello")), - (7, 14) - ), - actual_type: Type::String, - expected: Type::Number, - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } #[test] fn undefined_variable() { let source = "foo"; - assert_eq!( - analyze(source), - Err(DustError::AnalyzerError { - analyzer_error: AnalyzerError::UndefinedVariable { - identifier: Node::new(Statement::Identifier(Identifier::new("foo")), (0, 3)), - }, - source - }) - ); + assert_eq!(analyze(source), todo!()); } } diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index 240b5b8..755a8f6 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -28,10 +28,7 @@ pub mod r#type; pub mod value; pub mod vm; -pub use abstract_tree::{ - AbstractSyntaxTree, AssignmentOperator, BinaryOperator, Node, Statement, StructDefinition, - UnaryOperator, -}; +pub use abstract_tree::{AbstractSyntaxTree, Expression, Node, Statement}; pub use analyzer::{analyze, Analyzer, AnalyzerError}; pub use built_in_function::{BuiltInFunction, BuiltInFunctionError}; pub use context::{Context, VariableData}; diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index f7971a9..2f67f24 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -7,14 +7,13 @@ use std::{ collections::VecDeque, error::Error, fmt::{self, Display, Formatter}, - marker::PhantomData, num::{ParseFloatError, ParseIntError}, str::ParseBoolError, }; use crate::{ - abstract_tree::*, AbstractSyntaxTree, BuiltInFunction, DustError, Identifier, LexError, Lexer, - Node, Span, Statement, StructDefinition, Token, TokenKind, TokenOwned, Type, Value, + abstract_tree::*, DustError, Identifier, LexError, Lexer, Span, Token, TokenKind, TokenOwned, + Type, }; /// Parses the input into an abstract syntax tree. @@ -51,12 +50,12 @@ use crate::{ /// ``` pub fn parse(source: &str) -> Result { let lexer = Lexer::new(); - let mut parser = Parser::::new(source, lexer); + let mut parser = Parser::new(source, lexer); let mut nodes = VecDeque::new(); loop { let node = parser - .parse() + .parse_statement() .map_err(|parse_error| DustError::ParseError { parse_error, source, @@ -77,11 +76,11 @@ pub fn parse_into<'src>( tree: &mut AbstractSyntaxTree, ) -> Result<(), DustError<'src>> { let lexer = Lexer::new(); - let mut parser = Parser::::new(source, lexer); + let mut parser = Parser::new(source, lexer); loop { let node = parser - .parse() + .parse_statement() .map_err(|parse_error| DustError::ParseError { parse_error, source, @@ -103,7 +102,7 @@ pub fn parse_into<'src>( /// ``` /// # use std::collections::VecDeque; /// # use dust_lang::*; -/// let input = "x = 42"; +/// let source = "x = 42"; /// let lexer = Lexer::new(); /// let mut parser = Parser::new(input, lexer); /// let mut nodes = VecDeque::new(); @@ -121,15 +120,14 @@ pub fn parse_into<'src>( /// let tree = AbstractSyntaxTree { nodes }; /// /// ``` -pub struct Parser<'src, T> { +pub struct Parser<'src> { source: &'src str, lexer: Lexer, current_token: Token<'src>, current_position: Span, - product: PhantomData, } -impl<'src, T> Parser<'src, T> { +impl<'src> Parser<'src> { pub fn new(source: &'src str, lexer: Lexer) -> Self { let mut lexer = lexer; let (current_token, current_position) = @@ -140,12 +138,106 @@ impl<'src, T> Parser<'src, T> { lexer, current_token, current_position, - product: PhantomData, } } - pub fn parse(&mut self) -> Result { - self.parse_next(0) + pub fn parse_statement(&mut self) -> Result { + let start_position = self.current_position; + + if let Token::Struct = self.current_token { + self.next_token()?; + + let (name, name_end) = if let Token::Identifier(_) = self.current_token { + let end = self.current_position.1; + + (self.parse_identifier()?, end) + } else { + return Err(ParseError::ExpectedToken { + expected: TokenKind::Identifier, + actual: self.current_token.to_owned(), + position: self.current_position, + }); + }; + + if let Token::LeftParenthesis = self.current_token { + self.next_token()?; + + let mut types = Vec::new(); + + loop { + if let Token::RightParenthesis = self.current_token { + let position = (start_position.0, self.current_position.1); + + self.next_token()?; + + return Ok(Statement::struct_definition( + StructDefinition::Tuple { name, items: types }, + position, + )); + } + + if let Token::Comma = self.current_token { + self.next_token()?; + + continue; + } + + let type_node = self.parse_type()?; + + types.push(type_node); + } + } + + if let Token::LeftCurlyBrace = self.current_token { + self.next_token()?; + + let mut fields = Vec::new(); + + loop { + if let Token::RightCurlyBrace = self.current_token { + let position = (start_position.0, self.current_position.1); + + self.next_token()?; + + return Ok(Statement::struct_definition( + StructDefinition::Fields { name, fields }, + position, + )); + } + + if let Token::Comma = self.current_token { + self.next_token()?; + + continue; + } + + let field_name = self.parse_identifier()?; + + if let Token::Colon = self.current_token { + self.next_token()?; + } else { + return Err(ParseError::ExpectedToken { + expected: TokenKind::Colon, + actual: self.current_token.to_owned(), + position: self.current_position, + }); + } + + let field_type = self.parse_type()?; + + fields.push((field_name, field_type)); + } + } + + return Ok(Statement::struct_definition( + StructDefinition::Unit { name }, + (start_position.0, name_end), + )); + } + + let expression = self.parse_expression(0)?; + + Ok(Statement::Expression(expression)) } fn next_token(&mut self) -> Result<(), ParseError> { @@ -157,7 +249,7 @@ impl<'src, T> Parser<'src, T> { Ok(()) } - fn parse_next(&mut self, mut precedence: u8) -> Result { + fn parse_expression(&mut self, mut precedence: u8) -> Result { // Parse a statement starting from the current node. let mut left = if self.current_token.is_prefix() { self.parse_prefix()? @@ -184,7 +276,7 @@ impl<'src, T> Parser<'src, T> { Ok(left) } - fn parse_prefix(&mut self) -> Result { + fn parse_prefix(&mut self) -> Result { log::trace!("Parsing {} as prefix operator", self.current_token); let operator_start = self.current_position.0; @@ -196,10 +288,10 @@ impl<'src, T> Parser<'src, T> { let operand = self.parse_expression(0)?; let position = (operator_start, self.current_position.1); - Ok(Statement::Expression(Expression::operator_expression( + Ok(Expression::operator( OperatorExpression::Not(operand), position, - ))) + )) } Token::Minus => { self.next_token()?; @@ -207,10 +299,10 @@ impl<'src, T> Parser<'src, T> { let operand = self.parse_expression(0)?; let position = (operator_start, self.current_position.1); - Ok(Statement::Expression(Expression::operator_expression( + Ok(Expression::operator( OperatorExpression::Negation(operand), position, - ))) + )) } _ => Err(ParseError::UnexpectedToken { actual: self.current_token.to_owned(), @@ -219,7 +311,7 @@ impl<'src, T> Parser<'src, T> { } } - fn parse_primary(&mut self) -> Result { + fn parse_primary(&mut self) -> Result { log::trace!("Parsing {} as primary", self.current_token); let start_position = self.current_position; @@ -229,7 +321,7 @@ impl<'src, T> Parser<'src, T> { let block = self.parse_block()?; let position = (start_position.0, self.current_position.1); - return Ok(Statement::block(block.inner, position)); + return Ok(Expression::block(block.inner, position)); } Token::Boolean(text) => { self.next_token()?; @@ -239,7 +331,7 @@ impl<'src, T> Parser<'src, T> { position: start_position, })?; let right_end = self.current_position.1; - let statement = Statement::literal( + let statement = Expression::literal( LiteralExpression::Boolean(boolean), (start_position.0, right_end), ); @@ -255,7 +347,7 @@ impl<'src, T> Parser<'src, T> { })?; let position = (start_position.0, self.current_position.1); - return Ok(Statement::literal( + return Ok(Expression::literal( LiteralExpression::Float(float), position, )); @@ -277,7 +369,7 @@ impl<'src, T> Parser<'src, T> { self.next_token()?; - return Ok(Statement::struct_expression( + return Ok(Expression::r#struct( StructExpression::Fields { name: Node::new(identifier, identifier_position), fields, @@ -308,10 +400,7 @@ impl<'src, T> Parser<'src, T> { } } - Ok(Statement::identifier_expression( - identifier, - identifier_position, - )) + Ok(Expression::identifier(identifier, identifier_position)) } Token::Integer(text) => { self.next_token()?; @@ -337,7 +426,7 @@ impl<'src, T> Parser<'src, T> { position: end_position, })?; - Ok(Statement::literal( + Ok(Expression::literal( LiteralExpression::Range(integer, range_end), (start_position.0, end_position.1), )) @@ -349,7 +438,7 @@ impl<'src, T> Parser<'src, T> { }) } } else { - Ok(Statement::literal( + Ok(Expression::literal( LiteralExpression::Integer(integer), start_position, )) @@ -369,7 +458,7 @@ impl<'src, T> Parser<'src, T> { }; let position = (start_position.0, self.current_position.1); - Ok(Statement::r#if( + Ok(Expression::r#if( If { condition, if_block, @@ -381,7 +470,7 @@ impl<'src, T> Parser<'src, T> { Token::String(text) => { self.next_token()?; - Ok(Statement::literal( + Ok(Expression::literal( LiteralExpression::String(text.to_string()), start_position, )) @@ -389,7 +478,7 @@ impl<'src, T> Parser<'src, T> { Token::LeftCurlyBrace => { let block_node = self.parse_block()?; - Ok(Statement::block(block_node.inner, block_node.position)) + Ok(Expression::block(block_node.inner, block_node.position)) } Token::LeftParenthesis => { self.next_token()?; @@ -401,7 +490,7 @@ impl<'src, T> Parser<'src, T> { self.next_token()?; - Ok(Statement::grouped(node, position)) + Ok(Expression::grouped(node, position)) } else { Err(ParseError::ExpectedToken { expected: TokenKind::RightParenthesis, @@ -425,7 +514,7 @@ impl<'src, T> Parser<'src, T> { self.next_token()?; - return Ok(Statement::list( + return Ok(Expression::list( ListExpression::AutoFill { length_operand: first_expression, repeat_operand, @@ -449,7 +538,7 @@ impl<'src, T> Parser<'src, T> { self.next_token()?; - return Ok(Statement::list( + return Ok(Expression::list( ListExpression::Ordered(expressions), position, )); @@ -466,96 +555,6 @@ impl<'src, T> Parser<'src, T> { expressions.push(expression); } } - Token::Struct => { - self.next_token()?; - - let (name, name_end) = if let Token::Identifier(_) = self.current_token { - let end = self.current_position.1; - - (self.parse_identifier()?, end) - } else { - return Err(ParseError::ExpectedToken { - expected: TokenKind::Identifier, - actual: self.current_token.to_owned(), - position: self.current_position, - }); - }; - - if let Token::LeftParenthesis = self.current_token { - self.next_token()?; - - let mut types = Vec::new(); - - loop { - if let Token::RightParenthesis = self.current_token { - let position = (start_position.0, self.current_position.1); - - self.next_token()?; - - return Ok(Statement::struct_definition( - StructDefinition::Tuple { name, items: types }, - position, - )); - } - - if let Token::Comma = self.current_token { - self.next_token()?; - - continue; - } - - let type_node = self.parse_type()?; - - types.push(type_node); - } - } - - if let Token::LeftCurlyBrace = self.current_token { - self.next_token()?; - - let mut fields = Vec::new(); - - loop { - if let Token::RightCurlyBrace = self.current_token { - let position = (start_position.0, self.current_position.1); - - self.next_token()?; - - return Ok(Statement::struct_definition( - StructDefinition::Fields { name, fields }, - position, - )); - } - - if let Token::Comma = self.current_token { - self.next_token()?; - - continue; - } - - let field_name = self.parse_identifier()?; - - if let Token::Colon = self.current_token { - self.next_token()?; - } else { - return Err(ParseError::ExpectedToken { - expected: TokenKind::Colon, - actual: self.current_token.to_owned(), - position: self.current_position, - }); - } - - let field_type = self.parse_type()?; - - fields.push((field_name, field_type)); - } - } - - Ok(Statement::struct_definition( - StructDefinition::Unit { name }, - (start_position.0, name_end), - )) - } Token::While => { self.next_token()?; @@ -563,7 +562,7 @@ impl<'src, T> Parser<'src, T> { let block = self.parse_block()?; let position = (start_position.0, self.current_position.1); - Ok(Statement::r#loop( + Ok(Expression::r#loop( Loop::While { condition, block }, position, )) @@ -575,14 +574,9 @@ impl<'src, T> Parser<'src, T> { } } - fn parse_infix(&mut self, left: Statement) -> Result { + fn parse_infix(&mut self, left: Expression) -> Result { log::trace!("Parsing {} as infix operator", self.current_token); - let left = if let Statement::Expression(expression) = left { - expression - } else { - return Err(ParseError::ExpectedExpression { actual: left }); - }; let operator_precedence = self.current_token.precedence() - if self.current_token.is_right_associative() { 1 @@ -597,7 +591,7 @@ impl<'src, T> Parser<'src, T> { let value = self.parse_expression(operator_precedence)?; let position = (left_start, value.position().1); - return Ok(Statement::operator_expression( + return Ok(Expression::operator( OperatorExpression::Assignment { assignee: left, value, @@ -619,7 +613,7 @@ impl<'src, T> Parser<'src, T> { let value = self.parse_expression(operator_precedence)?; let position = (left_start, value.position().1); - return Ok(Statement::operator_expression( + return Ok(Expression::operator( OperatorExpression::CompoundAssignment { assignee: left, operator, @@ -635,7 +629,7 @@ impl<'src, T> Parser<'src, T> { let field = self.parse_identifier()?; let position = (left_start, self.current_position.1); - return Ok(Statement::field_access( + return Ok(Expression::field_access( FieldAccess { container: left, field, @@ -663,7 +657,7 @@ impl<'src, T> Parser<'src, T> { let right = self.parse_expression(operator_precedence)?; let position = (left_start, right.position().1); - Ok(Statement::operator_expression( + Ok(Expression::operator( OperatorExpression::Math { left, operator: math_operator, @@ -673,15 +667,9 @@ impl<'src, T> Parser<'src, T> { )) } - fn parse_postfix(&mut self, left: Statement) -> Result { + fn parse_postfix(&mut self, left: Expression) -> Result { log::trace!("Parsing {} as postfix operator", self.current_token); - let left = if let Statement::Expression(expression) = left { - expression - } else { - return Err(ParseError::ExpectedExpression { actual: left }); - }; - let statement = match &self.current_token { Token::LeftParenthesis => { self.next_token()?; @@ -704,7 +692,7 @@ impl<'src, T> Parser<'src, T> { let position = (left.position().0, self.current_position.1); - Statement::call_expression( + Expression::call( CallExpression { function: left, arguments, @@ -735,14 +723,7 @@ impl<'src, T> Parser<'src, T> { let position = (left.position().0, operator_end); - Statement::list_index(ListIndex { list: left, index }, position) - } - Token::Semicolon => { - let position = (left.position().0, self.current_position.1); - - self.next_token()?; - - Statement::ExpressionNullified(Node::new(left, position)) + Expression::list_index(ListIndex { list: left, index }, position) } _ => { return Err(ParseError::UnexpectedToken { @@ -759,18 +740,6 @@ impl<'src, T> Parser<'src, T> { } } - fn parse_expression(&mut self, precedence: u8) -> Result { - log::trace!("Parsing expression"); - - let statement = self.parse_next(precedence)?; - - if let Statement::Expression(expression) = statement { - Ok(expression) - } else { - Err(ParseError::ExpectedExpression { actual: statement }) - } - } - fn parse_identifier(&mut self) -> Result, ParseError> { if let Token::Identifier(text) = self.current_token { self.next_token()?; @@ -820,7 +789,7 @@ impl<'src, T> Parser<'src, T> { }; } - let statement = self.parse_next(0)?; + let statement = self.parse_statement()?; statements.push(statement); } @@ -959,34 +928,45 @@ impl Display for ParseError { #[cfg(test)] mod tests { - use crate::{Identifier, StructDefinition, Type}; + use fmt::Write; + + use crate::{Identifier, Type}; use super::*; #[test] fn mutable_variable() { - let input = "mut x = false"; + let source = "mut x = false"; - assert_eq!(parse(input), todo!()); + assert_eq!(parse(source), todo!()); } #[test] fn async_block() { - let input = "async { x = 42; y = 4.0 }"; + let source = "async { x = 42; y = 4.0 }"; assert_eq!( - parse(input), + parse(source), Ok(AbstractSyntaxTree { - statements: [Statement::block( - Block::Async(vec![Statement::operator_expression( - OperatorExpression::Assignment { - assignee: Expression::WithoutBlock(()), - value: () - }, - position - )]), - position - )] + statements: [Statement::Expression(Expression::block( + Block::Async(vec![ + Statement::Expression(Expression::operator( + OperatorExpression::Assignment { + assignee: Expression::identifier(Identifier::new("x"), (0, 0)), + value: Expression::literal(LiteralExpression::Integer(42), (0, 0)), + }, + (0, 0) + )), + Statement::Expression(Expression::operator( + OperatorExpression::Assignment { + assignee: Expression::identifier(Identifier::new("y"), (0, 0)), + value: Expression::literal(LiteralExpression::Float(4.0), (0, 0)), + }, + (0, 0) + )) + ]), + (0, 0) + ),)] .into() }) ); @@ -994,1343 +974,342 @@ mod tests { #[test] fn tuple_struct_access() { - let input = "(Foo(42, 'bar')).0"; - let mut tree = AbstractSyntaxTree::new(); + let source = "(Foo(42, 'bar')).0"; - if parse_into(input, &mut tree).is_err() { - println!("{tree:?}") - } - - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Invokation { - invokee: Box::new(Node::new( - Statement::Identifier(Identifier::new("Foo")), - (1, 4) - )), - type_arguments: None, - value_arguments: Some(vec![ - Node::new(Statement::Constant(Value::integer(42)), (5, 7)), - Node::new(Statement::Constant(Value::string("bar")), (9, 14)) - ]), - }, - (0, 16) - )), - operator: Node::new(BinaryOperator::FieldAccess, (16, 17)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(0)), - (17, 18) - )) - }, - (0, 18) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn fields_struct_instantiation() { - let input = "Foo { a = 42, b = 4.0 }"; + let source = "Foo { a = 42, b = 4.0 }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::FieldsStructInstantiation { - name: Node::new(Identifier::new("Foo"), (0, 3)), - fields: vec![ - ( - Node::new(Identifier::new("a"), (6, 7)), - Node::new(Statement::Constant(Value::integer(42)), (10, 12)) - ), - ( - Node::new(Identifier::new("b"), (14, 15)), - Node::new(Statement::Constant(Value::float(4.0)), (18, 21)) - ) - ] - }, - (0, 23) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn fields_struct() { - let input = "struct Foo { a: int, b: float }"; + let source = "struct Foo { a: int, b: float }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::StructDefinition(StructDefinition::Fields { - name: Node::new(Identifier::new("Foo"), (7, 10)), - fields: vec![ - ( - Node::new(Identifier::new("a"), (13, 14)), - Node::new(Type::Integer, (16, 19)) - ), - ( - Node::new(Identifier::new("b"), (21, 22)), - Node::new(Type::Float, (24, 29)) - ) - ] - }), - (0, 31) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn tuple_struct_instantiation() { - let input = "struct Foo(int, float) Foo(1, 2.0)"; + let source = "struct Foo(int, float) Foo(1, 2.0)"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [ - Node::new( - Statement::StructDefinition(StructDefinition::Tuple { - name: Node::new(Identifier::new("Foo"), (7, 10)), - items: vec![ - Node::new(Type::Integer, (11, 14)), - Node::new(Type::Float, (16, 21)) - ] - }), - (0, 22) - ), - Node::new( - Statement::Invokation { - invokee: Box::new(Node::new( - Statement::Identifier(Identifier::new("Foo")), - (23, 26) - )), - type_arguments: None, - value_arguments: Some(vec![ - Node::new(Statement::Constant(Value::integer(1)), (27, 28)), - Node::new(Statement::Constant(Value::float(2.0)), (30, 33)) - ]) - }, - (23, 34) - ) - ] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn tuple_struct() { - let input = "struct Foo(int, float)"; + let source = "struct Foo(int, float)"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::StructDefinition(StructDefinition::Tuple { - name: Node::new(Identifier::new("Foo"), (7, 10)), - items: vec![ - Node::new(Type::Integer, (11, 14)), - Node::new(Type::Float, (16, 21)) - ] - }), - (0, 22) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn unit_struct() { - let input = "struct Foo"; + let source = "struct Foo"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::StructDefinition(StructDefinition::Unit { - name: Node::new(Identifier::new("Foo"), (7, 10)), - }), - (0, 10) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn list_index_nested() { - let input = "[1, [2], 3][1][0]"; + let source = "[1, [2], 3][1][0]"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::List(vec![ - Node::new(Statement::Constant(Value::integer(1)), (1, 2)), - Node::new( - Statement::List(vec![Node::new( - Statement::Constant(Value::integer(2)), - (5, 6) - )]), - (4, 7) - ), - Node::new(Statement::Constant(Value::integer(3)), (9, 10)) - ]), - (0, 11) - )), - operator: Node::new(BinaryOperator::ListIndex, (11, 14)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (12, 13) - )) - }, - (0, 15) - )), - operator: Node::new(BinaryOperator::ListIndex, (14, 17)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(0)), - (15, 16) - )) - }, - (0, 17) - ),] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn map_property_nested() { - let input = "{ x = { y = 42 } }.x.y"; - - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Map(vec![( - Node::new(Identifier::new("x"), (2, 3)), - Node::new( - Statement::Map(vec![( - Node::new(Identifier::new("y"), (8, 9)), - Node::new( - Statement::Constant(Value::integer(42)), - (12, 14) - ) - )]), - (6, 16) - ) - )]), - (0, 18) - )), - operator: Node::new(BinaryOperator::FieldAccess, (18, 19)), - right: Box::new(Node::new( - Statement::Identifier(Identifier::new("x")), - (19, 20) - )) - }, - (0, 20) - )), - operator: Node::new(BinaryOperator::FieldAccess, (20, 21)), - right: Box::new(Node::new( - Statement::Identifier(Identifier::new("y")), - (21, 22) - )) - }, - (0, 22) - )] - .into() - }) - ) + let source = "{ x = { y = 42 } }.x.y"; } #[test] fn range() { - let input = "0..42"; + let source = "0..42"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new(Statement::Constant(Value::range(0..42)), (0, 5))].into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn negate_variable() { - let input = "a = 1; -a"; + let source = "a = 1; -a"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [ - Node::new( - Statement::Nil(Box::new(Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("a"), (0, 1)), - operator: Node::new(AssignmentOperator::Assign, (2, 3)), - value: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (4, 5) - )), - }, - (0, 5) - ))), - (0, 6) - ), - Node::new( - Statement::UnaryOperation { - operator: Node::new(UnaryOperator::Negate, (7, 8)), - operand: Box::new(Node::new( - Statement::Identifier(Identifier::new("a")), - (8, 9) - )), - }, - (7, 9) - ) - ] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn negate_expression() { - let input = "-(1 + 1)"; + let source = "-(1 + 1)"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::UnaryOperation { - operator: Node::new(UnaryOperator::Negate, (0, 1)), - operand: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (2, 3) - )), - operator: Node::new(BinaryOperator::Add, (4, 5)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (6, 7) - )), - }, - (1, 8) - )), - }, - (0, 8) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn not_expression() { - let input = "!(1 > 42)"; + let source = "!(1 > 42)"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::UnaryOperation { - operator: Node::new(UnaryOperator::Not, (0, 1)), - operand: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (2, 3) - )), - operator: Node::new(BinaryOperator::Greater, (4, 5)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(42)), - (6, 8) - )), - }, - (1, 9) - )), - }, - (0, 9) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn not_variable() { - let input = "a = false; !a"; + let source = "a = false; !a"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [ - Node::new( - Statement::Nil(Box::new(Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("a"), (0, 1)), - operator: Node::new(AssignmentOperator::Assign, (2, 3)), - value: Box::new(Node::new( - Statement::Constant(Value::boolean(false)), - (4, 9) - )), - }, - (0, 9) - ))), - (0, 10) - ), - Node::new( - Statement::UnaryOperation { - operator: Node::new(UnaryOperator::Not, (11, 12)), - operand: Box::new(Node::new( - Statement::Identifier(Identifier::new("a")), - (12, 13) - )), - }, - (11, 13) - ) - ] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn r#if() { - let input = "if x { y }"; + let source = "if x { y }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::If { - condition: Box::new(Node::new( - Statement::Identifier(Identifier::new("x")), - (3, 4) - )), - body: Box::new(Node::new( - Statement::Block(vec![Node::new( - Statement::Identifier(Identifier::new("y")), - (7, 8) - )]), - (5, 10) - )), - }, - (0, 10) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn if_else() { - let input = "if x { y } else { z }"; + let source = "if x { y } else { z }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::IfElse { - condition: Box::new(Node::new( - Statement::Identifier(Identifier::new("x")), - (3, 4) - )), - if_body: Box::new(Node::new( - Statement::Block(vec![Node::new( - Statement::Identifier(Identifier::new("y")), - (7, 8) - )]), - (5, 10) - )), - else_body: Box::new(Node::new( - Statement::Block(vec![Node::new( - Statement::Identifier(Identifier::new("z")), - (18, 19) - )]), - (16, 21) - )), - }, - (0, 21) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn if_else_if_else() { - let input = "if x { y } else if z { a } else { b }"; + let source = "if x { y } else if z { a } else { b }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::IfElseIfElse { - condition: Box::new(Node::new( - Statement::Identifier(Identifier::new("x")), - (3, 4) - )), - if_body: Box::new(Node::new( - Statement::Block(vec![Node::new( - Statement::Identifier(Identifier::new("y")), - (7, 8) - )]), - (5, 10) - )), - else_ifs: vec![( - Node::new(Statement::Identifier(Identifier::new("z")), (19, 20)), - Node::new( - Statement::Block(vec![Node::new( - Statement::Identifier(Identifier::new("a")), - (23, 24) - )]), - (21, 26) - ), - )], - else_body: Box::new(Node::new( - Statement::Block(vec![Node::new( - Statement::Identifier(Identifier::new("b")), - (34, 35) - )]), - (32, 37) - )), - }, - (0, 37) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn malformed_map() { - let input = "{ x = 1, y = 2, z = 3; }"; + let source = "{ x = 1, y = 2, z = 3; }"; - assert_eq!( - parse(input), - Err(DustError::ParseError { - source: input, - parse_error: ParseError::ExpectedAssignment { - actual: Node::new( - Statement::Nil(Box::new(Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("z"), (16, 17)), - operator: Node::new(AssignmentOperator::Assign, (18, 19)), - value: Box::new(Node::new( - Statement::Constant(Value::integer(3)), - (20, 21) - )), - }, - (16, 21) - ))), - (16, 22) - ), - } - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn while_loop() { - let input = "while x < 10 { x += 1 }"; + let source = "while x < 10 { x += 1 }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::While { - condition: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Identifier(Identifier::new("x")), - (6, 7) - )), - operator: Node::new(BinaryOperator::Less, (8, 9)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(10)), - (10, 12) - )), - }, - (6, 12) - )), - body: Box::new(Node::new( - Statement::Block(vec![Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("x"), (15, 16)), - operator: Node::new(AssignmentOperator::AddAssign, (17, 19)), - value: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (20, 21) - )), - }, - (15, 21) - )]), - (13, 23) - )), - }, - (0, 23) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn add_assign() { - let input = "a += 1"; + let source = "a += 1"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("a"), (0, 1)), - operator: Node::new(AssignmentOperator::AddAssign, (2, 4)), - value: Box::new(Node::new(Statement::Constant(Value::integer(1)), (5, 6))), - }, - (0, 6) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn or() { - let input = "true || false"; + let source = "true || false"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::boolean(true)), - (0, 4) - )), - operator: Node::new(BinaryOperator::Or, (5, 7)), - right: Box::new(Node::new( - Statement::Constant(Value::boolean(false)), - (8, 13) - )), - }, - (0, 13) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn misplaced_semicolon() { - let input = ";"; + let source = ";"; - assert_eq!( - parse(input), - Err(DustError::ParseError { - source: input, - parse_error: ParseError::UnexpectedToken { - actual: TokenOwned::Semicolon, - position: (0, 1) - } - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn block_with_one_statement() { - let input = "{ 40 + 2 }"; + let source = "{ 40 + 2 }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::Block(vec![Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(40)), - (2, 4) - )), - operator: Node::new(BinaryOperator::Add, (5, 6)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(2)), - (7, 8) - )), - }, - (2, 8) - )]), - (0, 10) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn block_with_assignment() { - let input = "{ foo = 42; bar = 42; baz = '42' }"; + let source = "{ foo = 42; bar = 42; baz = '42' }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::Block(vec![ - Node::new( - Statement::Nil(Box::new(Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("foo"), (2, 5)), - operator: Node::new(AssignmentOperator::Assign, (6, 7)), - value: Box::new(Node::new( - Statement::Constant(Value::integer(42)), - (8, 10) - )), - }, - (2, 10) - ),)), - (2, 11) - ), - Node::new( - Statement::Nil(Box::new(Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("bar"), (12, 15)), - operator: Node::new(AssignmentOperator::Assign, (16, 17)), - value: Box::new(Node::new( - Statement::Constant(Value::integer(42)), - (18, 20) - )), - }, - (12, 20) - ),)), - (12, 21) - ), - Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("baz"), (22, 25)), - operator: Node::new(AssignmentOperator::Assign, (26, 27)), - value: Box::new(Node::new( - Statement::Constant(Value::string("42")), - (28, 32) - )), - }, - (22, 32) - ) - ]), - (0, 34) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()) } #[test] fn empty_map() { - let input = "{}"; + let source = "{}"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new(Statement::Map(vec![]), (0, 2))].into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn map_with_trailing_comma() { - let input = "{ foo = 42, bar = 42, baz = '42', }"; + let source = "{ foo = 42, bar = 42, baz = '42', }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::Map(vec![ - ( - Node::new(Identifier::new("foo"), (2, 5)), - Node::new(Statement::Constant(Value::integer(42)), (8, 10)) - ), - ( - Node::new(Identifier::new("bar"), (12, 15)), - Node::new(Statement::Constant(Value::integer(42)), (18, 20)) - ), - ( - Node::new(Identifier::new("baz"), (22, 25)), - Node::new(Statement::Constant(Value::string("42")), (28, 32)) - ), - ]), - (0, 35) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn map_with_two_fields() { - let input = "{ x = 42, y = 'foobar' }"; + let source = "{ x = 42, y = 'foobar' }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::Map(vec![ - ( - Node::new(Identifier::new("x"), (2, 3)), - Node::new(Statement::Constant(Value::integer(42)), (6, 8)) - ), - ( - Node::new(Identifier::new("y"), (10, 11)), - Node::new(Statement::Constant(Value::string("foobar")), (14, 22)) - ) - ]), - (0, 24) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn map_with_one_field() { - let input = "{ x = 42 }"; + let source = "{ x = 42 }"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::Map(vec![( - Node::new(Identifier::new("x"), (2, 3)), - Node::new(Statement::Constant(Value::integer(42)), (6, 8)) - )]), - (0, 10) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn equal() { - let input = "42 == 42"; + let source = "42 == 42"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(42)), (0, 2))), - operator: Node::new(BinaryOperator::Equal, (3, 5)), - right: Box::new(Node::new(Statement::Constant(Value::integer(42)), (6, 8))) - }, - (0, 8) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn modulo() { - let input = "42 % 2"; + let source = "42 % 2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(42)), (0, 2))), - operator: Node::new(BinaryOperator::Modulo, (3, 4)), - right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (5, 6))) - }, - (0, 6) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn divide() { - let input = "42 / 2"; + let source = "42 / 2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(42)), (0, 2))), - operator: Node::new(BinaryOperator::Divide, (3, 4)), - right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (5, 6))) - }, - (0, 6) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn less_than() { - let input = "1 < 2"; + let source = "1 < 2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - operator: Node::new(BinaryOperator::Less, (2, 3)), - right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5))), - }, - (0, 5) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn less_than_or_equal() { - let input = "1 <= 2"; + let source = "1 <= 2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - operator: Node::new(BinaryOperator::LessOrEqual, (2, 4)), - right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (5, 6))), - }, - (0, 6) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn greater_than_or_equal() { - let input = "1 >= 2"; + let source = "1 >= 2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - operator: Node::new(BinaryOperator::GreaterOrEqual, (2, 4)), - right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (5, 6))), - }, - (0, 6) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn greater_than() { - let input = "1 > 2"; + let source = "1 > 2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - operator: Node::new(BinaryOperator::Greater, (2, 3)), - right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5))), - }, - (0, 5) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn subtract_negative_integers() { - let input = "-1 - -2"; + let source = "-1 - -2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Node::new(Statement::Constant(Value::integer(-1)), (0, 2)).into(), - operator: Node::new(BinaryOperator::Subtract, (3, 4)), - right: Node::new(Statement::Constant(Value::integer(-2)), (5, 7)).into() - }, - (0, 7) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn string_concatenation() { - let input = "\"Hello, \" + \"World!\""; + let source = "\"Hello, \" + \"World!\""; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::string("Hello, ")), - (0, 9) - )), - operator: Node::new(BinaryOperator::Add, (10, 11)), - right: Box::new(Node::new( - Statement::Constant(Value::string("World!")), - (12, 20) - )) - }, - (0, 20) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn string() { - let input = "\"Hello, World!\""; + let source = "\"Hello, World!\""; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::Constant(Value::string("Hello, World!")), - (0, 15) - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn boolean() { - let input = "true"; + let source = "true"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new(Statement::Constant(Value::boolean(true)), (0, 4))].into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn property_access_function_call() { - let input = "42.is_even()"; + let source = "42.is_even()"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BuiltInFunctionCall { - function: BuiltInFunction::IsEven, - type_arguments: None, - value_arguments: Some(vec![Node::new( - Statement::Constant(Value::integer(42)), - (0, 2) - )]) - }, - (0, 10), - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn list_index() { - let input = "[1, 2, 3][0]"; + let source = "[1, 2, 3][0]"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: 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) - )), - operator: Node::new(BinaryOperator::ListIndex, (9, 12)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(0)), - (10, 11) - )), - }, - (0, 12), - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn property_access() { - let input = "a.b"; + let source = "a.b"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Identifier(Identifier::new("a")), - (0, 1) - )), - operator: Node::new(BinaryOperator::FieldAccess, (1, 2)), - right: Box::new(Node::new( - Statement::Identifier(Identifier::new("b")), - (2, 3) - )), - }, - (0, 3), - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn complex_list() { - let input = "[1, 1 + 1, 2 + (4 * 10)]"; + let source = "[1, 1 + 1, 2 + (4 * 10)]"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::List(vec![ - Node::new(Statement::Constant(Value::integer(1)), (1, 2)), - Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (4, 5) - )), - operator: Node::new(BinaryOperator::Add, (6, 7)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (8, 9) - )) - }, - (4, 9) - ), - Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(2)), - (11, 12) - )), - operator: Node::new(BinaryOperator::Add, (13, 14)), - right: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(4)), - (16, 17) - )), - operator: Node::new(BinaryOperator::Multiply, (18, 19)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(10)), - (20, 22) - )) - }, - (15, 23) - )) - }, - (11, 23) - ), - ]), - (0, 24), - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn list() { - let input = "[1, 2]"; + let source = "[1, 2]"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [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() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn empty_list() { - let input = "[]"; + let source = "[]"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new(Statement::List(vec![]), (0, 2))].into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn float() { - let input = "42.0"; + let source = "42.0"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new(Statement::Constant(Value::float(42.0)), (0, 4))].into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn add() { - let input = "1 + 2"; + let source = "1 + 2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - operator: Node::new(BinaryOperator::Add, (2, 3)), - right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5)),) - }, - (0, 5), - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn multiply() { - let input = "1 * 2"; + let source = "1 * 2"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - operator: Node::new(BinaryOperator::Multiply, (2, 3)), - right: Box::new(Node::new(Statement::Constant(Value::integer(2)), (4, 5)),) - }, - (0, 5), - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn add_and_multiply() { - let input = "1 + 2 * 3"; + let source = "1 + 2 * 3"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new(Statement::Constant(Value::integer(1)), (0, 1))), - operator: Node::new(BinaryOperator::Add, (2, 3)), - right: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(2)), - (4, 5) - )), - operator: Node::new(BinaryOperator::Multiply, (6, 7)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(3)), - (8, 9) - ),) - }, - (4, 9) - ),) - }, - (0, 9), - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } #[test] fn assignment() { - let input = "a = 1 + 2 * 3"; + let source = "a = 1 + 2 * 3"; - assert_eq!( - parse(input), - Ok(AbstractSyntaxTree { - statements: [Node::new( - Statement::Assignment { - identifier: Node::new(Identifier::new("a"), (0, 1)), - operator: Node::new(AssignmentOperator::Assign, (2, 3)), - value: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(1)), - (4, 5) - )), - operator: Node::new(BinaryOperator::Add, (6, 7)), - right: Box::new(Node::new( - Statement::BinaryOperation { - left: Box::new(Node::new( - Statement::Constant(Value::integer(2)), - (8, 9) - )), - operator: Node::new(BinaryOperator::Multiply, (10, 11)), - right: Box::new(Node::new( - Statement::Constant(Value::integer(3)), - (12, 13) - ),) - }, - (8, 13) - ),) - }, - (4, 13) - ),) - }, - (0, 13), - )] - .into() - }) - ); + assert_eq!(parse(source), todo!()); } } diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 8b93e66..4750edf 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -9,12 +9,10 @@ use std::{ fmt::{self, Display, Formatter}, }; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; - use crate::{ - parse, AbstractSyntaxTree, Analyzer, AssignmentOperator, BinaryOperator, BuiltInFunctionError, - Context, DustError, Identifier, Node, ParseError, Span, Statement, Struct, StructType, Type, - UnaryOperator, Value, ValueError, + abstract_tree::{AbstractSyntaxTree, Node, Statement}, + parse, Analyzer, BuiltInFunctionError, Context, DustError, Identifier, ParseError, Span, + Struct, StructType, Type, Value, ValueError, }; /// Run the source code and return the result. @@ -89,7 +87,7 @@ impl Vm { let mut previous_value = None; while let Some(statement) = self.abstract_tree.statements.pop_front() { - let new_position = statement.position; + let new_position = statement.position(); previous_value = self.run_statement(statement)?; @@ -103,647 +101,8 @@ impl Vm { Ok(previous_value) } - fn run_statement(&self, node: Node) -> Result, VmError> { - match node.inner { - Statement::Assignment { - identifier, - operator, - value, - } => match operator.inner { - AssignmentOperator::Assign => { - let position = value.position; - let value = if let Some(value) = self.run_statement(*value)? { - value - } else { - return Err(VmError::ExpectedValue { position }); - }; - - if let Some(existing_value) = self.context.get_value(&identifier.inner) { - if existing_value.is_mutable() { - existing_value.mutate(&value); - } else { - return Err(VmError::CannotMutate { - value: existing_value, - position: identifier.position, - }); - } - } else { - self.context.set_value(identifier.inner, value); - } - - Ok(None) - } - AssignmentOperator::AddAssign => { - let left_value = if let Some(value) = self.context.get_value(&identifier.inner) - { - value - } else { - return Err(VmError::UndefinedVariable { identifier }); - }; - let value_position = value.position; - let right_value = if let Some(value) = self.run_statement(*value)? { - value - } else { - return Err(VmError::ExpectedValue { - position: value_position, - }); - }; - - if left_value.is_mutable() { - left_value.add_mut(&right_value).map_err(|value_error| { - VmError::ValueError { - error: value_error, - position: (identifier.position.0, value_position.1), - } - })?; - } else { - return Err(VmError::CannotMutate { - value: left_value, - position: identifier.position, - }); - } - - Ok(None) - } - AssignmentOperator::SubtractAssign => { - let left_value = if let Some(value) = self.context.get_value(&identifier.inner) - { - value - } else { - return Err(VmError::UndefinedVariable { identifier }); - }; - let value_position = value.position; - let right_value = if let Some(value) = self.run_statement(*value)? { - value - } else { - return Err(VmError::ExpectedValue { - position: value_position, - }); - }; - - if left_value.is_mutable() { - left_value - .subtract_mut(&right_value) - .map_err(|value_error| VmError::ValueError { - error: value_error, - position: (identifier.position.0, value_position.1), - })?; - } else { - return Err(VmError::CannotMutate { - value: left_value, - position: identifier.position, - }); - } - - Ok(None) - } - }, - Statement::AsyncBlock(statements) => { - let error_option = statements - .into_par_iter() - .find_map_any(|statement| self.run_statement(statement).err()); - - if let Some(error) = error_option { - return Err(error); - } - - Ok(None) - } - Statement::BinaryOperation { - left, - operator, - right, - } => { - let right_position = right.position; - - if let BinaryOperator::FieldAccess = operator.inner { - let left_span = left.position; - let left_value = if let Some(value) = self.run_statement(*left)? { - value - } else { - return Err(VmError::ExpectedValue { - position: left_span, - }); - }; - let right_span = right.position; - - if let Some(map) = left_value.as_map() { - if let Statement::Identifier(identifier) = right.inner { - let value = map.get(&identifier).cloned(); - - return Ok(value); - } - - if let Some(value) = self.run_statement(*right)? { - if let Some(string) = value.as_string() { - let identifier = Identifier::new(string); - - let value = map.get(&identifier).cloned(); - - return Ok(value); - } - } - - return Err(VmError::ExpectedIdentifierOrString { - position: right_span, - }); - } else { - return Err(VmError::ExpectedMap { - position: left_span, - }); - } - } - - if let BinaryOperator::ListIndex = operator.inner { - let list_position = left.position; - let list_value = if let Some(value) = self.run_statement(*left)? { - value - } else { - return Err(VmError::ExpectedValue { - position: list_position, - }); - }; - let list = if let Some(list) = list_value.as_list() { - list - } else { - return Err(VmError::ExpectedList { - position: list_position, - }); - }; - let index_position = right.position; - let index_value = if let Some(value) = self.run_statement(*right)? { - value - } else { - return Err(VmError::ExpectedValue { - position: index_position, - }); - }; - - if let Some(index) = index_value.as_integer() { - return if let Some(value) = list.get(index as usize) { - Ok(Some(value.clone())) - } else { - Ok(None) - }; - } - - if let Some(range) = index_value.as_range() { - let range = range.start as usize..range.end as usize; - - return if let Some(list) = list.get(range) { - Ok(Some(Value::list(list.to_vec()))) - } else { - Ok(None) - }; - } - - return Err(VmError::ExpectedIntegerOrRange { - position: index_position, - }); - } - - let left_position = left.position; - let left_value = if let Some(value) = self.run_statement(*left)? { - value - } else { - return Err(VmError::ExpectedValue { - position: left_position, - }); - }; - let right_value = if let Some(value) = self.run_statement(*right)? { - value - } else { - return Err(VmError::ExpectedValue { - position: right_position, - }); - }; - - match operator.inner { - BinaryOperator::Add => left_value.add(&right_value), - BinaryOperator::And => left_value.and(&right_value), - BinaryOperator::Divide => left_value.divide(&right_value), - BinaryOperator::Equal => Ok(Value::boolean(left_value == right_value)), - BinaryOperator::Greater => left_value.greater_than(&right_value), - BinaryOperator::GreaterOrEqual => { - left_value.greater_than_or_equal(&right_value) - } - BinaryOperator::Less => left_value.less_than(&right_value), - BinaryOperator::LessOrEqual => left_value.less_than_or_equal(&right_value), - BinaryOperator::Modulo => left_value.modulo(&right_value), - BinaryOperator::Multiply => left_value.multiply(&right_value), - BinaryOperator::Or => left_value.or(&right_value), - BinaryOperator::Subtract => left_value.subtract(&right_value), - _ => unreachable!(), - } - .map(Some) - .map_err(|value_error| VmError::ValueError { - error: value_error, - position: node.position, - }) - } - Statement::Block(statements) => { - let mut previous_value = None; - - for statement in statements { - previous_value = self.run_statement(statement)?; - } - - Ok(previous_value) - } - Statement::BuiltInFunctionCall { - function, - type_arguments: _, - value_arguments: value_nodes, - } => { - let values = if let Some(nodes) = value_nodes { - let mut values = Vec::new(); - - for node in nodes { - let position = node.position; - let value = if let Some(value) = self.run_statement(node)? { - value - } else { - return Err(VmError::ExpectedValue { position }); - }; - - values.push(value); - } - - Some(values) - } else { - None - }; - let function_call_return = - function - .call(None, values) - .map_err(|built_in_function_error| VmError::BuiltInFunctionError { - error: built_in_function_error, - position: node.position, - })?; - - Ok(function_call_return) - } - Statement::Constant(value) => Ok(Some(value)), - Statement::FieldsStructInstantiation { name, fields } => { - let mut values = Vec::new(); - - for (identifier, value_node) in fields { - let position = value_node.position; - let value = if let Some(value) = self.run_statement(value_node)? { - value - } else { - return Err(VmError::ExpectedValue { position }); - }; - - values.push((identifier.inner, value)); - } - - Ok(Some(Value::r#struct(Struct::Fields { - name: name.inner, - fields: values, - }))) - } - Statement::Invokation { - invokee, - type_arguments: _, - value_arguments: value_parameter_nodes, - } => { - let invokee_position = invokee.position; - let invokee_type = invokee.inner.expected_type(&self.context); - - if let Some(Type::Struct(StructType::Tuple { name, .. })) = invokee_type { - let mut fields = Vec::new(); - - if let Some(value_parameter_nodes) = value_parameter_nodes { - for statement in value_parameter_nodes { - let position = statement.position; - let value = if let Some(value) = self.run_statement(statement)? { - value - } else { - return Err(VmError::ExpectedValue { position }); - }; - - fields.push(value); - } - } - - let struct_value = Value::r#struct(Struct::Tuple { - name: name.clone(), - fields, - }); - - return Ok(Some(struct_value)); - } - - let function_value = if let Some(value) = self.run_statement(*invokee)? { - value - } else { - return Err(VmError::ExpectedValue { - position: invokee_position, - }); - }; - let function = if let Some(function) = function_value.as_function() { - function - } else { - return Err(VmError::ExpectedFunction { - actual: function_value, - position: invokee_position, - }); - }; - - let value_parameters = if let Some(value_nodes) = value_parameter_nodes { - let mut value_parameters = Vec::new(); - - for node in value_nodes { - let position = node.position; - let value = if let Some(value) = self.run_statement(node)? { - value - } else { - return Err(VmError::ExpectedValue { position }); - }; - - value_parameters.push(value); - } - - Some(value_parameters) - } else { - None - }; - - Ok(function - .clone() - .call(None, value_parameters, &self.context)?) - } - Statement::Identifier(identifier) => { - let value_option = self.context.get_value(&identifier); - - if let Some(value) = value_option { - return Ok(Some(value.clone())); - } - - let type_option = self.context.get_type(&identifier); - - println!("{type_option:?}"); - - if let Some(Type::Struct(StructType::Unit { name })) = type_option { - return Ok(Some(Value::r#struct(Struct::Unit { name }))); - } - - Err(VmError::UndefinedVariable { - identifier: Node::new(identifier, node.position), - }) - } - Statement::If { condition, body } => { - let condition_position = condition.position; - let condition_value = if let Some(value) = self.run_statement(*condition)? { - value - } else { - return Err(VmError::ExpectedValue { - position: condition_position, - }); - }; - let condition = if let Some(condition) = condition_value.as_boolean() { - condition - } else { - return Err(VmError::ExpectedBoolean { - position: condition_position, - }); - }; - - if condition { - self.run_statement(*body)?; - } - - Ok(None) - } - Statement::IfElse { - condition, - if_body, - else_body, - } => { - let condition_position = condition.position; - let condition_value = if let Some(value) = self.run_statement(*condition)? { - value - } else { - return Err(VmError::ExpectedValue { - position: condition_position, - }); - }; - - if let Some(condition) = condition_value.as_boolean() { - if condition { - self.run_statement(*if_body) - } else { - self.run_statement(*else_body) - } - } else { - Err(VmError::ExpectedBoolean { - position: condition_position, - }) - } - } - Statement::IfElseIf { - condition, - if_body, - else_ifs, - } => { - let condition_position = condition.position; - let condition_value = if let Some(value) = self.run_statement(*condition)? { - value - } else { - return Err(VmError::ExpectedValue { - position: condition_position, - }); - }; - - if let Some(condition) = condition_value.as_boolean() { - if condition { - self.run_statement(*if_body) - } else { - for (condition, body) in else_ifs { - let condition_position = condition.position; - let condition_value = - if let Some(value) = self.run_statement(condition)? { - value - } else { - return Err(VmError::ExpectedValue { - position: condition_position, - }); - }; - let condition = if let Some(condition) = condition_value.as_boolean() { - condition - } else { - return Err(VmError::ExpectedBoolean { - position: condition_position, - }); - }; - - if condition { - self.run_statement(body)?; - } - } - - Ok(None) - } - } else { - Err(VmError::ExpectedBoolean { - position: condition_position, - }) - } - } - Statement::IfElseIfElse { - condition, - if_body, - else_ifs, - else_body, - } => { - let condition_position = condition.position; - let condition_value = if let Some(value) = self.run_statement(*condition)? { - value - } else { - return Err(VmError::ExpectedValue { - position: condition_position, - }); - }; - - if let Some(condition) = condition_value.as_boolean() { - if condition { - self.run_statement(*if_body) - } else { - for (condition, body) in else_ifs { - let condition_position = condition.position; - let condition_value = - if let Some(value) = self.run_statement(condition)? { - value - } else { - return Err(VmError::ExpectedValue { - position: condition_position, - }); - }; - let condition = if let Some(condition) = condition_value.as_boolean() { - condition - } else { - return Err(VmError::ExpectedBoolean { - position: condition_position, - }); - }; - - if condition { - return self.run_statement(body); - } - } - - self.run_statement(*else_body) - } - } else { - Err(VmError::ExpectedBoolean { - position: condition_position, - }) - } - } - Statement::List(nodes) => { - let values = nodes - .into_iter() - .map(|node| { - let span = node.position; - if let Some(value) = self.run_statement(node)? { - Ok(value) - } else { - Err(VmError::ExpectedValue { position: span }) - } - }) - .collect::, VmError>>()?; - - Ok(Some(Value::list(values))) - } - Statement::Map(nodes) => { - let mut values = BTreeMap::new(); - - for (identifier, value_node) in nodes { - let position = value_node.position; - let value = if let Some(value) = self.run_statement(value_node)? { - value - } else { - return Err(VmError::ExpectedValue { position }); - }; - - values.insert(identifier.inner, value); - } - - Ok(Some(Value::map(values))) - } - Statement::AssignmentMut { identifier, value } => { - let position = value.position; - let value = if let Some(value) = self.run_statement(*value)? { - value.to_mut() - } else { - return Err(VmError::ExpectedValue { position }); - }; - - self.context.set_value(identifier.inner, value); - - Ok(None) - } - Statement::ConstantMut(value) => Ok(Some(value)), - Statement::Nil(node) => { - let _return = self.run_statement(*node)?; - - Ok(None) - } - Statement::StructDefinition(_) => Ok(None), - Statement::UnaryOperation { operator, operand } => { - let position = operand.position; - let value = if let Some(value) = self.run_statement(*operand)? { - value - } else { - return Err(VmError::ExpectedValue { position }); - }; - - match operator.inner { - UnaryOperator::Negate => { - if let Some(value) = value.as_integer() { - Ok(Some(Value::integer(-value))) - } else if let Some(value) = value.as_float() { - Ok(Some(Value::float(-value))) - } else { - Err(VmError::ExpectedNumber { position }) - } - } - UnaryOperator::Not => { - if let Some(value) = value.as_boolean() { - Ok(Some(Value::boolean(!value))) - } else { - Err(VmError::ExpectedBoolean { position }) - } - } - } - } - Statement::While { condition, body } => { - let mut return_value = None; - - let condition_position = condition.position; - - while let Some(condition_value) = self.run_statement(*condition.clone())? { - if let Some(condition) = condition_value.as_boolean() { - if !condition { - break; - } - } else { - return Err(VmError::ExpectedBoolean { - position: condition_position, - }); - } - - return_value = self.run_statement(*body.clone())?; - - if return_value.is_some() { - break; - } - } - - Ok(return_value) - } - } + fn run_statement(&self, node: Statement) -> Result, VmError> { + todo!() } }