summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/ccgcalls.nim13
-rw-r--r--compiler/ccgtypes.nim59
-rw-r--r--compiler/msgs.nim3
-rw-r--r--compiler/parser.nim3
-rw-r--r--compiler/vmdeps.nim4
6 files changed, 66 insertions, 18 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 55923b54c..4e22af287 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -796,8 +796,8 @@ type
                               # for enum types a list of symbols
                               # for tyInt it can be the int literal
                               # for procs and tyGenericBody, it's the
-                              # the body of the user-defined type class
                               # formal param list
+                              # for concepts, the concept body
                               # else: unused
     owner*: PSym              # the 'owner' of the type
     sym*: PSym                # types have the sym associated with them
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim
index 8f354d457..2dacc25e9 100644
--- a/compiler/ccgcalls.nim
+++ b/compiler/ccgcalls.nim
@@ -385,18 +385,11 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
       inc j
       inc i
     of '\'':
-      inc i
-      let stars = i
-      while pat[i] == '*': inc i
-      if pat[i] in Digits:
-        let j = pat[i].ord - '0'.ord
-        var t = typ.sons[j]
-        for k in 1..i-stars:
-          if t != nil and t.len > 0:
-            t = if t.kind == tyGenericInst: t.sons[1] else: t.elemType
+      var idx, stars: int
+      if scanCppGenericSlot(pat, i, idx, stars):
+        var t = resolveStarsInCppType(typ, idx, stars)
         if t == nil: result.add(~"void")
         else: result.add(getTypeDesc(p.module, t))
-        inc i
     else:
       let start = i
       while i < pat.len:
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 8fdabd6cc..60ebf591b 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -495,6 +495,33 @@ proc getTupleDesc(m: BModule, typ: PType, name: Rope,
   else: add(result, desc)
   add(result, "};" & tnl)
 
+proc scanCppGenericSlot(pat: string, cursor, outIdx, outStars: var int): bool =
+  # A helper proc for handling cppimport patterns, involving numeric
+  # placeholders for generic types (e.g. '0, '**2, etc).
+  # pre: the cursor must be placed at the ' symbol
+  # post: the cursor will be placed after the final digit
+  # false will returned if the input is not recognized as a placeholder
+  inc cursor
+  let begin = cursor
+  while pat[cursor] == '*': inc cursor
+  if pat[cursor] in Digits:
+    outIdx = pat[cursor].ord - '0'.ord
+    outStars = cursor - begin
+    inc cursor
+    return true
+  else:
+    return false
+
+proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
+  # XXX: we should catch this earlier and report it as a semantic error
+  if idx >= typ.len: internalError "invalid apostrophe type parameter index"
+
+  result = typ.sons[idx]
+  for i in 1..stars:
+    if result != nil and result.len > 0:
+      result = if result.kind == tyGenericInst: result.sons[1]
+               else: result.elemType
+
 proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope =
   # returns only the type's name
   var t = getUniqueType(typ)
@@ -597,11 +624,33 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope =
     if isImportedCppType(t) and typ.kind == tyGenericInst:
       # for instantiated templates we do not go through the type cache as the
       # the type cache is not aware of 'tyGenericInst'.
-      result = getTypeName(t) & "<"
-      for i in 1 .. typ.len-2:
-        if i > 1: result.add(", ")
-        result.add(getTypeDescAux(m, typ.sons[i], check))
-      result.add("> ")
+      let cppName = getTypeName(t)
+      var i = 0
+      var chunkStart = 0
+      while i < cppName.data.len:
+        if cppName.data[i] == '\'':
+          var chunkEnd = <i
+          var idx, stars: int
+          if scanCppGenericSlot(cppName.data, i, idx, stars):
+            result.add cppName.data.substr(chunkStart, chunkEnd)
+            chunkStart = i
+
+            let typeInSlot = resolveStarsInCppType(typ, idx + 1, stars)
+            if typeInSlot == nil or typeInSlot.kind == tyEmpty:
+              result.add(~"void")
+            else:
+              result.add getTypeDescAux(m, typeInSlot, check)
+        else:
+          inc i
+      
+      if chunkStart != 0:
+        result.add cppName.data.substr(chunkStart)
+      else:
+        result = cppName & "<"
+        for i in 1 .. typ.len-2:
+          if i > 1: result.add(", ")
+          result.add(getTypeDescAux(m, typ.sons[i], check))
+        result.add("> ")
       # always call for sideeffects:
       assert t.kind != tyTuple
       discard getRecordDesc(m, t, result, check)
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 3f5c4763e..778b839f3 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -827,6 +827,9 @@ proc localError*(info: TLineInfo, msg: TMsgKind, arg = "") =
 proc localError*(info: TLineInfo, arg: string) =
   liMessage(info, errGenerated, arg, doNothing)
 
+proc localError*(info: TLineInfo, format: string, params: openarray[string]) =
+  localError(info, format % params)
+
 proc message*(info: TLineInfo, msg: TMsgKind, arg = "") =
   liMessage(info, msg, arg, doNothing)
 
diff --git a/compiler/parser.nim b/compiler/parser.nim
index d600f0f85..7da2f0d22 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -212,7 +212,8 @@ proc getPrecedence(tok: TToken, strongSpaces: bool): int =
     let relevantChar = tok.ident.s[0]
 
     # arrow like?
-    if L > 1 and tok.ident.s[L-1] == '>': return considerStrongSpaces(1)
+    if L > 1 and tok.ident.s[L-1] == '>' and
+      tok.ident.s[L-2] in {'-', '~', '='}: return considerStrongSpaces(1)
 
     template considerAsgn(value: expr) =
       result = if tok.ident.s[L-1] == '=': 1 else: value
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
index 6148ed319..21ee4967b 100644
--- a/compiler/vmdeps.nim
+++ b/compiler/vmdeps.nim
@@ -144,7 +144,9 @@ proc mapTypeToAst(t: PType, info: TLineInfo; allowRecursion=false): PNode =
   of tyIter: result = mapTypeToBracket("iter", t, info)
   of tyProxy: result = atomicType"error"
   of tyBuiltInTypeClass: result = mapTypeToBracket("builtinTypeClass", t, info)
-  of tyUserTypeClass: result = mapTypeToBracket("userTypeClass", t, info)
+  of tyUserTypeClass:
+    result = mapTypeToBracket("concept", t, info)
+    result.add t.n.copyTree
   of tyCompositeTypeClass: result = mapTypeToBracket("compositeTypeClass", t, info)
   of tyAnd: result = mapTypeToBracket("and", t, info)
   of tyOr: result = mapTypeToBracket("or", t, info)