Skip to content

Setting a type in ast.Patch does not take effect #468

Closed
@antonmedv

Description

@antonmedv
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)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions