package parser
import (
- "container/vector"
"fmt"
"go/ast"
"go/scanner"
indent uint // indentation used for tracing output
// Comments
- comments vector.Vector // list of *CommentGroup
+ comments []*ast.CommentGroup
leadComment *ast.CommentGroup // the last lead comment
lineComment *ast.CommentGroup // the last line comment
// token terminates a comment group.
//
func (p *parser) consumeCommentGroup() (comments *ast.CommentGroup, endline int) {
- var list vector.Vector
+ var list []*ast.Comment
endline = p.pos.Line
for p.tok == token.COMMENT && endline+1 >= p.pos.Line {
var comment *ast.Comment
comment, endline = p.consumeComment()
- list.Push(comment)
- }
-
- // convert list
- group := make([]*ast.Comment, len(list))
- for i, x := range list {
- group[i] = x.(*ast.Comment)
+ list = append(list, comment)
}
// add comment group to the comments list
- comments = &ast.CommentGroup{group}
- p.comments.Push(comments)
+ comments = &ast.CommentGroup{list}
+ p.comments = append(p.comments, comments)
return
}
}
-func (p *parser) parseIdentList() []*ast.Ident {
+func (p *parser) parseIdentList() (list []*ast.Ident) {
if p.trace {
defer un(trace(p, "IdentList"))
}
- var list vector.Vector
- list.Push(p.parseIdent())
+ list = append(list, p.parseIdent())
for p.tok == token.COMMA {
p.next()
- list.Push(p.parseIdent())
- }
-
- // convert vector
- idents := make([]*ast.Ident, len(list))
- for i, x := range list {
- idents[i] = x.(*ast.Ident)
+ list = append(list, p.parseIdent())
}
- return idents
+ return
}
// ----------------------------------------------------------------------------
// Common productions
-func makeExprList(list *vector.Vector) []ast.Expr {
- exprs := make([]ast.Expr, len(*list))
- for i, x := range *list {
- exprs[i] = x.(ast.Expr)
- }
- return exprs
-}
-
-
-func (p *parser) parseExprList() []ast.Expr {
+func (p *parser) parseExprList() (list []ast.Expr) {
if p.trace {
defer un(trace(p, "ExpressionList"))
}
- var list vector.Vector
- list.Push(p.parseExpr())
+ list = append(list, p.parseExpr())
for p.tok == token.COMMA {
p.next()
- list.Push(p.parseExpr())
+ list = append(list, p.parseExpr())
}
- return makeExprList(&list)
+ return
}
}
-func (p *parser) makeIdentList(list *vector.Vector) []*ast.Ident {
- idents := make([]*ast.Ident, len(*list))
- for i, x := range *list {
+func (p *parser) makeIdentList(list []ast.Expr) []*ast.Ident {
+ idents := make([]*ast.Ident, len(list))
+ for i, x := range list {
ident, isIdent := x.(*ast.Ident)
if !isIdent {
pos := x.(ast.Expr).Pos()
idents = p.makeIdentList(list)
} else {
// ["*"] TypeName (AnonymousField)
- typ = (*list)[0].(ast.Expr) // we always have at least one element
- if len(*list) > 1 || !isTypeName(deref(typ)) {
+ typ = list[0] // we always have at least one element
+ if len(list) > 1 || !isTypeName(deref(typ)) {
pos := typ.Pos()
p.errorExpected(pos, "anonymous field")
typ = &ast.BadExpr{pos}
pos := p.expect(token.STRUCT)
lbrace := p.expect(token.LBRACE)
- var list vector.Vector
+ var list []*ast.Field
for p.tok == token.IDENT || p.tok == token.MUL || p.tok == token.LPAREN {
// a field declaration cannot start with a '(' but we accept
// it here for more robust parsing and better error messages
// (parseFieldDecl will check and complain if necessary)
- list.Push(p.parseFieldDecl())
+ list = append(list, p.parseFieldDecl())
}
rbrace := p.expect(token.RBRACE)
- // convert vector
- fields := make([]*ast.Field, len(list))
- for i, x := range list {
- fields[i] = x.(*ast.Field)
- }
-
- return &ast.StructType{pos, &ast.FieldList{lbrace, fields, rbrace}, false}
+ return &ast.StructType{pos, &ast.FieldList{lbrace, list, rbrace}, false}
}
}
-func (p *parser) parseVarList(isParam bool) (*vector.Vector, ast.Expr) {
+func (p *parser) parseVarList(isParam bool) (list []ast.Expr, typ ast.Expr) {
if p.trace {
defer un(trace(p, "VarList"))
}
// a list of identifiers looks like a list of type names
- var list vector.Vector
for {
// parseVarType accepts any type (including parenthesized ones)
// even though the syntax does not permit them here: we
// accept them all for more robust parsing and complain
// afterwards
- list.Push(p.parseVarType(isParam))
+ list = append(list, p.parseVarType(isParam))
if p.tok != token.COMMA {
break
}
}
// if we had a list of identifiers, it must be followed by a type
- typ := p.tryVarType(isParam)
+ typ = p.tryVarType(isParam)
- return &list, typ
+ return
}
-func (p *parser) parseParameterList(ellipsisOk bool) []*ast.Field {
+func (p *parser) parseParameterList(ellipsisOk bool) (params []*ast.Field) {
if p.trace {
defer un(trace(p, "ParameterList"))
}
if typ != nil {
// IdentifierList Type
idents := p.makeIdentList(list)
- list.Resize(0, 0)
- list.Push(&ast.Field{nil, idents, typ, nil, nil})
+ params = append(params, &ast.Field{nil, idents, typ, nil, nil})
if p.tok == token.COMMA {
p.next()
}
for p.tok != token.RPAREN && p.tok != token.EOF {
idents := p.parseIdentList()
typ := p.parseVarType(ellipsisOk)
- list.Push(&ast.Field{nil, idents, typ, nil, nil})
+ params = append(params, &ast.Field{nil, idents, typ, nil, nil})
if p.tok != token.COMMA {
break
}
} else {
// Type { "," Type } (anonymous parameters)
- // convert list of types into list of *Param
- for i, x := range *list {
- list.Set(i, &ast.Field{Type: x.(ast.Expr)})
+ params = make([]*ast.Field, len(list))
+ for i, x := range list {
+ params[i] = &ast.Field{Type: x}
}
}
- // convert list
- params := make([]*ast.Field, len(*list))
- for i, x := range *list {
- params[i] = x.(*ast.Field)
- }
-
- return params
+ return
}
pos := p.expect(token.INTERFACE)
lbrace := p.expect(token.LBRACE)
- var list vector.Vector
+ var list []*ast.Field
for p.tok == token.IDENT {
- list.Push(p.parseMethodSpec())
+ list = append(list, p.parseMethodSpec())
}
rbrace := p.expect(token.RBRACE)
- // convert vector
- methods := make([]*ast.Field, len(list))
- for i, x := range list {
- methods[i] = x.(*ast.Field)
- }
-
- return &ast.InterfaceType{pos, &ast.FieldList{lbrace, methods, rbrace}, false}
+ return &ast.InterfaceType{pos, &ast.FieldList{lbrace, list, rbrace}, false}
}
// ----------------------------------------------------------------------------
// Blocks
-func makeStmtList(list *vector.Vector) []ast.Stmt {
- stats := make([]ast.Stmt, len(*list))
- for i, x := range *list {
- stats[i] = x.(ast.Stmt)
- }
- return stats
-}
-
-
-func (p *parser) parseStmtList() []ast.Stmt {
+func (p *parser) parseStmtList() (list []ast.Stmt) {
if p.trace {
defer un(trace(p, "StatementList"))
}
- var list vector.Vector
for p.tok != token.CASE && p.tok != token.DEFAULT && p.tok != token.RBRACE && p.tok != token.EOF {
- list.Push(p.parseStmt())
+ list = append(list, p.parseStmt())
}
- return makeStmtList(&list)
+ return
}
lparen := p.expect(token.LPAREN)
p.exprLev++
- var list vector.Vector
+ var list []ast.Expr
var ellipsis token.Position
for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
- list.Push(p.parseExpr())
+ list = append(list, p.parseExpr())
if p.tok == token.ELLIPSIS {
ellipsis = p.pos
p.next()
p.exprLev--
rparen := p.expect(token.RPAREN)
- return &ast.CallExpr{fun, lparen, makeExprList(&list), ellipsis, rparen}
+ return &ast.CallExpr{fun, lparen, list, ellipsis, rparen}
}
}
-func (p *parser) parseElementList() []ast.Expr {
+func (p *parser) parseElementList() (list []ast.Expr) {
if p.trace {
defer un(trace(p, "ElementList"))
}
- var list vector.Vector
for p.tok != token.RBRACE && p.tok != token.EOF {
- list.Push(p.parseElement(true))
+ list = append(list, p.parseElement(true))
if p.tok != token.COMMA {
break
}
p.next()
}
- return makeExprList(&list)
+ return
}
}
-func (p *parser) parseTypeList() []ast.Expr {
+func (p *parser) parseTypeList() (list []ast.Expr) {
if p.trace {
defer un(trace(p, "TypeList"))
}
- var list vector.Vector
- list.Push(p.parseType())
+ list = append(list, p.parseType())
for p.tok == token.COMMA {
p.next()
- list.Push(p.parseType())
+ list = append(list, p.parseType())
}
- return makeExprList(&list)
+ return
}
if isExprSwitch(s2) {
lbrace := p.expect(token.LBRACE)
- var cases vector.Vector
+ var list []ast.Stmt
for p.tok == token.CASE || p.tok == token.DEFAULT {
- cases.Push(p.parseCaseClause())
+ list = append(list, p.parseCaseClause())
}
rbrace := p.expect(token.RBRACE)
- body := &ast.BlockStmt{lbrace, makeStmtList(&cases), rbrace}
+ body := &ast.BlockStmt{lbrace, list, rbrace}
p.expectSemi()
return &ast.SwitchStmt{pos, s1, p.makeExpr(s2), body}
}
// type switch
// TODO(gri): do all the checks!
lbrace := p.expect(token.LBRACE)
- var cases vector.Vector
+ var list []ast.Stmt
for p.tok == token.CASE || p.tok == token.DEFAULT {
- cases.Push(p.parseTypeCaseClause())
+ list = append(list, p.parseTypeCaseClause())
}
rbrace := p.expect(token.RBRACE)
p.expectSemi()
- body := &ast.BlockStmt{lbrace, makeStmtList(&cases), rbrace}
+ body := &ast.BlockStmt{lbrace, list, rbrace}
return &ast.TypeSwitchStmt{pos, s1, s2, body}
}
pos := p.expect(token.SELECT)
lbrace := p.expect(token.LBRACE)
- var cases vector.Vector
+ var list []ast.Stmt
for p.tok == token.CASE || p.tok == token.DEFAULT {
- cases.Push(p.parseCommClause())
+ list = append(list, p.parseCommClause())
}
rbrace := p.expect(token.RBRACE)
p.expectSemi()
- body := &ast.BlockStmt{lbrace, makeStmtList(&cases), rbrace}
+ body := &ast.BlockStmt{lbrace, list, rbrace}
return &ast.SelectStmt{pos, body}
}
doc := p.leadComment
pos := p.expect(keyword)
var lparen, rparen token.Position
- var list vector.Vector
+ var list []ast.Spec
if p.tok == token.LPAREN {
lparen = p.pos
p.next()
for p.tok != token.RPAREN && p.tok != token.EOF {
- list.Push(f(p, p.leadComment))
+ list = append(list, f(p, p.leadComment))
}
rparen = p.expect(token.RPAREN)
p.expectSemi()
} else {
- list.Push(f(p, nil))
+ list = append(list, f(p, nil))
}
- // convert vector
- specs := make([]ast.Spec, len(list))
- for i, x := range list {
- specs[i] = x.(ast.Spec)
- }
-
- return &ast.GenDecl{doc, pos, keyword, lparen, specs, rparen}
+ return &ast.GenDecl{doc, pos, keyword, lparen, list, rparen}
}
}
-func (p *parser) parseDeclList() []ast.Decl {
+func (p *parser) parseDeclList() (list []ast.Decl) {
if p.trace {
defer un(trace(p, "DeclList"))
}
- var list vector.Vector
for p.tok != token.EOF {
- list.Push(p.parseDecl())
- }
-
- // convert vector
- decls := make([]ast.Decl, len(list))
- for i, x := range list {
- decls[i] = x.(ast.Decl)
+ list = append(list, p.parseDecl())
}
- return decls
+ return
}
if p.ErrorCount() == 0 && p.mode&PackageClauseOnly == 0 {
// import decls
- var list vector.Vector
for p.tok == token.IMPORT {
- list.Push(p.parseGenDecl(token.IMPORT, parseImportSpec))
+ decls = append(decls, p.parseGenDecl(token.IMPORT, parseImportSpec))
}
if p.mode&ImportsOnly == 0 {
// rest of package body
for p.tok != token.EOF {
- list.Push(p.parseDecl())
+ decls = append(decls, p.parseDecl())
}
}
-
- // convert declaration list
- decls = make([]ast.Decl, len(list))
- for i, x := range list {
- decls[i] = x.(ast.Decl)
- }
- }
-
- // convert comments list
- comments := make([]*ast.CommentGroup, len(p.comments))
- for i, x := range p.comments {
- comments[i] = x.(*ast.CommentGroup)
}
- return &ast.File{doc, pos, ident, decls, comments}
+ return &ast.File{doc, pos, ident, decls, p.comments}
}