From 15b1808741276642302ea4c961431f3ee386d255 Mon Sep 17 00:00:00 2001 From: Jeff Date: Sat, 16 Mar 2024 15:01:45 -0400 Subject: [PATCH] Add spans to all statements --- src/abstract_tree/assignment.rs | 8 +- src/abstract_tree/block.rs | 13 +- src/abstract_tree/if_else.rs | 24 +- src/abstract_tree/logic.rs | 2 +- src/abstract_tree/loop.rs | 2 +- src/abstract_tree/statement.rs | 117 +++-- src/error.rs | 62 ++- src/lib.rs | 6 +- src/parser.rs | 769 ++++++++++++++++++++------------ tests/functions.rs | 2 +- tests/values.rs | 2 +- tests/variables.rs | 9 +- 12 files changed, 634 insertions(+), 382 deletions(-) diff --git a/src/abstract_tree/assignment.rs b/src/abstract_tree/assignment.rs index c691950..ae1b137 100644 --- a/src/abstract_tree/assignment.rs +++ b/src/abstract_tree/assignment.rs @@ -115,7 +115,7 @@ mod tests { Identifier::new("foobar"), None, AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::Integer(42))), + Statement::expression(Expression::Value(ValueNode::Integer(42)), (0..0).into()), ) .run(&context) .unwrap(); @@ -138,7 +138,7 @@ mod tests { Identifier::new("foobar"), None, AssignmentOperator::AddAssign, - Statement::Expression(Expression::Value(ValueNode::Integer(41))), + Statement::expression(Expression::Value(ValueNode::Integer(41)), (0..0).into()), ) .run(&context) .unwrap(); @@ -161,7 +161,7 @@ mod tests { Identifier::new("foobar"), None, AssignmentOperator::SubAssign, - Statement::Expression(Expression::Value(ValueNode::Integer(1))), + Statement::expression(Expression::Value(ValueNode::Integer(1)), (0..0).into()), ) .run(&context) .unwrap(); @@ -178,7 +178,7 @@ mod tests { Identifier::new("foobar"), Some(Type::Boolean), AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::Integer(42))), + Statement::expression(Expression::Value(ValueNode::Integer(42)), (0..0).into()), ) .validate(&Context::new()); diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index 57e62a8..21a3a24 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -61,9 +61,9 @@ mod tests { #[test] fn run_returns_value_of_final_statement() { let block = Block::new(vec![ - Statement::Expression(Expression::Value(ValueNode::Integer(1))), - Statement::Expression(Expression::Value(ValueNode::Integer(2))), - Statement::Expression(Expression::Value(ValueNode::Integer(42))), + Statement::expression(Expression::Value(ValueNode::Integer(1)), (0..0).into()), + Statement::expression(Expression::Value(ValueNode::Integer(2)), (0..0).into()), + Statement::expression(Expression::Value(ValueNode::Integer(42)), (0..0).into()), ]); assert_eq!( @@ -75,8 +75,11 @@ mod tests { #[test] fn expected_type_returns_type_of_final_statement() { let block = Block::new(vec![ - Statement::Expression(Expression::Value(ValueNode::String("42".to_string()))), - Statement::Expression(Expression::Value(ValueNode::Integer(42))), + Statement::expression( + Expression::Value(ValueNode::String("42".to_string())), + (0..0).into(), + ), + Statement::expression(Expression::Value(ValueNode::Integer(42)), (0..0).into()), ]); assert_eq!(block.expected_type(&Context::new()), Ok(Type::Integer)) diff --git a/src/abstract_tree/if_else.rs b/src/abstract_tree/if_else.rs index 89d0320..aee0d58 100644 --- a/src/abstract_tree/if_else.rs +++ b/src/abstract_tree/if_else.rs @@ -62,8 +62,7 @@ impl AbstractTree for IfElse { #[cfg(test)] mod tests { use crate::{ - abstract_tree::{Action, Statement, ValueNode}, - context::Context, + abstract_tree::{Statement, ValueNode}, Value, }; @@ -74,9 +73,10 @@ mod tests { assert_eq!( IfElse::new( Expression::Value(ValueNode::Boolean(true)), - Block::new(vec![Statement::Expression(Expression::Value( - ValueNode::String("foo".to_string()) - )),]), + Block::new(vec![Statement::expression( + Expression::Value(ValueNode::String("foo".to_string())), + (0..0).into() + )]), None ) .run(&Context::new()), @@ -89,12 +89,14 @@ mod tests { assert_eq!( IfElse::new( Expression::Value(ValueNode::Boolean(false)), - Block::new(vec![Statement::Expression(Expression::Value( - ValueNode::String("foo".to_string()) - )),]), - Some(Block::new(vec![Statement::Expression(Expression::Value( - ValueNode::String("bar".to_string()) - ))])) + Block::new(vec![Statement::expression( + Expression::Value(ValueNode::String("foo".to_string())), + (0..0).into() + ),]), + Some(Block::new(vec![Statement::expression( + Expression::Value(ValueNode::String("bar".to_string())), + (0..0).into() + )])) ) .run(&Context::new()), Ok(Action::Return(Value::string("bar".to_string()))) diff --git a/src/abstract_tree/logic.rs b/src/abstract_tree/logic.rs index c928fc8..2035b65 100644 --- a/src/abstract_tree/logic.rs +++ b/src/abstract_tree/logic.rs @@ -122,7 +122,7 @@ impl AbstractTree for Logic { #[cfg(test)] mod tests { - use crate::abstract_tree::{Expression, ValueNode}; + use crate::abstract_tree::ValueNode; use super::*; diff --git a/src/abstract_tree/loop.rs b/src/abstract_tree/loop.rs index f97e31f..e3d4879 100644 --- a/src/abstract_tree/loop.rs +++ b/src/abstract_tree/loop.rs @@ -58,7 +58,7 @@ mod tests { #[test] fn basic_loop() { let result = Loop { - statements: vec![Statement::Break], + statements: vec![Statement::r#break((0..1).into())], } .run(&Context::new()); diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index af8afd6..ec21a65 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -1,3 +1,5 @@ +use chumsky::span::{SimpleSpan, Span}; + use crate::{ context::Context, error::{RuntimeError, ValidationError}, @@ -6,7 +8,72 @@ use crate::{ use super::{AbstractTree, Action, Assignment, Block, Expression, IfElse, Loop, Type, While}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub enum Statement { +pub struct Statement { + pub inner: StatementInner, + pub span: (usize, usize), +} + +impl Statement { + pub fn assignment(assignment: Assignment, span: SimpleSpan) -> Self { + Statement { + inner: StatementInner::Assignment(assignment), + span: (span.start(), span.end()), + } + } + + pub fn block(block: Block, span: SimpleSpan) -> Self { + Statement { + inner: StatementInner::Block(block), + span: (span.start(), span.end()), + } + } + + pub fn r#break(span: SimpleSpan) -> Self { + Statement { + inner: StatementInner::Break, + span: (span.start(), span.end()), + } + } + + pub fn expression(expression: Expression, span: SimpleSpan) -> Self { + Statement { + inner: StatementInner::Expression(expression), + span: (span.start(), span.end()), + } + } + + pub fn if_else(if_else: IfElse, span: SimpleSpan) -> Self { + Statement { + inner: StatementInner::IfElse(if_else), + span: (span.start(), span.end()), + } + } + + pub fn r#loop(r#loop: Loop, span: SimpleSpan) -> Self { + Statement { + inner: StatementInner::Loop(r#loop), + span: (span.start(), span.end()), + } + } + + pub fn r#while(r#while: While, span: SimpleSpan) -> Self { + Statement { + inner: StatementInner::While(r#while), + span: (span.start(), span.end()), + } + } + + pub fn span(&self) -> (usize, usize) { + self.span + } + + pub fn inner(&self) -> &StatementInner { + &self.inner + } +} + +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub enum StatementInner { Assignment(Assignment), Block(Block), Break, @@ -18,38 +85,38 @@ pub enum Statement { impl AbstractTree for Statement { fn expected_type(&self, _context: &Context) -> Result { - match self { - Statement::Assignment(assignment) => assignment.expected_type(_context), - Statement::Block(block) => block.expected_type(_context), - Statement::Break => Ok(Type::None), - Statement::Expression(expression) => expression.expected_type(_context), - Statement::IfElse(if_else) => if_else.expected_type(_context), - Statement::Loop(r#loop) => r#loop.expected_type(_context), - Statement::While(r#while) => r#while.expected_type(_context), + match &self.inner { + StatementInner::Assignment(assignment) => assignment.expected_type(_context), + StatementInner::Block(block) => block.expected_type(_context), + StatementInner::Break => Ok(Type::None), + StatementInner::Expression(expression) => expression.expected_type(_context), + StatementInner::IfElse(if_else) => if_else.expected_type(_context), + StatementInner::Loop(r#loop) => r#loop.expected_type(_context), + StatementInner::While(r#while) => r#while.expected_type(_context), } } fn validate(&self, _context: &Context) -> Result<(), ValidationError> { - match self { - Statement::Assignment(assignment) => assignment.validate(_context), - Statement::Block(block) => block.validate(_context), - Statement::Break => Ok(()), - Statement::Expression(expression) => expression.validate(_context), - Statement::IfElse(if_else) => if_else.validate(_context), - Statement::Loop(r#loop) => r#loop.validate(_context), - Statement::While(r#while) => r#while.validate(_context), + match &self.inner { + StatementInner::Assignment(assignment) => assignment.validate(_context), + StatementInner::Block(block) => block.validate(_context), + StatementInner::Break => Ok(()), + StatementInner::Expression(expression) => expression.validate(_context), + StatementInner::IfElse(if_else) => if_else.validate(_context), + StatementInner::Loop(r#loop) => r#loop.validate(_context), + StatementInner::While(r#while) => r#while.validate(_context), } } fn run(self, _context: &Context) -> Result { - match self { - Statement::Assignment(assignment) => assignment.run(_context), - Statement::Block(block) => block.run(_context), - Statement::Break => Ok(Action::Break), - Statement::Expression(expression) => expression.run(_context), - Statement::IfElse(if_else) => if_else.run(_context), - Statement::Loop(r#loop) => r#loop.run(_context), - Statement::While(r#while) => r#while.run(_context), + match self.inner { + StatementInner::Assignment(assignment) => assignment.run(_context), + StatementInner::Block(block) => block.run(_context), + StatementInner::Break => Ok(Action::Break), + StatementInner::Expression(expression) => expression.run(_context), + StatementInner::IfElse(if_else) => if_else.run(_context), + StatementInner::Loop(r#loop) => r#loop.run(_context), + StatementInner::While(r#while) => r#while.run(_context), } } } diff --git a/src/error.rs b/src/error.rs index b017cf3..b0e3ba9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,7 @@ use std::sync::PoisonError; use ariadne::{Color, Label, Report, ReportKind}; -use chumsky::{prelude::Rich, span::SimpleSpan}; +use chumsky::{prelude::Rich, span::Span}; use crate::{ abstract_tree::{Identifier, Type}, @@ -12,76 +12,70 @@ use crate::{ pub enum Error { Parse { expected: String, - span: SimpleSpan, + span: (usize, usize), }, Lex { expected: String, - span: SimpleSpan, + span: (usize, usize), }, Runtime(RuntimeError), Validation { error: ValidationError, - span: SimpleSpan, + span: (usize, usize), }, } impl Error { pub fn report(&self) -> Report { match self { - Error::Parse { expected, span } => Report::build( - ReportKind::Custom("Parsing Error", Color::White), - (), - span.start, - ) - .with_label( - Label::new(span.start..span.end).with_message(format!("Expected {expected}.")), - ) - .finish(), - Error::Lex { expected, span } => { - let expected = match expected.as_str() { - "" => "something else", - expected => expected, + Error::Parse { expected, span } => { + let message = match expected.as_str() { + "" => "Invalid character.".to_string(), + expected => format!("Expected {expected}."), }; - Report::build( - ReportKind::Custom("Lexing Error", Color::White), - (), - span.start, - ) - .with_label( - Label::new(span.start..span.end).with_message(format!("Expected {expected}.")), - ) - .finish() + Report::build(ReportKind::Custom("Lexing Error", Color::White), (), span.0) + .with_label(Label::new(span.0..span.1).with_message(message)) + .finish() + } + Error::Lex { expected, span } => { + let message = match expected.as_str() { + "" => "Invalid character.".to_string(), + expected => format!("Expected {expected}."), + }; + + Report::build(ReportKind::Custom("Lexing Error", Color::White), (), span.0) + .with_label(Label::new(span.0..span.1).with_message(message)) + .finish() } Error::Runtime(_) => todo!(), Error::Validation { error, span } => { let mut report = Report::build( ReportKind::Custom("Validation Error", Color::White), (), - span.start, + span.0, ); match error { ValidationError::ExpectedBoolean => { report = report.with_label( - Label::new(span.start..span.end).with_message("Expected boolean."), + Label::new(span.0..span.1).with_message("Expected boolean."), ); } ValidationError::ExpectedIntegerOrFloat => { report = report.with_label( - Label::new(span.start..span.end) - .with_message("Expected integer or float."), + Label::new(span.0..span.1).with_message("Expected integer or float."), ); } ValidationError::RwLockPoison(_) => todo!(), ValidationError::TypeCheck(TypeCheckError { actual, expected }) => { - report = report.with_label(Label::new(span.start..span.end).with_message( + report = report.with_label(Label::new(span.0..span.1).with_message( format!("Type error. Expected {expected} but got {actual}."), )); } ValidationError::VariableNotFound(identifier) => { report = report - .with_label(Label::new(span.start..span.end).with_message(format!( + .with_label(Label::new(span.0..span.1).with_message(format!( "The variable {identifier} does not exist." ))); } @@ -102,7 +96,7 @@ impl From> for Error { fn from(error: Rich<'_, char>) -> Self { Error::Lex { expected: error.expected().map(|error| error.to_string()).collect(), - span: error.span().clone(), + span: (error.span().start(), error.span().end()), } } } @@ -111,7 +105,7 @@ impl<'src> From>> for Error { fn from(error: Rich<'_, Token<'src>>) -> Self { Error::Parse { expected: error.expected().map(|error| error.to_string()).collect(), - span: error.span().clone(), + span: (error.span().start(), error.span().end()), } } } diff --git a/src/lib.rs b/src/lib.rs index b67a81a..ecbedcd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,12 +33,12 @@ impl Interpreter { let statements = parse(&tokens)?; let errors = statements .iter() - .filter_map(|(statement, span)| { + .filter_map(|statement| { statement .validate(&self.context) .map_err(|validation_error| Error::Validation { error: validation_error, - span: span.clone(), + span: statement.span(), }) .err() }) @@ -50,7 +50,7 @@ impl Interpreter { let mut value = None; - for (statement, _span) in statements { + for statement in statements { value = match statement.run(&self.context) { Ok(action) => match action { Action::Break => None, diff --git a/src/parser.rs b/src/parser.rs index 869e4a7..14be7ee 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -12,7 +12,7 @@ pub type DustParser<'src> = Boxed< 'src, 'src, ParserInput<'src>, - Vec<(Statement, SimpleSpan)>, + Vec, extra::Err, SimpleSpan>>, >; @@ -21,7 +21,7 @@ pub type ParserInput<'src> = pub fn parse<'src>( tokens: &'src [(Token<'src>, SimpleSpan)], -) -> Result, Vec> { +) -> Result, Vec> { parser() .parse(tokens.spanned((tokens.len()..tokens.len()).into())) .into_result() @@ -292,10 +292,11 @@ pub fn parser<'src>() -> DustParser<'src> { let expression_statement = expression .clone() - .map(|expression| Statement::Expression(expression)) + .map_with(|expression, state| Statement::expression(expression, state.span())) .boxed(); - let r#break = just(Token::Keyword("break")).to(Statement::Break); + let r#break = + just(Token::Keyword("break")).map_with(|_, state| Statement::r#break(state.span())); let assignment = identifier .clone() @@ -306,12 +307,17 @@ pub fn parser<'src>() -> DustParser<'src> { just(Token::Operator(Operator::SubAssign)).to(AssignmentOperator::SubAssign), ))) .then(statement.clone()) - .map(|(((identifier, r#type), operator), statement)| { - Statement::Assignment(Assignment::new(identifier, r#type, operator, statement)) + .map_with(|(((identifier, r#type), operator), statement), state| { + Statement::assignment( + Assignment::new(identifier, r#type, operator, statement), + state.span(), + ) }) .boxed(); - let block_statement = block.clone().map(|block| Statement::Block(block)); + let block_statement = block + .clone() + .map_with(|block, state| Statement::block(block, state.span())); let r#loop = statement .clone() @@ -322,13 +328,15 @@ pub fn parser<'src>() -> DustParser<'src> { just(Token::Keyword("loop")).then(just(Token::Control(Control::CurlyOpen))), just(Token::Control(Control::CurlyClose)), ) - .map(|statements| Statement::Loop(Loop::new(statements))) + .map_with(|statements, state| Statement::r#loop(Loop::new(statements), state.span())) .boxed(); let r#while = just(Token::Keyword("while")) .ignore_then(expression.clone()) .then(block.clone()) - .map(|(expression, block)| Statement::While(While::new(expression, block))); + .map_with(|(expression, block), state| { + Statement::r#while(While::new(expression, block), state.span()) + }); let if_else = just(Token::Keyword("if")) .ignore_then(expression.clone()) @@ -338,8 +346,11 @@ pub fn parser<'src>() -> DustParser<'src> { .ignore_then(block.clone()) .or_not(), ) - .map(|((if_expression, if_block), else_block)| { - Statement::IfElse(IfElse::new(if_expression, if_block, else_block)) + .map_with(|((if_expression, if_block), else_block), state| { + Statement::if_else( + IfElse::new(if_expression, if_block, else_block), + state.span(), + ) }) .boxed(); @@ -356,216 +367,278 @@ pub fn parser<'src>() -> DustParser<'src> { .boxed() }); - statement - .map_with(|item, state| (item, state.span())) - .repeated() - .collect() - .boxed() + statement.repeated().collect().boxed() } #[cfg(test)] mod tests { - use crate::{abstract_tree::Logic, lexer::lex}; + use tests::statement::StatementInner; + + use crate::lexer::lex; use super::*; #[test] fn r#while() { assert_eq!( - parse(&lex("while true { output('hi') }").unwrap()).unwrap()[0].0, - Statement::While(While::new( - Expression::Value(ValueNode::Boolean(true)), - Block::new(vec![Statement::Expression(Expression::FunctionCall( - FunctionCall::new( - Expression::Identifier(Identifier::new("output")), - vec![Expression::Value(ValueNode::String("hi".to_string()))] - ) - ))]) - )) + parse(&lex("while true { output('hi') }").unwrap()).unwrap()[0], + Statement::r#while( + While::new( + Expression::Value(ValueNode::Boolean(true)), + Block::new(vec![Statement::expression( + Expression::FunctionCall(FunctionCall::new( + Expression::Identifier(Identifier::new("output")), + vec![Expression::Value(ValueNode::String("hi".to_string()))] + )), + (0..0).into() + )]) + ), + (0..0).into() + ) ) } #[test] fn types() { assert_eq!( - parse(&lex("foobar : bool = true").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - Some(Type::Boolean), - AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::Boolean(true))) - )) + parse(&lex("foobar : bool = true").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + Some(Type::Boolean), + AssignmentOperator::Assign, + Statement::expression( + Expression::Value(ValueNode::Boolean(true)), + (0..0).into() + ) + ), + (0..0).into() + ) ); assert_eq!( - parse(&lex("foobar : list(bool) = [true]").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - Some(Type::ListOf(Box::new(Type::Boolean))), - AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value( - ValueNode::Boolean(true) - )]))) - )) + parse(&lex("foobar : list(bool) = [true]").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + Some(Type::ListOf(Box::new(Type::Boolean))), + AssignmentOperator::Assign, + Statement::expression( + Expression::Value(ValueNode::List(vec![Expression::Value( + ValueNode::Boolean(true) + )])), + (0..0).into() + ) + ), + (0..0).into() + ) ); assert_eq!( - parse(&lex("foobar : [bool, str] = [true, '42']").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - Some(Type::ListExact(vec![Type::Boolean, Type::String])), - AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::List(vec![ - Expression::Value(ValueNode::Boolean(true)), - Expression::Value(ValueNode::String("42".to_string())) - ]))) - )) + parse(&lex("foobar : [bool, str] = [true, '42']").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + Some(Type::ListExact(vec![Type::Boolean, Type::String])), + AssignmentOperator::Assign, + Statement::expression( + Expression::Value(ValueNode::List(vec![ + Expression::Value(ValueNode::Boolean(true)), + Expression::Value(ValueNode::String("42".to_string())) + ])), + (0..0).into() + ) + ), + (0..0).into() + ) ); assert_eq!( - parse(&lex("foobar : () -> any = some_function").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - Some(Type::Function { - parameter_types: vec![], - return_type: Box::new(Type::Any) - }), - AssignmentOperator::Assign, - Statement::Expression(Expression::Identifier(Identifier::new("some_function"))) - )) + parse(&lex("foobar : () -> any = some_function").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + Some(Type::Function { + parameter_types: vec![], + return_type: Box::new(Type::Any) + }), + AssignmentOperator::Assign, + Statement::expression( + Expression::Identifier(Identifier::new("some_function")), + (0..0).into() + ) + ), + (0..0).into() + ) ); } #[test] fn function_call() { assert_eq!( - parse(&lex("output()").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::FunctionCall(FunctionCall::new( - Expression::Identifier(Identifier::new("output")), - Vec::with_capacity(0), - ))) + parse(&lex("output()").unwrap()).unwrap()[0], + Statement::expression( + Expression::FunctionCall(FunctionCall::new( + Expression::Identifier(Identifier::new("output")), + Vec::with_capacity(0), + )), + (0..0).into() + ) ) } #[test] fn range() { assert_eq!( - parse(&lex("1..10").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Range(1..10))) + parse(&lex("1..10").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Range(1..10)), (0..0).into()) ) } #[test] fn function() { assert_eq!( - parse(&lex("(x: int): int { x }").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Function { - parameters: vec![(Identifier::new("x"), Type::Integer)], - return_type: Type::Integer, - body: Block::new(vec![Statement::Expression(Expression::Identifier( - Identifier::new("x") - ))]) - })) + parse(&lex("(x: int): int { x }").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Function { + parameters: vec![(Identifier::new("x"), Type::Integer)], + return_type: Type::Integer, + body: Block::new(vec![Statement::expression( + Expression::Identifier(Identifier::new("x")), + (0..0).into() + )]) + }), + (0..0).into() + ) ) } #[test] fn r#if() { assert_eq!( - parse(&lex("if true { 'foo' }").unwrap()).unwrap()[0].0, - Statement::IfElse(IfElse::new( - Expression::Value(ValueNode::Boolean(true)), - Block::new(vec![Statement::Expression(Expression::Value( - ValueNode::String("foo".to_string()) - ))]), - None - )) + parse(&lex("if true { 'foo' }").unwrap()).unwrap()[0], + Statement::if_else( + IfElse::new( + Expression::Value(ValueNode::Boolean(true)), + Block::new(vec![Statement::expression( + Expression::Value(ValueNode::String("foo".to_string())), + (0..0).into() + )]), + None + ), + (0..0).into() + ) ); } #[test] fn if_else() { assert_eq!( - parse(&lex("if true {'foo' } else { 'bar' }").unwrap()).unwrap()[0].0, - Statement::IfElse(IfElse::new( - Expression::Value(ValueNode::Boolean(true)), - Block::new(vec![Statement::Expression(Expression::Value( - ValueNode::String("foo".to_string()) - ))]), - Some(Block::new(vec![Statement::Expression(Expression::Value( - ValueNode::String("bar".to_string()) - ))])) - )) + parse(&lex("if true {'foo' } else { 'bar' }").unwrap()).unwrap()[0], + Statement::if_else( + IfElse::new( + Expression::Value(ValueNode::Boolean(true)), + Block::new(vec![Statement::expression( + Expression::Value(ValueNode::String("foo".to_string())), + (0..0).into() + )]), + Some(Block::new(vec![Statement::expression( + Expression::Value(ValueNode::String("bar".to_string())), + (0..0).into() + )])) + ), + (0..0).into() + ) ) } #[test] fn map() { assert_eq!( - parse(&lex("{ foo = 'bar' }").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Map(vec![( - Identifier::new("foo"), - None, - Expression::Value(ValueNode::String("bar".to_string())) - )]))) + parse(&lex("{ foo = 'bar' }").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Map(vec![( + Identifier::new("foo"), + None, + Expression::Value(ValueNode::String("bar".to_string())) + )])), + (0..0).into() + ) ); assert_eq!( - parse(&lex("{ x = 1, y = 2, }").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Map(vec![ - ( - Identifier::new("x"), - None, - Expression::Value(ValueNode::Integer(1)) - ), - ( - Identifier::new("y"), - None, - Expression::Value(ValueNode::Integer(2)) - ), - ]))) + parse(&lex("{ x = 1, y = 2, }").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Map(vec![ + ( + Identifier::new("x"), + None, + Expression::Value(ValueNode::Integer(1)) + ), + ( + Identifier::new("y"), + None, + Expression::Value(ValueNode::Integer(2)) + ), + ])), + (0..0).into() + ) ); assert_eq!( - parse(&lex("{ x = 1 y = 2 }").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Map(vec![ - ( - Identifier::new("x"), - None, - Expression::Value(ValueNode::Integer(1)) - ), - ( - Identifier::new("y"), - None, - Expression::Value(ValueNode::Integer(2)) - ), - ]))) + parse(&lex("{ x = 1 y = 2 }").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Map(vec![ + ( + Identifier::new("x"), + None, + Expression::Value(ValueNode::Integer(1)) + ), + ( + Identifier::new("y"), + None, + Expression::Value(ValueNode::Integer(2)) + ), + ])), + (0..0).into() + ) ); } #[test] fn math() { assert_eq!( - parse(&lex("1 + 1").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Math(Box::new(Math::Add( - Expression::Value(ValueNode::Integer(1)), - Expression::Value(ValueNode::Integer(1)) - )))) + parse(&lex("1 + 1").unwrap()).unwrap()[0], + Statement::expression( + Expression::Math(Box::new(Math::Add( + Expression::Value(ValueNode::Integer(1)), + Expression::Value(ValueNode::Integer(1)) + ))), + (0..0).into() + ) ); } #[test] fn r#loop() { assert_eq!( - parse(&lex("loop { 42 }").unwrap()).unwrap()[0].0, - Statement::Loop(Loop::new(vec![Statement::Expression(Expression::Value( - ValueNode::Integer(42) - ))])) + parse(&lex("loop { 42 }").unwrap()).unwrap()[0], + Statement::r#loop( + Loop::new(vec![Statement::expression( + Expression::Value(ValueNode::Integer(42)), + (0..0).into() + )]), + (0..0).into() + ) ); } #[test] fn block() { assert_eq!( - parse(&lex("{ x }").unwrap()).unwrap()[0].0, - Statement::Block(Block::new(vec![Statement::Expression( - Expression::Identifier(Identifier::new("x")) - ),])) + parse(&lex("{ x }").unwrap()).unwrap()[0], + Statement::block( + Block::new(vec![Statement::expression( + Expression::Identifier(Identifier::new("x")), + (0..0).into() + )],), + (0..0).into() + ) ); assert_eq!( @@ -579,13 +652,24 @@ mod tests { ") .unwrap() ) - .unwrap()[0] - .0, - Statement::Block(Block::new(vec![ - Statement::Expression(Expression::Identifier(Identifier::new("x"))), - Statement::Expression(Expression::Identifier(Identifier::new("y"))), - Statement::Expression(Expression::Identifier(Identifier::new("z"))), - ])) + .unwrap()[0], + Statement::block( + Block::new(vec![ + Statement::expression( + Expression::Identifier(Identifier::new("x")), + (0..0).into() + ), + Statement::expression( + Expression::Identifier(Identifier::new("y")), + (0..0).into() + ), + Statement::expression( + Expression::Identifier(Identifier::new("z")), + (0..0).into() + ), + ]), + (0..0).into() + ) ); assert_eq!( @@ -598,123 +682,150 @@ mod tests { ") .unwrap() ) - .unwrap()[0] - .0, - Statement::Block(Block::new(vec![ - Statement::Expression(Expression::Logic(Box::new(Logic::Equal( - Expression::Value(ValueNode::Integer(1)), - Expression::Value(ValueNode::Integer(1)) - )))), - Statement::Expression(Expression::Identifier(Identifier::new("z"))), - ])) + .unwrap()[0], + Statement::block( + Block::new(vec![ + Statement::expression( + Expression::Logic(Box::new(Logic::Equal( + Expression::Value(ValueNode::Integer(1)), + Expression::Value(ValueNode::Integer(1)) + ))), + (0..0).into() + ), + Statement::expression( + Expression::Identifier(Identifier::new("z")), + (0..0).into() + ), + ]), + (0..0).into() + ) ); } #[test] fn identifier() { assert_eq!( - parse(&lex("x").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Identifier(Identifier::new("x"))) + parse(&lex("x").unwrap()).unwrap()[0], + Statement::expression(Expression::Identifier(Identifier::new("x")), (0..0).into()) ); assert_eq!( - parse(&lex("foobar").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Identifier(Identifier::new("foobar"))) + parse(&lex("foobar").unwrap()).unwrap()[0], + Statement::expression( + Expression::Identifier(Identifier::new("foobar")), + (0..0).into() + ) ); assert_eq!( - parse(&lex("HELLO").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Identifier(Identifier::new("HELLO"))) + parse(&lex("HELLO").unwrap()).unwrap()[0], + Statement::expression( + Expression::Identifier(Identifier::new("HELLO")), + (0..0).into() + ) ); } #[test] fn assignment() { assert_eq!( - parse(&lex("foobar = 1").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - None, - AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::Integer(1))) - )), + parse(&lex("foobar = 1").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + None, + AssignmentOperator::Assign, + Statement::expression(Expression::Value(ValueNode::Integer(1)), (0..0).into()) + ), + (0..0).into() + ), ); } #[test] fn assignment_with_basic_type() { assert_eq!( - parse(&lex("foobar: int = 1").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - Some(Type::Integer), - AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::Integer(1))) - )), + parse(&lex("foobar: int = 1").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + Some(Type::Integer), + AssignmentOperator::Assign, + Statement::expression(Expression::Value(ValueNode::Integer(1)), (0..0).into()) + ), + (0..0).into() + ), ); } #[test] fn assignment_with_list_types() { assert_eq!( - parse(&lex("foobar: list = []").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - Some(Type::List), - AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::List(vec![]))) - )), + parse(&lex("foobar: list = []").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + Some(Type::List), + AssignmentOperator::Assign, + Statement::expression( + Expression::Value(ValueNode::List(vec![])), + (0..0).into() + ) + ), + (0..0).into() + ), ); assert_eq!( - parse(&lex("foobar: list(int) = []").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - Some(Type::ListOf(Box::new(Type::Integer))), - AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::List(vec![]))) - )), + parse(&lex("foobar: list(int) = []").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + Some(Type::ListOf(Box::new(Type::Integer))), + AssignmentOperator::Assign, + Statement::expression( + Expression::Value(ValueNode::List(vec![])), + (0..0).into() + ) + ), + (0..0).into() + ), ); assert_eq!( - parse(&lex("foobar: [int, str] = [ 42, 'foo' ]").unwrap()).unwrap()[0].0, - Statement::Assignment(Assignment::new( - Identifier::new("foobar"), - Some(Type::ListExact(vec![Type::Integer, Type::String])), - AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::List(vec![ - Expression::Value(ValueNode::Integer(42)), - Expression::Value(ValueNode::String("foo".to_string())) - ]))) - )), + parse(&lex("foobar: [int, str] = [ 42, 'foo' ]").unwrap()).unwrap()[0], + Statement::assignment( + Assignment::new( + Identifier::new("foobar"), + Some(Type::ListExact(vec![Type::Integer, Type::String])), + AssignmentOperator::Assign, + Statement::expression( + Expression::Value(ValueNode::List(vec![ + Expression::Value(ValueNode::Integer(42)), + Expression::Value(ValueNode::String("foo".to_string())) + ])), + (0..0).into() + ) + ), + (0..0).into() + ), ); } #[test] fn logic() { assert_eq!( - parse(&lex("x == 1").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Logic(Box::new(Logic::Equal( - Expression::Identifier(Identifier::new("x")), - Expression::Value(ValueNode::Integer(1)) - )))) - ); - - assert_eq!( - parse(&lex("(x == 1) && (y == 2)").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Logic(Box::new(Logic::And( + parse(&lex("x == 1").unwrap()).unwrap()[0], + Statement::expression( Expression::Logic(Box::new(Logic::Equal( Expression::Identifier(Identifier::new("x")), Expression::Value(ValueNode::Integer(1)) ))), - Expression::Logic(Box::new(Logic::Equal( - Expression::Identifier(Identifier::new("y")), - Expression::Value(ValueNode::Integer(2)) - ))), - )))) + (0..0).into() + ) ); assert_eq!( - parse(&lex("(x == 1) && (y == 2) && true").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Logic(Box::new(Logic::And( + parse(&lex("(x == 1) && (y == 2)").unwrap()).unwrap()[0], + Statement::expression( Expression::Logic(Box::new(Logic::And( Expression::Logic(Box::new(Logic::Equal( Expression::Identifier(Identifier::new("x")), @@ -725,119 +836,160 @@ mod tests { Expression::Value(ValueNode::Integer(2)) ))), ))), - Expression::Value(ValueNode::Boolean(true)) - )))) + (0..0).into() + ) + ); + + assert_eq!( + parse(&lex("(x == 1) && (y == 2) && true").unwrap()).unwrap()[0], + Statement::expression( + Expression::Logic(Box::new(Logic::And( + Expression::Logic(Box::new(Logic::And( + Expression::Logic(Box::new(Logic::Equal( + Expression::Identifier(Identifier::new("x")), + Expression::Value(ValueNode::Integer(1)) + ))), + Expression::Logic(Box::new(Logic::Equal( + Expression::Identifier(Identifier::new("y")), + Expression::Value(ValueNode::Integer(2)) + ))), + ))), + Expression::Value(ValueNode::Boolean(true)) + ))), + (0..0).into() + ) ); } #[test] fn list() { assert_eq!( - parse(&lex("[]").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::List(Vec::with_capacity(0)))) + parse(&lex("[]").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::List(Vec::with_capacity(0))), + (0..0).into() + ) ); assert_eq!( - parse(&lex("[42]").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value( - ValueNode::Integer(42) - )]))) + parse(&lex("[42]").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::List(vec![Expression::Value( + ValueNode::Integer(42) + )])), + (0..0).into() + ) ); assert_eq!( - parse(&lex("[42, 'foo', 'bar', [1, 2, 3,]]").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::List(vec![ - Expression::Value(ValueNode::Integer(42)), - Expression::Value(ValueNode::String("foo".to_string())), - Expression::Value(ValueNode::String("bar".to_string())), + parse(&lex("[42, 'foo', 'bar', [1, 2, 3,]]").unwrap()).unwrap()[0], + Statement::expression( Expression::Value(ValueNode::List(vec![ - Expression::Value(ValueNode::Integer(1)), - Expression::Value(ValueNode::Integer(2)), - Expression::Value(ValueNode::Integer(3)), - ])) - ])),) + Expression::Value(ValueNode::Integer(42)), + Expression::Value(ValueNode::String("foo".to_string())), + Expression::Value(ValueNode::String("bar".to_string())), + Expression::Value(ValueNode::List(vec![ + Expression::Value(ValueNode::Integer(1)), + Expression::Value(ValueNode::Integer(2)), + Expression::Value(ValueNode::Integer(3)), + ])) + ])), + (0..0).into() + ) ); } #[test] fn r#true() { assert_eq!( - parse(&lex("true").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Boolean(true))) + parse(&lex("true").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Boolean(true)), (0..0).into()) ); } #[test] fn r#false() { assert_eq!( - parse(&lex("false").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Boolean(false))) + parse(&lex("false").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Boolean(false)), (0..0).into()) ); } #[test] fn positive_float() { assert_eq!( - parse(&lex("0.0").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(0.0))) + parse(&lex("0").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Float(0.0)), (0..0).into()) ); assert_eq!( - parse(&lex("42.0").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(42.0))) + parse(&lex("42").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Float(42.0)), (0..0).into()) ); let max_float = f64::MAX.to_string() + ".0"; assert_eq!( - parse(&lex(&max_float).unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(f64::MAX))) + parse(&lex(&max_float).unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Float(f64::MAX)), (0..0).into()) ); let min_positive_float = f64::MIN_POSITIVE.to_string(); assert_eq!( - parse(&lex(&min_positive_float).unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(f64::MIN_POSITIVE))) + parse(&lex(&min_positive_float).unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Float(f64::MIN_POSITIVE)), + (0..0).into() + ) ); } #[test] fn negative_float() { assert_eq!( - parse(&lex("-0.0").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(-0.0))) + parse(&lex("-0.0").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Float(-0.0)), (0..0).into()) ); assert_eq!( - parse(&lex("-42.0").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(-42.0))) + parse(&lex("-42.0").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Float(-42.0)), (0..0).into()) ); let min_float = f64::MIN.to_string() + ".0"; assert_eq!( - parse(&lex(&min_float).unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(f64::MIN))) + parse(&lex(&min_float).unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Float(f64::MIN)), (0..0).into()) ); let max_negative_float = format!("-{}", f64::MIN_POSITIVE); assert_eq!( - parse(&lex(&max_negative_float).unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(-f64::MIN_POSITIVE))) + parse(&lex(&max_negative_float).unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Float(-f64::MIN_POSITIVE)), + (0..0).into() + ) ); } #[test] fn other_float() { assert_eq!( - parse(&lex("Infinity").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(f64::INFINITY))) + parse(&lex("Infinity").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Float(f64::INFINITY)), + (0..0).into() + ) ); assert_eq!( - parse(&lex("-Infinity").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Float(f64::NEG_INFINITY))) + parse(&lex("-Infinity").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Float(f64::NEG_INFINITY)), + (0..0).into() + ) ); - if let Statement::Expression(Expression::Value(ValueNode::Float(float))) = - &parse(&lex("NaN").unwrap()).unwrap()[0].0 + if let StatementInner::Expression(Expression::Value(ValueNode::Float(float))) = + &parse(&lex("NaN").unwrap()).unwrap()[0].inner { assert!(float.is_nan()); } else { @@ -853,21 +1005,24 @@ mod tests { let statements = parse(&tokens).unwrap(); assert_eq!( - statements[0].0, - Statement::Expression(Expression::Value(ValueNode::Integer(i))) + statements[0], + Statement::expression(Expression::Value(ValueNode::Integer(i)), (0..0).into()) ) } assert_eq!( - parse(&lex("42").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Integer(42))) + parse(&lex("42").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Integer(42)), (0..0).into()) ); let maximum_integer = i64::MAX.to_string(); assert_eq!( - parse(&lex(&maximum_integer).unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Integer(i64::MAX))) + parse(&lex(&maximum_integer).unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Integer(i64::MAX)), + (0..0).into() + ) ); } @@ -879,69 +1034,99 @@ mod tests { let statements = parse(&tokens).unwrap(); assert_eq!( - statements[0].0, - Statement::Expression(Expression::Value(ValueNode::Integer(i))) + statements[0], + Statement::expression(Expression::Value(ValueNode::Integer(i)), (0..0).into()) ) } assert_eq!( - parse(&lex("-42").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Integer(-42))) + parse(&lex("-42").unwrap()).unwrap()[0], + Statement::expression(Expression::Value(ValueNode::Integer(-42)), (0..0).into()) ); let minimum_integer = i64::MIN.to_string(); assert_eq!( - parse(&lex(&minimum_integer).unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::Integer(i64::MIN))) + parse(&lex(&minimum_integer).unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::Integer(i64::MIN)), + (0..0).into() + ) ); } #[test] fn double_quoted_string() { assert_eq!( - parse(&lex("\"\"").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("".to_string()))) + parse(&lex("\"\"").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("".to_string())), + (0..0).into() + ) ); assert_eq!( - parse(&lex("\"42\"").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("42".to_string()))) + parse(&lex("\"42\"").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("42".to_string())), + (0..0).into() + ) ); assert_eq!( - parse(&lex("\"foobar\"").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("foobar".to_string()))) + parse(&lex("\"foobar\"").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("foobar".to_string())), + (0..0).into() + ) ); } #[test] fn single_quoted_string() { assert_eq!( - parse(&lex("''").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("".to_string()))) + parse(&lex("''").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("".to_string())), + (0..0).into() + ) ); assert_eq!( - parse(&lex("'42'").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("42".to_string()))) + parse(&lex("'42'").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("42".to_string())), + (0..0).into() + ) ); assert_eq!( - parse(&lex("'foobar'").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("foobar".to_string()))) + parse(&lex("'foobar'").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("foobar".to_string())), + (0..0).into() + ) ); } #[test] fn grave_quoted_string() { assert_eq!( - parse(&lex("``").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("".to_string()))) + parse(&lex("``").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("".to_string())), + (0..0).into() + ) ); assert_eq!( - parse(&lex("`42`").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("42".to_string()))) + parse(&lex("`42`").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("42".to_string())), + (0..0).into() + ) ); assert_eq!( - parse(&lex("`foobar`").unwrap()).unwrap()[0].0, - Statement::Expression(Expression::Value(ValueNode::String("foobar".to_string()))) + parse(&lex("`foobar`").unwrap()).unwrap()[0], + Statement::expression( + Expression::Value(ValueNode::String("foobar".to_string())), + (0..0).into() + ) ); } } diff --git a/tests/functions.rs b/tests/functions.rs index b0060e4..75e7d46 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -62,7 +62,7 @@ fn function_context_does_not_capture_values() { ), Err(vec![Error::Validation { error: ValidationError::VariableNotFound(Identifier::new("x")), - span: (32..66).into() + span: (32, 66) }]) ); diff --git a/tests/values.rs b/tests/values.rs index 4c0ca9d..eb46482 100644 --- a/tests/values.rs +++ b/tests/values.rs @@ -140,7 +140,7 @@ fn map_type_errors() { actual: Type::String, expected: Type::Boolean }), - span: (0..22).into() + span: (0, 22) }]) ); } diff --git a/tests/variables.rs b/tests/variables.rs index 72c8f47..bf50bea 100644 --- a/tests/variables.rs +++ b/tests/variables.rs @@ -29,7 +29,7 @@ fn set_variable_with_type_error() { actual: Type::Boolean, expected: Type::String }), - span: (0..18).into() + span: (0, 18) }]) ); } @@ -41,9 +41,10 @@ fn function_variable() { Ok(Some(Value::function( vec![(Identifier::new("x"), Type::Integer)], Type::Integer, - Block::new(vec![Statement::Expression(Expression::Identifier( - Identifier::new("x") - ))]) + Block::new(vec![Statement::expression( + Expression::Identifier(Identifier::new("x")), + (0..0).into() + )]) ))) ); }