summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-08-09 01:40:12 +0200
committerAraq <rumpf_a@web.de>2011-08-09 01:40:12 +0200
commit7000cf51b7c53808624dd7202c4213b84aacf708 (patch)
treef19810b24639f978f52dc7a02a569c952b4e9eff
parent12f22ba68a4c12042f2e72febdda32ff84b63307 (diff)
downloadNim-7000cf51b7c53808624dd7202c4213b84aacf708.tar.gz
modifyable results for generics; teventemitter works
-rwxr-xr-xcompiler/pragmas.nim21
-rwxr-xr-xcompiler/seminst.nim3
-rwxr-xr-xdoc/nimrodc.txt6
-rwxr-xr-xlib/pure/collections/sets.nim9
-rwxr-xr-xlib/pure/collections/tables.nim64
-rwxr-xr-xlib/pure/strtabs.nim8
-rwxr-xr-xlib/system.nim2
-rw-r--r--tests/accept/run/teventemitter.nim17
-rwxr-xr-xtodo.txt6
-rwxr-xr-xweb/index.txt7
10 files changed, 103 insertions, 40 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 014f431c4..ec97dd1d2 100755
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -18,7 +18,7 @@ const
   FirstCallConv* = wNimcall
   LastCallConv* = wNoconv
 
-const 
+const
   procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
     wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, 
     wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, 
@@ -26,9 +26,11 @@ const
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas
   macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
-    wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern}
+    wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern,
+    wImportcpp, wImportobjc}
   iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect, 
-    wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern}
+    wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
+    wImportcpp, wImportobjc}
   stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, 
     wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir, 
     wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal, 
@@ -37,14 +39,17 @@ const
     wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd}
   lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
     wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure, 
-    wDeprecated, wExtern, wThread}
+    wDeprecated, wExtern, wThread, wImportcpp, wImportobjc}
   typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, 
-    wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow}
-  fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern}
+    wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow, 
+    wImportcpp, wImportobjc}
+  fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, 
+    wImportcpp, wImportobjc}
   varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, 
-    wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib, wExtern}
+    wMagic, wHeader, wDeprecated, wCompilerProc, wDynLib, wExtern,
+    wImportcpp, wImportobjc}
   constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
-    wExtern}
+    wExtern, wImportcpp, wImportobjc}
   procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect,
                       wThread}
 
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 9feac18d2..87f988ed9 100755
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -121,10 +121,9 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
   instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry)
   n.sons[genericParamsPos] = ast.emptyNode
   # semantic checking for the parameters:
-  if n.sons[paramsPos].kind != nkEmpty:
+  if n.sons[paramsPos].kind != nkEmpty: 
     removeDefaultParamValues(n.sons[ParamsPos])
     semParamList(c, n.sons[ParamsPos], nil, result)
-    #echo "generated this return type: ", renderTree(n.sons[ParamsPos])
     addParams(c, result.typ.n)
   else: 
     result.typ = newTypeS(tyProc, c)
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 6961c41bd..2fd9267b2 100755
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -225,6 +225,9 @@ interfacing with libraries written in C++:
   proc run(device: PIrrlichtDevice): bool {.

     header: irr, importcpp: "run".}

   

+The compiler needs to be told to generate C++ (command ``cpp``) for 

+this to work.

+

 

 ImportObjC pragma

 -----------------

@@ -270,6 +273,9 @@ interfacing with libraries written in Objective C:
   g.greet(12, 34)

   g.free()

 

+The compiler needs to be told to generate Objective C (command ``objc``) for 

+this to work.

+

 

 LineDir option

 --------------

diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim
index 00056ff14..5f4b5a530 100755
--- a/lib/pure/collections/sets.nim
+++ b/lib/pure/collections/sets.nim
@@ -10,17 +10,12 @@
 ## The ``sets`` module implements an efficient hash set and ordered hash set.
 ##
 ## **Note**: The data types declared here have *value semantics*: This means
-## that ``=`` performs a copy of the hash table. If you are overly concerned
-## with efficiency and know what you do (!), you can define the symbol
-## ``shallowADT`` to compile a version that uses shallow copies instead.
+## that ``=`` performs a copy of the set.
 
 import
   os, hashes, math
 
-when defined(shallowADT):
-  {.pragma: myShallow, shallow.}
-else:
-  {.pragma: myShallow.}
+{.pragma: myShallow.}
 
 type
   TSlotEnum = enum seEmpty, seFilled, seDeleted
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 6fe77b26f..31b98a0cc 100755
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -11,17 +11,12 @@
 ## a mapping from keys to values.
 ##
 ## **Note:** The data types declared here have *value semantics*: This means
-## that ``=`` performs a copy of the hash table. If you are overly concerned
-## with efficiency and know what you do (!), you can define the symbol
-## ``shallowADT`` to compile a version that uses shallow copies instead.
+## that ``=`` performs a copy of the hash table.
 
 import
   hashes, math
 
-when defined(shallowADT):
-  {.pragma: myShallow, shallow.}
-else:
-  {.pragma: myShallow.}
+{.pragma: myShallow.}
 
 type
   TSlotEnum = enum seEmpty, seFilled, seDeleted
@@ -40,6 +35,12 @@ iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] =
   for h in 0..high(t.data):
     if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
 
+iterator mpairs*[A, B](t: var TTable[A, B]): tuple[key: A, val: var B] =
+  ## iterates over any (key, value) pair in the table `t`. The values
+  ## can be modified.
+  for h in 0..high(t.data):
+    if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
+
 iterator keys*[A, B](t: TTable[A, B]): A =
   ## iterates over any key in the table `t`.
   for h in 0..high(t.data):
@@ -50,6 +51,11 @@ iterator values*[A, B](t: TTable[A, B]): B =
   for h in 0..high(t.data):
     if t.data[h].slot == seFilled: yield t.data[h].val
 
+iterator mvalues*[A, B](t: var TTable[A, B]): var B =
+  ## iterates over any value in the table `t`. The values can be modified.
+  for h in 0..high(t.data):
+    if t.data[h].slot == seFilled: yield t.data[h].val
+
 const
   growthFactor = 2
 
@@ -87,6 +93,13 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B =
   var index = RawGet(t, key)
   if index >= 0: result = t.data[index].val
 
+proc mget*[A, B](t: var TTable[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: TTable[A, B], key: A): bool =
   ## returns true iff `key` is in the table `t`.
   result = rawGet(t, key) >= 0
@@ -197,6 +210,12 @@ iterator pairs*[A, B](t: TOrderedTable[A, B]): tuple[key: A, val: B] =
   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:
@@ -207,6 +226,12 @@ iterator values*[A, B](t: TOrderedTable[A, B]): B =
   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()
 
@@ -218,6 +243,13 @@ proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B =
   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
@@ -288,6 +320,12 @@ iterator pairs*[A](t: TCountTable[A]): tuple[key: A, val: int] =
   for h in 0..high(t.data):
     if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val)
 
+iterator mpairs*[A](t: var TCountTable[A]): tuple[key: A, val: var int] =
+  ## iterates over any (key, value) pair in the table `t`. The values can
+  ## be modified.
+  for h in 0..high(t.data):
+    if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val)
+
 iterator keys*[A](t: TCountTable[A]): A =
   ## iterates over any key in the table `t`.
   for h in 0..high(t.data):
@@ -298,6 +336,11 @@ iterator values*[A](t: TCountTable[A]): int =
   for h in 0..high(t.data):
     if t.data[h].val != 0: yield t.data[h].val
 
+iterator mvalues*[A](t: TCountTable[A]): var int =
+  ## iterates over any value in the table `t`. The values can be modified.
+  for h in 0..high(t.data):
+    if t.data[h].val != 0: yield t.data[h].val
+
 proc RawGet[A](t: TCountTable[A], key: A): int =
   var h: THash = hash(key) and high(t.data) # start with real hash value
   while t.data[h].val != 0:
@@ -312,6 +355,13 @@ proc `[]`*[A](t: TCountTable[A], key: A): int =
   var index = RawGet(t, key)
   if index >= 0: result = t.data[index].val
 
+proc mget*[A](t: var TCountTable[A], key: A): var int =
+  ## 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](t: TCountTable[A], key: A): bool =
   ## returns true iff `key` is in the table `t`.
   result = rawGet(t, key) >= 0
diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim
index 584282fbc..a9ce9016c 100755
--- a/lib/pure/strtabs.nim
+++ b/lib/pure/strtabs.nim
@@ -92,13 +92,13 @@ proc `[]`*(t: PStringTable, key: string): string {.rtl, extern: "nstGet".} =
   if index >= 0: result = t.data[index].val
   else: result = ""
 
