-
Notifications
You must be signed in to change notification settings - Fork 2
/
ast_statement.go
130 lines (108 loc) · 2.02 KB
/
ast_statement.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package spiker
import "strings"
// NodeIf if statement node
type NodeIf struct {
Ast
Expr AstNode
Body []AstNode
ElseIf *NodeIf
Else []AstNode
}
// Format .
func (ifs NodeIf) Format() string {
str := ""
if ifs.Expr != nil {
str += "if (" + ifs.Expr.Format() + ") {\n"
str += formatBody(ifs.Body)
str += "}"
}
if ifs.ElseIf != nil {
str += " else " + ifs.ElseIf.Format()
}
if ifs.Else != nil {
str += " else {\n"
for _, node := range ifs.Else {
str += indentStep + node.Format() + ";\n"
}
str += "}"
}
return str
}
// NodeWhile while statement node
type NodeWhile struct {
Ast
Expr AstNode
Body []AstNode
}
// Format .
func (nws NodeWhile) Format() string {
str := "while (" + nws.Expr.Format() + ") {\n"
str += formatBody(nws.Body)
str += "}"
return str
}
// NodeContinue continue node
type NodeContinue struct {
Ast
}
// Format .
func (nc NodeContinue) Format() string {
return SymbolContinue.String()
}
// NodeBreak break node
type NodeBreak struct {
Ast
}
// Format .
func (nb NodeBreak) Format() string {
return SymbolBreak.String()
}
// NodeReturn return node
type NodeReturn struct {
Ast
Tuples []AstNode
}
// Format .
func (nr NodeReturn) Format() string {
var str = SymbolReturn.String()
if len(nr.Tuples) > 0 {
var ts []string
for _, v := range nr.Tuples {
ts = append(ts, v.Format())
}
if len(ts) > 1 {
str += " (" + strings.Join(ts, ", ")
} else if len(ts) == 1 {
str += " " + ts[0]
}
}
return str
}
// format body statements for IF/FUNC/WHILE
func formatBody(bs []AstNode) string {
var str string
for _, node := range bs {
str += indentStep
switch node.(type) {
case NodeIf, NodeFuncDef, NodeWhile, *NodeIf, *NodeFuncDef, *NodeWhile:
split := strings.Split(node.Format(), "\n")
cnt := len(split)
for idx, s := range split {
if idx > 0 {
str += indentStep
}
if len(s) > 0 {
str += s
}
if idx+1 < cnt {
str += "\n"
}
}
default:
str += node.Format()
str += ";"
}
str += "\n"
}
return str
}