-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactored evaluation Also improved a technicality in the AST * Use Go's formatting * Refactor naming to account for package naming * Improve comments and address linter warnings * Update to use struct to reduce parameters in expression evaluation Also updated dependencies varaiable name for consistency * Refactor dependencies internal code Also changed it from map access to bracket access to account for list access
- Loading branch information
1 parent
6bd08b9
commit dd56a64
Showing
17 changed files
with
796 additions
and
684 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# IDE folders | ||
.idea/ | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
|
||
# Go workspace file | ||
go.work |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,91 @@ | ||
package expressions | ||
|
||
import ( | ||
"fmt" | ||
"fmt" | ||
|
||
"go.flow.arcalot.io/expressions/internal/ast" | ||
"go.flow.arcalot.io/pluginsdk/schema" | ||
"go.flow.arcalot.io/expressions/internal/ast" | ||
"go.flow.arcalot.io/pluginsdk/schema" | ||
) | ||
|
||
// New parses the specified expression and returns the expression structure. | ||
func New(expressionString string) (Expression, error) { | ||
parser, err := ast.InitParser(expressionString, "workflow.yaml") | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse expression: %s (%w)", expressionString, err) | ||
} | ||
exprAst, err := parser.ParseExpression() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse expression: %s (%v)", expressionString, err) | ||
} | ||
parser, err := ast.InitParser(expressionString, "workflow.yaml") | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse expression: %s (%w)", expressionString, err) | ||
} | ||
exprAst, err := parser.ParseExpression() | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse expression: %s (%v)", expressionString, err) | ||
} | ||
|
||
return &expression{ | ||
ast: exprAst, | ||
expression: expressionString, | ||
}, nil | ||
return &expression{ | ||
ast: exprAst, | ||
expression: expressionString, | ||
}, nil | ||
} | ||
|
||
// Expression is an interface describing how expressions should behave. | ||
type Expression interface { | ||
// Type evaluates the expression and evaluates the type on the specified schema. | ||
Type(schema schema.Scope, workflowContext map[string][]byte) (schema.Type, error) | ||
// Dependencies traverses the passed scope and evaluates the items this expression depends on. This is useful to | ||
// construct a dependency tree based on expressions. | ||
Dependencies(schema schema.Scope, workflowContext map[string][]byte) ([]Path, error) | ||
// Evaluate evaluates the expression on the given data set regardless of any | ||
// schema. The caller is responsible for validating the expected schema. | ||
Evaluate(data any, workflowContext map[string][]byte) (any, error) | ||
// String returns the string representation of the expression. | ||
String() string | ||
// Type evaluates the expression and evaluates the type on the specified schema. | ||
Type(schema schema.Scope, workflowContext map[string][]byte) (schema.Type, error) | ||
// Dependencies traverses the passed scope and evaluates the items this expression depends on. This is useful to | ||
// construct a dependency tree based on expressions. | ||
Dependencies(schema schema.Scope, workflowContext map[string][]byte) ([]Path, error) | ||
// Evaluate evaluates the expression on the given data set regardless of any | ||
// schema. The caller is responsible for validating the expected schema. | ||
Evaluate(data any, workflowContext map[string][]byte) (any, error) | ||
// String returns the string representation of the expression. | ||
String() string | ||
} | ||
|
||
// expression is the implementation of Expression. It holds the original expression, as well as the parsed AST. | ||
type expression struct { | ||
expression string | ||
ast ast.ASTNode | ||
expression string | ||
ast ast.Node | ||
} | ||
|
||
func (e expression) String() string { | ||
return e.expression | ||
return e.expression | ||
} | ||
|
||
func (e expression) Type(scope schema.Scope, workflowContext map[string][]byte) (schema.Type, error) { | ||
tree := &PathTree{ | ||
PathItem: "$", | ||
Subtrees: nil, | ||
} | ||
d := &dependencyContext{ | ||
rootType: scope, | ||
rootPath: tree, | ||
workflowContext: workflowContext, | ||
} | ||
result, _, err := d.dependencies(e.ast, scope, tree) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return result, nil | ||
tree := &PathTree{ | ||
PathItem: "$", | ||
Subtrees: nil, | ||
} | ||
d := &dependencyContext{ | ||
rootType: scope, | ||
rootPath: tree, | ||
workflowContext: workflowContext, | ||
} | ||
result, _, err := d.dependencies(e.ast, scope, tree) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return result, nil | ||
} | ||
|
||
func (e expression) Dependencies(scope schema.Scope, workflowContext map[string][]byte) ([]Path, error) { | ||
tree := &PathTree{ | ||
PathItem: "$", | ||
Subtrees: nil, | ||
} | ||
d := &dependencyContext{ | ||
rootType: scope, | ||
rootPath: tree, | ||
workflowContext: workflowContext, | ||
} | ||
_, _, err := d.dependencies(e.ast, scope, tree) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return tree.Unpack(), nil | ||
tree := &PathTree{ | ||
PathItem: "$", | ||
Subtrees: nil, | ||
} | ||
d := &dependencyContext{ | ||
rootType: scope, | ||
rootPath: tree, | ||
workflowContext: workflowContext, | ||
} | ||
_, _, err := d.dependencies(e.ast, scope, tree) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return tree.Unpack(), nil | ||
} | ||
|
||
func (e expression) Evaluate(data any, workflowContext map[string][]byte) (any, error) { | ||
return evaluate(e.ast, data, data, workflowContext) | ||
context := &evaluateContext{ | ||
rootData: data, | ||
workflowContext: workflowContext, | ||
} | ||
return context.evaluate(e.ast, data) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.