aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdvard Thörnros <edvard.thornros@gmail.com>2021-03-09 17:01:53 +0100
committerEdvard Thörnros <edvard.thornros@gmail.com>2021-03-09 17:01:53 +0100
commit9ef8eaa4564b2e498c56cad50491f2fdcea9d643 (patch)
treeba25bbccda274c8edd45b999fd41b9dc9c6eb841
parent50e3477ed34697be12890081b03d8412703ba8b3 (diff)
downloadsylt-9ef8eaa4564b2e498c56cad50491f2fdcea9d643.tar.gz
change union to hashset from vector
-rw-r--r--src/compiler.rs11
-rw-r--r--src/lib.rs50
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))
}
diff --git a/src/lib.rs b/src/lib.rs
index c085cca..6f63ad7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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 {