syntax compatibility between do blocks and stmt blocks

See the section `do notation` in the manual for more info.

* nkMacroStmt has been removed
   Macro statements are now mapped to regular nkCall nodes.
   The support for additional clauses (such as else, except, of, etc)
   have been restored - they will now appear as additional arguments
   for the nkCall node (as nkElse, nkExcept, etc nodes)

* fixed some regressions in the `is` operator and semCompiles
This commit is contained in:
Zahary Karadjov
2012-10-03 21:11:41 +03:00
parent a6d5707faf
commit d9d82fb0af
21 changed files with 142 additions and 168 deletions

View File

@@ -145,7 +145,6 @@ type
nkElifBranch, # used in if statements
nkExceptBranch, # an except section
nkElse, # an else part
nkMacroStmt, # a macro statement
nkAsmStmt, # an assembler block
nkPragma, # a pragma statement
nkPragmaBlock, # a pragma with a block
@@ -911,6 +910,18 @@ proc newMetaNodeIT*(tree: PNode, info: TLineInfo, typ: PType): PNode =
result = newNodeIT(nkMetaNode, info, typ)
result.add(tree)
var emptyParams = newNode(nkFormalParams)
emptyParams.addSon(emptyNode)
proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
params = emptyParams,
name, pattern, genericParams,
pragmas, exceptions = ast.emptyNode): PNode =
result = newNodeI(kind, info)
result.sons = @[name, pattern, genericParams, params,
pragmas, exceptions, body]
proc NewType(kind: TTypeKind, owner: PSym): PType =
new(result)
result.kind = kind

View File

@@ -1382,7 +1382,7 @@ proc nestedStatement(p: var TParser): PNode =
# Nimrod requires complex statements to be nested in whitespace!
const
complexStmt = {nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef,
nkTemplateDef, nkIteratorDef, nkMacroStmt, nkIfStmt,
nkTemplateDef, nkIteratorDef, nkIfStmt,
nkWhenStmt, nkForStmt, nkWhileStmt, nkCaseStmt, nkVarSection,
nkConstSection, nkTypeSection, nkTryStmt, nkBlockStmt, nkStmtList,
nkCommentStmt, nkStmtListExpr, nkBlockExpr, nkStmtListType, nkBlockType}

View File

@@ -1296,7 +1296,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
of nkEmpty: result = n
of nkSym: result = evalSym(c, n, flags)
of nkType..nkNilLit: result = copyNode(n) # end of atoms
of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit, nkInfix,
of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkInfix,
nkPrefix, nkPostfix:
result = evalMagicOrCall(c, n)
of nkCurly, nkBracket, nkRange:

View File

@@ -101,4 +101,6 @@ proc getIdent*(identifier: string, h: THash): PIdent =
proc IdentEq*(id: PIdent, name: string): bool =
result = id.id == getIdent(name).id
let idAnon* = getIdent":anonymous"

View File

@@ -585,22 +585,25 @@ proc inCheckpoint*(current: TLineInfo): TCheckPointResult =
type
TErrorHandling = enum doNothing, doAbort, doRaise
proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
if msg == errInternal:
assert(false) # we want a stack trace here
proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
template maybeTrace =
if defined(debug) or gVerbosity >= 3:
writeStackTrace()
if msg == errInternal:
writeStackTrace() # we always want a stack trace here
if msg >= fatalMin and msg <= fatalMax:
if gVerbosity >= 3: assert(false)
maybeTrace()
quit(1)
if msg >= errMin and msg <= errMax:
if gVerbosity >= 3: assert(false)
maybeTrace()
inc(gErrorCounter)
options.gExitcode = 1'i8
if gErrorCounter >= gErrorMax or eh == doAbort:
if gVerbosity >= 3: assert(false)
quit(1) # one error stops the compiler
quit(1) # one error stops the compiler
elif eh == doRaise:
raiseRecoverableError(s)
proc `==`*(a, b: TLineInfo): bool =
result = a.line == b.line and a.fileIndex == b.fileIndex

View File

@@ -227,5 +227,7 @@ proc binaryStrSearch*(x: openarray[string], y: string): int =
result = - 1
# Can we keep this? I'm using it all the time
template nimdbg*: expr = c.filename.endsWith"nimdbg.nim"
template cnimdbg*: expr = p.module.filename.endsWith"nimdbg.nim"
template nimdbg*: expr = c.filename.endsWith"hallo.nim"
template cnimdbg*: expr = p.module.filename.endsWith"hallo.nim"
template enimdbg*: expr = c.module.name.s == "hallo"
template pnimdbg*: expr = p.lex.fileIdx.ToFilename.endsWith"hallo.nim"

