Move operator override patcher to correct pkg

This commit is contained in:
Anton Medvedev
2024-02-17 19:17:27 +01:00
parent 3863d18bcc
commit 8ab750f2a2
5 changed files with 44 additions and 40 deletions
+4
View File
@@ -11,6 +11,10 @@ import (
type FunctionTable map[string]*builtin.Function
// OperatorsTable maps binary operators to corresponding list of functions.
// Functions should be provided in the environment to allow operator overloading.
type OperatorsTable map[string][]string
type Config struct {
Env any
Types TypesTable
-37
View File
@@ -2,14 +2,8 @@ package conf
import (
"reflect"
"github.com/expr-lang/expr/ast"
)
// OperatorsTable maps binary operators to corresponding list of functions.
// Functions should be provided in the environment to allow operator overloading.
type OperatorsTable map[string][]string
func FindSuitableOperatorOverload(fns []string, types TypesTable, funcs FunctionTable, l, r reflect.Type) (reflect.Type, string, bool) {
t, fn, ok := FindSuitableOperatorOverloadInFunctions(fns, funcs, l, r)
if !ok {
@@ -64,34 +58,3 @@ func checkTypeSuits(t reflect.Type, l reflect.Type, r reflect.Type, firstInIndex
}
return nil, false
}
type OperatorPatcher struct {
Operators OperatorsTable
Types TypesTable
Functions FunctionTable
}
func (p *OperatorPatcher) Visit(node *ast.Node) {
binaryNode, ok := (*node).(*ast.BinaryNode)
if !ok {
return
}
fns, ok := p.Operators[binaryNode.Operator]
if !ok {
return
}
leftType := binaryNode.Left.Type()
rightType := binaryNode.Right.Type()
ret, fn, ok := FindSuitableOperatorOverload(fns, p.Types, p.Functions, leftType, rightType)
if ok {
newNode := &ast.CallNode{
Callee: &ast.IdentifierNode{Value: fn},
Arguments: []ast.Node{binaryNode.Left, binaryNode.Right},
}
newNode.SetType(ret)
ast.Patch(node, newNode)
}
}
+2 -2
View File
@@ -6,6 +6,8 @@ import (
"github.com/expr-lang/expr/internal/deref"
)
type TypesTable map[string]Tag
type Tag struct {
Type reflect.Type
Ambiguous bool
@@ -14,8 +16,6 @@ type Tag struct {
MethodIndex int
}
type TypesTable map[string]Tag
// CreateTypesTable creates types table for type checks during parsing.
// If struct is passed, all fields will be treated as variables,
// as well as all fields of embedded structs and struct itself.
+1 -1
View File
@@ -189,7 +189,7 @@ func Compile(input string, ops ...Option) (*vm.Program, error) {
config.Check()
if len(config.Operators) > 0 {
config.Visitors = append(config.Visitors, &conf.OperatorPatcher{
config.Visitors = append(config.Visitors, &patcher.Operator{
Operators: config.Operators,
Types: config.Types,
Functions: config.Functions,
+37
View File
@@ -0,0 +1,37 @@
package patcher
import (
"github.com/expr-lang/expr/ast"
"github.com/expr-lang/expr/conf"
)
type Operator struct {
Operators conf.OperatorsTable
Types conf.TypesTable
Functions conf.FunctionTable
}
func (p *Operator) Visit(node *ast.Node) {
binaryNode, ok := (*node).(*ast.BinaryNode)
if !ok {
return
}
fns, ok := p.Operators[binaryNode.Operator]
if !ok {
return
}
leftType := binaryNode.Left.Type()
rightType := binaryNode.Right.Type()
ret, fn, ok := conf.FindSuitableOperatorOverload(fns, p.Types, p.Functions, leftType, rightType)
if ok {
newNode := &ast.CallNode{
Callee: &ast.IdentifierNode{Value: fn},
Arguments: []ast.Node{binaryNode.Left, binaryNode.Right},
}
newNode.SetType(ret)
ast.Patch(node, newNode)
}
}