Merge branch 'master' of github.com:Araq/Nimrod

This commit is contained in:
Araq 2013-01-27 00:42:51 +01:00
commit 0a5344b595
12 changed files with 222 additions and 42 deletions

View file

@ -12,8 +12,8 @@
## This module implements operations for the built-in `seq`:idx: type which
## were inspired by functional programming languages. If you are looking for
## the typical `map` function which applies a function to every element in a
## sequence, it already exists as the `each` proc in the `system
## <system.html>`_ module in both mutable and immutable styles.
## sequence, it already exists in the `system <system.html>`_ module in both
## mutable and immutable styles.
##
## Also, for functional style programming you may want to pass `anonymous procs
## <manual.html#anonymous-procs>`_ to procs like ``filter`` to reduce typing.

View file

@ -141,6 +141,11 @@ proc randomize*()
## number, i.e. a tickcount. Note: Does nothing for the ECMAScript target,
## as ECMAScript does not support this.
proc randomize*(seed: int)
## initializes the random number generator with a specific seed.
## Note: Does nothing for the ECMAScript target,
## as ECMAScript does not support this.
when not defined(ECMAScript):
proc sqrt*(x: float): float {.importc: "sqrt", header: "<math.h>".}
## computes the square root of `x`.
@ -190,15 +195,17 @@ when not defined(ECMAScript):
proc rand(): cint {.importc: "rand", nodecl.}
when not defined(windows):
proc srand48(seed: cint) {.importc: "srand48", nodecl.}
proc srand48(seed: clong) {.importc: "srand48", nodecl.}
proc drand48(): float {.importc: "drand48", nodecl.}
proc random(max: float): float =
result = drand48() * max
proc randomize() =
let x = gettime(nil)
srand(x)
when defined(srand48): srand48(x)
randomize(gettime(nil))
proc randomize(seed: int) =
srand(cint(seed))
when defined(srand48): srand48(seed)
proc random(max: int): int =
result = int(rand()) mod max
@ -217,6 +224,7 @@ else:
proc random(max: float): float =
result = float(mathrandom() * float(max))
proc randomize() = nil
proc randomize(seed: int) = nil
proc sqrt*(x: float): float {.importc: "Math.sqrt", nodecl.}
proc ln*(x: float): float {.importc: "Math.log", nodecl.}
@ -301,3 +309,18 @@ proc standardDeviation*(s: TRunningStat): float =
{.pop.}
{.pop.}
when isMainModule and not defined(ECMAScript):
# Verifies random seed initialization.
let seed = gettime(nil)
randomize(seed)
const SIZE = 10
var buf : array[0..SIZE, int]
# Fill the buffer with random values
for i in 0..SIZE-1:
buf[i] = random(high(int))
# Check that the second random calls are the same for each position.
randomize(seed)
for i in 0..SIZE-1:
assert buf[i] == random(high(int)), "non deterministic random seeding"
echo "random values equal after reseeding"

View file

@ -850,13 +850,51 @@ proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
for c in items(s):
case c
of '\0'..'\31', '\128'..'\255':
add(result, '\\')
add(result, "\\x")
add(result, toHex(ord(c), 2))
of '\\': add(result, "\\\\")
of '\'': add(result, "\\'")
of '\"': add(result, "\\\"")
else: add(result, c)
add(result, suffix)
proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
rtl, extern: "nsuUnescape".} =
## Unescapes a string `s`. This complements ``escape`` as it performs the
## opposite operations.
##
## If `s` does not begin with ``prefix`` and end with ``suffix`` a EInvalidValue
## exception will be raised.
result = newStringOfCap(s.len)
var i = 0
if s[0 .. prefix.len-1] != prefix:
raise newException(EInvalidValue,
"String does not start with a prefix of: " & prefix)
i.inc()
while True:
if i == s.len-suffix.len: break
case s[i]
of '\\':
case s[i+1]:
of 'x':
let j = parseHexInt(s[i+2 .. i+3])
result.add(chr(j))
inc(i, 2)
of '\\':
result.add('\\')
of '\'':
result.add('\'')
of '\"':
result.add('\"')
else: result.add("\\" & s[i+1])
inc(i)
of '\0': break
else:
result.add(s[i])
i.inc()
if s[i .. -1] != suffix:
raise newException(EInvalidValue,
"String does not end with a suffix of: " & suffix)
proc validIdentifier*(s: string): bool {.noSideEffect,
rtl, extern: "nsuValidIdentifier".} =

View file

