mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 21:43:33 +00:00
introduce nkTupleConstr AST node for unary tuple construction; breaking change
This commit is contained in:
@@ -5,6 +5,10 @@
|
||||
- The stdlib module ``future`` has been renamed to ``sugar``.
|
||||
- ``macros.callsite`` is now deprecated. Since the introduction of ``varargs``
|
||||
parameters this became unnecessary.
|
||||
- Anonymous tuples with a single element can now be written as ``(1,)`` with a
|
||||
trailing comma. The underlying AST is ``nnkTupleConst(newLit 1)`` for this
|
||||
example. ``nnkTupleConstr`` is a new node kind your macros need to be able
|
||||
to deal with!
|
||||
|
||||
#### Breaking changes in the standard library
|
||||
|
||||
|
||||
@@ -221,7 +221,8 @@ type
|
||||
nkGotoState, # used for the state machine (for iterators)
|
||||
nkState, # give a label to a code section (for iterators)
|
||||
nkBreakState, # special break statement for easier code generation
|
||||
nkFuncDef # a func
|
||||
nkFuncDef, # a func
|
||||
nkTupleConstr # a tuple constructor
|
||||
|
||||
TNodeKinds* = set[TNodeKind]
|
||||
|
||||
|
||||
@@ -2226,7 +2226,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||
genSeqConstr(p, n, d)
|
||||
else:
|
||||
genArrayConstr(p, n, d)
|
||||
of nkPar:
|
||||
of nkPar, nkTupleConstr:
|
||||
if isDeepConstExpr(n) and n.len != 0:
|
||||
exprComplexConst(p, n, d)
|
||||
else:
|
||||
@@ -2458,7 +2458,7 @@ proc genConstExpr(p: BProc, n: PNode): Rope =
|
||||
var cs: TBitSet
|
||||
toBitSet(n, cs)
|
||||
result = genRawSetData(cs, int(getSize(n.typ)))
|
||||
of nkBracket, nkPar, nkClosure:
|
||||
of nkBracket, nkPar, nkTupleConstr, nkClosure:
|
||||
var t = skipTypes(n.typ, abstractInst)
|
||||
if t.kind == tySequence:
|
||||
result = genConstSeq(p, n, n.typ)
|
||||
|
||||
@@ -323,7 +323,7 @@ proc gen(c: var Con; n: PNode) =
|
||||
of nkBreakStmt: genBreak(c, n)
|
||||
of nkTryStmt: genTry(c, n)
|
||||
of nkStmtList, nkStmtListExpr, nkChckRangeF, nkChckRange64, nkChckRange,
|
||||
nkBracket, nkCurly, nkPar, nkClosure, nkObjConstr:
|
||||
nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr:
|
||||
for x in n: gen(c, x)
|
||||
of nkPragmaBlock: gen(c, n.lastSon)
|
||||
of nkDiscardStmt: gen(c, n.sons[0])
|
||||
|
||||
@@ -151,7 +151,7 @@ proc getField(n: PNode; position: int): PSym =
|
||||
else: discard
|
||||
|
||||
proc packObject(x: PNode, typ: PType, res: pointer) =
|
||||
internalAssert x.kind in {nkObjConstr, nkPar}
|
||||
internalAssert x.kind in {nkObjConstr, nkPar, nkTupleConstr}
|
||||
# compute the field's offsets:
|
||||
discard typ.getSize
|
||||
for i in countup(ord(x.kind == nkObjConstr), sonsLen(x) - 1):
|
||||
@@ -260,14 +260,14 @@ proc unpackObject(x: pointer, typ: PType, n: PNode): PNode =
|
||||
# iterate over any actual field of 'n' ... if n is nil we need to create
|
||||
# the nkPar node:
|
||||
if n.isNil:
|
||||
result = newNode(nkPar)
|
||||
result = newNode(nkTupleConstr)
|
||||
result.typ = typ
|
||||
if typ.n.isNil:
|
||||
internalError("cannot unpack unnamed tuple")
|
||||
unpackObjectAdd(x, typ.n, result)
|
||||
else:
|
||||
result = n
|
||||
if result.kind notin {nkObjConstr, nkPar}:
|
||||
if result.kind notin {nkObjConstr, nkPar, nkTupleConstr}:
|
||||
globalError(n.info, "cannot map value from FFI")
|
||||
if typ.n.isNil:
|
||||
globalError(n.info, "cannot unpack unnamed tuple")
|
||||
|
||||
@@ -307,7 +307,7 @@ proc useMagic(p: PProc, name: string) =
|
||||
|
||||
proc isSimpleExpr(p: PProc; n: PNode): bool =
|
||||
# calls all the way down --> can stay expression based
|
||||
if n.kind in nkCallKinds+{nkBracketExpr, nkDotExpr, nkPar} or
|
||||
if n.kind in nkCallKinds+{nkBracketExpr, nkDotExpr, nkPar, nkTupleConstr} or
|
||||
(p.target == targetJS and n.kind in {nkObjConstr, nkBracket, nkCurly}):
|
||||
for c in n:
|
||||
if not p.isSimpleExpr(c): return false
|
||||
@@ -894,7 +894,7 @@ proc countJsParams(typ: PType): int =
|
||||
|
||||
const
|
||||
nodeKindsNeedNoCopy = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
||||
nkFloatLit..nkFloat64Lit, nkCurly, nkPar, nkObjConstr, nkStringToCString,
|
||||
nkFloatLit..nkFloat64Lit, nkCurly, nkPar, nkTupleConstr, nkObjConstr, nkStringToCString,
|
||||
nkCStringToString, nkCall, nkPrefix, nkPostfix, nkInfix,
|
||||
nkCommand, nkHiddenCallConv, nkCallStrLit}
|
||||
|
||||
@@ -1714,7 +1714,7 @@ proc genToArray(p: PProc; n: PNode; r: var TCompRes) =
|
||||
if x.kind == nkBracket:
|
||||
for i in countup(0, x.len - 1):
|
||||
let it = x[i]
|
||||
if it.kind == nkPar and it.len == 2:
|
||||
if it.kind in {nkPar, nkTupleConstr} and it.len == 2:
|
||||
if i > 0: r.res.add(", ")
|
||||
gen(p, it[0], a)
|
||||
gen(p, it[1], b)
|
||||
@@ -2309,7 +2309,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||
of nkClosure: gen(p, n[0], r)
|
||||
of nkCurly: genSetConstr(p, n, r)
|
||||
of nkBracket: genArrayConstr(p, n, r)
|
||||
of nkPar: genTupleConstr(p, n, r)
|
||||
of nkPar, nkTupleConstr: genTupleConstr(p, n, r)
|
||||
of nkObjConstr: genObjConstr(p, n, r)
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, r)
|
||||
of nkAddr, nkHiddenAddr:
|
||||
|
||||
@@ -399,6 +399,9 @@ proc exprColonEqExprListAux(p: var TParser, endTok: TTokType, result: PNode) =
|
||||
addSon(result, a)
|
||||
if p.tok.tokType != tkComma: break
|
||||
getTok(p)
|
||||
# (1,) produces a tuple expression
|
||||
if endTok == tkParRi and p.tok.tokType == tkParRi:
|
||||
result.kind = nkTupleConstr
|
||||
skipComment(p, a)
|
||||
optPar(p)
|
||||
eat(p, endTok)
|
||||
@@ -566,6 +569,9 @@ proc parsePar(p: var TParser): PNode =
|
||||
if p.tok.tokType == tkComma:
|
||||
getTok(p)
|
||||
skipComment(p, a)
|
||||
# (1,) produces a tuple expression:
|
||||
if p.tok.tokType == tkParRi:
|
||||
result.kind = nkTupleConstr
|
||||
# progress guaranteed
|
||||
while p.tok.tokType != tkParRi and p.tok.tokType != tkEof:
|
||||
var a = exprColonEqExpr(p)
|
||||
|
||||
@@ -423,7 +423,7 @@ proc processCompile(c: PContext, n: PNode) =
|
||||
result = ""
|
||||
|
||||
let it = if n.kind in nkPragmaCallKinds and n.len == 2: n.sons[1] else: n
|
||||
if it.kind == nkPar and it.len == 2:
|
||||
if it.kind in {nkPar, nkTupleConstr} and it.len == 2:
|
||||
let s = getStrLit(c, it, 0)
|
||||
let dest = getStrLit(c, it, 1)
|
||||
var found = parentDir(n.info.toFullPath) / s
|
||||
@@ -530,7 +530,7 @@ proc pragmaLine(c: PContext, n: PNode) =
|
||||
if n.kind in nkPragmaCallKinds and n.len == 2:
|
||||
n.sons[1] = c.semConstExpr(c, n.sons[1])
|
||||
let a = n.sons[1]
|
||||
if a.kind == nkPar:
|
||||
if a.kind in {nkPar, nkTupleConstr}:
|
||||
# unpack the tuple
|
||||
var x = a.sons[0]
|
||||
var y = a.sons[1]
|
||||
|
||||
@@ -437,6 +437,9 @@ proc lsub(g: TSrcGen; n: PNode): int =
|
||||
of nkCommand: result = lsub(g, n.sons[0]) + lcomma(g, n, 1) + 1
|
||||
of nkExprEqExpr, nkAsgn, nkFastAsgn: result = lsons(g, n) + 3
|
||||
of nkPar, nkCurly, nkBracket, nkClosure: result = lcomma(g, n) + 2
|
||||
of nkTupleConstr:
|
||||
# assume the trailing comma:
|
||||
result = lcomma(g, n) + 3
|
||||
of nkArgList: result = lcomma(g, n)
|
||||
of nkTableConstr:
|
||||
result = if n.len > 0: lcomma(g, n) + 2 else: len("{:}")
|
||||
@@ -1007,6 +1010,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||
put(g, tkParLe, "(")
|
||||
gcomma(g, n, c)
|
||||
put(g, tkParRi, ")")
|
||||
of nkTupleConstr:
|
||||
put(g, tkParLe, "(")
|
||||
gcomma(g, n, c)
|
||||
if n.len == 1: put(g, tkComma, ",")
|
||||
put(g, tkParRi, ")")
|
||||
of nkCurly:
|
||||
put(g, tkCurlyLe, "{")
|
||||
gcomma(g, n, c)
|
||||
|
||||
@@ -85,7 +85,7 @@ proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =
|
||||
result.typ = formal
|
||||
else:
|
||||
let x = result.skipConv
|
||||
if x.kind == nkPar and formal.kind != tyExpr:
|
||||
if x.kind in {nkPar, nkTupleConstr} and formal.kind != tyExpr:
|
||||
changeType(x, formal, check=true)
|
||||
else:
|
||||
result = skipHiddenSubConv(result)
|
||||
|
||||
@@ -215,7 +215,7 @@ proc semConv(c: PContext, n: PNode): PNode =
|
||||
# handle SomeProcType(SomeGenericProc)
|
||||
if op.kind == nkSym and op.sym.isGenericRoutine:
|
||||
result.sons[1] = fitNode(c, result.typ, result.sons[1], result.info)
|
||||
elif op.kind == nkPar and targetType.kind == tyTuple:
|
||||
elif op.kind in {nkPar, nkTupleConstr} and targetType.kind == tyTuple:
|
||||
op = fitNode(c, targetType, op, result.info)
|
||||
of convNotNeedeed:
|
||||
message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString)
|
||||
@@ -364,7 +364,7 @@ proc changeType(n: PNode, newType: PType, check: bool) =
|
||||
of nkCurly, nkBracket:
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
changeType(n.sons[i], elemType(newType), check)
|
||||
of nkPar:
|
||||
of nkPar, nkTupleConstr:
|
||||
let tup = newType.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||
if tup.kind != tyTuple:
|
||||
if tup.kind == tyObject: return
|
||||
@@ -1402,7 +1402,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||
result = buildOverloadedSubscripts(n.sons[0], getIdent"{}=")
|
||||
add(result, n[1])
|
||||
return semExprNoType(c, result)
|
||||
of nkPar:
|
||||
of nkPar, nkTupleConstr:
|
||||
if a.len >= 2:
|
||||
# unfortunately we need to rewrite ``(x, y) = foo()`` already here so
|
||||
# that overloading of the assignment operator still works. Usually we
|
||||
@@ -1521,10 +1521,10 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
|
||||
var e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink})
|
||||
if e.kind in {tyVar, tyLent}:
|
||||
if e.kind == tyVar: e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892
|
||||
if n.sons[0].kind == nkPar:
|
||||
if n.sons[0].kind in {nkPar, nkTupleConstr}:
|
||||
n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i], e.kind == tyLent)
|
||||
elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and
|
||||
n.sons[0].sons[1].kind == nkPar:
|
||||
n.sons[0].sons[1].kind in {nkPar, nkTupleConstr}:
|
||||
var a = n.sons[0].sons[1]
|
||||
a.sons[i] = takeImplicitAddr(c, a.sons[i], false)
|
||||
else:
|
||||
@@ -2047,12 +2047,12 @@ proc semTableConstr(c: PContext, n: PNode): PNode =
|
||||
var x = n.sons[i]
|
||||
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
||||
for j in countup(lastKey, i-1):
|
||||
var pair = newNodeI(nkPar, x.info)
|
||||
var pair = newNodeI(nkTupleConstr, x.info)
|
||||
pair.add(n.sons[j])
|
||||
pair.add(x[1])
|
||||
result.add(pair)
|
||||
|
||||
var pair = newNodeI(nkPar, x.info)
|
||||
var pair = newNodeI(nkTupleConstr, x.info)
|
||||
pair.add(x[0])
|
||||
pair.add(x[1])
|
||||
result.add(pair)
|
||||
@@ -2072,6 +2072,7 @@ proc checkPar(n: PNode): TParKind =
|
||||
result = paTuplePositions # ()
|
||||
elif length == 1:
|
||||
if n.sons[0].kind == nkExprColonExpr: result = paTupleFields
|
||||
elif n.kind == nkTupleConstr: result = paTuplePositions
|
||||
else: result = paSingle # (expr)
|
||||
else:
|
||||
if n.sons[0].kind == nkExprColonExpr: result = paTupleFields
|
||||
@@ -2088,7 +2089,7 @@ proc checkPar(n: PNode): TParKind =
|
||||
return paNone
|
||||
|
||||
proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
result = newNodeI(nkPar, n.info)
|
||||
result = newNodeI(nkTupleConstr, n.info)
|
||||
var typ = newTypeS(tyTuple, c)
|
||||
typ.n = newNodeI(nkRecList, n.info) # nkIdentDefs
|
||||
var ids = initIntSet()
|
||||
@@ -2113,6 +2114,7 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
|
||||
proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
result = n # we don't modify n, but compute the type:
|
||||
result.kind = nkTupleConstr
|
||||
var typ = newTypeS(tyTuple, c) # leave typ.n nil!
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
n.sons[i] = semExprWithType(c, n.sons[i], flags*{efAllowDestructor})
|
||||
@@ -2344,7 +2346,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
invalidPragma(n)
|
||||
|
||||
result = semExpr(c, n[0], flags)
|
||||
of nkPar:
|
||||
of nkPar, nkTupleConstr:
|
||||
case checkPar(n)
|
||||
of paNone: result = errorNode(c, n)
|
||||
of paTuplePositions:
|
||||
|
||||
@@ -427,7 +427,7 @@ proc foldArrayAccess(m: PSym, n: PNode): PNode =
|
||||
|
||||
var idx = getOrdValue(y)
|
||||
case x.kind
|
||||
of nkPar:
|
||||
of nkPar, nkTupleConstr:
|
||||
if idx >= 0 and idx < sonsLen(x):
|
||||
result = x.sons[int(idx)]
|
||||
if result.kind == nkExprColonExpr: result = result.sons[1]
|
||||
@@ -450,7 +450,7 @@ proc foldArrayAccess(m: PSym, n: PNode): PNode =
|
||||
proc foldFieldAccess(m: PSym, n: PNode): PNode =
|
||||
# a real field access; proc calls have already been transformed
|
||||
var x = getConstExpr(m, n.sons[0])
|
||||
if x == nil or x.kind notin {nkObjConstr, nkPar}: return
|
||||
if x == nil or x.kind notin {nkObjConstr, nkPar, nkTupleConstr}: return
|
||||
|
||||
var field = n.sons[1].sym
|
||||
for i in countup(ord(x.kind == nkObjConstr), sonsLen(x) - 1):
|
||||
@@ -624,7 +624,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
|
||||
# if a == nil: return nil
|
||||
# result.sons[i].sons[1] = a
|
||||
# incl(result.flags, nfAllConst)
|
||||
of nkPar:
|
||||
of nkPar, nkTupleConstr:
|
||||
# tuple constructor
|
||||
result = copyTree(n)
|
||||
if (sonsLen(n) > 0) and (n.sons[0].kind == nkExprColonExpr):
|
||||
|
||||
@@ -50,7 +50,7 @@ proc annotateType*(n: PNode, t: PType) =
|
||||
else:
|
||||
internalAssert(n.sons[i].kind == nkExprColonExpr)
|
||||
annotateType(n.sons[i].sons[1], field.typ)
|
||||
of nkPar:
|
||||
of nkPar, nkTupleConstr:
|
||||
if x.kind == tyTuple:
|
||||
n.typ = t
|
||||
for i in 0 ..< n.len:
|
||||
|
||||
@@ -73,7 +73,7 @@ proc expectIntLit(c: PContext, n: PNode): int =
|
||||
else: localError(n.info, errIntLiteralExpected)
|
||||
|
||||
proc semInstantiationInfo(c: PContext, n: PNode): PNode =
|
||||
result = newNodeIT(nkPar, n.info, n.typ)
|
||||
result = newNodeIT(nkTupleConstr, n.info, n.typ)
|
||||
let idx = expectIntLit(c, n.sons[1])
|
||||
let useFullPaths = expectIntLit(c, n.sons[2])
|
||||
let info = getInfoContext(idx)
|
||||
|
||||
@@ -552,7 +552,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
b.sons[length-2] = a.sons[length-2] # keep type desc for doc generator
|
||||
b.sons[length-1] = def
|
||||
addToVarSection(c, result, n, b)
|
||||
elif tup.kind == tyTuple and def.kind == nkPar and
|
||||
elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and
|
||||
a.kind == nkIdentDefs and a.len > 3:
|
||||
message(a.info, warnEachIdentIsTuple)
|
||||
|
||||
@@ -592,7 +592,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
addSon(b, copyTree(def))
|
||||
addToVarSection(c, result, n, b)
|
||||
else:
|
||||
if def.kind == nkPar: v.ast = def[j]
|
||||
if def.kind in {nkPar, nkTupleConstr}: v.ast = def[j]
|
||||
setVarType(v, tup.sons[j])
|
||||
b.sons[j] = newSymNode(v)
|
||||
checkNilable(v)
|
||||
|
||||
@@ -392,8 +392,8 @@ proc semAnonTuple(c: PContext, n: PNode, prev: PType): PType =
|
||||
if sonsLen(n) == 0:
|
||||
localError(n.info, errTypeExpected)
|
||||
result = newOrPrevType(tyTuple, prev, c)
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
addSonSkipIntLit(result, semTypeNode(c, n.sons[i], nil))
|
||||
for it in n:
|
||||
addSonSkipIntLit(result, semTypeNode(c, it, nil))
|
||||
|
||||
proc semTuple(c: PContext, n: PNode, prev: PType): PType =
|
||||
var typ: PType
|
||||
@@ -1341,6 +1341,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
|
||||
else:
|
||||
result = semAnonTuple(c, n, prev)
|
||||
of nkTupleConstr: result = semAnonTuple(c, n, prev)
|
||||
of nkCallKinds:
|
||||
let x = n[0]
|
||||
let ident = case x.kind
|
||||
|
||||
@@ -334,7 +334,7 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
|
||||
if skipTypes(e.typ, {tyGenericInst, tyAlias, tySink}).kind == tyTuple and
|
||||
c.transCon.forStmt.len != 3:
|
||||
e = skipConv(e)
|
||||
if e.kind == nkPar:
|
||||
if e.kind in {nkPar, nkTupleConstr}:
|
||||
for i in countup(0, sonsLen(e) - 1):
|
||||
var v = e.sons[i]
|
||||
if v.kind == nkExprColonExpr: v = v.sons[1]
|
||||
@@ -500,7 +500,7 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
|
||||
case arg.kind
|
||||
of nkEmpty..nkNilLit:
|
||||
result = paDirectMapping
|
||||
of nkPar, nkCurly, nkBracket:
|
||||
of nkPar, nkTupleConstr, nkCurly, nkBracket:
|
||||
result = paFastAsgn
|
||||
for i in countup(0, sonsLen(arg) - 1):
|
||||
if putArgInto(arg.sons[i], formal) != paDirectMapping: return
|
||||
@@ -745,7 +745,7 @@ proc transformExceptBranch(c: PTransf, n: PNode): PTransNode =
|
||||
proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
|
||||
# symbols that expand to a complex constant (array, etc.) should not be
|
||||
# inlined, unless it's the empty array:
|
||||
result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and
|
||||
result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkTupleConstr, nkBracket} and
|
||||
cnst.len != 0
|
||||
|
||||
proc commonOptimizations*(c: PSym, n: PNode): PNode =
|
||||
|
||||
@@ -97,7 +97,7 @@ proc isDeepConstExpr*(n: PNode): bool =
|
||||
result = true
|
||||
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
|
||||
result = isDeepConstExpr(n.sons[1])
|
||||
of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure, nkRange:
|
||||
of nkCurly, nkBracket, nkPar, nkTupleConstr, nkObjConstr, nkClosure, nkRange:
|
||||
for i in ord(n.kind == nkObjConstr) ..< n.len:
|
||||
if not isDeepConstExpr(n.sons[i]): return false
|
||||
if n.typ.isNil: result = true
|
||||
|
||||
@@ -418,14 +418,14 @@ proc setLenSeq(c: PCtx; node: PNode; newLen: int; info: TLineInfo) =
|
||||
let typ = node.typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc})
|
||||
let typeEntry = typ.sons[0].skipTypes(abstractInst+{tyRange}-{tyTypeDesc})
|
||||
let typeKind = case typeEntry.kind
|
||||
of tyUInt..tyUInt64: nkUIntLit
|
||||
of tyRange, tyEnum, tyBool, tyChar, tyInt..tyInt64: nkIntLit
|
||||
of tyFloat..tyFloat128: nkFloatLit
|
||||
of tyString: nkStrLit
|
||||
of tyObject: nkObjConstr
|
||||
of tySequence: nkNilLit
|
||||
of tyProc, tyTuple: nkPar
|
||||
else: nkEmpty
|
||||
of tyUInt..tyUInt64: nkUIntLit
|
||||
of tyRange, tyEnum, tyBool, tyChar, tyInt..tyInt64: nkIntLit
|
||||
of tyFloat..tyFloat128: nkFloatLit
|
||||
of tyString: nkStrLit
|
||||
of tyObject: nkObjConstr
|
||||
of tySequence: nkNilLit
|
||||
of tyProc, tyTuple: nkTupleConstr
|
||||
else: nkEmpty
|
||||
|
||||
let oldLen = node.len
|
||||
setLen(node.sons, newLen)
|
||||
@@ -939,7 +939,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
let rb = instr.regB
|
||||
let rc = instr.regC
|
||||
let bb = regs[rb].node
|
||||
let isClosure = bb.kind == nkPar
|
||||
let isClosure = bb.kind == nkTupleConstr
|
||||
let prc = if not isClosure: bb.sym else: bb.sons[0].sym
|
||||
if prc.offset < -1:
|
||||
# it's a callback:
|
||||
|
||||
@@ -186,7 +186,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
|
||||
if inst:
|
||||
# only named tuples have a node, unnamed tuples don't
|
||||
if t.n.isNil:
|
||||
result = newNodeX(nkPar)
|
||||
result = newNodeX(nkTupleConstr)
|
||||
for subType in t.sons:
|
||||
result.add mapTypeToAst(subType, info)
|
||||
else:
|
||||
|
||||
@@ -1560,7 +1560,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||
if t.callConv != ccClosure:
|
||||
result = newNodeIT(nkNilLit, info, t)
|
||||
else:
|
||||
result = newNodeIT(nkPar, info, t)
|
||||
result = newNodeIT(nkTupleConstr, info, t)
|
||||
result.add(newNodeIT(nkNilLit, info, t))
|
||||
result.add(newNodeIT(nkNilLit, info, t))
|
||||
of tyObject:
|
||||
@@ -1577,7 +1577,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||
for i in countup(0, int(lengthOrd(t)) - 1):
|
||||
addSon(result, getNullValue(elemType(t), info))
|
||||
of tyTuple:
|
||||
result = newNodeIT(nkPar, info, t)
|
||||
result = newNodeIT(nkTupleConstr, info, t)
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
addSon(result, getNullValue(t.sons[i], info))
|
||||
of tySet:
|
||||
@@ -1884,7 +1884,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||
of nkBracket: genArrayConstr(c, n, dest)
|
||||
of nkCurly: genSetConstr(c, n, dest)
|
||||
of nkObjConstr: genObjConstr(c, n, dest)
|
||||
of nkPar, nkClosure: genTupleConstr(c, n, dest)
|
||||
of nkPar, nkClosure, nkTupleConstr: genTupleConstr(c, n, dest)
|
||||
of nkCast:
|
||||
if allowCast in c.features:
|
||||
genConv(c, n, n.sons[1], dest, opcCast)
|
||||
|
||||
@@ -190,7 +190,7 @@ proc loadAny(p: var JsonParser, t: PType,
|
||||
of tyTuple:
|
||||
if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object")
|
||||
next(p)
|
||||
result = newNode(nkPar)
|
||||
result = newNode(nkTupleConstr)
|
||||
var i = 0
|
||||
while p.kind != jsonObjectEnd and p.kind != jsonEof:
|
||||
if p.kind != jsonString:
|
||||
|
||||
@@ -74,13 +74,13 @@ proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} =
|
||||
proc staticWalkDirImpl(path: string, relative: bool): PNode =
|
||||
result = newNode(nkBracket)
|
||||
for k, f in walkDir(path, relative):
|
||||
result.add newTree(nkPar, newIntNode(nkIntLit, k.ord),
|
||||
result.add newTree(nkTupleConstr, newIntNode(nkIntLit, k.ord),
|
||||
newStrNode(nkStrLit, f))
|
||||
|
||||
proc gorgeExWrapper(a: VmArgs) {.nimcall.} =
|
||||
let (s, e) = opGorge(getString(a, 0), getString(a, 1), getString(a, 2),
|
||||
a.currentLineInfo)
|
||||
setResult a, newTree(nkPar, newStrNode(nkStrLit, s), newIntNode(nkIntLit, e))
|
||||
setResult a, newTree(nkTupleConstr, newStrNode(nkStrLit, s), newIntNode(nkIntLit, e))
|
||||
|
||||
proc getProjectPathWrapper(a: VmArgs) {.nimcall.} =
|
||||
setResult a, gProjectPath
|
||||
|
||||
@@ -120,7 +120,7 @@ proc returnsNewExpr*(n: PNode): NewLocation =
|
||||
nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkOfBranch,
|
||||
nkElifBranch, nkElse, nkExceptBranch, nkFinally, nkCast:
|
||||
result = returnsNewExpr(n.lastSon)
|
||||
of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure,
|
||||
of nkCurly, nkBracket, nkPar, nkTupleConstr, nkObjConstr, nkClosure,
|
||||
nkIfExpr, nkIfStmt, nkWhenStmt, nkCaseStmt, nkTryStmt:
|
||||
result = newLit
|
||||
for i in ord(n.kind == nkObjConstr) ..< n.len:
|
||||
@@ -179,7 +179,7 @@ proc deps(w: var W; n: PNode) =
|
||||
for child in n:
|
||||
let last = lastSon(child)
|
||||
if last.kind == nkEmpty: continue
|
||||
if child.kind == nkVarTuple and last.kind == nkPar:
|
||||
if child.kind == nkVarTuple and last.kind in {nkPar, nkTupleConstr}:
|
||||
internalAssert child.len-2 == last.len
|
||||
for i in 0 .. child.len-3:
|
||||
deps(w, child.sons[i], last.sons[i], {})
|
||||
|
||||
@@ -82,7 +82,8 @@ type
|
||||
nnkGotoState,
|
||||
nnkState,
|
||||
nnkBreakState,
|
||||
nnkFuncDef
|
||||
nnkFuncDef,
|
||||
nnkTupleConstr
|
||||
|
||||
NimNodeKinds* = set[NimNodeKind]
|
||||
NimTypeKind* = enum # some types are no longer used, see ast.nim
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
discard """
|
||||
output: '''61, 125'''
|
||||
output: '''61, 125
|
||||
(Field0: 0) (Field0: 13)'''
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
proc `^` (a, b: int): int =
|
||||
result = 1
|
||||
for i in 1..b: result = result * a
|
||||
@@ -12,3 +15,12 @@ var n = (56, 3)
|
||||
m = (n[0] + m[1], m[1] ^ n[1])
|
||||
|
||||
echo m[0], ", ", m[1]
|
||||
|
||||
# also test we can produce unary anon tuples in a macro:
|
||||
macro mm(): untyped =
|
||||
result = newTree(nnkTupleConstr, newLit(13))
|
||||
|
||||
proc nowTuple(): (int,) =
|
||||
result = (0,)
|
||||
|
||||
echo nowTuple(), " ", mm()
|
||||
|
||||
Reference in New Issue
Block a user