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

This commit is contained in:
dom96 2011-01-28 00:07:08 +00:00
commit 557adbcaac
32 changed files with 629 additions and 147 deletions

View file

@ -51,6 +51,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/idents.c -o build/1_1/idents.o
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/idents.c -o build/1_1/idents.o %CC% %COMP_FLAGS% -Ibuild -c build/1_1/idents.c -o build/1_1/idents.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/astalgo.c -o build/1_1/astalgo.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/astalgo.c -o build/1_1/astalgo.o
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/astalgo.c -o build/1_1/astalgo.o %CC% %COMP_FLAGS% -Ibuild -c build/1_1/astalgo.c -o build/1_1/astalgo.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodutils.c -o build/1_1/rodutils.o
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/rodutils.c -o build/1_1/rodutils.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/extccomp.c -o build/1_1/extccomp.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/extccomp.c -o build/1_1/extccomp.o
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/extccomp.c -o build/1_1/extccomp.o %CC% %COMP_FLAGS% -Ibuild -c build/1_1/extccomp.c -o build/1_1/extccomp.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/osproc.c -o build/1_1/osproc.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/osproc.c -o build/1_1/osproc.o
@ -146,8 +148,8 @@ ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/transf.c -o build/1_1/transf.o
ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o ECHO %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o
%CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o %CC% %COMP_FLAGS% -Ibuild -c build/1_1/parseopt.c -o build/1_1/parseopt.o
ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/scanner.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/pnimsyn.o build/1_1/pbraces.o build/1_1/ptmplsyn.o build/1_1/rnimsyn.o build/1_1/filters.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/interact.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o ECHO %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/scanner.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/pnimsyn.o build/1_1/pbraces.o build/1_1/ptmplsyn.o build/1_1/rnimsyn.o build/1_1/filters.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/interact.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o
%LINKER% %LINK_FLAGS% -o bin\nimrod.exe build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/scanner.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/pnimsyn.o build/1_1/pbraces.o build/1_1/ptmplsyn.o build/1_1/rnimsyn.o build/1_1/filters.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/interact.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o %LINKER% %LINK_FLAGS% -o bin\nimrod.exe build/1_1/nim__dat.o build/1_1/system.o build/1_1/nimrod.o build/1_1/times.o build/1_1/strutils.o build/1_1/parseutils.o build/1_1/winlean.o build/1_1/commands.o build/1_1/os.o build/1_1/msgs.o build/1_1/options.o build/1_1/lists.o build/1_1/nstrtabs.o build/1_1/nhashes.o build/1_1/nversion.o build/1_1/condsyms.o build/1_1/ast.o build/1_1/crc.o build/1_1/ropes.o build/1_1/platform.o build/1_1/idents.o build/1_1/astalgo.o build/1_1/rodutils.o build/1_1/extccomp.o build/1_1/osproc.o build/1_1/strtabs.o build/1_1/hashes.o build/1_1/streams.o build/1_1/wordrecg.o build/1_1/scanner.o build/1_1/lexbase.o build/1_1/llstream.o build/1_1/nimconf.o build/1_1/main.o build/1_1/syntaxes.o build/1_1/pnimsyn.o build/1_1/pbraces.o build/1_1/ptmplsyn.o build/1_1/rnimsyn.o build/1_1/filters.o build/1_1/rodread.o build/1_1/rodwrite.o build/1_1/passes.o build/1_1/types.o build/1_1/trees.o build/1_1/math.o build/1_1/magicsys.o build/1_1/nimsets.o build/1_1/bitsets.o build/1_1/importer.o build/1_1/lookups.o build/1_1/semdata.o build/1_1/treetab.o build/1_1/sem.o build/1_1/evals.o build/1_1/semfold.o build/1_1/procfind.o build/1_1/pragmas.o build/1_1/docgen.o build/1_1/rst.o build/1_1/highlite.o build/1_1/cgen.o build/1_1/ccgutils.o build/1_1/cgmeth.o build/1_1/ecmasgen.o build/1_1/interact.o build/1_1/passaux.o build/1_1/depends.o build/1_1/transf.o build/1_1/parseopt.o
ECHO SUCCESS ECHO SUCCESS

View file

