From 1fe26e0296b72407db0b97ff0dc756b6c003e884 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 7 Aug 2024 19:03:50 -0400 Subject: [PATCH] Remove generic position from nodes and replace with Spans --- README.md | 6 ++-- dust-lang/src/abstract_tree.rs | 44 +++++++++++------------ dust-lang/src/analyzer.rs | 30 ++++++++-------- dust-lang/src/parse.rs | 10 +++--- dust-lang/src/value.rs | 6 ++-- dust-lang/src/vm.rs | 64 ++++++++++++---------------------- 6 files changed, 70 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index d3b2464..c13dded 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ important than safety and ease of use. ### Effortless Concurrency Rust promises *fearless* concurrency, and Dust takes it a step further by making concurrency as -simple as possible. Dust is organized into **statements**, and any sequence of statements can be -run concurrently by simply adding the `async` keyword before the block of statements. +*effortless* as possible. Dust is organized into **statements**, and any sequence of statements can +be run concurrently by simply adding the `async` keyword before the block of statements. ```dust # This function will count from 0 to 9, sleeping for an increasing amount of @@ -28,7 +28,7 @@ count_slowly = fn ( sleep_time = i * multiplier; thread.sleep(sleep_time) - thread.write_line(i as str) + io.write_line(i as str) i += 1 } diff --git a/dust-lang/src/abstract_tree.rs b/dust-lang/src/abstract_tree.rs index b20bd06..2718320 100644 --- a/dust-lang/src/abstract_tree.rs +++ b/dust-lang/src/abstract_tree.rs @@ -5,21 +5,21 @@ use std::{ use serde::{Deserialize, Serialize}; -use crate::{Identifier, Type, Value}; +use crate::{Identifier, Span, Type, Value}; #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] -pub struct AbstractSyntaxTree

{ - pub nodes: VecDeque>, +pub struct AbstractSyntaxTree { + pub nodes: VecDeque, } #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] -pub struct Node

{ - pub statement: Statement

, - pub position: P, +pub struct Node { + pub statement: Statement, + pub position: Span, } -impl

Node

{ - pub fn new(operation: Statement

, position: P) -> Self { +impl Node { + pub fn new(operation: Statement, position: Span) -> Self { Self { statement: operation, position, @@ -27,39 +27,39 @@ impl

Node

{ } } -impl

Display for Node

{ +impl Display for Node { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}", self.statement) } } #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] -pub enum Statement

{ +pub enum Statement { // Top-level statements - Assign(Box>, Box>), + Assign(Box, Box), // Expressions - Add(Box>, Box>), + Add(Box, Box), BuiltInFunctionCall { function: BuiltInFunction, - type_arguments: Option>>, - value_arguments: Option>>, + type_arguments: Option>, + value_arguments: Option>, }, FunctionCall { - function: Box>, - type_arguments: Option>>, - value_arguments: Option>>, + function: Box, + type_arguments: Option>, + value_arguments: Option>, }, - PropertyAccess(Box>, Box>), - List(Vec>), - Multiply(Box>, Box>), + PropertyAccess(Box, Box), + List(Vec), + Multiply(Box, Box), // Hard-coded values Constant(Value), Identifier(Identifier), } -impl

Statement

{ +impl Statement { pub fn expected_type(&self, variables: &HashMap) -> Option { match self { Statement::Add(left, _) => left.statement.expected_type(variables), @@ -77,7 +77,7 @@ impl

Statement

{ } } -impl

Display for Statement

{ +impl Display for Statement { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Statement::Assign(left, right) => write!(f, "{left} = {right}"), diff --git a/dust-lang/src/analyzer.rs b/dust-lang/src/analyzer.rs index ec9485c..d42681c 100644 --- a/dust-lang/src/analyzer.rs +++ b/dust-lang/src/analyzer.rs @@ -7,7 +7,7 @@ /// - `Analyzer` struct use std::collections::HashMap; -use crate::{AbstractSyntaxTree, Identifier, Node, Statement, Type, Value}; +use crate::{AbstractSyntaxTree, Identifier, Node, Span, Statement, Type, Value}; /// Analyzes the abstract syntax tree for errors. /// @@ -22,10 +22,10 @@ use crate::{AbstractSyntaxTree, Identifier, Node, Statement, Type, Value}; /// /// assert!(result.is_err()); /// ``` -pub fn analyze( - abstract_tree: &AbstractSyntaxTree

, +pub fn analyze( + abstract_tree: &AbstractSyntaxTree, variables: &HashMap, -) -> Result<(), AnalyzerError

> { +) -> Result<(), AnalyzerError> { let analyzer = Analyzer::new(abstract_tree, variables); analyzer.analyze() @@ -44,14 +44,14 @@ pub fn analyze( /// let result = analyzer.analyze(); /// /// assert!(result.is_err()); -pub struct Analyzer<'a, P> { - abstract_tree: &'a AbstractSyntaxTree

, +pub struct Analyzer<'a> { + abstract_tree: &'a AbstractSyntaxTree, variables: &'a HashMap, } -impl<'a, P: Clone> Analyzer<'a, P> { +impl<'a> Analyzer<'a> { pub fn new( - abstract_tree: &'a AbstractSyntaxTree

, + abstract_tree: &'a AbstractSyntaxTree, variables: &'a HashMap, ) -> Self { Self { @@ -60,7 +60,7 @@ impl<'a, P: Clone> Analyzer<'a, P> { } } - pub fn analyze(&self) -> Result<(), AnalyzerError

> { + pub fn analyze(&self) -> Result<(), AnalyzerError> { for node in &self.abstract_tree.nodes { self.analyze_node(node)?; } @@ -68,7 +68,7 @@ impl<'a, P: Clone> Analyzer<'a, P> { Ok(()) } - fn analyze_node(&self, node: &Node

) -> Result<(), AnalyzerError

> { + fn analyze_node(&self, node: &Node) -> Result<(), AnalyzerError> { match &node.statement { Statement::Add(left, right) => { if let Some(Type::Integer) | Some(Type::Float) = @@ -166,11 +166,11 @@ impl<'a, P: Clone> Analyzer<'a, P> { } #[derive(Clone, Debug, PartialEq)] -pub enum AnalyzerError

{ - ExpectedFunction { position: P }, - ExpectedIdentifier { actual: Node

}, - ExpectedIntegerOrFloat { actual: Node

}, - UnexpectedIdentifier { identifier: Node

}, +pub enum AnalyzerError { + ExpectedFunction { position: Span }, + ExpectedIdentifier { actual: Node }, + ExpectedIntegerOrFloat { actual: Node }, + UnexpectedIdentifier { identifier: Node }, } #[cfg(test)] diff --git a/dust-lang/src/parse.rs b/dust-lang/src/parse.rs index 026f523..d3f36af 100644 --- a/dust-lang/src/parse.rs +++ b/dust-lang/src/parse.rs @@ -39,7 +39,7 @@ use crate::{ /// }), /// ); /// ``` -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(); @@ -80,7 +80,7 @@ pub fn parse(input: &str) -> Result, ParseError> { /// /// assert_eq!( /// nodes, -/// Into::>>::into([ +/// Into::>::into([ /// Node { /// statement: Statement::Assign( /// Box::new(Node { @@ -110,7 +110,7 @@ impl<'src> Parser<'src> { Parser { lexer, current } } - pub fn parse(&mut self) -> Result, ParseError> { + pub fn parse(&mut self) -> Result { self.parse_node(0) } @@ -124,7 +124,7 @@ impl<'src> Parser<'src> { Ok(()) } - fn parse_node(&mut self, precedence: u8) -> Result, ParseError> { + fn parse_node(&mut self, precedence: u8) -> Result { let left_node = self.parse_primary()?; let left_start = left_node.position.0; @@ -181,7 +181,7 @@ impl<'src> Parser<'src> { Ok(left_node) } - fn parse_primary(&mut self) -> Result, ParseError> { + fn parse_primary(&mut self) -> Result { match self.current.clone() { (Token::Boolean(boolean), span) => { self.next_token()?; diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index c0fdcde..fa1f609 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -12,7 +12,7 @@ use serde::{ Deserialize, Deserializer, Serialize, }; -use crate::{identifier::Identifier, AbstractSyntaxTree, Type, Vm, VmError}; +use crate::{identifier::Identifier, AbstractSyntaxTree, Span, Type, Vm, VmError}; #[derive(Clone, Debug, PartialEq)] pub struct Value(Arc); @@ -551,7 +551,7 @@ pub struct Function { pub name: Identifier, pub type_parameters: Option>, pub value_parameters: Option>, - pub body: AbstractSyntaxTree<()>, + pub body: AbstractSyntaxTree, } impl Function { @@ -560,7 +560,7 @@ impl Function { _type_arguments: Option>, value_arguments: Option>, variables: &HashMap, - ) -> Result, VmError<()>> { + ) -> Result, VmError> { let mut new_variables = variables.clone(); if let (Some(value_parameters), Some(value_arguments)) = diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 314b8fd..3a09233 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -8,7 +8,7 @@ use crate::{ pub fn run( input: &str, variables: &mut HashMap, -) -> Result, VmError> { +) -> Result, VmError> { let abstract_syntax_tree = parse(input)?; let analyzer = Analyzer::new(&abstract_syntax_tree, variables); @@ -19,19 +19,19 @@ pub fn run( vm.run(variables) } -pub struct Vm

{ - abstract_tree: AbstractSyntaxTree

, +pub struct Vm { + abstract_tree: AbstractSyntaxTree, } -impl Vm

{ - pub fn new(abstract_tree: AbstractSyntaxTree

) -> Self { +impl Vm { + pub fn new(abstract_tree: AbstractSyntaxTree) -> Self { Self { abstract_tree } } pub fn run( &mut self, variables: &mut HashMap, - ) -> Result, VmError

> { + ) -> Result, VmError> { let mut previous_value = None; while let Some(node) = self.abstract_tree.nodes.pop_front() { @@ -43,9 +43,9 @@ impl Vm

{ fn run_node( &self, - node: Node

, + node: Node, variables: &mut HashMap, - ) -> Result, VmError

> { + ) -> Result, VmError> { match node.statement { Statement::Add(left, right) => { let left_span = left.position; @@ -158,13 +158,7 @@ impl Vm

{ None }; - Ok(function - .clone() - .call(None, value_parameters, variables) - .map_err(|error| VmError::FunctionCallFailed { - error: Box::new(error), - position: function_position, - })?) + Ok(function.clone().call(None, value_parameters, variables)?) } Statement::Identifier(_) => Ok(None), Statement::List(nodes) => { @@ -178,7 +172,7 @@ impl Vm

{ Err(VmError::ExpectedValue { position: span }) } }) - .collect::, VmError

>>()?; + .collect::, VmError>>()?; Ok(Some(Value::list(values))) } @@ -244,54 +238,40 @@ impl Vm

{ } #[derive(Clone, Debug, PartialEq)] -pub enum VmError

{ - AnaylyzerError(AnalyzerError

), +pub enum VmError { + AnaylyzerError(AnalyzerError), ParseError(ParseError), ValueError(ValueError), // Anaylsis Failures // These should be prevented by running the analyzer before the VM BuiltInFunctionCallFailed(BuiltInFunctionError), - ExpectedIdentifier { - position: P, - }, - ExpectedIdentifierOrInteger { - position: P, - }, - ExpectedInteger { - position: P, - }, - ExpectedList { - position: P, - }, - ExpectedValue { - position: P, - }, - FunctionCallFailed { - error: Box>, - position: P, - }, + ExpectedIdentifier { position: Span }, + ExpectedIdentifierOrInteger { position: Span }, + ExpectedInteger { position: Span }, + ExpectedList { position: Span }, + ExpectedValue { position: Span }, } -impl

From for VmError

{ +impl From for VmError { fn from(v: BuiltInFunctionError) -> Self { Self::BuiltInFunctionCallFailed(v) } } -impl

From> for VmError

{ - fn from(error: AnalyzerError

) -> Self { +impl From for VmError { + fn from(error: AnalyzerError) -> Self { Self::AnaylyzerError(error) } } -impl

From for VmError

{ +impl From for VmError { fn from(error: ParseError) -> Self { Self::ParseError(error) } } -impl

From for VmError

{ +impl From for VmError { fn from(error: ValueError) -> Self { Self::ValueError(error) }