diff --git a/vm.go b/vm.go index dd65111..4c2c7de 100644 --- a/vm.go +++ b/vm.go @@ -526,7 +526,7 @@ func init() { c := e.k(i.c()) if nb, ok := b.(float64); ok { if nc, ok := c.(float64); ok { - e.frame[i.a()] = math.Mod(nb, nc) + e.frame[i.a()] = arith(OpMod, nb, nc) if e.hooked() { e.hook() } @@ -1083,7 +1083,7 @@ func (l *State) executeSwitch() { c := k(i.c(), constants, frame) if nb, ok := b.(float64); ok { if nc, ok := c.(float64); ok { - frame[i.a()] = math.Mod(nb, nc) + frame[i.a()] = arith(OpMod, nb, nc) break } } diff --git a/vm_test.go b/vm_test.go index e78570c..49a3718 100644 --- a/vm_test.go +++ b/vm_test.go @@ -51,6 +51,24 @@ func TestProtectedCall(t *testing.T) { l.Call(0, 0) } +func TestModuloNegativeOperands(t *testing.T) { + l := NewState() + OpenLibraries(l) + + if err := DoString(l, `local a,b,c,d=-3,2,3,-2 + return -3%2, a%b, "-3"%b, c%d, math.fmod(a,b)`); err != nil { + t.Fatal(err) + } + + want := []float64{1, 1, 1, -1, -1} + for i, expected := range want { + got, ok := l.ToNumber(i + 1) + if !ok || got != expected { + t.Errorf("result %d = %v (number: %t), want %v", i+1, got, ok, expected) + } + } +} + func TestLua(t *testing.T) { tests := []struct { name string