1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
use std::fmt; use func::Func; use std::ops::Deref; use std::collections::hash_map::{HashMap, DefaultHasher, Entry}; use std::rc::Rc; use poly::Poly; use std::hash::{Hash, Hasher}; pub struct Cache { items: HashMap<u64, NodeRc> } impl Cache { pub fn new() -> Cache { Cache { items: HashMap::new() } } pub fn intern(&mut self, node: Node) -> NodeRc { let mut h = DefaultHasher::new(); node.hash(&mut h); let hash = h.finish(); match self.items.entry(hash) { Entry::Vacant(v) => v.insert(NodeRc { inner: Rc::new((node, hash)) }).clone(), Entry::Occupied(o) => { assert_eq!(o.get().inner.0, node); o.get().clone() } } } } #[derive(Clone, Debug, Ord, PartialOrd)] pub struct NodeRc { inner: Rc<(Node, u64)>, } impl Deref for NodeRc { type Target = Node; fn deref(&self) -> &Node { &self.inner.0 } } impl PartialEq for NodeRc { fn eq(&self, rhs: &NodeRc) -> bool { self.inner.1 == rhs.inner.1 } } impl Eq for NodeRc {} impl Hash for NodeRc { fn hash<H: Hasher>(&self, state: &mut H) { state.write_u64(self.inner.1); } } impl fmt::Display for NodeRc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.inner.0.fmt(f) } } #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum Sign { Negative, Positive } #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] pub enum Op { Diff(String), } impl fmt::Display for Op { fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { match *self { Op::Diff(ref v) => write!(w, "d/d{}", v) } } } #[derive(Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub enum Node { Var(String), Op(Func), Apply(NodeRc, NodeRc), Poly(Poly), Tuple(Vec<NodeRc>) } impl fmt::Display for Node { fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { use display::Tokens; Tokens::node(self).fmt(w) } }