diff --git a/src/ast.rs b/src/ast.rs index 04a884d0..90432830 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -8,11 +8,13 @@ //! just plain subroutines and they do not return any value, //! so their calls are statements. +use std::hash::Hash; + use crate::variables::Value; type Span = std::ops::Range; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, Clone)] pub struct Iden { pub iden: String, pub span: Span, @@ -24,19 +26,43 @@ impl Iden { } } -#[derive(Debug, PartialEq, Clone)] +impl PartialEq for Iden { + fn eq(&self, other: &Self) -> bool { + self.iden == other.iden + } +} + +impl Hash for Iden { + fn hash(&self, state: &mut H) { + self.iden.hash(state) + } +} + +#[derive(Debug, PartialEq, Clone, Hash)] pub struct Block { pub block: Vec, } /// A syntactic unit expressing an effect. -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, Clone)] pub struct Stmt { pub kind: StmtKind, pub span: Span, } -#[derive(Debug, PartialEq, Clone)] +impl PartialEq for Stmt { + fn eq(&self, other: &Self) -> bool { + self.kind == other.kind + } +} + +impl Hash for Stmt { + fn hash(&self, state: &mut H) { + self.kind.hash(state) + } +} + +#[derive(Debug, PartialEq, Clone, Hash)] pub enum StmtKind { // Control flow If { @@ -87,13 +113,25 @@ impl Stmt { /// Expression is parse unit which do not cause any effect, /// like math and logical operations or values. -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, Clone)] pub struct Expr { pub kind: ExprKind, pub span: Span, } -#[derive(Debug, PartialEq, Clone)] +impl PartialEq for Expr { + fn eq(&self, other: &Self) -> bool { + self.kind == other.kind + } +} + +impl Hash for Expr { + fn hash(&self, state: &mut H) { + self.kind.hash(state) + } +} + +#[derive(Debug, PartialEq, Clone, Hash)] pub enum ExprKind { BinOp { lhs: Box, @@ -116,7 +154,7 @@ impl Expr { } } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Hash)] pub enum BinOpKind { Add, Subtract, diff --git a/src/variables.rs b/src/variables.rs index 962f4b68..eeaab8d1 100644 --- a/src/variables.rs +++ b/src/variables.rs @@ -1,4 +1,7 @@ -use std::{cell::RefCell, collections::HashMap, fmt::Display, hash::Hash, io::Write, rc::Rc}; +use std::{ + cell::RefCell, collections::HashMap, fmt::Display, hash::Hash, io::Write, mem::discriminant, + rc::Rc, +}; use rand::Rng; @@ -31,7 +34,7 @@ impl From for bool { } } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Hash)] pub enum Functio { BfFunctio { instructions: Vec, @@ -56,13 +59,14 @@ pub enum Value { impl Hash for Value { fn hash(&self, state: &mut H) { + discriminant(self).hash(state); match self { Value::Nul => (), Value::Str(v) => v.hash(state), Value::Int(v) => v.hash(state), Value::Bool(v) => v.hash(state), Value::Abool(v) => v.to_string().hash(state), - Value::Functio(_) => todo!(), + Value::Functio(statements) => statements.hash(state), Value::Cart(_) => self.to_string().hash(state), } } @@ -77,9 +81,7 @@ impl PartialEq for Value { (Value::Bool(left), Value::Bool(right)) => left == right, (Value::Abool(left), Value::Abool(right)) => left == right, (Value::Functio(left), Value::Functio(right)) => left == right, - (Value::Cart(_left), Value::Cart(_right)) => { - todo!() - } + (Value::Cart(_), Value::Cart(_)) => self.to_string() == other.to_string(), (_, _) => false, // TODO: do more coercions! }