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 value_node;
|
||||||
pub mod r#while;
|
pub mod r#while;
|
||||||
|
|
||||||
|
use chumsky::span::{SimpleSpan, Span};
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
assignment::{Assignment, AssignmentOperator},
|
assignment::{Assignment, AssignmentOperator},
|
||||||
block::Block,
|
block::Block,
|
||||||
@ -36,6 +38,47 @@ use crate::{
|
|||||||
Value,
|
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 {
|
pub trait AbstractTree {
|
||||||
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError>;
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError>;
|
||||||
fn validate(&self, context: &Context) -> Result<(), ValidationError>;
|
fn validate(&self, context: &Context) -> Result<(), ValidationError>;
|
||||||
|
@ -3,11 +3,11 @@ use crate::{
|
|||||||
error::{RuntimeError, ValidationError},
|
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)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
Assignment(Assignment),
|
Assignment(Item<Assignment>),
|
||||||
Block(Block),
|
Block(Block),
|
||||||
Break,
|
Break,
|
||||||
Expression(Expression),
|
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),
|
just(Token::Operator(Operator::SubAssign)).to(AssignmentOperator::SubAssign),
|
||||||
)))
|
)))
|
||||||
.then(statement.clone())
|
.then(statement.clone())
|
||||||
.map(|(((identifier, r#type), operator), statement)| {
|
.map_with(|(((identifier, r#type), operator), statement), state| {
|
||||||
Statement::Assignment(Assignment::new(identifier, r#type, operator, statement))
|
let assignment = Assignment::new(identifier, r#type, operator, statement);
|
||||||
|
|
||||||
|
Statement::Assignment(Item(assignment, state.span()))
|
||||||
})
|
})
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
@ -389,46 +391,58 @@ mod tests {
|
|||||||
fn types() {
|
fn types() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar : bool = true").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar : bool = true").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
Some(Type::Boolean),
|
Identifier::new("foobar"),
|
||||||
AssignmentOperator::Assign,
|
Some(Type::Boolean),
|
||||||
Statement::Expression(Expression::Value(ValueNode::Boolean(true)))
|
AssignmentOperator::Assign,
|
||||||
|
Statement::Expression(Expression::Value(ValueNode::Boolean(true)))
|
||||||
|
),
|
||||||
|
(0..20).into()
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar : list(bool) = [true]").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar : list(bool) = [true]").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
Some(Type::ListOf(Box::new(Type::Boolean))),
|
Identifier::new("foobar"),
|
||||||
AssignmentOperator::Assign,
|
Some(Type::ListOf(Box::new(Type::Boolean))),
|
||||||
Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value(
|
AssignmentOperator::Assign,
|
||||||
ValueNode::Boolean(true)
|
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||||
)])))
|
Expression::Value(ValueNode::Boolean(true))
|
||||||
|
])))
|
||||||
|
),
|
||||||
|
(0..28).into()
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar : [bool, str] = [true, '42']").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar : [bool, str] = [true, '42']").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
Some(Type::ListExact(vec![Type::Boolean, Type::String])),
|
Identifier::new("foobar"),
|
||||||
AssignmentOperator::Assign,
|
Some(Type::ListExact(vec![Type::Boolean, Type::String])),
|
||||||
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
AssignmentOperator::Assign,
|
||||||
Expression::Value(ValueNode::Boolean(true)),
|
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||||
Expression::Value(ValueNode::String("42".to_string()))
|
Expression::Value(ValueNode::Boolean(true)),
|
||||||
])))
|
Expression::Value(ValueNode::String("42".to_string()))
|
||||||
|
])))
|
||||||
|
),
|
||||||
|
(0..35).into()
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar : () -> any = some_function").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar : () -> any = some_function").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
Some(Type::Function {
|
Identifier::new("foobar"),
|
||||||
parameter_types: vec![],
|
Some(Type::Function {
|
||||||
return_type: Box::new(Type::Any)
|
parameter_types: vec![],
|
||||||
}),
|
return_type: Box::new(Type::Any)
|
||||||
AssignmentOperator::Assign,
|
}),
|
||||||
Statement::Expression(Expression::Identifier(Identifier::new("some_function")))
|
AssignmentOperator::Assign,
|
||||||
|
Statement::Expression(Expression::Identifier(Identifier::new("some_function")))
|
||||||
|
),
|
||||||
|
(0..34).into()
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -630,12 +644,15 @@ mod tests {
|
|||||||
fn assignment() {
|
fn assignment() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar = 1").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar = 1").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
None,
|
Identifier::new("foobar"),
|
||||||
AssignmentOperator::Assign,
|
None,
|
||||||
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
AssignmentOperator::Assign,
|
||||||
)),
|
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
||||||
|
),
|
||||||
|
(0..0).into()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,12 +660,15 @@ mod tests {
|
|||||||
fn assignment_with_basic_type() {
|
fn assignment_with_basic_type() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar: int = 1").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar: int = 1").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
Some(Type::Integer),
|
Identifier::new("foobar"),
|
||||||
AssignmentOperator::Assign,
|
Some(Type::Integer),
|
||||||
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
AssignmentOperator::Assign,
|
||||||
)),
|
Statement::Expression(Expression::Value(ValueNode::Integer(1)))
|
||||||
|
),
|
||||||
|
(0..0).into()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,35 +676,44 @@ mod tests {
|
|||||||
fn assignment_with_list_types() {
|
fn assignment_with_list_types() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar: list = []").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar: list = []").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
Some(Type::List),
|
Identifier::new("foobar"),
|
||||||
AssignmentOperator::Assign,
|
Some(Type::List),
|
||||||
Statement::Expression(Expression::Value(ValueNode::List(vec![])))
|
AssignmentOperator::Assign,
|
||||||
)),
|
Statement::Expression(Expression::Value(ValueNode::List(vec![])))
|
||||||
|
),
|
||||||
|
(0..0).into()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar: list(int) = []").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar: list(int) = []").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
Some(Type::ListOf(Box::new(Type::Integer))),
|
Identifier::new("foobar"),
|
||||||
AssignmentOperator::Assign,
|
Some(Type::ListOf(Box::new(Type::Integer))),
|
||||||
Statement::Expression(Expression::Value(ValueNode::List(vec![])))
|
AssignmentOperator::Assign,
|
||||||
|
Statement::Expression(Expression::Value(ValueNode::List(vec![])))
|
||||||
|
),
|
||||||
|
(0..0).into()
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(&lex("foobar: [int, str] = [ 42, 'foo' ]").unwrap()).unwrap()[0].0,
|
parse(&lex("foobar: [int, str] = [ 42, 'foo' ]").unwrap()).unwrap()[0].0,
|
||||||
Statement::Assignment(Assignment::new(
|
Statement::Assignment(Item(
|
||||||
Identifier::new("foobar"),
|
Assignment::new(
|
||||||
Some(Type::ListExact(vec![Type::Integer, Type::String])),
|
Identifier::new("foobar"),
|
||||||
AssignmentOperator::Assign,
|
Some(Type::ListExact(vec![Type::Integer, Type::String])),
|
||||||
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
AssignmentOperator::Assign,
|
||||||
Expression::Value(ValueNode::Integer(42)),
|
Statement::Expression(Expression::Value(ValueNode::List(vec![
|
||||||
Expression::Value(ValueNode::String("foo".to_string()))
|
Expression::Value(ValueNode::Integer(42)),
|
||||||
])))
|
Expression::Value(ValueNode::String("foo".to_string()))
|
||||||
)),
|
])))
|
||||||
|
),
|
||||||
|
(0..0).into()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user