aboutsummaryrefslogtreecommitdiff
path: root/ast/modify.go
diff options
context:
space:
mode:
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)
+}