mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-10 05:38:10 +00:00
A minimal patch enabling the new typedesc and static types syntax
This commit is contained in:
@@ -571,8 +571,8 @@ type
|
||||
TMagic* = enum # symbols that require compiler magic:
|
||||
mNone,
|
||||
mDefined, mDefinedInScope, mCompiles, mArrGet, mArrPut, mAsgn,
|
||||
mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mTypeOf, mRoof, mPlugin,
|
||||
mEcho, mShallowCopy, mSlurp, mStaticExec,
|
||||
mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mType, mTypeOf,
|
||||
mRoof, mPlugin, mEcho, mShallowCopy, mSlurp, mStaticExec, mStatic,
|
||||
mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
|
||||
mUnaryLt, mInc, mDec, mOrd,
|
||||
mNew, mNewFinalize, mNewSeq, mNewSeqOfCap,
|
||||
|
||||
@@ -44,6 +44,7 @@ proc initDefines*(symbols: StringTableRef) =
|
||||
defineSymbol("nimcomputedgoto")
|
||||
defineSymbol("nimunion")
|
||||
defineSymbol("nimnewshared")
|
||||
defineSymbol("nimNewTypedesc")
|
||||
defineSymbol("nimrequiresnimframe")
|
||||
defineSymbol("nimparsebiggestfloatmagic")
|
||||
defineSymbol("nimalias")
|
||||
|
||||
@@ -50,6 +50,9 @@ type
|
||||
SymbolMode = enum
|
||||
smNormal, smAllowNil, smAfterDot
|
||||
|
||||
TPrimaryMode = enum
|
||||
pmNormal, pmTypeDesc, pmTypeDef, pmSkipSuffix
|
||||
|
||||
proc parseAll*(p: var TParser): PNode
|
||||
proc closeParser*(p: var TParser)
|
||||
proc parseTopLevelStmt*(p: var TParser): PNode
|
||||
@@ -81,6 +84,9 @@ proc parsePragma(p: var TParser): PNode
|
||||
proc postExprBlocks(p: var TParser, x: PNode): PNode
|
||||
proc parseExprStmt(p: var TParser): PNode
|
||||
proc parseBlock(p: var TParser): PNode
|
||||
proc primary(p: var TParser, mode: TPrimaryMode): PNode
|
||||
proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode
|
||||
|
||||
# implementation
|
||||
|
||||
proc getTok(p: var TParser) =
|
||||
@@ -332,6 +338,8 @@ proc colcom(p: var TParser, n: PNode) =
|
||||
eat(p, tkColon)
|
||||
skipComment(p, n)
|
||||
|
||||
const tkBuiltInMagics = {tkType, tkStatic, tkAddr}
|
||||
|
||||
proc parseSymbol(p: var TParser, mode = smNormal): PNode =
|
||||
#| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
||||
#| | IDENT | KEYW
|
||||
@@ -340,7 +348,7 @@ proc parseSymbol(p: var TParser, mode = smNormal): PNode =
|
||||
result = newIdentNodeP(p.tok.ident, p)
|
||||
getTok(p)
|
||||
of tokKeywordLow..tokKeywordHigh:
|
||||
if p.tok.tokType == tkAddr or p.tok.tokType == tkType or mode == smAfterDot:
|
||||
if p.tok.tokType in tkBuiltInMagics or mode == smAfterDot:
|
||||
# for backwards compatibility these 2 are always valid:
|
||||
result = newIdentNodeP(p.tok.ident, p)
|
||||
getTok(p)
|
||||
@@ -525,9 +533,6 @@ proc parseGStrLit(p: var TParser, a: PNode): PNode =
|
||||
else:
|
||||
result = a
|
||||
|
||||
type
|
||||
TPrimaryMode = enum pmNormal, pmTypeDesc, pmTypeDef, pmSkipSuffix
|
||||
|
||||
proc complexOrSimpleStmt(p: var TParser): PNode
|
||||
proc simpleExpr(p: var TParser, mode = pmNormal): PNode
|
||||
|
||||
@@ -625,7 +630,7 @@ proc identOrLiteral(p: var TParser, mode: TPrimaryMode): PNode =
|
||||
#| tupleConstr = '(' optInd (exprColonEqExpr comma?)* optPar ')'
|
||||
#| arrayConstr = '[' optInd (exprColonEqExpr comma?)* optPar ']'
|
||||
case p.tok.tokType
|
||||
of tkSymbol, tkType, tkAddr:
|
||||
of tkSymbol, tkBuiltInMagics:
|
||||
result = newIdentNodeP(p.tok.ident, p)
|
||||
getTok(p)
|
||||
result = parseGStrLit(p, result)
|
||||
@@ -741,7 +746,12 @@ proc commandParam(p: var TParser, isFirstParam: var bool): PNode =
|
||||
addSon(result, parseExpr(p))
|
||||
isFirstParam = false
|
||||
|
||||
proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
|
||||
const
|
||||
tkTypeClasses = {tkRef, tkPtr, tkVar, tkStatic, tkType,
|
||||
tkEnum, tkTuple, tkObject, tkProc}
|
||||
|
||||
proc primarySuffix(p: var TParser, r: PNode,
|
||||
baseIndent: int, mode: TPrimaryMode): PNode =
|
||||
#| primarySuffix = '(' (exprColonEqExpr comma?)* ')' doBlocks?
|
||||
#| | doBlocks
|
||||
#| | '.' optInd symbol generalizedLit?
|
||||
@@ -758,7 +768,14 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
|
||||
case p.tok.tokType
|
||||
of tkParLe:
|
||||
# progress guaranteed
|
||||
somePar()
|
||||
if p.tok.strongSpaceA > 0:
|
||||
# inside type sections, expressions such as `ref (int, bar)`
|
||||
# are parsed as a nkCommand with a single tuple argument (nkPar)
|
||||
if mode == pmTypeDef:
|
||||
result = newNodeP(nkCommand, p)
|
||||
result.addSon r
|
||||
result.addSon primary(p, pmNormal)
|
||||
break
|
||||
result = namedParams(p, result, nkCall, tkParRi)
|
||||
if result.len > 1 and result.sons[1].kind == nkExprColonExpr:
|
||||
result.kind = nkObjConstr
|
||||
@@ -774,9 +791,15 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
|
||||
# progress guaranteed
|
||||
somePar()
|
||||
result = namedParams(p, result, nkCurlyExpr, tkCurlyRi)
|
||||
of tkSymbol, tkAccent, tkIntLit..tkCharLit, tkNil, tkCast, tkAddr, tkType,
|
||||
tkOpr, tkDotDot:
|
||||
if p.inPragma == 0 and (isUnary(p) or p.tok.tokType notin {tkOpr, tkDotDot}):
|
||||
of tkSymbol, tkAccent, tkIntLit..tkCharLit, tkNil, tkCast,
|
||||
tkOpr, tkDotDot, tkTypeClasses - {tkRef, tkPtr}:
|
||||
# XXX: In type sections we allow the free application of the
|
||||
# command syntax, with the exception of expressions such as
|
||||
# `foo ref` or `foo ptr`. Unfortunately, these two are also
|
||||
# used as infix operators for the memory regions feature and
|
||||
# the current parsing rules don't play well here.
|
||||
if mode == pmTypeDef or
|
||||
(p.inPragma == 0 and (isUnary(p) or p.tok.tokType notin {tkOpr, tkDotDot})):
|
||||
# actually parsing {.push hints:off.} as {.push(hints:off).} is a sweet
|
||||
# solution, but pragmas.nim can't handle that
|
||||
let a = result
|
||||
@@ -800,9 +823,6 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
|
||||
else:
|
||||
break
|
||||
|
||||
proc primary(p: var TParser, mode: TPrimaryMode): PNode
|
||||
proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode
|
||||
|
||||
proc parseOperators(p: var TParser, headNode: PNode,
|
||||
limit: int, mode: TPrimaryMode): PNode =
|
||||
result = headNode
|
||||
@@ -1107,9 +1127,9 @@ proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode =
|
||||
proc isExprStart(p: TParser): bool =
|
||||
case p.tok.tokType
|
||||
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf,
|
||||
tkProc, tkFunc, tkIterator, tkBind, tkAddr,
|
||||
tkProc, tkFunc, tkIterator, tkBind, tkBuiltInMagics,
|
||||
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
|
||||
tkTuple, tkObject, tkType, tkWhen, tkCase, tkOut:
|
||||
tkTuple, tkObject, tkWhen, tkCase, tkOut:
|
||||
result = true
|
||||
else: result = false
|
||||
|
||||
@@ -1170,7 +1190,6 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
|
||||
#| | 'proc' | 'iterator' | 'distinct' | 'object' | 'enum'
|
||||
#| primary = typeKeyw typeDescK
|
||||
#| / prefixOperator* identOrLiteral primarySuffix*
|
||||
#| / 'static' primary
|
||||
#| / 'bind' primary
|
||||
if isOperator(p.tok):
|
||||
let isSigil = isSigilLike(p.tok)
|
||||
@@ -1183,7 +1202,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
|
||||
#XXX prefix operators
|
||||
let baseInd = p.lex.currLineIndent
|
||||
addSon(result, primary(p, pmSkipSuffix))
|
||||
result = primarySuffix(p, result, baseInd)
|
||||
result = primarySuffix(p, result, baseInd, mode)
|
||||
else:
|
||||
addSon(result, primary(p, pmNormal))
|
||||
return
|
||||
@@ -1213,14 +1232,6 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
|
||||
result = parseTypeClass(p)
|
||||
else:
|
||||
parMessage(p, "the 'concept' keyword is only valid in 'type' sections")
|
||||
of tkStatic:
|
||||
let info = parLineInfo(p)
|
||||
getTokNoInd(p)
|
||||
let next = primary(p, pmNormal)
|
||||
if next.kind == nkBracket and next.sonsLen == 1:
|
||||
result = newNode(nkStaticTy, info, @[next.sons[0]])
|
||||
else:
|
||||
result = newNode(nkStaticExpr, info, @[next])
|
||||
of tkBind:
|
||||
result = newNodeP(nkBind, p)
|
||||
getTok(p)
|
||||
@@ -1235,7 +1246,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
|
||||
let baseInd = p.lex.currLineIndent
|
||||
result = identOrLiteral(p, mode)
|
||||
if mode != pmSkipSuffix:
|
||||
result = primarySuffix(p, result, baseInd)
|
||||
result = primarySuffix(p, result, baseInd, mode)
|
||||
|
||||
proc parseTypeDesc(p: var TParser): PNode =
|
||||
#| typeDesc = simpleExpr
|
||||
|
||||
@@ -48,6 +48,9 @@ proc semQuoteAst(c: PContext, n: PNode): PNode
|
||||
proc finishMethod(c: PContext, s: PSym)
|
||||
proc evalAtCompileTime(c: PContext, n: PNode): PNode
|
||||
proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
|
||||
proc semStaticExpr(c: PContext, n: PNode): PNode
|
||||
proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType
|
||||
proc semTypeOf(c: PContext; n: PNode): PNode
|
||||
|
||||
proc isArrayConstr(n: PNode): bool {.inline.} =
|
||||
result = n.kind == nkBracket and
|
||||
|
||||
@@ -191,7 +191,25 @@ proc semConv(c: PContext, n: PNode): PNode =
|
||||
return n
|
||||
|
||||
result = newNodeI(nkConv, n.info)
|
||||
var targetType = semTypeNode(c, n.sons[0], nil).skipTypes({tyTypeDesc})
|
||||
|
||||
var targetType = semTypeNode(c, n.sons[0], nil)
|
||||
if targetType.kind == tyTypeDesc:
|
||||
internalAssert targetType.len > 0
|
||||
if targetType.base.kind == tyNone:
|
||||
return semTypeOf(c, n[1])
|
||||
else:
|
||||
targetType = targetType.base
|
||||
elif targetType.kind == tyStatic:
|
||||
var evaluated = semStaticExpr(c, n[1])
|
||||
if evaluated.kind == nkType or evaluated.typ.kind == tyTypeDesc:
|
||||
result = n
|
||||
result.typ = c.makeTypeDesc semStaticType(c, evaluated, nil)
|
||||
return
|
||||
elif targetType.base.kind == tyNone:
|
||||
return evaluated
|
||||
else:
|
||||
targetType = targetType.base
|
||||
|
||||
maybeLiftType(targetType, c, n[0].info)
|
||||
|
||||
if targetType.kind in {tySink, tyLent}:
|
||||
@@ -632,7 +650,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
||||
# echo "SUCCESS evaluated at compile time: ", call.renderTree
|
||||
|
||||
proc semStaticExpr(c: PContext, n: PNode): PNode =
|
||||
let a = semExpr(c, n.sons[0])
|
||||
let a = semExpr(c, n)
|
||||
if a.findUnresolvedStatic != nil: return a
|
||||
result = evalStaticExpr(c.module, c.graph, a, c.p.owner)
|
||||
if result.isNil:
|
||||
@@ -1034,7 +1052,7 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||
of skType:
|
||||
markUsed(c.config, n.info, s, c.graph.usageSym)
|
||||
styleCheckUse(n.info, s)
|
||||
if s.typ.kind == tyStatic and s.typ.n != nil:
|
||||
if s.typ.kind == tyStatic and s.typ.base.kind != tyNone and s.typ.n != nil:
|
||||
return s.typ.n
|
||||
result = newSymNode(s, n.info)
|
||||
result.typ = makeTypeDesc(c, s.typ)
|
||||
@@ -1261,8 +1279,18 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||
# make sure we don't evaluate generic macros/templates
|
||||
n.sons[0] = semExprWithType(c, n.sons[0],
|
||||
{efNoEvaluateGeneric})
|
||||
let arr = skipTypes(n.sons[0].typ, {tyGenericInst,
|
||||
var arr = skipTypes(n.sons[0].typ, {tyGenericInst,
|
||||
tyVar, tyLent, tyPtr, tyRef, tyAlias, tySink})
|
||||
if arr.kind == tyStatic:
|
||||
if arr.base.kind == tyNone:
|
||||
result = n
|
||||
result.typ = semStaticType(c, n[1], nil)
|
||||
return
|
||||
elif arr.n != nil:
|
||||
return semSubscript(c, arr.n, flags)
|
||||
else:
|
||||
arr = arr.base
|
||||
|
||||
case arr.kind
|
||||
of tyArray, tyOpenArray, tyVarargs, tySequence, tyString,
|
||||
tyCString:
|
||||
@@ -2426,8 +2454,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
# handling of sym choices is context dependent
|
||||
# the node is left intact for now
|
||||
discard
|
||||
of nkStaticExpr:
|
||||
result = semStaticExpr(c, n)
|
||||
of nkStaticExpr: result = semStaticExpr(c, n[0])
|
||||
of nkAsgn: result = semAsgn(c, n)
|
||||
of nkBlockStmt, nkBlockExpr: result = semBlock(c, n)
|
||||
of nkStmtList, nkStmtListExpr: result = semStmtList(c, n, flags)
|
||||
|
||||
@@ -37,6 +37,12 @@ const
|
||||
errNoGenericParamsAllowedForX = "no generic parameters allowed for $1"
|
||||
errInOutFlagNotExtern = "the '$1' modifier can be used only with imported types"
|
||||
|
||||
const
|
||||
mStaticTy = {mStatic}
|
||||
mTypeTy = {mType, mTypeOf}
|
||||
# XXX: This should be needed only temporarily until the C
|
||||
# sources are rebuilt
|
||||
|
||||
proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
|
||||
if prev == nil:
|
||||
result = newTypeS(kind, c)
|
||||
@@ -363,6 +369,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||
if result != nil:
|
||||
markUsed(c.config, n.info, result, c.graph.usageSym)
|
||||
styleCheckUse(n.info, result)
|
||||
|
||||
if result.kind == skParam and result.typ.kind == tyTypeDesc:
|
||||
# This is a typedesc param. is it already bound?
|
||||
# it's not bound when it's used multiple times in the
|
||||
@@ -388,8 +395,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||
else:
|
||||
localError(c.config, n.info, errTypeExpected)
|
||||
return errorSym(c, n)
|
||||
|
||||
if result.kind != skType:
|
||||
if result.kind != skType and result.magic notin (mStaticTy + mTypeTy):
|
||||
# this implements the wanted ``var v: V, x: V`` feature ...
|
||||
var ov: TOverloadIter
|
||||
var amb = initOverloadIter(ov, c, n)
|
||||
@@ -856,9 +862,9 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||
result = addImplicitGenericImpl(c, newTypeS(tyGenericParam, c), nil)
|
||||
|
||||
of tyStatic:
|
||||
# proc(a: expr{string}, b: expr{nkLambda})
|
||||
# overload on compile time values and AST trees
|
||||
if paramType.n != nil: return # this is a concrete type
|
||||
if paramType.base.kind != tyNone and paramType.n != nil:
|
||||
# this is a concrete type
|
||||
return
|
||||
if tfUnresolved in paramType.flags: return # already lifted
|
||||
let base = paramType.base.maybeLift
|
||||
if base.isMetaType and procKind == skMacro:
|
||||
@@ -879,7 +885,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||
of tyDistinct:
|
||||
if paramType.sonsLen == 1:
|
||||
# disable the bindOnce behavior for the type class
|
||||
result = liftingWalk(paramType.sons[0], true)
|
||||
result = liftingWalk(paramType.base, true)
|
||||
|
||||
of tySequence, tySet, tyArray, tyOpenArray,
|
||||
tyVar, tyLent, tyPtr, tyRef, tyProc:
|
||||
@@ -1349,6 +1355,12 @@ proc symFromExpectedTypeNode(c: PContext, n: PNode): PSym =
|
||||
localError(c.config, n.info, errTypeExpected)
|
||||
result = errorSym(c, n)
|
||||
|
||||
proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType =
|
||||
result = newOrPrevType(tyStatic, prev, c)
|
||||
var base = semTypeNode(c, childNode, nil).skipTypes({tyTypeDesc, tyAlias})
|
||||
result.rawAddSon(base)
|
||||
result.flags.incl tfHasStatic
|
||||
|
||||
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = nil
|
||||
inc c.inTypeContext
|
||||
@@ -1456,7 +1468,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
of mSeq: result = semContainer(c, n, tySequence, "seq", prev)
|
||||
of mOpt: result = semContainer(c, n, tyOpt, "opt", prev)
|
||||
of mVarargs: result = semVarargs(c, n, prev)
|
||||
of mTypeDesc: result = makeTypeDesc(c, semTypeNode(c, n[1], nil))
|
||||
of mTypeDesc, mTypeTy: result = makeTypeDesc(c, semTypeNode(c, n[1], nil))
|
||||
of mStaticTy: result = semStaticType(c, n[1], prev)
|
||||
of mExpr:
|
||||
result = semTypeNode(c, n.sons[0], nil)
|
||||
if result != nil:
|
||||
@@ -1545,11 +1558,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
of nkPtrTy: result = semAnyRef(c, n, tyPtr, prev)
|
||||
of nkVarTy: result = semVarType(c, n, prev)
|
||||
of nkDistinctTy: result = semDistinct(c, n, prev)
|
||||
of nkStaticTy:
|
||||
result = newOrPrevType(tyStatic, prev, c)
|
||||
var base = semTypeNode(c, n.sons[0], nil).skipTypes({tyTypeDesc})
|
||||
result.rawAddSon(base)
|
||||
result.flags.incl tfHasStatic
|
||||
of nkStaticTy: result = semStaticType(c, n[0], prev)
|
||||
of nkIteratorTy:
|
||||
if n.sonsLen == 0:
|
||||
result = newTypeS(tyBuiltInTypeClass, c)
|
||||
@@ -1645,9 +1654,12 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||
of mStmt:
|
||||
setMagicType(c.config, m, tyStmt, 0)
|
||||
if m.name.s == "stmt": m.typ.flags.incl tfOldSchoolExprStmt
|
||||
of mTypeDesc:
|
||||
of mTypeDesc, mType:
|
||||
setMagicType(c.config, m, tyTypeDesc, 0)
|
||||
rawAddSon(m.typ, newTypeS(tyNone, c))
|
||||
of mStatic:
|
||||
setMagicType(m, tyStatic, 0)
|
||||
rawAddSon(m.typ, newTypeS(tyNone, c))
|
||||
of mVoidType:
|
||||
setMagicType(c.config, m, tyVoid, 0)
|
||||
of mArray:
|
||||
|
||||
@@ -1666,13 +1666,17 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
let prev = PType(idTableGet(c.bindings, f))
|
||||
if prev == nil:
|
||||
if aOrig.kind == tyStatic:
|
||||
result = typeRel(c, f.lastSon, a)
|
||||
if result != isNone and f.n != nil:
|
||||
if not exprStructuralEquivalent(f.n, aOrig.n):
|
||||
result = isNone
|
||||
if f.base.kind != tyNone:
|
||||
result = typeRel(c, f.base, a)
|
||||
if result != isNone and f.n != nil:
|
||||
if not exprStructuralEquivalent(f.n, aOrig.n):
|
||||
result = isNone
|
||||
else:
|
||||
result = isGeneric
|
||||
if result != isNone: put(c, f, aOrig)
|
||||
elif aOrig.n != nil and aOrig.n.typ != nil:
|
||||
result = typeRel(c, f.lastSon, aOrig.n.typ)
|
||||
result = if f.base.kind != tyNone: typeRel(c, f.lastSon, aOrig.n.typ)
|
||||
else: isGeneric
|
||||
if result != isNone:
|
||||
var boundType = newTypeWithSons(c.c, tyStatic, @[aOrig.n.typ])
|
||||
boundType.n = aOrig.n
|
||||
|
||||
@@ -179,10 +179,24 @@ proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} =
|
||||
## Cannot be overloaded.
|
||||
discard
|
||||
|
||||
proc `type`*(x: untyped): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
|
||||
## Builtin 'type' operator for accessing the type of an expression.
|
||||
## Cannot be overloaded.
|
||||
discard
|
||||
when defined(nimNewTypedesc):
|
||||
type
|
||||
`static`* {.magic: "Static".}[T]
|
||||
## meta type representing all values that can be evaluated at compile-time.
|
||||
##
|
||||
## The type coercion ``static(x)`` can be used to force the compile-time
|
||||
## evaluation of the given expression ``x``.
|
||||
|
||||
`type`* {.magic: "Type".}[T]
|
||||
## meta type representing the type of all type values.
|
||||
##
|
||||
## The coercion ``type(x)`` can be used to obtain the type of the given
|
||||
## expression ``x``.
|
||||
else:
|
||||
proc `type`*(x: untyped): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
|
||||
## Builtin 'type' operator for accessing the type of an expression.
|
||||
## Cannot be overloaded.
|
||||
discard
|
||||
|
||||
proc `not` *(x: bool): bool {.magic: "Not", noSideEffect.}
|
||||
## Boolean not; returns true iff ``x == false``.
|
||||
|
||||
@@ -4,7 +4,7 @@ discard """
|
||||
errormsg: "invalid indentation"
|
||||
"""
|
||||
|
||||
import strutils var s: seq[int] = @[0, 1, 2, 3, 4, 5, 6]
|
||||
import strutils let s: seq[int] = @[0, 1, 2, 3, 4, 5, 6]
|
||||
|
||||
#s[1..3] = @[]
|
||||
|
||||
|
||||
@@ -53,25 +53,33 @@ StmtList
|
||||
Par
|
||||
Ident "a"
|
||||
Ident "b"
|
||||
TypeDef
|
||||
Ident "BareStatic"
|
||||
Empty
|
||||
Ident "static"
|
||||
TypeDef
|
||||
Ident "GenericStatic"
|
||||
Empty
|
||||
StaticTy
|
||||
BracketExpr
|
||||
Ident "static"
|
||||
Ident "int"
|
||||
TypeDef
|
||||
Ident "PrefixStatic"
|
||||
Empty
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
Ident "int"
|
||||
TypeDef
|
||||
Ident "StaticTupleCl"
|
||||
Empty
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
TupleClassTy
|
||||
TypeDef
|
||||
Ident "StaticTuple"
|
||||
Empty
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
Par
|
||||
Ident "int"
|
||||
Ident "string"
|
||||
@@ -91,6 +99,12 @@ StmtList
|
||||
BracketExpr
|
||||
Ident "type"
|
||||
TupleClassTy
|
||||
TypeDef
|
||||
Ident "TypeTupleCl"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
TupleClassTy
|
||||
TypeDef
|
||||
Ident "TypeInstance"
|
||||
Empty
|
||||
@@ -109,6 +123,13 @@ StmtList
|
||||
Call
|
||||
Ident "type"
|
||||
Ident "a"
|
||||
TypeDef
|
||||
Ident "TypeOfVarAlt"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
Par
|
||||
Ident "a"
|
||||
TypeDef
|
||||
Ident "TypeOfTuple1"
|
||||
Empty
|
||||
@@ -122,6 +143,29 @@ StmtList
|
||||
Ident "type"
|
||||
Ident "a"
|
||||
Ident "b"
|
||||
TypeDef
|
||||
Ident "TypeOfTuple1A"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
TupleConstr
|
||||
Ident "a"
|
||||
TypeDef
|
||||
Ident "TypeOfTuple2A"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
Par
|
||||
Ident "a"
|
||||
Ident "b"
|
||||
TypeDef
|
||||
Ident "TypeTuple"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
Par
|
||||
Ident "int"
|
||||
Ident "string"
|
||||
TypeDef
|
||||
Ident "GenericTypedesc"
|
||||
Empty
|
||||
@@ -172,32 +216,52 @@ StmtList
|
||||
Ident "foo"
|
||||
Ident "type"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "typeTupleCl"
|
||||
Command
|
||||
Ident "type"
|
||||
TupleClassTy
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "bareStatic"
|
||||
Ident "static"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "genStatic"
|
||||
StaticTy
|
||||
BracketExpr
|
||||
Ident "static"
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticInt"
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticVal1"
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
IntLit 10
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticVal2"
|
||||
StaticExpr
|
||||
Par
|
||||
StrLit "str"
|
||||
Call
|
||||
Ident "static"
|
||||
StrLit "str"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticVal3"
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
StrLit "str"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticVal4"
|
||||
CallStrLit
|
||||
Ident "static"
|
||||
RStrLit "str"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticDotVal"
|
||||
DotExpr
|
||||
@@ -285,50 +349,32 @@ StmtList
|
||||
StmtList
|
||||
Asgn
|
||||
Ident "staticTen"
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
IntLit 10
|
||||
Asgn
|
||||
Ident "staticA"
|
||||
StaticExpr
|
||||
Par
|
||||
Ident "a"
|
||||
Asgn
|
||||
Ident "staticAspace"
|
||||
StaticExpr
|
||||
Par
|
||||
Ident "a"
|
||||
Asgn
|
||||
Ident "staticAtuple"
|
||||
StaticExpr
|
||||
TupleConstr
|
||||
Ident "a"
|
||||
Asgn
|
||||
Ident "staticTuple"
|
||||
StaticExpr
|
||||
Par
|
||||
Ident "a"
|
||||
Ident "b"
|
||||
Asgn
|
||||
Ident "staticTypeTuple"
|
||||
StaticExpr
|
||||
Par
|
||||
Ident "int"
|
||||
Ident "string"
|
||||
Call
|
||||
Ident "static"
|
||||
Ident "a"
|
||||
Asgn
|
||||
Ident "staticCall"
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
Call
|
||||
Ident "foo"
|
||||
IntLit 1
|
||||
Asgn
|
||||
Ident "staticStrCall"
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
CallStrLit
|
||||
Ident "foo"
|
||||
RStrLit "x"
|
||||
Asgn
|
||||
Ident "staticChainCall"
|
||||
StaticExpr
|
||||
Command
|
||||
Ident "static"
|
||||
Command
|
||||
Ident "foo"
|
||||
Ident "bar"
|
||||
@@ -399,7 +445,7 @@ dumpTree:
|
||||
RefTupleCl = ref tuple
|
||||
RefTupleType = ref (int, string)
|
||||
RefTupleVars = ref (a, b)
|
||||
# BareStatic = static # Error: invalid indentation
|
||||
BareStatic = static # Used to be Error: invalid indentation
|
||||
GenericStatic = static[int]
|
||||
PrefixStatic = static int
|
||||
StaticTupleCl = static tuple
|
||||
@@ -407,16 +453,16 @@ dumpTree:
|
||||
BareType = type
|
||||
GenericType = type[float]
|
||||
TypeTupleGen = type[tuple]
|
||||
# TypeTupleCl = type tuple # Error: invalid indentation
|
||||
TypeTupleCl = type tuple # Used to be Error: invalid indentation
|
||||
TypeInstance = type Foo[ref]
|
||||
bareTypeDesc = typedesc
|
||||
TypeOfVar = type(a)
|
||||
# TypeOfVarAlt= type (a) # Error: invalid indentation
|
||||
TypeOfVarAlt = type (a) # Used to be Error: invalid indentation
|
||||
TypeOfTuple1 = type(a,)
|
||||
TypeOfTuple2 = type(a,b)
|
||||
# TypeOfTuple1A = type (a,) # Error: invalid indentation
|
||||
# TypeOfTuple2A = type (a,b) # Error: invalid indentation
|
||||
# TypeTuple = type (int, string) # Error: invalid indentation
|
||||
TypeOfTuple1A = type (a,) # Used to be Error: invalid indentation
|
||||
TypeOfTuple2A = type (a,b) # Used to be Error: invalid indentation
|
||||
TypeTuple = type (int, string) # Used to be Error: invalid indentation
|
||||
GenericTypedesc = typedesc[int]
|
||||
T = type
|
||||
|
||||
@@ -427,14 +473,14 @@ dumpTree:
|
||||
typeIntAlt : type(int),
|
||||
typeOfVar : type(a),
|
||||
typeDotType : foo.type,
|
||||
# typeTupleCl : type tuple, # Error: ')' expected
|
||||
# bareStatic : static, # Error: expression expected, but found ','
|
||||
typeTupleCl : type tuple, # Used to be Error: ')' expected
|
||||
bareStatic : static, # Used to be Error: expression expected, but found ','
|
||||
genStatic : static[int],
|
||||
staticInt : static int,
|
||||
staticVal1 : static 10,
|
||||
staticVal2 : static("str"),
|
||||
staticVal3 : static "str",
|
||||
# staticVal4 : static"str", # Error: expression expected, but found 'str'
|
||||
staticVal4 : static"str", # Used to be Error: expression expected, but found 'str'
|
||||
staticDotVal : 10.static,
|
||||
bareRef : ref,
|
||||
refTuple1 : ref (int),
|
||||
@@ -451,10 +497,10 @@ dumpTree:
|
||||
): type =
|
||||
staticTen = static 10
|
||||
staticA = static(a)
|
||||
staticAspace = static (a)
|
||||
staticAtuple = static (a,)
|
||||
staticTuple = static (a,b)
|
||||
staticTypeTuple = static (int,string)
|
||||
# staticAspace = static (a) # With newTypedesc: Error: invalid indentation
|
||||
# staticAtuple = static (a,) # With newTypedesc: Error: invalid indentation
|
||||
# staticTuple = static (a,b) # With newTypedesc: Error: invalid indentation
|
||||
# staticTypeTuple = static (int,string) # With newTypedesc: Error: invalid indentation
|
||||
staticCall = static foo(1)
|
||||
staticStrCall = static foo"x"
|
||||
staticChainCall = static foo bar
|
||||
|
||||
Reference in New Issue
Block a user