View File

@@ -693,20 +693,15 @@ proc optPragmas(p: var TParser): PNode =
else: result = ast.emptyNode
proc parseDoBlock(p: var TParser): PNode =
var info = parLineInfo(p)
let info = parLineInfo(p)
getTok(p)
var params = parseParamList(p, retColon=false)
var pragmas = optPragmas(p)
let params = parseParamList(p, retColon=false)
let pragmas = optPragmas(p)
eat(p, tkColon)
result = newNodeI(nkDo, info)
addSon(result, ast.emptyNode) # no name part
addSon(result, ast.emptyNode) # no pattern part
addSon(result, ast.emptyNode) # no generic parameters
addSon(result, params)
addSon(result, pragmas)
skipComment(p, result)
addSon(result, ast.emptyNode) # no exception list
addSon(result, parseStmt(p))
result = newProcNode(nkDo, info, parseStmt(p),
params = params,
pragmas = pragmas)
proc parseDoBlocks(p: var TParser, call: PNode) =
while p.tok.tokType == tkDo:
@@ -723,16 +718,11 @@ proc parseProcExpr(p: var TParser, isExpr: bool): PNode =
params = parseParamList(p)
pragmas = optPragmas(p)
if p.tok.tokType == tkEquals and isExpr:
result = newNodeI(nkLambda, info)
addSon(result, ast.emptyNode) # no name part
addSon(result, ast.emptyNode) # no pattern
addSon(result, ast.emptyNode) # no generic parameters
addSon(result, params)
addSon(result, pragmas)
getTok(p)
skipComment(p, result)
addSon(result, ast.emptyNode) # no exception list
addSon(result, parseStmt(p))
result = newProcNode(nkLambda, info, parseStmt(p),
params = params,
pragmas = pragmas)
else:
result = newNodeI(nkProcTy, info)
if hasSignature:
@@ -822,7 +812,7 @@ proc primary(p: var TParser, skipSuffix = false): PNode =
proc parseTypeDesc(p: var TParser): PNode =
if p.tok.toktype == tkProc: result = parseProcExpr(p, false)
else: result = parseExpr(p)
proc parseExprStmt(p: var TParser): PNode =
var a = lowestExpr(p)
if p.tok.tokType == tkEquals:
@@ -832,32 +822,29 @@ proc parseExprStmt(p: var TParser): PNode =
result = newNodeI(nkAsgn, a.info)
addSon(result, a)
addSon(result, b)
else:
result = newNodeP(nkCommand, p)
result.info = a.info
addSon(result, a)
while true:
else:
var call = if a.kind == nkCall: a
else: newNode(nkCommand, a.info, @[a])
while true:
if not isExprStart(p): break
var e = parseExpr(p)
addSon(result, e)
addSon(call, e)
if p.tok.tokType != tkComma: break
getTok(p)
optInd(p, a)
if p.tok.tokType == tkDo:
parseDoBlocks(p, result)
parseDoBlocks(p, call)
return
if sonsLen(result) <= 1: result = a
else: a = result
result = if call.sonsLen <= 1: a
else: call
if p.tok.tokType == tkColon:
# macro statement
result = newNodeP(nkMacroStmt, p)
result.info = a.info
addSon(result, a)
result = call
getTok(p)
skipComment(p, result)
if p.tok.tokType == tkSad: getTok(p)
if not (p.tok.TokType in {tkOf, tkElif, tkElse, tkExcept}):
addSon(result, parseStmt(p))
if not (p.tok.TokType in {tkOf, tkElif, tkElse, tkExcept}):
let body = parseStmt(p)
addSon(result, newProcNode(nkDo, body.info, body))
while true:
if p.tok.tokType == tkSad: getTok(p)
var b: PNode
@@ -882,7 +869,7 @@ proc parseExprStmt(p: var TParser): PNode =
else: break
addSon(b, parseStmt(p))
addSon(result, b)
if b.kind == nkElse: break
if b.kind == nkElse: break
proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode =
var a: PNode

View File

@@ -1051,7 +1051,6 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
of nkWhileStmt: gwhile(g, n)
of nkPragmaBlock: gpragmaBlock(g, n)
of nkCaseStmt, nkRecCase: gcase(g, n)
of nkMacroStmt: gmacro(g, n)
of nkTryStmt: gtry(g, n)
of nkForStmt, nkParForStmt: gfor(g, n)
of nkBlockStmt, nkBlockExpr: gblock(g, n)

