1use std::fmt;
10use std::fmt::{Debug, Display, Formatter};
11
12#[derive(Clone, PartialEq)]
13pub enum ASTNode {
14 Integer(i64),
15 Float(f64),
16 Bool(bool),
17 String(String),
18 Label(String),
19 Name(String),
20 Paren(Box<ASTNode>),
21
22 Block(Vec<ASTNode>, Box<Option<ASTNode>>),
23
24 EmptyStatement,
26 Break,
27 Goto(Box<ASTNode>),
28 RetStat(Box<Option<ASTNode>>),
29
30 Add(Box<ASTNode>, Box<ASTNode>),
32 Sub(Box<ASTNode>, Box<ASTNode>),
33 Mul(Box<ASTNode>, Box<ASTNode>),
34 Div(Box<ASTNode>, Box<ASTNode>),
35 Exp(Box<ASTNode>, Box<ASTNode>),
36 FDiv(Box<ASTNode>, Box<ASTNode>),
37 Mod(Box<ASTNode>, Box<ASTNode>),
38
39 And(Box<ASTNode>, Box<ASTNode>),
41 Or(Box<ASTNode>, Box<ASTNode>),
42
43 Lt(Box<ASTNode>, Box<ASTNode>),
45 Le(Box<ASTNode>, Box<ASTNode>),
46 Gt(Box<ASTNode>, Box<ASTNode>),
47 Ge(Box<ASTNode>, Box<ASTNode>),
48 Eq(Box<ASTNode>, Box<ASTNode>),
49 Ne(Box<ASTNode>, Box<ASTNode>),
50
51 BitOr(Box<ASTNode>, Box<ASTNode>),
53 BitAnd(Box<ASTNode>, Box<ASTNode>),
54 BitXor(Box<ASTNode>, Box<ASTNode>),
55 Rsh(Box<ASTNode>, Box<ASTNode>),
56 Lsh(Box<ASTNode>, Box<ASTNode>),
57
58 BinNot(Box<ASTNode>),
60 Not(Box<ASTNode>),
61 Len(Box<ASTNode>),
62 UMin(Box<ASTNode>),
63
64 Concat(Box<ASTNode>, Box<ASTNode>),
66
67 PrefixExp(Box<ASTNode>),
73
74 Nil,
75 VarArg,
76 TableConstructor(Box<Option<ASTNode>>),
77
78 Function(Box<ASTNode>),
81 FunctionBody(Box<Option<ASTNode>>, Box<ASTNode>),
83 FunctionName(Box<ASTNode>, Option<Vec<ASTNode>>, Option<Box<ASTNode>>),
90 NamedFunction(Box<ASTNode>, Box<ASTNode>),
92
93 ExpList(Vec<ASTNode>),
95 VarList(Vec<ASTNode>),
96 NameList(Vec<ASTNode>),
97 FieldList(Vec<ASTNode>),
98 ParameterList(Box<Option<ASTNode>>, bool),
100
101 FieldSingle(Box<ASTNode>),
104 FieldAssign(Box<ASTNode>, Box<ASTNode>),
107
108 Local(Box<ASTNode>),
110
111 Var(Box<ASTNode>),
114 VarPrefixed(Box<ASTNode>, Box<ASTNode>),
116 VarListAccess(Box<ASTNode>, Box<ASTNode>),
118}
119
120impl Debug for ASTNode {
121 fn fmt(&self, format: &mut Formatter) -> fmt::Result {
122 use self::ASTNode::*;
123 match *self {
124 Integer(val) => write!(format, "{}", val),
125 Float(val) => write!(format, "{}f", val),
126 Bool(val) => write!(format, "{}", val),
127 String(ref val) => write!(format, "\"{}\"", val),
128
129 Name(ref val) => write!(format, "(name {})", val),
132
133 Label(ref val) => write!(format, "::{}::", val),
136 Paren(ref expr) => write!(format, "({})", expr),
138
139 Block(ref statements, ref retstat) => {
141 write!(format, "(block\n");
142 for e in statements.iter() {
143 write!(format, "\t{}\n", e);
144 }
145 if let Some(ref ret_ast) = **retstat {
146 write!(format, "\treturn {}\n", ret_ast);
147 }
148 write!(format, ")")
149 }
150
151 EmptyStatement => write!(format, "(statement)"),
153 RetStat(ref para) => write!(format, "(ret {:?})", para),
154 Break => write!(format, "(break)"),
155 Goto(ref loc) => write!(format, "goto {}", loc),
156
157 Add(ref left, ref right) => write!(format, "({} + {})", left, right),
159 Sub(ref left, ref right) => write!(format, "({} - {})", left, right),
160 Mul(ref left, ref right) => write!(format, "({} * {})", left, right),
161 Div(ref left, ref right) => write!(format, "({} / {})", left, right),
162 Exp(ref left, ref right) => write!(format, "({} ^ {})", left, right),
163 FDiv(ref left, ref right) => write!(format, "({} // {})", left, right),
164 Mod(ref left, ref right) => write!(format, "({} % {})", left, right),
165
166 And(ref left, ref right) => write!(format, "({} and {})", left, right),
168 Or(ref left, ref right) => write!(format, "({} or {})", left, right),
169
170 Lt(ref left, ref right) => write!(format, "({} < {})", left, right),
172 Le(ref left, ref right) => write!(format, "({} <= {})", left, right),
173 Gt(ref left, ref right) => write!(format, "({} > {})", left, right),
174 Ge(ref left, ref right) => write!(format, "({} >= {})", left, right),
175 Eq(ref left, ref right) => write!(format, "({} == {})", left, right),
176 Ne(ref left, ref right) => write!(format, "({} ~= {})", left, right),
177
178 BitAnd(ref left, ref right) => write!(format, "({} & {})", left, right),
180 BitOr(ref left, ref right) => write!(format, "({} | {})", left, right),
181 BitXor(ref left, ref right) => write!(format, "({} ~ {})", left, right),
182 Rsh(ref left, ref right) => write!(format, "({} >> {})", left, right),
183 Lsh(ref left, ref right) => write!(format, "({} << {})", left, right),
184
185 BinNot(ref right) => write!(format, "~{}", right),
187 Len(ref right) => write!(format, "#{}", right),
188 UMin(ref right) => write!(format, "-{}", right),
189 Not(ref right) => write!(format, "not {}", right),
190
191 Concat(ref left, ref right) => write!(format, "{} .. {}", left, right),
193
194 PrefixExp(ref e) => write!(format, "{}", e),
196
197 Nil => write!(format, "nil"),
198 VarArg => write!(format, "..."),
199 TableConstructor(ref fieldlist) => write!(format, "{{ {:?} }}", fieldlist),
201
202 Function(ref f) => write!(format, "{}", f),
204 FunctionBody(ref parlist, ref fbody) => write!(format, "function ({:?}) {}", parlist, fbody),
205 FunctionName(ref n, ref m, ref f) => write!(format, "{}.{:?}:{:?}", n, m, f),
206 NamedFunction(ref n, ref f) => write!(format, "(named {} {})", n, f),
207
208 ExpList(ref explist) => {
210 write!(format, "(explist\n");
211 for e in explist.iter() {
212 write!(format, "\t{}\n", e);
213 }
214 write!(format, ")")
215 },
216 VarList(ref varlist) => {
217 write!(format, "(varlist\n");
218 for e in varlist.iter() {
219 write!(format, "\t{}\n", e);
220 }
221 write!(format, ")")
222 },
223 NameList(ref namelist) => {
224 write!(format, "(namelist\n");
225 for e in namelist.iter() {
226 write!(format, "\t{}\n", e);
227 }
228 write!(format, ")")
229 },
230 ParameterList(ref plist, ref va) => {
231 write!(format, "(paramlist\n");
232 for e in plist.iter() {
233 write!(format, "\t{}\n", e);
234 }
235 if *va {
236 write!(format, "\t...\n");
237 }
238 write!(format, ")")
239 },
240 FieldList(ref fieldlist) => {
241 write!(format, "(fieldlist\n");
242 for e in fieldlist.iter() {
243 write!(format, "\t{}\n", e);
244 }
245 write!(format, ")")
246 },
247
248 FieldSingle(ref e) => write!(format, "(field {})", e),
250 FieldAssign(ref n, ref e) => write!(format, "(field {} => {})", n, e),
251
252 Local(ref inner) => write!(format, "local {}", inner),
254
255 Var(ref name) => write!(format, "(var {})", name),
257 VarPrefixed(ref pe, ref e) => write!(format, "{}[{}]", pe, e),
258 VarListAccess(ref pe, ref n) => write!(format, "{}.{}", pe, n)
259 }
260 }
261
262}
263
264impl Display for ASTNode {
265 fn fmt(&self, format: &mut Formatter) -> fmt::Result {
266 use ASTNode::*;
267 match *self {
268 Integer(a) => write!(format, "Integer_{}_", a),
270 Float(a) => write!(format, "Float_{}_", a),
271 Bool(a) => write!(format, "Bool_{}_", a),
272 String(ref a) => write!(format, "String_{}_", a),
275 Label(ref a) => write!(format, "Label_{}_", a),
276 Name(ref a) => write!(format, "Name_{}_", a),
277 Paren(_) => write!(format, "Paren"),
278 Block(_, _) => write!(format, "Block"),
279 EmptyStatement => write!(format, "EmptyStatement"),
280 Break => write!(format, "Break"),
281 Goto(_) => write!(format, "Goto"),
282 RetStat(_) => write!(format, "RetStat"),
283 Add(_, _) => write!(format, "Add"),
284 Sub(_, _) => write!(format, "Sub"),
285 Mul(_, _) => write!(format, "Mul"),
286 Div(_, _) => write!(format, "Div"),
287 Exp(_, _) => write!(format, "Exp"),
288 FDiv(_, _) => write!(format, "FDiv"),
289 Mod(_, _) => write!(format, "Mod"),
290 And(_, _) => write!(format, "And"),
291 Or(_, _) => write!(format, "Or"),
292 Lt(_, _) => write!(format, "Lt"),
293 Le(_, _) => write!(format, "Le"),
294 Gt(_, _) => write!(format, "Gt"),
295 Ge(_, _) => write!(format, "Ge"),
296 Eq(_, _) => write!(format, "Eq"),
297 Ne(_, _) => write!(format, "Ne"),
298 BitOr(_, _) => write!(format, "BitOr"),
299 BitAnd(_, _) => write!(format, "BitAnd"),
300 BitXor(_, _) => write!(format, "BitXor"),
301 Rsh(_, _) => write!(format, "Rsh"),
302 Lsh(_, _) => write!(format, "Lsh"),
303 BinNot(_) => write!(format, "BinNot"),
304 Not(_) => write!(format, "Not"),
305 Len(_) => write!(format, "Len"),
306 UMin(_) => write!(format, "UMin"),
307 Concat(_, _) => write!(format, "Concat"),
308 PrefixExp(_) => write!(format, "PrefixExp"),
309 Nil => write!(format, "Nil"),
310 VarArg => write!(format, "VarArg"),
311 TableConstructor(_) => write!(format, "TableConstructor"),
312 Function(_) => write!(format, "Function"),
313 FunctionBody(_, _) => write!(format, "FunctionBody"),
314 FunctionName(_, _, _) => write!(format, "FunctionName"),
315 NamedFunction(_, _) => write!(format, "NamedFunction"),
316 ExpList(_) => write!(format, "ExpList"),
317 VarList(_) => write!(format, "VarList"),
318 NameList(_) => write!(format, "NameList"),
319 FieldList(_) => write!(format, "FieldList"),
320 ParameterList(_, _) => write!(format, "ParameterList"),
321 FieldSingle(_) => write!(format, "FieldSingle"),
322 FieldAssign(_, _) => write!(format, "FieldAssign"),
323 Local(_) => write!(format, "Local"),
324 Var(_) => write!(format, "Var"),
325 VarPrefixed(_, _) => write!(format, "VarPrefixed"),
326 VarListAccess(_, _) => write!(format, "VarListAccess"),
327 }
328 }
329}
330
331#[cfg(feature="graphviz")]
334type Node = ASTNode;
335#[cfg(feature="graphviz")]
336type Edge = (ASTNode, ASTNode);
337#[cfg(feature="graphviz")]
338struct Edges(Vec<Edge>);
339#[cfg(feature="graphviz")]
340use dot;
341#[cfg(feature="graphviz")]
342use std::borrow::Cow;
343#[cfg(feature="graphviz")]
344use std::io::Write;
345
346
347#[cfg(feature="graphviz")]
348impl<'a> dot::Labeller<'a, Node, Edge> for Edges {
349 fn graph_id(&'a self) -> dot::Id<'a> {
350 dot::Id::new("AST").unwrap()
351 }
352
353 fn node_id(&'a self, node: &Node) -> dot::Id<'a> {
354 dot::Id::new(format!("{}", node)).unwrap()
355 }
356}
357
358
359#[cfg(feature="graphviz")]
360impl<'a> dot::GraphWalk<'a, Node, Edge> for Edges {
361 fn nodes(&self) -> dot::Nodes<'a,Node> {
362 let &Edges(ref v) = self;
364 let mut node_vec = Vec::with_capacity(v.len());
365 for n in v {
366 let &(ref s, ref t) = n;
367 node_vec.extend(s.sub_nodes());
368 node_vec.extend(t.sub_nodes());
369 }
370 node_vec.dedup();
371 Cow::Owned(node_vec)
372 }
373
374 fn edges(&'a self) -> dot::Edges<'a,Edge> {
375 let &Edges(ref edges) = self;
376 Cow::Borrowed(&edges[..])
377 }
378
379 fn source(&self, e: &Edge) -> Node { let &(ref s,_) = e; s.clone() }
380
381 fn target(&self, e: &Edge) -> Node { let &(_,ref t) = e; t.clone() }
382}
383
384
385#[cfg(feature="graphviz")]
386impl ASTNode {
387 fn generate_edges(&self) -> Vec<(ASTNode, ASTNode)> {
388 use ASTNode::*;
389 let mut node_vec = Vec::new();
390 match (*self).clone() {
391
392 Integer(_) |
393 Float(_) |
394 Bool(_) |
395 String(_) |
396 Label(_) |
397 Name(_) |
398 Nil |
399 Break |
400 VarArg |
401 EmptyStatement => {},
402
403 Paren(a) |
404 Local(a) |
405 Var(a) |
406 Goto(a) |
407 BinNot(a) |
408 Not(a) |
409 Len(a) |
410 UMin(a) |
411 PrefixExp(a) |
412 Function(a) |
413 FieldSingle(a) |
414 PrefixExp(a) => {
415 node_vec.push(((*self).clone(), (*a).clone()));
416 node_vec.extend(a.generate_edges());
417 },
418
419 Add(a, b) |
420 Sub(a, b) |
421 Mul(a, b) |
422 Div(a, b) |
423 Exp(a, b) |
424 FDiv(a, b) |
425 Mod(a, b) |
426 And(a, b) |
427 Or(a, b) |
428 Lt(a, b) |
429 Le(a, b) |
430 Gt(a, b) |
431 Ge(a, b) |
432 Eq(a, b) |
433 Ne(a, b) |
434 BitOr(a, b) |
435 BitAnd(a, b) |
436 BitXor(a, b) |
437 Rsh(a, b) |
438 Lsh(a, b) |
439 Concat(a, b) |
440 FieldAssign(a, b) |
441 VarPrefixed(a, b) |
442 VarListAccess(a, b) |
443 NamedFunction(a, b) => {
444 node_vec.push(((*self).clone(), (*a).clone()));
445 node_vec.push(((*self).clone(), (*b).clone()));
446 node_vec.extend(a.generate_edges());
447 node_vec.extend(b.generate_edges());
448 },
449
450 RetStat(a) |
451 TableConstructor(a) |
452 ParameterList(a, _) => if let Some(sa) = *a {
453 node_vec.push(((*self).clone(), sa.clone()));
454 node_vec.extend(sa.generate_edges());
455 },
456
457 ExpList(a) |
458 VarList(a) |
459 NameList(a) |
460 FieldList(a) => {
461 a.iter().map(|ae| {
462 node_vec.push(((*self).clone(), (*ae).clone()));
463 node_vec.extend(ae.generate_edges());
464 });
465 },
466
467 Block(a, b) => {
468 a.iter().map(|ae| {
469 node_vec.push(((*self).clone(), (*ae).clone()));
470 node_vec.extend(ae.generate_edges());
471 });
472 if let Some(sb) = *b {
473 node_vec.push(((*self).clone(), sb.clone()));
474 node_vec.extend(sb.generate_edges());
475 };
476 },
477 FunctionBody(a, b) => {
478 if let Some(sa) = *a {
479 node_vec.push(((*self).clone(), sa.clone()));
480 node_vec.extend(sa.generate_edges());
481 };
482 node_vec.push(((*self).clone(), (*b).clone()));
483 node_vec.extend(b.generate_edges());
484 },
485 FunctionName(a, b, c) => {
486 node_vec.push(((*self).clone(), (*a).clone()));
487 node_vec.extend(a.generate_edges());
488 if let Some(sb) = b {
489 sb.iter().map(|sbe| {
490 node_vec.push(((*self).clone(), (*sbe).clone()));
491 node_vec.extend(sbe.generate_edges());
492 });
493 };
494 if let Some(sc) = c {
495 node_vec.push(((*self).clone(), (*sc).clone()));
496 node_vec.extend(sc.generate_edges());
497 };
498 },
499 _ => panic!("Unimplemented: GenEdges"),
500 }
501 node_vec
502 }
503
504 fn sub_nodes(&self) -> Vec<ASTNode> {
505 use ASTNode::*;
506 let mut node_vec = Vec::new();
507
508 node_vec.push((*self).clone());
509
510 match (*self).clone() {
511 Nil |
512 VarArg |
513 Break |
514 EmptyStatement |
515 Float(_) |
516 Bool(_) |
517 String(_) |
518 Label(_) |
519 Name(_) |
520 Integer(_) => {},
521
522 Goto(a) |
523 BinNot(a) |
524 Not(a) |
525 Len(a) |
526 UMin(a) |
527 PrefixExp(a) |
528 FieldSingle(a) |
529 Local(a) |
530 Var(a) |
531 Function(a) |
532 PrefixExp(a) |
533 Paren(a) => node_vec.extend(a.sub_nodes()),
534
535 And(a, b) |
536 Or(a, b) |
537 Lt(a, b) |
538 Le(a, b) |
539 Gt(a, b) |
540 Ge(a, b) |
541 Eq(a, b) |
542 Ne(a, b) |
543 BitOr(a, b) |
544 BitAnd(a, b) |
545 BitXor(a, b) |
546 Rsh(a, b) |
547 Lsh(a, b) |
548 FieldAssign(a, b) |
549 VarPrefixed(a, b) |
550 VarListAccess(a, b) |
551 NamedFunction(a, b) |
552 Concat(a, b) |
553 Add(a, b) |
554 Sub(a, b) |
555 Mul(a, b) |
556 Div(a, b) |
557 Exp(a, b) |
558 FDiv(a, b) |
559 Mod(a, b) => {
560 node_vec.extend(a.sub_nodes());
561 node_vec.extend(b.sub_nodes());
562 },
563
564 ExpList(a) |
565 VarList(a) |
566 NameList(a) |
567 FieldList(a) => { a.iter().map(|b| node_vec.extend(b.sub_nodes())); },
568
569 RetStat(a) |
570 ParameterList(a, _) |
571 TableConstructor(a) => if let Some(sa) = *a {
572 node_vec.extend(sa.sub_nodes());
573 },
574
575 Block(a, b) => {
576 a.iter().map(|ae| node_vec.extend(ae.sub_nodes()));
577 if let Some(sb) = *b {
578 node_vec.extend(sb.sub_nodes());
579 }
580 },
581
582 FunctionBody(a, b) => {
583 if let Some(sa) = *a {
584 node_vec.extend(sa.sub_nodes());
585 }
586 node_vec.extend(b.sub_nodes());
587 },
588
589 FunctionName(a, b, c) => {
590 node_vec.extend(a.sub_nodes());
591 if let Some(sb) = b {
592 sb.iter().map(|sbe| node_vec.extend(sbe.sub_nodes()));
593 };
594 if let Some(sc) = c {
595 node_vec.extend(sc.sub_nodes());
596 }
597 },
598 _ => panic!("Unimplemented: SubNodes"),
599 };
600 node_vec
601 }
602
603 #[cfg(feature="graphviz")]
604 pub fn graphviz_render<W: Write>(&self, output: &mut W) {
605 let edges = Edges(self.generate_edges());
606 dot::render(&edges, output).unwrap()
607 }
608}