1
0

Begin adding spans to abstract tree types

This commit is contained in:
Jeff 2024-03-15 14:34:40 -04:00
parent 5b79af6e85
commit 10b8d8e0a8
3 changed files with 136 additions and 64 deletions

View File

@ -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>;

View File

@ -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),

View File

@ -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()
))
); );
} }