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

This commit is contained in:
Zahary Karadjov 2012-04-10 22:39:00 +03:00
commit c1ad05c4c5
32 changed files with 12023 additions and 459 deletions

View file

@ -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:

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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/>`_.

View file

@ -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*:

View file

@ -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.

File diff suppressed because it is too large Load diff

View file

@ -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.

View file

@ -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()

View file

@ -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
View 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
View 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)

View file

@ -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
View 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

View file

@ -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".} =

View file

@ -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:

View file

@ -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

View file

@ -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):

View file

@ -2254,4 +2254,3 @@ template eval*(blk: stmt): stmt =
when defined(initDebugger): when defined(initDebugger):
initDebugger() initDebugger()

View file

@ -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
View 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

File diff suppressed because it is too large Load diff

View file

@ -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,

File diff suppressed because it is too large Load diff

16
tests/compile/tmongo.nim Normal file
View 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)

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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"