Merge branch 'master' of github.com:Araq/Nimrod into upstream
This commit is contained in:
commit
c1ad05c4c5
32 changed files with 12023 additions and 459 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
REM Generated by niminst
|
REM Generated by niminst
|
||||||
SET CC=gcc
|
SET CC=gcc
|
||||||
SET LINKER=gcc
|
SET LINKER=gcc
|
||||||
SET COMP_FLAGS= -w -O3 -fno-strict-aliasing
|
SET COMP_FLAGS=-w -O3 -fno-strict-aliasing
|
||||||
SET LINK_FLAGS=
|
SET LINK_FLAGS=
|
||||||
|
|
||||||
REM call the compiler:
|
REM call the compiler:
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
REM Generated by niminst
|
REM Generated by niminst
|
||||||
SET CC=gcc
|
SET CC=gcc
|
||||||
SET LINKER=gcc
|
SET LINKER=gcc
|
||||||
SET COMP_FLAGS= -w -O3 -fno-strict-aliasing
|
SET COMP_FLAGS=-w -O3 -fno-strict-aliasing
|
||||||
SET LINK_FLAGS=
|
SET LINK_FLAGS=
|
||||||
|
|
||||||
REM call the compiler:
|
REM call the compiler:
|
||||||
|
|
|
||||||
|
|
@ -386,7 +386,11 @@ proc lsub(n: PNode): int =
|
||||||
of nkTypeDef: result = lsons(n) + 3
|
of nkTypeDef: result = lsons(n) + 3
|
||||||
of nkOfInherit: result = lsub(n.sons[0]) + len("of_")
|
of nkOfInherit: result = lsub(n.sons[0]) + len("of_")
|
||||||
of nkProcTy: result = lsons(n) + len("proc_")
|
of nkProcTy: result = lsons(n) + len("proc_")
|
||||||
of nkEnumTy: result = lsub(n.sons[0]) + lcomma(n, 1) + len("enum_")
|
of nkEnumTy:
|
||||||
|
if sonsLen(n) > 0:
|
||||||
|
result = lsub(n.sons[0]) + lcomma(n, 1) + len("enum_")
|
||||||
|
else:
|
||||||
|
result = len("enum")
|
||||||
of nkEnumFieldDef: result = lsons(n) + 3
|
of nkEnumFieldDef: result = lsons(n) + 3
|
||||||
of nkVarSection, nkLetSection:
|
of nkVarSection, nkLetSection:
|
||||||
if sonsLen(n) > 1: result = maxLineLen + 1
|
if sonsLen(n) > 1: result = maxLineLen + 1
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,11 @@ hint[LineTooLong]=off
|
||||||
gcc.options.linker = "-ldl"
|
gcc.options.linker = "-ldl"
|
||||||
clang.options.linker = "-ldl"
|
clang.options.linker = "-ldl"
|
||||||
tcc.options.linker = "-ldl"
|
tcc.options.linker = "-ldl"
|
||||||
|
@else:
|
||||||
|
# BSD got posix_spawn only recently, so we deactivate it for osproc:
|
||||||
|
define:useFork
|
||||||
|
# at least NetBSD has problems with thread local storage:
|
||||||
|
tlsEmulation:on
|
||||||
@end
|
@end
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
||||||
24
doc/lib.txt
24
doc/lib.txt
|
|
@ -289,6 +289,15 @@ Miscellaneous
|
||||||
This module implements an event system that is not dependant on external
|
This module implements an event system that is not dependant on external
|
||||||
graphical toolkits.
|
graphical toolkits.
|
||||||
|
|
||||||
|
* `oids <oids.html>`_
|
||||||
|
An OID is a global ID that consists of a timestamp,
|
||||||
|
a unique counter and a random value. This combination should suffice to
|
||||||
|
produce a globally distributed unique ID. This implementation was extracted
|
||||||
|
from the Mongodb interface and it thus binary compatible with a Mongo OID.
|
||||||
|
|
||||||
|
* `endians <endians.html>`_
|
||||||
|
This module contains helpers that deal with different byte orders.
|
||||||
|
|
||||||
|
|
||||||
Database support
|
Database support
|
||||||
----------------
|
----------------
|
||||||
|
|
@ -331,6 +340,12 @@ Database support
|
||||||
A higher level SQLite database wrapper. The same interface is implemented
|
A higher level SQLite database wrapper. The same interface is implemented
|
||||||
for other databases too.
|
for other databases too.
|
||||||
|
|
||||||
|
* `db_mongo <db_mongo.html>`_
|
||||||
|
A higher level **mongodb** wrapper.
|
||||||
|
|
||||||
|
* `mongodb <mongo.html>`_
|
||||||
|
Lower level wrapper for the **mongodb** client C library.
|
||||||
|
|
||||||
|
|
||||||
Other
|
Other
|
||||||
-----
|
-----
|
||||||
|
|
@ -489,6 +504,9 @@ Graphics libraries
|
||||||
* `wingl <wingl.html>`_
|
* `wingl <wingl.html>`_
|
||||||
Part of the wrapper for OpenGL.
|
Part of the wrapper for OpenGL.
|
||||||
|
|
||||||
|
* `opengl <opengl.html>`_
|
||||||
|
New wrapper for OpenGL supporting up to version 4.2.
|
||||||
|
|
||||||
|
|
||||||
GUI libraries
|
GUI libraries
|
||||||
-------------
|
-------------
|
||||||
|
|
@ -581,3 +599,9 @@ Data Compression and Archiving
|
||||||
Interface to the `lib zip <http://www.nih.at/libzip/index.html>`_ library by
|
Interface to the `lib zip <http://www.nih.at/libzip/index.html>`_ library by
|
||||||
Dieter Baron and Thomas Klausner.
|
Dieter Baron and Thomas Klausner.
|
||||||
|
|
||||||
|
|
||||||
|
Scientific computing
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* `libsvm <libsvm.html>`_
|
||||||
|
Low level wrapper for `libsvm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/>`_.
|
||||||
|
|
|
||||||
|
|
@ -2567,11 +2567,11 @@ Type constraints
|
||||||
type parameter. Only the specified types are valid for instantiation:
|
type parameter. Only the specified types are valid for instantiation:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
proc onlyIntOrString[T: int|string](x, y: T): T = nil
|
proc onlyIntOrString[T: int|string](x, y: T) = nil
|
||||||
|
|
||||||
onlyIntOrString(45, 66) # valid
|
|
||||||
onlyIntOrString(56.0, 0.0) # type mismatch
|
|
||||||
|
|
||||||
|
onlyIntOrString(450, 616) # valid
|
||||||
|
onlyIntOrString(5.0, 0.0) # type mismatch
|
||||||
|
onlyIntOrString("xy", 50) # invalid as 'T' cannot be both at the same time
|
||||||
|
|
||||||
Apart from ordinary types, type constraints can also be of the
|
Apart from ordinary types, type constraints can also be of the
|
||||||
following *type classes*:
|
following *type classes*:
|
||||||
|
|
|
||||||
|
|
@ -451,34 +451,3 @@ efficient:
|
||||||
else: quit(errorStr(p, "expected: console or gui"))
|
else: quit(errorStr(p, "expected: console or gui"))
|
||||||
of "license": c.license = UnixToNativePath(k.value)
|
of "license": c.license = UnixToNativePath(k.value)
|
||||||
else: quit(errorStr(p, "unknown variable: " & k.key))
|
else: quit(errorStr(p, "unknown variable: " & k.key))
|
||||||
|
|
||||||
|
|
||||||
..
|
|
||||||
The ECMAScript code generator
|
|
||||||
=============================
|
|
||||||
|
|
||||||
Note: As of version 0.7.0 the ECMAScript code generator is not maintained any
|
|
||||||
longer. Help if you are interested.
|
|
||||||
|
|
||||||
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:,
|
|
||||||
since it is the proper term.
|
|
||||||
|
|
||||||
The ECMAScript code generator is experimental!
|
|
||||||
|
|
||||||
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
|
|
||||||
Since ECMAScript does not have a portable means to include another module,
|
|
||||||
Nimrod just generates a long ``.js`` file.
|
|
||||||
|
|
||||||
Features or modules that the ECMAScript platform does not support are not
|
|
||||||
available. This includes:
|
|
||||||
|
|
||||||
* manual memory management (``alloc``, etc.)
|
|
||||||
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
|
|
||||||
* file management
|
|
||||||
* most modules of the Standard library
|
|
||||||
* proper 64 bit integer arithmetic
|
|
||||||
* proper unsigned integer arithmetic
|
|
||||||
|
|
||||||
However, the modules `strutils`:idx:, `math`:idx:, and `times`:idx: are
|
|
||||||
available! To access the DOM, use the `dom`:idx: module that is only
|
|
||||||
available for the ECMAScript platform.
|
|
||||||
|
|
|
||||||
855
doc/theindex.txt
855
doc/theindex.txt
File diff suppressed because it is too large
Load diff
16
doc/tut1.txt
16
doc/tut1.txt
|
|
@ -91,8 +91,9 @@ keywords, comments, operators, and other punctuation marks. Case is
|
||||||
``This_is_an_identifier`` and ``ThisIsAnIdentifier`` are the same identifier.
|
``This_is_an_identifier`` and ``ThisIsAnIdentifier`` are the same identifier.
|
||||||
This feature enables you to use other
|
This feature enables you to use other
|
||||||
people's code without bothering about a naming convention that conflicts with
|
people's code without bothering about a naming convention that conflicts with
|
||||||
yours. It also frees you from remembering the exact spelling of an identifier
|
yours. A Nimrod-aware editor or IDE can show the identifiers as
|
||||||
(was it ``parseURL`` or ``parseUrl`` or ``parse_URL``?).
|
preferred. It also frees you from remembering the exact spelling of an
|
||||||
|
identifier (was it ``parseURL`` or ``parseUrl`` or ``parse_URL``?).
|
||||||
|
|
||||||
|
|
||||||
String and character literals
|
String and character literals
|
||||||
|
|
@ -117,16 +118,13 @@ Comments
|
||||||
--------
|
--------
|
||||||
|
|
||||||
`Comments`:idx: start anywhere outside a string or character literal with the
|
`Comments`:idx: start anywhere outside a string or character literal with the
|
||||||
hash character ``#``. Documentation comments start with ``##``.
|
hash character ``#``. Documentation comments start with ``##``. Multiline
|
||||||
Comments consist of a concatenation of `comment pieces`:idx:. A comment piece
|
comments need to be aligned at the same column:
|
||||||
starts with ``#`` and runs until the end of the line. The end of line characters
|
|
||||||
belong to the piece. If the next line only consists of a comment piece which is
|
|
||||||
aligned to the preceding one, it does not start a new comment:
|
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
||||||
i = 0 # This is a single comment over multiple lines belonging to the
|
i = 0 # This is a single comment over multiple lines belonging to the
|
||||||
# assignment statement. The scanner merges these two pieces.
|
# assignment statement.
|
||||||
# This is a new comment belonging to the current block, but to no particular
|
# This is a new comment belonging to the current block, but to no particular
|
||||||
# statement.
|
# statement.
|
||||||
i = i + 1 # This a new comment that is NOT
|
i = i + 1 # This a new comment that is NOT
|
||||||
|
|
@ -1206,7 +1204,7 @@ Traced references are declared with the **ref** keyword, untraced references
|
||||||
are declared with the **ptr** keyword.
|
are declared with the **ptr** keyword.
|
||||||
|
|
||||||
The empty ``[]`` subscript notation can be used to *derefer* a reference,
|
The empty ``[]`` subscript notation can be used to *derefer* a reference,
|
||||||
meaning to retrieve the item the reference points to. The ``addr`` procedure
|
meaning to retrieve the item the reference points to. The ``addr`` operator
|
||||||
returns the address of an item. An address is always an untraced reference:
|
returns the address of an item. An address is always an untraced reference:
|
||||||
``addr`` is an *unsafe* feature.
|
``addr`` is an *unsafe* feature.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
# Test/show CGI module
|
# Test/show CGI module
|
||||||
import strtabs, cgi
|
import strtabs, cgi
|
||||||
|
|
||||||
|
|
||||||
#setTestData("name", "the andreas", "password", "rumpf\t\ttab")
|
|
||||||
|
|
||||||
var myData = readData()
|
var myData = readData()
|
||||||
validateData(myData, "name", "password")
|
validateData(myData, "name", "password")
|
||||||
writeContentType()
|
writeContentType()
|
||||||
|
|
|
||||||
16
install.sh
16
install.sh
|
|
@ -124,6 +124,8 @@ if [ $# -eq 1 ] ; then
|
||||||
chmod 644 $docdir/rst.txt
|
chmod 644 $docdir/rst.txt
|
||||||
cp doc/subexes.txt $docdir/subexes.txt || exit 1
|
cp doc/subexes.txt $docdir/subexes.txt || exit 1
|
||||||
chmod 644 $docdir/subexes.txt
|
chmod 644 $docdir/subexes.txt
|
||||||
|
cp doc/targets.txt $docdir/targets.txt || exit 1
|
||||||
|
chmod 644 $docdir/targets.txt
|
||||||
cp doc/theindex.txt $docdir/theindex.txt || exit 1
|
cp doc/theindex.txt $docdir/theindex.txt || exit 1
|
||||||
chmod 644 $docdir/theindex.txt
|
chmod 644 $docdir/theindex.txt
|
||||||
cp doc/tools.txt $docdir/tools.txt || exit 1
|
cp doc/tools.txt $docdir/tools.txt || exit 1
|
||||||
|
|
@ -202,6 +204,8 @@ if [ $# -eq 1 ] ; then
|
||||||
chmod 644 $docdir/lib.html
|
chmod 644 $docdir/lib.html
|
||||||
cp doc/lists.html $docdir/lists.html || exit 1
|
cp doc/lists.html $docdir/lists.html || exit 1
|
||||||
chmod 644 $docdir/lists.html
|
chmod 644 $docdir/lists.html
|
||||||
|
cp doc/locks.html $docdir/locks.html || exit 1
|
||||||
|
chmod 644 $docdir/locks.html
|
||||||
cp doc/macros.html $docdir/macros.html || exit 1
|
cp doc/macros.html $docdir/macros.html || exit 1
|
||||||
chmod 644 $docdir/macros.html
|
chmod 644 $docdir/macros.html
|
||||||
cp doc/manual.html $docdir/manual.html || exit 1
|
cp doc/manual.html $docdir/manual.html || exit 1
|
||||||
|
|
@ -362,6 +366,8 @@ if [ $# -eq 1 ] ; then
|
||||||
chmod 644 $libdir/system/dyncalls.nim
|
chmod 644 $libdir/system/dyncalls.nim
|
||||||
cp lib/system/ecmasys.nim $libdir/system/ecmasys.nim || exit 1
|
cp lib/system/ecmasys.nim $libdir/system/ecmasys.nim || exit 1
|
||||||
chmod 644 $libdir/system/ecmasys.nim
|
chmod 644 $libdir/system/ecmasys.nim
|
||||||
|
cp lib/system/embedded.nim $libdir/system/embedded.nim || exit 1
|
||||||
|
chmod 644 $libdir/system/embedded.nim
|
||||||
cp lib/system/excpt.nim $libdir/system/excpt.nim || exit 1
|
cp lib/system/excpt.nim $libdir/system/excpt.nim || exit 1
|
||||||
chmod 644 $libdir/system/excpt.nim
|
chmod 644 $libdir/system/excpt.nim
|
||||||
cp lib/system/gc.nim $libdir/system/gc.nim || exit 1
|
cp lib/system/gc.nim $libdir/system/gc.nim || exit 1
|
||||||
|
|
@ -420,6 +426,8 @@ if [ $# -eq 1 ] ; then
|
||||||
chmod 644 $libdir/pure/dynlib.nim
|
chmod 644 $libdir/pure/dynlib.nim
|
||||||
cp lib/pure/encodings.nim $libdir/pure/encodings.nim || exit 1
|
cp lib/pure/encodings.nim $libdir/pure/encodings.nim || exit 1
|
||||||
chmod 644 $libdir/pure/encodings.nim
|
chmod 644 $libdir/pure/encodings.nim
|
||||||
|
cp lib/pure/endians.nim $libdir/pure/endians.nim || exit 1
|
||||||
|
chmod 644 $libdir/pure/endians.nim
|
||||||
cp lib/pure/events.nim $libdir/pure/events.nim || exit 1
|
cp lib/pure/events.nim $libdir/pure/events.nim || exit 1
|
||||||
chmod 644 $libdir/pure/events.nim
|
chmod 644 $libdir/pure/events.nim
|
||||||
cp lib/pure/ftpclient.nim $libdir/pure/ftpclient.nim || exit 1
|
cp lib/pure/ftpclient.nim $libdir/pure/ftpclient.nim || exit 1
|
||||||
|
|
@ -452,6 +460,8 @@ if [ $# -eq 1 ] ; then
|
||||||
chmod 644 $libdir/pure/md5.nim
|
chmod 644 $libdir/pure/md5.nim
|
||||||
cp lib/pure/memfiles.nim $libdir/pure/memfiles.nim || exit 1
|
cp lib/pure/memfiles.nim $libdir/pure/memfiles.nim || exit 1
|
||||||
chmod 644 $libdir/pure/memfiles.nim
|
chmod 644 $libdir/pure/memfiles.nim
|
||||||
|
cp lib/pure/oids.nim $libdir/pure/oids.nim || exit 1
|
||||||
|
chmod 644 $libdir/pure/oids.nim
|
||||||
cp lib/pure/os.nim $libdir/pure/os.nim || exit 1
|
cp lib/pure/os.nim $libdir/pure/os.nim || exit 1
|
||||||
chmod 644 $libdir/pure/os.nim
|
chmod 644 $libdir/pure/os.nim
|
||||||
cp lib/pure/osproc.nim $libdir/pure/osproc.nim || exit 1
|
cp lib/pure/osproc.nim $libdir/pure/osproc.nim || exit 1
|
||||||
|
|
@ -558,8 +568,12 @@ if [ $# -eq 1 ] ; then
|
||||||
chmod 644 $libdir/wrappers/joyent_http_parser.nim
|
chmod 644 $libdir/wrappers/joyent_http_parser.nim
|
||||||
cp lib/wrappers/libcurl.nim $libdir/wrappers/libcurl.nim || exit 1
|
cp lib/wrappers/libcurl.nim $libdir/wrappers/libcurl.nim || exit 1
|
||||||
chmod 644 $libdir/wrappers/libcurl.nim
|
chmod 644 $libdir/wrappers/libcurl.nim
|
||||||
|
cp lib/wrappers/libsvm.nim $libdir/wrappers/libsvm.nim || exit 1
|
||||||
|
chmod 644 $libdir/wrappers/libsvm.nim
|
||||||
cp lib/wrappers/libuv.nim $libdir/wrappers/libuv.nim || exit 1
|
cp lib/wrappers/libuv.nim $libdir/wrappers/libuv.nim || exit 1
|
||||||
chmod 644 $libdir/wrappers/libuv.nim
|
chmod 644 $libdir/wrappers/libuv.nim
|
||||||
|
cp lib/wrappers/mongo.nim $libdir/wrappers/mongo.nim || exit 1
|
||||||
|
chmod 644 $libdir/wrappers/mongo.nim
|
||||||
cp lib/wrappers/mysql.nim $libdir/wrappers/mysql.nim || exit 1
|
cp lib/wrappers/mysql.nim $libdir/wrappers/mysql.nim || exit 1
|
||||||
chmod 644 $libdir/wrappers/mysql.nim
|
chmod 644 $libdir/wrappers/mysql.nim
|
||||||
cp lib/wrappers/odbcsql.nim $libdir/wrappers/odbcsql.nim || exit 1
|
cp lib/wrappers/odbcsql.nim $libdir/wrappers/odbcsql.nim || exit 1
|
||||||
|
|
@ -630,6 +644,8 @@ if [ $# -eq 1 ] ; then
|
||||||
chmod 644 $libdir/wrappers/opengl/glut.nim
|
chmod 644 $libdir/wrappers/opengl/glut.nim
|
||||||
cp lib/wrappers/opengl/glx.nim $libdir/wrappers/opengl/glx.nim || exit 1
|
cp lib/wrappers/opengl/glx.nim $libdir/wrappers/opengl/glx.nim || exit 1
|
||||||
chmod 644 $libdir/wrappers/opengl/glx.nim
|
chmod 644 $libdir/wrappers/opengl/glx.nim
|
||||||
|
cp lib/wrappers/opengl/opengl.nim $libdir/wrappers/opengl/opengl.nim || exit 1
|
||||||
|
chmod 644 $libdir/wrappers/opengl/opengl.nim
|
||||||
cp lib/wrappers/opengl/wingl.nim $libdir/wrappers/opengl/wingl.nim || exit 1
|
cp lib/wrappers/opengl/wingl.nim $libdir/wrappers/opengl/wingl.nim || exit 1
|
||||||
chmod 644 $libdir/wrappers/opengl/wingl.nim
|
chmod 644 $libdir/wrappers/opengl/wingl.nim
|
||||||
cp lib/wrappers/sdl/sdl.nim $libdir/wrappers/sdl/sdl.nim || exit 1
|
cp lib/wrappers/sdl/sdl.nim $libdir/wrappers/sdl/sdl.nim || exit 1
|
||||||
|
|
|
||||||
213
lib/impure/db_mongo.nim
Normal file
213
lib/impure/db_mongo.nim
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nimrod's Runtime Library
|
||||||
|
# (c) Copyright 2012 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## This module implements a higher level wrapper for `mongodb`:idx:. Example:
|
||||||
|
##
|
||||||
|
## .. code-block:: nimrod
|
||||||
|
##
|
||||||
|
## import mongo, db_mongo, oids, json
|
||||||
|
##
|
||||||
|
## var conn = db_mongo.open()
|
||||||
|
##
|
||||||
|
## # construct JSON data:
|
||||||
|
## var data = %{"a": %13, "b": %"my string value",
|
||||||
|
## "inner": %{"i": %71} }
|
||||||
|
##
|
||||||
|
## var id = insertID(conn, "test.test", data)
|
||||||
|
##
|
||||||
|
## for v in find(conn, "test.test", "this.a == 13"):
|
||||||
|
## print v
|
||||||
|
##
|
||||||
|
## delete(conn, "test.test", id)
|
||||||
|
## close(conn)
|
||||||
|
|
||||||
|
import mongo, oids, json
|
||||||
|
|
||||||
|
type
|
||||||
|
EDb* = object of EIO ## exception that is raised if a database error occurs
|
||||||
|
TDbConn* = TMongo ## a database connection; alias for ``TMongo``
|
||||||
|
|
||||||
|
proc dbError*(db: TDbConn, msg: string) {.noreturn.} =
|
||||||
|
## raises an EDb exception with message `msg`.
|
||||||
|
var e: ref EDb
|
||||||
|
new(e)
|
||||||
|
if db.errstr[0] != '\0':
|
||||||
|
e.msg = $db.errstr
|
||||||
|
else:
|
||||||
|
e.msg = $db.err & " " & msg
|
||||||
|
raise e
|
||||||
|
|
||||||
|
proc Close*(db: var TDbConn) =
|
||||||
|
## closes the database connection.
|
||||||
|
disconnect(db)
|
||||||
|
destroy(db)
|
||||||
|
|
||||||
|
proc Open*(host: string = defaultHost, port: int = defaultPort): TDbConn =
|
||||||
|
## opens a database connection. Raises `EDb` if the connection could not
|
||||||
|
## be established.
|
||||||
|
init(result)
|
||||||
|
|
||||||
|
let x = connect(result, host, port.cint)
|
||||||
|
if x != 0'i32:
|
||||||
|
dbError(result, "cannot open: " & host)
|
||||||
|
|
||||||
|
proc jsonToBSon(b: var TBSon, key: string, j: PJsonNode) =
|
||||||
|
case j.kind
|
||||||
|
of JString:
|
||||||
|
add(b, key, j.str)
|
||||||
|
of JInt:
|
||||||
|
add(b, key, j.num)
|
||||||
|
of JFloat:
|
||||||
|
add(b, key, j.fnum)
|
||||||
|
of JBool:
|
||||||
|
addBool(b, key, ord(j.bval))
|
||||||
|
of JNull:
|
||||||
|
addNull(b, key)
|
||||||
|
of JObject:
|
||||||
|
addStartObject(b, key)
|
||||||
|
for k, v in items(j.fields):
|
||||||
|
jsonToBSon(b, k, v)
|
||||||
|
addFinishObject(b)
|
||||||
|
of JArray:
|
||||||
|
addStartArray(b, key)
|
||||||
|
for i, e in pairs(j.elems):
|
||||||
|
jsonToBSon(b, $i, e)
|
||||||
|
addFinishArray(b)
|
||||||
|
|
||||||
|
proc jsonToBSon*(j: PJsonNode, oid: TOid): TBSon =
|
||||||
|
## converts a JSON value into the BSON format. The result must be
|
||||||
|
## ``destroyed`` explicitely!
|
||||||
|
init(result)
|
||||||
|
assert j.kind == JObject
|
||||||
|
add(result, "_id", oid)
|
||||||
|
for key, val in items(j.fields):
|
||||||
|
jsonToBSon(result, key, val)
|
||||||
|
finish(result)
|
||||||
|
|
||||||
|
proc `[]`*(obj: var TBSon, fieldname: cstring): TBSon =
|
||||||
|
## retrieves the value belonging to `fieldname`. Raises `EInvalidKey` if
|
||||||
|
## the attribute does not exist.
|
||||||
|
var it = initIter(obj)
|
||||||
|
let res = find(it, result, fieldname)
|
||||||
|
if res == bkEOO:
|
||||||
|
raise newException(EInvalidIndex, "key not in object")
|
||||||
|
|
||||||
|
proc getId*(obj: var TBSon): TOid =
|
||||||
|
## retrieves the ``_id`` attribute of `obj`.
|
||||||
|
var it = initIter(obj)
|
||||||
|
var b: TBSon
|
||||||
|
let res = find(it, b, "_id")
|
||||||
|
if res == bkOID:
|
||||||
|
result = oidVal(it)[]
|
||||||
|
else:
|
||||||
|
raise newException(EInvalidIndex, "_id not in object")
|
||||||
|
|
||||||
|
proc insertID*(db: var TDbConn, namespace: string, data: PJsonNode): TOid =
|
||||||
|
## converts `data` to BSON format and inserts it in `namespace`. Returns
|
||||||
|
## the generated OID for the ``_id`` field.
|
||||||
|
result = genOid()
|
||||||
|
var x = jsonToBSon(data, result)
|
||||||
|
insert(db, namespace, x)
|
||||||
|
destroy(x)
|
||||||
|
|
||||||
|
proc insert*(db: var TDbConn, namespace: string, data: PJsonNode) =
|
||||||
|
## converts `data` to BSON format and inserts it in `namespace`.
|
||||||
|
discard InsertID(db, namespace, data)
|
||||||
|
|
||||||
|
proc update*(db: var TDbConn, namespace: string, obj: var TBSon) =
|
||||||
|
## updates `obj` in `namespace`.
|
||||||
|
var cond: TBson
|
||||||
|
init(cond)
|
||||||
|
cond.add("_id", getId(obj))
|
||||||
|
finish(cond)
|
||||||
|
update(db, namespace, cond, obj, ord(UPDATE_UPSERT))
|
||||||
|
destroy(cond)
|
||||||
|
|
||||||
|
proc update*(db: var TDbConn, namespace: string, oid: TOid, obj: PJsonNode) =
|
||||||
|
## updates the data with `oid` to have the new data `obj`.
|
||||||
|
var a = jsonToBSon(obj, oid)
|
||||||
|
Update(db, namespace, a)
|
||||||
|
destroy(a)
|
||||||
|
|
||||||
|
proc delete*(db: var TDbConn, namespace: string, oid: TOid) =
|
||||||
|
## Deletes the object belonging to `oid`.
|
||||||
|
var cond: TBson
|
||||||
|
init(cond)
|
||||||
|
cond.add("_id", oid)
|
||||||
|
finish(cond)
|
||||||
|
discard remove(db, namespace, cond)
|
||||||
|
destroy(cond)
|
||||||
|
|
||||||
|
proc delete*(db: var TDbConn, namespace: string, obj: var TBSon) =
|
||||||
|
## Deletes the object `obj`.
|
||||||
|
delete(db, namespace, getId(obj))
|
||||||
|
|
||||||
|
iterator find*(db: var TDbConn, namespace: string): var TBSon =
|
||||||
|
## iterates over any object in `namespace`.
|
||||||
|
var cursor: TCursor
|
||||||
|
init(cursor, db, namespace)
|
||||||
|
while next(cursor) == mongo.OK:
|
||||||
|
yield bson(cursor)[]
|
||||||
|
destroy(cursor)
|
||||||
|
|
||||||
|
iterator find*(db: var TDbConn, namespace: string,
|
||||||
|
query, fields: var TBSon): var TBSon =
|
||||||
|
## yields the `fields` of any document that suffices `query`.
|
||||||
|
var cursor = find(db, namespace, query, fields, 0'i32, 0'i32, 0'i32)
|
||||||
|
if cursor != nil:
|
||||||
|
while next(cursor[]) == mongo.OK:
|
||||||
|
yield bson(cursor[])[]
|
||||||
|
destroy(cursor[])
|
||||||
|
|
||||||
|
proc setupFieldnames(fields: openArray[string]): TBSon =
|
||||||
|
init(result)
|
||||||
|
for x in fields: add(result, x, 1'i32)
|
||||||
|
finish(result)
|
||||||
|
|
||||||
|
iterator find*(db: var TDbConn, namespace: string,
|
||||||
|
query: var TBSon, fields: openArray[string]): var TBSon =
|
||||||
|
## yields the `fields` of any document that suffices `query`. If `fields`
|
||||||
|
## is ``[]`` the whole document is yielded.
|
||||||
|
var f = setupFieldnames(fields)
|
||||||
|
var cursor = find(db, namespace, query, f, 0'i32, 0'i32, 0'i32)
|
||||||
|
if cursor != nil:
|
||||||
|
while next(cursor[]) == mongo.OK:
|
||||||
|
yield bson(cursor[])[]
|
||||||
|
destroy(cursor[])
|
||||||
|
destroy(f)
|
||||||
|
|
||||||
|
proc setupQuery(query: string): TBSon =
|
||||||
|
init(result)
|
||||||
|
add(result, "$where", query)
|
||||||
|
finish(result)
|
||||||
|
|
||||||
|
iterator find*(db: var TDbConn, namespace: string,
|
||||||
|
query: string, fields: openArray[string]): var TBSon =
|
||||||
|
## yields the `fields` of any document that suffices `query`. If `fields`
|
||||||
|
## is ``[]`` the whole document is yielded.
|
||||||
|
var f = setupFieldnames(fields)
|
||||||
|
var q = setupQuery(query)
|
||||||
|
var cursor = find(db, namespace, q, f, 0'i32, 0'i32, 0'i32)
|
||||||
|
if cursor != nil:
|
||||||
|
while next(cursor[]) == mongo.OK:
|
||||||
|
yield bson(cursor[])[]
|
||||||
|
destroy(cursor[])
|
||||||
|
destroy(q)
|
||||||
|
destroy(f)
|
||||||
|
|
||||||
|
when false:
|
||||||
|
# this doesn't work this way; would require low level hacking
|
||||||
|
iterator fieldPairs*(obj: var TBSon): tuple[key: cstring, value: TBSon] =
|
||||||
|
## iterates over `obj` and yields all (key, value)-Pairs.
|
||||||
|
var it = initIter(obj)
|
||||||
|
var v: TBSon
|
||||||
|
while next(it) != bkEOO:
|
||||||
|
let key = key(it)
|
||||||
|
discard init(v, value(it))
|
||||||
|
yield (key, v)
|
||||||
47
lib/pure/endians.nim
Normal file
47
lib/pure/endians.nim
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nimrod's Runtime Library
|
||||||
|
# (c) Copyright 2012 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## This module contains helpers that deal with different byte orders
|
||||||
|
## (`endian`:idx:).
|
||||||
|
|
||||||
|
proc swapEndian64*(outp, inp: pointer) =
|
||||||
|
## copies `inp` to `outp` swapping bytes. Both buffers are supposed to
|
||||||
|
## contain at least 8 bytes.
|
||||||
|
var i = cast[cstring](inp)
|
||||||
|
var o = cast[cstring](outp)
|
||||||
|
o[0] = i[7]
|
||||||
|
o[1] = i[6]
|
||||||
|
o[2] = i[5]
|
||||||
|
o[3] = i[4]
|
||||||
|
o[4] = i[3]
|
||||||
|
o[5] = i[2]
|
||||||
|
o[6] = i[1]
|
||||||
|
o[7] = i[0]
|
||||||
|
|
||||||
|
proc swapEndian32*(outp, inp: pointer) =
|
||||||
|
## copies `inp` to `outp` swapping bytes. Both buffers are supposed to
|
||||||
|
## contain at least 4 bytes.
|
||||||
|
var i = cast[cstring](inp)
|
||||||
|
var o = cast[cstring](outp)
|
||||||
|
o[0] = i[3]
|
||||||
|
o[1] = i[2]
|
||||||
|
o[2] = i[1]
|
||||||
|
o[3] = i[0]
|
||||||
|
|
||||||
|
when system.cpuEndian == bigEndian:
|
||||||
|
proc littleEndian64*(outp, inp: pointer) {.inline.} = swapEndian64(outp, inp)
|
||||||
|
proc littleEndian32*(outp, inp: pointer) {.inline.} = swapEndian32(outp, inp)
|
||||||
|
proc bigEndian64*(outp, inp: pointer) {.inline.} = copyMem(outp, inp, 8)
|
||||||
|
proc bigEndian32*(outp, inp: pointer) {.inline.} = copyMem(outp, inp, 4)
|
||||||
|
else:
|
||||||
|
proc littleEndian64*(outp, inp: pointer) {.inline.} = copyMem(outp, inp, 8)
|
||||||
|
proc littleEndian32*(outp, inp: pointer) {.inline.} = copyMem(outp, inp, 4)
|
||||||
|
proc bigEndian64*(outp, inp: pointer) {.inline.} = swapEndian64(outp, inp)
|
||||||
|
proc bigEndian32*(outp, inp: pointer) {.inline.} = swapEndian32(outp, inp)
|
||||||
|
|
||||||
|
|
@ -495,16 +495,16 @@ type
|
||||||
JArray
|
JArray
|
||||||
|
|
||||||
PJsonNode* = ref TJsonNode ## JSON node
|
PJsonNode* = ref TJsonNode ## JSON node
|
||||||
TJsonNode* {.final, pure.} = object
|
TJsonNode* {.final, pure, acyclic.} = object
|
||||||
case kind*: TJsonNodeKind
|
case kind*: TJsonNodeKind
|
||||||
of JString:
|
of JString:
|
||||||
str*: String
|
str*: string
|
||||||
of JInt:
|
of JInt:
|
||||||
num*: biggestInt
|
num*: biggestInt
|
||||||
of JFloat:
|
of JFloat:
|
||||||
fnum: Float
|
fnum*: float
|
||||||
of JBool:
|
of JBool:
|
||||||
bval*: Bool
|
bval*: bool
|
||||||
of JNull:
|
of JNull:
|
||||||
nil
|
nil
|
||||||
of JObject:
|
of JObject:
|
||||||
|
|
@ -558,6 +558,45 @@ proc newJArray*(): PJsonNode =
|
||||||
result.kind = JArray
|
result.kind = JArray
|
||||||
result.elems = @[]
|
result.elems = @[]
|
||||||
|
|
||||||
|
|
||||||
|
proc `%`*(s: string): PJsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JString PJsonNode`.
|
||||||
|
new(result)
|
||||||
|
result.kind = JString
|
||||||
|
result.str = s
|
||||||
|
|
||||||
|
proc `%`*(n: biggestInt): PJsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JInt PJsonNode`.
|
||||||
|
new(result)
|
||||||
|
result.kind = JInt
|
||||||
|
result.num = n
|
||||||
|
|
||||||
|
proc `%`*(n: float): PJsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JFloat PJsonNode`.
|
||||||
|
new(result)
|
||||||
|
result.kind = JFloat
|
||||||
|
result.fnum = n
|
||||||
|
|
||||||
|
proc `%`*(b: bool): PJsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JBool PJsonNode`.
|
||||||
|
new(result)
|
||||||
|
result.kind = JBool
|
||||||
|
result.bval = b
|
||||||
|
|
||||||
|
proc `%`*(keyVals: openArray[tuple[key: string, val: PJsonNode]]): PJsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JObject PJsonNode`
|
||||||
|
new(result)
|
||||||
|
result.kind = JObject
|
||||||
|
newSeq(result.fields, keyVals.len)
|
||||||
|
for i, p in pairs(keyVals): result.fields[i] = p
|
||||||
|
|
||||||
|
proc `%`*(elements: openArray[PJSonNode]): PJsonNode =
|
||||||
|
## Generic constructor for JSON data. Creates a new `JArray PJsonNode`
|
||||||
|
new(result)
|
||||||
|
result.kind = JArray
|
||||||
|
newSeq(result.elems, elements.len)
|
||||||
|
for i, p in pairs(elements): result.elems[i] = p
|
||||||
|
|
||||||
proc len*(n: PJsonNode): int =
|
proc len*(n: PJsonNode): int =
|
||||||
## If `n` is a `JArray`, it returns the number of elements.
|
## If `n` is a `JArray`, it returns the number of elements.
|
||||||
## If `n` is a `JObject`, it returns the number of pairs.
|
## If `n` is a `JObject`, it returns the number of pairs.
|
||||||
|
|
|
||||||
86
lib/pure/oids.nim
Normal file
86
lib/pure/oids.nim
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nimrod's Runtime Library
|
||||||
|
# (c) Copyright 2012 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## Nimrod OID support. An OID is a global ID that consists of a timestamp,
|
||||||
|
## a unique counter and a random value. This combination should suffice to
|
||||||
|
## produce a globally distributed unique ID. This implementation was extracted
|
||||||
|
## from the Mongodb interface and it thus binary compatible with a Mongo OID.
|
||||||
|
##
|
||||||
|
## This implementation calls ``math.randomize()`` for the first call of
|
||||||
|
## ``genOid``.
|
||||||
|
|
||||||
|
import times, endians
|
||||||
|
|
||||||
|
type
|
||||||
|
Toid* {.pure, final.} = object ## an OID
|
||||||
|
time: int32 ##
|
||||||
|
fuzz: int32 ##
|
||||||
|
count: int32 ##
|
||||||
|
|
||||||
|
proc hexbyte*(hex: char): int =
|
||||||
|
case hex
|
||||||
|
of '0'..'9': result = (ord(hex) - ord('0'))
|
||||||
|
of 'a'..'f': result = (ord(hex) - ord('a') + 10)
|
||||||
|
of 'A'..'F': result = (ord(hex) - ord('A') + 10)
|
||||||
|
else: nil
|
||||||
|
|
||||||
|
proc parseOid*(str: cstring): TOid =
|
||||||
|
## parses an OID.
|
||||||
|
var bytes = cast[cstring](addr(result.time))
|
||||||
|
var i = 0
|
||||||
|
while i < 12:
|
||||||
|
bytes[i] = chr((hexbyte(str[2 * i]) shl 4) or hexbyte(str[2 * i + 1]))
|
||||||
|
inc(i)
|
||||||
|
|
||||||
|
proc oidToString*(oid: TOid, str: cstring) =
|
||||||
|
const hex = "0123456789abcdef"
|
||||||
|
# work around a compiler bug:
|
||||||
|
var str = str
|
||||||
|
var o = oid
|
||||||
|
var bytes = cast[cstring](addr(o))
|
||||||
|
var i = 0
|
||||||
|
while i < 12:
|
||||||
|
let b = bytes[i].ord
|
||||||
|
str[2 * i] = hex[(b and 0xF0) shr 4]
|
||||||
|
str[2 * i + 1] = hex[b and 0xF]
|
||||||
|
inc(i)
|
||||||
|
str[24] = '\0'
|
||||||
|
|
||||||
|
var
|
||||||
|
incr, fuzz: int
|
||||||
|
|
||||||
|
proc genOid*(): TOid =
|
||||||
|
## generates a new OID.
|
||||||
|
proc rand(): cint {.importc: "rand", nodecl.}
|
||||||
|
proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
|
||||||
|
proc srand(seed: cint) {.importc: "srand", nodecl.}
|
||||||
|
|
||||||
|
var t = gettime(nil)
|
||||||
|
|
||||||
|
var i = int32(incr)
|
||||||
|
atomicInc(incr)
|
||||||
|
|
||||||
|
if fuzz == 0:
|
||||||
|
# racy, but fine semantically:
|
||||||
|
srand(t)
|
||||||
|
fuzz = rand()
|
||||||
|
bigEndian32(addr result.time, addr(t))
|
||||||
|
result.fuzz = fuzz
|
||||||
|
bigEndian32(addr result.count, addr(i))
|
||||||
|
|
||||||
|
proc generatedTime*(oid: TOid): TTime =
|
||||||
|
## returns the generated timestamp of the OID.
|
||||||
|
var tmp: int32
|
||||||
|
var dummy = oid.time
|
||||||
|
bigEndian32(addr(tmp), addr(dummy))
|
||||||
|
result = TTime(tmp)
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
let xo = genOID()
|
||||||
|
echo xo.generatedTime
|
||||||
|
|
@ -151,7 +151,7 @@ else: # UNIX-like operating system
|
||||||
ScriptExt* = ""
|
ScriptExt* = ""
|
||||||
DynlibFormat* = "lib$1.so"
|
DynlibFormat* = "lib$1.so"
|
||||||
|
|
||||||
when defined(macosx):
|
when defined(macosx) or defined(bsd):
|
||||||
var
|
var
|
||||||
pathMax {.importc: "PATH_MAX", header: "<stdlib.h>".}: cint
|
pathMax {.importc: "PATH_MAX", header: "<stdlib.h>".}: cint
|
||||||
|
|
||||||
|
|
@ -580,7 +580,7 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1".} =
|
||||||
var L = GetFullPathNameA(filename, bufsize, result, unused)
|
var L = GetFullPathNameA(filename, bufsize, result, unused)
|
||||||
if L <= 0'i32 or L >= bufsize: OSError()
|
if L <= 0'i32 or L >= bufsize: OSError()
|
||||||
setLen(result, L)
|
setLen(result, L)
|
||||||
elif defined(macosx):
|
elif defined(macosx) or defined(bsd):
|
||||||
# On Mac OS X 10.5, realpath does not allocate the buffer on its own
|
# On Mac OS X 10.5, realpath does not allocate the buffer on its own
|
||||||
var pathBuffer: cstring = newString(pathMax)
|
var pathBuffer: cstring = newString(pathMax)
|
||||||
var resultBuffer = realpath(filename, pathBuffer)
|
var resultBuffer = realpath(filename, pathBuffer)
|
||||||
|
|
@ -1355,6 +1355,7 @@ when defined(macosx):
|
||||||
|
|
||||||
proc getAppFilename*(): string {.rtl, extern: "nos$1".} =
|
proc getAppFilename*(): string {.rtl, extern: "nos$1".} =
|
||||||
## Returns the filename of the application's executable.
|
## Returns the filename of the application's executable.
|
||||||
|
## **Note**: This does not work reliably on BSD.
|
||||||
|
|
||||||
# Linux: /proc/<pid>/exe
|
# Linux: /proc/<pid>/exe
|
||||||
# Solaris:
|
# Solaris:
|
||||||
|
|
@ -1410,6 +1411,7 @@ proc getApplicationDir*(): string {.rtl, extern: "nos$1", deprecated.} =
|
||||||
|
|
||||||
proc getAppDir*(): string {.rtl, extern: "nos$1".} =
|
proc getAppDir*(): string {.rtl, extern: "nos$1".} =
|
||||||
## Returns the directory of the application's executable.
|
## Returns the directory of the application's executable.
|
||||||
|
## **Note**: This does not work reliably on BSD.
|
||||||
result = splitFile(getAppFilename()).dir
|
result = splitFile(getAppFilename()).dir
|
||||||
|
|
||||||
proc sleep*(milsecs: int) {.rtl, extern: "nos$1".} =
|
proc sleep*(milsecs: int) {.rtl, extern: "nos$1".} =
|
||||||
|
|
|
||||||
|
|
@ -1486,10 +1486,10 @@ proc primary(p: var TPegParser): TPeg =
|
||||||
return !primary(p)
|
return !primary(p)
|
||||||
of tkAt:
|
of tkAt:
|
||||||
getTok(p)
|
getTok(p)
|
||||||
return @primary(p)
|
return @(primary(p))
|
||||||
of tkCurlyAt:
|
of tkCurlyAt:
|
||||||
getTok(p)
|
getTok(p)
|
||||||
return @@primary(p).token(p)
|
return @@(primary(p).token(p))
|
||||||
else: nil
|
else: nil
|
||||||
case p.tok.kind
|
case p.tok.kind
|
||||||
of tkIdentifier:
|
of tkIdentifier:
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,22 @@ proc parseBool*(s: string): bool =
|
||||||
of "y", "yes", "true", "1", "on": result = true
|
of "y", "yes", "true", "1", "on": result = true
|
||||||
of "n", "no", "false", "0", "off": result = false
|
of "n", "no", "false", "0", "off": result = false
|
||||||
else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s)
|
else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s)
|
||||||
|
|
||||||
|
proc parseEnum*[T: enum](s: string): T =
|
||||||
|
## parses an enum ``T``. Raises ``EInvalidValue`` for an invalid value in
|
||||||
|
## `s`. The comparison is done in a style insensitive way.
|
||||||
|
for e in low(T)..high(T):
|
||||||
|
if cmpIgnoreStyle(s, $e) == 0:
|
||||||
|
return e
|
||||||
|
raise newException(EInvalidValue, "invalid enum value: " & s)
|
||||||
|
|
||||||
|
proc parseEnum*[T: enum](s: string, default: T): T =
|
||||||
|
## parses an enum ``T``. Uses `default` for an invalid value in
|
||||||
|
## `s`. The comparison is done in a style insensitive way.
|
||||||
|
for e in low(T)..high(T):
|
||||||
|
if cmpIgnoreStyle(s, $e) == 0:
|
||||||
|
return e
|
||||||
|
result = default
|
||||||
|
|
||||||
proc repeatChar*(count: int, c: Char = ' '): string {.noSideEffect,
|
proc repeatChar*(count: int, c: Char = ' '): string {.noSideEffect,
|
||||||
rtl, extern: "nsuRepeatChar".} =
|
rtl, extern: "nsuRepeatChar".} =
|
||||||
|
|
@ -1105,5 +1121,8 @@ when isMainModule:
|
||||||
|
|
||||||
doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz "
|
doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz "
|
||||||
doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc"
|
doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc"
|
||||||
|
|
||||||
|
type TMyEnum = enum enA, enB, enC, enuD, enE
|
||||||
|
doAssert parseEnum[TMyEnum]("enu_D") == enuD
|
||||||
|
|
||||||
|
doAssert parseEnum("invalid enum value", enC) == enC
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2009 Andreas Rumpf
|
# (c) Copyright 2012 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -307,6 +307,17 @@ proc setBackgroundColor*(bg: TBackgroundColor, bright=false) =
|
||||||
gBG = ord(bg)
|
gBG = ord(bg)
|
||||||
if bright: inc(gBG, 60)
|
if bright: inc(gBG, 60)
|
||||||
stdout.write("\e[" & $gBG & 'm')
|
stdout.write("\e[" & $gBG & 'm')
|
||||||
|
|
||||||
|
proc isatty*(f: TFile): bool =
|
||||||
|
## returns true if `f` is associated with a terminal device.
|
||||||
|
when defined(posix):
|
||||||
|
proc isatty(fildes: TFileHandle): cint {.
|
||||||
|
importc: "isatty", header: "<unistd.h>".}
|
||||||
|
else:
|
||||||
|
proc isatty(fildes: TFileHandle): cint {.
|
||||||
|
importc: "_isatty", header: "<io.h>".}
|
||||||
|
|
||||||
|
result = isatty(fileHandle(f)) != 0'i32
|
||||||
|
|
||||||
# XXX:
|
# XXX:
|
||||||
# These should be private, but there is no yet
|
# These should be private, but there is no yet
|
||||||
|
|
@ -317,7 +328,7 @@ proc styledEchoProcessArg*(style: set[TStyle]) = setStyle style
|
||||||
proc styledEchoProcessArg*(color: TForegroundColor) = setForeGroundColor color
|
proc styledEchoProcessArg*(color: TForegroundColor) = setForeGroundColor color
|
||||||
proc styledEchoProcessArg*(color: TBackgroundColor) = setBackGroundColor color
|
proc styledEchoProcessArg*(color: TBackgroundColor) = setBackGroundColor color
|
||||||
|
|
||||||
macro styledEcho*(m: stmt): stmt =
|
macro styledEcho*(m: stmt): stmt =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
|
|
||||||
for i in countup(1, m.len - 1):
|
for i in countup(1, m.len - 1):
|
||||||
|
|
|
||||||
|
|
@ -2254,4 +2254,3 @@ template eval*(blk: stmt): stmt =
|
||||||
|
|
||||||
when defined(initDebugger):
|
when defined(initDebugger):
|
||||||
initDebugger()
|
initDebugger()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ type
|
||||||
LONG* = int
|
LONG* = int
|
||||||
WINBOOL* = int32
|
WINBOOL* = int32
|
||||||
DWORD* = int32
|
DWORD* = int32
|
||||||
|
HDC* = THandle
|
||||||
|
HGLRC* = THandle
|
||||||
|
|
||||||
TSECURITY_ATTRIBUTES* {.final, pure.} = object
|
TSECURITY_ATTRIBUTES* {.final, pure.} = object
|
||||||
nLength*: int32
|
nLength*: int32
|
||||||
|
|
|
||||||
116
lib/wrappers/libsvm.nim
Normal file
116
lib/wrappers/libsvm.nim
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nimrod's Runtime Library
|
||||||
|
# (c) Copyright 2012 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## This module is a low level wrapper for `libsvm`:idx:.
|
||||||
|
|
||||||
|
{.deadCodeElim: on.}
|
||||||
|
const
|
||||||
|
LIBSVM_VERSION* = 312
|
||||||
|
|
||||||
|
when defined(windows):
|
||||||
|
const svmdll* = "libsvm.dll"
|
||||||
|
elif defined(macosx):
|
||||||
|
const svmdll* = "libsvm.dylib"
|
||||||
|
else:
|
||||||
|
const svmdll* = "libsvm.so"
|
||||||
|
|
||||||
|
type
|
||||||
|
Tnode*{.pure, final.} = object
|
||||||
|
index*: cint
|
||||||
|
value*: cdouble
|
||||||
|
|
||||||
|
Tproblem*{.pure, final.} = object
|
||||||
|
L*: cint
|
||||||
|
y*: ptr cdouble
|
||||||
|
x*: ptr ptr Tnode
|
||||||
|
|
||||||
|
Ttype*{.size: sizeof(cint).} = enum
|
||||||
|
C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR
|
||||||
|
|
||||||
|
TKernelType*{.size: sizeof(cint).} = enum
|
||||||
|
LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED
|
||||||
|
|
||||||
|
Tparameter*{.pure, final.} = object
|
||||||
|
typ*: TType
|
||||||
|
kernelType*: TKernelType
|
||||||
|
degree*: cint # for poly
|
||||||
|
gamma*: cdouble # for poly/rbf/sigmoid
|
||||||
|
coef0*: cdouble # for poly/sigmoid
|
||||||
|
# these are for training only
|
||||||
|
cache_size*: cdouble # in MB
|
||||||
|
eps*: cdouble # stopping criteria
|
||||||
|
C*: cdouble # for C_SVC, EPSILON_SVR and NU_SVR
|
||||||
|
nr_weight*: cint # for C_SVC
|
||||||
|
weight_label*: ptr cint # for C_SVC
|
||||||
|
weight*: ptr cdouble # for C_SVC
|
||||||
|
nu*: cdouble # for NU_SVC, ONE_CLASS, and NU_SVR
|
||||||
|
p*: cdouble # for EPSILON_SVR
|
||||||
|
shrinking*: cint # use the shrinking heuristics
|
||||||
|
probability*: cint # do probability estimates
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# svm_model
|
||||||
|
#
|
||||||
|
|
||||||
|
type
|
||||||
|
TModel*{.pure, final.} = object
|
||||||
|
param*: Tparameter # parameter
|
||||||
|
nr_class*: cint # number of classes, = 2 in regression/one class svm
|
||||||
|
L*: cint # total #SV
|
||||||
|
SV*: ptr ptr Tnode # SVs (SV[l])
|
||||||
|
sv_coef*: ptr ptr cdouble # coefficients for SVs in decision functions (sv_coef[k-1][l])
|
||||||
|
rho*: ptr cdouble # constants in decision functions (rho[k*(k-1)/2])
|
||||||
|
probA*: ptr cdouble # pariwise probability information
|
||||||
|
probB*: ptr cdouble # for classification only
|
||||||
|
label*: ptr cint # label of each class (label[k])
|
||||||
|
nSV*: ptr cint # number of SVs for each class (nSV[k])
|
||||||
|
# nSV[0] + nSV[1] + ... + nSV[k-1] = l
|
||||||
|
# XXX
|
||||||
|
free_sv*: cint # 1 if svm_model is created by svm_load_model
|
||||||
|
# 0 if svm_model is created by svm_train
|
||||||
|
|
||||||
|
|
||||||
|
proc train*(prob: ptr Tproblem, param: ptr Tparameter): ptr Tmodel{.cdecl,
|
||||||
|
importc: "svm_train", dynlib: svmdll.}
|
||||||
|
proc cross_validation*(prob: ptr Tproblem, param: ptr Tparameter, nr_fold: cint,
|
||||||
|
target: ptr cdouble){.cdecl,
|
||||||
|
importc: "svm_cross_validation", dynlib: svmdll.}
|
||||||
|
proc save_model*(model_file_name: cstring, model: ptr Tmodel): cint{.cdecl,
|
||||||
|
importc: "svm_save_model", dynlib: svmdll.}
|
||||||
|
proc load_model*(model_file_name: cstring): ptr Tmodel{.cdecl,
|
||||||
|
importc: "svm_load_model", dynlib: svmdll.}
|
||||||
|
proc get_svm_type*(model: ptr Tmodel): cint{.cdecl, importc: "svm_get_svm_type",
|
||||||
|
dynlib: svmdll.}
|
||||||
|
proc get_nr_class*(model: ptr Tmodel): cint{.cdecl, importc: "svm_get_nr_class",
|
||||||
|
dynlib: svmdll.}
|
||||||
|
proc get_labels*(model: ptr Tmodel, label: ptr cint){.cdecl,
|
||||||
|
importc: "svm_get_labels", dynlib: svmdll.}
|
||||||
|
proc get_svr_probability*(model: ptr Tmodel): cdouble{.cdecl,
|
||||||
|
importc: "svm_get_svr_probability", dynlib: svmdll.}
|
||||||
|
proc predict_values*(model: ptr Tmodel, x: ptr Tnode, dec_values: ptr cdouble): cdouble{.
|
||||||
|
cdecl, importc: "svm_predict_values", dynlib: svmdll.}
|
||||||
|
proc predict*(model: ptr Tmodel, x: ptr Tnode): cdouble{.cdecl,
|
||||||
|
importc: "svm_predict", dynlib: svmdll.}
|
||||||
|
proc predict_probability*(model: ptr Tmodel, x: ptr Tnode,
|
||||||
|
prob_estimates: ptr cdouble): cdouble{.cdecl,
|
||||||
|
importc: "svm_predict_probability", dynlib: svmdll.}
|
||||||
|
proc free_model_content*(model_ptr: ptr Tmodel){.cdecl,
|
||||||
|
importc: "svm_free_model_content", dynlib: svmdll.}
|
||||||
|
proc free_and_destroy_model*(model_ptr_ptr: ptr ptr Tmodel){.cdecl,
|
||||||
|
importc: "svm_free_and_destroy_model", dynlib: svmdll.}
|
||||||
|
proc destroy_param*(param: ptr Tparameter){.cdecl, importc: "svm_destroy_param",
|
||||||
|
dynlib: svmdll.}
|
||||||
|
proc check_parameter*(prob: ptr Tproblem, param: ptr Tparameter): cstring{.
|
||||||
|
cdecl, importc: "svm_check_parameter", dynlib: svmdll.}
|
||||||
|
proc check_probability_model*(model: ptr Tmodel): cint{.cdecl,
|
||||||
|
importc: "svm_check_probability_model", dynlib: svmdll.}
|
||||||
|
|
||||||
|
proc set_print_string_function*(print_func: proc (arg: cstring) {.cdecl.}){.
|
||||||
|
cdecl, importc: "svm_set_print_string_function", dynlib: svmdll.}
|
||||||
1186
lib/wrappers/mongo.nim
Normal file
1186
lib/wrappers/mongo.nim
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -27,9 +27,7 @@ elif defined(macosx):
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
dllname = "libglut.so.3"
|
dllname = "libglut.so.3"
|
||||||
type
|
type
|
||||||
PInteger* = ptr int
|
|
||||||
PPChar* = ptr cstring
|
|
||||||
TGlutVoidCallback* = proc (){.cdecl.}
|
TGlutVoidCallback* = proc (){.cdecl.}
|
||||||
TGlut1IntCallback* = proc (value: cint){.cdecl.}
|
TGlut1IntCallback* = proc (value: cint){.cdecl.}
|
||||||
TGlut2IntCallback* = proc (v1, v2: cint){.cdecl.}
|
TGlut2IntCallback* = proc (v1, v2: cint){.cdecl.}
|
||||||
|
|
@ -231,8 +229,16 @@ const # glutGet parameters.
|
||||||
GLUT_GAME_MODE_REFRESH_RATE* = 5
|
GLUT_GAME_MODE_REFRESH_RATE* = 5
|
||||||
GLUT_GAME_MODE_DISPLAY_CHANGED* = 6 # GLUT initialization sub-API.
|
GLUT_GAME_MODE_DISPLAY_CHANGED* = 6 # GLUT initialization sub-API.
|
||||||
|
|
||||||
proc glutInit*(argcp: PInteger, argv: PPChar){.dynlib: dllname,
|
proc glutInit*(argcp: ptr cint, argv: pointer){.dynlib: dllname,
|
||||||
importc: "glutInit".}
|
importc: "glutInit".}
|
||||||
|
|
||||||
|
proc glutInit*() =
|
||||||
|
## version that passes `argc` and `argc` implicitely.
|
||||||
|
var
|
||||||
|
cmdLine {.importc: "cmdLine".}: array[0..255, cstring]
|
||||||
|
cmdCount {.importc: "cmdCount".}: cint
|
||||||
|
glutInit(addr(cmdCount), addr(cmdLine))
|
||||||
|
|
||||||
proc glutInitDisplayMode*(mode: int16){.dynlib: dllname,
|
proc glutInitDisplayMode*(mode: int16){.dynlib: dllname,
|
||||||
importc: "glutInitDisplayMode".}
|
importc: "glutInitDisplayMode".}
|
||||||
proc glutInitDisplayString*(str: cstring){.dynlib: dllname,
|
proc glutInitDisplayString*(str: cstring){.dynlib: dllname,
|
||||||
|
|
|
||||||
9633
lib/wrappers/opengl/opengl.nim
Normal file
9633
lib/wrappers/opengl/opengl.nim
Normal file
File diff suppressed because it is too large
Load diff
16
tests/compile/tmongo.nim
Normal file
16
tests/compile/tmongo.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
import mongo, db_mongo, oids, json
|
||||||
|
|
||||||
|
var conn = db_mongo.open()
|
||||||
|
|
||||||
|
var data = %{"a": %13, "b": %"my string value",
|
||||||
|
"inner": %{"i": %71} }
|
||||||
|
|
||||||
|
var id = insertID(conn, "test.test", data)
|
||||||
|
|
||||||
|
for v in find(conn, "test.test", "this.a == 13"):
|
||||||
|
print v
|
||||||
|
|
||||||
|
delete(conn, "test.test", id)
|
||||||
|
|
||||||
|
close(conn)
|
||||||
37
todo.txt
37
todo.txt
|
|
@ -1,7 +1,11 @@
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
- sigil-like operator: @x.abc parsed as (@x).abc
|
||||||
|
- document AVR/embedded systems better
|
||||||
|
- implement ``--script:sh|bat`` command line option
|
||||||
- make GC realtime capable: GC_step(ms: int)
|
- make GC realtime capable: GC_step(ms: int)
|
||||||
|
- make templates hygienic by default
|
||||||
- ``=`` should be overloadable; requires specialization for ``=``
|
- ``=`` should be overloadable; requires specialization for ``=``
|
||||||
- fix remaining generics bugs
|
- fix remaining generics bugs
|
||||||
- fix remaining closure bugs:
|
- fix remaining closure bugs:
|
||||||
|
|
@ -11,7 +15,6 @@ version 0.9.0
|
||||||
- test constant closures
|
- test constant closures
|
||||||
|
|
||||||
- dead code elim for JS backend; 'of' operator for JS backend
|
- dead code elim for JS backend; 'of' operator for JS backend
|
||||||
- const ptr/ref
|
|
||||||
- unsigned ints and bignums; requires abstract integer literal type:
|
- unsigned ints and bignums; requires abstract integer literal type:
|
||||||
use tyInt+node for that
|
use tyInt+node for that
|
||||||
- implement the high level optimizer
|
- implement the high level optimizer
|
||||||
|
|
@ -22,10 +25,7 @@ version 0.9.0
|
||||||
- we need to support iteration of 2 different data structures in parallel
|
- we need to support iteration of 2 different data structures in parallel
|
||||||
- make exceptions compatible with C++ exceptions
|
- make exceptions compatible with C++ exceptions
|
||||||
- change how comments are part of the AST
|
- change how comments are part of the AST
|
||||||
- optional indentation for 'case' statement; hm, keep in mind other syntax
|
|
||||||
changes that people want; may turn out to be a bad idea
|
|
||||||
- activate more thread tests
|
- activate more thread tests
|
||||||
- optimize method dispatchers
|
|
||||||
- rethink the syntax: distinction between expr and stmt is unfortunate;
|
- rethink the syntax: distinction between expr and stmt is unfortunate;
|
||||||
indentation handling is quite complex too; problem with exception handling
|
indentation handling is quite complex too; problem with exception handling
|
||||||
is that often the scope of ``try`` is wrong and apart from that ``try`` is
|
is that often the scope of ``try`` is wrong and apart from that ``try`` is
|
||||||
|
|
@ -48,6 +48,7 @@ Bugs
|
||||||
- bug: stress testing basic method example (eval example)
|
- bug: stress testing basic method example (eval example)
|
||||||
without ``-d:release`` leaks memory?
|
without ``-d:release`` leaks memory?
|
||||||
- bug: object {.pure, final.} does not work again!
|
- bug: object {.pure, final.} does not work again!
|
||||||
|
- bug: {.error: "msg".} produces invalid pragma message
|
||||||
- bug: tsortdev does not run with native GC?
|
- bug: tsortdev does not run with native GC?
|
||||||
- bug: pragma statements in combination with symbol files are evaluated twice
|
- bug: pragma statements in combination with symbol files are evaluated twice
|
||||||
but this can lead to compilation errors
|
but this can lead to compilation errors
|
||||||
|
|
@ -59,21 +60,13 @@ version 0.9.XX
|
||||||
- implicit ref/ptr->var conversion; the compiler may store an object
|
- implicit ref/ptr->var conversion; the compiler may store an object
|
||||||
implicitly on the heap for write barrier efficiency; better:
|
implicitly on the heap for write barrier efficiency; better:
|
||||||
proc specialization in the code gen
|
proc specialization in the code gen
|
||||||
- shared memory heap: ``shared ref`` etc. The only hard part in the GC is to
|
|
||||||
"stop the world". However, it may be worthwhile to generate explicit
|
|
||||||
(or implicit) syncGC() calls in loops. Automatic loop injection seems
|
|
||||||
troublesome, but maybe we can come up with a simple heuristic. (All procs
|
|
||||||
that `new` shared memory are syncGC() candidates...)
|
|
||||||
- EcmaScript needs a new and better code gen: simply adapt the C code gen to it
|
- EcmaScript needs a new and better code gen: simply adapt the C code gen to it
|
||||||
- tlastmod returns wrong results on BSD (Linux, MacOS X: works)
|
- tlastmod returns wrong results on BSD (Linux, MacOS X: works)
|
||||||
- nested tuple unpacking; tuple unpacking in non-var-context
|
- nested tuple unpacking; tuple unpacking in non-var-context
|
||||||
- 'nimrod def': does not always work?
|
- 'nimrod def': does not always work?
|
||||||
- implement/generalize the effect system
|
|
||||||
- test branch coverage
|
- test branch coverage
|
||||||
- checked exceptions
|
|
||||||
- make pegs support a compile-time option and make c2nim use regexes instead
|
- make pegs support a compile-time option and make c2nim use regexes instead
|
||||||
per default?
|
per default?
|
||||||
- fix implicit generic routines
|
|
||||||
- 'const' objects including case objects
|
- 'const' objects including case objects
|
||||||
- improve docgen to use the semantic pass
|
- improve docgen to use the semantic pass
|
||||||
- 'export' feature (requires improved docgen)
|
- 'export' feature (requires improved docgen)
|
||||||
|
|
@ -100,8 +93,6 @@ version 0.9.XX
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
- provide more up to date OpenGL headers
|
|
||||||
- wrappers for mongodb; poppler; libharu
|
|
||||||
- suffix trees
|
- suffix trees
|
||||||
- locale support; i18n module
|
- locale support; i18n module
|
||||||
- bignums
|
- bignums
|
||||||
|
|
@ -142,6 +133,7 @@ Low priority
|
||||||
- implement explicit varargs; **but** ``len(varargs)`` problem remains!
|
- implement explicit varargs; **but** ``len(varargs)`` problem remains!
|
||||||
--> solve by implicit conversion from varargs to openarray
|
--> solve by implicit conversion from varargs to openarray
|
||||||
- implement closures that support nesting > 1
|
- implement closures that support nesting > 1
|
||||||
|
- optimize method dispatchers
|
||||||
|
|
||||||
|
|
||||||
Further optimization ideas
|
Further optimization ideas
|
||||||
|
|
@ -151,8 +143,21 @@ Further optimization ideas
|
||||||
information inlining would provide, but don't inline for code size reasons.
|
information inlining would provide, but don't inline for code size reasons.
|
||||||
|
|
||||||
|
|
||||||
Version 2
|
Version 2 and beyond
|
||||||
=========
|
====================
|
||||||
|
|
||||||
|
|
||||||
|
- shared memory heap: ``shared ref`` etc. The only hard part in the GC is to
|
||||||
|
"stop the world". However, it may be worthwhile to generate explicit
|
||||||
|
(or implicit) syncGC() calls in loops. Automatic loop injection seems
|
||||||
|
troublesome, but maybe we can come up with a simple heuristic. (All procs
|
||||||
|
that `new` shared memory are syncGC() candidates...)
|
||||||
|
|
||||||
|
- implement/generalize the effect system; checked exceptions
|
||||||
|
- const ptr/ref
|
||||||
|
|
||||||
|
- optional indentation for 'case' statement; hm, keep in mind other syntax
|
||||||
|
changes that people want; may turn out to be a bad idea
|
||||||
|
|
||||||
- language change: inheritance should only work with reference types, so that
|
- language change: inheritance should only work with reference types, so that
|
||||||
the ``type`` field is not needed for objects! --> zero overhead aggregation
|
the ``type`` field is not needed for objects! --> zero overhead aggregation
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import
|
||||||
os, strutils, parseopt, pegs, re, terminal
|
os, strutils, parseopt, pegs, re, terminal
|
||||||
|
|
||||||
const
|
const
|
||||||
Version = "0.8"
|
Version = "0.9"
|
||||||
Usage = "nimgrep - Nimrod Grep Utility Version " & version & """
|
Usage = "nimgrep - Nimrod Grep Utility Version " & version & """
|
||||||
|
|
||||||
(c) 2012 Andreas Rumpf
|
(c) 2012 Andreas Rumpf
|
||||||
|
|
@ -32,6 +32,7 @@ Options:
|
||||||
--ignoreCase, -i be case insensitive
|
--ignoreCase, -i be case insensitive
|
||||||
--ignoreStyle, -y be style insensitive
|
--ignoreStyle, -y be style insensitive
|
||||||
--ext:EX1|EX2|... only search the files with the given extension(s)
|
--ext:EX1|EX2|... only search the files with the given extension(s)
|
||||||
|
--verbose be verbose: list every processed file
|
||||||
--help, -h shows this help
|
--help, -h shows this help
|
||||||
--version, -v shows the version
|
--version, -v shows the version
|
||||||
"""
|
"""
|
||||||
|
|
@ -39,7 +40,7 @@ Options:
|
||||||
type
|
type
|
||||||
TOption = enum
|
TOption = enum
|
||||||
optFind, optReplace, optPeg, optRegex, optRecursive, optConfirm, optStdin,
|
optFind, optReplace, optPeg, optRegex, optRecursive, optConfirm, optStdin,
|
||||||
optWord, optIgnoreCase, optIgnoreStyle
|
optWord, optIgnoreCase, optIgnoreStyle, optVerbose
|
||||||
TOptions = set[TOption]
|
TOptions = set[TOption]
|
||||||
TConfirmEnum = enum
|
TConfirmEnum = enum
|
||||||
ceAbort, ceYes, ceAll, ceNo, ceNone
|
ceAbort, ceYes, ceAll, ceNo, ceNone
|
||||||
|
|
@ -50,6 +51,7 @@ var
|
||||||
replacement = ""
|
replacement = ""
|
||||||
extensions: seq[string] = @[]
|
extensions: seq[string] = @[]
|
||||||
options: TOptions = {optRegex}
|
options: TOptions = {optRegex}
|
||||||
|
useWriteStyled = true
|
||||||
|
|
||||||
proc ask(msg: string): string =
|
proc ask(msg: string): string =
|
||||||
stdout.write(msg)
|
stdout.write(msg)
|
||||||
|
|
@ -89,6 +91,12 @@ proc afterPattern(s: string, last: int): int =
|
||||||
inc(result)
|
inc(result)
|
||||||
dec(result)
|
dec(result)
|
||||||
|
|
||||||
|
proc writeColored(s: string) =
|
||||||
|
if useWriteStyled:
|
||||||
|
terminal.WriteStyled(s, {styleUnderscore, styleBright})
|
||||||
|
else:
|
||||||
|
stdout.write(s)
|
||||||
|
|
||||||
proc highlight(s, match, repl: string, t: tuple[first, last: int],
|
proc highlight(s, match, repl: string, t: tuple[first, last: int],
|
||||||
line: int, showRepl: bool) =
|
line: int, showRepl: bool) =
|
||||||
const alignment = 6
|
const alignment = 6
|
||||||
|
|
@ -96,24 +104,30 @@ proc highlight(s, match, repl: string, t: tuple[first, last: int],
|
||||||
var x = beforePattern(s, t.first)
|
var x = beforePattern(s, t.first)
|
||||||
var y = afterPattern(s, t.last)
|
var y = afterPattern(s, t.last)
|
||||||
for i in x .. t.first-1: stdout.write(s[i])
|
for i in x .. t.first-1: stdout.write(s[i])
|
||||||
terminal.WriteStyled(match, {styleUnderscore, styleBright})
|
writeColored(match)
|
||||||
for i in t.last+1 .. y: stdout.write(s[i])
|
for i in t.last+1 .. y: stdout.write(s[i])
|
||||||
stdout.write("\n")
|
stdout.write("\n")
|
||||||
if showRepl:
|
if showRepl:
|
||||||
stdout.write(repeatChar(alignment-1), "-> ")
|
stdout.write(repeatChar(alignment-1), "-> ")
|
||||||
for i in x .. t.first-1: stdout.write(s[i])
|
for i in x .. t.first-1: stdout.write(s[i])
|
||||||
terminal.WriteStyled(repl, {styleUnderscore, styleBright})
|
writeColored(repl)
|
||||||
for i in t.last+1 .. y: stdout.write(s[i])
|
for i in t.last+1 .. y: stdout.write(s[i])
|
||||||
stdout.write("\n")
|
stdout.write("\n")
|
||||||
|
|
||||||
proc processFile(filename: string) =
|
proc processFile(filename: string) =
|
||||||
|
var filenameShown = false
|
||||||
|
template beforeHighlight =
|
||||||
|
if not filenameShown and optVerbose notin options:
|
||||||
|
stdout.writeln(filename)
|
||||||
|
filenameShown = true
|
||||||
|
|
||||||
var buffer: string
|
var buffer: string
|
||||||
try:
|
try:
|
||||||
buffer = system.readFile(filename)
|
buffer = system.readFile(filename)
|
||||||
except EIO:
|
except EIO:
|
||||||
echo "cannot open file: ", filename
|
echo "cannot open file: ", filename
|
||||||
return
|
return
|
||||||
stdout.writeln(filename)
|
if optVerbose in options: stdout.writeln(filename)
|
||||||
var pegp: TPeg
|
var pegp: TPeg
|
||||||
var rep: TRegex
|
var rep: TRegex
|
||||||
var result: string
|
var result: string
|
||||||
|
|
@ -145,6 +159,7 @@ proc processFile(filename: string) =
|
||||||
|
|
||||||
var wholeMatch = buffer.substr(t.first, t.last)
|
var wholeMatch = buffer.substr(t.first, t.last)
|
||||||
|
|
||||||
|
beforeHighlight()
|
||||||
if optReplace notin options:
|
if optReplace notin options:
|
||||||
highlight(buffer, wholeMatch, "", t, line, showRepl=false)
|
highlight(buffer, wholeMatch, "", t, line, showRepl=false)
|
||||||
else:
|
else:
|
||||||
|
|
@ -276,11 +291,15 @@ for kind, key, val in getopt():
|
||||||
of "ignorecase", "i": incl(options, optIgnoreCase)
|
of "ignorecase", "i": incl(options, optIgnoreCase)
|
||||||
of "ignorestyle", "y": incl(options, optIgnoreStyle)
|
of "ignorestyle", "y": incl(options, optIgnoreStyle)
|
||||||
of "ext": extensions = val.split('|')
|
of "ext": extensions = val.split('|')
|
||||||
|
of "verbose": incl(options, optVerbose)
|
||||||
of "help", "h": writeHelp()
|
of "help", "h": writeHelp()
|
||||||
of "version", "v": writeVersion()
|
of "version", "v": writeVersion()
|
||||||
else: writeHelp()
|
else: writeHelp()
|
||||||
of cmdEnd: assert(false) # cannot happen
|
of cmdEnd: assert(false) # cannot happen
|
||||||
|
|
||||||
|
when defined(posix):
|
||||||
|
useWriteStyled = terminal.isatty(stdout)
|
||||||
|
|
||||||
checkOptions({optFind, optReplace}, "find", "replace")
|
checkOptions({optFind, optReplace}, "find", "replace")
|
||||||
checkOptions({optPeg, optRegex}, "peg", "re")
|
checkOptions({optPeg, optRegex}, "peg", "re")
|
||||||
checkOptions({optIgnoreCase, optIgnoreStyle}, "ignore_case", "ignore_style")
|
checkOptions({optIgnoreCase, optIgnoreStyle}, "ignore_case", "ignore_style")
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ Please choose your platform:
|
||||||
|
|
||||||
The source-based installation has been tested on these systems:
|
The source-based installation has been tested on these systems:
|
||||||
* Linux: i386, AMD64, PowerPC
|
* Linux: i386, AMD64, PowerPC
|
||||||
|
* BSD: AMD64
|
||||||
* Mac OS X: i386, AMD64
|
* Mac OS X: i386, AMD64
|
||||||
|
|
||||||
Other UNIX-based operating systems may work. An older version was tested on
|
Other UNIX-based operating systems may work.
|
||||||
FreeBSD (i386).
|
|
||||||
|
|
||||||
.. include:: ../install.txt
|
.. include:: ../install.txt
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,11 @@ Welcome to Nimrod
|
||||||
*Nimrod looks like this:*
|
*Nimrod looks like this:*
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
# Filter key=value pairs
|
import strutils
|
||||||
import re
|
|
||||||
|
echo "List of ints (separate by whitespace): "
|
||||||
for x in lines("myfile.txt"):
|
echo stdin.readLine.split.each(parseInt).max,
|
||||||
if x =~ re"(\w+)=(.*)":
|
" is the maximum"
|
||||||
echo "Key: ", matches[0],
|
|
||||||
" Value: ", matches[1]
|
|
||||||
|
|
||||||
**Nimrod** is a new statically typed, imperative
|
**Nimrod** is a new statically typed, imperative
|
||||||
programming language, that supports procedural, object oriented, functional
|
programming language, that supports procedural, object oriented, functional
|
||||||
|
|
|
||||||
16
web/news.txt
16
web/news.txt
|
|
@ -12,6 +12,7 @@ Bugfixes
|
||||||
|
|
||||||
- Fixed a bug where the compiler would "optimize away" valid constant parts of
|
- Fixed a bug where the compiler would "optimize away" valid constant parts of
|
||||||
a string concatenation.
|
a string concatenation.
|
||||||
|
- Fixed a bug concerning implicit type conversions in ``case`` statements.
|
||||||
|
|
||||||
|
|
||||||
Library Additions
|
Library Additions
|
||||||
|
|
@ -24,6 +25,16 @@ Library Additions
|
||||||
compile time as if was a macro.
|
compile time as if was a macro.
|
||||||
- Added ``macros.emit`` that can emit an arbitrary computed string as nimrod
|
- Added ``macros.emit`` that can emit an arbitrary computed string as nimrod
|
||||||
code during compilation.
|
code during compilation.
|
||||||
|
- Added ``strutils.parseEnum``.
|
||||||
|
- Added ``json.%`` constructor operator.
|
||||||
|
- The stdlib can now be avoided to a point where C code generation for 16bit
|
||||||
|
micro controllers is feasible.
|
||||||
|
- Added module ``oids``.
|
||||||
|
- Added module ``endians``.
|
||||||
|
- Added a new OpenGL wrapper that supports OpenGL up to version 4.2.
|
||||||
|
- Added a wrapper for ``libsvm``.
|
||||||
|
- Added a wrapper for ``mongodb``.
|
||||||
|
- Added ``terminal.isatty``.
|
||||||
|
|
||||||
|
|
||||||
Changes affecting backwards compatibility
|
Changes affecting backwards compatibility
|
||||||
|
|
@ -33,7 +44,7 @@ Changes affecting backwards compatibility
|
||||||
The ``system``, ``os``, ``osproc`` and ``memfiles`` modules use the wide
|
The ``system``, ``os``, ``osproc`` and ``memfiles`` modules use the wide
|
||||||
string versions of the WinAPI. Use the ``-d:useWinAnsi`` switch to revert
|
string versions of the WinAPI. Use the ``-d:useWinAnsi`` switch to revert
|
||||||
back to the old behaviour which uses the Ansi string versions.
|
back to the old behaviour which uses the Ansi string versions.
|
||||||
- ``static`` is now a keyword.
|
- ``static`` and ``do`` are now keywords.
|
||||||
- Templates now participate in overloading resolution which can break code that
|
- Templates now participate in overloading resolution which can break code that
|
||||||
uses templates in subtle ways. Use the new ``immediate`` pragma for templates
|
uses templates in subtle ways. Use the new ``immediate`` pragma for templates
|
||||||
to get a template of old behaviour.
|
to get a template of old behaviour.
|
||||||
|
|
@ -45,6 +56,8 @@ Compiler Additions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Win64 is now an officially supported target.
|
- Win64 is now an officially supported target.
|
||||||
|
- The Nimrod compiler works on BSD again, but has some issues
|
||||||
|
as ``os.getAppFilename`` and ``os.getAppDir`` cannot work reliably on BSD.
|
||||||
- The compiler can detect and evaluate calls that can be evaluated at compile
|
- The compiler can detect and evaluate calls that can be evaluated at compile
|
||||||
time for optimization purposes with the ``--implicitStatic`` command line
|
time for optimization purposes with the ``--implicitStatic`` command line
|
||||||
option or pragma.
|
option or pragma.
|
||||||
|
|
@ -56,6 +69,7 @@ Language Additions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Added explicit ``static`` sections for enforced compile time evaluation.
|
- Added explicit ``static`` sections for enforced compile time evaluation.
|
||||||
|
- Added an alternative notation for lambdas with ``do``.
|
||||||
- ``addr`` is now treated like a prefix operator syntactically.
|
- ``addr`` is now treated like a prefix operator syntactically.
|
||||||
- Added ``global`` pragma that can be used to introduce new global variables
|
- Added ``global`` pragma that can be used to introduce new global variables
|
||||||
from within procs.
|
from within procs.
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ srcdoc: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase"
|
||||||
srcdoc: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"
|
srcdoc: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"
|
||||||
srcdoc: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode"
|
srcdoc: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode"
|
||||||
srcdoc: "impure/zipfiles;pure/htmlgen;pure/parseutils;pure/browsers"
|
srcdoc: "impure/zipfiles;pure/htmlgen;pure/parseutils;pure/browsers"
|
||||||
srcdoc: "impure/db_postgres;impure/db_mysql;impure/db_sqlite"
|
srcdoc: "impure/db_postgres;impure/db_mysql;impure/db_sqlite;impure/db_mongo"
|
||||||
srcdoc: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl"
|
srcdoc: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl"
|
||||||
srcdoc: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
|
srcdoc: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
|
||||||
srcdoc: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors"
|
srcdoc: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors"
|
||||||
|
|
@ -43,7 +43,7 @@ srcdoc: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
|
||||||
srcdoc: "pure/collections/intsets;pure/collections/queues;pure/encodings"
|
srcdoc: "pure/collections/intsets;pure/collections/queues;pure/encodings"
|
||||||
srcdoc: "pure/events;pure/collections/sequtils;pure/irc;ecmas/dom"
|
srcdoc: "pure/events;pure/collections/sequtils;pure/irc;ecmas/dom"
|
||||||
srcdoc: "pure/ftpclient;pure/memfiles;pure/subexes;pure/collections/critbits"
|
srcdoc: "pure/ftpclient;pure/memfiles;pure/subexes;pure/collections/critbits"
|
||||||
srcdoc: "pure/asyncio;pure/actors;core/locks"
|
srcdoc: "pure/asyncio;pure/actors;core/locks;pure/oids;pure/endians"
|
||||||
|
|
||||||
webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup"
|
webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup"
|
||||||
webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc"
|
webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc"
|
||||||
|
|
@ -55,6 +55,7 @@ webdoc: "posix/posix;wrappers/odbcsql;impure/dialogs"
|
||||||
webdoc: "wrappers/zip/zlib;wrappers/zip/libzip"
|
webdoc: "wrappers/zip/zlib;wrappers/zip/libzip"
|
||||||
webdoc: "wrappers/cairo"
|
webdoc: "wrappers/cairo"
|
||||||
webdoc: "wrappers/gtk"
|
webdoc: "wrappers/gtk"
|
||||||
|
webdoc: "wrappers/libsvm.nim;wrappers/mongo.nim"
|
||||||
webdoc: "windows"
|
webdoc: "windows"
|
||||||
webdoc: "wrappers/x11;wrappers/opengl;wrappers/sdl;wrappers/lua"
|
webdoc: "wrappers/x11;wrappers/opengl;wrappers/sdl;wrappers/lua"
|
||||||
webdoc: "wrappers/readline/readline;wrappers/readline/history"
|
webdoc: "wrappers/readline/readline;wrappers/readline/history"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue