diff options
-rw-r--r-- | compiler/renderer.nim | 70 | ||||
-rw-r--r-- | tests/errmsgs/twrongcolon.nim | 6 | ||||
-rw-r--r-- | tests/macros/tmacrostmt.nim | 15 |
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 #------------------------------------ |