mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
propagate semExpr flags in macro/template expansion
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user