diff options
-rw-r--r-- | compiler/patterns.nim | 31 | ||||
-rwxr-xr-x | compiler/types.nim | 4 | ||||
-rw-r--r-- | tests/patterns/targlist.nim | 9 | ||||
-rw-r--r-- | tests/patterns/tor.nim | 9 | ||||
-rw-r--r-- | tests/patterns/tstar.nim | 19 | ||||
-rw-r--r-- | tests/patterns/tstmtlist.nim | 18 | ||||
-rw-r--r-- | tests/run/tmemoization.nim | 2 | ||||
-rw-r--r-- | tests/run/ttypedesc1.nim | 10 |
8 files changed, 74 insertions, 28 deletions
diff --git a/compiler/patterns.nim b/compiler/patterns.nim index ceadfe350..110fae08a 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -23,9 +23,6 @@ type PPatternContext = var TPatternContext proc matches(c: PPatternContext, p, n: PNode): bool -proc checkConstraints(c: PPatternContext, p, n: PNode): bool = - # XXX create a new mapping here? --> need use cases - result = matches(c, p, n) proc canonKind(n: PNode): TNodeKind = ## nodekind canonilization for pattern matching @@ -85,34 +82,28 @@ proc bindOrCheck(c: PPatternContext, param: PSym, n: PNode): bool = if pp != nil: # check if we got the same pattern (already unified): result = sameTrees(pp, n) #matches(c, pp, n) - elif checkTypes(c, param, n) and - (param.ast == nil or checkConstraints(c, param.ast, n)): + elif n.kind == nkArgList or checkTypes(c, param, n): IdNodeTablePutLazy(c.mapping, param, n) result = true proc matchStar(c: PPatternContext, p, n: PNode): bool = # match ``op*param`` - # this is quite hard: - # match against: f(a, ..., f(b, c, f(...))) - # we have different semantics if there is a choice as left operand: proc matchStarAux(c: PPatternContext, op, n, arglist: PNode) = if n.kind in nkCallKinds and matches(c, op, n.sons[0]): - for i in 1..sonsLen(n)-1: matchStarAux(c, op, n.sons[i], arglist) + for i in 1..sonsLen(n)-1: + matchStarAux(c, op, n[i], arglist) + elif n.kind == nkHiddenStdConv and n.sons[1].kind == nkBracket: + let n = n.sons[1] + for i in 0.. <n.len: matchStarAux(c, op, n[i], arglist) else: add(arglist, n) - + if n.kind notin nkCallKinds: return false - if p.sons[0].kind != nkPattern: - if matches(c, p.sons[0], n.sons[0]): - var arglist = newNodeI(nkArgList, n.info) - arglist.typ = p.sons[1].sym.typ - matchStarAux(c, p.sons[0], n, arglist) - result = bindOrCheck(c, p.sons[1].sym, arglist) - else: - # well it matches somehow ... - if matches(c, p.sons[0], n.sons[0]): - result = bindOrCheck(c, p.sons[1].sym, n) + if matches(c, p.sons[1], n.sons[0]): + var arglist = newNodeI(nkArgList, n.info) + matchStarAux(c, p.sons[1], n, arglist) + result = bindOrCheck(c, p.sons[2].sym, arglist) proc matches(c: PPatternContext, p, n: PNode): bool = # hidden conversions (?) diff --git a/compiler/types.nim b/compiler/types.nim index 8a01e6c76..bf7655ebb 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -432,12 +432,12 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string = add(result, ']') of tyTypeDesc: if t.sons.len == 0: result = "typedesc" - else: result = "typedesc{" & constraintsToStr(t) & "}" + else: result = "typedesc[" & constraintsToStr(t) & "]" of tyTypeClass: result = constraintsToStr(t) of tyExpr: if t.sons.len == 0: result = "expr" - else: result = "expr{" & constraintsToStr(t) & "}" + else: result = "expr[" & constraintsToStr(t) & "]" of tyArray: if t.sons[0].kind == tyRange: result = "array[" & rangeToStr(t.sons[0].n) & ", " & diff --git a/tests/patterns/targlist.nim b/tests/patterns/targlist.nim new file mode 100644 index 000000000..a2fa1fa48 --- /dev/null +++ b/tests/patterns/targlist.nim @@ -0,0 +1,9 @@ +discard """ + output: "12false3ha" +""" + +proc f(x: varargs[string, `$`]) = nil +template optF{f(X)}(x: varargs[expr]) = + writeln(stdout, x) + +f 1, 2, false, 3, "ha" diff --git a/tests/patterns/tor.nim b/tests/patterns/tor.nim new file mode 100644 index 000000000..304e1c692 --- /dev/null +++ b/tests/patterns/tor.nim @@ -0,0 +1,9 @@ +discard """ + output: "110" +""" + +template arithOps: expr = (`+` | `-` | `*`) +template testOr{ (arithOps{f})(a, b) }(a, b, f: expr): expr = f(a+1, b) + +let xx = 10 +echo 10*xx diff --git a/tests/patterns/tstar.nim b/tests/patterns/tstar.nim new file mode 100644 index 000000000..6dbff3cd6 --- /dev/null +++ b/tests/patterns/tstar.nim @@ -0,0 +1,19 @@ +discard """ + output: "my awesome concat" +""" + +var + calls = 0 + +proc `&&`(s: varargs[string]): string = + result = s[0] + for i in 1..len(s)-1: result.add s[i] + inc calls + +template optConc{ `&&` * a }(a: expr): expr = &&a + +let space = " " +echo "my" && (space & "awe" && "some " ) && "concat" + +# check that it's been properly optimized: +doAssert calls == 1 diff --git a/tests/patterns/tstmtlist.nim b/tests/patterns/tstmtlist.nim new file mode 100644 index 000000000..391c93d47 --- /dev/null +++ b/tests/patterns/tstmtlist.nim @@ -0,0 +1,18 @@ +discard """ + output: '''0 +|12|34 +''' +""" + +template optWrite{ + write(stdout, x) + write(stdout, y) +}(x, y: string) = + write(stdout, "|", x, y, "|") + +if true: + echo "0" + write stdout, "1" + write stdout, "2" + write stdout, "3" + echo "4" diff --git a/tests/run/tmemoization.nim b/tests/run/tmemoization.nim index 10db1fcf1..78f0515f3 100644 --- a/tests/run/tmemoization.nim +++ b/tests/run/tmemoization.nim @@ -5,7 +5,7 @@ discard """ import strutils -proc foo(s: expr{string}): string = +proc foo(s: expr[string]): string = static: echo s const R = s.toUpper diff --git a/tests/run/ttypedesc1.nim b/tests/run/ttypedesc1.nim index 9c960a809..b74440176 100644 --- a/tests/run/ttypedesc1.nim +++ b/tests/run/ttypedesc1.nim @@ -5,18 +5,18 @@ type x: T y: U -proc foo(T: typedesc{float}, a: expr): string = +proc foo(T: typedesc[float], a: expr): string = result = "float " & $(a.len > 5) -proc foo(T: typedesc{TFoo}, a: int): string = +proc foo(T: typedesc[TFoo], a: int): string = result = "TFoo " & $(a) -proc foo(T: typedesc{int or bool}): string = +proc foo(T: typedesc[int or bool]): string = var a: T a = 10 result = "int or bool " & ($a) -template foo(T: typedesc{seq}): expr = "seq" +template foo(T: typedesc[seq]): expr = "seq" test "types can be used as proc params": check foo(TFoo[int, float], 1000) == "TFoo 1000" @@ -31,5 +31,5 @@ test "types can be used as proc params": check foo(seq[TFoo[bool, string]]) == "seq" when false: - proc foo(T: typedesc{seq}, s: T) = nil + proc foo(T: typedesc[seq], s: T) = nil |