monna/ast/ast.go
tijani e456189c86 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
2022-05-30 05:51:27 +00:00

126 lines
2.2 KiB
Go

package ast
import (
"bytes"
"monkey/token"
)
type Node interface {
TokenLiteral() string
String() string
}
type Statement interface {
Node
statement_node()
}
type Expression interface {
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 {
Statements []Statement
}
type Identifier struct {
Token token.Token // the token.IDENT token
Value string
}
type LetStatement struct {
Token token.Token // token.LET token
Name *Identifier
Value Expression
}
type ReturnStatement struct {
Token token.Token // token.RETURN token
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) 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
func (i *Identifier) expression_node() {}
func (i *Identifier) TokenLiteral() string {
return i.Token.Literal
}
func (i *Identifier) String() string {
return i.Value
}
// Program
func (p *Program) TokenLiteral() string {
if len(p.Statements) > 0 {
return p.Statements[0].TokenLiteral()
} else {
return ""
}
}
// Return Statements
func (rs *ReturnStatement) statement_node() {}
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()
}
// 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 ""
}