var tuple unpacking works at compile time
This commit is contained in:
parent
df8e151408
commit
2ca05eeb16
4 changed files with 54 additions and 40 deletions
|
|
@ -287,18 +287,29 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
|||
result = newNodeIT(nkCurly, info, t)
|
||||
else: InternalError("getNullValue: " & $t.kind)
|
||||
|
||||
proc evalVarValue(c: PEvalContext, n: PNode): PNode =
|
||||
result = evalAux(c, n, {})
|
||||
if result.kind in {nkType..nkNilLit}: result = result.copyNode
|
||||
|
||||
proc evalVar(c: PEvalContext, n: PNode): PNode =
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
var a = n.sons[i]
|
||||
let a = n.sons[i]
|
||||
if a.kind == nkCommentStmt: continue
|
||||
if a.kind != nkIdentDefs: return raiseCannotEval(c, n.info)
|
||||
# XXX var (x, y) = z support?
|
||||
#assert(a.sons[0].kind == nkSym) can happen for transformed vars
|
||||
if a.sons[2].kind != nkEmpty:
|
||||
result = evalAux(c, a.sons[2], {})
|
||||
if a.kind == nkVarTuple:
|
||||
result = evalVarValue(c, a.lastSon)
|
||||
if result.kind in {nkType..nkNilLit}:
|
||||
result = result.copyNode
|
||||
if isSpecial(result): return
|
||||
if result.kind != nkPar:
|
||||
return raiseCannotEval(c, n.info)
|
||||
for i in 0 .. a.len-3:
|
||||
var v = a.sons[i].sym
|
||||
IdNodeTablePut(c.tos.mapping, v, result.sons[i])
|
||||
else:
|
||||
if a.sons[2].kind != nkEmpty:
|
||||
result = evalVarValue(c, a.sons[2])
|
||||
if isSpecial(result): return
|
||||
else:
|
||||
result = getNullValue(a.sons[0].typ, a.sons[0].info)
|
||||
if a.sons[0].kind == nkSym:
|
||||
|
|
|
|||
|
|
@ -798,11 +798,12 @@ proc addSourceLine*(fileIdx: int32, line: string) =
|
|||
proc sourceLine*(i: TLineInfo): PRope =
|
||||
if i.fileIndex < 0: return nil
|
||||
|
||||
if not optPreserveOrigSource and
|
||||
fileInfos[i.fileIndex].lines.len == 0:
|
||||
if not optPreserveOrigSource and fileInfos[i.fileIndex].lines.len == 0:
|
||||
try:
|
||||
for line in lines(i.toFullPath):
|
||||
addSourceLine i.fileIndex, line.string
|
||||
|
||||
except EIO:
|
||||
discard
|
||||
InternalAssert i.fileIndex < fileInfos.len
|
||||
# can happen if the error points to EOF:
|
||||
if i.line > fileInfos[i.fileIndex].lines.len: return nil
|
||||
|
|
|
|||
|
|
@ -380,11 +380,11 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
|||
# side of the '=':
|
||||
if warnShadowIdent in gNotes and not identWithin(def, v.name):
|
||||
Message(a.info, warnShadowIdent, v.name.s)
|
||||
if a.kind != nkVarTuple:
|
||||
if def != nil and def.kind != nkEmpty:
|
||||
# this is needed for the evaluation pass and for the guard checking:
|
||||
v.ast = def
|
||||
if sfThread in v.flags: LocalError(def.info, errThreadvarCannotInit)
|
||||
if a.kind != nkVarTuple:
|
||||
v.typ = typ
|
||||
b = newNodeI(nkIdentDefs, a.info)
|
||||
if importantComments():
|
||||
|
|
@ -395,6 +395,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
|||
addSon(b, copyTree(def))
|
||||
addSon(result, b)
|
||||
else:
|
||||
if def.kind == nkPar: v.ast = def[j]
|
||||
v.typ = tup.sons[j]
|
||||
b.sons[j] = newSymNode(v)
|
||||
checkNilable(v)
|
||||
|
|
|
|||
1
todo.txt
1
todo.txt
|
|
@ -15,6 +15,7 @@ version 0.9.4
|
|||
Bugs
|
||||
====
|
||||
|
||||
- REPL: after an error no evaluation is performed for the next line
|
||||
- simple closure iterator doesn't work
|
||||
- docgen: sometimes effects are listed twice
|
||||
- 'result' is not properly cleaned for NRVO --> use uninit checking instead
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue