summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/renderer.nim70
-rw-r--r--tests/errmsgs/twrongcolon.nim6
-rw-r--r--tests/macros/tmacrostmt.nim15
3 files changed, 71 insertions, 20 deletions
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 29ff80ca9..6c953dc18 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -874,12 +874,23 @@ proc gsub(g: var TSrcGen; n: PNode; i: int) =
   else:
     put(g, tkOpr, "<<" & $i & "th child missing for " & $n.kind & " >>")
 
-proc isBracket*(n: PNode): bool =
-  case n.kind
-  of nkClosedSymChoice, nkOpenSymChoice:
-    if n.len > 0: result = isBracket(n[0])
-  of nkSym: result = n.sym.name.s == "[]"
-  else: result = false
+type
+  BracketKind = enum
+    bkNone, bkBracket, bkBracketAsgn, bkCurly, bkCurlyAsgn
+
+proc bracketKind*(g: TSrcGen, n: PNode): BracketKind =
+  if renderIds notin g.flags:
+    case n.kind
+    of nkClosedSymChoice, nkOpenSymChoice:
+      if n.len > 0: result = bracketKind(g, n[0])
+    of nkSym: 
+      result = case n.sym.name.s
+        of "[]": bkBracket
+        of "[]=": bkBracketAsgn
+        of "{}": bkCurly
+        of "{}=": bkCurlyAsgn
+        else: bkNone
+    else: result = bkNone
 
 proc skipHiddenNodes(n: PNode): PNode =
   result = n
@@ -892,10 +903,11 @@ proc skipHiddenNodes(n: PNode): PNode =
     else: break
 
 proc accentedName(g: var TSrcGen, n: PNode) =
+  const backticksNeeded = OpChars + {'[', '{'}
   if n == nil: return
   let isOperator =
-    if n.kind == nkIdent and n.ident.s.len > 0 and n.ident.s[0] in OpChars: true
-    elif n.kind == nkSym and n.sym.name.s.len > 0 and n.sym.name.s[0] in OpChars: true
+    if n.kind == nkIdent and n.ident.s.len > 0 and n.ident.s[0] in backticksNeeded: true
+    elif n.kind == nkSym and n.sym.name.s.len > 0 and n.sym.name.s[0] in backticksNeeded: true
     else: false
 
   if isOperator:
@@ -954,12 +966,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
   of nkCharLit: put(g, tkCharLit, atom(g, n))
   of nkNilLit: put(g, tkNil, atom(g, n))    # complex expressions
   of nkCall, nkConv, nkDotCall, nkPattern, nkObjConstr:
-    if renderIds notin g.flags and n.len > 0 and isBracket(n[0]):
-      gsub(g, n, 1)
-      put(g, tkBracketLe, "[")
-      gcomma(g, n, 2)
-      put(g, tkBracketRi, "]")
-    elif n.len > 1 and n.lastSon.kind == nkStmtList:
+    if n.len > 1 and n.lastSon.kind in {nkStmtList, nkStmtListExpr}:
       accentedName(g, n[0])
       if n.len > 2:
         put(g, tkParLe, "(")
@@ -967,10 +974,41 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
         put(g, tkParRi, ")")
       put(g, tkColon, ":")
       gsub(g, n, n.len-1)
