pattern_compiler/simple_pattern/
mod.rs

1#[cfg(test)]
2mod test;
3
4use ::{ PatternProvider, ExpandedClauseNodes };
5
6use ::petgraph::{ Graph, Direction };
7use ::petgraph::graph::NodeIndex;
8
9#[derive(Copy, Clone, Hash, PartialEq, Eq)]
10pub struct CfgVar(usize);
11
12use ::std::fmt;
13impl fmt::Debug for CfgVar {
14    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
15        write!(fmt, "${}", self.0)
16    }
17}
18
19#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq)]
20pub enum NodeKind {
21    Tuple,
22    ListCell,
23    Terminal,
24    RootValues,
25    Wildcard,
26}
27
28#[derive(Debug, Clone)]
29pub struct SimplePatternProvider {
30    pattern: Graph<NodeKind, ()>,
31    roots: Vec<NodeIndex>,
32    root_var: CfgVar,
33    curr_var: CfgVar,
34}
35
36impl SimplePatternProvider {
37
38    pub fn new() -> Self {
39        SimplePatternProvider {
40            pattern: Graph::new(),
41            roots: Vec::new(),
42            root_var: CfgVar(0),
43            curr_var: CfgVar(0),
44        }
45    }
46
47    pub fn add_child(&mut self, node: NodeIndex, kind: NodeKind) -> NodeIndex {
48        let res = self.pattern.add_node(kind);
49        self.pattern.add_edge(node, res, ());
50        res
51    }
52
53    pub fn add_clause(&mut self, kind: NodeKind) -> NodeIndex {
54        let res = self.pattern.add_node(kind);
55        self.roots.push(res);
56        res
57    }
58}
59
60impl PatternProvider for SimplePatternProvider {
61
62    type PatternNodeKey = NodeIndex;
63    type PatternNodeKind = NodeKind;
64    type CfgVariable = CfgVar;
65
66    const WILDCARD: NodeKind = NodeKind::Wildcard;
67
68    fn get_root(&self) -> ExpandedClauseNodes<
69            Self::CfgVariable, Self::PatternNodeKey> {
70        ExpandedClauseNodes {
71            variables: vec![self.root_var],
72            clauses: self.roots.len(),
73            nodes: self.roots.clone(),
74        }
75    }
76
77    fn kind_includes(&self, kind: Self::PatternNodeKind,
78                     key: Self::PatternNodeKey) -> bool {
79        self.pattern[key] == kind
80    }
81
82    fn expand_clause_nodes(&mut self, clause_nodes: Vec<Self::PatternNodeKey>)
83                           -> ExpandedClauseNodes<
84            Self::CfgVariable, Self::PatternNodeKey>
85    {
86        if clause_nodes.len() == 0 {
87            return ExpandedClauseNodes {
88                clauses: 0,
89                variables: vec![],
90                nodes: vec![],
91            };
92        }
93
94        let typ = self.pattern[clause_nodes[0]];
95        let base_len = self.pattern.edges_directed(clause_nodes[0], Direction::Outgoing).count();
96        for node in &clause_nodes {
97            assert!(self.pattern.edges_directed(clause_nodes[0], Direction::Outgoing).count()
98                    == base_len);
99            assert!(self.pattern[*node] == typ);
100        }
101
102        let mut curr_var = self.curr_var;
103        let mut exp = ExpandedClauseNodes {
104            clauses: clause_nodes.len(),
105            variables: self.pattern
106                .edges_directed(clause_nodes[0], Direction::Outgoing)
107                .map(|_| {
108                    curr_var.0 += 1;
109                    curr_var
110                })
111                .collect(),
112            nodes: vec![],
113        };
114        self.curr_var = curr_var;
115
116        match typ {
117            NodeKind::RootValues => {
118                for node in &clause_nodes {
119                    for child in self.pattern.edges_directed(*node, Direction::Outgoing) {
120                        use ::petgraph::visit::EdgeRef;
121                        exp.nodes.push(child.target());
122                    }
123                }
124            },
125            NodeKind::ListCell => {
126                for node in &clause_nodes {
127                    for child in self.pattern.edges_directed(*node, Direction::Outgoing) {
128                        use ::petgraph::visit::EdgeRef;
129                        exp.nodes.push(child.target());
130                    }
131                }
132            },
133            NodeKind::Wildcard => {},
134            NodeKind::Terminal => {},
135            typ => unimplemented!("{:?}", typ),
136        }
137
138        println!("{:?}", exp);
139        exp
140    }
141
142    fn get_kind(&self, key: Self::PatternNodeKey) -> Self::PatternNodeKind {
143        self.pattern[key]
144    }
145
146}