From 10b8d8e0a86784406e6cbc86a3dc65224e67cf72 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 15 Mar 2024 14:34:40 -0400 Subject: [PATCH] Begin adding spans to abstract tree types --- src/abstract_tree/mod.rs | 43 +++++++++ src/abstract_tree/statement.rs | 4 +- src/parser.rs | 153 ++++++++++++++++++++------------- 3 files changed, 136 insertions(+), 64 deletions(-) diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index dd9ff4a..ad7685e 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -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(pub A, pub SimpleSpan); + +impl Ord for Item +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 PartialOrd for Item +where + A: AbstractTree + Eq + PartialEq, +{ + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl AbstractTree for Item { + fn expected_type(&self, context: &Context) -> Result { + todo!() + } + + fn validate(&self, context: &Context) -> Result<(), ValidationError> { + todo!() + } + + fn run(self, context: &Context) -> Result { + todo!() + } +} + pub trait AbstractTree { fn expected_type(&self, context: &Context) -> Result; fn validate(&self, context: &Context) -> Result<(), ValidationError>; diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index af8afd6..1d34dac 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -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), Block(Block), Break, Expression(Expression), diff --git a/src/parser.rs b/src/parser.rs index 869e4a7..4e4de22 100644 --- a/src/parser.rs +++ b/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() + )) ); }