mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-21 23:05:27 +00:00
New approach
This commit is contained in:
@@ -36,35 +36,27 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
|
||||
# we apply the last pattern first, so that pattern overriding is possible;
|
||||
# however the resulting AST would better not trigger the old rule then
|
||||
# anymore ;-)
|
||||
if c.patterns.len > 0:
|
||||
|
||||
# temporary disable converters
|
||||
var ctx_converters: TSymSeq
|
||||
shallowCopy(ctx_converters, c.converters)
|
||||
c.converters = @[]
|
||||
defer: shallowCopy(c.converters, ctx_converters)
|
||||
|
||||
for i in countdown(c.patterns.len-1, 0):
|
||||
let pattern = c.patterns[i]
|
||||
if not isNil(pattern):
|
||||
let x = applyRule(c, pattern, result)
|
||||
if not isNil(x):
|
||||
assert x.kind in {nkStmtList, nkCall}
|
||||
# better be safe than sorry, so check evalTemplateCounter too:
|
||||
inc(evalTemplateCounter)
|
||||
if evalTemplateCounter > evalTemplateLimit:
|
||||
globalError(c.config, n.info, "template instantiation too nested")
|
||||
# deactivate this pattern:
|
||||
c.patterns[i] = nil
|
||||
if x.kind == nkStmtList:
|
||||
assert x.len == 3
|
||||
x.sons[1] = evalPattern(c, x.sons[1], result)
|
||||
result = flattenStmts(x)
|
||||
else:
|
||||
result = evalPattern(c, x, result)
|
||||
dec(evalTemplateCounter)
|
||||
# activate this pattern again:
|
||||
c.patterns[i] = pattern
|
||||
for i in countdown(c.patterns.len-1, 0):
|
||||
let pattern = c.patterns[i]
|
||||
if not isNil(pattern):
|
||||
let x = applyRule(c, pattern, result)
|
||||
if not isNil(x):
|
||||
assert x.kind in {nkStmtList, nkCall}
|
||||
# better be safe than sorry, so check evalTemplateCounter too:
|
||||
inc(evalTemplateCounter)
|
||||
if evalTemplateCounter > evalTemplateLimit:
|
||||
globalError(c.config, n.info, "template instantiation too nested")
|
||||
# deactivate this pattern:
|
||||
c.patterns[i] = nil
|
||||
if x.kind == nkStmtList:
|
||||
assert x.len == 3
|
||||
x.sons[1] = evalPattern(c, x.sons[1], result)
|
||||
result = flattenStmts(x)
|
||||
else:
|
||||
result = evalPattern(c, x, result)
|
||||
dec(evalTemplateCounter)
|
||||
# activate this pattern again:
|
||||
c.patterns[i] = pattern
|
||||
|
||||
proc hlo(c: PContext, n: PNode): PNode =
|
||||
inc(c.hloLoopDetector)
|
||||
|
||||
@@ -77,7 +77,7 @@ proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool =
|
||||
if isNil(n.typ):
|
||||
result = p.typ.kind in {tyVoid, tyStmt}
|
||||
else:
|
||||
result = sigmatch.argtypeMatches(c.c, p.typ, n.typ)
|
||||
result = sigmatch.argtypeMatches(c.c, p.typ, n.typ, from_hlo = true)
|
||||
|
||||
proc isPatternParam(c: PPatternContext, p: PNode): bool {.inline.} =
|
||||
result = p.kind == nkSym and p.sym.kind == skParam and p.sym.owner == c.owner
|
||||
|
||||
@@ -2359,14 +2359,17 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
|
||||
for t in m.inferredTypes:
|
||||
if t.sonsLen > 1: t.sons.setLen 1
|
||||
|
||||
proc argtypeMatches*(c: PContext, f, a: PType): bool =
|
||||
proc argtypeMatches*(c: PContext, f, a: PType, from_hlo = false): bool =
|
||||
var m: TCandidate
|
||||
initCandidate(c, m, f)
|
||||
let res = paramTypesMatch(m, f, a, ast.emptyNode, nil)
|
||||
#instantiateGenericConverters(c, res, m)
|
||||
# XXX this is used by patterns.nim too; I think it's better to not
|
||||
# instantiate generic converters for that
|
||||
result = res != nil
|
||||
if not from_hlo:
|
||||
res != nil
|
||||
else:
|
||||
res != nil and m.convMatches == 0 and m.intConvMatches in [0, 256]
|
||||
|
||||
proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo;
|
||||
op: TTypeAttachedOp; col: int): PSym {.procvar.} =
|
||||
|
||||
Reference in New Issue
Block a user