diff --git a/dust-lang/src/abstract_tree.rs b/dust-lang/src/abstract_tree.rs index 14b9bfd..ef9b430 100644 --- a/dust-lang/src/abstract_tree.rs +++ b/dust-lang/src/abstract_tree.rs @@ -36,7 +36,7 @@ impl Display for Node { pub enum Statement { // Top-level statements Assignment { - identifier: Identifier, + identifier: Node, value_node: Box>, }, diff --git a/dust-lang/src/analyzer.rs b/dust-lang/src/analyzer.rs index 27ba33c..30a0d5b 100644 --- a/dust-lang/src/analyzer.rs +++ b/dust-lang/src/analyzer.rs @@ -80,7 +80,9 @@ impl<'a> Analyzer<'a> { Statement::Assignment { value_node: value, .. } => { - if let None = value.inner.expected_type(self.variables) { + self.analyze_node(value)?; + + if value.inner.expected_type(self.variables).is_none() { return Err(AnalyzerError::ExpectedValue { actual: value.as_ref().clone(), position: value.position, diff --git a/dust-lang/src/lex.rs b/dust-lang/src/lex.rs index 1c03adf..a9a4008 100644 --- a/dust-lang/src/lex.rs +++ b/dust-lang/src/lex.rs @@ -189,6 +189,16 @@ impl Lexer { (Token::Less, (self.position - 1, self.position)) } } + '{' => { + self.position += 1; + + (Token::LeftCurlyBrace, (self.position - 1, self.position)) + } + '}' => { + self.position += 1; + + (Token::RightCurlyBrace, (self.position - 1, self.position)) + } _ => { self.position += 1; @@ -415,6 +425,27 @@ impl From for LexError { mod tests { use super::*; + #[test] + fn map() { + let input = "{ x = 42, y = 'foobar' }"; + + assert_eq!( + lex(input), + Ok(vec![ + (Token::LeftCurlyBrace, (0, 1)), + (Token::Identifier("x"), (2, 3)), + (Token::Equal, (4, 5)), + (Token::Integer(42), (6, 8)), + (Token::Comma, (8, 9)), + (Token::Identifier("y"), (10, 11)), + (Token::Equal, (12, 13)), + (Token::String("foobar"), (14, 22)), + (Token::RightCurlyBrace, (23, 24)), + (Token::Eof, (24, 24)), + ]) + ) + } + #[test] fn greater_than() { let input = ">"; diff --git a/dust-lang/src/parse.rs b/dust-lang/src/parse.rs index 544143b..6d3d6da 100644 --- a/dust-lang/src/parse.rs +++ b/dust-lang/src/parse.rs @@ -27,16 +27,16 @@ use crate::{ /// Ok(AbstractSyntaxTree { /// nodes: [ /// Node { -/// inner: Statement::Assign( -/// Box::new(Node { -/// inner: Statement::Identifier("x".into()), +/// inner: Statement::Assignment { +/// identifier: Node { +/// inner: Identifier::new("x"), /// position: (0, 1), -/// }), -/// Box::new(Node { +/// }, +/// value_node: Box::new(Node { /// inner: Statement::Constant(Value::integer(42)), /// position: (4, 6), /// }) -/// ), +/// }, /// position: (0, 6), /// } /// ].into(), @@ -86,16 +86,16 @@ pub fn parse(input: &str) -> Result { /// nodes, /// Into::>>::into([ /// Node { -/// inner: Statement::Assign( -/// Box::new(Node { -/// inner: Statement::Identifier("x".into()), +/// inner: Statement::Assignment { +/// identifier: Node { +/// inner: Identifier::new("x"), /// position: (0, 1), -/// }), -/// Box::new(Node { +/// }, +/// value_node: Box::new(Node { /// inner: Statement::Constant(Value::integer(42)), /// position: (4, 6), -/// }) -/// ), +/// }), +/// }, /// position: (0, 6), /// } /// ]), @@ -182,7 +182,7 @@ impl<'src> Parser<'src> { return Ok(Node::new( Statement::Assignment { - identifier, + identifier: Node::new(identifier, left_node.position), value_node: Box::new(right_node), }, (left_start, right_end), @@ -964,7 +964,7 @@ mod tests { Ok(AbstractSyntaxTree { nodes: [Node::new( Statement::Assignment { - identifier: Identifier::new("a"), + identifier: Node::new(Identifier::new("a"), (0, 1)), value_node: Box::new(Node::new( Statement::BinaryOperation { left: Box::new(Node::new( diff --git a/dust-lang/src/token.rs b/dust-lang/src/token.rs index cd55aca..46fcfb2 100644 --- a/dust-lang/src/token.rs +++ b/dust-lang/src/token.rs @@ -31,12 +31,14 @@ pub enum Token<'src> { Equal, Greater, GreaterEqual, + LeftCurlyBrace, LeftParenthesis, LeftSquareBrace, Less, LessEqual, Minus, Plus, + RightCurlyBrace, RightParenthesis, RightSquareBrace, Star, @@ -59,6 +61,7 @@ impl<'src> Token<'src> { Token::Integer(integer) => TokenOwned::Integer(*integer), Token::IsEven => TokenOwned::IsEven, Token::IsOdd => TokenOwned::IsOdd, + Token::LeftCurlyBrace => TokenOwned::LeftCurlyBrace, Token::LeftParenthesis => TokenOwned::LeftParenthesis, Token::LeftSquareBrace => TokenOwned::LeftSquareBrace, Token::Length => TokenOwned::Length, @@ -67,6 +70,7 @@ impl<'src> Token<'src> { Token::Minus => TokenOwned::Minus, Token::Plus => TokenOwned::Plus, Token::ReadLine => TokenOwned::ReadLine, + Token::RightCurlyBrace => TokenOwned::RightCurlyBrace, Token::RightParenthesis => TokenOwned::RightParenthesis, Token::RightSquareBrace => TokenOwned::RightSquareBrace, Token::Star => TokenOwned::Star, @@ -91,6 +95,7 @@ impl<'src> Token<'src> { Token::Integer(_) => "integer", Token::IsEven => "is_even", Token::IsOdd => "is_odd", + Token::LeftCurlyBrace => "{", Token::LeftParenthesis => "(", Token::LeftSquareBrace => "[", Token::Length => "length", @@ -99,6 +104,7 @@ impl<'src> Token<'src> { Token::Minus => "-", Token::Plus => "+", Token::ReadLine => "read_line", + Token::RightCurlyBrace => "}", Token::RightParenthesis => ")", Token::RightSquareBrace => "]", Token::Star => "*", @@ -132,6 +138,7 @@ impl<'src> PartialEq for Token<'src> { (Token::Integer(left), Token::Integer(right)) => left == right, (Token::IsEven, Token::IsEven) => true, (Token::IsOdd, Token::IsOdd) => true, + (Token::LeftCurlyBrace, Token::LeftCurlyBrace) => true, (Token::LeftParenthesis, Token::LeftParenthesis) => true, (Token::LeftSquareBrace, Token::LeftSquareBrace) => true, (Token::Length, Token::Length) => true, @@ -140,6 +147,7 @@ impl<'src> PartialEq for Token<'src> { (Token::Minus, Token::Minus) => true, (Token::Plus, Token::Plus) => true, (Token::ReadLine, Token::ReadLine) => true, + (Token::RightCurlyBrace, Token::RightCurlyBrace) => true, (Token::RightParenthesis, Token::RightParenthesis) => true, (Token::RightSquareBrace, Token::RightSquareBrace) => true, (Token::Star, Token::Star) => true, @@ -180,12 +188,14 @@ pub enum TokenOwned { Equal, Greater, GreaterOrEqual, + LeftCurlyBrace, LeftParenthesis, LeftSquareBrace, Less, LessOrEqual, Minus, Plus, + RightCurlyBrace, RightParenthesis, RightSquareBrace, Star, @@ -208,6 +218,7 @@ impl Display for TokenOwned { TokenOwned::Integer(integer) => write!(f, "{integer}"), TokenOwned::IsEven => Token::IsEven.fmt(f), TokenOwned::IsOdd => Token::IsOdd.fmt(f), + TokenOwned::LeftCurlyBrace => Token::LeftCurlyBrace.fmt(f), TokenOwned::LeftParenthesis => Token::LeftParenthesis.fmt(f), TokenOwned::LeftSquareBrace => Token::LeftSquareBrace.fmt(f), TokenOwned::Length => Token::Length.fmt(f), @@ -216,6 +227,7 @@ impl Display for TokenOwned { TokenOwned::Minus => Token::Minus.fmt(f), TokenOwned::Plus => Token::Plus.fmt(f), TokenOwned::ReadLine => Token::ReadLine.fmt(f), + TokenOwned::RightCurlyBrace => Token::RightCurlyBrace.fmt(f), TokenOwned::RightParenthesis => Token::RightParenthesis.fmt(f), TokenOwned::RightSquareBrace => Token::RightSquareBrace.fmt(f), TokenOwned::Star => Token::Star.fmt(f), diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 11dc723..c5934f0 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -65,7 +65,7 @@ impl Vm { }); }; - variables.insert(identifier, value); + variables.insert(identifier.inner, value); Ok(None) }