@ -45,16 +45,12 @@ doc.body_toc = """
$tableofcontents $tableofcontents
<div class="content" id="content"> <div class="content" id="content">
$moduledesc $moduledesc
<h1>Dependencies</h1>
$deps
$content $content
</div> </div>
""" """
doc.body_no_toc = """ doc.body_no_toc = """
$moduledesc $moduledesc
<h1>Dependencies</h1>
$deps
$content $content
""" """

View file

@ -30,17 +30,11 @@ doc.toc = r"\tableofcontents \newpage"
doc.body_toc = """ doc.body_toc = """
$tableofcontents $tableofcontents
$moduledesc $moduledesc
Dependencies: $deps
$content $content
""" """
doc.body_no_toc = """ doc.body_no_toc = """
$moduledesc $moduledesc
Dependencies: $deps
$content $content
""" """

View file

@ -1,5 +1,5 @@
# Configuration file for the Nimrod Compiler. # Configuration file for the Nimrod Compiler.
# (c) 2010 Andreas Rumpf # (c) 2011 Andreas Rumpf
# Feel free to edit the default values as you need. # Feel free to edit the default values as you need.
@ -14,6 +14,7 @@ cc = gcc
lib = "nimlib" lib = "nimlib"
@end @end
path="$lib/core"
path="$lib/pure" path="$lib/pure"
path="$lib/impure" path="$lib/impure"
path="$lib/wrappers" path="$lib/wrappers"

View file

@ -31,6 +31,9 @@ Core
implicitly by the compiler. Do not import it directly. It relies on compiler implicitly by the compiler. Do not import it directly. It relies on compiler
magic to work. magic to work.
* `threads <threads.html>`_
Nimrod thread support.
* `macros <macros.html>`_ * `macros <macros.html>`_
Contains the AST API and documentation of Nimrod for writing macros. Contains the AST API and documentation of Nimrod for writing macros.

View file

@ -71,12 +71,23 @@ Linux does not compile on Windows, for instance. The comment on top of the
C file lists the OS, CPU and CC the file has been compiled for. C file lists the OS, CPU and CC the file has been compiled for.
Cross compilation
=================
To `cross compile`:idx:, use for example::
nimrod c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim
Then move the C code and the compile script ``compile_myproject.sh`` to your
Linux i386 machine and run the script.
DLL generation DLL generation
============== ==============
Nimrod supports the generation of DLLs. However, there must be only one Nimrod supports the generation of DLLs. However, there must be only one
instance of the GC per process/address space. This instance is contained in instance of the GC per process/address space. This instance is contained in
``nimrtl.dll``. This means that every generated Nimrod DLL depends ``nimrtl.dll``. This means that every generated Nimrod `DLL`:idx: depends
on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command:: on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command::
nimrod c -d:release lib/nimrtl.nim nimrod c -d:release lib/nimrtl.nim

View file

@ -321,6 +321,8 @@ if [ $# -eq 1 ] ; then
chmod 644 $libdir/system/sysstr.nim chmod 644 $libdir/system/sysstr.nim
cp lib/system/systhread.nim $libdir/system/systhread.nim cp lib/system/systhread.nim $libdir/system/systhread.nim
chmod 644 $libdir/system/systhread.nim chmod 644 $libdir/system/systhread.nim
cp lib/pure/base64.nim $libdir/pure/base64.nim
chmod 644 $libdir/pure/base64.nim
cp lib/pure/browsers.nim $libdir/pure/browsers.nim cp lib/pure/browsers.nim $libdir/pure/browsers.nim
chmod 644 $libdir/pure/browsers.nim chmod 644 $libdir/pure/browsers.nim
cp lib/pure/cgi.nim $libdir/pure/cgi.nim cp lib/pure/cgi.nim $libdir/pure/cgi.nim
@ -329,12 +331,12 @@ if [ $# -eq 1 ] ; then
chmod 644 $libdir/pure/colors.nim chmod 644 $libdir/pure/colors.nim
cp lib/pure/complex.nim $libdir/pure/complex.nim cp lib/pure/complex.nim $libdir/pure/complex.nim
chmod 644 $libdir/pure/complex.nim chmod 644 $libdir/pure/complex.nim
cp lib/pure/cookies.nim $libdir/pure/cookies.nim
chmod 644 $libdir/pure/cookies.nim
cp lib/pure/dynlib.nim $libdir/pure/dynlib.nim cp lib/pure/dynlib.nim $libdir/pure/dynlib.nim
chmod 644 $libdir/pure/dynlib.nim chmod 644 $libdir/pure/dynlib.nim
cp lib/pure/hashes.nim $libdir/pure/hashes.nim cp lib/pure/hashes.nim $libdir/pure/hashes.nim
chmod 644 $libdir/pure/hashes.nim chmod 644 $libdir/pure/hashes.nim
cp lib/pure/hashtabs.nim $libdir/pure/hashtabs.nim
chmod 644 $libdir/pure/hashtabs.nim
cp lib/pure/htmlparser.nim $libdir/pure/htmlparser.nim cp lib/pure/htmlparser.nim $libdir/pure/htmlparser.nim
chmod 644 $libdir/pure/htmlparser.nim chmod 644 $libdir/pure/htmlparser.nim
cp lib/pure/httpclient.nim $libdir/pure/httpclient.nim cp lib/pure/httpclient.nim $libdir/pure/httpclient.nim
@ -347,8 +349,6 @@ if [ $# -eq 1 ] ; then
chmod 644 $libdir/pure/lexbase.nim chmod 644 $libdir/pure/lexbase.nim
cp lib/pure/logging.nim $libdir/pure/logging.nim cp lib/pure/logging.nim $libdir/pure/logging.nim
chmod 644 $libdir/pure/logging.nim chmod 644 $libdir/pure/logging.nim
cp lib/pure/macros.nim $libdir/pure/macros.nim
chmod 644 $libdir/pure/macros.nim
cp lib/pure/math.nim $libdir/pure/math.nim cp lib/pure/math.nim $libdir/pure/math.nim
chmod 644 $libdir/pure/math.nim chmod 644 $libdir/pure/math.nim
cp lib/pure/md5.nim $libdir/pure/md5.nim cp lib/pure/md5.nim $libdir/pure/md5.nim
@ -377,6 +377,10 @@ if [ $# -eq 1 ] ; then
chmod 644 $libdir/pure/regexprs.nim chmod 644 $libdir/pure/regexprs.nim
cp lib/pure/ropes.nim $libdir/pure/ropes.nim cp lib/pure/ropes.nim $libdir/pure/ropes.nim
chmod 644 $libdir/pure/ropes.nim chmod 644 $libdir/pure/ropes.nim
cp lib/pure/scgi.nim $libdir/pure/scgi.nim
chmod 644 $libdir/pure/scgi.nim
cp lib/pure/smtp.nim $libdir/pure/smtp.nim
chmod 644 $libdir/pure/smtp.nim
cp lib/pure/sockets.nim $libdir/pure/sockets.nim cp lib/pure/sockets.nim $libdir/pure/sockets.nim
chmod 644 $libdir/pure/sockets.nim chmod 644 $libdir/pure/sockets.nim
cp lib/pure/streams.nim $libdir/pure/streams.nim cp lib/pure/streams.nim $libdir/pure/streams.nim
@ -391,8 +395,6 @@ if [ $# -eq 1 ] ; then
chmod 644 $libdir/pure/times.nim chmod 644 $libdir/pure/times.nim
cp lib/pure/unicode.nim $libdir/pure/unicode.nim cp lib/pure/unicode.nim $libdir/pure/unicode.nim
chmod 644 $libdir/pure/unicode.nim chmod 644 $libdir/pure/unicode.nim
cp lib/pure/variants.nim $libdir/pure/variants.nim
chmod 644 $libdir/pure/variants.nim
cp lib/pure/xmldom.nim $libdir/pure/xmldom.nim cp lib/pure/xmldom.nim $libdir/pure/xmldom.nim
chmod 644 $libdir/pure/xmldom.nim chmod 644 $libdir/pure/xmldom.nim
cp lib/pure/xmldomparser.nim $libdir/pure/xmldomparser.nim cp lib/pure/xmldomparser.nim $libdir/pure/xmldomparser.nim
@ -421,10 +423,14 @@ if [ $# -eq 1 ] ; then
chmod 644 $libdir/impure/osinfo_win.nim chmod 644 $libdir/impure/osinfo_win.nim
cp lib/impure/re.nim $libdir/impure/re.nim cp lib/impure/re.nim $libdir/impure/re.nim
chmod 644 $libdir/impure/re.nim chmod 644 $libdir/impure/re.nim
cp lib/impure/ssl.nim $libdir/impure/ssl.nim
chmod 644 $libdir/impure/ssl.nim
cp lib/impure/web.nim $libdir/impure/web.nim cp lib/impure/web.nim $libdir/impure/web.nim
chmod 644 $libdir/impure/web.nim chmod 644 $libdir/impure/web.nim
cp lib/impure/zipfiles.nim $libdir/impure/zipfiles.nim cp lib/impure/zipfiles.nim $libdir/impure/zipfiles.nim
chmod 644 $libdir/impure/zipfiles.nim chmod 644 $libdir/impure/zipfiles.nim
cp lib/wrappers/claro.nim $libdir/wrappers/claro.nim
chmod 644 $libdir/wrappers/claro.nim
cp lib/wrappers/expat.nim $libdir/wrappers/expat.nim cp lib/wrappers/expat.nim $libdir/wrappers/expat.nim
chmod 644 $libdir/wrappers/expat.nim chmod 644 $libdir/wrappers/expat.nim
cp lib/wrappers/iup.nim $libdir/wrappers/iup.nim cp lib/wrappers/iup.nim $libdir/wrappers/iup.nim
@ -435,6 +441,8 @@ if [ $# -eq 1 ] ; then
chmod 644 $libdir/wrappers/mysql.nim chmod 644 $libdir/wrappers/mysql.nim
cp lib/wrappers/odbcsql.nim $libdir/wrappers/odbcsql.nim cp lib/wrappers/odbcsql.nim $libdir/wrappers/odbcsql.nim
chmod 644 $libdir/wrappers/odbcsql.nim chmod 644 $libdir/wrappers/odbcsql.nim
cp lib/wrappers/openssl.nim $libdir/wrappers/openssl.nim
chmod 644 $libdir/wrappers/openssl.nim
cp lib/wrappers/pcre.nim $libdir/wrappers/pcre.nim cp lib/wrappers/pcre.nim $libdir/wrappers/pcre.nim
chmod 644 $libdir/wrappers/pcre.nim chmod 644 $libdir/wrappers/pcre.nim
cp lib/wrappers/postgres.nim $libdir/wrappers/postgres.nim cp lib/wrappers/postgres.nim $libdir/wrappers/postgres.nim

259
lib/core/marshal.nim Normal file
View file

@ -0,0 +1,259 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2011 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## This module contains procs for serialization and deseralization of
## arbitrary Nimrod data structures. XXX This is not implemented yet!
import streams
proc load*[T](s: PStream, data: var T) {.magic: "Load".}
## loads `data` from the stream `s`. Raises `EIO` in case of an error.
proc store*[T](s: PStream, data: T) {.magic: "Store".}
## stores `data` into the stream `s`. Raises `EIO` in case of an error.
proc reprInt(x: int64): string {.compilerproc.} = return $x
proc reprFloat(x: float): string {.compilerproc.} = return $x
proc reprPointer(x: pointer): string {.compilerproc.} =
var buf: array [0..59, char]
c_sprintf(buf, "%p", x)
return $buf
proc reprStrAux(result: var string, s: string) =
if cast[pointer](s) == nil:
add result, "nil"
return
add result, reprPointer(cast[pointer](s)) & "\""
for c in items(s):
case c
of '"': add result, "\\\""
of '\\': add result, "\\\\" # BUGFIX: forgotten
of '\10': add result, "\\10\"\n\"" # " \n " # better readability
of '\128' .. '\255', '\0'..'\9', '\11'..'\31':
add result, "\\" & reprInt(ord(c))
else: result.add(c)
add result, "\""
proc reprStr(s: string): string {.compilerRtl.} =
result = ""
reprStrAux(result, s)
proc reprBool(x: bool): string {.compilerRtl.} =
if x: result = "true"
else: result = "false"
proc reprChar(x: char): string {.compilerRtl.} =
result = "\'"
case x
of '"': add result, "\\\""
of '\\': add result, "\\\\"
of '\128' .. '\255', '\0'..'\31': add result, "\\" & reprInt(ord(x))
else: add result, x
add result, "\'"
proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
if e <% typ.node.len: # BUGFIX
result = $typ.node.sons[e].name
else:
result = $e & " (invalid data!)"
type
pbyteArray = ptr array[0.. 0xffff, byte]
proc addSetElem(result: var string, elem: int, typ: PNimType) =
case typ.kind
of tyEnum: add result, reprEnum(elem, typ)
of tyBool: add result, reprBool(bool(elem))
of tyChar: add result, reprChar(chr(elem))
of tyRange: addSetElem(result, elem, typ.base)
of tyInt..tyInt64: add result, reprInt(elem)
else: # data corrupt --> inform the user
add result, " (invalid data!)"
proc reprSetAux(result: var string, p: pointer, typ: PNimType) =
# "typ.slots.len" field is for sets the "first" field
var elemCounter = 0 # we need this flag for adding the comma at
# the right places
add result, "{"
var u: int64
case typ.size
of 1: u = ze64(cast[ptr int8](p)^)
of 2: u = ze64(cast[ptr int16](p)^)
of 4: u = ze64(cast[ptr int32](p)^)
of 8: u = cast[ptr int64](p)^
else:
var a = cast[pbyteArray](p)
for i in 0 .. typ.size*8-1:
if (ze(a[i div 8]) and (1 shl (i mod 8))) != 0:
if elemCounter > 0: add result, ", "
addSetElem(result, i+typ.node.len, typ.base)
inc(elemCounter)
if typ.size <= 8:
for i in 0..sizeof(int64)*8-1:
if (u and (1 shl i)) != 0:
if elemCounter > 0: add result, ", "
addSetElem(result, i+typ.node.len, typ.base)
inc(elemCounter)
add result, "}"
proc reprSet(p: pointer, typ: PNimType): string {.compilerRtl.} =
result = ""
reprSetAux(result, p, typ)
type
TReprClosure {.final.} = object # we cannot use a global variable here
# as this wouldn't be thread-safe
marked: TCellSet
recdepth: int # do not recurse endless
indent: int # indentation
when not defined(useNimRtl):
proc initReprClosure(cl: var TReprClosure) =
Init(cl.marked)
cl.recdepth = -1 # default is to display everything!
cl.indent = 0
proc deinitReprClosure(cl: var TReprClosure) =
Deinit(cl.marked)
proc reprBreak(result: var string, cl: TReprClosure) =
add result, "\n"
for i in 0..cl.indent-1: add result, ' '
proc reprAux(result: var string, p: pointer, typ: PNimType,
cl: var TReprClosure)
proc reprArray(result: var string, p: pointer, typ: PNimType,
cl: var TReprClosure) =
add result, "["
var bs = typ.base.size
for i in 0..typ.size div bs - 1:
if i > 0: add result, ", "
reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), typ.base, cl)
add result, "]"
proc reprSequence(result: var string, p: pointer, typ: PNimType,
cl: var TReprClosure) =
if p == nil:
add result, "nil"
return
result.add(reprPointer(p) & "[")
var bs = typ.base.size
for i in 0..cast[PGenericSeq](p).len-1:
if i > 0: add result, ", "
reprAux(result, cast[pointer](cast[TAddress](p) + GenericSeqSize + i*bs),
typ.Base, cl)
add result, "]"
proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode,
cl: var TReprClosure) =
case n.kind
of nkNone: assert(false)
of nkSlot:
add result, $n.name
add result, " = "
reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl)
of nkList:
for i in 0..n.len-1:
if i > 0: add result, ",\n"
reprRecordAux(result, p, n.sons[i], cl)
of nkCase:
var m = selectBranch(p, n)
reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl)
if m != nil: reprRecordAux(result, p, m, cl)
proc reprRecord(result: var string, p: pointer, typ: PNimType,
cl: var TReprClosure) =
add result, "["
reprRecordAux(result, p, typ.node, cl)
add result, "]"
proc reprRef(result: var string, p: pointer, typ: PNimType,
cl: var TReprClosure) =
# we know that p is not nil here:
when defined(boehmGC) or defined(nogc):
var cell = cast[PCell](p)
else:
var cell = usrToCell(p)
add result, "ref " & reprPointer(p)
if cell notin cl.marked:
# only the address is shown:
incl(cl.marked, cell)
add result, " --> "
reprAux(result, p, typ.base, cl)
proc reprAux(result: var string, p: pointer, typ: PNimType,
cl: var TReprClosure) =
if cl.recdepth == 0:
add result, "..."
return
dec(cl.recdepth)
case typ.kind
of tySet: reprSetAux(result, p, typ)
of tyArray: reprArray(result, p, typ, cl)
of tyTuple, tyPureObject: reprRecord(result, p, typ, cl)
of tyObject:
var t = cast[ptr PNimType](p)^
reprRecord(result, p, t, cl)
of tyRef, tyPtr:
assert(p != nil)
if cast[ppointer](p)^ == nil: add result, "nil"
else: reprRef(result, cast[ppointer](p)^, typ, cl)
of tySequence:
reprSequence(result, cast[ppointer](p)^, typ, cl)
of tyInt: add result, $(cast[ptr int](p)^)
of tyInt8: add result, $int(cast[ptr Int8](p)^)
of tyInt16: add result, $int(cast[ptr Int16](p)^)
of tyInt32: add result, $int(cast[ptr Int32](p)^)
of tyInt64: add result, $(cast[ptr Int64](p)^)
of tyFloat: add result, $(cast[ptr float](p)^)
of tyFloat32: add result, $(cast[ptr float32](p)^)
of tyFloat64: add result, $(cast[ptr float64](p)^)
of tyEnum: add result, reprEnum(cast[ptr int](p)^, typ)
of tyBool: add result, reprBool(cast[ptr bool](p)^)
of tyChar: add result, reprChar(cast[ptr char](p)^)
of tyString: reprStrAux(result, cast[ptr string](p)^)
of tyCString: reprStrAux(result, $(cast[ptr cstring](p)^))
of tyRange: reprAux(result, p, typ.base, cl)
of tyProc, tyPointer:
if cast[ppointer](p)^ == nil: add result, "nil"
else: add result, reprPointer(cast[ppointer](p)^)
else:
add result, "(invalid data!)"
inc(cl.recdepth)
proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {.
compilerRtl.} =
var
cl: TReprClosure
initReprClosure(cl)
result = "["
var bs = elemtyp.size
for i in 0..length - 1:
if i > 0: add result, ", "
reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), elemtyp, cl)
add result, "]"
deinitReprClosure(cl)
when not defined(useNimRtl):
proc reprAny(p: pointer, typ: PNimType): string =
var
cl: TReprClosure
initReprClosure(cl)
result = ""
if typ.kind in {tyObject, tyPureObject, tyTuple, tyArray, tySet}:
reprAux(result, p, typ, cl)
else:
var p = p
reprAux(result, addr(p), typ, cl)
add result, "\n"
deinitReprClosure(cl)

174
lib/core/threads.nim Normal file
View file

@ -0,0 +1,174 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2011 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Basic thread support for Nimrod. Note that Nimrod's default GC is still
## single-threaded. This means that either your threads should not allocate
## GC'ed memory, or you should compile with ``--gc:none`` or ``--gc:boehm``.
##
## Example:
##
## .. code-block:: nimrod
##
## var
## thr: array [0..4, TThread]
## L: TLock
##
## proc threadFunc(c: pointer) {.procvar.} =
## for i in 0..9:
## Aquire(L) # lock stdout
## echo i
## Release(L)
##
## InitLock(L)
##
## for i in 0..high(thr):
## createThread(thr[i], threadFunc)
## for i in 0..high(thr):
## joinThread(thr[i])
# We jump through some hops here to ensure that Nimrod thread procs can have
# the Nimrod calling convention. This is needed because thread procs are
# ``stdcall`` on Windows and ``noconv`` on UNIX. Alternative would be to just
# use ``stdcall`` since it is mapped to ``noconv`` on UNIX anyway. However,
# the current approach will likely result in less problems later when we have
# GC'ed closures in Nimrod.
type
TThreadProc* = proc (closure: pointer) ## Standard Nimrod thread proc.
TThreadProcClosure {.pure, final.} = object
fn: TThreadProc
data: pointer
when defined(Windows):
type
THandle = int
TSysThread = THandle
TSysLock {.final, pure.} = object # CRITICAL_SECTION in WinApi
DebugInfo: pointer
LockCount: int32
RecursionCount: int32
OwningThread: int
LockSemaphore: int
Reserved: int32
TWinThreadProc = proc (x: pointer): int32 {.stdcall.}
TLock* = TSysLock ## Standard Nimrod Lock type.
proc InitLock*(L: var TLock) {.stdcall,
dynlib: "kernel32", importc: "InitializeCriticalSection".}
## Initializes the lock `L`.
proc Aquire*(L: var TLock) {.stdcall,
dynlib: "kernel32", importc: "EnterCriticalSection".}
## Aquires the lock `L`.
proc Release*(L: var TLock) {.stdcall,
dynlib: "kernel32", importc: "LeaveCriticalSection".}
## Releases the lock `L`.
proc CreateThread(lpThreadAttributes: Pointer, dwStackSize: int32,
lpStartAddress: TWinThreadProc,
lpParameter: Pointer,
dwCreationFlags: int32, lpThreadId: var int32): THandle {.
stdcall, dynlib: "kernel32", importc: "CreateThread".}
when false:
proc winSuspendThread(hThread: TSysThread): int32 {.
stdcall, dynlib: "kernel32", importc: "SuspendThread".}
proc winResumeThread(hThread: TSysThread): int32 {.
stdcall, dynlib: "kernel32", importc: "ResumeThread".}
proc WaitForMultipleObjects(nCount: int32,
lpHandles: ptr array[0..10, THandle],
bWaitAll: int32,
dwMilliseconds: int32): int32 {.
stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".}
proc WaitForSingleObject(hHandle: THANDLE, dwMilliseconds: int32): int32 {.
stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".}
proc TerminateThread(hThread: THandle, dwExitCode: int32): int32 {.
stdcall, dynlib: "kernel32", importc: "TerminateThread".}
proc threadProcWrapper(closure: pointer): int32 {.stdcall.} =
var c = cast[ptr TThreadProcClosure](closure)
c.fn(c.data)
# implicitely return 0
else:
type
TSysLock {.importc: "pthread_mutex_t", header: "<sys/types.h>".} = int
TSysThread {.importc: "pthread_t", header: "<sys/types.h>".} = int
TLock* = TSysLock
proc InitLockAux(L: var TSysLock, attr: pointer = nil) {.
importc: "pthread_mutex_init", header: "<pthread.h>".}
proc InitLock*(L: var TLock) {.inline.} =
InitLockAux(L)
proc Aquire*(L: var TLock) {.
importc: "pthread_mutex_lock", header: "<pthread.h>".}
proc Release*(L: var TLock) {.
importc: "pthread_mutex_unlock", header: "<pthread.h>".}
proc pthread_create(a1: var TSysThread, a2: ptr int,
a3: proc (x: pointer) {.noconv.},
a4: pointer): cint {.importc: "pthread_create",
header: "<pthread.h>".}
proc pthread_join(a1: TSysThread, a2: ptr pointer): cint {.
importc, header: "<pthread.h>".}
proc pthread_cancel(a1: TSysThread): cint {.
importc: "pthread_cancel", header: "<pthread.h>".}
proc threadProcWrapper(closure: pointer) {.noconv.} =
var c = cast[ptr TThreadProcClosure](closure)
c.fn(c.data)
{.passL: "-pthread".}
{.passC: "-pthread".}
type
TThread* = object of TObject ## Nimrod thread.
sys: TSysThread
c: TThreadProcClosure
proc createThread*(t: var TThread, tp: TThreadProc,
closure: pointer = nil) =
## creates a new thread `t` and starts its execution. Entry point is the
## proc `tp`. `closure` is passed to `tp`.
t.c.data = closure
t.c.fn = tp
when defined(windows):
var dummyThreadId: int32
t.sys = CreateThread(nil, 0'i32, threadProcWrapper, addr(t.c), 0'i32,
dummyThreadId)
else:
discard pthread_create(t.sys, nil, threadProcWrapper, addr(t.c))
proc joinThread*(t: TThread) =
## waits for the thread `t` until it has terminated.
when defined(windows):
discard WaitForSingleObject(t.sys, -1'i32)
else:
discard pthread_join(t.sys, nil)
proc destroyThread*(t: var TThread) =
## forces the thread `t` to terminate. This is potentially dangerous if
## you don't have full control over `t` and its aquired ressources.
when defined(windows):
discard TerminateThread(t.sys, 1'i32)
else:
discard pthread_cancel(t.sys)

View file

@ -71,7 +71,11 @@ __TINYC__
# define NIM_CONST const # define NIM_CONST const
#endif #endif
#define NIM_THREADVAR __thread #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
# define NIM_THREADVAR __declspec(thread)
#else
# define NIM_THREADVAR __thread
#endif
/* --------------- how int64 constants should be declared: ----------- */ /* --------------- how int64 constants should be declared: ----------- */
#if defined(__GNUC__) || defined(__LCC__) || \ #if defined(__GNUC__) || defined(__LCC__) || \
@ -415,8 +419,9 @@ struct TFrame {
NI len; NI len;
}; };
/*
extern TFrame* framePtr; extern TFrame* framePtr;
/*extern TSafePoint* excHandler; */ extern TSafePoint* excHandler; */
#if defined(__cplusplus) #if defined(__cplusplus)
struct NimException { struct NimException {

View file

@ -1,7 +1,7 @@
# #
# #
# Nimrod's Runtime Library # Nimrod's Runtime Library
# (c) Copyright 2010 Andreas Rumpf # (c) Copyright 2011 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.
@ -19,11 +19,11 @@
## Coding conventions: ## Coding conventions:
## ALL types are named the same as in the POSIX standard except that they start ## ALL types are named the same as in the POSIX standard except that they start
## with 'T' or 'P' (if they are pointers) and without the '_t' prefix to be ## with 'T' or 'P' (if they are pointers) and without the '_t' suffix to be
## consistent with Nimrod conventions. If an identifier is a Nimrod keyword ## consistent with Nimrod conventions. If an identifier is a Nimrod keyword
## the \`identifier\` notation is used. ## the \`identifier\` notation is used.
## ##
## This library relies on the header files of your C compiler. Thus the ## This library relies on the header files of your C compiler. The
## resulting C code will just include <XYZ.h> and *not* define the ## resulting C code will just include <XYZ.h> and *not* define the
## symbols declared here. ## symbols declared here.

View file

@ -1259,6 +1259,18 @@ var
## each executed instruction. This should only be used by debuggers! ## each executed instruction. This should only be used by debuggers!
## Only code compiled with the ``debugger:on`` switch calls this hook. ## Only code compiled with the ``debugger:on`` switch calls this hook.
type
PFrame = ptr TFrame
TFrame {.importc, nodecl, final.} = object
prev: PFrame
procname: CString
line: int # current line number
filename: CString
len: int # length of slots (when not debugging always zero)
var
framePtr {.threadvar, compilerproc.}: PFrame
when not defined(ECMAScript): when not defined(ECMAScript):
{.push overflow_checks:off} {.push overflow_checks:off}
proc add* (x: var string, y: cstring) = proc add* (x: var string, y: cstring) =

View file

@ -1,7 +1,7 @@
# #
# #
# Nimrod's Runtime Library # Nimrod's Runtime Library
# (c) Copyright 2010 Andreas Rumpf # (c) Copyright 2011 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.
@ -40,10 +40,10 @@ type
context: C_JmpBuf context: C_JmpBuf
var var
excHandler {.compilerproc.}: PSafePoint = nil excHandler {.threadvar, compilerproc.}: PSafePoint = nil
# list of exception handlers # list of exception handlers
# a global variable for the root of all try blocks # a global variable for the root of all try blocks
currException: ref E_Base currException {.threadvar.}: ref E_Base
proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} = proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} =
s.prev = excHandler s.prev = excHandler
@ -107,23 +107,11 @@ when nativeStacktrace:
# interested in # interested in
enabled = true enabled = true
type
PFrame = ptr TFrame
TFrame {.importc, nodecl, final.} = object
prev: PFrame
procname: CString
line: int # current line number
filename: CString
len: int # length of slots (when not debugging always zero)
var var
buf: string # cannot be allocated on the stack! buf: string # cannot be allocated on the stack!
assertBuf: string # we need a different buffer for assertBuf: string # we need a different buffer for
# assert, as it raises an exception and # assert, as it raises an exception and
# exception handler needs the buffer too # exception handler needs the buffer too
framePtr {.exportc.}: PFrame
tempFrames: array [0..127, PFrame] # cannot be allocated on the stack! tempFrames: array [0..127, PFrame] # cannot be allocated on the stack!
proc auxWriteStackTrace(f: PFrame, s: var string) = proc auxWriteStackTrace(f: PFrame, s: var string) =

View file

@ -61,6 +61,7 @@ type
decStack: TCellSeq # cells in the stack that are to decref again decStack: TCellSeq # cells in the stack that are to decref again
cycleRoots: TCellSet cycleRoots: TCellSet
tempStack: TCellSeq # temporary stack for recursion elimination tempStack: TCellSeq # temporary stack for recursion elimination
when hasThreadSupport:
cycleRootsLock: TSysLock cycleRootsLock: TSysLock
zctLock: TSysLock zctLock: TSysLock
stat: TGcStat stat: TGcStat
@ -281,6 +282,7 @@ proc initGC() =
init(gch.tempStack) init(gch.tempStack)
Init(gch.cycleRoots) Init(gch.cycleRoots)
Init(gch.decStack) Init(gch.decStack)
when hasThreadSupport:
InitLock(gch.cycleRootsLock) InitLock(gch.cycleRootsLock)
InitLock(gch.zctLock) InitLock(gch.zctLock)
new(gOutOfMem) # reserve space for the EOutOfMemory exception here! new(gOutOfMem) # reserve space for the EOutOfMemory exception here!

View file

@ -1,7 +1,7 @@
# #
# #
# Nimrod's Runtime Library # Nimrod's Runtime Library
# (c) Copyright 2010 Andreas Rumpf # (c) Copyright 2011 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.
@ -45,71 +45,3 @@ proc atomicDec(memLoc: var int, x: int): int =
dec(memLoc, x) dec(memLoc, x)
result = memLoc result = memLoc
when defined(Windows):
type
THandle = int
TSysThread = THandle
TSysLock {.final, pure.} = object # CRITICAL_SECTION in WinApi
DebugInfo: pointer
LockCount: int32
RecursionCount: int32
OwningThread: int
LockSemaphore: int
Reserved: int32
proc InitLock(L: var TSysLock) {.stdcall,
dynlib: "kernel32", importc: "InitializeCriticalSection".}
proc Aquire(L: var TSysLock) {.stdcall,
dynlib: "kernel32", importc: "EnterCriticalSection".}
proc Release(L: var TSysLock) {.stdcall,
dynlib: "kernel32", importc: "LeaveCriticalSection".}
proc CreateThread(lpThreadAttributes: Pointer, dwStackSize: int32,
lpStartAddress: pointer, lpParameter: Pointer,
dwCreationFlags: int32, lpThreadId: var int32): THandle {.
stdcall, dynlib: "kernel32", importc: "CreateThread".}
else:
type
TSysLock {.importc: "pthread_mutex_t", header: "<sys/types.h>".} = int
TSysThread {.importc: "pthread_t", header: "<sys/types.h>".} = int
proc InitLock(L: var TSysLock, attr: pointer = nil) {.
importc: "pthread_mutex_init", header: "<pthread.h>".}
proc Aquire(L: var TSysLock) {.
importc: "pthread_mutex_lock", header: "<pthread.h>".}
proc Release(L: var TSysLock) {.
importc: "pthread_mutex_unlock", header: "<pthread.h>".}
type
TThread* = TSysThread
TLock* = TSysLock
TThreadFunc* = proc (closure: pointer) {.cdecl.}
#DWORD WINAPI SuspendThread(
# __in HANDLE hThread
#);
#DWORD WINAPI ResumeThread(
# __in HANDLE hThread
#);
#DWORD WINAPI ThreadProc(
# __in LPVOID lpParameter
#);
proc createThread*(t: var TThread, fn: TThreadFunc, closure: pointer) =
when defined(windows):
nil
else:
nil
#pthread_create(
proc joinThread*(t: TThread) =
nil
#proc pthread_exit(void *value_ptr)
proc destroyThread*(t: var TThread) =
nil

View file

@ -280,6 +280,7 @@ type
skParam, # a parameter skParam, # a parameter
skGenericParam, # a generic parameter; eq in ``proc x[eq=`==`]()`` skGenericParam, # a generic parameter; eq in ``proc x[eq=`==`]()``
skTemp, # a temporary variable (introduced by compiler) skTemp, # a temporary variable (introduced by compiler)
skModule, # module identifier
skType, # a type skType, # a type
skConst, # a constant skConst, # a constant
skVar, # a variable skVar, # a variable
@ -293,7 +294,6 @@ type
skField, # a field in a record or object skField, # a field in a record or object
skEnumField, # an identifier in an enum skEnumField, # an identifier in an enum
skForVar, # a for loop variable skForVar, # a for loop variable
skModule, # module identifier
skLabel, # a label (for block statement) skLabel, # a label (for block statement)
skStub # symbol is a stub and not yet loaded from the ROD skStub # symbol is a stub and not yet loaded from the ROD
# file (it is loaded on demand, which may mean: never) # file (it is loaded on demand, which may mean: never)

View file

@ -16,7 +16,7 @@ proc eatNewLine(p: var TParser, n: PNode) =
if p.tok.xkind == pxLineComment: if p.tok.xkind == pxLineComment:
skipCom(p, n) skipCom(p, n)
if p.tok.xkind == pxNewLine: getTok(p) if p.tok.xkind == pxNewLine: getTok(p)
else: elif p.tok.xkind == pxNewLine:
eat(p, pxNewLine) eat(p, pxNewLine)
proc skipLine(p: var TParser) = proc skipLine(p: var TParser) =

View file

@ -9,6 +9,15 @@ extern "C" {
# endif # endif
#endif #endif
typedef void (*callback_t) (int rc);
int aw_callback_set (AW_CALLBACK c, callback_t callback );
int aw_instance_callback_set (AW_CALLBACK c, callback_t callback);
#define AW_BUILD 85 // AW 5.0
// Limits
#define AW_MAX_AVCHANGE_PER_SECOND 10
#private expatDll #private expatDll
#if !defined(expatDll) #if !defined(expatDll)

View file

@ -477,7 +477,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
rethrowFlag = getTempName() rethrowFlag = getTempName()
appf(p.s[cpsLocals], "volatile NIM_BOOL $1 = NIM_FALSE;$n", [rethrowFlag]) appf(p.s[cpsLocals], "volatile NIM_BOOL $1 = NIM_FALSE;$n", [rethrowFlag])
if optStackTrace in p.Options: if optStackTrace in p.Options:
app(p.s[cpsStmts], "framePtr = (TFrame*)&F;" & tnl) appcg(p, cpsStmts, "#framePtr = (TFrame*)&F;" & tnl)
app(p.s[cpsStmts], "try {" & tnl) app(p.s[cpsStmts], "try {" & tnl)
add(p.nestedTryStmts, t) add(p.nestedTryStmts, t)
genStmts(p, t.sons[0]) genStmts(p, t.sons[0])
@ -542,7 +542,7 @@ proc genTryStmt(p: BProc, t: PNode) =
appcg(p, cpsStmts, "#pushSafePoint(&$1);$n" & appcg(p, cpsStmts, "#pushSafePoint(&$1);$n" &
"$1.status = setjmp($1.context);$n", [safePoint]) "$1.status = setjmp($1.context);$n", [safePoint])
if optStackTrace in p.Options: if optStackTrace in p.Options:
app(p.s[cpsStmts], "framePtr = (TFrame*)&F;" & tnl) appcg(p, cpsStmts, "#framePtr = (TFrame*)&F;" & tnl)
appf(p.s[cpsStmts], "if ($1.status == 0) {$n", [safePoint]) appf(p.s[cpsStmts], "if ($1.status == 0) {$n", [safePoint])
var length = sonsLen(t) var length = sonsLen(t)
add(p.nestedTryStmts, t) add(p.nestedTryStmts, t)

View file

@ -386,10 +386,10 @@ proc assignGlobalVar(p: BProc, s: PSym) =
useHeader(p.module, s) useHeader(p.module, s)
if lfNoDecl in s.loc.flags: return if lfNoDecl in s.loc.flags: return
if sfImportc in s.flags: app(p.module.s[cfsVars], "extern ") if sfImportc in s.flags: app(p.module.s[cfsVars], "extern ")
if sfThreadVar in s.flags: app(p.module.s[cfsVars], "NIM_THREADVAR ")
app(p.module.s[cfsVars], getTypeDesc(p.module, s.loc.t)) app(p.module.s[cfsVars], getTypeDesc(p.module, s.loc.t))
if sfRegister in s.flags: app(p.module.s[cfsVars], " register") if sfRegister in s.flags: app(p.module.s[cfsVars], " register")
if sfVolatile in s.flags: app(p.module.s[cfsVars], " volatile") if sfVolatile in s.flags: app(p.module.s[cfsVars], " volatile")
if sfThreadVar in s.flags: app(p.module.s[cfsVars], " NIM_THREADVAR")
appf(p.module.s[cfsVars], " $1;$n", [s.loc.r]) appf(p.module.s[cfsVars], " $1;$n", [s.loc.r])
if {optStackTrace, optEndb} * p.module.module.options == if {optStackTrace, optEndb} * p.module.module.options ==
{optStackTrace, optEndb}: {optStackTrace, optEndb}:
@ -550,19 +550,12 @@ proc retIsNotVoid(s: PSym): bool =
result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0]) result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0])
proc initFrame(p: BProc, procname, filename: PRope): PRope = proc initFrame(p: BProc, procname, filename: PRope): PRope =
inc(p.labels, 5) result = ropecg(p.module,
result = ropeff("F.procname = $1;$n" & "F.prev = framePtr;$n" & "F.procname = $1;$n" &
"F.filename = $2;$n" & "F.line = 0;$n" & "framePtr = (TFrame*)&F;$n", "F.prev = #framePtr;$n" &
"%LOC$3 = getelementptr %TF %F, %NI 1$n" & "F.filename = $2;$n" &
"%LOC$4 = getelementptr %TF %F, %NI 0$n" & "F.line = 0;$n" &
"%LOC$5 = getelementptr %TF %F, %NI 3$n" & "framePtr = (TFrame*)&F;$n", [procname, filename])
"%LOC$6 = getelementptr %TF %F, %NI 2$n" & "store i8* $1, i8** %LOC$3$n" &
"store %TFrame* @framePtr, %TFrame** %LOC$4$n" &
"store i8* $2, i8** %LOC$5$n" & "store %NI 0, %NI* %LOC$6$n" &
"%LOC$7 = bitcast %TF* %F to %TFrame*$n" &
"store %TFrame* %LOC$7, %TFrame** @framePtr$n", [procname, filename,
toRope(p.labels), toRope(p.labels - 1), toRope(p.labels - 2),
toRope(p.labels - 3), toRope(p.labels - 4)])
proc deinitFrame(p: BProc): PRope = proc deinitFrame(p: BProc): PRope =
inc(p.labels, 3) inc(p.labels, 3)
@ -693,10 +686,10 @@ proc genVarPrototype(m: BModule, sym: PSym) =
[sym.loc.r, getTypeDesc(m, sym.loc.t)]) [sym.loc.r, getTypeDesc(m, sym.loc.t)])
else: else:
app(m.s[cfsVars], "extern ") app(m.s[cfsVars], "extern ")
if sfThreadVar in sym.flags: app(m.s[cfsVars], "NIM_THREADVAR ")
app(m.s[cfsVars], getTypeDesc(m, sym.loc.t)) app(m.s[cfsVars], getTypeDesc(m, sym.loc.t))
if sfRegister in sym.flags: app(m.s[cfsVars], " register") if sfRegister in sym.flags: app(m.s[cfsVars], " register")
if sfVolatile in sym.flags: app(m.s[cfsVars], " volatile") if sfVolatile in sym.flags: app(m.s[cfsVars], " volatile")
if sfThreadVar in sym.flags: app(m.s[cfsVars], " NIM_THREADVAR")
appf(m.s[cfsVars], " $1;$n", [sym.loc.r]) appf(m.s[cfsVars], " $1;$n", [sym.loc.r])
proc genConstPrototype(m: BModule, sym: PSym) = proc genConstPrototype(m: BModule, sym: PSym) =

View file

@ -32,7 +32,6 @@ type
filename*: string # filename of the source file; without extension filename*: string # filename of the source file; without extension
basedir*: string # base directory (where to put the documentation) basedir*: string # base directory (where to put the documentation)
modDesc*: PRope # module description modDesc*: PRope # module description
deps*: PRope # dependencies
id*: int # for generating IDs id*: int # for generating IDs
splitAfter*: int # split too long entries in the TOC splitAfter*: int # split too long entries in the TOC
tocPart*: seq[TTocEntry] tocPart*: seq[TTocEntry]
@ -765,8 +764,11 @@ proc getModuleFile(n: PNode): string =
result = "" result = ""
proc traceDeps(d: PDoc, n: PNode) = proc traceDeps(d: PDoc, n: PNode) =
if d.deps != nil: app(d.deps, ", ") const k = skModule
app(d.deps, getModuleFile(n)) if d.section[k] != nil: app(d.section[k], ", ")
dispA(d.section[k],
"<a class=\"reference external\" href=\"$1.html\">$1</a>",
"$1", [toRope(getModuleFile(n))])
proc generateDoc(d: PDoc, n: PNode) = proc generateDoc(d: PDoc, n: PNode) =
if n == nil: return if n == nil: return
@ -802,8 +804,12 @@ proc generateDoc(d: PDoc, n: PNode) =
else: nil else: nil
proc genSection(d: PDoc, kind: TSymKind) = proc genSection(d: PDoc, kind: TSymKind) =
const sectionNames: array[skModule..skTemplate, string] = [
"Imports", "Types", "Consts", "Vars", "Procs", "Methods",
"Iterators", "Converters", "Macros", "Templates"
]
if d.section[kind] == nil: return if d.section[kind] == nil: return
var title = toRope(copy($kind, 2) & 's') var title = toRope(sectionNames[kind])
d.section[kind] = ropeFormatNamedVars(getConfigVar("doc.section"), [ d.section[kind] = ropeFormatNamedVars(getConfigVar("doc.section"), [
"sectionid", "sectionTitle", "sectionTitleID", "content"], [ "sectionid", "sectionTitle", "sectionTitleID", "content"], [
toRope(ord(kind)), title, toRope(ord(kind) + 50), d.section[kind]]) toRope(ord(kind)), title, toRope(ord(kind) + 50), d.section[kind]])
@ -833,14 +839,14 @@ proc genOutFile(d: PDoc): PRope =
if d.hasToc: bodyname = "doc.body_toc" if d.hasToc: bodyname = "doc.body_toc"
else: bodyname = "doc.body_no_toc" else: bodyname = "doc.body_no_toc"
content = ropeFormatNamedVars(getConfigVar(bodyname), ["title", content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
"tableofcontents", "moduledesc", "deps", "date", "time", "content"], "tableofcontents", "moduledesc", "date", "time", "content"],
[title, toc, d.modDesc, d.deps, toRope(getDateStr()), [title, toc, d.modDesc, toRope(getDateStr()),
toRope(getClockStr()), code]) toRope(getClockStr()), code])
if optCompileOnly notin gGlobalOptions: if optCompileOnly notin gGlobalOptions:
code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title", code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
"tableofcontents", "moduledesc", "deps", "date", "time", "tableofcontents", "moduledesc", "date", "time",
"content", "author", "version"], "content", "author", "version"],
[title, toc, d.modDesc, d.deps, toRope(getDateStr()), [title, toc, d.modDesc, toRope(getDateStr()),
toRope(getClockStr()), content, d.meta[metaAuthor], toRope(getClockStr()), content, d.meta[metaAuthor],
d.meta[metaVersion]]) d.meta[metaVersion]])
else: else:

View file

@ -94,6 +94,7 @@ type
errXCannotBeInParamDecl, errPragmaOnlyInHeaderOfProc, errImplOfXNotAllowed, errXCannotBeInParamDecl, errPragmaOnlyInHeaderOfProc, errImplOfXNotAllowed,
errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValue, errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValue,
errInvalidDiscard, errIllegalConvFromXtoY, errCannotBindXTwice, errInvalidDiscard, errIllegalConvFromXtoY, errCannotBindXTwice,
errInvalidOrderInArrayConstructor,
errInvalidOrderInEnumX, errEnumXHasWholes, errExceptExpected, errInvalidTry, errInvalidOrderInEnumX, errEnumXHasWholes, errExceptExpected, errInvalidTry,
errOptionExpected, errXisNoLabel, errNotAllCasesCovered, errOptionExpected, errXisNoLabel, errNotAllCasesCovered,
errUnkownSubstitionVar, errComplexStmtRequiresInd, errXisNotCallable, errUnkownSubstitionVar, errComplexStmtRequiresInd, errXisNotCallable,
@ -214,6 +215,7 @@ const
"value returned by statement has to be discarded", "value returned by statement has to be discarded",
"statement returns no value that can be discarded", "statement returns no value that can be discarded",
"conversion from $1 to $2 is invalid", "cannot bind parameter \'$1\' twice", "conversion from $1 to $2 is invalid", "cannot bind parameter \'$1\' twice",
"invalid order in array constructor",
"invalid order in enum \'$1\'", "enum \'$1\' has wholes", "invalid order in enum \'$1\'", "enum \'$1\' has wholes",
"\'except\' or \'finally\' expected", "\'except\' or \'finally\' expected",
"after catch all \'except\' or \'finally\' no section may follow", "after catch all \'except\' or \'finally\' no section may follow",

View file

@ -260,11 +260,29 @@ proc semArrayConstr(c: PContext, n: PNode): PNode =
if sonsLen(n) == 0: if sonsLen(n) == 0:
addSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype! addSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
else: else:
addSon(result, semExprWithType(c, n.sons[0])) var x = n.sons[0]
var lastIndex: biggestInt = 0
var indexType = getSysType(tyInt)
if x.kind == nkExprColonExpr:
var idx = semConstExpr(c, x.sons[0])
lastIndex = getOrdValue(idx)
indexType = idx.typ
x = x.sons[1]
addSon(result, semExprWithType(c, x))
var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal}) var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal})
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
n.sons[i] = semExprWithType(c, n.sons[i]) x = n.sons[i]
if x.kind == nkExprColonExpr:
var idx = semConstExpr(c, x.sons[0])
idx = fitNode(c, indexType, idx)
if lastIndex+1 != getOrdValue(idx):
liMessage(x.info, errInvalidOrderInArrayConstructor)
x = x.sons[1]
n.sons[i] = semExprWithType(c, x)
addSon(result, fitNode(c, typ, n.sons[i])) addSon(result, fitNode(c, typ, n.sons[i]))
inc(lastIndex)
addSon(result.typ, typ) addSon(result.typ, typ)
result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info) result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info)

View file

@ -2,6 +2,7 @@ tack.nim;125
tambsym2.nim;7 tambsym2.nim;7
tambsys.nim; tambsys.nim;
tarray.nim;10012 tarray.nim;10012
tarraycons.nim;6
tarray2.nim;[16, 25, 36] tarray2.nim;[16, 25, 36]
tarray3.nim;3 tarray3.nim;3
tassert.nim;assertion failure!this shall be always written tassert.nim;assertion failure!this shall be always written

1 tack.nim 125
2 tambsym2.nim 7
3 tambsys.nim
4 tarray.nim 10012
5 tarraycons.nim 6
6 tarray2.nim [16, 25, 36]
7 tarray3.nim 3
8 tassert.nim assertion failure!this shall be always written

View file

@ -0,0 +1,17 @@
type
TEnum = enum
eA, eB, eC, eD, eE, eF
const
myMapping: array[TEnum, array[0..1, int]] = [
eA: [1, 2],
eB: [3, 4],
[5, 6],
eD: [0: 8, 1: 9],
eE: [0: 8, 9],
eF: [2, 1: 9]
]
echo myMapping[eC][1]

21
tests/gc/tthreads.nim Normal file
View file

@ -0,0 +1,21 @@
import threads
var
thr: array [0..4, TThread]
L: TLock
proc threadFunc(c: pointer) {.procvar.} =
for i in 0..9:
Aquire(L)
echo i
Release(L)
InitLock(L)
for i in 0..high(thr):
createThread(thr[i], threadFunc)
for i in 0..high(thr):
joinThread(thr[i])

View file

@ -3,6 +3,7 @@ tadrdisc.nim;15;for a 'var' type a variable needs to be passed
tambsym.nim;6;ambiguous identifier tambsym.nim;6;ambiguous identifier
tambsym2.nim;4;undeclared identifier: 'CreateRGBSurface' tambsym2.nim;4;undeclared identifier: 'CreateRGBSurface'
tambsym3.nim;6;ambiguous identifier tambsym3.nim;6;ambiguous identifier
tarraycons.nim;9;invalid order in array constructor
tatomic.nim;2;identifier expected, but found 'atomic' tatomic.nim;2;identifier expected, but found 'atomic'
tbind2.nim;7;ambiguous call tbind2.nim;7;ambiguous call
tbind4.nim;4;undeclared identifier: 'lastId' tbind4.nim;4;undeclared identifier: 'lastId'

1 t99bott.nim 20 constant expression expected
3 tambsym.nim 6 ambiguous identifier
4 tambsym2.nim 4 undeclared identifier: 'CreateRGBSurface'
5 tambsym3.nim 6 ambiguous identifier
6 tarraycons.nim 9 invalid order in array constructor
7 tatomic.nim 2 identifier expected, but found 'atomic'
8 tbind2.nim 7 ambiguous call
9 tbind4.nim 4 undeclared identifier: 'lastId'

View file

@ -0,0 +1,17 @@
type
TEnum = enum
eA, eB, eC, eD, eE, eF
const
myMapping: array[TEnum, array[0..1, int]] = [
eA: [1, 2],
eC: [3, 4],
eB: [5, 6],
eD: [0: 8, 1: 9],
eE: [0: 8, 9],
eF: [2, 1: 9]
]
echo myMapping[eC][1]

View file

@ -1,11 +1,16 @@
- built-in serialization
- thread support: threadvar on Windows seems broken;
add --deadlock_prevention:on|off switch
- ban ``nil`` from the AST. This might also fix bugs concerning macros.
- we need a way to disable tests - we need a way to disable tests
- deprecate ^ and make it available as operator - deprecate ^ and make it available as operator
- test branch coverage - test branch coverage
- checked exceptions - checked exceptions
- explicit indices for array literals - do not ambiguity error for methods if ambiguity only affects the same
- built-in serialization
- do not ambiguity error for methods if amibiguity only affects the same
dispatcher anyway dispatcher anyway
- slicing
High priority (version 0.9.0) High priority (version 0.9.0)
@ -23,6 +28,7 @@ Bugs
- proc (x: int) is passable to proc (x: var int) !? - proc (x: int) is passable to proc (x: var int) !?
- detected by pegs module 64bit: p(result, result) should use a temporary! - detected by pegs module 64bit: p(result, result) should use a temporary!
- the parser allows empty object case branches - the parser allows empty object case branches
- Exception matching needs to take subclasses into account
To implement To implement

View file

@ -47,6 +47,9 @@ Additions
- A field in an ``enum`` may be given an explicit string representation. - A field in an ``enum`` may be given an explicit string representation.
This yields more maintainable code than using a constant This yields more maintainable code than using a constant
``array[TMyEnum, string]`` mapping. ``array[TMyEnum, string]`` mapping.
- Indices in array literals may be explicitly given, enhancing readability:
``[enumValueA: "a", enumValueB: "b"]``.
- Added basic thread support via the ``threads`` core module.

View file

@ -24,13 +24,14 @@ file: ticker
doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview" doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview"
doc: "tools;c2nim;niminst" doc: "tools;c2nim;niminst"
pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst" pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst"
srcdoc: "core/macros;core/threads;core/marshal"
srcdoc: "impure/graphics;pure/sockets" srcdoc: "impure/graphics;pure/sockets"
srcdoc: "system.nim;pure/os;pure/strutils;pure/math" srcdoc: "system.nim;pure/os;pure/strutils;pure/math"
srcdoc: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib" srcdoc: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib"
srcdoc: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase" 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/xmlgen;pure/macros;pure/parseutils;pure/browsers" srcdoc: "impure/zipfiles;pure/xmlgen;pure/parseutils;pure/browsers"
srcdoc: "impure/db_postgres;impure/db_mysql;impure/db_sqlite" srcdoc: "impure/db_postgres;impure/db_mysql;impure/db_sqlite"
srcdoc: "pure/httpserver;pure/httpclient;pure/stmp;impure/ssl" srcdoc: "pure/httpserver;pure/httpclient;pure/stmp;impure/ssl"
srcdoc: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser" srcdoc: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"