preparations for making 'closure' the default calling convention for proc types
This commit is contained in:
parent
56b4e3ad91
commit
8d99753d63
36 changed files with 117 additions and 102 deletions
|
|
@ -35,9 +35,10 @@ proc ObjectSetContainsOrIncl*(t: var TObjectSet, obj: PObject): bool
|
||||||
proc TablePut*(t: var TTable, key, val: PObject)
|
proc TablePut*(t: var TTable, key, val: PObject)
|
||||||
proc TableGet*(t: TTable, key: PObject): PObject
|
proc TableGet*(t: TTable, key: PObject): PObject
|
||||||
type
|
type
|
||||||
TCmpProc* = proc (key, closure: PObject): bool # should return true if found
|
TCmpProc* = proc (key, closure: PObject): bool {.nimcall.} # true if found
|
||||||
|
|
||||||
proc TableSearch*(t: TTable, key, closure: PObject, comparator: TCmpProc): PObject
|
proc TableSearch*(t: TTable, key, closure: PObject,
|
||||||
|
comparator: TCmpProc): PObject
|
||||||
# return val as soon as comparator returns true; if this never happens,
|
# return val as soon as comparator returns true; if this never happens,
|
||||||
# nil is returned
|
# nil is returned
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ type
|
||||||
head*, tail*: PListEntry
|
head*, tail*: PListEntry
|
||||||
Counter*: int
|
Counter*: int
|
||||||
|
|
||||||
TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool
|
TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool {.nimcall.}
|
||||||
|
|
||||||
proc InitLinkedList*(list: var TLinkedList) =
|
proc InitLinkedList*(list: var TLinkedList) =
|
||||||
list.Counter = 0
|
list.Counter = 0
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ type
|
||||||
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
||||||
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
|
||||||
warnXisPassedToProcVar, warnAnalysisLoophole,
|
warnXisPassedToProcVar, warnAnalysisLoophole,
|
||||||
warnDifferentHeaps, warnWriteToForeignHeap, warnImplicitNarrowing,
|
warnDifferentHeaps, warnWriteToForeignHeap, warnImplicitClosure,
|
||||||
warnUser,
|
warnUser,
|
||||||
hintSuccess, hintSuccessX,
|
hintSuccess, hintSuccessX,
|
||||||
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
||||||
|
|
@ -345,7 +345,7 @@ const
|
||||||
warnAnalysisLoophole: "thread analysis incomplete due to unkown call '$1' [AnalysisLoophole]",
|
warnAnalysisLoophole: "thread analysis incomplete due to unkown call '$1' [AnalysisLoophole]",
|
||||||
warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
|
warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
|
||||||
warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
|
warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
|
||||||
warnImplicitNarrowing: "implicit narrowing conversion: '$1' [ImplicitNarrowing]",
|
warnImplicitClosure: "implicit closure convention: '$1' [ImplicitClosure]",
|
||||||
warnUser: "$1 [User]",
|
warnUser: "$1 [User]",
|
||||||
hintSuccess: "operation successful [Success]",
|
hintSuccess: "operation successful [Success]",
|
||||||
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]",
|
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]",
|
||||||
|
|
@ -370,7 +370,7 @@ const
|
||||||
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
|
||||||
"CommentXIgnored", "XisPassedToProcVar",
|
"CommentXIgnored", "XisPassedToProcVar",
|
||||||
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap",
|
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap",
|
||||||
"ImplicitNarrowing,", "User"]
|
"ImplicitClosure,", "User"]
|
||||||
|
|
||||||
HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong",
|
HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong",
|
||||||
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
||||||
|
|
|
||||||
|
|
@ -1164,7 +1164,7 @@ proc newCommentStmt(p: var TParser): PNode =
|
||||||
result.info.line = result.info.line - int16(1)
|
result.info.line = result.info.line - int16(1)
|
||||||
|
|
||||||
type
|
type
|
||||||
TDefParser = proc (p: var TParser): PNode
|
TDefParser = proc (p: var TParser): PNode {.nimcall.}
|
||||||
|
|
||||||
proc parseSection(p: var TParser, kind: TNodeKind,
|
proc parseSection(p: var TParser, kind: TNodeKind,
|
||||||
defparser: TDefParser): PNode =
|
defparser: TDefParser): PNode =
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@ type
|
||||||
|
|
||||||
PPassContext* = ref TPassContext
|
PPassContext* = ref TPassContext
|
||||||
TPass* = tuple[
|
TPass* = tuple[
|
||||||
open: proc (module: PSym, filename: string): PPassContext,
|
open: proc (module: PSym, filename: string): PPassContext {.nimcall.},
|
||||||
openCached: proc (module: PSym, filename: string,
|
openCached: proc (module: PSym, filename: string,
|
||||||
rd: PRodReader): PPassContext,
|
rd: PRodReader): PPassContext {.nimcall.},
|
||||||
close: proc (p: PPassContext, n: PNode): PNode,
|
close: proc (p: PPassContext, n: PNode): PNode {.nimcall.},
|
||||||
process: proc (p: PPassContext, topLevelStmt: PNode): PNode]
|
process: proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.}]
|
||||||
|
|
||||||
# a pass is a tuple of procedure vars ``TPass.close`` may produce additional
|
# a pass is a tuple of procedure vars ``TPass.close`` may produce additional
|
||||||
# nodes. These are passed to the other close procedures.
|
# nodes. These are passed to the other close procedures.
|
||||||
|
|
@ -47,8 +47,8 @@ proc processModule*(module: PSym, filename: string, stream: PLLStream,
|
||||||
|
|
||||||
# the semantic checker needs these:
|
# the semantic checker needs these:
|
||||||
var
|
var
|
||||||
gImportModule*: proc (filename: string): PSym
|
gImportModule*: proc (filename: string): PSym {.nimcall.}
|
||||||
gIncludeFile*: proc (filename: string): PNode
|
gIncludeFile*: proc (filename: string): PNode {.nimcall.}
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,9 +66,9 @@ type
|
||||||
converters*: TSymSeq # sequence of converters
|
converters*: TSymSeq # sequence of converters
|
||||||
optionStack*: TLinkedList
|
optionStack*: TLinkedList
|
||||||
libs*: TLinkedList # all libs used by this module
|
libs*: TLinkedList # all libs used by this module
|
||||||
semConstExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
|
semConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # for the pragmas
|
||||||
semExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
|
semExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # for the pragmas
|
||||||
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode # XXX bite the bullet
|
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
|
||||||
includedFiles*: TIntSet # used to detect recursive include files
|
includedFiles*: TIntSet # used to detect recursive include files
|
||||||
filename*: string # the module's filename
|
filename*: string # the module's filename
|
||||||
userPragmas*: TStrTable
|
userPragmas*: TStrTable
|
||||||
|
|
|
||||||
|
|
@ -566,7 +566,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
block addImplicitGeneric:
|
block addImplicitGeneric:
|
||||||
# is this a bindOnce type class already present in the param list?
|
# is this a bindOnce type class already present in the param list?
|
||||||
for i in countup(0, genericParams.len - 1):
|
for i in countup(0, genericParams.len - 1):
|
||||||
if genericParams.sons[i].sym.name == paramTypId:
|
if genericParams.sons[i].sym.name.id == paramTypId.id:
|
||||||
result = genericParams.sons[i].typ
|
result = genericParams.sons[i].typ
|
||||||
break addImplicitGeneric
|
break addImplicitGeneric
|
||||||
|
|
||||||
|
|
@ -808,7 +808,12 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
# dummy symbol for `pragma`:
|
# dummy symbol for `pragma`:
|
||||||
var s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c)
|
var s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c)
|
||||||
s.typ = result
|
s.typ = result
|
||||||
pragma(c, s, n.sons[1], procTypePragmas)
|
if n.sons[1].kind == nkEmpty or n.sons[1].len == 0:
|
||||||
|
if result.callConv == ccDefault:
|
||||||
|
#result.callConv = ccClosure
|
||||||
|
Message(n.info, warnImplicitClosure, renderTree(n))
|
||||||
|
else:
|
||||||
|
pragma(c, s, n.sons[1], procTypePragmas)
|
||||||
closeScope(c.tab)
|
closeScope(c.tab)
|
||||||
of nkEnumTy: result = semEnum(c, n, prev)
|
of nkEnumTy: result = semEnum(c, n, prev)
|
||||||
of nkType: result = n.typ
|
of nkType: result = n.typ
|
||||||
|
|
|
||||||
|
|
@ -457,7 +457,9 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||||
case a.kind
|
case a.kind
|
||||||
of tyPointer: result = isEqual
|
of tyPointer: result = isEqual
|
||||||
of tyNil: result = isSubtype
|
of tyNil: result = isSubtype
|
||||||
of tyPtr, tyProc, tyCString: result = isConvertible
|
of tyProc:
|
||||||
|
if a.callConv != ccClosure: result = isConvertible
|
||||||
|
of tyPtr, tyCString: result = isConvertible
|
||||||
else: nil
|
else: nil
|
||||||
of tyString:
|
of tyString:
|
||||||
case a.kind
|
case a.kind
|
||||||
|
|
|
||||||
|
|
@ -640,14 +640,6 @@ proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
|
||||||
result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and
|
result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and
|
||||||
cnst.len != 0
|
cnst.len != 0
|
||||||
|
|
||||||
proc warnNarrowingConversion(n: PNode) =
|
|
||||||
if n.kind == nkHiddenStdConv:
|
|
||||||
var dest = skipTypes(n.typ, abstractVarRange)
|
|
||||||
var source = skipTypes(n.sons[1].typ, abstractVarRange)
|
|
||||||
if source.kind == tyInt and
|
|
||||||
source.size > dest.size and n.sons[1].kind != nkIntLit:
|
|
||||||
Message(n.info, warnImplicitNarrowing, renderTree(n.sons[1]))
|
|
||||||
|
|
||||||
proc transform(c: PTransf, n: PNode): PTransNode =
|
proc transform(c: PTransf, n: PNode): PTransNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@ proc getProcHeader*(sym: PSym): string
|
||||||
proc base*(t: PType): PType
|
proc base*(t: PType): PType
|
||||||
# ------------------- type iterator: ----------------------------------------
|
# ------------------- type iterator: ----------------------------------------
|
||||||
type
|
type
|
||||||
TTypeIter* = proc (t: PType, closure: PObject): bool # should return true if the iteration should stop
|
TTypeIter* = proc (t: PType, closure: PObject): bool {.nimcall.} # true if iteration should stop
|
||||||
TTypeMutator* = proc (t: PType, closure: PObject): PType # copy t and mutate it
|
TTypeMutator* = proc (t: PType, closure: PObject): PType {.nimcall.} # copy t and mutate it
|
||||||
TTypePredicate* = proc (t: PType): bool
|
TTypePredicate* = proc (t: PType): bool {.nimcall.}
|
||||||
|
|
||||||
proc IterOverType*(t: PType, iter: TTypeIter, closure: PObject): bool
|
proc IterOverType*(t: PType, iter: TTypeIter, closure: PObject): bool
|
||||||
# Returns result of `iter`.
|
# Returns result of `iter`.
|
||||||
|
|
|
||||||
|
|
@ -1177,6 +1177,17 @@ that expects a proc of the calling convention ``closure``.
|
||||||
|
|
||||||
Nimrod supports these `calling conventions`:idx:\:
|
Nimrod supports these `calling conventions`:idx:\:
|
||||||
|
|
||||||
|
`nimcall`:idx:
|
||||||
|
is the default convention used for a Nimrod **proc**. It is the
|
||||||
|
same as ``fastcall``, but only for C compilers that support ``fastcall``.
|
||||||
|
|
||||||
|
`closure`:idx:
|
||||||
|
is the default calling convention for a **procedural type** that lacks
|
||||||
|
any pragma annotations. It indicates that the procedure has a hidden
|
||||||
|
implicit parameter (an *environment*). Proc vars that have the calling
|
||||||
|
convention ``closure`` take up two machine words: One for the proc pointer
|
||||||
|
and another one for the pointer to implicitely passed environment.
|
||||||
|
|
||||||
`stdcall`:idx:
|
`stdcall`:idx:
|
||||||
This the stdcall convention as specified by Microsoft. The generated C
|
This the stdcall convention as specified by Microsoft. The generated C
|
||||||
procedure is declared with the ``__stdcall`` keyword.
|
procedure is declared with the ``__stdcall`` keyword.
|
||||||
|
|
@ -1203,16 +1214,6 @@ Nimrod supports these `calling conventions`:idx:\:
|
||||||
Fastcall means different things to different C compilers. One gets whatever
|
Fastcall means different things to different C compilers. One gets whatever
|
||||||
the C ``__fastcall`` means.
|
the C ``__fastcall`` means.
|
||||||
|
|
||||||
`nimcall`:idx:
|
|
||||||
Nimcall is the default convention used for Nimrod procedures. It is the
|
|
||||||
same as ``fastcall``, but only for C compilers that support ``fastcall``.
|
|
||||||
|
|
||||||
`closure`:idx:
|
|
||||||
indicates that the procedure has a hidden implicit parameter
|
|
||||||
(an *environment*). Proc vars that have the calling convention ``closure``
|
|
||||||
take up two machine words: One for the proc pointer and another one for
|
|
||||||
the pointer to implicitely passed environment.
|
|
||||||
|
|
||||||
`syscall`:idx:
|
`syscall`:idx:
|
||||||
The syscall convention is the same as ``__syscall`` in C. It is used for
|
The syscall convention is the same as ``__syscall`` in C. It is used for
|
||||||
interrupts.
|
interrupts.
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ const
|
||||||
onlySafeCode = true
|
onlySafeCode = true
|
||||||
|
|
||||||
proc merge[T](a, b: var openArray[T], lo, m, hi: int,
|
proc merge[T](a, b: var openArray[T], lo, m, hi: int,
|
||||||
cmp: proc (x, y: T): int, order: TSortOrder) =
|
cmp: proc (x, y: T): int {.closure.}, order: TSortOrder) =
|
||||||
template `<-` (a, b: expr) =
|
template `<-` (a, b: expr) =
|
||||||
when false:
|
when false:
|
||||||
a = b
|
a = b
|
||||||
|
|
@ -102,7 +102,7 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int,
|
||||||
if k < j: copyMem(addr(a[k]), addr(b[i]), sizeof(T)*(j-k))
|
if k < j: copyMem(addr(a[k]), addr(b[i]), sizeof(T)*(j-k))
|
||||||
|
|
||||||
proc sort*[T](a: var openArray[T],
|
proc sort*[T](a: var openArray[T],
|
||||||
cmp: proc (x, y: T): int,
|
cmp: proc (x, y: T): int {.closure.},
|
||||||
order = TSortOrder.Ascending) =
|
order = TSortOrder.Ascending) =
|
||||||
## Default Nimrod sort. The sorting is guaranteed to be stable and
|
## Default Nimrod sort. The sorting is guaranteed to be stable and
|
||||||
## the worst case is guaranteed to be O(n log n).
|
## the worst case is guaranteed to be O(n log n).
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,14 @@ type
|
||||||
TDelegate = object
|
TDelegate = object
|
||||||
deleVal*: PObject
|
deleVal*: PObject
|
||||||
|
|
||||||
handleRead*: proc (h: PObject)
|
handleRead*: proc (h: PObject) {.nimcall.}
|
||||||
handleWrite*: proc (h: PObject)
|
handleWrite*: proc (h: PObject) {.nimcall.}
|
||||||
handleConnect*: proc (h: PObject)
|
handleConnect*: proc (h: PObject) {.nimcall.}
|
||||||
|
|
||||||
handleAccept*: proc (h: PObject)
|
handleAccept*: proc (h: PObject) {.nimcall.}
|
||||||
getSocket*: proc (h: PObject): tuple[info: TInfo, sock: TSocket]
|
getSocket*: proc (h: PObject): tuple[info: TInfo, sock: TSocket] {.nimcall.}
|
||||||
|
|
||||||
task*: proc (h: PObject)
|
task*: proc (h: PObject) {.nimcall.}
|
||||||
mode*: TMode
|
mode*: TMode
|
||||||
|
|
||||||
PDelegate* = ref TDelegate
|
PDelegate* = ref TDelegate
|
||||||
|
|
@ -56,10 +56,10 @@ type
|
||||||
|
|
||||||
userArg: PObject
|
userArg: PObject
|
||||||
|
|
||||||
handleRead*: proc (s: PAsyncSocket, arg: PObject)
|
handleRead*: proc (s: PAsyncSocket, arg: PObject) {.nimcall.}
|
||||||
handleConnect*: proc (s: PAsyncSocket, arg: PObject)
|
handleConnect*: proc (s: PAsyncSocket, arg: PObject) {.nimcall.}
|
||||||
|
|
||||||
handleAccept*: proc (s: PAsyncSocket, arg: PObject)
|
handleAccept*: proc (s: PAsyncSocket, arg: PObject) {.nimcall.}
|
||||||
|
|
||||||
lineBuffer: TaintedString ## Temporary storage for ``recvLine``
|
lineBuffer: TaintedString ## Temporary storage for ``recvLine``
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,14 @@ proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] =
|
||||||
newSeq(result, m)
|
newSeq(result, m)
|
||||||
for i in 0 .. m-1: result[i] = (seq1[i], seq2[i])
|
for i in 0 .. m-1: result[i] = (seq1[i], seq2[i])
|
||||||
|
|
||||||
iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool): T =
|
iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T =
|
||||||
## Iterates through a sequence and yields every item that fulfills the
|
## Iterates through a sequence and yields every item that fulfills the
|
||||||
## predicate.
|
## predicate.
|
||||||
for i in countup(0, len(seq1) -1):
|
for i in countup(0, len(seq1) -1):
|
||||||
var item = seq1[i]
|
var item = seq1[i]
|
||||||
if pred(item): yield seq1[i]
|
if pred(item): yield seq1[i]
|
||||||
|
|
||||||
proc filter*[T](seq1: seq[T], pred: proc(item: T): bool): seq[T] =
|
proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T] =
|
||||||
## Returns all items in a sequence that fulfilled the predicate.
|
## Returns all items in a sequence that fulfilled the predicate.
|
||||||
accumulateResult(filter(seq1, pred))
|
accumulateResult(filter(seq1, pred))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
##
|
##
|
||||||
## This module implements an event system that is not dependant on external
|
## This module implements an event system that is not dependant on external
|
||||||
## graphical toolkits. It was originally called ``NimEE`` because
|
## graphical toolkits. It was originally called ``NimEE`` because
|
||||||
## it was inspired by Python's PyEE module. There are two ways you can use events: one is a python-inspired way; the other is more of a C-style way.
|
## it was inspired by Python's PyEE module. There are two ways you can use
|
||||||
|
## events: one is a python-inspired way; the other is more of a C-style way.
|
||||||
##
|
##
|
||||||
## .. code-block:: Nimrod
|
## .. code-block:: Nimrod
|
||||||
## var ee = initEventEmitter()
|
## var ee = initEventEmitter()
|
||||||
|
|
@ -44,22 +45,21 @@ type
|
||||||
|
|
||||||
proc initEventHandler*(name: string): TEventHandler =
|
proc initEventHandler*(name: string): TEventHandler =
|
||||||
## Initializes an EventHandler with the specified name and returns it.
|
## Initializes an EventHandler with the specified name and returns it.
|
||||||
#new(result)
|
|
||||||
result.handlers = @[]
|
result.handlers = @[]
|
||||||
result.name = name
|
result.name = name
|
||||||
|
|
||||||
proc addHandler*(handler: var TEventHandler, func: proc(e: TEventArgs)) =
|
proc addHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}) =
|
||||||
## Adds the callback to the specified event handler.
|
## Adds the callback to the specified event handler.
|
||||||
handler.handlers.add(func)
|
handler.handlers.add(func)
|
||||||
|
|
||||||
proc removeHandler*(handler: var TEventHandler, func: proc(e: TEventArgs)) =
|
proc removeHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}) =
|
||||||
## Removes the callback from the specified event handler.
|
## Removes the callback from the specified event handler.
|
||||||
for i in countup(0, len(handler.handlers) -1):
|
for i in countup(0, len(handler.handlers) -1):
|
||||||
if func == handler.handlers[i]:
|
if func == handler.handlers[i]:
|
||||||
handler.handlers.del(i)
|
handler.handlers.del(i)
|
||||||
break
|
break
|
||||||
|
|
||||||
proc containsHandler*(handler: var TEventHandler, func: proc(e: TEventArgs)): bool =
|
proc containsHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}): bool =
|
||||||
## Checks if a callback is registered to this event handler.
|
## Checks if a callback is registered to this event handler.
|
||||||
return handler.handlers.contains(func)
|
return handler.handlers.contains(func)
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ proc getEventhandler(emitter: var TEventEmitter, event: string): int =
|
||||||
if emitter.s[k].name == event: return k
|
if emitter.s[k].name == event: return k
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
|
proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs) {.closure.}) =
|
||||||
## Assigns a event handler with the specified callback. If the event
|
## Assigns a event handler with the specified callback. If the event
|
||||||
## doesn't exist, it will be created.
|
## doesn't exist, it will be created.
|
||||||
var i = getEventHandler(emitter, event)
|
var i = getEventHandler(emitter, event)
|
||||||
|
|
@ -99,5 +99,4 @@ proc emit*(emitter: var TEventEmitter, event: string, args: TEventArgs) =
|
||||||
|
|
||||||
proc initEventEmitter*(): TEventEmitter =
|
proc initEventEmitter*(): TEventEmitter =
|
||||||
## Creates and returns a new EventEmitter.
|
## Creates and returns a new EventEmitter.
|
||||||
#new(result)
|
|
||||||
result.s = @[]
|
result.s = @[]
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,8 @@ proc close*(s: TServer) =
|
||||||
## closes the server (and the socket the server uses).
|
## closes the server (and the socket the server uses).
|
||||||
close(s.socket)
|
close(s.socket)
|
||||||
|
|
||||||
proc run*(handleRequest: proc (client: TSocket, path, query: string): bool,
|
proc run*(handleRequest: proc (client: TSocket,
|
||||||
|
path, query: string): bool {.closure.},
|
||||||
port = TPort(80)) =
|
port = TPort(80)) =
|
||||||
## encapsulates the server object and main loop
|
## encapsulates the server object and main loop
|
||||||
var s: TServer
|
var s: TServer
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,14 @@ type
|
||||||
## here shouldn't be used directly. They are
|
## here shouldn't be used directly. They are
|
||||||
## accessible so that a stream implementation
|
## accessible so that a stream implementation
|
||||||
## can override them.
|
## can override them.
|
||||||
closeImpl*: proc (s: PStream)
|
closeImpl*: proc (s: PStream) {.nimcall.}
|
||||||
atEndImpl*: proc (s: PStream): bool
|
atEndImpl*: proc (s: PStream): bool {.nimcall.}
|
||||||
setPositionImpl*: proc (s: PStream, pos: int)
|
setPositionImpl*: proc (s: PStream, pos: int) {.nimcall.}
|
||||||
getPositionImpl*: proc (s: PStream): int
|
getPositionImpl*: proc (s: PStream): int {.nimcall.}
|
||||||
readDataImpl*: proc (s: PStream, buffer: pointer, bufLen: int): int
|
readDataImpl*: proc (s: PStream, buffer: pointer,
|
||||||
writeDataImpl*: proc (s: PStream, buffer: pointer, bufLen: int)
|
bufLen: int): int {.nimcall.}
|
||||||
flushImpl*: proc (s: PStream)
|
writeDataImpl*: proc (s: PStream, buffer: pointer, bufLen: int) {.nimcall.}
|
||||||
|
flushImpl*: proc (s: PStream) {.nimcall.}
|
||||||
|
|
||||||
proc flush*(s: PStream) =
|
proc flush*(s: PStream) =
|
||||||
## flushes the buffers that the stream `s` might use.
|
## flushes the buffers that the stream `s` might use.
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ proc new*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
||||||
proc internalNew*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
proc internalNew*[T](a: var ref T) {.magic: "New", noSideEffect.}
|
||||||
## leaked implementation detail. Do not use.
|
## leaked implementation detail. Do not use.
|
||||||
|
|
||||||
proc new*[T](a: var ref T, finalizer: proc (x: ref T)) {.
|
proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
|
||||||
magic: "NewFinalize", noSideEffect.}
|
magic: "NewFinalize", noSideEffect.}
|
||||||
## creates a new object of type ``T`` and returns a safe (traced)
|
## creates a new object of type ``T`` and returns a safe (traced)
|
||||||
## reference to it in ``a``. When the garbage collector frees the object,
|
## reference to it in ``a``. When the garbage collector frees the object,
|
||||||
|
|
@ -1416,13 +1416,13 @@ proc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =
|
||||||
result = s[L]
|
result = s[L]
|
||||||
setLen(s, L)
|
setLen(s, L)
|
||||||
|
|
||||||
proc each*[T, S](data: openArray[T], op: proc (x: T): S): seq[S] =
|
proc each*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] =
|
||||||
## The well-known ``map`` operation from functional programming. Applies
|
## The well-known ``map`` operation from functional programming. Applies
|
||||||
## `op` to every item in `data` and returns the result as a sequence.
|
## `op` to every item in `data` and returns the result as a sequence.
|
||||||
newSeq(result, data.len)
|
newSeq(result, data.len)
|
||||||
for i in 0..data.len-1: result[i] = op(data[i])
|
for i in 0..data.len-1: result[i] = op(data[i])
|
||||||
|
|
||||||
proc each*[T](data: var openArray[T], op: proc (x: var T)) =
|
proc each*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) =
|
||||||
## The well-known ``map`` operation from functional programming. Applies
|
## The well-known ``map`` operation from functional programming. Applies
|
||||||
## `op` to every item in `data`.
|
## `op` to every item in `data`.
|
||||||
for i in 0..data.len-1: op(data[i])
|
for i in 0..data.len-1: op(data[i])
|
||||||
|
|
@ -1567,11 +1567,11 @@ const nimrodStackTrace = compileOption("stacktrace")
|
||||||
# of the code
|
# of the code
|
||||||
|
|
||||||
var
|
var
|
||||||
dbgLineHook*: proc ()
|
dbgLineHook*: proc () {.nimcall.}
|
||||||
## set this variable to provide a procedure that should be called before
|
## set this variable to provide a procedure that should be called before
|
||||||
## each executed instruction. This should only be used by debuggers!
|
## each executed instruction. This should only be used by debuggers!
|
||||||
## Only code compiled with the ``debugger:on`` switch calls this hook.
|
## Only code compiled with the ``debugger:on`` switch calls this hook.
|
||||||
globalRaiseHook*: proc (e: ref E_Base): bool
|
globalRaiseHook*: proc (e: ref E_Base): bool {.nimcall.}
|
||||||
## with this hook you can influence exception handling on a global level.
|
## with this hook you can influence exception handling on a global level.
|
||||||
## If not nil, every 'raise' statement ends up calling this hook. Ordinary
|
## If not nil, every 'raise' statement ends up calling this hook. Ordinary
|
||||||
## application code should never set this hook! You better know what you
|
## application code should never set this hook! You better know what you
|
||||||
|
|
@ -1579,7 +1579,7 @@ var
|
||||||
## exception is caught and does not propagate further through the call
|
## exception is caught and does not propagate further through the call
|
||||||
## stack.
|
## stack.
|
||||||
|
|
||||||
localRaiseHook* {.threadvar.}: proc (e: ref E_Base): bool
|
localRaiseHook* {.threadvar.}: proc (e: ref E_Base): bool {.nimcall.}
|
||||||
## with this hook you can influence exception handling on a
|
## with this hook you can influence exception handling on a
|
||||||
## thread local level.
|
## thread local level.
|
||||||
## If not nil, every 'raise' statement ends up calling this hook. Ordinary
|
## If not nil, every 'raise' statement ends up calling this hook. Ordinary
|
||||||
|
|
@ -1587,7 +1587,7 @@ var
|
||||||
## do when setting this. If ``localRaiseHook`` returns false, the exception
|
## do when setting this. If ``localRaiseHook`` returns false, the exception
|
||||||
## is caught and does not propagate further through the call stack.
|
## is caught and does not propagate further through the call stack.
|
||||||
|
|
||||||
outOfMemHook*: proc ()
|
outOfMemHook*: proc () {.nimcall.}
|
||||||
## set this variable to provide a procedure that should be called
|
## set this variable to provide a procedure that should be called
|
||||||
## in case of an `out of memory`:idx: event. The standard handler
|
## in case of an `out of memory`:idx: event. The standard handler
|
||||||
## writes an error message and terminates the program. `outOfMemHook` can
|
## writes an error message and terminates the program. `outOfMemHook` can
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ type
|
||||||
TWalkOp = enum
|
TWalkOp = enum
|
||||||
waZctDecRef, waPush, waCycleDecRef
|
waZctDecRef, waPush, waCycleDecRef
|
||||||
|
|
||||||
TFinalizer {.compilerproc.} = proc (self: pointer)
|
TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall.}
|
||||||
# A ref type can have a finalizer that is called before the object's
|
# A ref type can have a finalizer that is called before the object's
|
||||||
# storage is freed.
|
# storage is freed.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ type # This should be he same as ast.TTypeKind
|
||||||
base: ptr TNimType
|
base: ptr TNimType
|
||||||
node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
|
node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
|
||||||
finalizer: pointer # the finalizer for the type
|
finalizer: pointer # the finalizer for the type
|
||||||
marker: proc (p: pointer, op: int) # marker proc for GC
|
marker: proc (p: pointer, op: int) {.nimcall.} # marker proc for GC
|
||||||
PNimType = ptr TNimType
|
PNimType = ptr TNimType
|
||||||
|
|
||||||
# node.len may be the ``first`` element of a set
|
# node.len may be the ``first`` element of a set
|
||||||
|
|
|
||||||
|
|
@ -255,9 +255,9 @@ type
|
||||||
## that **must not** be part of a message! Use
|
## that **must not** be part of a message! Use
|
||||||
## a ``TThreadId`` for that.
|
## a ``TThreadId`` for that.
|
||||||
when TArg is void:
|
when TArg is void:
|
||||||
dataFn: proc ()
|
dataFn: proc () {.nimcall.}
|
||||||
else:
|
else:
|
||||||
dataFn: proc (m: TArg)
|
dataFn: proc (m: TArg) {.nimcall.}
|
||||||
data: TArg
|
data: TArg
|
||||||
TThreadId*[TArg] = ptr TThread[TArg] ## the current implementation uses
|
TThreadId*[TArg] = ptr TThread[TArg] ## the current implementation uses
|
||||||
## a pointer as a thread ID.
|
## a pointer as a thread ID.
|
||||||
|
|
|
||||||
|
|
@ -419,7 +419,7 @@ type
|
||||||
pad32*: TFunction
|
pad32*: TFunction
|
||||||
|
|
||||||
TEventListener* = proc (para1: PObject){.cdecl.}
|
TEventListener* = proc (para1: PObject){.cdecl.}
|
||||||
TEventListenerInitProc* = proc ()
|
TEventListenerInitProc* = proc (){.cdecl.}
|
||||||
TEventListenerInit* = proc (para1: TEventListenerInitProc){.cdecl.}
|
TEventListenerInit* = proc (para1: TEventListenerInitProc){.cdecl.}
|
||||||
PKeyEventStruct* = ptr TKeyEventStruct
|
PKeyEventStruct* = ptr TKeyEventStruct
|
||||||
TKeyEventStruct*{.final, pure.} = object
|
TKeyEventStruct*{.final, pure.} = object
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ type
|
||||||
PEvent* = ptr TEvent
|
PEvent* = ptr TEvent
|
||||||
TEventFunc* = proc (event: PEvent, data: gpointer){.cdecl.}
|
TEventFunc* = proc (event: PEvent, data: gpointer){.cdecl.}
|
||||||
PXEvent* = ptr TXEvent
|
PXEvent* = ptr TXEvent
|
||||||
TXEvent* = proc ()
|
TXEvent* = proc () {.cdecl.}
|
||||||
PFilterReturn* = ptr TFilterReturn
|
PFilterReturn* = ptr TFilterReturn
|
||||||
TFilterReturn* = enum
|
TFilterReturn* = enum
|
||||||
FILTER_CONTINUE, FILTER_TRANSLATE, FILTER_REMOVE
|
FILTER_CONTINUE, FILTER_TRANSLATE, FILTER_REMOVE
|
||||||
|
|
@ -775,7 +775,7 @@ type
|
||||||
PWindowObjectClass* = ptr TWindowObjectClass
|
PWindowObjectClass* = ptr TWindowObjectClass
|
||||||
TWindowObjectClass* = object of TDrawableClass
|
TWindowObjectClass* = object of TDrawableClass
|
||||||
window_invalidate_maybe_recurse_child_func* = proc (para1: PWindow,
|
window_invalidate_maybe_recurse_child_func* = proc (para1: PWindow,
|
||||||
para2: gpointer): gboolean
|
para2: gpointer): gboolean {.cdecl.}
|
||||||
|
|
||||||
proc TYPE_COLORMAP*(): GType
|
proc TYPE_COLORMAP*(): GType
|
||||||
proc COLORMAP*(anObject: pointer): PColormap
|
proc COLORMAP*(anObject: pointer): PColormap
|
||||||
|
|
|
||||||
|
|
@ -2676,7 +2676,7 @@ when false:
|
||||||
proc g_critical*(format: cstring){.varargs.}
|
proc g_critical*(format: cstring){.varargs.}
|
||||||
proc g_warning*(format: cstring){.varargs.}
|
proc g_warning*(format: cstring){.varargs.}
|
||||||
type
|
type
|
||||||
TGPrintFunc* = proc (str: cstring)
|
TGPrintFunc* = proc (str: cstring){.cdecl, varargs.}
|
||||||
|
|
||||||
proc g_set_print_handler*(func: TGPrintFunc): TGPrintFunc{.cdecl,
|
proc g_set_print_handler*(func: TGPrintFunc): TGPrintFunc{.cdecl,
|
||||||
dynlib: gliblib, importc: "g_set_print_handler".}
|
dynlib: gliblib, importc: "g_set_print_handler".}
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ type
|
||||||
Tfree_callback* = proc (p: pointer){.cdecl.}
|
Tfree_callback* = proc (p: pointer){.cdecl.}
|
||||||
Trealloc_callback* = proc (p: pointer, size: int): pointer{.cdecl.}
|
Trealloc_callback* = proc (p: pointer, size: int): pointer{.cdecl.}
|
||||||
Tstrdup_callback* = proc (str: cstring): cstring{.cdecl.}
|
Tstrdup_callback* = proc (str: cstring): cstring{.cdecl.}
|
||||||
Tcalloc_callback* = proc (nmemb: int, size: int): pointer
|
Tcalloc_callback* = proc (nmemb: int, size: int): pointer{.noconv.}
|
||||||
Tinfotype* = enum
|
Tinfotype* = enum
|
||||||
INFO_TEXT = 0, INFO_HEADER_IN, INFO_HEADER_OUT, INFO_DATA_IN, INFO_DATA_OUT,
|
INFO_TEXT = 0, INFO_HEADER_IN, INFO_HEADER_OUT, INFO_DATA_IN, INFO_DATA_OUT,
|
||||||
INFO_SSL_DATA_IN, INFO_SSL_DATA_OUT, INFO_END
|
INFO_SSL_DATA_IN, INFO_SSL_DATA_OUT, INFO_END
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.}
|
||||||
|
{.push, callconv: cdecl.}
|
||||||
|
|
||||||
when defined(Unix):
|
when defined(Unix):
|
||||||
const
|
const
|
||||||
lib = "libmysqlclient.so.15"
|
lib = "libmysqlclient.so.15"
|
||||||
|
|
@ -1071,3 +1073,5 @@ proc INTERNAL_NUM_FIELD(f: Pst_mysql_field): bool =
|
||||||
|
|
||||||
proc reload(mysql: PMySQL): cint =
|
proc reload(mysql: PMySQL): cint =
|
||||||
result = refresh(mysql, REFRESH_GRANT)
|
result = refresh(mysql, REFRESH_GRANT)
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@
|
||||||
import
|
import
|
||||||
GL
|
GL
|
||||||
|
|
||||||
|
when defined(windows):
|
||||||
|
{.push, callconv: stdcall.}
|
||||||
|
else:
|
||||||
|
{.push, callconv: cdecl.}
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
const
|
const
|
||||||
dllname = "glu32.dll"
|
dllname = "glu32.dll"
|
||||||
|
|
@ -326,4 +331,5 @@ const # Contours types -- obsolete!
|
||||||
GLU_ERROR* = GLU_TESS_ERROR
|
GLU_ERROR* = GLU_TESS_ERROR
|
||||||
GLU_EDGE_FLAG* = GLU_TESS_EDGE_FLAG
|
GLU_EDGE_FLAG* = GLU_TESS_EDGE_FLAG
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
# implementation
|
# implementation
|
||||||
|
|
|
||||||
|
|
@ -1156,7 +1156,7 @@ proc PyWeakref_NewProxy*(ob, callback: PPyObject): PPyObject{.cdecl, importc, dy
|
||||||
proc PyWeakref_NewRef*(ob, callback: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
|
proc PyWeakref_NewRef*(ob, callback: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
|
||||||
proc PyWrapper_New*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
|
proc PyWrapper_New*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
|
||||||
proc PyBool_FromLong*(ok: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
|
proc PyBool_FromLong*(ok: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
|
||||||
proc Py_AtExit*(prc: proc ()): int{.cdecl, importc, dynlib: dllname.} #-
|
proc Py_AtExit*(prc: proc () {.cdecl.}): int{.cdecl, importc, dynlib: dllname.} #-
|
||||||
#Py_Cleanup:procedure; cdecl, importc, dynlib: dllname;
|
#Py_Cleanup:procedure; cdecl, importc, dynlib: dllname;
|
||||||
#-
|
#-
|
||||||
proc Py_CompileString*(s1, s2: cstring, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
|
proc Py_CompileString*(s1, s2: cstring, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
|
||||||
|
|
|
||||||
|
|
@ -1279,7 +1279,6 @@ type # This is the system-independent thread info struc
|
||||||
TByteArray* = array[0..32767, int8]
|
TByteArray* = array[0..32767, int8]
|
||||||
PWordArray* = ptr TWordArray
|
PWordArray* = ptr TWordArray
|
||||||
TWordArray* = array[0..16383, int16] # Generic procedure pointer
|
TWordArray* = array[0..16383, int16] # Generic procedure pointer
|
||||||
TProcedure* = proc ()
|
|
||||||
|
|
||||||
type TEventSeq = set[TEventKind]
|
type TEventSeq = set[TEventKind]
|
||||||
template evconv(procName: expr, ptrName: typeDesc, assertions: TEventSeq): stmt {.immediate.} =
|
template evconv(procName: expr, ptrName: typeDesc, assertions: TEventSeq): stmt {.immediate.} =
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ const
|
||||||
XrmEnumOneLevel* = 1
|
XrmEnumOneLevel* = 1
|
||||||
|
|
||||||
type
|
type
|
||||||
funcbool* = proc (): TBool
|
funcbool* = proc (): TBool {.cdecl.}
|
||||||
|
|
||||||
proc XrmEnumerateDatabase*(para1: TXrmDatabase, para2: TXrmNameList,
|
proc XrmEnumerateDatabase*(para1: TXrmDatabase, para2: TXrmNameList,
|
||||||
para3: TXrmClassList, para4: int32, para5: funcbool,
|
para3: TXrmClassList, para4: int32, para5: funcbool,
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ type
|
||||||
mwUnsupportedLanguage
|
mwUnsupportedLanguage
|
||||||
|
|
||||||
TMsgHandler* = proc (filename: string, line, col: int, msgKind: TMsgKind,
|
TMsgHandler* = proc (filename: string, line, col: int, msgKind: TMsgKind,
|
||||||
arg: string) ## what to do in case of an error
|
arg: string) {.nimcall.} ## what to do in case of an error
|
||||||
TFindFileHandler* = proc (filename: string): string
|
TFindFileHandler* = proc (filename: string): string {.nimcall.}
|
||||||
|
|
||||||
const
|
const
|
||||||
messages: array [TMsgKind, string] = [
|
messages: array [TMsgKind, string] = [
|
||||||
|
|
@ -1356,7 +1356,7 @@ type
|
||||||
TDirFlag = enum
|
TDirFlag = enum
|
||||||
hasArg, hasOptions, argIsFile, argIsWord
|
hasArg, hasOptions, argIsFile, argIsWord
|
||||||
TDirFlags = set[TDirFlag]
|
TDirFlags = set[TDirFlag]
|
||||||
TSectionParser = proc (p: var TRstParser): PRstNode
|
TSectionParser = proc (p: var TRstParser): PRstNode {.nimcall.}
|
||||||
|
|
||||||
proc parseDirective(p: var TRstParser, flags: TDirFlags): PRstNode =
|
proc parseDirective(p: var TRstParser, flags: TDirFlags): PRstNode =
|
||||||
result = newRstNode(rnDirective)
|
result = newRstNode(rnDirective)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ import
|
||||||
osproc,
|
osproc,
|
||||||
cairowin32, cairoxlib,
|
cairowin32, cairoxlib,
|
||||||
gl, glut, glu, glx, glext, wingl,
|
gl, glut, glu, glx, glext, wingl,
|
||||||
lua, lualib, lauxlib, mysql, sqlite3, db_mongo, md5
|
lua, lualib, lauxlib, mysql, sqlite3, db_mongo, md5, asyncio, mimetypes,
|
||||||
|
cookies, events, ftpclient
|
||||||
|
|
||||||
|
|
||||||
writeln(stdout, "test compilation of binding modules")
|
writeln(stdout, "test compilation of binding modules")
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ discard """
|
||||||
proc main =
|
proc main =
|
||||||
const n = 30
|
const n = 30
|
||||||
for iterations in 0..50_000:
|
for iterations in 0..50_000:
|
||||||
var s: seq[proc(): int {.closure.}] = @[]
|
var s: seq[proc(): string {.closure.}] = @[]
|
||||||
for i in 0 .. n-1:
|
for i in 0 .. n-1:
|
||||||
let ii = i
|
let ii = i
|
||||||
s.add(proc(): int = return ii*ii)
|
s.add(proc(): string = return $(ii*ii))
|
||||||
for i in 0 .. n-1:
|
for i in 0 .. n-1:
|
||||||
let val = s[i]()
|
let val = s[i]()
|
||||||
if val != i*i: echo "bug ", val
|
if val != $(i*i): echo "bug ", val
|
||||||
|
|
||||||
if getOccupiedMem() > 3000_000: quit("still a leak!")
|
if getOccupiedMem() > 3000_000: quit("still a leak!")
|
||||||
echo "success"
|
echo "success"
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,22 @@ import tables, lists
|
||||||
type
|
type
|
||||||
TEventArgs = object of TObject
|
TEventArgs = object of TObject
|
||||||
TEventEmitter = object of TObject
|
TEventEmitter = object of TObject
|
||||||
events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]
|
events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}]]
|
||||||
|
|
||||||
proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) =
|
proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) =
|
||||||
for func in nodes(emitter.events[event]):
|
for func in nodes(emitter.events[event]):
|
||||||
func.value(args) #call function with args.
|
func.value(args) #call function with args.
|
||||||
|
|
||||||
proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) =
|
proc on*(emitter: var TEventEmitter, event: string,
|
||||||
|
func: proc(e: TEventArgs) {.nimcall.}) =
|
||||||
if not hasKey(emitter.events, event):
|
if not hasKey(emitter.events, event):
|
||||||
var list: TDoublyLinkedList[proc(e: TEventArgs)]
|
var list: TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}]
|
||||||
add(emitter.events, event, list) #if not, add it.
|
add(emitter.events, event, list) #if not, add it.
|
||||||
append(emitter.events.mget(event), func)
|
append(emitter.events.mget(event), func)
|
||||||
|
|
||||||
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) {.nimcall.}]]()
|
||||||
|
|
||||||
var
|
var
|
||||||
ee: TEventEmitter
|
ee: TEventEmitter
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -16,8 +16,9 @@ New pragmas:
|
||||||
- fix remaining closure bugs:
|
- fix remaining closure bugs:
|
||||||
- make toplevel but in a scope vars local; make procs there inner procs
|
- make toplevel but in a scope vars local; make procs there inner procs
|
||||||
- fix evals.nim with closures
|
- fix evals.nim with closures
|
||||||
- proc types shall have closure calling convention per default
|
|
||||||
- implement "closure tuple consists of a single 'ref'" optimization
|
- implement "closure tuple consists of a single 'ref'" optimization
|
||||||
|
- make closure default calling convention for proc types
|
||||||
|
- fix '==' for closures
|
||||||
|
|
||||||
- document 'do' notation
|
- document 'do' notation
|
||||||
- rethink the syntax: distinction between expr and stmt is unfortunate;
|
- rethink the syntax: distinction between expr and stmt is unfortunate;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue