From 426f42c79952e6a249734229bbcbc60034ef4621 Mon Sep 17 00:00:00 2001 From: brettlangdon Date: Sat, 19 Sep 2015 10:14:45 -0400 Subject: [PATCH] add Repr(), added ListNode back in, and some more nodes --- ast/base.go | 6 ++++++ ast/expressionstatement.go | 7 +++++++ ast/fileinput.go | 21 ++++--------------- ast/listnode.go | 41 ++++++++++++++++++++++++++++++++++++++ ast/node.go | 1 + ast/simplestatement.go | 7 +++---- ast/smallstatement.go | 7 +++++++ ast/statement.go | 7 +++++++ ast/testliststartexpr.go | 11 ++++++++++ main.go | 2 +- parser/parser.go | 19 ++++++++++++++---- 11 files changed, 103 insertions(+), 26 deletions(-) create mode 100644 ast/listnode.go create mode 100644 ast/testliststartexpr.go diff --git a/ast/base.go b/ast/base.go index f129bed..dbcd00c 100644 --- a/ast/base.go +++ b/ast/base.go @@ -11,3 +11,9 @@ func (node *BaseNode) initBaseNode(id NodeID) { func (node *BaseNode) Name() string { return NodeNames[node.ID] } + +func (node *BaseNode) Repr() []interface{} { + out := make([]interface{}, 0) + out = append(out, node.Name()) + return out +} diff --git a/ast/expressionstatement.go b/ast/expressionstatement.go index b7b6ddf..723e669 100644 --- a/ast/expressionstatement.go +++ b/ast/expressionstatement.go @@ -2,6 +2,7 @@ package ast type ExpressionStatement struct { BaseNode + Expression *TestlistStartExpr } func NewExpressionStatement() *ExpressionStatement { @@ -11,3 +12,9 @@ func NewExpressionStatement() *ExpressionStatement { } func (node *ExpressionStatement) SmallStatementNode() {} + +func (node *ExpressionStatement) Repr() []interface{} { + out := node.BaseNode.Repr() + out = append(out, node.Expression.Repr()) + return out +} diff --git a/ast/fileinput.go b/ast/fileinput.go index bc9274a..e2ce5ef 100644 --- a/ast/fileinput.go +++ b/ast/fileinput.go @@ -1,28 +1,15 @@ package ast -import "github.com/brettlangdon/gython/token" - type FileInput struct { - BaseNode - children []interface{} + ListNode } func NewFileInput() *FileInput { - node := &FileInput{ - children: make([]interface{}, 0), - } + node := &FileInput{} node.initBaseNode(FILE_INPUT) + node.initListNode() return node } - -func (node *FileInput) AppendToken(t *token.Token) { - node.children = append(node.children, t) -} - func (node *FileInput) AppendNode(n StatementNode) { - node.children = append(node.children, n) -} - -func (node *FileInput) Children() []interface{} { - return node.children + node.ListNode.AppendNode(n) } diff --git a/ast/listnode.go b/ast/listnode.go new file mode 100644 index 0000000..33290f3 --- /dev/null +++ b/ast/listnode.go @@ -0,0 +1,41 @@ +package ast + +import "github.com/brettlangdon/gython/token" + +type ListNode struct { + BaseNode + children []interface{} +} + +func (node *ListNode) initListNode() { + node.children = make([]interface{}, 0) +} + +func (node *ListNode) AppendToken(t *token.Token) { + node.children = append(node.children, t) +} + +func (node *ListNode) AppendNode(n Node) { + node.children = append(node.children, n) +} + +func (node *ListNode) Children() []interface{} { + return node.children +} + +func (node *ListNode) Length() int { + return len(node.children) +} + +func (node *ListNode) Repr() []interface{} { + out := node.BaseNode.Repr() + for _, child := range node.Children() { + switch child.(type) { + case Node: + out = append(out, child.(Node).Repr()) + default: + out = append(out, child) + } + } + return out +} diff --git a/ast/node.go b/ast/node.go index bbc0d0a..6c42856 100644 --- a/ast/node.go +++ b/ast/node.go @@ -2,4 +2,5 @@ package ast type Node interface { Name() string + Repr() []interface{} } diff --git a/ast/simplestatement.go b/ast/simplestatement.go index 517d5d7..c5aea0c 100644 --- a/ast/simplestatement.go +++ b/ast/simplestatement.go @@ -1,8 +1,7 @@ package ast type SimpleStatement struct { - BaseNode - Statements []*SmallStatement + ListNode } func NewSimpleStatement() *SimpleStatement { @@ -13,6 +12,6 @@ func NewSimpleStatement() *SimpleStatement { func (node *SimpleStatement) StatementNode() {} -func (node *SimpleStatement) AppendSmallStatement(n *SmallStatement) { - node.Statements = append(node.Statements, n) +func (node *SimpleStatement) AppendNode(n *SmallStatement) { + node.ListNode.AppendNode(n) } diff --git a/ast/smallstatement.go b/ast/smallstatement.go index afaf76a..0bbdad2 100644 --- a/ast/smallstatement.go +++ b/ast/smallstatement.go @@ -1,6 +1,7 @@ package ast type SmallStatementNode interface { + Node SmallStatementNode() } @@ -14,3 +15,9 @@ func NewSmallStatement() *SmallStatement { node.initBaseNode(SMALL_STMT) return node } + +func (node *SmallStatement) Repr() []interface{} { + out := node.BaseNode.Repr() + out = append(out, node.Statement.Repr()) + return out +} diff --git a/ast/statement.go b/ast/statement.go index ace66b3..013ee99 100644 --- a/ast/statement.go +++ b/ast/statement.go @@ -1,6 +1,7 @@ package ast type StatementNode interface { + Node StatementNode() } @@ -16,3 +17,9 @@ func NewStatement() *Statement { } func (node *Statement) StatementNode() {} + +func (node *Statement) Repr() []interface{} { + out := node.BaseNode.Repr() + out = append(out, node.Statement.Repr()) + return out +} diff --git a/ast/testliststartexpr.go b/ast/testliststartexpr.go new file mode 100644 index 0000000..cd3f462 --- /dev/null +++ b/ast/testliststartexpr.go @@ -0,0 +1,11 @@ +package ast + +type TestlistStartExpr struct { + BaseNode +} + +func NewTestListStartExpr() *TestlistStartExpr { + node := &TestlistStartExpr{} + node.initBaseNode(TESTLIST_STAR_EXPR) + return node +} diff --git a/main.go b/main.go index 661831b..0625137 100644 --- a/main.go +++ b/main.go @@ -25,5 +25,5 @@ func tokenize() { func main() { root, p := parser.ParseReader(os.Stdin) fmt.Println(p) - fmt.Println(root) + fmt.Println(root.Repr()) } diff --git a/parser/parser.go b/parser/parser.go index 6cf1086..7365427 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -50,10 +50,21 @@ func (parser *Parser) parseCompoundStatement() *ast.CompoundStatement { return compoundStmt } +// testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] +func (parser *Parser) parseTestlistStartExpr() *ast.TestlistStartExpr { + testlistStartExpr := ast.NewTestListStartExpr() + return testlistStartExpr +} + // expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | // ('=' (yield_expr|testlist_star_expr))*) func (parser *Parser) parseExpressionStatement() *ast.ExpressionStatement { exprStmt := ast.NewExpressionStatement() + testlistStartExpr := parser.parseTestlistStartExpr() + if testlistStartExpr == nil { + return nil + } + exprStmt.Expression = testlistStartExpr return exprStmt } @@ -82,19 +93,19 @@ func (parser *Parser) parseSimpleStatement() *ast.SimpleStatement { if smallStmt == nil { break } - simpleStmt.AppendSmallStatement(smallStmt) + simpleStmt.AppendNode(smallStmt) next := parser.nextToken() if next.ID != token.SEMI { parser.unreadToken(next) break } } + parser.expect(token.NEWLINE) + // no small statements found - if len(simpleStmt.Statements) == 0 { + if simpleStmt.Length() == 0 { return nil } - - parser.expect(token.NEWLINE) return simpleStmt }