mirror of
https://github.com/hanzoai/expr.git
synced 2026-09-24 16:58:58 +00:00
Move operator override patcher to correct pkg
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user