fix: catch mismatched types in binary operator expressions (#109)

The types of operands are checked prior to generate closures.

- test: improve evalCheck() to check against expected output and/or expected errors.
This commit is contained in:
Marc Vertes
2019-02-26 11:08:57 +01:00
committed by Ludovic Fernandez
parent 0fb2370c33
commit 005a3cf93c
4 changed files with 36 additions and 6 deletions

View File

@@ -428,6 +428,9 @@ func (interp *Interpreter) Cfg(root *Node) ([]*Node, error) {
wireChild(n)
n.findex = scope.inc(interp)
nilSym := interp.universe.sym["nil"]
if t0, t1 := n.child[0].typ, n.child[1].typ; !t0.untyped && !t1.untyped && t0.id() != t1.id() {
err = n.cfgError("mismatched types %s and %s", t0.id(), t1.id())
}
switch n.action {
case NotEqual:
n.typ = scope.getType("bool")

View File

@@ -163,7 +163,7 @@ func initUniverse() *Scope {
"iota": &Symbol{kind: Const, typ: &Type{cat: IntT}},
// predefined Go zero value
"nil": &Symbol{typ: &Type{cat: NilT}},
"nil": &Symbol{typ: &Type{cat: NilT, untyped: true}},
// predefined Go builtins
"append": &Symbol{kind: Bltn, builtin: _append},

View File

@@ -209,6 +209,18 @@ func Foo() {
}
}
func TestEvalComparison(t *testing.T) {
i := interp.New(interp.Opt{})
evalCheck(t, i, `
type Foo string
type Bar string
var a = Foo("test")
var b = Bar("test")
var c = a == b
`, "", "7:9: mismatched types _.Foo and _.Bar")
}
func TestEvalCompositeArray0(t *testing.T) {
i := interp.New(interp.Opt{})
v := evalCheck(t, i, `a := []int{1, 2, 7: 20, 30}`)
@@ -226,12 +238,27 @@ func TestEvalUnary0(t *testing.T) {
}
}
func evalCheck(t *testing.T, i *interp.Interpreter, src string) reflect.Value {
func evalCheck(t *testing.T, i *interp.Interpreter, src string, expect ...string) reflect.Value {
t.Helper()
res, err := i.Eval(src)
if err != nil {
t.Fatal(err)
if len(expect) == 0 {
if err != nil {
t.Fatal(err)
}
return res
}
if expect[0] != "" && expect[0] != fmt.Sprintf("%v", res) {
t.Fatalf("expected %v, got %v", expect[0], res)
}
if len(expect) == 1 {
if err != nil {
t.Fatal(err)
}
return res
}
if expect[1] != err.Error() {
t.Fatalf("expected error %v, got %v", expect[1], err.Error())
}
return res
}

View File

@@ -386,9 +386,9 @@ func (t *Type) id() string {
res := ""
if t.cat == ValueT {
res = t.rtype.PkgPath() + t.rtype.Name()
res = t.rtype.PkgPath() + "." + t.rtype.Name()
} else {
res = t.pkgPath + t.name
res = t.pkgPath + "." + t.name
}
return res
}