ExpressionStatement in the AST to represent the typse of expressions that is supported in monkey.

Hand written test in the AST to test the String() function for accuracy



git-svn-id: https://svn.tlawal.org/svn/monkey@22 f6afcba9-9ef1-4bdd-9b72-7484f5705bac
This commit is contained in:
Tijani Lawal 2022-05-30 05:51:27 +00:00
parent fdf6a8a552
commit e456189c86
3 changed files with 95 additions and 6 deletions

View File

@ -1,9 +1,13 @@
package ast package ast
import "monkey/token" import (
"bytes"
"monkey/token"
)
type Node interface { type Node interface {
TokenLiteral() string TokenLiteral() string
String() string
} }
type Statement interface { type Statement interface {
@ -16,6 +20,14 @@ type Expression interface {
expression_node() expression_node()
} }
func (l_program *Program) String() string {
var out bytes.Buffer
for _, s := range l_program.Statements {
out.WriteString(s.String())
}
return out.String()
}
type Program struct { type Program struct {
Statements []Statement Statements []Statement
} }
@ -36,18 +48,43 @@ type ReturnStatement struct {
ReturnValue Expression ReturnValue Expression
} }
type ExpressionStatement struct {
Token token.Token // the first token in the expression
Expression Expression
}
// Let Statements
func (ls *LetStatement) statement_node() {} func (ls *LetStatement) statement_node() {}
func (ls *LetStatement) TokenLiteral() string { func (ls *LetStatement) TokenLiteral() string {
return ls.Token.Literal 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
func (i *Identifier) expression_node() {} func (i *Identifier) expression_node() {}
func (i *Identifier) TokenLiteral() string { func (i *Identifier) TokenLiteral() string {
return i.Token.Literal return i.Token.Literal
} }
func (i *Identifier) String() string {
return i.Value
}
// Program
func (p *Program) TokenLiteral() string { func (p *Program) TokenLiteral() string {
if len(p.Statements) > 0 { if len(p.Statements) > 0 {
return p.Statements[0].TokenLiteral() return p.Statements[0].TokenLiteral()
@ -56,8 +93,33 @@ func (p *Program) TokenLiteral() string {
} }
} }
// Return Statements
func (rs *ReturnStatement) statement_node() {} func (rs *ReturnStatement) statement_node() {}
func (rs *ReturnStatement) TokenLiteral() string { func (rs *ReturnStatement) TokenLiteral() string {
return rs.Token.Literal 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()
}
// Expression Statement
func (es *ExpressionStatement) statement_node() {}
func (es *ExpressionStatement) TokenLiteral() string {
return es.Token.Literal
}
func (es *ExpressionStatement) String() string {
if es.Expression != nil {
return es.Expression.String()
}
return ""
}

28
ast/ast_test.go Normal file
View File

@ -0,0 +1,28 @@
package ast
import (
"monkey/token"
"testing"
)
func TestString(l_test *testing.T) {
program := &Program{
Statements: []Statement{
&LetStatement{
Token: token.Token{Type: token.LET, Literal: "let"},
Name: &Identifier{
Token: token.Token{Type: token.IDENT, Literal: "my_var"},
Value: "my_var",
},
Value: &Identifier{
Token: token.Token{Type: token.IDENT, Literal: "another_var"},
Value: "another_var",
},
},
},
}
if program.String() != "let my_var = another_var;" {
l_test.Errorf("program.String() wrong, got=%q", program.String())
}
}

View File

@ -1,10 +1,9 @@
/* TODO(tijani): /* TODO(tijani):
- add quit command to the repl.
- remove semicolons from the language to mark the end of a statement.
- add line and position reporting in the lexer when a lexing or parsing error occurs.
*/
- add quit command to the repl.
- remove semicolons from the language to mark the end of a statement.
- add line and position reporting in the lexer when a lexing or parsing error occurs.
*/
package main package main