diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiler.rs | 11 | ||||
| -rw-r--r-- | src/lib.rs | 50 |
2 files changed, 54 insertions, 7 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index bdc5901..588a9e9 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -1,6 +1,6 @@ use std::path::{Path, PathBuf}; use std::cell::RefCell; -use std::collections::{HashMap, hash_map::Entry}; +use std::collections::{HashMap, HashSet, hash_map::Entry}; use std::rc::Rc; use crate::{Blob, Block, Op, Prog, RustFunction, Type, Value}; @@ -1403,18 +1403,19 @@ impl Compiler { } fn parse_type(&mut self) -> Result<Type, ()> { - let mut tys = vec![self.parse_simple_type()?]; + let mut tys = HashSet::new(); + tys.insert(self.parse_simple_type()?); loop { match self.peek() { Token::Questionmark => { self.eat(); - tys.push(Type::Void); + tys.insert(Type::Void); return Ok(Type::Union(tys)); }, Token::Pipe => { self.eat(); - tys.push(self.parse_simple_type()?); + tys.insert(self.parse_simple_type()?); }, _ => { @@ -1423,7 +1424,7 @@ impl Compiler { } } if tys.len() == 1 { - Ok(tys[0].clone()) + Ok(tys.iter().next().unwrap().clone()) } else { Ok(Type::Union(tys)) } @@ -1,5 +1,5 @@ use std::cell::RefCell; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::collections::hash_map::Entry; use std::fmt::Debug; use std::path::{Path, PathBuf}; @@ -86,12 +86,56 @@ pub enum Type { Bool, String, Tuple(Vec<Type>), - Union(Vec<Type>), + Union(HashSet<Type>), Function(Vec<Type>, Box<Type>), Blob(Rc<Blob>), Instance(Rc<Blob>), } +impl Hash for Type { + fn hash<H: Hasher>(&self, h: &mut H) { + match self { + Type::Void => 0, + Type::Unknown => 1, + Type::Int => 2, + Type::Float => 3, + Type::Bool => 4, + Type::String => 5, + Type::Tuple(ts) => { + for t in ts.iter() { + t.hash(h); + } + 6 + } + Type::Union(ts) => { + for t in ts { + t.hash(h); + } + 7 + } + Type::Function(args, ret) => { + ret.hash(h); + for t in args.iter() { + t.hash(h); + } + 8 + } + Type::Blob(b) => { + for (_, t) in b.fields.values() { + t.hash(h); + } + 10 + } + Type::Instance(b) => { + for (_, t) in b.fields.values() { + t.hash(h); + } + 11 + } + }.hash(h); + } +} + impl PartialEq for Type { fn eq(&self, other: &Self) -> bool { match (self, other) { @@ -115,6 +159,8 @@ impl PartialEq for Type { } } +impl Eq for Type {} + impl From<&Value> for Type { fn from(value: &Value) -> Type { match value { |