View File

@@ -22,8 +22,7 @@ proc semPass*(): TPass
type
TExprFlag = enum
efLValue, efWantIterator, efInTypeof, efWantStmt,
efMacroStmt # expr to semcheck is a macro statement
efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType
TExprFlags = set[TExprFlag]
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
@@ -35,7 +34,7 @@ proc semProcBody(c: PContext, n: PNode): PNode
proc fitNode(c: PContext, formal: PType, arg: PNode): PNode
proc changeType(n: PNode, newType: PType)
proc semLambda(c: PContext, n: PNode): PNode
proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
proc semStmt(c: PContext, n: PNode): PNode
proc semParamList(c: PContext, n, genericParams: PNode, s: PSym)
@@ -44,6 +43,8 @@ proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind)
proc addResultNode(c: PContext, n: PNode)
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
proc fixImmediateParams(n: PNode): PNode
proc activate(c: PContext, n: PNode)
proc typeMismatch(n: PNode, formal, actual: PType) =
if formal.kind != tyError and actual.kind != tyError:
@@ -91,8 +92,6 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
semCheck: bool = true): PNode
proc semMacroStmt(c: PContext, n: PNode, flags: TExprFlags,
semCheck = true): PNode
proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode
proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode

View File

@@ -304,16 +304,17 @@ proc semIs(c: PContext, n: PNode): PNode =
# BUGFIX: don't evaluate this too early: ``T is void``
if not containsGenericType(t1): result = evalIsOp(n)
proc semOpAux(c: PContext, n: PNode, tailToExclude = 1) =
for i in countup(1, sonsLen(n) - tailToExclude):
proc semOpAux(c: PContext, n: PNode) =
let flags = {efDetermineType}
for i in countup(1, n.sonsLen- 1):
var a = n.sons[i]
if a.kind == nkExprEqExpr and sonsLen(a) == 2:
var info = a.sons[0].info
a.sons[0] = newIdentNode(considerAcc(a.sons[0]), info)
a.sons[1] = semExprWithType(c, a.sons[1])
a.sons[1] = semExprWithType(c, a.sons[1], flags)
a.typ = a.sons[1].typ
else:
n.sons[i] = semExprWithType(c, a)
n.sons[i] = semExprWithType(c, a, flags)
proc overloadedCallOpr(c: PContext, n: PNode): PNode =
# quick check if there is *any* () operator overloaded:
@@ -668,8 +669,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
# this seems to be a hotspot in the compiler!
let nOrig = n.copyTree
semOpAux(c, n, 1 + ord(efMacroStmt in flags))
let flags = flags - {efMacroStmt}
semOpAux(c, n)
result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
if result == nil:
result = overloadedCallOpr(c, n)
@@ -679,8 +679,9 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
let callee = result.sons[0].sym
case callee.kind
of skMacro: result = semMacroExpr(c, result, nOrig, callee)
of skTemplate: result = semTemplateExpr(c, nOrig, callee)
of skTemplate: result = semTemplateExpr(c, result, callee)
else:
activate(c, n)
fixAbstractType(c, result)
analyseIfAddressTakenInCall(c, result)
if callee.magic != mNone:
@@ -1281,7 +1282,7 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode =
# we replace this node by a 'true' or 'false' node:
if sonsLen(n) != 2: return semDirectOp(c, n, flags)
result = newIntNode(nkIntLit, ord(tryExpr(c, n, flags) != nil))
result = newIntNode(nkIntLit, ord(tryExpr(c, n[1], flags) != nil))
result.info = n.info
result.typ = getSysType(tyBool)
@@ -1496,52 +1497,6 @@ proc buildCall(n: PNode): PNode =
else:
result = n
proc semMacroStmt(c: PContext, n: PNode, flags: TExprFlags,
semCheck = true): PNode =
checkMinSonsLen(n, 2)
var a: PNode
if isCallExpr(n.sons[0]): a = n.sons[0].sons[0]
else: a = n.sons[0]
var s = qualifiedLookup(c, a, {checkUndeclared})
if s != nil:
# transform
# nkMacroStmt(nkCall(a...), stmt, b...)
# to
# nkCall(a..., stmt, b...)
result = newNodeI(nkCall, n.info)
addSon(result, a)
if isCallExpr(n.sons[0]):
for i in countup(1, sonsLen(n.sons[0]) - 1):
addSon(result, n.sons[0].sons[i])
# for sigmatch this need to have a type; we use 'void':
for i in countup(1, sonsLen(n) - 1):
n.sons[i].typ = newTypeS(tyEmpty, c)
addSon(result, n.sons[i])
case s.kind
of skMacro:
if sfImmediate notin s.flags:
result = semDirectOp(c, result, flags+{efMacroStmt})
else:
result = semMacroExpr(c, result, n, s, semCheck)
of skTemplate:
if sfImmediate notin s.flags:
result = semDirectOp(c, result, flags+{efMacroStmt})
else:
result = semTemplateExpr(c, result, s, semCheck)
else:
LocalError(n.info, errXisNoMacroOrTemplate, s.name.s)
result = errorNode(c, n)
elif a.kind == nkDotExpr:
# 'x.m(y): stmt' == nkMacroStmt(nkCall(nkDotExpr(x, m), y), stmt)
# --> nkMacroStmt(nkCall(m, x, y), stmt)
n.sons[0] = buildCall(n.sons[0])
result = semMacroStmt(c, n, flags, semCheck)
else:
LocalError(n.info, errInvalidExpressionX,
renderTree(a, {renderNoComments}))
result = errorNode(c, n)
proc semCaseExpr(c: PContext, caseStmt: PNode): PNode =
# The case expression is simply rewritten to a StmtListExpr:
# var res {.noInit, genSym.}: type(values)
@@ -1553,7 +1508,7 @@ proc semCaseExpr(c: PContext, caseStmt: PNode): PNode =
# res
var
info = caseStmt.info
resVar = newSym(skVar, getIdent":res", getCurrOwner(), info)
resVar = newSym(skVar, idAnon, getCurrOwner(), info)
resNode = newSymNode(resVar, info)
resType: PType
@@ -1592,7 +1547,15 @@ proc semCaseExpr(c: PContext, caseStmt: PNode): PNode =
resNode])
result = semStmtListExpr(c, result)
proc fixImmediateParams(n: PNode): PNode =
# XXX: Temporary work-around until we carry out
# the planned overload resolution reforms
for i in 1 .. <n.len:
if n[i].kind == nkDo: n.sons[i] = n[i][bodyPos]
result = n
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result = n
if gCmd == cmdIdeTools: suggestExpr(c, n)
@@ -1670,12 +1633,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
if sfImmediate notin s.flags:
result = semDirectOp(c, n, flags)
else:
result = semMacroExpr(c, n, n, s)
var p = fixImmediateParams(n)
result = semMacroExpr(c, p, p, s)
of skTemplate:
if sfImmediate notin s.flags:
result = semDirectOp(c, n, flags)
else:
result = semTemplateExpr(c, n, s)
var p = fixImmediateParams(n)
result = semTemplateExpr(c, p, s)
of skType:
# XXX think about this more (``set`` procs)
if n.len == 2:
@@ -1695,8 +1660,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result = semDirectOp(c, n, flags)
else:
result = semIndirectOp(c, n, flags)
of nkMacroStmt:
result = semMacroStmt(c, n, flags)
of nkWhen:
if efWantStmt in flags:
result = semWhen(c, n, true)
@@ -1725,7 +1688,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of paSingle: result = semExpr(c, n.sons[0], flags)
of nkCurly: result = semSetConstr(c, n)
of nkBracket: result = semArrayConstr(c, n)
of nkLambdaKinds: result = semLambda(c, n)
of nkLambdaKinds: result = semLambda(c, n, flags)
of nkDerefExpr: result = semDeref(c, n)
of nkAddr:
result = n

