diff --git a/runtime/Go/antlr/utils.go b/runtime/Go/antlr/utils.go index 8fc8763345..0e9687468f 100644 --- a/runtime/Go/antlr/utils.go +++ b/runtime/Go/antlr/utils.go @@ -121,13 +121,18 @@ func (b *BitSet) clear(index int) { } func (b *BitSet) or(set *BitSet) { - size := intMax(b.minLen(), set.minLen()) - if size > len(b.data) { - data := make([]uint64, size) + // Get min size necessary to represent the bits in both sets. + bLen := b.minLen() + setLen := set.minLen() + maxLen := intMax(bLen, setLen) + if maxLen > len(b.data) { + // Increase the size of len(b.data) to repesent the bits in both sets. + data := make([]uint64, maxLen) copy(data, b.data) b.data = data } - for i := 0; i < size; i++ { + // len(b.data) is at least setLen. + for i := 0; i < setLen; i++ { b.data[i] |= set.data[i] } } diff --git a/runtime/Go/antlr/utils_test.go b/runtime/Go/antlr/utils_test.go index 88e7aa9fe8..783bd573e0 100644 --- a/runtime/Go/antlr/utils_test.go +++ b/runtime/Go/antlr/utils_test.go @@ -2,150 +2,55 @@ package antlr import "testing" +func testBitSet(t *testing.T, bs *BitSet, str string, length int, contains []int, minValue int, minLen int) { + t.Helper() + if got, want := bs.String(), str; got != want { + t.Errorf("%+v.String() = %q, want %q", bs, got, want) + } + if got, want := bs.length(), length; got != want { + t.Errorf("%+v.length() = %q, want %q", bs, got, want) + } + for i := 0; i < len(bs.data)*bitsPerWord; i++ { + var want bool + for _, val := range contains { + if i == val { + want = true + break + } + } + if got := bs.contains(i); got != want { + t.Errorf("%+v.contains(%v) = %v, want %v", bs, i, got, want) + } + } + if got, want := bs.minValue(), minValue; got != want { + t.Errorf("%+v.minValue() = %v, want %v", bs, got, want) + } + if got, want := bs.minLen(), minLen; got != want { + t.Errorf("%+v.minLen() = %v, want %v", bs, got, want) + } +} + func TestBitSet(t *testing.T) { bs1 := NewBitSet() - if got, want := bs1.String(), "{}"; got != want { - t.Errorf("String() = %q, want %q", got, want) - } - if got, want := bs1.length(), 0; got != want { - t.Errorf("length() = %q, want %q", got, want) - } - if got, want := bs1.contains(1), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.minValue(), 2147483647; got != want { - t.Errorf("minValue() = %v, want %v", got, want) - } + testBitSet(t, bs1, "{}", 0, []int{}, 2147483647, 0) bs1.add(0) - if got, want := bs1.String(), "{0}"; got != want { - t.Errorf("String() = %q, want %q", got, want) - } - if got, want := bs1.length(), 1; got != want { - t.Errorf("length() = %q, want %q", got, want) - } - if got, want := bs1.contains(0), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.minValue(), 0; got != want { - t.Errorf("minValue() = %v, want %v", got, want) - } + testBitSet(t, bs1, "{0}", 1, []int{0}, 0, 1) bs1.add(63) - if got, want := bs1.String(), "{0, 63}"; got != want { - t.Errorf("String() = %q, want %q", got, want) - } - if got, want := bs1.length(), 2; got != want { - t.Errorf("length() = %q, want %q", got, want) - } - if got, want := bs1.contains(1), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(0), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(63), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.minValue(), 0; got != want { - t.Errorf("minValue() = %v, want %v", got, want) - } + testBitSet(t, bs1, "{0, 63}", 2, []int{0, 63}, 0, 1) bs1.remove(0) - if got, want := bs1.String(), "{63}"; got != want { - t.Errorf("String() = %q, want %q", got, want) - } - if got, want := bs1.length(), 1; got != want { - t.Errorf("length() = %q, want %q", got, want) - } - if got, want := bs1.contains(0), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(63), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.minValue(), 63; got != want { - t.Errorf("minValue() = %v, want %v", got, want) - } + testBitSet(t, bs1, "{63}", 1, []int{63}, 63, 1) bs1.add(20) - if got, want := bs1.String(), "{20, 63}"; got != want { - t.Errorf("String() = %q, want %q", got, want) - } - if got, want := bs1.length(), 2; got != want { - t.Errorf("length() = %q, want %q", got, want) - } - if got, want := bs1.contains(0), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(20), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(63), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.minValue(), 20; got != want { - t.Errorf("minValue() = %v, want %v", got, want) - } + testBitSet(t, bs1, "{20, 63}", 2, []int{20, 63}, 20, 1) bs1.clear(63) - if got, want := bs1.String(), "{20}"; got != want { - t.Errorf("String() = %q, want %q", got, want) - } - if got, want := bs1.length(), 1; got != want { - t.Errorf("length() = %q, want %q", got, want) - } - if got, want := bs1.contains(0), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(20), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(63), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.minValue(), 20; got != want { - t.Errorf("minValue() = %v, want %v", got, want) - } + testBitSet(t, bs1, "{20}", 1, []int{20}, 20, 1) bs2 := NewBitSet() bs2.add(64) bs1.or(bs2) - if got, want := bs1.String(), "{20, 64}"; got != want { - t.Errorf("String() = %q, want %q", got, want) - } - if got, want := bs1.length(), 2; got != want { - t.Errorf("length() = %q, want %q", got, want) - } - if got, want := bs1.contains(0), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(20), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(63), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(64), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.minValue(), 20; got != want { - t.Errorf("minValue() = %v, want %v", got, want) - } + testBitSet(t, bs1, "{20, 64}", 2, []int{20, 64}, 20, 2) bs1.remove(20) - if got, want := bs1.String(), "{64}"; got != want { - t.Errorf("String() = %q, want %q", got, want) - } - if got, want := bs1.length(), 1; got != want { - t.Errorf("length() = %q, want %q", got, want) - } - if got, want := bs1.contains(0), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(20), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(63), false; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.contains(64), true; got != want { - t.Errorf("contains(%v) = %v, want %v", 1, got, want) - } - if got, want := bs1.minValue(), 64; got != want { - t.Errorf("minValue() = %v, want %v", got, want) - } + testBitSet(t, bs1, "{64}", 1, []int{64}, 64, 2) + bs3 := NewBitSet() + bs3.add(63) + bs1.or(bs3) + testBitSet(t, bs1, "{63, 64}", 2, []int{63, 64}, 63, 2) }