Fix tests; Add SourcePosition type

This commit is contained in:
Jeff 2024-03-17 07:48:06 -04:00
parent 4ea19f238e
commit 1b367d4dfb
8 changed files with 97 additions and 96 deletions

View File

@ -125,8 +125,7 @@ mod tests {
Identifier::new("foobar"), Identifier::new("foobar"),
None, None,
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::Expression(Expression::Value(ValueNode::Integer(42))) Statement::Expression(Expression::Value(ValueNode::Integer(42))).with_position((0, 0)),
.with_position((0..0).into()),
) )
.run(&context) .run(&context)
.unwrap(); .unwrap();
@ -149,8 +148,7 @@ mod tests {
Identifier::new("foobar"), Identifier::new("foobar"),
None, None,
AssignmentOperator::AddAssign, AssignmentOperator::AddAssign,
Statement::Expression(Expression::Value(ValueNode::Integer(41))) Statement::Expression(Expression::Value(ValueNode::Integer(41))).with_position((0, 0)),
.with_position((0..0).into()),
) )
.run(&context) .run(&context)
.unwrap(); .unwrap();
@ -173,8 +171,7 @@ mod tests {
Identifier::new("foobar"), Identifier::new("foobar"),
None, None,
AssignmentOperator::SubAssign, AssignmentOperator::SubAssign,
Statement::Expression(Expression::Value(ValueNode::Integer(1))) Statement::Expression(Expression::Value(ValueNode::Integer(1))).with_position((0, 0)),
.with_position((0..0).into()),
) )
.run(&context) .run(&context)
.unwrap(); .unwrap();
@ -191,11 +188,10 @@ mod tests {
Identifier::new("foobar"), Identifier::new("foobar"),
Some(WithPosition { Some(WithPosition {
node: Type::Boolean, node: Type::Boolean,
position: (0, 0), position: (0, 0).into(),
}), }),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::Expression(Expression::Value(ValueNode::Integer(42))) Statement::Expression(Expression::Value(ValueNode::Integer(42))).with_position((0, 0)),
.with_position((0..0).into()),
) )
.validate(&Context::new()); .validate(&Context::new());
@ -206,8 +202,8 @@ mod tests {
actual: Type::Integer, actual: Type::Integer,
expected: Type::Boolean expected: Type::Boolean
}, },
actual_position: (0, 0), actual_position: (0, 0).into(),
expected_position: (0, 0), expected_position: (0, 0).into(),
}) })
) )
} }

View File

@ -61,12 +61,9 @@ mod tests {
#[test] #[test]
fn run_returns_value_of_final_statement() { fn run_returns_value_of_final_statement() {
let block = Block::new(vec![ let block = Block::new(vec![
Statement::Expression(Expression::Value(ValueNode::Integer(1))) Statement::Expression(Expression::Value(ValueNode::Integer(1))).with_position((0, 0)),
.with_position((0..0).into()), Statement::Expression(Expression::Value(ValueNode::Integer(2))).with_position((0, 0)),
Statement::Expression(Expression::Value(ValueNode::Integer(2))) Statement::Expression(Expression::Value(ValueNode::Integer(42))).with_position((0, 0)),
.with_position((0..0).into()),
Statement::Expression(Expression::Value(ValueNode::Integer(42)))
.with_position((0..0).into()),
]); ]);
assert_eq!( assert_eq!(
@ -79,9 +76,8 @@ mod tests {
fn expected_type_returns_type_of_final_statement() { fn expected_type_returns_type_of_final_statement() {
let block = Block::new(vec![ let block = Block::new(vec![
Statement::Expression(Expression::Value(ValueNode::String("42".to_string()))) Statement::Expression(Expression::Value(ValueNode::String("42".to_string())))
.with_position((0..0).into()), .with_position((0, 0)),
Statement::Expression(Expression::Value(ValueNode::Integer(42))) Statement::Expression(Expression::Value(ValueNode::Integer(42))).with_position((0, 0)),
.with_position((0..0).into()),
]); ]);
assert_eq!(block.expected_type(&Context::new()), Ok(Type::Integer)) assert_eq!(block.expected_type(&Context::new()), Ok(Type::Integer))

View File

@ -83,12 +83,12 @@ mod tests {
fn simple_if() { fn simple_if() {
assert_eq!( assert_eq!(
IfElse::new( 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( Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("foo".to_string()) ValueNode::String("foo".to_string())
)) ))
.with_position((0..0).into())]) .with_position((0, 0))])
.with_position((0..0).into()), .with_position((0, 0)),
None None
) )
.run(&Context::new()), .run(&Context::new()),
@ -100,18 +100,18 @@ mod tests {
fn simple_if_else() { fn simple_if_else() {
assert_eq!( assert_eq!(
IfElse::new( 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( Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("foo".to_string()) ValueNode::String("foo".to_string())
)) ))
.with_position((0..0).into())]) .with_position((0, 0))])
.with_position((0..0).into()), .with_position((0, 0)),
Some( Some(
Block::new(vec![Statement::Expression(Expression::Value( Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("bar".to_string()) ValueNode::String("bar".to_string())
)) ))
.with_position((0..0).into())]) .with_position((0, 0))])
.with_position((0..0).into()) .with_position((0, 0))
) )
) )
.run(&Context::new()), .run(&Context::new()),

