package ast import ( "bytes" "github/runnignwater/monkey/token" "strings" ) // Node @Author: simon // @Author: ynwdlxm@163.com // @Date: 2022/10/2 下午8:58 type Node interface { TokenLiteral() string // 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 } // Statement expressions produce values, statements don't type Statement interface { Node statementNode() } type Expression interface { Node expressionNode() } // ---------------------implementation of Node----------------------------------BEGIN----------------------------------- // Program 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------------------------------------- // LetStatement let = ; 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 } // ReturnStatement 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() {} // IntegerLiteral integer value e.g. 5 6 ... 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() {} // PrefixExpression 前缀表示式 e.g. !a -6 type PrefixExpression struct { Token token.Token // The prefix token, e.g. ! Operator string Right Expression } 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() } func (pe *PrefixExpression) expressionNode() {} // InfixExpression type InfixExpression struct { Token token.Token // The operator token, e.g. + - * / Left Expression Operator string Right Expression } func (oe *InfixExpression) TokenLiteral() string { return oe.Token.Literal } func (oe *InfixExpression) String() string { var out bytes.Buffer out.WriteString("(") out.WriteString(oe.Left.String()) out.WriteString(" " + oe.Operator + " ") out.WriteString(oe.Right.String()) out.WriteString(")") return out.String() } func (oe *InfixExpression) expressionNode() {} // Boolean bool 表达式 e.g. true/false type Boolean struct { Token token.Token Value bool } func (b *Boolean) TokenLiteral() string { return b.Token.Literal } func (b *Boolean) String() string { return b.Token.Literal } func (b *Boolean) expressionNode() {} // IfExpression if () else type IfExpression struct { Token token.Token // The 'if' token Condition Expression Consequence *BlockStatement Alternative *BlockStatement } func (ie *IfExpression) TokenLiteral() string { return ie.Token.Literal } func (ie *IfExpression) String() string { var out bytes.Buffer out.WriteString("if") out.WriteString(ie.Condition.String()) out.WriteString(" ") out.WriteString(ie.Consequence.String()) if ie.Alternative != nil { out.WriteString("else ") out.WriteString(ie.Alternative.String()) } return out.String() } func (ie *IfExpression) expressionNode() {} type BlockStatement struct { Token token.Token // the { token Statements []Statement } func (bs *BlockStatement) TokenLiteral() string { return bs.Token.Literal } func (bs *BlockStatement) String() string { var out bytes.Buffer for _, s := range bs.Statements { out.WriteString(s.String()) } return out.String() } func (bs *BlockStatement) statementNode() {} // FunctionLiteral fn type FunctionLiteral struct { Token token.Token // The 'fn' token Parameters []*Identifier Body *BlockStatement } func (fl *FunctionLiteral) TokenLiteral() string { return fl.Token.Literal } func (fl *FunctionLiteral) String() string { var out bytes.Buffer params := []string{} for _, p := range fl.Parameters { params = append(params, p.String()) } out.WriteString(fl.TokenLiteral()) out.WriteString("(") out.WriteString(strings.Join(params, ", ")) out.WriteString(")") out.WriteString(fl.Body.String()) return out.String() } func (fl *FunctionLiteral) expressionNode() {}