1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
package compiler
import (
"github.com/antonmedv/expr/ast"
"github.com/antonmedv/expr/conf"
)
type operatorPatcher struct {
ops map[string][]string
types conf.TypesTable
}
func (p *operatorPatcher) Enter(node *ast.Node) {}
func (p *operatorPatcher) Exit(node *ast.Node) {
binaryNode, ok := (*node).(*ast.BinaryNode)
if !ok {
return
}
fns, ok := p.ops[binaryNode.Operator]
if !ok {
return
}
leftType := binaryNode.Left.Type()
rightType := binaryNode.Right.Type()
_, fn, ok := conf.FindSuitableOperatorOverload(fns, p.types, leftType, rightType)
if ok {
newNode := &ast.FunctionNode{
Name: fn,
Arguments: []ast.Node{binaryNode.Left, binaryNode.Right},
}
ast.Patch(node, newNode)
}
}
func PatchOperators(node *ast.Node, config *conf.Config) {
if len(config.Operators) == 0 {
return
}
patcher := &operatorPatcher{ops: config.Operators, types: config.Types}
ast.Walk(node, patcher)
}
|