propagate semExpr flags in macro/template expansion
This commit is contained in:
parent
4d2f1396cb
commit
f6f5c9e9e6
5 changed files with 27 additions and 23 deletions
|
|
@ -161,12 +161,13 @@ proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} =
|
||||||
localError(typ.n.info, errXisNoType, typeToString(typ))
|
localError(typ.n.info, errXisNoType, typeToString(typ))
|
||||||
|
|
||||||
proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym
|
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 semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode
|
||||||
proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode
|
proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode
|
||||||
proc isOpImpl(c: PContext, n: PNode): 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,
|
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||||
semCheck: bool = true): PNode
|
flags: TExprFlags = {}): PNode
|
||||||
|
|
||||||
proc symFromType(t: PType, info: TLineInfo): PSym =
|
proc symFromType(t: PType, info: TLineInfo): PSym =
|
||||||
if t.sym != nil: return t.sym
|
if t.sym != nil: return t.sym
|
||||||
|
|
@ -265,7 +266,8 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||||
|
|
||||||
include hlo, seminst, semcall
|
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)
|
inc(evalTemplateCounter)
|
||||||
if evalTemplateCounter > 100:
|
if evalTemplateCounter > 100:
|
||||||
globalError(s.info, errTemplateInstantiationTooNested)
|
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
|
# BUGFIX: we cannot expect a type here, because module aliases would not
|
||||||
# work then (see the ``tmodulealias`` test)
|
# work then (see the ``tmodulealias`` test)
|
||||||
# semExprWithType(c, result)
|
# semExprWithType(c, result)
|
||||||
result = semExpr(c, result)
|
result = semExpr(c, result, flags)
|
||||||
of tyStmt:
|
of tyStmt:
|
||||||
result = semStmt(c, result)
|
result = semStmt(c, result)
|
||||||
of tyTypeDesc:
|
of tyTypeDesc:
|
||||||
|
|
@ -290,14 +292,14 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
result.typ = makeTypeDesc(c, typ)
|
result.typ = makeTypeDesc(c, typ)
|
||||||
#result = symNodeFromType(c, typ, n.info)
|
#result = symNodeFromType(c, typ, n.info)
|
||||||
else:
|
else:
|
||||||
result = semExpr(c, result)
|
result = semExpr(c, result, flags)
|
||||||
result = fitNode(c, s.typ.sons[0], result)
|
result = fitNode(c, s.typ.sons[0], result)
|
||||||
#GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
|
#GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
|
||||||
dec(evalTemplateCounter)
|
dec(evalTemplateCounter)
|
||||||
c.friendModule = oldFriend
|
c.friendModule = oldFriend
|
||||||
|
|
||||||
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||||
semCheck: bool = true): PNode =
|
flags: TExprFlags = {}): PNode =
|
||||||
markUsed(n, sym)
|
markUsed(n, sym)
|
||||||
if sym == c.p.owner:
|
if sym == c.p.owner:
|
||||||
globalError(n.info, errRecursiveDependencyX, sym.name.s)
|
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)
|
# c.evalContext = c.createEvalContext(emStatic)
|
||||||
|
|
||||||
result = evalMacroCall(c.module, n, nOrig, sym)
|
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 =
|
proc forceBool(c: PContext, n: PNode): PNode =
|
||||||
result = fitNode(c, getSysType(tyBool), n)
|
result = fitNode(c, getSysType(tyBool), n)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ type
|
||||||
|
|
||||||
TExprFlag* = enum
|
TExprFlag* = enum
|
||||||
efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType,
|
efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType,
|
||||||
efAllowDestructor, efWantValue, efOperand
|
efAllowDestructor, efWantValue, efOperand, efNoSemCheck
|
||||||
TExprFlags* = set[TExprFlag]
|
TExprFlags* = set[TExprFlag]
|
||||||
|
|
||||||
PContext* = ref TContext
|
PContext* = ref TContext
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,12 @@
|
||||||
# this module does the semantic checking for expressions
|
# this module does the semantic checking for expressions
|
||||||
# included from sem.nim
|
# 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)
|
markUsed(n, s)
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(n.info)
|
||||||
result = evalTemplate(n, s, getCurrOwner())
|
result = evalTemplate(n, s, getCurrOwner())
|
||||||
if semCheck: result = semAfterMacroCall(c, result, s)
|
if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
|
|
||||||
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
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)
|
||||||
else:
|
else:
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
of skMacro: result = semMacroExpr(c, n, n, s)
|
of skMacro: result = semMacroExpr(c, n, n, s, flags)
|
||||||
of skTemplate: result = semTemplateExpr(c, n, s)
|
of skTemplate: result = semTemplateExpr(c, n, s, flags)
|
||||||
of skVar, skLet, skResult, skParam, skForVar:
|
of skVar, skLet, skResult, skParam, skForVar:
|
||||||
markUsed(n, s)
|
markUsed(n, s)
|
||||||
# if a proc accesses a global variable, it is not side effect free:
|
# 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
|
result = n
|
||||||
let callee = result.sons[0].sym
|
let callee = result.sons[0].sym
|
||||||
case callee.kind
|
case callee.kind
|
||||||
of skMacro: result = semMacroExpr(c, result, orig, callee)
|
of skMacro: result = semMacroExpr(c, result, orig, callee, flags)
|
||||||
of skTemplate: result = semTemplateExpr(c, result, callee)
|
of skTemplate: result = semTemplateExpr(c, result, callee, flags)
|
||||||
else:
|
else:
|
||||||
semFinishOperands(c, result)
|
semFinishOperands(c, result)
|
||||||
activate(c, result)
|
activate(c, result)
|
||||||
|
|
@ -1966,13 +1967,13 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
result = semDirectOp(c, n, flags)
|
result = semDirectOp(c, n, flags)
|
||||||
else:
|
else:
|
||||||
var p = fixImmediateParams(n)
|
var p = fixImmediateParams(n)
|
||||||
result = semMacroExpr(c, p, p, s)
|
result = semMacroExpr(c, p, p, s, flags)
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if sfImmediate notin s.flags:
|
if sfImmediate notin s.flags:
|
||||||
result = semDirectOp(c, n, flags)
|
result = semDirectOp(c, n, flags)
|
||||||
else:
|
else:
|
||||||
var p = fixImmediateParams(n)
|
var p = fixImmediateParams(n)
|
||||||
result = semTemplateExpr(c, p, s)
|
result = semTemplateExpr(c, p, s, flags)
|
||||||
of skType:
|
of skType:
|
||||||
# XXX think about this more (``set`` procs)
|
# XXX think about this more (``set`` procs)
|
||||||
if n.len == 2:
|
if n.len == 2:
|
||||||
|
|
|
||||||
|
|
@ -47,12 +47,12 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode =
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if macroToExpand(s):
|
if macroToExpand(s):
|
||||||
let n = fixImmediateParams(n)
|
let n = fixImmediateParams(n)
|
||||||
result = semTemplateExpr(c, n, s, false)
|
result = semTemplateExpr(c, n, s, {efNoSemCheck})
|
||||||
else:
|
else:
|
||||||
result = symChoice(c, n, s, scOpen)
|
result = symChoice(c, n, s, scOpen)
|
||||||
of skMacro:
|
of skMacro:
|
||||||
if macroToExpand(s):
|
if macroToExpand(s):
|
||||||
result = semMacroExpr(c, n, n, s, false)
|
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
|
||||||
else:
|
else:
|
||||||
result = symChoice(c, n, s, scOpen)
|
result = symChoice(c, n, s, scOpen)
|
||||||
of skGenericParam:
|
of skGenericParam:
|
||||||
|
|
@ -126,14 +126,14 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
case s.kind
|
case s.kind
|
||||||
of skMacro:
|
of skMacro:
|
||||||
if macroToExpand(s):
|
if macroToExpand(s):
|
||||||
result = semMacroExpr(c, n, n, s, false)
|
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
|
||||||
else:
|
else:
|
||||||
n.sons[0] = symChoice(c, n.sons[0], s, scOption)
|
n.sons[0] = symChoice(c, n.sons[0], s, scOption)
|
||||||
result = n
|
result = n
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if macroToExpand(s):
|
if macroToExpand(s):
|
||||||
let n = fixImmediateParams(n)
|
let n = fixImmediateParams(n)
|
||||||
result = semTemplateExpr(c, n, s, false)
|
result = semTemplateExpr(c, n, s, {efNoSemCheck})
|
||||||
else:
|
else:
|
||||||
n.sons[0] = symChoice(c, n.sons[0], s, scOption)
|
n.sons[0] = symChoice(c, n.sons[0], s, scOption)
|
||||||
result = n
|
result = n
|
||||||
|
|
|
||||||
|
|
@ -539,7 +539,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
elif contains(c.toBind, s.id):
|
elif contains(c.toBind, s.id):
|
||||||
result = symChoice(c.c, n, s, scClosed)
|
result = symChoice(c.c, n, s, scClosed)
|
||||||
elif templToExpand(s):
|
elif templToExpand(s):
|
||||||
result = semPatternBody(c, semTemplateExpr(c.c, n, s, false))
|
result = semPatternBody(c, semTemplateExpr(c.c, n, s, {efNoSemCheck}))
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
# we keep the ident unbound for matching instantiated symbols and
|
# 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
|
if s.owner == c.owner and s.kind == skParam: discard
|
||||||
elif contains(c.toBind, s.id): discard
|
elif contains(c.toBind, s.id): discard
|
||||||
elif templToExpand(s):
|
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:
|
if n.kind == nkInfix and n.sons[0].kind == nkIdent:
|
||||||
# we interpret `*` and `|` only as pattern operators if they occur in
|
# we interpret `*` and `|` only as pattern operators if they occur in
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue