summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/patterns.nim31
-rwxr-xr-xcompiler/types.nim4
-rw-r--r--tests/patterns/targlist.nim9
-rw-r--r--tests/patterns/tor.nim9
-rw-r--r--tests/patterns/tstar.nim19
-rw-r--r--tests/patterns/tstmtlist.nim18
-rw-r--r--tests/run/tmemoization.nim2
-rw-r--r--tests/run/ttypedesc1.nim10
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