Skip to content

Commit 8ecb18a

Browse files
committed
Move operator override patcher to correct pkg
1 parent 9569d4b commit 8ecb18a

File tree

5 files changed

+44
-40
lines changed

5 files changed

+44
-40
lines changed

conf/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import (
1111

1212
type FunctionTable map[string]*builtin.Function
1313

14+
// OperatorsTable maps binary operators to corresponding list of functions.
15+
// Functions should be provided in the environment to allow operator overloading.
16+
type OperatorsTable map[string][]string
17+
1418
type Config struct {
1519
Env any
1620
Types TypesTable

conf/operators.go

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,8 @@ package conf
22

33
import (
44
"reflect"
5-
6-
"github.com/expr-lang/expr/ast"
75
)
86

9-
// OperatorsTable maps binary operators to corresponding list of functions.
10-
// Functions should be provided in the environment to allow operator overloading.
11-
type OperatorsTable map[string][]string
12-
137
func FindSuitableOperatorOverload(fns []string, types TypesTable, funcs FunctionTable, l, r reflect.Type) (reflect.Type, string, bool) {
148
t, fn, ok := FindSuitableOperatorOverloadInFunctions(fns, funcs, l, r)
159
if !ok {
@@ -64,34 +58,3 @@ func checkTypeSuits(t reflect.Type, l reflect.Type, r reflect.Type, firstInIndex
6458
}
6559
return nil, false
6660
}
67-
68-
type OperatorPatcher struct {
69-
Operators OperatorsTable
70-
Types TypesTable
71-
Functions FunctionTable
72-
}
73-
74-
func (p *OperatorPatcher) Visit(node *ast.Node) {
75-
binaryNode, ok := (*node).(*ast.BinaryNode)
76-
if !ok {
77-
return
78-
}
79-
80-
fns, ok := p.Operators[binaryNode.Operator]
81-
if !ok {
82-
return
83-
}
84-
85-
leftType := binaryNode.Left.Type()
86-
rightType := binaryNode.Right.Type()
87-
88-
ret, fn, ok := FindSuitableOperatorOverload(fns, p.Types, p.Functions, leftType, rightType)
89-
if ok {
90-
newNode := &ast.CallNode{
91-
Callee: &ast.IdentifierNode{Value: fn},
92-
Arguments: []ast.Node{binaryNode.Left, binaryNode.Right},
93-
}
94-
newNode.SetType(ret)
95-
ast.Patch(node, newNode)
96-
}
97-
}

conf/types_table.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"github.com/expr-lang/expr/internal/deref"
77
)
88

9+
type TypesTable map[string]Tag
10+
911
type Tag struct {
1012
Type reflect.Type
1113
Ambiguous bool
@@ -14,8 +16,6 @@ type Tag struct {
1416
MethodIndex int
1517
}
1618

17-
type TypesTable map[string]Tag
18-
1919
// CreateTypesTable creates types table for type checks during parsing.
2020
// If struct is passed, all fields will be treated as variables,
2121
// as well as all fields of embedded structs and struct itself.

expr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func Compile(input string, ops ...Option) (*vm.Program, error) {
189189
config.Check()
190190

191191
if len(config.Operators) > 0 {
192-
config.Visitors = append(config.Visitors, &conf.OperatorPatcher{
192+
config.Visitors = append(config.Visitors, &patcher.Operator{
193193
Operators: config.Operators,
194194
Types: config.Types,
195195
Functions: config.Functions,

patcher/operator_override.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package patcher
2+
3+
import (
4+
"github.com/expr-lang/expr/ast"
5+
"github.com/expr-lang/expr/conf"
6+
)
7+
8+
type Operator struct {
9+
Operators conf.OperatorsTable
10+
Types conf.TypesTable
11+
Functions conf.FunctionTable
12+
}
13+
14+
func (p *Operator) Visit(node *ast.Node) {
15+
binaryNode, ok := (*node).(*ast.BinaryNode)
16+
if !ok {
17+
return
18+
}
19+
20+
fns, ok := p.Operators[binaryNode.Operator]
21+
if !ok {
22+
return
23+
}
24+
25+
leftType := binaryNode.Left.Type()
26+
rightType := binaryNode.Right.Type()
27+
28+
ret, fn, ok := conf.FindSuitableOperatorOverload(fns, p.Types, p.Functions, leftType, rightType)
29+
if ok {
30+
newNode := &ast.CallNode{
31+
Callee: &ast.IdentifierNode{Value: fn},
32+
Arguments: []ast.Node{binaryNode.Left, binaryNode.Right},
33+
}
34+
newNode.SetType(ret)
35+
ast.Patch(node, newNode)
36+
}
37+
}

0 commit comments

Comments
 (0)