diff options
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/coro.nim | 36 | ||||
-rw-r--r-- | lib/pure/strutils.nim | 27 |
2 files changed, 34 insertions, 29 deletions
diff --git a/lib/pure/coro.nim b/lib/pure/coro.nim index 6ef5f6f54..8fa529474 100644 --- a/lib/pure/coro.nim +++ b/lib/pure/coro.nim @@ -15,8 +15,7 @@ import macros import arch import lists -const coroDefaultStackSize = 512 * 1024 - +const defaultStackSize = 512 * 1024 type Coroutine = ref object # prev: ptr Coroutine @@ -38,8 +37,7 @@ proc GC_addStack(starts: pointer) {.cdecl, importc.} proc GC_removeStack(starts: pointer) {.cdecl, importc.} proc GC_setCurrentStack(starts, pos: pointer) {.cdecl, importc.} - -proc coroStart*(c: proc(), stacksize: int=coroDefaultStackSize) = +proc start*(c: proc(), stacksize: int=defaultStackSize) = ## Adds coroutine to event loop. It does not run immediately. var coro = Coroutine() coro.fn = c @@ -49,20 +47,22 @@ proc coroStart*(c: proc(), stacksize: int=coroDefaultStackSize) = coroutines.append(coro) {.push stackTrace: off.} -proc coroYield*(sleepTime: float=0) = +proc suspend*(sleepTime: float=0) = ## Stops coroutine execution and resumes no sooner than after ``sleeptime`` seconds. ## Until then other coroutines are executed. + ## + ## This is similar to a `yield`:idx:, or a `yieldFrom`:idx in Python. var oldFrame = getFrame() var sp {.volatile.}: pointer GC_setCurrentStack(current.stack, cast[pointer](addr sp)) - current.sleepTime = sleep_time + current.sleepTime = sleepTime current.lastRun = epochTime() if setjmp(current.ctx) == 0: longjmp(mainCtx, 1) setFrame(oldFrame) {.pop.} -proc coroRun*() = +proc run*() = ## Starts main event loop which exits when all coroutines exit. Calling this proc ## starts execution of first coroutine. var node = coroutines.head @@ -108,18 +108,16 @@ proc coroRun*() = else: node = node.next - -proc coroAlive*(c: proc()): bool = +proc alive*(c: proc()): bool = ## Returns ``true`` if coroutine has not returned, ``false`` otherwise. for coro in items(coroutines): if coro.fn == c: return true -proc coroWait*(c: proc(), interval=0.01) = +proc wait*(c: proc(), interval=0.01) = ## Returns only after coroutine ``c`` has returned. ``interval`` is time in seconds how often. - while coroAlive(c): - coroYield interval - + while alive(c): + suspend interval when isMainModule: var stackCheckValue = 1100220033 @@ -128,18 +126,18 @@ when isMainModule: proc c1() = for i in 0 .. 3: echo "c1" - coroYield 0.05 + suspend 0.05 echo "c1 exits" proc c2() = for i in 0 .. 3: echo "c2" - coroYield 0.025 - coroWait(c1) + suspend 0.025 + wait(c1) echo "c2 exits" - coroStart(c1) - coroStart(c2) - coroRun() + start(c1) + start(c2) + run() echo "done ", stackCheckValue diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index e3f99b895..ae3bd7f63 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -1197,8 +1197,8 @@ proc editDistance*(a, b: string): int {.noSideEffect, # floating point formating: -proc c_sprintf(buf, frmt: cstring) {.header: "<stdio.h>", importc: "sprintf", - varargs, noSideEffect.} +proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>", + importc: "sprintf", varargs, noSideEffect.} type FloatFormatMode* = enum ## the different modes of floating point formating @@ -1209,7 +1209,8 @@ type {.deprecated: [TFloatFormat: FloatFormatMode].} proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, - precision: range[0..32] = 16): string {. + precision: range[0..32] = 16; + decimalSep = '.'): string {. noSideEffect, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. ## @@ -1225,6 +1226,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, var frmtstr {.noinit.}: array[0..5, char] buf {.noinit.}: array[0..2500, char] + L: cint frmtstr[0] = '%' if precision > 0: frmtstr[1] = '#' @@ -1232,15 +1234,20 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, frmtstr[3] = '*' frmtstr[4] = floatFormatToChar[format] frmtstr[5] = '\0' - c_sprintf(buf, frmtstr, precision, f) + L = c_sprintf(buf, frmtstr, precision, f) else: frmtstr[1] = floatFormatToChar[format] frmtstr[2] = '\0' - c_sprintf(buf, frmtstr, f) - result = $buf + L = c_sprintf(buf, frmtstr, f) + result = newString(L) + for i in 0 ..< L: + # Depending on the locale either dot or comma is produced, + # but nothing else is possible: + if buf[i] in {'.', ','}: result[i] = decimalsep + else: result[i] = buf[i] proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, - precision: range[0..32] = 16): string {. + precision: range[0..32] = 16; decimalSep = '.'): string {. noSideEffect, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. ## @@ -1250,7 +1257,7 @@ proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, ## of significant digits to be printed. ## `precision`'s default value is the maximum number of meaningful digits ## after the decimal point for Nim's ``float`` type. - result = formatBiggestFloat(f, format, precision) + result = formatBiggestFloat(f, format, precision, decimalSep) proc formatSize*(bytes: BiggestInt, decimalSep = '.'): string = ## Rounds and formats `bytes`. Examples: @@ -1464,8 +1471,8 @@ when isMainModule: doAssert wordWrap(inp, 10, false) == outp doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" - doAssert formatBiggestFloat(0.00000000001, ffScientific, 1) in - ["1.0e-11", "1.0e-011"] + doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in + ["1,0e-11", "1,0e-011"] doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c" when not defined(testing): |