'bind' default for clean templates
This commit is contained in:
parent
635ad3b336
commit
886a1ab15d
5 changed files with 49 additions and 8 deletions
|
|
@ -163,7 +163,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||||
app(pl, genArgNoParam(p, ri.sons[i]))
|
app(pl, genArgNoParam(p, ri.sons[i]))
|
||||||
if i < length - 1: app(pl, ~", ")
|
if i < length - 1: app(pl, ~", ")
|
||||||
|
|
||||||
template genCallPattern =
|
template genCallPattern {.dirty.} =
|
||||||
lineF(p, cpsStmts, CallPattern & ";$n", op.r, pl, pl.addComma, rawProc)
|
lineF(p, cpsStmts, CallPattern & ";$n", op.r, pl, pl.addComma, rawProc)
|
||||||
|
|
||||||
let rawProc = getRawProcType(p, typ)
|
let rawProc = getRawProcType(p, typ)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ discard """
|
||||||
|
|
||||||
template `||` (a, b: expr): expr =
|
template `||` (a, b: expr): expr =
|
||||||
let aa = a
|
let aa = a
|
||||||
(if aa: aa else: b)
|
if aa: aa else: b
|
||||||
|
|
||||||
var
|
var
|
||||||
a, b: T
|
a, b: T
|
||||||
|
|
@ -156,6 +156,37 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
|
||||||
else:
|
else:
|
||||||
n = semTemplBody(c, n)
|
n = semTemplBody(c, n)
|
||||||
|
|
||||||
|
proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
|
incl(s.flags, sfUsed)
|
||||||
|
case s.kind
|
||||||
|
of skUnknown:
|
||||||
|
# Introduced in this pass! Leave it as an identifier.
|
||||||
|
result = n
|
||||||
|
of skProc, skMethod, skIterator, skConverter, skTemplate, skMacro:
|
||||||
|
result = symChoice(c, n, s, scOpen)
|
||||||
|
of skGenericParam:
|
||||||
|
result = newSymNodeTypeDesc(s, n.info)
|
||||||
|
of skParam:
|
||||||
|
result = n
|
||||||
|
of skType:
|
||||||
|
if (s.typ != nil) and (s.typ.kind != tyGenericParam):
|
||||||
|
result = newSymNodeTypeDesc(s, n.info)
|
||||||
|
else:
|
||||||
|
result = n
|
||||||
|
else: result = newSymNode(s, n.info)
|
||||||
|
|
||||||
|
proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode =
|
||||||
|
result = n
|
||||||
|
if n.kind == nkIdent:
|
||||||
|
let s = QualifiedLookUp(c.c, n, {})
|
||||||
|
if s != nil:
|
||||||
|
if s.owner == c.owner and (s.kind == skParam or sfGenSym in s.flags):
|
||||||
|
incl(s.flags, sfUsed)
|
||||||
|
result = newSymNode(s, n.info)
|
||||||
|
else:
|
||||||
|
for i in countup(0, safeLen(n) - 1):
|
||||||
|
result.sons[i] = semRoutineInTemplName(c, n.sons[i])
|
||||||
|
|
||||||
proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
|
proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkSonsLen(n, bodyPos + 1)
|
checkSonsLen(n, bodyPos + 1)
|
||||||
|
|
@ -170,14 +201,14 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
|
||||||
else:
|
else:
|
||||||
n.sons[namePos] = ident
|
n.sons[namePos] = ident
|
||||||
else:
|
else:
|
||||||
n.sons[namePos] = semTemplBody(c, n.sons[namePos])
|
n.sons[namePos] = semRoutineInTemplName(c, n.sons[namePos])
|
||||||
openScope(c)
|
openScope(c)
|
||||||
for i in patternPos..bodyPos:
|
for i in patternPos..bodyPos:
|
||||||
n.sons[i] = semTemplBody(c, n.sons[i])
|
n.sons[i] = semTemplBody(c, n.sons[i])
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
|
|
||||||
proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind) =
|
proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind) =
|
||||||
for i in countup(ord(symkind == skConditional), sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var a = n.sons[i]
|
var a = n.sons[i]
|
||||||
if a.kind == nkCommentStmt: continue
|
if a.kind == nkCommentStmt: continue
|
||||||
if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): IllFormedAst(a)
|
if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): IllFormedAst(a)
|
||||||
|
|
@ -200,11 +231,15 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
elif Contains(c.toBind, s.id):
|
elif Contains(c.toBind, s.id):
|
||||||
result = symChoice(c.c, n, s, scClosed)
|
result = symChoice(c.c, n, s, scClosed)
|
||||||
|
elif Contains(c.toMixin, s.name.id):
|
||||||
|
result = symChoice(c.c, n, s, scForceOpen)
|
||||||
elif s.owner == c.owner and sfGenSym in s.flags:
|
elif s.owner == c.owner and sfGenSym in s.flags:
|
||||||
# template tmp[T](x: var seq[T]) =
|
# template tmp[T](x: var seq[T]) =
|
||||||
# var yz: T
|
# var yz: T
|
||||||
incl(s.flags, sfUsed)
|
incl(s.flags, sfUsed)
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
|
else:
|
||||||
|
result = semTemplSymbol(c.c, n, s)
|
||||||
of nkBind:
|
of nkBind:
|
||||||
result = semTemplBody(c, n.sons[0])
|
result = semTemplBody(c, n.sons[0])
|
||||||
of nkBindStmt:
|
of nkBindStmt:
|
||||||
|
|
@ -310,6 +345,10 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = semRoutineInTemplBody(c, n, skMacro)
|
result = semRoutineInTemplBody(c, n, skMacro)
|
||||||
of nkConverterDef:
|
of nkConverterDef:
|
||||||
result = semRoutineInTemplBody(c, n, skConverter)
|
result = semRoutineInTemplBody(c, n, skConverter)
|
||||||
|
of nkPragmaExpr:
|
||||||
|
result.sons[0] = semTemplBody(c, n.sons[0])
|
||||||
|
of nkPragma:
|
||||||
|
discard
|
||||||
else:
|
else:
|
||||||
# dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam',
|
# dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam',
|
||||||
# so we use the generic code for nkDotExpr too
|
# so we use the generic code for nkDotExpr too
|
||||||
|
|
@ -318,6 +357,8 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
if s != nil:
|
if s != nil:
|
||||||
if Contains(c.toBind, s.id):
|
if Contains(c.toBind, s.id):
|
||||||
return symChoice(c.c, n, s, scClosed)
|
return symChoice(c.c, n, s, scClosed)
|
||||||
|
elif Contains(c.toMixin, s.name.id):
|
||||||
|
return symChoice(c.c, n, s, scForceOpen)
|
||||||
result = n
|
result = n
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result.sons[i] = semTemplBody(c, n.sons[i])
|
result.sons[i] = semTemplBody(c, n.sons[i])
|
||||||
|
|
|
||||||
|
|
@ -1028,7 +1028,7 @@ proc readIntoBuf(socket: TSocket, flags: int32): int =
|
||||||
socket.bufLen = result
|
socket.bufLen = result
|
||||||
socket.currPos = 0
|
socket.currPos = 0
|
||||||
|
|
||||||
template retRead(flags, readBytes: int) =
|
template retRead(flags, readBytes: int) {.dirty.} =
|
||||||
let res = socket.readIntoBuf(flags.int32)
|
let res = socket.readIntoBuf(flags.int32)
|
||||||
if res <= 0:
|
if res <= 0:
|
||||||
if readBytes > 0:
|
if readBytes > 0:
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,8 @@ when not defined(JS) and not defined(NimrodVM):
|
||||||
data: array[0..100_000_000, char]
|
data: array[0..100_000_000, char]
|
||||||
NimString = ptr NimStringDesc
|
NimString = ptr NimStringDesc
|
||||||
|
|
||||||
template space(s: PGenericSeq): int = s.reserved and not seqShallowFlag
|
template space(s: PGenericSeq): int {.dirty.} =
|
||||||
|
s.reserved and not seqShallowFlag
|
||||||
|
|
||||||
include "system/hti"
|
include "system/hti"
|
||||||
|
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -1,8 +1,7 @@
|
||||||
version 0.9.2
|
version 0.9.2
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- make 'bind' default for templates and introduce 'mixin';
|
- special rule for ``[]=``
|
||||||
special rule for ``[]=``
|
|
||||||
- ``=`` should be overloadable; requires specialization for ``=``; general
|
- ``=`` should be overloadable; requires specialization for ``=``; general
|
||||||
lift mechanism in the compiler is already implemented for 'fields'
|
lift mechanism in the compiler is already implemented for 'fields'
|
||||||
- mocking support with ``tyProxy`` that does: fallback for ``.`` operator
|
- mocking support with ``tyProxy`` that does: fallback for ``.`` operator
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue