mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-24 16:25:25 +00:00
tmatrix.nim works now
This commit is contained in:
@@ -17,11 +17,20 @@ import
|
||||
type
|
||||
TPatternContext = object
|
||||
owner: PSym
|
||||
mapping: TIdNodeTable # maps formal parameters to nodes
|
||||
mapping: seq[PNode] # maps formal parameters to nodes
|
||||
formals: int
|
||||
c: PContext
|
||||
subMatch: bool # subnode matches are special
|
||||
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 =
|
||||
@@ -78,22 +87,22 @@ proc matchChoice(c: PPatternContext, p, n: PNode): bool =
|
||||
if matches(c, p.sons[i], n): return true
|
||||
|
||||
proc bindOrCheck(c: PPatternContext, param: PSym, n: PNode): bool =
|
||||
var pp = IdNodeTableGetLazy(c.mapping, param)
|
||||
var pp = GetLazy(c, param)
|
||||
if pp != nil:
|
||||
# check if we got the same pattern (already unified):
|
||||
result = sameTrees(pp, n) #matches(c, pp, n)
|
||||
elif n.kind == nkArgList or checkTypes(c, param, n):
|
||||
IdNodeTablePutLazy(c.mapping, param, n)
|
||||
PutLazy(c, param, n)
|
||||
result = true
|
||||
|
||||
proc gather(c: PPatternContext, param: PSym, n: PNode) =
|
||||
var pp = IdNodeTableGetLazy(c.mapping, param)
|
||||
var pp = GetLazy(c, param)
|
||||
if pp != nil and pp.kind == nkArgList:
|
||||
pp.add(n)
|
||||
else:
|
||||
pp = newNodeI(nkArgList, n.info, 1)
|
||||
pp.sons[0] = n
|
||||
IdNodeTablePutLazy(c.mapping, param, pp)
|
||||
PutLazy(c, param, pp)
|
||||
|
||||
proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
|
||||
# match ``op * param`` or ``op *| param``
|
||||
@@ -112,6 +121,9 @@ proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
|
||||
add(arglist, n)
|
||||
else:
|
||||
result = false
|
||||
debug p.sons[2].sym.typ
|
||||
debug n.typ
|
||||
echo "type check failed!"
|
||||
|
||||
if n.kind notin nkCallKinds: return false
|
||||
if matches(c, p.sons[1], n.sons[0]):
|
||||
@@ -198,7 +210,7 @@ proc matchStmtList(c: PPatternContext, p, n: PNode): PNode =
|
||||
for j in 0 .. <p.len:
|
||||
if not matches(c, p.sons[j], n.sons[i+j]):
|
||||
# we need to undo any bindings:
|
||||
if not isNil(c.mapping.data): reset(c.mapping)
|
||||
if not isNil(c.mapping): c.mapping = nil
|
||||
return false
|
||||
result = true
|
||||
|
||||
@@ -233,7 +245,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
|
||||
var ctx: TPatternContext
|
||||
ctx.owner = s
|
||||
ctx.c = c
|
||||
# we perform 'initIdNodeTable' lazily for performance
|
||||
ctx.formals = sonsLen(s.typ)-1
|
||||
var m = matchStmtList(ctx, s.ast.sons[patternPos], n)
|
||||
if isNil(m): return nil
|
||||
# each parameter should have been bound; we simply setup a call and
|
||||
@@ -247,7 +259,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
|
||||
args = newNodeI(nkArgList, n.info)
|
||||
for i in 1 .. < params.len:
|
||||
let param = params.sons[i].sym
|
||||
let x = IdNodeTableGetLazy(ctx.mapping, param)
|
||||
let x = GetLazy(ctx, param)
|
||||
# couldn't bind parameter:
|
||||
if isNil(x): return nil
|
||||
result.add(x)
|
||||
|
||||
@@ -422,12 +422,21 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||
template templToExpand(s: expr): expr =
|
||||
s.kind == skTemplate and (s.typ.len == 1 or sfImmediate in s.flags)
|
||||
|
||||
proc newParam(c: var TemplCtx, n: PNode, s: PSym): PNode =
|
||||
# the param added in the current scope is actually wrong here for
|
||||
# macros because they have a shadowed param of type 'PNimNode' (see
|
||||
# semtypes.addParamOrResult). Within the pattern we have to ensure
|
||||
# to use the param with the proper type though:
|
||||
incl(s.flags, sfUsed)
|
||||
let x = c.owner.typ.n.sons[s.position+1].sym
|
||||
assert x.name == s.name
|
||||
result = newSymNode(x, n.info)
|
||||
|
||||
proc handleSym(c: var TemplCtx, n: PNode, s: PSym): PNode =
|
||||
result = n
|
||||
if s != nil:
|
||||
if s.owner == c.owner and s.kind == skParam:
|
||||
incl(s.flags, sfUsed)
|
||||
result = newSymNode(s, n.info)
|
||||
result = newParam(c, n, s)
|
||||
elif Contains(c.toBind, s.id):
|
||||
result = symChoice(c.c, n, s, scClosed)
|
||||
elif templToExpand(s):
|
||||
@@ -440,8 +449,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||
proc expectParam(c: var TemplCtx, n: PNode): PNode =
|
||||
let s = QualifiedLookUp(c.c, n, {})
|
||||
if s != nil and s.owner == c.owner and s.kind == skParam:
|
||||
incl(s.flags, sfUsed)
|
||||
result = newSymNode(s, n.info)
|
||||
result = newParam(c, n, s)
|
||||
else:
|
||||
localError(n.info, errInvalidExpression)
|
||||
result = n
|
||||
|
||||
@@ -554,15 +554,12 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
|
||||
if kind == skMacro:
|
||||
# within a macro, every param has the type PNimrodNode!
|
||||
# and param.typ.kind in {tyTypeDesc, tyExpr, tyStmt}:
|
||||
# We used to copySym(param) here, but this is not possible for term
|
||||
# rewriting macros; so we simply overwrite param.typ here and hope for
|
||||
# the best ...
|
||||
let nn = getSysSym"PNimrodNode"
|
||||
#var a = copySym(param)
|
||||
#a.typ = nn.typ
|
||||
param.typ = nn.typ
|
||||
#if sfGenSym notin a.flags: addDecl(c, a)
|
||||
if sfGenSym notin param.flags: addDecl(c, param)
|
||||
var a = copySym(param)
|
||||
a.typ = nn.typ
|
||||
if sfGenSym notin a.flags: addDecl(c, a)
|
||||
else:
|
||||
if sfGenSym notin param.flags: addDecl(c, param)
|
||||
|
||||
proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
|
||||
tuple[typ: PType, id: PIdent] =
|
||||
|
||||
@@ -13,8 +13,8 @@ proc `+`(a, b: TMat): TMat = nil
|
||||
proc `-`(a, b: TMat): TMat = nil
|
||||
proc `$`(a: TMat): string = result = $a.dummy
|
||||
|
||||
macro optOps{ (`+`|`-`|`*`) *| a }(a: varargs[TMat]): expr =
|
||||
result = newIntLitNode(21)
|
||||
macro optOps{ (`+`|`-`|`*`) *| a }(a: TMat): expr =
|
||||
result = callsite()
|
||||
|
||||
#macro optPlus{ `+` * a }(a: varargs[TMat]): expr =
|
||||
# result = newIntLitNode(21)
|
||||
|
||||
Reference in New Issue
Block a user