diff options
author | Neelesh Chandola <neelesh.chandola@outlook.com> | 2018-12-19 15:22:41 +0530 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-12-19 10:52:41 +0100 |
commit | 8e90ed06188ca27932028703b7f31640cdbfa99a (patch) | |
tree | 3bacbf604fe2d17b63da985173ede1c2956490b7 /compiler/semstmts.nim | |
parent | 3f917c8d914fdd26023703acd046dc2b4a8105dd (diff) | |
download | Nim-8e90ed06188ca27932028703b7f31640cdbfa99a.tar.gz |
Const tuple unpacking (#9964)
* tuple unpacking is now supported for consts * Move nkConstTuple to the end of TNodeKind * Add nnkConstTuple in macros.nim * Fix Formatting
Diffstat (limited to 'compiler/semstmts.nim')
-rw-r--r-- | compiler/semstmts.nim | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 4d6c6dfb0..9bc5fa432 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -542,17 +542,17 @@ proc semConst(c: PContext, n: PNode): PNode = var a = n.sons[i] if c.config.cmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue - if a.kind != nkConstDef: illFormedAst(a, c.config) - checkSonsLen(a, 3, c.config) - var v = semIdentDef(c, a.sons[0], skConst) - styleCheckDef(c.config, v) - onDef(a[0].info, v) + if a.kind notin {nkConstDef, nkConstTuple}: illFormedAst(a, c.config) + checkMinSonsLen(a, 3, c.config) + var length = sonsLen(a) + var typ: PType = nil - if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil) + if a.sons[length-2].kind != nkEmpty: + typ = semTypeNode(c, a.sons[length-2], nil) - var def = semConstExpr(c, a.sons[2]) + var def = semConstExpr(c, a.sons[length-1]) if def == nil: - localError(c.config, a.sons[2].info, errConstExprExpected) + localError(c.config, a.sons[length-1].info, errConstExprExpected) continue # check type compatibility between def.typ and typ: if typ != nil: @@ -560,21 +560,43 @@ proc semConst(c: PContext, n: PNode): PNode = else: typ = def.typ if typ == nil: - localError(c.config, a.sons[2].info, errConstExprExpected) + localError(c.config, a.sons[length-1].info, errConstExprExpected) continue if typeAllowed(typ, skConst) != nil and def.kind != nkNilLit: localError(c.config, a.info, "invalid type for const: " & typeToString(typ)) continue - setVarType(c, v, typ) - v.ast = def # no need to copy - if sfGenSym notin v.flags: addInterfaceDecl(c, v) - elif v.owner == nil: v.owner = getCurrOwner(c) - var b = newNodeI(nkConstDef, a.info) - if importantComments(c.config): b.comment = a.comment - addSon(b, newSymNode(v)) - addSon(b, a.sons[1]) - addSon(b, copyTree(def)) - addSon(result, b) + + var b: PNode + if a.kind == nkConstTuple: + if typ.kind != tyTuple: + localError(c.config, a.info, errXExpected, "tuple") + elif int(length/2) != sonsLen(typ): + localError(c.config, a.info, errWrongNumberOfVariables) + b = newNodeI(nkConstTuple, a.info) + newSons(b, length) + b.sons[length-2] = a.sons[length-2] + b.sons[length-1] = def + + for j in countup(0, length-3): + var v = semIdentDef(c, a.sons[j], skConst) + if sfGenSym notin v.flags: addInterfaceDecl(c, v) + elif v.owner == nil: v.owner = getCurrOwner(c) + styleCheckDef(c.config, v) + onDef(a[j].info, v) + + if a.kind != nkConstTuple: + setVarType(c, v, typ) + v.ast = def # no need to copy + b = newNodeI(nkConstDef, a.info) + if importantComments(c.config): b.comment = a.comment + addSon(b, newSymNode(v)) + addSon(b, a.sons[1]) + addSon(b, copyTree(def)) + else: + setVarType(c, v, typ.sons[j]) + v.ast = def[j] + b.sons[j] = newSymNode(v) + addSon(result,b) include semfields |