From 4179f6ebe50c7f6c36a3a1ea2c38f7759d8bd7e6 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 26 Feb 2024 16:27:01 -0500 Subject: [PATCH] Rework parser and abstract tree --- src/abstract_tree/assignment.rs | 50 +++--- src/abstract_tree/block.rs | 14 +- src/abstract_tree/expression.rs | 18 +-- src/abstract_tree/identifier.rs | 21 +-- src/abstract_tree/logic.rs | 32 ++-- src/abstract_tree/loop.rs | 10 +- src/abstract_tree/mod.rs | 9 +- src/abstract_tree/statement.rs | 20 +-- src/abstract_tree/value_node.rs | 72 +++++++++ src/context.rs | 17 +- src/lib.rs | 6 +- src/parser.rs | 258 +++++++++++++++++-------------- src/{abstract_tree => }/value.rs | 35 ++--- 13 files changed, 323 insertions(+), 239 deletions(-) create mode 100644 src/abstract_tree/value_node.rs rename src/{abstract_tree => }/value.rs (81%) diff --git a/src/abstract_tree/assignment.rs b/src/abstract_tree/assignment.rs index 2fdcdfa..c4fcdf4 100644 --- a/src/abstract_tree/assignment.rs +++ b/src/abstract_tree/assignment.rs @@ -1,15 +1,15 @@ -use crate::{error::RuntimeError, Context}; +use crate::{error::RuntimeError, value::Value, Context}; -use super::{AbstractTree, Identifier, Statement, Value}; +use super::{AbstractTree, Identifier, Statement}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub struct Assignment { - identifier: Identifier, - statement: Box, +pub struct Assignment<'src> { + identifier: Identifier<'src>, + statement: Box>, } -impl Assignment { - pub fn new(identifier: Identifier, statement: Statement) -> Self { +impl<'src> Assignment<'src> { + pub fn new(identifier: Identifier<'src>, statement: Statement<'src>) -> Self { Self { identifier, statement: Box::new(statement), @@ -17,34 +17,36 @@ impl Assignment { } } -impl AbstractTree for Assignment { - fn run(self, context: &Context) -> Result { - let value = self.statement.run(context)?; +impl<'src> AbstractTree for Assignment<'src> { + fn run(self, _context: &Context) -> Result { + todo!() + // let value = self.statement.run(context)?; - context.set(self.identifier, value)?; + // context.set(self.identifier, value)?; - Ok(Value::none()) + // Ok(Value::none()) } } #[cfg(test)] mod tests { - use super::*; + // use super::*; #[test] fn assign_value() { - let context = Context::new(); + todo!() + // let context = Context::new(); - Assignment::new( - Identifier::new("foobar"), - Statement::Value(Value::integer(42)), - ) - .run(&context) - .unwrap(); + // Assignment::new( + // Identifier::new("foobar"), + // Statement::Value(Value::integer(42)), + // ) + // .run(&context) + // .unwrap(); - assert_eq!( - context.get(&Identifier::new("foobar")).unwrap(), - Some(Value::integer(42)) - ) + // assert_eq!( + // context.get(&Identifier::new("foobar")).unwrap(), + // Some(Value::integer(42)) + // ) } } diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index 67215e1..616c39a 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -1,19 +1,19 @@ -use crate::{context::Context, error::RuntimeError}; +use crate::{context::Context, error::RuntimeError, Value}; -use super::{AbstractTree, Statement, Value}; +use super::{AbstractTree, Statement}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub struct Block { - statements: Vec, +pub struct Block<'src> { + statements: Vec>, } -impl Block { - pub fn new(statements: Vec) -> Self { +impl<'src> Block<'src> { + pub fn new(statements: Vec>) -> Self { Self { statements } } } -impl AbstractTree for Block { +impl<'src> AbstractTree for Block<'src> { fn run(self, _: &Context) -> Result { todo!() } diff --git a/src/abstract_tree/expression.rs b/src/abstract_tree/expression.rs index 1df2d84..d19e81a 100644 --- a/src/abstract_tree/expression.rs +++ b/src/abstract_tree/expression.rs @@ -1,20 +1,20 @@ -use crate::{context::Context, error::RuntimeError}; +use crate::{context::Context, error::RuntimeError, Value}; -use super::{AbstractTree, Identifier, Logic, Value}; +use super::{AbstractTree, Identifier, Logic, ValueNode}; -#[derive(Clone, Debug, PartialEq)] -pub enum Expression { - Identifier(Identifier), - Logic(Box), - Value(Value), +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub enum Expression<'src> { + Identifier(Identifier<'src>), + Logic(Box>), + Value(ValueNode<'src>), } -impl AbstractTree for Expression { +impl<'src> AbstractTree for Expression<'src> { fn run(self, context: &Context) -> Result { match self { Expression::Identifier(identifier) => identifier.run(context), Expression::Logic(logic) => logic.run(context), - Expression::Value(value) => value.run(context), + Expression::Value(value_node) => value_node.run(context), } } } diff --git a/src/abstract_tree/identifier.rs b/src/abstract_tree/identifier.rs index 30f44e3..3f545c7 100644 --- a/src/abstract_tree/identifier.rs +++ b/src/abstract_tree/identifier.rs @@ -1,20 +1,21 @@ -use crate::{context::Context, error::RuntimeError}; +use crate::{context::Context, error::RuntimeError, Value}; -use super::{AbstractTree, Value}; +use super::AbstractTree; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub struct Identifier(String); +pub struct Identifier<'src>(&'src str); -impl Identifier { - pub fn new(string: T) -> Identifier { - Identifier(string.to_string()) +impl<'src> Identifier<'src> { + pub fn new(string: &'src str) -> Self { + Identifier(string) } } -impl AbstractTree for Identifier { - fn run(self, context: &Context) -> Result { - let value = context.get(&self)?.unwrap_or_else(Value::none).clone(); +impl<'src> AbstractTree for Identifier<'src> { + fn run(self, _context: &Context) -> Result { + todo!() + // let value = context.get(&self)?.unwrap_or_else(Value::none).clone(); - Ok(value) + // Ok(value) } } diff --git a/src/abstract_tree/logic.rs b/src/abstract_tree/logic.rs index 42c2102..be32c1b 100644 --- a/src/abstract_tree/logic.rs +++ b/src/abstract_tree/logic.rs @@ -1,21 +1,21 @@ -use crate::{context::Context, error::RuntimeError}; +use crate::{context::Context, error::RuntimeError, Value}; -use super::{AbstractTree, Statement, Value}; +use super::{AbstractTree, Expression}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub enum Logic { - Equal(Statement, Statement), - NotEqual(Statement, Statement), - Greater(Statement, Statement), - Less(Statement, Statement), - GreaterOrEqual(Statement, Statement), - LessOrEqual(Statement, Statement), - And(Statement, Statement), - Or(Statement, Statement), - Not(Statement), +pub enum Logic<'src> { + Equal(Expression<'src>, Expression<'src>), + NotEqual(Expression<'src>, Expression<'src>), + Greater(Expression<'src>, Expression<'src>), + Less(Expression<'src>, Expression<'src>), + GreaterOrEqual(Expression<'src>, Expression<'src>), + LessOrEqual(Expression<'src>, Expression<'src>), + And(Expression<'src>, Expression<'src>), + Or(Expression<'src>, Expression<'src>), + Not(Expression<'src>), } -impl AbstractTree for Logic { +impl<'src> AbstractTree for Logic<'src> { fn run(self, _context: &Context) -> Result { let boolean = match self { Logic::Equal(left, right) => left.run(_context)? == right.run(_context)?, @@ -39,13 +39,15 @@ impl AbstractTree for Logic { #[cfg(test)] mod tests { + use crate::abstract_tree::{Expression, ValueNode}; + use super::*; #[test] fn equal() { assert!(Logic::Equal( - Statement::Value(Value::integer(42)), - Statement::Value(Value::integer(42)), + Expression::Value(ValueNode::Integer(42)), + Expression::Value(ValueNode::Integer(42)), ) .run(&Context::new()) .unwrap() diff --git a/src/abstract_tree/loop.rs b/src/abstract_tree/loop.rs index 3d3ce54..938a1c4 100644 --- a/src/abstract_tree/loop.rs +++ b/src/abstract_tree/loop.rs @@ -1,13 +1,13 @@ -use crate::{context::Context, error::RuntimeError}; +use crate::{context::Context, error::RuntimeError, Value}; -use super::{AbstractTree, Block, Value}; +use super::{AbstractTree, Block}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub struct Loop { - block: Block, +pub struct Loop<'src> { + block: Block<'src>, } -impl AbstractTree for Loop { +impl<'src> AbstractTree for Loop<'src> { fn run(self, _: &Context) -> Result { todo!() } diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index a437700..c3822e9 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -1,17 +1,18 @@ pub mod assignment; pub mod block; +pub mod expression; pub mod identifier; pub mod logic; pub mod r#loop; pub mod statement; -pub mod value; +pub mod value_node; pub use self::{ - assignment::Assignment, block::Block, identifier::Identifier, logic::Logic, r#loop::Loop, - statement::Statement, value::Value, + assignment::Assignment, block::Block, expression::Expression, identifier::Identifier, + logic::Logic, r#loop::Loop, statement::Statement, value_node::ValueNode, }; -use crate::{context::Context, error::RuntimeError}; +use crate::{context::Context, error::RuntimeError, Value}; pub trait AbstractTree { fn run(self, context: &Context) -> Result; diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index 47978a8..e37083f 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -1,26 +1,22 @@ use crate::{context::Context, error::RuntimeError}; -use super::{AbstractTree, Assignment, Block, Identifier, Logic, Loop, Value}; +use super::{AbstractTree, Assignment, Block, Expression, Loop, Value}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub enum Statement { - Assignment(Assignment), - Block(Block), - Identifier(Identifier), - Loop(Loop), - Value(Value), - Logic(Box), +pub enum Statement<'src> { + Assignment(Assignment<'src>), + Block(Block<'src>), + Expression(Expression<'src>), + Loop(Loop<'src>), } -impl AbstractTree for Statement { +impl<'src> AbstractTree for Statement<'src> { fn run(self, _context: &Context) -> Result { match self { Statement::Assignment(assignment) => assignment.run(_context), Statement::Block(_) => todo!(), - Statement::Identifier(identifier) => identifier.run(_context), + Statement::Expression(_) => todo!(), Statement::Loop(_) => todo!(), - Statement::Value(value) => value.run(_context), - Statement::Logic(_) => todo!(), } } } diff --git a/src/abstract_tree/value_node.rs b/src/abstract_tree/value_node.rs new file mode 100644 index 0000000..898663c --- /dev/null +++ b/src/abstract_tree/value_node.rs @@ -0,0 +1,72 @@ +use std::{cmp::Ordering, collections::BTreeMap, ops::Range}; + +use crate::{context::Context, error::RuntimeError, Value}; + +use super::{AbstractTree, Expression, Identifier}; + +#[derive(Clone, Debug, PartialEq)] +pub enum ValueNode<'src> { + Boolean(bool), + Float(f64), + Integer(i64), + List(Vec>), + Map(BTreeMap, Expression<'src>>), + Range(Range), + String(&'src str), + Enum(&'src str, &'src str), +} + +impl<'src> Eq for ValueNode<'src> {} + +impl<'src> PartialOrd for ValueNode<'src> { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl<'src> Ord for ValueNode<'src> { + fn cmp(&self, other: &Self) -> Ordering { + use ValueNode::*; + + match (self, other) { + (Boolean(left), Boolean(right)) => left.cmp(right), + (Boolean(_), _) => Ordering::Greater, + (Float(left), Float(right)) => left.total_cmp(right), + (Float(_), _) => Ordering::Greater, + (Integer(left), Integer(right)) => left.cmp(right), + (Integer(_), _) => Ordering::Greater, + (List(left), List(right)) => left.cmp(right), + (List(_), _) => Ordering::Greater, + (Map(left), Map(right)) => left.cmp(right), + (Map(_), _) => Ordering::Greater, + (Range(left), Range(right)) => { + let start_cmp = left.start.cmp(&right.start); + + if start_cmp.is_eq() { + left.end.cmp(&right.end) + } else { + start_cmp + } + } + (Range(_), _) => Ordering::Greater, + (String(left), String(right)) => left.cmp(right), + (String(_), _) => Ordering::Greater, + (Enum(left_name, left_variant), Enum(right_name, right_variant)) => { + let name_cmp = left_name.cmp(right_name); + + if name_cmp.is_eq() { + left_variant.cmp(right_variant) + } else { + name_cmp + } + } + (Enum(_, _), _) => Ordering::Greater, + } + } +} + +impl<'src> AbstractTree for ValueNode<'src> { + fn run(self, _context: &Context) -> Result { + todo!() + } +} diff --git a/src/context.rs b/src/context.rs index 1891278..9859894 100644 --- a/src/context.rs +++ b/src/context.rs @@ -3,13 +3,10 @@ use std::{ sync::{Arc, RwLock}, }; -use crate::{ - abstract_tree::{Identifier, Value}, - error::RwLockPoisonError, -}; +use crate::{error::RwLockPoisonError, Value}; pub struct Context { - inner: Arc>>, + inner: Arc>>, } impl Context { @@ -19,20 +16,20 @@ impl Context { } } - pub fn with_values(values: BTreeMap) -> Self { + pub fn with_values(values: BTreeMap) -> Self { Self { inner: Arc::new(RwLock::new(values)), } } - pub fn get(&self, identifier: &Identifier) -> Result, RwLockPoisonError> { - let value = self.inner.read()?.get(&identifier).cloned(); + pub fn get(&self, key: &str) -> Result, RwLockPoisonError> { + let value = self.inner.read()?.get(key).cloned(); Ok(value) } - pub fn set(&self, identifier: Identifier, value: Value) -> Result<(), RwLockPoisonError> { - self.inner.write()?.insert(identifier, value); + pub fn set(&self, key: String, value: Value) -> Result<(), RwLockPoisonError> { + self.inner.write()?.insert(key, value); Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index a6f7ba3..8c550bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,11 +3,13 @@ pub mod context; pub mod error; pub mod lexer; pub mod parser; +pub mod value; -use abstract_tree::{Statement, Value}; +use abstract_tree::Statement; use chumsky::{prelude::*, Parser}; use context::Context; use error::Error; +pub use value::Value; pub struct Interpreter

{ _parser: P, @@ -16,7 +18,7 @@ pub struct Interpreter

{ impl<'src, P> Interpreter

where - P: Parser<'src, &'src str, Statement, extra::Err>>, + P: Parser<'src, &'src str, Statement<'src>, extra::Err>>, { pub fn run(&self, _source: &'src str) -> Result> { todo!(); diff --git a/src/parser.rs b/src/parser.rs index b2f6a58..2f2ae51 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -8,93 +8,108 @@ type ParserInput<'tokens, 'src> = fn parser<'tokens, 'src: 'tokens>() -> impl Parser< 'tokens, ParserInput<'tokens, 'src>, - Vec<(Statement, SimpleSpan)>, + Vec<(Statement<'src>, SimpleSpan)>, extra::Err, SimpleSpan>>, > { - recursive(|statement| { - let identifier = select! { - Token::Identifier(text) => Identifier::new(text), - }; - - let identifier_statement = identifier.map(|identifier| Statement::Identifier(identifier)); + let identifier = select! { + Token::Identifier(text) => Identifier::new(text), + }; + let expression = recursive(|expression| { let basic_value = select! { - Token::None => Value::none(), - Token::Boolean(boolean) => Value::boolean(boolean), - Token::Integer(integer) => Value::integer(integer), - Token::Float(float) => Value::float(float), - Token::String(string) => Value::string(string.to_string()), + Token::None => ValueNode::Enum("Option", "None"), + Token::Boolean(boolean) => ValueNode::Boolean(boolean), + Token::Integer(integer) => ValueNode::Integer(integer), + Token::Float(float) => ValueNode::Float(float), + Token::String(string) => ValueNode::String(string), }; - let list = statement + let identifier_expression = identifier + .map(|identifier| Expression::Identifier(identifier)) + .boxed(); + + let list = expression .clone() .separated_by(just(Token::Control(','))) .allow_trailing() .collect() .delimited_by(just(Token::Control('[')), just(Token::Control(']'))) - .map(Value::list); + .map(ValueNode::List); let value = choice(( - basic_value.map(|value| Statement::Value(value)), - list.map(|list| Statement::Value(list)), + basic_value.map(|value| Expression::Value(value)), + list.map(|list| Expression::Value(list)), + )) + .boxed(); + + let atom = choice(( + identifier_expression.clone(), + value.clone(), + expression + .clone() + .delimited_by(just(Token::Control('(')), just(Token::Control(')'))), )); + let logic = atom + .pratt(( + prefix(2, just(Token::Operator("!")), |expression| { + Expression::Logic(Box::new(Logic::Not(expression))) + }), + infix(left(1), just(Token::Operator("==")), |left, right| { + Expression::Logic(Box::new(Logic::Equal(left, right))) + }), + infix(left(1), just(Token::Operator("!=")), |left, right| { + Expression::Logic(Box::new(Logic::NotEqual(left, right))) + }), + infix(left(1), just(Token::Operator(">")), |left, right| { + Expression::Logic(Box::new(Logic::Greater(left, right))) + }), + infix(left(1), just(Token::Operator("<")), |left, right| { + Expression::Logic(Box::new(Logic::Less(left, right))) + }), + infix(left(1), just(Token::Operator(">=")), |left, right| { + Expression::Logic(Box::new(Logic::GreaterOrEqual(left, right))) + }), + infix(left(1), just(Token::Operator("<=")), |left, right| { + Expression::Logic(Box::new(Logic::LessOrEqual(left, right))) + }), + infix(left(1), just(Token::Operator("&&")), |left, right| { + Expression::Logic(Box::new(Logic::And(left, right))) + }), + infix(left(1), just(Token::Operator("||")), |left, right| { + Expression::Logic(Box::new(Logic::Or(left, right))) + }), + )) + .boxed(); + + choice([logic, identifier_expression, value]) + }); + + let statement = recursive(|statement| { + let expression_statement = expression + .map(|expression| Statement::Expression(expression)) + .boxed(); + let assignment = identifier .then_ignore(just(Token::Operator("="))) .then(statement.clone()) .map(|(identifier, statement)| { Statement::Assignment(Assignment::new(identifier, statement)) - }); + }) + .boxed(); - let atom = choice(( - identifier_statement, - value.clone(), - assignment.clone(), - statement - .clone() - .delimited_by(just(Token::Control('(')), just(Token::Control(')'))), - )); + choice([assignment, expression_statement]) + }); - let logic = atom.pratt(( - prefix(2, just(Token::Operator("!")), |statement| { - Statement::Logic(Box::new(Logic::Not(statement))) - }), - infix(left(1), just(Token::Operator("==")), |left, right| { - Statement::Logic(Box::new(Logic::Equal(left, right))) - }), - infix(left(1), just(Token::Operator("!=")), |left, right| { - Statement::Logic(Box::new(Logic::NotEqual(left, right))) - }), - infix(left(1), just(Token::Operator(">")), |left, right| { - Statement::Logic(Box::new(Logic::Greater(left, right))) - }), - infix(left(1), just(Token::Operator("<")), |left, right| { - Statement::Logic(Box::new(Logic::Less(left, right))) - }), - infix(left(1), just(Token::Operator(">=")), |left, right| { - Statement::Logic(Box::new(Logic::GreaterOrEqual(left, right))) - }), - infix(left(1), just(Token::Operator("<=")), |left, right| { - Statement::Logic(Box::new(Logic::LessOrEqual(left, right))) - }), - infix(left(1), just(Token::Operator("&&")), |left, right| { - Statement::Logic(Box::new(Logic::And(left, right))) - }), - infix(left(1), just(Token::Operator("||")), |left, right| { - Statement::Logic(Box::new(Logic::Or(left, right))) - }), - )); - - choice((assignment, logic, value, identifier_statement)) - }) - .map_with(|statement, state| (statement, state.span())) - .repeated() - .collect() + statement + .map_with(|item, state| (item, state.span())) + .repeated() + .collect() } -pub fn parse<'tokens>( - tokens: &'tokens [(Token, SimpleSpan)], -) -> Result, Error<'tokens>> { +pub fn parse<'tokens, 'src: 'tokens>( + tokens: &'tokens [(Token<'src>, SimpleSpan)], +) -> Result, SimpleSpan)>, Error<'tokens>> { parser() .parse(tokens.spanned((0..0).into())) .into_result() @@ -103,10 +118,7 @@ pub fn parse<'tokens>( #[cfg(test)] mod tests { - use crate::{ - abstract_tree::{value::ValueInner, Logic}, - lexer::lex, - }; + use crate::{abstract_tree::Logic, lexer::lex}; use super::*; @@ -114,15 +126,15 @@ mod tests { fn identifier() { assert_eq!( parse(&lex("x").unwrap()).unwrap()[0].0, - Statement::Identifier(Identifier::new("x")), + Statement::Expression(Expression::Identifier(Identifier::new("x"))) ); assert_eq!( parse(&lex("foobar").unwrap()).unwrap()[0].0, - Statement::Identifier(Identifier::new("foobar")), + Statement::Expression(Expression::Identifier(Identifier::new("foobar"))) ); assert_eq!( parse(&lex("HELLO").unwrap()).unwrap()[0].0, - Statement::Identifier(Identifier::new("HELLO")), + Statement::Expression(Expression::Identifier(Identifier::new("HELLO"))) ); } @@ -132,7 +144,7 @@ mod tests { parse(&lex("foobar = 1").unwrap()).unwrap()[0].0, Statement::Assignment(Assignment::new( Identifier::new("foobar"), - Statement::Value(Value::integer(1)) + Statement::Expression(Expression::Value(ValueNode::Integer(1))) )), ); } @@ -141,10 +153,10 @@ mod tests { fn logic() { assert_eq!( parse(&lex("x == 1").unwrap()).unwrap()[0].0, - Statement::Logic(Box::new(Logic::Equal( - Statement::Identifier(Identifier::new("x")), - Statement::Value(Value::integer(1)) - ))), + Statement::Expression(Expression::Logic(Box::new(Logic::Equal( + Expression::Identifier(Identifier::new("x")), + Expression::Value(ValueNode::Integer(1)) + )))) ); } @@ -152,24 +164,26 @@ mod tests { fn list() { assert_eq!( parse(&lex("[]").unwrap()).unwrap()[0].0, - Statement::Value(Value::list(vec![])), + Statement::Expression(Expression::Value(ValueNode::List(Vec::with_capacity(0)))) ); assert_eq!( parse(&lex("[42]").unwrap()).unwrap()[0].0, - Statement::Value(Value::list(vec![Statement::Value(Value::integer(42))])), + Statement::Expression(Expression::Value(ValueNode::List(vec![Expression::Value( + ValueNode::Integer(42) + )]))) ); assert_eq!( parse(&lex("[42, 'foo', 'bar', [1, 2, 3,]]").unwrap()).unwrap()[0].0, - Statement::Value(Value::list(vec![ - Statement::Value(Value::integer(42)), - Statement::Value(Value::string("foo")), - Statement::Value(Value::string("bar")), - Statement::Value(Value::list(vec![ - Statement::Value(Value::integer(1)), - Statement::Value(Value::integer(2)), - Statement::Value(Value::integer(3)), + Statement::Expression(Expression::Value(ValueNode::List(vec![ + Expression::Value(ValueNode::Integer(42)), + Expression::Value(ValueNode::String("foo")), + Expression::Value(ValueNode::String("bar")), + Expression::Value(ValueNode::List(vec![ + Expression::Value(ValueNode::Integer(1)), + Expression::Value(ValueNode::Integer(2)), + Expression::Value(ValueNode::Integer(3)), ])) - ])), + ])),) ); } @@ -177,7 +191,7 @@ mod tests { fn r#true() { assert_eq!( parse(&lex("true").unwrap()).unwrap()[0].0, - Statement::Value(Value::boolean(true)) + Statement::Expression(Expression::Value(ValueNode::Boolean(true))) ); } @@ -185,7 +199,7 @@ mod tests { fn r#false() { assert_eq!( parse(&lex("false").unwrap()).unwrap()[0].0, - Statement::Value(Value::boolean(false)) + Statement::Expression(Expression::Value(ValueNode::Boolean(false))) ); } @@ -193,25 +207,25 @@ mod tests { fn positive_float() { assert_eq!( parse(&lex("0.0").unwrap()).unwrap()[0].0, - Statement::Value(Value::float(0.0)) + Statement::Expression(Expression::Value(ValueNode::Float(0.0))) ); assert_eq!( parse(&lex("42.0").unwrap()).unwrap()[0].0, - Statement::Value(Value::float(42.0)) + Statement::Expression(Expression::Value(ValueNode::Float(42.0))) ); let max_float = f64::MAX.to_string() + ".0"; assert_eq!( parse(&lex(&max_float).unwrap()).unwrap()[0].0, - Statement::Value(Value::float(f64::MAX)) + Statement::Expression(Expression::Value(ValueNode::Float(f64::MAX))) ); let min_positive_float = f64::MIN_POSITIVE.to_string(); assert_eq!( parse(&lex(&min_positive_float).unwrap()).unwrap()[0].0, - Statement::Value(Value::float(f64::MIN_POSITIVE)) + Statement::Expression(Expression::Value(ValueNode::Float(f64::MIN_POSITIVE))) ); } @@ -219,25 +233,25 @@ mod tests { fn negative_float() { assert_eq!( parse(&lex("-0.0").unwrap()).unwrap()[0].0, - Statement::Value(Value::float(-0.0)) + Statement::Expression(Expression::Value(ValueNode::Float(-0.0))) ); assert_eq!( parse(&lex("-42.0").unwrap()).unwrap()[0].0, - Statement::Value(Value::float(-42.0)) + Statement::Expression(Expression::Value(ValueNode::Float(-42.0))) ); let min_float = f64::MIN.to_string() + ".0"; assert_eq!( parse(&lex(&min_float).unwrap()).unwrap()[0].0, - Statement::Value(Value::float(f64::MIN)) + Statement::Expression(Expression::Value(ValueNode::Float(f64::MIN))) ); let max_negative_float = format!("-{}", f64::MIN_POSITIVE); assert_eq!( parse(&lex(&max_negative_float).unwrap()).unwrap()[0].0, - Statement::Value(Value::float(-f64::MIN_POSITIVE)) + Statement::Expression(Expression::Value(ValueNode::Float(-f64::MIN_POSITIVE))) ); } @@ -245,20 +259,20 @@ mod tests { fn other_float() { assert_eq!( parse(&lex("Infinity").unwrap()).unwrap()[0].0, - Statement::Value(Value::float(f64::INFINITY)) + Statement::Expression(Expression::Value(ValueNode::Float(f64::INFINITY))) ); assert_eq!( parse(&lex("-Infinity").unwrap()).unwrap()[0].0, - Statement::Value(Value::float(f64::NEG_INFINITY)) + Statement::Expression(Expression::Value(ValueNode::Float(f64::NEG_INFINITY))) ); - if let Statement::Value(value) = &parse(&lex("NaN").unwrap()).unwrap()[0].0 { - if let ValueInner::Float(float) = value.inner().as_ref() { - return assert!(float.is_nan()); - } + if let Statement::Expression(Expression::Value(ValueNode::Float(float))) = + &parse(&lex("NaN").unwrap()).unwrap()[0].0 + { + assert!(float.is_nan()); + } else { + panic!("Expected a float."); } - - panic!("Expected a float.") } #[test] @@ -267,19 +281,22 @@ mod tests { let source = i.to_string(); let statements = parse(&lex(&source).unwrap()).unwrap(); - assert_eq!(statements[0].0, Statement::Value(Value::integer(i))) + assert_eq!( + statements[0].0, + Statement::Expression(Expression::Value(ValueNode::Integer(i))) + ) } assert_eq!( parse(&lex("42").unwrap()).unwrap()[0].0, - Statement::Value(Value::integer(42)) + Statement::Expression(Expression::Value(ValueNode::Integer(42))) ); let maximum_integer = i64::MAX.to_string(); assert_eq!( parse(&lex(&maximum_integer).unwrap()).unwrap()[0].0, - Statement::Value(Value::integer(i64::MAX)) + Statement::Expression(Expression::Value(ValueNode::Integer(i64::MAX))) ); } @@ -289,19 +306,22 @@ mod tests { let source = i.to_string(); let statements = parse(&lex(&source).unwrap()).unwrap(); - assert_eq!(statements[0].0, Statement::Value(Value::integer(i))) + assert_eq!( + statements[0].0, + Statement::Expression(Expression::Value(ValueNode::Integer(i))) + ) } assert_eq!( parse(&lex("-42").unwrap()).unwrap()[0].0, - Statement::Value(Value::integer(-42)) + Statement::Expression(Expression::Value(ValueNode::Integer(-42))) ); let minimum_integer = i64::MIN.to_string(); assert_eq!( parse(&lex(&minimum_integer).unwrap()).unwrap()[0].0, - Statement::Value(Value::integer(i64::MIN)) + Statement::Expression(Expression::Value(ValueNode::Integer(i64::MIN))) ); } @@ -309,15 +329,15 @@ mod tests { fn double_quoted_string() { assert_eq!( parse(&lex("\"\"").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("".to_string())) + Statement::Expression(Expression::Value(ValueNode::String(""))) ); assert_eq!( parse(&lex("\"42\"").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("42".to_string())) + Statement::Expression(Expression::Value(ValueNode::String("42"))) ); assert_eq!( parse(&lex("\"foobar\"").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("foobar".to_string())) + Statement::Expression(Expression::Value(ValueNode::String("foobar"))) ); } @@ -325,15 +345,15 @@ mod tests { fn single_quoted_string() { assert_eq!( parse(&lex("''").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("".to_string())) + Statement::Expression(Expression::Value(ValueNode::String(""))) ); assert_eq!( parse(&lex("'42'").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("42".to_string())) + Statement::Expression(Expression::Value(ValueNode::String("42"))) ); assert_eq!( parse(&lex("'foobar'").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("foobar".to_string())) + Statement::Expression(Expression::Value(ValueNode::String("foobar"))) ); } @@ -341,15 +361,15 @@ mod tests { fn grave_quoted_string() { assert_eq!( parse(&lex("``").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("".to_string())) + Statement::Expression(Expression::Value(ValueNode::String(""))) ); assert_eq!( parse(&lex("`42`").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("42".to_string())) + Statement::Expression(Expression::Value(ValueNode::String("42"))) ); assert_eq!( parse(&lex("`foobar`").unwrap()).unwrap()[0].0, - Statement::Value(Value::string("foobar".to_string())) + Statement::Expression(Expression::Value(ValueNode::String("foobar"))) ); } } diff --git a/src/abstract_tree/value.rs b/src/value.rs similarity index 81% rename from src/abstract_tree/value.rs rename to src/value.rs index cb01337..043d611 100644 --- a/src/abstract_tree/value.rs +++ b/src/value.rs @@ -1,13 +1,10 @@ use std::{ cmp::Ordering, - collections::BTreeMap, ops::Range, sync::{Arc, OnceLock}, }; -use crate::{context::Context, error::RuntimeError}; - -use super::{AbstractTree, Identifier, Statement}; +use crate::error::RuntimeError; pub static NONE: OnceLock = OnceLock::new(); @@ -22,8 +19,8 @@ impl Value { pub fn none() -> Self { NONE.get_or_init(|| { Value::r#enum(EnumInstance { - type_name: Identifier::new("Option"), - variant: Identifier::new("None"), + type_name: "Option".to_string(), + variant: "None".to_string(), }) }) .clone() @@ -41,13 +38,13 @@ impl Value { Value(Arc::new(ValueInner::Integer(integer))) } - pub fn list(list: Vec) -> Self { + pub fn list(list: Vec) -> Self { Value(Arc::new(ValueInner::List(list))) } - pub fn map(map: BTreeMap) -> Self { - Value(Arc::new(ValueInner::Map(map))) - } + // pub fn map(map: BTreeMap) -> Self { + // Value(Arc::new(ValueInner::Map(map))) + // } pub fn range(range: Range) -> Self { Value(Arc::new(ValueInner::Range(range))) @@ -89,8 +86,8 @@ pub enum ValueInner { Boolean(bool), Float(f64), Integer(i64), - List(Vec), - Map(BTreeMap), + List(Vec), + // Map(BTreeMap), Range(Range), String(String), Enum(EnumInstance), @@ -117,8 +114,8 @@ impl Ord for ValueInner { (Integer(_), _) => Ordering::Greater, (List(left), List(right)) => left.cmp(right), (List(_), _) => Ordering::Greater, - (Map(left), Map(right)) => left.cmp(right), - (Map(_), _) => Ordering::Greater, + // (Map(left), Map(right)) => left.cmp(right), + // (Map(_), _) => Ordering::Greater, (Range(left), Range(right)) => { let start_cmp = left.start.cmp(&right.start); @@ -139,12 +136,6 @@ impl Ord for ValueInner { #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub struct EnumInstance { - type_name: Identifier, - variant: Identifier, -} - -impl AbstractTree for Value { - fn run(self, _: &Context) -> Result { - Ok(self) - } + type_name: String, + variant: String, }