diff options
-rw-r--r-- | compiler/installer.ini | 101 | ||||
-rw-r--r-- | compiler/nimsuggest/nimsuggest.nim | 11 | ||||
-rw-r--r-- | compiler/types.nim | 2 | ||||
-rw-r--r-- | doc/lib.txt | 47 | ||||
-rw-r--r-- | doc/nimsuggest.txt | 174 | ||||
-rw-r--r-- | doc/tools.txt | 5 | ||||
-rw-r--r-- | koch.nim | 27 | ||||
-rw-r--r-- | lib/system.nim | 4 | ||||
-rw-r--r-- | tests/tuples/tuple_with_nil.nim | 766 | ||||
-rw-r--r-- | tools/niminst/niminst.nim | 68 | ||||
-rw-r--r-- | tools/niminst/nsis.tmpl | 18 | ||||
-rw-r--r-- | web/documentation.txt | 21 | ||||
-rw-r--r-- | web/download.txt | 12 | ||||
-rw-r--r-- | web/learn.txt | 6 | ||||
-rw-r--r-- | web/news.txt | 734 | ||||
-rw-r--r-- | web/ticker.txt | 10 | ||||
-rw-r--r-- | web/website.ini | 6 |
17 files changed, 1570 insertions, 442 deletions
diff --git a/compiler/installer.ini b/compiler/installer.ini index 12a8e702d..4ee50f2ff 100644 --- a/compiler/installer.ini +++ b/compiler/installer.ini @@ -126,12 +126,109 @@ Files: "examples/*.txt" Files: "examples/*.cfg" Files: "examples/*.tmpl" +Files: "tests/actiontable/*.nim" +Files: "tests/alias/*.nim" +Files: "tests/ambsym/*.nim" +Files: "tests/array/*.nim" +Files: "tests/assign/*.nim" +Files: "tests/astoverload/*.nim" +Files: "tests/async/*.nim" +Files: "tests/benchmarks/*.nim" +Files: "tests/bind/*.nim" +Files: "tests/borrow/*.nim" +Files: "tests/casestmt/*.nim" +Files: "tests/ccgbugs/*.nim" +Files: "tests/clearmsg/*.nim" +Files: "tests/closure/*.nim" +Files: "tests/cnstseq/*.nim" +Files: "tests/collections/*.nim" +Files: "tests/compiles/*.nim" +Files: "tests/concat/*.nim" +Files: "tests/concepts/*.nim" +Files: "tests/constr/*.nim" +Files: "tests/constraints/*.nim" +Files: "tests/controlflow/*.nim" +Files: "tests/converter/*.nim" +Files: "tests/cpp/*.nim" +Files: "tests/defaultprocparam/*.nim" +Files: "tests/deprecated/*.nim" +Files: "tests/destructor/*.nim" +Files: "tests/dir with space/*.nim" +Files: "tests/discard/*.nim" +Files: "tests/distinct/*.nim" +Files: "tests/dll/*.nim" +Files: "tests/effects/*.nim" +Files: "tests/enum/*.nim" +Files: "tests/exception/*.nim" +Files: "tests/exprs/*.nim" +Files: "tests/fields/*.nim" +Files: "tests/float/*.nim" +Files: "tests/friends/*.nim" +Files: "tests/gc/*.nim" +Files: "tests/generics/*.nim" +Files: "tests/gensym/*.nim" +Files: "tests/global/*.nim" +Files: "tests/implicit/*.nim" +Files: "tests/init/*.nim" +Files: "tests/iter/*.nim" +Files: "tests/js/*.nim" +Files: "tests/js/*.cfg" +Files: "tests/let/*.nim" +Files: "tests/lexer/*.nim" +Files: "tests/lookups/*.nim" +Files: "tests/macros/*.nim" +Files: "tests/magics/*.nim" +Files: "tests/metatype/*.nim" +Files: "tests/method/*.nim" +Files: "tests/misc/*.nim" +Files: "tests/modules/*.nim" +Files: "tests/namedparams/*.nim" +Files: "tests/notnil/*.nim" +Files: "tests/objects/*.nim" +Files: "tests/objvariant/*.nim" +Files: "tests/openarray/*.nim" +Files: "tests/osproc/*.nim" +Files: "tests/overflw/*.nim" +Files: "tests/overload/*.nim" +Files: "tests/parallel/*.nim" +Files: "tests/parallel/*.cfg" +Files: "tests/parser/*.nim" +Files: "tests/pragmas/*.nim" +Files: "tests/proc/*.nim" +Files: "tests/procvar/*.nim" +Files: "tests/range/*.nim" +Files: "tests/rodfiles/*.nim" +Files: "tests/seq/*.nim" +Files: "tests/sets/*.nim" +Files: "tests/showoff/*.nim" +Files: "tests/specialops/*.nim" +Files: "tests/stdlib/*.nim" +Files: "tests/system/*.nim" +Files: "tests/template/*.nim" +Files: "tests/testament/*.nim" +Files: "tests/testdata/*.nim" +Files: "tests/threads/*.nim" +Files: "tests/threads/*.cfg" +Files: "tests/trmacros/*.nim" +Files: "tests/tuples/*.nim" +Files: "tests/typerel/*.nim" +Files: "tests/types/*.nim" +Files: "tests/usingstmt/*.nim" +Files: "tests/varres/*.nim" +Files: "tests/varstmt/*.nim" +Files: "tests/vm/*.nim" +Files: "tests/readme.txt" +Files: "tests/testament/css/*.css" +Files: "tests/testament/*.cfg" +Files: "lib/pure/unidecode/unidecode.dat" [Windows] Files: "bin/nim.exe" -Files: "bin/nim_debug.exe" Files: "bin/c2nim.exe" Files: "bin/nimgrep.exe" +Files: "bin/nimsuggest.exe" +Files: "bin/nimble.exe" +Files: "bin/*.dll" Files: "dist/*.dll" Files: "koch.exe" @@ -142,7 +239,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.1.3.zip|aporia\bin\aporia.exe" +Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.3.0.zip|aporia\bin\aporia.exe" ; for now only NSIS supports optional downloads [UnixBin] diff --git a/compiler/nimsuggest/nimsuggest.nim b/compiler/nimsuggest/nimsuggest.nim index b45ca475c..8285d81d9 100644 --- a/compiler/nimsuggest/nimsuggest.nim +++ b/compiler/nimsuggest/nimsuggest.nim @@ -82,7 +82,8 @@ proc action(cmd: string) = if cmd[i] == ';': i = parseQuoted(cmd, dirtyfile, i+1) i += skipWhile(cmd, seps, i) - var line, col = -1 + var line = -1 + var col = 0 i += parseInt(cmd, line, i) i += skipWhile(cmd, seps, i) i += parseInt(cmd, col, i) @@ -97,7 +98,7 @@ proc action(cmd: string) = resetModule dirtyIdx if dirtyIdx != gProjectMainIdx: resetModule gProjectMainIdx - gTrackPos = newLineInfo(dirtyIdx, line, col) + gTrackPos = newLineInfo(dirtyIdx, line, col-1) #echo dirtyfile, gDirtyBufferIdx, " project ", gProjectMainIdx gErrorCounter = 0 if not isKnownFile: @@ -150,11 +151,11 @@ proc mainCommand = proc processCmdLine*(pass: TCmdLinePass, cmd: string) = var p = parseopt.initOptParser(cmd) - while true: + while true: parseopt.next(p) case p.kind - of cmdEnd: break - of cmdLongoption, cmdShortOption: + of cmdEnd: break + of cmdLongoption, cmdShortOption: case p.key.normalize of "port": gPort = parseInt(p.val).Port of "address": gAddress = p.val diff --git a/compiler/types.nim b/compiler/types.nim index 1b30afc76..e205f5722 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1460,7 +1460,7 @@ proc takeType*(formal, arg: PType): PType = let a = copyType(arg.skipTypes({tyGenericInst}), arg.owner, keepId=false) a.sons[ord(arg.kind in {tyArray, tyArrayConstr})] = formal.sons[0] result = a - elif formal.kind == tySet and arg.kind == tySet: + elif formal.kind in {tyTuple, tySet} and arg.kind == formal.kind: result = formal else: result = arg diff --git a/doc/lib.txt b/doc/lib.txt index 385e7a91a..1c0278068 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -37,7 +37,7 @@ Core * `unsigned <unsigned.html>`_ This module implements basic arithmetic operators for unsigned integers. - To discourage users from using unsigned integers, it's not part + To discourage users from using unsigned integers, it's not part of ``system``, but an extra import. * `threads <threads.html>`_ @@ -45,7 +45,7 @@ Core import it explicitly. * `channels <channels.html>`_ - Nim message passing support for threads. **Note**: This is part of the + Nim message passing support for threads. **Note**: This is part of the system module. Do not import it explicitly. * `locks <locks.html>`_ @@ -55,7 +55,7 @@ Core Contains the AST API and documentation of Nim for writing macros. * `typeinfo <typeinfo.html>`_ - Provides (unsafe) access to Nim's run time type information. + Provides (unsafe) access to Nim's run time type information. * `typetraits <typetraits.html>`_ This module defines compile-time reflection procs for working with types. @@ -110,9 +110,9 @@ String handling * `unicode <unicode.html>`_ This module provides support to handle the Unicode UTF-8 encoding. - + * `encodings <encodings.html>`_ - Converts between different character encodings. On UNIX, this uses + Converts between different character encodings. On UNIX, this uses the ``iconv`` library, on Windows the Windows API. * `pegs <pegs.html>`_ @@ -159,7 +159,7 @@ Generic Operating System Services may provide other implementations for this standard stream interface. * `marshal <marshal.html>`_ - Contains procs for serialization and deseralization of arbitrary Nim + Contains procs for serialization and deseralization of arbitrary Nim data structures. * `terminal <terminal.html>`_ @@ -168,7 +168,7 @@ Generic Operating System Services sequences and does not depend on any other module. * `memfiles <memfiles.html>`_ - This module provides support for memory mapped files (Posix's ``mmap``) + This module provides support for memory mapped files (Posix's ``mmap``) on the different operating systems. * `fsmonitor <fsmonitor.html>`_ @@ -228,7 +228,7 @@ Internet Protocols and Support This module implements a simple HTTP client. * `smtp <smtp.html>`_ - This module implement a simple SMTP client. + This module implement a simple SMTP client. * `ftpclient <ftpclient.html>`_ This module implements an FTP client. @@ -346,7 +346,7 @@ XML Processing This module parses an HTML document and creates its XML tree representation. * `htmlgen <htmlgen.html>`_ - This module implements a simple XML and HTML code + This module implements a simple XML and HTML code generator. Each commonly used HTML tag has a corresponding macro that generates a string with its HTML representation. @@ -381,7 +381,7 @@ Miscellaneous * `oids <oids.html>`_ An OID is a global ID that consists of a timestamp, - a unique counter and a random value. This combination should suffice to + a unique counter and a random value. This combination should suffice to produce a globally distributed unique ID. This implementation was extracted from the Mongodb interface and it thus binary compatible with a Mongo OID. @@ -453,12 +453,8 @@ Other * `zipfiles <zipfiles.html>`_ This module implements a zip archive creator/reader/modifier. -* `web <web.html>`_ - This module contains simple high-level procedures for dealing with the - Web like loading the contents of a Web page from an URL. - * `ssl <ssl.html>`_ - This module provides an easy to use sockets-style + This module provides an easy to use sockets-style Nim interface to the OpenSSL library. * `rdstdin <rdstdin.html>`_ @@ -513,25 +509,6 @@ Regular expressions Wrapper for the TRE library. -Graphics libraries ------------------- - -* `sdl <sdl.html>`_ - Part of the wrapper for SDL. -* `sdl_gfx <sdl_gfx.html>`_ - Part of the wrapper for SDL. -* `sdl_image <sdl_image.html>`_ - Part of the wrapper for SDL. -* `sdl_mixer <sdl_mixer.html>`_ - Part of the wrapper for SDL. -* `sdl_net <sdl_net.html>`_ - Part of the wrapper for SDL. -* `sdl_ttf <sdl_ttf.html>`_ - Part of the wrapper for SDL. -* `smpeg <smpeg.html>`_ - Part of the wrapper for SDL. - - GUI libraries ------------- @@ -591,7 +568,7 @@ Data Compression and Archiving Scientific computing -------------------- -* `libsvm <libsvm.html>`_ +* `libsvm <libsvm.html>`_ Low level wrapper for `lib svm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/>`_. Nimble diff --git a/doc/nimsuggest.txt b/doc/nimsuggest.txt new file mode 100644 index 000000000..2b52196b9 --- /dev/null +++ b/doc/nimsuggest.txt @@ -0,0 +1,174 @@ +================================ + Nim IDE Integration Guide +================================ + +:Author: Unknown +:Version: |nimversion| + +.. contents:: + + +Nim differs from many other compilers in that it is really fast, +and being so fast makes it suited to provide external queries for +text editors about the source code being written. Through the +``nimsuggest`` tool, any IDE +can query a ``.nim`` source file and obtain useful information like +definition of symbols or suggestions for completion. + +This document will guide you through the available options. If you +want to look at practical examples of nimsuggest support you can look +at the +`various editor integrations <https://github.com/Araq/Nim/wiki/Editor-Support>`_ +already available. + + +Installation +============ + +Nimsuggest is available as a Nimble package but currently does not install +properly via Nimble. As nimsuggest is part of the compiler it also doesn't make +too much sense as a Nimble package. Instead we will do the building manually:: + + cd compiler/nimsuggest + nim c -d:release nimsuggest + cp nimsuggest ../../bin + # OR: copy the nimsuggest binary to where your 'nim' binary is + cd ../.. + + + +Nimsuggest invocation +===================== + +Run it via ``nimsuggest --stdin myproject.nim``. Nimsuggest is a server that +takes queries that are related to ``myproject``. There is some support so that +you can throw random ``.nim`` files which are not part of ``myproject`` at +Nimsuggest too, but usually the query refer to modules/files that are part of +``myproject``. + +``--stdin`` means that Nimsuggest reads the query from ``stdin``. This is great +for testing things out and playing with it but for an editor communication +via sockets is more reasonable so that is the default. It listens to port 6000 +by default. + + +Specifying the location of the query +------------------------------------ + +Nimsuggest than waits for queries to process. A query consists of a +cryptic 3 letter "command" ``def`` or ``con`` or ``sug`` or ``use`` followed by +a location. A query location consists of: + + +``file.nim`` + This is the name of the module or include file the query refers to. + +``dirtyfile.nim`` + This is optional. + + The ``file`` paramater is enough for static analysis, but IDEs + tend to have *unsaved buffers* where the user may still be in + the middle of typing a line. In such situations the IDE can + save the current contents to a temporary file and then use the + ``dirtyfile.nim`` option to tell Nimsuggest that ``foobar.nim`` should + be taken from ``temporary/foobar.nim``. + + +``line`` + An integer with the line you are going to query. For the compiler + lines start at **1**. + +``col`` + An integer with the column you are going to query. For the + compiler columns start at **1**. + + +Definitions +----------- + +The ``def`` Nimsuggest command performs a query about the definition +of a specific symbol. If available, Nimsuggest will answer with the +type, source file, line/column information and other accessory data +if available like a docstring. With this information an IDE can +provide the typical *Jump to definition* where a user puts the +cursor on a symbol or uses the mouse to select it and is redirected +to the place where the symbol is located. + +Since Nim is implemented in Nim, one of the nice things of +this feature is that any user with an IDE supporting it can quickly +jump around the standard library implementation and see exactly +what a proc does, learning about the language and seeing real life +examples of how to write/implement specific features. + +Nimsuggest will always answer with a single definition or none if it +can't find any valid symbol matching the position of the query. + + +Suggestions +----------- + +The ``sug`` Nimsuggest command performs a query about possible +completion symbols at some point in the file. + +The typical usage scenario for this option is to call it after the +user has typed the dot character for `the object oriented call +syntax <tut2.html#method-call-syntax>`_. Nimsuggest will try to return +the suggestions sorted first by scope (from innermost to outermost) +and then by item name. + + +Invocation context +------------------ + +The ``con`` Nimsuggest command is very similar to the suggestions +command, but instead of being used after the user has typed a dot +character, this one is meant to be used after the user has typed +an opening brace to start typing parameters. + + +Symbol usages +------------- + +The ``use`` Nimsuggest command lists all usages of the symbol at +a position. IDEs can use this to find all the places in the file +where the symbol is used and offer the user to rename it in all +places at the same time. + +For this kind of query the IDE will most likely ignore all the +type/signature info provided by Nimsuggest and concentrate on the +filename, line and column position of the multiple returned answers. + + + +Parsing nimsuggest output +========================= + +Nimsuggest output is always returned on single lines separated by +tab characters (``\t``). The values of each column are: + +1. Three characters indicating the type of returned answer (e.g. + ``def`` for definition, ``sug`` for suggestion, etc). +2. Type of the symbol. This can be ``skProc``, ``skLet``, and just + about any of the enums defined in the module ``compiler/ast.nim``. +3. Full qualitifed path of the symbol. If you are querying a symbol + defined in the ``proj.nim`` file, this would have the form + ``proj.symbolName``. +4. Type/signature. For variables and enums this will contain the + type of the symbol, for procs, methods and templates this will + contain the full unique signature (e.g. ``proc (File)``). +5. Full path to the file containing the symbol. +6. Line where the symbol is located in the file. Lines start to + count at **1**. +7. Column where the symbol is located in the file. Columns start + to count at **1**. +8. Docstring for the symbol if available or the empty string. To + differentiate the docstring from end of answer, + the docstring is always provided enclosed in double quotes, and + if the docstring spans multiple lines, all following lines of the + docstring will start with a blank space to align visually with + the starting quote. + + Also, you won't find raw ``\n`` characters breaking the one + answer per line format. Instead you will need to parse sequences + in the form ``\xHH``, where *HH* is a hexadecimal value (e.g. + newlines generate the sequence ``\x0A``). diff --git a/doc/tools.txt b/doc/tools.txt index 7f2830879..b0a45c575 100644 --- a/doc/tools.txt +++ b/doc/tools.txt @@ -4,6 +4,11 @@ Tools available with Nim The standard distribution ships with the following tools: +- | `Nimsuggest for IDE support <nimsuggest.html>`_ + | Through the ``nimsuggest`` tool, any IDE can query a ``.nim`` source file + and obtain useful information like definition of symbols or suggestions for + completion. + - | `Nim Installation Generator <niminst.html>`_ | How to generate a nice installer for your Nim program. diff --git a/koch.nim b/koch.nim index 3ebfb6655..55019b544 100644 --- a/koch.nim +++ b/koch.nim @@ -106,6 +106,12 @@ proc zip(args: string) = exec("$# --var:version=$# --var:mingw=none --main:compiler/nim.nim zip compiler/installer.ini" % ["tools/niminst/niminst".exe, VersionAsString]) +proc targz(args: string) = + exec("$3 cc -r $2 --var:version=$1 --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" % + [VersionAsString, compileNimInst, findNim()]) + exec("$# --var:version=$# --var:mingw=none --main:compiler/nim.nim targz compiler/installer.ini" % + ["tools" / "niminst" / "niminst".exe, VersionAsString]) + proc buildTool(toolname, args: string) = exec("$# cc $# $#" % [findNim(), args, toolname]) copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe) @@ -113,12 +119,12 @@ proc buildTool(toolname, args: string) = proc nsis(args: string) = # make sure we have generated the niminst executables: buildTool("tools/niminst/niminst", args) - buildTool("tools/nimgrep", args) + #buildTool("tools/nimgrep", args) # produce 'nim_debug.exe': - exec "nim c compiler" / "nim.nim" - copyExe("compiler/nim".exe, "bin/nim_debug".exe) + #exec "nim c compiler" / "nim.nim" + #copyExe("compiler/nim".exe, "bin/nim_debug".exe) exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" & - " nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)]) + " nsis compiler/installer.ini") % [VersionAsString, $(sizeof(pointer)*8)]) proc install(args: string) = exec("$# cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" % @@ -308,12 +314,14 @@ proc winRelease() = #buildTool("tools/niminst/niminst", " -d:release") buildTool("tools/nimgrep", " -d:release") buildTool("compiler/nimfix/nimfix", " -d:release") + buildTool("compiler/nimsuggest/nimsuggest", " -d:release") + + #run7z("win32", "bin/nim.exe", "bin/c2nim.exe", "bin/nimgrep.exe", + # "bin/nimfix.exe", + # "bin/nimble.exe", "bin/*.dll", + # "config", "dist/*.dll", "examples", "lib", + # "readme.txt", "contributors.txt", "copying.txt") - run7z("win32", "bin/nim.exe", "bin/c2nim.exe", "bin/nimgrep.exe", - "bin/nimfix.exe", - "bin/nimble.exe", "bin/*.dll", - "config", "dist/*.dll", "examples", "lib", - "readme.txt", "contributors.txt", "copying.txt") # second step: XXX build 64 bit version # -------------- tests -------------------------------------------------------- @@ -357,6 +365,7 @@ of cmdArgument: of "pdf": pdf() of "csource", "csources": csource(op.cmdLineRest) of "zip": zip(op.cmdLineRest) + of "targz": targz(op.cmdLineRest) of "nsis": nsis(op.cmdLineRest) of "install": install(op.cmdLineRest) of "test", "tests": tests(op.cmdLineRest) diff --git a/lib/system.nim b/lib/system.nim index 85f1350d7..33eee42f0 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1532,10 +1532,10 @@ const NimMajor*: int = 0 ## is the major number of Nim's version. - NimMinor*: int = 10 + NimMinor*: int = 11 ## is the minor number of Nim's version. - NimPatch*: int = 3 + NimPatch*: int = 0 ## is the patch number of Nim's version. NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim new file mode 100644 index 000000000..26e4ae85e --- /dev/null +++ b/tests/tuples/tuple_with_nil.nim @@ -0,0 +1,766 @@ +import macros +from strutils import IdentStartChars +import parseutils +import unicode +import math +import fenv +import unsigned +import pegs +import streams + +type + FormatError = object of Exception ## Error in the format string. + + Writer = concept W + ## Writer to output a character `c`. + when (NimMajor, NimMinor, NimPatch) > (0, 10, 2): + write(W, 'c') + else: + block: + var x: W + write(x, char) + + FmtAlign = enum ## Format alignment + faDefault ## default for given format type + faLeft ## left aligned + faRight ## right aligned + faCenter ## centered + faPadding ## right aligned, fill characters after sign (numbers only) + + FmtSign = enum ## Format sign + fsMinus ## only unary minus, no reservered sign space for positive numbers + fsPlus ## unary minus and unary plus + fsSpace ## unary minus and reserved space for positive numbers + + FmtType = enum ## Format type + ftDefault ## default format for given parameter type + ftStr ## string + ftChar ## character + ftDec ## decimal integer + ftBin ## binary integer + ftOct ## octal integer + ftHex ## hexadecimal integer + ftFix ## real number in fixed point notation + ftSci ## real number in scientific notation + ftGen ## real number in generic form (either fixed point or scientific) + ftPercent ## real number multiplied by 100 and % added + + Format = tuple ## Formatting information. + typ: FmtType ## format type + precision: int ## floating point precision + width: int ## minimal width + fill: string ## the fill character, UTF8 + align: FmtAlign ## aligment + sign: FmtSign ## sign notation + baseprefix: bool ## whether binary, octal, hex should be prefixed by 0b, 0x, 0o + upcase: bool ## upper case letters in hex or exponential formats + comma: bool ## + arysep: string ## separator for array elements + + PartKind = enum pkStr, pkFmt + + Part = object + ## Information of a part of the target string. + case kind: PartKind ## type of the part + of pkStr: + str: string ## literal string + of pkFmt: + arg: int ## position argument + fmt: string ## format string + field: string ## field of argument to be accessed + index: int ## array index of argument to be accessed + nested: bool ## true if the argument contains nested formats + +const + DefaultPrec = 6 ## Default precision for floating point numbers. + DefaultFmt: Format = (ftDefault, -1, -1, nil, faDefault, fsMinus, false, false, false, nil) + ## Default format corresponding to the empty format string, i.e. + ## `x.format("") == x.format(DefaultFmt)`. + round_nums = [0.5, 0.05, 0.005, 0.0005, 0.00005, 0.000005, 0.0000005, 0.00000005] + ## Rounding offset for floating point numbers up to precision 8. + +proc write(s: var string; c: char) = + s.add(c) + +proc has(c: Captures; i: range[0..pegs.MaxSubpatterns-1]): bool {.nosideeffect, inline.} = + ## Tests whether `c` contains a non-empty capture `i`. + let b = c.bounds(i) + result = b.first <= b.last + +proc get(str: string; c: Captures; i: range[0..MaxSubpatterns-1]; def: char): char {.nosideeffect, inline.} = + ## If capture `i` is non-empty return that portion of `str` casted + ## to `char`, otherwise return `def`. + result = if c.has(i): str[c.bounds(i).first] else: def + +proc get(str: string; c: Captures; i: range[0..MaxSubpatterns-1]; def: string; begoff: int = 0): string {.nosideeffect, inline.} = + ## If capture `i` is non-empty return that portion of `str` as + ## string, otherwise return `def`. + let b = c.bounds(i) + result = if c.has(i): str.substr(b.first + begoff, b.last) else: def + +proc get(str: string; c: Captures; i: range[0..MaxSubpatterns-1]; def: int; begoff: int = 0): int {.nosideeffect, inline.} = + ## If capture `i` is non-empty return that portion of `str` + ## converted to int, otherwise return `def`. + if c.has(i): + discard str.parseInt(result, c.bounds(i).first + begoff) + else: + result = def + +proc parse(fmt: string): Format {.nosideeffect.} = + # Converts the format string `fmt` into a `Format` structure. + let p = + sequence(capture(?sequence(anyRune(), &charSet({'<', '>', '=', '^'}))), + capture(?charSet({'<', '>', '=', '^'})), + capture(?charSet({'-', '+', ' '})), + capture(?charSet({'#'})), + capture(?(+digits())), + capture(?charSet({','})), + capture(?sequence(charSet({'.'}), +digits())), + capture(?charSet({'b', 'c', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 's', 'x', 'X', '%'})), + capture(?sequence(charSet({'a'}), *pegs.any()))) + # let p=peg"{(_&[<>=^])?}{[<>=^]?}{[-+ ]?}{[#]?}{[0-9]+?}{[,]?}{([.][0-9]+)?}{[bcdeEfFgGnosxX%]?}{(a.*)?}" + + var caps: Captures + if fmt.rawmatch(p, 0, caps) < 0: + raise newException(FormatError, "Invalid format string") + + result.fill = fmt.get(caps, 0, nil) + + case fmt.get(caps, 1, 0.char) + of '<': result.align = faLeft + of '>': result.align = faRight + of '^': result.align = faCenter + of '=': result.align = faPadding + else: result.align = faDefault + + case fmt.get(caps, 2, '-') + of '-': result.sign = fsMinus + of '+': result.sign = fsPlus + of ' ': result.sign = fsSpace + else: result.sign = fsMinus + + result.baseprefix = caps.has(3) + + result.width = fmt.get(caps, 4, -1) + + if caps.has(4) and fmt[caps.bounds(4).first] == '0': + if result.fill != nil: + raise newException(FormatError, "Leading 0 in with not allowed with explicit fill character") + if result.align != faDefault: + raise newException(FormatError, "Leading 0 in with not allowed with explicit alignment") + result.fill = "0" + result.align = faPadding + + result.comma = caps.has(5) + + result.precision = fmt.get(caps, 6, -1, 1) + + case fmt.get(caps, 7, 0.char) + of 's': result.typ = ftStr + of 'c': result.typ = ftChar + of 'd', 'n': result.typ = ftDec + of 'b': result.typ = ftBin + of 'o': result.typ = ftOct + of 'x': result.typ = ftHex + of 'X': result.typ = ftHex; result.upcase = true + of 'f', 'F': result.typ = ftFix + of 'e': result.typ = ftSci + of 'E': result.typ = ftSci; result.upcase = true + of 'g': result.typ = ftGen + of 'G': result.typ = ftGen; result.upcase = true + of '%': result.typ = ftPercent + else: result.typ = ftDefault + + result.arysep = fmt.get(caps, 8, nil, 1) + +proc getalign(fmt: Format; defalign: FmtAlign; slen: int) : tuple[left, right:int] {.nosideeffect.} = + ## Returns the number of left and right padding characters for a + ## given format alignment and width of the object to be printed. + ## + ## `fmt` + ## the format data + ## `default` + ## if `fmt.align == faDefault`, then this alignment is used + ## `slen` + ## the width of the object to be printed. + ## + ## The returned values `(left, right)` will be as minimal as possible + ## so that `left + slen + right >= fmt.width`. + result.left = 0 + result.right = 0 + if (fmt.width >= 0) and (slen < fmt.width): + let alg = if fmt.align == faDefault: defalign else: fmt.align + case alg: + of faLeft: result.right = fmt.width - slen + of faRight, faPadding: result.left = fmt.width - slen + of faCenter: + result.left = (fmt.width - slen) div 2 + result.right = fmt.width - slen - result.left + else: discard + +proc writefill(o: var Writer; fmt: Format; n: int; signum: int = 0) = + ## Write characters for filling. This function also writes the sign + ## of a numeric format and handles the padding alignment + ## accordingly. + ## + ## `o` + ## output object + ## `add` + ## output function + ## `fmt` + ## format to be used (important for padding aligment) + ## `n` + ## the number of filling characters to be written + ## `signum` + ## the sign of the number to be written, < 0 negative, > 0 positive, = 0 zero + if fmt.align == faPadding and signum != 0: + if signum < 0: write(o, '-') + elif fmt.sign == fsPlus: write(o, '+') + elif fmt.sign == fsSpace: write(o, ' ') + + if fmt.fill == nil: + for i in 1..n: write(o, ' ') + else: + for i in 1..n: + for c in fmt.fill: + write(o, c) + + if fmt.align != faPadding and signum != 0: + if signum < 0: write(o, '-') + elif fmt.sign == fsPlus: write(o, '+') + elif fmt.sign == fsSpace: write(o, ' ') + +proc writeformat(o: var Writer; s: string; fmt: Format) = + ## Write string `s` according to format `fmt` using output object + ## `o` and output function `add`. + if fmt.typ notin {ftDefault, ftStr}: + raise newException(FormatError, "String variable must have 's' format type") + + # compute alignment + let len = if fmt.precision < 0: runelen(s) else: min(runelen(s), fmt.precision) + var alg = getalign(fmt, faLeft, len) + writefill(o, fmt, alg.left) + var pos = 0 + for i in 0..len-1: + let rlen = runeLenAt(s, pos) + for j in pos..pos+rlen-1: write(o, s[j]) + pos += rlen + writefill(o, fmt, alg.right) + +proc writeformat(o: var Writer; c: char; fmt: Format) = + ## Write character `c` according to format `fmt` using output object + ## `o` and output function `add`. + if not (fmt.typ in {ftChar, ftDefault}): + raise newException(FormatError, "Character variable must have 'c' format type") + + # compute alignment + var alg = getalign(fmt, faLeft, 1) + writefill(o, fmt, alg.left) + write(o, c) + writefill(o, fmt, alg.right) + +proc writeformat(o: var Writer; c: Rune; fmt: Format) = + ## Write rune `c` according to format `fmt` using output object + ## `o` and output function `add`. + if not (fmt.typ in {ftChar, ftDefault}): + raise newException(FormatError, "Character variable must have 'c' format type") + + # compute alignment + var alg = getalign(fmt, faLeft, 1) + writefill(o, fmt, alg.left) + let s = c.toUTF8 + for c in s: write(o, c) + writefill(o, fmt, alg.right) + +proc abs(x: SomeUnsignedInt): SomeUnsignedInt {.inline.} = x + ## Return the absolute value of the unsigned int `x`. + +proc writeformat(o: var Writer; i: SomeInteger; fmt: Format) = + ## Write integer `i` according to format `fmt` using output object + ## `o` and output function `add`. + var fmt = fmt + if fmt.typ == ftDefault: + fmt.typ = ftDec + if not (fmt.typ in {ftBin, ftOct, ftHex, ftDec}): + raise newException(FormatError, "Integer variable must of one of the following types: b,o,x,X,d,n") + + var base: type(i) + var len = 0 + case fmt.typ: + of ftDec: + base = 10 + of ftBin: + base = 2 + if fmt.baseprefix: len += 2 + of ftOct: + base = 8 + if fmt.baseprefix: len += 2 + of ftHex: + base = 16 + if fmt.baseprefix: len += 2 + else: assert(false) + + if fmt.sign != fsMinus or i < 0: len.inc + + var x: type(i) = abs(i) + var irev: type(i) = 0 + var ilen = 0 + while x > 0.SomeInteger: + len.inc + ilen.inc + irev = irev * base + x mod base + x = x div base + if ilen == 0: + ilen.inc + len.inc + + var alg = getalign(fmt, faRight, len) + writefill(o, fmt, alg.left, if i >= 0.SomeInteger: 1 else: -1) + if fmt.baseprefix: + case fmt.typ + of ftBin: + write(o, '0') + write(o, 'b') + of ftOct: + write(o, '0') + write(o, 'o') + of ftHex: + write(o, '0') + write(o, 'x') + else: + raise newException(FormatError, "# only allowed with b, o, x or X") + while ilen > 0: + ilen.dec + let c = irev mod base + irev = irev div base + if c < 10: + write(o, ('0'.int + c.int).char) + elif fmt.upcase: + write(o, ('A'.int + c.int - 10).char) + else: + write(o, ('a'.int + c.int - 10).char) + writefill(o, fmt, alg.right) + +proc writeformat(o: var Writer; p: pointer; fmt: Format) = + ## Write pointer `i` according to format `fmt` using output object + ## `o` and output function `add`. + ## + ## Pointers are casted to unsigned int and formated as hexadecimal + ## with prefix unless specified otherwise. + var f = fmt + if f.typ == 0.char: + f.typ = 'x' + f.baseprefix = true + writeformat(o, add, cast[uint](p), f) + +proc writeformat(o: var Writer; x: SomeReal; fmt: Format) = + ## Write real number `x` according to format `fmt` using output + ## object `o` and output function `add`. + var fmt = fmt + # handle default format + if fmt.typ == ftDefault: + fmt.typ = ftGen + if fmt.precision < 0: fmt.precision = DefaultPrec + if not (fmt.typ in {ftFix, ftSci, ftGen, ftPercent}): + raise newException(FormatError, "Integer variable must of one of the following types: f,F,e,E,g,G,%") + + let positive = x >= 0 and classify(x) != fcNegZero + var len = 0 + + if fmt.sign != fsMinus or not positive: len.inc + + var prec = if fmt.precision < 0: DefaultPrec else: fmt.precision + var y = abs(x) + var exp = 0 + var numstr, frstr: array[0..31, char] + var numlen, frbeg, frlen = 0 + + if fmt.typ == ftPercent: y *= 100 + + case classify(x): + of fcNan: + numstr[0..2] = ['n', 'a', 'n'] + numlen = 3 + of fcInf, fcNegInf: + numstr[0..2] = ['f', 'n', 'i'] + numlen = 3 + of fcZero, fcNegZero: + numstr[0] = '0' + numlen = 1 + else: # a usual fractional number + if not (fmt.typ in {ftFix, ftPercent}): # not fixed point + exp = int(floor(log10(y))) + if fmt.typ == ftGen: + if prec == 0: prec = 1 + if -4 <= exp and exp < prec: + prec = prec-1-exp + exp = 0 + else: + prec = prec - 1 + len += 4 # exponent + else: + len += 4 # exponent + # shift y so that 1 <= abs(y) < 2 + if exp > 0: y /= pow(10.SomeReal, abs(exp).SomeReal) + elif exp < 0: y *= pow(10.SomeReal, abs(exp).SomeReal) + elif fmt.typ == ftPercent: + len += 1 # percent sign + + # handle rounding by adding +0.5 * LSB + if prec < len(round_nums): y += round_nums[prec] + + # split into integer and fractional part + var mult = 1'i64 + for i in 1..prec: mult *= 10 + var num = y.int64 + var fr = ((y - num.SomeReal) * mult.SomeReal).int64 + # build integer part string + while num != 0: + numstr[numlen] = ('0'.int + (num mod 10)).char + numlen.inc + num = num div 10 + if numlen == 0: + numstr[0] = '0' + numlen.inc + # build fractional part string + while fr != 0: + frstr[frlen] = ('0'.int + (fr mod 10)).char + frlen.inc + fr = fr div 10 + while frlen < prec: + frstr[frlen] = '0' + frlen.inc + # possible remove trailing 0 + if fmt.typ == ftGen: + while frbeg < frlen and frstr[frbeg] == '0': frbeg.inc + # update length of string + len += numlen; + if frbeg < frlen: + len += 1 + frlen - frbeg # decimal point and fractional string + + let alg = getalign(fmt, faRight, len) + writefill(o, fmt, alg.left, if positive: 1 else: -1) + for i in (numlen-1).countdown(0): write(o, numstr[i]) + if frbeg < frlen: + write(o, '.') + for i in (frlen-1).countdown(frbeg): write(o, frstr[i]) + if fmt.typ == ftSci or (fmt.typ == ftGen and exp != 0): + write(o, if fmt.upcase: 'E' else: 'e') + if exp >= 0: + write(o, '+') + else: + write(o, '-') + exp = -exp + if exp < 10: + write(o, '0') + write(o, ('0'.int + exp).char) + else: + var i=0 + while exp > 0: + numstr[i] = ('0'.int + exp mod 10).char + i+=1 + exp = exp div 10 + while i>0: + i-=1 + write(o, numstr[i]) + if fmt.typ == ftPercent: write(o, '%') + writefill(o, fmt, alg.right) + +proc writeformat(o: var Writer; b: bool; fmt: Format) = + ## Write boolean value `b` according to format `fmt` using output + ## object `o`. A boolean may be formatted numerically or as string. + ## In the former case true is written as 1 and false as 0, in the + ## latter the strings "true" and "false" are shown, respectively. + ## The default is string format. + if fmt.typ in {ftStr, ftDefault}: + writeformat(o, + if b: "true" + else: "false", + fmt) + elif fmt.typ in {ftBin, ftOct, ftHex, ftDec}: + writeformat(o, + if b: 1 + else: 0, + fmt) + else: + raise newException(FormatError, "Boolean values must of one of the following types: s,b,o,x,X,d,n") + +proc writeformat(o: var Writer; ary: openarray[any]; fmt: Format) = + ## Write array `ary` according to format `fmt` using output object + ## `o` and output function `add`. + if ary.len == 0: return + + var sep: string + var nxtfmt = fmt + if fmt.arysep == nil: + sep = "\t" + elif fmt.arysep.len == 0: + sep = "" + else: + let sepch = fmt.arysep[0] + let nxt = 1 + skipUntil(fmt.arysep, sepch, 1) + if nxt >= 1: + nxtfmt.arysep = fmt.arysep.substr(nxt) + sep = fmt.arysep.substr(1, nxt-1) + else: + nxtfmt.arysep = "" + sep = fmt.arysep.substr(1) + writeformat(o, ary[0], nxtfmt) + for i in 1..ary.len-1: + for c in sep: write(o, c) + writeformat(o, ary[i], nxtfmt) + +proc addformat[T](o: var Writer; x: T; fmt: Format = DefaultFmt) {.inline.} = + ## Write `x` formatted with `fmt` to `o`. + writeformat(o, x, fmt) + +proc addformat[T](o: var Writer; x: T; fmt: string) {.inline.} = + ## The same as `addformat(o, x, parse(fmt))`. + addformat(o, x, fmt.parse) + +proc addformat(s: var string; x: string) {.inline.} = + ## Write `x` to `s`. This is a fast specialized version for + ## appending unformatted strings. + add(s, x) + +proc addformat(f: File; x: string) {.inline.} = + ## Write `x` to `f`. This is a fast specialized version for + ## writing unformatted strings to a file. + write(f, x) + +proc addformat[T](f: File; x: T; fmt: Format = DefaultFmt) {.inline.} = + ## Write `x` to file `f` using format `fmt`. + var g = f + writeformat(g, x, fmt) + +proc addformat[T](f: File; x: T; fmt: string) {.inline.} = + ## Write `x` to file `f` using format string `fmt`. This is the same + ## as `addformat(f, x, parse(fmt))` + addformat(f, x, parse(fmt)) + +proc addformat(s: Stream; x: string) {.inline.} = + ## Write `x` to `s`. This is a fast specialized version for + ## writing unformatted strings to a stream. + write(s, x) + +proc addformat[T](s: Stream; x: T; fmt: Format = DefaultFmt) {.inline.} = + ## Write `x` to stream `s` using format `fmt`. + var g = s + writeformat(g, x, fmt) + +proc addformat[T](s: Stream; x: T; fmt: string) {.inline.} = + ## Write `x` to stream `s` using format string `fmt`. This is the same + ## as `addformat(s, x, parse(fmt))` + addformat(s, x, parse(fmt)) + +proc format[T](x: T; fmt: Format): string = + ## Return `x` formatted as a string according to format `fmt`. + result = "" + addformat(result, x, fmt) + +proc format[T](x: T; fmt: string): string = + ## Return `x` formatted as a string according to format string `fmt`. + result = format(x, fmt.parse) + +proc format[T](x: T): string {.inline.} = + ## Return `x` formatted as a string according to the default format. + ## The default format corresponds to an empty format string. + var fmt {.global.} : Format = DefaultFmt + result = format(x, fmt) + +proc unquoted(s: string): string {.compileTime.} = + ## Return `s` {{ and }} by single { and }, respectively. + result = "" + var pos = 0 + while pos < s.len: + let nxt = pos + skipUntil(s, {'{', '}'}) + result.add(s.substr(pos, nxt)) + pos = nxt + 2 + +proc splitfmt(s: string): seq[Part] {.compiletime, nosideeffect.} = + ## Split format string `s` into a sequence of "parts". + ## + + ## Each part is either a literal string or a format specification. A + ## format specification is a substring of the form + ## "{[arg][:format]}" where `arg` is either empty or a number + ## refering to the arg-th argument and an additional field or array + ## index. The format string is a string accepted by `parse`. + let subpeg = sequence(capture(digits()), + capture(?sequence(charSet({'.'}), *pegs.identStartChars(), *identChars())), + capture(?sequence(charSet({'['}), +digits(), charSet({']'}))), + capture(?sequence(charSet({':'}), *pegs.any()))) + result = @[] + var pos = 0 + while true: + let oppos = pos + skipUntil(s, {'{', '}'}, pos) + # reached the end + if oppos >= s.len: + if pos < s.len: + result.add(Part(kind: pkStr, str: s.substr(pos).unquoted)) + return + # skip double + if oppos + 1 < s.len and s[oppos] == s[oppos+1]: + result.add(Part(kind: pkStr, str: s.substr(pos, oppos))) + pos = oppos + 2 + continue + if s[oppos] == '}': + error("Single '}' encountered in format string") + if oppos > pos: + result.add(Part(kind: pkStr, str: s.substr(pos, oppos-1).unquoted)) + # find matching closing } + var lvl = 1 + var nested = false + pos = oppos + while lvl > 0: + pos.inc + pos = pos + skipUntil(s, {'{', '}'}, pos) + if pos >= s.len: + error("Single '{' encountered in format string") + if s[pos] == '{': + lvl.inc + if lvl == 2: + nested = true + if lvl > 2: + error("Too many nested format levels") + else: + lvl.dec + let clpos = pos + var fmtpart = Part(kind: pkFmt, arg: -1, fmt: s.substr(oppos+1, clpos-1), field: nil, index: int.high, nested: nested) + if fmtpart.fmt.len > 0: + var m: array[0..3, string] + if not fmtpart.fmt.match(subpeg, m): + error("invalid format string") + + if m[1] != nil and m[1].len > 0: + fmtpart.field = m[1].substr(1) + if m[2] != nil and m[2].len > 0: + discard parseInt(m[2].substr(1, m[2].len-2), fmtpart.index) + + if m[0].len > 0: discard parseInt(m[0], fmtpart.arg) + if m[3] == nil or m[3].len == 0: + fmtpart.fmt = "" + elif m[3][0] == ':': + fmtpart.fmt = m[3].substr(1) + else: + fmtpart.fmt = m[3] + result.add(fmtpart) + pos = clpos + 1 + +proc literal(s: string): NimNode {.compiletime, nosideeffect.} = + ## Return the nim literal of string `s`. This handles the case if + ## `s` is nil. + result = if s == nil: newNilLit() else: newLit(s) + +proc literal(b: bool): NimNode {.compiletime, nosideeffect.} = + ## Return the nim literal of boolean `b`. This is either `true` + ## or `false` symbol. + result = if b: "true".ident else: "false".ident + +proc literal[T](x: T): NimNode {.compiletime, nosideeffect.} = + ## Return the nim literal of value `x`. + when type(x) is enum: + result = ($x).ident + else: + result = newLit(x) + +proc generatefmt(fmtstr: string; + args: var openarray[tuple[arg:NimNode, cnt:int]]; + arg: var int;): seq[tuple[val, fmt:NimNode]] {.compiletime.} = + ## fmtstr + ## the format string + ## args + ## array of expressions for the arguments + ## arg + ## the number of the next argument for automatic parsing + ## + ## If arg is < 0 then the functions assumes that explicit numbering + ## must be used, otherwise automatic numbering is used starting at + ## `arg`. The value of arg is updated according to the number of + ## arguments being used. If arg == 0 then automatic and manual + ## numbering is not decided (because no explicit manual numbering is + ## fixed und no automatically numbered argument has been used so + ## far). + ## + ## The function returns a list of pairs `(val, fmt)` where `val` is + ## an expression to be formatted and `fmt` is the format string (or + ## Format). Therefore, the resulting string can be generated by + ## concatenating expressions `val.format(fmt)`. If `fmt` is `nil` + ## then `val` is a (literal) string expression. + try: + result = @[] + for part in splitfmt(fmtstr): + case part.kind + of pkStr: result.add((newLit(part.str), nil)) + of pkFmt: + # first compute the argument expression + # start with the correct index + var argexpr : NimNode + if part.arg >= 0: + if arg > 0: + error("Cannot switch from automatic field numbering to manual field specification") + if part.arg >= args.len: + error("Invalid explicit argument index: " & $part.arg) + argexpr = args[part.arg].arg + args[part.arg].cnt = args[part.arg].cnt + 1 + arg = -1 + else: + if arg < 0: + error("Cannot switch from manual field specification to automatic field numbering") + if arg >= args.len: + error("Too few arguments for format string") + argexpr = args[arg].arg + args[arg].cnt = args[arg].cnt + 1 + arg.inc + # possible field access + if part.field != nil and part.field.len > 0: + argexpr = newDotExpr(argexpr, part.field.ident) + # possible array access + if part.index < int.high: + argexpr = newNimNode(nnkBracketExpr).add(argexpr, newLit(part.index)) + # now the expression for the format data + var fmtexpr: NimNode + if part.nested: + # nested format string. Compute the format string by + # concatenating the parts of the substring. + for e in generatefmt(part.fmt, args, arg): + var newexpr = if part.fmt == nil: e.val else: newCall(bindsym"format", e.val, e.fmt) + if fmtexpr != nil and fmtexpr.kind != nnkNilLit: + fmtexpr = infix(fmtexpr, "&", newexpr) + else: + fmtexpr = newexpr + else: + # literal format string, precompute the format data + fmtexpr = newNimNode(nnkPar) + for field, val in part.fmt.parse.fieldPairs: + fmtexpr.add(newNimNode(nnkExprColonExpr).add(field.ident, literal(val))) + # add argument + result.add((argexpr, fmtexpr)) + finally: + discard + +proc addfmtfmt(fmtstr: string; args: NimNode; retvar: NimNode): NimNode {.compileTime.} = + var argexprs = newseq[tuple[arg:NimNode; cnt:int]](args.len) + result = newNimNode(nnkStmtListExpr) + # generate let bindings for arguments + for i in 0..args.len-1: + let argsym = gensym(nskLet, "arg" & $i) + result.add(newLetStmt(argsym, args[i])) + argexprs[i].arg = argsym + # add result values + var arg = 0 + for e in generatefmt(fmtstr, argexprs, arg): + if e.fmt == nil or e.fmt.kind == nnkNilLit: + result.add(newCall(bindsym"addformat", retvar, e.val)) + else: + result.add(newCall(bindsym"addformat", retvar, e.val, e.fmt)) + for i, arg in argexprs: + if arg.cnt == 0: + warning("Argument " & $(i+1) & " `" & args[i].repr & "` is not used in format string") + +macro addfmt(s: var string, fmtstr: string{lit}, args: varargs[expr]): expr = + ## The same as `s.add(fmtstr.fmt(args...))` but faster. + result = addfmtfmt($fmtstr, args, s) + +var s: string = "" +s.addfmt("a:{}", 42) diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index e50b251d3..f0ae45484 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -35,6 +35,7 @@ type actionNsis, # action: create NSIS installer actionScripts # action: create install and deinstall scripts actionZip, # action: create zip file + actionTargz, # action: create targz file actionDeb # action: prepare deb package FileCategory = enum @@ -171,6 +172,7 @@ proc parseCmdLine(c: var ConfigData) = of "csource": incl(c.actions, actionCSource) of "scripts": incl(c.actions, actionScripts) of "zip": incl(c.actions, actionZip) + of "targz": incl(c.actions, actionTargz) of "inno": incl(c.actions, actionInno) of "nsis": incl(c.actions, actionNsis) of "deb": incl(c.actions, actionDeb) @@ -181,10 +183,10 @@ proc parseCmdLine(c: var ConfigData) = break of cmdLongoption, cmdShortOption: case normalize(key.string) - of "help", "h": + of "help", "h": stdout.write(Usage) quit(0) - of "version", "v": + of "version", "v": stdout.write(Version & "\n") quit(0) of "o", "output": c.outdir = val @@ -240,7 +242,7 @@ proc incl(s: var seq[string], x: string): int = for i in 0.. <s.len: if cmpIgnoreStyle(s[i], x) == 0: return i s.add(x) - result = s.len-1 + result = s.len-1 proc platforms(c: var ConfigData, v: string) = for line in splitLines(v): @@ -277,17 +279,17 @@ proc parseIniFile(c: var ConfigData) = of "name": c.name = v of "displayname": c.displayName = v of "version": c.version = v - of "os": + of "os": c.oses = split(v, {';'}) hasCpuOs = true if c.explicitPlatforms: quit(errorStr(p, "you cannot have both 'platforms' and 'os'")) - of "cpu": + of "cpu": c.cpus = split(v, {';'}) hasCpuOs = true if c.explicitPlatforms: quit(errorStr(p, "you cannot have both 'platforms' and 'cpu'")) - of "platforms": + of "platforms": platforms(c, v) c.explicitPlatforms = true if hasCpuOs: @@ -389,7 +391,7 @@ proc readCFiles(c: var ConfigData, osA, cpuA: int) = of cfgKeyValuePair: case section of "ccompiler": pathFlags(p, k.key, k.value, c.ccompiler) - of "linker": + of "linker": pathFlags(p, k.key, k.value, c.linker) # HACK: we conditionally add ``-lm -ldl``, so remove them from the # linker flags: @@ -558,28 +560,68 @@ when haveZipLib: else: quit("Cannot open for writing: " & n) +proc targzDist(c: var ConfigData) = + let proj = toLower(c.name) & "-" & c.version + var n = "$#.tar.gz" % proj + let tmpDir = if c.outdir.len == 0: "build" else: c.outdir + + template processFile(z, dest, src) = + let s = src + let d = dest + echo "Copying ", s, " to ", tmpDir / d + let destdir = tmpdir / d.splitFile.dir + if not dirExists(destdir): createDir(destdir) + copyFile(s, tmpDir / d) + + processFile(z, proj / buildBatFile32, "build" / buildBatFile32) + processFile(z, proj / buildBatFile64, "build" / buildBatFile64) + processFile(z, proj / buildShFile, "build" / buildShFile) + processFile(z, proj / makeFile, "build" / makeFile) + processFile(z, proj / installShFile, installShFile) + processFile(z, proj / deinstallShFile, deinstallShFile) + for f in walkFiles(c.libpath / "lib/*.h"): + processFile(z, proj / "c_code" / extractFilename(f), f) + for osA in 1..c.oses.len: + for cpuA in 1..c.cpus.len: + var dir = buildDir(osA, cpuA) + for k, f in walkDir("build" / dir): + if k == pcFile: processFile(z, proj / dir / extractFilename(f), f) + + for cat in items({fcConfig..fcOther, fcUnix}): + for f in items(c.cat[cat]): processFile(z, proj / f, f) + + let oldDir = getCurrentDir() + setCurrentDir(tmpDir) + try: + #if execShellCmd("7z a -ttar $1.tar $1" % proj) != 0 or + # execShellCmd("7z a -tgzip $1.tar.gz $1.tar" % proj) != 0 or + if execShellCmd("7z a -tzip $1.zip $1" % proj) != 0: + echo("External program failed") + finally: + setCurrentDir(oldDir) + # -- prepare build files for .deb creation proc debDist(c: var ConfigData) = if not existsFile(getOutputDir(c) / "build.sh"): quit("No build.sh found.") if not existsFile(getOutputDir(c) / "install.sh"): quit("No install.sh found.") - + if c.debOpts.shortDesc == "": quit("shortDesc must be set in the .ini file.") if c.debOpts.licenses.len == 0: echo("[Warning] No licenses specified for .deb creation.") - + # -- Copy files into /tmp/.. echo("Copying source to tmp/niminst/deb/") var currentSource = getCurrentDir() var workingDir = getTempDir() / "niminst" / "deb" var upstreamSource = (c.name.toLower() & "-" & c.version) - + createDir(workingDir / upstreamSource) - + template copyNimDist(f, dest: string): stmt = createDir((workingDir / upstreamSource / dest).splitFile.dir) copyFile(currentSource / f, workingDir / upstreamSource / dest) - + # Don't copy all files, only the ones specified in the config: copyNimDist(buildShFile, buildShFile) copyNimDist(makeFile, makeFile) @@ -624,5 +666,7 @@ if actionZip in c.actions: zipDist(c) else: quit("libzip is not installed") +if actionTargz in c.actions: + targzDist(c) if actionDeb in c.actions: debDist(c) diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl index c21bfb9d5..843a8cf44 100644 --- a/tools/niminst/nsis.tmpl +++ b/tools/niminst/nsis.tmpl @@ -1,5 +1,5 @@ #! stdtmpl(subsChar='?') | standard -#proc generateNsisSetup(c: ConfigData): string = +#proc generateNsisSetup(c: ConfigData): string = # result = "; NSIS script generated by niminst\n" & # "; To regenerate run ``niminst nsis`` or ``koch nsis``\n" @@ -35,8 +35,8 @@ ; Default installation folder ; This is changed later (in .onInit) to the root directory, if possible. - InstallDir "$LOCALAPPDATA\?{c.name}" - + InstallDir "$LOCALAPPDATA\?{c.name}-?{c.version}" + ; Get installation folder from registry if available InstallDirRegKey HKCU "Software\c.name\c.version" "" @@ -86,14 +86,14 @@ !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH - + ; Setup the uninstaller pages !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES - + ;-------------------------------- ;Languages - + !insertmacro MUI_LANGUAGE "English" ;-------------------------------- @@ -104,7 +104,7 @@ ; Nim binary. Section "Core Files" CoreSection ; This is a mandotory section - SectionIn RO + SectionIn RO ; Output files to the base installation directory SetOutPath "$INSTDIR" @@ -164,7 +164,7 @@ ; The downloadable sections. These sections are automatically generated by ; niminst and the template filters. - #var i = 0 + #var i = 0 #for download in c.downloads: # inc i # let d = download.split('|') @@ -207,7 +207,7 @@ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\?{e}.lnk" "$INSTDIR\?dir\?{startMenuEntry.toWin}" !insertmacro MUI_STARTMENU_WRITE_END # end if - + ignore: SectionEnd #end diff --git a/web/documentation.txt b/web/documentation.txt index dbb737cd9..145a6e827 100644 --- a/web/documentation.txt +++ b/web/documentation.txt @@ -8,13 +8,13 @@ Nim's Documentation .. container:: libraries - - | `Standard Library <lib.html>`_ + - | `Standard Library <0.11.0/lib.html>`_ | This document describes Nim's standard library. - - | `Language Manual <manual.html>`_ + - | `Language Manual <0.11.0/manual.html>`_ | The Nim manual is a draft that will evolve into a proper specification. - - | `Compiler User Guide <nimc.html>`_ + - | `Compiler User Guide <0.11.0/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 <filters.html>`_ + - | `Source Code Filters <0.11.0/filters.html>`_ | The Nim compiler supports source code filters as a simple yet powerful builtin templating system. - - | `Tools Documentation <tools.html>`_ + - | `Tools Documentation <0.11.0/tools.html>`_ | Description of some tools that come with the standard distribution. @@ -41,16 +41,17 @@ Nim's Documentation .. container:: internals - - | `Garbage Collector <gc.html>`_ + - | `Garbage Collector <0.11.0/gc.html>`_ | Additional documentation about Nim's GC and how to operate it in a realtime setting. - - | `Internal Documentation <intern.html>`_ - | The internal documentation describes how the compiler is implemented. Read - this if you want to hack the compiler. + - | `Internal Documentation <0.11.0/intern.html>`_ + | The internal documentation describes how the compiler is implemented. + Read this if you want to hack the compiler. Search Options -------------- -`Documentation Index <theindex.html>`_ - The generated index. **Index + (Ctrl+F) == Joy** +`Documentation Index <0.11.0/theindex.html>`_ - The generated +index. **Index + (Ctrl+F) == Joy** diff --git a/web/download.txt b/web/download.txt index 3d47467f2..c9bc202cd 100644 --- a/web/download.txt +++ b/web/download.txt @@ -13,8 +13,8 @@ Binaries -------- Unfortunately for now we only provide builds for Windows. -* 32 bit: `nim-0.10.2_x32.exe <download/nim-0.10.2_x32.exe>`_ -* 64 bit: `nim-0.10.2_x64.exe <download/nim-0.10.2_x64.exe>`_ +* 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>`_ Installation based on generated C code @@ -24,8 +24,12 @@ This installation method is the preferred way for Linux, Mac OS X, and other Uni like systems. Binary packages may be provided later. -Download `nim-0.10.2.zip <download/nim-0.10.2.zip>`_, extract it and follow -these instructions: +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>`_ + +Extract the file and follow these instructions: * sh build.sh * Add ``$your_install_dir/bin`` to your PATH. diff --git a/web/learn.txt b/web/learn.txt index 7a9600e57..a2df38cde 100644 --- a/web/learn.txt +++ b/web/learn.txt @@ -8,10 +8,10 @@ Learning Nim .. container:: tutorials - - | `Tutorial (part I) <tut1.html>`_ + - | `Tutorial (part I) <0.11.0/tut1.html>`_ | Learn the basics of Nim's types, variables, procedures, control flow, etc... - - | `Tutorial (part II) <tut2.html>`_ + - | `Tutorial (part II) <0.11.0/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 <manual.html>`_. +More examples of Nim code can be found in the `Nim Language Documentation <0.11.0/manual.html>`_. diff --git a/web/news.txt b/web/news.txt index 6cb92b581..0f3f8def6 100644 --- a/web/news.txt +++ b/web/news.txt @@ -2,349 +2,399 @@ News ==== + +2015-04-30 Version 0.11.0 released +================================== + +With this release we are one step closer to reaching version 1.0 and by +extension the persistence of the Nim specification. As mentioned in the +previous release notes, starting with version 1.0, we will not be introducing +any more breaking changes to Nim. + +The *language* itself is very close to 1.0, the primary area that requires +more work is the standard library. + +Take a look at the `download <download.html>`_ page for binaries (Windows-only) +and 0.11.0 snapshots of the source code. The Windows installer now also +includes `Aporia <https://github.com/nim-lang/aporia>`_, +`Nimble <https://github.com/nim-lang/nimble>`_ and other useful tools to get +you started with Nim. + +What's left to be done +~~~~~~~~~~~~~~~~~~~~~~ + +The 1.0 release is expected by the end of this year. Rumors say it will be in +summer 2015. What's left: + +* Bug fixes, bug fixes, bug fixes, in particular: + - 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. + - ``static[T]`` needs to be fixed. + - Finish the implementation of the 'parallel' statement. +* ``immediate`` templates and macros will be deprecated as these will soon be + completely unnecessary, instead the ``typed`` or ``untyped`` metatypes can + be used. +* More of the standard library should be moved to Nimble packages and what's + left should use the features we have for concurrency and parallelism. + + + +Changes affecting backwards compatibility +----------------------------------------- + +- Parameter names are finally properly ``gensym``'ed. This can break + templates though that used to rely on the fact that they are not. + (Bug #1915.) This means this doesn't compile anymore: + +.. code-block:: nim + + template doIt(body: stmt) {.immediate.} = + # this used to inject the 'str' parameter: + proc res(str: string) = + body + + doIt: + echo str # Error: undeclared identifier: 'str' .. - 2015-03-01 Version 0.11.0 released - ================================== - - - Changes affecting backwards compatibility - ----------------------------------------- - - - Parameter names are finally properly ``gensym``'ed. This can break - templates though that used to rely on the fact that they are not. - (Bug #1915.) This means this doesn't compile anymore: - - .. code-block:: nim - - template doIt(body: stmt) {.immediate.} = - # this used to inject the 'str' parameter: - proc res(str: string) = - body - - doIt: - echo str # Error: undeclared identifier: 'str' - - Declare the ``doIt`` template as ``immediate, dirty`` to get the old - behaviour. - - Tuple field names are not ignored anymore, this caused too many problems - in practice so now the behaviour as it was for version 0.9.6: If field - names exist for the tuple type, they are checked. - - ``logging.level`` and ``logging.handlers`` are no longer exported. - ``addHandler``, ``getHandlers``, ``setLogFilter`` and ``getLogFilter`` - should be used instead. - - ``nim idetools`` has been replaced by a separate tool `nimsuggest`_. - - *arrow like* operators are not right associative anymore. - - *arrow like* operators are now required to end with either ``->``, ``~>`` or - ``=>``, not just ``>``. Examples of operators still considered arrow like: - ``->``, ``==>``, ``+=>``. On the other hand, the following operators are now - considered regular operators again: ``|>``, ``-+>``, etc. - - Typeless parameters are now only allowed in templates and macros. The old - way turned out to be too error-prone. - - The 'addr' and 'type' operators are now parsed as unary function - application. This means ``type(x).name`` is now parsed as ``(type(x)).name`` - and not as ``type((x).name)``. Note that this also affects the AST - structure; for immediate macro parameters ``nkCall('addr', 'x')`` is - produced instead of ``nkAddr('x')``. - - ``concept`` is now a keyword and is used instead of ``generic``. - - The ``inc``, ``dec``, ``+=``, ``-=`` builtins now produce OverflowError - exceptions. This means code like the following: - - .. code-block:: nim - var x = low(T) - while x <= high(T): - echo x - inc x - - Needs to be replaced by something like this: - - .. code-block:: nim - var x = low(T).int - while x <= high(T).int: - echo x.T - inc x - - - **Negative indexing for slicing does not work anymore!** Instead - of ``a[0.. -1]`` you can - use ``a[0.. ^1]``. This also works with accessing a single - element ``a[^1]``. Note that we cannot detect this reliably as it is - determined at **runtime** whether negative indexing is used! - ``a[0.. -1]`` now produces the empty string/sequence. - - The compiler now warns about code like ``foo +=1`` which uses inconsistent - spacing around binary operators. Later versions of the language will parse - these as unary operators instead so that ``echo $foo`` finally can do what - people expect it to do. - - ``system.untyped`` and ``system.typed`` have been introduced as aliases - for ``expr`` and ``stmt``. The new names capture the semantics much better - and most likely ``expr`` and ``stmt`` will be deprecated in favor of the - new names. - - The ``split`` method in module ``re`` has changed. It now handles the case - of matches having a length of 0, and empty strings being yielded from the - iterator. A notable change might be that a pattern being matched at the - beginning and end of a string, will result in an empty string being produced - at the start and the end of the iterator. - - Language Additions - ------------------ - - - For empty ``case object`` branches ``discard`` can finally be used instead - of ``nil``. - - Automatic dereferencing is now done for the first argument of a routine - call if overloading resolution produces no match otherwise. This feature - has to be enabled with the `experimental`_ pragma. - - Objects that do not use inheritance nor ``case`` can be put into ``const`` - sections. This means that finally this is possible and produces rather - nice code: - - .. code-block:: nim - import tables - - const - foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable() - - - - Ordinary parameters can follow after a varargs parameter. This means the - following is finally accepted by the compiler: - - .. code-block:: nim - template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) = - blck - echo a, b - - takesBlock 1, 2, "some", 0.90, "random stuff": - echo "yay" - - - Overloading by 'var T' is now finally possible: - - .. code-block:: nim - proc varOrConst(x: var int) = echo "var" - proc varOrConst(x: int) = echo "const" - - var x: int - varOrConst(x) # "var" - varOrConst(45) # "const" - - - Array and seq indexing can now use the builtin ``^`` operator to access - things from backwards: ``a[^1]`` is like Python's ``a[-1]``. - - A first version of the specification and implementation of the overloading - of the assignment operator has arrived! - - ``system.len`` for strings and sequences now returns 0 for nil. - - - A single underscore can now be used to discard values when unpacking tuples. - - ``marshal.$$`` and ``marshal.to`` can be executed at compile-time. - - Interoperability with C++ improved tremendously; C++'s templates and - operators can be wrapped directly. See `this <nimc.html#ImportCpp-pragma>`_ - for more information. - - - Library additions - ----------------- - - - ``reversed`` proc added to the ``unicode`` module. - - Added multipart param to httpclient's ``post`` and ``postContent`` together - with a ``newMultipartData`` proc. - - Added `%*` operator for JSON. - - The compiler is now available as Nimble package for c2nim. - - Added ``..^`` and ``..<`` templates to system so that the rather annoying - space between ``.. <`` and ``.. ^`` is not necessary anymore. - - Added ``system.xlen`` for strings and sequences to get back the old ``len`` - operation that doesn't check for ``nil`` for efficiency. - - - Bugfixes - -------- - - - Fixed internal compiler error when using ``char()`` in an echo call - (`#1788 <https://github.com/Araq/Nim/issues/1788>`_). - - Fixed Windows cross-compilation on Linux. - - Overload resolution now works for types distinguished only by a - ``static[int]`` param - (`#1056 <https://github.com/Araq/Nim/issues/1056>`_). - - Other fixes relating to generic types and static params. - - Fixed some compiler crashes with unnamed tuples - (`#1774 <https://github.com/Araq/Nim/issues/1774>`_). - - Fixed ``channels.tryRecv`` blocking - (`#1816 <https://github.com/Araq/Nim/issues/1816>`_). - - Fixed generic instantiation errors with ``typedesc`` - (`#419 <https://github.com/Araq/Nim/issues/419>`_). - - Fixed generic regression where the compiler no longer detected constant - expressions properly (`#544 <https://github.com/Araq/Nim/issues/544>`_). - - Fixed internal error with generic proc using ``static[T]`` in a specific - way (`#1049 <https://github.com/Araq/Nim/issues/1049>`_). - - More fixes relating to generics - (`#1820 <https://github.com/Araq/Nim/issues/1820>`_, - `#1050 <https://github.com/Araq/Nim/issues/1050>`_, - `#1859 <https://github.com/Araq/Nim/issues/1859>`_, - `#1858 <https://github.com/Araq/Nim/issues/1858>`_). - - Fixed httpclient to properly encode queries. - - Many fixes to the ``uri`` module. - - Async sockets are now closed on error. - - Fixes to httpclient's handling of multipart data. - - Fixed GC segfaults with asynchronous sockets - (`#1796 <https://github.com/Araq/Nim/issues/1796>`_). - - Added more versions to openssl's DLL version list - (`076f993 <https://github.com/Araq/Nim/commit/076f993>`_). - - Fixed shallow copy in iterators being broken - (`#1803 <https://github.com/Araq/Nim/issues/1803>`_). - - ``nil`` can now be inserted into tables with the ``db_sqlite`` module - (`#1866 <https://github.com/Araq/Nim/issues/1866>`_). - - Fixed "Incorrect assembler generated" - (`#1907 <https://github.com/Araq/Nim/issues/1907>`_) - - Fixed "Expression templates that define macros are unusable in some contexts" - (`#1903 <https://github.com/Araq/Nim/issues/1903>`_) - - Fixed "a second level generic subclass causes the compiler to crash" - (`#1919 <https://github.com/Araq/Nim/issues/1919>`_) - - Fixed "nim 0.10.2 generates invalid AsyncHttpClient C code for MSVC " - (`#1901 <https://github.com/Araq/Nim/issues/1901>`_) - - Fixed "1 shl n produces wrong C code" - (`#1928 <https://github.com/Araq/Nim/issues/1928>`_) - - Fixed "Internal error on tuple yield" - (`#1838 <https://github.com/Araq/Nim/issues/1838>`_) - - Fixed "ICE with template" - (`#1915 <https://github.com/Araq/Nim/issues/1915>`_) - - Fixed "include the tool directory in the installer as it is required by koch" - (`#1947 <https://github.com/Araq/Nim/issues/1947>`_) - - Fixed "Can't compile if file location contains spaces on Windows" - (`#1955 <https://github.com/Araq/Nim/issues/1955>`_) - - Fixed "List comprehension macro only supports infix checks as guards" - (`#1920 <https://github.com/Araq/Nim/issues/1920>`_) - - Fixed "wrong field names of compatible tuples in generic types" - (`#1910 <https://github.com/Araq/Nim/issues/1910>`_) - - Fixed "Macros within templates no longer work as expected" - (`#1944 <https://github.com/Araq/Nim/issues/1944>`_) - - Fixed "Compiling for Standalone AVR broken in 0.10.2" - (`#1964 <https://github.com/Araq/Nim/issues/1964>`_) - - Fixed "Compiling for Standalone AVR broken in 0.10.2" - (`#1964 <https://github.com/Araq/Nim/issues/1964>`_) - - Fixed "Code generation for mitems with tuple elements" - (`#1833 <https://github.com/Araq/Nim/issues/1833>`_) - - Fixed "httpclient.HttpMethod should not be an enum" - (`#1962 <https://github.com/Araq/Nim/issues/1962>`_) - - Fixed "terminal / eraseScreen() throws an OverflowError" - (`#1906 <https://github.com/Araq/Nim/issues/1906>`_) - - Fixed "setControlCHook(nil) disables registered quit procs" - (`#1546 <https://github.com/Araq/Nim/issues/1546>`_) - - Fixed "Unexpected idetools behaviour" - (`#325 <https://github.com/Araq/Nim/issues/325>`_) - - Fixed "Unused lifted lambda does not compile" - (`#1642 <https://github.com/Araq/Nim/issues/1642>`_) - - Fixed "'low' and 'high' don't work with cstring asguments" - (`#2030 <https://github.com/Araq/Nim/issues/2030>`_) - - Fixed "Converting to int does not round in JS backend" - (`#1959 <https://github.com/Araq/Nim/issues/1959>`_) - - Fixed "Internal error genRecordField 2 when adding region to pointer." - (`#2039 <https://github.com/Araq/Nim/issues/2039>`_) - - Fixed "Macros fail to compile when compiled with --os:standalone" - (`#2041 <https://github.com/Araq/Nim/issues/2041>`_) - - Fixed "Reading from {.compileTime.} variables can cause code generation to fail" - (`#2022 <https://github.com/Araq/Nim/issues/2022>`_) - - Fixed "Passing overloaded symbols to templates fails inside generic procedures" - (`#1988 <https://github.com/Araq/Nim/issues/1988>`_) - - Fixed "Compiling iterator with object assignment in release mode causes "var not init"" - (`#2023 <https://github.com/Araq/Nim/issues/2023>`_) - - Fixed "calling a large number of macros doing some computation fails" - (`#1989 <https://github.com/Araq/Nim/issues/1989>`_) - - Fixed "Can't get Koch to install nim under Windows" - (`#2061 <https://github.com/Araq/Nim/issues/2061>`_) - - Fixed "Template with two stmt parameters segfaults compiler" - (`#2057 <https://github.com/Araq/Nim/issues/2057>`_) - - Fixed "`noSideEffect` not affected by `echo`" - (`#2011 <https://github.com/Araq/Nim/issues/2011>`_) - - Fixed "Compiling with the cpp backend ignores --passc" - (`#1601 <https://github.com/Araq/Nim/issues/1601>`_) - - Fixed "Put untyped procedure parameters behind the experimental pragma" - (`#1956 <https://github.com/Araq/Nim/issues/1956>`_) - - Fixed "generic regression" - (`#2073 <https://github.com/Araq/Nim/issues/2073>`_) - - Fixed "generic regression" - (`#2073 <https://github.com/Araq/Nim/issues/2073>`_) - - Fixed "Regression in template lookup with generics" - (`#2004 <https://github.com/Araq/Nim/issues/2004>`_) - - Fixed "GC's growObj is wrong for edge cases" - (`#2070 <https://github.com/Araq/Nim/issues/2070>`_) - - Fixed "Compiler internal error when creating an array out of a typeclass" - (`#1131 <https://github.com/Araq/Nim/issues/1131>`_) - - Fixed "GC's growObj is wrong for edge cases" - (`#2070 <https://github.com/Araq/Nim/issues/2070>`_) - - Fixed "Invalid Objective-C code generated when calling class method" - (`#2068 <https://github.com/Araq/Nim/issues/2068>`_) - - Fixed "walkDirRec Error" - (`#2116 <https://github.com/Araq/Nim/issues/2116>`_) - - Fixed "Typo in code causes compiler SIGSEGV in evalAtCompileTime" - (`#2113 <https://github.com/Araq/Nim/issues/2113>`_) - - Fixed "Regression on exportc" - (`#2118 <https://github.com/Araq/Nim/issues/2118>`_) - - Fixed "Error message" - (`#2102 <https://github.com/Araq/Nim/issues/2102>`_) - - Fixed "hint[path] = off not working in nim.cfg" - (`#2103 <https://github.com/Araq/Nim/issues/2103>`_) - - Fixed "compiler crashes when getting a tuple from a sequence of generic tuples" - (`#2121 <https://github.com/Araq/Nim/issues/2121>`_) - - Fixed "nim check hangs with when" - (`#2123 <https://github.com/Araq/Nim/issues/2123>`_) - - Fixed "static[T] param in nested type resolve/caching issue" - (`#2125 <https://github.com/Araq/Nim/issues/2125>`_) - - Fixed "repr should display ``\0``" - (`#2124 <https://github.com/Araq/Nim/issues/2124>`_) - - Fixed "'nim check' never ends in case of recursive dependency " - (`#2051 <https://github.com/Araq/Nim/issues/2051>`_) - - Fixed "From macros: Error: unhandled exception: sons is not accessible" - (`#2167 <https://github.com/Araq/Nim/issues/2167>`_) - - Fixed "`fieldPairs` doesn't work inside templates" - (`#1902 <https://github.com/Araq/Nim/issues/1902>`_) - - Fixed "fields iterator misbehavior on break statement" - (`#2134 <https://github.com/Araq/Nim/issues/2134>`_) - - Fixed "Fix for compiler not building anymore since #c3244ef1ff" - (`#2193 <https://github.com/Araq/Nim/issues/2193>`_) - - Fixed "JSON parser fails in cpp output mode" - (`#2199 <https://github.com/Araq/Nim/issues/2199>`_) - - Fixed "macros.getType mishandles void return" - (`#2211 <https://github.com/Araq/Nim/issues/2211>`_) - - Fixed "Regression involving templates instantiated within generics" - (`#2215 <https://github.com/Araq/Nim/issues/2215>`_) - - Fixed ""Error: invalid type" for 'not nil' on generic type." - (`#2216 <https://github.com/Araq/Nim/issues/2216>`_) - - Fixed "--threads:on breaks async" - (`#2074 <https://github.com/Araq/Nim/issues/2074>`_) - - Fixed "Type mismatch not always caught, can generate bad code for C backend." - (`#2169 <https://github.com/Araq/Nim/issues/2169>`_) - - Fixed "Failed C compilation when storing proc to own type in object" - (`#2233 <https://github.com/Araq/Nim/issues/2233>`_) - - Fixed "Unknown line/column number in constant declaration type conversion error" - (`#2252 <https://github.com/Araq/Nim/issues/2252>`_) - - Fixed "Adding {.compile.} fails if nimcache already exists." - (`#2247 <https://github.com/Araq/Nim/issues/2247>`_) - - Fixed "Two different type names generated for a single type (C backend)" - (`#2250 <https://github.com/Araq/Nim/issues/2250>`_) - - Fixed "Ambigous call when it should not be" - (`#2229 <https://github.com/Araq/Nim/issues/2229>`_) - - Fixed "Make sure we can load root urls" - (`#2227 <https://github.com/Araq/Nim/issues/2227>`_) - - Fixed "Failure to slice a string with an int subrange type" - (`#794 <https://github.com/Araq/Nim/issues/794>`_) - - Fixed "documentation error" - (`#2205 <https://github.com/Araq/Nim/issues/2205>`_) - - Fixed "Code growth when using `const`" - (`#1940 <https://github.com/Araq/Nim/issues/1940>`_) - - Fixed "Instances of generic types confuse overload resolution" - (`#2220 <https://github.com/Araq/Nim/issues/2220>`_) - - Fixed "Compiler error when initializing sdl2's EventType" - (`#2316 <https://github.com/Araq/Nim/issues/2316>`_) - - Fixed "Parallel disjoint checking can't handle `<`, `items`, or arrays" - (`#2287 <https://github.com/Araq/Nim/issues/2287>`_) - - Fixed "Strings aren't copied in parallel loop" - (`#2286 <https://github.com/Araq/Nim/issues/2286>`_) - - Fixed "JavaScript compiler crash with tables" - (`#2298 <https://github.com/Araq/Nim/issues/2298>`_) - - Fixed "Range checker too restrictive" - (`#1845 <https://github.com/Araq/Nim/issues/1845>`_) - - Fixed "Failure to slice a string with an int subrange type" - (`#794 <https://github.com/Araq/Nim/issues/794>`_) - - Fixed "Remind user when compiling in debug mode" - (`#1868 <https://github.com/Araq/Nim/issues/1868>`_) - - Fixed "Compiler user guide has jumbled options/commands." - (`#1819 <https://github.com/Araq/Nim/issues/1819>`_) - - Fixed "using `method`: 1 in a objects constructor fails when compiling" - (`#1791 <https://github.com/Araq/Nim/issues/1791>`_) + + This used to inject the ``str`` parameter into the scope of the body. + Declare the ``doIt`` template as ``immediate, dirty`` to get the old + behaviour. +- Tuple field names are not ignored anymore, this caused too many problems + in practice so now the behaviour is as it was for version 0.9.6: If field + names exist for the tuple type, they are checked. +- ``logging.level`` and ``logging.handlers`` are no longer exported. + ``addHandler``, ``getHandlers``, ``setLogFilter`` and ``getLogFilter`` + should be used instead. +- ``nim idetools`` has been replaced by a separate + tool `nimsuggest <0.11.0/nimsuggest.html>`_. +- *arrow like* operators are not right associative anymore and are required + to end with either ``->``, ``~>`` or + ``=>``, not just ``>``. Examples of operators still considered arrow like: + ``->``, ``==>``, ``+=>``. On the other hand, the following operators are now + considered regular operators again: ``|>``, ``-+>``, etc. +- Typeless parameters are now only allowed in templates and macros. The old + way turned out to be too error-prone. +- The 'addr' and 'type' operators are now parsed as unary function + application. This means ``type(x).name`` is now parsed as ``(type(x)).name`` + and not as ``type((x).name)``. Note that this also affects the AST + structure; for immediate macro parameters ``nkCall('addr', 'x')`` is + produced instead of ``nkAddr('x')``. +- ``concept`` is now a keyword and is used instead of ``generic``. +- The ``inc``, ``dec``, ``+=``, ``-=`` builtins now produce OverflowError + exceptions. This means code like the following: + +.. code-block:: nim + var x = low(T) + while x <= high(T): + echo x + inc x + +Needs to be replaced by something like this: + +.. code-block:: nim + var x = low(T).int + while x <= high(T).int: + echo x.T + inc x + +- **Negative indexing for slicing does not work anymore!** Instead + of ``a[0.. -1]`` you can + use ``a[0.. ^1]``. This also works with accessing a single + element ``a[^1]``. Note that we cannot detect this reliably as it is + determined at **runtime** whether negative indexing is used! + ``a[0.. -1]`` now produces the empty string/sequence. +- The compiler now warns about code like ``foo +=1`` which uses inconsistent + spacing around binary operators. Later versions of the language will parse + these as unary operators instead so that ``echo $foo`` finally can do what + people expect it to do. +- ``system.untyped`` and ``system.typed`` have been introduced as aliases + for ``expr`` and ``stmt``. The new names capture the semantics much better + and most likely ``expr`` and ``stmt`` will be deprecated in favor of the + new names. +- The ``split`` method in module ``re`` has changed. It now handles the case + of matches having a length of 0, and empty strings being yielded from the + iterator. A notable change might be that a pattern being matched at the + beginning and end of a string, will result in an empty string being produced + at the start and the end of the iterator. +- The compiler and nimsuggest now count columns starting with 1, not 0 for + consistency with the rest of the world. + + +Language Additions +------------------ + +- For empty ``case object`` branches ``discard`` can finally be used instead + of ``nil``. +- Automatic dereferencing is now done for the first argument of a routine + call if overloading resolution produces no match otherwise. This feature + has to be enabled with + the `experimental <0.11.0/manual.html#pragmas-experimental-pragma>`_ pragma. +- Objects that do not use inheritance nor ``case`` can be put into ``const`` + sections. This means that finally this is possible and produces rather + nice code: + +.. code-block:: nim + import tables + + const + foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable() + + +- Ordinary parameters can follow after a varargs parameter. This means the + following is finally accepted by the compiler: + +.. code-block:: nim + template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) = + blck + echo a, b + + takesBlock 1, 2, "some", 0.90, "random stuff": + echo "yay" + +- Overloading by 'var T' is now finally possible: + +.. code-block:: nim + proc varOrConst(x: var int) = echo "var" + proc varOrConst(x: int) = echo "const" + + var x: int + varOrConst(x) # "var" + varOrConst(45) # "const" + +- Array and seq indexing can now use the builtin ``^`` operator to access + things from backwards: ``a[^1]`` is like Python's ``a[-1]``. +- A first version of the specification and implementation of the overloading + of the assignment operator has arrived! +- ``system.len`` for strings and sequences now returns 0 for nil. + +- A single underscore can now be used to discard values when unpacking tuples: + +.. code-block:: nim + let (path, _, _) = os.splitFile("path/file.ext") + + +- ``marshal.$$`` and ``marshal.to`` can be executed at compile-time. +- Interoperability with C++ improved tremendously; C++'s templates and + operators can be wrapped directly. See + `this <0.11.0/nimc.html#additional-features-importcpp-pragma>`_ + for more information. +- ``macros.getType`` can be used to query an AST's type at compile-time. This + enables more powerful macros, for instance *currying* can now be done with + a macro. + + +Library additions +----------------- + +- ``reversed`` proc added to the ``unicode`` module. +- Added multipart param to httpclient's ``post`` and ``postContent`` together + with a ``newMultipartData`` proc. +- Added `%*` operator for JSON. +- The compiler is now available as Nimble package for c2nim. +- Added ``..^`` and ``..<`` templates to system so that the rather annoying + space between ``.. <`` and ``.. ^`` is not necessary anymore. +- Added ``system.xlen`` for strings and sequences to get back the old ``len`` + operation that doesn't check for ``nil`` for efficiency. + + +Bugfixes +-------- + +- Fixed internal compiler error when using ``char()`` in an echo call + (`#1788 <https://github.com/Araq/Nim/issues/1788>`_). +- Fixed Windows cross-compilation on Linux. +- Overload resolution now works for types distinguished only by a + ``static[int]`` param + (`#1056 <https://github.com/Araq/Nim/issues/1056>`_). +- Other fixes relating to generic types and static params. +- Fixed some compiler crashes with unnamed tuples + (`#1774 <https://github.com/Araq/Nim/issues/1774>`_). +- Fixed ``channels.tryRecv`` blocking + (`#1816 <https://github.com/Araq/Nim/issues/1816>`_). +- Fixed generic instantiation errors with ``typedesc`` + (`#419 <https://github.com/Araq/Nim/issues/419>`_). +- Fixed generic regression where the compiler no longer detected constant + expressions properly (`#544 <https://github.com/Araq/Nim/issues/544>`_). +- Fixed internal error with generic proc using ``static[T]`` in a specific + way (`#1049 <https://github.com/Araq/Nim/issues/1049>`_). +- More fixes relating to generics (`#1820 <https://github.com/Araq/Nim/issues/1820>`_, + `#1050 <https://github.com/Araq/Nim/issues/1050>`_, + `#1859 <https://github.com/Araq/Nim/issues/1859>`_, + `#1858 <https://github.com/Araq/Nim/issues/1858>`_). +- Fixed httpclient to properly encode queries. +- Many fixes to the ``uri`` module. +- Async sockets are now closed on error. +- Fixes to httpclient's handling of multipart data. +- Fixed GC segfaults with asynchronous sockets + (`#1796 <https://github.com/Araq/Nim/issues/1796>`_). +- Added more versions to openssl's DLL version list + (`076f993 <https://github.com/Araq/Nim/commit/076f993>`_). +- Fixed shallow copy in iterators being broken + (`#1803 <https://github.com/Araq/Nim/issues/1803>`_). +- ``nil`` can now be inserted into tables with the ``db_sqlite`` module + (`#1866 <https://github.com/Araq/Nim/issues/1866>`_). +- Fixed "Incorrect assembler generated" + (`#1907 <https://github.com/Araq/Nim/issues/1907>`_) +- Fixed "Expression templates that define macros are unusable in some contexts" + (`#1903 <https://github.com/Araq/Nim/issues/1903>`_) +- Fixed "a second level generic subclass causes the compiler to crash" + (`#1919 <https://github.com/Araq/Nim/issues/1919>`_) +- Fixed "nim 0.10.2 generates invalid AsyncHttpClient C code for MSVC " + (`#1901 <https://github.com/Araq/Nim/issues/1901>`_) +- Fixed "1 shl n produces wrong C code" + (`#1928 <https://github.com/Araq/Nim/issues/1928>`_) +- Fixed "Internal error on tuple yield" + (`#1838 <https://github.com/Araq/Nim/issues/1838>`_) +- Fixed "ICE with template" + (`#1915 <https://github.com/Araq/Nim/issues/1915>`_) +- Fixed "include the tool directory in the installer as it is required by koch" + (`#1947 <https://github.com/Araq/Nim/issues/1947>`_) +- Fixed "Can't compile if file location contains spaces on Windows" + (`#1955 <https://github.com/Araq/Nim/issues/1955>`_) +- Fixed "List comprehension macro only supports infix checks as guards" + (`#1920 <https://github.com/Araq/Nim/issues/1920>`_) +- Fixed "wrong field names of compatible tuples in generic types" + (`#1910 <https://github.com/Araq/Nim/issues/1910>`_) +- Fixed "Macros within templates no longer work as expected" + (`#1944 <https://github.com/Araq/Nim/issues/1944>`_) +- Fixed "Compiling for Standalone AVR broken in 0.10.2" + (`#1964 <https://github.com/Araq/Nim/issues/1964>`_) +- Fixed "Compiling for Standalone AVR broken in 0.10.2" + (`#1964 <https://github.com/Araq/Nim/issues/1964>`_) +- Fixed "Code generation for mitems with tuple elements" + (`#1833 <https://github.com/Araq/Nim/issues/1833>`_) +- Fixed "httpclient.HttpMethod should not be an enum" + (`#1962 <https://github.com/Araq/Nim/issues/1962>`_) +- Fixed "terminal / eraseScreen() throws an OverflowError" + (`#1906 <https://github.com/Araq/Nim/issues/1906>`_) +- Fixed "setControlCHook(nil) disables registered quit procs" + (`#1546 <https://github.com/Araq/Nim/issues/1546>`_) +- Fixed "Unexpected idetools behaviour" + (`#325 <https://github.com/Araq/Nim/issues/325>`_) +- Fixed "Unused lifted lambda does not compile" + (`#1642 <https://github.com/Araq/Nim/issues/1642>`_) +- Fixed "'low' and 'high' don't work with cstring asguments" + (`#2030 <https://github.com/Araq/Nim/issues/2030>`_) +- Fixed "Converting to int does not round in JS backend" + (`#1959 <https://github.com/Araq/Nim/issues/1959>`_) +- Fixed "Internal error genRecordField 2 when adding region to pointer." + (`#2039 <https://github.com/Araq/Nim/issues/2039>`_) +- Fixed "Macros fail to compile when compiled with --os:standalone" + (`#2041 <https://github.com/Araq/Nim/issues/2041>`_) +- Fixed "Reading from {.compileTime.} variables can cause code generation to fail" + (`#2022 <https://github.com/Araq/Nim/issues/2022>`_) +- Fixed "Passing overloaded symbols to templates fails inside generic procedures" + (`#1988 <https://github.com/Araq/Nim/issues/1988>`_) +- Fixed "Compiling iterator with object assignment in release mode causes "var not init"" + (`#2023 <https://github.com/Araq/Nim/issues/2023>`_) +- Fixed "calling a large number of macros doing some computation fails" + (`#1989 <https://github.com/Araq/Nim/issues/1989>`_) +- Fixed "Can't get Koch to install nim under Windows" + (`#2061 <https://github.com/Araq/Nim/issues/2061>`_) +- Fixed "Template with two stmt parameters segfaults compiler" + (`#2057 <https://github.com/Araq/Nim/issues/2057>`_) +- Fixed "`noSideEffect` not affected by `echo`" + (`#2011 <https://github.com/Araq/Nim/issues/2011>`_) +- Fixed "Compiling with the cpp backend ignores --passc" + (`#1601 <https://github.com/Araq/Nim/issues/1601>`_) +- Fixed "Put untyped procedure parameters behind the experimental pragma" + (`#1956 <https://github.com/Araq/Nim/issues/1956>`_) +- Fixed "generic regression" + (`#2073 <https://github.com/Araq/Nim/issues/2073>`_) +- Fixed "generic regression" + (`#2073 <https://github.com/Araq/Nim/issues/2073>`_) +- Fixed "Regression in template lookup with generics" + (`#2004 <https://github.com/Araq/Nim/issues/2004>`_) +- Fixed "GC's growObj is wrong for edge cases" + (`#2070 <https://github.com/Araq/Nim/issues/2070>`_) +- Fixed "Compiler internal error when creating an array out of a typeclass" + (`#1131 <https://github.com/Araq/Nim/issues/1131>`_) +- Fixed "GC's growObj is wrong for edge cases" + (`#2070 <https://github.com/Araq/Nim/issues/2070>`_) +- Fixed "Invalid Objective-C code generated when calling class method" + (`#2068 <https://github.com/Araq/Nim/issues/2068>`_) +- Fixed "walkDirRec Error" + (`#2116 <https://github.com/Araq/Nim/issues/2116>`_) +- Fixed "Typo in code causes compiler SIGSEGV in evalAtCompileTime" + (`#2113 <https://github.com/Araq/Nim/issues/2113>`_) +- Fixed "Regression on exportc" + (`#2118 <https://github.com/Araq/Nim/issues/2118>`_) +- Fixed "Error message" + (`#2102 <https://github.com/Araq/Nim/issues/2102>`_) +- Fixed "hint[path] = off not working in nim.cfg" + (`#2103 <https://github.com/Araq/Nim/issues/2103>`_) +- Fixed "compiler crashes when getting a tuple from a sequence of generic tuples" + (`#2121 <https://github.com/Araq/Nim/issues/2121>`_) +- Fixed "nim check hangs with when" + (`#2123 <https://github.com/Araq/Nim/issues/2123>`_) +- Fixed "static[T] param in nested type resolve/caching issue" + (`#2125 <https://github.com/Araq/Nim/issues/2125>`_) +- Fixed "repr should display ``\0``" + (`#2124 <https://github.com/Araq/Nim/issues/2124>`_) +- Fixed "'nim check' never ends in case of recursive dependency " + (`#2051 <https://github.com/Araq/Nim/issues/2051>`_) +- Fixed "From macros: Error: unhandled exception: sons is not accessible" + (`#2167 <https://github.com/Araq/Nim/issues/2167>`_) +- Fixed "`fieldPairs` doesn't work inside templates" + (`#1902 <https://github.com/Araq/Nim/issues/1902>`_) +- Fixed "fields iterator misbehavior on break statement" + (`#2134 <https://github.com/Araq/Nim/issues/2134>`_) +- Fixed "Fix for compiler not building anymore since #c3244ef1ff" + (`#2193 <https://github.com/Araq/Nim/issues/2193>`_) +- Fixed "JSON parser fails in cpp output mode" + (`#2199 <https://github.com/Araq/Nim/issues/2199>`_) +- Fixed "macros.getType mishandles void return" + (`#2211 <https://github.com/Araq/Nim/issues/2211>`_) +- Fixed "Regression involving templates instantiated within generics" + (`#2215 <https://github.com/Araq/Nim/issues/2215>`_) +- Fixed ""Error: invalid type" for 'not nil' on generic type." + (`#2216 <https://github.com/Araq/Nim/issues/2216>`_) +- Fixed "--threads:on breaks async" + (`#2074 <https://github.com/Araq/Nim/issues/2074>`_) +- Fixed "Type mismatch not always caught, can generate bad code for C backend." + (`#2169 <https://github.com/Araq/Nim/issues/2169>`_) +- Fixed "Failed C compilation when storing proc to own type in object" + (`#2233 <https://github.com/Araq/Nim/issues/2233>`_) +- Fixed "Unknown line/column number in constant declaration type conversion error" + (`#2252 <https://github.com/Araq/Nim/issues/2252>`_) +- Fixed "Adding {.compile.} fails if nimcache already exists." + (`#2247 <https://github.com/Araq/Nim/issues/2247>`_) +- Fixed "Two different type names generated for a single type (C backend)" + (`#2250 <https://github.com/Araq/Nim/issues/2250>`_) +- Fixed "Ambigous call when it should not be" + (`#2229 <https://github.com/Araq/Nim/issues/2229>`_) +- Fixed "Make sure we can load root urls" + (`#2227 <https://github.com/Araq/Nim/issues/2227>`_) +- Fixed "Failure to slice a string with an int subrange type" + (`#794 <https://github.com/Araq/Nim/issues/794>`_) +- Fixed "documentation error" + (`#2205 <https://github.com/Araq/Nim/issues/2205>`_) +- Fixed "Code growth when using `const`" + (`#1940 <https://github.com/Araq/Nim/issues/1940>`_) +- Fixed "Instances of generic types confuse overload resolution" + (`#2220 <https://github.com/Araq/Nim/issues/2220>`_) +- Fixed "Compiler error when initializing sdl2's EventType" + (`#2316 <https://github.com/Araq/Nim/issues/2316>`_) +- Fixed "Parallel disjoint checking can't handle `<`, `items`, or arrays" + (`#2287 <https://github.com/Araq/Nim/issues/2287>`_) +- Fixed "Strings aren't copied in parallel loop" + (`#2286 <https://github.com/Araq/Nim/issues/2286>`_) +- Fixed "JavaScript compiler crash with tables" + (`#2298 <https://github.com/Araq/Nim/issues/2298>`_) +- Fixed "Range checker too restrictive" + (`#1845 <https://github.com/Araq/Nim/issues/1845>`_) +- Fixed "Failure to slice a string with an int subrange type" + (`#794 <https://github.com/Araq/Nim/issues/794>`_) +- Fixed "Remind user when compiling in debug mode" + (`#1868 <https://github.com/Araq/Nim/issues/1868>`_) +- Fixed "Compiler user guide has jumbled options/commands." + (`#1819 <https://github.com/Araq/Nim/issues/1819>`_) +- Fixed "using `method`: 1 in a objects constructor fails when compiling" + (`#1791 <https://github.com/Araq/Nim/issues/1791>`_) + 2014-12-29 Version 0.10.2 released ================================== diff --git a/web/ticker.txt b/web/ticker.txt index 724d29231..799246521 100644 --- a/web/ticker.txt +++ b/web/ticker.txt @@ -1,13 +1,13 @@ +<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> + <a class="news" href="news.html#Z2014-12-29-version-0-10-2-released"> <h4>Dec 29, 2014</h4> <p>Nim version 0.10.2 has been released!</p> </a> -<a class="news" href="news.html#Z2014-12-09-new-website-design"> - <h4>Dec 9, 2014</h4> - <p>The new website design and forum are now online!</p> -</a> - <a class="news" href="news.html#Z2014-02-11-nimrod-featured-in-dr-dobb-s-journal"> <h4>Feb 11, 2014</h4> <p>Nimrod featured in Dr. Dobb's Journal</p> diff --git a/web/website.ini b/web/website.ini index 6266f05bb..bb9f1b204 100644 --- a/web/website.ini +++ b/web/website.ini @@ -31,7 +31,7 @@ file: ticker.txt [Documentation] doc: "endb;intern;apis;lib;manual.txt;tut1;tut2;nimc;overview;filters" doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt" -doc: "nimfix.txt" +doc: "nimfix.txt;nimsuggest.txt" pdf: "manual.txt;lib;tut1;tut2;nimc;niminst;gc" srcdoc2: "system.nim" srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned" @@ -49,7 +49,7 @@ srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl;pure/fsmonitor" srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser" srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes" srcdoc2: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics" -srcdoc2: "impure/rdstdin" +srcdoc2: "impure/rdstdin;impure/dialogs" srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists" srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/encodings" srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies" @@ -60,7 +60,7 @@ srcdoc2: "packages/docutils/rst;packages/docutils/rstast" srcdoc2: "packages/docutils/rstgen;pure/logging;pure/asyncdispatch;pure/asyncnet" srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors;pure/future" srcdoc2: "pure/asyncfile" -srcdoc2: "pure/md5" +srcdoc2: "pure/md5;pure/rationals" srcdoc2: "posix/posix" srcdoc2: "pure/fenv" srcdoc2: "pure/basic2d;pure/basic3d" |