guards.nim does compile
This commit is contained in:
parent
e1a921ce4f
commit
7eb39d9d26
13 changed files with 241 additions and 230 deletions
|
|
@ -10,7 +10,8 @@
|
|||
## This module implements the pattern matching features for term rewriting
|
||||
## macro support.
|
||||
|
||||
import strutils, ast, astalgo, types, msgs, idents, renderer, wordrecg, trees
|
||||
import strutils, ast, astalgo, types, msgs, idents, renderer, wordrecg, trees,
|
||||
options
|
||||
|
||||
# we precompile the pattern here for efficiency into some internal
|
||||
# stack based VM :-) Why? Because it's fun; I did no benchmarks to see if that
|
||||
|
|
@ -41,8 +42,8 @@ type
|
|||
const
|
||||
MaxStackSize* = 64 ## max required stack size by the VM
|
||||
|
||||
proc patternError(n: PNode) =
|
||||
localError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
|
||||
proc patternError(n: PNode; conf: ConfigRef) =
|
||||
localError(conf, n.info, "illformed AST: " & renderTree(n, {renderNoComments}))
|
||||
|
||||
proc add(code: var TPatternCode, op: TOpcode) {.inline.} =
|
||||
add(code, chr(ord(op)))
|
||||
|
|
@ -53,42 +54,42 @@ proc whichAlias*(p: PSym): TAliasRequest =
|
|||
else:
|
||||
result = aqNone
|
||||
|
||||
proc compileConstraints(p: PNode, result: var TPatternCode) =
|
||||
proc compileConstraints(p: PNode, result: var TPatternCode; conf: ConfigRef) =
|
||||
case p.kind
|
||||
of nkCallKinds:
|
||||
if p.sons[0].kind != nkIdent:
|
||||
patternError(p.sons[0])
|
||||
patternError(p.sons[0], conf)
|
||||
return
|
||||
let op = p.sons[0].ident
|
||||
if p.len == 3:
|
||||
if op.s == "|" or op.id == ord(wOr):
|
||||
compileConstraints(p.sons[1], result)
|
||||
compileConstraints(p.sons[2], result)
|
||||
compileConstraints(p.sons[1], result, conf)
|
||||
compileConstraints(p.sons[2], result, conf)
|
||||
result.add(ppOr)
|
||||
elif op.s == "&" or op.id == ord(wAnd):
|
||||
compileConstraints(p.sons[1], result)
|
||||
compileConstraints(p.sons[2], result)
|
||||
compileConstraints(p.sons[1], result, conf)
|
||||
compileConstraints(p.sons[2], result, conf)
|
||||
result.add(ppAnd)
|
||||
else:
|
||||
patternError(p)
|
||||
patternError(p, conf)
|
||||
elif p.len == 2 and (op.s == "~" or op.id == ord(wNot)):
|
||||
compileConstraints(p.sons[1], result)
|
||||
compileConstraints(p.sons[1], result, conf)
|
||||
result.add(ppNot)
|
||||
else:
|
||||
patternError(p)
|
||||
patternError(p, conf)
|
||||
of nkAccQuoted, nkPar:
|
||||
if p.len == 1:
|
||||
compileConstraints(p.sons[0], result)
|
||||
compileConstraints(p.sons[0], result, conf)
|
||||
else:
|
||||
patternError(p)
|
||||
patternError(p, conf)
|
||||
of nkIdent:
|
||||
let spec = p.ident.s.normalize
|
||||
case spec
|
||||
of "atom": result.add(ppAtom)
|
||||
of "lit": result.add(ppLit)
|
||||
of "sym": result.add(ppSym)
|
||||
of "atom": result.add(ppAtom)
|
||||
of "lit": result.add(ppLit)
|
||||
of "sym": result.add(ppSym)
|
||||
of "ident": result.add(ppIdent)
|
||||
of "call": result.add(ppCall)
|
||||
of "call": result.add(ppCall)
|
||||
of "alias": result[0] = chr(aqShouldAlias.ord)
|
||||
of "noalias": result[0] = chr(aqNoAlias.ord)
|
||||
of "lvalue": result.add(ppLValue)
|
||||
|
|
@ -97,24 +98,24 @@ proc compileConstraints(p: PNode, result: var TPatternCode) =
|
|||
of "nosideeffect": result.add(ppNoSideEffect)
|
||||
else:
|
||||
# check all symkinds:
|
||||
internalAssert int(high(TSymKind)) < 255
|
||||
internalAssert conf, int(high(TSymKind)) < 255
|
||||
for i in low(TSymKind)..high(TSymKind):
|
||||
if cmpIgnoreStyle(($i).substr(2), spec) == 0:
|
||||
result.add(ppSymKind)
|
||||
result.add(chr(i.ord))
|
||||
return
|
||||
# check all nodekinds:
|
||||
internalAssert int(high(TNodeKind)) < 255
|
||||
internalAssert conf, int(high(TNodeKind)) < 255
|
||||
for i in low(TNodeKind)..high(TNodeKind):
|
||||
if cmpIgnoreStyle($i, spec) == 0:
|
||||
result.add(ppNodeKind)
|
||||
result.add(chr(i.ord))
|
||||
return
|
||||
patternError(p)
|
||||
patternError(p, conf)
|
||||
else:
|
||||
patternError(p)
|
||||
patternError(p, conf)
|
||||
|
||||
proc semNodeKindConstraints*(p: PNode): PNode =
|
||||
proc semNodeKindConstraints*(p: PNode; conf: ConfigRef): PNode =
|
||||
## does semantic checking for a node kind pattern and compiles it into an
|
||||
## efficient internal format.
|
||||
assert p.kind == nkCurlyExpr
|
||||
|
|
@ -123,11 +124,11 @@ proc semNodeKindConstraints*(p: PNode): PNode =
|
|||
result.strVal.add(chr(aqNone.ord))
|
||||
if p.len >= 2:
|
||||
for i in 1..<p.len:
|
||||
compileConstraints(p.sons[i], result.strVal)
|
||||
compileConstraints(p.sons[i], result.strVal, conf)
|
||||
if result.strVal.len > MaxStackSize-1:
|
||||
internalError(p.info, "parameter pattern too complex")
|
||||
internalError(conf, p.info, "parameter pattern too complex")
|
||||
else:
|
||||
patternError(p)
|
||||
patternError(p, conf)
|
||||
result.strVal.add(ppEof)
|
||||
|
||||
type
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue