summary refs log tree commit diff stats
path: root/tests/compile
diff options
context:
space:
mode:
Diffstat (limited to 'tests/compile')
-rw-r--r--tests/compile/mexporta.nim8
-rw-r--r--tests/compile/mexportb.nim7
-rw-r--r--tests/compile/tclosure4.nim13
-rw-r--r--tests/compile/tclosurebug2.nim194
-rw-r--r--tests/compile/tcolonisproc.nim12
-rw-r--r--tests/compile/teffects1.nim17
-rw-r--r--tests/compile/texport.nim10
-rw-r--r--tests/compile/tforwardgeneric.nim1
-rw-r--r--tests/compile/tircbot.nim15
-rw-r--r--tests/compile/titerovl.nim21
-rw-r--r--tests/compile/tnamedparamanonproc.nim14
-rw-r--r--tests/compile/tobject3.nim28
-rwxr-xr-xtests/compile/toverprc.nim2
-rw-r--r--tests/compile/tsecondarrayproperty.nim28
-rwxr-xr-xtests/compile/twalker.nim2
15 files changed, 363 insertions, 9 deletions
diff --git a/tests/compile/mexporta.nim b/tests/compile/mexporta.nim
new file mode 100644
index 000000000..b7d4ddec9
--- /dev/null
+++ b/tests/compile/mexporta.nim
@@ -0,0 +1,8 @@
+# module A
+import mexportb
+export mexportb.TMyObject, mexportb.xyz
+
+export mexportb.q
+
+proc `$`*(x: TMyObject): string = "my object"
+
diff --git a/tests/compile/mexportb.nim b/tests/compile/mexportb.nim
new file mode 100644
index 000000000..10d89f388
--- /dev/null
+++ b/tests/compile/mexportb.nim
@@ -0,0 +1,7 @@
+# module B
+type TMyObject* = object
+
+const xyz* = 13
+
+proc q*(x: int): int = 6
+proc q*(x: string): string = "8"
diff --git a/tests/compile/tclosure4.nim b/tests/compile/tclosure4.nim
new file mode 100644
index 000000000..8e08376b6
--- /dev/null
+++ b/tests/compile/tclosure4.nim
@@ -0,0 +1,13 @@
+
+import json, tables
+
+proc run(json_params: TTable) =
+  let json_elems = json_params["files"].elems
+  # These fail compilation.
+  var files = map(json_elems, proc (x: PJsonNode): string = x.str)
+  #var files = json_elems.map do (x: PJsonNode) -> string: x.str
+  echo "Hey!"
+
+when isMainModule:
+  let text = """{"files": ["a", "b", "c"]}"""
+  run(toTable((text.parseJson).fields))
diff --git a/tests/compile/tclosurebug2.nim b/tests/compile/tclosurebug2.nim
new file mode 100644
index 000000000..ec4f0045b
--- /dev/null
+++ b/tests/compile/tclosurebug2.nim
@@ -0,0 +1,194 @@
+import hashes, math
+
+type
+  TSlotEnum = enum seEmpty, seFilled, seDeleted
+  TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B]
+  TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]]
+
+  TOrderedKeyValuePair[A, B] = tuple[
+    slot: TSlotEnum, next: int, key: A, val: B]
+  TOrderedKeyValuePairSeq[A, B] = seq[TOrderedKeyValuePair[A, B]]
+  TOrderedTable*[A, B] = object ## table that remembers insertion order
+    data: TOrderedKeyValuePairSeq[A, B]
+    counter, first, last: int
+
+const
+  growthFactor = 2
+
+proc mustRehash(length, counter: int): bool {.inline.} =
+  assert(length > counter)
+  result = (length * 2 < counter * 3) or (length - counter < 4)
+
+proc nextTry(h, maxHash: THash): THash {.inline.} =
+  result = ((5 * h) + 1) and maxHash
+
+template rawGetImpl() {.dirty.} =
+  var h: THash = hash(key) and high(t.data) # start with real hash value
+  while t.data[h].slot != seEmpty:
+    if t.data[h].key == key and t.data[h].slot == seFilled:
+      return h
+    h = nextTry(h, high(t.data))
+  result = -1
+
+template rawInsertImpl() {.dirty.} =
+  var h: THash = hash(key) and high(data)
+  while data[h].slot == seFilled:
+    h = nextTry(h, high(data))
+  data[h].key = key
+  data[h].val = val
+  data[h].slot = seFilled
+
+template AddImpl() {.dirty.} =
+  if mustRehash(len(t.data), t.counter): Enlarge(t)
+  RawInsert(t, t.data, key, val)
+  inc(t.counter)
+
+template PutImpl() {.dirty.} =
+  var index = RawGet(t, key)
+  if index >= 0:
+    t.data[index].val = val
+  else:
+    AddImpl()
+
+proc len*[A, B](t: TOrderedTable[A, B]): int {.inline.} =
+  ## returns the number of keys in `t`.
+  result = t.counter
+
+template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
+  var h = t.first
+  while h >= 0:
+    var nxt = t.data[h].next
+    if t.data[h].slot == seFilled: yieldStmt
+    h = nxt
+
+iterator pairs*[A, B](t: TOrderedTable[A, B]): tuple[key: A, val: B] =
+  ## iterates over any (key, value) pair in the table `t` in insertion
+  ## order.
+  forAllOrderedPairs:
+    yield (t.data[h].key, t.data[h].val)
+
+iterator mpairs*[A, B](t: var TOrderedTable[A, B]): tuple[key: A, val: var B] =
+  ## iterates over any (key, value) pair in the table `t` in insertion
+  ## order. The values can be modified.
+  forAllOrderedPairs:
+    yield (t.data[h].key, t.data[h].val)
+
+iterator keys*[A, B](t: TOrderedTable[A, B]): A =
+  ## iterates over any key in the table `t` in insertion order.
+  forAllOrderedPairs:
+    yield t.data[h].key
+
+iterator values*[A, B](t: TOrderedTable[A, B]): B =
+  ## iterates over any value in the table `t` in insertion order.
+  forAllOrderedPairs:
+    yield t.data[h].val
+
+iterator mvalues*[A, B](t: var TOrderedTable[A, B]): var B =
+  ## iterates over any value in the table `t` in insertion order. The values
+  ## can be modified.
+  forAllOrderedPairs:
+    yield t.data[h].val
+
+proc RawGet[A, B](t: TOrderedTable[A, B], key: A): int =
+  rawGetImpl()
+
+proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B =
+  ## retrieves the value at ``t[key]``. If `key` is not in `t`,
+  ## default empty value for the type `B` is returned
+  ## and no exception is raised. One can check with ``hasKey`` whether the key
+  ## exists.
+  var index = RawGet(t, key)
+  if index >= 0: result = t.data[index].val
+
+proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B =
+  ## retrieves the value at ``t[key]``. The value can be modified.
+  ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised.
+  var index = RawGet(t, key)
+  if index >= 0: result = t.data[index].val
+  else: raise newException(EInvalidKey, "key not found: " & $key)
+
+proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool =
+  ## returns true iff `key` is in the table `t`.
+  result = rawGet(t, key) >= 0
+
+proc RawInsert[A, B](t: var TOrderedTable[A, B], 
+                     data: var TOrderedKeyValuePairSeq[A, B],
+                     key: A, val: B) =
+  rawInsertImpl()
+  data[h].next = -1
+  if t.first < 0: t.first = h
+  if t.last >= 0: data[t.last].next = h
+  t.last = h
+
+proc Enlarge[A, B](t: var TOrderedTable[A, B]) =
+  var n: TOrderedKeyValuePairSeq[A, B]
+  newSeq(n, len(t.data) * growthFactor)
+  var h = t.first
+  t.first = -1
+  t.last = -1
+  while h >= 0:
+    var nxt = t.data[h].next
+    if t.data[h].slot == seFilled: 
+      RawInsert(t, n, t.data[h].key, t.data[h].val)
+    h = nxt
+  swap(t.data, n)
+
+proc `[]=`*[A, B](t: var TOrderedTable[A, B], key: A, val: B) =
+  ## puts a (key, value)-pair into `t`.
+  putImpl()
+
+proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) =
+  ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.
+  AddImpl()
+
+proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] =
+  ## creates a new ordered hash table that is empty. `initialSize` needs to be
+  ## a power of two.
+  assert isPowerOfTwo(initialSize)
+  result.counter = 0
+  result.first = -1
+  result.last = -1
+  newSeq(result.data, initialSize)
+
+proc toOrderedTable*[A, B](pairs: openarray[tuple[key: A, 
+                           val: B]]): TOrderedTable[A, B] =
+  ## creates a new ordered hash table that contains the given `pairs`.
+  result = initOrderedTable[A, B](nextPowerOfTwo(pairs.len+10))
+  for key, val in items(pairs): result[key] = val
+
+proc sort*[A, B](t: var TOrderedTable[A,B], 
+                 cmp: proc (x, y: tuple[key: A, val: B]): int {.closure.}) =
+  ## sorts the ordered table so that the entry with the highest counter comes
+  ## first. This is destructive (with the advantage of being efficient)! 
+  ## You must not modify `t` afterwards!
+  ## You can use the iterators `pairs`,  `keys`, and `values` to iterate over
+  ## `t` in the sorted order.
+
+  # we use shellsort here; fast enough and simple
+  var h = 1
+  while true:
+    h = 3 * h + 1
+    if h >= high(t.data): break
+  while true:
+    h = h div 3
+    for i in countup(h, high(t.data)):
+      var j = i
+      #echo(t.data.len, " ", j, " - ", h)
+      #echo(repr(t.data[j-h]))
+      proc rawCmp(x, y: TOrderedKeyValuePair[A, B]): int =
+        if x.slot in {seEmpty, seDeleted} and y.slot in {seEmpty, seDeleted}:
+          return 0
+        elif x.slot in {seEmpty, seDeleted}:
+          return -1
+        elif y.slot in {seEmpty, seDeleted}:
+          return 1
+        else:
+          let item1 = (x.key, x.val)
+          let item2 = (y.key, y.val)
+          return cmp(item1, item2)
+      
+      while rawCmp(t.data[j-h], t.data[j]) <= 0:
+        swap(t.data[j], t.data[j-h])
+        j = j-h
+        if j < h: break
+    if h == 1: break
diff --git a/tests/compile/tcolonisproc.nim b/tests/compile/tcolonisproc.nim
new file mode 100644
index 000000000..e55587dfc
--- /dev/null
+++ b/tests/compile/tcolonisproc.nim
@@ -0,0 +1,12 @@
+
+proc p(a, b: int, c: proc ()) =
+  c()
+
+ 
+p(1, 3): 
+  echo 1
+  echo 3
+    
+p(1, 1, proc() =
+  echo 1
+  echo 2)
diff --git a/tests/compile/teffects1.nim b/tests/compile/teffects1.nim
new file mode 100644
index 000000000..49af28469
--- /dev/null
+++ b/tests/compile/teffects1.nim
@@ -0,0 +1,17 @@
+
+type
+  PMenu = ref object
+  PMenuItem = ref object
+
+proc createMenuItem*(menu: PMenu, label: string, 
+                     action: proc (i: PMenuItem, p: pointer) {.cdecl.}) = nil
+
+var s: PMenu
+createMenuItem(s, "Go to definition...",
+      proc (i: PMenuItem, p: pointer) {.cdecl.} =
+        try:
+          echo(i.repr)
+        except EInvalidValue:
+          echo("blah")
+)
+
diff --git a/tests/compile/texport.nim b/tests/compile/texport.nim
new file mode 100644
index 000000000..99228dfce
--- /dev/null
+++ b/tests/compile/texport.nim
@@ -0,0 +1,10 @@
+discard """
+  output: "my object68"
+"""
+
+import mexporta
+
+# B.TMyObject has been imported implicitly here: 
+var x: TMyObject
+echo($x, q(0), q"0")
+
diff --git a/tests/compile/tforwardgeneric.nim b/tests/compile/tforwardgeneric.nim
index 84bef15cc..ef263d733 100644
--- a/tests/compile/tforwardgeneric.nim
+++ b/tests/compile/tforwardgeneric.nim
@@ -1,5 +1,6 @@
 discard """
   output: "1.0000000000000000e+00 10"
+  ccodecheck: "!@'ClEnv'"
 """
 
 proc p[T](a, b: T): T
diff --git a/tests/compile/tircbot.nim b/tests/compile/tircbot.nim
index 10482c3f6..d16c99b69 100644
--- a/tests/compile/tircbot.nim
+++ b/tests/compile/tircbot.nim
@@ -272,7 +272,7 @@ proc handleWebMessage(state: PState, line: string) =
       message.add(limitCommitMsg(commit["message"].str))
 
       # Send message to #nimrod.
-      state.ircClient[].privmsg(joinChans[0], message)
+      state.ircClient.privmsg(joinChans[0], message)
   elif json.existsKey("redisinfo"):
     assert json["redisinfo"].existsKey("port")
     #let redisPort = json["redisinfo"]["port"].num
@@ -336,10 +336,11 @@ proc hubConnect(state: PState) =
 
   state.dispatcher.register(state.sock)
 
-proc handleIrc(irc: var TAsyncIRC, event: TIRCEvent, state: PState) =
+proc handleIrc(irc: PAsyncIRC, event: TIRCEvent, state: PState) =
   case event.typ
+  of EvConnected: nil
   of EvDisconnected:
-    while not state.ircClient[].isConnected:
+    while not state.ircClient.isConnected:
       try:
         state.ircClient.connect()
       except:
@@ -355,12 +356,12 @@ proc handleIrc(irc: var TAsyncIRC, event: TIRCEvent, state: PState) =
       let msg = event.params[event.params.len-1]
       let words = msg.split(' ')
       template pm(msg: string): stmt =