@ -38,7 +38,8 @@ type
char* {.magic: Char.} ## built-in 8 bit character type (unsigned)
string* {.magic: String.} ## built-in string type
cstring* {.magic: Cstring.} ## built-in cstring (*compatible string*) type
pointer* {.magic: Pointer.} ## built-in pointer type
pointer* {.magic: Pointer.} ## built-in pointer type, use the ``addr``
## operator to get a pointer to a variable
const
on* = true ## alias for ``true``
@ -1460,15 +1461,51 @@ proc pop*[T](s: var seq[T]): T {.inline, noSideEffect.} =
result = s[L]
setLen(s, L)
proc each*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] =
## The well-known `map`:idx: operation from functional programming. Applies
proc each*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] {.
deprecated.} =
## The well-known ``map`` operation from functional programming. Applies
## `op` to every item in `data` and returns the result as a sequence.
##
## **Deprecated since version 0.9:** Use the ``map`` proc instead.
newSeq(result, data.len)
for i in 0..data.len-1: result[i] = op(data[i])
proc each*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) =
## The well-known `map`:idx: operation from functional programming. Applies
proc each*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) {.
deprecated.} =
## The well-known ``map`` operation from functional programming. Applies
## `op` to every item in `data` modifying it directly.
##
## **Deprecated since version 0.9:** Use the ``map`` proc instead.
for i in 0..data.len-1: op(data[i])
proc map*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] =
## Returns a new sequence with the results of `op` applied to every item in
## `data`.
##
## Since the input is not modified you can use this version of ``map`` to
## transform the type of the elements in the input sequence. Example:
##
## .. code-block:: nimrod
## let
## a = @[1, 2, 3, 4]
## b = map(a, proc(x: int): string = $x)
## assert b == @["1", "2", "3", "4"]
newSeq(result, data.len)
for i in 0..data.len-1: result[i] = op(data[i])
proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) =
## Applies `op` to every item in `data` modifying it directly.
##
## Note that this version of ``map`` requires your input and output types to
## be the same, since they are modified in-place. Example:
##
## .. code-block:: nimrod
## var a = @["1", "2", "3", "4"]
## echo repr(a)
## # --> ["1", "2", "3", "4"]
## map(a, proc(x: var string) = x &= "42")
## echo repr(a)
## # --> ["142", "242", "342", "442"]
for i in 0..data.len-1: op(data[i])
iterator fields*[T: tuple](x: T): TObject {.

View file

@ -16598,6 +16598,7 @@ proc message_dialog_new*(parent: PWindow, flags: TDialogFlags,
cdecl, importc: "gtk_message_dialog_new", dynlib: lib.}
proc set_markup*(msgDialog: PMessageDialog, str: cstring) {.cdecl,
importc: "gtk_message_dialog_set_markup", dynlib: lib.}
proc signal_new*(name: cstring, signal_flags: TSignalRunType,
object_type: TType, function_offset: guint,
marshaller: TSignalMarshaller, return_val: TType, n_args: guint): guint{.
@ -16895,6 +16896,15 @@ type
proc set_tooltip_text*(w: PWidget, t: cstring){.cdecl,
dynlib: lib, importc: "gtk_widget_set_tooltip_text".}
proc get_tooltip_text*(w: PWidget): cstring{.cdecl,
dynlib: lib, importc: "gtk_widget_get_tooltip_text".}
proc set_tooltip_markup*(w: PWidget, m: cstring) {.cdecl, dynlib: lib,
importc: "gtk_widget_set_tooltip_markup".}
proc get_tooltip_markup*(w: PWidget): cstring {.cdecl, dynlib: lib,
importc: "gtk_widget_get_tooltip_markup".}
proc set_tooltip_column*(w: PTreeview, column: gint){.cdecl,
dynlib: lib, importc: "gtk_tree_view_set_tooltip_column".}
@ -16907,6 +16917,9 @@ proc trigger_tooltip_query*(widg: PTooltip){.cdecl, dynlib: lib,
proc set_has_tooltip*(widget: PWidget, b: gboolean){.cdecl, dynlib: lib,
importc: "gtk_widget_set_has_tooltip".}
proc get_has_tooltip*(widget: PWidget): gboolean{.cdecl, dynlib: lib,
importc: "gtk_widget_get_has_tooltip".}
proc set_markup*(tp: PTooltip, mk: cstring){.cdecl, dynlib: lib,
importc: "gtk_tooltip_set_markup".}
@ -17037,6 +17050,10 @@ proc remove*(combo_box: PComboBoxText; position: gint){.cdecl,
importc: "gtk_combo_box_text_remove", dynlib: lib.}
proc get_active_text*(combo_box: PComboBoxText): cstring{.cdecl,
importc: "gtk_combo_box_text_get_active_text", dynlib: lib.}
proc is_active*(win: PWindow): gboolean{.cdecl,
importc: "gtk_window_is_active", dynlib: lib.}
proc has_toplevel_focus*(win: PWindow): gboolean{.cdecl,
importc: "gtk_window_has_toplevel_focus", dynlib: lib.}
proc nimrod_init*() =
var