mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 09:24:36 +00:00
next steps to hygienic templates
This commit is contained in:
@@ -259,7 +259,10 @@ const
|
||||
sfImmediate* = sfDeadCodeElim
|
||||
# macro or template is immediately expanded
|
||||
# without considering any possible overloads
|
||||
|
||||
|
||||
sfDirty* = sfPure
|
||||
# template is not hygienic (old styled template)
|
||||
|
||||
sfAnon* = sfDiscardable
|
||||
# symbol name that was generated by the compiler
|
||||
# the compiler will avoid printing such names
|
||||
@@ -691,7 +694,8 @@ const
|
||||
|
||||
|
||||
# creator procs:
|
||||
proc NewSym*(symKind: TSymKind, Name: PIdent, owner: PSym): PSym
|
||||
proc NewSym*(symKind: TSymKind, Name: PIdent, owner: PSym,
|
||||
info: TLineInfo): PSym
|
||||
proc NewType*(kind: TTypeKind, owner: PSym): PType
|
||||
proc newNode*(kind: TNodeKind): PNode
|
||||
proc newIntNode*(kind: TNodeKind, intVal: BiggestInt): PNode
|
||||
@@ -922,11 +926,10 @@ proc copyType(t: PType, owner: PSym, keepId: bool): PType =
|
||||
result.sym = t.sym # backend-info should not be copied
|
||||
|
||||
proc copySym(s: PSym, keepId: bool = false): PSym =
|
||||
result = newSym(s.kind, s.name, s.owner)
|
||||
result = newSym(s.kind, s.name, s.owner, s.info)
|
||||
result.ast = nil # BUGFIX; was: s.ast which made problems
|
||||
result.info = s.info
|
||||
result.typ = s.typ
|
||||
if keepId:
|
||||
if keepId:
|
||||
result.id = s.id
|
||||
else:
|
||||
result.id = getID()
|
||||
@@ -939,13 +942,14 @@ proc copySym(s: PSym, keepId: bool = false): PSym =
|
||||
result.loc = s.loc
|
||||
result.annex = s.annex # BUGFIX
|
||||
|
||||
proc NewSym(symKind: TSymKind, Name: PIdent, owner: PSym): PSym =
|
||||
proc NewSym(symKind: TSymKind, Name: PIdent, owner: PSym,
|
||||
info: TLineInfo): PSym =
|
||||
# generates a symbol and initializes the hash field too
|
||||
new(result)
|
||||
result.Name = Name
|
||||
result.Kind = symKind
|
||||
result.flags = {}
|
||||
result.info = UnknownLineInfo()
|
||||
result.info = info
|
||||
result.options = gOptions
|
||||
result.owner = owner
|
||||
result.offset = - 1
|
||||
|
||||
@@ -254,7 +254,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
var p = newNodeIT(nkExprColonExpr, info, t.sons[i])
|
||||
var field = if t.n != nil: t.n.sons[i].sym else: newSym(
|
||||
skField, getIdent(":tmp" & $i), t.owner)
|
||||
skField, getIdent(":tmp" & $i), t.owner, info)
|
||||
addSon(p, newSymNode(field, info))
|
||||
addSon(p, getNullValue(t.sons[i], info))
|
||||
addSon(result, p)
|
||||
@@ -1358,7 +1358,7 @@ proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode =
|
||||
if evalTemplateCounter > 100:
|
||||
GlobalError(n.info, errTemplateInstantiationTooNested)
|
||||
|
||||
inc genSymBaseId
|
||||
#inc genSymBaseId
|
||||
var s = newStackFrame()
|
||||
s.call = n
|
||||
setlen(s.params, 2)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
import idents, strutils, os, options
|
||||
|
||||
var gFrontEndId, gBackendId*, genSymBaseId*: int
|
||||
var gFrontEndId, gBackendId*: int
|
||||
|
||||
const
|
||||
debugIds* = false
|
||||
@@ -34,9 +34,6 @@ proc backendId*(): int {.inline.} =
|
||||
result = gBackendId
|
||||
inc(gBackendId)
|
||||
|
||||
proc genSym*(basename: string): PIdent =
|
||||
result = getIdent(basename & $genSymBaseId)
|
||||
|
||||
proc setId*(id: int) {.inline.} =
|
||||
gFrontEndId = max(gFrontEndId, id + 1)
|
||||
|
||||
@@ -66,4 +63,3 @@ proc loadMaxIds*(project: string) =
|
||||
gFrontEndId = max(gFrontEndId, frontEndId)
|
||||
gBackEndId = max(gBackEndId, backEndId)
|
||||
f.close()
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ proc newEnv(outerProc: PSym, up: PEnv, n: PNode): PEnv =
|
||||
result.attachedNode = n
|
||||
|
||||
proc addField(tup: PType, s: PSym) =
|
||||
var field = newSym(skField, s.name, s.owner)
|
||||
var field = newSym(skField, s.name, s.owner, s.info)
|
||||
let t = skipIntLit(s.typ)
|
||||
field.typ = t
|
||||
field.position = sonsLen(tup)
|
||||
@@ -179,7 +179,7 @@ proc addDep(e, d: PEnv, owner: PSym): PSym =
|
||||
for x, field in items(e.deps):
|
||||
if x == d: return field
|
||||
var pos = sonsLen(e.tup)
|
||||
result = newSym(skField, getIdent(upName & $pos), owner)
|
||||
result = newSym(skField, getIdent(upName & $pos), owner, owner.info)
|
||||
result.typ = newType(tyRef, owner)
|
||||
result.position = pos
|
||||
assert d.tup != nil
|
||||
@@ -220,8 +220,7 @@ proc isInnerProc(s, outerProc: PSym): bool {.inline.} =
|
||||
#s.typ.callConv == ccClosure
|
||||
|
||||
proc addClosureParam(i: PInnerContext, e: PEnv) =
|
||||
var cp = newSym(skParam, getIdent(paramname), i.fn)
|
||||
cp.info = i.fn.info
|
||||
var cp = newSym(skParam, getIdent(paramname), i.fn, i.fn.info)
|
||||
incl(cp.flags, sfFromGeneric)
|
||||
cp.typ = newType(tyRef, i.fn)
|
||||
rawAddSon(cp.typ, e.tup)
|
||||
@@ -449,9 +448,8 @@ proc addVar*(father, v: PNode) =
|
||||
|
||||
proc getClosureVar(o: POuterContext, e: PEnv): PSym =
|
||||
if e.closure == nil:
|
||||
result = newSym(skVar, getIdent(envName), o.fn)
|
||||
result = newSym(skVar, getIdent(envName), o.fn, e.attachedNode.info)
|
||||
incl(result.flags, sfShadowed)
|
||||
result.info = e.attachedNode.info
|
||||
result.typ = newType(tyRef, o.fn)
|
||||
result.typ.rawAddSon(e.tup)
|
||||
e.closure = result
|
||||
@@ -590,8 +588,7 @@ type
|
||||
tup: PType
|
||||
|
||||
proc newIterResult(iter: PSym): PSym =
|
||||
result = newSym(skResult, getIdent":result", iter)
|
||||
result.info = iter.info
|
||||
result = newSym(skResult, getIdent":result", iter, iter.info)
|
||||
result.typ = iter.typ.sons[0]
|
||||
incl(result.flags, sfUsed)
|
||||
|
||||
@@ -650,15 +647,14 @@ proc liftIterator*(iter: PSym, body: PNode): PNode =
|
||||
c.tup = newType(tyTuple, iter)
|
||||
c.tup.n = newNodeI(nkRecList, iter.info)
|
||||
|
||||
var cp = newSym(skParam, getIdent(paramname), iter)
|
||||
cp.info = iter.info
|
||||
var cp = newSym(skParam, getIdent(paramname), iter, iter.info)
|
||||
incl(cp.flags, sfFromGeneric)
|
||||
cp.typ = newType(tyRef, iter)
|
||||
rawAddSon(cp.typ, c.tup)
|
||||
c.closureParam = cp
|
||||
addHiddenParam(iter, cp)
|
||||
|
||||
c.state = newSym(skField, getIdent(":state"), iter)
|
||||
c.state = newSym(skField, getIdent(":state"), iter, iter.info)
|
||||
c.state.typ = getStateType(iter)
|
||||
addField(c.tup, c.state)
|
||||
|
||||
|
||||
@@ -22,18 +22,14 @@ proc considerAcc*(n: PNode): PIdent =
|
||||
of 0: GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
of 1: result = considerAcc(n.sons[0])
|
||||
else:
|
||||
if n.len == 2 and n[0].kind == nkIdent and n[0].ident.id == ord(wStar):
|
||||
# XXX find a better way instead of `*x` for 'genSym'
|
||||
result = genSym(n[1].ident.s)
|
||||
else:
|
||||
var id = ""
|
||||
for i in 0.. <n.len:
|
||||
let x = n.sons[i]
|
||||
case x.kind
|
||||
of nkIdent: id.add(x.ident.s)
|
||||
of nkSym: id.add(x.sym.name.s)
|
||||
else: GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
result = getIdent(id)
|
||||
var id = ""
|
||||
for i in 0.. <n.len:
|
||||
let x = n.sons[i]
|
||||
case x.kind
|
||||
of nkIdent: id.add(x.ident.s)
|
||||
of nkSym: id.add(x.sym.name.s)
|
||||
else: GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
result = getIdent(id)
|
||||
else:
|
||||
GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
|
||||
@@ -46,8 +42,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
|
||||
considerAcc(m)
|
||||
else:
|
||||
getIdent("err:" & renderTree(m))
|
||||
result = newSym(skError, ident, getCurrOwner())
|
||||
result.info = n.info
|
||||
result = newSym(skError, ident, getCurrOwner(), n.info)
|
||||
result.typ = errorType(c)
|
||||
incl(result.flags, sfDiscardable)
|
||||
# pretend it's imported from some unknown module to prevent cascading errors:
|
||||
|
||||
@@ -27,7 +27,7 @@ const
|
||||
wGenSym, wInject}
|
||||
converterPragmas* = procPragmas
|
||||
methodPragmas* = procPragmas
|
||||
templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject}
|
||||
templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject, wDirty}
|
||||
macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc,
|
||||
wNodecl, wMagic, wNosideEffect, wCompilerProc, wDeprecated, wExtern,
|
||||
wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject}
|
||||
@@ -454,8 +454,7 @@ proc processPragma(c: PContext, n: PNode, i: int) =
|
||||
elif it.sons[0].kind != nkIdent: invalidPragma(n)
|
||||
elif it.sons[1].kind != nkIdent: invalidPragma(n)
|
||||
|
||||
var userPragma = NewSym(skTemplate, it.sons[1].ident, nil)
|
||||
userPragma.info = it.info
|
||||
var userPragma = NewSym(skTemplate, it.sons[1].ident, nil, it.info)
|
||||
var body = newNodeI(nkPragma, n.info)
|
||||
for j in i+1 .. sonsLen(n)-1: addSon(body, n.sons[j])
|
||||
userPragma.ast = body
|
||||
@@ -488,6 +487,9 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||
of wImmediate:
|
||||
if sym.kind in {skTemplate, skMacro}: incl(sym.flags, sfImmediate)
|
||||
else: invalidPragma(it)
|
||||
of wDirty:
|
||||
if sym.kind == skTemplate: incl(sym.flags, sfDirty)
|
||||
else: invalidPragma(it)
|
||||
of wImportCpp:
|
||||
processImportCpp(sym, getOptionalStr(c, it, sym.name.s))
|
||||
of wImportObjC:
|
||||
|
||||
@@ -55,8 +55,7 @@ proc isTopLevel(c: PContext): bool {.inline.} =
|
||||
result = c.tab.tos <= 2
|
||||
|
||||
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||
result = newSym(kind, considerAcc(n), getCurrOwner())
|
||||
result.info = n.info
|
||||
result = newSym(kind, considerAcc(n), getCurrOwner(), n.info)
|
||||
|
||||
proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||
# like newSymS, but considers gensym'ed symbols
|
||||
@@ -65,8 +64,7 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||
InternalAssert sfGenSym in result.flags
|
||||
InternalAssert result.kind == kind
|
||||
else:
|
||||
result = newSym(kind, considerAcc(n), getCurrOwner())
|
||||
result.info = n.info
|
||||
result = newSym(kind, considerAcc(n), getCurrOwner(), n.info)
|
||||
|
||||
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||
allowed: TSymFlags): PSym
|
||||
|
||||
@@ -1470,7 +1470,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
of nkTypeOfExpr:
|
||||
var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
|
||||
typ = makeTypedesc(c, typ)
|
||||
var sym = newSym(skType, getIdent"TypeOfExpr", typ.owner).linkTo(typ)
|
||||
var sym = newSym(skType, getIdent"TypeOfExpr",
|
||||
typ.owner, n.info).linkTo(typ)
|
||||
sym.flags.incl(sfAnon)
|
||||
result = newSymNode(sym, n.info)
|
||||
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
|
||||
|
||||
@@ -255,7 +255,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
flags, toBind)
|
||||
if n.sons[paramsPos].kind != nkEmpty:
|
||||
if n.sons[paramsPos].sons[0].kind != nkEmpty:
|
||||
addPrelimDecl(c, newSym(skUnknown, getIdent("result"), nil))
|
||||
addPrelimDecl(c, newSym(skUnknown, getIdent("result"), nil, n.info))
|
||||
n.sons[paramsPos] = semGenericStmt(c, n.sons[paramsPos], flags, toBind)
|
||||
n.sons[pragmasPos] = semGenericStmt(c, n.sons[pragmasPos], flags, toBind)
|
||||
var body: PNode
|
||||
|
||||
@@ -21,8 +21,7 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
|
||||
InternalError(a.info, "instantiateGenericParamList; no symbol")
|
||||
var q = a.sym
|
||||
if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyTypeClass, tyExpr}: continue
|
||||
var s = newSym(skType, q.name, getCurrOwner())
|
||||
s.info = q.info
|
||||
var s = newSym(skType, q.name, getCurrOwner(), q.info)
|
||||
s.flags = s.flags + {sfUsed, sfFromGeneric}
|
||||
var t = PType(IdTableGet(pt, q.typ))
|
||||
if t == nil:
|
||||
|
||||
@@ -380,7 +380,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
||||
var trueSymbol = StrTableGet(magicsys.systemModule.Tab, getIdent"true")
|
||||
if trueSymbol == nil:
|
||||
LocalError(n.info, errSystemNeeds, "true")
|
||||
trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner())
|
||||
trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(), n.info)
|
||||
trueSymbol.typ = getSysType(tyBool)
|
||||
|
||||
result.add(newSymNode(trueSymbol, n.info))
|
||||
@@ -620,10 +620,8 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
|
||||
aa.sons[0].kind == nkObjectTy:
|
||||
# give anonymous object a dummy symbol:
|
||||
assert s.typ.sons[0].sym == nil
|
||||
var anonObj = newSym(skType, getIdent(s.name.s & ":ObjectType"),
|
||||
getCurrOwner())
|
||||
anonObj.info = s.info
|
||||
s.typ.sons[0].sym = anonObj
|
||||
s.typ.sons[0].sym = newSym(skType, getIdent(s.name.s & ":ObjectType"),
|
||||
getCurrOwner(), s.info)
|
||||
|
||||
proc SemTypeSection(c: PContext, n: PNode): PNode =
|
||||
typeSectionLeftSidePass(c, n)
|
||||
@@ -650,8 +648,7 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) =
|
||||
|
||||
proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) =
|
||||
if t != nil:
|
||||
var s = newSym(skResult, getIdent"result", getCurrOwner())
|
||||
s.info = info
|
||||
var s = newSym(skResult, getIdent"result", getCurrOwner(), info)
|
||||
s.typ = t
|
||||
incl(s.flags, sfUsed)
|
||||
addParamOrResult(c, s, owner)
|
||||
@@ -697,8 +694,7 @@ proc semLambda(c: PContext, n: PNode): PNode =
|
||||
if result != nil: return result
|
||||
result = n
|
||||
checkSonsLen(n, bodyPos + 1)
|
||||
var s = newSym(skProc, getIdent":anonymous", getCurrOwner())
|
||||
s.info = n.info
|
||||
var s = newSym(skProc, getIdent":anonymous", getCurrOwner(), n.info)
|
||||
s.ast = n
|
||||
n.sons[namePos] = newSymNode(s)
|
||||
pushOwner(s)
|
||||
@@ -830,7 +826,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
popProcCon(c)
|
||||
else:
|
||||
if s.typ.sons[0] != nil and kind != skIterator:
|
||||
addDecl(c, newSym(skUnknown, getIdent"result", nil))
|
||||
addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info))
|
||||
var toBind = initIntSet()
|
||||
n.sons[bodyPos] = semGenericStmtScope(c, n.sons[bodyPos], {}, toBind)
|
||||
fixupInstantiatedSymbols(c, s)
|
||||
|
||||
@@ -104,9 +104,9 @@ proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
|
||||
illFormedAst(n)
|
||||
result = n
|
||||
|
||||
proc isTemplParam(n: PNode): bool {.inline.} =
|
||||
proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} =
|
||||
result = n.kind == nkSym and n.sym.kind == skParam and
|
||||
n.sym.owner.kind == skTemplate
|
||||
n.sym.owner == c.owner
|
||||
|
||||
proc semTemplBody(c: var TemplCtx, n: PNode): PNode
|
||||
|
||||
@@ -119,15 +119,15 @@ proc semTemplBodyScope(c: var TemplCtx, n: PNode): PNode =
|
||||
closeScope(c)
|
||||
|
||||
proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
|
||||
result = newSym(kind, considerAcc(n), c.owner)
|
||||
result = newSym(kind, considerAcc(n), c.owner, n.info)
|
||||
incl(result.flags, sfGenSym)
|
||||
incl(result.flags, sfShadowed)
|
||||
|
||||
proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
|
||||
# locals default to 'gensym':
|
||||
if n.kind != nkPragmaExpr or symBinding(n.sons[1]) != spInject:
|
||||
let ident = getIdentNode(c, n)
|
||||
if not isTemplParam(ident):
|
||||
let ident = getIdentNode(c, n)
|
||||
if not isTemplParam(c, ident):
|
||||
let local = newGenSym(k, ident, c)
|
||||
addPrelimDecl(c.c, local)
|
||||
replaceIdentBySym(n, newSymNode(local, n.info))
|
||||
@@ -142,7 +142,7 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
|
||||
# routines default to 'inject':
|
||||
if n.kind notin nkLambdaKinds and symBinding(n.sons[pragmasPos]) == spGenSym:
|
||||
let ident = getIdentNode(c, n.sons[namePos])
|
||||
if not isTemplParam(ident):
|
||||
if not isTemplParam(c, ident):
|
||||
let s = newGenSym(k, ident, c)
|
||||
addPrelimDecl(c.c, s)
|
||||
n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
|
||||
@@ -164,6 +164,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||
let s = QualifiedLookUp(c.c, n, {})
|
||||
if s != nil:
|
||||
if s.owner == c.owner and s.kind == skParam:
|
||||
incl(s.flags, sfUsed)
|
||||
result = newSymNode(s, n.info)
|
||||
elif Contains(c.toBind, s.id):
|
||||
result = symChoice(c.c, n, s)
|
||||
@@ -286,6 +287,33 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||
result = n
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
result.sons[i] = semTemplBody(c, n.sons[i])
|
||||
|
||||
proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
|
||||
result = n
|
||||
case n.kind
|
||||
of nkIdent:
|
||||
let s = QualifiedLookUp(c.c, n, {})
|
||||
if s != nil:
|
||||
if s.owner == c.owner and s.kind == skParam:
|
||||
result = newSymNode(s, n.info)
|
||||
elif Contains(c.toBind, s.id):
|
||||
result = symChoice(c.c, n, s)
|
||||
of nkBind:
|
||||
result = semTemplBodyDirty(c, n.sons[0])
|
||||
of nkBindStmt:
|
||||
result = semBindStmt(c.c, n, c.toBind)
|
||||
of nkEmpty, nkSym..nkNilLit:
|
||||
nil
|
||||
else:
|
||||
# dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam',
|
||||
# so we use the generic code for nkDotExpr too
|
||||
if n.kind == nkDotExpr or n.kind == nkAccQuoted:
|
||||
let s = QualifiedLookUp(c.c, n, {})
|
||||
if s != nil and Contains(c.toBind, s.id):
|
||||
return symChoice(c.c, n, s)
|
||||
result = n
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
result.sons[i] = semTemplBodyDirty(c, n.sons[i])
|
||||
|
||||
proc transformToExpr(n: PNode): PNode =
|
||||
var realStmt: int
|
||||
@@ -340,7 +368,10 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
|
||||
ctx.toBind = initIntSet()
|
||||
ctx.c = c
|
||||
ctx.owner = s
|
||||
n.sons[bodyPos] = semTemplBody(ctx, n.sons[bodyPos])
|
||||
if sfDirty in s.flags:
|
||||
n.sons[bodyPos] = semTemplBodyDirty(ctx, n.sons[bodyPos])
|
||||
else:
|
||||
n.sons[bodyPos] = semTemplBody(ctx, n.sons[bodyPos])
|
||||
if s.typ.sons[0].kind notin {tyStmt, tyTypeDesc}:
|
||||
n.sons[bodyPos] = transformToExpr(n.sons[bodyPos])
|
||||
# only parameters are resolved, no type checking is performed
|
||||
|
||||
@@ -622,7 +622,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||
result = genericParams.sons[i].typ
|
||||
break addImplicitGeneric
|
||||
|
||||
var s = newSym(skType, paramTypId, getCurrOwner())
|
||||
var s = newSym(skType, paramTypId, getCurrOwner(), info)
|
||||
if isAnon: s.flags.incl(sfAnon)
|
||||
s.linkTo(typeClass)
|
||||
s.position = genericParams.len
|
||||
|
||||
@@ -96,8 +96,7 @@ proc getCurrOwner(c: PTransf): PSym =
|
||||
else: result = c.module
|
||||
|
||||
proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PSym =
|
||||
result = newSym(skTemp, getIdent(genPrefix), getCurrOwner(c))
|
||||
result.info = info
|
||||
result = newSym(skTemp, getIdent(genPrefix), getCurrOwner(c), info)
|
||||
result.typ = skipTypes(typ, {tyGenericInst})
|
||||
incl(result.flags, sfFromGeneric)
|
||||
|
||||
@@ -205,9 +204,8 @@ proc hasContinue(n: PNode): bool =
|
||||
if hasContinue(n.sons[i]): return true
|
||||
|
||||
proc newLabel(c: PTransf, n: PNode): PSym =
|
||||
result = newSym(skLabel, nil, getCurrOwner(c))
|
||||
result = newSym(skLabel, nil, getCurrOwner(c), n.info)
|
||||
result.name = getIdent(genPrefix & $result.id)
|
||||
result.info = n.info
|
||||
|
||||
proc transformBlock(c: PTransf, n: PNode): PTransNode =
|
||||
var labl: PSym
|
||||
|
||||
@@ -60,7 +60,8 @@ type
|
||||
wFieldChecks,
|
||||
wWatchPoint, wSubsChar,
|
||||
wAcyclic, wShallow, wUnroll, wLinearScanEnd,
|
||||
wWrite, wGensym, wInject, wInheritable, wThreadVar, wEmit, wNoStackFrame,
|
||||
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
|
||||
wNoStackFrame,
|
||||
wImplicitStatic, wGlobal, wHoist
|
||||
|
||||
wAuto, wBool, wCatch, wChar, wClass,
|
||||
@@ -138,7 +139,7 @@ const
|
||||
"passc", "passl", "borrow", "discardable", "fieldchecks",
|
||||
"watchpoint",
|
||||
"subschar", "acyclic", "shallow", "unroll", "linearscanend",
|
||||
"write", "gensym", "inject", "inheritable", "threadvar", "emit",
|
||||
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
|
||||
"nostackframe", "implicitstatic", "global", "hoist",
|
||||
|
||||
"auto", "bool", "catch", "char", "class",
|
||||
|
||||
@@ -2290,6 +2290,9 @@ template doAssert*(cond: bool, msg = "") =
|
||||
if not cond:
|
||||
raiseAssert(astToStr(cond) & ' ' & msg)
|
||||
|
||||
when not defined(nimhygiene):
|
||||
{.pragma: inject.}
|
||||
|
||||
template onFailedAssert*(msg: expr, code: stmt): stmt =
|
||||
## Sets an assertion failure handler that will intercept any assert statements
|
||||
## following `onFailedAssert` in the current lexical scope.
|
||||
@@ -2310,7 +2313,7 @@ template onFailedAssert*(msg: expr, code: stmt): stmt =
|
||||
## assert(...)
|
||||
##
|
||||
template raiseAssert(msgIMPL: string): stmt =
|
||||
let `msg` = msgIMPL
|
||||
let msg {.inject.} = msgIMPL
|
||||
code
|
||||
|
||||
proc shallow*[T](s: var seq[T]) {.noSideEffect, inline.} =
|
||||
|
||||
3
todo.txt
3
todo.txt
@@ -1,7 +1,8 @@
|
||||
version 0.9.0
|
||||
=============
|
||||
|
||||
- make templates hygienic by default: 'gensym', 'inject' pragmas
|
||||
- make templates hygienic by default: 'gensym', 'inject' pragmas;
|
||||
document 'gensym', 'inject' and 'dirty'
|
||||
- make 'bind' default for templates and introduce 'mixin'
|
||||
- use ``\`` for comment continuations
|
||||
- ``final`` should be the default for objects
|
||||
|
||||
Reference in New Issue
Block a user