package ast import ( "bytes" "github/runnignwater/monkey/token" ) /** * @Author: simon * @Author: ynwdlxm@163.com * @Date: 2022/10/2 δΈ‹εˆ8:58 * @Desc: */ type Node interface { TokenLiteral() string // This will allow us to print AST nodes for debugging and to compare them with other AST nodes. // This is going to be really handy in tests! String() string } // expressions produce values, statements don't type Statement interface { Node statementNode() } type Expression interface { Node expressionNode() } // ---------------------implementation of Node----------------------------------BEGIN----------------------------------- // Root Node of our parser produces. type Program struct { Statements []Statement } func (p *Program) TokenLiteral() string { if len(p.Statements) > 0 { return p.Statements[0].TokenLiteral() } else { return "" } } func (p *Program) String() string { var out bytes.Buffer for _, s := range p.Statements { out.WriteString(s.String()) } return out.String() } //---------------------implementation of Node-----------------------------------END------------------------------------- // let = ; // // let x = 5 AST // |-------------------| // | *ast.Program | // |-------------------| // | Statements | // |-------------------| // ↓ // |-------------------| // | *ast.LetStatement | // |-------------------| // | Name | // |-------------------| // | Value | // |-------------------| // // *ast.Identifier *ast.Expression // type LetStatement struct { Token token.Token // the token.LET token Name *Identifier Value Expression } 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() } func (ls *LetStatement) statementNode() { panic("implement me") } type Identifier struct { Token token.Token // the token.IDENT token Value string } func (i *Identifier) expressionNode() { panic("implement me") } func (i *Identifier) String() string { return i.Value } func (i *Identifier) TokenLiteral() string { return i.Token.Literal } // return ; type ReturnStatement struct { Token token.Token // the token.RETURN returnValue Expression } 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() } func (rs *ReturnStatement) statementNode() { panic("implement me") } type ExpressionStatement struct { Token token.Token // the first token of the expression Expression Expression } func (es *ExpressionStatement) TokenLiteral() string { return es.Token.Literal } func (es *ExpressionStatement) String() string { if es.Expression != nil { return es.Expression.String() } return "" } func (es *ExpressionStatement) statementNode() {} type IntegerLiteral struct { Token token.Token Value int64 } func (i *IntegerLiteral) TokenLiteral() string { return i.Token.Literal } func (i *IntegerLiteral) String() string { return i.Token.Literal } func (i *IntegerLiteral) expressionNode() {}