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"),
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(),
})
)
}

View File

@ -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))

View File

@ -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()),

View File

@ -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())
}
}

View File

@ -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());

View File

@ -41,7 +41,22 @@ use crate::{
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct WithPosition<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 {
@ -49,10 +64,10 @@ pub trait AbstractTree: Sized {
fn validate(&self, context: &Context) -> Result<(), ValidationError>;
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 {
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 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),
}

View File

@ -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()