v2 / vlib / toml / ast / walker / walker.v
70 lines · 61 sloc · 1.85 KB · 3d60410b605d001e54f280070d5f952da9de1112
Raw
1module walker
2
3import toml.ast
4
5// Visitor defines a visit method which is invoked by the walker on each Value node it encounters.
6pub interface Visitor {
7 visit(value &ast.Value) !
8}
9
10// Modifier defines a modify method which is invoked by the walker on each Value node it encounters.
11pub interface Modifier {
12 modify(mut value ast.Value) !
13}
14
15pub type InspectorFn = fn (value &ast.Value, data voidptr) !
16
17struct Inspector {
18 inspector_callback InspectorFn = unsafe { nil }
19mut:
20 data voidptr
21}
22
23// visit calls the inspector callback on the specified Value node.
24pub fn (i &Inspector) visit(value &ast.Value) ! {
25 i.inspector_callback(value, i.data) or { return err }
26}
27
28// inspect traverses and checks the AST Value node on a depth-first order and based on the data given
29pub fn inspect(value &ast.Value, data voidptr, inspector_callback InspectorFn) ! {
30 walk(Inspector{inspector_callback, data}, value)!
31}
32
33// walk traverses the AST using the given visitor
34@[autofree_bug; manualfree]
35pub fn walk(visitor Visitor, value &ast.Value) ! {
36 if value is map[string]ast.Value {
37 value_map := value as map[string]ast.Value
38 for _, val in value_map {
39 walk(visitor, &val)!
40 }
41 }
42 if value is []ast.Value {
43 value_array := value as []ast.Value
44 for val in value_array {
45 walk(visitor, &val)!
46 }
47 } else {
48 visitor.visit(value)!
49 }
50}
51
52// walk_and_modify traverses the AST using the given modifier and lets the visitor
53// modify the contents.
54@[autofree_bug; manualfree]
55pub fn walk_and_modify(modifier Modifier, mut value ast.Value) ! {
56 if value is map[string]ast.Value {
57 mut value_map := value as map[string]ast.Value
58 for _, mut val in value_map {
59 walk_and_modify(modifier, mut &val)!
60 }
61 }
62 if value is []ast.Value {
63 mut value_array := value as []ast.Value
64 for mut val in value_array {
65 walk_and_modify(modifier, mut &val)!
66 }
67 } else {
68 modifier.modify(mut value)!
69 }
70}
71