summaryrefslogtreecommitdiff
path: root/ast
diff options
context:
space:
mode:
Diffstat (limited to 'ast')
-rw-r--r--ast/ast.go91
-rw-r--r--ast/ast_test.go37
2 files changed, 128 insertions, 0 deletions
diff --git a/ast/ast.go b/ast/ast.go
index 033005f..619cb9f 100644
--- a/ast/ast.go
+++ b/ast/ast.go
@@ -1,11 +1,14 @@
package ast
import (
+ "bytes"
+
"github.com/mewsen/interpreter/token"
)
type Node interface {
TokenLiteral() string
+ String() string
}
type Statement interface {
@@ -30,6 +33,16 @@ func (p *Program) TokenLiteral() string {
}
}
+func (p *Program) String() string {
+ var out bytes.Buffer
+
+ for _, s := range p.Statements {
+ out.WriteString(s.String())
+ }
+
+ return out.String()
+}
+
type LetStatement struct {
Token token.Token
Name *Identifier
@@ -38,6 +51,19 @@ type LetStatement struct {
func (ls *LetStatement) statementNode() {}
func (ls *LetStatement) TokenLiteral() string { return ls.Token.Literal }
+func (ls *LetStatement) String() string {
+ var out bytes.Buffer
+
+ out.WriteString(ls.TokenLiteral() + " ")
+ out.WriteString(ls.Name.String())
+ out.WriteString(" = ")
+
+ if ls.Value != nil {
+ out.WriteString(ls.Value.String())
+ }
+
+ return out.String()
+}
type Identifier struct {
Token token.Token
@@ -46,3 +72,68 @@ type Identifier struct {
func (i *Identifier) expressionNode() {}
func (i *Identifier) TokenLiteral() string { return i.Token.Literal }
+func (i *Identifier) String() string { return i.Value }
+
+type ReturnStatement struct {
+ Token token.Token
+ ReturnValue Expression
+}
+
+func (rs *ReturnStatement) statementNode() {}
+func (rs *ReturnStatement) TokenLiteral() string { return rs.Token.Literal }
+func (rs *ReturnStatement) String() string {
+ var out bytes.Buffer
+
+ out.WriteString(rs.TokenLiteral() + " ")
+
+ if rs.ReturnValue != nil {
+ out.WriteString(rs.ReturnValue.String())
+ }
+
+ out.WriteString(";")
+
+ return out.String()
+}
+
+type ExpressionStatement struct {
+ Token token.Token
+ Expression Expression
+}
+
+func (es *ExpressionStatement) statementNode() {}
+func (es *ExpressionStatement) TokenLiteral() string { return es.Token.Literal }
+func (es *ExpressionStatement) String() string {
+ if es.Expression != nil {
+ return es.Expression.String()
+ }
+
+ return ""
+}
+
+type IntegerLiteral struct {
+ Token token.Token
+ Value int64
+}
+
+func (il *IntegerLiteral) expressionNode() {}
+func (il *IntegerLiteral) TokenLiteral() string { return il.Token.Literal }
+func (il *IntegerLiteral) String() string { return il.Token.Literal }
+
+type PrefixExpression struct {
+ Token token.Token
+ Operator string
+ Right Expression
+}
+
+func (pe *PrefixExpression) expressionNode() {}
+func (pe *PrefixExpression) TokenLiteral() string { return pe.Token.Literal }
+func (pe *PrefixExpression) String() string {
+ var out bytes.Buffer
+
+ out.WriteString("(")
+ out.WriteString(pe.Operator)
+ out.WriteString(pe.Right.String())
+ out.WriteString(")")
+
+ return out.String()
+}
diff --git a/ast/ast_test.go b/ast/ast_test.go
new file mode 100644
index 0000000..887827b
--- /dev/null
+++ b/ast/ast_test.go
@@ -0,0 +1,37 @@
+package ast
+
+import (
+ "testing"
+
+ "github.com/mewsen/interpreter/token"
+)
+
+func TestString(t *testing.T) {
+ program := &Program{
+ Statements: []Statement{
+ &LetStatement{
+ Token: token.Token{
+ Type: token.LET,
+ Literal: "let",
+ },
+ Name: &Identifier{
+ Token: token.Token{
+ Type: token.IDENT,
+ Literal: "myVar",
+ },
+ Value: "myVar",
+ },
+ Value: &Identifier{
+ Token: token.Token{
+ Type: token.IDENT,
+ Literal: "anotherVar",
+ },
+ Value: "anotherVar",
+ },
+ },
+ },
+ }
+ if program.String() != "let myVar = anotherVar;" {
+ t.Errorf("program.String() wrong. got=%q", program.String())
+ }
+}