Skip to content

Commit

Permalink
feat: add String() method to all statements
Browse files Browse the repository at this point in the history
  • Loading branch information
vighnesh153 committed Jan 20, 2024
1 parent e05f924 commit 0e11ff4
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 3 deletions.
63 changes: 60 additions & 3 deletions golang-tools/interpreters/monkey-lang/ast/ast.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package ast

import "vighnesh153/interpreters/monkey-lang/token"
import (
"bytes"
"vighnesh153/interpreters/monkey-lang/token"
)

type Node interface {
TokenLiteral() string
String() string
}

type Statement interface {
Expand All @@ -20,6 +24,16 @@ type Program struct {
Statements []Statement
}

func (p *Program) String() string {
var out bytes.Buffer

for _, s := range p.Statements {
out.WriteString(s.String())
}

return out.String()
}

func (p *Program) TokenLiteral() string {
if len(p.Statements) > 0 {
return p.Statements[0].TokenLiteral()
Expand All @@ -36,6 +50,21 @@ 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())
}

out.WriteString(";")

return out.String()
}

type Identifier struct {
Token token.Token // token.IDENTIFIER token
Expand All @@ -44,11 +73,39 @@ 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 // the token.RETURN token
ReturnValue Expression
}

func (ls *ReturnStatement) statementNode() {}
func (ls *ReturnStatement) TokenLiteral() string { return ls.Token.Literal }
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 // the first token of the expression
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 ""
}
37 changes: 37 additions & 0 deletions golang-tools/interpreters/monkey-lang/ast/ast_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ast

import (
"testing"
"vighnesh153/interpreters/monkey-lang/token"
)

func TestAstString(t *testing.T) {
program := &Program{
Statements: []Statement{
&LetStatement{
Token: token.Token{
Type: token.LET,
Literal: "let",
},
Name: &Identifier{
Token: token.Token{
Type: token.IDENTIFIER,
Literal: "pikachu",
},
Value: "pikachu",
},
Value: &Identifier{
Token: token.Token{
Type: token.IDENTIFIER,
Literal: "best",
},
Value: "best",
},
},
},
}

if program.String() != "let pikachu = best;" {
t.Errorf("program.String() wrong. got=%q", program.String())
}
}

0 comments on commit 0e11ff4

Please sign in to comment.