From d34f95d1940d31d42bf0ce3c16c5366e41e668aa Mon Sep 17 00:00:00 2001 From: Simon Hafner Date: Sun, 10 Mar 2013 19:49:02 -0500 Subject: [PATCH 1/7] nestedTryStmts removed It makes tests fail and they work fine without. Given my ignorance of the exact workings, I can only rely on the tests. --- compiler/jsgen.nim | 13 ------------- tests/run/tfinally.nim | 8 +++++--- tests/run/tfinally2.nim | 17 ++++++++++------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 64175dc93a..1f95f79555 100755 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -44,7 +44,6 @@ type TBlock{.final.} = object id: int # the ID of the label; positive means that it # has been used (i.e. the label should be emitted) - nestedTryStmts: int # how many try statements is it nested into isLoop: bool # whether it's a 'block' or 'while' TGlobals{.final.} = object @@ -62,7 +61,6 @@ type module: BModule g: PGlobals BeforeRetNeeded: bool - nestedTryStmts: int unique: int blocks: seq[TBlock] @@ -485,10 +483,6 @@ proc genLineDir(p: var TProc, n: PNode, r: var TCompRes) = ((p.prc == nil) or not (sfPure in p.prc.flags)): appf(r.com, "F.line = $1;$n", [toRope(line)]) -proc finishTryStmt(p: var TProc, r: var TCompRes, howMany: int) = - for i in countup(1, howMany): - app(r.com, "excHandler = excHandler.prev;" & tnl) - proc genWhileStmt(p: var TProc, n: PNode, r: var TCompRes) = var cond, stmt: TCompRes @@ -498,7 +492,6 @@ proc genWhileStmt(p: var TProc, n: PNode, r: var TCompRes) = length = len(p.blocks) setlen(p.blocks, length + 1) p.blocks[length].id = - p.unique - p.blocks[length].nestedTryStmts = p.nestedTryStmts p.blocks[length].isLoop = true labl = p.unique gen(p, n.sons[0], cond) @@ -543,7 +536,6 @@ proc genTryStmt(p: var TProc, n: PNode, r: var TCompRes) = if optStackTrace in p.Options: app(r.com, "framePtr = F;" & tnl) app(r.com, "try {" & tnl) length = sonsLen(n) - inc(p.nestedTryStmts) genStmt(p, n.sons[0], a) app(r.com, mergeStmt(a)) i = 1 @@ -571,8 +563,6 @@ proc genTryStmt(p: var TProc, n: PNode, r: var TCompRes) = appf(epart, "$1}$n", [mergeStmt(a)]) inc(i) if epart != nil: appf(r.com, "} catch (EXC) {$n$1", [epart]) - finishTryStmt(p, r, p.nestedTryStmts) - dec(p.nestedTryStmts) app(r.com, "} finally {" & tnl & "excHandler = excHandler.prev;" & tnl) if (i < length) and (n.sons[i].kind == nkFinally): genStmt(p, n.sons[i].sons[0], a) @@ -655,7 +645,6 @@ proc genBlock(p: var TProc, n: PNode, r: var TCompRes) = sym.loc.a = idx setlen(p.blocks, idx + 1) p.blocks[idx].id = - p.unique # negative because it isn't used yet - p.blocks[idx].nestedTryStmts = p.nestedTryStmts labl = p.unique if n.kind == nkBlockExpr: genStmtListExpr(p, n.sons[1], r) else: genStmt(p, n.sons[1], r) @@ -682,7 +671,6 @@ proc genBreakStmt(p: var TProc, n: PNode, r: var TCompRes) = if idx < 0 or not p.blocks[idx].isLoop: InternalError(n.info, "no loop to break") p.blocks[idx].id = abs(p.blocks[idx].id) # label is used - finishTryStmt(p, r, p.nestedTryStmts - p.blocks[idx].nestedTryStmts) appf(r.com, "break L$1;$n", [toRope(p.blocks[idx].id)]) proc genAsmStmt(p: var TProc, n: PNode, r: var TCompRes) = @@ -1433,7 +1421,6 @@ proc genReturnStmt(p: var TProc, n: PNode, r: var TCompRes) = if a.com != nil: appf(r.com, "$1;$n", mergeStmt(a)) else: genLineDir(p, n, r) - finishTryStmt(p, r, p.nestedTryStmts) app(r.com, "break BeforeRet;" & tnl) proc genProcBody(p: var TProc, prc: PSym, r: TCompRes): PRope = diff --git a/tests/run/tfinally.nim b/tests/run/tfinally.nim index 29313c3fdf..2522dd0e4f 100755 --- a/tests/run/tfinally.nim +++ b/tests/run/tfinally.nim @@ -1,6 +1,8 @@ discard """ file: "tfinally.nim" - output: "came here 3" + output: "came +here +3" """ # Test return in try statement: @@ -9,10 +11,10 @@ proc main: int = try: return 1 finally: - stdout.write("came ") + echo("came") return 2 finally: - stdout.write("here ") + echo("here ") return 3 echo main() #OUT came here 3 diff --git a/tests/run/tfinally2.nim b/tests/run/tfinally2.nim index 3ed212a7c7..af94aee5b2 100755 --- a/tests/run/tfinally2.nim +++ b/tests/run/tfinally2.nim @@ -1,6 +1,9 @@ discard """ file: "tfinally2.nim" - output: "ABCD" + output: "A +B +C +D" """ # Test break in try statement: @@ -11,15 +14,15 @@ proc main: int = try: break AB finally: - stdout.write("A") - stdout.write("skipped") + echo("A") + echo("skipped") finally: block B: - stdout.write("B") - stdout.write("skipped") - stdout.write("C") + echo("B") + echo("skipped") + echo("C") finally: - stdout.writeln("D") + echo("D") discard main() #OUT ABCD From 75be9c8d552ab83be01d7f173efcbadc7a531e2a Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Mon, 11 Mar 2013 23:48:15 +0100 Subject: [PATCH 2/7] Implements `$` proc for a sequence of TRunes. --- lib/pure/unicode.nim | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index f76573788b..142178a868 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -132,6 +132,11 @@ proc toUTF8*(c: TRune): string {.rtl, extern: "nuc$1".} = result = newString(1) result[0] = chr(i) +proc `$`*(runes: seq[TRune]): string = + ## converts a sequence of runes to a string + result = "" + for rune in runes: result.add(rune.toUTF8) + const alphaRanges = [ 0x00d8, 0x00f6, # - @@ -1208,3 +1213,10 @@ proc cmpRunesIgnoreCase*(a, b: string): int {.rtl, extern: "nuc$1", procvar.} = result = irune(toLower(ar)) - irune(toLower(br)) if result != 0: return result = a.len - b.len + +when isMainModule: + let + someString = "öÑ" + someRunes = @[runeAt(someString, 0), runeAt(someString, 2)] + compared = (someString == $someRunes) + assert compared == true From 15af40bc1da55d0c9e4f0eff78e81ebf2727b26d Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Mon, 11 Mar 2013 23:57:25 +0100 Subject: [PATCH 3/7] Adds babel package manager link to library index. --- doc/lib.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/lib.txt b/doc/lib.txt index f186936148..2f781f3755 100755 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -16,7 +16,10 @@ Pure libraries do not depend on any external ``*.dll`` or ``lib*.so`` binary while impure libraries do. A wrapper is an impure library that is a very low-level interface to a C library. -Read this `document `_ for a quick overview of the API design. +Read this `document `_ for a quick overview of the API design. If +you can't find here some functionality you are looking for you could try using +the 3rd party `package manager Babel `_ +and its list of packages. Pure libraries From 9c0798d638e5d5aebc45056804ba11b9932abb96 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Tue, 12 Mar 2013 00:21:42 +0100 Subject: [PATCH 4/7] Adds left alignment example to strutils. --- lib/pure/strutils.nim | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 090ad640cb..b5f5a41eba 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -415,7 +415,15 @@ proc parseEnum*[T: enum](s: string, default: T): T = proc repeatChar*(count: int, c: Char = ' '): string {.noSideEffect, rtl, extern: "nsuRepeatChar".} = ## Returns a string of length `count` consisting only of - ## the character `c`. + ## the character `c`. You can use this proc to left align strings. Example: + ## + ## .. code-block:: nimrod + ## let + ## width = 15 + ## text1 = "Hello user!" + ## text2 = "This is a very long string" + ## echo text1 & repeatChar(max(0, width - text1.len)) & "|" + ## echo text2 & repeatChar(max(0, width - text2.len)) & "|" result = newString(count) for i in 0..count-1: result[i] = c @@ -429,7 +437,8 @@ proc align*(s: string, count: int): string {. noSideEffect, rtl, extern: "nsuAlignString".} = ## Aligns a string `s` with spaces, so that is of length `count`. Spaces are ## added before `s` resulting in right alignment. If ``s.len >= count``, no - ## spaces are added and `s` is returned unchanged. + ## spaces are added and `s` is returned unchanged. If you need to left align + ## a string use the repeatChar proc. if s.len < count: result = newString(count) var spaces = count - s.len From 9cd4482aa1edebdb45a048177112c871466252ce Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Tue, 12 Mar 2013 23:58:17 +0100 Subject: [PATCH 5/7] Adds newSeq documentation example. --- lib/system.nim | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/system.nim b/lib/system.nim index db78d27405..d25823a618 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -370,9 +370,34 @@ proc newSeq*[T](s: var seq[T], len: int) {.magic: "NewSeq", noSideEffect.} ## creates a new sequence of type ``seq[T]`` with length ``len``. ## This is equivalent to ``s = @[]; setlen(s, len)``, but more ## efficient since no reallocation is needed. + ## + ## Note that the sequence will be filled with uninitialized entries, which + ## can be a problem for sequences containing strings. After the creation of + ## the sequence you should assign entries to the sequence instead of adding + ## them. Example: + ## + ## .. code-block:: nimrod + ## var inputStrings : seq[string] + ## newSeq(inputStrings, 3) + ## inputStrings[0] = "The fourth" + ## inputStrings[1] = "assignment" + ## inputStrings[2] = "would crash" + ## #inputStrings[3] = "out of bounds" proc newSeq*[T](len = 0): seq[T] = ## creates a new sequence of type ``seq[T]`` with length ``len``. + ## + ## Note that the sequence will be filled with uninitialized entries, which + ## can be a problem for sequences containing strings. After the creation of + ## the sequence you should assign entries to the sequence instead of adding + ## them. Example: + ## + ## .. code-block:: nimrod + ## var inputStrings = newSeq[string](3) + ## inputStrings[0] = "The fourth" + ## inputStrings[1] = "assignment" + ## inputStrings[2] = "would crash" + ## #inputStrings[3] = "out of bounds" newSeq(result, len) proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {. From 1d9f680b788499fc3c3d1a9571ed89ab479c4e86 Mon Sep 17 00:00:00 2001 From: Simon Hafner Date: Sat, 16 Mar 2013 07:21:06 -0500 Subject: [PATCH 6/7] hack to include hti correctly --- lib/system/jssys.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 789e39d6dc..1c43bfdc76 100755 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -491,6 +491,7 @@ proc toU32(a: int): int32 {.noStackFrame, compilerproc.} = proc nimMin(a, b: int): int {.compilerproc.} = return if a <= b: a else: b proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b +type NimString = string # hack for hti.nim include "system/hti" proc isFatPointer(ti: PNimType): bool = From 129fcb327fb1900af0d9e55a668d7808344d29f3 Mon Sep 17 00:00:00 2001 From: Simon Hafner Date: Sat, 16 Mar 2013 07:21:31 -0500 Subject: [PATCH 7/7] used correct syntax for multiline results in tests And also modified the runner to actually run them in JS. --- tests/run/tfinally.nim | 4 ++-- tests/run/tfinally2.nim | 4 ++-- tests/specials.nim | 8 ++------ 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/run/tfinally.nim b/tests/run/tfinally.nim index 2522dd0e4f..273aac72b0 100755 --- a/tests/run/tfinally.nim +++ b/tests/run/tfinally.nim @@ -1,8 +1,8 @@ discard """ file: "tfinally.nim" - output: "came + output: '''came here -3" +3''' """ # Test return in try statement: diff --git a/tests/run/tfinally2.nim b/tests/run/tfinally2.nim index af94aee5b2..e1e8d4c7ee 100755 --- a/tests/run/tfinally2.nim +++ b/tests/run/tfinally2.nim @@ -1,9 +1,9 @@ discard """ file: "tfinally2.nim" - output: "A + output: '''A B C -D" +D''' """ # Test break in try statement: diff --git a/tests/specials.nim b/tests/specials.nim index 1818497a40..b5c49ec3c0 100644 --- a/tests/specials.nim +++ b/tests/specials.nim @@ -176,14 +176,10 @@ proc runJsTests(r: var TResults, options: string) = runSingleTest(r, filename, options & " -d:nodejs", targetJS) runSingleTest(r, filename, options & " -d:nodejs -d:release", targetJS) - # texceptions, texcpt1, texcsub, tfinally, tfinally2, - # tfinally3 for t in os.walkFiles("tests/js/t*.nim"): test(t) - test "tests/run/tactiontable" - test "tests/run/tmultim1" - test "tests/run/tmultim3" - test "tests/run/tmultim4" + for testfile in ["texceptions", "texcpt1", "texcsub", "tfinally", "tfinally2", "tfinally3", "tactiontable", "tmultim1", "tmultim3", "tmultim4"]: + test "tests/run/" & testfile & ".nim" # ------------------------- register special tests here ----------------------- proc runSpecialTests(r: var TResults, options: string) =