From b090b7ea4dd1d996aa80cab6a95d63187866771d Mon Sep 17 00:00:00 2001 From: Felix Krause Date: Wed, 25 Jun 2014 17:01:22 +0200 Subject: Fixed handling swap in vmgen --- compiler/vmgen.nim | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 186d27ae4..305ea7f9e 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -787,10 +787,12 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = c.freeTemp(tmp) of mSwap: unused(n, dest) - var d = c.genx(n.sons[1]) - var tmp = c.genx(n.sons[2]) - c.gABC(n, opcSwap, d, tmp) - c.freeTemp(tmp) + var + d1 = c.genx(n.sons[1]) + d2 = c.genx(n.sons[2]) + c.gABC(n, opcSwap, d1, d2) + c.genAsgnPatch(n.sons[1], d1) + c.genAsgnPatch(n.sons[2], d2) of mIsNil: genUnaryABC(c, n, dest, opcIsNil) of mCopyStr: if dest < 0: dest = c.getTemp(n.typ) -- cgit 1.4.1-2-gfad0 From bdd3b6c612a29723954f62e242888eedee0b35e4 Mon Sep 17 00:00:00 2001 From: Felix Krause Date: Wed, 25 Jun 2014 21:57:06 +0200 Subject: Added logical set operations to TSet --- lib/pure/collections/sets.nim | 49 ++++++++++++++++++++++++++ tests/sets/tsets3.nim | 81 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 tests/sets/tsets3.nim diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index bc249ed63..380a33c5b 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -112,6 +112,10 @@ proc incl*[A](s: var TSet[A], key: A) = ## includes an element `key` in `s`. inclImpl() +proc incl*[A](s: var TSet[A], other: TSet[A]) = + ## includes everything in `other` in `s` + for item in other: incl(s, item) + proc excl*[A](s: var TSet[A], key: A) = ## excludes `key` from the set `s`. var index = rawGet(s, key) @@ -119,6 +123,10 @@ proc excl*[A](s: var TSet[A], key: A) = s.data[index].slot = seDeleted dec(s.counter) +proc excl*[A](s: var TSet[A], other: TSet[A]) = + ## excludes everything in `other` from `s`. + for item in other: excl(s, item) + proc containsOrIncl*[A](s: var TSet[A], key: A): bool = ## returns true if `s` contains `key`, otherwise `key` is included in `s` ## and false is returned. @@ -147,6 +155,43 @@ proc `$`*[A](s: TSet[A]): string = ## The `$` operator for hash sets. dollarImpl() +proc union*[A](s1, s2: TSet[A]): TSet[A] = + ## returns a new set of all items that are contained in at + ## least one of `l` and `r` + result = s1 + incl(result, s2) + +proc intersection*[A](s1, s2: TSet[A]): TSet[A] = + ## returns a new set of all items that are contained in both `l` and `r` + result = initSet[A](min(s1.data.len, s2.data.len)) + for item in s1: + if item in s2: incl(result, item) + +proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] = + ## returns a new set of all items that are contained in either + ## `l` or `r`, but not both + result = s1 + for item in s2: + if containsOrIncl(result, item): excl(result, item) + +proc `or`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = + ## alias for `union` + result = union(s1, s2) + +proc `and`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = + ## alias for `intersection` + result = intersection(s1, s2) + +proc `xor`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = + ## alias for `symmetricDifference` + result = symmetricDifference(s1, s2) + +proc disjoint*[A](s1, s2: TSet[A]): bool = + ## returns true iff `l` and `r` have no items in common + for item in s1: + if item in s2: return false + return true + # ------------------------------ ordered set ------------------------------ type @@ -211,6 +256,10 @@ proc incl*[A](s: var TOrderedSet[A], key: A) = ## includes an element `key` in `s`. inclImpl() +proc incl*[A](s: var TSet[A], other: TOrderedSet[A]) = + ## includes everything in `other` in `s` + for item in other: incl(s, item) + proc containsOrIncl*[A](s: var TOrderedSet[A], key: A): bool = ## returns true if `s` contains `key`, otherwise `key` is included in `s` ## and false is returned. diff --git a/tests/sets/tsets3.nim b/tests/sets/tsets3.nim new file mode 100644 index 000000000..5d14a1d8f --- /dev/null +++ b/tests/sets/tsets3.nim @@ -0,0 +1,81 @@ +include sets + +let + s1: TSet[int] = toSet([1, 2, 4, 8, 16]) + s2: TSet[int] = toSet([1, 2, 3, 5, 8]) + s3: TSet[int] = toSet([3, 5, 7]) + +block union: + let + s1_s2 = union(s1, s2) + s1_s3 = s1 or s3 + s2_s3 = s2 or s3 + + assert s1_s2.len == 7 + assert s1_s3.len == 8 + assert s2_s3.len == 6 + + for i in s1: + assert i in s1_s2 + assert i in s1_s3 + for i in s2: + assert i in s1_s2 + assert i in s2_s3 + for i in s3: + assert i in s1_s3 + assert i in s2_s3 + + assert((s1 or s1) == s1) + assert((s2 or s1) == s1_s2) + +block intersection: + let + s1_s2 = intersection(s1, s2) + s1_s3 = intersection(s1, s3) + s2_s3 = s2 and s3 + + assert s1_s2.len == 3 + assert s1_s3.len == 0 + assert s2_s3.len == 2 + + for i in s1_s2: + assert i in s1 + assert i in s2 + for i in s1_s3: + assert i in s1 + assert i in s3 + for i in s2_s3: + assert i in s2 + assert i in s3 + + assert((s2 and s2) == s2) + assert((s3 and s2) == s2_s3) + +block symmetricDifference: + let + s1_s2 = symmetricDifference(s1, s2) + s1_s3 = s1 xor s3 + s2_s3 = s2 xor s3 + + assert s1_s2.len == 4 + assert s1_s3.len == 8 + assert s2_s3.len == 4 + + for i in s1: + assert i in s1_s2 xor i in s2 + assert i in s1_s3 xor i in s3 + for i in s2: + assert i in s1_s2 xor i in s1 + assert i in s2_s3 xor i in s3 + for i in s3: + assert i in s1_s3 xor i in s1 + assert i in s2_s3 xor i in s2 + + assert((s3 xor s3) == initSet[int]()) + assert((s3 xor s1) == s1_s3) + +block disjoint: + assert(not disjoint(s1, s2)) + assert disjoint(s1, s3) + assert(not disjoint(s2, s3)) + assert(not disjoint(s2, s2)) \ No newline at end of file -- cgit 1.4.1-2-gfad0