tmatrix.nim works now
This commit is contained in:
parent
e2ecfb8438
commit
46e9ff6139
5 changed files with 40 additions and 24 deletions
|
|
@ -17,11 +17,20 @@ import
|
||||||
type
|
type
|
||||||
TPatternContext = object
|
TPatternContext = object
|
||||||
owner: PSym
|
owner: PSym
|
||||||
mapping: TIdNodeTable # maps formal parameters to nodes
|
mapping: seq[PNode] # maps formal parameters to nodes
|
||||||
|
formals: int
|
||||||
c: PContext
|
c: PContext
|
||||||
subMatch: bool # subnode matches are special
|
subMatch: bool # subnode matches are special
|
||||||
PPatternContext = var TPatternContext
|
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 matches(c: PPatternContext, p, n: PNode): bool
|
||||||
|
|
||||||
proc canonKind(n: PNode): TNodeKind =
|
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
|
if matches(c, p.sons[i], n): return true
|
||||||
|
|
||||||
proc bindOrCheck(c: PPatternContext, param: PSym, n: PNode): bool =
|
proc bindOrCheck(c: PPatternContext, param: PSym, n: PNode): bool =
|
||||||
var pp = IdNodeTableGetLazy(c.mapping, param)
|
var pp = GetLazy(c, param)
|
||||||
if pp != nil:
|
if pp != nil:
|
||||||
# check if we got the same pattern (already unified):
|
# check if we got the same pattern (already unified):
|
||||||
result = sameTrees(pp, n) #matches(c, pp, n)
|
result = sameTrees(pp, n) #matches(c, pp, n)
|
||||||
elif n.kind == nkArgList or checkTypes(c, param, n):
|
elif n.kind == nkArgList or checkTypes(c, param, n):
|
||||||
IdNodeTablePutLazy(c.mapping, param, n)
|
PutLazy(c, param, n)
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc gather(c: PPatternContext, param: PSym, n: PNode) =
|
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:
|
if pp != nil and pp.kind == nkArgList:
|
||||||
pp.add(n)
|
pp.add(n)
|
||||||
else:
|
else:
|
||||||
pp = newNodeI(nkArgList, n.info, 1)
|
pp = newNodeI(nkArgList, n.info, 1)
|
||||||
pp.sons[0] = n
|
pp.sons[0] = n
|
||||||
IdNodeTablePutLazy(c.mapping, param, pp)
|
PutLazy(c, param, pp)
|
||||||
|
|
||||||
proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
|
proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
|
||||||
# match ``op * param`` or ``op *| param``
|
# match ``op * param`` or ``op *| param``
|
||||||
|
|
@ -112,6 +121,9 @@ proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
|
||||||
add(arglist, n)
|
add(arglist, n)
|
||||||
else:
|
else:
|
||||||
result = false
|
result = false
|
||||||
|
debug p.sons[2].sym.typ
|
||||||
|
debug n.typ
|
||||||
|
echo "type check failed!"
|
||||||
|
|
||||||
if n.kind notin nkCallKinds: return false
|
if n.kind notin nkCallKinds: return false
|
||||||
if matches(c, p.sons[1], n.sons[0]):
|
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:
|
for j in 0 .. <p.len:
|
||||||
if not matches(c, p.sons[j], n.sons[i+j]):
|
if not matches(c, p.sons[j], n.sons[i+j]):
|
||||||
# we need to undo any bindings:
|
# 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
|
return false
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
|
@ -233,7 +245,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
|
||||||
var ctx: TPatternContext
|
var ctx: TPatternContext
|
||||||
ctx.owner = s
|
ctx.owner = s
|
||||||
ctx.c = c
|
ctx.c = c
|
||||||
# we perform 'initIdNodeTable' lazily for performance
|
ctx.formals = sonsLen(s.typ)-1
|
||||||
var m = matchStmtList(ctx, s.ast.sons[patternPos], n)
|
var m = matchStmtList(ctx, s.ast.sons[patternPos], n)
|
||||||
if isNil(m): return nil
|
if isNil(m): return nil
|
||||||
# each parameter should have been bound; we simply setup a call and
|
# 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)
|
args = newNodeI(nkArgList, n.info)
|
||||||
for i in 1 .. < params.len:
|
for i in 1 .. < params.len:
|
||||||
let param = params.sons[i].sym
|
let param = params.sons[i].sym
|
||||||
let x = IdNodeTableGetLazy(ctx.mapping, param)
|
let x = GetLazy(ctx, param)
|
||||||
# couldn't bind parameter:
|
# couldn't bind parameter:
|
||||||
if isNil(x): return nil
|
if isNil(x): return nil
|
||||||
result.add(x)
|
result.add(x)
|
||||||
|
|
|
||||||
|
|
@ -422,12 +422,21 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
template templToExpand(s: expr): expr =
|
template templToExpand(s: expr): expr =
|
||||||
s.kind == skTemplate and (s.typ.len == 1 or sfImmediate in s.flags)
|
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 =
|
proc handleSym(c: var TemplCtx, n: PNode, s: PSym): PNode =
|
||||||
result = n
|
result = n
|
||||||
if s != nil:
|
if s != nil:
|
||||||
if s.owner == c.owner and s.kind == skParam:
|
if s.owner == c.owner and s.kind == skParam:
|
||||||
incl(s.flags, sfUsed)
|
result = newParam(c, n, s)
|
||||||
result = newSymNode(s, n.info)
|
|
||||||
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):
|
||||||
|
|
@ -440,8 +449,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
proc expectParam(c: var TemplCtx, n: PNode): PNode =
|
proc expectParam(c: var TemplCtx, n: PNode): PNode =
|
||||||
let s = QualifiedLookUp(c.c, n, {})
|
let s = QualifiedLookUp(c.c, n, {})
|
||||||
if s != nil and s.owner == c.owner and s.kind == skParam:
|
if s != nil and s.owner == c.owner and s.kind == skParam:
|
||||||
incl(s.flags, sfUsed)
|
result = newParam(c, n, s)
|
||||||
result = newSymNode(s, n.info)
|
|
||||||
else:
|
else:
|
||||||
localError(n.info, errInvalidExpression)
|
localError(n.info, errInvalidExpression)
|
||||||
result = n
|
result = n
|
||||||
|
|
|
||||||
|
|
@ -554,15 +554,12 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
|
||||||
if kind == skMacro:
|
if kind == skMacro:
|
||||||
# within a macro, every param has the type PNimrodNode!
|
# within a macro, every param has the type PNimrodNode!
|
||||||
# and param.typ.kind in {tyTypeDesc, tyExpr, tyStmt}:
|
# 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"
|
let nn = getSysSym"PNimrodNode"
|
||||||
#var a = copySym(param)
|
var a = copySym(param)
|
||||||
#a.typ = nn.typ
|
a.typ = nn.typ
|
||||||
param.typ = nn.typ
|
if sfGenSym notin a.flags: addDecl(c, a)
|
||||||
#if sfGenSym notin a.flags: addDecl(c, a)
|
else:
|
||||||
if sfGenSym notin param.flags: addDecl(c, param)
|
if sfGenSym notin param.flags: addDecl(c, param)
|
||||||
|
|
||||||
proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
|
proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
|
||||||
tuple[typ: PType, id: PIdent] =
|
tuple[typ: PType, id: PIdent] =
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ proc `+`(a, b: TMat): TMat = nil
|
||||||
proc `-`(a, b: TMat): TMat = nil
|
proc `-`(a, b: TMat): TMat = nil
|
||||||
proc `$`(a: TMat): string = result = $a.dummy
|
proc `$`(a: TMat): string = result = $a.dummy
|
||||||
|
|
||||||
macro optOps{ (`+`|`-`|`*`) *| a }(a: varargs[TMat]): expr =
|
macro optOps{ (`+`|`-`|`*`) *| a }(a: TMat): expr =
|
||||||
result = newIntLitNode(21)
|
result = callsite()
|
||||||
|
|
||||||
#macro optPlus{ `+` * a }(a: varargs[TMat]): expr =
|
#macro optPlus{ `+` * a }(a: varargs[TMat]): expr =
|
||||||
# result = newIntLitNode(21)
|
# result = newIntLitNode(21)
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -2,7 +2,6 @@ version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- make 'm: stmt' use overloading resolution
|
- make 'm: stmt' use overloading resolution
|
||||||
- finish, test and document tmatrix
|
|
||||||
- document pattern matching
|
- document pattern matching
|
||||||
|
|
||||||
- make 'bind' default for templates and introduce 'mixin'
|
- make 'bind' default for templates and introduce 'mixin'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue