# # # The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # ## This module implements the pattern matching features for term rewriting ## macro support. import ast, astalgo, types, semdata, sigmatch, msgs, idents, aliases, parampatterns, trees type TPatternContext = object owner: PSym mapping: seq[PNode] # maps formal parameters to nodes formals: int c: PContext subMatch: bool # subnode matches are special PPatternContext = var TPatternContext proc getLazy(c: PPatternContext, sym: PSym): PNode = if not isNil(c.mapping): result = c.mapping[sym.position] proc putLazy(c: PPatternContext, sym: PSym, n: PNode) = if isNil(c.mapping): newSeq(c.mapping, c.formals) c.mapping[sym.position] = n proc matches(c: PPatternContext, p, n: PNode): bool proc canonKind(n: PNode): TNodeKind = ## nodekind canonilization for pattern matching result = n.kind case result of nkCallKinds: result = nkCall of nkStrLit..nkTripleStrLit: result = nkStrLit of nkFastAsgn: result = nkAsgn else: discard proc sameKinds(a, b: PNode): bool {.inline.} = result = a.kind == b.kind or a.canonKind == b.canonKind proc sameTrees(a, b: PNode): bool = if sameKinds(a, b): case a.kind of nkSym: result = a.sym == b.sym of nkIdent: result = a.ident.id == b.ident.id of nkCharLit..nkInt64Lit: result = a.intVal == b.intVal of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal of nkEmpty, nkNilLit: result = true of nkType: result = sameTypeOrNil(a.typ, b.typ) else: if sonsLen(a) == sonsLen(b): for i in countup(0, sonsLen(a) - 1): if not sameTrees(a.sons[i], b.sons[i]): return result = true proc inSymChoice(sc, x: PNode): bool = if sc.kind == nkClosedSymChoice: for i in 0.. = 2: for i in 1 .. < params.len: let param = params.sons[i].sym if whichAlias(param) != aqNone: return true proc addToArgList(result, n: PNode) = if n.typ != nil and n.typ.kind != tyStmt: if n.kind != nkArgList: result.add(n) else: for i in 0 ..