-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpreter.go
61 lines (51 loc) · 1.31 KB
/
interpreter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package main
import (
"fmt"
"strconv"
)
func runSequence(ast *ASTNode) []float64 {
// ast root is always a sequence
results := make([]float64, 0)
for _, child := range ast.Children {
switch child.Type {
case LOOP:
results = append(results, runLoop(child)...)
case VALUE:
results = append(results, runNumber(child))
case SEQUENCE:
results = append(results, runSequence(child)...)
}
}
return results
}
func runLoop(ast *ASTNode) []float64 {
element := ast.Fields["repeat"].(*ASTNode)
count := ast.Fields["count"].(*ASTNode)
if count.Type != VALUE {
panic(fmt.Sprintf("Count is not a number: %+v", count))
}
countNum, err := strconv.Atoi(count.Fields["value"].(string))
if err != nil {
panic(fmt.Sprintf("Failed to parse count: %s", count.Fields["value"].(string)))
}
results := make([]float64, 0)
for i := 0; i < countNum; i++ {
switch element.Type {
case VALUE:
results = append(results, runNumber(element))
case SEQUENCE:
results = append(results, runSequence(element)...)
default:
panic(fmt.Sprintf("Unknown element type: %s", element.Type))
}
}
return results
}
func runNumber(ast *ASTNode) float64 {
str := ast.Fields["value"].(string)
num, err := strconv.ParseFloat(str, 64)
if err != nil {
panic(fmt.Sprintf("Failed to parse number: %s", str))
}
return num
}