Closed
Description
package main
import (
"fmt"
"reflect"
"github.com/antonmedv/expr"
"github.com/antonmedv/expr/ast"
)
type Value struct {
Int int
}
type Env struct {
Value Value
}
var valueType = reflect.TypeOf((*Value)(nil)).Elem()
type getValuePatcher struct{}
func (getValuePatcher) Visit(node *ast.Node) {
id, ok := (*node).(*ast.IdentifierNode)
if !ok {
return
}
if id.Type() == valueType {
(*node).SetType(reflect.TypeOf(int(0)))
ast.Patch(node, &ast.CallNode{
Callee: &ast.IdentifierNode{Value: "getValue"},
Arguments: []ast.Node{id},
})
}
}
func main() {
code := `Value + "astring"`
program, err := expr.Compile(code,
expr.Env(Env{}),
expr.Function("getValue", func(params ...any) (any, error) {
return params[0].(Value).Int, nil
}),
expr.Patch(getValuePatcher{}),
)
if err != nil {
panic(err)
}
env := Env{
Value: Value{1},
}
output, err := expr.Run(program, env)
if err != nil {
panic(err)
}
fmt.Println(output)
}
That's what I was trying to use, but it doesn't seem to help catch type mismatches at compile time. I just assume I'm doing something wrong.
https://go.dev/play/p/hori9Xtni-k
Panic happens at Run
and not Compile
I also tried using a type of new(func (Value) int))
.
Originally posted by @rrb3942 in #460 (comment)