diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgmerge.nim | 2 | ||||
-rwxr-xr-x | compiler/ccgstmts.nim | 2 | ||||
-rwxr-xr-x | compiler/extccomp.nim | 2 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 44 | ||||
-rwxr-xr-x | compiler/semgnrc.nim | 35 | ||||
-rwxr-xr-x | compiler/types.nim | 2 |
6 files changed, 60 insertions, 27 deletions
diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index 8c490a693..df7e7f68b 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -228,7 +228,7 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) = when not defined(nimhygiene): {.pragma: inject.} -template withCFile(cfilename: string, body: stmt) = +template withCFile(cfilename: string, body: stmt) {.immediate.} = var s = LLStreamOpen(cfilename, fmRead) if s == nil: return var L {.inject.}: TBaseLexer diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 7a2eaec9c..dfa624821 100755 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -87,7 +87,7 @@ proc genSimpleBlock(p: BProc, stmts: PNode) {.inline.} = genStmts(p, stmts) endBlock(p) -template preserveBreakIdx(body: stmt): stmt = +template preserveBreakIdx(body: stmt): stmt {.immediate.} = var oldBreakIdx = p.breakIdx body p.breakIdx = oldBreakIdx diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index f6ce307d6..7b3dc0b3e 100755 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -50,7 +50,7 @@ type # When adding new compilers, the cmake sources could be a good reference: # http://cmake.org/gitweb?p=cmake.git;a=tree;f=Modules/Platform; -template compiler(name: expr, settings: stmt):stmt = +template compiler(name: expr, settings: stmt): stmt {.immediate.} = proc name: TInfoCC {.compileTime.} = settings compiler gcc: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index fc3ea1820..027cd0946 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1356,30 +1356,40 @@ proc semBlockExpr(c: PContext, n: PNode): PNode = closeScope(c.tab) Dec(c.p.nestedBlockCounter) -proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode = - # XXX why no overloading here? +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: - result = semMacroExpr(c, n, n, s, semCheck) + of skMacro: + if sfImmediate notin s.flags: + result = semDirectOp(c, result, flags) + else: + result = semMacroExpr(c, result, n, s, semCheck) of skTemplate: - # 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 i in countup(1, sonsLen(n) - 1): addSon(result, n.sons[i]) - result = semTemplateExpr(c, result, s, semCheck) - else: + if sfImmediate notin s.flags: + result = semDirectOp(c, result, flags) + else: + result = semTemplateExpr(c, result, s, semCheck) + else: LocalError(n.info, errXisNoMacroOrTemplate, s.name.s) result = errorNode(c, n) else: @@ -1494,7 +1504,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = else: result = semIndirectOp(c, n, flags) of nkMacroStmt: - result = semMacroStmt(c, n) + result = semMacroStmt(c, n, flags) of nkWhenExpr: result = semWhen(c, n, false) result = semExpr(c, result) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index ea3eebc3a..e9c746db5 100755 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -40,6 +40,9 @@ proc semGenericStmtScope(c: PContext, n: PNode, result = semGenericStmt(c, n, flags, toBind) closeScope(c.tab) +template macroToExpand(s: expr): expr = + s.kind in {skMacro, skTemplate} and (s.typ.len == 1 or sfImmediate in s.flags) + proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = incl(s.flags, sfUsed) case s.kind @@ -49,9 +52,15 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = of skProc, skMethod, skIterator, skConverter: result = symChoice(c, n, s, scOpen) of skTemplate: - result = semTemplateExpr(c, n, s, false) + if macroToExpand(s): + result = semTemplateExpr(c, n, s, false) + else: + result = symChoice(c, n, s, scOpen) of skMacro: - result = semMacroExpr(c, n, n, s, false) + if macroToExpand(s): + result = semMacroExpr(c, n, n, s, false) + else: + result = symChoice(c, n, s, scOpen) of skGenericParam: result = newSymNode(s, n.info) of skParam: @@ -96,10 +105,18 @@ proc semGenericStmt(c: PContext, n: PNode, if s != nil: incl(s.flags, sfUsed) case s.kind - of skMacro: - result = semMacroExpr(c, n, n, s, false) + of skMacro: + if macroToExpand(s): + result = semMacroExpr(c, n, n, s, false) + else: + n.sons[0] = symChoice(c, n.sons[0], s, scOpen) + result = n of skTemplate: - result = semTemplateExpr(c, n, s, false) + if macroToExpand(s): + result = semTemplateExpr(c, n, s, false) + else: + n.sons[0] = symChoice(c, n.sons[0], s, scOpen) + result = n # BUGFIX: we must not return here, we need to do first phase of # symbol lookup ... of skUnknown, skParam: @@ -121,7 +138,13 @@ proc semGenericStmt(c: PContext, n: PNode, for i in countup(first, sonsLen(result) - 1): result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind) of nkMacroStmt: - result = semMacroStmt(c, n, false) + 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, {}) + 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: diff --git a/compiler/types.nim b/compiler/types.nim index bf7655ebb..a0650abba 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -701,7 +701,7 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = else: result = false -template IfFastObjectTypeCheckFailed(a, b: PType, body: stmt) = +template IfFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = if tfFromGeneric notin a.flags + b.flags: # fast case: id comparison suffices: result = a.id == b.id |