View File

@@ -53,6 +53,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode =
result = symChoice(c, n, s, scOpen)
of skTemplate:
if macroToExpand(s):
let n = fixImmediateParams(n)
result = semTemplateExpr(c, n, s, false)
else:
result = symChoice(c, n, s, scOpen)
@@ -123,6 +124,7 @@ proc semGenericStmt(c: PContext, n: PNode,
result = n
of skTemplate:
if macroToExpand(s):
let n = fixImmediateParams(n)
result = semTemplateExpr(c, n, s, false)
else:
n.sons[0] = symChoice(c, n.sons[0], s, scOpen)
@@ -151,17 +153,6 @@ proc semGenericStmt(c: PContext, n: PNode,
let flags = if isDefinedMagic: flags+{withinMixin} else: flags
for i in countup(first, sonsLen(result) - 1):
result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind)
of nkMacroStmt:
checkMinSonsLen(n, 2)
var a: PNode
if isCallExpr(n.sons[0]): a = n.sons[0].sons[0]
else: a = n.sons[0]
let luf = if withinMixin notin flags: {checkUndeclared} else: {}
var s = qualifiedLookup(c, a, luf)
if s != nil and macroToExpand(s):
result = semMacroStmt(c, n, {}, false)
for i in countup(0, sonsLen(result)-1):
result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind)
of nkIfStmt:
for i in countup(0, sonsLen(n)-1):
n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, toBind)

