diff options
| author | Bobby <[email protected]> | 2023-11-03 14:38:47 +0000 |
|---|---|---|
| committer | Bobby <[email protected]> | 2023-11-03 14:38:47 +0000 |
| commit | 15f9a15757322221d8bf9a3ecd5d8ce8490ebda6 (patch) | |
| tree | 1b3e5008cca84aa614d70b4e5c553a329ef47c7d /ast | |
| parent | a2480336996a7b1be082386e8db1c59ed6509b2a (diff) | |
| download | mana-15f9a15757322221d8bf9a3ecd5d8ce8490ebda6.tar.xz mana-15f9a15757322221d8bf9a3ecd5d8ce8490ebda6.zip | |
ast:String() method and tests
Diffstat (limited to 'ast')
| -rw-r--r-- | ast/ast.go | 56 | ||||
| -rw-r--r-- | ast/ast_test.go | 28 |
2 files changed, 83 insertions, 1 deletions
@@ -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()) + } +} |
