modifyable results for generics; teventemitter works
This commit is contained in:
parent
12f22ba68a
commit
7000cf51b7
10 changed files with 103 additions and 40 deletions
|
|
@ -26,9 +26,11 @@ const
|
||||||
converterPragmas* = procPragmas
|
converterPragmas* = procPragmas
|
||||||
methodPragmas* = procPragmas
|
methodPragmas* = procPragmas
|
||||||
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern}
|
wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern,
|
||||||
|
wImportcpp, wImportobjc}
|
||||||
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect,
|
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,
|
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
|
||||||
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir,
|
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir,
|
||||||
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
|
wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, wFatal,
|
||||||
|
|
@ -37,14 +39,17 @@ const
|
||||||
wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd}
|
wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd}
|
||||||
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure,
|
wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wPure,
|
||||||
wDeprecated, wExtern, wThread}
|
wDeprecated, wExtern, wThread, wImportcpp, wImportobjc}
|
||||||
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
||||||
wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow}
|
wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow,
|
||||||
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern}
|
wImportcpp, wImportobjc}
|
||||||
|
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
||||||
|
wImportcpp, wImportobjc}
|
||||||
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
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,
|
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
|
||||||
wExtern}
|
wExtern, wImportcpp, wImportobjc}
|
||||||
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect,
|
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideEffect,
|
||||||
wThread}
|
wThread}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,6 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
if n.sons[paramsPos].kind != nkEmpty:
|
if n.sons[paramsPos].kind != nkEmpty:
|
||||||
removeDefaultParamValues(n.sons[ParamsPos])
|
removeDefaultParamValues(n.sons[ParamsPos])
|
||||||
semParamList(c, n.sons[ParamsPos], nil, result)
|
semParamList(c, n.sons[ParamsPos], nil, result)
|
||||||
#echo "generated this return type: ", renderTree(n.sons[ParamsPos])
|
|
||||||
addParams(c, result.typ.n)
|
addParams(c, result.typ.n)
|
||||||
else:
|
else:
|
||||||
result.typ = newTypeS(tyProc, c)
|
result.typ = newTypeS(tyProc, c)
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,9 @@ interfacing with libraries written in C++:
|
||||||
proc run(device: PIrrlichtDevice): bool {.
|
proc run(device: PIrrlichtDevice): bool {.
|
||||||
header: irr, importcpp: "run".}
|
header: irr, importcpp: "run".}
|
||||||
|
|
||||||
|
The compiler needs to be told to generate C++ (command ``cpp``) for
|
||||||
|
this to work.
|
||||||
|
|
||||||
|
|
||||||
ImportObjC pragma
|
ImportObjC pragma
|
||||||
-----------------
|
-----------------
|
||||||
|
|
@ -270,6 +273,9 @@ interfacing with libraries written in Objective C:
|
||||||
g.greet(12, 34)
|
g.greet(12, 34)
|
||||||
g.free()
|
g.free()
|
||||||
|
|
||||||
|
The compiler needs to be told to generate Objective C (command ``objc``) for
|
||||||
|
this to work.
|
||||||
|
|
||||||
|
|
||||||
LineDir option
|
LineDir option
|
||||||
--------------
|
--------------
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,12 @@
|
||||||
## The ``sets`` module implements an efficient hash set and ordered hash set.
|
## The ``sets`` module implements an efficient hash set and ordered hash set.
|
||||||
##
|
##
|
||||||
## **Note**: The data types declared here have *value semantics*: This means
|
## **Note**: The data types declared here have *value semantics*: This means
|
||||||
## that ``=`` performs a copy of the hash table. If you are overly concerned
|
## that ``=`` performs a copy of the set.
|
||||||
## with efficiency and know what you do (!), you can define the symbol
|
|
||||||
## ``shallowADT`` to compile a version that uses shallow copies instead.
|
|
||||||
|
|
||||||
import
|
import
|
||||||
os, hashes, math
|
os, hashes, math
|
||||||
|
|
||||||
when defined(shallowADT):
|
{.pragma: myShallow.}
|
||||||
{.pragma: myShallow, shallow.}
|
|
||||||
else:
|
|
||||||
{.pragma: myShallow.}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TSlotEnum = enum seEmpty, seFilled, seDeleted
|
TSlotEnum = enum seEmpty, seFilled, seDeleted
|
||||||
|
|
|
||||||
|
|
@ -11,17 +11,12 @@
|
||||||
## a mapping from keys to values.
|
## a mapping from keys to values.
|
||||||
##
|
##
|
||||||
## **Note:** The data types declared here have *value semantics*: This means
|
## **Note:** The data types declared here have *value semantics*: This means
|
||||||
## that ``=`` performs a copy of the hash table. If you are overly concerned
|
## that ``=`` performs a copy of the hash table.
|
||||||
## with efficiency and know what you do (!), you can define the symbol
|
|
||||||
## ``shallowADT`` to compile a version that uses shallow copies instead.
|
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, math
|
hashes, math
|
||||||
|
|
||||||
when defined(shallowADT):
|
{.pragma: myShallow.}
|
||||||
{.pragma: myShallow, shallow.}
|
|
||||||
else:
|
|
||||||
{.pragma: myShallow.}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TSlotEnum = enum seEmpty, seFilled, seDeleted
|
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):
|
for h in 0..high(t.data):
|
||||||
if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
|
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 =
|
iterator keys*[A, B](t: TTable[A, B]): A =
|
||||||
## iterates over any key in the table `t`.
|
## iterates over any key in the table `t`.
|
||||||
for h in 0..high(t.data):
|
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):
|
for h in 0..high(t.data):
|
||||||
if t.data[h].slot == seFilled: yield t.data[h].val
|
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
|
const
|
||||||
growthFactor = 2
|
growthFactor = 2
|
||||||
|
|
||||||
|
|
@ -87,6 +93,13 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B =
|
||||||
var index = RawGet(t, key)
|
var index = RawGet(t, key)
|
||||||
if index >= 0: result = t.data[index].val
|
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 =
|
proc hasKey*[A, B](t: TTable[A, B], key: A): bool =
|
||||||
## returns true iff `key` is in the table `t`.
|
## returns true iff `key` is in the table `t`.
|
||||||
result = rawGet(t, key) >= 0
|
result = rawGet(t, key) >= 0
|
||||||
|
|
@ -197,6 +210,12 @@ iterator pairs*[A, B](t: TOrderedTable[A, B]): tuple[key: A, val: B] =
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
yield (t.data[h].key, t.data[h].val)
|
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 =
|
iterator keys*[A, B](t: TOrderedTable[A, B]): A =
|
||||||
## iterates over any key in the table `t` in insertion order.
|
## iterates over any key in the table `t` in insertion order.
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
|
|
@ -207,6 +226,12 @@ iterator values*[A, B](t: TOrderedTable[A, B]): B =
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
yield t.data[h].val
|
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 =
|
proc RawGet[A, B](t: TOrderedTable[A, B], key: A): int =
|
||||||
rawGetImpl()
|
rawGetImpl()
|
||||||
|
|
||||||
|
|
@ -218,6 +243,13 @@ proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B =
|
||||||
var index = RawGet(t, key)
|
var index = RawGet(t, key)
|
||||||
if index >= 0: result = t.data[index].val
|
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 =
|
proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool =
|
||||||
## returns true iff `key` is in the table `t`.
|
## returns true iff `key` is in the table `t`.
|
||||||
result = rawGet(t, key) >= 0
|
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):
|
for h in 0..high(t.data):
|
||||||
if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val)
|
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 =
|
iterator keys*[A](t: TCountTable[A]): A =
|
||||||
## iterates over any key in the table `t`.
|
## iterates over any key in the table `t`.
|
||||||
for h in 0..high(t.data):
|
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):
|
for h in 0..high(t.data):
|
||||||
if t.data[h].val != 0: yield t.data[h].val
|
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 =
|
proc RawGet[A](t: TCountTable[A], key: A): int =
|
||||||
var h: THash = hash(key) and high(t.data) # start with real hash value
|
var h: THash = hash(key) and high(t.data) # start with real hash value
|
||||||
while t.data[h].val != 0:
|
while t.data[h].val != 0:
|
||||||
|
|
@ -312,6 +355,13 @@ proc `[]`*[A](t: TCountTable[A], key: A): int =
|
||||||
var index = RawGet(t, key)
|
var index = RawGet(t, key)
|
||||||
if index >= 0: result = t.data[index].val
|
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 =
|
proc hasKey*[A](t: TCountTable[A], key: A): bool =
|
||||||
## returns true iff `key` is in the table `t`.
|
## returns true iff `key` is in the table `t`.
|
||||||
result = rawGet(t, key) >= 0
|
result = rawGet(t, key) >= 0
|
||||||
|
|
|
||||||
|
|
@ -92,13 +92,13 @@ proc `[]`*(t: PStringTable, key: string): string {.rtl, extern: "nstGet".} =
|
||||||
if index >= 0: result = t.data[index].val
|
if index >= 0: result = t.data[index].val
|
||||||
else: result = ""
|
else: result = ""
|
||||||
|
|
||||||
proc modGet*(t: PStringTable, key: string): var string {.
|
proc mget*(t: PStringTable, key: string): var string {.
|
||||||
rtl, extern: "nstTake".} =
|
rtl, extern: "nstTake".} =
|
||||||
## retrieves the location at ``t[key]``. If `key` is not in `t`, the
|
## 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)
|
var index = RawGet(t, key)
|
||||||
if index >= 0: result = t.data[index].val
|
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".} =
|
proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} =
|
||||||
## returns true iff `key` is in the table `t`.
|
## returns true iff `key` is in the table `t`.
|
||||||
|
|
@ -221,6 +221,6 @@ when isMainModule:
|
||||||
assert x["k"] == "v"
|
assert x["k"] == "v"
|
||||||
assert x["11"] == "22"
|
assert x["11"] == "22"
|
||||||
assert x["565"] == "67"
|
assert x["565"] == "67"
|
||||||
x.modGet("11") = "23"
|
x.mget("11") = "23"
|
||||||
assert x["11"] == "23"
|
assert x["11"] == "23"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,8 @@ type
|
||||||
|
|
||||||
EInvalidValue* = object of ESynch ## is the exception class for string
|
EInvalidValue* = object of ESynch ## is the exception class for string
|
||||||
## and object conversion errors.
|
## 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
|
EOutOfMemory* = object of ESystem ## is the exception class for
|
||||||
## unsuccessful attempts to allocate
|
## unsuccessful attempts to allocate
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
import tables
|
discard """
|
||||||
import lists
|
output: "pie"
|
||||||
|
"""
|
||||||
|
|
||||||
|
import tables, lists
|
||||||
|
|
||||||
type
|
type
|
||||||
TEventArgs = object of TObject
|
TEventArgs = object of TObject
|
||||||
type
|
|
||||||
TEventEmitter = object of TObject
|
TEventEmitter = object of TObject
|
||||||
events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]
|
events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]
|
||||||
|
|
||||||
|
|
@ -13,9 +16,8 @@ proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) =
|
||||||
proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
|
proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
|
||||||
if not hasKey(emitter.events, event):
|
if not hasKey(emitter.events, event):
|
||||||
var list: TDoublyLinkedList[proc(e: TEventArgs)]
|
var list: TDoublyLinkedList[proc(e: TEventArgs)]
|
||||||
add(emitter.events,event,list) #if not, add it.
|
add(emitter.events, event, list) #if not, add it.
|
||||||
#append(emitter.events[event], func)
|
append(emitter.events.mget(event), func)
|
||||||
#adds the function to the event's list. I get a error here too.
|
|
||||||
|
|
||||||
proc initEmitter(emitter: var TEventEmitter) =
|
proc initEmitter(emitter: var TEventEmitter) =
|
||||||
emitter.events = initTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]()
|
emitter.events = initTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]()
|
||||||
|
|
@ -23,6 +25,7 @@ proc initEmitter(emitter: var TEventEmitter) =
|
||||||
var
|
var
|
||||||
ee: TEventEmitter
|
ee: TEventEmitter
|
||||||
args: TEventArgs
|
args: TEventArgs
|
||||||
|
initEmitter(ee)
|
||||||
ee.on("print", proc(e: TEventArgs) = echo("pie"))
|
ee.on("print", proc(e: TEventArgs) = echo("pie"))
|
||||||
ee.emit("print", args)
|
ee.emit("print", args)
|
||||||
|
|
||||||
|
|
|
||||||
6
todo.txt
6
todo.txt
|
|
@ -1,18 +1,18 @@
|
||||||
Version 0.8.14
|
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
|
- optional indentation for 'case' statement
|
||||||
- make threadvar efficient again on linux after testing
|
- make threadvar efficient again on linux after testing
|
||||||
- test the sort implementation again
|
- test the sort implementation again
|
||||||
- export re-entrant and non-reentrant locks and condition vars; threads should
|
- export re-entrant and non-reentrant locks and condition vars; threads should
|
||||||
not have an inbox per default
|
not have an inbox per default
|
||||||
|
- add --deadlock_prevention:on|off switch? timeout for locks?
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- add --deadlock_prevention:on|off switch? timeout for locks?
|
- unsigned ints and bignums
|
||||||
- warning for implicit openArray -> varargs convention
|
- warning for implicit openArray -> varargs convention
|
||||||
- implement explicit varargs
|
- implement explicit varargs
|
||||||
- tests: run the GC tests
|
- tests: run the GC tests
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,11 @@ Nimrod plays nice with others
|
||||||
|
|
||||||
* The Nimrod Compiler runs on Windows, Linux, BSD and Mac OS X.
|
* The Nimrod Compiler runs on Windows, Linux, BSD and Mac OS X.
|
||||||
Porting to other platforms is easy.
|
Porting to other platforms is easy.
|
||||||
* **There are bindings to GTK2, the Windows API, the POSIX API, OpenGL, SDL,
|
* **The Nimrod Compiler can also generate C++ or Objective C for easier
|
||||||
Cario, Python, Lua, TCL, X11, libzip, PRCE, ODBC, libcurl, mySQL and SQLite.**
|
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
|
* A C to Nimrod conversion utility: New bindings to C libraries are easily
|
||||||
generated by ``c2nim``.
|
generated by ``c2nim``.
|
||||||
* A Pascal to Nimrod conversion utility: A large subset of Object Pascal
|
* A Pascal to Nimrod conversion utility: A large subset of Object Pascal
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue