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 } type IntegerLiteral struct { Token token.Token Value int64 } type PrefixExpression struct { Token token.Token // prefix token i.e. ! Operator string Right Expression } type InfixExpression struct { Token token.Token // operator tokens i.e. +, -, *, / Left Expression Operator string Right Expression } type Boolean struct { Token token.Token Value bool } // 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 "" } // IntegerLiteral func (il *IntegerLiteral) expression_node() {} func (il *IntegerLiteral) TokenLiteral() string { return il.Token.Literal } func (il *IntegerLiteral) String() string { return il.Token.Literal } // PrefixExpression func (pe *PrefixExpression) expression_node() {} func (pe *PrefixExpression) TokenLiteral() string { return pe.Token.Literal } func (pe *PrefixExpression) String() string { var out bytes.Buffer out.WriteString("(") out.WriteString(pe.Operator) out.WriteString(pe.Right.String()) out.WriteString(")") return out.String() } // Infix Expression func (ie *InfixExpression) expression_node() {} func (ie *InfixExpression) TokenLiteral() string { return ie.Token.Literal } func (ie *InfixExpression) String() string { var out bytes.Buffer out.WriteString("(") out.WriteString(ie.Left.String()) out.WriteString(" " + ie.Operator + " ") out.WriteString(ie.Right.String()) out.WriteString(")") return out.String() } // Booleans func (b *Boolean) expression_node() {} func (b *Boolean) TokenLiteral() string { return b.Token.Literal } func (b *Boolean) String() string { return b.Token.Literal }