Fix tests and parser
This commit is contained in:
parent
062a3b606c
commit
199e1c9184
@ -14,6 +14,10 @@ impl Block {
|
|||||||
pub fn new(statements: Vec<WithPosition<Statement>>) -> Self {
|
pub fn new(statements: Vec<WithPosition<Statement>>) -> Self {
|
||||||
Self { statements }
|
Self { statements }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn last_statement(&self) -> &WithPosition<Statement> {
|
||||||
|
self.statements.last().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Block {
|
impl AbstractTree for Block {
|
||||||
|
@ -8,15 +8,15 @@ use super::{AbstractTree, Action, Block, Expression, Type, WithPosition};
|
|||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct IfElse {
|
pub struct IfElse {
|
||||||
if_expression: WithPosition<Expression>,
|
if_expression: WithPosition<Expression>,
|
||||||
if_block: WithPosition<Block>,
|
if_block: Block,
|
||||||
else_block: Option<WithPosition<Block>>,
|
else_block: Option<Block>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IfElse {
|
impl IfElse {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
if_expression: WithPosition<Expression>,
|
if_expression: WithPosition<Expression>,
|
||||||
if_block: WithPosition<Block>,
|
if_block: Block,
|
||||||
else_block: Option<WithPosition<Block>>,
|
else_block: Option<Block>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
if_expression,
|
if_expression,
|
||||||
@ -28,20 +28,20 @@ impl IfElse {
|
|||||||
|
|
||||||
impl AbstractTree for IfElse {
|
impl AbstractTree for IfElse {
|
||||||
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
self.if_block.node.expected_type(_context)
|
self.if_block.expected_type(_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, context: &Context) -> Result<(), ValidationError> {
|
fn validate(&self, context: &Context) -> Result<(), ValidationError> {
|
||||||
if let Type::Boolean = self.if_expression.node.expected_type(context)? {
|
if let Type::Boolean = self.if_expression.node.expected_type(context)? {
|
||||||
if let Some(else_block) = &self.else_block {
|
if let Some(else_block) = &self.else_block {
|
||||||
let expected = self.if_block.node.expected_type(context)?;
|
let expected = self.if_block.expected_type(context)?;
|
||||||
let actual = else_block.node.expected_type(context)?;
|
let actual = else_block.expected_type(context)?;
|
||||||
|
|
||||||
expected
|
expected
|
||||||
.check(&actual)
|
.check(&actual)
|
||||||
.map_err(|conflict| ValidationError::TypeCheck {
|
.map_err(|conflict| ValidationError::TypeCheck {
|
||||||
conflict,
|
conflict,
|
||||||
actual_position: self.if_block.position,
|
actual_position: self.if_block.last_statement().position,
|
||||||
expected_position: self.if_expression.position,
|
expected_position: self.if_expression.position,
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
@ -61,9 +61,9 @@ impl AbstractTree for IfElse {
|
|||||||
.as_boolean()?;
|
.as_boolean()?;
|
||||||
|
|
||||||
if if_boolean {
|
if if_boolean {
|
||||||
self.if_block.node.run(_context)
|
self.if_block.run(_context)
|
||||||
} else if let Some(else_statement) = self.else_block {
|
} else if let Some(else_statement) = self.else_block {
|
||||||
else_statement.node.run(_context)
|
else_statement.run(_context)
|
||||||
} else {
|
} else {
|
||||||
Ok(Action::None)
|
Ok(Action::None)
|
||||||
}
|
}
|
||||||
@ -87,8 +87,7 @@ mod tests {
|
|||||||
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))])
|
.with_position((0, 0))]),
|
||||||
.with_position((0, 0)),
|
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
.run(&Context::new()),
|
.run(&Context::new()),
|
||||||
@ -104,15 +103,11 @@ mod tests {
|
|||||||
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))])
|
.with_position((0, 0))]),
|
||||||
.with_position((0, 0)),
|
Some(Block::new(vec![Statement::Expression(Expression::Value(
|
||||||
Some(
|
ValueNode::String("bar".to_string())
|
||||||
Block::new(vec![Statement::Expression(Expression::Value(
|
))
|
||||||
ValueNode::String("bar".to_string())
|
.with_position((0, 0))]))
|
||||||
))
|
|
||||||
.with_position((0, 0))])
|
|
||||||
.with_position((0, 0))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
.run(&Context::new()),
|
.run(&Context::new()),
|
||||||
Ok(Action::Return(Value::string("bar".to_string())))
|
Ok(Action::Return(Value::string("bar".to_string())))
|
||||||
|
@ -121,10 +121,6 @@ pub fn parser<'src>() -> DustParser<'src> {
|
|||||||
)
|
)
|
||||||
.map(|statements| Block::new(statements));
|
.map(|statements| Block::new(statements));
|
||||||
|
|
||||||
let positioned_block = block
|
|
||||||
.clone()
|
|
||||||
.map_with(|block, state| block.with_position(state.span()));
|
|
||||||
|
|
||||||
let positioned_expression = recursive(|positioned_expression| {
|
let positioned_expression = recursive(|positioned_expression| {
|
||||||
let identifier_expression = identifier.clone().map_with(|identifier, state| {
|
let identifier_expression = identifier.clone().map_with(|identifier, state| {
|
||||||
Expression::Identifier(identifier).with_position(state.span())
|
Expression::Identifier(identifier).with_position(state.span())
|
||||||
@ -336,10 +332,10 @@ pub fn parser<'src>() -> DustParser<'src> {
|
|||||||
));
|
));
|
||||||
|
|
||||||
choice((
|
choice((
|
||||||
function,
|
|
||||||
function_call,
|
|
||||||
range,
|
range,
|
||||||
logic_math_and_index,
|
logic_math_and_index,
|
||||||
|
function,
|
||||||
|
function_call,
|
||||||
identifier_expression,
|
identifier_expression,
|
||||||
list,
|
list,
|
||||||
map,
|
map,
|
||||||
@ -397,10 +393,10 @@ pub fn parser<'src>() -> DustParser<'src> {
|
|||||||
|
|
||||||
let if_else = just(Token::Keyword("if"))
|
let if_else = just(Token::Keyword("if"))
|
||||||
.ignore_then(positioned_expression.clone())
|
.ignore_then(positioned_expression.clone())
|
||||||
.then(positioned_block.clone())
|
.then(block.clone())
|
||||||
.then(
|
.then(
|
||||||
just(Token::Keyword("else"))
|
just(Token::Keyword("else"))
|
||||||
.ignore_then(positioned_block.clone())
|
.ignore_then(block.clone())
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.map_with(|((if_expression, if_block), else_block), state| {
|
.map_with(|((if_expression, if_block), else_block), state| {
|
||||||
@ -574,8 +570,7 @@ mod tests {
|
|||||||
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((10, 15))])
|
.with_position((10, 15))]),
|
||||||
.with_position((8, 17)),
|
|
||||||
None
|
None
|
||||||
),)
|
),)
|
||||||
);
|
);
|
||||||
@ -590,15 +585,11 @@ mod tests {
|
|||||||
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((9, 14))])
|
.with_position((9, 14))]),
|
||||||
.with_position((8, 17)),
|
Some(Block::new(vec![Statement::Expression(Expression::Value(
|
||||||
Some(
|
ValueNode::String("bar".to_string())
|
||||||
Block::new(vec![Statement::Expression(Expression::Value(
|
),)
|
||||||
ValueNode::String("bar".to_string())
|
.with_position((24, 29))]))
|
||||||
),)
|
|
||||||
.with_position((24, 29))])
|
|
||||||
.with_position((22, 31))
|
|
||||||
)
|
|
||||||
),)
|
),)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ fn function_context_does_not_capture_values() {
|
|||||||
),
|
),
|
||||||
Err(vec![Error::Validation {
|
Err(vec![Error::Validation {
|
||||||
error: ValidationError::VariableNotFound(Identifier::new("x")),
|
error: ValidationError::VariableNotFound(Identifier::new("x")),
|
||||||
position: (0, 0).into()
|
position: (32, 66).into()
|
||||||
}])
|
}])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user