first implementation of the 'func' keyword
This commit is contained in:
parent
2e93bac227
commit
1a61c4d46d
31 changed files with 97 additions and 84 deletions
|
|
@ -95,7 +95,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
|
||||||
if a.kind == b.kind:
|
if a.kind == b.kind:
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
const varKinds = {skVar, skTemp, skProc}
|
const varKinds = {skVar, skTemp, skProc, skFunc}
|
||||||
# same symbol: aliasing:
|
# same symbol: aliasing:
|
||||||
if a.sym.id == b.sym.id: result = arYes
|
if a.sym.id == b.sym.id: result = arYes
|
||||||
elif a.sym.kind in varKinds or b.sym.kind in varKinds:
|
elif a.sym.kind in varKinds or b.sym.kind in varKinds:
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,8 @@ type
|
||||||
nkGotoState, # used for the state machine (for iterators)
|
nkGotoState, # used for the state machine (for iterators)
|
||||||
nkState, # give a label to a code section (for iterators)
|
nkState, # give a label to a code section (for iterators)
|
||||||
nkBreakState, # special break statement for easier code generation
|
nkBreakState, # special break statement for easier code generation
|
||||||
|
nkFuncDef # a func
|
||||||
|
|
||||||
TNodeKinds* = set[TNodeKind]
|
TNodeKinds* = set[TNodeKind]
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -534,6 +536,7 @@ type
|
||||||
skConst, # a constant
|
skConst, # a constant
|
||||||
skResult, # special 'result' variable
|
skResult, # special 'result' variable
|
||||||
skProc, # a proc
|
skProc, # a proc
|
||||||
|
skFunc, # a func
|
||||||
skMethod, # a method
|
skMethod, # a method
|
||||||
skIterator, # an iterator
|
skIterator, # an iterator
|
||||||
skConverter, # a type converter
|
skConverter, # a type converter
|
||||||
|
|
@ -552,7 +555,7 @@ type
|
||||||
TSymKinds* = set[TSymKind]
|
TSymKinds* = set[TSymKind]
|
||||||
|
|
||||||
const
|
const
|
||||||
routineKinds* = {skProc, skMethod, skIterator,
|
routineKinds* = {skProc, skFunc, skMethod, skIterator,
|
||||||
skConverter, skMacro, skTemplate}
|
skConverter, skMacro, skTemplate}
|
||||||
tfIncompleteStruct* = tfVarargs
|
tfIncompleteStruct* = tfVarargs
|
||||||
tfUncheckedArray* = tfVarargs
|
tfUncheckedArray* = tfVarargs
|
||||||
|
|
@ -931,7 +934,7 @@ type
|
||||||
# the poor naming choices in the standard library.
|
# the poor naming choices in the standard library.
|
||||||
|
|
||||||
const
|
const
|
||||||
OverloadableSyms* = {skProc, skMethod, skIterator,
|
OverloadableSyms* = {skProc, skFunc, skMethod, skIterator,
|
||||||
skConverter, skModule, skTemplate, skMacro}
|
skConverter, skModule, skTemplate, skMacro}
|
||||||
|
|
||||||
GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody,
|
GenericTypes*: TTypeKinds = {tyGenericInvocation, tyGenericBody,
|
||||||
|
|
@ -954,7 +957,7 @@ const
|
||||||
tyTuple, tySequence}
|
tyTuple, tySequence}
|
||||||
NilableTypes*: TTypeKinds = {tyPointer, tyCString, tyRef, tyPtr, tySequence,
|
NilableTypes*: TTypeKinds = {tyPointer, tyCString, tyRef, tyPtr, tySequence,
|
||||||
tyProc, tyString, tyError}
|
tyProc, tyString, tyError}
|
||||||
ExportableSymKinds* = {skVar, skConst, skProc, skMethod, skType,
|
ExportableSymKinds* = {skVar, skConst, skProc, skFunc, skMethod, skType,
|
||||||
skIterator,
|
skIterator,
|
||||||
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub, skAlias}
|
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub, skAlias}
|
||||||
PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
|
PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
|
||||||
|
|
@ -978,14 +981,14 @@ const
|
||||||
|
|
||||||
nkLiterals* = {nkCharLit..nkTripleStrLit}
|
nkLiterals* = {nkCharLit..nkTripleStrLit}
|
||||||
nkLambdaKinds* = {nkLambda, nkDo}
|
nkLambdaKinds* = {nkLambda, nkDo}
|
||||||
declarativeDefs* = {nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef}
|
declarativeDefs* = {nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef}
|
||||||
procDefs* = nkLambdaKinds + declarativeDefs
|
procDefs* = nkLambdaKinds + declarativeDefs
|
||||||
|
|
||||||
nkSymChoices* = {nkClosedSymChoice, nkOpenSymChoice}
|
nkSymChoices* = {nkClosedSymChoice, nkOpenSymChoice}
|
||||||
nkStrKinds* = {nkStrLit..nkTripleStrLit}
|
nkStrKinds* = {nkStrLit..nkTripleStrLit}
|
||||||
|
|
||||||
skLocalVars* = {skVar, skLet, skForVar, skParam, skResult}
|
skLocalVars* = {skVar, skLet, skForVar, skParam, skResult}
|
||||||
skProcKinds* = {skProc, skTemplate, skMacro, skIterator,
|
skProcKinds* = {skProc, skFunc, skTemplate, skMacro, skIterator,
|
||||||
skMethod, skConverter}
|
skMethod, skConverter}
|
||||||
|
|
||||||
var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things
|
var ggDebug* {.deprecated.}: bool ## convenience switch for trying out things
|
||||||
|
|
|
||||||
|
|
@ -2039,7 +2039,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
else:
|
else:
|
||||||
genProc(p.module, sym)
|
genProc(p.module, sym)
|
||||||
putLocIntoDest(p, d, sym.loc)
|
putLocIntoDest(p, d, sym.loc)
|
||||||
of skProc, skConverter, skIterator:
|
of skProc, skConverter, skIterator, skFunc:
|
||||||
#if sym.kind == skIterator:
|
#if sym.kind == skIterator:
|
||||||
# echo renderTree(sym.getBody, {renderIds})
|
# echo renderTree(sym.getBody, {renderIds})
|
||||||
if sfCompileTime in sym.flags:
|
if sfCompileTime in sym.flags:
|
||||||
|
|
@ -2205,7 +2205,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
discard
|
discard
|
||||||
of nkPragma: genPragma(p, n)
|
of nkPragma: genPragma(p, n)
|
||||||
of nkPragmaBlock: expr(p, n.lastSon, d)
|
of nkPragmaBlock: expr(p, n.lastSon, d)
|
||||||
of nkProcDef, nkMethodDef, nkConverterDef:
|
of nkProcDef, nkFuncDef, nkMethodDef, nkConverterDef:
|
||||||
if n.sons[genericParamsPos].kind == nkEmpty:
|
if n.sons[genericParamsPos].kind == nkEmpty:
|
||||||
var prc = n.sons[namePos].sym
|
var prc = n.sons[namePos].sym
|
||||||
# due to a bug/limitation in the lambda lifting, unused inner procs
|
# due to a bug/limitation in the lambda lifting, unused inner procs
|
||||||
|
|
|
||||||
|
|
@ -960,7 +960,7 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
|
||||||
res.add(t.sons[i].strVal)
|
res.add(t.sons[i].strVal)
|
||||||
of nkSym:
|
of nkSym:
|
||||||
var sym = t.sons[i].sym
|
var sym = t.sons[i].sym
|
||||||
if sym.kind in {skProc, skIterator, skMethod}:
|
if sym.kind in {skProc, skFunc, skIterator, skMethod}:
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, t.sons[i], a)
|
initLocExpr(p, t.sons[i], a)
|
||||||
res.add($rdLoc(a))
|
res.add($rdLoc(a))
|
||||||
|
|
|
||||||
|
|
@ -603,7 +603,7 @@ proc cgsym(m: BModule, name: string): Rope =
|
||||||
var sym = magicsys.getCompilerProc(name)
|
var sym = magicsys.getCompilerProc(name)
|
||||||
if sym != nil:
|
if sym != nil:
|
||||||
case sym.kind
|
case sym.kind
|
||||||
of skProc, skMethod, skConverter, skIterator: genProc(m, sym)
|
of skProc, skFunc, skMethod, skConverter, skIterator: genProc(m, sym)
|
||||||
of skVar, skResult, skLet: genVarPrototype(m, newSymNode sym)
|
of skVar, skResult, skLet: genVarPrototype(m, newSymNode sym)
|
||||||
of skType: discard getTypeDesc(m, sym.typ)
|
of skType: discard getTypeDesc(m, sym.typ)
|
||||||
else: internalError("cgsym: " & name & ": " & $sym.kind)
|
else: internalError("cgsym: " & name & ": " & $sym.kind)
|
||||||
|
|
|
||||||
|
|
@ -325,7 +325,7 @@ proc complexName(k: TSymKind, n: PNode, baseName: string): string =
|
||||||
## section of ``doc/docgen.txt``.
|
## section of ``doc/docgen.txt``.
|
||||||
result = baseName
|
result = baseName
|
||||||
case k:
|
case k:
|
||||||
of skProc: result.add(defaultParamSeparator)
|
of skProc, skFunc: result.add(defaultParamSeparator)
|
||||||
of skMacro: result.add(".m" & defaultParamSeparator)
|
of skMacro: result.add(".m" & defaultParamSeparator)
|
||||||
of skMethod: result.add(".e" & defaultParamSeparator)
|
of skMethod: result.add(".e" & defaultParamSeparator)
|
||||||
of skIterator: result.add(".i" & defaultParamSeparator)
|
of skIterator: result.add(".i" & defaultParamSeparator)
|
||||||
|
|
@ -341,7 +341,7 @@ proc isCallable(n: PNode): bool =
|
||||||
## Returns true if `n` contains a callable node.
|
## Returns true if `n` contains a callable node.
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkProcDef, nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef,
|
of nkProcDef, nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef,
|
||||||
nkConverterDef: result = true
|
nkConverterDef, nkFuncDef: result = true
|
||||||
else:
|
else:
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
|
|
@ -533,6 +533,9 @@ proc generateDoc*(d: PDoc, n: PNode) =
|
||||||
of nkProcDef:
|
of nkProcDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
genItem(d, n, n.sons[namePos], skProc)
|
genItem(d, n, n.sons[namePos], skProc)
|
||||||
|
of nkFuncDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
genItem(d, n, n.sons[namePos], skFunc)
|
||||||
of nkMethodDef:
|
of nkMethodDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
genItem(d, n, n.sons[namePos], skMethod)
|
genItem(d, n, n.sons[namePos], skMethod)
|
||||||
|
|
@ -574,6 +577,9 @@ proc generateJson*(d: PDoc, n: PNode) =
|
||||||
of nkProcDef:
|
of nkProcDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
d.add genJsonItem(d, n, n.sons[namePos], skProc)
|
d.add genJsonItem(d, n, n.sons[namePos], skProc)
|
||||||
|
of nkFuncDef:
|
||||||
|
when useEffectSystem: documentRaises(n)
|
||||||
|
d.add genJsonItem(d, n, n.sons[namePos], skFunc)
|
||||||
of nkMethodDef:
|
of nkMethodDef:
|
||||||
when useEffectSystem: documentRaises(n)
|
when useEffectSystem: documentRaises(n)
|
||||||
d.add genJsonItem(d, n, n.sons[namePos], skMethod)
|
d.add genJsonItem(d, n, n.sons[namePos], skMethod)
|
||||||
|
|
@ -604,8 +610,8 @@ proc generateJson*(d: PDoc, n: PNode) =
|
||||||
|
|
||||||
proc genSection(d: PDoc, kind: TSymKind) =
|
proc genSection(d: PDoc, kind: TSymKind) =
|
||||||
const sectionNames: array[skModule..skTemplate, string] = [
|
const sectionNames: array[skModule..skTemplate, string] = [
|
||||||
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Methods",
|
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Funcs",
|
||||||
"Iterators", "Converters", "Macros", "Templates"
|
"Methods", "Iterators", "Converters", "Macros", "Templates"
|
||||||
]
|
]
|
||||||
if d.section[kind] == nil: return
|
if d.section[kind] == nil: return
|
||||||
var title = sectionNames[kind].rope
|
var title = sectionNames[kind].rope
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,7 @@ proc useMagic(p: PProc, name: string) =
|
||||||
if name.len == 0: return
|
if name.len == 0: return
|
||||||
var s = magicsys.getCompilerProc(name)
|
var s = magicsys.getCompilerProc(name)
|
||||||
if s != nil:
|
if s != nil:
|
||||||
internalAssert s.kind in {skProc, skMethod, skConverter}
|
internalAssert s.kind in {skProc, skFunc, skMethod, skConverter}
|
||||||
if not p.g.generatedSyms.containsOrIncl(s.id):
|
if not p.g.generatedSyms.containsOrIncl(s.id):
|
||||||
let code = genProc(p, s)
|
let code = genProc(p, s)
|
||||||
add(p.g.constants, code)
|
add(p.g.constants, code)
|
||||||
|
|
@ -1111,7 +1111,7 @@ template isIndirect(x: PSym): bool =
|
||||||
({sfAddrTaken, sfGlobal} * v.flags != {} and
|
({sfAddrTaken, sfGlobal} * v.flags != {} and
|
||||||
#(mapType(v.typ) != etyObject) and
|
#(mapType(v.typ) != etyObject) and
|
||||||
{sfImportc, sfVolatile, sfExportc} * v.flags == {} and
|
{sfImportc, sfVolatile, sfExportc} * v.flags == {} and
|
||||||
v.kind notin {skProc, skConverter, skMethod, skIterator,
|
v.kind notin {skProc, skFunc, skConverter, skMethod, skIterator,
|
||||||
skConst, skTemp, skLet} and p.target == targetJS)
|
skConst, skTemp, skLet} and p.target == targetJS)
|
||||||
|
|
||||||
proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
|
|
@ -1237,7 +1237,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
else:
|
else:
|
||||||
r.res = "$" & s.loc.r
|
r.res = "$" & s.loc.r
|
||||||
p.declareGlobal(s.id, r.res)
|
p.declareGlobal(s.id, r.res)
|
||||||
of skProc, skConverter, skMethod:
|
of skProc, skFunc, skConverter, skMethod:
|
||||||
discard mangleName(s, p.target)
|
discard mangleName(s, p.target)
|
||||||
if p.target == targetPHP and r.kind != resCallee:
|
if p.target == targetPHP and r.kind != resCallee:
|
||||||
r.res = makeJsString($s.loc.r)
|
r.res = makeJsString($s.loc.r)
|
||||||
|
|
@ -2338,7 +2338,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
||||||
nkFromStmt, nkTemplateDef, nkMacroDef: discard
|
nkFromStmt, nkTemplateDef, nkMacroDef: discard
|
||||||
of nkPragma: genPragma(p, n)
|
of nkPragma: genPragma(p, n)
|
||||||
of nkProcDef, nkMethodDef, nkConverterDef:
|
of nkProcDef, nkFuncDef, nkMethodDef, nkConverterDef:
|
||||||
var s = n.sons[namePos].sym
|
var s = n.sons[namePos].sym
|
||||||
if {sfExportc, sfCompilerProc} * s.flags == {sfExportc}:
|
if {sfExportc, sfCompilerProc} * s.flags == {sfExportc}:
|
||||||
genSym(p, n.sons[namePos], r)
|
genSym(p, n.sons[namePos], r)
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ proc illegalCapture(s: PSym): bool {.inline.} =
|
||||||
s.kind == skResult
|
s.kind == skResult
|
||||||
|
|
||||||
proc isInnerProc(s: PSym): bool =
|
proc isInnerProc(s: PSym): bool =
|
||||||
if s.kind in {skProc, skMethod, skConverter, skIterator} and s.magic == mNone:
|
if s.kind in {skProc, skFunc, skMethod, skConverter, skIterator} and s.magic == mNone:
|
||||||
result = s.skipGenericOwner.kind in routineKinds
|
result = s.skipGenericOwner.kind in routineKinds
|
||||||
|
|
||||||
proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode =
|
proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode =
|
||||||
|
|
@ -371,7 +371,8 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
let s = n.sym
|
let s = n.sym
|
||||||
if s.kind in {skProc, skMethod, skConverter, skIterator} and s.typ != nil and s.typ.callConv == ccClosure:
|
if s.kind in {skProc, skFunc, skMethod, skConverter, skIterator} and
|
||||||
|
s.typ != nil and s.typ.callConv == ccClosure:
|
||||||
# this handles the case that the inner proc was declared as
|
# this handles the case that the inner proc was declared as
|
||||||
# .closure but does not actually capture anything:
|
# .closure but does not actually capture anything:
|
||||||
addClosureParam(c, s, n.info)
|
addClosureParam(c, s, n.info)
|
||||||
|
|
@ -443,7 +444,7 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
|
||||||
discard
|
discard
|
||||||
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef:
|
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef:
|
||||||
discard
|
discard
|
||||||
of nkLambdaKinds, nkIteratorDef:
|
of nkLambdaKinds, nkIteratorDef, nkFuncDef:
|
||||||
if n.typ != nil:
|
if n.typ != nil:
|
||||||
detectCapturedVars(n[namePos], owner, c)
|
detectCapturedVars(n[namePos], owner, c)
|
||||||
else:
|
else:
|
||||||
|
|
@ -730,7 +731,7 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||||
# now we know better, so patch it:
|
# now we know better, so patch it:
|
||||||
n.sons[0] = x.sons[0]
|
n.sons[0] = x.sons[0]
|
||||||
n.sons[1] = x.sons[1]
|
n.sons[1] = x.sons[1]
|
||||||
of nkLambdaKinds, nkIteratorDef:
|
of nkLambdaKinds, nkIteratorDef, nkFuncDef:
|
||||||
if n.typ != nil and n[namePos].kind == nkSym:
|
if n.typ != nil and n[namePos].kind == nkSym:
|
||||||
let m = newSymNode(n[namePos].sym)
|
let m = newSymNode(n[namePos].sym)
|
||||||
m.typ = n.typ
|
m.typ = n.typ
|
||||||
|
|
|
||||||
|
|
@ -144,8 +144,10 @@ type
|
||||||
|
|
||||||
proc getSymRepr*(s: PSym): string =
|
proc getSymRepr*(s: PSym): string =
|
||||||
case s.kind
|
case s.kind
|
||||||
of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s)
|
of skProc, skFunc, skMethod, skConverter, skIterator:
|
||||||
else: result = s.name.s
|
result = getProcHeader(s)
|
||||||
|
else:
|
||||||
|
result = s.name.s
|
||||||
|
|
||||||
proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
|
proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
|
||||||
# check if all symbols have been used and defined:
|
# check if all symbols have been used and defined:
|
||||||
|
|
|
||||||
|
|
@ -633,7 +633,7 @@ proc wrapProcForSpawn*(owner: PSym; spawnExpr: PNode; retType: PType;
|
||||||
if fn.kind == nkClosure:
|
if fn.kind == nkClosure:
|
||||||
localError(n.info, "closure in spawn environment is not allowed")
|
localError(n.info, "closure in spawn environment is not allowed")
|
||||||
if not (fn.kind == nkSym and fn.sym.kind in {skProc, skTemplate, skMacro,
|
if not (fn.kind == nkSym and fn.sym.kind in {skProc, skTemplate, skMacro,
|
||||||
skMethod, skConverter}):
|
skFunc, skMethod, skConverter}):
|
||||||
# for indirect calls we pass the function pointer in the scratchObj
|
# for indirect calls we pass the function pointer in the scratchObj
|
||||||
var argType = n[0].typ.skipTypes(abstractInst)
|
var argType = n[0].typ.skipTypes(abstractInst)
|
||||||
var field = newSym(skField, getIdent"fn", owner, n.info)
|
var field = newSym(skField, getIdent"fn", owner, n.info)
|
||||||
|
|
|
||||||
|
|
@ -991,7 +991,7 @@ proc parseDoBlock(p: var TParser; info: TLineInfo): PNode =
|
||||||
if params.kind != nkEmpty:
|
if params.kind != nkEmpty:
|
||||||
result = newProcNode(nkDo, info, result, params = params, pragmas = pragmas)
|
result = newProcNode(nkDo, info, result, params = params, pragmas = pragmas)
|
||||||
|
|
||||||
proc parseProcExpr(p: var TParser, isExpr: bool): PNode =
|
proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode =
|
||||||
#| procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)?
|
#| procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)?
|
||||||
# either a proc type or a anonymous proc
|
# either a proc type or a anonymous proc
|
||||||
let info = parLineInfo(p)
|
let info = parLineInfo(p)
|
||||||
|
|
@ -1002,7 +1002,7 @@ proc parseProcExpr(p: var TParser, isExpr: bool): PNode =
|
||||||
if p.tok.tokType == tkEquals and isExpr:
|
if p.tok.tokType == tkEquals and isExpr:
|
||||||
getTok(p)
|
getTok(p)
|
||||||
skipComment(p, result)
|
skipComment(p, result)
|
||||||
result = newProcNode(nkLambda, info, parseStmt(p),
|
result = newProcNode(kind, info, parseStmt(p),
|
||||||
params = params,
|
params = params,
|
||||||
pragmas = pragmas)
|
pragmas = pragmas)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1014,7 +1014,7 @@ proc parseProcExpr(p: var TParser, isExpr: bool): PNode =
|
||||||
proc isExprStart(p: TParser): bool =
|
proc isExprStart(p: TParser): bool =
|
||||||
case p.tok.tokType
|
case p.tok.tokType
|
||||||
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf,
|
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf,
|
||||||
tkProc, tkIterator, tkBind, tkAddr,
|
tkProc, tkFunc, tkIterator, tkBind, tkAddr,
|
||||||
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
|
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
|
||||||
tkTuple, tkObject, tkType, tkWhen, tkCase, tkOut:
|
tkTuple, tkObject, tkType, tkWhen, tkCase, tkOut:
|
||||||
result = true
|
result = true
|
||||||
|
|
@ -1088,21 +1088,12 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
|
||||||
|
|
||||||
case p.tok.tokType:
|
case p.tok.tokType:
|
||||||
of tkTuple: result = parseTuple(p, mode == pmTypeDef)
|
of tkTuple: result = parseTuple(p, mode == pmTypeDef)
|
||||||
of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef})
|
of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
|
||||||
|
of tkFunc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkFuncDef)
|
||||||
of tkIterator:
|
of tkIterator:
|
||||||
when false:
|
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
|
||||||
if mode in {pmTypeDesc, pmTypeDef}:
|
if result.kind == nkLambda: result.kind = nkIteratorDef
|
||||||
result = parseProcExpr(p, false)
|
else: result.kind = nkIteratorTy
|
||||||
result.kind = nkIteratorTy
|
|
||||||
else:
|
|
||||||
# no anon iterators for now:
|
|
||||||
parMessage(p, errExprExpected, p.tok)
|
|
||||||
getTok(p) # we must consume a token here to prevend endless loops!
|
|
||||||
result = ast.emptyNode
|
|
||||||
else:
|
|
||||||
result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef})
|
|
||||||
if result.kind == nkLambda: result.kind = nkIteratorDef
|
|
||||||
else: result.kind = nkIteratorTy
|
|
||||||
of tkEnum:
|
of tkEnum:
|
||||||
if mode == pmTypeDef:
|
if mode == pmTypeDef:
|
||||||
result = parseEnum(p)
|
result = parseEnum(p)
|
||||||
|
|
@ -2000,6 +1991,7 @@ proc complexOrSimpleStmt(p: var TParser): PNode =
|
||||||
of tkDefer: result = parseStaticOrDefer(p, nkDefer)
|
of tkDefer: result = parseStaticOrDefer(p, nkDefer)
|
||||||
of tkAsm: result = parseAsm(p)
|
of tkAsm: result = parseAsm(p)
|
||||||
of tkProc: result = parseRoutine(p, nkProcDef)
|
of tkProc: result = parseRoutine(p, nkProcDef)
|
||||||
|
of tkFunc: result = parseRoutine(p, nkFuncDef)
|
||||||
of tkMethod: result = parseRoutine(p, nkMethodDef)
|
of tkMethod: result = parseRoutine(p, nkMethodDef)
|
||||||
of tkIterator: result = parseRoutine(p, nkIteratorDef)
|
of tkIterator: result = parseRoutine(p, nkIteratorDef)
|
||||||
of tkMacro: result = parseRoutine(p, nkMacroDef)
|
of tkMacro: result = parseRoutine(p, nkMacroDef)
|
||||||
|
|
@ -2056,8 +2048,8 @@ proc parseStmt(p: var TParser): PNode =
|
||||||
else:
|
else:
|
||||||
# the case statement is only needed for better error messages:
|
# the case statement is only needed for better error messages:
|
||||||
case p.tok.tokType
|
case p.tok.tokType
|
||||||
of tkIf, tkWhile, tkCase, tkTry, tkFor, tkBlock, tkAsm, tkProc, tkIterator,
|
of tkIf, tkWhile, tkCase, tkTry, tkFor, tkBlock, tkAsm, tkProc, tkFunc,
|
||||||
tkMacro, tkType, tkConst, tkWhen, tkVar:
|
tkIterator, tkMacro, tkType, tkConst, tkWhen, tkVar:
|
||||||
parMessage(p, errComplexStmtRequiresInd)
|
parMessage(p, errComplexStmtRequiresInd)
|
||||||
result = ast.emptyNode
|
result = ast.emptyNode
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ proc astNeeded*(s: PSym): bool =
|
||||||
# needs to be stored. The passes manager frees s.sons[codePos] when
|
# needs to be stored. The passes manager frees s.sons[codePos] when
|
||||||
# appropriate to free the procedure body's memory. This is important
|
# appropriate to free the procedure body's memory. This is important
|
||||||
# to keep memory usage down.
|
# to keep memory usage down.
|
||||||
if (s.kind in {skMethod, skProc}) and
|
if (s.kind in {skMethod, skProc, skFunc}) and
|
||||||
({sfCompilerProc, sfCompileTime} * s.flags == {}) and
|
({sfCompilerProc, sfCompileTime} * s.flags == {}) and
|
||||||
(s.typ.callConv != ccInline) and
|
(s.typ.callConv != ccInline) and
|
||||||
(s.ast.sons[genericParamsPos].kind == nkEmpty):
|
(s.ast.sons[genericParamsPos].kind == nkEmpty):
|
||||||
|
|
|
||||||
|
|
@ -1166,6 +1166,9 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||||
of nkProcDef:
|
of nkProcDef:
|
||||||
if renderNoProcDefs notin g.flags: putWithSpace(g, tkProc, "proc")
|
if renderNoProcDefs notin g.flags: putWithSpace(g, tkProc, "proc")
|
||||||
gproc(g, n)
|
gproc(g, n)
|
||||||
|
of nkFuncDef:
|
||||||
|
if renderNoProcDefs notin g.flags: putWithSpace(g, tkFunc, "func")
|
||||||
|
gproc(g, n)
|
||||||
of nkConverterDef:
|
of nkConverterDef:
|
||||||
if renderNoProcDefs notin g.flags: putWithSpace(g, tkConverter, "converter")
|
if renderNoProcDefs notin g.flags: putWithSpace(g, tkConverter, "converter")
|
||||||
gproc(g, n)
|
gproc(g, n)
|
||||||
|
|
|
||||||
|
|
@ -580,7 +580,7 @@ proc process(c: PPassContext, n: PNode): PNode =
|
||||||
for i in countup(0, sonsLen(n) - 1): discard process(c, n.sons[i])
|
for i in countup(0, sonsLen(n) - 1): discard process(c, n.sons[i])
|
||||||
#var s = n.sons[namePos].sym
|
#var s = n.sons[namePos].sym
|
||||||
#addInterfaceSym(w, s)
|
#addInterfaceSym(w, s)
|
||||||
of nkProcDef, nkIteratorDef, nkConverterDef,
|
of nkProcDef, nkFuncDef, nkIteratorDef, nkConverterDef,
|
||||||
nkTemplateDef, nkMacroDef:
|
nkTemplateDef, nkMacroDef:
|
||||||
let s = n.sons[namePos].sym
|
let s = n.sons[namePos].sym
|
||||||
if s == nil: internalError(n.info, "rodwrite.process")
|
if s == nil: internalError(n.info, "rodwrite.process")
|
||||||
|
|
|
||||||
|
|
@ -449,7 +449,7 @@ include semtypes, semtempl, semgnrc, semstmts, semexprs
|
||||||
proc addCodeForGenerics(c: PContext, n: PNode) =
|
proc addCodeForGenerics(c: PContext, n: PNode) =
|
||||||
for i in countup(c.lastGenericIdx, c.generics.len - 1):
|
for i in countup(c.lastGenericIdx, c.generics.len - 1):
|
||||||
var prc = c.generics[i].inst.sym
|
var prc = c.generics[i].inst.sym
|
||||||
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
|
if prc.kind in {skProc, skFunc, skMethod, skConverter} and prc.magic == mNone:
|
||||||
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
|
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
|
||||||
internalError(prc.info, "no code for " & prc.name.s)
|
internalError(prc.info, "no code for " & prc.name.s)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -468,7 +468,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
for i in countup(0, len(a)-1):
|
for i in countup(0, len(a)-1):
|
||||||
var candidate = a.sons[i].sym
|
var candidate = a.sons[i].sym
|
||||||
if candidate.kind in {skProc, skMethod, skConverter,
|
if candidate.kind in {skProc, skMethod, skConverter,
|
||||||
skIterator}:
|
skFunc, skIterator}:
|
||||||
# it suffices that the candidate has the proper number of generic
|
# it suffices that the candidate has the proper number of generic
|
||||||
# type parameters:
|
# type parameters:
|
||||||
if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1:
|
if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1:
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ proc makeRangeType*(c: PContext; first, last: BiggestInt;
|
||||||
addSonSkipIntLit(result, intType) # basetype of range
|
addSonSkipIntLit(result, intType) # basetype of range
|
||||||
|
|
||||||
proc markIndirect*(c: PContext, s: PSym) {.inline.} =
|
proc markIndirect*(c: PContext, s: PSym) {.inline.} =
|
||||||
if s.kind in {skProc, skConverter, skMethod, skIterator}:
|
if s.kind in {skProc, skFunc, skConverter, skMethod, skIterator}:
|
||||||
incl(s.flags, sfAddrTaken)
|
incl(s.flags, sfAddrTaken)
|
||||||
# XXX add to 'c' for global analysis
|
# XXX add to 'c' for global analysis
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -574,7 +574,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
||||||
optImplicitStatic notin gOptions: return
|
optImplicitStatic notin gOptions: return
|
||||||
|
|
||||||
if callee.magic notin ctfeWhitelist: return
|
if callee.magic notin ctfeWhitelist: return
|
||||||
if callee.kind notin {skProc, skConverter} or callee.isGenericRoutine:
|
if callee.kind notin {skProc, skFunc, skConverter} or callee.isGenericRoutine:
|
||||||
return
|
return
|
||||||
|
|
||||||
if n.typ != nil and typeAllowed(n.typ, skConst) != nil: return
|
if n.typ != nil and typeAllowed(n.typ, skConst) != nil: return
|
||||||
|
|
@ -616,10 +616,10 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
||||||
# for typeof support.
|
# for typeof support.
|
||||||
# for ``type(countup(1,3))``, see ``tests/ttoseq``.
|
# for ``type(countup(1,3))``, see ``tests/ttoseq``.
|
||||||
result = semOverloadedCall(c, n, nOrig,
|
result = semOverloadedCall(c, n, nOrig,
|
||||||
{skProc, skMethod, skConverter, skMacro, skTemplate, skIterator}, flags)
|
{skProc, skFunc, skMethod, skConverter, skMacro, skTemplate, skIterator}, flags)
|
||||||
else:
|
else:
|
||||||
result = semOverloadedCall(c, n, nOrig,
|
result = semOverloadedCall(c, n, nOrig,
|
||||||
{skProc, skMethod, skConverter, skMacro, skTemplate}, flags)
|
{skProc, skFunc, skMethod, skConverter, skMacro, skTemplate}, flags)
|
||||||
|
|
||||||
if result != nil:
|
if result != nil:
|
||||||
if result.sons[0].kind != nkSym:
|
if result.sons[0].kind != nkSym:
|
||||||
|
|
@ -1230,7 +1230,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
else: nil
|
else: nil
|
||||||
if s != nil:
|
if s != nil:
|
||||||
case s.kind
|
case s.kind
|
||||||
of skProc, skMethod, skConverter, skIterator:
|
of skProc, skFunc, skMethod, skConverter, skIterator:
|
||||||
# type parameters: partial generic specialization
|
# type parameters: partial generic specialization
|
||||||
n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s)
|
n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s)
|
||||||
result = explicitGenericInstantiation(c, n, s)
|
result = explicitGenericInstantiation(c, n, s)
|
||||||
|
|
@ -1398,7 +1398,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||||
proc semReturn(c: PContext, n: PNode): PNode =
|
proc semReturn(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkSonsLen(n, 1)
|
checkSonsLen(n, 1)
|
||||||
if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro} or (
|
if c.p.owner.kind in {skConverter, skMethod, skProc, skFunc, skMacro} or (
|
||||||
c.p.owner.kind == skIterator and c.p.owner.typ.callConv == ccClosure):
|
c.p.owner.kind == skIterator and c.p.owner.typ.callConv == ccClosure):
|
||||||
if n.sons[0].kind != nkEmpty:
|
if n.sons[0].kind != nkEmpty:
|
||||||
# transform ``return expr`` to ``result = expr; return``
|
# transform ``return expr`` to ``result = expr; return``
|
||||||
|
|
@ -2122,7 +2122,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
var s = qualifiedLookUp(c, n, checks)
|
var s = qualifiedLookUp(c, n, checks)
|
||||||
if c.matchedConcept == nil: semCaptureSym(s, c.p.owner)
|
if c.matchedConcept == nil: semCaptureSym(s, c.p.owner)
|
||||||
result = semSym(c, n, s, flags)
|
result = semSym(c, n, s, flags)
|
||||||
if s.kind in {skProc, skMethod, skConverter, skIterator}:
|
if s.kind in {skProc, skFunc, skMethod, skConverter, skIterator}:
|
||||||
#performProcvarCheck(c, n, s)
|
#performProcvarCheck(c, n, s)
|
||||||
result = symChoice(c, n, s, scClosed)
|
result = symChoice(c, n, s, scClosed)
|
||||||
if result.kind == nkSym:
|
if result.kind == nkSym:
|
||||||
|
|
@ -2217,7 +2217,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
errorUseQualifier(c, n.info, s)
|
errorUseQualifier(c, n.info, s)
|
||||||
elif s.magic == mNone: result = semDirectOp(c, n, flags)
|
elif s.magic == mNone: result = semDirectOp(c, n, flags)
|
||||||
else: result = semMagic(c, n, s, flags)
|
else: result = semMagic(c, n, s, flags)
|
||||||
of skProc, skMethod, skConverter, skIterator:
|
of skProc, skFunc, skMethod, skConverter, skIterator:
|
||||||
if s.magic == mNone: result = semDirectOp(c, n, flags)
|
if s.magic == mNone: result = semDirectOp(c, n, flags)
|
||||||
else: result = semMagic(c, n, s, flags)
|
else: result = semMagic(c, n, s, flags)
|
||||||
else:
|
else:
|
||||||
|
|
@ -2330,7 +2330,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkYieldStmt: result = semYield(c, n)
|
of nkYieldStmt: result = semYield(c, n)
|
||||||
of nkPragma: pragma(c, c.p.owner, n, stmtPragmas)
|
of nkPragma: pragma(c, c.p.owner, n, stmtPragmas)
|
||||||
of nkIteratorDef: result = semIterator(c, n)
|
of nkIteratorDef: result = semIterator(c, n)
|
||||||
of nkProcDef: result = semProc(c, n)
|
of nkProcDef, nkFuncDef: result = semProc(c, n)
|
||||||
of nkMethodDef: result = semMethod(c, n)
|
of nkMethodDef: result = semMethod(c, n)
|
||||||
of nkConverterDef: result = semConverterDef(c, n)
|
of nkConverterDef: result = semConverterDef(c, n)
|
||||||
of nkMacroDef: result = semMacroDef(c, n)
|
of nkMacroDef: result = semMacroDef(c, n)
|
||||||
|
|
|
||||||
|
|
@ -630,7 +630,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
|
||||||
result = newStrNodeT(lookupSymbol(s.name), n)
|
result = newStrNodeT(lookupSymbol(s.name), n)
|
||||||
else:
|
else:
|
||||||
result = copyTree(s.ast)
|
result = copyTree(s.ast)
|
||||||
of {skProc, skMethod}:
|
of {skProc, skFunc, skMethod}:
|
||||||
result = n
|
result = n
|
||||||
of skType:
|
of skType:
|
||||||
# XXX gensym'ed symbols can come here and cannot be resolved. This is
|
# XXX gensym'ed symbols can come here and cannot be resolved. This is
|
||||||
|
|
@ -654,7 +654,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
if n.sons[0].kind != nkSym: return
|
if n.sons[0].kind != nkSym: return
|
||||||
var s = n.sons[0].sym
|
var s = n.sons[0].sym
|
||||||
if s.kind != skProc: return
|
if s.kind != skProc and s.kind != skFunc: return
|
||||||
try:
|
try:
|
||||||
case s.magic
|
case s.magic
|
||||||
of mNone:
|
of mNone:
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||||
of skUnknown:
|
of skUnknown:
|
||||||
# Introduced in this pass! Leave it as an identifier.
|
# Introduced in this pass! Leave it as an identifier.
|
||||||
result = n
|
result = n
|
||||||
of skProc, skMethod, skIterator, skConverter, skModule:
|
of skProc, skFunc, skMethod, skIterator, skConverter, skModule:
|
||||||
result = symChoice(c, n, s, scOpen)
|
result = symChoice(c, n, s, scOpen)
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if macroToExpandSym(s):
|
if macroToExpandSym(s):
|
||||||
|
|
@ -243,7 +243,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
of skUnknown, skParam:
|
of skUnknown, skParam:
|
||||||
# Leave it as an identifier.
|
# Leave it as an identifier.
|
||||||
discard
|
discard
|
||||||
of skProc, skMethod, skIterator, skConverter, skModule:
|
of skProc, skFunc, skMethod, skIterator, skConverter, skModule:
|
||||||
result.sons[0] = sc
|
result.sons[0] = sc
|
||||||
# do not check of 's.magic==mRoof' here because it might be some
|
# do not check of 's.magic==mRoof' here because it might be some
|
||||||
# other '^' but after overload resolution the proper one:
|
# other '^' but after overload resolution the proper one:
|
||||||
|
|
@ -437,7 +437,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
for j in countup(0, L-3):
|
for j in countup(0, L-3):
|
||||||
addTempDecl(c, getIdentNode(a.sons[j]), skParam)
|
addTempDecl(c, getIdentNode(a.sons[j]), skParam)
|
||||||
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
|
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
|
||||||
nkIteratorDef, nkLambdaKinds:
|
nkFuncDef, nkIteratorDef, nkLambdaKinds:
|
||||||
checkSonsLen(n, bodyPos + 1)
|
checkSonsLen(n, bodyPos + 1)
|
||||||
if n.sons[namePos].kind != nkEmpty:
|
if n.sons[namePos].kind != nkEmpty:
|
||||||
addTempDecl(c, getIdentNode(n.sons[0]), skProc)
|
addTempDecl(c, getIdentNode(n.sons[0]), skProc)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ proc rawPushProcCon(c: PContext, owner: PSym) =
|
||||||
c.p = x
|
c.p = x
|
||||||
|
|
||||||
proc rawHandleSelf(c: PContext; owner: PSym) =
|
proc rawHandleSelf(c: PContext; owner: PSym) =
|
||||||
const callableSymbols = {skProc, skMethod, skConverter, skIterator, skMacro}
|
const callableSymbols = {skProc, skFunc, skMethod, skConverter, skIterator, skMacro}
|
||||||
if c.selfName != nil and owner.kind in callableSymbols and owner.typ != nil:
|
if c.selfName != nil and owner.kind in callableSymbols and owner.typ != nil:
|
||||||
let params = owner.typ.n
|
let params = owner.typ.n
|
||||||
if params.len > 1:
|
if params.len > 1:
|
||||||
|
|
|
||||||
|
|
@ -387,7 +387,7 @@ proc analyse(c: var AnalysisCtx; n: PNode) =
|
||||||
addFactNeg(c.guards, canon(n.sons[0]))
|
addFactNeg(c.guards, canon(n.sons[0]))
|
||||||
dec c.inLoop
|
dec c.inLoop
|
||||||
of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef,
|
of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef,
|
||||||
nkMacroDef, nkTemplateDef, nkConstSection, nkPragma:
|
nkMacroDef, nkTemplateDef, nkConstSection, nkPragma, nkFuncDef:
|
||||||
discard
|
discard
|
||||||
else:
|
else:
|
||||||
analyseSons(c, n)
|
analyseSons(c, n)
|
||||||
|
|
|
||||||
|
|
@ -835,7 +835,7 @@ proc track(tracked: PEffects, n: PNode) =
|
||||||
setLen(tracked.locked, oldLocked)
|
setLen(tracked.locked, oldLocked)
|
||||||
tracked.currLockLevel = oldLockLevel
|
tracked.currLockLevel = oldLockLevel
|
||||||
of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef,
|
of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef,
|
||||||
nkMacroDef, nkTemplateDef, nkLambda, nkDo:
|
nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef:
|
||||||
discard
|
discard
|
||||||
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||||
if n.len == 2: track(tracked, n.sons[1])
|
if n.len == 2: track(tracked, n.sons[1])
|
||||||
|
|
@ -937,7 +937,7 @@ proc trackProc*(s: PSym, body: PNode) =
|
||||||
track(t, body)
|
track(t, body)
|
||||||
if not isEmptyType(s.typ.sons[0]) and
|
if not isEmptyType(s.typ.sons[0]) and
|
||||||
{tfNeedsInit, tfNotNil} * s.typ.sons[0].flags != {} and
|
{tfNeedsInit, tfNotNil} * s.typ.sons[0].flags != {} and
|
||||||
s.kind in {skProc, skConverter, skMethod}:
|
s.kind in {skProc, skFunc, skConverter, skMethod}:
|
||||||
var res = s.ast.sons[resultPos].sym # get result symbol
|
var res = s.ast.sons[resultPos].sym # get result symbol
|
||||||
if res.id notin t.init:
|
if res.id notin t.init:
|
||||||
message(body.info, warnProveInit, "result")
|
message(body.info, warnProveInit, "result")
|
||||||
|
|
@ -979,10 +979,10 @@ proc trackProc*(s: PSym, body: PNode) =
|
||||||
message(s.info, warnLockLevel,
|
message(s.info, warnLockLevel,
|
||||||
"declared lock level is $1, but real lock level is $2" %
|
"declared lock level is $1, but real lock level is $2" %
|
||||||
[$s.typ.lockLevel, $t.maxLockLevel])
|
[$s.typ.lockLevel, $t.maxLockLevel])
|
||||||
when useWriteTracking: trackWrites(s, body)
|
if s.kind == skFunc: trackWrites(s, body)
|
||||||
|
|
||||||
proc trackTopLevelStmt*(module: PSym; n: PNode) =
|
proc trackTopLevelStmt*(module: PSym; n: PNode) =
|
||||||
if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef,
|
if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef, nkFuncDef,
|
||||||
nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}:
|
nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}:
|
||||||
return
|
return
|
||||||
var effects = newNode(nkEffectList, n.info)
|
var effects = newNode(nkEffectList, n.info)
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,8 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
a.sons[2] = semTemplBody(c, a.sons[2])
|
a.sons[2] = semTemplBody(c, a.sons[2])
|
||||||
of nkProcDef, nkLambdaKinds:
|
of nkProcDef, nkLambdaKinds:
|
||||||
result = semRoutineInTemplBody(c, n, skProc)
|
result = semRoutineInTemplBody(c, n, skProc)
|
||||||
|
of nkFuncDef:
|
||||||
|
result = semRoutineInTemplBody(c, n, skFunc)
|
||||||
of nkMethodDef:
|
of nkMethodDef:
|
||||||
result = semRoutineInTemplBody(c, n, skMethod)
|
result = semRoutineInTemplBody(c, n, skMethod)
|
||||||
of nkIteratorDef:
|
of nkIteratorDef:
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode =
|
||||||
if isTypeParam(n[i]): needsFixing = true
|
if isTypeParam(n[i]): needsFixing = true
|
||||||
if needsFixing:
|
if needsFixing:
|
||||||
n.sons[0] = newSymNode(n.sons[0].sym.owner)
|
n.sons[0] = newSymNode(n.sons[0].sym.owner)
|
||||||
return cl.c.semOverloadedCall(cl.c, n, n, {skProc}, {})
|
return cl.c.semOverloadedCall(cl.c, n, n, {skProc, skFunc}, {})
|
||||||
|
|
||||||
for i in 0 .. <n.safeLen:
|
for i in 0 .. <n.safeLen:
|
||||||
n.sons[i] = reResolveCallsWithTypedescParams(cl, n[i])
|
n.sons[i] = reResolveCallsWithTypedescParams(cl, n[i])
|
||||||
|
|
|
||||||
|
|
@ -1373,7 +1373,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
# XXX: This is very hacky. It should be moved back into liftTypeParam
|
# XXX: This is very hacky. It should be moved back into liftTypeParam
|
||||||
if x.kind in {tyGenericInst, tyArray} and
|
if x.kind in {tyGenericInst, tyArray} and
|
||||||
c.calleeSym != nil and
|
c.calleeSym != nil and
|
||||||
c.calleeSym.kind == skProc:
|
c.calleeSym.kind in {skProc, skFunc}:
|
||||||
let inst = prepareMetatypeForSigmatch(c.c, c.bindings, c.call.info, f)
|
let inst = prepareMetatypeForSigmatch(c.c, c.bindings, c.call.info, f)
|
||||||
return typeRel(c, inst, a)
|
return typeRel(c, inst, a)
|
||||||
|
|
||||||
|
|
@ -1832,7 +1832,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
|
||||||
bothMetaCounter < 100:
|
bothMetaCounter < 100:
|
||||||
lastBindingsLength = m.bindings.counter
|
lastBindingsLength = m.bindings.counter
|
||||||
inc(bothMetaCounter)
|
inc(bothMetaCounter)
|
||||||
if arg.kind in {nkProcDef, nkIteratorDef} + nkLambdaKinds:
|
if arg.kind in {nkProcDef, nkFuncDef, nkIteratorDef} + nkLambdaKinds:
|
||||||
result = c.semInferredLambda(c, m.bindings, arg)
|
result = c.semInferredLambda(c, m.bindings, arg)
|
||||||
elif arg.kind != nkSym:
|
elif arg.kind != nkSym:
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -1865,7 +1865,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
|
||||||
else:
|
else:
|
||||||
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
|
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
|
||||||
of isInferred, isInferredConvertible:
|
of isInferred, isInferredConvertible:
|
||||||
if arg.kind in {nkProcDef, nkIteratorDef} + nkLambdaKinds:
|
if arg.kind in {nkProcDef, nkFuncDef, nkIteratorDef} + nkLambdaKinds:
|
||||||
result = c.semInferredLambda(c, m.bindings, arg)
|
result = c.semInferredLambda(c, m.bindings, arg)
|
||||||
elif arg.kind != nkSym:
|
elif arg.kind != nkSym:
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -1952,7 +1952,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||||
z.calleeSym = m.calleeSym
|
z.calleeSym = m.calleeSym
|
||||||
var best = -1
|
var best = -1
|
||||||
for i in countup(0, sonsLen(arg) - 1):
|
for i in countup(0, sonsLen(arg) - 1):
|
||||||
if arg.sons[i].sym.kind in {skProc, skMethod, skConverter, skIterator}:
|
if arg.sons[i].sym.kind in {skProc, skFunc, skMethod, skConverter, skIterator}:
|
||||||
copyCandidate(z, m)
|
copyCandidate(z, m)
|
||||||
z.callee = arg.sons[i].typ
|
z.callee = arg.sons[i].typ
|
||||||
if tfUnresolved in z.callee.flags: continue
|
if tfUnresolved in z.callee.flags: continue
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
|
||||||
if s.kind == skIterator:
|
if s.kind == skIterator:
|
||||||
if c.tooEarly: return n
|
if c.tooEarly: return n
|
||||||
else: return liftIterSym(n, getCurrOwner(c))
|
else: return liftIterSym(n, getCurrOwner(c))
|
||||||
elif s.kind in {skProc, skConverter, skMethod} and not c.tooEarly:
|
elif s.kind in {skProc, skFunc, skConverter, skMethod} and not c.tooEarly:
|
||||||
# top level .closure procs are still somewhat supported for 'Nake':
|
# top level .closure procs are still somewhat supported for 'Nake':
|
||||||
return makeClosure(s, nil, n.info)
|
return makeClosure(s, nil, n.info)
|
||||||
#elif n.sym.kind in {skVar, skLet} and n.sym.typ.callConv == ccClosure:
|
#elif n.sym.kind in {skVar, skLet} and n.sym.typ.callConv == ccClosure:
|
||||||
|
|
|
||||||
|
|
@ -1089,7 +1089,7 @@ proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind,
|
||||||
of nkNone..nkNilLit:
|
of nkNone..nkNilLit:
|
||||||
discard
|
discard
|
||||||
else:
|
else:
|
||||||
if n.kind == nkRecCase and kind in {skProc, skConst}:
|
if n.kind == nkRecCase and kind in {skProc, skFunc, skConst}:
|
||||||
return n[0].typ
|
return n[0].typ
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
let it = n.sons[i]
|
let it = n.sons[i]
|
||||||
|
|
@ -1107,7 +1107,7 @@ proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
|
||||||
|
|
||||||
proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
flags: TTypeAllowedFlags = {}): PType =
|
flags: TTypeAllowedFlags = {}): PType =
|
||||||
assert(kind in {skVar, skLet, skConst, skProc, skParam, skResult})
|
assert(kind in {skVar, skLet, skConst, skProc, skFunc, skParam, skResult})
|
||||||
# if we have already checked the type, return true, because we stop the
|
# if we have already checked the type, return true, because we stop the
|
||||||
# evaluation if something is wrong:
|
# evaluation if something is wrong:
|
||||||
result = nil
|
result = nil
|
||||||
|
|
@ -1116,7 +1116,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
var t = skipTypes(typ, abstractInst-{tyTypeDesc})
|
var t = skipTypes(typ, abstractInst-{tyTypeDesc})
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyVar:
|
of tyVar:
|
||||||
if kind in {skProc, skConst}: return t
|
if kind in {skProc, skFunc, skConst}: return t
|
||||||
var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
|
var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
|
||||||
case t2.kind
|
case t2.kind
|
||||||
of tyVar:
|
of tyVar:
|
||||||
|
|
@ -1176,7 +1176,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
||||||
if result != nil: break
|
if result != nil: break
|
||||||
of tyObject, tyTuple:
|
of tyObject, tyTuple:
|
||||||
if kind in {skProc, skConst} and
|
if kind in {skProc, skFunc, skConst} and
|
||||||
t.kind == tyObject and t.sons[0] != nil: return t
|
t.kind == tyObject and t.sons[0] != nil: return t
|
||||||
let flags = flags+{taField}
|
let flags = flags+{taField}
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
|
|
|
||||||
|
|
@ -1289,7 +1289,7 @@ proc checkCanEval(c: PCtx; n: PNode) =
|
||||||
if s.kind in {skVar, skTemp, skLet, skParam, skResult} and
|
if s.kind in {skVar, skTemp, skLet, skParam, skResult} and
|
||||||
not s.isOwnedBy(c.prc.sym) and s.owner != c.module and c.mode != emRepl:
|
not s.isOwnedBy(c.prc.sym) and s.owner != c.module and c.mode != emRepl:
|
||||||
cannotEval(n)
|
cannotEval(n)
|
||||||
elif s.kind in {skProc, skConverter, skMethod,
|
elif s.kind in {skProc, skFunc, skConverter, skMethod,
|
||||||
skIterator} and sfForward in s.flags:
|
skIterator} and sfForward in s.flags:
|
||||||
cannotEval(n)
|
cannotEval(n)
|
||||||
|
|
||||||
|
|
@ -1712,7 +1712,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
case s.kind
|
case s.kind
|
||||||
of skVar, skForVar, skTemp, skLet, skParam, skResult:
|
of skVar, skForVar, skTemp, skLet, skParam, skResult:
|
||||||
genRdVar(c, n, dest, flags)
|
genRdVar(c, n, dest, flags)
|
||||||
of skProc, skConverter, skMacro, skTemplate, skMethod, skIterator:
|
of skProc, skFunc, skConverter, skMacro, skTemplate, skMethod, skIterator:
|
||||||
# 'skTemplate' is only allowed for 'getAst' support:
|
# 'skTemplate' is only allowed for 'getAst' support:
|
||||||
if procIsCallback(c, s): discard
|
if procIsCallback(c, s): discard
|
||||||
elif sfImportc in s.flags: c.importcSym(n.info, s)
|
elif sfImportc in s.flags: c.importcSym(n.info, s)
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,8 @@ proc markWriteOrEscape(w: var W) =
|
||||||
for p in a.dest:
|
for p in a.dest:
|
||||||
if p.kind == skParam and p.owner == w.owner:
|
if p.kind == skParam and p.owner == w.owner:
|
||||||
incl(p.flags, sfWrittenTo)
|
incl(p.flags, sfWrittenTo)
|
||||||
|
if w.owner.kind == skFunc and p.typ.kind != tyVar:
|
||||||
|
localError(a.info, "write access to non-var parameter: " & p.name.s)
|
||||||
|
|
||||||
if {rootIsResultOrParam, rootIsHeapAccess, markAsEscaping}*a.destInfo != {}:
|
if {rootIsResultOrParam, rootIsHeapAccess, markAsEscaping}*a.destInfo != {}:
|
||||||
var destIsParam = false
|
var destIsParam = false
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,8 @@ type
|
||||||
nnkClosure,
|
nnkClosure,
|
||||||
nnkGotoState,
|
nnkGotoState,
|
||||||
nnkState,
|
nnkState,
|
||||||
nnkBreakState
|
nnkBreakState,
|
||||||
|
nnkFuncDef
|
||||||
|
|
||||||
NimNodeKinds* = set[NimNodeKind]
|
NimNodeKinds* = set[NimNodeKind]
|
||||||
NimTypeKind* = enum # some types are no longer used, see ast.nim
|
NimTypeKind* = enum # some types are no longer used, see ast.nim
|
||||||
|
|
@ -103,7 +104,7 @@ type
|
||||||
nskUnknown, nskConditional, nskDynLib, nskParam,
|
nskUnknown, nskConditional, nskDynLib, nskParam,
|
||||||
nskGenericParam, nskTemp, nskModule, nskType, nskVar, nskLet,
|
nskGenericParam, nskTemp, nskModule, nskType, nskVar, nskLet,
|
||||||
nskConst, nskResult,
|
nskConst, nskResult,
|
||||||
nskProc, nskMethod, nskIterator,
|
nskProc, nskFunc, nskMethod, nskIterator,
|
||||||
nskConverter, nskMacro, nskTemplate, nskField,
|
nskConverter, nskMacro, nskTemplate, nskField,
|
||||||
nskEnumField, nskForVar, nskLabel,
|
nskEnumField, nskForVar, nskLabel,
|
||||||
nskStub
|
nskStub
|
||||||
|
|
@ -843,7 +844,8 @@ proc last*(node: NimNode): NimNode {.compileTime.} = node[<node.len]
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
RoutineNodes* = {nnkProcDef, nnkMethodDef, nnkDo, nnkLambda, nnkIteratorDef, nnkTemplateDef, nnkConverterDef}
|
RoutineNodes* = {nnkProcDef, nnkFuncDef, nnkMethodDef, nnkDo, nnkLambda,
|
||||||
|
nnkIteratorDef, nnkTemplateDef, nnkConverterDef}
|
||||||
AtomicNodes* = {nnkNone..nnkNilLit}
|
AtomicNodes* = {nnkNone..nnkNilLit}
|
||||||
CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
|
CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
|
||||||
nnkCallStrLit, nnkHiddenCallConv}
|
nnkCallStrLit, nnkHiddenCallConv}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue