aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast/ast.go56
-rw-r--r--ast/ast_test.go28
2 files changed, 83 insertions, 1 deletions
diff --git a/ast/ast.go b/ast/ast.go
index c53dfdf..fea8b60 100644
--- a/ast/ast.go
+++ b/ast/ast.go
@@ -1,9 +1,13 @@
package ast
-import "mana/tokens"
+import (
+ "bytes"
+ "mana/tokens"
+)
type Node interface {
TokenLiteral() string
+ String() string
}
type Statement interface {
@@ -30,6 +34,19 @@ func (p *Program) TokenLiteral() string {
return ""
}
+// String returns a string representation of the program. This is used only for
+// debugging and testing.
+
+func (p *Program) String() string {
+ var out bytes.Buffer
+
+ for _, s := range p.Statements {
+ out.WriteString(s.String())
+ }
+
+ return out.String()
+}
+
// LetStatement represents a let statement.
type LetStatement struct {
Token tokens.Token // the token.LET token
@@ -41,6 +58,21 @@ 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())
+ }
+
+ out.WriteString(";")
+
+ return out.String()
+}
// Identifier represents an identifier.
type Identifier struct {
@@ -52,6 +84,9 @@ func (i *Identifier) expressionNode() {}
func (i *Identifier) TokenLiteral() string {
return i.Token.Literal
}
+func (i *Identifier) String() string {
+ return i.Value
+}
// ReturnStatement represents a return statement.
type ReturnStatement struct {
@@ -63,6 +98,19 @@ 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()
+}
// ExpressionStatement represents an expression statement.
type ExpressionStatement struct {
@@ -74,3 +122,9 @@ 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 ""
+}
diff --git a/ast/ast_test.go b/ast/ast_test.go
new file mode 100644
index 0000000..e16cc11
--- /dev/null
+++ b/ast/ast_test.go
@@ -0,0 +1,28 @@
+package ast
+
+import (
+ "mana/tokens"
+ "testing"
+)
+
+func TestString(t *testing.T) {
+ var program = &Program{
+ Statements: []Statement{
+ &LetStatement{
+ Token: tokens.Token{Type: tokens.LET, Literal: "let"},
+ Name: &Identifier{
+ Token: tokens.Token{Type: tokens.IDENT, Literal: "myVar"},
+ Value: "myVar",
+ },
+ Value: &Identifier{
+ Token: tokens.Token{Type: tokens.IDENT, Literal: "anotherVar"},
+ Value: "anotherVar",
+ },
+ },
+ },
+ }
+
+ if program.String() != "let myVar = anotherVar;" {
+ t.Errorf("program.String() wrong. got=%q", program.String())
+ }
+}