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,41 +287,52 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
result = newNodeIT(nkCurly, info, t)
|
result = newNodeIT(nkCurly, info, t)
|
||||||
else: InternalError("getNullValue: " & $t.kind)
|
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 =
|
proc evalVar(c: PEvalContext, n: PNode): PNode =
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
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 == 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
|
#assert(a.sons[0].kind == nkSym) can happen for transformed vars
|
||||||
if a.sons[2].kind != nkEmpty:
|
if a.kind == nkVarTuple:
|
||||||
result = evalAux(c, a.sons[2], {})
|
result = evalVarValue(c, a.lastSon)
|
||||||
if result.kind in {nkType..nkNilLit}:
|
if result.kind in {nkType..nkNilLit}:
|
||||||
result = result.copyNode
|
result = result.copyNode
|
||||||
if isSpecial(result): return
|
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:
|
else:
|
||||||
result = getNullValue(a.sons[0].typ, a.sons[0].info)
|
if a.sons[2].kind != nkEmpty:
|
||||||
if a.sons[0].kind == nkSym:
|
result = evalVarValue(c, a.sons[2])
|
||||||
var v = a.sons[0].sym
|
if isSpecial(result): return
|
||||||
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:
|
else:
|
||||||
if x.kind notin {nkEmpty..nkNilLit}:
|
result = getNullValue(a.sons[0].typ, a.sons[0].info)
|
||||||
discardSons(x)
|
if a.sons[0].kind == nkSym:
|
||||||
for j in countup(0, sonsLen(result) - 1): addSon(x, result.sons[j])
|
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
|
result = emptyNode
|
||||||
|
|
||||||
proc aliasNeeded(n: PNode, flags: TEvalFlags): bool =
|
proc aliasNeeded(n: PNode, flags: TEvalFlags): bool =
|
||||||
|
|
|
||||||
|
|
@ -798,11 +798,12 @@ proc addSourceLine*(fileIdx: int32, line: string) =
|
||||||
proc sourceLine*(i: TLineInfo): PRope =
|
proc sourceLine*(i: TLineInfo): PRope =
|
||||||
if i.fileIndex < 0: return nil
|
if i.fileIndex < 0: return nil
|
||||||
|
|
||||||
if not optPreserveOrigSource and
|
if not optPreserveOrigSource and fileInfos[i.fileIndex].lines.len == 0:
|
||||||
fileInfos[i.fileIndex].lines.len == 0:
|
try:
|
||||||
for line in lines(i.toFullPath):
|
for line in lines(i.toFullPath):
|
||||||
addSourceLine i.fileIndex, line.string
|
addSourceLine i.fileIndex, line.string
|
||||||
|
except EIO:
|
||||||
|
discard
|
||||||
InternalAssert i.fileIndex < fileInfos.len
|
InternalAssert i.fileIndex < fileInfos.len
|
||||||
# can happen if the error points to EOF:
|
# can happen if the error points to EOF:
|
||||||
if i.line > fileInfos[i.fileIndex].lines.len: return nil
|
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 '=':
|
# side of the '=':
|
||||||
if warnShadowIdent in gNotes and not identWithin(def, v.name):
|
if warnShadowIdent in gNotes and not identWithin(def, v.name):
|
||||||
Message(a.info, warnShadowIdent, v.name.s)
|
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 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
|
v.typ = typ
|
||||||
b = newNodeI(nkIdentDefs, a.info)
|
b = newNodeI(nkIdentDefs, a.info)
|
||||||
if importantComments():
|
if importantComments():
|
||||||
|
|
@ -395,6 +395,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
addSon(b, copyTree(def))
|
addSon(b, copyTree(def))
|
||||||
addSon(result, b)
|
addSon(result, b)
|
||||||
else:
|
else:
|
||||||
|
if def.kind == nkPar: v.ast = def[j]
|
||||||
v.typ = tup.sons[j]
|
v.typ = tup.sons[j]
|
||||||
b.sons[j] = newSymNode(v)
|
b.sons[j] = newSymNode(v)
|
||||||
checkNilable(v)
|
checkNilable(v)
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -15,6 +15,7 @@ version 0.9.4
|
||||||
Bugs
|
Bugs
|
||||||
====
|
====
|
||||||
|
|
||||||
|
- REPL: after an error no evaluation is performed for the next line
|
||||||
- simple closure iterator doesn't work
|
- simple closure iterator doesn't work
|
||||||
- docgen: sometimes effects are listed twice
|
- docgen: sometimes effects are listed twice
|
||||||
- 'result' is not properly cleaned for NRVO --> use uninit checking instead
|
- 'result' is not properly cleaned for NRVO --> use uninit checking instead
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue