Merge branch 'devel'

This commit is contained in:
Dominik Picheta
2015-05-05 14:14:22 +01:00
24 changed files with 339 additions and 181 deletions

View File

@@ -964,8 +964,11 @@ proc genEcho(p: BProc, n: PNode) =
var args: Rope = nil
var a: TLoc
for i in countup(0, n.len-1):
initLocExpr(p, n.sons[i], a)
addf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
if n.sons[i].skipConv.kind == nkNilLit:
add(args, ", \"nil\"")
else:
initLocExpr(p, n.sons[i], a)
addf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
linefmt(p, cpsStmts, "printf($1$2);$n",
makeCString(repeat("%s", n.len) & tnl), args)

View File

@@ -47,7 +47,7 @@ Start: "doc/overview.html"
[Other]
Files: "readme.txt;install.txt;contributors.txt;copying.txt"
Files: "configure;makefile"
Files: "makefile"
Files: "*.ini"
Files: "koch.nim"
@@ -70,6 +70,10 @@ Files: "doc/*.nim"
Files: "doc/*.cfg"
Files: "compiler/nimfix/*.nim"
Files: "compiler/nimfix/*.cfg"
Files: "compiler/nimsuggest/*.nim"
Files: "compiler/nimsuggest/*.cfg"
Files: "compiler/plugins/locals/*.nim"
Files: "compiler/plugins/active.nim"
Files: "tools/*.nim"
Files: "tools/*.cfg"
Files: "tools/*.tmpl"
@@ -97,13 +101,8 @@ Files: "lib/pure/concurrency/*.cfg"
Files: "lib/impure/*.nim"
Files: "lib/wrappers/*.nim"
Files: "lib/wrappers/cairo/*.nim"
Files: "lib/wrappers/gtk/*.nim"
Files: "lib/wrappers/lua/*.nim"
Files: "lib/wrappers/opengl/*.nim"
Files: "lib/wrappers/readline/*.nim"
Files: "lib/wrappers/sdl/*.nim"
Files: "lib/wrappers/x11/*.nim"
Files: "lib/wrappers/zip/*.nim"
Files: "lib/wrappers/zip/libzip_all.c"
@@ -115,8 +114,6 @@ Files: "lib/packages/docutils/*.nim"
[Other]
Files: "examples/*.nim"
Files: "examples/gtk/*.nim"
Files: "examples/0mq/*.nim"
Files: "examples/c++iface/*.nim"
Files: "examples/objciface/*.nim"
Files: "examples/cross_calculator/"
@@ -239,7 +236,7 @@ BinPath: r"bin;dist\mingw\bin;dist"
; Section | dir | zipFile | size hint (in KB) | url | exe start menu entry
Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|overview.html"
Download: r"C Compiler (MingW)|dist|mingw.zip|82944|http://nim-lang.org/download/${mingw}.zip"
Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.3.0.zip|aporia\bin\aporia.exe"
Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.3.0.zip|aporia-0.3.0\bin\aporia.exe"
; for now only NSIS supports optional downloads
[UnixBin]

View File

@@ -1,7 +1,7 @@
#
#
# The Nim Compiler
# (c) Copyright 2013 Andreas Rumpf
# (c) Copyright 2015 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.

View File

@@ -535,7 +535,18 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
result.sons[i] = fitNode(c, typ, result.sons[i])
result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info)
template fixAbstractType(c: PContext, n: PNode) =
proc fixAbstractType(c: PContext, n: PNode) =
for i in 1 .. < n.len:
let it = n.sons[i]
# do not get rid of nkHiddenSubConv for OpenArrays, the codegen needs it:
if it.kind == nkHiddenSubConv and
skipTypes(it.typ, abstractVar).kind notin {tyOpenArray, tyVarargs}:
if skipTypes(it.sons[1].typ, abstractVar).kind in
{tyNil, tyArrayConstr, tyTuple, tySet}:
var s = skipTypes(it.typ, abstractVar)
if s.kind != tyExpr:
changeType(it.sons[1], s, check=true)
n.sons[i] = it.sons[1]
when false:
# XXX finally rewrite that crap!
for i in countup(1, sonsLen(n) - 1):
@@ -2042,7 +2053,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of nkEmpty, nkNone, nkCommentStmt:
discard
of nkNilLit:
result.typ = getSysType(tyNil)
if result.typ == nil: result.typ = getSysType(tyNil)
of nkIntLit:
if result.typ == nil: setIntLitType(result)
of nkInt8Lit:

View File

@@ -286,10 +286,13 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
of mNot: result = newIntNodeT(1 - getInt(a), n)
of mCard: result = newIntNodeT(nimsets.cardSet(a), n)
of mBitnotI, mBitnotI64: result = newIntNodeT(not getInt(a), n)
of mLengthStr, mXLenStr: result = newIntNodeT(len(getStr(a)), n)
of mLengthStr, mXLenStr:
if a.kind == nkNilLit: result = newIntNodeT(0, n)
else: result = newIntNodeT(len(getStr(a)), n)
of mLengthArray: result = newIntNodeT(lengthOrd(a.typ), n)
of mLengthSeq, mLengthOpenArray, mXLenSeq:
result = newIntNodeT(sonsLen(a), n) # BUGFIX
if a.kind == nkNilLit: result = newIntNodeT(0, n)
else: result = newIntNodeT(sonsLen(a), n) # BUGFIX
of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
of mToFloat, mToBiggestFloat:
result = newFloatNodeT(toFloat(int(getInt(a))), n)
@@ -545,7 +548,7 @@ proc foldConv*(n, a: PNode; check = false): PNode =
discard
else:
result = a
result.typ = takeType(n.typ, a.typ)
result.typ = n.typ
proc getArrayConstr(m: PSym, n: PNode): PNode =
if n.kind == nkBracket:
@@ -652,7 +655,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
result = copyNode(n)
of nkIfExpr:
result = getConstIfExpr(m, n)
of nkCall, nkCommand, nkCallStrLit, nkPrefix, nkInfix:
of nkCallKinds:
if n.sons[0].kind != nkSym: return
var s = n.sons[0].sym
if s.kind != skProc: return

View File

@@ -716,8 +716,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
add(result, PTransNode(newSymNode(labl)))
of nkBreakStmt: result = transformBreak(c, n)
of nkWhileStmt: result = transformWhile(c, n)
of nkCall, nkHiddenCallConv, nkCommand, nkInfix, nkPrefix, nkPostfix,
nkCallStrLit:
of nkCallKinds:
result = transformCall(c, n)
of nkAddr, nkHiddenAddr:
result = transformAddrDeref(c, n, nkDerefExpr, nkHiddenDeref)

View File

@@ -96,7 +96,7 @@ path="$lib/pure/unidecode"
# Configuration for the GNU C/C++ compiler:
@if windows:
#gcc.path = r"$nimrod\dist\mingw\bin"
#gcc.path = r"$nim\dist\mingw\bin"
@if gcc:
tlsEmulation:on
@end

View File

@@ -16,7 +16,7 @@ Introduction
</p></blockquote>
This document is a tutorial for the programming language *Nim*.
This document is a tutorial for the programming language *Nim*.
This tutorial assumes that you are familiar with basic programming concepts
like variables, types or statements but is kept very basic. The `manual
<manual.html>`_ contains many more examples of the advanced language features.
@@ -50,7 +50,7 @@ Commonly used commands and switches have abbreviations, so you can also use::
nim c -r greetings.nim
To compile a release version use::
nim c -d:release greetings.nim
By default the Nim compiler generates a large amount of runtime checks
@@ -116,7 +116,7 @@ hash character ``#``. Documentation comments start with ``##``:
.. code-block:: nim
# A comment.
var myVariable: int ## a documentation comment
@@ -200,7 +200,7 @@ constant declaration at compile time:
.. code-block:: nim
const x = "abc" # the constant x contains the string "abc"
Indentation can be used after the ``const`` keyword to list a whole section of
constants:
@@ -214,7 +214,7 @@ constants:
The let statement
=================
The ``let`` statement works like the ``var`` statement but the declared
The ``let`` statement works like the ``var`` statement but the declared
symbols are *single assignment* variables: After the initialization their
value cannot change:
@@ -228,7 +228,7 @@ and put it into a data section":
.. code-block::
const input = readLine(stdin) # Error: constant expression expected
.. code-block::
let input = readLine(stdin) # works
@@ -310,8 +310,8 @@ the compiler that for every other value nothing should be done:
else: discard
The empty `discard statement`_ is a *do nothing* statement. The compiler knows
that a case statement with an else part cannot fail and thus the error
disappears. Note that it is impossible to cover all possible string values:
that a case statement with an else part cannot fail and thus the error
disappears. Note that it is impossible to cover all possible string values:
that is why string cases always need an ``else`` branch.
In general the case statement is used for subrange types or enumerations where
@@ -406,7 +406,7 @@ The block's *label* (``myblock`` in the example) is optional.
Break statement
---------------
A block can be left prematurely with a ``break`` statement. The break statement
can leave a ``while``, ``for``, or a ``block`` statement. It leaves the
can leave a ``while``, ``for``, or a ``block`` statement. It leaves the
innermost construct, unless a label of a block is given:
.. code-block:: nim
@@ -461,7 +461,7 @@ differences:
* The statements within a branch do not open a new scope.
* The compiler checks the semantics and produces code *only* for the statements
that belong to the first condition that evaluates to ``true``.
The ``when`` statement is useful for writing platform specific code, similar to
the ``#ifdef`` construct in the C programming language.
@@ -486,14 +486,14 @@ to be indented, but single simple statements do not:
.. code-block:: nim
# no indentation needed for single assignment statement:
if x: x = false
# indentation needed for nested if statement:
if x:
if y:
y = false
else:
y = true
# indentation needed, because two statements follow the condition:
if x:
x = false
@@ -514,7 +514,7 @@ contain indentation at certain places for better readability:
As a rule of thumb, indentation within expressions is allowed after operators,
an open parenthesis and after commas.
With parenthesis and semicolons ``(;)`` you can use statements where only
With parenthesis and semicolons ``(;)`` you can use statements where only
an expression is allowed:
.. code-block:: nim
@@ -560,45 +560,45 @@ Some terminology: in the example ``question`` is called a (formal) *parameter*,
Result variable
---------------
A procedure that returns a value has an implicit ``result`` variable declared
A procedure that returns a value has an implicit ``result`` variable declared
that represents the return value. A ``return`` statement with no expression is a
shorthand for ``return result``. The ``result`` value is always returned
shorthand for ``return result``. The ``result`` value is always returned
automatically at the end a procedure if there is no ``return`` statement at
the exit.
.. code-block:: nim
proc sumTillNegative(x: varargs[int]): int =
proc sumTillNegative(x: varargs[int]): int =
for i in x:
if i < 0:
return
result = result + i
result = result + i
echo sumTillNegative() # echos 0
echo sumTillNegative(3, 4, 5) # echos 12
echo sumTillNegative(3, 4 , -1 , 6) # echos 7
The ``result`` variable is already implicitly declared at the start of the
The ``result`` variable is already implicitly declared at the start of the
function, so declaring it again with 'var result', for example, would shadow it
with a normal variable of the same name. The result variable is also already
initialised with the type's default value. Note that referential data types will
be ``nil`` at the start of the procedure, and thus may require manual
initialisation.
Parameters
----------
Parameters are constant in the procedure body. By default, their value cannot be
changed because this allows the compiler to implement parameter passing in the
changed because this allows the compiler to implement parameter passing in the
most efficient way. If a mutable variable is needed inside the procedure, it has
to be declared with ``var`` in the procedure body. Shadowing the parameter name
is possible, and actually an idiom:
is possible, and actually an idiom:
.. code-block:: nim
proc printSeq(s: seq, nprinted: int = -1) =
var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len)
for i in 0 .. <nprinted:
echo s[i]
If the procedure needs to modify the argument for the
caller, a ``var`` parameter can be used:
@@ -630,12 +630,12 @@ allow to silently throw away a return value:
The return value can be ignored implicitly if the called proc/iterator has
been declared with the ``discardable`` pragma:
been declared with the ``discardable`` pragma:
.. code-block:: nim
proc p(x, y: int): int {.discardable.} =
proc p(x, y: int): int {.discardable.} =
return x + y
p(3, 4) # now valid
The ``discard`` statement can also be used to create block comments as
@@ -899,7 +899,7 @@ object on the heap, so there is a trade-off to be made here.
Integers
--------
Nim has these integer types built-in:
Nim has these integer types built-in:
``int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64``.
The default integer type is ``int``. Integer literals can have a *type suffix*
@@ -1114,7 +1114,7 @@ Arrays
An array is a simple fixed length container. Each element in
the array has the same type. The array's index type can be any ordinal type.
Arrays can be constructed via ``[]``:
Arrays can be constructed via ``[]``:
.. code-block:: nim
@@ -1370,12 +1370,12 @@ integer.
var building: tuple[street: string, number: int]
building = ("Rue del Percebe", 13)
echo(building.street)
# The following line does not compile, they are different tuples!
#person = building
# --> Error: type mismatch: got (tuple[street: string, number: int])
# but expected 'Person'
# The following works because the field names and types are the same.
var teacher: tuple[name: string, age: int] = ("Mark", 42)
person = teacher
@@ -1450,13 +1450,13 @@ operators perform implicit dereferencing operations for reference types:
type
Node = ref NodeObj
NodeObj = object
le, ri: PNode
NodeObj = object
le, ri: Node
data: int
var
n: Node
new(n)
n.data = 9
n.data = 9
# no need to write n[].data; in fact n[].data is highly discouraged!
To allocate a new traced object, the built-in procedure ``new`` has to be used.
@@ -1559,9 +1559,9 @@ This is best illustrated by an example:
A symbol of a module *can* be *qualified* with the ``module.symbol`` syntax. If
the symbol is ambiguous, it even *has* to be qualified. A symbol is ambiguous
if it is defined in two (or more) different modules and both modules are
imported by a third one:
the symbol is ambiguous, it even *has* to be qualified. A symbol is ambiguous
if it is defined in two (or more) different modules and both modules are
imported by a third one:
.. code-block:: nim
# Module A

