Begin adding spans to abstract tree types
This commit is contained in:
parent
5b79af6e85
commit
10b8d8e0a8
@ -13,6 +13,8 @@ pub mod r#type;
|
||||
pub mod value_node;
|
||||
pub mod r#while;
|
||||
|
||||
use chumsky::span::{SimpleSpan, Span};
|
||||
|
||||
pub use self::{
|
||||
assignment::{Assignment, AssignmentOperator},
|
||||
block::Block,
|
||||
@ -36,6 +38,47 @@ use crate::{
|
||||
Value,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Item<A: AbstractTree>(pub A, pub SimpleSpan);
|
||||
|
||||
impl<A> Ord for Item<A>
|
||||
where
|
||||
A: AbstractTree + Eq + PartialEq,
|
||||
{
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
let start_cmp = self.1.start().cmp(&other.1.start());
|
||||
|
||||
if start_cmp.is_eq() {
|
||||
self.1.end().cmp(&other.1.end())
|
||||
} else {
|
||||
start_cmp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: AbstractTree> PartialOrd for Item<A>
|
||||
where
|
||||
A: AbstractTree + Eq + PartialEq,
|
||||
{
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: AbstractTree> AbstractTree for Item<A> {
|
||||
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn run(self, context: &Context) -> Result<Action, RuntimeError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AbstractTree {
|
||||
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError>;
|
||||
fn validate(&self, context: &Context) -> Result<(), ValidationError>;
|
||||
|
@ -3,11 +3,11 @@ use crate::{
|
||||
error::{RuntimeError, ValidationError},
|
||||
};
|
||||
|
||||
use super::{AbstractTree, Action, Assignment, Block, Expression, IfElse, Loop, Type, While};
|
||||
use super::{AbstractTree, Action, Assignment, Block, Expression, IfElse, Item, Loop, Type, While};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub enum Statement {
|
||||
Assignment(Assignment),
|
||||
Assignment(Item<Assignment>),
|
||||
Block(Block),
|
||||
Break,
|
||||
Expression(Expression),
|
||||
|
153
src/parser.rs
153
src/parser.rs
@ -306,8 +306,10 @@ pub fn parser<'src>() -> DustParser<'src> {
|
||||
just(Token::Operator(Operator::SubAssign)).to(AssignmentOperator::SubAssign),
|
||||
)))
|
||||
.then(statement.clone())
|
||||
.map(|(((identifier, r#type), operator), statement)| {
|
||||
Statement::Assignment(Assignment::new(identifier, r#type, operator, statement))
|
||||
.map_with(|(((identifier, r#type), operator), statement), state| {
|
||||
let assignment = Assignment::new(identifier, r#type, operator, statement);
|
||||
|
||||
Statement::Assignment(Item(assignment, state.span()))
|
||||
})
|
||||
.boxed();
|
||||
|
||||
@ -389,46 +391,58 @@ mod tests {
|
||||
fn types() {
|
||||
assert_eq!(
|
||||
parse(&lex("foobar : bool = true").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::Boolean),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::Boolean(true)))
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::Boolean),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::Boolean(true)))
|
||||
),
|
||||
(0..20).into()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
parse(&lex("foobar : list(bool) = [true]").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListOf(Box::new(Type::Boolean))),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value(
|
||||
ValueNode::Boolean(true)
|
||||
)])))
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListOf(Box::new(Type::Boolean))),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||
Expression::Value(ValueNode::Boolean(true))
|
||||
])))
|
||||
),
|
||||
(0..28).into()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
parse(&lex("foobar : [bool, str] = [true, '42']").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListExact(vec![Type::Boolean, Type::String])),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||
Expression::Value(ValueNode::Boolean(true)),
|
||||
Expression::Value(ValueNode::String("42".to_string()))
|
||||
])))
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListExact(vec![Type::Boolean, Type::String])),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||
Expression::Value(ValueNode::Boolean(true)),
|
||||
Expression::Value(ValueNode::String("42".to_string()))
|
||||
])))
|
||||
),
|
||||
(0..35).into()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
parse(&lex("foobar : () -> any = some_function").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::Function {
|
||||
parameter_types: vec![],
|
||||
return_type: Box::new(Type::Any)
|
||||
}),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Identifier(Identifier::new("some_function")))
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::Function {
|
||||
parameter_types: vec![],
|
||||
return_type: Box::new(Type::Any)
|
||||
}),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Identifier(Identifier::new("some_function")))
|
||||
),
|
||||
(0..34).into()
|
||||
))
|
||||
);
|
||||
}
|
||||
@ -630,12 +644,15 @@ mod tests {
|
||||
fn assignment() {
|
||||
assert_eq!(
|
||||
parse(&lex("foobar = 1").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
None,
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
||||
)),
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
None,
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
||||
),
|
||||
(0..0).into()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
@ -643,12 +660,15 @@ mod tests {
|
||||
fn assignment_with_basic_type() {
|
||||
assert_eq!(
|
||||
parse(&lex("foobar: int = 1").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::Integer),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
||||
)),
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::Integer),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
||||
),
|
||||
(0..0).into()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
@ -656,35 +676,44 @@ mod tests {
|
||||
fn assignment_with_list_types() {
|
||||
assert_eq!(
|
||||
parse(&lex("foobar: list = []").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::List),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![])))
|
||||
)),
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::List),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![])))
|
||||
),
|
||||
(0..0).into()
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse(&lex("foobar: list(int) = []").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListOf(Box::new(Type::Integer))),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![])))
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListOf(Box::new(Type::Integer))),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![])))
|
||||
),
|
||||
(0..0).into()
|
||||
)),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse(&lex("foobar: [int, str] = [ 42, 'foo' ]").unwrap()).unwrap()[0].0,
|
||||
Statement::Assignment(Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListExact(vec![Type::Integer, Type::String])),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||
Expression::Value(ValueNode::Integer(42)),
|
||||
Expression::Value(ValueNode::String("foo".to_string()))
|
||||
])))
|
||||
)),
|
||||
Statement::Assignment(Item(
|
||||
Assignment::new(
|
||||
Identifier::new("foobar"),
|
||||
Some(Type::ListExact(vec![Type::Integer, Type::String])),
|
||||
AssignmentOperator::Assign,
|
||||
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||
Expression::Value(ValueNode::Integer(42)),
|
||||
Expression::Value(ValueNode::String("foo".to_string()))
|
||||
])))
|
||||
),
|
||||
(0..0).into()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user