preparations for making 'closure' the default calling convention for proc types

This commit is contained in:
Araq 2012-07-16 23:00:57 +02:00
commit 8d99753d63
36 changed files with 117 additions and 102 deletions

View file

@ -35,9 +35,10 @@ proc ObjectSetContainsOrIncl*(t: var TObjectSet, obj: PObject): bool
proc TablePut*(t: var TTable, key, val: PObject)
proc TableGet*(t: TTable, key: PObject): PObject
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,
# nil is returned

View file

@ -22,7 +22,7 @@ type
head*, tail*: PListEntry
Counter*: int
TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool
TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool {.nimcall.}
proc InitLinkedList*(list: var TLinkedList) =
list.Counter = 0

View file

@ -102,7 +102,7 @@ type
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored,
warnXisPassedToProcVar, warnAnalysisLoophole,
warnDifferentHeaps, warnWriteToForeignHeap, warnImplicitNarrowing,
warnDifferentHeaps, warnWriteToForeignHeap, warnImplicitClosure,
warnUser,
hintSuccess, hintSuccessX,
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
@ -345,7 +345,7 @@ const
warnAnalysisLoophole: "thread analysis incomplete due to unkown call '$1' [AnalysisLoophole]",
warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
warnImplicitNarrowing: "implicit narrowing conversion: '$1' [ImplicitNarrowing]",
warnImplicitClosure: "implicit closure convention: '$1' [ImplicitClosure]",
warnUser: "$1 [User]",
hintSuccess: "operation successful [Success]",
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]",
@ -370,7 +370,7 @@ const
"RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported",
"CommentXIgnored", "XisPassedToProcVar",
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap",
"ImplicitNarrowing,", "User"]
"ImplicitClosure,", "User"]
HintsToStr*: array[0..13, string] = ["Success", "SuccessX", "LineTooLong",
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",

View file

@ -1164,7 +1164,7 @@ proc newCommentStmt(p: var TParser): PNode =
result.info.line = result.info.line - int16(1)
type
TDefParser = proc (p: var TParser): PNode
TDefParser = proc (p: var TParser): PNode {.nimcall.}
proc parseSection(p: var TParser, kind: TNodeKind,
defparser: TDefParser): PNode =

View file

@ -26,11 +26,11 @@ type
PPassContext* = ref TPassContext
TPass* = tuple[
open: proc (module: PSym, filename: string): PPassContext,
open: proc (module: PSym, filename: string): PPassContext {.nimcall.},
openCached: proc (module: PSym, filename: string,
rd: PRodReader): PPassContext,
close: proc (p: PPassContext, n: PNode): PNode,
process: proc (p: PPassContext, topLevelStmt: PNode): PNode]
rd: PRodReader): PPassContext {.nimcall.},
close: proc (p: PPassContext, n: PNode): PNode {.nimcall.},
process: proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.}]
# a pass is a tuple of procedure vars ``TPass.close`` may produce additional
# 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:
var
gImportModule*: proc (filename: string): PSym
gIncludeFile*: proc (filename: string): PNode
gImportModule*: proc (filename: string): PSym {.nimcall.}
gIncludeFile*: proc (filename: string): PNode {.nimcall.}
# implementation

View file

@ -66,9 +66,9 @@ type
converters*: TSymSeq # sequence of converters
optionStack*: TLinkedList
libs*: TLinkedList # all libs used by this module
semConstExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
semExpr*: proc (c: PContext, n: PNode): PNode # for the pragmas
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode # XXX bite the bullet
semConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # for the pragmas
semExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # for the pragmas
semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
includedFiles*: TIntSet # used to detect recursive include files
filename*: string # the module's filename
userPragmas*: TStrTable

View file

@ -616,7 +616,7 @@ proc SemTypeSection(c: PContext, n: PNode): PNode =
typeSectionFinalPass(c, n)
result = n
proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) =
proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) =
s.typ = semProcTypeNode(c, n, genericParams, nil, s.kind)
proc addParams(c: PContext, n: PNode, kind: TSymKind) =

View file

@ -566,7 +566,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
block addImplicitGeneric:
# is this a bindOnce type class already present in the param list?
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
break addImplicitGeneric
@ -800,7 +800,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
of nkPtrTy: result = semAnyRef(c, n, tyPtr, prev)
of nkVarTy: result = semVarType(c, n, prev)
of nkDistinctTy: result = semDistinct(c, n, prev)
of nkProcTy:
of nkProcTy:
if n.sonsLen == 0: return newConstraint(c, tyProc)
checkSonsLen(n, 2)
openScope(c.tab)
@ -808,7 +808,12 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
# dummy symbol for `pragma`:
var s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c)
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)
of nkEnumTy: result = semEnum(c, n, prev)
of nkType: result = n.typ

View file

@ -457,7 +457,9 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
case a.kind
of tyPointer: result = isEqual
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
of tyString:
case a.kind

View file

@ -640,14 +640,6 @@ proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and
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 =
case n.kind
of nkSym:

View file

@ -24,9 +24,9 @@ proc getProcHeader*(sym: PSym): string
proc base*(t: PType): PType
# ------------------- type iterator: ----------------------------------------
type
TTypeIter* = proc (t: PType, closure: PObject): bool # should return true if the iteration should stop
TTypeMutator* = proc (t: PType, closure: PObject): PType # copy t and mutate it
TTypePredicate* = proc (t: PType): bool
TTypeIter* = proc (t: PType, closure: PObject): bool {.nimcall.} # true if iteration should stop
TTypeMutator* = proc (t: PType, closure: PObject): PType {.nimcall.} # copy t and mutate it
TTypePredicate* = proc (t: PType): bool {.nimcall.}
proc IterOverType*(t: PType, iter: TTypeIter, closure: PObject): bool
# Returns result of `iter`.