summary refs log tree commit diff stats
path: root/tests/accept/run/tvarnums.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/accept/run/tvarnums.nim')
-rw-r--r--tests/accept/run/tvarnums.nim136
1 files changed, 136 insertions, 0 deletions
diff --git a/tests/accept/run/tvarnums.nim b/tests/accept/run/tvarnums.nim
new file mode 100644
index 000000000..1b683ad94
--- /dev/null
+++ b/tests/accept/run/tvarnums.nim
@@ -0,0 +1,136 @@
+# Test variable length binary integers

+

+import

+  strutils

+

+type

+  TBuffer = array [0..10, int8]

+

+proc toVarNum(x: int32, b: var TBuffer) =

+  # encoding: first bit indicates end of number (0 if at end)

+  # second bit of the first byte denotes the sign (1 --> negative)

+  var a = x

+  if x != low(x):

+    # low(int) is a special case,

+    # because abs() does not work here!

+    # we leave x as it is and use the check >% instead of >

+    # for low(int) this is needed and positive numbers are not affected

+    # anyway

+    a = abs(x)

+  # first 6 bits:

+  b[0] = toU8(ord(a >% 63'i32) shl 7 or (ord(x < 0'i32) shl 6) or (int(a) and 63))

+  a = a shr 6'i32 # skip first 6 bits

+  var i = 1

+  while a != 0'i32:

+    b[i] = toU8(ord(a >% 127'i32) shl 7 or (int(a) and 127))

+    inc(i)

+    a = a shr 7'i32

+

+proc toVarNum64(x: int64, b: var TBuffer) =

+  # encoding: first bit indicates end of number (0 if at end)

+  # second bit of the first byte denotes the sign (1 --> negative)

+  var a = x

+  if x != low(x):

+    # low(int) is a special case,

+    # because abs() does not work here!

+    # we leave x as it is and use the check >% instead of >

+    # for low(int) this is needed and positive numbers are not affected

+    # anyway

+    a = abs(x)

+  # first 6 bits:

+  b[0] = toU8(ord(a >% 63'i64) shl 7 or (ord(x < 0'i64) shl 6) or int(a and 63))

+  a = a shr 6 # skip first 6 bits

+  var i = 1

+  while a != 0'i64:

+    b[i] = toU8(ord(a >% 127'i64) shl 7 or int(a and 127))

+    inc(i)

+    a = a shr 7

+

+proc toNum64(b: TBuffer): int64 =

+  # treat first byte different:

+  result = ze64(b[0]) and 63

+  var

+    i = 0

+    Shift = 6'i64

+  while (ze(b[i]) and 128) != 0:

+    inc(i)

+    result = result or ((ze64(b[i]) and 127) shl Shift)

+    inc(Shift, 7)

+  if (ze(b[0]) and 64) != 0: # sign bit set?

+    result = not result +% 1

+    # this is the same as ``- result``

+    # but gives no overflow error for low(int)

+

+proc toNum(b: TBuffer): int32 =

+  # treat first byte different:

+  result = ze(b[0]) and 63

+  var

+    i = 0

+    Shift = 6'i32

+  while (ze(b[i]) and 128) != 0:

+    inc(i)

+    result = result or ((int32(ze(b[i])) and 127'i32) shl Shift)

+    Shift = shift + 7'i32

+  if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set?

+    result = (not result) +% 1'i32

+    # this is the same as ``- result``

+    # but gives no overflow error for low(int)

+

+proc toBinary(x: int64): string =

+  result = newString(64)

+  for i in 0..63:

+    result[63-i] = chr((int(x shr i) and 1) + ord('0'))

+

+proc t64(i: int64) =

+  var

+    b: TBuffer

+  toVarNum64(i, b)

+  var x = toNum64(b)

+  if x != i:

+    writeln(stdout, $i)

+    writeln(stdout, toBinary(i))

+    writeln(stdout, toBinary(x))

+

+proc t32(i: int32) =

+  var

+    b: TBuffer

+  toVarNum(i, b)

+  var x = toNum(b)

+  if x != i:

+    writeln(stdout, toBinary(i))

+    writeln(stdout, toBinary(x))

+

+proc tm(i: int32) =

+  var

+    b: TBuffer

+  toVarNum64(i, b)

+  var x = toNum(b)

+  if x != i:

+    writeln(stdout, toBinary(i))

+    writeln(stdout, toBinary(x))

+

+t32(0)

+t32(1)

+t32(-1)

+t32(-100_000)

+t32(100_000)

+t32(low(int32))

+t32(high(int32))

+

+t64(low(int64))

+t64(high(int64))

+t64(0)

+t64(-1)

+t64(1)

+t64(1000_000)

+t64(-1000_000)

+

+tm(0)

+tm(1)

+tm(-1)

+tm(-100_000)

+tm(100_000)

+tm(low(int32))

+tm(high(int32))

+

+writeln(stdout, "Success!") #OUT Success!