forked from goby-lang/goby
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ast.go
80 lines (64 loc) · 1.34 KB
/
ast.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
package ast
import (
"bytes"
"github.com/goby-lang/goby/compiler/token"
)
// BaseNode holds the attribute every expression or statement should have
type BaseNode struct {
Token token.Token
isStmt bool
}
// Line returns node's token's line number
func (b *BaseNode) Line() int {
return b.Token.Line
}
// IsExp returns if current node should be considered as an expression
func (b *BaseNode) IsExp() bool {
return !b.isStmt
}
// IsStmt returns if current node should be considered as a statement
func (b *BaseNode) IsStmt() bool {
return b.isStmt
}
// MarkAsStmt marks current node to be statement
func (b *BaseNode) MarkAsStmt() {
b.isStmt = true
}
// MarkAsExp marks current node to be expression
func (b *BaseNode) MarkAsExp() {
b.isStmt = false
}
type node interface {
TokenLiteral() string
String() string
Line() int
IsExp() bool
IsStmt() bool
MarkAsStmt()
MarkAsExp()
}
type Statement interface {
node
statementNode()
}
type Expression interface {
node
expressionNode()
}
// Program is the root node of entire AST
type Program struct {
Statements []Statement
}
func (p *Program) TokenLiteral() string {
if len(p.Statements) > 0 {
return p.Statements[0].TokenLiteral()
}
return ""
}
func (p *Program) String() string {
var out bytes.Buffer
for _, s := range p.Statements {
out.WriteString(s.String())
}
return out.String()
}