propagate semExpr flags in macro/template expansion

This commit is contained in:
Zahary Karadjov
2014-04-06 16:55:16 +03:00
parent 4d2f1396cb
commit f6f5c9e9e6
5 changed files with 27 additions and 23 deletions

View File

@@ -161,12 +161,13 @@ proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} =
localError(typ.n.info, errXisNoType, typeToString(typ))
proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym
proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode
proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode
proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode
proc isOpImpl(c: PContext, n: PNode): PNode
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
flags: TExprFlags = {}): PNode
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
semCheck: bool = true): PNode
flags: TExprFlags = {}): PNode
proc symFromType(t: PType, info: TLineInfo): PSym =
if t.sym != nil: return t.sym
@@ -265,7 +266,8 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
include hlo, seminst, semcall
proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
proc semAfterMacroCall(c: PContext, n: PNode, s: PSym,
flags: TExprFlags): PNode =
inc(evalTemplateCounter)
if evalTemplateCounter > 100:
globalError(s.info, errTemplateInstantiationTooNested)
@@ -281,7 +283,7 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
# BUGFIX: we cannot expect a type here, because module aliases would not
# work then (see the ``tmodulealias`` test)
# semExprWithType(c, result)
result = semExpr(c, result)
result = semExpr(c, result, flags)
of tyStmt:
result = semStmt(c, result)
of tyTypeDesc:
@@ -290,14 +292,14 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
result.typ = makeTypeDesc(c, typ)
#result = symNodeFromType(c, typ, n.info)
else:
result = semExpr(c, result)
result = semExpr(c, result, flags)
result = fitNode(c, s.typ.sons[0], result)
#GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
dec(evalTemplateCounter)
c.friendModule = oldFriend
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
semCheck: bool = true): PNode =
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
flags: TExprFlags = {}): PNode =
markUsed(n, sym)
if sym == c.p.owner:
globalError(n.info, errRecursiveDependencyX, sym.name.s)
@@ -306,7 +308,8 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
# c.evalContext = c.createEvalContext(emStatic)
result = evalMacroCall(c.module, n, nOrig, sym)
if semCheck: result = semAfterMacroCall(c, result, sym)
if efNoSemCheck notin flags:
result = semAfterMacroCall(c, result, sym, flags)
proc forceBool(c: PContext, n: PNode): PNode =
result = fitNode(c, getSysType(tyBool), n)

View File

@@ -42,7 +42,7 @@ type
TExprFlag* = enum
efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType,
efAllowDestructor, efWantValue, efOperand
efAllowDestructor, efWantValue, efOperand, efNoSemCheck
TExprFlags* = set[TExprFlag]
PContext* = ref TContext

View File

@@ -10,11 +10,12 @@
# this module does the semantic checking for expressions
# included from sem.nim
proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode =
proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
flags: TExprFlags = {}): PNode =
markUsed(n, s)
pushInfoContext(n.info)
result = evalTemplate(n, s, getCurrOwner())
if semCheck: result = semAfterMacroCall(c, result, s)
if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags)
popInfoContext()
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
@@ -95,8 +96,8 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
else: result = newSymNode(s, n.info)
else:
result = newSymNode(s, n.info)
of skMacro: result = semMacroExpr(c, n, n, s)
of skTemplate: result = semTemplateExpr(c, n, s)
of skMacro: result = semMacroExpr(c, n, n, s, flags)
of skTemplate: result = semTemplateExpr(c, n, s, flags)
of skVar, skLet, skResult, skParam, skForVar:
markUsed(n, s)
# if a proc accesses a global variable, it is not side effect free:
@@ -793,8 +794,8 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
result = n
let callee = result.sons[0].sym
case callee.kind
of skMacro: result = semMacroExpr(c, result, orig, callee)
of skTemplate: result = semTemplateExpr(c, result, callee)
of skMacro: result = semMacroExpr(c, result, orig, callee, flags)
of skTemplate: result = semTemplateExpr(c, result, callee, flags)
else:
semFinishOperands(c, result)
activate(c, result)
@@ -1966,13 +1967,13 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result = semDirectOp(c, n, flags)
else:
var p = fixImmediateParams(n)
result = semMacroExpr(c, p, p, s)
result = semMacroExpr(c, p, p, s, flags)
of skTemplate:
if sfImmediate notin s.flags:
result = semDirectOp(c, n, flags)
else:
var p = fixImmediateParams(n)
result = semTemplateExpr(c, p, s)
result = semTemplateExpr(c, p, s, flags)
of skType:
# XXX think about this more (``set`` procs)
if n.len == 2:

View File

@@ -47,12 +47,12 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode =
of skTemplate:
if macroToExpand(s):
let n = fixImmediateParams(n)
result = semTemplateExpr(c, n, s, false)
result = semTemplateExpr(c, n, s, {efNoSemCheck})
else:
result = symChoice(c, n, s, scOpen)
of skMacro:
if macroToExpand(s):
result = semMacroExpr(c, n, n, s, false)
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
else:
result = symChoice(c, n, s, scOpen)
of skGenericParam:
@@ -126,14 +126,14 @@ proc semGenericStmt(c: PContext, n: PNode,
case s.kind
of skMacro:
if macroToExpand(s):
result = semMacroExpr(c, n, n, s, false)
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
else:
n.sons[0] = symChoice(c, n.sons[0], s, scOption)
result = n
of skTemplate:
if macroToExpand(s):
let n = fixImmediateParams(n)
result = semTemplateExpr(c, n, s, false)
result = semTemplateExpr(c, n, s, {efNoSemCheck})
else:
n.sons[0] = symChoice(c, n.sons[0], s, scOption)
result = n

View File

@@ -539,7 +539,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
elif contains(c.toBind, s.id):
result = symChoice(c.c, n, s, scClosed)
elif templToExpand(s):
result = semPatternBody(c, semTemplateExpr(c.c, n, s, false))
result = semPatternBody(c, semTemplateExpr(c.c, n, s, {efNoSemCheck}))
else:
discard
# we keep the ident unbound for matching instantiated symbols and
@@ -584,7 +584,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
if s.owner == c.owner and s.kind == skParam: discard
elif contains(c.toBind, s.id): discard
elif templToExpand(s):
return semPatternBody(c, semTemplateExpr(c.c, n, s, false))
return semPatternBody(c, semTemplateExpr(c.c, n, s, {efNoSemCheck}))
if n.kind == nkInfix and n.sons[0].kind == nkIdent:
# we interpret `*` and `|` only as pattern operators if they occur in