View File

@@ -9,8 +9,8 @@
## This module implements a zip archive creator/reader/modifier.
import
streams, libzip, times, os
import
streams, libzip, times, os, strutils
type
TZipArchive* = object of RootObj ## represents a zip archive
@@ -18,14 +18,14 @@ type
w: PZip
proc zipError(z: var TZipArchive) =
proc zipError(z: var TZipArchive) =
var e: ref IOError
new(e)
e.msg = $zip_strerror(z.w)
raise e
proc open*(z: var TZipArchive, filename: string, mode: FileMode = fmRead): bool =
## Opens a zip file for reading, writing or appending. All file modes are
## Opens a zip file for reading, writing or appending. All file modes are
## supported. Returns true iff successful, false otherwise.
var err, flags: int32
case mode
@@ -41,21 +41,21 @@ proc open*(z: var TZipArchive, filename: string, mode: FileMode = fmRead): bool
proc close*(z: var TZipArchive) =
## Closes a zip file.
zip_close(z.w)
proc createDir*(z: var TZipArchive, dir: string) =
proc createDir*(z: var TZipArchive, dir: string) =
## Creates a directory within the `z` archive. This does not fail if the
## directory already exists. Note that for adding a file like
## directory already exists. Note that for adding a file like
## ``"path1/path2/filename"`` it is not necessary
## to create the ``"path/path2"`` subdirectories - it will be done
## automatically by ``addFile``.
assert(z.mode != fmRead)
## to create the ``"path/path2"`` subdirectories - it will be done
## automatically by ``addFile``.
assert(z.mode != fmRead)
discard zip_add_dir(z.w, dir)
zip_error_clear(z.w)
proc addFile*(z: var TZipArchive, dest, src: string) =
proc addFile*(z: var TZipArchive, dest, src: string) =
## Adds the file `src` to the archive `z` with the name `dest`. `dest`
## may contain a path that will be created.
assert(z.mode != fmRead)
## may contain a path that will be created.
assert(z.mode != fmRead)
if not fileExists(src):
raise newException(IOError, "File '" & src & "' does not exist")
var zipsrc = zip_source_file(z.w, src, 0, -1)
@@ -67,21 +67,21 @@ proc addFile*(z: var TZipArchive, dest, src: string) =
zip_source_free(zipsrc)
zipError(z)
proc addFile*(z: var TZipArchive, file: string) =
proc addFile*(z: var TZipArchive, file: string) =
## A shortcut for ``addFile(z, file, file)``, i.e. the name of the source is
## the name of the destination.
addFile(z, file, file)
proc mySourceCallback(state, data: pointer, len: int,
cmd: TZipSourceCmd): int {.cdecl.} =
proc mySourceCallback(state, data: pointer, len: int,
cmd: TZipSourceCmd): int {.cdecl.} =
var src = cast[Stream](state)
case cmd
of ZIP_SOURCE_OPEN:
of ZIP_SOURCE_OPEN:
if src.setPositionImpl != nil: setPosition(src, 0) # reset
of ZIP_SOURCE_READ:
result = readData(src, data, len)
of ZIP_SOURCE_CLOSE: close(src)
of ZIP_SOURCE_STAT:
of ZIP_SOURCE_STAT:
var stat = cast[PZipStat](data)
zip_stat_init(stat)
stat.size = high(int32)-1 # we don't know the size
@@ -94,8 +94,8 @@ proc mySourceCallback(state, data: pointer, len: int,
result = 2*sizeof(cint)
of constZIP_SOURCE_FREE: GC_unref(src)
else: assert(false)
proc addFile*(z: var TZipArchive, dest: string, src: Stream) =
proc addFile*(z: var TZipArchive, dest: string, src: Stream) =
## Adds a file named with `dest` to the archive `z`. `dest`
## may contain a path. The file's content is read from the `src` stream.
assert(z.mode != fmRead)
@@ -105,39 +105,45 @@ proc addFile*(z: var TZipArchive, dest: string, src: Stream) =
if zip_add(z.w, dest, zipsrc) < 0'i32:
zip_source_free(zipsrc)
zipError(z)
# -------------- zip file stream ---------------------------------------------
type
TZipFileStream = object of StreamObj
f: PZipFile
atEnd: bool
PZipFileStream* =
ref TZipFileStream ## a reader stream of a file within a zip archive
PZipFileStream* =
ref TZipFileStream ## a reader stream of a file within a zip archive
proc fsClose(s: Stream) = zip_fclose(PZipFileStream(s).f)
proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int =
proc fsAtEnd(s: Stream): bool = PZipFileStream(s).atEnd
proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int =
result = zip_fread(PZipFileStream(s).f, buffer, bufLen)
if result == 0:
PZipFileStream(s).atEnd = true
proc newZipFileStream(f: PZipFile): PZipFileStream =
proc newZipFileStream(f: PZipFile): PZipFileStream =
new(result)
result.f = f
result.atEnd = false
result.closeImpl = fsClose
result.readDataImpl = fsReadData
result.atEndImpl = fsAtEnd
# other methods are nil!
# ----------------------------------------------------------------------------
proc getStream*(z: var TZipArchive, filename: string): PZipFileStream =
proc getStream*(z: var TZipArchive, filename: string): PZipFileStream =
## returns a stream that can be used to read the file named `filename`
## from the archive `z`. Returns nil in case of an error.
## The returned stream does not support the `setPosition`, `getPosition`,
## The returned stream does not support the `setPosition`, `getPosition`,
## `writeData` or `atEnd` methods.
var x = zip_fopen(z.w, filename, 0'i32)
if x != nil: result = newZipFileStream(x)
iterator walkFiles*(z: var TZipArchive): string =
## walks over all files in the archive `z` and returns the filename
iterator walkFiles*(z: var TZipArchive): string =
## walks over all files in the archive `z` and returns the filename
## (including the path).
var i = 0'i32
var num = zip_get_num_files(z.w)
@@ -158,12 +164,20 @@ proc extractFile*(z: var TZipArchive, srcFile: string, dest: Stream) =
proc extractFile*(z: var TZipArchive, srcFile: string, dest: string) =
## extracts a file from the zip archive `z` to the destination filename.
var file = newFileStream(dest, fmReadWrite)
var file = newFileStream(dest, fmWrite)
extractFile(z, srcFile, file)
file.close()
proc extractAll*(z: var TZipArchive, dest: string) =
## extracts all files from archive `z` to the destination directory.
for file in walkFiles(z):
extractFile(z, file, dest / extractFilename(file))
if file.endsWith("/"):
createDir(dest / file)
else:
extractFile(z, file, dest / file)
when not defined(testing) and isMainModule:
var zip: TZipArchive
if not zip.open("nim-0.11.0.zip"):
raise newException(IOError, "opening zip failed")
zip.extractAll("test")

View File

@@ -152,10 +152,12 @@ type
DocumentObj {.importc.} = object of NodeObj
alinkColor*: cstring
bgColor*: cstring
body*: Element
charset*: cstring
cookie*: cstring
defaultCharset*: cstring
fgColor*: cstring
head*: Element
lastModified*: cstring
linkColor*: cstring
referrer*: cstring

View File

@@ -819,15 +819,18 @@ proc enlarge[A](t: var CountTable[A]) =
swap(t.data, n)
proc `[]=`*[A](t: var CountTable[A], key: A, val: int) =
## puts a (key, value)-pair into `t`. `val` has to be positive.
## puts a (key, value)-pair into `t`.
assert val > 0
var h = rawGet(t, key)
if h >= 0:
t.data[h].val = val
else:
h = -1 - h
t.data[h].key = key
t.data[h].val = val
if mustRehash(len(t.data), t.counter): enlarge(t)
rawInsert(t, t.data, key, val)
inc(t.counter)
#h = -1 - h
#t.data[h].key = key
#t.data[h].val = val
proc initCountTable*[A](initialSize=64): CountTable[A] =
## creates a new count table that is empty.

View File

@@ -1535,7 +1535,7 @@ const
NimMinor*: int = 11
## is the minor number of Nim's version.
NimPatch*: int = 0
NimPatch*: int = 2
## is the patch number of Nim's version.
NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch

View File

@@ -10,6 +10,8 @@
## This module implements a small wrapper for some needed Win API procedures,
## so that the Nim compiler does not depend on the huge Windows module.
{.deadCodeElim:on.}
const
useWinUnicode* = not defined(useWinAnsi)
@@ -29,7 +31,7 @@ type
nLength*: int32
lpSecurityDescriptor*: pointer
bInheritHandle*: WINBOOL
TSTARTUPINFO* {.final, pure.} = object
cb*: int32
lpReserved*: cstring
@@ -59,7 +61,7 @@ type
TFILETIME* {.final, pure.} = object ## CANNOT BE int64 BECAUSE OF ALIGNMENT
dwLowDateTime*: DWORD
dwHighDateTime*: DWORD
TBY_HANDLE_FILE_INFORMATION* {.final, pure.} = object
dwFileAttributes*: DWORD
ftCreationTime*: TFILETIME
@@ -94,26 +96,26 @@ const
STD_ERROR_HANDLE* = -12'i32
DETACHED_PROCESS* = 8'i32
SW_SHOWNORMAL* = 1'i32
INVALID_HANDLE_VALUE* = THandle(-1)
CREATE_UNICODE_ENVIRONMENT* = 1024'i32
proc closeHandle*(hObject: THandle): WINBOOL {.stdcall, dynlib: "kernel32",
importc: "CloseHandle".}
proc readFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: int32,
lpNumberOfBytesRead: ptr int32, lpOverlapped: pointer): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "ReadFile".}
proc writeFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: int32,
lpNumberOfBytesWritten: ptr int32,
lpNumberOfBytesWritten: ptr int32,
lpOverlapped: pointer): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "WriteFile".}
proc createPipe*(hReadPipe, hWritePipe: var THandle,
lpPipeAttributes: var TSECURITY_ATTRIBUTES,
lpPipeAttributes: var TSECURITY_ATTRIBUTES,
nSize: int32): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "CreatePipe".}
@@ -159,7 +161,7 @@ proc setStdHandle*(nStdHandle: int32, hHandle: THandle): WINBOOL {.stdcall,
proc flushFileBuffers*(hFile: THandle): WINBOOL {.stdcall, dynlib: "kernel32",
importc: "FlushFileBuffers".}
proc getLastError*(): int32 {.importc: "GetLastError",
proc getLastError*(): int32 {.importc: "GetLastError",
stdcall, dynlib: "kernel32".}
when useWinUnicode:
@@ -179,7 +181,7 @@ proc localFree*(p: pointer) {.
importc: "LocalFree", stdcall, dynlib: "kernel32".}
when useWinUnicode:
proc getCurrentDirectoryW*(nBufferLength: int32,
proc getCurrentDirectoryW*(nBufferLength: int32,
lpBuffer: WideCString): int32 {.
importc: "GetCurrentDirectoryW", dynlib: "kernel32", stdcall.}
proc setCurrentDirectoryW*(lpPathName: WideCString): int32 {.
@@ -191,8 +193,8 @@ when useWinUnicode:
proc setEnvironmentVariableW*(lpName, lpValue: WideCString): int32 {.
stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableW".}
proc getModuleFileNameW*(handle: THandle, buf: WideCString,
size: int32): int32 {.importc: "GetModuleFileNameW",
proc getModuleFileNameW*(handle: THandle, buf: WideCString,
size: int32): int32 {.importc: "GetModuleFileNameW",
dynlib: "kernel32", stdcall.}
else:
proc getCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {.
@@ -269,14 +271,14 @@ proc findClose*(hFindFile: THandle) {.stdcall, dynlib: "kernel32",
when useWinUnicode:
proc getFullPathNameW*(lpFileName: WideCString, nBufferLength: int32,
lpBuffer: WideCString,
lpBuffer: WideCString,
lpFilePart: var WideCString): int32 {.
stdcall, dynlib: "kernel32",
stdcall, dynlib: "kernel32",
importc: "GetFullPathNameW".}
proc getFileAttributesW*(lpFileName: WideCString): int32 {.
stdcall, dynlib: "kernel32",
stdcall, dynlib: "kernel32",
importc: "GetFileAttributesW".}
proc setFileAttributesW*(lpFileName: WideCString,
proc setFileAttributesW*(lpFileName: WideCString,
dwFileAttributes: int32): WINBOOL {.
stdcall, dynlib: "kernel32", importc: "SetFileAttributesW".}
@@ -299,12 +301,12 @@ when useWinUnicode:
else:
proc getFullPathNameA*(lpFileName: cstring, nBufferLength: int32,
lpBuffer: cstring, lpFilePart: var cstring): int32 {.
stdcall, dynlib: "kernel32",
stdcall, dynlib: "kernel32",
importc: "GetFullPathNameA".}
proc getFileAttributesA*(lpFileName: cstring): int32 {.
stdcall, dynlib: "kernel32",
stdcall, dynlib: "kernel32",
importc: "GetFileAttributesA".}
proc setFileAttributesA*(lpFileName: cstring,
proc setFileAttributesA*(lpFileName: cstring,
dwFileAttributes: int32): WINBOOL {.
stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".}
@@ -324,10 +326,10 @@ else:
proc getCommandLineA*(): cstring {.
importc: "GetCommandLineA", stdcall, dynlib: "kernel32".}
proc rdFileTime*(f: TFILETIME): int64 =
proc rdFileTime*(f: TFILETIME): int64 =
result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32)
proc rdFileSize*(f: TWIN32_FIND_DATA): int64 =
proc rdFileSize*(f: TWIN32_FIND_DATA): int64 =
result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32)
proc getSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var TFILETIME) {.
@@ -347,7 +349,7 @@ else:
lpParameters, lpDirectory: cstring,
nShowCmd: int32): THandle{.
stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".}
proc getFileInformationByHandle*(hFile: THandle,
lpFileInformation: ptr TBY_HANDLE_FILE_INFORMATION): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "GetFileInformationByHandle".}
@@ -357,12 +359,12 @@ const
WSASYS_STATUS_LEN* = 128
FD_SETSIZE* = 64
MSG_PEEK* = 2
INADDR_ANY* = 0
INADDR_LOOPBACK* = 0x7F000001
INADDR_BROADCAST* = -1
INADDR_NONE* = -1
ws2dll = "Ws2_32.dll"
WSAEWOULDBLOCK* = 10035
@@ -376,31 +378,31 @@ type
{.deprecated: [TSocketHandle: SocketHandle].}
type
WSAData* {.importc: "WSADATA", header: "winsock2.h".} = object
WSAData* {.importc: "WSADATA", header: "winsock2.h".} = object
wVersion, wHighVersion: int16
szDescription: array[0..WSADESCRIPTION_LEN, char]
szSystemStatus: array[0..WSASYS_STATUS_LEN, char]
iMaxSockets, iMaxUdpDg: int16
lpVendorInfo: cstring
SockAddr* {.importc: "SOCKADDR", header: "winsock2.h".} = object
SockAddr* {.importc: "SOCKADDR", header: "winsock2.h".} = object
sa_family*: int16 # unsigned
sa_data: array[0..13, char]
InAddr* {.importc: "IN_ADDR", header: "winsock2.h".} = object
s_addr*: int32 # IP address
Sockaddr_in* {.importc: "SOCKADDR_IN",
Sockaddr_in* {.importc: "SOCKADDR_IN",
header: "winsock2.h".} = object
sin_family*: int16
sin_port*: int16 # unsigned
sin_addr*: InAddr
sin_zero*: array[0..7, char]
In6_addr* {.importc: "IN6_ADDR", header: "winsock2.h".} = object
In6_addr* {.importc: "IN6_ADDR", header: "winsock2.h".} = object
bytes*: array[0..15, char]
Sockaddr_in6* {.importc: "SOCKADDR_IN6",
Sockaddr_in6* {.importc: "SOCKADDR_IN6",
header: "winsock2.h".} = object
sin6_family*: int16
sin6_port*: int16 # unsigned
@@ -430,23 +432,23 @@ type
h_addrtype*: int16
h_length*: int16
h_addr_list*: cstringArray
TFdSet* = object
fd_count*: cint # unsigned
fd_array*: array[0..FD_SETSIZE-1, SocketHandle]
Timeval* = object
tv_sec*, tv_usec*: int32
AddrInfo* = object
ai_flags*: cint ## Input flags.
ai_family*: cint ## Address family of socket.
ai_socktype*: cint ## Socket type.
ai_protocol*: cint ## Protocol of socket.
ai_addrlen*: int ## Length of socket address.
ai_flags*: cint ## Input flags.
ai_family*: cint ## Address family of socket.
ai_socktype*: cint ## Socket type.
ai_protocol*: cint ## Protocol of socket.
ai_addrlen*: int ## Length of socket address.
ai_canonname*: cstring ## Canonical name of service location.
ai_addr*: ptr SockAddr ## Socket address of socket.
ai_next*: ptr AddrInfo ## Pointer to next in list.
ai_addr*: ptr SockAddr ## Socket address of socket.
ai_next*: ptr AddrInfo ## Pointer to next in list.
SockLen* = cuint
@@ -501,7 +503,7 @@ proc bindSocket*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
stdcall, importc: "bind", dynlib: ws2dll.}
proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
stdcall, importc: "connect", dynlib: ws2dll.}
proc getsockname*(s: SocketHandle, name: ptr SockAddr,
proc getsockname*(s: SocketHandle, name: ptr SockAddr,
namelen: ptr SockLen): cint {.
stdcall, importc: "getsockname", dynlib: ws2dll.}
proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
@@ -515,7 +517,7 @@ proc listen*(s: SocketHandle, backlog: cint): cint {.
stdcall, importc: "listen", dynlib: ws2dll.}
proc recv*(s: SocketHandle, buf: pointer, len, flags: cint): cint {.
stdcall, importc: "recv", dynlib: ws2dll.}
proc recvfrom*(s: SocketHandle, buf: cstring, len, flags: cint,
proc recvfrom*(s: SocketHandle, buf: cstring, len, flags: cint,
fromm: ptr SockAddr, fromlen: ptr SockLen): cint {.
stdcall, importc: "recvfrom", dynlib: ws2dll.}
proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet,
@@ -529,22 +531,22 @@ proc sendto*(s: SocketHandle, buf: pointer, len, flags: cint,
proc shutdown*(s: SocketHandle, how: cint): cint {.
stdcall, importc: "shutdown", dynlib: ws2dll.}
proc getnameinfo*(a1: ptr SockAddr, a2: SockLen,
a3: cstring, a4: SockLen, a5: cstring,
a6: SockLen, a7: cint): cint {.
stdcall, importc: "getnameinfo", dynlib: ws2dll.}
proc inet_addr*(cp: cstring): int32 {.
stdcall, importc: "inet_addr", dynlib: ws2dll.}
stdcall, importc: "inet_addr", dynlib: ws2dll.}
proc WSAFDIsSet(s: SocketHandle, set: var TFdSet): bool {.
stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll, noSideEffect.}
proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint =
proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint =
result = if WSAFDIsSet(socket, set): 1'i32 else: 0'i32
proc FD_SET*(socket: SocketHandle, s: var TFdSet) =
proc FD_SET*(socket: SocketHandle, s: var TFdSet) =
if s.fd_count < FD_SETSIZE:
s.fd_array[int(s.fd_count)] = socket
inc(s.fd_count)
@@ -575,8 +577,8 @@ type
proc waitForMultipleObjects*(nCount: DWORD, lpHandles: PWOHandleArray,
bWaitAll: WINBOOL, dwMilliseconds: DWORD): DWORD{.
stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".}
# for memfiles.nim:
const
@@ -586,7 +588,7 @@ const
FILE_SHARE_READ* = 1'i32
FILE_SHARE_DELETE* = 4'i32
FILE_SHARE_WRITE* = 2'i32
CREATE_ALWAYS* = 2'i32
CREATE_NEW* = 1'i32
OPEN_EXISTING* = 3'i32
@@ -628,7 +630,7 @@ proc setEndOfFile*(hFile: THandle): WINBOOL {.stdcall, dynlib: "kernel32",
importc: "SetEndOfFile".}
proc setFilePointer*(hFile: THandle, lDistanceToMove: LONG,
lpDistanceToMoveHigh: ptr LONG,
lpDistanceToMoveHigh: ptr LONG,
dwMoveMethod: DWORD): DWORD {.
stdcall, dynlib: "kernel32", importc: "SetFilePointer".}
@@ -637,14 +639,14 @@ proc getFileSize*(hFile: THandle, lpFileSizeHigh: ptr DWORD): DWORD{.stdcall,
proc mapViewOfFileEx*(hFileMappingObject: THandle, dwDesiredAccess: DWORD,
dwFileOffsetHigh, dwFileOffsetLow: DWORD,
dwNumberOfBytesToMap: DWORD,
dwNumberOfBytesToMap: DWORD,
lpBaseAddress: pointer): pointer{.
stdcall, dynlib: "kernel32", importc: "MapViewOfFileEx".}
proc createFileMappingW*(hFile: THandle,
lpFileMappingAttributes: pointer,
flProtect, dwMaximumSizeHigh: DWORD,
dwMaximumSizeLow: DWORD,
dwMaximumSizeLow: DWORD,
lpName: pointer): THandle {.
stdcall, dynlib: "kernel32", importc: "CreateFileMappingW".}
@@ -702,7 +704,7 @@ proc getOverlappedResult*(hFile: THandle, lpOverlapped: TOVERLAPPED,
lpNumberOfBytesTransferred: var DWORD, bWait: WINBOOL): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "GetOverlappedResult".}
const
const
IOC_OUT* = 0x40000000
IOC_IN* = 0x80000000
IOC_WS2* = 0x08000000
@@ -725,7 +727,7 @@ var
proc WSAIoctl*(s: SocketHandle, dwIoControlCode: DWORD, lpvInBuffer: pointer,
cbInBuffer: DWORD, lpvOutBuffer: pointer, cbOutBuffer: DWORD,
lpcbBytesReturned: PDWORD, lpOverlapped: POVERLAPPED,
lpCompletionRoutine: POVERLAPPED_COMPLETION_ROUTINE): cint
lpCompletionRoutine: POVERLAPPED_COMPLETION_ROUTINE): cint
{.stdcall, importc: "WSAIoctl", dynlib: "Ws2_32.dll".}
type
@@ -746,7 +748,7 @@ proc WSASend*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD,
proc get_osfhandle*(fd:FileHandle): THandle {.
importc: "_get_osfhandle", header:"<io.h>".}
proc getSystemTimes*(lpIdleTime, lpKernelTime,
proc getSystemTimes*(lpIdleTime, lpKernelTime,
lpUserTime: var TFILETIME): WINBOOL {.stdcall,
dynlib: "kernel32", importc: "GetSystemTimes".}

View File

@@ -0,0 +1,19 @@
discard """
output: "And we get here"
"""
# bug #2625
const s_len = 32
import tables
var substr_counts: CountTable[string] = initCountTable[string]()
var my_string = "Hello, this is sadly broken for strings over 64 characters. Note that it *does* appear to work for short strings."
for i in 0..(my_string.len - s_len):
let s = my_string[i..i+s_len-1]
substr_counts[s] = 1
# substr_counts[s] = substr_counts[s] + 1 # Also breaks, + 2 as well, etc.
# substr_counts.inc(s) # This works
#echo "Iteration ", i
echo "And we get here"

View File

@@ -0,0 +1,20 @@
# bug #2641
type MyChar = distinct char
const c:MyChar = MyChar('a')
type MyBool = distinct bool
const b:MyBool = MyBool(true)
type MyBoolSet = distinct set[bool]
const bs:MyBoolSet = MyBoolSet({true})
type MyCharSet= distinct set[char]
const cs:MyCharSet = MyCharSet({'a'})
type MyBoolSeq = distinct seq[bool]
const bseq:MyBoolSeq = MyBoolSeq(@[true, false])
type MyBoolArr = distinct array[3, bool]
const barr:MyBoolArr = MyBoolArr([true, false, true])

View File

@@ -0,0 +1,14 @@
# bug #2629
import sequtils, os
template glob_rst(basedir: string = nil): expr =
if baseDir.isNil:
to_seq(walk_files("*.rst"))
else:
to_seq(walk_files(basedir/"*.rst"))
let
rst_files = concat(glob_rst(), glob_rst("docs"))
when isMainModule: echo rst_files

View File

@@ -0,0 +1,46 @@
discard """
output: '''it's nil
@[1, 2, 3]'''
"""
template foo(s: string = nil) =
if isNil(s):
echo "it's nil"
else:
echo s
foo
# bug #2632
proc takeTup(x: tuple[s: string;x: seq[int]]) =
discard
takeTup(("foo", @[]))
#proc foobar(): () =
proc f(xs: seq[int]) =
discard
proc g(t: tuple[n:int, xs:seq[int]]) =
discard
when isMainModule:
f(@[]) # OK
g((1,@[1])) # OK
g((0,@[])) # NG
# bug #2630
type T = tuple[a: seq[int], b: int]
var t: T = (@[1,2,3], 7)
proc test(s: seq[int]): T =
echo s
(s, 7)
t = test(t.a)

View File

@@ -1,14 +1,14 @@
version 0.10.4
version 0.11.2
==============
version 0.10.6 (RC1?)
=====================
- The remaining bugs of the lambda lifting pass that is responsible to enable
closures and closure iterators need to be fixed.
- ``concept`` needs to be refined, a nice name for the feature is not enough.
- Destructors need to be refined.
- make '--implicitStatic:on' the default; then we can also clean up the
'static[T]' mess in the compiler!
- finish 'parallel' or mark as experimental
- Finish the implementation of the 'parallel' statement.
- Deprecate ``immediate`` for templates and macros
- special case varargs[untyped] and varargs[typed]
- make 'nil' work for 'add':

View File

@@ -125,8 +125,8 @@ pre .end { background:url("images/tabEnd.png") no-repeat left bottom; }
opacity 1s ease-in-out; }
#slideshow > div.active { visibility:visible; opacity:1; transition-delay:0s; }
#slideshow > div.init { transition-delay:0s; }
#slideshow-nav { z-index:3; position:absolute; top:110px;; right:-12px; }
#slideshow-nav > div { margin:5px 0; width:23px; height:23px; background:url("images/slideshow-nav.png") no-repeat; }
#slideshow-nav { z-index:3; position:absolute; top:341px; left:18px; }
#slideshow-nav > div { display:inline-block; margin:5px 0; width:23px; height:23px; background:url("images/slideshow-nav.png") no-repeat; }
#slideshow-nav > div:hover { background-image:url("images/slideshow-nav_active.png"); opacity:0.5; }
#slideshow-nav > div.active { background-image:url("images/slideshow-nav_active.png"); opacity:1; }

View File

@@ -8,13 +8,13 @@ Nim's Documentation
.. container:: libraries
- | `Standard Library <0.11.0/lib.html>`_
- | `Standard Library <docs/lib.html>`_
| This document describes Nim's standard library.
- | `Language Manual <0.11.0/manual.html>`_
- | `Language Manual <docs/manual.html>`_
| The Nim manual is a draft that will evolve into a proper specification.
- | `Compiler User Guide <0.11.0/nimc.html>`_
- | `Compiler User Guide <docs/nimc.html>`_
| The user guide lists command line arguments, special features of the
compiler, etc.
@@ -26,11 +26,11 @@ Nim's Documentation
.. container:: tools
- | `Source Code Filters <0.11.0/filters.html>`_
- | `Source Code Filters <docs/filters.html>`_
| The Nim compiler supports source code filters as a simple yet powerful
builtin templating system.
- | `Tools Documentation <0.11.0/tools.html>`_
- | `Tools Documentation <docs/tools.html>`_
| Description of some tools that come with the standard distribution.
@@ -41,11 +41,11 @@ Nim's Documentation
.. container:: internals
- | `Garbage Collector <0.11.0/gc.html>`_
- | `Garbage Collector <docs/gc.html>`_
| Additional documentation about Nim's GC and how to operate it in a
realtime setting.
- | `Internal Documentation <0.11.0/intern.html>`_
- | `Internal Documentation <docs/intern.html>`_
| The internal documentation describes how the compiler is implemented.
Read this if you want to hack the compiler.
@@ -53,5 +53,5 @@ Nim's Documentation
Search Options
--------------
`Documentation Index <0.11.0/theindex.html>`_ - The generated
`Documentation Index <docs/theindex.html>`_ - The generated
index. **Index + (Ctrl+F) == Joy**

View File

@@ -13,8 +13,8 @@ Binaries
--------
Unfortunately for now we only provide builds for Windows.
* 32 bit: `nim-0.11.0_x32.exe <download/nim-0.11.0_x32.exe>`_
* 64 bit: `nim-0.11.0_x64.exe <download/nim-0.11.0_x64.exe>`_
* 32 bit: `nim-0.11.2_x32.exe <download/nim-0.11.2_x32.exe>`_
* 64 bit: `nim-0.11.2_x64.exe <download/nim-0.11.2_x64.exe>`_
Installation based on generated C code
@@ -26,8 +26,8 @@ like systems. Binary packages may be provided later.
Download one of these:
* `nim-0.11.0.zip (28 MB) <download/nim-0.11.0.zip>`_
* `nim-0.11.0.tar.xz (2.6MB) <download/nim-0.11.0.tar.xz>`_
* `nim-0.11.2.zip (28 MB) <download/nim-0.11.2.zip>`_
* `nim-0.11.2.tar.xz (2.6MB) <download/nim-0.11.2.tar.xz>`_
Extract the file and follow these instructions:

View File

@@ -8,10 +8,10 @@ Learning Nim
.. container:: tutorials
- | `Tutorial (part I) <0.11.0/tut1.html>`_
- | `Tutorial (part I) <docs/tut1.html>`_
| Learn the basics of Nim's types, variables, procedures, control flow, etc...
- | `Tutorial (part II) <0.11.0/tut2.html>`_
- | `Tutorial (part II) <docs/tut2.html>`_
| Learn Nim's more advanced features such as OOP, generics, macros, etc...
@@ -52,5 +52,5 @@ Learning Nim
Documentation
-------------
More examples of Nim code can be found in the `Nim Language Documentation <0.11.0/manual.html>`_.
More examples of Nim code can be found in the `Nim Language Documentation <docs/manual.html>`_.

View File

@@ -2,6 +2,31 @@
News
====
..
2015-05-05 Version 0.11.2 released
==================================
Changes affecting backwards compatibility
-----------------------------------------
Language Additions
------------------
Bugfixes
--------
2015-05-04 Version 0.11.2 released
==================================
This is just a bugfix release that fixes the most pressing regressions we
introduced with version 0.11.0. The way types are computed was
changed significantly causing all sort of problems. Sorry for the
inconvenience; we grew overconfident our large test suite would prevent these
things.
2015-04-30 Version 0.11.0 released
==================================

View File

@@ -1,6 +1,6 @@
<a class="news" href="news.html#Z2015-04-30-version-0-11-0-released">
<h4>Apr 30, 2015</h4>
<p>Nim version 0.11.0 has been released!</p>
<a class="news" href="news.html#Z2015-05-04-version-0-11-2-released">
<h4>May 4, 2015</h4>
<p>Nim version 0.11.2 has been released!</p>
</a>
<a class="news" href="news.html#Z2014-12-29-version-0-10-2-released">