Skip to content

Commit

Permalink
Add checker.ParseCheck func
Browse files Browse the repository at this point in the history
  • Loading branch information
antonmedv committed May 18, 2024
1 parent cae6003 commit 65c7bc9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 28 deletions.
39 changes: 39 additions & 0 deletions checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,45 @@ import (
"github.com/expr-lang/expr/parser"
)

// ParseCheck parses input expression and checks its types. Also, it applies
// all provided patchers. In case of error, it returns error with a tree.
func ParseCheck(input string, config *conf.Config) (*parser.Tree, error) {
tree, err := parser.ParseWithConfig(input, config)
if err != nil {
return nil, err
}

if len(config.Visitors) > 0 {
for i := 0; i < 1000; i++ {
more := false
for _, v := range config.Visitors {
// We need to perform types check, because some visitors may rely on
// types information available in the tree.
_, _ = Check(tree, config)

ast.Walk(&tree.Node, v)

if v, ok := v.(interface {
ShouldRepeat() bool
}); ok {
more = more || v.ShouldRepeat()
}
}
if !more {
break
}
}
}
_, err = Check(tree, config)
if err != nil {
return tree, err
}

return tree, nil
}

// Check checks types of the expression tree. It returns type of the expression
// and error if any. If config is nil, then default configuration will be used.
func Check(tree *parser.Tree, config *conf.Config) (t reflect.Type, err error) {
if config == nil {
config = conf.New(nil)
Expand Down
29 changes: 1 addition & 28 deletions expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/expr-lang/expr/conf"
"github.com/expr-lang/expr/file"
"github.com/expr-lang/expr/optimizer"
"github.com/expr-lang/expr/parser"
"github.com/expr-lang/expr/patcher"
"github.com/expr-lang/expr/vm"
)
Expand Down Expand Up @@ -206,33 +205,7 @@ func Compile(input string, ops ...Option) (*vm.Program, error) {
}
config.Check()

tree, err := parser.ParseWithConfig(input, config)
if err != nil {
return nil, err
}

if len(config.Visitors) > 0 {
for i := 0; i < 1000; i++ {
more := false
for _, v := range config.Visitors {
// We need to perform types check, because some visitors may rely on
// types information available in the tree.
_, _ = checker.Check(tree, config)

ast.Walk(&tree.Node, v)

if v, ok := v.(interface {
ShouldRepeat() bool
}); ok {
more = more || v.ShouldRepeat()
}
}
if !more {
break
}
}
}
_, err = checker.Check(tree, config)
tree, err := checker.ParseCheck(input, config)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 65c7bc9

Please sign in to comment.