-proc modGet*(t: PStringTable, key: string): var string {.
+proc mget*(t: PStringTable, key: string): var string {.
              rtl, extern: "nstTake".} =
   ## retrieves the location at ``t[key]``. If `key` is not in `t`, the
-  ## ``EInvalidValue`` exception is raised.
+  ## ``EInvalidKey`` exception is raised.
   var index = RawGet(t, key)
   if index >= 0: result = t.data[index].val
-  else: raise newException(EInvalidValue, "key does not exist: " & key)
+  else: raise newException(EInvalidKey, "key does not exist: " & key)
 
 proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} =
   ## returns true iff `key` is in the table `t`.
@@ -221,6 +221,6 @@ when isMainModule:
   assert x["k"] == "v"
   assert x["11"] == "22"
   assert x["565"] == "67"
-  x.modGet("11") = "23"
+  x.mget("11") = "23"
   assert x["11"] == "23"
 
diff --git a/lib/system.nim b/lib/system.nim
index b32f17d6a..024b84077 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -215,6 +215,8 @@ type
 
   EInvalidValue* = object of ESynch     ## is the exception class for string
                                         ## and object conversion errors.
+  EInvalidKey* = object of EInvalidValue ## is the exception class if a key
+                                         ## cannot be found in a table.
 
   EOutOfMemory* = object of ESystem     ## is the exception class for
                                         ## unsuccessful attempts to allocate
diff --git a/tests/accept/run/teventemitter.nim b/tests/accept/run/teventemitter.nim
index 1fa2f2a25..8394776a8 100644
--- a/tests/accept/run/teventemitter.nim
+++ b/tests/accept/run/teventemitter.nim
@@ -1,11 +1,14 @@
-import tables
-import lists
+discard """
+  output: "pie"
+"""
+
+import tables, lists
+
 type
   TEventArgs = object of TObject
-type
   TEventEmitter = object of TObject
     events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]
-        
+
 proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) =
   for func in nodes(emitter.events[event]):
     func.value(args) #call function with args.
@@ -13,9 +16,8 @@ proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) =
 proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
   if not hasKey(emitter.events, event):
     var list: TDoublyLinkedList[proc(e: TEventArgs)]
-    add(emitter.events,event,list) #if not, add it.
-  #append(emitter.events[event], func)
-  #adds the function to the event's list. I get a error here too.
+    add(emitter.events, event, list) #if not, add it.
+  append(emitter.events.mget(event), func)
 
 proc initEmitter(emitter: var TEventEmitter) =
   emitter.events = initTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]()
@@ -23,6 +25,7 @@ proc initEmitter(emitter: var TEventEmitter) =
 var 
   ee: TEventEmitter
   args: TEventArgs
+initEmitter(ee)
 ee.on("print", proc(e: TEventArgs) = echo("pie"))
 ee.emit("print", args)
 
diff --git a/todo.txt b/todo.txt
index cb6f9e74d..1dd6853fc 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,18 +1,18 @@
 Version 0.8.14
 ==============
 
-- ``var T`` as a return type: add ``modGet`` for generics
+- test ``m*`` for generics; document 'm' convention
 - optional indentation for 'case' statement
 - make threadvar efficient again on linux after testing
 - test the sort implementation again
 - export re-entrant and non-reentrant locks and condition vars; threads should
   not have an inbox per default
-
+  - add --deadlock_prevention:on|off switch? timeout for locks?
 
 version 0.9.0
 =============
 
-- add --deadlock_prevention:on|off switch? timeout for locks?
+- unsigned ints and bignums
 - warning for implicit openArray -> varargs convention
 - implement explicit varargs
 - tests: run the GC tests
diff --git a/web/index.txt b/web/index.txt
index 9e39f5dd3..c4c8f2f97 100755
--- a/web/index.txt
+++ b/web/index.txt
@@ -91,8 +91,11 @@ Nimrod plays nice with others
 
 * The Nimrod Compiler runs on Windows, Linux, BSD and Mac OS X.
   Porting to other platforms is easy.
-* **There are bindings to GTK2, the Windows API, the POSIX API, OpenGL, SDL, 
-  Cario, Python, Lua, TCL, X11, libzip, PRCE, ODBC, libcurl, mySQL and SQLite.** 
+* **The Nimrod Compiler can also generate C++ or Objective C for easier
+  interfacing.**
+* There are lots of bindings: for example, bindings to GTK2, the Windows API, 
+  the POSIX API, OpenGL, SDL, Cario, Python, Lua, TCL, X11, libzip, PCRE, 
+  libcurl, mySQL and SQLite are included in the standard distribution.
 * A C to Nimrod conversion utility: New bindings to C libraries are easily 
   generated by ``c2nim``.
 * A Pascal to Nimrod conversion utility: A large subset of Object Pascal