View File

@@ -623,9 +623,9 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode =
var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
let m = lookupMacro(c, key)
if m == nil: continue
# we transform ``proc p {.m, rest.}`` into ``m: proc p {.rest.}`` and
# we transform ``proc p {.m, rest.}`` into ``m(proc p {.rest.})`` and
# let the semantic checker deal with it:
var x = newNodeI(nkMacroStmt, n.info)
var x = newNodeI(nkCall, n.info)
x.add(newSymNode(m))
prc.sons[pragmasPos] = copyExcept(n, i)
if it.kind == nkExprColonExpr:
@@ -634,15 +634,19 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode =
x.add(prc)
# recursion assures that this works for multiple macro annotations too:
return semStmt(c, x)
proc semLambda(c: PContext, n: PNode): PNode =
proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
result = semProcAnnotation(c, n)
if result != nil: return result
result = n
checkSonsLen(n, bodyPos + 1)
var s = newSym(skProc, getIdent":anonymous", getCurrOwner(), n.info)
s.ast = n
n.sons[namePos] = newSymNode(s)
var s: PSym
if n[namePos].kind != nkSym:
s = newSym(skProc, idAnon, getCurrOwner(), n.info)
s.ast = n
n.sons[namePos] = newSymNode(s)
else:
s = n[namePos].sym
pushOwner(s)
openScope(c.tab)
if n.sons[genericParamsPos].kind != nkEmpty:
@@ -659,19 +663,31 @@ proc semLambda(c: PContext, n: PNode): PNode =
if n.sons[bodyPos].kind != nkEmpty:
if sfImportc in s.flags:
LocalError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s)
pushProcCon(c, s)
addResult(c, s.typ.sons[0], n.info, skProc)
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
n.sons[bodyPos] = transformBody(c.module, semBody, s)
addResultNode(c, n)
popProcCon(c)
if efDetermineType notin flags:
pushProcCon(c, s)
addResult(c, s.typ.sons[0], n.info, skProc)
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
n.sons[bodyPos] = transformBody(c.module, semBody, s)
addResultNode(c, n)
popProcCon(c)
sideEffectsCheck(c, s)
else:
LocalError(n.info, errImplOfXexpected, s.name.s)
sideEffectsCheck(c, s)
closeScope(c.tab) # close scope for parameters
popOwner()
result.typ = s.typ
proc activate(c: PContext, n: PNode) =
# XXX: This proc is part of my plan for getting rid of
# forward declarations. stay tuned.
case n.kind
of nkLambdaKinds:
discard semLambda(c, n, {})
of nkCallKinds:
for i in 1 .. <n.len: activate(c, n[i])
else:
nil
proc instantiateDestructor*(c: PContext, typ: PType): bool
proc doDestructorStuff(c: PContext, s: PSym, n: PNode) =

View File

@@ -64,10 +64,11 @@ proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode
proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode =
result = copyNode(n)
result.typ = ReplaceTypeVarsT(cl, n.typ)
if result.kind == nkSym: result.sym = ReplaceTypeVarsS(cl, n.sym)
for i in 0 .. safeLen(n)-1:
# XXX HACK: ``f(a, b)``, avoid to instantiate `f`
if i == 0: result.add(n[i])
else: result.add(ReplaceTypeVarsN(cl, n[i]))
else: result.add(prepareNode(cl, n[i]))
proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode =
if n == nil: return

View File

@@ -637,8 +637,12 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
of isGeneric:
inc(m.genericMatches)
if m.calleeSym != nil and m.calleeSym.kind in {skMacro, skTemplate}:
if f.kind == tyTypeDesc: result = arg
else: result = argOrig
if f.kind == tyStmt and argOrig.kind == nkDo:
result = argOrig[bodyPos]
elif f.kind == tyTypeDesc:
result = arg
else:
result = argOrig
else:
result = copyTree(arg)
result.typ = getInstantiatedType(c, arg, m, f)

