|
|
@@ -3,6 +3,7 @@ package ast
|
|
|
import (
|
|
|
"bytes"
|
|
|
"github/runnignwater/monkey/token"
|
|
|
+ "strings"
|
|
|
)
|
|
|
|
|
|
/**
|
|
|
@@ -13,12 +14,12 @@ import (
|
|
|
*/
|
|
|
type Node interface {
|
|
|
TokenLiteral() string
|
|
|
- // This will allow us to print AST nodes for debugging and to compare them with other AST nodes.
|
|
|
+ // 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
|
|
|
+// Statement expressions produce values, statements don't
|
|
|
type Statement interface {
|
|
|
Node
|
|
|
statementNode()
|
|
|
@@ -53,23 +54,22 @@ func (p *Program) String() string {
|
|
|
|
|
|
// let <identifier> = <expression>;
|
|
|
//
|
|
|
-// let x = 5 AST
|
|
|
-// |-------------------|
|
|
|
-// | *ast.Program |
|
|
|
-// |-------------------|
|
|
|
-// | Statements |
|
|
|
-// |-------------------|
|
|
|
-// ↓
|
|
|
-// |-------------------|
|
|
|
-// | *ast.LetStatement |
|
|
|
-// |-------------------|
|
|
|
-// | Name |
|
|
|
-// |-------------------|
|
|
|
-// | Value |
|
|
|
-// |-------------------|
|
|
|
-//
|
|
|
-// *ast.Identifier *ast.Expression
|
|
|
+// 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
|
|
|
@@ -111,7 +111,7 @@ func (i *Identifier) TokenLiteral() string {
|
|
|
return i.Token.Literal
|
|
|
}
|
|
|
|
|
|
-// return <expression>;
|
|
|
+// ReturnStatement return <expression>;
|
|
|
type ReturnStatement struct {
|
|
|
Token token.Token // the token.RETURN
|
|
|
returnValue Expression
|
|
|
@@ -270,3 +270,32 @@ func (bs *BlockStatement) String() string {
|
|
|
}
|
|
|
|
|
|
func (bs *BlockStatement) statementNode() {}
|
|
|
+
|
|
|
+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() {}
|