View File

@ -139,8 +139,8 @@ mod tests {
#[test] #[test]
fn equal() { fn equal() {
assert!(Logic::Equal( assert!(Logic::Equal(
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).into()), Expression::Value(ValueNode::Integer(42)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -153,8 +153,8 @@ mod tests {
#[test] #[test]
fn not_equal() { fn not_equal() {
assert!(Logic::NotEqual( assert!(Logic::NotEqual(
Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(42)).with_position((0, 0)),
Expression::Value(ValueNode::Integer(43)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(43)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -167,8 +167,8 @@ mod tests {
#[test] #[test]
fn greater() { fn greater() {
assert!(Logic::Greater( assert!(Logic::Greater(
Expression::Value(ValueNode::Integer(43)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(43)).with_position((0, 0)),
Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(42)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -181,8 +181,8 @@ mod tests {
#[test] #[test]
fn less() { fn less() {
assert!(Logic::Less( assert!(Logic::Less(
Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(42)).with_position((0, 0)),
Expression::Value(ValueNode::Integer(43)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(43)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -195,8 +195,8 @@ mod tests {
#[test] #[test]
fn greater_or_equal() { fn greater_or_equal() {
assert!(Logic::GreaterOrEqual( assert!(Logic::GreaterOrEqual(
Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(42)).with_position((0, 0)),
Expression::Value(ValueNode::Integer(41)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(41)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -206,8 +206,8 @@ mod tests {
.unwrap()); .unwrap());
assert!(Logic::GreaterOrEqual( assert!(Logic::GreaterOrEqual(
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).into()), Expression::Value(ValueNode::Integer(42)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -220,8 +220,8 @@ mod tests {
#[test] #[test]
fn less_or_equal() { fn less_or_equal() {
assert!(Logic::LessOrEqual( assert!(Logic::LessOrEqual(
Expression::Value(ValueNode::Integer(42)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(42)).with_position((0, 0)),
Expression::Value(ValueNode::Integer(43)).with_position((0..0).into()), Expression::Value(ValueNode::Integer(43)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -231,8 +231,8 @@ mod tests {
.unwrap()); .unwrap());
assert!(Logic::LessOrEqual( assert!(Logic::LessOrEqual(
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).into()), Expression::Value(ValueNode::Integer(42)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -245,8 +245,8 @@ mod tests {
#[test] #[test]
fn and() { fn and() {
assert!(Logic::And( assert!(Logic::And(
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).into()), Expression::Value(ValueNode::Boolean(true)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -259,8 +259,8 @@ mod tests {
#[test] #[test]
fn or() { fn or() {
assert!(Logic::Or( assert!(Logic::Or(
Expression::Value(ValueNode::Boolean(true)).with_position((0..0).into()), Expression::Value(ValueNode::Boolean(true)).with_position((0, 0)),
Expression::Value(ValueNode::Boolean(false)).with_position((0..0).into()), Expression::Value(ValueNode::Boolean(false)).with_position((0, 0)),
) )
.run(&Context::new()) .run(&Context::new())
.unwrap() .unwrap()
@ -272,14 +272,14 @@ mod tests {
#[test] #[test]
fn not() { fn not() {
assert!(Logic::Not( assert!(
Expression::Value(ValueNode::Boolean(false)).with_position((0..0).into()) 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())
} }
} }

View File

@ -58,7 +58,7 @@ mod tests {
#[test] #[test]
fn basic_loop() { fn basic_loop() {
let result = Loop { let result = Loop {
statements: vec![Statement::Break.with_position((0..0).into())], statements: vec![Statement::Break.with_position((0, 0))],
} }
.run(&Context::new()); .run(&Context::new());

View File

@ -41,7 +41,22 @@ use crate::{
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct WithPosition<T> { pub struct WithPosition<T> {
pub node: T, 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<SimpleSpan> 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 { pub trait AbstractTree: Sized {
@ -49,10 +64,10 @@ pub trait AbstractTree: Sized {
fn validate(&self, context: &Context) -> Result<(), ValidationError>; fn validate(&self, context: &Context) -> Result<(), ValidationError>;
fn run(self, context: &Context) -> Result<Action, RuntimeError>; fn run(self, context: &Context) -> Result<Action, RuntimeError>;
fn with_position(self, span: SimpleSpan) -> WithPosition<Self> { fn with_position<T: Into<SourcePosition>>(self, span: T) -> WithPosition<Self> {
WithPosition { WithPosition {
node: self, node: self,
position: (span.start(), span.end()), position: span.into(),
} }
} }
} }

View File

@ -4,7 +4,7 @@ use ariadne::{Color, Label, Report, ReportKind};
use chumsky::{prelude::Rich, span::Span}; use chumsky::{prelude::Rich, span::Span};
use crate::{ use crate::{
abstract_tree::{Identifier, Type}, abstract_tree::{Identifier, SourcePosition, Type},
lexer::Token, lexer::Token,
}; };
@ -21,7 +21,7 @@ pub enum Error {
Runtime(RuntimeError), Runtime(RuntimeError),
Validation { Validation {
error: ValidationError, error: ValidationError,
position: (usize, usize), position: SourcePosition,
}, },
} }
@ -160,10 +160,10 @@ pub enum ValidationError {
conflict: TypeConflict, conflict: TypeConflict,
/// The position of the item that gave the "actual" type. /// 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. /// The position of the item that gave the "expected" type.
expected_position: (usize, usize), expected_position: SourcePosition,
}, },
VariableNotFound(Identifier), VariableNotFound(Identifier),
} }

View File

@ -350,8 +350,8 @@ pub fn parser<'src>() -> DustParser<'src> {
let expression_statement = let expression_statement =
positioned_expression positioned_expression
.clone() .clone()
.map_with(|positioned_expression, state| { .map(|WithPosition { node, position }| {
Statement::Expression(positioned_expression.node).with_position(state.span()) Statement::Expression(node).with_position(position)
}); });
let r#break = just(Token::Keyword("break")) let r#break = just(Token::Keyword("break"))
@ -434,18 +434,17 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex("while true { output('hi') }").unwrap()).unwrap()[0], parse(&lex("while true { output('hi') }").unwrap()).unwrap()[0],
Statement::While(While::new( 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( Block::new(vec![Statement::Expression(Expression::FunctionCall(
FunctionCall::new( FunctionCall::new(
Expression::Identifier(Identifier::new("output")) Expression::Identifier(Identifier::new("output")).with_position((13, 19)),
.with_position((13..19).into()),
vec![Expression::Value(ValueNode::String("hi".to_string())) 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], parse(&lex("foobar : bool = true").unwrap()).unwrap()[0],
Statement::Assignment(Assignment::new( Statement::Assignment(Assignment::new(
Identifier::new("foobar"), Identifier::new("foobar"),
Some(Type::Boolean.with_position((9..14).into())), Some(Type::Boolean.with_position((9, 14))),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::Expression(Expression::Value(ValueNode::Boolean(true))) 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], parse(&lex("foobar : list(bool) = [true]").unwrap()).unwrap()[0],
Statement::Assignment(Assignment::new( Statement::Assignment(Assignment::new(
Identifier::new("foobar"), 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, AssignmentOperator::Assign,
Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value( Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value(
ValueNode::Boolean(true) ValueNode::Boolean(true)
) )
.with_position((23..27).into())]))) .with_position((23, 27))])))
.with_position((22..28).into()) .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], parse(&lex("foobar : [bool, str] = [true, '42']").unwrap()).unwrap()[0],
Statement::Assignment(Assignment::new( Statement::Assignment(Assignment::new(
Identifier::new("foobar"), Identifier::new("foobar"),
Some( Some(Type::ListExact(vec![Type::Boolean, Type::String]).with_position((9, 21))),
Type::ListExact(vec![Type::Boolean, Type::String])
.with_position((9..21).into())
),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::Expression(Expression::Value(ValueNode::List(vec![ Statement::Expression(Expression::Value(ValueNode::List(vec![
Expression::Value(ValueNode::Boolean(true)).with_position((24..28).into()), Expression::Value(ValueNode::Boolean(true)).with_position((24, 28)),
Expression::Value(ValueNode::String("42".to_string())) Expression::Value(ValueNode::String("42".to_string())).with_position((30, 34))
.with_position((30..34).into())
]))) ])))
.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![], parameter_types: vec![],
return_type: Box::new(Type::Any) return_type: Box::new(Type::Any)
} }
.with_position((9..19).into()) .with_position((9, 19))
), ),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::Expression(Expression::Identifier(Identifier::new("some_function"))) 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!( assert_eq!(
parse(&lex("output()").unwrap()).unwrap()[0], parse(&lex("output()").unwrap()).unwrap()[0],
Statement::Expression(Expression::FunctionCall(FunctionCall::new( 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), Vec::with_capacity(0),
))) )))
.with_position((0..8).into()) .with_position((0, 8))
) )
} }
@ -541,8 +536,7 @@ mod tests {
fn range() { fn range() {
assert_eq!( assert_eq!(
parse(&lex("1..10").unwrap()).unwrap()[0], parse(&lex("1..10").unwrap()).unwrap()[0],
Statement::Expression(Expression::Value(ValueNode::Range(1..10))) Statement::Expression(Expression::Value(ValueNode::Range(1..10))).with_position((0, 5))
.with_position((0..5).into())
) )
} }
@ -556,7 +550,7 @@ mod tests {
// return_type: Type::Integer, // return_type: Type::Integer,
// body: Block::new(vec![Statement::expression( // body: Block::new(vec![Statement::expression(
// Expression::Identifier(Identifier::new("x")), // Expression::Identifier(Identifier::new("x")),
// (0..0).into() // (0..0)
// )]) // )])
// }), // }),
// (0..0).into() // (0..0).into()