aboutsummaryrefslogtreecommitdiff
path: root/ast/modify.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-03-25 01:50:10 +0100
committerDimitri Sokolyuk <demon@dim13.org>2018-03-25 01:50:10 +0100
commite5ed6e13a4adbbe61317194af36c33c82b33c90f (patch)
tree790b5c954959ac852f0072f8bb2bd3137a4dac48 /ast/modify.go
parent88efa3eb20001d1dc23e6b5a8413ea7adf10294e (diff)
lost chapter
Diffstat (limited to 'ast/modify.go')
-rw-r--r--ast/modify.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/ast/modify.go b/ast/modify.go
new file mode 100644
index 0000000..60567bf
--- /dev/null
+++ b/ast/modify.go
@@ -0,0 +1,68 @@
+package ast
+
+type ModifierFunc func(Node) Node
+
+func Modify(node Node, modifier ModifierFunc) Node {
+ switch node := node.(type) {
+
+ case *Program:
+ for i, statement := range node.Statements {
+ node.Statements[i], _ = Modify(statement, modifier).(Statement)
+ }
+
+ case *ExpressionStatement:
+ node.Expression, _ = Modify(node.Expression, modifier).(Expression)
+
+ case *InfixExpression:
+ node.Left, _ = Modify(node.Left, modifier).(Expression)
+ node.Right, _ = Modify(node.Right, modifier).(Expression)
+
+ case *PrefixExpression:
+ node.Right, _ = Modify(node.Right, modifier).(Expression)
+
+ case *IndexExpression:
+ node.Left, _ = Modify(node.Left, modifier).(Expression)
+ node.Index, _ = Modify(node.Index, modifier).(Expression)
+
+ case *IfExpression:
+ node.Condition, _ = Modify(node.Condition, modifier).(Expression)
+ node.Consequence, _ = Modify(node.Consequence, modifier).(*BlockStatement)
+ if node.Alternative != nil {
+ node.Alternative, _ = Modify(node.Alternative, modifier).(*BlockStatement)
+ }
+
+ case *BlockStatement:
+ for i, _ := range node.Statements {
+ node.Statements[i], _ = Modify(node.Statements[i], modifier).(Statement)
+ }
+
+ case *ReturnStatement:
+ node.ReturnValue, _ = Modify(node.ReturnValue, modifier).(Expression)
+
+ case *LetStatement:
+ node.Value, _ = Modify(node.Value, modifier).(Expression)
+
+ case *FunctionLiteral:
+ for i, _ := range node.Parameters {
+ node.Parameters[i], _ = Modify(node.Parameters[i], modifier).(*Identifier)
+ }
+ node.Body, _ = Modify(node.Body, modifier).(*BlockStatement)
+
+ case *ArrayLiteral:
+ for i, _ := range node.Elements {
+ node.Elements[i], _ = Modify(node.Elements[i], modifier).(Expression)
+ }
+
+ case *HashLiteral:
+ newPairs := make(map[Expression]Expression)
+ for key, val := range node.Pairs {
+ newKey, _ := Modify(key, modifier).(Expression)
+ newVal, _ := Modify(val, modifier).(Expression)
+ newPairs[newKey] = newVal
+ }
+ node.Pairs = newPairs
+
+ }
+
+ return modifier(node)
+}