summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/jsgen.nim13
-rwxr-xr-xdoc/lib.txt5
-rwxr-xr-xlib/pure/strutils.nim13
-rw-r--r--lib/pure/unicode.nim12
-rwxr-xr-xlib/system.nim25
-rwxr-xr-xlib/system/jssys.nim1
-rwxr-xr-xtests/run/tfinally.nim8
-rwxr-xr-xtests/run/tfinally2.nim17
-rw-r--r--tests/specials.nim8
9 files changed, 70 insertions, 32 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 64175dc93..1f95f7955 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/doc/lib.txt b/doc/lib.txt
index f18693614..2f781f375 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 <apis.html>`_ for a quick overview of the API design.
+Read this `document <apis.html>`_ 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 <https://github.com/nimrod-code/babel>`_
+and its list of packages.
 
 
 Pure libraries
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 090ad640c..b5f5a41eb 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

diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index f76573788..142178a86 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
diff --git a/lib/system.nim b/lib/system.nim
index 4aa7ecad5..8885de624 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 {.
diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim
index 789e39d6d..1c43bfdc7 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 =
diff --git a/tests/run/tfinally.nim b/tests/run/tfinally.nim
index 29313c3fd..273aac72b 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 3ed212a7c..e1e8d4c7e 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
 
diff --git a/tests/specials.nim b/tests/specials.nim
index 1818497a4..b5c49ec3c 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) =