Flesh out interface for evaluating expressions
Expressions can now be evaluated within an "EvalContext", which provides the variable and function scopes. The JSON implementation of this currently ignores the context entirely and just returns literal values, since we've not yet implemented the template language parser that would be needed for the JSON parser to properly support expressions.
This commit is contained in:
parent
92e407e672
commit
dfafa6fc00
19
zcl/eval_context.go
Normal file
19
zcl/eval_context.go
Normal file
@ -0,0 +1,19 @@
|
||||
package zcl
|
||||
|
||||
import (
|
||||
"github.com/apparentlymart/go-cty/cty"
|
||||
"github.com/apparentlymart/go-cty/cty/function"
|
||||
)
|
||||
|
||||
// An EvalContext provides the variables and functions that should be used
|
||||
// to evaluate an expression.
|
||||
type EvalContext struct {
|
||||
Variables map[string]cty.Value
|
||||
Functions map[string]function.Function
|
||||
parent *EvalContext
|
||||
}
|
||||
|
||||
// NewChild returns a new EvalContext that is a child of the receiver.
|
||||
func (ctx *EvalContext) NewChild() *EvalContext {
|
||||
return &EvalContext{parent: ctx}
|
||||
}
|
@ -226,7 +226,36 @@ func (b *body) unpackBlock(v node, typeName string, typeRange *zcl.Range, labels
|
||||
return
|
||||
}
|
||||
|
||||
func (e *expression) LiteralValue() (cty.Value, zcl.Diagnostics) {
|
||||
// TODO: Implement
|
||||
return cty.NilVal, nil
|
||||
func (e *expression) Value(ctx *zcl.EvalContext) (cty.Value, zcl.Diagnostics) {
|
||||
// TEMP: Since we've not yet implemented the zcl native template language
|
||||
// parser, for the moment we'll support only literal values here.
|
||||
// FIXME: Once the template language parser is implemented, parse string
|
||||
// values as templates and evaluate them.
|
||||
|
||||
switch v := e.src.(type) {
|
||||
case *stringVal:
|
||||
return cty.StringVal(v.Value), nil
|
||||
case *numberVal:
|
||||
return cty.NumberVal(v.Value), nil
|
||||
case *booleanVal:
|
||||
return cty.BoolVal(v.Value), nil
|
||||
case *arrayVal:
|
||||
vals := []cty.Value{}
|
||||
for _, jsonVal := range v.Values {
|
||||
val, _ := (&expression{src: jsonVal}).Value(ctx)
|
||||
vals = append(vals, val)
|
||||
}
|
||||
return cty.TupleVal(vals), nil
|
||||
case *objectVal:
|
||||
attrs := map[string]cty.Value{}
|
||||
for name, jsonAttr := range v.Attrs {
|
||||
val, _ := (&expression{src: jsonAttr.Value}).Value(ctx)
|
||||
attrs[name] = val
|
||||
}
|
||||
return cty.ObjectVal(attrs), nil
|
||||
default:
|
||||
// Default to DynamicVal so that ASTs containing invalid nodes can
|
||||
// still be partially-evaluated.
|
||||
return cty.DynamicVal, nil
|
||||
}
|
||||
}
|
||||
|
@ -82,8 +82,28 @@ type Attribute struct {
|
||||
// Expression is a literal value or an expression provided in the
|
||||
// configuration, which can be evaluated within a scope to produce a value.
|
||||
type Expression interface {
|
||||
LiteralValue() (cty.Value, Diagnostics)
|
||||
// TODO: evaluation of non-literal expressions
|
||||
// Value returns the value resulting from evaluating the expression
|
||||
// in the given evaluation context.
|
||||
//
|
||||
// The context may be nil, in which case the expression may contain
|
||||
// only constants and diagnostics will be produced for any non-constant
|
||||
// sub-expressions. (The exact definition of this depends on the source
|
||||
// language.)
|
||||
//
|
||||
// The context may instead be set but have either its Variables or
|
||||
// Functions maps set to nil, in which case only use of these features
|
||||
// will return diagnostics.
|
||||
//
|
||||
// Different diagnostics are provided depending on whether the given
|
||||
// context maps are nil or empty. In the former case, the message
|
||||
// tells the user that variables/functions are not permitted at all,
|
||||
// while in the latter case usage will produce a "not found" error for
|
||||
// the specific symbol in question.
|
||||
Value(ctx *EvalContext) (cty.Value, Diagnostics)
|
||||
|
||||
// TODO: A "Variables" method that returns a description of all of the
|
||||
// variables used in the expression, so callers can populate the scope
|
||||
// only with variables that are actually used.
|
||||
}
|
||||
|
||||
// OfType filters the receiving block sequence by block type name,
|
||||
|
Loading…
Reference in New Issue
Block a user