-        state.ircClient[].privmsg(event.origin, msg)
+        state.ircClient.privmsg(event.origin, msg)
       case words[0]
       of "!ping": pm("pong")
       of "!lag":
-        if state.ircClient[].getLag != -1.0:
-          var lag = state.ircClient[].getLag
+        if state.ircClient.getLag != -1.0:
+          var lag = state.ircClient.getLag
           lag = lag * 1000.0
           pm($int(lag) & "ms between me and the server.")
         else:
@@ -433,7 +434,7 @@ proc open(port: TPort = TPort(5123)): PState =
   res.hubPort = port
   res.hubConnect()
   let hirc =
-    proc (a: var TAsyncIRC, ev: TIRCEvent) =
+    proc (a: PAsyncIRC, ev: TIRCEvent) =
       handleIrc(a, ev, res)
   # Connect to the irc server.
   res.ircClient = AsyncIrc(ircServer, nick = botNickname, user = botNickname,
diff --git a/tests/compile/titerovl.nim b/tests/compile/titerovl.nim
new file mode 100644
index 000000000..be665b2b7
--- /dev/null
+++ b/tests/compile/titerovl.nim
@@ -0,0 +1,21 @@
+discard """
+  output: '''9
+1
+2
+3
+'''
+"""
+
+# Test the new overloading rules for iterators:
+
+# test that iterator 'p' is preferred:
+proc p(): seq[int] = @[1, 2, 3]
+iterator p(): int = yield 9
+
+for x in p(): echo x
+
+# test that 'q' works in this position:
+proc q(): seq[int] = @[1, 2, 3]
+
+for x in q(): echo x
+
diff --git a/tests/compile/tnamedparamanonproc.nim b/tests/compile/tnamedparamanonproc.nim
new file mode 100644
index 000000000..272b84e91
--- /dev/null
+++ b/tests/compile/tnamedparamanonproc.nim
@@ -0,0 +1,14 @@
+
+type
+  PButton = ref object
+  TButtonClicked = proc(button: PButton) {.nimcall.}
+
+proc newButton*(onClick: TButtonClicked) =
+  nil
+  
+proc main() =
+  newButton(onClick = proc(b: PButton) =
+    var requestomat = 12
+    )
+
+main()
diff --git a/tests/compile/tobject3.nim b/tests/compile/tobject3.nim
new file mode 100644
index 000000000..935e6ca8c
--- /dev/null
+++ b/tests/compile/tobject3.nim
@@ -0,0 +1,28 @@
+type
+  TFoo = ref object of TObject
+    Data: int  
+  TBar = ref object of TFoo
+    nil
+  TBar2 = ref object of TBar
+    d2: int
+
+template super(self: TBar): TFoo = self
+
+template super(self: TBar2): TBar = self
+
+proc Foo(self: TFoo) =
+  echo "TFoo"
+
+#proc Foo(self: TBar) =
+#  echo "TBar"
+#  Foo(super(self))
+# works when this code is uncommented
+
+proc Foo(self: TBar2) =
+  echo "TBar2"
+  Foo(super(self))
+
+var b: TBar2
+new(b)
+
+Foo(b)
diff --git a/tests/compile/toverprc.nim b/tests/compile/toverprc.nim
index 43271b684..f3aa66b80 100755
--- a/tests/compile/toverprc.nim
+++ b/tests/compile/toverprc.nim
@@ -21,7 +21,7 @@ proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int =
   result = x("123")

   

 echo "Give a list of numbers (separated by spaces): "

-var x = stdin.readline.split.each(parseInt).max

+var x = stdin.readline.split.map(parseInt).max

 echo x, " is the maximum!"

 echo "another number: ", takeParseInt(parseInt)

 

diff --git a/tests/compile/tsecondarrayproperty.nim b/tests/compile/tsecondarrayproperty.nim
new file mode 100644
index 000000000..07fdac1c4
--- /dev/null
+++ b/tests/compile/tsecondarrayproperty.nim
@@ -0,0 +1,28 @@
+
+type
+  TFoo = object
+    data: array[0..100, int]
+  TSecond = distinct TFoo
+
+proc `[]` (self: var TFoo, x: int): var int =
+  return self.data[x]
+
+proc `[]=` (self: var TFoo, x, y: int) =
+  # only `[]` returning a 'var T' seems to not work for now :-/
+  self.data[x] = y
+
+proc second(self: var TFoo): var TSecond =
+  return TSecond(self)
+
+proc `[]`(self: var TSecond, x: int): var int =  
+  return TFoo(self).data[2*x]
+
+var f: TFoo
+
+for i in 0..f.data.high: f[i] = 2 * i
+
+echo f.second[1]
+
+#echo `second[]`(f,1)
+# this is the only way I could use it, but not what I expected
+
diff --git a/tests/compile/twalker.nim b/tests/compile/twalker.nim
index 3fdd8769b..89e6c2b9d 100755
--- a/tests/compile/twalker.nim
+++ b/tests/compile/twalker.nim
@@ -1,7 +1,7 @@
 # iterate over all files with a given filter:

 

 import

-  os, times

+  "../../lib/pure/os.nim", ../../ lib / pure / times

 

 proc main(filter: string) =

   for filename in walkFiles(filter):