mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 01:44:37 +00:00
var tuple unpacking works at compile time
This commit is contained in:
@@ -287,41 +287,52 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||
result = newNodeIT(nkCurly, info, t)
|
||||
else: InternalError("getNullValue: " & $t.kind)
|
||||
|
||||
proc evalVar(c: PEvalContext, n: PNode): PNode =
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
var a = n.sons[i]
|
||||
if a.kind == nkCommentStmt: continue
|
||||
if a.kind != nkIdentDefs: return raiseCannotEval(c, n.info)
|
||||
# XXX var (x, y) = z support?
|
||||
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):
|
||||
let a = n.sons[i]
|
||||
if a.kind == nkCommentStmt: continue
|
||||
#assert(a.sons[0].kind == nkSym) can happen for transformed vars
|
||||
if a.sons[2].kind != nkEmpty:
|
||||
result = evalAux(c, a.sons[2], {})
|
||||
if result.kind in {nkType..nkNilLit}:
|
||||
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:
|
||||
result = getNullValue(a.sons[0].typ, a.sons[0].info)
|
||||
if a.sons[0].kind == nkSym:
|
||||
var v = a.sons[0].sym
|
||||
IdNodeTablePut(c.tos.mapping, v, result)
|
||||
else:
|
||||
# assign to a.sons[0]:
|
||||
var x = result
|
||||
result = evalAux(c, a.sons[0], {})
|
||||
if isSpecial(result): return
|
||||
myreset(x)
|
||||
x.kind = result.kind
|
||||
x.typ = result.typ
|
||||
case x.kind
|
||||
of nkCharLit..nkInt64Lit: x.intVal = result.intVal
|
||||
of nkFloatLit..nkFloat64Lit: x.floatVal = result.floatVal
|
||||
of nkStrLit..nkTripleStrLit: x.strVal = result.strVal
|
||||
of nkIdent: x.ident = result.ident
|
||||
of nkSym: x.sym = result.sym
|
||||
if a.sons[2].kind != nkEmpty:
|
||||
result = evalVarValue(c, a.sons[2])
|
||||
if isSpecial(result): return
|
||||
else:
|
||||
if x.kind notin {nkEmpty..nkNilLit}:
|
||||
discardSons(x)
|
||||
for j in countup(0, sonsLen(result) - 1): addSon(x, result.sons[j])
|
||||
result = getNullValue(a.sons[0].typ, a.sons[0].info)
|
||||
if a.sons[0].kind == nkSym:
|
||||
var v = a.sons[0].sym
|
||||
IdNodeTablePut(c.tos.mapping, v, result)
|
||||
else:
|
||||
# assign to a.sons[0]:
|
||||
var x = result
|
||||
result = evalAux(c, a.sons[0], {})
|
||||
if isSpecial(result): return
|
||||
myreset(x)
|
||||
x.kind = result.kind
|
||||
x.typ = result.typ
|
||||
case x.kind
|
||||
of nkCharLit..nkInt64Lit: x.intVal = result.intVal
|
||||
of nkFloatLit..nkFloat64Lit: x.floatVal = result.floatVal
|
||||
of nkStrLit..nkTripleStrLit: x.strVal = result.strVal
|
||||
of nkIdent: x.ident = result.ident
|
||||
of nkSym: x.sym = result.sym
|
||||
else:
|
||||
if x.kind notin {nkEmpty..nkNilLit}:
|
||||
discardSons(x)
|
||||
for j in countup(0, sonsLen(result) - 1): addSon(x, result.sons[j])
|
||||
result = emptyNode
|
||||
|
||||
proc aliasNeeded(n: PNode, flags: TEvalFlags): bool =
|
||||
|
||||
@@ -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:
|
||||
for line in lines(i.toFullPath):
|
||||
addSourceLine i.fileIndex, line.string
|
||||
|
||||
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 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:
|
||||
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)
|
||||
v.typ = typ
|
||||
b = newNodeI(nkIdentDefs, a.info)
|
||||
if importantComments():
|
||||
@@ -394,7 +394,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
addSon(b, a.sons[length-2]) # keep type desc for doc generator
|
||||
addSon(b, copyTree(def))
|
||||
addSon(result, b)
|
||||
else:
|
||||
else:
|
||||
if def.kind == nkPar: v.ast = def[j]
|
||||
v.typ = tup.sons[j]
|
||||
b.sons[j] = newSymNode(v)
|
||||
checkNilable(v)
|
||||
|
||||
Reference in New Issue
Block a user