Fix tests; Add SourcePosition type
This commit is contained in:
parent
4ea19f238e
commit
1b367d4dfb
@ -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(),
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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()),
|
||||
|
@ -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())
|
||||
.unwrap()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user