View File

@@ -175,8 +175,7 @@ proc findClosestDot(n: PNode): PNode =
if result != nil: return
const
CallNodes = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit,
nkMacroStmt}
CallNodes = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit}
proc findClosestCall(n: PNode): PNode =
if n.kind in callNodes and msgs.inCheckpoint(n.info) == cpExact:

View File

@@ -38,7 +38,7 @@ type
nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit,
nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef,
nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,
nnkElifBranch, nnkExceptBranch, nnkElse, nnkMacroStmt,
nnkElifBranch, nnkExceptBranch, nnkElse,
nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt,
nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt,
nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection,

View File

@@ -22,7 +22,7 @@ type
PSurface* = ref TSurface ## a surface to draw onto
TSurface* {.pure, final.} = object
w*, h*: int
w*, h*: Natural
s*: sdl.PSurface
EGraphics* = object of EIO

View File

@@ -940,7 +940,7 @@ proc readIntoBuf(socket: TSocket, flags: int32): int =
socket.currPos = 0
template retRead(flags, readBytes: int) =
let res = socket.readIntoBuf(flags)
let res = socket.readIntoBuf(flags.int32)
if res <= 0:
if readBytes > 0:
return readBytes

View File

@@ -151,7 +151,7 @@ template require*(conditions: stmt): stmt {.immediate, dirty.} =
const AbortOnError {.inject.} = true
check conditions
macro expect*(exp: stmt): stmt {.immediate.} =
macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
let exp = callsite()
template expectBody(errorTypes, lineInfoLit: expr,
body: stmt): PNimrodNode {.dirty.} =
@@ -162,12 +162,11 @@ macro expect*(exp: stmt): stmt {.immediate.} =
except errorTypes:
nil
var expectCall = exp[0]
var body = exp[1]
var body = exp[exp.len - 1]
var errorTypes = newNimNode(nnkBracket)
for i in countup(1, expectCall.len - 1):
errorTypes.add(expectCall[i])
for i in countup(1, exp.len - 2):
errorTypes.add(exp[i])
result = getAst(expectBody(errorTypes, exp.lineinfo, body))

View File

@@ -1,5 +1,5 @@
discard """
output: "Got: 'nnkMacroStmt' hi"
output: "Got: 'nnkCall' hi"
"""
import
@@ -11,17 +11,15 @@ macro outterMacro*(n: stmt): stmt {.immediate.} =
proc innerProc(i: int): string =
echo "Using arg ! " & n.repr
result = "Got: '" & $n.kind & "' " & $j
if n.kind != TNimrodNodeKind.nnkMacroStmt:
error("Macro " & n[0].repr & " requires a block.")
var callNode = n[0]
expectKind(callNode, TNimrodNodeKind.nnkCall)
if callNode.len != 2 or callNode[1].kind != TNimrodNodeKind.nnkIdent:
expectKind(n, TNimrodNodeKind.nnkCall)
if n.len != 3 or n[1].kind != TNimrodNodeKind.nnkIdent:
error("Macro " & callNode.repr &
" requires the ident passed as parameter (eg: " & callNode.repr &
"(the_name_you_want)): statements.")
result = newNimNode(TNimrodNodeKind.nnkStmtList)
var ass : PNimrodNode = newNimNode(TNimrodNodeKind.nnkAsgn)
ass.add(newIdentNode(callNode[1].ident))
var ass : PNimrodNode = newNimNode(nnkAsgn)
ass.add(newIdentNode(n[1].ident))
ass.add(newStrLitNode(innerProc(4)))
result.add(ass)

View File

@@ -28,12 +28,12 @@ import
# `opened` is defined to `optional.hasValue`
macro using(e: expr): stmt {.immediate.} =
let e = callsite()
if e.len != 2:
if e.len != 3:
error "Using statement: unexpected number of arguments. Got " &
$e.len & ", expected: 1 or more variable assignments and a block"
var args = e[0]
var body = e[1]
var args = e
var body = e[2]
var
variables : seq[PNimrodNode]
@@ -41,8 +41,8 @@ macro using(e: expr): stmt {.immediate.} =
newSeq(variables, 0)
newSeq(closingCalls, 0)
for i in countup(1, args.len-1):
for i in countup(1, args.len-2):
if args[i].kind == nnkExprEqExpr:
var varName = args[i][0]
var varValue = args[i][1]