diff --git a/src/ast/parser.rs b/src/ast/parser.rs index 4c33829..2f744a8 100644 --- a/src/ast/parser.rs +++ b/src/ast/parser.rs @@ -144,7 +144,7 @@ impl<'a, T: Iterator>> Parser<'a, T> { fn primary(&mut self) -> Result { let node = match self.token_iter.next().map(|it| it.token_type) { Some(TokenType::False) => ASTNode::Literal(astnode::Literal::Bool(false)), - Some(TokenType::True) => ASTNode::Literal(astnode::Literal::Bool(false)), + Some(TokenType::True) => ASTNode::Literal(astnode::Literal::Bool(true)), Some(TokenType::Int(i)) => ASTNode::Literal(astnode::Literal::Int(i)), Some(TokenType::String(i)) => ASTNode::Literal(astnode::Literal::String(i)), Some(TokenType::Float(f)) => ASTNode::Literal(astnode::Literal::Float(f)), diff --git a/src/interpreter/ast_walker.rs b/src/interpreter/ast_walker.rs index f8c8539..268e600 100644 --- a/src/interpreter/ast_walker.rs +++ b/src/interpreter/ast_walker.rs @@ -47,9 +47,9 @@ impl Interpret for astnode::BinaryExpr { impl Interpret for astnode::UnaryExpr { fn interpret(&self) -> Result { - let _val = self.right.interpret(); + let val = self.right.interpret()?; match self.operator { - UnaryOperator::Bang => todo!(), + UnaryOperator::Bang => Ok(types::Value::Bool(!val.truthy())), UnaryOperator::Minus => todo!(), } } diff --git a/src/interpreter/types.rs b/src/interpreter/types.rs index c55e432..879dbdb 100644 --- a/src/interpreter/types.rs +++ b/src/interpreter/types.rs @@ -2,48 +2,31 @@ use crate::ast::astnode; use from_variants::FromVariants; #[derive(Debug, PartialEq, PartialOrd, FromVariants)] -pub enum Primitive { +pub enum Value { Int(i32), Float(f32), Bool(bool), Null, -} - -#[derive(Debug, PartialEq, PartialOrd, FromVariants)] -pub enum Value { - #[from_variants(into)] - Primitive(Primitive), + // TODO: create a cow(not rust cow) string instead of cloning a normal string + String(String), } impl From for Value { fn from(l: astnode::Literal) -> Self { match_any::match_any!(l, - astnode::Literal::Int(v) | astnode::Literal::Bool(v)| astnode::Literal::Float(v) => v.into(), - astnode::Literal::String(_s) => todo!() + astnode::Literal::Int(v) | astnode::Literal::Bool(v) | astnode::Literal::Float(v) | astnode::Literal::String(v) => v.into() ) } } -impl Value { - pub fn int(i: i32) -> Value { - Value::Primitive(Primitive::Int(i)) - } - - pub fn float(f: f32) -> Value { - Value::Primitive(Primitive::Float(f)) - } - - pub fn bool(b: bool) -> Value { - Value::Primitive(Primitive::Bool(b)) - } - - pub fn null() -> Value { - Value::Primitive(Primitive::Null) - } -} - impl Default for Value { fn default() -> Self { - Self::null() + Self::Null + } +} + +impl Value { + pub fn truthy(&self) -> bool { + !(matches!(*self, Self::Bool(false))) } } diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 1650aef..511a24f 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,4 +1,3 @@ -use crftng_intrprtrs::interpreter::types; use crftng_intrprtrs::run; #[test] @@ -12,5 +11,5 @@ fn test_one_equality() { } fn run_check_result_eq_bool(code: &str, value: bool) { - assert_eq!(run(code).unwrap(), types::Value::bool(value)) + assert_eq!(run(code).unwrap(), value.into()) }