From c6a8bd264e77da69fc95de17a7febe5a32955a40 Mon Sep 17 00:00:00 2001 From: cooldome Date: Mon, 24 Apr 2017 19:17:06 +0100 Subject: [PATCH 1/3] Fix for #5695 make subscript operator overloadable for tuples (#5749) --- compiler/semexprs.nim | 6 ++--- tests/tuples/tuple_subscript.nim | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 tests/tuples/tuple_subscript.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 316cf55c8f..25f62983dc 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1266,7 +1266,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = result.typ = makeTypeDesc(c, semTypeNode(c, n, nil)) #result = symNodeFromType(c, semTypeNode(c, n, nil), n.info) of tyTuple: - checkSonsLen(n, 2) + if n.len != 2: return nil n.sons[0] = makeDeref(n.sons[0]) c.p.bracketExpr = n.sons[0] # [] operator for tuples requires constant expression: @@ -1276,9 +1276,9 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = var idx = getOrdValue(n.sons[1]) if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)] else: localError(n.info, errInvalidIndexValueForTuple) + result = n else: - localError(n.info, errIndexTypesDoNotMatch) - result = n + result = nil else: let s = if n.sons[0].kind == nkSym: n.sons[0].sym elif n[0].kind in nkSymChoices: n.sons[0][0].sym diff --git a/tests/tuples/tuple_subscript.nim b/tests/tuples/tuple_subscript.nim new file mode 100644 index 0000000000..021793dc3f --- /dev/null +++ b/tests/tuples/tuple_subscript.nim @@ -0,0 +1,40 @@ +discard """ + output: '''5 +5 +str2 +str2 +4''' +""" + +proc`[]` (t: tuple, key: string): string = + for name, field in fieldPairs(t): + if name == key: + return $field + return "" + + +proc`[]` [A,B](t: tuple, key: string, op: (proc(x: A): B)): B = + for name, field in fieldPairs(t): + when field is A: + if name == key: + return op(field) + +proc`[]=`[T](t: var tuple, key: string, val: T) = + for name, field in fieldPairs(t): + when field is T: + if name == key: + field = val + +var tt = (a: 1, b: "str1") + +# test built in operator +tt[0] = 5 +echo tt[0] +echo `[]`(tt, 0) + + +# test overloaded operator +tt["b"] = "str2" +echo tt["b"] +echo `[]`(tt, "b") +echo tt["b", proc(s: string) : int = s.len] \ No newline at end of file From 05c20bc4ffc8d3c4d0514d2834830d057ecd194a Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 25 Apr 2017 19:36:05 +0200 Subject: [PATCH 2/3] fixes a parser bug --- compiler/parser.nim | 5 +---- tests/parser/twrongcmdsyntax.nim | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 tests/parser/twrongcmdsyntax.nim diff --git a/compiler/parser.nim b/compiler/parser.nim index e9dff25acd..fabe4bcc8c 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1238,10 +1238,7 @@ proc parseExprStmt(p: var TParser): PNode = addSon(result, e) if p.tok.tokType != tkComma: break elif p.tok.indent < 0 and isExprStart(p): - if a.kind == nkCommand: - result = a - else: - result = newNode(nkCommand, a.info, @[a]) + result = newNode(nkCommand, a.info, @[a]) while true: var e = parseExpr(p) addSon(result, e) diff --git a/tests/parser/twrongcmdsyntax.nim b/tests/parser/twrongcmdsyntax.nim new file mode 100644 index 0000000000..affe72c340 --- /dev/null +++ b/tests/parser/twrongcmdsyntax.nim @@ -0,0 +1,6 @@ +discard """ + errormsg: '''identifier expected, but found 'echo 4''' + line: 6 +""" + +echo 4 +2 From 6ac37ee2fbfdd46f2ddffbd98eb64994a490d841 Mon Sep 17 00:00:00 2001 From: Daniil Yarancev Date: Tue, 25 Apr 2017 21:47:26 +0300 Subject: [PATCH 3/3] Small base64.nim refactor (#5755) * Small changes (var to let) * Some additional `var` to `let` * Fix * Finally removed immediate --- lib/pure/base64.nim | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index eee03d7ae7..4b0d082928 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -44,21 +44,23 @@ const cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" -template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediate.} = +template encodeInternal(s: typed, lineLen: int, newLine: string): untyped = ## encodes `s` into base64 representation. After `lineLen` characters, a ## `newline` is added. var total = ((len(s) + 2) div 3) * 4 - var numLines = (total + lineLen - 1) div lineLen + let numLines = (total + lineLen - 1) div lineLen if numLines > 0: inc(total, (numLines - 1) * newLine.len) result = newString(total) - var i = 0 - var r = 0 - var currLine = 0 + var + i = 0 + r = 0 + currLine = 0 while i < s.len - 2: - var a = ord(s[i]) - var b = ord(s[i+1]) - var c = ord(s[i+2]) + let + a = ord(s[i]) + b = ord(s[i+1]) + c = ord(s[i+2]) result[r] = cb64[a shr 2] result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] result[r+2] = cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)] @@ -74,8 +76,9 @@ template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediat currLine = 0 if i < s.len-1: - var a = ord(s[i]) - var b = ord(s[i+1]) + let + a = ord(s[i]) + b = ord(s[i+1]) result[r] = cb64[a shr 2] result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] result[r+2] = cb64[((b and 0x0F) shl 2)] @@ -83,7 +86,7 @@ template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediat if r+4 != result.len: setLen(result, r+4) elif i < s.len: - var a = ord(s[i]) + let a = ord(s[i]) result[r] = cb64[a shr 2] result[r+1] = cb64[(a and 3) shl 4] result[r+2] = '=' @@ -127,15 +130,17 @@ proc decode*(s: string): string = # total is an upper bound, as we will skip arbitrary whitespace: result = newString(total) - var i = 0 - var r = 0 + var + i = 0 + r = 0 while true: while s[i] in Whitespace: inc(i) if i < s.len-3: - var a = s[i].decodeByte - var b = s[i+1].decodeByte - var c = s[i+2].decodeByte - var d = s[i+3].decodeByte + let + a = s[i].decodeByte + b = s[i+1].decodeByte + c = s[i+2].decodeByte + d = s[i+3].decodeByte result[r] = chr((a shl 2) and 0xff or ((b shr 4) and 0x03)) result[r+1] = chr((b shl 4) and 0xff or ((c shr 2) and 0x0F)) @@ -169,4 +174,4 @@ when isMainModule: for t in items(tests): assert decode(encode(t)) == t assert decode(encode(t, lineLen=40)) == t - assert decode(encode(t, lineLen=76)) == t \ No newline at end of file + assert decode(encode(t, lineLen=76)) == t