From 1b367d4dfb3fbac1fc5d2e255319f44834b89aa2 Mon Sep 17 00:00:00 2001 From: Jeff Date: Sun, 17 Mar 2024 07:48:06 -0400 Subject: [PATCH] Fix tests; Add SourcePosition type --- src/abstract_tree/assignment.rs | 18 ++++------ src/abstract_tree/block.rs | 14 +++----- src/abstract_tree/if_else.rs | 16 ++++----- src/abstract_tree/logic.rs | 56 +++++++++++++++---------------- src/abstract_tree/loop.rs | 2 +- src/abstract_tree/mod.rs | 21 ++++++++++-- src/error.rs | 8 ++--- src/parser.rs | 58 +++++++++++++++------------------ 8 files changed, 97 insertions(+), 96 deletions(-) diff --git a/src/abstract_tree/assignment.rs b/src/abstract_tree/assignment.rs index 74c5eb9..c88070e 100644 --- a/src/abstract_tree/assignment.rs +++ b/src/abstract_tree/assignment.rs @@ -125,8 +125,7 @@ mod tests { Identifier::new("foobar"), None, AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::Integer(42))) - .with_position((0..0).into()), + Statement::Expression(Expression::Value(ValueNode::Integer(42))).with_position((0, 0)), ) .run(&context) .unwrap(); @@ -149,8 +148,7 @@ mod tests { Identifier::new("foobar"), None, AssignmentOperator::AddAssign, - Statement::Expression(Expression::Value(ValueNode::Integer(41))) - .with_position((0..0).into()), + Statement::Expression(Expression::Value(ValueNode::Integer(41))).with_position((0, 0)), ) .run(&context) .unwrap(); @@ -173,8 +171,7 @@ mod tests { Identifier::new("foobar"), None, AssignmentOperator::SubAssign, - Statement::Expression(Expression::Value(ValueNode::Integer(1))) - .with_position((0..0).into()), + Statement::Expression(Expression::Value(ValueNode::Integer(1))).with_position((0, 0)), ) .run(&context) .unwrap(); @@ -191,11 +188,10 @@ mod tests { Identifier::new("foobar"), Some(WithPosition { node: Type::Boolean, - position: (0, 0), + position: (0, 0).into(), }), AssignmentOperator::Assign, - Statement::Expression(Expression::Value(ValueNode::Integer(42))) - .with_position((0..0).into()), + Statement::Expression(Expression::Value(ValueNode::Integer(42))).with_position((0, 0)), ) .validate(&Context::new()); @@ -206,8 +202,8 @@ mod tests { actual: Type::Integer, expected: Type::Boolean }, - actual_position: (0, 0), - expected_position: (0, 0), + actual_position: (0, 0).into(), + expected_position: (0, 0).into(), }) ) } diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index ebb4d8e..343aa5a 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -61,12 +61,9 @@ mod tests { #[test] fn run_returns_value_of_final_statement() { let block = Block::new(vec![ - Statement::Expression(Expression::Value(ValueNode::Integer(1))) - .with_position((0..0).into()), - Statement::Expression(Expression::Value(ValueNode::Integer(2))) - .with_position((0..0).into()), - Statement::Expression(Expression::Value(ValueNode::Integer(42))) - .with_position((0..0).into()), + Statement::Expression(Expression::Value(ValueNode::Integer(1))).with_position((0, 0)), + Statement::Expression(Expression::Value(ValueNode::Integer(2))).with_position((0, 0)), + Statement::Expression(Expression::Value(ValueNode::Integer(42))).with_position((0, 0)), ]); assert_eq!( @@ -79,9 +76,8 @@ mod tests { fn expected_type_returns_type_of_final_statement() { let block = Block::new(vec![ Statement::Expression(Expression::Value(ValueNode::String("42".to_string()))) - .with_position((0..0).into()), - Statement::Expression(Expression::Value(ValueNode::Integer(42))) - .with_position((0..0).into()), + .with_position((0, 0)), + Statement::Expression(Expression::Value(ValueNode::Integer(42))).with_position((0, 0)), ]); 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 a3e1c94..eec8065 100644 --- a/src/abstract_tree/if_else.rs +++ b/src/abstract_tree/if_else.rs @@ -83,12 +83,12 @@ mod tests { fn simple_if() { assert_eq!( IfElse::new( - Expression::Value(ValueNode::Boolean(true)).with_position((0..0).into()), + Expression::Value(ValueNode::Boolean(true)).with_position((0, 0)), Block::new(vec![Statement::Expression(Expression::Value( ValueNode::String("foo".to_string()) )) - .with_position((0..0).into())]) - .with_position((0..0).into()), + .with_position((0, 0))]) + .with_position((0, 0)), None ) .run(&Context::new()), @@ -100,18 +100,18 @@ mod tests { fn simple_if_else() { assert_eq!( IfElse::new( - Expression::Value(ValueNode::Boolean(false)).with_position((0..0).into()), + Expression::Value(ValueNode::Boolean(false)).with_position((0, 0)), Block::new(vec![Statement::Expression(Expression::Value( ValueNode::String("foo".to_string()) )) - .with_position((0..0).into())]) - .with_position((0..0).into()), + .with_position((0, 0))]) + .with_position((0, 0)), Some( Block::new(vec![Statement::Expression(Expression::Value( ValueNode::String("bar".to_string()) )) - .with_position((0..0).into())]) - .with_position((0..0).into()) + .with_position((0, 0))]) + .with_position((0, 0)) ) ) .run(&Context::new()), diff --git a/src/abstract_tree/logic.rs b/src/abstract_tree/logic.rs index 0faebb1..de04c5a 100644 --- a/src/abstract_tree/logic.rs +++ b/src/abstract_tree/logic.rs @@ -139,8 +139,8 @@ mod tests { #[test] fn equal() { assert!(Logic::Equal( - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -153,8 +153,8 @@ mod tests { #[test] fn not_equal() { assert!(Logic::NotEqual( - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), - Expression::Value(ValueNode::Integer(43)).with_position((0..0).into()), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), + Expression::Value(ValueNode::Integer(43)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -167,8 +167,8 @@ mod tests { #[test] fn greater() { assert!(Logic::Greater( - Expression::Value(ValueNode::Integer(43)).with_position((0..0).into()), - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), + Expression::Value(ValueNode::Integer(43)).with_position((0, 0)), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -181,8 +181,8 @@ mod tests { #[test] fn less() { assert!(Logic::Less( - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), - Expression::Value(ValueNode::Integer(43)).with_position((0..0).into()), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), + Expression::Value(ValueNode::Integer(43)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -195,8 +195,8 @@ mod tests { #[test] fn greater_or_equal() { assert!(Logic::GreaterOrEqual( - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), - Expression::Value(ValueNode::Integer(41)).with_position((0..0).into()), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), + Expression::Value(ValueNode::Integer(41)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -206,8 +206,8 @@ mod tests { .unwrap()); assert!(Logic::GreaterOrEqual( - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -220,8 +220,8 @@ mod tests { #[test] fn less_or_equal() { assert!(Logic::LessOrEqual( - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), - Expression::Value(ValueNode::Integer(43)).with_position((0..0).into()), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), + Expression::Value(ValueNode::Integer(43)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -231,8 +231,8 @@ mod tests { .unwrap()); assert!(Logic::LessOrEqual( - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), - Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), + Expression::Value(ValueNode::Integer(42)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -245,8 +245,8 @@ mod tests { #[test] fn and() { assert!(Logic::And( - Expression::Value(ValueNode::Boolean(true)).with_position((0..0).into()), - Expression::Value(ValueNode::Boolean(true)).with_position((0..0).into()), + Expression::Value(ValueNode::Boolean(true)).with_position((0, 0)), + Expression::Value(ValueNode::Boolean(true)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -259,8 +259,8 @@ mod tests { #[test] fn or() { assert!(Logic::Or( - Expression::Value(ValueNode::Boolean(true)).with_position((0..0).into()), - Expression::Value(ValueNode::Boolean(false)).with_position((0..0).into()), + Expression::Value(ValueNode::Boolean(true)).with_position((0, 0)), + Expression::Value(ValueNode::Boolean(false)).with_position((0, 0)), ) .run(&Context::new()) .unwrap() @@ -272,14 +272,14 @@ mod tests { #[test] fn not() { - assert!(Logic::Not( - Expression::Value(ValueNode::Boolean(false)).with_position((0..0).into()) + assert!( + Logic::Not(Expression::Value(ValueNode::Boolean(false)).with_position((0, 0))) + .run(&Context::new()) + .unwrap() + .as_return_value() + .unwrap() + .as_boolean() + .unwrap() ) - .run(&Context::new()) - .unwrap() - .as_return_value() - .unwrap() - .as_boolean() - .unwrap()) } } diff --git a/src/abstract_tree/loop.rs b/src/abstract_tree/loop.rs index 3161a25..19a6095 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.with_position((0..0).into())], + statements: vec![Statement::Break.with_position((0, 0))], } .run(&Context::new()); diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index 3cd4f82..428c4a9 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -41,7 +41,22 @@ use crate::{ #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub struct WithPosition { pub node: T, - pub position: (usize, usize), + pub position: SourcePosition, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub struct SourcePosition(pub usize, pub usize); + +impl From for SourcePosition { + fn from(span: SimpleSpan) -> Self { + SourcePosition(span.start(), span.end()) + } +} + +impl From<(usize, usize)> for SourcePosition { + fn from((start, end): (usize, usize)) -> Self { + SourcePosition(start, end) + } } pub trait AbstractTree: Sized { @@ -49,10 +64,10 @@ pub trait AbstractTree: Sized { fn validate(&self, context: &Context) -> Result<(), ValidationError>; fn run(self, context: &Context) -> Result; - fn with_position(self, span: SimpleSpan) -> WithPosition { + fn with_position>(self, span: T) -> WithPosition { WithPosition { node: self, - position: (span.start(), span.end()), + position: span.into(), } } } diff --git a/src/error.rs b/src/error.rs index 73d6a0c..9ce1148 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,7 +4,7 @@ use ariadne::{Color, Label, Report, ReportKind}; use chumsky::{prelude::Rich, span::Span}; use crate::{ - abstract_tree::{Identifier, Type}, + abstract_tree::{Identifier, SourcePosition, Type}, lexer::Token, }; @@ -21,7 +21,7 @@ pub enum Error { Runtime(RuntimeError), Validation { error: ValidationError, - position: (usize, usize), + position: SourcePosition, }, } @@ -160,10 +160,10 @@ pub enum ValidationError { conflict: TypeConflict, /// The position of the item that gave the "actual" type. - actual_position: (usize, usize), + actual_position: SourcePosition, /// The position of the item that gave the "expected" type. - expected_position: (usize, usize), + expected_position: SourcePosition, }, VariableNotFound(Identifier), } diff --git a/src/parser.rs b/src/parser.rs index 0de6cd8..9b88bc9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -350,8 +350,8 @@ pub fn parser<'src>() -> DustParser<'src> { let expression_statement = positioned_expression .clone() - .map_with(|positioned_expression, state| { - Statement::Expression(positioned_expression.node).with_position(state.span()) + .map(|WithPosition { node, position }| { + Statement::Expression(node).with_position(position) }); let r#break = just(Token::Keyword("break")) @@ -434,18 +434,17 @@ mod tests { assert_eq!( parse(&lex("while true { output('hi') }").unwrap()).unwrap()[0], Statement::While(While::new( - Expression::Value(ValueNode::Boolean(true)).with_position((6..11).into()), + Expression::Value(ValueNode::Boolean(true)).with_position((6, 11)), Block::new(vec![Statement::Expression(Expression::FunctionCall( FunctionCall::new( - Expression::Identifier(Identifier::new("output")) - .with_position((13..19).into()), + Expression::Identifier(Identifier::new("output")).with_position((13, 19)), vec![Expression::Value(ValueNode::String("hi".to_string())) - .with_position((20..24).into())] + .with_position((20, 24))] ) )) - .with_position((13..26).into())]) + .with_position((13, 26))]) )) - .with_position((0..27).into()) + .with_position((0, 27)) ) } @@ -455,12 +454,12 @@ mod tests { parse(&lex("foobar : bool = true").unwrap()).unwrap()[0], Statement::Assignment(Assignment::new( Identifier::new("foobar"), - Some(Type::Boolean.with_position((9..14).into())), + Some(Type::Boolean.with_position((9, 14))), AssignmentOperator::Assign, Statement::Expression(Expression::Value(ValueNode::Boolean(true))) - .with_position((16..20).into()) + .with_position((16, 20)) ),) - .with_position((0..20).into()) + .with_position((0, 20)) ); } @@ -470,15 +469,15 @@ mod tests { parse(&lex("foobar : list(bool) = [true]").unwrap()).unwrap()[0], Statement::Assignment(Assignment::new( Identifier::new("foobar"), - Some(Type::ListOf(Box::new(Type::Boolean)).with_position((9..20).into())), + Some(Type::ListOf(Box::new(Type::Boolean)).with_position((9, 20))), AssignmentOperator::Assign, Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value( ValueNode::Boolean(true) ) - .with_position((23..27).into())]))) - .with_position((22..28).into()) + .with_position((23, 27))]))) + .with_position((22, 28)) )) - .with_position((0..28).into()) + .with_position((0, 28)) ); } @@ -488,19 +487,15 @@ mod tests { 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]) - .with_position((9..21).into()) - ), + Some(Type::ListExact(vec![Type::Boolean, Type::String]).with_position((9, 21))), AssignmentOperator::Assign, Statement::Expression(Expression::Value(ValueNode::List(vec![ - Expression::Value(ValueNode::Boolean(true)).with_position((24..28).into()), - Expression::Value(ValueNode::String("42".to_string())) - .with_position((30..34).into()) + Expression::Value(ValueNode::Boolean(true)).with_position((24, 28)), + Expression::Value(ValueNode::String("42".to_string())).with_position((30, 34)) ]))) - .with_position((23..35).into()) + .with_position((23, 35)) ),) - .with_position((0..35).into()) + .with_position((0, 35)) ); } @@ -515,13 +510,13 @@ mod tests { parameter_types: vec![], return_type: Box::new(Type::Any) } - .with_position((9..19).into()) + .with_position((9, 19)) ), AssignmentOperator::Assign, Statement::Expression(Expression::Identifier(Identifier::new("some_function"))) - .with_position((21..34).into()) + .with_position((21, 34)) ),) - .with_position((0..34).into()) + .with_position((0, 34)) ); } @@ -530,10 +525,10 @@ mod tests { assert_eq!( parse(&lex("output()").unwrap()).unwrap()[0], Statement::Expression(Expression::FunctionCall(FunctionCall::new( - Expression::Identifier(Identifier::new("output")).with_position((0..6).into()), + Expression::Identifier(Identifier::new("output")).with_position((0, 6)), Vec::with_capacity(0), ))) - .with_position((0..8).into()) + .with_position((0, 8)) ) } @@ -541,8 +536,7 @@ mod tests { fn range() { assert_eq!( parse(&lex("1..10").unwrap()).unwrap()[0], - Statement::Expression(Expression::Value(ValueNode::Range(1..10))) - .with_position((0..5).into()) + Statement::Expression(Expression::Value(ValueNode::Range(1..10))).with_position((0, 5)) ) } @@ -556,7 +550,7 @@ mod tests { // return_type: Type::Integer, // body: Block::new(vec![Statement::expression( // Expression::Identifier(Identifier::new("x")), - // (0..0).into() + // (0..0) // )]) // }), // (0..0).into()