Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
commit
f24f9fec1d
9 changed files with 70 additions and 32 deletions
|
|
@ -44,7 +44,6 @@ type
|
||||||
TBlock{.final.} = object
|
TBlock{.final.} = object
|
||||||
id: int # the ID of the label; positive means that it
|
id: int # the ID of the label; positive means that it
|
||||||
# has been used (i.e. the label should be emitted)
|
# 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'
|
isLoop: bool # whether it's a 'block' or 'while'
|
||||||
|
|
||||||
TGlobals{.final.} = object
|
TGlobals{.final.} = object
|
||||||
|
|
@ -62,7 +61,6 @@ type
|
||||||
module: BModule
|
module: BModule
|
||||||
g: PGlobals
|
g: PGlobals
|
||||||
BeforeRetNeeded: bool
|
BeforeRetNeeded: bool
|
||||||
nestedTryStmts: int
|
|
||||||
unique: int
|
unique: int
|
||||||
blocks: seq[TBlock]
|
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)):
|
((p.prc == nil) or not (sfPure in p.prc.flags)):
|
||||||
appf(r.com, "F.line = $1;$n", [toRope(line)])
|
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) =
|
proc genWhileStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
var
|
var
|
||||||
cond, stmt: TCompRes
|
cond, stmt: TCompRes
|
||||||
|
|
@ -498,7 +492,6 @@ proc genWhileStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
length = len(p.blocks)
|
length = len(p.blocks)
|
||||||
setlen(p.blocks, length + 1)
|
setlen(p.blocks, length + 1)
|
||||||
p.blocks[length].id = - p.unique
|
p.blocks[length].id = - p.unique
|
||||||
p.blocks[length].nestedTryStmts = p.nestedTryStmts
|
|
||||||
p.blocks[length].isLoop = true
|
p.blocks[length].isLoop = true
|
||||||
labl = p.unique
|
labl = p.unique
|
||||||
gen(p, n.sons[0], cond)
|
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)
|
if optStackTrace in p.Options: app(r.com, "framePtr = F;" & tnl)
|
||||||
app(r.com, "try {" & tnl)
|
app(r.com, "try {" & tnl)
|
||||||
length = sonsLen(n)
|
length = sonsLen(n)
|
||||||
inc(p.nestedTryStmts)
|
|
||||||
genStmt(p, n.sons[0], a)
|
genStmt(p, n.sons[0], a)
|
||||||
app(r.com, mergeStmt(a))
|
app(r.com, mergeStmt(a))
|
||||||
i = 1
|
i = 1
|
||||||
|
|
@ -571,8 +563,6 @@ proc genTryStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
appf(epart, "$1}$n", [mergeStmt(a)])
|
appf(epart, "$1}$n", [mergeStmt(a)])
|
||||||
inc(i)
|
inc(i)
|
||||||
if epart != nil: appf(r.com, "} catch (EXC) {$n$1", [epart])
|
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)
|
app(r.com, "} finally {" & tnl & "excHandler = excHandler.prev;" & tnl)
|
||||||
if (i < length) and (n.sons[i].kind == nkFinally):
|
if (i < length) and (n.sons[i].kind == nkFinally):
|
||||||
genStmt(p, n.sons[i].sons[0], a)
|
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
|
sym.loc.a = idx
|
||||||
setlen(p.blocks, idx + 1)
|
setlen(p.blocks, idx + 1)
|
||||||
p.blocks[idx].id = - p.unique # negative because it isn't used yet
|
p.blocks[idx].id = - p.unique # negative because it isn't used yet
|
||||||
p.blocks[idx].nestedTryStmts = p.nestedTryStmts
|
|
||||||
labl = p.unique
|
labl = p.unique
|
||||||
if n.kind == nkBlockExpr: genStmtListExpr(p, n.sons[1], r)
|
if n.kind == nkBlockExpr: genStmtListExpr(p, n.sons[1], r)
|
||||||
else: genStmt(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:
|
if idx < 0 or not p.blocks[idx].isLoop:
|
||||||
InternalError(n.info, "no loop to break")
|
InternalError(n.info, "no loop to break")
|
||||||
p.blocks[idx].id = abs(p.blocks[idx].id) # label is used
|
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)])
|
appf(r.com, "break L$1;$n", [toRope(p.blocks[idx].id)])
|
||||||
|
|
||||||
proc genAsmStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
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))
|
if a.com != nil: appf(r.com, "$1;$n", mergeStmt(a))
|
||||||
else:
|
else:
|
||||||
genLineDir(p, n, r)
|
genLineDir(p, n, r)
|
||||||
finishTryStmt(p, r, p.nestedTryStmts)
|
|
||||||
app(r.com, "break BeforeRet;" & tnl)
|
app(r.com, "break BeforeRet;" & tnl)
|
||||||
|
|
||||||
proc genProcBody(p: var TProc, prc: PSym, r: TCompRes): PRope =
|
proc genProcBody(p: var TProc, prc: PSym, r: TCompRes): PRope =
|
||||||
|
|
|
||||||
|
|
@ -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
|
while impure libraries do. A wrapper is an impure library that is a very
|
||||||
low-level interface to a C library.
|
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
|
Pure libraries
|
||||||
|
|
|
||||||
|
|
@ -415,7 +415,15 @@ proc parseEnum*[T: enum](s: string, default: T): T =
|
||||||
proc repeatChar*(count: int, c: Char = ' '): string {.noSideEffect,
|
proc repeatChar*(count: int, c: Char = ' '): string {.noSideEffect,
|
||||||
rtl, extern: "nsuRepeatChar".} =
|
rtl, extern: "nsuRepeatChar".} =
|
||||||
## Returns a string of length `count` consisting only of
|
## 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)
|
result = newString(count)
|
||||||
for i in 0..count-1: result[i] = c
|
for i in 0..count-1: result[i] = c
|
||||||
|
|
||||||
|
|
@ -429,7 +437,8 @@ proc align*(s: string, count: int): string {.
|
||||||
noSideEffect, rtl, extern: "nsuAlignString".} =
|
noSideEffect, rtl, extern: "nsuAlignString".} =
|
||||||
## Aligns a string `s` with spaces, so that is of length `count`. Spaces are
|
## 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
|
## 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:
|
if s.len < count:
|
||||||
result = newString(count)
|
result = newString(count)
|
||||||
var spaces = count - s.len
|
var spaces = count - s.len
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,11 @@ proc toUTF8*(c: TRune): string {.rtl, extern: "nuc$1".} =
|
||||||
result = newString(1)
|
result = newString(1)
|
||||||
result[0] = chr(i)
|
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
|
const
|
||||||
alphaRanges = [
|
alphaRanges = [
|
||||||
0x00d8, 0x00f6, # -
|
0x00d8, 0x00f6, # -
|
||||||
|
|
@ -1208,3 +1213,10 @@ proc cmpRunesIgnoreCase*(a, b: string): int {.rtl, extern: "nuc$1", procvar.} =
|
||||||
result = irune(toLower(ar)) - irune(toLower(br))
|
result = irune(toLower(ar)) - irune(toLower(br))
|
||||||
if result != 0: return
|
if result != 0: return
|
||||||
result = a.len - b.len
|
result = a.len - b.len
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
let
|
||||||
|
someString = "öÑ"
|
||||||
|
someRunes = @[runeAt(someString, 0), runeAt(someString, 2)]
|
||||||
|
compared = (someString == $someRunes)
|
||||||
|
assert compared == true
|
||||||
|
|
|
||||||
|
|
@ -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``.
|
## creates a new sequence of type ``seq[T]`` with length ``len``.
|
||||||
## This is equivalent to ``s = @[]; setlen(s, len)``, but more
|
## This is equivalent to ``s = @[]; setlen(s, len)``, but more
|
||||||
## efficient since no reallocation is needed.
|
## 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] =
|
proc newSeq*[T](len = 0): seq[T] =
|
||||||
## creates a new sequence of type ``seq[T]`` with length ``len``.
|
## 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)
|
newSeq(result, len)
|
||||||
|
|
||||||
proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.
|
proc len*[TOpenArray: openArray|varargs](x: TOpenArray): int {.
|
||||||
|
|
|
||||||
|
|
@ -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 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
|
proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b
|
||||||
|
|
||||||
|
type NimString = string # hack for hti.nim
|
||||||
include "system/hti"
|
include "system/hti"
|
||||||
|
|
||||||
proc isFatPointer(ti: PNimType): bool =
|
proc isFatPointer(ti: PNimType): bool =
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tfinally.nim"
|
file: "tfinally.nim"
|
||||||
output: "came here 3"
|
output: '''came
|
||||||
|
here
|
||||||
|
3'''
|
||||||
"""
|
"""
|
||||||
# Test return in try statement:
|
# Test return in try statement:
|
||||||
|
|
||||||
|
|
@ -9,10 +11,10 @@ proc main: int =
|
||||||
try:
|
try:
|
||||||
return 1
|
return 1
|
||||||
finally:
|
finally:
|
||||||
stdout.write("came ")
|
echo("came")
|
||||||
return 2
|
return 2
|
||||||
finally:
|
finally:
|
||||||
stdout.write("here ")
|
echo("here ")
|
||||||
return 3
|
return 3
|
||||||
|
|
||||||
echo main() #OUT came here 3
|
echo main() #OUT came here 3
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tfinally2.nim"
|
file: "tfinally2.nim"
|
||||||
output: "ABCD"
|
output: '''A
|
||||||
|
B
|
||||||
|
C
|
||||||
|
D'''
|
||||||
"""
|
"""
|
||||||
# Test break in try statement:
|
# Test break in try statement:
|
||||||
|
|
||||||
|
|
@ -11,15 +14,15 @@ proc main: int =
|
||||||
try:
|
try:
|
||||||
break AB
|
break AB
|
||||||
finally:
|
finally:
|
||||||
stdout.write("A")
|
echo("A")
|
||||||
stdout.write("skipped")
|
echo("skipped")
|
||||||
finally:
|
finally:
|
||||||
block B:
|
block B:
|
||||||
stdout.write("B")
|
echo("B")
|
||||||
stdout.write("skipped")
|
echo("skipped")
|
||||||
stdout.write("C")
|
echo("C")
|
||||||
finally:
|
finally:
|
||||||
stdout.writeln("D")
|
echo("D")
|
||||||
|
|
||||||
discard main() #OUT ABCD
|
discard main() #OUT ABCD
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,14 +176,10 @@ proc runJsTests(r: var TResults, options: string) =
|
||||||
runSingleTest(r, filename, options & " -d:nodejs", targetJS)
|
runSingleTest(r, filename, options & " -d:nodejs", targetJS)
|
||||||
runSingleTest(r, filename, options & " -d:nodejs -d:release", 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"):
|
for t in os.walkFiles("tests/js/t*.nim"):
|
||||||
test(t)
|
test(t)
|
||||||
test "tests/run/tactiontable"
|
for testfile in ["texceptions", "texcpt1", "texcsub", "tfinally", "tfinally2", "tfinally3", "tactiontable", "tmultim1", "tmultim3", "tmultim4"]:
|
||||||
test "tests/run/tmultim1"
|
test "tests/run/" & testfile & ".nim"
|
||||||
test "tests/run/tmultim3"
|
|
||||||
test "tests/run/tmultim4"
|
|
||||||
|
|
||||||
# ------------------------- register special tests here -----------------------
|
# ------------------------- register special tests here -----------------------
|
||||||
proc runSpecialTests(r: var TResults, options: string) =
|
proc runSpecialTests(r: var TResults, options: string) =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue