Merge pull request #10150 from hashicorp/update-hil

vendor: update HIL
This commit is contained in:
Mitchell Hashimoto 2016-11-15 15:32:38 -08:00 committed by GitHub
commit 20e3ae3aa7
4 changed files with 77 additions and 44 deletions

29
vendor/github.com/hashicorp/hil/parser/binary_op.go generated vendored Normal file
View File

@ -0,0 +1,29 @@
package parser
import (
"github.com/hashicorp/hil/ast"
"github.com/hashicorp/hil/scanner"
)
var binaryOps []map[scanner.TokenType]ast.ArithmeticOp
func init() {
// This operation table maps from the operator's scanner token type
// to the AST arithmetic operation. All expressions produced from
// binary operators are *ast.Arithmetic nodes.
//
// Binary operator groups are listed in order of precedence, with
// the *lowest* precedence first. Operators within the same group
// have left-to-right associativity.
binaryOps = []map[scanner.TokenType]ast.ArithmeticOp{
{
scanner.PLUS: ast.ArithmeticOpAdd,
scanner.MINUS: ast.ArithmeticOpSub,
},
{
scanner.STAR: ast.ArithmeticOpMul,
scanner.SLASH: ast.ArithmeticOpDiv,
scanner.PERCENT: ast.ArithmeticOpMod,
},
}
}

View File

@ -188,6 +188,21 @@ func (p *parser) ParseInterpolation() (ast.Node, error) {
} }
func (p *parser) ParseExpression() (ast.Node, error) { func (p *parser) ParseExpression() (ast.Node, error) {
return p.parseBinaryOps(binaryOps)
}
// parseBinaryOps calls itself recursively to work through all of the
// operator precedence groups, and then eventually calls ParseExpressionTerm
// for each operand.
func (p *parser) parseBinaryOps(ops []map[scanner.TokenType]ast.ArithmeticOp) (ast.Node, error) {
if len(ops) == 0 {
// We've run out of operators, so now we'll just try to parse a term.
return p.ParseExpressionTerm()
}
thisLevel := ops[0]
remaining := ops[1:]
startPos := p.peeker.Peek().Pos startPos := p.peeker.Peek().Pos
var lhs, rhs ast.Node var lhs, rhs ast.Node
@ -198,37 +213,24 @@ func (p *parser) ParseExpression() (ast.Node, error) {
// expression or it might just be a standalone term, but // expression or it might just be a standalone term, but
// we won't know until we've parsed it and can look ahead // we won't know until we've parsed it and can look ahead
// to see if there's an operator token. // to see if there's an operator token.
lhs, err = p.ParseExpressionTerm() lhs, err = p.parseBinaryOps(remaining)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// We'll keep eating up arithmetic operators until we run // We'll keep eating up arithmetic operators until we run
// out, so that binary expressions will combine in a manner // out, so that operators with the same precedence will combine in a
// that is compatible with the old yacc-based parser: // left-associative manner:
// a+b*c => (a+b)*c, *not* a+(b*c) // a+b+c => (a+b)+c, not a+(b+c)
// //
// (perhaps later we'll implement some more intuitive precendence // Should we later want to have right-associative operators, a way
// rules here, but for now being compatible with the old parser // to achieve that would be to call back up to ParseExpression here
// is the goal.) // instead of iteratively parsing only the remaining operators.
for { for {
next := p.peeker.Peek() next := p.peeker.Peek()
newOperator := ast.ArithmeticOpInvalid var newOperator ast.ArithmeticOp
var ok bool
switch next.Type { if newOperator, ok = thisLevel[next.Type]; !ok {
case scanner.PLUS:
newOperator = ast.ArithmeticOpAdd
case scanner.MINUS:
newOperator = ast.ArithmeticOpSub
case scanner.STAR:
newOperator = ast.ArithmeticOpMul
case scanner.SLASH:
newOperator = ast.ArithmeticOpDiv
case scanner.PERCENT:
newOperator = ast.ArithmeticOpMod
}
if newOperator == ast.ArithmeticOpInvalid {
break break
} }
@ -244,7 +246,7 @@ func (p *parser) ParseExpression() (ast.Node, error) {
operator = newOperator operator = newOperator
p.peeker.Read() // eat operator token p.peeker.Read() // eat operator token
rhs, err = p.ParseExpressionTerm() rhs, err = p.parseBinaryOps(remaining)
if err != nil { if err != nil {
return nil, err return nil, err
} }

18
vendor/vendor.json vendored
View File

@ -1426,26 +1426,26 @@
{ {
"checksumSHA1": "/TJCBetWCMVsOpehJzVk3S/xtWM=", "checksumSHA1": "/TJCBetWCMVsOpehJzVk3S/xtWM=",
"path": "github.com/hashicorp/hil", "path": "github.com/hashicorp/hil",
"revision": "fceef4715de114b559e042e19fd2cec06003628a", "revision": "6861984a28be5acf4e47b5769bc841ec653bf3ba",
"revisionTime": "2016-11-15T03:45:18Z" "revisionTime": "2016-11-15T22:45:22Z"
}, },
{ {
"checksumSHA1": "YPJwewz3dAqEWOGP2qIIWeCufF0=", "checksumSHA1": "YPJwewz3dAqEWOGP2qIIWeCufF0=",
"path": "github.com/hashicorp/hil/ast", "path": "github.com/hashicorp/hil/ast",
"revision": "fceef4715de114b559e042e19fd2cec06003628a", "revision": "6861984a28be5acf4e47b5769bc841ec653bf3ba",
"revisionTime": "2016-11-15T03:45:18Z" "revisionTime": "2016-11-15T22:45:22Z"
}, },
{ {
"checksumSHA1": "BeqAygYXJlCHpU0HVWg4mxuROks=", "checksumSHA1": "FlyG9T7bd3jNK6R9XwXSobecVEQ=",
"path": "github.com/hashicorp/hil/parser", "path": "github.com/hashicorp/hil/parser",
"revision": "fceef4715de114b559e042e19fd2cec06003628a", "revision": "6861984a28be5acf4e47b5769bc841ec653bf3ba",
"revisionTime": "2016-11-15T03:45:18Z" "revisionTime": "2016-11-15T22:45:22Z"
}, },
{ {
"checksumSHA1": "2aIAMbqPrE0qyYoJSL6qjVm+Tt0=", "checksumSHA1": "2aIAMbqPrE0qyYoJSL6qjVm+Tt0=",
"path": "github.com/hashicorp/hil/scanner", "path": "github.com/hashicorp/hil/scanner",
"revision": "fceef4715de114b559e042e19fd2cec06003628a", "revision": "6861984a28be5acf4e47b5769bc841ec653bf3ba",
"revisionTime": "2016-11-15T03:45:18Z" "revisionTime": "2016-11-15T22:45:22Z"
}, },
{ {
"path": "github.com/hashicorp/logutils", "path": "github.com/hashicorp/logutils",

View File

@ -381,19 +381,21 @@ The supported operations are:
- *Add* (`+`), *Subtract* (`-`), *Multiply* (`*`), and *Divide* (`/`) for **float** types - *Add* (`+`), *Subtract* (`-`), *Multiply* (`*`), and *Divide* (`/`) for **float** types
- *Add* (`+`), *Subtract* (`-`), *Multiply* (`*`), *Divide* (`/`), and *Modulo* (`%`) for **integer** types - *Add* (`+`), *Subtract* (`-`), *Multiply* (`*`), *Divide* (`/`), and *Modulo* (`%`) for **integer** types
Operator precedences is the standard mathematical order of operations:
*Multiply* (`*`), *Divide* (`/`), and *Modulo* (`%`) have precedence over
*Add* (`+`) and *Subtract* (`-`). Parenthesis can be used to force ordering.
```
"${2 * 4 + 3 * 3}" # computes to 17
"${3 * 3 + 2 * 4}" # computes to 17
"${2 * (4 + 3) * 3}" # computes to 42
```
You can use the [terraform console](/docs/commands/console.html) command to
try the math operations.
-> **Note:** Since Terraform allows hyphens in resource and variable names, -> **Note:** Since Terraform allows hyphens in resource and variable names,
it's best to use spaces between math operators to prevent confusion or unexpected it's best to use spaces between math operators to prevent confusion or unexpected
behavior. For example, `${var.instance-count - 1}` will subtract **1** from the behavior. For example, `${var.instance-count - 1}` will subtract **1** from the
`instance-count` variable value, while `${var.instance-count-1}` will interpolate `instance-count` variable value, while `${var.instance-count-1}` will interpolate
the `instance-count-1` variable value. the `instance-count-1` variable value.
-> **Note:** Operator precedence is not the usual one where *Multiply* (`*`),
*Divide* (`/`), and *Modulo* (`%`) have precedence over *Add* (`+`) and *Subtract* (`-`).
The operations are made in the order they appear. Parenthesis can be used to force ordering :
```
"${2 * 4 + 3 * 3}" # computes to 33
"${3 * 3 + 2 * 4}" # computes to 44
"${(2 * 4) + (3 * 3)}" # computes to 17
"${(3 * 3) + (2 * 4)}" # computes to 17
```