diff options
author | Max Zerzouri <maxdamantus@gmail.com> | 2015-03-04 11:52:48 +1300 |
---|---|---|
committer | Max Zerzouri <maxdamantus@gmail.com> | 2015-03-06 12:23:31 +1300 |
commit | dba25d2622eb3b1414c847caa6d5a675ddc34344 (patch) | |
tree | 5f535a03c0d7e0d0a4fda7c3654fd2b76742ac49 /compiler | |
parent | 9c126282b2da1c3916627a81537a456e1aeb63c8 (diff) | |
download | Nim-dba25d2622eb3b1414c847caa6d5a675ddc34344.tar.gz |
enable syntax for anonymous tuples.
Turns out to be slightly problematic as `(int, int)` could be logically thought of as an expression evaluating to a tuple value containing two typedesc[int]s. To disambiguate, the zero-tuple's type must still be written as `tuple[]`, and what would be tuple value expressions containing only typedescs are interpreted as types. () # value of type `tuple[]` (int, int) # tuple type (int, int, ()) # value of type `(typedesc[int], typedesc[int], tuple[])`
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semexprs.nim | 17 | ||||
-rw-r--r-- | compiler/semtypes.nim | 13 | ||||
-rw-r--r-- | compiler/types.nim | 8 |
3 files changed, 31 insertions, 7 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 40d6ef0b2..5fa812f3a 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1866,6 +1866,14 @@ proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = addSonSkipIntLit(typ, n.sons[i].typ) result.typ = typ +proc isTupleType(n: PNode): bool = + if n.len == 0: + return false # don't interpret () as type + for i in countup(0, n.len - 1): + if n[i].typ == nil or n[i].typ.kind != tyTypeDesc: + return false + return true + proc checkInitialized(n: PNode, ids: IntSet, info: TLineInfo) = case n.kind of nkRecList: @@ -2129,7 +2137,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkPar: case checkPar(n) of paNone: result = errorNode(c, n) - of paTuplePositions: result = semTuplePositionsConstr(c, n, flags) + of paTuplePositions: + var tupexp = semTuplePositionsConstr(c, n, flags) + if isTupleType(tupexp): + # reinterpret as type + var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc, tyIter}) + result.typ = makeTypeDesc(c, typ) + else: + result = tupexp of paTupleFields: result = semTupleFieldsConstr(c, n, flags) of paSingle: result = semExpr(c, n.sons[0], flags) of nkCurly: result = semSetConstr(c, n) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 520c4154a..ac0636211 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -344,7 +344,14 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = else: localError(n.info, errIdentifierExpected) result = errorSym(c, n) - + +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)) + proc semTuple(c: PContext, n: PNode, prev: PType): PType = var typ: PType result = newOrPrevType(tyTuple, prev, c) @@ -1116,9 +1123,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkPar: if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) else: - # XXX support anon tuple here - localError(n.info, errTypeExpected) - result = newOrPrevType(tyError, prev, c) + result = semAnonTuple(c, n, prev) of nkCallKinds: if isRange(n): result = semRangeAux(c, n, prev) diff --git a/compiler/types.nim b/compiler/types.nim index 0cc5a212b..89a3c6f96 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -507,18 +507,22 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = if prefer == preferModuleInfo: preferModuleInfo else: preferName) of tyTuple: # we iterate over t.sons here, because t.n may be nil - result = "tuple[" if t.n != nil: + result = "tuple[" assert(sonsLen(t.n) == sonsLen(t)) for i in countup(0, sonsLen(t.n) - 1): assert(t.n.sons[i].kind == nkSym) add(result, t.n.sons[i].sym.name.s & ": " & typeToString(t.sons[i])) if i < sonsLen(t.n) - 1: add(result, ", ") + add(result, ']') + elif sonsLen(t) == 0: + result = "tuple[]" else: + result = "(" for i in countup(0, sonsLen(t) - 1): add(result, typeToString(t.sons[i])) if i < sonsLen(t) - 1: add(result, ", ") - add(result, ']') + add(result, ')') of tyPtr, tyRef, tyVar, tyMutable, tyConst: result = typeToStr[t.kind] if t.len >= 2: |