+    elif n.len >= 1:     
+      case bracketKind(g, n[0])
+      of bkBracket:
+        gsub(g, n, 1)
+        put(g, tkBracketLe, "[")
+        gcomma(g, n, 2)
+        put(g, tkBracketRi, "]")
+      of bkBracketAsgn:
+        gsub(g, n, 1)
+        put(g, tkBracketLe, "[")
+        gcomma(g, n, 2, -2)
+        put(g, tkBracketRi, "]")
+        put(g, tkSpaces, Space)
+        putWithSpace(g, tkEquals, "=")
+        gsub(g, n, n.len - 1)
+      of bkCurly:
+        gsub(g, n, 1)
+        put(g, tkCurlyLe, "{")
+        gcomma(g, n, 2)
+        put(g, tkCurlyRi, "}")
+      of bkCurlyAsgn:
+        gsub(g, n, 1)
+        put(g, tkCurlyLe, "{")
+        gcomma(g, n, 2, -2)
+        put(g, tkCurlyRi, "}")
+        put(g, tkSpaces, Space)
+        putWithSpace(g, tkEquals, "=")
+        gsub(g, n, n.len - 1)
+      of bkNone:
+        accentedName(g, n[0])
+        put(g, tkParLe, "(")
+        gcomma(g, n, 1)
+        put(g, tkParRi, ")")
     else:
-      if n.len >= 1: accentedName(g, n[0])
       put(g, tkParLe, "(")
-      gcomma(g, n, 1)
       put(g, tkParRi, ")")
   of nkCallStrLit:
     if n.len > 0: accentedName(g, n[0])
diff --git a/tests/errmsgs/twrongcolon.nim b/tests/errmsgs/twrongcolon.nim
index 6f5cc3e5d..e59e37660 100644
--- a/tests/errmsgs/twrongcolon.nim
+++ b/tests/errmsgs/twrongcolon.nim
@@ -1,8 +1,8 @@
 discard """
-errormsg: "in expression '("
+errormsg: "in expression ':"
 nimout: '''
-Error: in expression '(
-  890)': identifier expected, but found ''
+Error: in expression ':
+  890': identifier expected, but found ''
 '''
 
 line: 11
diff --git a/tests/macros/tmacrostmt.nim b/tests/macros/tmacrostmt.nim
index 56a0bf840..79be5f764 100644
--- a/tests/macros/tmacrostmt.nim
+++ b/tests/macros/tmacrostmt.nim
@@ -100,18 +100,30 @@ proc fn4(x: int): int =
 proc fn5(a, b: float): float =
   result = - a * a / (b * b)
 
+proc `{}`(x: seq[float], i: int, j: int): float = 
+  x[i + 0 * j]
+
+proc `{}=`(x: var seq[float], i: int, val: float) = 
+  x[i] = val
+
+proc fn6() =
+  var a = @[1.0, 2.0]
+  let z = a{0, 1} 
+  a{2} = 5.0
+
+
 #------------------------------------
 # bug #10807
 proc fn_unsafeaddr(x: int): int =
   cast[int](unsafeAddr(x))
 
 static:
-  echo fn_unsafeaddr.repr_to_string
   let fn1s = "proc fn1(x, y: int): int =\n  result = 2 * (x + y)\n"
   let fn2s = "proc fn2(x, y: float): float =\n  result = (y + 2 * x) / (x - y)\n"
   let fn3s = "proc fn3(x, y: int): bool =\n  result = ((x and 3) div 4 or x mod (y xor -1)) == 0 or not contains([1, 2], y)\n"
   let fn4s = "proc fn4(x: int): int =\n  if x mod 2 == 0:\n    return x + 2\n  else:\n    return 0\n"
   let fn5s = "proc fn5(a, b: float): float =\n  result = -a * a / (b * b)\n"
+  let fn6s = "proc fn6() =\n  var a = @[1.0, 2.0]\n  let z = a{0, 1}\n  a{2} = 5.0\n"
   let fnAddr = "proc fn_unsafeaddr(x: int): int =\n  result = cast[int](unsafeAddr(x))\n"
 
   doAssert fn1.repr_to_string == fn1s
@@ -119,6 +131,7 @@ static:
   doAssert fn3.repr_to_string == fn3s
   doAssert fn4.repr_to_string == fn4s
   doAssert fn5.repr_to_string == fn5s
+  doAssert fn6.repr_to_string == fn6s
   doAssert fn_unsafeaddr.repr_to_string == fnAddr
 
 #------------------------------------