pattern_compiler/simple_pattern/
mod.rs1#[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}