From 4e690ec67d04223c3306c2b49935b08c1d230e6b Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Sat, 17 Oct 2015 00:00:05 +0300 Subject: [PATCH] parser: add ListType support --- ast/ast.go | 4 ++++ parser/parser.go | 42 +++++++++++++++++++++++++++++++++++------- parser/parser_test.go | 18 ++++++++++++------ 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index 9c8a01e..b0d8251 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -82,6 +82,10 @@ func (l *ListType) Pos() token.Pos { return l.Lbrack } +func (l *ListType) Add(node Node) { + l.List = append(l.List, node) +} + // ObjectType represents a HCL Object Type type ObjectType struct { Lbrace token.Pos // position of "{" diff --git a/parser/parser.go b/parser/parser.go index 3fea2a9..d007578 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -154,6 +154,41 @@ func (p *Parser) parseObjectKey() ([]*ast.ObjectKey, error) { } } +// parseListType parses a list type and returns a ListType AST +func (p *Parser) parseListType() (*ast.ListType, error) { + defer un(trace(p, "ParseListType")) + + l := &ast.ListType{ + Lbrack: p.tok.Pos, + } + + for { + tok := p.scan() + switch tok.Type { + case token.NUMBER, token.FLOAT, token.STRING: + node, err := p.parseLiteralType() + if err != nil { + return nil, err + } + l.Add(node) + case token.COMMA: + // get next list item or we are at the end + continue + case token.BOOL: + // TODO(arslan) should we support? not supported by HCL yet + case token.LBRACK: + // TODO(arslan) should we support nested lists? + case token.RBRACK: + // finished + l.Rbrack = p.tok.Pos + return l, nil + default: + return nil, fmt.Errorf("unexpected token while parsing list: %s", tok.Type) + } + + } +} + // parseLiteralType parses a literal type and returns a LiteralType AST func (p *Parser) parseLiteralType() (*ast.LiteralType, error) { defer un(trace(p, "ParseLiteral")) @@ -170,13 +205,6 @@ func (p *Parser) parseObjectType() (*ast.ObjectType, error) { return nil, errors.New("ObjectType is not implemented yet") } -// parseListType parses a list type and returns a ListType AST -func (p *Parser) parseListType() (*ast.ListType, error) { - defer un(trace(p, "ParseListType")) - - return nil, errors.New("ListType is not implemented yet") -} - // scan returns the next token from the underlying scanner. // If a token has been unscanned then read that instead. func (p *Parser) scan() token.Token { diff --git a/parser/parser_test.go b/parser/parser_test.go index 31216a2..437c254 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -12,19 +12,25 @@ import ( ) func TestParseType(t *testing.T) { - src := `foo = true` + src := `foo = ["fatih", "arslan", 1224]` p := New([]byte(src)) p.enableTrace = true - n, err := p.Parse() + node, err := p.Parse() if err != nil { t.Fatal(err) } - fmt.Printf("n = %+v\n", n) - - ast.Walk(n, func(node ast.Node) bool { - fmt.Printf("node = %+v\n", node) + ast.Walk(node, func(n ast.Node) bool { + if list, ok := n.(*ast.ObjectList); ok { + for _, l := range list.Items { + for _, k := range l.Keys { + fmt.Printf("key = %+v\n", k) + } + fmt.Printf("val = %+v\n", l.Val) + } + return false + } return true }) }