diff options
-rwxr-xr-x | compiler/pragmas.nim | 21 | ||||
-rwxr-xr-x | compiler/seminst.nim | 3 | ||||
-rwxr-xr-x | doc/nimrodc.txt | 6 | ||||
-rwxr-xr-x | lib/pure/collections/sets.nim | 9 | ||||
-rwxr-xr-x | lib/pure/collections/tables.nim | 64 | ||||
-rwxr-xr-x | lib/pure/strtabs.nim | 8 | ||||
-rwxr-xr-x | lib/system.nim | 2 | ||||
-rw-r--r-- | tests/accept/run/teventemitter.nim | 17 | ||||
-rwxr-xr-x | todo.txt | 6 | ||||
-rwxr-xr-x | web/index.txt | 7 |
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 |