diff --git a/parser/ast.go b/parser/ast.go index 8b0dc0a..eec25cc 100644 --- a/parser/ast.go +++ b/parser/ast.go @@ -2,18 +2,6 @@ package parser import "github.com/fatih/hcl/scanner" -type NodeType int - -const ( - Unknown NodeType = 0 - Number - Float - Bool - String - List - Object -) - // Node is an element in the abstract syntax tree. type Node interface { node() @@ -109,15 +97,18 @@ func (o *ObjectStatement) Pos() scanner.Pos { // LiteralType represents a literal of basic type. Valid types are: // scanner.NUMBER, scanner.FLOAT, scanner.BOOL and scanner.STRING type LiteralType struct { - token scanner.Token + *Ident } -func (l *LiteralType) String() string { - return l.token.Text -} - -func (l *LiteralType) Pos() scanner.Pos { - return l.token.Pos +// isValid() returns true if the underlying identifier satisfies one of the +// valid types. +func (l *LiteralType) isValid() bool { + switch l.token.Type { + case scanner.NUMBER, scanner.FLOAT, scanner.BOOL, scanner.STRING: + return true + default: + return false + } } // ListStatement represents a HCL List type diff --git a/parser/parser.go b/parser/parser.go index 4d47810..5eb03da 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -55,7 +55,7 @@ func (p *Parser) parseNode() (Node, error) { if tok.Type.IsLiteral() { if p.prevTok.Type.IsLiteral() { - return p.parseObjectType() + return p.parseObjectStatement() } tok := p.scan() @@ -70,6 +70,7 @@ func (p *Parser) parseNode() (Node, error) { return nil, errors.New("not yet implemented") } +// parseAssignment parses an assignment and returns a AssignStatement AST func (p *Parser) parseAssignment() (*AssignStatement, error) { defer un(trace(p, "ParseAssignment")) a := &AssignStatement{ @@ -88,6 +89,7 @@ func (p *Parser) parseAssignment() (*AssignStatement, error) { return a, nil } +// parseIdent parses a generic identifier and returns a Ident AST func (p *Parser) parseIdent() (*Ident, error) { defer un(trace(p, "ParseIdent")) @@ -100,12 +102,37 @@ func (p *Parser) parseIdent() (*Ident, error) { }, nil } -func (p *Parser) parseObjectType() (*ObjectStatement, error) { +// parseLiteralType parses a literal type and returns a LiteralType AST +func (p *Parser) parseLiteralType() (*LiteralType, error) { + i, err := p.parseIdent() + if err != nil { + return nil, err + } + + l := &LiteralType{} + l.Ident = i + + if !l.isValid() { + return nil, fmt.Errorf("Identifier is not a LiteralType: %s", l.token) + } + + return l, nil +} + +// parseObjectStatement parses an object statement returns an ObjectStatement +// AST. ObjectsStatements represents both normal and nested objects statement +func (p *Parser) parseObjectStatement() (*ObjectStatement, error) { return nil, errors.New("ObjectStatement is not implemented yet") } +// parseObjectType parses an object type and returns a ObjectType AST +func (p *Parser) parseObjectType() (*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() (*ListType, error) { - return nil, errors.New("ListStatement is not implemented yet") + return nil, errors.New("ListType is not implemented yet") } // scan returns the next token from the underlying scanner.