From 0dbec5a2789fefd32de29a8b04b2482a8da6d5ed Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 19 Jul 2014 13:56:42 +0200 Subject: [PATCH 001/409] Adds support for the ``.. code::`` rst directive. This modifies the existing ``.. code-block::`` to be treated as spec extension with a specific default language syntax. Also implements line numbering. --- lib/packages/docutils/rst.nim | 82 +++++++++++++++++++---- lib/packages/docutils/rstgen.nim | 110 +++++++++++++++++++++++++++---- 2 files changed, 167 insertions(+), 25 deletions(-) diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 23459ade6..153fe92c8 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -39,7 +39,8 @@ type meInvalidDirective, mwRedefinitionOfLabel, mwUnknownSubstitution, - mwUnsupportedLanguage + mwUnsupportedLanguage, + mwUnsupportedField TMsgHandler* = proc (filename: string, line, col: int, msgKind: TMsgKind, arg: string) {.nimcall.} ## what to do in case of an error @@ -55,7 +56,8 @@ const meInvalidDirective: "invalid directive: '$1'", mwRedefinitionOfLabel: "redefinition of label '$1'", mwUnknownSubstitution: "unknown substitution '$1'", - mwUnsupportedLanguage: "language '$1' not supported" + mwUnsupportedLanguage: "language '$1' not supported", + mwUnsupportedField: "field '$1' not supported" ] proc rstnodeToRefname*(n: PRstNode): string @@ -850,13 +852,13 @@ proc parseComment(p: var TRstParser): PRstNode = type TDirKind = enum # must be ordered alphabetically! - dkNone, dkAuthor, dkAuthors, dkCodeBlock, dkContainer, dkContents, + dkNone, dkAuthor, dkAuthors, dkCode, dkCodeBlock, dkContainer, dkContents, dkFigure, dkImage, dkInclude, dkIndex, dkRaw, dkTitle const - DirIds: array[0..11, string] = ["", "author", "authors", "code-block", - "container", "contents", "figure", "image", "include", "index", "raw", - "title"] + DirIds: array[0..12, string] = ["", "author", "authors", "code", + "code-block", "container", "contents", "figure", "image", "include", + "index", "raw", "title"] proc getDirKind(s: string): TDirKind = let i = find(DirIds, s) @@ -876,7 +878,10 @@ proc parseUntilNewline(p: var TRstParser, father: PRstNode) = of tkEof, tkIndent: break proc parseSection(p: var TRstParser, result: PRstNode) -proc parseField(p: var TRstParser): PRstNode = +proc parseField(p: var TRstParser): PRstNode = + ## Returns a parsed rnField node. + ## + ## rnField nodes have two children nodes, a rnFieldName and a rnFieldBody. result = newRstNode(rnField) var col = p.tok[p.idx].col var fieldname = newRstNode(rnFieldName) @@ -892,7 +897,11 @@ proc parseField(p: var TRstParser): PRstNode = add(result, fieldname) add(result, fieldbody) -proc parseFields(p: var TRstParser): PRstNode = +proc parseFields(p: var TRstParser): PRstNode = + ## Parses fields for a section or directive block. + ## + ## This proc may return nil if the parsing doesn't find anything of value, + ## otherwise it will return a node of rnFieldList type with children. result = nil var atStart = p.idx == 0 and p.tok[0].symbol == ":" if (p.tok[p.idx].kind == tkIndent) and (p.tok[p.idx + 1].symbol == ":") or @@ -908,6 +917,18 @@ proc parseFields(p: var TRstParser): PRstNode = else: break +proc getFieldValue*(n: PRstNode): string = + ## Returns the value of a specific ``rnField`` node. + ## + ## This proc will assert if the node is not of the expected type. The empty + ## string will be returned as a minimum. Any value in the rst will be + ## stripped form leading/trailing whitespace. + assert n.kind == rnField + assert n.len == 2 + assert n.sons[0].kind == rnFieldName + assert n.sons[1].kind == rnFieldBody + result = addNodes(n.sons[1]).strip + proc getFieldValue(n: PRstNode, fieldname: string): string = result = "" if n.sons[1] == nil: return @@ -1387,7 +1408,16 @@ type TDirFlags = set[TDirFlag] TSectionParser = proc (p: var TRstParser): PRstNode {.nimcall.} -proc parseDirective(p: var TRstParser, flags: TDirFlags): PRstNode = +proc parseDirective(p: var TRstParser, flags: TDirFlags): PRstNode = + ## Parses arguments and options for a directive block. + ## + ## A directive block will always have three sons: the arguments for the + ## directive (rnDirArg), the options (rnFieldList) and the block + ## (rnLineBlock). This proc parses the two first nodes, the block is left to + ## the outer `parseDirective` call. + ## + ## Both rnDirArg and rnFieldList children nodes might be nil, so you need to + ## check them before accessing. result = newRstNode(rnDirective) var args: PRstNode = nil var options: PRstNode = nil @@ -1421,6 +1451,9 @@ proc indFollows(p: TRstParser): bool = proc parseDirective(p: var TRstParser, flags: TDirFlags, contentParser: TSectionParser): PRstNode = + ## Returns a generic rnDirective tree. + ## + ## The children are rnDirArg, rnFieldList and rnLineBlock. Any might be nil. result = parseDirective(p, flags) if not isNil(contentParser) and indFollows(p): pushInd(p, p.tok[p.idx].ival) @@ -1474,7 +1507,19 @@ proc dirInclude(p: var TRstParser): PRstNode = # InternalError("Too many binary zeros in include file") result = parseDoc(q) -proc dirCodeBlock(p: var TRstParser): PRstNode = +proc dirCodeBlock(p: var TRstParser, nimrodExtension = false): PRstNode = + ## Parses a code block. + ## + ## Code blocks are rnDirective trees with a `kind` of rnCodeBlock. See the + ## description of ``parseDirective`` for further structure information. + ## + ## Code blocks can come in two forms, the standard `code directive + ## `_ and + ## the nimrod extension ``.. code-block::``. If the block is an extension, we + ## want the default language syntax highlighting to be Nimrod, so we create a + ## fake internal field to comminicate with the generator. The field is named + ## ``default-language``, which is unlikely to collide with a field specified + ## by any random rst input file. result = parseDirective(p, {hasArg, hasOptions}, parseLiteralBlock) var filename = strip(getFieldValue(result, "file")) if filename != "": @@ -1483,6 +1528,20 @@ proc dirCodeBlock(p: var TRstParser): PRstNode = var n = newRstNode(rnLiteralBlock) add(n, newRstNode(rnLeaf, readFile(path))) result.sons[2] = n + + # Extend the field block if we are using our custom extension. + if nimrodExtension: + # Create a field block if the input block didn't have any. + if result.sons[1].isNil: result.sons[1] = newRstNode(rnFieldList) + assert result.sons[1].kind == rnFieldList + # Hook the extra field and specify the Nimrod language as value. + var extraNode = newRstNode(rnField) + extraNode.add(newRstNode(rnFieldName)) + extraNode.add(newRstNode(rnFieldBody)) + extraNode.sons[0].add(newRstNode(rnLeaf, "default-language")) + extraNode.sons[1].add(newRstNode(rnLeaf, "Nimrod")) + result.sons[1].add(extraNode) + result.kind = rnCodeBlock proc dirContainer(p: var TRstParser): PRstNode = @@ -1566,7 +1625,8 @@ proc parseDotDot(p: var TRstParser): PRstNode = result = dirRaw(p) else: rstMessage(p, meInvalidDirective, d) - of dkCodeBlock: result = dirCodeBlock(p) + of dkCode: result = dirCodeBlock(p) + of dkCodeBlock: result = dirCodeBlock(p, nimrodExtension = true) of dkIndex: result = dirIndex(p) else: rstMessage(p, meInvalidDirective, d) popInd(p) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index fdbca4ca8..7d0847c10 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -24,7 +24,7 @@ ## generate `LaTeX documents `_ too. import strutils, os, hashes, strtabs, rstast, rst, highlite, tables, sequtils, - algorithm + algorithm, parseutils const HtmlExt = "html" @@ -63,6 +63,19 @@ type PDoc = var TRstGenerator ## Alias to type less. + CodeBlockParams = object ## Stores code block params. + numberLines: bool ## True if the renderer has to show line numbers. + startLine: int ## The starting line of the code block, by default 1. + langStr: string ## Input string used to specify the language. + lang: TSourceLanguage ## Type of highlighting, by default none. + + +proc init(p: var CodeBlockParams) = + ## Default initialisation of CodeBlockParams to sane values. + p.startLine = 1 + p.lang = langNone + p.langStr = "" + proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, config: PStringTable, filename: string, options: TRstParseOptions, @@ -761,26 +774,95 @@ proc renderSmiley(d: PDoc, n: PRstNode, result: var string) = height="17" hspace="2" vspace="2" />""", "\\includegraphics{$1}", [n.text]) +proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) = + ## Parses useful fields which can appear before a code block. + ## + ## This supports the special ``default-language`` internal string generated + ## by the ``rst`` module to communicate a specific default language. + case n.getArgument.toLower + of "number-lines": + params.numberLines = true + # See if the field has a parameter specifying a different line than 1. + var number: int + if parseInt(n.getFieldValue, number) > 0: + params.startLine = number + of "default-language": + params.langStr = n.getFieldValue.strip + params.lang = params.langStr.getSourceLanguage + else: + d.msgHandler(d.filename, 1, 0, mwUnsupportedField, n.getArgument) + +proc parseCodeBlockParams(d: PDoc, n: PRstNode): CodeBlockParams = + ## Iterates over all code block fields and returns processed params. + ## + ## Also processes the argument of the directive as the default language. This + ## is done last so as to override any internal communication field variables. + result.init + if n.isNil: + return + assert n.kind == rnCodeBlock + assert(not n.sons[2].isNil) + + # Parse the field list for rendering parameters if there are any. + if not n.sons[1].isNil: + for son in n.sons[1].sons: d.parseCodeBlockField(son, result) + + # Parse the argument and override the language. + result.langStr = strip(getArgument(n)) + if result.langStr != "": + result.lang = getSourceLanguage(result.langStr) + +proc buildLinesHTMLTable(params: CodeBlockParams, code: string): + tuple[beginTable, endTable: string] = + ## Returns the necessary tags to start/end a code block in HTML. + ## + ## If the numberLines has not been used, the tags will default to a simple + ##
 pair. Otherwise it will build a table and insert an initial column
+  ## with all the line numbers, which requires you to pass the `code` to detect
+  ## how many lines have to be generated (and starting at which point!).
+  if not params.numberLines:
+    result = ("
", "
") + return + + var codeLines = code.strip(leading = false).countLines + assert codeLines > 0 + result.beginTable = """
"""
+  var line = params.startLine
+  while codeLines > 0:
+    result.beginTable.add($line & "\n")
+    line.inc
+    codeLines.dec
+  result.beginTable.add("
")
+  result.endTable = "
" + proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) = + ## Renders a code block, appending it to `result`. + ## + ## If the code block uses the ``number-lines`` option, a table will be + ## generated with two columns, the first being a list of numbers and the + ## second the code block itself. The code block can use syntax highlighting, + ## which depends on the directive argument specified by the rst input, and + ## may also come from the parser through the internal ``default-language`` + ## option to differentiate between a plain code block and nimrod's code block + ## extension. + assert n.kind == rnCodeBlock if n.sons[2] == nil: return + var params = d.parseCodeBlockParams(n) var m = n.sons[2].sons[0] assert m.kind == rnLeaf - var langstr = strip(getArgument(n)) - var lang: TSourceLanguage - if langstr == "": - lang = langNimrod # default language - else: - lang = getSourceLanguage(langstr) - - dispA(d.target, result, "
", "\\begin{rstpre}\n", [])
-  if lang == langNone:
-    d.msgHandler(d.filename, 1, 0, mwUnsupportedLanguage, langstr)
+
+  let (blockStart, blockEnd) = params.buildLinesHTMLTable(m.text)
+
+  dispA(d.target, result, blockStart, "\\begin{rstpre}\n", [])
+  if params.lang == langNone:
+    if len(params.langStr) > 0:
+      d.msgHandler(d.filename, 1, 0, mwUnsupportedLanguage, params.langStr)
     result.add(m.text)
   else:
     var g: TGeneralTokenizer
     initGeneralTokenizer(g, m.text)
     while true: 
-      getNextToken(g, lang)
+      getNextToken(g, params.lang)
       case g.kind
       of gtEof: break 
       of gtNone, gtWhitespace: 
@@ -790,8 +872,8 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) =
           esc(d.target, substr(m.text, g.start, g.length+g.start-1)),
           tokenClassToStr[g.kind]])
     deinitGeneralTokenizer(g)
-  dispA(d.target, result, "
", "\n\\end{rstpre}\n") - + dispA(d.target, result, blockEnd, "\n\\end{rstpre}\n") + proc renderContainer(d: PDoc, n: PRstNode, result: var string) = var tmp = "" renderRstToOut(d, n.sons[2], tmp) From d935633eb69e3fce3e683537507268e29f5a5548 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 19 Jul 2014 14:11:22 +0200 Subject: [PATCH 002/409] Modifies docgen to support new warning message. --- compiler/docgen.nim | 1 + compiler/msgs.nim | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 4c9803401..ac0c3fbfd 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -41,6 +41,7 @@ proc compilerMsgHandler(filename: string, line, col: int, of mwRedefinitionOfLabel: k = warnRedefinitionOfLabel of mwUnknownSubstitution: k = warnUnknownSubstitutionX of mwUnsupportedLanguage: k = warnLanguageXNotSupported + of mwUnsupportedField: k = warnFieldXNotSupported globalError(newLineInfo(filename, line, col), k, arg) proc docgenFindFile(s: string): string {.procvar.} = diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 730cb9605..87c905a58 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -114,7 +114,8 @@ type warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit, warnDeprecated, warnConfigDeprecated, warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel, - warnUnknownSubstitutionX, warnLanguageXNotSupported, warnCommentXIgnored, + warnUnknownSubstitutionX, warnLanguageXNotSupported, + warnFieldXNotSupported, warnCommentXIgnored, warnNilStatement, warnAnalysisLoophole, warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode, warnEachIdentIsTuple, warnShadowIdent, @@ -375,6 +376,7 @@ const warnRedefinitionOfLabel: "redefinition of label \'$1\' [RedefinitionOfLabel]", warnUnknownSubstitutionX: "unknown substitution \'$1\' [UnknownSubstitutionX]", warnLanguageXNotSupported: "language \'$1\' not supported [LanguageXNotSupported]", + warnFieldXNotSupported: "field \'$1\' not supported [FieldXNotSupported]", warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]", warnNilStatement: "'nil' statement is deprecated; use an empty 'discard' statement instead [NilStmt]", warnAnalysisLoophole: "thread analysis incomplete due to unknown call '$1' [AnalysisLoophole]", @@ -409,11 +411,12 @@ const hintUser: "$1 [User]"] const - WarningsToStr*: array[0..26, string] = ["CannotOpenFile", "OctalEscape", + WarningsToStr*: array[0..27, string] = ["CannotOpenFile", "OctalEscape", "XIsNeverRead", "XmightNotBeenInit", "Deprecated", "ConfigDeprecated", "SmallLshouldNotBeUsed", "UnknownMagic", - "RedefinitionOfLabel", "UnknownSubstitutionX", "LanguageXNotSupported", + "RedefinitionOfLabel", "UnknownSubstitutionX", + "LanguageXNotSupported", "FieldXNotSupported", "CommentXIgnored", "NilStmt", "AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", "UnsafeCode", "EachIdentIsTuple", "ShadowIdent", From 078594cac6c79757566b337bcf53610c60e790bb Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 19 Jul 2014 14:36:47 +0200 Subject: [PATCH 003/409] Improves macro tutorial with hyperlinks and numbered lines. --- doc/tut2.txt | 101 +++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/doc/tut2.txt b/doc/tut2.txt index 1e23618e0..87f659ab7 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -752,9 +752,8 @@ variable number of arguments: debug(a[0], a[1], x) -The macro call expands to: +The macro call expands to:: -.. code-block:: nimrod write(stdout, "a[0]") write(stdout, ": ") writeln(stdout, a[0]) @@ -851,9 +850,9 @@ to be included along the program containing the license information:: The ``readCfgAtRuntime`` proc will open the given filename and return a ``TTable`` from the `tables module `_. The parsing of the file is done (without much care for handling invalid data or corner cases) using the -``splitLines`` proc from the `strutils module `_. There are many -things which can fail; mind the purpose is explaining how to make this run at -compile time, not how to properly implement a DRM scheme. +`splitLines proc from the strutils module `_. There +are many things which can fail; mind the purpose is explaining how to make +this run at compile time, not how to properly implement a DRM scheme. The reimplementation of this code as a compile time proc will allow us to get rid of the ``data.cfg`` file we would need to distribute along the binary, plus @@ -876,6 +875,8 @@ time string with the *generated source code*, which we then pass to the modified source code implementing the macro: .. code-block:: nimrod + :number-lines: + import macros, strutils macro readCfgAndBuildSource(cfgFilename: string): stmt = @@ -902,29 +903,31 @@ modified source code implementing the macro: echo cfglicenseKey echo cfgversion -The good news is not much has changed! First, we need to change the handling of -the input parameter. In the dynamic version the ``readCfgAtRuntime`` proc -receives a string parameter. However, in the macro version it is also declared -as string, but this is the *outside* interface of the macro. When the macro is -run, it actually gets a ``PNimrodNode`` object instead of a string, and we have -to call the ``strVal`` proc from the `macros module `_ to obtain -the string being passed in to the macro. +The good news is not much has changed! First, we need to change the handling +of the input parameter (line 3). In the dynamic version the +``readCfgAtRuntime`` proc receives a string parameter. However, in the macro +version it is also declared as string, but this is the *outside* interface of +the macro. When the macro is run, it actually gets a ``PNimrodNode`` object +instead of a string, and we have to call the `strVal proc +`_ (line 5) from the `macros module `_ to +obtain the string being passed in to the macro. -Second, we cannot use the ``readFile`` proc from the `system module -`_ due to FFI restriction at compile time. If we try to use this -proc, or any other which depends on FFI, the compiler will error with the -message ``cannot evaluate`` and a dump of the macro's source code, along with a -stack trace where the compiler reached before bailing out. We can get around -this limitation by using the ``slurp`` proc from the `system module -`_, which was precisely made for compilation time (just like -``gorge`` which executes an external program and captures its output). +Second, we cannot use the `readFile proc `_ from the +`system module `_ due to FFI restriction at compile time. If we +try to use this proc, or any other which depends on FFI, the compiler will +error with the message ``cannot evaluate`` and a dump of the macro's source +code, along with a stack trace where the compiler reached before bailing out. +We can get around this limitation by using the `slurp proc +`_ from the `system module `_, which was +precisely made for compilation time (just like `gorge `_ +which executes an external program and captures its output). -The interesting thing is that our macro does not return a runtime ``TTable`` -object. Instead, it builds up Nimrod source code into the ``source`` variable. -For each line of the configuration file a ``const`` variable will be generated. -To avoid conflicts we prefix these variables with ``cfg``. In essence, what the -compiler is doing is replacing the line calling the macro with the following -snippet of code: +The interesting thing is that our macro does not return a runtime `TTable +`_ object. Instead, it builds up Nimrod source code into +the ``source`` variable. For each line of the configuration file a ``const`` +variable will be generated (line 15). To avoid conflicts we prefix these +variables with ``cfg``. In essence, what the compiler is doing is replacing +the line calling the macro with the following snippet of code: .. code-block:: nimrod const cfgversion= "1.1" @@ -933,13 +936,14 @@ snippet of code: You can verify this yourself adding the line ``echo source`` somewhere at the end of the macro and compiling the program. Another difference is that instead -of calling the usual ``quit`` proc to abort (which we could still call) this -version calls the ``error`` proc. The ``error`` proc has the same behavior as -``quit`` but will dump also the source and file line information where the -error happened, making it easier for the programmer to find where compilation -failed. In this situation it would point to the line invoking the macro, but -**not** the line of ``data.cfg`` we are processing, that's something the macro -itself would need to control. +of calling the usual `quit proc `_ to abort (which we could +still call) this version calls the `error proc `_ (line +14). The ``error`` proc has the same behavior as ``quit`` but will dump also +the source and file line information where the error happened, making it +easier for the programmer to find where compilation failed. In this situation +it would point to the line invoking the macro, but **not** the line of +``data.cfg`` we are processing, that's something the macro itself would need +to control. Generating AST by hand @@ -947,11 +951,11 @@ Generating AST by hand To generate an AST we would need to intimately know the structures used by the Nimrod compiler exposed in the `macros module `_, which at first -look seems a daunting task. But we can use as helper shortcut the ``dumpTree`` -macro, which is used as a statement macro instead of an expression macro. -Since we know that we want to generate a bunch of ``const`` symbols we can -create the following source file and compile it to see what the compiler -*expects* from us: +look seems a daunting task. But we can use as helper shortcut the `dumpTree +macro `_, which is used as a statement macro instead of +an expression macro. Since we know that we want to generate a bunch of +``const`` symbols we can create the following source file and compile it to +see what the compiler *expects* from us: .. code-block:: nimrod import macros @@ -997,6 +1001,8 @@ with this knowledge, let's look at the finished version of the AST building macro: .. code-block:: nimrod + :number-lines: + import macros, strutils macro readCfgAndBuildAST(cfgFilename: string): stmt = @@ -1032,19 +1038,20 @@ Since we are building on the previous example generating source code, we will only mention the differences to it. Instead of creating a temporary ``string`` variable and writing into it source code as if it were written *by hand*, we use the ``result`` variable directly and create a statement list node -(``nnkStmtList``) which will hold our children. +(``nnkStmtList``) which will hold our children (line 7). For each input line we have to create a constant definition (``nnkConstDef``) and wrap it inside a constant section (``nnkConstSection``). Once these -variables are created, we fill them hierarchichally like the previous AST dump -tree showed: the constant definition is a child of the section definition, and -the constant definition has an identifier node, an empty node (we let the -compiler figure out the type), and a string literal with the value. +variables are created, we fill them hierarchichally (line 17) like the +previous AST dump tree showed: the constant definition is a child of the +section definition, and the constant definition has an identifier node, an +empty node (we let the compiler figure out the type), and a string literal +with the value. A last tip when writing a macro: if you are not sure the AST you are building looks ok, you may be tempted to use the ``dumpTree`` macro. But you can't use it *inside* the macro you are writting/debugging. Instead ``echo`` the string -generated by ``treeRepr``. If at the end of the this example you add ``echo -treeRepr(result)`` you should get the same output as using the ``dumpTree`` -macro, but of course you can call that at any point of the macro where you -might be having troubles. +generated by `treeRepr `_. If at the end of the this +example you add ``echo treeRepr(result)`` you should get the same output as +using the ``dumpTree`` macro, but of course you can call that at any point of +the macro where you might be having troubles. From 9c6d54dec6660985a02c9b59de578fd9aef1b7ee Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 19 Jul 2014 14:44:41 +0200 Subject: [PATCH 004/409] Hyperlinks quit related docstrings in system module. --- lib/system.nim | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 2fb08563a..1a9951ca1 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1006,11 +1006,11 @@ else: const QuitSuccess* = 0 - ## is the value that should be passed to ``quit`` to indicate + ## is the value that should be passed to `quit <#quit>`_ to indicate ## success. QuitFailure* = 1 - ## is the value that should be passed to ``quit`` to indicate + ## is the value that should be passed to `quit <#quit>`_ to indicate ## failure. var programResult* {.exportc: "nim_program_result".}: int @@ -1023,10 +1023,11 @@ proc quit*(errorcode: int = QuitSuccess) {. ## Stops the program immediately with an exit code. ## ## Before stopping the program the "quit procedures" are called in the - ## opposite order they were added with ``addQuitProc``. ``quit`` never - ## returns and ignores any exception that may have been raised by the quit - ## procedures. It does *not* call the garbage collector to free all the - ## memory, unless a quit procedure calls ``GC_collect``. + ## opposite order they were added with `addQuitProc <#addQuitProc>`_. + ## ``quit`` never returns and ignores any exception that may have been raised + ## by the quit procedures. It does *not* call the garbage collector to free + ## all the memory, unless a quit procedure calls `GC_fullCollect + ## <#GC_fullCollect>`_. ## ## The proc ``quit(QuitSuccess)`` is called implicitly when your nimrod ## program finishes without incident. A raised unhandled exception is @@ -1034,7 +1035,8 @@ proc quit*(errorcode: int = QuitSuccess) {. ## ## Note that this is a *runtime* call and using ``quit`` inside a macro won't ## have any compile time effect. If you need to stop the compiler inside a - ## macro, use the ``error`` or ``fatal`` pragmas. + ## macro, use the `error `_ or `fatal + ## `_ pragmas. template sysAssert(cond: bool, msg: string) = when defined(useSysAssert): @@ -1186,11 +1188,12 @@ proc toBiggestInt*(f: BiggestFloat): BiggestInt {. proc addQuitProc*(QuitProc: proc() {.noconv.}) {. importc: "atexit", header: "".} - ## adds/registers a quit procedure. Each call to ``addQuitProc`` - ## registers another quit procedure. Up to 30 procedures can be - ## registered. They are executed on a last-in, first-out basis - ## (that is, the last function registered is the first to be executed). - ## ``addQuitProc`` raises an EOutOfIndex if ``quitProc`` cannot be + ## Adds/registers a quit procedure. + ## + ## Each call to ``addQuitProc`` registers another quit procedure. Up to 30 + ## procedures can be registered. They are executed on a last-in, first-out + ## basis (that is, the last function registered is the first to be executed). + ## ``addQuitProc`` raises an EOutOfIndex exception if ``QuitProc`` cannot be ## registered. # Support for addQuitProc() is done by Ansi C's facilities here. From c0aaff028b17fcea0c8cd48b0e1fa46ba3b0f60e Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 19 Jul 2014 14:48:30 +0200 Subject: [PATCH 005/409] Hyperlinks slurp related docstrings in system module. --- lib/system.nim | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 1a9951ca1..f3a7de145 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2232,9 +2232,12 @@ when not defined(JS): #and not defined(NimrodVM): ## current file position is not at the beginning of the file. proc readFile*(filename: string): TaintedString {.tags: [FReadIO], gcsafe.} - ## Opens a file named `filename` for reading. Then calls `readAll` - ## and closes the file afterwards. Returns the string. - ## Raises an IO exception in case of an error. + ## Opens a file named `filename` for reading. + ## + ## Then calls `readAll <#readAll>`_ and closes the file afterwards. + ## Returns the string. Raises an IO exception in case of an error. If + ## you need to call this inside a compile time macro you can use + ## `staticRead <#staticRead>`_. proc writeFile*(filename, content: string) {.tags: [FWriteIO], gcsafe.} ## Opens a file named `filename` for writing. Then writes the @@ -2726,19 +2729,20 @@ proc `[]=`*[T](s: var seq[T], x: TSlice[int], b: openArray[T]) = spliceImpl(s, a, L, b) proc slurp*(filename: string): string {.magic: "Slurp".} - ## This is an alias for ``staticRead``. + ## This is an alias for `staticRead <#staticRead>`_. proc staticRead*(filename: string): string {.magic: "Slurp".} - ## Compile-time ``readFile`` proc for easy `resource`:idx: embedding: + ## Compile-time `readFile <#readFile>`_ proc for easy `resource`:idx: + ## embedding: ## ## .. code-block:: nimrod ## const myResource = staticRead"mydatafile.bin" ## - ## ``slurp`` is an alias for ``staticRead``. + ## `slurp <#slurp>`_ is an alias for ``staticRead``. proc gorge*(command: string, input = ""): string {. magic: "StaticExec".} = discard - ## This is an alias for ``staticExec``. + ## This is an alias for `staticExec <#staticExec>`_. proc staticExec*(command: string, input = ""): string {. magic: "StaticExec".} = discard @@ -2750,9 +2754,9 @@ proc staticExec*(command: string, input = ""): string {. ## const buildInfo = "Revision " & staticExec("git rev-parse HEAD") & ## "\nCompiled on " & staticExec("uname -v") ## - ## ``gorge`` is an alias for ``staticExec``. Note that you can use this proc - ## inside a pragma like `passC `_ or `passL - ## `_. + ## `gorge <#gorge>`_ is an alias for ``staticExec``. Note that you can use + ## this proc inside a pragma like `passC `_ or + ## `passL `_. proc `+=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} ## Increments an ordinal From b287f13d4a1b3347628b5b488a41d714587f407d Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 26 Jul 2014 14:39:01 +0200 Subject: [PATCH 006/409] Handles :file: option for code blocks to avoid warnings. --- lib/packages/docutils/rst.nim | 4 ++++ lib/packages/docutils/rstgen.nim | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 153fe92c8..9f8e9c153 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -1520,6 +1520,10 @@ proc dirCodeBlock(p: var TRstParser, nimrodExtension = false): PRstNode = ## fake internal field to comminicate with the generator. The field is named ## ``default-language``, which is unlikely to collide with a field specified ## by any random rst input file. + ## + ## As an extension this proc will process the ``file`` extension field and if + ## present will replace the code block with the contents of the referenced + ## file. result = parseDirective(p, {hasArg, hasOptions}, parseLiteralBlock) var filename = strip(getFieldValue(result, "file")) if filename != "": diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 7d0847c10..e62b627bd 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -786,6 +786,13 @@ proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) = var number: int if parseInt(n.getFieldValue, number) > 0: params.startLine = number + of "file": + # The ``file`` option is a Nimrod extension to the official spec, it acts + # like it would for other directives like ``raw`` or ``cvs-table``. This + # field is dealt with in ``rst.nim`` which replaces the existing block with + # the referenced file, so we only need to ignore it here to avoid incorrect + # warning messages. + discard of "default-language": params.langStr = n.getFieldValue.strip params.lang = params.langStr.getSourceLanguage From dbf9117c562601d6b571d964a6cb152e95fe8c4e Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 22 Aug 2014 23:54:26 +0200 Subject: [PATCH 007/409] the big renamefest: first steps --- compiler/ast.nim | 5 +- compiler/ccgstmts.nim | 12 +- compiler/condsyms.nim | 1 + compiler/lookups.nim | 91 +++++++------ compiler/magicsys.nim | 12 +- compiler/msgs.nim | 2 +- compiler/pragmas.nim | 39 ++++-- compiler/pretty.nim | 114 ++-------------- compiler/prettybase.nim | 59 ++++++++ compiler/semgnrc.nim | 4 +- compiler/sempass2.nim | 15 ++- compiler/transf.nim | 4 +- doc/exception_hierarchy_fragment.txt | 59 ++++---- doc/lib.txt | 60 ++++----- doc/manual.txt | 184 ++++++++++++------------- doc/nimrodc.txt | 192 +++++++++++++-------------- lib/packages/docutils/highlite.nim | 18 +-- lib/packages/docutils/rstgen.nim | 12 +- lib/system.nim | 2 +- lib/system/alloc.nim | 4 +- lib/system/ansi_c.nim | 4 +- lib/system/arithm.nim | 2 +- lib/system/assign.nim | 2 +- lib/system/atomics.nim | 5 +- lib/system/avltree.nim | 2 +- lib/system/cellsets.nim | 2 +- lib/system/cgprocs.nim | 2 +- lib/system/channels.nim | 2 +- lib/system/chcks.nim | 2 +- lib/system/debugger.nim | 4 +- lib/system/deepcopy.nim | 2 +- lib/system/dyncalls.nim | 2 +- lib/system/embedded.nim | 2 +- lib/system/endb.nim | 4 +- lib/system/excpt.nim | 10 +- lib/system/gc.nim | 2 +- lib/system/gc2.nim | 2 +- lib/system/gc_ms.nim | 4 +- lib/system/hti.nim | 2 +- lib/system/inclrtl.nim | 2 +- lib/system/jssys.nim | 4 +- lib/system/mmdisp.nim | 8 +- lib/system/profiler.nim | 4 +- lib/system/repr.nim | 2 +- lib/system/reprjs.nim | 2 +- lib/system/sets.nim | 2 +- lib/system/syslocks.nim | 2 +- lib/system/sysspawn.nim | 4 +- lib/system/sysstr.nim | 8 +- lib/system/threads.nim | 14 +- lib/system/timers.nim | 2 +- lib/system/widestrs.nim | 4 +- tests/parallel/tflowvar.nim | 22 ++- todo.txt | 5 + web/news.txt | 2 + web/question.txt | 4 +- 56 files changed, 529 insertions(+), 508 deletions(-) create mode 100644 compiler/prettybase.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index 7ad294695..63cab5998 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -501,7 +501,8 @@ type skStub, # symbol is a stub and not yet loaded from the ROD # file (it is loaded on demand, which may # mean: never) - skPackage # symbol is a package (used for canonicalization) + skPackage, # symbol is a package (used for canonicalization) + skAlias # an alias (needs to be resolved immediately) TSymKinds* = set[TSymKind] const @@ -872,7 +873,7 @@ const tyProc, tyString, tyError} ExportableSymKinds* = {skVar, skConst, skProc, skMethod, skType, skIterator, skClosureIterator, - skMacro, skTemplate, skConverter, skEnumField, skLet, skStub} + skMacro, skTemplate, skConverter, skEnumField, skLet, skStub, skAlias} PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16, nfDotSetter, nfDotField, nfIsRef} diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index eca026e12..0c3d35f7b 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -489,6 +489,8 @@ proc genBreakStmt(p: BProc, t: PNode) = proc getRaiseFrmt(p: BProc): string = if gCmd == cmdCompileToCpp: result = "throw NimException($1, $2);$n" + elif getCompilerProc("Exception") != nil: + result = "#raiseException((#Exception*)$1, $2);$n" else: result = "#raiseException((#E_Base*)$1, $2);$n" @@ -733,7 +735,10 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = i, length, blen: int genLineDir(p, t) exc = getTempName() - discard cgsym(p.module, "E_Base") + if getCompilerProc("Exception") != nil: + discard cgsym(p.module, "Exception") + else: + discard cgsym(p.module, "E_Base") add(p.nestedTryStmts, t) startBlock(p, "try {$n") expr(p, t.sons[0], d) @@ -815,7 +820,10 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = discard lists.includeStr(p.module.headerFiles, "") genLineDir(p, t) var safePoint = getTempName() - discard cgsym(p.module, "E_Base") + if getCompilerProc("Exception") != nil: + discard cgsym(p.module, "Exception") + else: + discard cgsym(p.module, "E_Base") linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint) linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint) linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index dc61d2f89..6b93b1c12 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -85,6 +85,7 @@ proc initDefines*() = defineSymbol("nimnewshared") defineSymbol("nimrequiresnimframe") defineSymbol("nimparsebiggestfloatmagic") + defineSymbol("nimalias") # add platform specific symbols: for c in low(CPU)..high(CPU): diff --git a/compiler/lookups.nim b/compiler/lookups.nim index aee64f52f..9fecdba6b 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ import intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread, - renderer, wordrecg, idgen + renderer, wordrecg, idgen, prettybase proc ensureNoMissingOrUnusedSymbols(scope: PScope) @@ -65,6 +65,17 @@ iterator walkScopes*(scope: PScope): PScope = yield current current = current.parent +proc skipAlias*(s: PSym; n: PNode): PSym = + if s == nil or s.kind != skAlias: + result = s + else: + result = s.owner + if gCmd == cmdPretty: + prettybase.replaceDeprecated(n.info, s, result) + else: + message(n.info, warnDeprecated, "use " & result.name.s & " instead; " & + s.name.s) + proc localSearchInScope*(c: PContext, s: PIdent): PSym = result = strTableGet(c.currentScope.symbols, s) @@ -183,15 +194,15 @@ proc lookUp*(c: PContext, n: PNode): PSym = # Looks up a symbol. Generates an error in case of nil. case n.kind of nkIdent: - result = searchInScopes(c, n.ident) - if result == nil: + result = searchInScopes(c, n.ident).skipAlias(n) + if result == nil: localError(n.info, errUndeclaredIdentifier, n.ident.s) result = errorSym(c, n) of nkSym: result = n.sym of nkAccQuoted: var ident = considerQuotedIdent(n) - result = searchInScopes(c, ident) + result = searchInScopes(c, ident).skipAlias(n) if result == nil: localError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) @@ -210,32 +221,32 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerQuotedIdent(n) - result = searchInScopes(c, ident) - if result == nil and checkUndeclared in flags: + result = searchInScopes(c, ident).skipAlias(n) + if result == nil and checkUndeclared in flags: localError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) - elif checkAmbiguity in flags and result != nil and - contains(c.ambiguousSymbols, result.id): + elif checkAmbiguity in flags and result != nil and + contains(c.ambiguousSymbols, result.id): localError(n.info, errUseQualifier, ident.s) of nkSym: result = n.sym - if checkAmbiguity in flags and contains(c.ambiguousSymbols, result.id): + if checkAmbiguity in flags and contains(c.ambiguousSymbols, result.id): localError(n.info, errUseQualifier, n.sym.name.s) - of nkDotExpr: + of nkDotExpr: result = nil var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared}) - if (m != nil) and (m.kind == skModule): + if m != nil and m.kind == skModule: var ident: PIdent = nil - if n.sons[1].kind == nkIdent: + if n.sons[1].kind == nkIdent: ident = n.sons[1].ident - elif n.sons[1].kind == nkAccQuoted: + elif n.sons[1].kind == nkAccQuoted: ident = considerQuotedIdent(n.sons[1]) - if ident != nil: - if m == c.module: - result = strTableGet(c.topLevelScope.symbols, ident) - else: - result = strTableGet(m.tab, ident) - if result == nil and checkUndeclared in flags: + if ident != nil: + if m == c.module: + result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n) + else: + result = strTableGet(m.tab, ident).skipAlias(n) + if result == nil and checkUndeclared in flags: localError(n.sons[1].info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n.sons[1]) elif n.sons[1].kind == nkSym: @@ -256,7 +267,7 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = o.scope = c.currentScope o.mode = oimNoQualifier while true: - result = initIdentIter(o.it, o.scope.symbols, ident) + result = initIdentIter(o.it, o.scope.symbols, ident).skipAlias(n) if result != nil: break else: @@ -277,11 +288,12 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = if ident != nil: if o.m == c.module: # a module may access its private members: - result = initIdentIter(o.it, c.topLevelScope.symbols, ident) + result = initIdentIter(o.it, c.topLevelScope.symbols, + ident).skipAlias(n) o.mode = oimSelfModule - else: - result = initIdentIter(o.it, o.m.tab, ident) - else: + else: + result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n) + else: localError(n.sons[1].info, errIdentifierExpected, renderTree(n.sons[1])) result = errorSym(c, n.sons[1]) @@ -307,18 +319,18 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = result = nil of oimNoQualifier: if o.scope != nil: - result = nextIdentIter(o.it, o.scope.symbols) + result = nextIdentIter(o.it, o.scope.symbols).skipAlias(n) while result == nil: o.scope = o.scope.parent if o.scope == nil: break - result = initIdentIter(o.it, o.scope.symbols, o.it.name) + result = initIdentIter(o.it, o.scope.symbols, o.it.name).skipAlias(n) # BUGFIX: o.it.name <-> n.ident else: result = nil of oimSelfModule: - result = nextIdentIter(o.it, c.topLevelScope.symbols) + result = nextIdentIter(o.it, c.topLevelScope.symbols).skipAlias(n) of oimOtherModule: - result = nextIdentIter(o.it, o.m.tab) + result = nextIdentIter(o.it, o.m.tab).skipAlias(n) of oimSymChoice: if o.symChoiceIndex < sonsLen(n): result = n.sons[o.symChoiceIndex].sym @@ -329,31 +341,18 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = o.mode = oimSymChoiceLocalLookup o.scope = c.currentScope result = firstIdentExcluding(o.it, o.scope.symbols, - n.sons[0].sym.name, o.inSymChoice) + n.sons[0].sym.name, o.inSymChoice).skipAlias(n) while result == nil: o.scope = o.scope.parent if o.scope == nil: break result = firstIdentExcluding(o.it, o.scope.symbols, - n.sons[0].sym.name, o.inSymChoice) + n.sons[0].sym.name, o.inSymChoice).skipAlias(n) of oimSymChoiceLocalLookup: - result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice) + result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n) while result == nil: o.scope = o.scope.parent if o.scope == nil: break result = firstIdentExcluding(o.it, o.scope.symbols, - n.sons[0].sym.name, o.inSymChoice) + n.sons[0].sym.name, o.inSymChoice).skipAlias(n) if result != nil and result.kind == skStub: loadStub(result) - -when false: - proc qualifiedLookUpPreferImmediate*(c: PContext, n: PNode, - flags = {checkUndeclared}): PSym = - var o: TOverloadIter - result = initOverloadIter(o, c, n) - var a = result - while a != nil: - if sfImmediate in a.flags: return a - a = nextOverloadIter(o, c, n) - if result == nil and checkUndeclared in flags: - localError(n.info, errUndeclaredIdentifier, n.considerQuotedIdent.s) - result = errorSym(c, n) diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index 475326161..a794253df 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -44,6 +44,7 @@ proc getSysSym(name: string): PSym = result = newSym(skError, getIdent(name), systemModule, systemModule.info) result.typ = newType(tyError, systemModule) if result.kind == skStub: loadStub(result) + if result.kind == skAlias: result = result.owner proc getSysMagic*(name: string, m: TMagic): PSym = var ti: TIdentIter @@ -165,13 +166,14 @@ proc setIntLitType*(result: PNode) = proc getCompilerProc(name: string): PSym = var ident = getIdent(name, hashIgnoreStyle(name)) result = strTableGet(compilerprocs, ident) - if result == nil: + if result == nil: result = strTableGet(rodCompilerprocs, ident) - if result != nil: + if result != nil: strTableAdd(compilerprocs, result) if result.kind == skStub: loadStub(result) - -proc registerCompilerProc(s: PSym) = + if result.kind == skAlias: result = result.owner + +proc registerCompilerProc(s: PSym) = strTableAdd(compilerprocs, s) proc finishSystem(tab: TStrTable) = discard diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 730cb9605..cd5b34194 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -368,7 +368,7 @@ const warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]", warnXIsNeverRead: "\'$1\' is never read [XIsNeverRead]", warnXmightNotBeenInit: "\'$1\' might not have been initialized [XmightNotBeenInit]", - warnDeprecated: "\'$1\' is deprecated [Deprecated]", + warnDeprecated: "$1 is deprecated [Deprecated]", warnConfigDeprecated: "config file '$1' is deprecated [ConfigDeprecated]", warnSmallLshouldNotBeUsed: "\'l\' should not be used as an identifier; may look like \'1\' (one) [SmallLshouldNotBeUsed]", warnUnknownMagic: "unknown magic \'$1\' might crash the compiler [UnknownMagic]", diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 024401b86..24b2f6750 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -45,7 +45,7 @@ const wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated, wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto, - wInjectStmt} + wInjectStmt, wDeprecated} lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, @@ -542,6 +542,27 @@ proc typeBorrow(sym: PSym, n: PNode) = localError(n.info, "a type can only borrow `.` for now") incl(sym.typ.flags, tfBorrowDot) +proc markCompilerProc(s: PSym) = + makeExternExport(s, "$1", s.info) + incl(s.flags, sfCompilerProc) + incl(s.flags, sfUsed) + registerCompilerProc(s) + +proc deprecatedStmt(c: PContext; pragma: PNode) = + let pragma = pragma[1] + if pragma.kind != nkBracket: + localError(pragma.info, "list of key:value pairs expected"); return + for n in pragma: + if n.kind in {nkExprColonExpr, nkExprEqExpr}: + let dest = qualifiedLookUp(c, n[1]) + let src = considerQuotedIdent(n[0]) + let alias = newSym(skAlias, src, dest, n[0].info) + incl(alias.flags, sfExported) + if sfCompilerProc in dest.flags: markCompilerProc(alias) + addInterfaceDecl(c, alias) + else: + localError(n.info, "key:value pair expected") + proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, validPragmas: TSpecialWords): bool = var it = n.sons[i] @@ -648,17 +669,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, processDynLib(c, it, sym) of wCompilerproc: noVal(it) # compilerproc may not get a string! - if sfFromGeneric notin sym.flags: - makeExternExport(sym, "$1", it.info) - incl(sym.flags, sfCompilerProc) - incl(sym.flags, sfUsed) # suppress all those stupid warnings - registerCompilerProc(sym) - of wProcVar: + if sfFromGeneric notin sym.flags: markCompilerProc(sym) + of wProcVar: noVal(it) incl(sym.flags, sfProcvar) - of wDeprecated: - noVal(it) - if sym != nil: incl(sym.flags, sfDeprecated) + of wDeprecated: + if it.kind == nkExprColonExpr: deprecatedStmt(c, it) + elif sym != nil: incl(sym.flags, sfDeprecated) else: incl(c.module.flags, sfDeprecated) of wVarargs: noVal(it) diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 17311f9e6..8d20d205b 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,41 +8,19 @@ # ## This module implements the code "prettifier". This is part of the toolchain -## to convert Nimrod code into a consistent style. +## to convert Nim code into a consistent style. import strutils, os, options, ast, astalgo, msgs, ropes, idents, passes, - intsets, strtabs, semdata - -const - removeTP = false # when true, "nimrod pretty" converts TTyp to Typ. + intsets, strtabs, semdata, prettybase type TGen = object of TPassContext module*: PSym PGen = ref TGen - - TSourceFile = object - lines: seq[string] - dirty: bool - fullpath: string var - gSourceFiles: seq[TSourceFile] = @[] gCheckExtern: bool - rules: PStringTable - -proc loadFile(info: TLineInfo) = - let i = info.fileIndex - if i >= gSourceFiles.len: - gSourceFiles.setLen(i+1) - if gSourceFiles[i].lines.isNil: - gSourceFiles[i].lines = @[] - let path = info.toFullPath - gSourceFiles[i].fullpath = path - # we want to die here for EIO: - for line in lines(path): - gSourceFiles[i].lines.add(line) proc overwriteFiles*() = let overWrite = options.getConfigVar("pretty.overwrite").normalize == "on" @@ -78,9 +56,6 @@ proc beautifyName(s: string, k: TSymKind): string = case k of skType, skGenericParam: # Types should start with a capital unless builtins like 'int' etc.: - when removeTP: - if s[0] == 'T' and s[1] in {'A'..'Z'}: - i = 1 if s =~ ["int", "uint", "cint", "cuint", "clong", "cstring", "string", "char", "byte", "bool", "openArray", "seq", "array", "void", "pointer", "float", "csize", "cdouble", "cchar", "cschar", @@ -120,26 +95,10 @@ proc checkStyle*(info: TLineInfo, s: string, k: TSymKind) = if s != beau: message(info, errGenerated, "name should be: " & beau) -const - Letters = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'} - -proc identLen(line: string, start: int): int = - while start+result < line.len and line[start+result] in Letters: - inc result - -proc differ(line: string, a, b: int, x: string): bool = - let y = line[a..b] - result = cmpIgnoreStyle(y, x) == 0 and y != x - when false: - var j = 0 - for i in a..b: - if line[i] != x[j]: return true - inc j - return false - proc checkDef*(n: PNode; s: PSym) = # operators stay as they are: - if s.kind in {skResult, skTemp} or s.name.s[0] notin Letters: return + if s.kind in {skResult, skTemp} or s.name.s[0] notin prettybase.Letters: + return if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return if {sfImportc, sfExportc} * s.flags == {} or gCheckExtern: @@ -155,7 +114,8 @@ proc checkUse*(info: TLineInfo; s: PSym) = # for consistency # operators stay as they are: - if s.kind in {skResult, skTemp} or s.name.s[0] notin Letters: return + if s.kind in {skResult, skTemp} or s.name.s[0] notin prettybase.Letters: + return if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return let newName = s.name.s @@ -165,61 +125,17 @@ proc checkUse*(info: TLineInfo; s: PSym) = var first = min(info.col.int, line.len) if first < 0: return #inc first, skipIgnoreCase(line, "proc ", first) - while first > 0 and line[first-1] in Letters: dec first + while first > 0 and line[first-1] in prettybase.Letters: dec first if first < 0: return if line[first] == '`': inc first let last = first+identLen(line, first)-1 if differ(line, first, last, newName): # last-first+1 != newName.len or - var x = line.substr(0, first-1) & newName & line.substr(last+1) - when removeTP: - # the WinAPI module is full of 'TX = X' which after the substitution - # becomes 'X = X'. We remove those lines: - if x.match(peg"\s* {\ident} \s* '=' \s* y$1 ('#' .*)?"): - x = "" - + var x = line.substr(0, first-1) & newName & line.substr(last+1) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true -when false: - var cannotRename = initIntSet() - - proc beautifyName(s: string, k: TSymKind): string = - let allUpper = allCharsInSet(s, {'A'..'Z', '0'..'9', '_'}) - result = newStringOfCap(s.len) - var i = 0 - case k - of skType, skGenericParam: - # skip leading 'T' - when removeTP: - if s[0] == 'T' and s[1] in {'A'..'Z'}: - i = 1 - if s =~ ["int", "uint", "cint", "cuint", "clong", "cstring", "string", - "char", "byte", "bool", "openArray", "seq", "array", "void", - "pointer", "float", "csize", "cdouble", "cchar", "cschar", - "cshort", "cu"]: - result.add s[i] - else: - result.add toUpper(s[i]) - of skConst, skEnumField: - # for 'const' we keep how it's spelt; either upper case or lower case: - result.add s[0] - else: - # as a special rule, don't transform 'L' to 'l' - if s.len == 1 and s[0] == 'L': result.add 'L' - else: result.add toLower(s[0]) - inc i - while i < s.len: - if s[i] == '_': - inc i - result.add toUpper(s[i]) - elif allUpper: - result.add toLower(s[i]) - else: - result.add s[i] - inc i - proc check(c: PGen, n: PNode) = case n.kind of nkSym: checkUse(n.info, n.sym) @@ -264,18 +180,6 @@ proc myOpen(module: PSym): PPassContext = g.module = module gCheckExtern = options.getConfigVar("pretty.checkextern").normalize == "on" result = g - if rules.isNil: - rules = newStringTable(modeStyleInsensitive) - when removeTP: - # XXX activate when the T/P stuff is deprecated - let path = joinPath([getPrefixDir(), "config", "rename.rules.cfg"]) - for line in lines(path): - if line.len > 0: - let colon = line.find(':') - if colon > 0: - rules[line.substr(0, colon-1)] = line.substr(colon+1) - else: - rules[line] = line const prettyPass* = makePass(open = myOpen, process = processSym) diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim new file mode 100644 index 000000000..581114441 --- /dev/null +++ b/compiler/prettybase.nim @@ -0,0 +1,59 @@ +# +# +# The Nim Compiler +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +import ast, msgs, strutils + +type + TSourceFile* = object + lines*: seq[string] + dirty*: bool + fullpath*: string + +var + gSourceFiles*: seq[TSourceFile] = @[] + +proc loadFile*(info: TLineInfo) = + let i = info.fileIndex + if i >= gSourceFiles.len: + gSourceFiles.setLen(i+1) + if gSourceFiles[i].lines.isNil: + gSourceFiles[i].lines = @[] + let path = info.toFullPath + gSourceFiles[i].fullpath = path + # we want to die here for EIO: + for line in lines(path): + gSourceFiles[i].lines.add(line) + +const + Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'} + +proc identLen*(line: string, start: int): int = + while start+result < line.len and line[start+result] in Letters: + inc result + +proc differ*(line: string, a, b: int, x: string): bool = + let y = line[a..b] + result = cmpIgnoreStyle(y, x) == 0 and y != x + +proc replaceDeprecated*(info: TlineInfo; oldSym, newSym: PSym) = + loadFile(info) + + let line = gSourceFiles[info.fileIndex].lines[info.line-1] + var first = min(info.col.int, line.len) + if first < 0: return + #inc first, skipIgnoreCase(line, "proc ", first) + while first > 0 and line[first-1] in Letters: dec first + if first < 0: return + if line[first] == '`': inc first + + let last = first+identLen(line, first)-1 + if cmpIgnoreStyle(line[first..last], oldSym.name.s) == 0: + var x = line.substr(0, first-1) & newSym.name.s & line.substr(last+1) + system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) + gSourceFiles[info.fileIndex].dirty = true diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 934434951..224168528 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -70,7 +70,7 @@ proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags, ctx: var TIntSet): PNode = result = n let ident = considerQuotedIdent(n) - var s = searchInScopes(c, ident) + var s = searchInScopes(c, ident).skipAlias(n) if s == nil: if ident.id notin ctx and withinMixin notin flags: localError(n.info, errUndeclaredIdentifier, ident.s) @@ -100,7 +100,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, result = n let n = n[1] let ident = considerQuotedIdent(n) - var s = searchInScopes(c, ident) + var s = searchInScopes(c, ident).skipAlias(n) if s != nil and s.kind in routineKinds: if withinBind in flags: result = newDot(result, symChoice(c, n, s, scClosed)) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index acc2425f1..332b74155 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -130,20 +130,27 @@ proc addToIntersection(inter: var TIntersection, s: int) = proc throws(tracked, n: PNode) = if n.typ == nil or n.typ.kind != tyError: tracked.add n - + +proc getEbase(): PType = + result = if getCompilerProc("Exception") != nil: sysTypeFromName"Exception" + else: sysTypeFromName"E_Base" + proc excType(n: PNode): PType = # reraise is like raising E_Base: - let t = if n.kind == nkEmpty: sysTypeFromName"E_Base" else: n.typ + let t = if n.kind == nkEmpty: getEbase() else: n.typ result = skipTypes(t, skipPtrs) proc createRaise(n: PNode): PNode = result = newNode(nkType) - result.typ = sysTypeFromName"E_Base" + result.typ = getEbase() if not n.isNil: result.info = n.info proc createTag(n: PNode): PNode = result = newNode(nkType) - result.typ = sysTypeFromName"TEffect" + if getCompilerProc("RootEffect") != nil: + result.typ = sysTypeFromName"RootEffect" + else: + result.typ = sysTypeFromName"TEffect" if not n.isNil: result.info = n.info proc createAnyGlobal(n: PNode): PNode = diff --git a/compiler/transf.nim b/compiler/transf.nim index b9b06675e..00fe03ab6 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -782,8 +782,8 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode = # result = lambdalifting.liftIterator(prc, result) incl(result.flags, nfTransf) when useEffectSystem: trackProc(prc, result) - if prc.name.s == "testbody": - echo renderTree(result) + #if prc.name.s == "testbody": + # echo renderTree(result) proc transformStmt*(module: PSym, n: PNode): PNode = if nfTransf in n.flags: diff --git a/doc/exception_hierarchy_fragment.txt b/doc/exception_hierarchy_fragment.txt index 6ca68921f..f4a419fc4 100644 --- a/doc/exception_hierarchy_fragment.txt +++ b/doc/exception_hierarchy_fragment.txt @@ -1,31 +1,28 @@ -* `E_Base `_ - * `EAccessViolation `_ - * `EArithmetic `_ - * `EDivByZero `_ - * `EOverflow `_ - * `EAssertionFailed `_ - * `EAsynch `_ - * `EControlC `_ - * `EDeadThread `_ - * `EFloatingPoint `_ - * `EFloatDivByZero `_ - * `EFloatInexact `_ - * `EFloatInvalidOp `_ - * `EFloatOverflow `_ - * `EFloatUnderflow `_ - * `EInvalidField `_ - * `EInvalidIndex `_ - * `EInvalidObjectAssignment `_ - * `EInvalidObjectConversion `_ - * `EInvalidValue `_ - * `EInvalidKey `_ - * `ENoExceptionToReraise `_ - * `EOutOfRange `_ - * `ESynch `_ - * `EOutOfMemory `_ - * `EResourceExhausted `_ - * `EStackOverflow `_ - * `ESystem `_ - * `EIO `_ - * `EOS `_ - * `EInvalidLibrary `_ +* `Exception `_ + * `AccessViolationError `_ + * `ArithmeticError `_ + * `DivByZeroError `_ + * `OverflowError `_ + * `AssertionError `_ + * `DeadThreadError `_ + * `FloatingPointError `_ + * `FloatDivByZeroError `_ + * `FloatInexactError `_ + * `FloatInvalidOpError `_ + * `FloatOverflowError `_ + * `FloatUnderflowError `_ + * `FieldError `_ + * `IndexError `_ + * `ObjectAssignmentError `_ + * `ObjectConversionError `_ + * `ValueError `_ + * `KeyError `_ + * `ReraiseError `_ + * `RangeError `_ + * `OutOfMemoryError `_ + * `ResourceExhaustedError `_ + * `StackOverflowError `_ + * `SystemError `_ + * `IOError `_ + * `OSError `_ + * `LibraryError `_ diff --git a/doc/lib.txt b/doc/lib.txt index 26ea1b735..a29e32429 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -1,15 +1,15 @@ -======================= -Nimrod Standard Library -======================= +==================== +Nim Standard Library +==================== :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: "The good thing about reinventing the wheel is that you can get a round one." -Though the Nimrod Standard Library is still evolving, it is already quite +Though the Nim Standard Library is still evolving, it is already quite usable. It is divided into *pure libraries*, *impure libraries* and *wrappers*. Pure libraries do not depend on any external ``*.dll`` or ``lib*.so`` binary @@ -19,7 +19,7 @@ low-level interface to a C library. Read this `document `_ for a quick overview of the API design. The `bottom <#babel>`_ of this page includes a list of 3rd party packages -created by the Nimrod community. These packages are a useful addition to the +created by the Nim community. These packages are a useful addition to the modules in the standard library. @@ -41,27 +41,27 @@ Core of ``system``, but an extra import. * `threads `_ - Nimrod thread support. **Note**: This is part of the system module. Do not + Nim thread support. **Note**: This is part of the system module. Do not import it explicitly. * `channels `_ - Nimrod 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 and condition variables for Nimrod. + Locks and condition variables for Nim. * `macros `_ - Contains the AST API and documentation of Nimrod for writing macros. + Contains the AST API and documentation of Nim for writing macros. * `typeinfo `_ - Provides (unsafe) access to Nimrod's run time type information. + Provides (unsafe) access to Nim's run time type information. * `typetraits `_ This module defines compile-time reflection procs for working with types. * `actors `_ - Actor support for Nimrod; implemented as a layer on top of the threads and + Actor support for Nim; implemented as a layer on top of the threads and channels modules. @@ -71,11 +71,11 @@ Collections and algorithms * `algorithm `_ Implements some common generic algorithms like sort or binary search. * `tables `_ - Nimrod hash table support. Contains tables, ordered tables and count tables. + Nim hash table support. Contains tables, ordered tables and count tables. * `sets `_ - Nimrod hash and bit set support. + Nim hash and bit set support. * `lists `_ - Nimrod linked list support. Contains singly and doubly linked lists and + Nim linked list support. Contains singly and doubly linked lists and circular lists ("rings"). * `queues `_ Implementation of a queue. The underlying implementation uses a ``seq``. @@ -153,11 +153,11 @@ Generic Operating System Services * `streams `_ This module provides a stream interface and two implementations thereof: the `PFileStream` and the `PStringStream` which implement the stream - interface for Nimrod file objects (`TFile`) and strings. Other modules + interface for Nim file objects (`TFile`) and strings. Other modules may provide other implementations for this standard stream interface. * `marshal `_ - Contains procs for serialization and deseralization of arbitrary Nimrod + Contains procs for serialization and deseralization of arbitrary Nim data structures. * `terminal `_ @@ -273,7 +273,7 @@ Parsers parser. The configuration file's syntax is similar to the Windows ``.ini`` format, but much more powerful, as it is not a line based parser. String literals, raw string literals and triple quote string literals are supported - as in the Nimrod programming language. + as in the Nim programming language. * `parsexml `_ The ``parsexml`` module implements a simple high performance XML/HTML parser. @@ -340,7 +340,7 @@ Cryptography and Hashing * `hashes `_ This module implements efficient computations of hash values for diverse - Nimrod types. + Nim types. * `md5 `_ This module implements the MD5 checksum algorithm. @@ -353,7 +353,7 @@ Multimedia support ------------------ * `colors `_ - This module implements color handling for Nimrod. It is used by + This module implements color handling for Nim. It is used by the ``graphics`` module. @@ -426,12 +426,12 @@ Other ----- * `graphics `_ - This module implements graphical output for Nimrod; the current + This module implements graphical output for Nim; the current implementation uses SDL but the interface is meant to support multiple backends some day. * `dialogs `_ - This module implements portable dialogs for Nimrod; the implementation + This module implements portable dialogs for Nim; the implementation builds on the GTK interface. On Windows, native dialogs are shown if appropriate. @@ -444,7 +444,7 @@ Other * `ssl `_ This module provides an easy to use sockets-style - Nimrod interface to the OpenSSL library. + Nim interface to the OpenSSL library. * `rdstdin `_ This module contains code for reading from `stdin`:idx:. On UNIX the GNU @@ -532,7 +532,7 @@ Database support * `odbcsql `_ interface to the ODBC driver. * `sphinx `_ - Nimrod wrapper for ``sphinx``. + Nim wrapper for ``sphinx``. XML Processing @@ -578,15 +578,15 @@ Scientific computing Babel ==================== -Babel is a package manager for the Nimrod programming language. +Babel is a package manager for the Nim programming language. For instructions on how to install Babel packages see -`its README `_. +`its README `_. Official packages ----------------- These packages are officially supported and will therefore be continually -maintained to ensure that they work with the latest versions of the Nimrod +maintained to ensure that they work with the latest versions of the Nim compiler. .. raw:: html @@ -597,9 +597,9 @@ compiler. Unofficial packages ------------------- -These packages have been developed by independent Nimrod developers and as +These packages have been developed by independent Nim developers and as such may not always be up to date with the latest developments in the -Nimrod programming language. +Nim programming language. .. raw:: html @@ -607,4 +607,4 @@ Nimrod programming language. babelpkglist.js or have javascript disabled in your browser. - + diff --git a/doc/manual.txt b/doc/manual.txt index 89a417fb2..d18ede409 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -1,9 +1,9 @@ -============= -Nimrod Manual -============= +========== +Nim Manual +========== :Authors: Andreas Rumpf, Zahary Karadjov -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -17,11 +17,11 @@ Nimrod Manual About this document =================== -**Note**: This document is a draft! Several of Nimrod's features need more +**Note**: This document is a draft! Several of Nim's features need more precise wording. This manual will evolve into a proper specification some day. -This document describes the lexis, the syntax, and the semantics of Nimrod. +This document describes the lexis, the syntax, and the semantics of Nim. The language constructs are explained using an extended BNF, in which ``(a)*`` means 0 or more ``a``'s, ``a+`` means 1 or more ``a``'s, and @@ -48,14 +48,14 @@ and ``a ^* b`` is short for ``(a (b a)*)?``. Example:: arrayConstructor = '[' expr ^* ',' ']' -Other parts of Nimrod - like scoping rules or runtime semantics are only +Other parts of Nim - like scoping rules or runtime semantics are only described in an informal manner for now. Definitions =========== -A Nimrod program specifies a computation that acts on a memory consisting of +A Nim program specifies a computation that acts on a memory consisting of components called `locations`:idx:. A variable is basically a name for a location. Each variable and location is of a certain `type`:idx:. The variable's type is called `static type`:idx:, the location's type is called @@ -107,7 +107,7 @@ Lexical Analysis Encoding -------- -All Nimrod source files are in the UTF-8 encoding (or its ASCII subset). Other +All Nim source files are in the UTF-8 encoding (or its ASCII subset). Other encodings are not supported. Any of the standard platform line termination sequences can be used - the Unix form using ASCII LF (linefeed), the Windows form using the ASCII sequence CR LF (return followed by linefeed), or the old @@ -118,13 +118,13 @@ used equally, regardless of platform. Indentation ----------- -Nimrod's standard grammar describes an `indentation sensitive`:idx: language. +Nim's standard grammar describes an `indentation sensitive`:idx: language. This means that all the control structures are recognized by indentation. Indentation consists only of spaces; tabulators are not allowed. The indentation handling is implemented as follows: The lexer annotates the following token with the preceding number of spaces; indentation is not -a separate token. This trick allows parsing of Nimrod with only 1 token of +a separate token. This trick allows parsing of Nim with only 1 token of lookahead. The parser uses a stack of indentation levels: the stack consists of integers @@ -188,7 +188,7 @@ which code snippet the comment refers to. Identifiers & Keywords ---------------------- -Identifiers in Nimrod can be any string of letters, digits +Identifiers in Nim can be any string of letters, digits and underscores, beginning with a letter. Two immediate following underscores ``__`` are not allowed:: @@ -209,12 +209,12 @@ The following keywords are reserved and cannot be used as identifiers: Some keywords are unused; they are reserved for future developments of the language. -Nimrod is a `style-insensitive`:idx: language. This means that it is not +Nim is a `style-insensitive`:idx: language. This means that it is not case-sensitive and even underscores are ignored: **type** is a reserved word, and so is **TYPE** or **T_Y_P_E**. The idea behind this is that this allows programmers to use their own preferred spelling style and libraries written by different programmers cannot use incompatible -conventions. A Nimrod-aware editor or IDE can show the identifiers as +conventions. A Nim-aware editor or IDE can show the identifiers as preferred. Another advantage is that it frees the programmer from remembering the exact spelling of an identifier. @@ -250,7 +250,7 @@ contain the following `escape sequences`:idx:\ : ================== =================================================== -Strings in Nimrod may contain any 8-bit value, even embedded zeros. However +Strings in Nim may contain any 8-bit value, even embedded zeros. However some operations may interpret the first binary zero as a terminator. @@ -317,7 +317,7 @@ identifier and the opening quotation mark) is a generalized raw string literal. It is a shortcut for the construct ``identifier(r"string literal")``, so it denotes a procedure call with a raw string literal as its only argument. Generalized raw string literals -are especially convenient for embedding mini languages directly into Nimrod +are especially convenient for embedding mini languages directly into Nim (for example regular expressions). The construct ``identifier"""string literal"""`` exists too. It is a shortcut @@ -357,7 +357,7 @@ literals: A character is not an Unicode character but a single byte. The reason for this is efficiency: for the overwhelming majority of use-cases, the resulting programs will still handle UTF-8 properly as UTF-8 was specially designed for -this. Another reason is that Nimrod can thus support ``array[char, int]`` or +this. Another reason is that Nim can thus support ``array[char, int]`` or ``set[char]`` efficiently as many algorithms rely on this feature. The `TRune` type is used for Unicode characters, it can represent any Unicode character. ``TRune`` is declared in the `unicode module `_. @@ -441,7 +441,7 @@ is approximately 1.72826e35 according to the IEEE floating point standard. Operators --------- -In Nimrod one can define his own operators. An operator is any +In Nim one can define his own operators. An operator is any combination of the following characters:: = + - * / < > @@ -474,10 +474,10 @@ and not the two tokens `{.`:tok:, `.}`:tok:. Syntax ====== -This section lists Nimrod's standard syntax. How the parser handles +This section lists Nim's standard syntax. How the parser handles the indentation is already described in the `Lexical Analysis`_ section. -Nimrod allows user-definable operators. +Nim allows user-definable operators. Binary operators have 10 different levels of precedence. Relevant character @@ -588,7 +588,7 @@ The grammar's start symbol is ``module``. Types ===== -All expressions have a type which is known at compile time. Nimrod +All expressions have a type which is known at compile time. Nim is statically typed. One can declare new types, which is in essence defining an identifier that can be used to denote this custom type. @@ -686,7 +686,7 @@ kinds of integer types are used: the smaller type is converted to the larger. A `narrowing type conversion`:idx: converts a larger to a smaller type (for example ``int32 -> int16``. A `widening type conversion`:idx: converts a -smaller type to a larger type (for example ``int16 -> int32``). In Nimrod only +smaller type to a larger type (for example ``int16 -> int32``). In Nim only widening type conversions are *implicit*: .. code-block:: nimrod @@ -723,7 +723,7 @@ determined). Assignments from the base type to one of its subrange types A subrange type has the same size as its base type (``int`` in the example). -Nimrod requires `interval arithmetic`:idx: for subrange types over a set +Nim requires `interval arithmetic`:idx: for subrange types over a set of built-in operators that involve constants: ``x %% 3`` is of type ``range[0..2]``. The following built-in operators for integers are affected by this rule: ``-``, ``+``, ``*``, ``min``, ``max``, ``succ``, @@ -781,12 +781,12 @@ The IEEE standard defines five types of floating-point exceptions: precision, for example, 2.0 / 3.0, log(1.1) and 0.1 in input. The IEEE exceptions are either ignored at runtime or mapped to the -Nimrod exceptions: `EFloatInvalidOp`:idx:, `EFloatDivByZero`:idx:, +Nim exceptions: `EFloatInvalidOp`:idx:, `EFloatDivByZero`:idx:, `EFloatOverflow`:idx:, `EFloatUnderflow`:idx:, and `EFloatInexact`:idx:. These exceptions inherit from the `EFloatingPoint`:idx: base class. -Nimrod provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control -whether the IEEE exceptions are ignored or trap a Nimrod exception: +Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control +whether the IEEE exceptions are ignored or trap a Nim exception: .. code-block:: nimrod {.NanChecks: on, InfChecks: on.} @@ -807,7 +807,7 @@ the ``+``, ``-``, ``*``, ``/`` operators for floating point types. Boolean type ------------ -The boolean type is named `bool`:idx: in Nimrod and can be one of the two +The boolean type is named `bool`:idx: in Nim and can be one of the two pre-defined values ``true`` and ``false``. Conditions in while, if, elif, when statements need to be of type bool. @@ -831,12 +831,12 @@ The size of the bool type is one byte. Character type -------------- -The character type is named ``char`` in Nimrod. Its size is one byte. +The character type is named ``char`` in Nim. Its size is one byte. Thus it cannot represent an UTF-8 character, but a part of it. The reason for this is efficiency: for the overwhelming majority of use-cases, the resulting programs will still handle UTF-8 properly as UTF-8 was specially designed for this. -Another reason is that Nimrod can support ``array[char, int]`` or +Another reason is that Nim can support ``array[char, int]`` or ``set[char]`` efficiently as many algorithms rely on this feature. The `TRune` type is used for Unicode characters, it can represent any Unicode character. ``TRune`` is declared in the `unicode module `_. @@ -916,8 +916,8 @@ via ``TMyEnum.value``: String type ----------- -All string literals are of the type ``string``. A string in Nimrod is very -similar to a sequence of characters. However, strings in Nimrod are both +All string literals are of the type ``string``. A string in Nim is very +similar to a sequence of characters. However, strings in Nim are both zero-terminated and have a length field. One can retrieve the length with the builtin ``len`` procedure; the length never counts the terminating zero. The assignment operator for strings always copies the string. @@ -949,8 +949,8 @@ interfacing with C. The index operation ``s[i]`` means the i-th *char* of ``s``; however no bounds checking for ``cstring`` is performed making the index operation unsafe. -A Nimrod ``string`` is implicitly convertible -to ``cstring`` for convenience. If a Nimrod string is passed to a C-style +A Nim ``string`` is implicitly convertible +to ``cstring`` for convenience. If a Nim string is passed to a C-style variadic proc, it is implicitly converted to ``cstring`` too: .. code-block:: nimrod @@ -1169,7 +1169,7 @@ An example: .. code-block:: nimrod - # This is an example how an abstract syntax tree could be modelled in Nimrod + # This is an example how an abstract syntax tree could be modelled in Nim type TNodeKind = enum # the different node types nkInt, # a leaf with an integer value @@ -1230,7 +1230,7 @@ References (similar to pointers in other programming languages) are a way to introduce many-to-one relationships. This means different references can point to and modify the same location in memory (also called `aliasing`:idx:). -Nimrod distinguishes between `traced`:idx: and `untraced`:idx: references. +Nim distinguishes between `traced`:idx: and `untraced`:idx: references. Untraced references are also called *pointers*. Traced references point to objects of a garbage collected heap, untraced references point to manually allocated objects or to objects somewhere else in memory. Thus @@ -1409,7 +1409,7 @@ Future directions: Procedural type --------------- A procedural type is internally a pointer to a procedure. ``nil`` is -an allowed value for variables of a procedural type. Nimrod uses procedural +an allowed value for variables of a procedural type. Nim uses procedural types to achieve `functional`:idx: programming techniques. Examples: @@ -1446,10 +1446,10 @@ compatible if they have the same calling convention. As a special extension, a procedure of the calling convention ``nimcall`` can be passed to a parameter that expects a proc of the calling convention ``closure``. -Nimrod supports these `calling conventions`:idx:\: +Nim supports these `calling conventions`:idx:\: `nimcall`:idx: - is the default convention used for a Nimrod **proc**. It is the + is the default convention used for a Nim **proc**. It is the same as ``fastcall``, but only for C compilers that support ``fastcall``. `closure`:idx: @@ -1476,7 +1476,7 @@ Nimrod supports these `calling conventions`:idx:\: `inline`:idx: The inline convention means the the caller should not call the procedure, - but inline its code directly. Note that Nimrod does not inline, but leaves + but inline its code directly. Note that Nim does not inline, but leaves this to the C compiler; it generates ``__inline`` procedures. This is only a hint for the compiler: it may completely ignore it and it may inline procedures that are not marked as ``inline``. @@ -1492,7 +1492,7 @@ Nimrod supports these `calling conventions`:idx:\: `noconv`:idx: The generated C code will not have any explicit calling convention and thus use the C compiler's default calling convention. This is needed because - Nimrod's default calling convention for procedures is ``fastcall`` to + Nim's default calling convention for procedures is ``fastcall`` to improve speed. Most calling conventions exist only for the Windows 32-bit platform. @@ -1636,7 +1636,7 @@ Currently only the dot accessor can be borrowed in this way. Avoiding SQL injection attacks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -An SQL statement that is passed from Nimrod to an SQL database might be +An SQL statement that is passed from Nim to an SQL database might be modelled as a string. However, using string templates and filling in the values is vulnerable to the famous `SQL injection attack`:idx:\: @@ -1745,7 +1745,7 @@ describe the type checking done by the compiler. Type equality ------------- -Nimrod uses structural type equivalence for most types. Only for objects, +Nim uses structural type equivalence for most types. Only for objects, enumerations and distinct types name equivalence is used. The following algorithm (in pseudo-code) determines type equality: @@ -1932,7 +1932,7 @@ To be written. Statements and expressions ========================== -Nimrod uses the common statement/expression paradigm: Statements do not +Nim uses the common statement/expression paradigm: Statements do not produce a value in contrast to expressions. However, some expressions are statements. @@ -2079,7 +2079,7 @@ Const section cannot change. The compiler must be able to evaluate the expression in a constant declaration at compile time. -Nimrod contains a sophisticated compile-time evaluator, so procedures which +Nim contains a sophisticated compile-time evaluator, so procedures which have no side-effect can be used in constant expressions too: .. code-block:: nimrod @@ -2119,7 +2119,7 @@ time. The current implementation poses some restrictions for compile time evaluation: Code which contains ``cast`` or makes use of the foreign function -interface cannot be evaluated at compile time. Later versions of Nimrod will +interface cannot be evaluated at compile time. Later versions of Nim will support the FFI at compile time. @@ -2374,9 +2374,9 @@ Is equivalent to: Assembler statement ------------------- -The direct embedding of assembler code into Nimrod code is supported +The direct embedding of assembler code into Nim code is supported by the unsafe ``asm`` statement. Identifiers in the assembler code that refer to -Nimrod identifiers shall be enclosed in a special character which can be +Nim identifiers shall be enclosed in a special character which can be specified in the statement's pragmas. The default special character is ``'`'``: .. code-block:: nimrod @@ -2425,7 +2425,7 @@ Using statement The using statement provides syntactic convenience for procs that heavily use a single contextual parameter. When applied to a variable or a -constant, it will instruct Nimrod to automatically consider the used symbol as +constant, it will instruct Nim to automatically consider the used symbol as a hidden leading parameter for any procedure calls, following the using statement in the current scope. Thus, it behaves much like the hidden `this` parameter available in some object-oriented programming languages. @@ -2502,7 +2502,7 @@ The `case expression` is again very similar to the case statement: "ice cream" As seen in the above example, the case expression can also introduce side -effects. When multiple statements are given for a branch, Nimrod will use +effects. When multiple statements are given for a branch, Nim will use the last expression as the result value, much like in an `expr` template. Table constructor @@ -2582,7 +2582,7 @@ Procedures ========== What most programming languages call `methods`:idx: or `functions`:idx: are -called `procedures`:idx: in Nimrod (which is the correct terminology). A +called `procedures`:idx: in Nim (which is the correct terminology). A procedure declaration defines an identifier and associates it with a block of code. A procedure may call itself recursively. A parameter may be given a default @@ -2672,7 +2672,7 @@ postfix notation. Properties ---------- -Nimrod has no need for *get-properties*: Ordinary get-procedures that are called +Nim has no need for *get-properties*: Ordinary get-procedures that are called with the *method call syntax* achieve the same. But setting a value is different; for this a special setter syntax is needed: @@ -2961,7 +2961,7 @@ Invocation of a multi-method cannot be ambiguous: collide 2 is preferred over collide 1 because the resolution works from left to right. In the example ``TUnit, TThing`` is preferred over ``TThing, TUnit``. -**Performance note**: Nimrod does not produce a virtual method table, but +**Performance note**: Nim does not produce a virtual method table, but generates dispatch trees. This avoids the expensive indirect branch for method calls and enables inlining. However, other optimizations like compile time evaluation or dead code elimination do not work with methods. @@ -3033,7 +3033,7 @@ into account. First class iterators --------------------- -There are 2 kinds of iterators in Nimrod: *inline* and *closure* iterators. +There are 2 kinds of iterators in Nim: *inline* and *closure* iterators. An `inline iterator`:idx: is an iterator that's always inlined by the compiler leading to zero overhead for the abstraction, but may result in a heavy increase in code size. Inline iterators are second class citizens; @@ -3290,7 +3290,7 @@ Effect system Exception tracking ------------------ -Nimrod supports exception tracking. The `raises`:idx: pragma can be used +Nim supports exception tracking. The `raises`:idx: pragma can be used to explicitly define which exceptions a proc/iterator/method/converter is allowed to raise. The compiler verifies this: @@ -3367,7 +3367,7 @@ conservative in its effect analysis. Tag tracking ------------ -The exception tracking is part of Nimrod's `effect system`:idx:. Raising an +The exception tracking is part of Nim's `effect system`:idx:. Raising an exception is an *effect*. Other effects can also be defined. A user defined effect is a means to *tag* a routine and to perform checks against this tag: @@ -3467,7 +3467,7 @@ Example: for str in inorder(root): writeln(stdout, str) -Generics are Nimrod's means to parametrize procs, iterators or types with +Generics are Nim's means to parametrize procs, iterators or types with `type parameters`:idx:. Depending on context, the brackets are used either to introduce type parameters or to instantiate a generic proc, iterator or type. @@ -3515,7 +3515,7 @@ Type Classes A type class is a special pseudo-type that can be used to match against types in the context of overload resolution or the ``is`` operator. -Nimrod supports the following built-in type classes: +Nim supports the following built-in type classes: ================== =================================================== type class matches @@ -3553,7 +3553,7 @@ Procedures utilizing type classes in such manner are considered to be `implicitly generic`:idx:. They will be instantiated once for each unique combination of param types used within the program. -Nimrod also allows for type classes and regular types to be specified +Nim also allows for type classes and regular types to be specified as `type constraints`:idx: of the generic type parameter: .. code-block:: nimrod @@ -3579,7 +3579,7 @@ module to illustrate this: Alternatively, the ``distinct`` type modifier can be applied to the type class to allow each param matching the type class to bind to a different type. -If a proc param doesn't have a type specified, Nimrod will use the +If a proc param doesn't have a type specified, Nim will use the ``distinct auto`` type class (also known as ``any``): .. code-block:: nimrod @@ -3675,7 +3675,7 @@ Return Type Inference --------------------- If a type class is used as the return type of a proc and it won't be bound to -a concrete type by some of the proc params, Nimrod will infer the return type +a concrete type by some of the proc params, Nim will infer the return type from the proc body. This is usually used with the ``auto`` type class: .. code-block:: nimrod @@ -3684,7 +3684,7 @@ from the proc body. This is usually used with the ``auto`` type class: The return type will be treated as additional generic param and can be explicitly specified at call sites as any other generic param. -Future versions of Nimrod may also support overloading based on the return type +Future versions of Nim may also support overloading based on the return type of the overloads. In such settings, the expected result type at call sites may also influence the inferred return type. @@ -3760,7 +3760,7 @@ Templates ========= A template is a simple form of a macro: It is a simple substitution -mechanism that operates on Nimrod's abstract syntax trees. It is processed in +mechanism that operates on Nim's abstract syntax trees. It is processed in the semantic pass of the compiler. The syntax to *invoke* a template is the same as calling a procedure. @@ -3991,10 +3991,10 @@ to implement `domain specific languages`:idx:. Like templates, macros come in the 2 flavors *immediate* and *ordinary*. While macros enable advanced compile-time code transformations, they -cannot change Nimrod's syntax. However, this is no real restriction because -Nimrod's syntax is flexible enough anyway. +cannot change Nim's syntax. However, this is no real restriction because +Nim's syntax is flexible enough anyway. -To write macros, one needs to know how the Nimrod concrete syntax is converted +To write macros, one needs to know how the Nim concrete syntax is converted to an abstract syntax tree. There are two ways to invoke a macro: @@ -4009,12 +4009,12 @@ The following example implements a powerful ``debug`` command that accepts a variable number of arguments: .. code-block:: nimrod - # to work with Nimrod syntax trees, we need an API that is defined in the + # to work with Nim syntax trees, we need an API that is defined in the # ``macros`` module: import macros macro debug(n: varargs[expr]): stmt = - # `n` is a Nimrod AST that contains the whole macro invocation + # `n` is a Nim AST that contains the whole macro invocation # this macro returns a list of statements: result = newNimNode(nnkStmtList, n) # iterate over any argument that is passed to this macro: @@ -4313,14 +4313,14 @@ Special Operators dot operators ------------- -Nimrod offers a special family of dot operators that can be used to +Nim offers a special family of dot operators that can be used to intercept and rewrite proc call and field access attempts, referring to previously undeclared symbol names. They can be used to provide a fluent interface to objects lying outside the static confines of the type system such as values from dynamic scripting languages or dynamic file formats such as JSON or XML. -When Nimrod encounters an expression that cannot be resolved by the +When Nim encounters an expression that cannot be resolved by the standard overload resolution rules, the current scope will be searched for a dot operator that can be matched against a re-written form of the expression, where the unknown field or proc name is converted to @@ -4504,7 +4504,7 @@ is **wrong**: echo f() * 2 We cannot duplicate 'a' if it denotes an expression that has a side effect! -Fortunately Nimrod supports side effect analysis: +Fortunately Nim supports side effect analysis: .. code-block:: nimrod template optMul{`*`(a, 2)}(a: int{noSideEffect}): int = a+a @@ -4835,7 +4835,7 @@ optimization for types that have copying semantics: Modules ======= -Nimrod supports splitting a program into pieces by a module concept. +Nim supports splitting a program into pieces by a module concept. Each module needs to be in its own file and has its own `namespace`:idx:. Modules enable `information hiding`:idx: and `separate compilation`:idx:. A module may gain access to symbols of another module by the `import`:idx: @@ -5023,7 +5023,7 @@ iterator in which case the overloading resolution takes place: Compiler Messages ================= -The Nimrod compiler emits different kinds of messages: `hint`:idx:, +The Nim compiler emits different kinds of messages: `hint`:idx:, `warning`:idx:, and `error`:idx: messages. An *error* message is emitted if the compiler encounters any static error. @@ -5031,7 +5031,7 @@ the compiler encounters any static error. Pragmas ======= -Pragmas are Nimrod's method to give the compiler additional information / +Pragmas are Nim's method to give the compiler additional information / commands without introducing a massive number of new keywords. Pragmas are processed on the fly during semantic checking. Pragmas are enclosed in the special ``{.`` and ``.}`` curly brackets. Pragmas are also often used as a @@ -5133,7 +5133,7 @@ shallow pragma The ``shallow`` pragma affects the semantics of a type: The compiler is allowed to make a shallow copy. This can cause serious semantic issues and break memory safety! However, it can speed up assignments considerably, -because the semantics of Nimrod require deep copying of sequences and strings. +because the semantics of Nim require deep copying of sequences and strings. This can be expensive, especially if sequences are used to build a tree structure: @@ -5223,7 +5223,7 @@ If the ``line`` pragma is used with a parameter, the parameter needs be a linearScanEnd pragma -------------------- The ``linearScanEnd`` pragma can be used to tell the compiler how to -compile a Nimrod `case`:idx: statement. Syntactically it has to be used as a +compile a Nim `case`:idx: statement. Syntactically it has to be used as a statement: .. code-block:: nimrod @@ -5251,7 +5251,7 @@ whole ``case`` statement, the whole ``case`` statement uses linear scanning. computedGoto pragma ------------------- The ``computedGoto`` pragma can be used to tell the compiler how to -compile a Nimrod `case`:idx: in a ``while true`` statement. +compile a Nim `case`:idx: in a ``while true`` statement. Syntactically it has to be used as a statement inside the loop: .. code-block:: nimrod @@ -5469,7 +5469,7 @@ Pragma pragma ------------- The ``pragma`` pragma can be used to declare user defined pragmas. This is -useful because Nimrod's templates and macros do not affect pragmas. User +useful because Nim's templates and macros do not affect pragmas. User defined pragmas are in a different module-wide scope than all other symbols. They cannot be imported from a module. @@ -5491,12 +5491,12 @@ generation. Disabling certain messages -------------------------- -Nimrod generates some warnings and hints ("line too long") that may annoy the +Nim generates some warnings and hints ("line too long") that may annoy the user. A mechanism for disabling certain messages is provided: Each hint and warning message contains a symbol in brackets. This is the message's identifier that can be used to enable or disable it: -.. code-block:: Nimrod +.. code-block:: Nim {.hint[LineTooLong]: off.} # turn off the hint about too long lines This is often better than disabling all warnings at once. @@ -5505,7 +5505,7 @@ This is often better than disabling all warnings at once. Foreign function interface ========================== -Nimrod's `FFI`:idx: (foreign function interface) is extensive and only the +Nim's `FFI`:idx: (foreign function interface) is extensive and only the parts that scale to other future backends (like the LLVM/JavaScript backends) are documented here. @@ -5514,7 +5514,7 @@ Importc pragma -------------- The ``importc`` pragma provides a means to import a proc or a variable from C. The optional argument is a string containing the C identifier. If -the argument is missing, the C name is the Nimrod identifier *exactly as +the argument is missing, the C name is the Nim identifier *exactly as spelled*: .. code-block:: @@ -5532,9 +5532,9 @@ Exportc pragma The ``exportc`` pragma provides a means to export a type, a variable, or a procedure to C. Enums and constants can't be exported. The optional argument is a string containing the C identifier. If the argument is missing, the C -name is the Nimrod identifier *exactly as spelled*: +name is the Nim identifier *exactly as spelled*: -.. code-block:: Nimrod +.. code-block:: Nim proc callme(formatstr: cstring) {.exportc: "callMe", varargs.} Note that this pragma is somewhat of a misnomer: Other backends will provide @@ -5546,7 +5546,7 @@ Extern pragma Like ``exportc`` or ``importc``, the ``extern`` pragma affects name mangling. The string literal passed to ``extern`` can be a format string: -.. code-block:: Nimrod +.. code-block:: Nim proc p(s: string) {.extern: "prefix$1".} = echo s @@ -5575,11 +5575,11 @@ the compiler to pass the type by reference (hidden pointer) to procs. Varargs pragma -------------- The ``varargs`` pragma can be applied to procedures only (and procedure -types). It tells Nimrod that the proc can take a variable number of parameters -after the last specified parameter. Nimrod string values will be converted to C +types). It tells Nim that the proc can take a variable number of parameters +after the last specified parameter. Nim string values will be converted to C strings automatically: -.. code-block:: Nimrod +.. code-block:: Nim proc printf(formatstr: cstring) {.nodecl, varargs.} printf("hallo %s", "world") # "world" will be passed as C string @@ -5648,7 +5648,7 @@ With the ``dynlib`` pragma a procedure or a variable can be imported from a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). The non-optional argument has to be the name of the dynamic library: -.. code-block:: Nimrod +.. code-block:: Nim proc gtk_image_new(): PGtkWidget {.cdecl, dynlib: "libgtk-x11-2.0.so", importc.} @@ -5706,7 +5706,7 @@ With the ``dynlib`` pragma a procedure can also be exported to a dynamic library. The pragma then has no argument and has to be used in conjunction with the ``exportc`` pragma: -.. code-block:: Nimrod +.. code-block:: Nim proc exportme(): int {.cdecl, exportc, dynlib.} This is only useful if the program is compiled as a dynamic library via the @@ -5721,7 +5721,7 @@ be used. The ``system`` module then contains several threading primitives. See the `threads `_ and `channels `_ modules for the thread API. -Nimrod's memory model for threads is quite different than that of other common +Nim's memory model for threads is quite different than that of other common programming languages (C, Pascal, Java): Each thread has its own (garbage collected) heap and sharing of memory is restricted to global variables. This helps to prevent race conditions. GC efficiency is improved quite a lot, @@ -5797,7 +5797,7 @@ exception in one thread terminates the whole *process*! Spawn ----- -Nimrod has a builtin thread pool that can be used for CPU intensive tasks. For +Nim has a builtin thread pool that can be used for CPU intensive tasks. For IO intensive tasks the upcoming ``async`` and ``await`` features should be used instead. `spawn`:idx: is used to pass a task to the thread pool: @@ -5828,7 +5828,7 @@ Currently the expression that ``spawn`` takes is however quite restricted: Taint mode ========== -The Nimrod compiler and most parts of the standard library support +The Nim compiler and most parts of the standard library support a taint mode. Input strings are declared with the `TaintedString`:idx: string type declared in the ``system`` module. diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index 016f0ed50..8af045e2e 100644 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -1,9 +1,9 @@ =================================== - Nimrod Compiler User Guide + Nim Compiler User Guide =================================== :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -15,11 +15,11 @@ Introduction ============ -This document describes the usage of the *Nimrod compiler* -on the different supported platforms. It is not a definition of the Nimrod +This document describes the usage of the *Nim compiler* +on the different supported platforms. It is not a definition of the Nim programming language (therefore is the `manual `_). -Nimrod is free software; it is licensed under the +Nim is free software; it is licensed under the `MIT License `_. @@ -107,14 +107,14 @@ Configuration files passed as a command line argument to the compiler. -The ``nimrod`` executable processes configuration files in the following +The ``nim`` executable processes configuration files in the following directories (in this order; later files overwrite previous settings): -1) ``$nimrod/config/nimrod.cfg``, ``/etc/nimrod.cfg`` (UNIX) or ``%NIMROD%/config/nimrod.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option. -2) ``/home/$user/.config/nimrod.cfg`` (UNIX) or ``%APPDATA%/nimrod.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option. -3) ``$parentDir/nimrod.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option. -4) ``$projectDir/nimrod.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option. -5) A project can also have a project specific configuration file named ``$project.nimrod.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option. +1) ``$nim/config/nim.cfg``, ``/etc/nim.cfg`` (UNIX) or ``%NIMROD%/config/nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option. +2) ``/home/$user/.config/nim.cfg`` (UNIX) or ``%APPDATA%/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option. +3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option. +4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option. +5) A project can also have a project specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option. Command line settings have priority over configuration file settings. @@ -122,17 +122,17 @@ Command line settings have priority over configuration file settings. The default build of a project is a `debug build`:idx:. To compile a `release build`:idx: define the ``release`` symbol:: - nimrod c -d:release myproject.nim + nim c -d:release myproject.nim Search path handling -------------------- -Nimrod has the concept of a global search path (PATH) that is queried to +Nim has the concept of a global search path (PATH) that is queried to determine where to find imported modules or include files. If multiple files are found an ambiguity error is produced. -``nimrod dump`` shows the contents of the PATH. +``nim dump`` shows the contents of the PATH. However before the PATH is used the current directory is checked for the file's existance. So if PATH contains ``$lib`` and ``$lib/bar`` and the @@ -152,10 +152,10 @@ the first matching file is used. Generated C code directory -------------------------- -The generated files that Nimrod produces all go into a subdirectory called +The generated files that Nim produces all go into a subdirectory called ``nimcache`` in your project directory. This makes it easy to delete all generated files. Files generated in this directory follow a naming logic which -you can read about in the `Nimrod Backend Integration document +you can read about in the `Nim Backend Integration document `_. However, the generated C code is not platform independent. C code generated for @@ -190,14 +190,14 @@ Cross compilation To cross compile, use for example:: - nimrod c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim + nim c --cpu:i386 --os:linux --compile_only --gen_script myproject.nim Then move the C code and the compile script ``compile_myproject.sh`` to your Linux i386 machine and run the script. -Another way is to make Nimrod invoke a cross compiler toolchain:: +Another way is to make Nim invoke a cross compiler toolchain:: - nimrod c --cpu:arm --os:linux myproject.nim + nim c --cpu:arm --os:linux myproject.nim For cross compilation, the compiler invokes a C compiler named like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration @@ -212,16 +212,16 @@ configuration file should contain something like:: DLL generation ============== -Nimrod supports the generation of DLLs. However, there must be only one +Nim supports the generation of DLLs. However, there must be only one instance of the GC per process/address space. This instance is contained in -``nimrtl.dll``. This means that every generated Nimrod DLL depends +``nimrtl.dll``. This means that every generated Nim DLL depends on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command:: - nimrod c -d:release lib/nimrtl.nim + nim c -d:release lib/nimrtl.nim To link against ``nimrtl.dll`` use the command:: - nimrod c -d:useNimRtl myprog.nim + nim c -d:useNimRtl myprog.nim **Note**: Currently the creation of ``nimrtl.dll`` with thread support has never been tested and is unlikely to work! @@ -243,9 +243,9 @@ Define Effect version. ``useFork`` Makes ``osproc`` use ``fork`` instead of ``posix_spawn``. ``useNimRtl`` Compile and link against ``nimrtl.dll``. -``useMalloc`` Makes Nimrod use C's `malloc`:idx: instead of Nimrod's +``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's own memory manager. This only works with ``gc:none``. -``useRealtimeGC`` Enables support of Nimrod's GC for *soft* realtime +``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime systems. See the documentation of the `gc `_ for further information. ``nodejs`` The JS target is actually ``node.js``. @@ -258,8 +258,8 @@ Define Effect Additional Features =================== -This section describes Nimrod's additional features that are not listed in the -Nimrod manual. Some of the features here only make sense for the C code +This section describes Nim's additional features that are not listed in the +Nim manual. Some of the features here only make sense for the C code generator and are subject to change. @@ -267,13 +267,13 @@ NoDecl pragma ------------- The ``noDecl`` pragma can be applied to almost any symbol (variable, proc, type, etc.) and is sometimes useful for interoperability with C: -It tells Nimrod that it should not generate a declaration for the symbol in +It tells Nim that it should not generate a declaration for the symbol in the C code. For example: -.. code-block:: Nimrod +.. code-block:: Nim var EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as - # Nimrod does not know its value + # Nim does not know its value However, the ``header`` pragma is often the better alternative. @@ -286,14 +286,14 @@ The ``header`` pragma is very similar to the ``noDecl`` pragma: It can be applied to almost any symbol and specifies that it should not be declared and instead the generated code should contain an ``#include``: -.. code-block:: Nimrod +.. code-block:: Nim type PFile {.importc: "FILE*", header: "".} = distinct pointer - # import C's FILE* type; Nimrod will treat it as a new pointer type + # import C's FILE* type; Nim will treat it as a new pointer type The ``header`` pragma always expects a string constant. The string contant contains the header file: As usual for C, a system header file is enclosed -in angle brackets: ``<>``. If no angle brackets are given, Nimrod +in angle brackets: ``<>``. If no angle brackets are given, Nim encloses the header file in ``""`` in the generated C code. **Note**: This will not work for the LLVM backend. @@ -304,7 +304,7 @@ IncompleteStruct pragma The ``incompleteStruct`` pragma tells the compiler to not use the underlying C ``struct`` in a ``sizeof`` expression: -.. code-block:: Nimrod +.. code-block:: Nim type TDIR* {.importc: "DIR", header: "", final, pure, incompleteStruct.} = object @@ -315,10 +315,10 @@ Compile pragma The ``compile`` pragma can be used to compile and link a C/C++ source file with the project: -.. code-block:: Nimrod +.. code-block:: Nim {.compile: "myfile.cpp".} -**Note**: Nimrod computes a CRC checksum and only recompiles the file if it +**Note**: Nim computes a CRC checksum and only recompiles the file if it has changed. You can use the ``-f`` command line option to force recompilation of the file. @@ -327,7 +327,7 @@ Link pragma ----------- The ``link`` pragma can be used to link an additional file with the project: -.. code-block:: Nimrod +.. code-block:: Nim {.link: "myfile.o".} @@ -336,13 +336,13 @@ PassC pragma The ``passC`` pragma can be used to pass additional parameters to the C compiler like you would using the commandline switch ``--passC``: -.. code-block:: Nimrod +.. code-block:: Nim {.passC: "-Wall -Werror".} Note that you can use ``gorge`` from the `system module `_ to embed parameters from an external command at compile time: -.. code-block:: Nimrod +.. code-block:: Nim {.passC: gorge("pkg-config --cflags sdl").} PassL pragma @@ -350,13 +350,13 @@ PassL pragma The ``passL`` pragma can be used to pass additional parameters to the linker like you would using the commandline switch ``--passL``: -.. code-block:: Nimrod +.. code-block:: Nim {.passL: "-lSDLmain -lSDL".} Note that you can use ``gorge`` from the `system module `_ to embed parameters from an external command at compile time: -.. code-block:: Nimrod +.. code-block:: Nim {.passL: gorge("pkg-config --libs sdl").} @@ -369,16 +369,16 @@ extremely useful for interfacing with `C++`:idx: or `Objective C`:idx: code. Example: -.. code-block:: Nimrod +.. code-block:: Nim {.emit: """ static int cvariable = 420; """.} {.push stackTrace:off.} proc embedsC() = - var nimrodVar = 89 - # use backticks to access Nimrod symbols within an emit section: - {.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimrodVar`);""".} + var nimVar = 89 + # use backticks to access Nim symbols within an emit section: + {.emit: """fprintf(stdout, "%d\n", cvariable + (int)`nimVar`);""".} {.pop.} embedsC() @@ -392,7 +392,7 @@ code then uses the C++ method calling syntax: ``obj->method(arg)``. In addition with the ``header`` and ``emit`` pragmas this allows *sloppy* interfacing with libraries written in C++: -.. code-block:: Nimrod +.. code-block:: Nim # Horrible example of how to interface with a C++ engine ... ;-) {.link: "/usr/lib/libIrrlicht.so".} @@ -431,7 +431,7 @@ generated code then uses the Objective C method calling syntax: ``[obj method param1: arg]``. In addition with the ``header`` and ``emit`` pragmas this allows *sloppy* interfacing with libraries written in Objective C: -.. code-block:: Nimrod +.. code-block:: Nim # horrible example of how to interface with GNUStep ... {.passL: "-lobjc".} @@ -475,11 +475,11 @@ emits Objective C code. CodegenDecl pragma ------------------ -The ``codegenDecl`` pragma can be used to directly influence Nimrod's code +The ``codegenDecl`` pragma can be used to directly influence Nim's code generator. It receives a format string that determines how the variable or proc is declared in the generated code: -.. code-block:: nimrod +.. code-block:: nim var a {.codegenDecl: "$# progmem $#".}: int @@ -494,7 +494,7 @@ The ``injectStmt`` pragma can be used to inject a statement before every other statement in the current module. It is only supposed to be used for debugging: -.. code-block:: nimrod +.. code-block:: nim {.injectStmt: gcInvariants().} # ... complex code here that produces crashes ... @@ -523,7 +523,7 @@ is raised. Debugger option --------------- -The ``debugger`` option enables or disables the *Embedded Nimrod Debugger*. +The ``debugger`` option enables or disables the *Embedded Nim Debugger*. See the documentation of endb_ for further information. @@ -545,11 +545,11 @@ in C/C++). Source code style ================= -Nimrod allows you to `mix freely case and underscores as identifier separators +Nim allows you to `mix freely case and underscores as identifier separators `_, so variables named ``MyPrecioussInt`` and ``my_preciouss_int`` are equivalent: -.. code-block:: Nimrod +.. code-block:: Nim var MyPrecioussInt = 3 # Following line compiles fine! echo my_preciouss_int @@ -557,16 +557,16 @@ Nimrod allows you to `mix freely case and underscores as identifier separators Since this can lead to many variants of the same source code (you can use `nimgrep `_ instead of your typical ``grep`` to ignore style problems) the compiler provides the command ``pretty`` to help unifying the -style of source code. Running ``nimrod pretty ugly_test.nim`` with this +style of source code. Running ``nim pretty ugly_test.nim`` with this example will generate a secondary file named ``ugly_test.pretty.nim`` with the following content: -.. code-block:: Nimrod +.. code-block:: Nim var MyPrecioussInt = 3 # Following line compiles fine! echo MyPrecioussInt -During execution the ``pretty`` command will also run on Nimrod's standard +During execution the ``pretty`` command will also run on Nim's standard library, since it doesn't differentiate the standard library as something special, and hence will warn of many *errors* which are out of your hand to fix, creating respective ``.pretty.nim`` files all the way. You can ignore @@ -583,11 +583,11 @@ important changes for you to review. In this case the command is warning that a variable name should not start with a capital letter, which is usually reserved to `object types `_. To learn about the accepted `camel case style `_ read `Coding Guidelines in -the Internals of Nimrod Compiler `_ or `Coding -Guidelines `_ and `NEP 1 -: Style Guide for Nimrod Code -`_ -from the Nimrod `GitHub wiki`_. +the Internals of Nim Compiler `_ or `Coding +Guidelines `_ and `NEP 1 +: Style Guide for Nim Code +`_ +from the Nim `GitHub wiki`_. This command is safe to run because it will never attempt to overwrite your existing sources, but the respective ``.pretty.nim`` files **will** be @@ -597,14 +597,14 @@ overwritten without notice. DynlibOverride ============== -By default Nimrod's ``dynlib`` pragma causes the compiler to generate +By default Nim's ``dynlib`` pragma causes the compiler to generate ``GetProcAddress`` (or their Unix counterparts) calls to bind to a DLL. With the ``dynlibOverride`` command line switch this can be prevented and then via ``--passL`` the static library can be linked against. For instance, to link statically against Lua this command might work on Linux:: - nimrod c --dynlibOverride:lua --passL:liblua.lib program.nim + nim c --dynlibOverride:lua --passL:liblua.lib program.nim Backend language options @@ -614,32 +614,32 @@ The typical compiler usage involves using the ``compile`` or ``c`` command to transform a ``.nim`` file into one or more ``.c`` files which are then compiled with the platform's C compiler into a static binary. However there are other commands to compile to C++, Objective-C or Javascript. More details -can be read in the `Nimrod Backend Integration document `_. +can be read in the `Nim Backend Integration document `_. -Nimrod documentation tools -========================== +Nim documentation tools +======================= -Nimrod provides the `doc`:idx: and `doc2`:idx: commands to generate HTML +Nim provides the `doc`:idx: and `doc2`:idx: commands to generate HTML documentation from ``.nim`` source files. Only exported symbols will appear in the output. For more details `see the docgen documentation `_. -Nimrod idetools integration -=========================== +Nim idetools integration +======================== -Nimrod provides language integration with external IDEs through the +Nim provides language integration with external IDEs through the idetools command. See the documentation of `idetools `_ for further information. -Nimrod interactive mode -======================= +Nim interactive mode +==================== -The Nimrod compiler supports an interactive mode. This is also known as -a `REPL`:idx: (*read eval print loop*). If Nimrod has been built with the +The Nim compiler supports an interactive mode. This is also known as +a `REPL`:idx: (*read eval print loop*). If Nim has been built with the ``-d:useGnuReadline`` switch, it uses the GNU readline library for terminal -input management. To start Nimrod in interactive mode use the command -``nimrod i``. To quit use the ``quit()`` command. To determine whether an input +input management. To start Nim in interactive mode use the command +``nim i``. To quit use the ``quit()`` command. To determine whether an input line is an incomplete statement to be continued these rules are used: 1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace). @@ -648,8 +648,8 @@ line is an incomplete statement to be continued these rules are used: does not work if the line contains more than one ``"""``. -Nimrod for embedded systems -=========================== +Nim for embedded systems +======================== The standard library can be avoided to a point where C code generation for 16bit micro controllers is feasible. Use the `standalone`:idx: target @@ -661,7 +661,7 @@ target. For example, to generate code for an `AVR`:idx: processor use this command:: - nimrod c --cpu:avr --os:standalone --deadCodeElim:on --genScript x.nim + nim c --cpu:avr --os:standalone --deadCodeElim:on --genScript x.nim For the ``standalone`` target you need to provide a file ``panicoverride.nim``. @@ -669,27 +669,27 @@ See ``tests/manyloc/standalone/panicoverride.nim`` for an example implementation. -Nimrod for realtime systems -=========================== +Nim for realtime systems +======================== -See the documentation of Nimrod's soft realtime `GC `_ for further +See the documentation of Nim's soft realtime `GC `_ for further information. -Debugging with Nimrod -===================== +Debugging with Nim +================== -Nimrod comes with its own *Embedded Nimrod Debugger*. See +Nim comes with its own *Embedded Nim Debugger*. See the documentation of endb_ for further information. -Optimizing for Nimrod -===================== +Optimizing for Nim +================== -Nimrod has no separate optimizer, but the C code that is produced is very +Nim has no separate optimizer, but the C code that is produced is very efficient. Most C compilers have excellent optimizers, so usually it is -not needed to optimize one's code. Nimrod has been designed to encourage -efficient code: The most readable code in Nimrod is often the most efficient +not needed to optimize one's code. Nim has been designed to encourage +efficient code: The most readable code in Nim is often the most efficient too. However, sometimes one has to optimize. Do it in the following order: @@ -706,32 +706,32 @@ This section can only help you with the last item. Optimizing string handling -------------------------- -String assignments are sometimes expensive in Nimrod: They are required to +String assignments are sometimes expensive in Nim: They are required to copy the whole string. However, the compiler is often smart enough to not copy strings. Due to the argument passing semantics, strings are never copied when passed to subroutines. The compiler does not copy strings that are a result from a procedure call, because the callee returns a new string anyway. Thus it is efficient to do: -.. code-block:: Nimrod +.. code-block:: Nim var s = procA() # assignment will not copy the string; procA allocates a new # string already However it is not efficient to do: -.. code-block:: Nimrod +.. code-block:: Nim var s = varA # assignment has to copy the whole string into a new buffer! For ``let`` symbols a copy is not always necessary: -.. code-block:: Nimrod +.. code-block:: Nim let s = varA # may only copy a pointer if it safe to do so If you know what you're doing, you can also mark single string (or sequence) objects as `shallow`:idx:\: -.. code-block:: Nimrod +.. code-block:: Nim var s = "abc" shallow(s) # mark 's' as shallow string var x = s # now might not copy the string! @@ -744,7 +744,7 @@ The compiler optimizes string case statements: A hashing scheme is used for them if several different string constants are used. So code like this is reasonably efficient: -.. code-block:: Nimrod +.. code-block:: Nim case normalize(k.key) of "name": c.name = v of "displayname": c.displayName = v diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index ff371f4e1..3d55fe1fc 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -31,10 +31,10 @@ type state: TTokenClass TSourceLanguage* = enum - langNone, langNimrod, langCpp, langCsharp, langC, langJava + langNone, langNim, langCpp, langCsharp, langC, langJava const - sourceLanguageToStr*: array[TSourceLanguage, string] = ["none", "Nimrod", + sourceLanguageToStr*: array[TSourceLanguage, string] = ["none", "Nim", "C++", "C#", "C", "Java"] tokenClassToStr*: array[TTokenClass, string] = ["Eof", "None", "Whitespace", "DecNumber", "BinNumber", "HexNumber", "OctNumber", "FloatNumber", @@ -46,7 +46,7 @@ const # The following list comes from doc/keywords.txt, make sure it is # synchronized with this array by running the module itself as a test case. - nimrodKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", + nimKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", "break", "case", "cast", "const", "continue", "converter", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", "finally", "for", "from", "generic", "if", "import", "in", "include", @@ -79,7 +79,7 @@ proc deinitGeneralTokenizer*(g: var TGeneralTokenizer) = discard proc nimGetKeyword(id: string): TTokenClass = - for k in nimrodKeywords: + for k in nimKeywords: if cmpIgnoreStyle(id, k) == 0: return gtKeyword result = gtIdentifier when false: @@ -542,7 +542,7 @@ proc javaNextToken(g: var TGeneralTokenizer) = proc getNextToken*(g: var TGeneralTokenizer, lang: TSourceLanguage) = case lang of langNone: assert false - of langNimrod: nimNextToken(g) + of langNim: nimNextToken(g) of langCpp: cppNextToken(g) of langCsharp: csharpNextToken(g) of langC: cNextToken(g) @@ -557,7 +557,7 @@ when isMainModule: keywords = input.split() break doAssert(not keywords.isNil, "Couldn't read any keywords.txt file!") - doAssert keywords.len == nimrodKeywords.len, "No matching lengths" + doAssert keywords.len == nimKeywords.len, "No matching lengths" for i in 0..keywords.len-1: - #echo keywords[i], " == ", nimrodKeywords[i] - doAssert keywords[i] == nimrodKeywords[i], "Unexpected keyword" + #echo keywords[i], " == ", nimKeywords[i] + doAssert keywords[i] == nimKeywords[i], "Unexpected keyword" diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index e9bae69b5..5d69fcf51 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -103,7 +103,7 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## import packages/docutils/rstgen ## @@ -231,7 +231,7 @@ proc renderRstToOut*(d: var TRstGenerator, n: PRstNode, result: var string) ## ``initRstGenerator`` and parse a rst file with ``rstParse`` from the ## `packages/docutils/rst module `_. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## # ...configure gen and rst vars... ## var generatedHTML = "" @@ -597,7 +597,7 @@ proc mergeIndexes*(dir: string): string = ## Merges all index files in `dir` and returns the generated index as HTML. ## ## This proc will first scan `dir` for index files with the ``.idx`` - ## extension previously created by commands like ``nimrod doc|rst2html`` + ## extension previously created by commands like ``nim doc|rst2html`` ## which use the ``--index:on`` switch. These index files are the result of ## calls to `setIndexTerm() <#setIndexTerm>`_ and `writeIndexFile() ## <#writeIndexFile>`_, so they are simple tab separated files. @@ -768,7 +768,7 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) = var langstr = strip(getArgument(n)) var lang: TSourceLanguage if langstr == "": - lang = langNimrod # default language + lang = langNim # default language else: lang = getSourceLanguage(langstr) @@ -1123,7 +1123,7 @@ proc rstToHtml*(s: string, options: TRstParseOptions, ## work. For an explanation of the ``config`` parameter see the ## ``initRstGenerator`` proc. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## import packages/docutils/rstgen, strtabs ## ## echo rstToHtml("*Hello* **world**!", {}, diff --git a/lib/system.nim b/lib/system.nim index 0d8f63bd4..0ba99f915 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2015,7 +2015,7 @@ template accumulateResult*(iter: expr) = for x in iter: add(result, x) # we have to compute this here before turning it off in except.nim anyway ... -const nimrodStackTrace = compileOption("stacktrace") +const NimStackTrace = compileOption("stacktrace") {.push checks: off.} # obviously we cannot generate checking operations here :-) diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 602e5c7fa..9638472c2 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# Low level allocator for Nimrod. Has been designed to support the GC. +# Low level allocator for Nim. Has been designed to support the GC. # TODO: # - eliminate "used" field # - make searching for block O(1) diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index e012697ae..121cd207d 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,7 +8,7 @@ # # This include file contains headers of Ansi C procs -# and definitions of Ansi C types in Nimrod syntax +# and definitions of Ansi C types in Nim syntax # All symbols are prefixed with 'c_' to avoid ambiguities {.push hints:off} diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim index 7672947cd..1cc9b41e6 100644 --- a/lib/system/arithm.nim +++ b/lib/system/arithm.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/assign.nim b/lib/system/assign.nim index 0e27eb57f..a213a9d97 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 695a5f63e..d5f9b3599 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# Atomic operations for Nimrod. +# Atomic operations for Nim. {.push stackTrace:off.} const someGcc = defined(gcc) or defined(llvm_gcc) or defined(clang) @@ -159,6 +159,7 @@ when someGcc and hasThreadSupport: elif defined(vcc) and hasThreadSupport: proc addAndFetch*(p: ptr int, val: int): int {. importc: "NimXadd", nodecl.} + proc fence*() {.importc: "_ReadWriteBarrier", header: "".} else: proc addAndFetch*(p: ptr int, val: int): int {.inline.} = diff --git a/lib/system/avltree.nim b/lib/system/avltree.nim index bced15d6a..157799b28 100644 --- a/lib/system/avltree.nim +++ b/lib/system/avltree.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/cellsets.nim b/lib/system/cellsets.nim index 3825e5b47..653aed241 100644 --- a/lib/system/cellsets.nim +++ b/lib/system/cellsets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim index d483c61bd..d46e715f1 100644 --- a/lib/system/cgprocs.nim +++ b/lib/system/cgprocs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/channels.nim b/lib/system/channels.nim index df46922e4..0715d05e5 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index 387b54ef1..c018a7631 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim index af7b6d515..37a7c89f6 100644 --- a/lib/system/debugger.nim +++ b/lib/system/debugger.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -293,7 +293,7 @@ proc checkWatchpoints = Watchpoints[i].oldValue = newHash proc endb(line: int, file: cstring) {.compilerproc, noinline.} = - # This proc is called before every Nimrod code line! + # This proc is called before every Nim code line! if framePtr == nil: return if dbgWatchpointHook != nil: checkWatchpoints() framePtr.line = line # this is done here for smaller code size! diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index e7eb1cdb4..243cc85e8 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index 9ef1a99ca..eb57559fd 100644 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/embedded.nim b/lib/system/embedded.nim index 661992e81..c6db9bca4 100644 --- a/lib/system/embedded.nim +++ b/lib/system/embedded.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/endb.nim b/lib/system/endb.nim index f7e95e216..9d3ae574c 100644 --- a/lib/system/endb.nim +++ b/lib/system/endb.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ # with the application. Mostly we do not use dynamic memory here as that # would interfere with the GC and trigger ON/OFF errors if the # user program corrupts memory. Unfortunately, for dispaying -# variables we use the ``system.repr()`` proc which uses Nimrod +# variables we use the ``system.repr()`` proc which uses Nim # strings and thus allocates memory from the heap. Pity, but # I do not want to implement ``repr()`` twice. diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 3c5436afb..04a23db9d 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -68,8 +68,8 @@ proc popCurrentException {.compilerRtl, inl.} = # some platforms have native support for stack traces: const nativeStackTraceSupported* = (defined(macosx) or defined(linux)) and - not nimrodStackTrace - hasSomeStackTrace = nimrodStackTrace or + not NimStackTrace + hasSomeStackTrace = NimStackTrace or defined(nativeStackTrace) and nativeStackTraceSupported when defined(nativeStacktrace) and nativeStackTraceSupported: @@ -177,7 +177,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) = when hasSomeStackTrace: proc rawWriteStackTrace(s: var string) = - when nimrodStackTrace: + when NimStackTrace: if framePtr == nil: add(s, "No stack traceback available\n") else: @@ -318,7 +318,7 @@ when not defined(noSignalHandler): GC_disable() var buf = newStringOfCap(2000) rawWriteStackTrace(buf) - processSignal(sig, buf.add) # nice hu? currying a la nimrod :-) + processSignal(sig, buf.add) # nice hu? currying a la Nim :-) showErrorMessage(buf) GC_enable() else: diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 0c1fc7748..053c7df69 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index 132da9885..ee52b54f5 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index 05bcdcc82..629219bf7 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# A simple mark&sweep garbage collector for Nimrod. Define the +# A simple mark&sweep garbage collector for Nim. Define the # symbol ``gcUseBitvectors`` to generate a variant of this GC. {.push profiler:off.} diff --git a/lib/system/hti.nim b/lib/system/hti.nim index ef8f50831..4a8ab2485 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/inclrtl.nim b/lib/system/inclrtl.nim index 5c82db4da..a975bb7c2 100644 --- a/lib/system/inclrtl.nim +++ b/lib/system/inclrtl.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 8766906e3..894f259f3 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -103,7 +103,7 @@ proc raiseException(e: ref E_Base, ename: cstring) {. if excHandler != nil: excHandler.exc = e else: - when nimrodStackTrace: + when NimStackTrace: var buf = rawWriteStackTrace() else: var buf = "" diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index a09b6cf93..803c1f5c0 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -1,14 +1,14 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# Nimrod high-level memory manager: It supports Boehm's GC, no GC and the -# native Nimrod GC. The native Nimrod GC is the default. +# Nim high-level memory manager: It supports Boehm's GC, no GC and the +# native Nim GC. The native Nim GC is the default. #{.push checks:on, assertions:on.} {.push checks:off.} @@ -259,7 +259,7 @@ elif defined(nogc) and defined(useMalloc): elif defined(nogc): # Even though we don't want the GC, we cannot simply use C's memory manager - # because Nimrod's runtime wants ``realloc`` to zero out the additional + # because Nim's runtime wants ``realloc`` to zero out the additional # space which C's ``realloc`` does not. And we cannot get the old size of an # object, because C does not support this operation... Even though every # possible implementation has to have a way to determine the object's size. diff --git a/lib/system/profiler.nim b/lib/system/profiler.nim index 8e4c51dd9..96ab6abc7 100644 --- a/lib/system/profiler.nim +++ b/lib/system/profiler.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# This file implements the Nimrod profiler. The profiler needs support by the +# This file implements the Nim profiler. The profiler needs support by the # code generator. The idea is to inject the instruction stream # with 'nimProfile()' calls. These calls are injected at every loop end # (except perhaps loops that have no side-effects). At every Nth call a diff --git a/lib/system/repr.nim b/lib/system/repr.nim index 8e1bc5f26..7408552f9 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/reprjs.nim b/lib/system/reprjs.nim index fd1cb5c8b..57237cfff 100644 --- a/lib/system/reprjs.nim +++ b/lib/system/reprjs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/sets.nim b/lib/system/sets.nim index 794c65cb8..626d43c33 100644 --- a/lib/system/sets.nim +++ b/lib/system/sets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index b8ed29cfc..cff873cf4 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/sysspawn.nim b/lib/system/sysspawn.nim index 5161104a9..04f30872d 100644 --- a/lib/system/sysspawn.nim +++ b/lib/system/sysspawn.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Implements Nimrod's 'spawn'. +## Implements Nim's 'spawn'. when not declared(NimString): {.error: "You must not import this module explicitly".} diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index bc79bb254..14b24cca6 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -119,7 +119,7 @@ proc addChar(s: NimString, c: char): NimString = inc(result.len) # These routines should be used like following: -# +# # s &= "Hello " & name & ", how do you feel?" # # @@ -130,7 +130,7 @@ proc addChar(s: NimString, c: char): NimString = # appendString(s, strLit3); # } # -# +# # s = "Hello " & name & ", how do you feel?" # # @@ -143,7 +143,7 @@ proc addChar(s: NimString, c: char): NimString = # s = tmp0; # } # -# +# # s = "" # # diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 4717659e5..9e945544f 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -1,17 +1,17 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Thread support for Nimrod. **Note**: This is part of the system module. +## Thread support for Nim. **Note**: This is part of the system module. ## Do not import it directly. To activate thread support you need to compile ## with the ``--threads:on`` command line switch. ## -## Nimrod's memory model for threads is quite different from other common +## Nim's memory model for threads is quite different from other common ## programming languages (C, Pascal): Each thread has its own ## (garbage collected) heap and sharing of memory is restricted. This helps ## to prevent race conditions and improves efficiency. See `the manual for @@ -19,7 +19,7 @@ ## ## Example: ## -## .. code-block:: nimrod +## .. code-block:: Nim ## ## import locks ## @@ -245,14 +245,14 @@ when not defined(useNimRtl): # the GC can examine the stacks? proc stopTheWord() = discard -# We jump through some hops here to ensure that Nimrod thread procs can have -# the Nimrod calling convention. This is needed because thread procs are +# We jump through some hops here to ensure that Nim thread procs can have +# the Nim calling convention. This is needed because thread procs are # ``stdcall`` on Windows and ``noconv`` on UNIX. Alternative would be to just # use ``stdcall`` since it is mapped to ``noconv`` on UNIX anyway. type TThread* {.pure, final.}[TArg] = - object of TGcThread ## Nimrod thread. A thread is a heavy object (~14K) + object of TGcThread ## Nim thread. A thread is a heavy object (~14K) ## that **must not** be part of a message! Use ## a ``TThreadId`` for that. when TArg is void: diff --git a/lib/system/timers.nim b/lib/system/timers.nim index fa1a13a5f..e58ff7adc 100644 --- a/lib/system/timers.nim +++ b/lib/system/timers.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/system/widestrs.nim b/lib/system/widestrs.nim index cd64ff410..1e8bc6791 100644 --- a/lib/system/widestrs.nim +++ b/lib/system/widestrs.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# Nimrod support for C/C++'s `wide strings`:idx:. This is part of the system +# Nim support for C/C++'s `wide strings`:idx:. This is part of the system # module! Do not import it directly! when not declared(NimString): diff --git a/tests/parallel/tflowvar.nim b/tests/parallel/tflowvar.nim index 77fab14b5..96d42255d 100644 --- a/tests/parallel/tflowvar.nim +++ b/tests/parallel/tflowvar.nim @@ -1,11 +1,13 @@ discard """ - output: '''foobarfoobarbazbearbazbear''' + output: '''foobarfoobar +bazbearbazbear +1''' cmd: "nimrod $target --threads:on $options $file" """ import threadpool -proc computeSomething(a, b: string): string = a & b & a & b +proc computeSomething(a, b: string): string = a & b & a & b & "\n" proc main = let fvA = spawn computeSomething("foo", "bar") @@ -15,3 +17,19 @@ proc main = main() sync() + + +type + TIntSeq = seq[int] + +proc t(): TIntSeq = + result = @[1] + +proc p(): int = + var a: FlowVar[TIntSeq] + parallel: + var aa = spawn t() + a = aa + result = (^a)[0] + +echo p() diff --git a/todo.txt b/todo.txt index d8085226d..20fba45e9 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,11 @@ version 0.9.6 ============= +- fix bug #1320 +- fix tflowvar codegen test +- split idetools into separate tool +- split docgen into separate tool +- .benign pragma - scopes are still broken for generic instantiation! - implicit deref for parameter matching diff --git a/web/news.txt b/web/news.txt index 2d7086be6..3b48140e5 100644 --- a/web/news.txt +++ b/web/news.txt @@ -29,6 +29,8 @@ News - ``--threadanalysis:on`` is now the default. To make your program compile you can disable it but this is only a temporary solution as this option will disappear soon! + - ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to + prevent name conflicts with the new type ``FileHandle``. Language Additions diff --git a/web/question.txt b/web/question.txt index be90cc67a..e6f4d40a5 100644 --- a/web/question.txt +++ b/web/question.txt @@ -31,8 +31,8 @@ runtime or interpreter. What have been the major influences in the language's design? ------------------------------------------------------------- -The language borrows heavily from: Modula 3, Delphi, Ada, C++, Python, Lisp, -Oberon. As far as possible the list is sorted by the impact of influence. +The language borrows heavily from (in order of impact): Modula 3, Delphi, Ada, +C++, Python, Lisp, Oberon. From fc0fda14ae1caf83d1b39029bebb702ff306b1e0 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 23 Aug 2014 00:58:04 +0200 Subject: [PATCH 008/409] system files use new identifiers --- lib/system.nim | 361 ++++++++++++++++++++++------------------ lib/system/alloc.nim | 70 ++++---- lib/system/arithm.nim | 10 +- lib/system/assign.nim | 26 +-- lib/system/cellsets.nim | 14 +- lib/system/chcks.nim | 14 +- lib/system/deepcopy.nim | 24 +-- lib/system/dyncalls.nim | 2 +- lib/system/excpt.nim | 16 +- lib/system/gc.nim | 36 ++-- lib/system/repr.nim | 10 +- lib/system/sysio.nim | 122 +++++++------- lib/system/sysstr.nim | 4 +- 13 files changed, 371 insertions(+), 338 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 0ba99f915..73b470052 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2013 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -77,23 +77,23 @@ type auto* = expr any* = distinct auto - TSignedInt* = int|int8|int16|int32|int64 + SomeSignedInt* = int|int8|int16|int32|int64 ## type class matching all signed integer types - TUnsignedInt* = uint|uint8|uint16|uint32|uint64 + SomeUnsignedInt* = uint|uint8|uint16|uint32|uint64 ## type class matching all unsigned integer types - TInteger* = TSignedInt|TUnsignedInt + SomeInteger* = SomeSignedInt|SomeUnsignedInt ## type class matching all integer types - TOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32 + SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint8|uint16|uint32 ## type class matching all ordinal types; however this includes enums with ## holes. - TReal* = float|float32|float64 + SomeReal* = float|float32|float64 ## type class matching all floating point number types - TNumber* = TInteger|TReal + SomeNumber* = SomeInteger|SomeReal ## type class matching all number types proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.} @@ -108,6 +108,15 @@ proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.} ## # Do here programmer friendly expensive sanity checks. ## # Put here the normal code +when defined(nimalias): + {.deprecated: [ + TSignedInt: SomeSignedInt, + TUnsignedInt: SomeUnsignedInt, + TInteger: SomeInteger, + TReal: SomeReal, + TNumber: SomeNumber, + TOrdinal: SomeOrdinal].} + proc declared*(x: expr): bool {.magic: "Defined", noSideEffect.} ## Special compile-time procedure that checks whether `x` is ## declared. `x` has to be an identifier or a qualified identifier. @@ -202,10 +211,13 @@ type set*{.magic: "Set".}[T] ## Generic type to construct bit sets. type - TSlice* {.final, pure.}[T] = object ## builtin slice type - a*, b*: T ## the bounds + Slice* {.final, pure.}[T] = object ## builtin slice type + a*, b*: T ## the bounds -proc `..`*[T](a, b: T): TSlice[T] {.noSideEffect, inline.} = +when defined(nimalias): + {.deprecated: [TSlice: Slice].} + +proc `..`*[T](a, b: T): Slice[T] {.noSideEffect, inline.} = ## `slice`:idx: operator that constructs an interval ``[a, b]``, both `a` ## and `b` are inclusive. Slices can also be used in the set constructor ## and in ordinal case statements, but then they are special-cased by the @@ -213,7 +225,7 @@ proc `..`*[T](a, b: T): TSlice[T] {.noSideEffect, inline.} = result.a = a result.b = b -proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} = +proc `..`*[T](b: T): Slice[T] {.noSideEffect, inline.} = ## `slice`:idx: operator that constructs an interval ``[default(T), b]`` result.b = b @@ -307,29 +319,29 @@ type ## is an int type ranging from one to the maximum value ## of an int. This type is often useful for documentation and debugging. - TObject* {.exportc: "TNimObject", inheritable.} = + RootObj* {.exportc: "TNimObject", inheritable.} = object ## the root of Nimrod's object hierarchy. Objects should ## inherit from TObject or one of its descendants. However, ## objects that have no ancestor are allowed. - PObject* = ref TObject ## reference to TObject + RootRef* = ref RootObj ## reference to RootObj - TEffect* {.compilerproc.} = object of TObject ## \ + RootEffect* {.compilerproc.} = object of RootObj ## \ ## base effect class; each effect should ## inherit from `TEffect` unless you know what ## you doing. - FTime* = object of TEffect ## Time effect. - FIO* = object of TEffect ## IO effect. - FReadIO* = object of FIO ## Effect describing a read IO operation. - FWriteIO* = object of FIO ## Effect describing a write IO operation. - FExecIO* = object of FIO ## Effect describing an executing IO operation. + TimeEffect* = object of RootEffect ## Time effect. + IOEffect* = object of RootEffect ## IO effect. + ReadIOEffect* = object of IOEffect ## Effect describing a read IO operation. + WriteIOEffect* = object of IOEffect ## Effect describing a write IO operation. + ExecIOEffect* = object of IOEffect ## Effect describing an executing IO operation. - E_Base* {.compilerproc.} = object of TObject ## \ + Exception* {.compilerproc.} = object of RootObj ## \ ## Base exception class. ## - ## Each exception has to inherit from `E_Base`. See the full `exception + ## Each exception has to inherit from `Exception`. See the full `exception ## hierarchy`_. - parent: ref E_Base ## parent exception (can be used as a stack) - name: cstring ## The exception's name is its Nimrod identifier. + parent: ref Exception ## parent exception (can be used as a stack) + name: cstring ## The exception's name is its Nim identifier. ## This field is filled automatically in the ## ``raise`` statement. msg* {.exportc: "message".}: string ## the exception's message. Not @@ -337,130 +349,117 @@ type ## is bad style. trace: string - EAsynch* = object of E_Base ## \ - ## Abstract exception class for *asynchronous exceptions* (interrupts). - ## - ## This is rarely needed: most exception types inherit from `ESynch - ## <#ESynch>`_. See the full `exception hierarchy`_. - EControlC* = object of EAsynch ## \ - ## Raised for Ctrl+C key presses in console applications. - ## - ## See the full `exception hierarchy`_. - ESynch* = object of E_Base ## \ - ## Abstract exception class for *synchronous exceptions*. - ## - ## Most exceptions should be inherited (directly or indirectly) from - ## `ESynch` instead of from `EAsynch <#EAsynch>`_. See the full `exception - ## hierarchy`_. - ESystem* = object of ESynch ## \ + SystemError* = object of Exception ## \ ## Abstract class for exceptions that the runtime system raises. ## ## See the full `exception hierarchy`_. - EIO* = object of ESystem ## \ + IOError* = object of SystemError ## \ ## Raised if an IO error occured. ## ## See the full `exception hierarchy`_. - EOS* = object of ESystem ## \ + OSError* = object of SystemError ## \ ## Raised if an operating system service failed. ## ## See the full `exception hierarchy`_. errorCode*: int32 ## OS-defined error code describing this error. - EInvalidLibrary* = object of EOS ## \ + LibraryError* = object of OSError ## \ ## Raised if a dynamic library could not be loaded. ## ## See the full `exception hierarchy`_. - EResourceExhausted* = object of ESystem ## \ + ResourceExhaustedError* = object of SystemError ## \ ## Raised if a resource request could not be fullfilled. ## ## See the full `exception hierarchy`_. - EArithmetic* = object of ESynch ## \ + ArithmeticError* = object of Exception ## \ ## Raised if any kind of arithmetic error occured. ## ## See the full `exception hierarchy`_. - EDivByZero* {.compilerproc.} = object of EArithmetic ## \ + DivByZeroError* = object of ArithmeticError ## \ ## Raised for runtime integer divide-by-zero errors. ## ## See the full `exception hierarchy`_. - EOverflow* {.compilerproc.} = object of EArithmetic ## \ + + OverflowError* = object of ArithmeticError ## \ ## Raised for runtime integer overflows. ## ## This happens for calculations whose results are too large to fit in the ## provided bits. See the full `exception hierarchy`_. - EAccessViolation* {.compilerproc.} = object of ESynch ## \ + AccessViolationError* {.compilerproc.} = object of Exception ## \ ## Raised for invalid memory access errors ## ## See the full `exception hierarchy`_. - EAssertionFailed* {.compilerproc.} = object of ESynch ## \ + AssertionError* {.compilerproc.} = object of Exception ## \ ## Raised when assertion is proved wrong. ## ## Usually the result of using the `assert() template <#assert>`_. See the ## full `exception hierarchy`_. - EInvalidValue* = object of ESynch ## \ + ValueError* = object of Exception ## \ ## Raised for string and object conversion errors. - EInvalidKey* = object of EInvalidValue ## \ + KeyError* = object of ValueError ## \ ## Raised if a key cannot be found in a table. ## ## Mostly used by the `tables `_ module, it can also be raised ## by other collection modules like `sets `_ or `strtabs ## `_. See the full `exception hierarchy`_. - EOutOfMemory* = object of ESystem ## \ + OutOfMemError* = object of SystemError ## \ ## Raised for unsuccessful attempts to allocate memory. ## ## See the full `exception hierarchy`_. - EInvalidIndex* = object of ESynch ## \ + IndexError* = object of Exception ## \ ## Raised if an array index is out of bounds. ## ## See the full `exception hierarchy`_. - EInvalidField* = object of ESynch ## \ + + FieldError* = object of Exception ## \ ## Raised if a record field is not accessible because its dicriminant's ## value does not fit. ## ## See the full `exception hierarchy`_. - EOutOfRange* = object of ESynch ## \ + RangeError* = object of Exception ## \ ## Raised if a range check error occurred. ## ## See the full `exception hierarchy`_. - EStackOverflow* = object of ESystem ## \ + StackOverflowError* = object of SystemError ## \ ## Raised if the hardware stack used for subroutine calls overflowed. ## ## See the full `exception hierarchy`_. - ENoExceptionToReraise* = object of ESynch ## \ + ReraiseError* = object of Exception ## \ ## Raised if there is no exception to reraise. ## ## See the full `exception hierarchy`_. - EInvalidObjectAssignment* = object of ESynch ## \ + ObjectAssignmentError* = object of Exception ## \ ## Raised if an object gets assigned to its parent's object. ## ## See the full `exception hierarchy`_. - EInvalidObjectConversion* = object of ESynch ## \ + ObjectConversionError* = object of Exception ## \ ## Raised if an object is converted to an incompatible object type. ## ## See the full `exception hierarchy`_. - EFloatingPoint* = object of ESynch ## \ + FloatingPointError* = object of Exception ## \ ## Base class for floating point exceptions. ## ## See the full `exception hierarchy`_. - EFloatInvalidOp* {.compilerproc.} = object of EFloatingPoint ## \ + FloatInvalidOpError* = object of FloatingPointError ## \ ## Raised by invalid operations according to IEEE. ## ## Raised by ``0.0/0.0``, for example. See the full `exception ## hierarchy`_. - EFloatDivByZero* {.compilerproc.} = object of EFloatingPoint ## \ + FloatDivByZeroError* = object of FloatingPointError ## \ ## Raised by division by zero. ## ## Divisor is zero and dividend is a finite nonzero number. See the full ## `exception hierarchy`_. - EFloatOverflow* {.compilerproc.} = object of EFloatingPoint ## \ + FloatOverflowError* = object of FloatingPointError ## \ ## Raised for overflows. ## ## The operation produced a result that exceeds the range of the exponent. ## See the full `exception hierarchy`_. - EFloatUnderflow* {.compilerproc.} = object of EFloatingPoint ## \ + FloatUnderflowError* = object of FloatingPointError ## \ ## Raised for underflows. ## ## The operation produced a result that is too small to be represented as a ## normal number. See the full `exception hierarchy`_. - EFloatInexact* {.compilerproc.} = object of EFloatingPoint ## \ + FloatInexactError* = object of FloatingPointError ## \ ## Raised for inexact results. ## ## The operation produced a result that cannot be represented with infinite @@ -468,12 +467,37 @@ type ## ## **NOTE**: Nimrod currently does not detect these! See the full ## `exception hierarchy`_. - EDeadThread* = object of ESynch ## \ + DeadThreadError* = object of Exception ## \ ## Raised if it is attempted to send a message to a dead thread. ## ## See the full `exception hierarchy`_. - TResult* = enum Failure, Success + TResult* {.deprecated.} = enum Failure, Success + +{.deprecated: [TObject: RootObj, PObject: RootRef, TEffect: RootEffect, + FTime: TimeEffect, FIO: IOEffect, FReadIO: ReadIOEffect, + FWriteIO: WriteIOEffect, FExecIO: ExecIOEffect, + + E_Base: Exception, ESystem: SystemError, EIO: IOError, + EOS: OSError, EInvalidLibrary: LibraryError, + EResourceExhausted: ResourceExhaustedError, + EArithmetic: ArithmeticError, EDivByZero: DivByZeroError, + EOverflow: OverflowError, EAccessViolation: AccessViolationError, + EAssertionFailed: AssertionError, EInvalidValue: ValueError, + EInvalidKey: KeyError, EOutOfMemory: OutOfMemError, + EInvalidIndex: IndexError, EInvalidField: FieldError, + EOutOfRange: RangeError, EStackOverflow: StackOverflowError, + ENoExceptionToReraise: ReraiseError, + EInvalidObjectAssignment: ObjectAssignmentError, + EInvalidObjectConversion: ObjectConversionError, + EDeadThread: DeadThreadError, + EFloatInexact: FloatInexactError, + EFloatUnderflow: FloatUnderflowError, + EFloatingPoint: FloatingPointError, + EFloatInvalidOp: FloatInvalidOpError, + EFloatDivByZero: FloatDivByZeroError, + EFloatOverflow: FloatOverflowError +].} proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.} ## returns the size of ``x`` in bytes. Since this is a low-level proc, @@ -839,7 +863,7 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## is achieved by reversing the parameters for ``contains``; ``in`` then ## passes its arguments in reverse order. -proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} = +proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = ## Checks if `value` is withing the range of `s`; returns true iff ## `value >= s.a and value <= s.b` ## @@ -978,7 +1002,7 @@ proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} ## assert(tmp == "abcd") type - TEndian* = enum ## is a type describing the endianness of a processor. + Endianness* = enum ## is a type describing the endianness of a processor. littleEndian, bigEndian const @@ -994,23 +1018,23 @@ const ## is the time of compilation as a string of the form ## ``HH:MM:SS``. This works thanks to compiler magic. - NimrodVersion* {.magic: "NimrodVersion"}: string = "0.0.0" + NimVersion* {.magic: "NimrodVersion"}: string = "0.0.0" ## is the version of Nimrod as a string. ## This works thanks to compiler magic. - NimrodMajor* {.magic: "NimrodMajor"}: int = 0 + NimMajor* {.magic: "NimrodMajor"}: int = 0 ## is the major number of Nimrod's version. ## This works thanks to compiler magic. - NimrodMinor* {.magic: "NimrodMinor"}: int = 0 + NimMinor* {.magic: "NimrodMinor"}: int = 0 ## is the minor number of Nimrod's version. ## This works thanks to compiler magic. - NimrodPatch* {.magic: "NimrodPatch"}: int = 0 + NimPatch* {.magic: "NimrodPatch"}: int = 0 ## is the patch number of Nimrod's version. ## This works thanks to compiler magic. - cpuEndian* {.magic: "CpuEndian"}: TEndian = littleEndian + cpuEndian* {.magic: "CpuEndian"}: Endianness = littleEndian ## is the endianness of the target CPU. This is a valuable piece of ## information for low-level code only. This works thanks to compiler ## magic. @@ -1025,7 +1049,10 @@ const ## "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm". seqShallowFlag = low(int) - + +{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion, + NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].} + proc compileOption*(option: string): bool {. magic: "CompileOption", noSideEffect.} ## can be used to determine an on|off compile-time option. Example: @@ -1160,7 +1187,7 @@ proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.} ## debugging tool. type - TAddress* = int + ByteAddress* = int ## is the signed integer type that should be used for converting ## pointers to integer addresses for readability. @@ -1174,6 +1201,8 @@ type ## compiler supports. Currently this is ``float64``, but it is ## platform-dependant in general. +{.deprecated: [TAddress: ByteAddress].} + when defined(windows): type clong* {.importc: "long", nodecl.} = int32 @@ -1833,7 +1862,7 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) = ## # --> ["142", "242", "342", "442"] for i in 0..data.len-1: op(data[i]) -iterator fields*[T: tuple|object](x: T): TObject {. +iterator fields*[T: tuple|object](x: T): RootObj {. magic: "Fields", noSideEffect.} ## iterates over every field of `x`. Warning: This really transforms ## the 'for' and unrolls the loop. The current implementation also has a bug @@ -1844,7 +1873,7 @@ iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[a,b: expr] { ## Warning: This is really transforms the 'for' and unrolls the loop. ## The current implementation also has a bug that affects symbol binding ## in the loop body. -iterator fieldPairs*[T: tuple|object](x: T): TObject {. +iterator fieldPairs*[T: tuple|object](x: T): RootObj {. magic: "FieldPairs", noSideEffect.} ## Iterates over every field of `x` returning their name and value. ## @@ -1975,13 +2004,15 @@ when not defined(nimrodVM) and hostOS != "standalone": ## Ordinary code does not need to call this (and should not). type - TGC_Strategy* = enum ## the strategy the GC should use for the application + GC_Strategy* = enum ## the strategy the GC should use for the application gcThroughput, ## optimize for throughput gcResponsiveness, ## optimize for responsiveness (default) gcOptimizeTime, ## optimize for speed gcOptimizeSpace ## optimize for memory footprint - proc GC_setStrategy*(strategy: TGC_Strategy) {.rtl, deprecated.} + {.deprecated: [TGC_Strategy: GC_Strategy].} + + proc GC_setStrategy*(strategy: GC_Strategy) {.rtl, deprecated.} ## tells the GC the desired strategy for the application. ## **Deprecated** since version 0.8.14. This has always been a nop. @@ -2024,7 +2055,7 @@ const NimStackTrace = compileOption("stacktrace") # of the code var - globalRaiseHook*: proc (e: ref E_Base): bool {.nimcall, gcsafe.} + globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, gcsafe.} ## with this hook you can influence exception handling on a global level. ## If not nil, every 'raise' statement ends up calling this hook. Ordinary ## application code should never set this hook! You better know what you @@ -2032,7 +2063,7 @@ var ## exception is caught and does not propagate further through the call ## stack. - localRaiseHook* {.threadvar.}: proc (e: ref E_Base): bool {.nimcall, gcsafe.} + localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, gcsafe.} ## with this hook you can influence exception handling on a ## thread local level. ## If not nil, every 'raise' statement ends up calling this hook. Ordinary @@ -2092,7 +2123,7 @@ elif hostOS != "standalone": inc(i) {.pop.} -proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [FWriteIO], gcsafe.} +proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], gcsafe.} ## Writes and flushes the parameters to the standard output. ## ## Special built-in that takes a variable number of arguments. Each argument @@ -2224,9 +2255,9 @@ when not defined(JS): #and not defined(NimrodVM): type CFile {.importc: "FILE", header: "", final, incompletestruct.} = object - TFile* = ptr CFile ## The type representing a file handle. + File* = ptr CFile ## The type representing a file handle. - TFileMode* = enum ## The file mode when opening a file. + FileMode* = enum ## The file mode when opening a file. fmRead, ## Open the file for read access only. fmWrite, ## Open the file for write access only. fmReadWrite, ## Open the file for read and write access. @@ -2238,49 +2269,51 @@ when not defined(JS): #and not defined(NimrodVM): fmAppend ## Open the file for writing only; append data ## at the end. - TFileHandle* = cint ## type that represents an OS file handle; this is - ## useful for low-level file access + FileHandle* = cint ## type that represents an OS file handle; this is + ## useful for low-level file access + + {.deprecated: [TFile: File, TFileHandle: FileHandle, TFileMode: FileMode].} # text file handling: var - stdin* {.importc: "stdin", header: "".}: TFile + stdin* {.importc: "stdin", header: "".}: File ## The standard input stream. - stdout* {.importc: "stdout", header: "".}: TFile + stdout* {.importc: "stdout", header: "".}: File ## The standard output stream. - stderr* {.importc: "stderr", header: "".}: TFile + stderr* {.importc: "stderr", header: "".}: File ## The standard error stream. when defined(useStdoutAsStdmsg): - template stdmsg*: TFile = stdout + template stdmsg*: File = stdout else: - template stdmsg*: TFile = stderr + template stdmsg*: File = stderr ## Template which expands to either stdout or stderr depending on ## `useStdoutAsStdmsg` compile-time switch. - proc open*(f: var TFile, filename: string, - mode: TFileMode = fmRead, bufSize: int = -1): bool {.tags: [], + proc open*(f: var File, filename: string, + mode: FileMode = fmRead, bufSize: int = -1): bool {.tags: [], gcsafe.} ## Opens a file named `filename` with given `mode`. ## ## Default mode is readonly. Returns true iff the file could be opened. ## This throws no exception if the file could not be opened. - proc open*(f: var TFile, filehandle: TFileHandle, - mode: TFileMode = fmRead): bool {.tags: [], gcsafe.} + proc open*(f: var File, filehandle: FileHandle, + mode: FileMode = fmRead): bool {.tags: [], gcsafe.} ## Creates a ``TFile`` from a `filehandle` with given `mode`. ## ## Default mode is readonly. Returns true iff the file could be opened. proc open*(filename: string, - mode: TFileMode = fmRead, bufSize: int = -1): TFile = + mode: FileMode = fmRead, bufSize: int = -1): File = ## Opens a file named `filename` with given `mode`. ## ## Default mode is readonly. Raises an ``IO`` exception if the file ## could not be opened. if not open(result, filename, mode, bufSize): - sysFatal(EIO, "cannot open: ", filename) + sysFatal(IOError, "cannot open: ", filename) - proc reopen*(f: TFile, filename: string, mode: TFileMode = fmRead): bool {. + proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {. tags: [], gcsafe.} ## reopens the file `f` with given `filename` and `mode`. This ## is often used to redirect the `stdin`, `stdout` or `stderr` @@ -2288,52 +2321,52 @@ when not defined(JS): #and not defined(NimrodVM): ## ## Default mode is readonly. Returns true iff the file could be reopened. - proc close*(f: TFile) {.importc: "fclose", header: "", tags: [].} + proc close*(f: File) {.importc: "fclose", header: "", tags: [].} ## Closes the file. - proc endOfFile*(f: TFile): bool {.tags: [], gcsafe.} + proc endOfFile*(f: File): bool {.tags: [], gcsafe.} ## Returns true iff `f` is at the end. - proc readChar*(f: TFile): char {. - importc: "fgetc", header: "", tags: [FReadIO].} + proc readChar*(f: File): char {. + importc: "fgetc", header: "", tags: [ReadIOEffect].} ## Reads a single character from the stream `f`. - proc flushFile*(f: TFile) {. - importc: "fflush", header: "", tags: [FWriteIO].} + proc flushFile*(f: File) {. + importc: "fflush", header: "", tags: [WriteIOEffect].} ## Flushes `f`'s buffer. - proc readAll*(file: TFile): TaintedString {.tags: [FReadIO], gcsafe.} + proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], gcsafe.} ## Reads all data from the stream `file`. ## ## Raises an IO exception in case of an error. It is an error if the ## current file position is not at the beginning of the file. - proc readFile*(filename: string): TaintedString {.tags: [FReadIO], gcsafe.} + proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], gcsafe.} ## Opens a file named `filename` for reading. Then calls `readAll` ## and closes the file afterwards. Returns the string. ## Raises an IO exception in case of an error. - proc writeFile*(filename, content: string) {.tags: [FWriteIO], gcsafe.} + proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], gcsafe.} ## Opens a file named `filename` for writing. Then writes the ## `content` completely to the file and closes the file afterwards. ## Raises an IO exception in case of an error. - proc write*(f: TFile, r: float32) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, i: int) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, i: BiggestInt) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, r: BiggestFloat) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, s: string) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, b: bool) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, c: char) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, c: cstring) {.tags: [FWriteIO], gcsafe.} - proc write*(f: TFile, a: varargs[string, `$`]) {.tags: [FWriteIO], gcsafe.} + proc write*(f: File, r: float32) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, i: int) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, s: string) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, b: bool) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, c: char) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], gcsafe.} + proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], gcsafe.} ## Writes a value to the file `f`. May throw an IO exception. - proc readLine*(f: TFile): TaintedString {.tags: [FReadIO], gcsafe.} + proc readLine*(f: File): TaintedString {.tags: [ReadIOEffect], gcsafe.} ## reads a line of text from the file `f`. May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or ## ``CRLF``. The newline character(s) are not part of the returned string. - proc readLine*(f: TFile, line: var TaintedString): bool {.tags: [FReadIO], + proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect], gcsafe.} ## reads a line of text from the file `f` into `line`. `line` must not be ## ``nil``! May throw an IO exception. @@ -2343,63 +2376,63 @@ when not defined(JS): #and not defined(NimrodVM): ## otherwise. If ``false`` is returned `line` contains no new data. when not defined(booting): - proc writeln*[Ty](f: TFile, x: varargs[Ty, `$`]) {.inline, - tags: [FWriteIO], gcsafe.} + proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, + tags: [WriteIOEffect], gcsafe.} ## writes the values `x` to `f` and then writes "\n". ## May throw an IO exception. else: - proc writeln*[Ty](f: TFile, x: varargs[Ty, `$`]) {.inline, - tags: [FWriteIO].} + proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, + tags: [WriteIOEffect].} - proc getFileSize*(f: TFile): int64 {.tags: [FReadIO], gcsafe.} + proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], gcsafe.} ## retrieves the file size (in bytes) of `f`. - proc readBytes*(f: TFile, a: var openArray[int8], start, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readBytes*(f: File, a: var openArray[int8], start, len: int): int {. + tags: [ReadIOEffect], gcsafe.} ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc readChars*(f: TFile, a: var openArray[char], start, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readChars*(f: File, a: var openArray[char], start, len: int): int {. + tags: [ReadIOEffect], gcsafe.} ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc readBuffer*(f: TFile, buffer: pointer, len: int): int {. - tags: [FReadIO], gcsafe.} + proc readBuffer*(f: File, buffer: pointer, len: int): int {. + tags: [ReadIOEffect], gcsafe.} ## reads `len` bytes into the buffer pointed to by `buffer`. Returns ## the actual number of bytes that have been read which may be less than ## `len` (if not as many bytes are remaining), but not greater. - proc writeBytes*(f: TFile, a: openArray[int8], start, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeBytes*(f: File, a: openArray[int8], start, len: int): int {. + tags: [WriteIOEffect], gcsafe.} ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns ## the number of actual written bytes, which may be less than `len` in case ## of an error. - proc writeChars*(f: TFile, a: openArray[char], start, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeChars*(f: File, a: openArray[char], start, len: int): int {. + tags: [WriteIOEffect], gcsafe.} ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns ## the number of actual written bytes, which may be less than `len` in case ## of an error. - proc writeBuffer*(f: TFile, buffer: pointer, len: int): int {. - tags: [FWriteIO], gcsafe.} + proc writeBuffer*(f: File, buffer: pointer, len: int): int {. + tags: [WriteIOEffect], gcsafe.} ## writes the bytes of buffer pointed to by the parameter `buffer` to the ## file `f`. Returns the number of actual written bytes, which may be less ## than `len` in case of an error. - proc setFilePos*(f: TFile, pos: int64) {.gcsafe.} + proc setFilePos*(f: File, pos: int64) {.gcsafe.} ## sets the position of the file pointer that is used for read/write ## operations. The file's first byte has the index zero. - proc getFilePos*(f: TFile): int64 {.gcsafe.} + proc getFilePos*(f: File): int64 {.gcsafe.} ## retrieves the current position of the file pointer that is used to ## read from the file `f`. The file's first byte has the index zero. - proc fileHandle*(f: TFile): TFileHandle {.importc: "fileno", - header: ""} + proc getFileHandle*(f: File): FileHandle {.importc: "fileno", + header: ""} ## returns the OS file handle of the file ``f``. This is only useful for ## platform specific programming. @@ -2454,7 +2487,7 @@ when not defined(JS): #and not defined(NimrodVM): status: int context: C_JmpBuf hasRaiseAction: bool - raiseAction: proc (e: ref E_Base): bool {.closure.} + raiseAction: proc (e: ref Exception): bool {.closure.} when declared(initAllocator): initAllocator() @@ -2470,14 +2503,14 @@ when not defined(JS): #and not defined(NimrodVM): ## allows you to override the behaviour of your application when CTRL+C ## is pressed. Only one such hook is supported. - proc writeStackTrace*() {.tags: [FWriteIO].} + proc writeStackTrace*() {.tags: [WriteIOEffect].} ## writes the current stack trace to ``stderr``. This is only works ## for debug builds. when hostOS != "standalone": proc getStackTrace*(): string ## gets the current stack trace. This only works for debug builds. - proc getStackTrace*(e: ref E_Base): string + proc getStackTrace*(e: ref Exception): string ## gets the stack trace associated with `e`, which is the stack that ## lead to the ``raise`` statement. This only works for debug builds. @@ -2505,7 +2538,7 @@ when not defined(JS): #and not defined(NimrodVM): proc getDiscriminant(aa: pointer, n: ptr TNimNode): int = sysAssert(n.kind == nkCase, "getDiscriminant: node != nkCase") var d: int - var a = cast[TAddress](aa) + var a = cast[ByteAddress](aa) case n.typ.size of 1: d = ze(cast[ptr int8](a +% n.offset)[]) of 2: d = ze(cast[ptr int16](a +% n.offset)[]) @@ -2534,7 +2567,7 @@ when not defined(JS): #and not defined(NimrodVM): include "system/sysio" when hostOS != "standalone": - iterator lines*(filename: string): TaintedString {.tags: [FReadIO].} = + iterator lines*(filename: string): TaintedString {.tags: [ReadIOEffect].} = ## Iterates over any line in the file named `filename`. ## ## If the file does not exist `EIO` is raised. The trailing newline @@ -2553,14 +2586,14 @@ when not defined(JS): #and not defined(NimrodVM): while f.readLine(res): yield res close(f) - iterator lines*(f: TFile): TaintedString {.tags: [FReadIO].} = + iterator lines*(f: File): TaintedString {.tags: [ReadIOEffect].} = ## Iterate over any line in the file `f`. ## ## The trailing newline character(s) are removed from the iterated lines. ## Example: ## ## .. code-block:: nimrod - ## proc countZeros(filename: TFile): tuple[lines, zeros: int] = + ## proc countZeros(filename: File): tuple[lines, zeros: int] = ## for line in filename.lines: ## for letter in line: ## if letter == '0': @@ -2573,7 +2606,7 @@ when not defined(JS): #and not defined(NimrodVM): include "system/assign" include "system/repr" - proc getCurrentException*(): ref E_Base {.compilerRtl, inl, gcsafe.} = + proc getCurrentException*(): ref Exception {.compilerRtl, inl, gcsafe.} = ## retrieves the current exception; if there is none, nil is returned. result = currException @@ -2583,7 +2616,7 @@ when not defined(JS): #and not defined(NimrodVM): var e = getCurrentException() return if e == nil: "" else: e.msg - proc onRaise*(action: proc(e: ref E_Base): bool{.closure.}) = + proc onRaise*(action: proc(e: ref Exception): bool{.closure.}) = ## can be used in a ``try`` statement to setup a Lisp-like ## `condition system`:idx:\: This prevents the 'raise' statement to ## raise an exception but instead calls ``action``. @@ -2721,11 +2754,11 @@ template spliceImpl(s, a, L, b: expr): stmt {.immediate.} = for i in 0 .. `_ or `passL ## `_. -proc `+=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} +proc `+=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} ## Increments an ordinal -proc `-=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.magic: "Dec", noSideEffect.} +proc `-=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Dec", noSideEffect.} ## Decrements an ordinal -proc `*=`*[T: TOrdinal|uint|uint64](x: var T, y: T) {.inline, noSideEffect.} = +proc `*=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.inline, noSideEffect.} = ## Binary `*=` operator for ordinals x = x * y @@ -2897,7 +2930,7 @@ template currentSourcePath*: string = instantiationInfo(-1, true).filename ## returns the full file-system path of the current source proc raiseAssert*(msg: string) {.noinline.} = - sysFatal(EAssertionFailed, msg) + sysFatal(AssertionError, msg) when true: proc failedAssertImpl*(msg: string) {.raises: [], tags: [].} = @@ -3046,7 +3079,7 @@ when hostOS != "standalone": if x == nil: x = y else: x.add(y) -proc locals*(): TObject {.magic: "Locals", noSideEffect.} = +proc locals*(): RootObj {.magic: "Locals", noSideEffect.} = ## generates a tuple constructor expression listing all the local variables ## in the current scope. This is quite fast as it does not rely ## on any debug or runtime information. Note that in constrast to what diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 9638472c2..f225b53ed 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -218,7 +218,7 @@ proc llAlloc(a: var TMemRegion, size: int): pointer = a.llmem.size = PageSize - sizeof(TLLChunk) a.llmem.acc = sizeof(TLLChunk) a.llmem.next = old - result = cast[pointer](cast[TAddress](a.llmem) + a.llmem.acc) + result = cast[pointer](cast[ByteAddress](a.llmem) + a.llmem.acc) dec(a.llmem.size, size) inc(a.llmem.acc, size) zeroMem(result, size) @@ -321,7 +321,7 @@ iterator allObjects(m: TMemRegion): pointer {.inline.} = var c = cast[PSmallChunk](c) let size = c.size - var a = cast[TAddress](addr(c.data)) + var a = cast[ByteAddress](addr(c.data)) let limit = a + c.acc while a <% limit: yield cast[pointer](a) @@ -335,27 +335,27 @@ proc isCell(p: pointer): bool {.inline.} = # ------------- chunk management ---------------------------------------------- proc pageIndex(c: PChunk): int {.inline.} = - result = cast[TAddress](c) shr PageShift + result = cast[ByteAddress](c) shr PageShift proc pageIndex(p: pointer): int {.inline.} = - result = cast[TAddress](p) shr PageShift + result = cast[ByteAddress](p) shr PageShift proc pageAddr(p: pointer): PChunk {.inline.} = - result = cast[PChunk](cast[TAddress](p) and not PageMask) + result = cast[PChunk](cast[ByteAddress](p) and not PageMask) #sysAssert(Contains(allocator.chunkStarts, pageIndex(result))) proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk = incCurrMem(a, size) inc(a.freeMem, size) result = cast[PBigChunk](osAllocPages(size)) - sysAssert((cast[TAddress](result) and PageMask) == 0, "requestOsChunks 1") + sysAssert((cast[ByteAddress](result) and PageMask) == 0, "requestOsChunks 1") #zeroMem(result, size) result.next = nil result.prev = nil result.used = false result.size = size # update next.prevSize: - var nxt = cast[TAddress](result) +% size + var nxt = cast[ByteAddress](result) +% size sysAssert((nxt and PageMask) == 0, "requestOsChunks 2") var next = cast[PChunk](nxt) if pageIndex(next) in a.chunkStarts: @@ -363,7 +363,7 @@ proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk = next.prevSize = size # set result.prevSize: var lastSize = if a.lastSize != 0: a.lastSize else: PageSize - var prv = cast[TAddress](result) -% lastSize + var prv = cast[ByteAddress](result) -% lastSize sysAssert((nxt and PageMask) == 0, "requestOsChunks 3") var prev = cast[PChunk](prv) if pageIndex(prev) in a.chunkStarts and prev.size == lastSize: @@ -376,7 +376,7 @@ proc requestOsChunks(a: var TMemRegion, size: int): PBigChunk = proc freeOsChunks(a: var TMemRegion, p: pointer, size: int) = # update next.prevSize: var c = cast[PChunk](p) - var nxt = cast[TAddress](p) +% c.size + var nxt = cast[ByteAddress](p) +% c.size sysAssert((nxt and PageMask) == 0, "freeOsChunks") var next = cast[PChunk](nxt) if pageIndex(next) in a.chunkStarts: @@ -429,8 +429,8 @@ proc listRemove[T](head: var T, c: T) {.inline.} = proc updatePrevSize(a: var TMemRegion, c: PBigChunk, prevSize: int) {.inline.} = - var ri = cast[PChunk](cast[TAddress](c) +% c.size) - sysAssert((cast[TAddress](ri) and PageMask) == 0, "updatePrevSize") + var ri = cast[PChunk](cast[ByteAddress](c) +% c.size) + sysAssert((cast[ByteAddress](ri) and PageMask) == 0, "updatePrevSize") if isAccessible(a, ri): ri.prevSize = prevSize @@ -439,8 +439,8 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = sysAssert(c.size >= PageSize, "freeBigChunk") inc(a.freeMem, c.size) when coalescRight: - var ri = cast[PChunk](cast[TAddress](c) +% c.size) - sysAssert((cast[TAddress](ri) and PageMask) == 0, "freeBigChunk 2") + var ri = cast[PChunk](cast[ByteAddress](c) +% c.size) + sysAssert((cast[ByteAddress](ri) and PageMask) == 0, "freeBigChunk 2") if isAccessible(a, ri) and chunkUnused(ri): sysAssert(not isSmallChunk(ri), "freeBigChunk 3") if not isSmallChunk(ri): @@ -449,8 +449,8 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = excl(a.chunkStarts, pageIndex(ri)) when coalescLeft: if c.prevSize != 0: - var le = cast[PChunk](cast[TAddress](c) -% c.prevSize) - sysAssert((cast[TAddress](le) and PageMask) == 0, "freeBigChunk 4") + var le = cast[PChunk](cast[ByteAddress](c) -% c.prevSize) + sysAssert((cast[ByteAddress](le) and PageMask) == 0, "freeBigChunk 4") if isAccessible(a, le) and chunkUnused(le): sysAssert(not isSmallChunk(le), "freeBigChunk 5") if not isSmallChunk(le): @@ -468,7 +468,7 @@ proc freeBigChunk(a: var TMemRegion, c: PBigChunk) = freeOsChunks(a, c, c.size) proc splitChunk(a: var TMemRegion, c: PBigChunk, size: int) = - var rest = cast[PBigChunk](cast[TAddress](c) +% size) + var rest = cast[PBigChunk](cast[ByteAddress](c) +% size) sysAssert(rest notin a.freeChunksList, "splitChunk") rest.size = c.size - size rest.used = false @@ -559,7 +559,7 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = c.prev = nil listAdd(a.freeSmallChunks[s], c) result = addr(c.data) - sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 4") + sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 4") else: sysAssert(allocInv(a), "rawAlloc: begin c != nil") sysAssert c.next != c, "rawAlloc 5" @@ -569,21 +569,21 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = if c.freeList == nil: sysAssert(c.acc + smallChunkOverhead() + size <= SmallChunkSize, "rawAlloc 7") - result = cast[pointer](cast[TAddress](addr(c.data)) +% c.acc) + result = cast[pointer](cast[ByteAddress](addr(c.data)) +% c.acc) inc(c.acc, size) else: result = c.freeList sysAssert(c.freeList.zeroField == 0, "rawAlloc 8") c.freeList = c.freeList.next dec(c.free, size) - sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 9") + sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 9") sysAssert(allocInv(a), "rawAlloc: end c != nil") sysAssert(allocInv(a), "rawAlloc: before c.free < size") if c.free < size: sysAssert(allocInv(a), "rawAlloc: before listRemove test") listRemove(a.freeSmallChunks[s], c) sysAssert(allocInv(a), "rawAlloc: end listRemove test") - sysAssert(((cast[TAddress](result) and PageMask) - smallChunkOverhead()) %% + sysAssert(((cast[ByteAddress](result) and PageMask) - smallChunkOverhead()) %% size == 0, "rawAlloc 21") sysAssert(allocInv(a), "rawAlloc: end small size") else: @@ -594,9 +594,9 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = sysAssert c.next == nil, "rawAlloc 11" sysAssert c.size == size, "rawAlloc 12" result = addr(c.data) - sysAssert((cast[TAddress](result) and (MemAlign-1)) == 0, "rawAlloc 13") + sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 13") if a.root == nil: a.root = bottom - add(a, a.root, cast[TAddress](result), cast[TAddress](result)+%size) + add(a, a.root, cast[ByteAddress](result), cast[TAddress](result)+%size) sysAssert(isAccessible(a, result), "rawAlloc 14") sysAssert(allocInv(a), "rawAlloc: end") when logAlloc: cprintf("rawAlloc: %ld %p\n", requestedSize, result) @@ -613,7 +613,7 @@ proc rawDealloc(a: var TMemRegion, p: pointer) = # `p` is within a small chunk: var c = cast[PSmallChunk](c) var s = c.size - sysAssert(((cast[TAddress](p) and PageMask) - smallChunkOverhead()) %% + sysAssert(((cast[ByteAddress](p) and PageMask) - smallChunkOverhead()) %% s == 0, "rawDealloc 3") var f = cast[ptr TFreeCell](p) #echo("setting to nil: ", $cast[TAddress](addr(f.zeroField))) @@ -636,7 +636,7 @@ proc rawDealloc(a: var TMemRegion, p: pointer) = listRemove(a.freeSmallChunks[s div MemAlign], c) c.size = SmallChunkSize freeBigChunk(a, cast[PBigChunk](c)) - sysAssert(((cast[TAddress](p) and PageMask) - smallChunkOverhead()) %% + sysAssert(((cast[ByteAddress](p) and PageMask) - smallChunkOverhead()) %% s == 0, "rawDealloc 2") else: # set to 0xff to check for usage after free bugs: @@ -655,7 +655,7 @@ proc isAllocatedPtr(a: TMemRegion, p: pointer): bool = if not chunkUnused(c): if isSmallChunk(c): var c = cast[PSmallChunk](c) - var offset = (cast[TAddress](p) and (PageSize-1)) -% + var offset = (cast[ByteAddress](p) and (PageSize-1)) -% smallChunkOverhead() result = (c.acc >% offset) and (offset %% c.size == 0) and (cast[ptr TFreeCell](p).zeroField >% 1) @@ -673,12 +673,12 @@ proc interiorAllocatedPtr(a: TMemRegion, p: pointer): pointer = if not chunkUnused(c): if isSmallChunk(c): var c = cast[PSmallChunk](c) - var offset = (cast[TAddress](p) and (PageSize-1)) -% + var offset = (cast[ByteAddress](p) and (PageSize-1)) -% smallChunkOverhead() if c.acc >% offset: - sysAssert(cast[TAddress](addr(c.data)) +% offset == - cast[TAddress](p), "offset is not what you think it is") - var d = cast[ptr TFreeCell](cast[TAddress](addr(c.data)) +% + sysAssert(cast[ByteAddress](addr(c.data)) +% offset == + cast[ByteAddress](p), "offset is not what you think it is") + var d = cast[ptr TFreeCell](cast[ByteAddress](addr(c.data)) +% offset -% (offset %% c.size)) if d.zeroField >% 1: result = d @@ -704,7 +704,7 @@ proc interiorAllocatedPtr(a: TMemRegion, p: pointer): pointer = sysAssert isAllocatedPtr(a, result), " result wrong pointer!" proc ptrSize(p: pointer): int = - var x = cast[pointer](cast[TAddress](p) -% sizeof(TFreeCell)) + var x = cast[pointer](cast[ByteAddress](p) -% sizeof(TFreeCell)) var c = pageAddr(p) sysAssert(not chunkUnused(c), "ptrSize") result = c.size -% sizeof(TFreeCell) @@ -715,7 +715,7 @@ proc alloc(allocator: var TMemRegion, size: int): pointer = result = rawAlloc(allocator, size+sizeof(TFreeCell)) cast[ptr TFreeCell](result).zeroField = 1 # mark it as used sysAssert(not isAllocatedPtr(allocator, result), "alloc") - result = cast[pointer](cast[TAddress](result) +% sizeof(TFreeCell)) + result = cast[pointer](cast[ByteAddress](result) +% sizeof(TFreeCell)) proc alloc0(allocator: var TMemRegion, size: int): pointer = result = alloc(allocator, size) @@ -723,7 +723,7 @@ proc alloc0(allocator: var TMemRegion, size: int): pointer = proc dealloc(allocator: var TMemRegion, p: pointer) = sysAssert(p != nil, "dealloc 0") - var x = cast[pointer](cast[TAddress](p) -% sizeof(TFreeCell)) + var x = cast[pointer](cast[ByteAddress](p) -% sizeof(TFreeCell)) sysAssert(x != nil, "dealloc 1") sysAssert(isAccessible(allocator, x), "is not accessible") sysAssert(cast[ptr TFreeCell](x).zeroField == 1, "dealloc 2") @@ -769,7 +769,7 @@ template instantiateForRegion(allocator: expr) = result = interiorAllocatedPtr(allocator, p) proc isAllocatedPtr*(p: pointer): bool = - let p = cast[pointer](cast[TAddress](p)-%TAddress(sizeof(TCell))) + let p = cast[pointer](cast[ByteAddress](p)-%TAddress(sizeof(TCell))) result = isAllocatedPtr(allocator, p) proc deallocOsPages = deallocOsPages(allocator) @@ -784,7 +784,7 @@ template instantiateForRegion(allocator: expr) = dealloc(allocator, p) proc realloc(p: pointer, newsize: int): pointer = - result = realloc(allocator, p, newsize) + result = realloc(allocator, p, newSize) when false: proc countFreeMem(): int = @@ -833,7 +833,7 @@ template instantiateForRegion(allocator: expr) = result = realloc(sharedHeap, p, newsize) releaseSys(heapLock) else: - result = realloc(p, newsize) + result = realloc(p, newSize) when hasThreadSupport: diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim index 1cc9b41e6..c4df287cf 100644 --- a/lib/system/arithm.nim +++ b/lib/system/arithm.nim @@ -12,10 +12,10 @@ proc raiseOverflow {.compilerproc, noinline, noreturn.} = # a single proc to reduce code size to a minimum - sysFatal(EOverflow, "over- or underflow") + sysFatal(OverflowError, "over- or underflow") proc raiseDivByZero {.compilerproc, noinline, noreturn.} = - sysFatal(EDivByZero, "divison by zero") + sysFatal(DivByZeroError, "divison by zero") proc addInt64(a, b: int64): int64 {.compilerProc, inline.} = result = a +% b @@ -328,16 +328,16 @@ when not declared(mulInt): # written in other languages. proc raiseFloatInvalidOp {.noinline, noreturn.} = - sysFatal(EFloatInvalidOp, "FPU operation caused a NaN result") + sysFatal(FloatInvalidOpError, "FPU operation caused a NaN result") proc nanCheck(x: float64) {.compilerProc, inline.} = if x != x: raiseFloatInvalidOp() proc raiseFloatOverflow(x: float64) {.noinline, noreturn.} = if x > 0.0: - sysFatal(EFloatOverflow, "FPU operation caused an overflow") + sysFatal(FloatOverflowError, "FPU operation caused an overflow") else: - sysFatal(EFloatUnderflow, "FPU operations caused an underflow") + sysFatal(FloatUnderflowError, "FPU operations caused an underflow") proc infCheck(x: float64) {.compilerProc, inline.} = if x != 0.0 and x*0.5 == x: raiseFloatOverflow(x) diff --git a/lib/system/assign.nim b/lib/system/assign.nim index a213a9d97..6c58c24c2 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -13,8 +13,8 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.gcsafe. proc genericAssignAux(dest, src: pointer, n: ptr TNimNode, shallow: bool) {.gcsafe.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) case n.kind of nkSlot: genericAssignAux(cast[pointer](d +% n.offset), @@ -40,8 +40,8 @@ proc genericAssignAux(dest, src: pointer, n: ptr TNimNode, proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) sysAssert(mt != nil, "genericAssignAux 2") case mt.kind of tyString: @@ -62,11 +62,11 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) = return sysAssert(dest != nil, "genericAssignAux 3") unsureAsgnRef(x, newSeq(mt, seq.len)) - var dst = cast[TAddress](cast[PPointer](dest)[]) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: genericAssignAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% + cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), mt.base, shallow) of tyObject: @@ -130,15 +130,15 @@ proc genericSeqAssign(dest, src: pointer, mt: PNimType) {.compilerProc.} = proc genericAssignOpenArray(dest, src: pointer, len: int, mt: PNimType) {.compilerproc.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) for i in 0..len-1: genericAssign(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base) proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, gcsafe.} proc objectInitAux(dest: pointer, n: ptr TNimNode) {.gcsafe.} = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case n.kind of nkNone: sysAssert(false, "objectInitAux") of nkSlot: objectInit(cast[pointer](d +% n.offset), n.typ) @@ -152,7 +152,7 @@ proc objectInitAux(dest: pointer, n: ptr TNimNode) {.gcsafe.} = proc objectInit(dest: pointer, typ: PNimType) = # the generic init proc that takes care of initialization of complex # objects on the stack or heap - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case typ.kind of tyObject: # iterate over any structural type @@ -184,7 +184,7 @@ else: proc genericReset(dest: pointer, mt: PNimType) {.compilerProc, gcsafe.} proc genericResetAux(dest: pointer, n: ptr TNimNode) = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case n.kind of nkNone: sysAssert(false, "genericResetAux") of nkSlot: genericReset(cast[pointer](d +% n.offset), n.typ) @@ -196,7 +196,7 @@ proc genericResetAux(dest: pointer, n: ptr TNimNode) = zeroMem(cast[pointer](d +% n.offset), n.typ.size) proc genericReset(dest: pointer, mt: PNimType) = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) sysAssert(mt != nil, "genericReset 2") case mt.kind of tyString, tyRef, tySequence: @@ -223,4 +223,4 @@ proc FieldDiscriminantCheck(oldDiscVal, newDiscVal: int, var oldBranch = selectBranch(oldDiscVal, L, a) var newBranch = selectBranch(newDiscVal, L, a) if newBranch != oldBranch and oldDiscVal != 0: - sysFatal(EInvalidField, "assignment to discriminant changes object branch") + sysFatal(FieldError, "assignment to discriminant changes object branch") diff --git a/lib/system/cellsets.nim b/lib/system/cellsets.nim index 653aed241..0e3a01eba 100644 --- a/lib/system/cellsets.nim +++ b/lib/system/cellsets.nim @@ -27,7 +27,7 @@ type TBitIndex = range[0..UnitsPerPage-1] TPageDesc {.final, pure.} = object next: PPageDesc # all nodes are connected with this pointer - key: TAddress # start address at bit 0 + key: ByteAddress # start address at bit 0 bits: array[TBitIndex, int] # a bit vector PPageDescArray = ptr array[0..1000_000, PPageDesc] @@ -98,7 +98,7 @@ proc nextTry(h, maxHash: int): int {.inline.} = # generates each int in range(maxHash) exactly once (see any text on # random-number generation for proof). -proc cellSetGet(t: TCellSet, key: TAddress): PPageDesc = +proc cellSetGet(t: TCellSet, key: ByteAddress): PPageDesc = var h = cast[int](key) and t.max while t.data[h] != nil: if t.data[h].key == key: return t.data[h] @@ -123,7 +123,7 @@ proc cellSetEnlarge(t: var TCellSet) = dealloc(t.data) t.data = n -proc cellSetPut(t: var TCellSet, key: TAddress): PPageDesc = +proc cellSetPut(t: var TCellSet, key: ByteAddress): PPageDesc = var h = cast[int](key) and t.max while true: var x = t.data[h] @@ -147,7 +147,7 @@ proc cellSetPut(t: var TCellSet, key: TAddress): PPageDesc = # ---------- slightly higher level procs -------------------------------------- proc contains(s: TCellSet, cell: PCell): bool = - var u = cast[TAddress](cell) + var u = cast[ByteAddress](cell) var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign @@ -156,13 +156,13 @@ proc contains(s: TCellSet, cell: PCell): bool = result = false proc incl(s: var TCellSet, cell: PCell) {.noinline.} = - var u = cast[TAddress](cell) + var u = cast[ByteAddress](cell) var t = cellSetPut(s, u shr PageShift) u = (u %% PageSize) /% MemAlign t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask)) proc excl(s: var TCellSet, cell: PCell) = - var u = cast[TAddress](cell) + var u = cast[ByteAddress](cell) var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign @@ -170,7 +170,7 @@ proc excl(s: var TCellSet, cell: PCell) = not (1 shl (u and IntMask))) proc containsOrIncl(s: var TCellSet, cell: PCell): bool = - var u = cast[TAddress](cell) + var u = cast[ByteAddress](cell) var t = cellSetGet(s, u shr PageShift) if t != nil: u = (u %% PageSize) /% MemAlign diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index c018a7631..5c32a307a 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -13,13 +13,13 @@ proc raiseRangeError(val: BiggestInt) {.compilerproc, noreturn, noinline.} = when hostOS == "standalone": sysFatal(EOutOfRange, "value out of range") else: - sysFatal(EOutOfRange, "value out of range: ", $val) + sysFatal(RangeError, "value out of range: ", $val) proc raiseIndexError() {.compilerproc, noreturn, noinline.} = - sysFatal(EInvalidIndex, "index out of bounds") + sysFatal(IndexError, "index out of bounds") proc raiseFieldError(f: string) {.compilerproc, noreturn, noinline.} = - sysFatal(EInvalidField, f, " is not accessible") + sysFatal(FieldError, f, " is not accessible") proc chckIndx(i, a, b: int): int = if i >= a and i <= b: @@ -46,11 +46,11 @@ proc chckRangeF(x, a, b: float): float = when hostOS == "standalone": sysFatal(EOutOfRange, "value out of range") else: - sysFatal(EOutOfRange, "value out of range: ", $x) + sysFatal(RangeError, "value out of range: ", $x) proc chckNil(p: pointer) = if p == nil: - sysFatal(EInvalidValue, "attempt to write to a nil address") + sysFatal(ValueError, "attempt to write to a nil address") #c_raise(SIGSEGV) proc chckObj(obj, subclass: PNimType) {.compilerproc.} = @@ -59,13 +59,13 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} = if x == subclass: return # optimized fast path while x != subclass: if x == nil: - sysFatal(EInvalidObjectConversion, "invalid object conversion") + sysFatal(ObjectConversionError, "invalid object conversion") break x = x.base proc chckObjAsgn(a, b: PNimType) {.compilerproc, inline.} = if a != b: - sysFatal(EInvalidObjectAssignment, "invalid object assignment") + sysFatal(ObjectAssignmentError, "invalid object assignment") type ObjCheckCache = array[0..1, PNimType] diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index 243cc85e8..902999970 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -10,8 +10,8 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.gcsafe.} proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.gcsafe.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) case n.kind of nkSlot: genericDeepCopyAux(cast[pointer](d +% n.offset), @@ -40,8 +40,8 @@ proc copyDeepString(src: NimString): NimString {.inline.} = proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) sysAssert(mt != nil, "genericDeepCopyAux 2") case mt.kind of tyString: @@ -60,11 +60,11 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = return sysAssert(dest != nil, "genericDeepCopyAux 3") unsureAsgnRef(x, newSeq(mt, seq.len)) - var dst = cast[TAddress](cast[PPointer](dest)[]) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: genericDeepCopyAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% + cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), mt.base) of tyObject: @@ -82,8 +82,8 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base) of tyRef: - if mt.base.deepCopy != nil: - let z = mt.base.deepCopy(cast[PPointer](src)[]) + if mt.base.deepcopy != nil: + let z = mt.base.deepcopy(cast[PPointer](src)[]) unsureAsgnRef(cast[PPointer](dest), z) else: # we modify the header of the cell temporarily; instead of the type @@ -116,8 +116,8 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = genericDeepCopyAux(z, s2, realType.base) of tyPtr: # no cycle check here, but also not really required - if mt.base.deepCopy != nil: - cast[PPointer](dest)[] = mt.base.deepCopy(cast[PPointer](s)[]) + if mt.base.deepcopy != nil: + cast[PPointer](dest)[] = mt.base.deepcopy(cast[PPointer](s)[]) else: cast[PPointer](dest)[] = cast[PPointer](s)[] else: @@ -134,8 +134,8 @@ proc genericSeqDeepCopy(dest, src: pointer, mt: PNimType) {.compilerProc.} = proc genericDeepCopyOpenArray(dest, src: pointer, len: int, mt: PNimType) {.compilerproc.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) for i in 0..len-1: genericDeepCopy(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base) diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index eb57559fd..e0d99cf88 100644 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -17,7 +17,7 @@ const NilLibHandle: TLibHandle = nil -proc rawWrite(f: TFile, s: string) = +proc rawWrite(f: File, s: string) = # we cannot throw an exception here! discard writeBuffer(f, cstring(s), s.len) diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 04a23db9d..c7e6803d2 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -11,7 +11,7 @@ # use the heap (and nor exceptions) do not include the GC or memory allocator. var - errorMessageWriter*: (proc(msg: string) {.tags: [FWriteIO], gcsafe.}) + errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], gcsafe.}) ## Function that will be called ## instead of stdmsg.write when printing stacktrace. ## Unstable API. @@ -42,7 +42,7 @@ var excHandler {.threadvar.}: PSafePoint # list of exception handlers # a global variable for the root of all try blocks - currException {.threadvar.}: ref E_Base + currException {.threadvar.}: ref Exception proc popFrame {.compilerRtl, inl.} = framePtr = framePtr.prev @@ -58,7 +58,7 @@ proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} = proc popSafePoint {.compilerRtl, inl.} = excHandler = excHandler.prev -proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} = +proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} = e.parent = currException currException = e @@ -195,7 +195,7 @@ proc quitOrDebug() {.inline.} = else: endbStep() # call the debugger -proc raiseExceptionAux(e: ref E_Base) = +proc raiseExceptionAux(e: ref Exception) = if localRaiseHook != nil: if not localRaiseHook(e): return if globalRaiseHook != nil: @@ -204,7 +204,7 @@ proc raiseExceptionAux(e: ref E_Base) = if not excHandler.hasRaiseAction or excHandler.raiseAction(e): pushCurrentException(e) c_longjmp(excHandler.context, 1) - elif e[] of EOutOfMemory: + elif e[] of OutOfMemError: showErrorMessage(e.name) quitOrDebug() else: @@ -236,7 +236,7 @@ proc raiseExceptionAux(e: ref E_Base) = showErrorMessage(buf) quitOrDebug() -proc raiseException(e: ref E_Base, ename: cstring) {.compilerRtl.} = +proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = e.name = ename when hasSomeStackTrace: e.trace = "" @@ -245,7 +245,7 @@ proc raiseException(e: ref E_Base, ename: cstring) {.compilerRtl.} = proc reraiseException() {.compilerRtl.} = if currException == nil: - sysFatal(ENoExceptionToReraise, "no exception to reraise") + sysFatal(ReraiseError, "no exception to reraise") else: raiseExceptionAux(currException) @@ -264,7 +264,7 @@ proc getStackTrace(): string = else: result = "No stack traceback available\n" -proc getStackTrace(e: ref E_Base): string = +proc getStackTrace(e: ref Exception): string = if not isNil(e) and not isNil(e.trace): result = e.trace else: diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 053c7df69..cf8ebbe60 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -111,11 +111,11 @@ proc addZCT(s: var TCellSeq, c: PCell) {.noinline.} = proc cellToUsr(cell: PCell): pointer {.inline.} = # convert object (=pointer to refcount) to pointer to userdata - result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell))) + result = cast[pointer](cast[ByteAddress](cell)+%TAddress(sizeof(TCell))) proc usrToCell(usr: pointer): PCell {.inline.} = # convert pointer to userdata to object (=pointer to refcount) - result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell))) + result = cast[PCell](cast[ByteAddress](usr)-%TAddress(sizeof(TCell))) proc canbeCycleRoot(c: PCell): bool {.inline.} = result = ntfAcyclic notin c.typ.flags @@ -312,7 +312,7 @@ proc cellsetReset(s: var TCellSet) = init(s) proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case n.kind of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op) of nkList: @@ -332,7 +332,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = of nkNone: sysAssert(false, "forAllSlotsAux") proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) if dest == nil: return # nothing to do if ntfNoRefs notin mt.flags: case mt.kind @@ -358,7 +358,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) = of tyRef: # common case forAllChildrenAux(cellToUsr(cell), cell.typ.base, op) of tySequence: - var d = cast[TAddress](cellToUsr(cell)) + var d = cast[ByteAddress](cellToUsr(cell)) var s = cast[PGenericSeq](d) if s != nil: for i in 0..s.len-1: @@ -424,7 +424,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer = gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1") collectCT(gch) var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell))) - gcAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2") + gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2") # now it is buffered in the ZCT res.typ = typ when leakDetector and not hasThreadSupport: @@ -470,7 +470,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} = var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell))) sysAssert(allocInv(gch.region), "newObjRC1 after rawAlloc") - sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2") + sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2") # now it is buffered in the ZCT res.typ = typ when leakDetector and not hasThreadSupport: @@ -511,9 +511,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize copyMem(res, ol, oldsize + sizeof(TCell)) - zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)), + zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)), newsize-oldsize) - sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3") + sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3") sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4") #if res.refcount <% rcIncrement: # add(gch.zct, res) @@ -728,7 +728,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} = # the addresses are not as cells on the stack, so turn them to cells: sysAssert(allocInv(gch.region), "gcMark begin") var cell = usrToCell(p) - var c = cast[TAddress](cell) + var c = cast[ByteAddress](cell) if c >% PageSize: # fast check: does it look like a cell? var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell)) @@ -778,8 +778,8 @@ when not defined(useNimRtl): # the first init must be the one that defines the stack bottom: if gch.stackBottom == nil: gch.stackBottom = theStackBottom else: - var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2 - var b = cast[TAddress](gch.stackBottom) + var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2 + var b = cast[ByteAddress](gch.stackBottom) #c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom) when stackIncreases: gch.stackBottom = cast[pointer](min(a, b)) @@ -854,9 +854,9 @@ else: proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var b = cast[TAddress](gch.stackBottom) - var a = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var b = cast[ByteAddress](gch.stackBottom) + var a = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} = @@ -866,8 +866,8 @@ else: type PStackSlice = ptr array [0..7, pointer] var registers {.noinit.}: C_JmpBuf if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. - var max = cast[TAddress](gch.stackBottom) - var sp = cast[TAddress](addr(registers)) + var max = cast[ByteAddress](gch.stackBottom) + var sp = cast[ByteAddress](addr(registers)) # loop unrolled: while sp <% max - 8*sizeof(pointer): gcMark(gch, cast[PStackSlice](sp)[0]) @@ -1040,7 +1040,7 @@ when not defined(useNimRtl): else: dec(gch.recGcLock) - proc GC_setStrategy(strategy: TGC_Strategy) = + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = diff --git a/lib/system/repr.nim b/lib/system/repr.nim index 7408552f9..2de603cea 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -155,7 +155,7 @@ when not defined(useNimRtl): var bs = typ.base.size for i in 0..typ.size div bs - 1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), typ.base, cl) + reprAux(result, cast[pointer](cast[ByteAddress](p) + i*bs), typ.base, cl) add result, "]" proc reprSequence(result: var string, p: pointer, typ: PNimType, @@ -167,7 +167,7 @@ when not defined(useNimRtl): var bs = typ.base.size for i in 0..cast[PGenericSeq](p).len-1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[TAddress](p) + GenericSeqSize + i*bs), + reprAux(result, cast[pointer](cast[ByteAddress](p) + GenericSeqSize + i*bs), typ.base, cl) add result, "]" @@ -178,14 +178,14 @@ when not defined(useNimRtl): of nkSlot: add result, $n.name add result, " = " - reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl) + reprAux(result, cast[pointer](cast[ByteAddress](p) + n.offset), n.typ, cl) of nkList: for i in 0..n.len-1: if i > 0: add result, ",\n" reprRecordAux(result, p, n.sons[i], cl) of nkCase: var m = selectBranch(p, n) - reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl) + reprAux(result, cast[pointer](cast[ByteAddress](p) + n.offset), n.typ, cl) if m != nil: reprRecordAux(result, p, m, cl) proc reprRecord(result: var string, p: pointer, typ: PNimType, @@ -265,7 +265,7 @@ proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {. var bs = elemtyp.size for i in 0..length - 1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), elemtyp, cl) + reprAux(result, cast[pointer](cast[ByteAddress](p) + i*bs), elemtyp, cl) add result, "]" deinitReprClosure(cl) diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 32d4c3e91..56de5e6e8 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,7 +8,7 @@ # -# Nimrod's standard IO library. It contains high-performance +# Nim's standard IO library. It contains high-performance # routines for reading and writing data to (buffered) files or # TTYs. @@ -16,33 +16,33 @@ # of the standard library! -proc fputs(c: cstring, f: TFile) {.importc: "fputs", header: "", - tags: [FWriteIO].} -proc fgets(c: cstring, n: int, f: TFile): cstring {. - importc: "fgets", header: "", tags: [FReadIO].} -proc fgetc(stream: TFile): cint {.importc: "fgetc", header: "", - tags: [FReadIO].} -proc ungetc(c: cint, f: TFile) {.importc: "ungetc", header: "", +proc fputs(c: cstring, f: File) {.importc: "fputs", header: "", + tags: [WriteIOEffect].} +proc fgets(c: cstring, n: int, f: File): cstring {. + importc: "fgets", header: "", tags: [ReadIOEffect].} +proc fgetc(stream: File): cint {.importc: "fgetc", header: "", + tags: [ReadIOEffect].} +proc ungetc(c: cint, f: File) {.importc: "ungetc", header: "", tags: [].} -proc putc(c: char, stream: TFile) {.importc: "putc", header: "", - tags: [FWriteIO].} -proc fprintf(f: TFile, frmt: cstring) {.importc: "fprintf", - header: "", varargs, tags: [FWriteIO].} +proc putc(c: char, stream: File) {.importc: "putc", header: "", + tags: [WriteIOEffect].} +proc fprintf(f: File, frmt: cstring) {.importc: "fprintf", + header: "", varargs, tags: [WriteIOEffect].} proc strlen(c: cstring): int {. importc: "strlen", header: "", tags: [].} # C routine that is used here: -proc fread(buf: pointer, size, n: int, f: TFile): int {. - importc: "fread", header: "", tags: [FReadIO].} -proc fseek(f: TFile, offset: clong, whence: int): int {. +proc fread(buf: pointer, size, n: int, f: File): int {. + importc: "fread", header: "", tags: [ReadIOEffect].} +proc fseek(f: File, offset: clong, whence: int): int {. importc: "fseek", header: "", tags: [].} -proc ftell(f: TFile): int {.importc: "ftell", header: "", tags: [].} -proc setvbuf(stream: TFile, buf: pointer, typ, size: cint): cint {. +proc ftell(f: File): int {.importc: "ftell", header: "", tags: [].} +proc setvbuf(stream: File, buf: pointer, typ, size: cint): cint {. importc, header: "", tags: [].} {.push stackTrace:off, profiler:off.} -proc write(f: TFile, c: cstring) = fputs(c, f) +proc write(f: File, c: cstring) = fputs(c, f) {.pop.} when NoFakeVars: @@ -65,9 +65,9 @@ const BufSize = 4000 proc raiseEIO(msg: string) {.noinline, noreturn.} = - sysFatal(EIO, msg) + sysFatal(IOError, msg) -proc readLine(f: TFile, line: var TaintedString): bool = +proc readLine(f: File, line: var TaintedString): bool = # of course this could be optimized a bit; but IO is slow anyway... # and it was difficult to get this CORRECT with Ansi C's methods setLen(line.string, 0) # reuse the buffer! @@ -84,34 +84,34 @@ proc readLine(f: TFile, line: var TaintedString): bool = add line.string, chr(int(c)) result = true -proc readLine(f: TFile): TaintedString = +proc readLine(f: File): TaintedString = result = TaintedString(newStringOfCap(80)) if not readLine(f, result): raiseEIO("EOF reached") -proc write(f: TFile, i: int) = +proc write(f: File, i: int) = when sizeof(int) == 8: fprintf(f, "%lld", i) else: fprintf(f, "%ld", i) -proc write(f: TFile, i: BiggestInt) = +proc write(f: File, i: BiggestInt) = when sizeof(BiggestInt) == 8: fprintf(f, "%lld", i) else: fprintf(f, "%ld", i) -proc write(f: TFile, b: bool) = +proc write(f: File, b: bool) = if b: write(f, "true") else: write(f, "false") -proc write(f: TFile, r: float32) = fprintf(f, "%g", r) -proc write(f: TFile, r: BiggestFloat) = fprintf(f, "%g", r) +proc write(f: File, r: float32) = fprintf(f, "%g", r) +proc write(f: File, r: BiggestFloat) = fprintf(f, "%g", r) -proc write(f: TFile, c: char) = putc(c, f) -proc write(f: TFile, a: varargs[string, `$`]) = +proc write(f: File, c: char) = putc(c, f) +proc write(f: File, a: varargs[string, `$`]) = for x in items(a): write(f, x) -proc readAllBuffer(file: TFile): string = - # This proc is for TFile we want to read but don't know how many +proc readAllBuffer(file: File): string = + # This proc is for File we want to read but don't know how many # bytes we need to read before the buffer is empty. result = "" var buffer = newString(BufSize) @@ -124,27 +124,27 @@ proc readAllBuffer(file: TFile): string = result.add(buffer) break -proc rawFileSize(file: TFile): int = +proc rawFileSize(file: File): int = # this does not raise an error opposed to `getFileSize` var oldPos = ftell(file) discard fseek(file, 0, 2) # seek the end of the file result = ftell(file) discard fseek(file, clong(oldPos), 0) -proc readAllFile(file: TFile, len: int): string = +proc readAllFile(file: File, len: int): string = # We aquire the filesize beforehand and hope it doesn't change. # Speeds things up. result = newString(int(len)) if readBuffer(file, addr(result[0]), int(len)) != len: raiseEIO("error while reading from file") -proc readAllFile(file: TFile): string = +proc readAllFile(file: File): string = var len = rawFileSize(file) result = readAllFile(file, len) -proc readAll(file: TFile): TaintedString = +proc readAll(file: File): TaintedString = # Separate handling needed because we need to buffer when we - # don't know the overall length of the TFile. + # don't know the overall length of the File. var len = rawFileSize(file) if len >= 0: result = readAllFile(file, len).TaintedString @@ -165,13 +165,13 @@ proc writeFile(filename, content: string) = finally: close(f) -proc endOfFile(f: TFile): bool = +proc endOfFile(f: File): bool = # do not blame me; blame the ANSI C standard this is so brain-damaged var c = fgetc(f) ungetc(c, f) return c < 0'i32 -proc writeln[Ty](f: TFile, x: varargs[Ty, `$`]) = +proc writeln[Ty](f: File, x: varargs[Ty, `$`]) = for i in items(x): write(f, i) write(f, "\n") @@ -186,7 +186,7 @@ when (defined(windows) and not defined(useWinAnsi)) or defined(nimdoc): when defined(windows) and not defined(useWinAnsi): proc wfopen(filename, mode: WideCString): pointer {. importc: "_wfopen", nodecl.} - proc wfreopen(filename, mode: WideCString, stream: TFile): TFile {. + proc wfreopen(filename, mode: WideCString, stream: File): File {. importc: "_wfreopen", nodecl.} proc fopen(filename, mode: cstring): pointer = @@ -194,82 +194,82 @@ when defined(windows) and not defined(useWinAnsi): var m = newWideCString(mode) result = wfopen(f, m) - proc freopen(filename, mode: cstring, stream: TFile): TFile = + proc freopen(filename, mode: cstring, stream: File): File = var f = newWideCString(filename) var m = newWideCString(mode) result = wfreopen(f, m, stream) else: proc fopen(filename, mode: cstring): pointer {.importc: "fopen", noDecl.} - proc freopen(filename, mode: cstring, stream: TFile): TFile {. + proc freopen(filename, mode: cstring, stream: File): File {. importc: "freopen", nodecl.} const - FormatOpen: array [TFileMode, string] = ["rb", "wb", "w+b", "r+b", "ab"] + FormatOpen: array [FileMode, string] = ["rb", "wb", "w+b", "r+b", "ab"] #"rt", "wt", "w+t", "r+t", "at" - # we always use binary here as for Nimrod the OS line ending + # we always use binary here as for Nim the OS line ending # should not be translated. -proc open(f: var TFile, filename: string, - mode: TFileMode = fmRead, +proc open(f: var File, filename: string, + mode: FileMode = fmRead, bufSize: int = -1): bool = var p: pointer = fopen(filename, FormatOpen[mode]) result = (p != nil) - f = cast[TFile](p) + f = cast[File](p) if bufSize > 0 and bufSize <= high(cint).int: if setvbuf(f, nil, IOFBF, bufSize.cint) != 0'i32: - sysFatal(EOutOfMemory, "out of memory") + sysFatal(OutOfMemError, "out of memory") elif bufSize == 0: discard setvbuf(f, nil, IONBF, 0) -proc reopen(f: TFile, filename: string, mode: TFileMode = fmRead): bool = +proc reopen(f: File, filename: string, mode: FileMode = fmRead): bool = var p: pointer = freopen(filename, FormatOpen[mode], f) result = p != nil -proc fdopen(filehandle: TFileHandle, mode: cstring): TFile {. +proc fdopen(filehandle: FileHandle, mode: cstring): File {. importc: pccHack & "fdopen", header: "".} -proc open(f: var TFile, filehandle: TFileHandle, mode: TFileMode): bool = +proc open(f: var File, filehandle: FileHandle, mode: FileMode): bool = f = fdopen(filehandle, FormatOpen[mode]) result = f != nil -proc fwrite(buf: pointer, size, n: int, f: TFile): int {. +proc fwrite(buf: pointer, size, n: int, f: File): int {. importc: "fwrite", noDecl.} -proc readBuffer(f: TFile, buffer: pointer, len: int): int = +proc readBuffer(f: File, buffer: pointer, len: int): int = result = fread(buffer, 1, len, f) -proc readBytes(f: TFile, a: var openArray[int8], start, len: int): int = +proc readBytes(f: File, a: var openArray[int8], start, len: int): int = result = readBuffer(f, addr(a[start]), len) -proc readChars(f: TFile, a: var openArray[char], start, len: int): int = +proc readChars(f: File, a: var openArray[char], start, len: int): int = result = readBuffer(f, addr(a[start]), len) {.push stackTrace:off, profiler:off.} -proc writeBytes(f: TFile, a: openArray[int8], start, len: int): int = +proc writeBytes(f: File, a: openArray[int8], start, len: int): int = var x = cast[ptr array[0..1000_000_000, int8]](a) result = writeBuffer(f, addr(x[start]), len) -proc writeChars(f: TFile, a: openArray[char], start, len: int): int = +proc writeChars(f: File, a: openArray[char], start, len: int): int = var x = cast[ptr array[0..1000_000_000, int8]](a) result = writeBuffer(f, addr(x[start]), len) -proc writeBuffer(f: TFile, buffer: pointer, len: int): int = +proc writeBuffer(f: File, buffer: pointer, len: int): int = result = fwrite(buffer, 1, len, f) -proc write(f: TFile, s: string) = +proc write(f: File, s: string) = if writeBuffer(f, cstring(s), s.len) != s.len: raiseEIO("cannot write string to file") {.pop.} -proc setFilePos(f: TFile, pos: int64) = +proc setFilePos(f: File, pos: int64) = if fseek(f, clong(pos), 0) != 0: raiseEIO("cannot set file position") -proc getFilePos(f: TFile): int64 = +proc getFilePos(f: File): int64 = result = ftell(f) if result < 0: raiseEIO("cannot retrieve file position") -proc getFileSize(f: TFile): int64 = +proc getFileSize(f: File): int64 = var oldPos = getFilePos(f) discard fseek(f, 0, 2) # seek the end of the file result = getFilePos(f) diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 14b24cca6..ba973e9b5 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -217,7 +217,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. gch.tempStack.len = len0 else: for i in newLen..result.len-1: - forAllChildrenAux(cast[pointer](cast[TAddress](result) +% + forAllChildrenAux(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +% (i*%elemSize)), extGetCellType(result).base, waZctDecRef) @@ -227,7 +227,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. # presense of user defined destructors, the user will expect the cell to be # "destroyed" thus creating the same problem. We can destoy the cell in the # finalizer of the sequence, but this makes destruction non-deterministic. - zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +% + zeroMem(cast[pointer](cast[ByteAddress](result) +% GenericSeqSize +% (newLen*%elemSize)), (result.len-%newLen) *% elemSize) result.len = newLen From 2f43fdb8379acd783beee58b1b2c8225a486a70c Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 23 Aug 2014 01:43:49 +0200 Subject: [PATCH 009/409] renamefest --- compiler/ast.nim | 6 +- compiler/astalgo.nim | 62 ++++++------- compiler/ccgtypes.nim | 4 +- compiler/ccgutils.nim | 2 +- compiler/commands.nim | 2 +- compiler/crc.nim | 2 +- compiler/docgen.nim | 4 +- compiler/docgen2.nim | 2 +- compiler/extccomp.nim | 2 +- compiler/idents.nim | 2 +- compiler/idgen.nim | 2 +- compiler/lambdalifting.nim | 2 +- compiler/lexer.nim | 6 +- compiler/lists.nim | 2 +- compiler/llstream.nim | 12 +-- compiler/lowerings.nim | 12 +-- compiler/modules.nim | 2 +- compiler/msgs.nim | 6 +- compiler/nimlexbase.nim | 2 +- compiler/nimrod.nim | 2 +- compiler/options.nim | 2 +- compiler/parser.nim | 2 +- compiler/passes.nim | 2 +- compiler/pretty.nim | 2 +- compiler/prettybase.nim | 2 +- compiler/renderer.nim | 2 +- compiler/rodread.nim | 12 +-- compiler/rodwrite.nim | 2 +- compiler/ropes.nim | 10 +- compiler/semfold.nim | 4 +- compiler/semmacrosanity.nim | 2 +- compiler/semparallel.nim | 6 +- compiler/syntaxes.nim | 2 +- compiler/types.nim | 26 +++--- compiler/vmdeps.nim | 2 +- lib/core/macros.nim | 6 +- lib/packages/docutils/highlite.nim | 2 +- lib/packages/docutils/rst.nim | 6 +- lib/packages/docutils/rstgen.nim | 12 +-- lib/pure/algorithm.nim | 6 +- lib/pure/cgi.nim | 76 +++++++-------- lib/pure/collections/sets.nim | 2 +- lib/pure/collections/tables.nim | 6 +- lib/pure/cookies.nim | 4 +- lib/pure/json.nim | 6 +- lib/pure/lexbase.nim | 2 +- lib/pure/math.nim | 4 +- lib/pure/memfiles.nim | 4 +- lib/pure/os.nim | 48 +++++----- lib/pure/osproc.nim | 38 ++++---- lib/pure/parseopt.nim | 2 +- lib/pure/parseutils.nim | 6 +- lib/pure/sockets.nim | 142 ++++++++++++++--------------- lib/pure/streams.nim | 18 ++-- lib/pure/strtabs.nim | 6 +- lib/pure/strutils.nim | 20 ++-- lib/pure/times.nim | 28 +++--- lib/pure/xmltree.nim | 2 +- lib/system/alloc.nim | 4 +- lib/system/gc.nim | 4 +- lib/windows/winlean.nim | 16 ++-- todo.txt | 1 - 62 files changed, 342 insertions(+), 343 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 63cab5998..c5b367977 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -799,7 +799,7 @@ type loc*: TLoc TPair*{.final.} = object - key*, val*: PObject + key*, val*: RootRef TPairSeq* = seq[TPair] TTable*{.final.} = object # the same as table[PObject] of PObject @@ -808,7 +808,7 @@ type TIdPair*{.final.} = object key*: PIdObj - val*: PObject + val*: RootRef TIdPairSeq* = seq[TIdPair] TIdTable*{.final.} = object # the same as table[PIdent] of PObject @@ -835,7 +835,7 @@ type counter*: int data*: TNodePairSeq - TObjectSeq* = seq[PObject] + TObjectSeq* = seq[RootRef] TObjectSet*{.final.} = object counter*: int data*: TObjectSeq diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index eb7ffc63e..e95dbf7c8 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -14,7 +14,7 @@ import ast, hashes, intsets, strutils, options, msgs, ropes, idents, rodutils -proc hashNode*(p: PObject): THash +proc hashNode*(p: RootRef): THash proc treeToYaml*(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope # Convert a tree into its YAML representation; this is used by the # YAML code generator and it is invaluable for debugging purposes. @@ -24,21 +24,21 @@ proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope proc lineInfoToStr*(info: TLineInfo): PRope # ----------------------- node sets: --------------------------------------- -proc objectSetContains*(t: TObjectSet, obj: PObject): bool +proc objectSetContains*(t: TObjectSet, obj: RootRef): bool # returns true whether n is in t -proc objectSetIncl*(t: var TObjectSet, obj: PObject) +proc objectSetIncl*(t: var TObjectSet, obj: RootRef) # include an element n in the table t -proc objectSetContainsOrIncl*(t: var TObjectSet, obj: PObject): bool +proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool # more are not needed ... # ----------------------- (key, val)-Hashtables ---------------------------- -proc tablePut*(t: var TTable, key, val: PObject) -proc tableGet*(t: TTable, key: PObject): PObject +proc tablePut*(t: var TTable, key, val: RootRef) +proc tableGet*(t: TTable, key: RootRef): RootRef type - TCmpProc* = proc (key, closure: PObject): bool {.nimcall.} # true if found + TCmpProc* = proc (key, closure: RootRef): bool {.nimcall.} # true if found -proc tableSearch*(t: TTable, key, closure: PObject, - comparator: TCmpProc): PObject +proc tableSearch*(t: TTable, key, closure: RootRef, + comparator: TCmpProc): RootRef # return val as soon as comparator returns true; if this never happens, # nil is returned @@ -79,9 +79,9 @@ proc debug*(n: PType) {.deprecated.} proc debug*(n: PNode) {.deprecated.} # --------------------------- ident tables ---------------------------------- -proc idTableGet*(t: TIdTable, key: PIdObj): PObject -proc idTableGet*(t: TIdTable, key: int): PObject -proc idTablePut*(t: var TIdTable, key: PIdObj, val: PObject) +proc idTableGet*(t: TIdTable, key: PIdObj): RootRef +proc idTableGet*(t: TIdTable, key: int): RootRef +proc idTablePut*(t: var TIdTable, key: PIdObj, val: RootRef) proc idTableHasObjectAsKey*(t: TIdTable, key: PIdObj): bool # checks if `t` contains the `key` (compared by the pointer value, not only # `key`'s id) @@ -196,7 +196,7 @@ proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym = else: internalError(list.info, "getSymFromList") result = nil -proc hashNode(p: PObject): THash = +proc hashNode(p: RootRef): THash = result = hash(cast[pointer](p)) proc mustRehash(length, counter: int): bool = @@ -283,7 +283,7 @@ proc symToYamlAux(n: PSym, marker: var TIntSet, indent: int, result = toRope("null") elif containsOrIncl(marker, n.id): result = ropef("\"$1 @$2\"", [toRope(n.name.s), toRope( - strutils.toHex(cast[TAddress](n), sizeof(n) * 2))]) + strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))]) else: var ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1) result = ropeConstr(indent, [toRope("kind"), @@ -304,7 +304,7 @@ proc typeToYamlAux(n: PType, marker: var TIntSet, indent: int, result = toRope("null") elif containsOrIncl(marker, n.id): result = ropef("\"$1 @$2\"", [toRope($n.kind), toRope( - strutils.toHex(cast[TAddress](n), sizeof(n) * 2))]) + strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))]) else: if sonsLen(n) > 0: result = toRope("[") @@ -469,7 +469,7 @@ proc nextTry(h, maxHash: THash): THash = # generates each int in range(maxHash) exactly once (see any text on # random-number generation for proof). -proc objectSetContains(t: TObjectSet, obj: PObject): bool = +proc objectSetContains(t: TObjectSet, obj: RootRef): bool = # returns true whether n is in t var h: THash = hashNode(obj) and high(t.data) # start with real hash value while t.data[h] != nil: @@ -478,7 +478,7 @@ proc objectSetContains(t: TObjectSet, obj: PObject): bool = h = nextTry(h, high(t.data)) result = false -proc objectSetRawInsert(data: var TObjectSeq, obj: PObject) = +proc objectSetRawInsert(data: var TObjectSeq, obj: RootRef) = var h: THash = hashNode(obj) and high(data) while data[h] != nil: assert(data[h] != obj) @@ -493,12 +493,12 @@ proc objectSetEnlarge(t: var TObjectSet) = if t.data[i] != nil: objectSetRawInsert(n, t.data[i]) swap(t.data, n) -proc objectSetIncl(t: var TObjectSet, obj: PObject) = +proc objectSetIncl(t: var TObjectSet, obj: RootRef) = if mustRehash(len(t.data), t.counter): objectSetEnlarge(t) objectSetRawInsert(t.data, obj) inc(t.counter) -proc objectSetContainsOrIncl(t: var TObjectSet, obj: PObject): bool = +proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool = # returns true if obj is already in the string table: var h: THash = hashNode(obj) and high(t.data) while true: @@ -516,7 +516,7 @@ proc objectSetContainsOrIncl(t: var TObjectSet, obj: PObject): bool = inc(t.counter) result = false -proc tableRawGet(t: TTable, key: PObject): int = +proc tableRawGet(t: TTable, key: RootRef): int = var h: THash = hashNode(key) and high(t.data) # start with real hash value while t.data[h].key != nil: if t.data[h].key == key: @@ -524,8 +524,8 @@ proc tableRawGet(t: TTable, key: PObject): int = h = nextTry(h, high(t.data)) result = -1 -proc tableSearch(t: TTable, key, closure: PObject, - comparator: TCmpProc): PObject = +proc tableSearch(t: TTable, key, closure: RootRef, + comparator: TCmpProc): RootRef = var h: THash = hashNode(key) and high(t.data) # start with real hash value while t.data[h].key != nil: if t.data[h].key == key: @@ -535,12 +535,12 @@ proc tableSearch(t: TTable, key, closure: PObject, h = nextTry(h, high(t.data)) result = nil -proc tableGet(t: TTable, key: PObject): PObject = +proc tableGet(t: TTable, key: RootRef): RootRef = var index = tableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = nil -proc tableRawInsert(data: var TPairSeq, key, val: PObject) = +proc tableRawInsert(data: var TPairSeq, key, val: RootRef) = var h: THash = hashNode(key) and high(data) while data[h].key != nil: assert(data[h].key != key) @@ -556,7 +556,7 @@ proc tableEnlarge(t: var TTable) = if t.data[i].key != nil: tableRawInsert(n, t.data[i].key, t.data[i].val) swap(t.data, n) -proc tablePut(t: var TTable, key, val: PObject) = +proc tablePut(t: var TTable, key, val: RootRef) = var index = tableRawGet(t, key) if index >= 0: t.data[index].val = val @@ -740,22 +740,22 @@ proc idTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool = if index >= 0: result = t.data[index].key == key else: result = false -proc idTableGet(t: TIdTable, key: PIdObj): PObject = +proc idTableGet(t: TIdTable, key: PIdObj): RootRef = var index = idTableRawGet(t, key.id) if index >= 0: result = t.data[index].val else: result = nil -proc idTableGet(t: TIdTable, key: int): PObject = +proc idTableGet(t: TIdTable, key: int): RootRef = var index = idTableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = nil -iterator pairs*(t: TIdTable): tuple[key: int, value: PObject] = +iterator pairs*(t: TIdTable): tuple[key: int, value: RootRef] = for i in 0..high(t.data): if t.data[i].key != nil: yield (t.data[i].key.id, t.data[i].val) -proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) = +proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: RootRef) = var h: THash h = key.id and high(data) while data[h].key != nil: @@ -765,7 +765,7 @@ proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) = data[h].key = key data[h].val = val -proc idTablePut(t: var TIdTable, key: PIdObj, val: PObject) = +proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) = var index: int n: TIdPairSeq @@ -784,7 +784,7 @@ proc idTablePut(t: var TIdTable, key: PIdObj, val: PObject) = idTableRawInsert(t.data, key, val) inc(t.counter) -iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: PObject] = +iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: RootRef] = for i in 0 .. high(t.data): if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index fc6febc6f..0bd96e89f 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -428,10 +428,10 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope, var hasField = false var attribute: PRope = - if tfPacked in typ.flags: toRope(CC[ccompiler].packedPragma) + if tfPacked in typ.flags: toRope(CC[cCompiler].packedPragma) else: nil - result = ropecg(m, CC[ccompiler].structStmtFmt, + result = ropecg(m, CC[cCompiler].structStmtFmt, [structOrUnion(typ), name, attribute]) if typ.kind == tyObject: diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 65957584a..48fdacf46 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -149,7 +149,7 @@ proc getUniqueType*(key: PType): PType = idTablePut(gTypeTable[k], key, key) result = key -proc tableGetType*(tab: TIdTable, key: PType): PObject = +proc tableGetType*(tab: TIdTable, key: PType): RootRef = # returns nil if we need to declare this type result = idTableGet(tab, key) if (result == nil) and (tab.counter > 0): diff --git a/compiler/commands.nim b/compiler/commands.nim index c15cc674c..712e0e1c5 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -284,7 +284,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = if pass in {passCmd2, passPP} and not options.gNoBabelPath: expectArg(switch, arg, pass, info) let path = processPath(arg, notRelativeToProj=true) - babelpath(path, info) + babelPath(path, info) of "nobabelpath": expectNoArg(switch, arg, pass, info) options.gNoBabelPath = true diff --git a/compiler/crc.nim b/compiler/crc.nim index ae1df3ff1..22b1d1b69 100644 --- a/compiler/crc.nim +++ b/compiler/crc.nim @@ -102,7 +102,7 @@ proc crcFromFile(filename: string): TCrc32 = const bufSize = 8000 # don't use 8K for the memory allocator! var - bin: TFile + bin: File result = InitCrc32 if not open(bin, filename): return # not equal if file does not exist diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 4c9803401..7d9a11fbc 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -374,11 +374,11 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = cleanPlainSymbol = renderPlainSymbolName(nameNode) complexSymbol = complexName(k, n, cleanPlainSymbol) plainSymbolRope = toRope(cleanPlainSymbol) - plainSymbolEncRope = toRope(URLEncode(cleanPlainSymbol)) + plainSymbolEncRope = toRope(URLencode(cleanPlainSymbol)) itemIDRope = toRope(d.id) symbolOrId = d.newUniquePlainSymbol(complexSymbol) symbolOrIdRope = symbolOrId.toRope - symbolOrIdEncRope = URLEncode(symbolOrId).toRope + symbolOrIdEncRope = URLencode(symbolOrId).toRope var seeSrcRope: PRope = nil let docItemSeeSrc = getConfigVar("doc.item.seesrc") diff --git a/compiler/docgen2.nim b/compiler/docgen2.nim index d76be8e3c..1bff89b55 100644 --- a/compiler/docgen2.nim +++ b/compiler/docgen2.nim @@ -26,7 +26,7 @@ proc close(p: PPassContext, n: PNode): PNode = writeOutput(g.doc, g.module.filename, HtmlExt, useWarning) try: generateIndex(g.doc) - except EIO: + except IOError: discard proc processNode(c: PPassContext, n: PNode): PNode = diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index f0e5dad11..8dc399f43 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -551,7 +551,7 @@ proc footprint(filename: string): TCrc32 = proc externalFileChanged(filename: string): bool = var crcFile = toGeneratedFile(filename.withPackageName, "crc") var currentCrc = int(footprint(filename)) - var f: TFile + var f: File if open(f, crcFile, fmRead): var line = newStringOfCap(40) if not f.readLine(line): line = "0" diff --git a/compiler/idents.nim b/compiler/idents.nim index ec903826a..c37d94362 100644 --- a/compiler/idents.nim +++ b/compiler/idents.nim @@ -15,7 +15,7 @@ import hashes, strutils type - TIdObj* = object of TObject + TIdObj* = object of RootObj id*: int # unique id; use this for comparisons and not the pointers PIdObj* = ref TIdObj diff --git a/compiler/idgen.nim b/compiler/idgen.nim index d932e3d9d..7f137b885 100644 --- a/compiler/idgen.nim +++ b/compiler/idgen.nim @@ -53,7 +53,7 @@ proc saveMaxIds*(project: string) = f.close() proc loadMaxIds*(project: string) = - var f: TFile + var f: File if open(f, project.toGid, fmRead): var line = newStringOfCap(20) if f.readLine(line): diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 6c650eee3..c29d20a0a 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -128,7 +128,7 @@ type obj: PType PEnv = ref TEnv - TEnv {.final.} = object of TObject + TEnv {.final.} = object of RootObj attachedNode, replacementNode: PNode createdVar: PNode # if != nil it is a used environment; for closure # iterators this can be 'envParam.env' diff --git a/compiler/lexer.nim b/compiler/lexer.nim index ea51a1399..bcc02da9e 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -429,9 +429,9 @@ proc getNumber(L: var TLexer): TToken = elif result.tokType == tkInt16Lit and (result.iNumber < int16.low or result.iNumber > int16.high): lexMessage(L, errNumberOutOfRange, result.literal) - except EInvalidValue: + except ValueError: lexMessage(L, errInvalidNumber, result.literal) - except EOverflow, EOutOfRange: + except OverflowError, EOutOfRange: lexMessage(L, errNumberOutOfRange, result.literal) L.bufpos = endpos @@ -519,7 +519,7 @@ proc handleCRLF(L: var TLexer, pos: int): int = lexMessagePos(L, hintLineTooLong, pos) if optEmbedOrigSrc in gGlobalOptions: - let lineStart = cast[TAddress](L.buf) + L.lineStart + let lineStart = cast[ByteAddress](L.buf) + L.lineStart let line = newString(cast[cstring](lineStart), col) addSourceLine(L.fileIdx, line) diff --git a/compiler/lists.nim b/compiler/lists.nim index efffe60fe..2b3a9f3fc 100644 --- a/compiler/lists.nim +++ b/compiler/lists.nim @@ -12,7 +12,7 @@ import os type PListEntry* = ref TListEntry - TListEntry* = object of TObject + TListEntry* = object of RootObj prev*, next*: PListEntry TStrEntry* = object of TListEntry diff --git a/compiler/llstream.nim b/compiler/llstream.nim index 5aefd468a..8dc3dcea3 100644 --- a/compiler/llstream.nim +++ b/compiler/llstream.nim @@ -21,9 +21,9 @@ type llsString, # stream encapsulates a string llsFile, # stream encapsulates a file llsStdIn # stream encapsulates stdin - TLLStream* = object of TObject + TLLStream* = object of RootObj kind*: TLLStreamKind # accessible for low-level access (lexbase uses this) - f*: TFile + f*: File s*: string rd*, wr*: int # for string streams lineOffset*: int # for fake stdin line numbers @@ -31,8 +31,8 @@ type PLLStream* = ref TLLStream proc llStreamOpen*(data: string): PLLStream -proc llStreamOpen*(f: var TFile): PLLStream -proc llStreamOpen*(filename: string, mode: TFileMode): PLLStream +proc llStreamOpen*(f: var File): PLLStream +proc llStreamOpen*(filename: string, mode: FileMode): PLLStream proc llStreamOpen*(): PLLStream proc llStreamOpenStdIn*(): PLLStream proc llStreamClose*(s: PLLStream) @@ -50,12 +50,12 @@ proc llStreamOpen(data: string): PLLStream = result.s = data result.kind = llsString -proc llStreamOpen(f: var TFile): PLLStream = +proc llStreamOpen(f: var File): PLLStream = new(result) result.f = f result.kind = llsFile -proc llStreamOpen(filename: string, mode: TFileMode): PLLStream = +proc llStreamOpen(filename: string, mode: FileMode): PLLStream = new(result) result.kind = llsFile if not open(result.f, filename, mode): result = nil diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index ddfcb4f01..c4155724f 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -260,7 +260,7 @@ proc createWrapperProc(f: PNode; threadParam, argsParam: PSym; threadLocalBarrier = addLocalVar(varSection2, nil, argsParam.owner, barrier.typ, barrier) body.add varSection2 - body.add callCodeGenProc("barrierEnter", threadLocalBarrier.newSymNode) + body.add callCodegenProc("barrierEnter", threadLocalBarrier.newSymNode) var threadLocalProm: PSym if spawnKind == srByVar: threadLocalProm = addLocalVar(varSection, nil, argsParam.owner, fv.typ, fv) @@ -275,7 +275,7 @@ proc createWrapperProc(f: PNode; threadParam, argsParam: PSym; body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode, "owner", fv.info), threadParam.newSymNode) - body.add callCodeGenProc("nimArgsPassingDone", threadParam.newSymNode) + body.add callCodegenProc("nimArgsPassingDone", threadParam.newSymNode) if spawnKind == srByVar: body.add newAsgnStmt(genDeref(threadLocalProm.newSymNode), call) elif fv != nil: @@ -288,11 +288,11 @@ proc createWrapperProc(f: PNode; threadParam, argsParam: PSym; if barrier == nil: # by now 'fv' is shared and thus might have beeen overwritten! we need # to use the thread-local view instead: - body.add callCodeGenProc("nimFlowVarSignal", threadLocalProm.newSymNode) + body.add callCodegenProc("nimFlowVarSignal", threadLocalProm.newSymNode) else: body.add call if barrier != nil: - body.add callCodeGenProc("barrierLeave", threadLocalBarrier.newSymNode) + body.add callCodegenProc("barrierLeave", threadLocalBarrier.newSymNode) var params = newNodeI(nkFormalParams, f.info) params.add emptyNode @@ -542,7 +542,7 @@ proc wrapProcForSpawn*(owner: PSym; spawnExpr: PNode; retType: PType; # create flowVar: result.add newFastAsgnStmt(fvField, callProc(spawnExpr[2])) if barrier == nil: - result.add callCodeGenProc("nimFlowVarCreateCondVar", fvField) + result.add callCodegenProc("nimFlowVarCreateCondVar", fvField) elif spawnKind == srByVar: var field = newSym(skField, getIdent"fv", owner, n.info) @@ -555,7 +555,7 @@ proc wrapProcForSpawn*(owner: PSym; spawnExpr: PNode; retType: PType; let wrapper = createWrapperProc(fn, threadParam, argsParam, varSection, varInit, call, barrierAsExpr, fvAsExpr, spawnKind) - result.add callCodeGenProc("nimSpawn", wrapper.newSymNode, + result.add callCodegenProc("nimSpawn", wrapper.newSymNode, genAddrOf(scratchObj.newSymNode)) if spawnKind == srFlowVar: result.add fvField diff --git a/compiler/modules.nim b/compiler/modules.nim index b102224cd..65c438cc3 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -177,7 +177,7 @@ proc includeModule*(s: PSym, fileIdx: int32): PNode {.procvar.} = proc `==^`(a, b: string): bool = try: result = sameFile(a, b) - except EOS: + except OSError: result = false proc compileSystemModule* = diff --git a/compiler/msgs.nim b/compiler/msgs.nim index cd5b34194..00f80a438 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -468,8 +468,8 @@ type TErrorOutputs* = set[TErrorOutput] - ERecoverableError* = object of EInvalidValue - ESuggestDone* = object of E_Base + ERecoverableError* = object of ValueError + ESuggestDone* = object of Exception const InvalidFileIDX* = int32(-1) @@ -858,7 +858,7 @@ proc sourceLine*(i: TLineInfo): PRope = try: for line in lines(i.toFullPath): addSourceLine i.fileIndex, line.string - except EIO: + except IOError: discard internalAssert i.fileIndex < fileInfos.len # can happen if the error points to EOF: diff --git a/compiler/nimlexbase.nim b/compiler/nimlexbase.nim index 038573c35..cabcac390 100644 --- a/compiler/nimlexbase.nim +++ b/compiler/nimlexbase.nim @@ -37,7 +37,7 @@ const NewLines* = {CR, LF} type - TBaseLexer* = object of TObject + TBaseLexer* = object of RootObj bufpos*: int buf*: cstring bufLen*: int # length of buffer in characters diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 618d98698..69cb8bb99 100644 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -40,7 +40,7 @@ proc handleCmdLine() = if gProjectName != "": try: gProjectFull = canonicalizePath(gProjectName) - except EOS: + except OSError: gProjectFull = gProjectName var p = splitFile(gProjectFull) gProjectPath = p.dir diff --git a/compiler/options.nim b/compiler/options.nim index 02719cacc..8acf9e830 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -295,7 +295,7 @@ proc completeGeneratedFilePath*(f: string, createSubDir: bool = true): string = createDir(subdir) when noTimeMachine: excludeDirFromTimeMachine(subdir) - except EOS: + except OSError: writeln(stdout, "cannot create directory: " & subdir) quit(1) result = joinPath(subdir, tail) diff --git a/compiler/parser.nim b/compiler/parser.nim index 6ff0c2dfc..548084974 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -84,7 +84,7 @@ proc openParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream, proc openParser*(p: var TParser, filename: string, inputStream: PLLStream, strongSpaces=false) = - openParser(p, filename.fileInfoIdx, inputstream, strongSpaces) + openParser(p, filename.fileInfoIdx, inputStream, strongSpaces) proc closeParser(p: var TParser) = ## Close a parser, freeing up its resources. diff --git a/compiler/passes.nim b/compiler/passes.nim index 66a1a4954..1af9739bd 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -16,7 +16,7 @@ import nimsets, syntaxes, times, rodread, idgen type - TPassContext* = object of TObject # the pass's context + TPassContext* = object of RootObj # the pass's context fromCache*: bool # true if created by "openCached" PPassContext* = ref TPassContext diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 8d20d205b..5f990a658 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -38,7 +38,7 @@ proc overwriteFiles*() = f.write line f.write("\L") f.close - except EIO: + except IOError: rawMessage(errCannotOpenFile, newFile) proc `=~`(s: string, a: openArray[string]): bool = diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim index 581114441..baf2484e4 100644 --- a/compiler/prettybase.nim +++ b/compiler/prettybase.nim @@ -41,7 +41,7 @@ proc differ*(line: string, a, b: int, x: string): bool = let y = line[a..b] result = cmpIgnoreStyle(y, x) == 0 and y != x -proc replaceDeprecated*(info: TlineInfo; oldSym, newSym: PSym) = +proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = loadFile(info) let line = gSourceFiles[info.fileIndex].lines[info.line-1] diff --git a/compiler/renderer.nim b/compiler/renderer.nim index c97b2f321..e01916920 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1306,7 +1306,7 @@ proc renderTree(n: PNode, renderFlags: TRenderFlags = {}): string = proc renderModule(n: PNode, filename: string, renderFlags: TRenderFlags = {}) = var - f: TFile + f: File g: TSrcGen initSrcGen(g, renderFlags) for i in countup(0, sonsLen(n) - 1): diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 036e6cc3c..47020253f 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -121,7 +121,7 @@ type r*: string # writers use this offset*: int # readers use this - TRodReader* = object of TObject + TRodReader* = object of RootObj pos: int # position; used for parsing s: cstring # mmap'ed file contents options: TOptions @@ -503,7 +503,7 @@ proc processCompilerProcs(r: PRodReader, module: PSym) = idTablePut(r.syms, s, s) strTableAdd(rodCompilerprocs, s) -proc processIndex(r: PRodReader; idx: var TIndex; outf: TFile = nil) = +proc processIndex(r: PRodReader; idx: var TIndex; outf: File = nil) = var key, val, tmp: int inc(r.pos, 2) # skip "(\10" inc(r.line) @@ -659,7 +659,7 @@ proc newRodReader(modfilename: string, crc: TCrc32, new(result) try: result.memfile = memfiles.open(modfilename) - except EOS: + except OSError: return nil result.files = @[] result.modDeps = @[] @@ -916,7 +916,7 @@ initIdTable(gTypeTable) initStrTable(rodCompilerprocs) # viewer: -proc writeNode(f: TFile; n: PNode) = +proc writeNode(f: File; n: PNode) = f.write("(") if n != nil: f.write($n.kind) @@ -947,7 +947,7 @@ proc writeNode(f: TFile; n: PNode) = writeNode(f, n.sons[i]) f.write(")") -proc writeSym(f: TFile; s: PSym) = +proc writeSym(f: File; s: PSym) = if s == nil: f.write("{}\n") return @@ -985,7 +985,7 @@ proc writeSym(f: TFile; s: PSym) = f.writeNode(s.ast) f.write("}\n") -proc writeType(f: TFile; t: PType) = +proc writeType(f: File; t: PType) = if t == nil: f.write("[]\n") return diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 4231da2d0..4948c8fc2 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -422,7 +422,7 @@ proc addStmt(w: PRodWriter, n: PNode) = proc writeRod(w: PRodWriter) = processStacks(w, true) - var f: TFile + var f: File if not open(f, completeGeneratedFilePath(changeFileExt( w.filename.withPackageName, RodExt)), fmWrite): diff --git a/compiler/ropes.nim b/compiler/ropes.nim index fcf5dd202..6eb3673b4 100644 --- a/compiler/ropes.nim +++ b/compiler/ropes.nim @@ -64,7 +64,7 @@ type # copy the format strings # though it is not necessary) PRope* = ref TRope - TRope*{.acyclic.} = object of TObject # the empty rope is represented + TRope*{.acyclic.} = object of RootObj # the empty rope is represented # by nil to safe space left*, right*: PRope length*: int @@ -216,7 +216,7 @@ proc app(a: var PRope, b: PRope) = a = con(a, b) proc app(a: var PRope, b: string) = a = con(a, b) proc prepend(a: var PRope, b: PRope) = a = con(b, a) -proc writeRope*(f: TFile, c: PRope) = +proc writeRope*(f: File, c: PRope) = var stack = @[c] while len(stack) > 0: var it = pop(stack) @@ -228,7 +228,7 @@ proc writeRope*(f: TFile, c: PRope) = write(f, it.data) proc writeRope*(head: PRope, filename: string, useWarning = false) = - var f: TFile + var f: File if open(f, filename, fmWrite): if head != nil: writeRope(f, head) close(f) @@ -299,7 +299,7 @@ proc appf(c: var PRope, frmt: TFormatStr, args: varargs[PRope]) = const bufSize = 1024 # 1 KB is reasonable -proc auxRopeEqualsFile(r: PRope, bin: var TFile, buf: pointer): bool = +proc auxRopeEqualsFile(r: PRope, bin: var File, buf: pointer): bool = if r.data != nil: if r.length > bufSize: errorHandler(rTokenTooLong, r.data) @@ -312,7 +312,7 @@ proc auxRopeEqualsFile(r: PRope, bin: var TFile, buf: pointer): bool = if result: result = auxRopeEqualsFile(r.right, bin, buf) proc ropeEqualsFile(r: PRope, f: string): bool = - var bin: TFile + var bin: File result = open(bin, f) if not result: return # not equal if file does not exist diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 30e02dcc9..8e53fd670 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -683,9 +683,9 @@ proc getConstExpr(m: PSym, n: PNode): PNode = result = evalIs(n, a) else: result = magicCall(m, n) - except EOverflow: + except OverflowError: localError(n.info, errOverOrUnderflow) - except EDivByZero: + except DivByZeroError: localError(n.info, errConstantDivisionByZero) of nkAddr: var a = getConstExpr(m, n.sons[0]) diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim index 1bece95c2..8106aa179 100644 --- a/compiler/semmacrosanity.nim +++ b/compiler/semmacrosanity.nim @@ -55,7 +55,7 @@ proc annotateType*(n: PNode, t: PType) = else: globalError(n.info, "() must have an object or tuple type") of nkBracket: - if x.kind in {tyArrayConstr, tyArray, tySequence, tyOpenarray}: + if x.kind in {tyArrayConstr, tyArray, tySequence, tyOpenArray}: n.typ = t for m in n: annotateType(m, x.elemType) else: diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim index 7c489c3b6..5571d1bed 100644 --- a/compiler/semparallel.nim +++ b/compiler/semparallel.nim @@ -320,7 +320,7 @@ proc analyse(c: var AnalysisCtx; n: PNode) = # since we already ensure sfAddrTaken is not in s.flags, we only need to # prevent direct assignments to the monotonic variable: let slot = c.getSlot(n[0].sym) - slot.blackListed = true + slot.blacklisted = true invalidateFacts(c.guards, n[0]) analyseSons(c, n) addAsgnFact(c.guards, n[0], n[1]) @@ -464,6 +464,6 @@ proc liftParallel*(owner: PSym; n: PNode): PNode = result = newNodeI(nkStmtList, n.info) generateAliasChecks(a, result) result.add varSection - result.add callCodeGenProc("openBarrier", barrier) + result.add callCodegenProc("openBarrier", barrier) result.add transformSpawn(owner, body, barrier) - result.add callCodeGenProc("closeBarrier", barrier) + result.add callCodegenProc("closeBarrier", barrier) diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index d5062544f..8de6dcd91 100644 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -44,7 +44,7 @@ proc parseTopLevelStmt*(p: var TParsers): PNode proc parseFile(fileIdx: int32): PNode = var p: TParsers - f: TFile + f: File let filename = fileIdx.toFullPath if not open(f, filename): rawMessage(errCannotOpenFile, filename) diff --git a/compiler/types.nim b/compiler/types.nim index ec2271deb..ba796b6c3 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -24,13 +24,13 @@ proc getProcHeader*(sym: PSym): string proc base*(t: PType): PType # ------------------- type iterator: ---------------------------------------- type - TTypeIter* = proc (t: PType, closure: PObject): bool {.nimcall.} # true if iteration should stop - TTypeMutator* = proc (t: PType, closure: PObject): PType {.nimcall.} # copy t and mutate it + TTypeIter* = proc (t: PType, closure: RootRef): bool {.nimcall.} # true if iteration should stop + TTypeMutator* = proc (t: PType, closure: RootRef): PType {.nimcall.} # copy t and mutate it TTypePredicate* = proc (t: PType): bool {.nimcall.} -proc iterOverType*(t: PType, iter: TTypeIter, closure: PObject): bool +proc iterOverType*(t: PType, iter: TTypeIter, closure: RootRef): bool # Returns result of `iter`. -proc mutateType*(t: PType, iter: TTypeMutator, closure: PObject): PType +proc mutateType*(t: PType, iter: TTypeMutator, closure: RootRef): PType # Returns result of `iter`. type @@ -161,9 +161,9 @@ proc enumHasHoles(t: PType): bool = result = b.kind == tyEnum and tfEnumHasHoles in b.flags proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter, - closure: PObject): bool + closure: RootRef): bool proc iterOverNode(marker: var TIntSet, n: PNode, iter: TTypeIter, - closure: PObject): bool = + closure: RootRef): bool = if n != nil: case n.kind of nkNone..nkNilLit: @@ -175,7 +175,7 @@ proc iterOverNode(marker: var TIntSet, n: PNode, iter: TTypeIter, if result: return proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter, - closure: PObject): bool = + closure: RootRef): bool = result = false if t == nil: return result = iter(t, closure) @@ -190,7 +190,7 @@ proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter, if result: return if t.n != nil: result = iterOverNode(marker, t.n, iter, closure) -proc iterOverType(t: PType, iter: TTypeIter, closure: PObject): bool = +proc iterOverType(t: PType, iter: TTypeIter, closure: RootRef): bool = var marker = initIntSet() result = iterOverTypeAux(marker, t, iter, closure) @@ -354,9 +354,9 @@ proc canFormAcycle(typ: PType): bool = result = canFormAcycleAux(marker, typ, typ.id) proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator, - closure: PObject): PType + closure: RootRef): PType proc mutateNode(marker: var TIntSet, n: PNode, iter: TTypeMutator, - closure: PObject): PNode = + closure: RootRef): PNode = result = nil if n != nil: result = copyNode(n) @@ -370,7 +370,7 @@ proc mutateNode(marker: var TIntSet, n: PNode, iter: TTypeMutator, addSon(result, mutateNode(marker, n.sons[i], iter, closure)) proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator, - closure: PObject): PType = + closure: RootRef): PType = result = nil if t == nil: return result = iter(t, closure) @@ -380,7 +380,7 @@ proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator, if t.n != nil: result.n = mutateNode(marker, t.n, iter, closure) assert(result != nil) -proc mutateType(t: PType, iter: TTypeMutator, closure: PObject): PType = +proc mutateType(t: PType, iter: TTypeMutator, closure: RootRef): PType = var marker = initIntSet() result = mutateTypeAux(marker, t, iter, closure) @@ -1283,7 +1283,7 @@ proc getSize(typ: PType): BiggestInt = result = computeSize(typ) if result < 0: internalError("getSize: " & $typ.kind) -proc containsGenericTypeIter(t: PType, closure: PObject): bool = +proc containsGenericTypeIter(t: PType, closure: RootRef): bool = if t.kind == tyStatic: return t.n == nil diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 9a213d813..c0916fbd8 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -33,6 +33,6 @@ proc opSlurp*(file: string, info: TLineInfo, module: PSym): string = # the module dependencies are accurate: appendToModule(module, newNode(nkIncludeStmt, info, @[ newStrNode(nkStrLit, filename)])) - except EIO: + except IOError: localError(info, errCannotOpenFile, file) result = "" diff --git a/lib/core/macros.nim b/lib/core/macros.nim index e290cce32..0acd948fe 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -97,7 +97,7 @@ type TNimSymKinds* = set[TNimrodSymKind] type - TNimrodIdent* = object of TObject + TNimrodIdent* = object of RootObj ## represents a Nimrod identifier in the AST TNimrodSymbol {.final.} = object # hidden @@ -596,7 +596,7 @@ proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}= someProc[4] = val -template badnodekind(k; f): stmt{.immediate.} = +template badNodeKind(k; f): stmt{.immediate.} = assert false, "Invalid node kind $# for macros.`$2`".format(k, f) proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} = @@ -608,7 +608,7 @@ proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} = of nnkForStmt: return someProc.last else: - badNodeKind someproc.kind, "body" + badNodeKind someProc.kind, "body" proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} = case someProc.kind diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index 3d55fe1fc..c3e54e67d 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -23,7 +23,7 @@ type gtTagStart, gtTagEnd, gtKey, gtValue, gtRawData, gtAssembler, gtPreprocessor, gtDirective, gtCommand, gtRule, gtHyperlink, gtLabel, gtReference, gtOther - TGeneralTokenizer* = object of TObject + TGeneralTokenizer* = object of RootObj kind*: TTokenClass start*, length*: int buf: cstring diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 23459ade6..27d520493 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -118,7 +118,7 @@ type line*, col*: int # line and column of the token TTokenSeq = seq[TToken] - TLexer = object of TObject + TLexer = object of RootObj buf*: cstring bufpos*: int line*, col*, baseIndent*: int @@ -273,7 +273,7 @@ type findFile: TFindFileHandler # How to find files. PSharedState = ref TSharedState - TRstParser = object of TObject + TRstParser = object of RootObj idx*: int tok*: TTokenSeq s*: PSharedState @@ -282,7 +282,7 @@ type line*, col*: int hasToc*: bool - EParseError* = object of EInvalidValue + EParseError* = object of ValueError proc whichMsgClass*(k: TMsgKind): TMsgClass = ## returns which message class `k` belongs to. diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 5d69fcf51..e1bf1f649 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -42,7 +42,7 @@ type TMetaEnum* = enum metaNone, metaTitle, metaSubtitle, metaAuthor, metaVersion - TRstGenerator* = object of TObject + TRstGenerator* = object of RootObj target*: TOutputTarget config*: PStringTable splitAfter*: int # split too long entries in the TOC @@ -1011,7 +1011,7 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], inc(i) if i > L-1 or frmt[i] notin {'0'..'9'}: break if j > high(varvalues) + 1: - raise newException(EInvalidValue, "invalid index: " & $j) + raise newException(ValueError, "invalid index: " & $j) num = j add(result, varvalues[j - 1]) of 'A'..'Z', 'a'..'z', '\x80'..'\xFF': @@ -1024,13 +1024,13 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], if idx >= 0: add(result, varvalues[idx]) else: - raise newException(EInvalidValue, "unknown substitution var: " & id) + raise newException(ValueError, "unknown substitution var: " & id) of '{': var id = "" inc(i) while frmt[i] != '}': if frmt[i] == '\0': - raise newException(EInvalidValue, "'}' expected") + raise newException(ValueError, "'}' expected") add(id, frmt[i]) inc(i) inc(i) # skip } @@ -1038,9 +1038,9 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], var idx = getVarIdx(varnames, id) if idx >= 0: add(result, varvalues[idx]) else: - raise newException(EInvalidValue, "unknown substitution var: " & id) + raise newException(ValueError, "unknown substitution var: " & id) else: - raise newException(EInvalidValue, "unknown substitution: $" & $frmt[i]) + raise newException(ValueError, "unknown substitution: $" & $frmt[i]) var start = i while i < L: if frmt[i] != '$': inc(i) diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 89c83a8a4..df94c9eb5 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -69,7 +69,7 @@ proc smartBinarySearch*[T](a: openArray[T], key: T): int = const onlySafeCode = true -proc lowerBound*[T](a: openarray[T], key: T, cmp: proc(x,y: T): int {.closure.}): int = +proc lowerBound*[T](a: openArray[T], key: T, cmp: proc(x,y: T): int {.closure.}): int = ## same as binarySearch except that if key is not in `a` then this ## returns the location where `key` would be if it were. In other ## words if you have a sorted sequence and you call insert(thing, elm, lowerBound(thing, elm)) @@ -98,7 +98,7 @@ proc lowerBound*[T](a: openarray[T], key: T, cmp: proc(x,y: T): int {.closure.}) else: count = step -proc lowerBound*[T](a: openarray[T], key: T): int = lowerBound(a, key, cmp[T]) +proc lowerBound*[T](a: openArray[T], key: T): int = lowerBound(a, key, cmp[T]) proc merge[T](a, b: var openArray[T], lo, m, hi: int, cmp: proc (x, y: T): int {.closure.}, order: TSortOrder) = template `<-` (a, b: expr) = @@ -184,7 +184,7 @@ proc sort*[T](a: var openArray[T], dec(m, s*2) s = s*2 -proc product*[T](x: openarray[seq[T]]): seq[seq[T]] = +proc product*[T](x: openArray[seq[T]]): seq[seq[T]] = ## produces the Cartesian product of the array. Warning: complexity ## may explode. result = @[] diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index 31fb24eef..0d3231b93 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -93,7 +93,7 @@ proc XMLencode*(s: string): string = for i in 0..len(s)-1: addXmlChar(result, s[i]) type - ECgi* = object of EIO ## the exception that is raised, if a CGI error occurs + ECgi* = object of IOError ## the exception that is raised, if a CGI error occurs TRequestMethod* = enum ## the used request method methodNone, ## no REQUEST_METHOD environment variable methodPost, ## query uses the POST method @@ -107,18 +107,18 @@ proc cgiError*(msg: string) {.noreturn.} = raise e proc getEncodedData(allowedMethods: set[TRequestMethod]): string = - case getenv("REQUEST_METHOD").string + case getEnv("REQUEST_METHOD").string of "POST": if methodPost notin allowedMethods: cgiError("'REQUEST_METHOD' 'POST' is not supported") - var L = parseInt(getenv("CONTENT_LENGTH").string) + var L = parseInt(getEnv("CONTENT_LENGTH").string) result = newString(L) if readBuffer(stdin, addr(result[0]), L) != L: cgiError("cannot read from stdin") of "GET": if methodGet notin allowedMethods: cgiError("'REQUEST_METHOD' 'GET' is not supported") - result = getenv("QUERY_STRING").string + result = getEnv("QUERY_STRING").string else: if methodNone notin allowedMethods: cgiError("'REQUEST_METHOD' must be 'POST' or 'GET'") @@ -192,131 +192,131 @@ proc validateData*(data: PStringTable, validKeys: varargs[string]) = proc getContentLength*(): string = ## returns contents of the ``CONTENT_LENGTH`` environment variable - return getenv("CONTENT_LENGTH").string + return getEnv("CONTENT_LENGTH").string proc getContentType*(): string = ## returns contents of the ``CONTENT_TYPE`` environment variable - return getenv("CONTENT_Type").string + return getEnv("CONTENT_Type").string proc getDocumentRoot*(): string = ## returns contents of the ``DOCUMENT_ROOT`` environment variable - return getenv("DOCUMENT_ROOT").string + return getEnv("DOCUMENT_ROOT").string proc getGatewayInterface*(): string = ## returns contents of the ``GATEWAY_INTERFACE`` environment variable - return getenv("GATEWAY_INTERFACE").string + return getEnv("GATEWAY_INTERFACE").string proc getHttpAccept*(): string = ## returns contents of the ``HTTP_ACCEPT`` environment variable - return getenv("HTTP_ACCEPT").string + return getEnv("HTTP_ACCEPT").string proc getHttpAcceptCharset*(): string = ## returns contents of the ``HTTP_ACCEPT_CHARSET`` environment variable - return getenv("HTTP_ACCEPT_CHARSET").string + return getEnv("HTTP_ACCEPT_CHARSET").string proc getHttpAcceptEncoding*(): string = ## returns contents of the ``HTTP_ACCEPT_ENCODING`` environment variable - return getenv("HTTP_ACCEPT_ENCODING").string + return getEnv("HTTP_ACCEPT_ENCODING").string proc getHttpAcceptLanguage*(): string = ## returns contents of the ``HTTP_ACCEPT_LANGUAGE`` environment variable - return getenv("HTTP_ACCEPT_LANGUAGE").string + return getEnv("HTTP_ACCEPT_LANGUAGE").string proc getHttpConnection*(): string = ## returns contents of the ``HTTP_CONNECTION`` environment variable - return getenv("HTTP_CONNECTION").string + return getEnv("HTTP_CONNECTION").string proc getHttpCookie*(): string = ## returns contents of the ``HTTP_COOKIE`` environment variable - return getenv("HTTP_COOKIE").string + return getEnv("HTTP_COOKIE").string proc getHttpHost*(): string = ## returns contents of the ``HTTP_HOST`` environment variable - return getenv("HTTP_HOST").string + return getEnv("HTTP_HOST").string proc getHttpReferer*(): string = ## returns contents of the ``HTTP_REFERER`` environment variable - return getenv("HTTP_REFERER").string + return getEnv("HTTP_REFERER").string proc getHttpUserAgent*(): string = ## returns contents of the ``HTTP_USER_AGENT`` environment variable - return getenv("HTTP_USER_AGENT").string + return getEnv("HTTP_USER_AGENT").string proc getPathInfo*(): string = ## returns contents of the ``PATH_INFO`` environment variable - return getenv("PATH_INFO").string + return getEnv("PATH_INFO").string proc getPathTranslated*(): string = ## returns contents of the ``PATH_TRANSLATED`` environment variable - return getenv("PATH_TRANSLATED").string + return getEnv("PATH_TRANSLATED").string proc getQueryString*(): string = ## returns contents of the ``QUERY_STRING`` environment variable - return getenv("QUERY_STRING").string + return getEnv("QUERY_STRING").string proc getRemoteAddr*(): string = ## returns contents of the ``REMOTE_ADDR`` environment variable - return getenv("REMOTE_ADDR").string + return getEnv("REMOTE_ADDR").string proc getRemoteHost*(): string = ## returns contents of the ``REMOTE_HOST`` environment variable - return getenv("REMOTE_HOST").string + return getEnv("REMOTE_HOST").string proc getRemoteIdent*(): string = ## returns contents of the ``REMOTE_IDENT`` environment variable - return getenv("REMOTE_IDENT").string + return getEnv("REMOTE_IDENT").string proc getRemotePort*(): string = ## returns contents of the ``REMOTE_PORT`` environment variable - return getenv("REMOTE_PORT").string + return getEnv("REMOTE_PORT").string proc getRemoteUser*(): string = ## returns contents of the ``REMOTE_USER`` environment variable - return getenv("REMOTE_USER").string + return getEnv("REMOTE_USER").string proc getRequestMethod*(): string = ## returns contents of the ``REQUEST_METHOD`` environment variable - return getenv("REQUEST_METHOD").string + return getEnv("REQUEST_METHOD").string proc getRequestURI*(): string = ## returns contents of the ``REQUEST_URI`` environment variable - return getenv("REQUEST_URI").string + return getEnv("REQUEST_URI").string proc getScriptFilename*(): string = ## returns contents of the ``SCRIPT_FILENAME`` environment variable - return getenv("SCRIPT_FILENAME").string + return getEnv("SCRIPT_FILENAME").string proc getScriptName*(): string = ## returns contents of the ``SCRIPT_NAME`` environment variable - return getenv("SCRIPT_NAME").string + return getEnv("SCRIPT_NAME").string proc getServerAddr*(): string = ## returns contents of the ``SERVER_ADDR`` environment variable - return getenv("SERVER_ADDR").string + return getEnv("SERVER_ADDR").string proc getServerAdmin*(): string = ## returns contents of the ``SERVER_ADMIN`` environment variable - return getenv("SERVER_ADMIN").string + return getEnv("SERVER_ADMIN").string proc getServerName*(): string = ## returns contents of the ``SERVER_NAME`` environment variable - return getenv("SERVER_NAME").string + return getEnv("SERVER_NAME").string proc getServerPort*(): string = ## returns contents of the ``SERVER_PORT`` environment variable - return getenv("SERVER_PORT").string + return getEnv("SERVER_PORT").string proc getServerProtocol*(): string = ## returns contents of the ``SERVER_PROTOCOL`` environment variable - return getenv("SERVER_PROTOCOL").string + return getEnv("SERVER_PROTOCOL").string proc getServerSignature*(): string = ## returns contents of the ``SERVER_SIGNATURE`` environment variable - return getenv("SERVER_SIGNATURE").string + return getEnv("SERVER_SIGNATURE").string proc getServerSoftware*(): string = ## returns contents of the ``SERVER_SOFTWARE`` environment variable - return getenv("SERVER_SOFTWARE").string + return getEnv("SERVER_SOFTWARE").string proc setTestData*(keysvalues: varargs[string]) = ## fills the appropriate environment variables to test your CGI application. @@ -325,7 +325,7 @@ proc setTestData*(keysvalues: varargs[string]) = ## ## .. code-block:: Nimrod ## setTestData("name", "Hanz", "password", "12345") - putenv("REQUEST_METHOD", "GET") + putEnv("REQUEST_METHOD", "GET") var i = 0 var query = "" while i < keysvalues.len: @@ -334,7 +334,7 @@ proc setTestData*(keysvalues: varargs[string]) = add(query, URLencode(keysvalues[i+1])) add(query, '&') inc(i, 2) - putenv("QUERY_STRING", query) + putEnv("QUERY_STRING", query) proc writeContentType*() = ## call this before starting to send your HTML data to `stdout`. This diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 22eff9c55..3adf21a25 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -129,7 +129,7 @@ proc mget*[A](s: var TSet[A], key: A): var A = assert s.isValid, "The set needs to be initialized." var index = rawGet(s, key) if index >= 0: result = t.data[index].key - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) proc contains*[A](s: TSet[A], key: A): bool = ## Returns true iff `key` is in `s`. diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index dcf2ab481..95caf9195 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -144,7 +144,7 @@ proc mget*[A, B](t: var TTable[A, B], key: A): var B = ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) iterator allValues*[A, B](t: TTable[A, B]; key: A): B = ## iterates over any value in the table `t` that belongs to the given `key`. @@ -411,7 +411,7 @@ proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B = ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. @@ -663,7 +663,7 @@ proc mget*[A](t: var TCountTable[A], key: A): var int = ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) proc hasKey*[A](t: TCountTable[A], key: A): bool = ## returns true iff `key` is in the table `t`. diff --git a/lib/pure/cookies.nim b/lib/pure/cookies.nim index d1cf36a87..54ca164c7 100644 --- a/lib/pure/cookies.nim +++ b/lib/pure/cookies.nim @@ -47,7 +47,7 @@ proc setCookie*(key, value: string, expires: TTimeInfo, ## **Note:** UTC is assumed as the timezone for ``expires``. return setCookie(key, value, domain, path, - format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"), noname) + format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"), noName) when isMainModule: var tim = TTime(int(getTime()) + 76 * (60 * 60 * 24)) @@ -56,4 +56,4 @@ when isMainModule: echo parseCookies("uid=1; kp=2") - \ No newline at end of file + diff --git a/lib/pure/json.nim b/lib/pure/json.nim index a45900f29..383f924ca 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -529,7 +529,7 @@ type of JArray: elems*: seq[PJsonNode] - EJsonParsingError* = object of EInvalidValue ## is raised for a JSON error + EJsonParsingError* = object of ValueError ## is raised for a JSON error proc raiseParseErr*(p: TJsonParser, msg: string) {.noinline, noreturn.} = ## raises an `EJsonParsingError` exception. @@ -741,7 +741,7 @@ proc delete*(obj: PJsonNode, key: string) = if obj.fields[i].key == key: obj.fields.delete(i) return - raise newException(EInvalidIndex, "key not in object") + raise newException(IndexError, "key not in object") proc copy*(p: PJsonNode): PJsonNode = ## Performs a deep copy of `a`. @@ -942,7 +942,7 @@ when not defined(js): ## Parses `file` into a `PJsonNode`. var stream = newFileStream(filename, fmRead) if stream == nil: - raise newException(EIO, "cannot read from file: " & filename) + raise newException(IOError, "cannot read from file: " & filename) result = parseJson(stream, filename) else: from math import `mod` diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim index eee95e2e6..0e10b95e4 100644 --- a/lib/pure/lexbase.nim +++ b/lib/pure/lexbase.nim @@ -25,7 +25,7 @@ const # type - TBaseLexer* = object of TObject ## the base lexer. Inherit your lexer from + TBaseLexer* = object of RootObj ## the base lexer. Inherit your lexer from ## this object. bufpos*: int ## the current position within the buffer buf*: cstring ## the buffer itself diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 8af09114b..99849d98e 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -278,11 +278,11 @@ else: proc `mod`*(x, y: float): float = result = if y == 0.0: x else: x - y * (x/y).floor -proc random*[T](x: TSlice[T]): T = +proc random*[T](x: Slice[T]): T = ## For a slice `a .. b` returns a value in the range `a .. b-1`. result = random(x.b - x.a) + x.a -proc random[T](a: openarray[T]): T = +proc random[T](a: openArray[T]): T = ## returns a random element from the openarray `a`. result = a[random(a.low..a.len)] diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index ffeb0beff..5577fa5cf 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -35,7 +35,7 @@ type handle: cint -proc mapMem*(m: var TMemFile, mode: TFileMode = fmRead, +proc mapMem*(m: var TMemFile, mode: FileMode = fmRead, mappedSize = -1, offset = 0): pointer = var readonly = mode == fmRead when defined(windows): @@ -71,7 +71,7 @@ proc unmapMem*(f: var TMemFile, p: pointer, size: int) = if munmap(p, size) != 0: osError(osLastError()) -proc open*(filename: string, mode: TFileMode = fmRead, +proc open*(filename: string, mode: FileMode = fmRead, mappedSize = -1, offset = 0, newFileSize = -1): TMemFile = ## opens a memory mapped file. If this fails, ``EOS`` is raised. ## `newFileSize` can only be set if the file does not exist and is opened diff --git a/lib/pure/os.nim b/lib/pure/os.nim index cfff58eb0..d8a0f910a 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -29,14 +29,14 @@ else: include "system/ansi_c" type - FReadEnv* = object of FReadIO ## effect that denotes a read + FReadEnv* = object of ReadIOEffect ## effect that denotes a read ## from an environment variable - FWriteEnv* = object of FWriteIO ## effect that denotes a write + FWriteEnv* = object of WriteIOEffect ## effect that denotes a write ## to an environment variable - FReadDir* = object of FReadIO ## effect that denotes a write operation to + FReadDir* = object of ReadIOEffect ## effect that denotes a write operation to ## the directory structure - FWriteDir* = object of FWriteIO ## effect that denotes a write operation to + FWriteDir* = object of WriteIOEffect ## effect that denotes a write operation to ## the directory structure TOSErrorCode* = distinct int32 ## Specifies an OS Error Code. @@ -214,9 +214,9 @@ proc osError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = ## **Deprecated since version 0.9.4**: use the other ``OSError`` proc. if len(msg) == 0: var m = osErrorMsg() - raise newException(EOS, if m.len > 0: m else: "unknown OS error") + raise newException(OSError, if m.len > 0: m else: "unknown OS error") else: - raise newException(EOS, msg) + raise newException(OSError, msg) {.pop.} proc `==`*(err1, err2: TOSErrorCode): bool {.borrow.} @@ -260,7 +260,7 @@ proc osError*(errorCode: TOSErrorCode) = ## ## If the error code is ``0`` or an error message could not be retrieved, ## the message ``unknown OS error`` will be used. - var e: ref EOS; new(e) + var e: ref OSError; new(e) e.errorCode = errorCode.int32 e.msg = osErrorMsg(errorCode) if e.msg == "": @@ -840,13 +840,13 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1", result = a.st_dev == b.st_dev and a.st_ino == b.st_ino proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1", - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## Returns True if both pathname arguments refer to files with identical ## binary content. const bufSize = 8192 # 8K buffer var - a, b: TFile + a, b: File if not open(a, path1): return false if not open(b, path2): close(a) @@ -951,7 +951,7 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. if res2 == - 1'i32: osError(osLastError()) proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, FWriteIO].} = ## Copies a file from `source` to `dest`. ## ## If this fails, `EOS` is raised. On the Windows platform this proc will @@ -993,10 +993,10 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", close(d) proc moveFile*(source, dest: string) {.rtl, extern: "nos$1", - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, FWriteIO].} = ## Moves a file from `source` to `dest`. If this fails, `EOS` is raised. if c_rename(source, dest) != 0'i32: - raise newException(EOS, $strerror(errno)) + raise newException(OSError, $strerror(errno)) when not declared(ENOENT) and not defined(Windows): when NoFakeVars: @@ -1034,7 +1034,7 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = raise newException(EOS, $strerror(errno)) proc execShellCmd*(command: string): int {.rtl, extern: "nos$1", - tags: [FExecIO].} = + tags: [ExecIOEffect].} = ## Executes a `shell command`:idx:. ## ## Command has the form 'program args' where args are the command @@ -1076,7 +1076,7 @@ when defined(windows): while true: var eend = strEnd(e) add(environment, $e) - e = cast[WideCString](cast[TAddress](eend)+2) + e = cast[WideCString](cast[ByteAddress](eend)+2) if eend[1].int == 0: break discard freeEnvironmentStringsW(env) else: @@ -1364,7 +1364,7 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = rawCreateDir(dir) proc copyDir*(source, dest: string) {.rtl, extern: "nos$1", - tags: [FWriteIO, FReadIO].} = + tags: [WriteIOEffect, FReadIO].} = ## Copies a directory from `source` to `dest`. ## ## If this fails, `EOS` is raised. On the Windows platform this proc will @@ -1537,7 +1537,7 @@ proc copyFileWithPermissions*(source, dest: string, proc copyDirWithPermissions*(source, dest: string, ignorePermissionErrors = true) {.rtl, extern: "nos$1", - tags: [FWriteIO, FReadIO].} = + tags: [WriteIOEffect, FReadIO].} = ## Copies a directory from `source` to `dest` preserving file permissions. ## ## If this fails, `EOS` is raised. This is a wrapper proc around `copyDir() @@ -1657,13 +1657,13 @@ elif defined(windows): var ownArgv {.threadvar.}: seq[string] - proc paramCount*(): int {.rtl, extern: "nos$1", tags: [FReadIO].} = + proc paramCount*(): int {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = # Docstring in nimdoc block. if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine()) result = ownArgv.len-1 proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1", - tags: [FReadIO].} = + tags: [ReadIOEffect].} = # Docstring in nimdoc block. if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine()) return TaintedString(ownArgv[i]) @@ -1739,7 +1739,7 @@ when defined(macosx): proc getExecPath2(c: cstring, size: var cuint32): bool {. importc: "_NSGetExecutablePath", header: "".} -proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} = +proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = ## Returns the filename of the application's executable. ## ## This procedure will resolve symlinks. @@ -1795,12 +1795,12 @@ proc getApplicationDir*(): string {.rtl, extern: "nos$1", deprecated.} = ## instead. result = splitFile(getAppFilename()).dir -proc getAppDir*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} = +proc getAppDir*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = ## Returns the directory of the application's executable. ## **Note**: This does not work reliably on BSD. result = splitFile(getAppFilename()).dir -proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [FTime].} = +proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [TimeEffect].} = ## sleeps `milsecs` milliseconds. when defined(windows): winlean.sleep(int32(milsecs)) @@ -1811,7 +1811,7 @@ proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [FTime].} = discard posix.nanosleep(a, b) proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1", - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## returns the file size of `file`. Can raise ``EOS``. when defined(windows): var a: TWIN32_FIND_DATA @@ -1939,7 +1939,7 @@ template rawToFormalFileInfo(rawInfo, formalInfo): expr = if S_ISDIR(rawInfo.st_mode): formalInfo.kind = pcDir if S_ISLNK(rawInfo.st_mode): formalInfo.kind.inc() -proc getFileInfo*(handle: TFileHandle): FileInfo = +proc getFileInfo*(handle: FileHandle): FileInfo = ## Retrieves file information for the file object represented by the given ## handle. ## @@ -1960,7 +1960,7 @@ proc getFileInfo*(handle: TFileHandle): FileInfo = osError(osLastError()) rawToFormalFileInfo(rawInfo, result) -proc getFileInfo*(file: TFile): FileInfo = +proc getFileInfo*(file: File): FileInfo = result = getFileInfo(file.fileHandle()) proc getFileInfo*(path: string, followSymlink = true): FileInfo = diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 3c181bf53..37b36e7cc 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -24,10 +24,10 @@ when defined(linux): import linux type - TProcess = object of TObject + TProcess = object of RootObj when defined(windows): fProcessHandle: THandle - inHandle, outHandle, errHandle: TFileHandle + inHandle, outHandle, errHandle: FileHandle id: THandle else: inHandle, outHandle, errHandle: TFileHandle @@ -103,19 +103,19 @@ proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = {.error:"quoteShell is not supported on your system".} proc execProcess*(command: string, - args: openarray[string] = [], + args: openArray[string] = [], env: PStringTable = nil, options: set[TProcessOption] = {poStdErrToStdOut, poUsePath, poEvalCommand}): TaintedString {. rtl, extern: "nosp$1", - tags: [FExecIO, FReadIO].} + tags: [ExecIOEffect, FReadIO].} ## A convenience procedure that executes ``command`` with ``startProcess`` ## and returns its output as a string. ## WARNING: this function uses poEvalCommand by default for backward compatibility. ## Make sure to pass options explicitly. -proc execCmd*(command: string): int {.rtl, extern: "nosp$1", tags: [FExecIO].} +proc execCmd*(command: string): int {.rtl, extern: "nosp$1", tags: [ExecIOEffect].} ## Executes ``command`` and returns its error code. Standard input, output, ## error streams are inherited from the calling process. This operation ## is also often called `system`:idx:. @@ -125,7 +125,7 @@ proc startProcess*(command: string, args: openArray[string] = [], env: PStringTable = nil, options: set[TProcessOption] = {poStdErrToStdOut}): - PProcess {.rtl, extern: "nosp$1", tags: [FExecIO, FReadEnv].} + PProcess {.rtl, extern: "nosp$1", tags: [ExecIOEffect, FReadEnv].} ## Starts a process. `Command` is the executable file, `workingDir` is the ## process's working directory. If ``workingDir == ""`` the current directory ## is used. `args` are the command line arguments that are passed to the @@ -150,7 +150,7 @@ proc startProcess*(command: string, proc startCmd*(command: string, options: set[TProcessOption] = { poStdErrToStdOut, poUsePath}): PProcess {. - tags: [FExecIO, FReadEnv], deprecated.} = + tags: [ExecIOEffect, FReadEnv], deprecated.} = ## Deprecated - use `startProcess` directly. result = startProcess(command=command, options=options + {poEvalCommand}) @@ -201,7 +201,7 @@ proc errorStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. -proc inputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", +proc inputHandle*(p: PProcess): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s input file handle for writing to. ## @@ -209,7 +209,7 @@ proc inputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", ## it is closed when closing the PProcess ``p``. result = p.inHandle -proc outputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", +proc outputHandle*(p: PProcess): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s output file handle for reading from. ## @@ -217,7 +217,7 @@ proc outputHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", ## it is closed when closing the PProcess ``p``. result = p.outHandle -proc errorHandle*(p: PProcess): TFileHandle {.rtl, extern: "nosp$1", +proc errorHandle*(p: PProcess): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s error file handle for reading from. ## @@ -233,7 +233,7 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} = proc execProcesses*(cmds: openArray[string], options = {poStdErrToStdOut, poParentStreams}, n = countProcessors()): int {.rtl, extern: "nosp$1", - tags: [FExecIO, FTime, FReadEnv]} = + tags: [ExecIOEffect, FTime, FReadEnv]} = ## executes the commands `cmds` in parallel. Creates `n` processes ## that execute in parallel. The highest return value of all processes ## is returned. @@ -294,7 +294,7 @@ proc select*(readfds: var seq[PProcess], timeout = 500): int when not defined(useNimRtl): proc execProcess(command: string, - args: openarray[string] = [], + args: openArray[string] = [], env: PStringTable = nil, options: set[TProcessOption] = {poStdErrToStdOut, poUsePath, @@ -406,16 +406,16 @@ when defined(Windows) and not defined(useNimRtl): he = ho else: createPipeHandles(he, si.hStdError) - result.inHandle = TFileHandle(hi) - result.outHandle = TFileHandle(ho) - result.errHandle = TFileHandle(he) + result.inHandle = FileHandle(hi) + result.outHandle = FileHandle(ho) + result.errHandle = FileHandle(he) else: si.hStdError = getStdHandle(STD_ERROR_HANDLE) si.hStdInput = getStdHandle(STD_INPUT_HANDLE) si.hStdOutput = getStdHandle(STD_OUTPUT_HANDLE) - result.inHandle = TFileHandle(si.hStdInput) - result.outHandle = TFileHandle(si.hStdOutput) - result.errHandle = TFileHandle(si.hStdError) + result.inHandle = FileHandle(si.hStdInput) + result.outHandle = FileHandle(si.hStdOutput) + result.errHandle = FileHandle(si.hStdError) var cmdl: cstring if poEvalCommand in options: @@ -916,7 +916,7 @@ elif not defined(useNimRtl): proc execCmdEx*(command: string, options: set[TProcessOption] = { poStdErrToStdOut, poUsePath}): tuple[ output: TaintedString, - exitCode: int] {.tags: [FExecIO, FReadIO], gcsafe.} = + exitCode: int] {.tags: [ExecIOEffect, FReadIO], gcsafe.} = ## a convenience proc that runs the `command`, grabs all its output and ## exit code and returns both. var p = startCmd(command, options) diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index f43853fe6..d7379a9a9 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -28,7 +28,7 @@ type cmdLongoption, ## a long option ``--option`` detected cmdShortOption ## a short option ``-c`` detected TOptParser* = - object of TObject ## this object implements the command line parser + object of RootObj ## this object implements the command line parser cmd: string pos: int inShortState: bool diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index 06ee07aa8..0c045bc5a 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -227,7 +227,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {. result = parseBiggestInt(s, res, start) if (sizeof(int) <= 4) and ((res < low(int)) or (res > high(int))): - raise newException(EOverflow, "overflow") + raise newException(OverflowError, "overflow") else: number = int(res) @@ -376,7 +376,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, break dec nesting of '\0': - raise newException(EInvalidValue, + raise newException(ValueError, "Expected closing '}': " & s[i..s.len]) else: discard inc j @@ -392,7 +392,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, inc i # skip $ kind = ikDollar else: - raise newException(EInvalidValue, + raise newException(ValueError, "Unable to parse a varible name at " & s[i..s.len]) else: while j < s.len and s[j] != '$': inc j diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 7b8b3d557..68c5ec6ae 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -377,14 +377,14 @@ proc socketError*(socket: TSocket, err: int = -1, async = false) = else: osError(lastError) else: osError(lastError) -proc listen*(socket: TSocket, backlog = SOMAXCONN) {.tags: [FReadIO].} = +proc listen*(socket: TSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. if listen(socket.fd, cint(backlog)) < 0'i32: osError(osLastError()) proc invalidIp4(s: string) {.noreturn, noinline.} = - raise newException(EInvalidValue, "invalid ip4 address: " & s) + raise newException(ValueError, "invalid ip4 address: " & s) proc parseIp4*(s: string): BiggestInt = ## parses an IP version 4 in dotted decimal form like "a.b.c.d". @@ -422,10 +422,10 @@ template gaiNim(a, p, h, list: expr): stmt = when defined(windows): osError(osLastError()) else: - raise newException(EOS, $gai_strerror(gaiResult)) + raise newException(OSError, $gai_strerror(gaiResult)) proc bindAddr*(socket: TSocket, port = TPort(0), address = "") {. - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## binds an address/port number to a socket. ## Use address string in dotted decimal form like "a.b.c.d" ## or leave "" for any address. @@ -439,16 +439,16 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") {. name.sin_port = sockets.htons(int16(port)) name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)), - sizeof(name).TSocklen) < 0'i32: + sizeof(name).TSockLen) < 0'i32: osError(osLastError()) else: - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: TAddrInfo + var aiList: ptr TAddrInfo = nil hints.ai_family = toInt(AF_INET) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) gaiNim(address, port, hints, aiList) - if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSocklen) < 0'i32: + if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSockLen) < 0'i32: osError(osLastError()) proc getSockName*(socket: TSocket): TPort = @@ -460,7 +460,7 @@ proc getSockName*(socket: TSocket): TPort = name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).TSocklen + var namelen = sizeof(name).TSockLen if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)), addr(namelen)) == -1'i32: osError(osLastError()) @@ -470,7 +470,7 @@ template acceptAddrPlain(noClientRet, successRet: expr, sslImplementation: stmt): stmt {.immediate.} = assert(client != nil) var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen + var addrLen = sizeof(sockAddress).TSockLen var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) @@ -506,7 +506,7 @@ template acceptAddrPlain(noClientRet, successRet: expr, return successRet proc acceptAddr*(server: TSocket, client: var TSocket, address: var string) {. - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## Blocks until a connection is being made from a client. When a connection ## is made sets ``client`` to the client socket and ``address`` to the address ## of the connecting client. @@ -601,7 +601,7 @@ when defined(ssl): acceptAddrPlain(AcceptNoClient, AcceptSuccess): doHandshake() -proc accept*(server: TSocket, client: var TSocket) {.tags: [FReadIO].} = +proc accept*(server: TSocket, client: var TSocket) {.tags: [ReadIOEffect].} = ## Equivalent to ``acceptAddr`` but doesn't return the address, only the ## socket. ## @@ -612,7 +612,7 @@ proc accept*(server: TSocket, client: var TSocket) {.tags: [FReadIO].} = acceptAddr(server, client, addrDummy) proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] {. - deprecated, tags: [FReadIO].} = + deprecated, tags: [ReadIOEffect].} = ## Slightly different version of ``acceptAddr``. ## ## **Deprecated since version 0.9.0:** Please use the function above. @@ -622,7 +622,7 @@ proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] {. acceptAddr(server, client, address) return (client, address) -proc accept*(server: TSocket): TSocket {.deprecated, tags: [FReadIO].} = +proc accept*(server: TSocket): TSocket {.deprecated, tags: [ReadIOEffect].} = ## **Deprecated since version 0.9.0:** Please use the function above. new(result) var address = "" @@ -640,7 +640,7 @@ proc close*(socket: TSocket) = if socket.isSSL: discard SSLShutdown(socket.sslHandle) -proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} = +proc getServByName*(name, proto: string): TServent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the service name specified by ``name`` matches the s_name member ## and the protocol name specified by ``proto`` matches the s_proto member. @@ -650,13 +650,13 @@ proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} = var s = winlean.getservbyname(name, proto) else: var s = posix.getservbyname(name, proto) - if s == nil: raise newException(EOS, "Service not found.") + if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) result.port = TPort(s.s_port) result.proto = $s.s_proto -proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = +proc getServByPort*(port: TPort, proto: string): TServent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the port specified by ``port`` matches the s_port member and the ## protocol name specified by ``proto`` matches the s_proto member. @@ -666,13 +666,13 @@ proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = var s = winlean.getservbyport(ze(int16(port)).cint, proto) else: var s = posix.getservbyport(ze(int16(port)).cint, proto) - if s == nil: raise newException(EOS, "Service not found.") + if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) result.port = TPort(s.s_port) result.proto = $s.s_proto -proc getHostByAddr*(ip: string): Thostent {.tags: [FReadIO].} = +proc getHostByAddr*(ip: string): Thostent {.tags: [ReadIOEffect].} = ## This function will lookup the hostname of an IP Address. var myaddr: TInAddr myaddr.s_addr = inet_addr(ip) @@ -701,7 +701,7 @@ proc getHostByAddr*(ip: string): Thostent {.tags: [FReadIO].} = result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getHostByName*(name: string): Thostent {.tags: [FReadIO].} = +proc getHostByName*(name: string): Thostent {.tags: [ReadIOEffect].} = ## This function will lookup the IP address of a hostname. when defined(Windows): var s = winlean.gethostbyname(name) @@ -723,21 +723,21 @@ proc getHostByName*(name: string): Thostent {.tags: [FReadIO].} = result.length = int(s.h_length) proc getSockOptInt*(socket: TSocket, level, optname: int): int {. - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).TSocklen + var size = sizeof(res).TSockLen if getsockopt(socket.fd, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: osError(osLastError()) result = int(res) proc setSockOptInt*(socket: TSocket, level, optname, optval: int) {. - tags: [FWriteIO].} = + tags: [WriteIOEffect].} = ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket.fd, cint(level), cint(optname), addr(value), - sizeof(value).TSocklen) < 0'i32: + sizeof(value).TSockLen) < 0'i32: osError(osLastError()) proc toCInt(opt: TSOBool): cint = @@ -751,33 +751,33 @@ proc toCInt(opt: TSOBool): cint = of OptReuseAddr: SO_REUSEADDR proc getSockOpt*(socket: TSocket, opt: TSOBool, level = SOL_SOCKET): bool {. - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## Retrieves option ``opt`` as a boolean value. var res: cint - var size = sizeof(res).TSocklen + var size = sizeof(res).TSockLen if getsockopt(socket.fd, cint(level), toCInt(opt), addr(res), addr(size)) < 0'i32: osError(osLastError()) result = res != 0 proc setSockOpt*(socket: TSocket, opt: TSOBool, value: bool, level = SOL_SOCKET) {. - tags: [FWriteIO].} = + tags: [WriteIOEffect].} = ## Sets option ``opt`` to a boolean value specified by ``value``. var valuei = cint(if value: 1 else: 0) if setsockopt(socket.fd, cint(level), toCInt(opt), addr(valuei), - sizeof(valuei).TSocklen) < 0'i32: + sizeof(valuei).TSockLen) < 0'i32: osError(osLastError()) proc connect*(socket: TSocket, address: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [FReadIO].} = + af: TDomain = AF_INET) {.tags: [ReadIOEffect].} = ## Connects socket to ``address``:``port``. ``Address`` can be an IP address or a ## host name. If ``address`` is a host name, this function will try each IP ## of that host name. ``htons`` is already performed on ``port`` so you must ## not do it. ## ## If ``socket`` is an SSL socket a handshake will be automatically performed. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: TAddrInfo + var aiList: ptr TAddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -787,7 +787,7 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), var lastError: TOSErrorCode var it = aiList while it != nil: - if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) == 0'i32: + if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSockLen) == 0'i32: success = true break else: lastError = osLastError() @@ -830,7 +830,7 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), OSError() proc connectAsync*(socket: TSocket, name: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [FReadIO].} = + af: TDomain = AF_INET) {.tags: [ReadIOEffect].} = ## A variant of ``connect`` for non-blocking sockets. ## ## This procedure will immediatelly return, it will not block until a connection @@ -839,8 +839,8 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), ## ## **Note**: For SSL sockets, the ``handshake`` procedure must be called ## whenever the socket successfully connects to a server. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: TAddrInfo + var aiList: ptr TAddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -850,7 +850,7 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), var lastError: TOSErrorCode var it = aiList while it != nil: - var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) + var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSockLen) if ret == 0'i32: success = true break @@ -915,7 +915,7 @@ when defined(ssl): else: SSLError("Socket is not an SSL socket.") -proc timeValFromMilliseconds(timeout = 500): Ttimeval = +proc timeValFromMilliseconds(timeout = 500): TTimeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 @@ -962,7 +962,7 @@ proc checkBuffer(readfds: var seq[TSocket]): int = readfds = res proc select*(readfds, writefds, exceptfds: var seq[TSocket], - timeout = 500): int {.tags: [FReadIO].} = + timeout = 500): int {.tags: [ReadIOEffect].} = ## Traditional select function. This function will return the number of ## sockets that are ready to be read from, written to, or which have errors. ## If there are none; 0 is returned. @@ -975,7 +975,7 @@ proc select*(readfds, writefds, exceptfds: var seq[TSocket], if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) var rd, wr, ex: TFdSet var m = 0 @@ -993,12 +993,12 @@ proc select*(readfds, writefds, exceptfds: var seq[TSocket], pruneSocketSet(exceptfds, (ex)) proc select*(readfds, writefds: var seq[TSocket], - timeout = 500): int {.tags: [FReadIO].} = + timeout = 500): int {.tags: [ReadIOEffect].} = ## Variant of select with only a read and write list. let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) var rd, wr: TFdSet var m = 0 @@ -1014,7 +1014,7 @@ proc select*(readfds, writefds: var seq[TSocket], pruneSocketSet(writefds, (wr)) proc selectWrite*(writefds: var seq[TSocket], - timeout = 500): int {.tags: [FReadIO].} = + timeout = 500): int {.tags: [ReadIOEffect].} = ## When a socket in ``writefds`` is ready to be written to then a non-zero ## value will be returned specifying the count of the sockets which can be ## written to. The sockets which **cannot** be written to will also be removed @@ -1022,7 +1022,7 @@ proc selectWrite*(writefds: var seq[TSocket], ## ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for ## an unlimited time. - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) var wr: TFdSet var m = 0 @@ -1040,7 +1040,7 @@ proc select*(readfds: var seq[TSocket], timeout = 500): int = let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) var rd: TFdSet var m = 0 @@ -1077,7 +1077,7 @@ template retRead(flags, readBytes: int) {.dirty.} = else: return res -proc recv*(socket: TSocket, data: pointer, size: int): int {.tags: [FReadIO].} = +proc recv*(socket: TSocket, data: pointer, size: int): int {.tags: [ReadIOEffect].} = ## Receives data from a socket. ## ## **Note**: This is a low-level function, you may be interested in the higher @@ -1118,7 +1118,7 @@ proc recv*(socket: TSocket, data: pointer, size: int): int {.tags: [FReadIO].} = result = recv(socket.fd, data, size.cint, 0'i32) proc waitFor(socket: TSocket, waited: var float, timeout, size: int, - funcName: string): int {.tags: [FTime].} = + funcName: string): int {.tags: [TimeEffect].} = ## determines the amount of characters that can be read. Result will never ## be larger than ``size``. For unbuffered sockets this will be ``1``. ## For buffered sockets it can be as big as ``BufferSize``. @@ -1153,7 +1153,7 @@ proc waitFor(socket: TSocket, waited: var float, timeout, size: int, waited += (epochTime() - startTime) proc recv*(socket: TSocket, data: pointer, size: int, timeout: int): int {. - tags: [FReadIO, FTime].} = + tags: [ReadIOEffect, FTime].} = ## overload with a ``timeout`` parameter in miliseconds. var waited = 0.0 # number of seconds already waited @@ -1203,7 +1203,7 @@ proc recvAsync*(socket: TSocket, data: var string, size: int): int = result = -1 data.setLen(result) -proc peekChar(socket: TSocket, c: var char): int {.tags: [FReadIO].} = +proc peekChar(socket: TSocket, c: var char): int {.tags: [ReadIOEffect].} = if socket.isBuffered: result = 1 if socket.bufLen == 0 or socket.currPos > socket.bufLen-1: @@ -1224,7 +1224,7 @@ proc peekChar(socket: TSocket, c: var char): int {.tags: [FReadIO].} = result = recv(socket.fd, addr(c), 1, MSG_PEEK) proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. - tags: [FReadIO, FTime], deprecated.} = + tags: [ReadIOEffect, FTime], deprecated.} = ## Receive a line of data from ``socket``. ## ## If a full line is received ``\r\L`` is not @@ -1271,7 +1271,7 @@ proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. add(line.string, c) proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. - tags: [FReadIO, FTime].} = + tags: [ReadIOEffect, FTime].} = ## Reads a line of data from ``socket``. ## ## If a full line is read ``\r\L`` is not @@ -1312,7 +1312,7 @@ proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. add(line.string, c) proc recvLineAsync*(socket: TSocket, - line: var TaintedString): TRecvLineResult {.tags: [FReadIO], deprecated.} = + line: var TaintedString): TRecvLineResult {.tags: [ReadIOEffect], deprecated.} = ## Similar to ``recvLine`` but designed for non-blocking sockets. ## ## The values of the returned enum should be pretty self explanatory: @@ -1344,7 +1344,7 @@ proc recvLineAsync*(socket: TSocket, add(line.string, c) proc readLineAsync*(socket: TSocket, - line: var TaintedString): TReadLineResult {.tags: [FReadIO].} = + line: var TaintedString): TReadLineResult {.tags: [ReadIOEffect].} = ## Similar to ``recvLine`` but designed for non-blocking sockets. ## ## The values of the returned enum should be pretty self explanatory: @@ -1378,7 +1378,7 @@ proc readLineAsync*(socket: TSocket, elif c == '\L': return ReadFullLine add(line.string, c) -proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} = +proc recv*(socket: TSocket): TaintedString {.tags: [ReadIOEffect], deprecated.} = ## receives all the available data from the socket. ## Socket errors will result in an ``EOS`` error. ## If socket is not a connectionless socket and socket is not connected @@ -1411,7 +1411,7 @@ proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} = {.push warning[deprecated]: off.} proc recvTimeout*(socket: TSocket, timeout: int): TaintedString {. - tags: [FReadIO], deprecated.} = + tags: [ReadIOEffect], deprecated.} = ## overloaded variant to support a ``timeout`` parameter, the ``timeout`` ## parameter specifies the amount of miliseconds to wait for data on the ## socket. @@ -1426,7 +1426,7 @@ proc recvTimeout*(socket: TSocket, timeout: int): TaintedString {. {.pop.} proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. - tags: [FReadIO], deprecated.} = + tags: [ReadIOEffect], deprecated.} = ## receives all the data from a non-blocking socket. If socket is non-blocking ## and there are no messages available, `False` will be returned. ## Other socket errors will result in an ``EOS`` error. @@ -1478,7 +1478,7 @@ proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. proc recvFrom*(socket: TSocket, data: var string, length: int, address: var string, port: var TPort, flags = 0'i32): int {. - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## Receives data from ``socket``. This function should normally be used with ## connection-less sockets (UDP sockets). ## @@ -1493,7 +1493,7 @@ proc recvFrom*(socket: TSocket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen + var addrLen = sizeof(sockAddress).TSockLen result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) @@ -1504,7 +1504,7 @@ proc recvFrom*(socket: TSocket, data: var string, length: int, proc recvFromAsync*(socket: TSocket, data: var string, length: int, address: var string, port: var TPort, - flags = 0'i32): bool {.tags: [FReadIO].} = + flags = 0'i32): bool {.tags: [ReadIOEffect].} = ## Variant of ``recvFrom`` for non-blocking sockets. Unlike ``recvFrom``, ## this function will raise an EOS error whenever a socket error occurs. ## @@ -1522,7 +1522,7 @@ proc recvFromAsync*(socket: TSocket, data: var string, length: int, return false else: osError(err) -proc skip*(socket: TSocket) {.tags: [FReadIO], deprecated.} = +proc skip*(socket: TSocket) {.tags: [ReadIOEffect], deprecated.} = ## skips all the data that is pending for the socket ## ## **Deprecated since version 0.9.2**: This function is not safe for use. @@ -1547,7 +1547,7 @@ proc skip*(socket: TSocket, size: int, timeout = -1) = dealloc(dummy) proc send*(socket: TSocket, data: pointer, size: int): int {. - tags: [FWriteIO].} = + tags: [WriteIOEffect].} = ## sends data to a socket. when defined(ssl): if socket.isSSL: @@ -1560,10 +1560,10 @@ proc send*(socket: TSocket, data: pointer, size: int): int {. const MSG_NOSIGNAL = 0 result = send(socket.fd, data, size, int32(MSG_NOSIGNAL)) -proc send*(socket: TSocket, data: string) {.tags: [FWriteIO].} = +proc send*(socket: TSocket, data: string) {.tags: [WriteIOEffect].} = ## sends data to a socket. if socket.nonblocking: - raise newException(EInvalidValue, "This function cannot be used on non-blocking sockets.") + raise newException(ValueError, "This function cannot be used on non-blocking sockets.") let sent = send(socket, cstring(data), data.len) if sent < 0: when defined(ssl): @@ -1573,9 +1573,9 @@ proc send*(socket: TSocket, data: string) {.tags: [FWriteIO].} = osError(osLastError()) if sent != data.len: - raise newException(EOS, "Could not send all data.") + raise newException(OSError, "Could not send all data.") -proc sendAsync*(socket: TSocket, data: string): int {.tags: [FWriteIO].} = +proc sendAsync*(socket: TSocket, data: string): int {.tags: [WriteIOEffect].} = ## sends data to a non-blocking socket. ## Returns ``0`` if no data could be sent, if data has been sent ## returns the amount of bytes of ``data`` that was successfully sent. This @@ -1614,21 +1614,21 @@ proc sendAsync*(socket: TSocket, data: string): int {.tags: [FWriteIO].} = else: osError(err) -proc trySend*(socket: TSocket, data: string): bool {.tags: [FWriteIO].} = +proc trySend*(socket: TSocket, data: string): bool {.tags: [WriteIOEffect].} = ## safe alternative to ``send``. Does not raise an EOS when an error occurs, ## and instead returns ``false`` on failure. result = send(socket, cstring(data), data.len) == data.len proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, size: int, af: TDomain = AF_INET, flags = 0'i32): int {. - tags: [FWriteIO].} = + tags: [WriteIOEffect].} = ## low-level sendTo proc. This proc sends ``data`` to the specified ``address``, ## which may be an IP address or a hostname, if a hostname is specified ## this function will try each IP of that hostname. ## ## **Note:** This proc is not available for SSL sockets. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: TAddrInfo + var aiList: ptr TAddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -1639,7 +1639,7 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, var it = aiList while it != nil: result = sendto(socket.fd, data, size.cint, flags.cint, it.ai_addr, - it.ai_addrlen.TSocklen) + it.ai_addrlen.TSockLen) if result != -1'i32: success = true break @@ -1648,7 +1648,7 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, freeaddrinfo(aiList) proc sendTo*(socket: TSocket, address: string, port: TPort, - data: string): int {.tags: [FWriteIO].} = + data: string): int {.tags: [WriteIOEffect].} = ## Friendlier version of the low-level ``sendTo``. result = socket.sendTo(address, port, cstring(data), data.len) @@ -1685,7 +1685,7 @@ discard """ proc setReuseAddr*(s: TSocket) = OSError(OSLastError()) """ proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, - af: TDomain = AF_INET) {.tags: [FReadIO, FWriteIO].} = + af: TDomain = AF_INET) {.tags: [ReadIOEffect, FWriteIO].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## ## The ``timeout`` paremeter specifies the time in miliseconds to allow for diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 63622a26c..c4e969f21 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -14,13 +14,13 @@ include "system/inclrtl" -proc newEIO(msg: string): ref EIO = +proc newEIO(msg: string): ref IOError = new(result) result.msg = msg type PStream* = ref TStream - TStream* = object of TObject ## Stream interface that supports + TStream* = object of RootObj ## Stream interface that supports ## writing or reading. Note that these fields ## here shouldn't be used directly. They are ## accessible so that a stream implementation @@ -30,10 +30,10 @@ type setPositionImpl*: proc (s: PStream, pos: int) {.nimcall, tags: [], gcsafe.} getPositionImpl*: proc (s: PStream): int {.nimcall, tags: [], gcsafe.} readDataImpl*: proc (s: PStream, buffer: pointer, - bufLen: int): int {.nimcall, tags: [FReadIO], gcsafe.} + bufLen: int): int {.nimcall, tags: [ReadIOEffect], gcsafe.} writeDataImpl*: proc (s: PStream, buffer: pointer, bufLen: int) {.nimcall, - tags: [FWriteIO], gcsafe.} - flushImpl*: proc (s: PStream) {.nimcall, tags: [FWriteIO], gcsafe.} + tags: [WriteIOEffect], gcsafe.} + flushImpl*: proc (s: PStream) {.nimcall, tags: [WriteIOEffect], gcsafe.} proc flush*(s: PStream) = ## flushes the buffers that the stream `s` might use. @@ -246,7 +246,7 @@ when not defined(js): type PFileStream* = ref TFileStream ## a stream that encapsulates a `TFile` TFileStream* = object of TStream - f: TFile + f: File proc fsClose(s: PStream) = if PFileStream(s).f != nil: @@ -264,7 +264,7 @@ when not defined(js): if writeBuffer(PFileStream(s).f, buffer, bufLen) != bufLen: raise newEIO("cannot write to stream") - proc newFileStream*(f: TFile): PFileStream = + proc newFileStream*(f: File): PFileStream = ## creates a new stream from the file `f`. new(result) result.f = f @@ -276,11 +276,11 @@ when not defined(js): result.writeDataImpl = fsWriteData result.flushImpl = fsFlush - proc newFileStream*(filename: string, mode: TFileMode): PFileStream = + proc newFileStream*(filename: string, mode: FileMode): PFileStream = ## creates a new stream from the file named `filename` with the mode `mode`. ## If the file cannot be opened, nil is returned. See the `system ## `_ module for a list of available TFileMode enums. - var f: TFile + var f: File if open(f, filename, mode): result = newFileStream(f) diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 7003acfcf..12621a0fc 100644 --- a/lib/pure/strtabs.nim +++ b/lib/pure/strtabs.nim @@ -24,7 +24,7 @@ type modeStyleInsensitive ## the table is style insensitive TKeyValuePair = tuple[key, val: string] TKeyValuePairSeq = seq[TKeyValuePair] - TStringTable* = object of TObject + TStringTable* = object of RootObj counter: int data: TKeyValuePairSeq mode: TStringTableMode @@ -110,7 +110,7 @@ proc mget*(t: PStringTable, key: string): var string {. ## ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key does not exist: " & key) + else: raise newException(KeyError, "key does not exist: " & key) proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} = ## returns true iff `key` is in the table `t`. @@ -141,7 +141,7 @@ proc `[]=`*(t: PStringTable, key, val: string) {.rtl, extern: "nstPut".} = inc(t.counter) proc raiseFormatException(s: string) = - var e: ref EInvalidValue + var e: ref ValueError new(e) e.msg = "format string: key not found: " & s raise e diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 6f8924d83..cc62ad1ee 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -420,7 +420,7 @@ proc parseInt*(s: string): int {.noSideEffect, procvar, ## If `s` is not a valid integer, `EInvalidValue` is raised. var L = parseutils.parseInt(s, result, 0) if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid integer: " & s) + raise newException(ValueError, "invalid integer: " & s) proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar, rtl, extern: "nsuParseBiggestInt".} = @@ -429,7 +429,7 @@ proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar, ## If `s` is not a valid integer, `EInvalidValue` is raised. var L = parseutils.parseBiggestInt(s, result, 0) if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid integer: " & s) + raise newException(ValueError, "invalid integer: " & s) proc parseFloat*(s: string): float {.noSideEffect, procvar, rtl, extern: "nsuParseFloat".} = @@ -438,7 +438,7 @@ proc parseFloat*(s: string): float {.noSideEffect, procvar, ## ``INF``, ``-INF`` are also supported (case insensitive comparison). var L = parseutils.parseFloat(s, result, 0) if L != s.len or L == 0: - raise newException(EInvalidValue, "invalid float: " & s) + raise newException(ValueError, "invalid float: " & s) proc parseHexInt*(s: string): int {.noSideEffect, procvar, rtl, extern: "nsuParseHexInt".} = @@ -463,7 +463,7 @@ proc parseHexInt*(s: string): int {.noSideEffect, procvar, result = result shl 4 or (ord(s[i]) - ord('A') + 10) inc(i) of '\0': break - else: raise newException(EInvalidValue, "invalid integer: " & s) + else: raise newException(ValueError, "invalid integer: " & s) proc parseBool*(s: string): bool = ## Parses a value into a `bool`. @@ -475,7 +475,7 @@ proc parseBool*(s: string): bool = case normalize(s) of "y", "yes", "true", "1", "on": result = true of "n", "no", "false", "0", "off": result = false - else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s) + else: raise newException(ValueError, "cannot interpret as a bool: " & s) proc parseEnum*[T: enum](s: string): T = ## Parses an enum ``T``. @@ -485,7 +485,7 @@ proc parseEnum*[T: enum](s: string): T = for e in low(T)..high(T): if cmpIgnoreStyle(s, $e) == 0: return e - raise newException(EInvalidValue, "invalid enum value: " & s) + raise newException(ValueError, "invalid enum value: " & s) proc parseEnum*[T: enum](s: string, default: T): T = ## Parses an enum ``T``. @@ -911,7 +911,7 @@ proc parseOctInt*(s: string): int {.noSideEffect, result = result shl 3 or (ord(s[i]) - ord('0')) inc(i) of '\0': break - else: raise newException(EInvalidValue, "invalid integer: " & s) + else: raise newException(ValueError, "invalid integer: " & s) proc toOct*(x: BiggestInt, len: int): string {.noSideEffect, rtl, extern: "nsuToOct".} = @@ -1003,7 +1003,7 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, result = newStringOfCap(s.len) var i = 0 if s[0 .. prefix.len-1] != prefix: - raise newException(EInvalidValue, + raise newException(ValueError, "String does not start with a prefix of: " & prefix) i.inc() while true: @@ -1028,7 +1028,7 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, result.add(s[i]) i.inc() if s[i .. -1] != suffix: - raise newException(EInvalidValue, + raise newException(ValueError, "String does not end with a suffix of: " & suffix) proc validIdentifier*(s: string): bool {.noSideEffect, @@ -1219,7 +1219,7 @@ proc findNormalized(x: string, inArray: openArray[string]): int = return -1 proc invalidFormatString() {.noinline.} = - raise newException(EInvalidValue, "invalid format string") + raise newException(ValueError, "invalid format string") proc addf*(s: var string, formatstr: string, a: varargs[string, `$`]) {. noSideEffect, rtl, extern: "nsuAddf".} = diff --git a/lib/pure/times.nim b/lib/pure/times.nim index ebc3b9fdb..c156a4479 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -103,7 +103,7 @@ elif defined(JS): toLocaleString: proc (): cstring {.tags: [], raises: [], gcsafe.} type - TTimeInfo* = object of TObject ## represents a time in different parts + TTimeInfo* = object of RootObj ## represents a time in different parts second*: range[0..61] ## The number of seconds after the minute, ## normally in the range 0 to 59, but can ## be up to 61 to allow for leap seconds. @@ -136,14 +136,14 @@ type months*: int ## The number of months years*: int ## The number of years -proc getTime*(): TTime {.tags: [FTime], gcsafe.} +proc getTime*(): TTime {.tags: [TimeEffect], gcsafe.} ## gets the current calendar time as a UNIX epoch value (number of seconds ## elapsed since 1970) with integer precission. Use epochTime for higher ## resolution. -proc getLocalTime*(t: TTime): TTimeInfo {.tags: [FTime], raises: [], gcsafe.} +proc getLocalTime*(t: TTime): TTimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} ## converts the calendar time `t` to broken-time representation, ## expressed relative to the user's specified time zone. -proc getGMTime*(t: TTime): TTimeInfo {.tags: [FTime], raises: [], gcsafe.} +proc getGMTime*(t: TTime): TTimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} ## converts the calendar time `t` to broken-down time representation, ## expressed in Coordinated Universal Time (UTC). @@ -190,15 +190,15 @@ proc `==`*(a, b: TTime): bool {. result = a - b == 0 when not defined(JS): - proc getTzname*(): tuple[nonDST, DST: string] {.tags: [FTime], raises: [], + proc getTzname*(): tuple[nonDST, DST: string] {.tags: [TimeEffect], raises: [], gcsafe.} ## returns the local timezone; ``nonDST`` is the name of the local non-DST ## timezone, ``DST`` is the name of the local DST timezone. -proc getTimezone*(): int {.tags: [FTime], raises: [], gcsafe.} +proc getTimezone*(): int {.tags: [TimeEffect], raises: [], gcsafe.} ## returns the offset of the local (non-DST) timezone in seconds west of UTC. -proc getStartMilsecs*(): int {.deprecated, tags: [FTime], gcsafe.} +proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], gcsafe.} ## get the miliseconds from the start of the program. **Deprecated since ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead. @@ -282,12 +282,12 @@ proc `-`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = result = getLocalTime(fromSeconds(t - secs)) when not defined(JS): - proc epochTime*(): float {.rtl, extern: "nt$1", tags: [FTime].} + proc epochTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].} ## gets time after the UNIX epoch (1970) in seconds. It is a float ## because sub-second resolution is likely to be supported (depending ## on the hardware/OS). - proc cpuTime*(): float {.rtl, extern: "nt$1", tags: [FTime].} + proc cpuTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].} ## gets time spent that the CPU spent to run the current process in ## seconds. This may be more useful for benchmarking than ``epochTime``. ## However, it may measure the real time instead (depending on the OS). @@ -333,7 +333,7 @@ when not defined(JS): importc: "ctime", header: "", tags: [].} # strftime(s: CString, maxsize: int, fmt: CString, t: tm): int {. # importc: "strftime", header: "".} - proc clock(): TClock {.importc: "clock", header: "", tags: [FTime].} + proc clock(): TClock {.importc: "clock", header: "", tags: [TimeEffect].} proc difftime(a, b: TTime): float {.importc: "difftime", header: "", tags: [].} @@ -458,7 +458,7 @@ when not defined(JS): posix_gettimeofday(a) result = toFloat(a.tv_sec) + toFloat(a.tv_usec)*0.00_0001 elif defined(windows): - var f: winlean.TFiletime + var f: winlean.TFILETIME getSystemTimeAsFileTime(f) var i64 = rdFileTime(f) - epochDiff var secs = i64 div rateDiff @@ -534,13 +534,13 @@ elif defined(JS): proc getTimezone(): int = result = newDate().getTimezoneOffset() -proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [FTime].} = +proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} = ## gets the current date as a string of the format ``YYYY-MM-DD``. var ti = getLocalTime(getTime()) result = $ti.year & '-' & intToStr(ord(ti.month)+1, 2) & '-' & intToStr(ti.monthday, 2) -proc getClockStr*(): string {.rtl, extern: "nt$1", tags: [FTime].} = +proc getClockStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} = ## gets the current clock time as a string of the format ``HH:MM:SS``. var ti = getLocalTime(getTime()) result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) & @@ -669,7 +669,7 @@ proc format_token(info: TTimeInfo, token: string, buf: var string) = of "": discard else: - raise newException(EInvalidValue, "Invalid format string: " & token) + raise newException(ValueError, "Invalid format string: " & token) proc format*(info: TTimeInfo, f: string): string = diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 95b48a850..7392eb470 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -218,7 +218,7 @@ proc add*(result: var string, n: PXmlNode, indent = 0, indWidth = 2) = result.add("") - of xnCDATA: + of xnCData: result.add("") diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index f225b53ed..9f227f0c5 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -596,7 +596,7 @@ proc rawAlloc(a: var TMemRegion, requestedSize: int): pointer = result = addr(c.data) sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 13") if a.root == nil: a.root = bottom - add(a, a.root, cast[ByteAddress](result), cast[TAddress](result)+%size) + add(a, a.root, cast[ByteAddress](result), cast[ByteAddress](result)+%size) sysAssert(isAccessible(a, result), "rawAlloc 14") sysAssert(allocInv(a), "rawAlloc: end") when logAlloc: cprintf("rawAlloc: %ld %p\n", requestedSize, result) @@ -769,7 +769,7 @@ template instantiateForRegion(allocator: expr) = result = interiorAllocatedPtr(allocator, p) proc isAllocatedPtr*(p: pointer): bool = - let p = cast[pointer](cast[ByteAddress](p)-%TAddress(sizeof(TCell))) + let p = cast[pointer](cast[ByteAddress](p)-%ByteAddress(sizeof(TCell))) result = isAllocatedPtr(allocator, p) proc deallocOsPages = deallocOsPages(allocator) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index cf8ebbe60..c4b3a4928 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -111,11 +111,11 @@ proc addZCT(s: var TCellSeq, c: PCell) {.noinline.} = proc cellToUsr(cell: PCell): pointer {.inline.} = # convert object (=pointer to refcount) to pointer to userdata - result = cast[pointer](cast[ByteAddress](cell)+%TAddress(sizeof(TCell))) + result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell))) proc usrToCell(usr: pointer): PCell {.inline.} = # convert pointer to userdata to object (=pointer to refcount) - result = cast[PCell](cast[ByteAddress](usr)-%TAddress(sizeof(TCell))) + result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell))) proc canbeCycleRoot(c: PCell): bool {.inline.} = result = ntfAcyclic notin c.typ.flags diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 09696b67f..293551bc9 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -644,7 +644,7 @@ type InternalHigh*: PULONG Offset*: DWORD OffsetHigh*: DWORD - hEvent*: THANDLE + hEvent*: THandle POVERLAPPED* = ptr TOVERLAPPED @@ -666,14 +666,14 @@ const WSAETIMEDOUT* = 10060 ERROR_NETNAME_DELETED* = 64 -proc CreateIoCompletionPort*(FileHandle: THANDLE, ExistingCompletionPort: THANDLE, +proc CreateIoCompletionPort*(FileHandle: THandle, ExistingCompletionPort: THandle, CompletionKey: DWORD, - NumberOfConcurrentThreads: DWORD): THANDLE{.stdcall, + NumberOfConcurrentThreads: DWORD): THandle{.stdcall, dynlib: "kernel32", importc: "CreateIoCompletionPort".} proc GetQueuedCompletionStatus*(CompletionPort: THandle, lpNumberOfBytesTransferred: PDWORD, lpCompletionKey: PULONG, - lpOverlapped: ptr POverlapped, + lpOverlapped: ptr POVERLAPPED, dwMilliseconds: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "GetQueuedCompletionStatus".} @@ -699,7 +699,7 @@ var proc WSAIoctl*(s: TSocketHandle, dwIoControlCode: DWORD, lpvInBuffer: pointer, cbInBuffer: DWORD, lpvOutBuffer: pointer, cbOutBuffer: DWORD, - lpcbBytesReturned: PDword, lpOverlapped: POVERLAPPED, + lpcbBytesReturned: PDWORD, lpOverlapped: POVERLAPPED, lpCompletionRoutine: POVERLAPPED_COMPLETION_ROUTINE): cint {.stdcall, importc: "WSAIoctl", dynlib: "Ws2_32.dll".} @@ -709,16 +709,16 @@ type buf*: cstring proc WSARecv*(s: TSocketHandle, buf: ptr TWSABuf, bufCount: DWORD, - bytesReceived, flags: PDWORD, lpOverlapped: POverlapped, + bytesReceived, flags: PDWORD, lpOverlapped: POVERLAPPED, completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {. stdcall, importc: "WSARecv", dynlib: "Ws2_32.dll".} proc WSASend*(s: TSocketHandle, buf: ptr TWSABuf, bufCount: DWORD, - bytesSent: PDWord, flags: DWORD, lpOverlapped: POverlapped, + bytesSent: PDWORD, flags: DWORD, lpOverlapped: POVERLAPPED, completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {. stdcall, importc: "WSASend", dynlib: "Ws2_32.dll".} -proc get_osfhandle*(fd:TFileHandle): THandle {. +proc get_osfhandle*(fd:FileHandle): THandle {. importc: "_get_osfhandle", header:"".} proc getSystemTimes*(lpIdleTime, lpKernelTime, diff --git a/todo.txt b/todo.txt index 20fba45e9..68965584b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ version 0.9.6 ============= -- fix bug #1320 - fix tflowvar codegen test - split idetools into separate tool - split docgen into separate tool From 15a7bcc89f43b36da1973b53db3b9e466f9f49f6 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 23 Aug 2014 01:59:59 +0200 Subject: [PATCH 010/409] renamefest --- compiler/lexer.nim | 2 +- lib/pure/os.nim | 22 +++++++-------- lib/pure/osproc.nim | 22 +++++++-------- lib/pure/sockets.nim | 66 ++++++++++++++++++++++---------------------- lib/system.nim | 7 +++-- 5 files changed, 60 insertions(+), 59 deletions(-) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index bcc02da9e..abc491bfe 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -431,7 +431,7 @@ proc getNumber(L: var TLexer): TToken = lexMessage(L, errNumberOutOfRange, result.literal) except ValueError: lexMessage(L, errInvalidNumber, result.literal) - except OverflowError, EOutOfRange: + except OverflowError, RangeError: lexMessage(L, errNumberOutOfRange, result.literal) L.bufpos = endpos diff --git a/lib/pure/os.nim b/lib/pure/os.nim index d8a0f910a..483044d0a 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -951,7 +951,7 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. if res2 == - 1'i32: osError(osLastError()) proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", - tags: [ReadIOEffect, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = ## Copies a file from `source` to `dest`. ## ## If this fails, `EOS` is raised. On the Windows platform this proc will @@ -972,7 +972,7 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", else: # generic version of copyFile which works for any platform: const bufSize = 8000 # better for memory manager - var d, s: TFile + var d, s: File if not open(s, source): osError(osLastError()) if not open(d, dest, fmWrite): close(s) @@ -993,7 +993,7 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", close(d) proc moveFile*(source, dest: string) {.rtl, extern: "nos$1", - tags: [ReadIOEffect, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = ## Moves a file from `source` to `dest`. If this fails, `EOS` is raised. if c_rename(source, dest) != 0'i32: raise newException(OSError, $strerror(errno)) @@ -1031,7 +1031,7 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = osError(osLastError()) else: if c_remove(file) != 0'i32 and errno != ENOENT: - raise newException(EOS, $strerror(errno)) + raise newException(OSError, $strerror(errno)) proc execShellCmd*(command: string): int {.rtl, extern: "nos$1", tags: [ExecIOEffect].} = @@ -1364,7 +1364,7 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = rawCreateDir(dir) proc copyDir*(source, dest: string) {.rtl, extern: "nos$1", - tags: [WriteIOEffect, FReadIO].} = + tags: [WriteIOEffect, ReadIOEffect].} = ## Copies a directory from `source` to `dest`. ## ## If this fails, `EOS` is raised. On the Windows platform this proc will @@ -1537,7 +1537,7 @@ proc copyFileWithPermissions*(source, dest: string, proc copyDirWithPermissions*(source, dest: string, ignorePermissionErrors = true) {.rtl, extern: "nos$1", - tags: [WriteIOEffect, FReadIO].} = + tags: [WriteIOEffect, ReadIOEffect].} = ## Copies a directory from `source` to `dest` preserving file permissions. ## ## If this fails, `EOS` is raised. This is a wrapper proc around `copyDir() @@ -1674,12 +1674,12 @@ elif not defined(createNimRtl): cmdCount {.importc: "cmdCount".}: cint cmdLine {.importc: "cmdLine".}: cstringArray - proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} = + proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} = # Docstring in nimdoc block. if i < cmdCount and i >= 0: return TaintedString($cmdLine[i]) - raise newException(EInvalidIndex, "invalid index") + raise newException(IndexError, "invalid index") - proc paramCount*(): int {.tags: [FReadIO].} = + proc paramCount*(): int {.tags: [ReadIOEffect].} = # Docstring in nimdoc block. result = cmdCount-1 @@ -1820,7 +1820,7 @@ proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1", result = rdFileSize(a) findClose(resA) else: - var f: TFile + var f: File if open(f, file): result = getFileSize(f) close(f) @@ -1867,7 +1867,7 @@ when defined(Windows): else: type DeviceId* = TDev - FileId* = TIno + FileId* = Tino type FileInfo* = object diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 37b36e7cc..d5ca2f5a5 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -30,7 +30,7 @@ type inHandle, outHandle, errHandle: FileHandle id: THandle else: - inHandle, outHandle, errHandle: TFileHandle + inHandle, outHandle, errHandle: FileHandle inStream, outStream, errStream: PStream id: TPid exitCode: cint @@ -109,7 +109,7 @@ proc execProcess*(command: string, poUsePath, poEvalCommand}): TaintedString {. rtl, extern: "nosp$1", - tags: [ExecIOEffect, FReadIO].} + tags: [ExecIOEffect, ReadIOEffect].} ## A convenience procedure that executes ``command`` with ``startProcess`` ## and returns its output as a string. ## WARNING: this function uses poEvalCommand by default for backward compatibility. @@ -233,7 +233,7 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} = proc execProcesses*(cmds: openArray[string], options = {poStdErrToStdOut, poParentStreams}, n = countProcessors()): int {.rtl, extern: "nosp$1", - tags: [ExecIOEffect, FTime, FReadEnv]} = + tags: [ExecIOEffect, TimeEffect, FReadEnv]} = ## executes the commands `cmds` in parallel. Creates `n` processes ## that execute in parallel. The highest return value of all processes ## is returned. @@ -584,12 +584,12 @@ elif not defined(useNimRtl): when not defined(useFork): proc startProcessAuxSpawn(data: TStartProcessData): TPid {. - tags: [FExecIO, FReadEnv], gcsafe.} + tags: [ExecIOEffect, FReadEnv], gcsafe.} proc startProcessAuxFork(data: TStartProcessData): TPid {. - tags: [FExecIO, FReadEnv], gcsafe.} + tags: [ExecIOEffect, FReadEnv], gcsafe.} {.push stacktrace: off, profiler: off.} proc startProcessAfterFork(data: ptr TStartProcessData) {. - tags: [FExecIO, FReadEnv], cdecl, gcsafe.} + tags: [ExecIOEffect, FReadEnv], cdecl, gcsafe.} {.pop.} proc startProcess(command: string, @@ -850,9 +850,9 @@ elif not defined(useNimRtl): if p.exitCode == -3: result = -1 else: result = p.exitCode.int shr 8 - proc createStream(stream: var PStream, handle: var TFileHandle, - fileMode: TFileMode) = - var f: TFile + proc createStream(stream: var PStream, handle: var FileHandle, + fileMode: FileMode) = + var f: File if not open(f, handle, fileMode): osError(osLastError()) stream = newFileStream(f) @@ -897,7 +897,7 @@ elif not defined(useNimRtl): setLen(s, L) proc select(readfds: var seq[PProcess], timeout = 500): int = - var tv: TTimeVal + var tv: Ttimeval tv.tv_sec = 0 tv.tv_usec = timeout * 1000 @@ -916,7 +916,7 @@ elif not defined(useNimRtl): proc execCmdEx*(command: string, options: set[TProcessOption] = { poStdErrToStdOut, poUsePath}): tuple[ output: TaintedString, - exitCode: int] {.tags: [ExecIOEffect, FReadIO], gcsafe.} = + exitCode: int] {.tags: [ExecIOEffect, ReadIOEffect], gcsafe.} = ## a convenience proc that runs the `command`, grabs all its output and ## exit code and returns both. var p = startCmd(command, options) diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 68c5ec6ae..b0cc67c70 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -131,7 +131,7 @@ type TReadLineResult* = enum ## result for readLineAsync ReadFullLine, ReadPartialLine, ReadDisconnected, ReadNone - ETimeout* = object of ESynch + ETimeout* = object of Exception let invalidSocket*: TSocket = nil ## invalid socket @@ -439,16 +439,16 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") {. name.sin_port = sockets.htons(int16(port)) name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)), - sizeof(name).TSockLen) < 0'i32: + sizeof(name).TSocklen) < 0'i32: osError(osLastError()) else: - var hints: TAddrInfo - var aiList: ptr TAddrInfo = nil + var hints: Taddrinfo + var aiList: ptr Taddrinfo = nil hints.ai_family = toInt(AF_INET) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) gaiNim(address, port, hints, aiList) - if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSockLen) < 0'i32: + if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSocklen) < 0'i32: osError(osLastError()) proc getSockName*(socket: TSocket): TPort = @@ -460,7 +460,7 @@ proc getSockName*(socket: TSocket): TPort = name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).TSockLen + var namelen = sizeof(name).TSocklen if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)), addr(namelen)) == -1'i32: osError(osLastError()) @@ -470,7 +470,7 @@ template acceptAddrPlain(noClientRet, successRet: expr, sslImplementation: stmt): stmt {.immediate.} = assert(client != nil) var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSockLen + var addrLen = sizeof(sockAddress).TSocklen var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) @@ -685,7 +685,7 @@ proc getHostByAddr*(ip: string): Thostent {.tags: [ReadIOEffect].} = var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).TSocklen, cint(posix.AF_INET)) if s == nil: - raise newException(EOS, $hstrerror(h_errno)) + raise newException(OSError, $hstrerror(h_errno)) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) @@ -697,7 +697,7 @@ proc getHostByAddr*(ip: string): Thostent {.tags: [ReadIOEffect].} = elif s.h_addrtype == posix.AF_INET6: result.addrtype = AF_INET6 else: - raise newException(EOS, "unknown h_addrtype") + raise newException(OSError, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) @@ -718,7 +718,7 @@ proc getHostByName*(name: string): Thostent {.tags: [ReadIOEffect].} = elif s.h_addrtype == posix.AF_INET6: result.addrtype = AF_INET6 else: - raise newException(EOS, "unknown h_addrtype") + raise newException(OSError, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) @@ -726,7 +726,7 @@ proc getSockOptInt*(socket: TSocket, level, optname: int): int {. tags: [ReadIOEffect].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).TSockLen + var size = sizeof(res).TSocklen if getsockopt(socket.fd, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: osError(osLastError()) @@ -737,7 +737,7 @@ proc setSockOptInt*(socket: TSocket, level, optname, optval: int) {. ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket.fd, cint(level), cint(optname), addr(value), - sizeof(value).TSockLen) < 0'i32: + sizeof(value).TSocklen) < 0'i32: osError(osLastError()) proc toCInt(opt: TSOBool): cint = @@ -754,7 +754,7 @@ proc getSockOpt*(socket: TSocket, opt: TSOBool, level = SOL_SOCKET): bool {. tags: [ReadIOEffect].} = ## Retrieves option ``opt`` as a boolean value. var res: cint - var size = sizeof(res).TSockLen + var size = sizeof(res).TSocklen if getsockopt(socket.fd, cint(level), toCInt(opt), addr(res), addr(size)) < 0'i32: osError(osLastError()) @@ -765,7 +765,7 @@ proc setSockOpt*(socket: TSocket, opt: TSOBool, value: bool, level = SOL_SOCKET) ## Sets option ``opt`` to a boolean value specified by ``value``. var valuei = cint(if value: 1 else: 0) if setsockopt(socket.fd, cint(level), toCInt(opt), addr(valuei), - sizeof(valuei).TSockLen) < 0'i32: + sizeof(valuei).TSocklen) < 0'i32: osError(osLastError()) proc connect*(socket: TSocket, address: string, port = TPort(0), @@ -776,8 +776,8 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), ## not do it. ## ## If ``socket`` is an SSL socket a handshake will be automatically performed. - var hints: TAddrInfo - var aiList: ptr TAddrInfo = nil + var hints: Taddrinfo + var aiList: ptr Taddrinfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -787,7 +787,7 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), var lastError: TOSErrorCode var it = aiList while it != nil: - if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSockLen) == 0'i32: + if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) == 0'i32: success = true break else: lastError = osLastError() @@ -839,8 +839,8 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), ## ## **Note**: For SSL sockets, the ``handshake`` procedure must be called ## whenever the socket successfully connects to a server. - var hints: TAddrInfo - var aiList: ptr TAddrInfo = nil + var hints: Taddrinfo + var aiList: ptr Taddrinfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -850,7 +850,7 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), var lastError: TOSErrorCode var it = aiList while it != nil: - var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSockLen) + var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) if ret == 0'i32: success = true break @@ -915,7 +915,7 @@ when defined(ssl): else: SSLError("Socket is not an SSL socket.") -proc timeValFromMilliseconds(timeout = 500): TTimeval = +proc timeValFromMilliseconds(timeout = 500): Ttimeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 @@ -975,7 +975,7 @@ proc select*(readfds, writefds, exceptfds: var seq[TSocket], if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) var rd, wr, ex: TFdSet var m = 0 @@ -998,7 +998,7 @@ proc select*(readfds, writefds: var seq[TSocket], let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) var rd, wr: TFdSet var m = 0 @@ -1022,7 +1022,7 @@ proc selectWrite*(writefds: var seq[TSocket], ## ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for ## an unlimited time. - var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) var wr: TFdSet var m = 0 @@ -1040,7 +1040,7 @@ proc select*(readfds: var seq[TSocket], timeout = 500): int = let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) var rd: TFdSet var m = 0 @@ -1153,7 +1153,7 @@ proc waitFor(socket: TSocket, waited: var float, timeout, size: int, waited += (epochTime() - startTime) proc recv*(socket: TSocket, data: pointer, size: int, timeout: int): int {. - tags: [ReadIOEffect, FTime].} = + tags: [ReadIOEffect, TimeEffect].} = ## overload with a ``timeout`` parameter in miliseconds. var waited = 0.0 # number of seconds already waited @@ -1224,7 +1224,7 @@ proc peekChar(socket: TSocket, c: var char): int {.tags: [ReadIOEffect].} = result = recv(socket.fd, addr(c), 1, MSG_PEEK) proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. - tags: [ReadIOEffect, FTime], deprecated.} = + tags: [ReadIOEffect, TimeEffect], deprecated.} = ## Receive a line of data from ``socket``. ## ## If a full line is received ``\r\L`` is not @@ -1271,7 +1271,7 @@ proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. add(line.string, c) proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. - tags: [ReadIOEffect, FTime].} = + tags: [ReadIOEffect, TimeEffect].} = ## Reads a line of data from ``socket``. ## ## If a full line is read ``\r\L`` is not @@ -1493,7 +1493,7 @@ proc recvFrom*(socket: TSocket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSockLen + var addrLen = sizeof(sockAddress).TSocklen result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) @@ -1627,8 +1627,8 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, ## this function will try each IP of that hostname. ## ## **Note:** This proc is not available for SSL sockets. - var hints: TAddrInfo - var aiList: ptr TAddrInfo = nil + var hints: Taddrinfo + var aiList: ptr Taddrinfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -1639,7 +1639,7 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, var it = aiList while it != nil: result = sendto(socket.fd, data, size.cint, flags.cint, it.ai_addr, - it.ai_addrlen.TSockLen) + it.ai_addrlen.TSocklen) if result != -1'i32: success = true break @@ -1685,7 +1685,7 @@ discard """ proc setReuseAddr*(s: TSocket) = OSError(OSLastError()) """ proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, - af: TDomain = AF_INET) {.tags: [ReadIOEffect, FWriteIO].} = + af: TDomain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## ## The ``timeout`` paremeter specifies the time in miliseconds to allow for diff --git a/lib/system.nim b/lib/system.nim index 73b470052..ad1cbd423 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -384,11 +384,11 @@ type ## ## This happens for calculations whose results are too large to fit in the ## provided bits. See the full `exception hierarchy`_. - AccessViolationError* {.compilerproc.} = object of Exception ## \ + AccessViolationError* = object of Exception ## \ ## Raised for invalid memory access errors ## ## See the full `exception hierarchy`_. - AssertionError* {.compilerproc.} = object of Exception ## \ + AssertionError* = object of Exception ## \ ## Raised when assertion is proved wrong. ## ## Usually the result of using the `assert() template <#assert>`_. See the @@ -496,7 +496,8 @@ type EFloatingPoint: FloatingPointError, EFloatInvalidOp: FloatInvalidOpError, EFloatDivByZero: FloatDivByZeroError, - EFloatOverflow: FloatOverflowError + EFloatOverflow: FloatOverflowError, + ESynch: Exception ].} proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.} From 11b69587554a99deb93ca2447ee3aeeacdb647c5 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 27 Aug 2014 23:42:51 +0200 Subject: [PATCH 011/409] big rename --- compiler/ast.nim | 2 +- compiler/semtypinst.nim | 2 +- config/nimrod.cfg | 6 +- doc/manual.txt | 465 +++++++++++++------------- doc/pegdocs.txt | 4 +- doc/tut1.txt | 258 +++++++------- doc/tut2.txt | 139 ++++---- examples/htmlrefs.nim | 2 +- examples/htmltitle.nim | 2 +- lib/pure/actors.nim | 7 +- lib/pure/algorithm.nim | 7 +- lib/pure/asyncdispatch.nim | 92 ++--- lib/pure/asynchttpserver.nim | 13 +- lib/pure/asyncio.nim | 75 +++-- lib/pure/asyncnet.nim | 14 +- lib/pure/base64.nim | 2 +- lib/pure/basic2d.nim | 2 +- lib/pure/basic3d.nim | 2 +- lib/pure/browsers.nim | 4 +- lib/pure/cgi.nim | 12 +- lib/pure/collections/LockFreeHash.nim | 73 ++-- lib/pure/collections/baseutils.nim | 41 --- lib/pure/collections/critbits.nim | 82 ++--- lib/pure/collections/intsets.nim | 17 +- lib/pure/collections/lists.nim | 84 ++--- lib/pure/collections/queues.nim | 10 +- lib/pure/collections/sequtils.nim | 52 +-- lib/pure/collections/sets.nim | 47 +-- lib/pure/collections/tables.nim | 44 +-- lib/pure/colors.nim | 314 ++++++++--------- lib/pure/complex.nim | 6 +- lib/pure/concurrency/cpuload.nim | 2 +- lib/pure/concurrency/threadpool.nim | 4 +- lib/pure/cookies.nim | 8 +- lib/pure/dynlib.nim | 6 +- lib/pure/encodings.nim | 34 +- lib/pure/endians.nim | 2 +- lib/pure/events.nim | 27 +- lib/pure/fsmonitor.nim | 52 +-- lib/pure/ftpclient.nim | 65 ++-- lib/pure/future.nim | 2 +- lib/pure/gentabs.nim | 4 +- lib/pure/hashes.nim | 8 +- lib/pure/htmlgen.nim | 17 +- lib/pure/htmlparser.nim | 6 +- lib/pure/httpclient.nim | 50 +-- lib/pure/httpserver.nim | 2 +- lib/pure/json.nim | 62 ++-- lib/pure/lexbase.nim | 4 +- lib/pure/logging.nim | 31 +- lib/pure/marshal.nim | 10 +- lib/pure/matchers.nim | 8 +- lib/pure/math.nim | 32 +- lib/pure/md5.nim | 2 +- lib/pure/memfiles.nim | 33 +- lib/pure/mersenne.nim | 14 +- lib/pure/mimetypes.nim | 19 +- lib/pure/net.nim | 44 +-- lib/pure/nimprof.nim | 6 +- lib/pure/numeric.nim | 7 +- lib/pure/oids.nim | 20 +- lib/pure/os.nim | 99 +++--- lib/pure/osproc.nim | 23 +- lib/pure/parsecfg.nim | 70 ++-- lib/pure/parsecsv.nim | 56 ++-- lib/pure/parseopt.nim | 29 +- lib/pure/parseopt2.nim | 38 ++- lib/pure/parsesql.nim | 155 ++++----- lib/pure/parseurl.nim | 14 +- lib/pure/parseutils.nim | 12 +- lib/pure/parsexml.nim | 33 +- lib/pure/pegs.nim | 272 ++++++++------- lib/pure/poly.nim | 19 +- lib/pure/rawsockets.nim | 143 ++++---- lib/pure/redis.nim | 40 ++- lib/pure/romans.nim | 2 +- lib/pure/ropes.nim | 66 ++-- lib/pure/scgi.nim | 136 ++++---- lib/pure/selectors.nim | 160 ++++----- lib/pure/smtp.nim | 24 +- lib/pure/sockets.nim | 158 +++++---- lib/pure/streams.nim | 191 ++++++----- lib/pure/strtabs.nim | 25 +- lib/pure/strutils.nim | 88 ++--- lib/pure/subexes.nim | 28 +- lib/pure/terminal.nim | 67 ++-- lib/pure/times.nim | 195 +++++------ lib/pure/typetraits.nim | 2 +- lib/pure/unicode.nim | 98 +++--- lib/pure/unidecode/unidecode.nim | 4 +- lib/pure/unittest.nim | 31 +- lib/pure/uri.nim | 12 +- lib/pure/xmldom.nim | 5 +- lib/pure/xmldomparser.nim | 4 +- lib/pure/xmlparser.nim | 32 +- lib/pure/xmltree.nim | 37 +- lib/system.nim | 2 + todo.txt | 1 - 98 files changed, 2491 insertions(+), 2341 deletions(-) delete mode 100644 lib/pure/collections/baseutils.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index c5b367977..b6878c56e 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index eeaf53649..9484bbe90 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/config/nimrod.cfg b/config/nimrod.cfg index df3835ace..6d56bba2c 100644 --- a/config/nimrod.cfg +++ b/config/nimrod.cfg @@ -1,5 +1,5 @@ -# Configuration file for the Nimrod Compiler. -# (c) 2013 Andreas Rumpf +# Configuration file for the Nim Compiler. +# (c) 2014 Andreas Rumpf # Feel free to edit the default values as you need. @@ -13,6 +13,8 @@ cc = gcc arm.linux.gcc.exe = "arm-linux-gcc" arm.linux.gcc.linkerexe = "arm-linux-gcc" +cs:partial + path="$lib/core" path="$lib/pure" path="$lib/pure/collections" diff --git a/doc/manual.txt b/doc/manual.txt index d18ede409..10fe78336 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -87,7 +87,7 @@ Wether a checked runtime error results in an exception or in a fatal error at runtime is implementation specific. Thus the following program is always invalid: -.. code-block:: nimrod +.. code-block:: nim var a: array[0..1, char] let i = 5 try: @@ -159,7 +159,7 @@ starts with ``#`` and runs until the end of the line. The end of line characters belong to the piece. If the next line only consists of a comment piece which is aligned to the preceding one, it does not start a new comment: -.. code-block:: nimrod +.. code-block:: nim i = 0 # This is a single comment over multiple lines belonging to the # assignment statement. The scanner merges these two pieces. @@ -172,7 +172,7 @@ aligned to the preceding one, it does not start a new comment: The alignment requirement does not hold if the preceding comment piece ends in a backslash (followed by optional whitespace): -.. code-block:: nimrod +.. code-block:: nim type TMyObject {.final, pure, acyclic.} = object # comment continues: \ # we have lots of space here to comment 'TMyObject'. @@ -203,7 +203,7 @@ operator characters instead. The following keywords are reserved and cannot be used as identifiers: -.. code-block:: nimrod +.. code-block:: nim :file: keywords.txt Some keywords are unused; they are reserved for future developments of the @@ -268,7 +268,7 @@ be whitespace between the opening ``"""`` and the newline), the newline (and the preceding whitespace) is not included in the string. The ending of the string literal is defined by the pattern ``"""[^"]``, so this: -.. code-block:: nimrod +.. code-block:: nim """"long string within quotes"""" Produces:: @@ -286,13 +286,13 @@ letter ``r`` (or ``R``) and are delimited by matching double quotes (just like ordinary string literals) and do not interpret the escape sequences. This is especially convenient for regular expressions or Windows paths: -.. code-block:: nimrod +.. code-block:: nim var f = openFile(r"C:\texts\text.txt") # a raw string, so ``\t`` is no tab To produce a single ``"`` within a raw string literal, it has to be doubled: -.. code-block:: nimrod +.. code-block:: nim r"a""b" @@ -542,7 +542,7 @@ is not used to determine the number of spaces. If 2 or more operators have the same number of preceding spaces the precedence table applies, so ``1 + 3 * 4`` is still parsed as ``1 + (3 * 4)``, but ``1+3 * 4`` is parsed as ``(1+3) * 4``: -.. code-block:: nimrod +.. code-block:: nim #! strongSpaces if foo+4 * 4 == 8 and b&c | 9 ++ bar: @@ -554,7 +554,7 @@ is still parsed as ``1 + (3 * 4)``, but ``1+3 * 4`` is parsed as ``(1+3) * 4``: Furthermore whether an operator is used a prefix operator is affected by the number of spaces: -.. code-block:: nimrod +.. code-block:: nim #! strongSpaces echo $foo # is parsed as @@ -563,7 +563,7 @@ number of spaces: This also affects whether ``[]``, ``{}``, ``()`` are parsed as constructors or as accessors: -.. code-block:: nimrod +.. code-block:: nim #! strongSpaces echo (1,2) # is parsed as @@ -689,7 +689,7 @@ example ``int32 -> int16``. A `widening type conversion`:idx: converts a smaller type to a larger type (for example ``int16 -> int32``). In Nim only widening type conversions are *implicit*: -.. code-block:: nimrod +.. code-block:: nim var myInt16 = 5i16 var myInt: int myInt16 + 34 # of type ``int16`` @@ -710,7 +710,7 @@ A subrange type is a range of values from an ordinal type (the base type). To define a subrange type, one must specify it's limiting values: the lowest and highest value of the type: -.. code-block:: nimrod +.. code-block:: nim type TSubrange = range[0..5] @@ -735,7 +735,7 @@ constant *x* so that (x+1) is a number of two. This means that the following code is accepted: -.. code-block:: nimrod +.. code-block:: nim case (x and 3) + 7 of 7: echo "A" of 8: echo "B" @@ -788,7 +788,7 @@ These exceptions inherit from the `EFloatingPoint`:idx: base class. Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control whether the IEEE exceptions are ignored or trap a Nim exception: -.. code-block:: nimrod +.. code-block:: nim {.NanChecks: on, InfChecks: on.} var a = 1.0 var b = 0.0 @@ -819,7 +819,7 @@ The operators ``not, and, or, xor, <, <=, >, >=, !=, ==`` are defined for the bool type. The ``and`` and ``or`` operators perform short-cut evaluation. Example: -.. code-block:: nimrod +.. code-block:: nim while p != nil and p.name != "xyz": # p.name is not evaluated if p == nil @@ -849,7 +849,7 @@ Enumeration types Enumeration types define a new type whose values consist of the ones specified. The values are ordered. Example: -.. code-block:: nimrod +.. code-block:: nim type TDirection = enum @@ -873,7 +873,7 @@ explicitly given is assigned the value of the previous field + 1. An explicit ordered enum can have *holes*: -.. code-block:: nimrod +.. code-block:: nim type TTokenType = enum a = 2, b = 4, c = 89 # holes are valid @@ -887,7 +887,7 @@ The compiler supports the built-in stringify operator ``$`` for enumerations. The stringify's result can be controlled by explicitly giving the string values to use: -.. code-block:: nimrod +.. code-block:: nim type TMyEnum = enum @@ -904,7 +904,7 @@ An enum can be marked with the ``pure`` pragma so that it's fields are not added to the current scope, so they always need to be accessed via ``TMyEnum.value``: -.. code-block:: nimrod +.. code-block:: nim type TMyEnum {.pure.} = enum @@ -927,7 +927,7 @@ Strings are compared by their lexicographical order. All comparison operators are available. Strings can be indexed like arrays (lower bound is 0). Unlike arrays, they can be used in case statements: -.. code-block:: nimrod +.. code-block:: nim case paramStr(i) of "-v": incl(options, optVerbose) @@ -953,7 +953,7 @@ A Nim ``string`` is implicitly convertible to ``cstring`` for convenience. If a Nim string is passed to a C-style variadic proc, it is implicitly converted to ``cstring`` too: -.. code-block:: nimrod +.. code-block:: nim proc printf(formatstr: cstring) {.importc: "printf", varargs, header: "".} @@ -966,10 +966,10 @@ stack roots conservatively. One can use the builtin procs ``GC_ref`` and ``GC_unref`` to keep the string data alive for the rare cases where it does not work. -A `$` proc is defined for cstrings that returns a string. Thus to get a nimrod +A `$` proc is defined for cstrings that returns a string. Thus to get a nim string from a cstring: -.. code-block:: nimrod +.. code-block:: nim var str: string = "Hello!" var cstr: cstring = s var newstr: string = $cstr @@ -1002,7 +1002,7 @@ A sequence may be passed to a parameter that is of type *open array*. Example: -.. code-block:: nimrod +.. code-block:: nim type TIntArray = array[0..5, int] # an array that is indexed with 0..5 @@ -1051,7 +1051,7 @@ A ``varargs`` parameter is an openarray parameter that additionally allows to pass a variable number of arguments to a procedure. The compiler converts the list of arguments to an array implicitly: -.. code-block:: nimrod +.. code-block:: nim proc myWriteln(f: TFile, a: varargs[string]) = for s in items(a): write(f, s) @@ -1065,7 +1065,7 @@ This transformation is only done if the varargs parameter is the last parameter in the procedure header. It is also possible to perform type conversions in this context: -.. code-block:: nimrod +.. code-block:: nim proc myWriteln(f: TFile, a: varargs[string, `$`]) = for s in items(a): write(f, s) @@ -1098,7 +1098,7 @@ The default assignment operator for objects copies each component. Overloading of the assignment operator for objects is not possible, but this will change in future versions of the compiler. -.. code-block:: nimrod +.. code-block:: nim type TPerson = tuple[name: string, age: int] # type representing a person: @@ -1116,7 +1116,7 @@ is compatible with the way the C compiler does it. For consistency with ``object`` declarations, tuples in a ``type`` section can also be defined with indentation instead of ``[]``: -.. code-block:: nimrod +.. code-block:: nim type TPerson = tuple # type representing a person name: string # a person consists of a name @@ -1126,7 +1126,7 @@ Objects provide many features that tuples do not. Object provide inheritance and information hiding. Objects have access to their type at runtime, so that the ``of`` operator can be used to determine the object's type. -.. code-block:: nimrod +.. code-block:: nim type TPerson {.inheritable.} = object name*: string # the * means that `name` is accessible from other modules @@ -1154,7 +1154,7 @@ Objects can also be created with an `object construction expression`:idx: that has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is an ``object`` type or a ``ref object`` type: -.. code-block:: nimrod +.. code-block:: nim var student = TStudent(name: "Anton", age: 5, id: 3) For a ``ref object`` type ``system.new`` is invoked implicitly. @@ -1167,7 +1167,7 @@ variant types are needed. An example: -.. code-block:: nimrod +.. code-block:: nim # This is an example how an abstract syntax tree could be modelled in Nim type @@ -1249,7 +1249,7 @@ The ``.`` (access a tuple/object field operator) and ``[]`` (array/string/sequence index operator) operators perform implicit dereferencing operations for reference types: -.. code-block:: nimrod +.. code-block:: nim type PNode = ref TNode @@ -1267,7 +1267,7 @@ As a syntactical extension ``object`` types can be anonymous if declared in a type section via the ``ref object`` or ``ptr object`` notations. This feature is useful if an object should only gain reference semantics: -.. code-block:: nimrod +.. code-block:: nim type Node = ref object @@ -1287,7 +1287,7 @@ traced references, strings or sequences: in order to free everything properly, the built-in procedure ``GCunref`` has to be called before freeing the untraced memory manually: -.. code-block:: nimrod +.. code-block:: nim type TData = tuple[x, y: int, s: string] @@ -1326,7 +1326,7 @@ Not nil annotation All types for that ``nil`` is a valid value can be annotated to exclude ``nil`` as a valid value with the ``not nil`` annotation: -.. code-block:: nimrod +.. code-block:: nim type PObject = ref TObj not nil TProc = (proc (x, y: int)) not nil @@ -1355,7 +1355,7 @@ A region has to be an object type. Regions are very useful to separate user space and kernel memory in the development of OS kernels: -.. code-block:: nimrod +.. code-block:: nim type Kernel = object Userspace = object @@ -1377,7 +1377,7 @@ the pointer types: If ``A <: B`` then ``ptr[A, T] <: ptr[B, T]``. This can be used to model subregions of memory. As a special typing rule ``ptr[R, T]`` is not compatible to ``pointer`` to prevent the following from compiling: -.. code-block:: nimrod +.. code-block:: nim # from system proc dealloc(p: pointer) @@ -1414,7 +1414,7 @@ types to achieve `functional`:idx: programming techniques. Examples: -.. code-block:: nimrod +.. code-block:: nim proc printItem(x: int) = ... @@ -1424,7 +1424,7 @@ Examples: forEach(printItem) # this will NOT work because calling conventions differ -.. code-block:: nimrod +.. code-block:: nim type TOnMouseMove = proc (x, y: int) {.closure.} @@ -1532,7 +1532,7 @@ numerical base type, for example. The following example models currencies. Different currencies should not be mixed in monetary calculations. Distinct types are a perfect tool to model different currencies: -.. code-block:: nimrod +.. code-block:: nim type TDollar = distinct int TEuro = distinct int @@ -1570,7 +1570,7 @@ should not generate all this code only to optimize it away later - after all The pragma `borrow`:idx: has been designed to solve this problem; in principle it generates the above trivial implementations: -.. code-block:: nimrod +.. code-block:: nim proc `*` (x: TDollar, y: int): TDollar {.borrow.} proc `*` (x: int, y: TDollar): TDollar {.borrow.} proc `div` (x: TDollar, y: int): TDollar {.borrow.} @@ -1582,7 +1582,7 @@ generated. But it seems all this boilerplate code needs to be repeated for the ``TEuro`` currency. This can be solved with templates_. -.. code-block:: nimrod +.. code-block:: nim template additive(typ: typedesc): stmt = proc `+` *(x, y: typ): typ {.borrow.} proc `-` *(x, y: typ): typ {.borrow.} @@ -1616,7 +1616,7 @@ currency. This can be solved with templates_. The borrow pragma can also be used to annotate the distinct type to allow certain builtin operations to be lifted: -.. code-block:: nimrod +.. code-block:: nim type Foo = object a, b: int @@ -1640,7 +1640,7 @@ An SQL statement that is passed from Nim to an SQL database might be modelled as a string. However, using string templates and filling in the values is vulnerable to the famous `SQL injection attack`:idx:\: -.. code-block:: nimrod +.. code-block:: nim import strutils proc query(db: TDbHandle, statement: string) = ... @@ -1655,7 +1655,7 @@ This can be avoided by distinguishing strings that contain SQL from strings that don't. Distinct types provide a means to introduce a new string type ``TSQL`` that is incompatible with ``string``: -.. code-block:: nimrod +.. code-block:: nim type TSQL = distinct string @@ -1672,7 +1672,7 @@ It is an essential property of abstract types that they **do not** imply a subtype relation between the abtract type and its base type. Explict type conversions from ``string`` to ``TSQL`` are allowed: -.. code-block:: nimrod +.. code-block:: nim import strutils, sequtils proc properQuote(s: string): TSQL = @@ -1703,7 +1703,7 @@ The ``void`` type denotes the absense of any type. Parameters of type ``void`` are treated as non-existent, ``void`` as a return type means that the procedure does not return a value: -.. code-block:: nimrod +.. code-block:: nim proc nothing(x, y: void): void = echo "ha" @@ -1711,7 +1711,7 @@ the procedure does not return a value: The ``void`` type is particularly useful for generic code: -.. code-block:: nimrod +.. code-block:: nim proc callProc[T](p: proc (x: T), x: T) = when T is void: p() @@ -1726,7 +1726,7 @@ The ``void`` type is particularly useful for generic code: However, a ``void`` type cannot be inferred in generic code: -.. code-block:: nimrod +.. code-block:: nim callProc(emptyProc) # Error: type mismatch: got (proc ()) # but expected one of: @@ -1749,7 +1749,7 @@ Nim uses structural type equivalence for most types. Only for objects, enumerations and distinct types name equivalence is used. The following algorithm (in pseudo-code) determines type equality: -.. code-block:: nimrod +.. code-block:: nim proc typeEqualsAux(a, b: PType, s: var set[PType * PType]): bool = if (a,b) in s: return true @@ -1795,7 +1795,7 @@ The following algorithm (in pseudo-code) determines whether two types are equal with no respect to ``distinct`` types. For brevity the cycle check with an auxiliary set ``s`` is omitted: -.. code-block:: nimrod +.. code-block:: nim proc typeEqualsOrDistinct(a, b: PType): bool = if a.kind == b.kind: case a.kind @@ -1835,7 +1835,7 @@ Subtype relation If object ``a`` inherits from ``b``, ``a`` is a subtype of ``b``. This subtype relation is extended to the types ``var``, ``ref``, ``ptr``: -.. code-block:: nimrod +.. code-block:: nim proc isSubtype(a, b: PType): bool = if a.kind == b.kind: case a.kind @@ -1854,7 +1854,7 @@ Convertible relation A type ``a`` is **implicitly** convertible to type ``b`` iff the following algorithm returns true: -.. code-block:: nimrod +.. code-block:: nim # XXX range types? proc isImplicitlyConvertible(a, b: PType): bool = case a.kind @@ -1884,7 +1884,7 @@ algorithm returns true: A type ``a`` is **explicitly** convertible to type ``b`` iff the following algorithm returns true: -.. code-block:: nimrod +.. code-block:: nim proc isIntegralType(t: PType): bool = result = isOrdinal(t) or t.kind in {float, float32, float64} @@ -1898,7 +1898,7 @@ algorithm returns true: The convertible relation can be relaxed by a user-defined type `converter`:idx:. -.. code-block:: nimrod +.. code-block:: nim converter toInt(x: char): int = result = ord(x) var @@ -1960,7 +1960,7 @@ Discard statement Example: -.. code-block:: nimrod +.. code-block:: nim proc p(x, y: int): int = result = x + y @@ -1975,7 +1975,7 @@ a static error. The return value can be ignored implicitly if the called proc/iterator has been declared with the `discardable`:idx: pragma: -.. code-block:: nimrod +.. code-block:: nim proc p(x, y: int): int {.discardable.} = result = x + y @@ -1983,7 +1983,7 @@ been declared with the `discardable`:idx: pragma: An empty ``discard`` statement is often used as a null statement: -.. code-block:: nimrod +.. code-block:: nim proc classify(s: string) = case s[0] of SymChars, '_': echo "an identifier" @@ -1998,7 +1998,7 @@ Var statements declare new local and global variables and initialize them. A comma separated list of variables can be used to specify variables of the same type: -.. code-block:: nimrod +.. code-block:: nim var a: int = 0 @@ -2031,14 +2031,14 @@ T = enum cast[T](0); this may be an invalid value The implicit initialization can be avoided for optimization reasons with the `noinit`:idx: pragma: -.. code-block:: nimrod +.. code-block:: nim var a {.noInit.}: array [0..1023, char] If a proc is annotated with the ``noinit`` pragma this refers to its implicit ``result`` variable: -.. code-block:: nimrod +.. code-block:: nim proc returnUndefinedValue: int {.noinit.} = discard @@ -2047,7 +2047,7 @@ type pragma. The compiler requires an explicit initialization then. However it does a `control flow analysis`:idx: to prove the variable has been initialized and does not rely on syntactic properties: -.. code-block:: nimrod +.. code-block:: nim type TMyObject = object {.requiresInit.} @@ -2082,7 +2082,7 @@ constant declaration at compile time. Nim contains a sophisticated compile-time evaluator, so procedures which have no side-effect can be used in constant expressions too: -.. code-block:: nimrod +.. code-block:: nim import strutils const constEval = contains("abc", 'b') # computed at compile time! @@ -2128,7 +2128,7 @@ If statement Example: -.. code-block:: nimrod +.. code-block:: nim var name = readLine(stdin) @@ -2152,7 +2152,7 @@ The scoping for an ``if`` statement is slightly subtle to support an important use case. A new scope starts for the ``if``/``elif`` condition and ends after the corresponding *then* block: -.. code-block:: nimrod +.. code-block:: nim if {| (let m = input =~ re"(\w+)=\w+"; m.isMatch): echo "key ", m[0], " value ", m[1] |} elif {| (let m = input =~ re""; m.isMatch): @@ -2168,7 +2168,7 @@ Case statement Example: -.. code-block:: nimrod +.. code-block:: nim case readline(stdin) of "delete-everything", "restart-computer": @@ -2205,7 +2205,7 @@ As a special semantic extension, an expression in an ``of`` branch of a case statement may evaluate to a set or array constructor; the set or array is then expanded into a list of its elements: -.. code-block:: nimrod +.. code-block:: nim const SymChars: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'} @@ -2228,7 +2228,7 @@ When statement Example: -.. code-block:: nimrod +.. code-block:: nim when sizeof(int) == 2: echo("running on a 16 bit system!") @@ -2258,14 +2258,14 @@ Return statement Example: -.. code-block:: nimrod +.. code-block:: nim return 40+2 The ``return`` statement ends the execution of the current procedure. It is only allowed in procedures. If there is an ``expr``, this is syntactic sugar for: -.. code-block:: nimrod +.. code-block:: nim result = expr return result @@ -2275,7 +2275,7 @@ the proc has a return type. The `result`:idx: variable is always the return value of the procedure. It is automatically declared by the compiler. As all variables, ``result`` is initialized to (binary) zero: -.. code-block:: nimrod +.. code-block:: nim proc returnZero(): int = # implicitly returns 0 @@ -2285,7 +2285,7 @@ Yield statement Example: -.. code-block:: nimrod +.. code-block:: nim yield (1, 2, 3) The ``yield`` statement is used instead of the ``return`` statement in @@ -2301,7 +2301,7 @@ Block statement Example: -.. code-block:: nimrod +.. code-block:: nim var found = false block myblock: for i in 0..3: @@ -2322,7 +2322,7 @@ Break statement Example: -.. code-block:: nimrod +.. code-block:: nim break The ``break`` statement is used to leave a block immediately. If ``symbol`` @@ -2335,7 +2335,7 @@ While statement Example: -.. code-block:: nimrod +.. code-block:: nim echo("Please tell me your password: \n") var pw = readLine(stdin) while pw != "12345": @@ -2355,7 +2355,7 @@ A ``continue`` statement leads to the immediate next iteration of the surrounding loop construct. It is only allowed within a loop. A continue statement is syntactic sugar for a nested block: -.. code-block:: nimrod +.. code-block:: nim while expr1: stmt1 continue @@ -2363,7 +2363,7 @@ statement is syntactic sugar for a nested block: Is equivalent to: -.. code-block:: nimrod +.. code-block:: nim while expr1: block myBlockName: stmt1 @@ -2379,7 +2379,7 @@ by the unsafe ``asm`` statement. Identifiers in the assembler code that refer to Nim identifiers shall be enclosed in a special character which can be specified in the statement's pragmas. The default special character is ``'`'``: -.. code-block:: nimrod +.. code-block:: nim {.push stackTrace:off.} proc addInt(a, b: int): int = # a in eax, and b in edx @@ -2394,7 +2394,7 @@ specified in the statement's pragmas. The default special character is ``'`'``: If the GNU assembler is used, quotes and newlines are inserted automatically: -.. code-block:: nimrod +.. code-block:: nim proc addInt(a, b: int): int = asm """ addl %%ecx, %%eax @@ -2407,7 +2407,7 @@ If the GNU assembler is used, quotes and newlines are inserted automatically: Instead of: -.. code-block:: nimrod +.. code-block:: nim proc addInt(a, b: int): int = asm """ "addl %%ecx, %%eax\n" @@ -2430,7 +2430,7 @@ a hidden leading parameter for any procedure calls, following the using statement in the current scope. Thus, it behaves much like the hidden `this` parameter available in some object-oriented programming languages. -.. code-block:: nimrod +.. code-block:: nim var s = socket() using s @@ -2447,7 +2447,7 @@ When applied to a callable symbol, it brings the designated symbol in the current scope. Thus, it can be used to disambiguate between imported symbols from different modules having the same name. -.. code-block:: nimrod +.. code-block:: nim import windows, sdl using sdl.SetTimer @@ -2456,7 +2456,7 @@ replace, **neither** does it create a new scope. What this means is that if one applies this to multiple variables the compiler will find conflicts in what variable to use: -.. code-block:: nimrod +.. code-block:: nim var a, b = "kill it" using a add(" with fire") @@ -2476,7 +2476,7 @@ If expression An `if expression` is almost like an if statement, but it is an expression. Example: -.. code-block:: nimrod +.. code-block:: nim var y = if x > 8: 9 else: 10 An if expression always results in a value, so the ``else`` part is @@ -2492,7 +2492,7 @@ Case expression The `case expression` is again very similar to the case statement: -.. code-block:: nimrod +.. code-block:: nim var favoriteFood = case animal of "dog": "bones" of "cat": "mice" @@ -2510,7 +2510,7 @@ Table constructor A table constructor is syntactic sugar for an array constructor: -.. code-block:: nimrod +.. code-block:: nim {"key1": "value1", "key2", "key3": "value2"} # is the same as: @@ -2545,7 +2545,7 @@ Type casts ---------- Example: -.. code-block:: nimrod +.. code-block:: nim cast[int](x) Type casts are a crude mechanism to interpret the bit pattern of @@ -2563,7 +2563,7 @@ object on the stack and can thus reference a non-existing object. One can get the address of variables, but one can't use it on variables declared through ``let`` statements: -.. code-block:: nimrod +.. code-block:: nim let t1 = "Hello" var @@ -2594,7 +2594,7 @@ variable named `result`:idx: that represents the return value. Procs can be overloaded. The overloading resolution algorithm tries to find the proc that is the best match for the arguments. Example: -.. code-block:: nimrod +.. code-block:: nim proc toLower(c: Char): Char = # toLower for characters if c in {'A'..'Z'}: @@ -2609,7 +2609,7 @@ the best match for the arguments. Example: Calling a procedure can be done in many different ways: -.. code-block:: nimrod +.. code-block:: nim proc callme(x, y: int, s: string = "", c: char, b: bool = false) = ... # call with positional arguments # parameter bindings: @@ -2627,7 +2627,7 @@ A procedure cannot modify its parameters (unless the parameters have the type `Operators`:idx: are procedures with a special operator symbol as identifier: -.. code-block:: nimrod +.. code-block:: nim proc `$` (x: int): string = # converts an integer to a string; this is a prefix operator. result = intToStr(x) @@ -2641,7 +2641,7 @@ grammar explicitly. Any operator can be called like an ordinary proc with the '`opr`' notation. (Thus an operator can have more than two parameters): -.. code-block:: nimrod +.. code-block:: nim proc `*+` (a, b, c: int): int = # Multiply and add result = a * b + c @@ -2659,7 +2659,7 @@ remaining arguments: ``obj.len`` (instead of ``len(obj)``). This method call syntax is not restricted to objects, it can be used to supply any type of first argument for procedures: -.. code-block:: nimrod +.. code-block:: nim echo("abc".len) # is the same as echo(len("abc")) echo("abc".toUpper()) @@ -2676,7 +2676,7 @@ Nim has no need for *get-properties*: Ordinary get-procedures that are called with the *method call syntax* achieve the same. But setting a value is different; for this a special setter syntax is needed: -.. code-block:: nimrod +.. code-block:: nim type TSocket* = object of TObject @@ -2707,7 +2707,7 @@ means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as ``echo(f(1, f(2)))``. The method call syntax may be used to provide one more argument in this case: -.. code-block:: nimrod +.. code-block:: nim proc optarg(x:int, y:int = 0):int = x + y proc singlearg(x:int):int = 20*x @@ -2744,7 +2744,7 @@ Anonymous Procs Procs can also be treated as expressions, in which case it's allowed to omit the proc's name. -.. code-block:: nimrod +.. code-block:: nim var cities = @["Frankfurt", "Tokyo", "New York"] cities.sort(proc (x,y: string): int = @@ -2761,7 +2761,7 @@ Do notation As a special more convenient notation, proc expressions involved in procedure calls can use the ``do`` keyword: -.. code-block:: nimrod +.. code-block:: nim sort(cities) do (x,y: string) -> int: cmp(x.len, y.len) # Less parenthesis using the method plus command syntax: @@ -2773,7 +2773,7 @@ The proc expression represented by the do block is appended to them. More than one ``do`` block can appear in a single call: -.. code-block:: nimrod +.. code-block:: nim proc performWithUndo(task: proc(), undo: proc()) = ... performWithUndo do: @@ -2806,7 +2806,7 @@ Var parameters -------------- The type of a parameter may be prefixed with the ``var`` keyword: -.. code-block:: nimrod +.. code-block:: nim proc divmod(a, b: int; res, remainder: var int) = res = a div b remainder = a mod b @@ -2824,7 +2824,7 @@ visible to the caller. The argument passed to a var parameter has to be an l-value. Var parameters are implemented as hidden pointers. The above example is equivalent to: -.. code-block:: nimrod +.. code-block:: nim proc divmod(a, b: int; res, remainder: ptr int) = res[] = a div b remainder[] = a mod b @@ -2838,7 +2838,7 @@ above example is equivalent to: In the examples, var parameters or pointers are used to provide two return values. This can be done in a cleaner way by returning a tuple: -.. code-block:: nimrod +.. code-block:: nim proc divmod(a, b: int): tuple[res, remainder: int] = (a div b, a mod b) @@ -2849,7 +2849,7 @@ return values. This can be done in a cleaner way by returning a tuple: One can use `tuple unpacking`:idx: to access the tuple's fields: -.. code-block:: nimrod +.. code-block:: nim var (x, y) = divmod(8, 5) # tuple unpacking assert x == 1 assert y == 3 @@ -2861,7 +2861,7 @@ Var return type A proc, converter or iterator may return a ``var`` type which means that the returned value is an l-value and can be modified by the caller: -.. code-block:: nimrod +.. code-block:: nim var g = 0 proc WriteAccessToG(): var int = @@ -2873,14 +2873,14 @@ returned value is an l-value and can be modified by the caller: It is a compile time error if the implicitly introduced pointer could be used to access a location beyond its lifetime: -.. code-block:: nimrod +.. code-block:: nim proc WriteAccessToG(): var int = var g = 0 result = g # Error! For iterators, a component of a tuple return type can have a ``var`` type too: -.. code-block:: nimrod +.. code-block:: nim iterator mpairs(a: var seq[string]): tuple[key: int, val: var string] = for i in 0..a.high: yield (i, a[i]) @@ -2901,7 +2901,7 @@ Multi-methods Procedures always use static dispatch. Multi-methods use dynamic dispatch. -.. code-block:: nimrod +.. code-block:: nim type TExpr = object ## abstract base class for an expression TLiteral = object of TExpr @@ -2937,7 +2937,7 @@ requires dynamic binding. In a multi-method all parameters that have an object type are used for the dispatching: -.. code-block:: nimrod +.. code-block:: nim type TThing = object TUnit = object of TThing @@ -2987,7 +2987,7 @@ reached the data is bound to the ``for`` loop variables and control continues in the body of the ``for`` loop. The iterator's local variables and execution state are automatically saved between calls. Example: -.. code-block:: nimrod +.. code-block:: nim # this definition exists in the system module iterator items*(a: string): char {.inline.} = var i = 0 @@ -3000,7 +3000,7 @@ state are automatically saved between calls. Example: The compiler generates code as if the programmer would have written this: -.. code-block:: nimrod +.. code-block:: nim var i = 0 while i < len(a): var ch = a[i] @@ -3019,7 +3019,7 @@ If the for loop expression ``e`` does not denote an iterator and the for loop has exactly 1 variable, the for loop expression is rewritten to ``items(e)``; ie. an ``items`` iterator is implicitly invoked: -.. code-block:: nimrod +.. code-block:: nim for x in [1,2,3]: echo x If the for loop has exactly 2 variables, a ``pairs`` iterator is implicitly @@ -3042,7 +3042,7 @@ templates, macros and other inline iterators. In contrast to that, a `closure iterator`:idx: can be passed around more freely: -.. code-block:: nimrod +.. code-block:: nim iterator count0(): int {.closure.} = yield 0 @@ -3073,7 +3073,7 @@ The ``iterator`` type is always of the calling convention ``closure`` implicitly; the following example shows how to use iterators to implement a `collaborative tasking`:idx: system: -.. code-block:: nimrod +.. code-block:: nim # simple tasking: type TTask = iterator (ticker: int) @@ -3112,7 +3112,7 @@ Closure iterators are *resumable functions* and so one has to provide the arguments to every call. To get around this limitation one can capture parameters of an outer factory proc: -.. code-block:: nimrod +.. code-block:: nim proc mycount(a, b: int): iterator (): int = result = iterator (): int = var x = a @@ -3139,7 +3139,7 @@ Type sections Example: -.. code-block:: nimrod +.. code-block:: nim type # example demonstrating mutually recursive types PNode = ref TNode # a traced pointer to a TNode TNode = object @@ -3166,7 +3166,7 @@ Try statement Example: -.. code-block:: nimrod +.. code-block:: nim # read the first two lines of a text file that should contain numbers # and tries to add them var @@ -3214,7 +3214,7 @@ Except and finally statements Any statements following them in the current block will be considered to be in an implicit try block: -.. code-block:: nimrod +.. code-block:: nim var f = open("numbers.txt") finally: close(f) ... @@ -3224,7 +3224,7 @@ type of the exception, one has to catch everything. Also, if one wants to use both ``finally`` and ``except`` one needs to reverse the usual sequence of the statements. Example: -.. code-block:: nimrod +.. code-block:: nim proc test() = raise newException(E_base, "Hey ho") @@ -3242,7 +3242,7 @@ Raise statement Example: -.. code-block:: nimrod +.. code-block:: nim raise newEOS("operating system failed") Apart from built-in operations like array indexing, memory allocation, etc. @@ -3265,7 +3265,7 @@ called within the ``try`` statement that should be affected. This allows for a Lisp-like `condition system`:idx:\: -.. code-block:: nimrod +.. code-block:: nim var myFile = open("broken.txt", fmWrite) try: onRaise do (e: ref E_Base)-> bool: @@ -3294,14 +3294,14 @@ Nim supports exception tracking. The `raises`:idx: pragma can be used to explicitly define which exceptions a proc/iterator/method/converter is allowed to raise. The compiler verifies this: -.. code-block:: nimrod +.. code-block:: nim proc p(what: bool) {.raises: [EIO, EOS].} = if what: raise newException(EIO, "IO") else: raise newException(EOS, "OS") An empty ``raises`` list (``raises: []``) means that no exception may be raised: -.. code-block:: nimrod +.. code-block:: nim proc p(): bool {.raises: [].} = try: unsafeCall() @@ -3313,7 +3313,7 @@ An empty ``raises`` list (``raises: []``) means that no exception may be raised: A ``raises`` list can also be attached to a proc type. This affects type compatibility: -.. code-block:: nimrod +.. code-block:: nim type TCallback = proc (s: string) {.raises: [EIO].} var @@ -3348,7 +3348,7 @@ possibly raised exceptions; the algorithm operates on ``p``'s call graph: Rules 1-2 ensure the following works: -.. code-block:: nimrod +.. code-block:: nim proc noRaise(x: proc()) {.raises: [].} = # unknown call that might raise anything, but valid: x() @@ -3371,7 +3371,7 @@ The exception tracking is part of Nim's `effect system`:idx:. Raising an exception is an *effect*. Other effects can also be defined. A user defined effect is a means to *tag* a routine and to perform checks against this tag: -.. code-block:: nimrod +.. code-block:: nim type IO = object ## input/output effect proc readLine(): string {.tags: [IO].} @@ -3402,7 +3402,7 @@ The ``effects`` pragma has been designed to assist the programmer with the effects analysis. It is a statement that makes the compiler output all inferred effects up to the ``effects``'s position: -.. code-block:: nimrod +.. code-block:: nim proc p(what: bool) = if what: raise newException(EIO, "IO") @@ -3419,7 +3419,7 @@ Generics Example: -.. code-block:: nimrod +.. code-block:: nim type TBinaryTree[T] = object # TBinaryTree is a generic type with # with generic param ``T`` @@ -3478,7 +3478,7 @@ Is operator The ``is`` operator checks for type equivalence at compile time. It is therefore very useful for type specialization within generic code: -.. code-block:: nimrod +.. code-block:: nim type TTable[TKey, TValue] = object keys: seq[TKey] @@ -3493,7 +3493,7 @@ Type operator The ``type`` (in many other languages called `typeof`:idx:) operator can be used to get the type of an expression: -.. code-block:: nimrod +.. code-block:: nim var x = 0 var y: type(x) # y has type int @@ -3502,7 +3502,7 @@ call ``c(X)`` (where ``X`` stands for a possibly empty list of arguments), the interpretation where ``c`` is an iterator is preferred over the other interpretations: -.. code-block:: nimrod +.. code-block:: nim import strutils # strutils contains both a ``split`` proc and iterator, but since an @@ -3541,7 +3541,7 @@ name that will match any instantiation of the generic type. Type classes can be combined using the standard boolean operators to form more complex type classes: -.. code-block:: nimrod +.. code-block:: nim # create a type class that will match all tuple and object types type TRecordType = tuple or object @@ -3556,7 +3556,7 @@ combination of param types used within the program. Nim also allows for type classes and regular types to be specified as `type constraints`:idx: of the generic type parameter: -.. code-block:: nimrod +.. code-block:: nim proc onlyIntOrString[T: int|string](x, y: T) = discard onlyIntOrString(450, 616) # valid @@ -3567,7 +3567,7 @@ By default, during overload resolution each named type class will bind to exactly one concrete type. Here is an example taken directly from the system module to illustrate this: -.. code-block:: nimrod +.. code-block:: nim proc `==`*(x, y: tuple): bool = ## requires `x` and `y` to be of the same tuple type ## generic ``==`` operator for tuples that is lifted from the components @@ -3582,7 +3582,7 @@ to allow each param matching the type class to bind to a different type. If a proc param doesn't have a type specified, Nim will use the ``distinct auto`` type class (also known as ``any``): -.. code-block:: nimrod +.. code-block:: nim # allow any combination of param types proc concat(a, b): string = $a & $b @@ -3590,7 +3590,7 @@ Procs written with the implicitly generic style will often need to refer to the type parameters of the matched generic type. They can be easily accessed using the dot syntax: -.. code-block:: nimrod +.. code-block:: nim type TMatrix[T, Rows, Columns] = object ... @@ -3603,7 +3603,7 @@ effect when anonymous or distinct type classes are used. When a generic type is instantiated with a type class instead of a concrete type, this results in another more specific type class: -.. code-block:: nimrod +.. code-block:: nim seq[ref object] # Any sequence storing references to any object type type T1 = auto @@ -3630,7 +3630,7 @@ matched type must satisfy. Declarative type classes are written in the following form: -.. code-block:: nimrod +.. code-block:: nim type Comparable = generic x, y (x < y) is bool @@ -3661,7 +3661,7 @@ type value appearing in a callable expression will be treated as a variable of the designated type for overload resolution purposes, unless the type value was passed in its explicit ``typedesc[T]`` form: -.. code-block:: nimrod +.. code-block:: nim type OutputStream = generic S write(var S, string) @@ -3678,7 +3678,7 @@ If a type class is used as the return type of a proc and it won't be bound to a concrete type by some of the proc params, Nim will infer the return type from the proc body. This is usually used with the ``auto`` type class: -.. code-block:: nimrod +.. code-block:: nim proc makePair(a, b): auto = (first: a, second: b) The return type will be treated as additional generic param and can be @@ -3700,7 +3700,7 @@ and every other symbol is closed. Open symbols are looked up in two different contexts: Both the context at definition and the context at instantiation are considered: -.. code-block:: nimrod +.. code-block:: nim type TIndex = distinct int @@ -3719,7 +3719,7 @@ too. A symbol can be forced to be open by a `mixin`:idx: declaration: -.. code-block:: nimrod +.. code-block:: nim proc create*[T](): ref T = # there is no overloaded 'init' here, so we need to state that it's an # open symbol explicitly: @@ -3736,7 +3736,7 @@ can be used to explicitly declare identifiers that should be bound early (i.e. the identifiers should be looked up in the scope of the template/generic definition): -.. code-block:: nimrod +.. code-block:: nim # Module A var lastId = 0 @@ -3746,7 +3746,7 @@ definition): inc(lastId) lastId -.. code-block:: nimrod +.. code-block:: nim # Module B import A @@ -3767,7 +3767,7 @@ The syntax to *invoke* a template is the same as calling a procedure. Example: -.. code-block:: nimrod +.. code-block:: nim template `!=` (a, b: expr): expr = # this definition exists in the System module not (a == b) @@ -3796,7 +3796,7 @@ ordinary templates. Ordinary templates take part in overloading resolution. As such their arguments need to be type checked before the template is invoked. So ordinary templates cannot receive undeclared identifiers: -.. code-block:: nimrod +.. code-block:: nim template declareInt(x: expr) = var x: int @@ -3807,7 +3807,7 @@ An ``immediate`` template does not participate in overload resolution and so its arguments are not checked for semantics before invocation. So they can receive undeclared identifiers: -.. code-block:: nimrod +.. code-block:: nim template declareInt(x: expr) {.immediate.} = var x: int @@ -3822,7 +3822,7 @@ If there is a ``stmt`` parameter it should be the last in the template declaration, because statements are passed to a template via a special ``:`` syntax: -.. code-block:: nimrod +.. code-block:: nim template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} = var f: TFile @@ -3848,7 +3848,7 @@ Symbol binding in templates A template is a `hygienic`:idx: macro and so opens a new scope. Most symbols are bound from the definition scope of the template: -.. code-block:: nimrod +.. code-block:: nim # Module A var lastId = 0 @@ -3857,7 +3857,7 @@ bound from the definition scope of the template: inc(lastId) lastId -.. code-block:: nimrod +.. code-block:: nim # Module B import A @@ -3873,7 +3873,7 @@ Identifier construction In templates identifiers can be constructed with the backticks notation: -.. code-block:: nimrod +.. code-block:: nim template typedef(name: expr, typ: typedesc) {.immediate.} = type @@ -3894,7 +3894,7 @@ A parameter ``p`` in a template is even substituted in the expression ``x.p``. Thus template arguments can be used as field names and a global symbol can be shadowed by the same argument name even when fully qualified: -.. code-block:: nimrod +.. code-block:: nim # module 'm' type @@ -3911,7 +3911,7 @@ shadowed by the same argument name even when fully qualified: But the global symbol can properly be captured by a ``bind`` statement: -.. code-block:: nimrod +.. code-block:: nim # module 'm' type @@ -3934,7 +3934,7 @@ Hygiene in templates Per default templates are `hygienic`:idx:\: Local identifiers declared in a template cannot be accessed in the instantiation context: -.. code-block:: nimrod +.. code-block:: nim template newException*(exceptn: typedesc, message: string): expr = var @@ -3957,7 +3957,7 @@ is ``gensym`` and for ``proc``, ``iterator``, ``converter``, ``template``, ``macro`` is ``inject``. However, if the name of the entity is passed as a template parameter, it is an inject'ed symbol: -.. code-block:: nimrod +.. code-block:: nim template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} = block: var f: TFile # since 'f' is a template param, it's injected implicitly @@ -3971,7 +3971,7 @@ template parameter, it is an inject'ed symbol: The ``inject`` and ``gensym`` pragmas are second class annotations; they have no semantics outside of a template definition and cannot be abstracted over: -.. code-block:: nimrod +.. code-block:: nim {.pragma myInject: inject.} template t() = @@ -4008,7 +4008,7 @@ Expression Macros The following example implements a powerful ``debug`` command that accepts a variable number of arguments: -.. code-block:: nimrod +.. code-block:: nim # to work with Nim syntax trees, we need an API that is defined in the # ``macros`` module: import macros @@ -4037,7 +4037,7 @@ variable number of arguments: The macro call expands to: -.. code-block:: nimrod +.. code-block:: nim write(stdout, "a[0]") write(stdout, ": ") writeln(stdout, a[0]) @@ -4065,7 +4065,7 @@ instantiating context. There is a way to use bound identifiers (aka `symbols`:idx:) instead of using unbound identifiers. The ``bindSym`` builtin can be used for that: -.. code-block:: nimrod +.. code-block:: nim import macros macro debug(n: varargs[expr]): stmt = @@ -4086,7 +4086,7 @@ builtin can be used for that: The macro call expands to: -.. code-block:: nimrod +.. code-block:: nim write(stdout, "a[0]") write(stdout, ": ") writeln(stdout, a[0]) @@ -4113,7 +4113,7 @@ invoked by an expression following a colon. The following example outlines a macro that generates a lexical analyzer from regular expressions: -.. code-block:: nimrod +.. code-block:: nim import macros macro case_token(n: stmt): stmt = @@ -4147,14 +4147,14 @@ Macros as pragmas Whole routines (procs, iterators etc.) can also be passed to a template or a macro via the pragma notation: -.. code-block:: nimrod +.. code-block:: nim template m(s: stmt) = discard proc p() {.m.} = discard This is a simple syntactic transformation into: -.. code-block:: nimrod +.. code-block:: nim template m(s: stmt) = discard m: @@ -4171,7 +4171,7 @@ static[T] As their name suggests, static params must be known at compile-time: -.. code-block:: nimrod +.. code-block:: nim proc precompiledRegex(pattern: static[string]): TRegEx = var res {.global.} = re(pattern) @@ -4193,7 +4193,7 @@ used to declare procs accepting both static and run-time values, which can optimize their body according to the supplied param using the `isStatic(p)` predicate: -.. code-block:: nimrod +.. code-block:: nim # The following proc will be compiled once for each unique static # value and also once for the case handling all run-time values: @@ -4206,7 +4206,7 @@ predicate: Static params can also appear in the signatures of generic types: -.. code-block:: nimrod +.. code-block:: nim type Matrix[M,N: static[int]; T: Number] = array[0..(M*N - 1), T] @@ -4231,7 +4231,7 @@ When used as a regular proc param, typedesc acts as a type class. The proc will be instantiated for each unique type parameter and one can refer to the instantiation type using the param name: -.. code-block:: nimrod +.. code-block:: nim proc new(T: typedesc): ref T = echo "allocating ", T.name @@ -4244,7 +4244,7 @@ When multiple typedesc params are present, they act like a distinct type class (i.e. they will bind freely to different types). To force a bind-once behavior one can use a named alias or an explicit `typedesc` generic param: -.. code-block:: nimrod +.. code-block:: nim # `type1` and `type2` are aliases for typedesc available from system.nim proc acceptOnlyTypePairs(A, B: type1; C, D: type2) @@ -4252,7 +4252,7 @@ one can use a named alias or an explicit `typedesc` generic param: Once bound, typedesc params can appear in the rest of the proc signature: -.. code-block:: nimrod +.. code-block:: nim template declareVariableWithType(T: typedesc, value: T) = var x: T = value @@ -4266,7 +4266,7 @@ typedesc acts as any other type. One can create variables, store typedesc values inside containers and so on. For example, here is how one can create a type-safe wrapper for the unsafe `printf` function from C: -.. code-block:: nimrod +.. code-block:: nim macro safePrintF(formatString: string{lit}, args: varargs[expr]): expr = var i = 0 for c in formatChars(formatString): @@ -4295,7 +4295,7 @@ a type-safe wrapper for the unsafe `printf` function from C: Overload resolution can be further influenced by constraining the set of types that will match the typedesc param: -.. code-block:: nimrod +.. code-block:: nim template maxval(T: typedesc[int]): int = high(int) template maxval(T: typedesc[float]): float = Inf @@ -4326,14 +4326,14 @@ for a dot operator that can be matched against a re-written form of the expression, where the unknown field or proc name is converted to an additional static string parameter: -.. code-block:: nimrod +.. code-block:: nim a.b # becomes `.`(a, "b") a.b(c, d) # becomes `.`(a, "b", c, d) The matched dot operators can be symbols of any callable kind (procs, templates and macros), depending on the desired effect: -.. code-block:: nimrod +.. code-block:: nim proc `.` (js: PJsonNode, field: string): JSON = js[field] var js = parseJson("{ x: 1, y: 2}") @@ -4357,7 +4357,7 @@ operator `.=` ------------- This operator will be matched against assignments to missing fields. -.. code-block:: nimrod +.. code-block:: nim a.b = c # becomes `.=`(a, "b", c) @@ -4408,7 +4408,7 @@ destructors in both user-defined and generated destructors will be inserted. A destructor is attached to the type it destructs; expressions of this type can then only be used in *destructible contexts* and as parameters: -.. code-block:: nimrod +.. code-block:: nim type TMyObj = object x, y: int @@ -4460,7 +4460,7 @@ language may weaken this restriction.) The signature has to be: -.. code-block:: nimrod +.. code-block:: nim proc deepCopy(x: T): T {.override.} This mechanism is used by most data structures that support shared memory like @@ -4478,7 +4478,7 @@ a *name* but also a *pattern* that is searched for after the semantic checking phase of the compiler: This means they provide an easy way to enhance the compilation pipeline with user defined optimizations: -.. code-block:: nimrod +.. code-block:: nim template optMul{`*`(a, 2)}(a: int): int = a+a let x = 3 @@ -4494,7 +4494,7 @@ needs to be used. Unfortunately optimizations are hard to get right and even the tiny example is **wrong**: -.. code-block:: nimrod +.. code-block:: nim template optMul{`*`(a, 2)}(a: int): int = a+a proc f(): int = @@ -4506,7 +4506,7 @@ is **wrong**: We cannot duplicate 'a' if it denotes an expression that has a side effect! Fortunately Nim supports side effect analysis: -.. code-block:: nimrod +.. code-block:: nim template optMul{`*`(a, 2)}(a: int{noSideEffect}): int = a+a proc f(): int = @@ -4519,12 +4519,12 @@ So what about ``2 * a``? We should tell the compiler ``*`` is commutative. We cannot really do that however as the following code only swaps arguments blindly: -.. code-block:: nimrod +.. code-block:: nim template mulIsCommutative{`*`(a, b)}(a, b: int): int = b*a What optimizers really need to do is a *canonicalization*: -.. code-block:: nimrod +.. code-block:: nim template canonMul{`*`(a, b)}(a: int{lit}, b: int): int = b*a The ``int{lit}`` parameter pattern matches against an expression of @@ -4581,7 +4581,7 @@ The ``alias`` and ``noalias`` predicates refer not only to the matching AST, but also to every other bound parameter; syntactially they need to occur after the ordinary AST predicates: -.. code-block:: nimrod +.. code-block:: nim template ex{a = b + c}(a: int{noalias}, b, c: int) = # this transformation is only valid if 'b' and 'c' do not alias 'a': a = b @@ -4600,7 +4600,7 @@ The ``|`` operator The ``|`` operator if used as infix operator creates an ordered choice: -.. code-block:: nimrod +.. code-block:: nim template t{0|1}(): expr = 3 let a = 1 # outputs 3: @@ -4609,7 +4609,7 @@ The ``|`` operator if used as infix operator creates an ordered choice: The matching is performed after the compiler performed some optimizations like constant folding, so the following does not work: -.. code-block:: nimrod +.. code-block:: nim template t{0|1}(): expr = 3 # outputs 1: echo 1 @@ -4626,7 +4626,7 @@ The ``{}`` operator A pattern expression can be bound to a pattern parameter via the ``expr{param}`` notation: -.. code-block:: nimrod +.. code-block:: nim template t{(0|1|2){x}}(x: expr): expr = x+1 let a = 1 # outputs 2: @@ -4638,7 +4638,7 @@ The ``~`` operator The ``~`` operator is the **not** operator in patterns: -.. code-block:: nimrod +.. code-block:: nim template t{x = (~x){y} and (~x){z}}(x, y, z: bool): stmt = x = y if x: x = z @@ -4657,7 +4657,7 @@ The ``*`` operator The ``*`` operator can *flatten* a nested binary expression like ``a & b & c`` to ``&(a, b, c)``: -.. code-block:: nimrod +.. code-block:: nim var calls = 0 @@ -4681,7 +4681,7 @@ is passed to ``optConc`` in ``a`` as a special list (of kind ``nkArgList``) which is flattened into a call expression; thus the invocation of ``optConc`` produces: -.. code-block:: nimrod +.. code-block:: nim `&&`("my", space & "awe", "some ", "concat") @@ -4691,7 +4691,7 @@ The ``**`` operator The ``**`` is much like the ``*`` operator, except that it gathers not only all the arguments, but also the matched operators in reverse polish notation: -.. code-block:: nimrod +.. code-block:: nim import macros type @@ -4735,7 +4735,7 @@ Parameters in a pattern are type checked in the matching process. If a parameter is of the type ``varargs`` it is treated specially and it can match 0 or more arguments in the AST to be matched against: -.. code-block:: nimrod +.. code-block:: nim template optWrite{ write(f, x) ((write|writeln){w})(f, y) @@ -4750,7 +4750,7 @@ Example: Partial evaluation The following example shows how some simple partial evaluation can be implemented with term rewriting: -.. code-block:: nimrod +.. code-block:: nim proc p(x, y: int; cond: bool): int = result = if cond: x + y else: x - y @@ -4763,7 +4763,7 @@ Example: Hoisting The following example shows how some form of hoisting can be implemented: -.. code-block:: nimrod +.. code-block:: nim import pegs template optPeg{peg(pattern)}(pattern: string{lit}): TPeg = @@ -4786,7 +4786,7 @@ AST based overloading Parameter constraints can also be used for ordinary routine parameters; these constraints affect ordinary overloading resolution then: -.. code-block:: nimrod +.. code-block:: nim proc optLit(a: string{lit|`const`}) = echo "string literal" proc optLit(a: string) = @@ -4812,7 +4812,7 @@ Move optimization The ``call`` constraint is particularly useful to implement a move optimization for types that have copying semantics: -.. code-block:: nimrod +.. code-block:: nim proc `[]=`*(t: var TTable, key: string, val: string) = ## puts a (key, value)-pair into `t`. The semantics of string require ## a copy here: @@ -4852,7 +4852,7 @@ The algorithm for compiling modules is: This is best illustrated by an example: -.. code-block:: nimrod +.. code-block:: nim # Module A type T1* = int # Module A exports the type ``T1`` @@ -4864,7 +4864,7 @@ This is best illustrated by an example: main() -.. code-block:: nimrod +.. code-block:: nim # Module B import A # A is not parsed here! Only the already known symbols # of A are imported. @@ -4881,7 +4881,7 @@ Import statement After the ``import`` statement a list of module names can follow or a single module name followed by an ``except`` to prevent some symbols to be imported: -.. code-block:: nimrod +.. code-block:: nim import strutils except `%` # doesn't work then: @@ -4893,7 +4893,7 @@ Module names in imports A module alias can be introduced via the ``as`` keyword: -.. code-block:: nimrod +.. code-block:: nim import strutils as su, sequtils as qu echo su.format("$1", "lalelu") @@ -4902,19 +4902,19 @@ The original module name is then not accessible. The notations ``path/to/module`` or ``path.to.module`` or ``"path/to/module"`` can be used to refer to a module in subdirectories: -.. code-block:: nimrod +.. code-block:: nim import lib.pure.strutils, lib/pure/os, "lib/pure/times" Note that the module name is still ``strutils`` and not ``lib.pure.strutils`` and so one **cannot** do: -.. code-block:: nimrod +.. code-block:: nim import lib.pure.strutils echo lib.pure.strutils Likewise the following does not make sense as the name is ``strutils`` already: -.. code-block:: nimrod +.. code-block:: nim import lib.pure.strutils as strutils @@ -4925,7 +4925,7 @@ After the ``from`` statement a module name follows followed by an ``import`` to list the symbols one likes to use without explict full qualification: -.. code-block:: nimrod +.. code-block:: nim from strutils import `%` echo "$1" % "abc" @@ -4943,11 +4943,11 @@ Export statement An ``export`` statement can be used for symbol fowarding so that client modules don't need to import a module's dependencies: -.. code-block:: nimrod +.. code-block:: nim # module B type TMyObject* = object -.. code-block:: nimrod +.. code-block:: nim # module A import B export B.TMyObject @@ -4955,7 +4955,7 @@ modules don't need to import a module's dependencies: proc `$`*(x: TMyObject): string = "my object" -.. code-block:: nimrod +.. code-block:: nim # module C import A @@ -5002,15 +5002,15 @@ If a module imports an identifier by two different modules, each occurrence of the identifier has to be qualified, unless it is an overloaded procedure or iterator in which case the overloading resolution takes place: -.. code-block:: nimrod +.. code-block:: nim # Module A var x*: string -.. code-block:: nimrod +.. code-block:: nim # Module B var x*: int -.. code-block:: nimrod +.. code-block:: nim # Module C import A, B write(stdout, x) # error: x is ambiguous @@ -5056,7 +5056,7 @@ routines marked as ``noSideEffect``. **Future directions**: ``func`` may become a keyword and syntactic sugar for a proc with no side effects: -.. code-block:: nimrod +.. code-block:: nim func `+` (x, y: int): int @@ -5097,7 +5097,7 @@ The ``acyclic`` pragma can be used for object types to mark them as acyclic even though they seem to be cyclic. This is an **optimization** for the garbage collector to not consider objects of this type as part of a cycle: -.. code-block:: nimrod +.. code-block:: nim type PNode = ref TNode TNode {.acyclic, final.} = object @@ -5114,7 +5114,7 @@ memory, but nothing worse happens. **Future directions**: The ``acyclic`` pragma may become a property of a ``ref`` type: -.. code-block:: nimrod +.. code-block:: nim type PNode = acyclic ref TNode TNode = object @@ -5137,7 +5137,7 @@ because the semantics of Nim require deep copying of sequences and strings. This can be expensive, especially if sequences are used to build a tree structure: -.. code-block:: nimrod +.. code-block:: nim type TNodeKind = enum nkLeaf, nkInner TNode {.final, shallow.} = object @@ -5177,7 +5177,7 @@ annotate a symbol (like an iterator or proc). The *usage* of the symbol then triggers a compile-time error. This is especially useful to rule out that some operation is valid due to overloading and type conversions: -.. code-block:: nimrod +.. code-block:: nim ## check that underlying int values are compared and not the pointers: proc `==`(x, y: ptr int): bool {.error.} @@ -5188,7 +5188,7 @@ The ``fatal`` pragma is used to make the compiler output an error message with the given content. In contrast to the ``error`` pragma, compilation is guaranteed to be aborted by this pragma. Example: -.. code-block:: nimrod +.. code-block:: nim when not defined(objc): {.fatal: "Compile this program with the objc command!".} @@ -5207,7 +5207,7 @@ line pragma The ``line`` pragma can be used to affect line information of the annotated statement as seen in stack backtraces: -.. code-block:: nimrod +.. code-block:: nim template myassert*(cond: expr, msg = "") = if not cond: @@ -5226,7 +5226,7 @@ The ``linearScanEnd`` pragma can be used to tell the compiler how to compile a Nim `case`:idx: statement. Syntactically it has to be used as a statement: -.. code-block:: nimrod +.. code-block:: nim case myInt of 0: echo "most common case" @@ -5254,7 +5254,7 @@ The ``computedGoto`` pragma can be used to tell the compiler how to compile a Nim `case`:idx: in a ``while true`` statement. Syntactically it has to be used as a statement inside the loop: -.. code-block:: nimrod +.. code-block:: nim type MyEnum = enum @@ -5298,7 +5298,7 @@ unroll pragma The ``unroll`` pragma can be used to tell the compiler that it should unroll a `for`:idx: or `while`:idx: loop for runtime efficiency: -.. code-block:: nimrod +.. code-block:: nim proc searchChar(s: string, c: char): int = for i in 0 .. s.high: {.unroll: 4.} @@ -5354,7 +5354,7 @@ callconv cdecl|... Specifies the default calling convention for Example: -.. code-block:: nimrod +.. code-block:: nim {.checks: off, optimization: speed.} # compile without runtime checks and optimize for speed @@ -5364,7 +5364,7 @@ push and pop pragmas The `push/pop`:idx: pragmas are very similar to the option directive, but are used to override the settings temporarily. Example: -.. code-block:: nimrod +.. code-block:: nim {.push checks: off.} # compile this section without runtime checks as it is # speed critical @@ -5389,7 +5389,7 @@ The ``global`` pragma can be applied to a variable within a proc to instruct the compiler to store it in a global location and initialize it once at program startup. -.. code-block:: nimrod +.. code-block:: nim proc isHexNumber(s: string): bool = var pattern {.global.} = re"[0-9a-fA-F]+" result = s.match(pattern) @@ -5413,7 +5413,7 @@ no matter if it is globally active or not. Example: -.. code-block:: nimrod +.. code-block:: nim {.deadCodeElim: on.} @@ -5448,11 +5448,11 @@ Example: Please note that if a callable symbol is never used in this scenario, its body will never be compiled. This is the default behavior leading to best compilation times, but if exhaustive compilation of all definitions is required, using - ``nimrod check`` provides this option as well. + ``nim check`` provides this option as well. Example: - .. code-block:: nimrod + .. code-block:: nim {.noforward: on.} @@ -5475,7 +5475,7 @@ They cannot be imported from a module. Example: -.. code-block:: nimrod +.. code-block:: nim when appType == "lib": {.pragma: rtl, exportc, dynlib, cdecl.} else: @@ -5522,9 +5522,9 @@ spelled*: Note that this pragma is somewhat of a misnomer: Other backends will provide the same feature under the same name. Also, if one is interfacing with C++ -the `ImportCpp pragma `_ and +the `ImportCpp pragma `_ and interfacing with Objective-C the `ImportObjC pragma -`_ can be used. +`_ can be used. Exportc pragma @@ -5559,7 +5559,7 @@ Bycopy pragma The ``bycopy`` pragma can be applied to an object or tuple type and instructs the compiler to pass the type by value to procs: -.. code-block:: nimrod +.. code-block:: nim type TVector {.bycopy, pure.} = object x, y, z: float @@ -5614,7 +5614,7 @@ meaning its bounds are not checked. This is often useful when one wishes to implement his own flexibly sized arrays. Additionally an unchecked array is translated into a C array of undetermined size: -.. code-block:: nimrod +.. code-block:: nim type ArrayPart{.unchecked.} = array[0..0, int] MySeq = object @@ -5658,7 +5658,7 @@ packages need to be installed. The ``dynlib`` import mechanism supports a versioning scheme: -.. code-block:: nimrod +.. code-block:: nim proc Tcl_Eval(interp: pTcl_Interp, script: cstring): int {.cdecl, importc, dynlib: "libtcl(|8.5|8.4|8.3).so.(1|0)".} @@ -5676,7 +5676,7 @@ At runtime the dynamic library is searched for (in this order):: The ``dynlib`` pragma supports not only constant strings as argument but also string expressions in general: -.. code-block:: nimrod +.. code-block:: nim import os proc getDllName: string = @@ -5778,7 +5778,7 @@ Threadvar pragma A global variable can be marked with the ``threadvar`` pragma; it is a `thread-local`:idx: variable then: -.. code-block:: nimrod +.. code-block:: nim var checkpoints* {.threadvar.}: seq[string] Due to implementation restrictions thread local variables cannot be @@ -5801,7 +5801,7 @@ Nim has a builtin thread pool that can be used for CPU intensive tasks. For IO intensive tasks the upcoming ``async`` and ``await`` features should be used instead. `spawn`:idx: is used to pass a task to the thread pool: -.. code-block:: nimrod +.. code-block:: nim proc processLine(line: string) = # do some heavy lifting here: discard @@ -5836,7 +5836,7 @@ If the taint mode is turned on (via the ``--taintMode:on`` command line option) it is a distinct string type which helps to detect input validation errors: -.. code-block:: nimrod +.. code-block:: nim echo "your name: " var name: TaintedString = stdin.readline # it is safe here to output the name without any input validation, so @@ -5845,4 +5845,3 @@ validation errors: If the taint mode is turned off, ``TaintedString`` is simply an alias for ``string``. - diff --git a/doc/pegdocs.txt b/doc/pegdocs.txt index eb7f4562f..e2f3cdf4b 100644 --- a/doc/pegdocs.txt +++ b/doc/pegdocs.txt @@ -180,7 +180,7 @@ So it is not necessary to write ``peg" 'abc' "`` in the above example. Examples -------- -Check if `s` matches Nimrod's "while" keyword: +Check if `s` matches Nim's "while" keyword: .. code-block:: nimrod s =~ peg" y'while'" @@ -212,7 +212,7 @@ example ``*`` should not be greedy, so ``\[.*?\]`` should be used instead. PEG construction ---------------- -There are two ways to construct a PEG in Nimrod code: +There are two ways to construct a PEG in Nim code: (1) Parsing a string into an AST which consists of `TPeg` nodes with the `peg` proc. (2) Constructing the AST directly with proc calls. This method does not diff --git a/doc/tut1.txt b/doc/tut1.txt index ee642ce17..73d90b008 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -1,9 +1,9 @@ -======================== -Nimrod Tutorial (Part I) -======================== +===================== +Nim Tutorial (Part I) +===================== :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -16,7 +16,7 @@ Introduction

-This document is a tutorial for the programming language *Nimrod*. +This document is a tutorial for the programming language *Nim*. This tutorial assumes that you are familiar with basic programming concepts like variables, types or statements but is kept very basic. The `manual `_ contains many more examples of the advanced language features. @@ -28,7 +28,7 @@ The first program We start the tour with a modified "hello world" program: -.. code-block:: Nimrod +.. code-block:: Nim # This is a comment echo("What's your name? ") var name: string = readLine(stdin) @@ -37,30 +37,30 @@ We start the tour with a modified "hello world" program: Save this code to the file "greetings.nim". Now compile and run it:: - nimrod compile --run greetings.nim + nim compile --run greetings.nim -With the ``--run`` `switch `_ Nimrod +With the ``--run`` `switch `_ Nim executes the file automatically after compilation. You can give your program command line arguments by appending them after the filename:: - nimrod compile --run greetings.nim arg1 arg2 + nim compile --run greetings.nim arg1 arg2 Commonly used commands and switches have abbreviations, so you can also use:: - nimrod c -r greetings.nim + nim c -r greetings.nim To compile a release version use:: - nimrod c -d:release greetings.nim + nim c -d:release greetings.nim -By default the Nimrod compiler generates a large amount of runtime checks +By default the Nim compiler generates a large amount of runtime checks aiming for your debugging pleasure. With ``-d:release`` these checks are `turned off and optimizations are turned on -`_. +`_. Though it should be pretty obvious what the program does, I will explain the syntax: statements which are not indented are executed when the program -starts. Indentation is Nimrod's way of grouping statements. Indentation is +starts. Indentation is Nim's way of grouping statements. Indentation is done with spaces only, tabulators are not allowed. String literals are enclosed in double quotes. The ``var`` statement declares @@ -70,11 +70,11 @@ compiler knows that `readLine `_ returns a string, you can leave out the type in the declaration (this is called `local type inference`:idx:). So this will work too: -.. code-block:: Nimrod +.. code-block:: Nim var name = readLine(stdin) Note that this is basically the only form of type inference that exists in -Nimrod: it is a good compromise between brevity and readability. +Nim: it is a good compromise between brevity and readability. The "hello world" program contains several identifiers that are already known to the compiler: ``echo``, `readLine `_, etc. @@ -85,8 +85,8 @@ imported by any other module. Lexical elements ================ -Let us look at Nimrod's lexical elements in more detail: like other -programming languages Nimrod consists of (string) literals, identifiers, +Let us look at Nim's lexical elements in more detail: like other +programming languages Nim consists of (string) literals, identifiers, keywords, comments, operators, and other punctuation marks. @@ -97,7 +97,7 @@ String literals are enclosed in double quotes; character literals in single quotes. Special characters are escaped with ``\``: ``\n`` means newline, ``\t`` means tabulator, etc. There are also *raw* string literals: -.. code-block:: Nimrod +.. code-block:: Nim r"C:\program files\nim" In raw literals the backslash is not an escape character. @@ -115,7 +115,7 @@ Comments start anywhere outside a string or character literal with the hash character ``#``. Documentation comments start with ``##``. Multiline comments need to be aligned at the same column: -.. code-block:: nimrod +.. code-block:: nim i = 0 # This is a single comment over multiple lines belonging to the # assignment statement. @@ -128,7 +128,7 @@ comments need to be aligned at the same column: The alignment requirement does not hold if the preceding comment piece ends in a backslash: -.. code-block:: nimrod +.. code-block:: nim type TMyObject {.final, pure, acyclic.} = object # comment continues: \ # we have lots of space here to comment 'TMyObject'. @@ -151,15 +151,15 @@ the syntax, watch their indentation: **Note**: To comment out a large piece of code, it is often better to use a ``when false:`` statement. -.. code-block:: nimrod +.. code-block:: nim when false: brokenCode() Another option is to use the `discard statement`_ together with *long string literals* to create block comments: -.. code-block:: nimrod - discard """ You can have any Nimrod code text commented +.. code-block:: nim + discard """ You can have any Nim code text commented out inside this with no indentation restrictions. yes("May I ask a pointless question?") """ @@ -204,7 +204,7 @@ to a storage location: ``=`` is the *assignment operator*. The assignment operator cannot be overloaded, overwritten or forbidden, but this might change in a future version -of Nimrod. You can declare multiple variables with a single assignment +of Nim. You can declare multiple variables with a single assignment statement and all the variables will have the same value: .. code-block:: @@ -229,7 +229,7 @@ Constants are symbols which are bound to a value. The constant's value cannot change. The compiler must be able to evaluate the expression in a constant declaration at compile time: -.. code-block:: nimrod +.. code-block:: nim const x = "abc" # the constant x contains the string "abc" Indentation can be used after the ``const`` keyword to list a whole section of @@ -277,7 +277,7 @@ If statement The if statement is one way to branch the control flow: -.. code-block:: nimrod +.. code-block:: nim let name = readLine(stdin) if name == "": echo("Poor soul, you lost your name?") @@ -298,7 +298,7 @@ Case statement Another way to branch is provided by the case statement. A case statement is a multi-branch: -.. code-block:: nimrod +.. code-block:: nim let name = readLine(stdin) case name of "": @@ -317,7 +317,7 @@ The case statement can deal with integers, other ordinal types and strings. (What an ordinal type is will be explained soon.) For integers or other ordinal types value ranges are also possible: -.. code-block:: nimrod +.. code-block:: nim # this statement will be explained later: from strutils import parseInt @@ -333,7 +333,7 @@ every value that ``n`` may contain, but the code only handles the values (though it is possible thanks to the range notation), we fix this by telling the compiler that for every other value nothing should be done: -.. code-block:: nimrod +.. code-block:: nim ... case n of 0..2, 4..7: echo("The number is in the set: {0, 1, 2, 4, 5, 6, 7}") @@ -355,7 +355,7 @@ While statement The while statement is a simple looping construct: -.. code-block:: nimrod +.. code-block:: nim echo("What's your name? ") var name = readLine(stdin) @@ -375,7 +375,7 @@ The ``for`` statement is a construct to loop over any element an *iterator* provides. The example uses the built-in `countup `_ iterator: -.. code-block:: nimrod +.. code-block:: nim echo("Counting to ten: ") for i in countup(1, 10): echo($i) @@ -387,7 +387,7 @@ other types into a string. The variable ``i`` is implicitly declared by the `_ returns. ``i`` runs through the values 1, 2, .., 10. Each value is ``echo``-ed. This code does the same: -.. code-block:: nimrod +.. code-block:: nim echo("Counting to 10: ") var i = 1 while i <= 10: @@ -397,16 +397,16 @@ Each value is ``echo``-ed. This code does the same: Counting down can be achieved as easily (but is less often needed): -.. code-block:: nimrod +.. code-block:: nim echo("Counting down from 10 to 1: ") for i in countdown(10, 1): echo($i) # --> Outputs 10 9 8 7 6 5 4 3 2 1 on different lines -Since counting up occurs so often in programs, Nimrod also has a `.. +Since counting up occurs so often in programs, Nim also has a `.. `_ iterator that does the same: -.. code-block:: nimrod +.. code-block:: nim for i in 1..10: ... @@ -417,7 +417,7 @@ Control flow statements have a feature not covered yet: they open a new scope. This means that in the following example, ``x`` is not accessible outside the loop: -.. code-block:: nimrod +.. code-block:: nim while false: var x = "hi" echo(x) # does not work @@ -426,7 +426,7 @@ A while (for) statement introduces an implicit block. Identifiers are only visible within the block they have been declared. The ``block`` statement can be used to open a new block explicitly: -.. code-block:: nimrod +.. code-block:: nim block myblock: var x = "hi" echo(x) # does not work either @@ -440,7 +440,7 @@ A block can be left prematurely with a ``break`` statement. The break statement can leave a ``while``, ``for``, or a ``block`` statement. It leaves the innermost construct, unless a label of a block is given: -.. code-block:: nimrod +.. code-block:: nim block myblock: echo("entering block") while true: @@ -461,7 +461,7 @@ Continue statement Like in many other programming languages, a ``continue`` statement starts the next iteration immediately: -.. code-block:: nimrod +.. code-block:: nim while true: let x = readLine(stdin) if x == "": continue @@ -473,7 +473,7 @@ When statement Example: -.. code-block:: nimrod +.. code-block:: nim when system.hostOS == "windows": echo("running on Windows!") @@ -504,17 +504,17 @@ possible. Statements and indentation ========================== -Now that we covered the basic control flow statements, let's return to Nimrod +Now that we covered the basic control flow statements, let's return to Nim indentation rules. -In Nimrod there is a distinction between *simple statements* and *complex +In Nim there is a distinction between *simple statements* and *complex statements*. *Simple statements* cannot contain other statements: Assignment, procedure calls or the ``return`` statement belong to the simple statements. *Complex statements* like ``if``, ``when``, ``for``, ``while`` can contain other statements. To avoid ambiguities, complex statements always have to be indented, but single simple statements do not: -.. code-block:: nimrod +.. code-block:: nim # no indentation needed for single assignment statement: if x: x = false @@ -535,7 +535,7 @@ to be indented, but single simple statements do not: condition in an if statement is an example for an expression. Expressions can contain indentation at certain places for better readability: -.. code-block:: nimrod +.. code-block:: nim if thisIsaLongCondition() and thisIsAnotherLongCondition(1, @@ -548,7 +548,7 @@ an open parenthesis and after commas. With parenthesis and semicolons ``(;)`` you can use statements where only an expression is allowed: -.. code-block:: nimrod +.. code-block:: nim # computes fac(4) at compile time: const fac4 = (var x = 1; for i in 1..4: x *= i; x) @@ -558,10 +558,10 @@ Procedures To define new commands like `echo `_ and `readLine `_ in the examples, the concept of a `procedure` -is needed. (Some languages call them *methods* or *functions*.) In Nimrod new +is needed. (Some languages call them *methods* or *functions*.) In Nim new procedures are defined with the ``proc`` keyword: -.. code-block:: nimrod +.. code-block:: nim proc yes(question: string): bool = echo(question, " (y/n)") while true: @@ -597,7 +597,7 @@ shorthand for ``return result``. The ``result`` value is always returned automatically at the end a procedure if there is no ``return`` statement at the exit. -.. code-block:: nimrod +.. code-block:: nim proc sumTillNegative(x: varargs[int]): int = for i in x: if i < 0: @@ -624,7 +624,7 @@ most efficient way. If a mutable variable is needed inside the procedure, it has to be declared with ``var`` in the procedure body. Shadowing the parameter name is possible, and actually an idiom: -.. code-block:: nimrod +.. code-block:: nim proc printSeq(s: seq, nprinted: int = -1) = var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len) for i in 0 .. `_ operator in -Nimrod.) The compiler chooses the most appropriate proc for the ``toString`` +Nim.) The compiler chooses the most appropriate proc for the ``toString`` calls. How this overloading resolution algorithm works exactly is not discussed here (it will be specified in the manual soon). However, it does not lead to nasty surprises and is based on a quite simple unification @@ -744,13 +744,13 @@ algorithm. Ambiguous calls are reported as errors. Operators --------- -The Nimrod library makes heavy use of overloading - one reason for this is that +The Nim library makes heavy use of overloading - one reason for this is that each operator like ``+`` is a just an overloaded proc. The parser lets you use operators in `infix notation` (``a + b``) or `prefix notation` (``+ a``). An infix operator always receives two arguments, a prefix operator always one. Postfix operators are not possible, because this would be ambiguous: does ``a @ @ b`` mean ``(a) @ (@b)`` or ``(a@) @ (b)``? It always means -``(a) @ (@b)``, because there are no postfix operators in Nimrod. +``(a) @ (@b)``, because there are no postfix operators in Nim. Apart from a few built-in keyword operators such as ``and``, ``or``, ``not``, operators always consist of these characters: @@ -764,7 +764,7 @@ can be found in the manual. To define a new operator enclose the operator in backticks "``": -.. code-block:: nimrod +.. code-block:: nim proc `$` (x: myDataType): string = ... # now the $ operator also works with myDataType, overloading resolution # ensures that $ works for built-in types just like before @@ -772,7 +772,7 @@ To define a new operator enclose the operator in backticks "``": The "``" notation can also be used to call an operator just like any other procedure: -.. code-block:: nimrod +.. code-block:: nim if `==`( `+`(3, 4), 7): echo("True") @@ -783,7 +783,7 @@ Every variable, procedure, etc. needs to be declared before it can be used. (The reason for this is compilation efficiency.) However, this cannot be done for mutually recursive procedures: -.. code-block:: nimrod +.. code-block:: nim # forward declaration: proc even(n: int): bool @@ -810,7 +810,7 @@ Iterators Let's return to the boring counting example: -.. code-block:: nimrod +.. code-block:: nim echo("Counting to ten: ") for i in countup(1, 10): echo($i) @@ -818,7 +818,7 @@ Let's return to the boring counting example: Can a `countup `_ proc be written that supports this loop? Lets try: -.. code-block:: nimrod +.. code-block:: nim proc countup(a, b: int): int = var res = a while res <= b: @@ -831,7 +831,7 @@ finished. This *return and continue* is called a `yield` statement. Now the only thing left to do is to replace the ``proc`` keyword by ``iterator`` and there it is - our first iterator: -.. code-block:: nimrod +.. code-block:: nim iterator countup(a, b: int): int = var res = a while res <= b: @@ -868,7 +868,7 @@ that are available for them in detail. Booleans -------- -The boolean type is named ``bool`` in Nimrod and consists of the two +The boolean type is named ``bool`` in Nim and consists of the two pre-defined values ``true`` and ``false``. Conditions in while, if, elif, when statements need to be of type bool. @@ -876,7 +876,7 @@ The operators ``not, and, or, xor, <, <=, >, >=, !=, ==`` are defined for the bool type. The ``and`` and ``or`` operators perform short-cut evaluation. Example: -.. code-block:: nimrod +.. code-block:: nim while p != nil and p.name != "xyz": # p.name is not evaluated if p == nil @@ -885,7 +885,7 @@ evaluation. Example: Characters ---------- -The `character type` is named ``char`` in Nimrod. Its size is one byte. +The `character type` is named ``char`` in Nim. Its size is one byte. Thus it cannot represent an UTF-8 character, but a part of it. The reason for this is efficiency: for the overwhelming majority of use-cases, the resulting programs will still handle UTF-8 properly as UTF-8 was specially @@ -900,13 +900,13 @@ Converting from an integer to a ``char`` is done with the ``chr`` proc. Strings ------- -String variables in Nimrod are **mutable**, so appending to a string -is quite efficient. Strings in Nimrod are both zero-terminated and have a +String variables in Nim are **mutable**, so appending to a string +is quite efficient. Strings in Nim are both zero-terminated and have a length field. One can retrieve a string's length with the builtin ``len`` procedure; the length never counts the terminating zero. Accessing the terminating zero is no error and often leads to simpler code: -.. code-block:: nimrod +.. code-block:: nim if s[i] == 'a' and s[i+1] == 'b': # no need to check whether ``i < len(s)``! ... @@ -929,14 +929,14 @@ object on the heap, so there is a trade-off to be made here. Integers -------- -Nimrod has these integer types built-in: +Nim has these integer types built-in: ``int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64``. The default integer type is ``int``. Integer literals can have a *type suffix* to mark them to be of another integer type: -.. code-block:: nimrod +.. code-block:: nim let x = 0 # x is of type ``int`` y = 0'i8 # y is of type ``int8`` @@ -964,7 +964,7 @@ cannot be detected at compile time). Floats ------ -Nimrod has these floating point types built-in: ``float float32 float64``. +Nim has these floating point types built-in: ``float float32 float64``. The default float type is ``float``. In the current implementation, ``float`` is always 64 bit wide. @@ -972,7 +972,7 @@ The default float type is ``float``. In the current implementation, Float literals can have a *type suffix* to mark them to be of another float type: -.. code-block:: nimrod +.. code-block:: nim var x = 0.0 # x is of type ``float`` y = 0.0'f32 # y is of type ``float32`` @@ -1001,11 +1001,11 @@ having to write its ``$`` operator. You can use then the `repr graphs with cycles. The following example shows that even for basic types there is a difference between the ``$`` and ``repr`` outputs: -.. code-block:: nimrod +.. code-block:: nim var myBool = true myCharacter = 'n' - myString = "nimrod" + myString = "nim" myInteger = 42 myFloat = 3.14 echo($myBool, ":", repr(myBool)) @@ -1013,7 +1013,7 @@ there is a difference between the ``$`` and ``repr`` outputs: echo($myCharacter, ":", repr(myCharacter)) # --> n:'n' echo($myString, ":", repr(myString)) - # --> nimrod:0x10fa8c050"nimrod" + # --> nim:0x10fa8c050"nim" echo($myInteger, ":", repr(myInteger)) # --> 42:42 echo($myFloat, ":", repr(myFloat)) @@ -1023,9 +1023,9 @@ there is a difference between the ``$`` and ``repr`` outputs: Advanced types ============== -In Nimrod new types can be defined within a ``type`` statement: +In Nim new types can be defined within a ``type`` statement: -.. code-block:: nimrod +.. code-block:: nim type biggestInt = int64 # biggest integer type that is available biggestFloat = float64 # biggest float type that is available @@ -1041,7 +1041,7 @@ limited set. This set consists of ordered symbols. Each symbol is mapped to an integer value internally. The first symbol is represented at runtime by 0, the second by 1 and so on. Example: -.. code-block:: nimrod +.. code-block:: nim type TDirection = enum @@ -1050,7 +1050,7 @@ at runtime by 0, the second by 1 and so on. Example: var x = south # `x` is of type `TDirection`; its value is `south` echo($x) # writes "south" to `stdout` -(To prefix a new type with the letter ``T`` is a convention in Nimrod.) +(To prefix a new type with the letter ``T`` is a convention in Nim.) All comparison operators can be used with enumeration types. An enumeration's symbol can be qualified to avoid ambiguities: @@ -1066,7 +1066,7 @@ explicitly given is assigned the value of the previous symbol + 1. An explicit ordered enum can have *holes*: -.. code-block:: nimrod +.. code-block:: nim type TMyEnum = enum a = 2, b = 4, c = 89 @@ -1104,7 +1104,7 @@ Subranges A subrange type is a range of values from an integer or enumeration type (the base type). Example: -.. code-block:: nimrod +.. code-block:: nim type TSubrange = range[0..5] @@ -1119,7 +1119,7 @@ type as ``range[0..high(int)]`` (`high `_ returns the maximal value). Other programming languages mandate the usage of unsigned integers for natural numbers. This is often **wrong**: you don't want unsigned arithmetic (which wraps around) just because the numbers cannot be negative. -Nimrod's ``Natural`` type helps to avoid this common programming error. +Nim's ``Natural`` type helps to avoid this common programming error. Sets @@ -1134,7 +1134,7 @@ the array has the same type. The array's index type can be any ordinal type. Arrays can be constructed via ``[]``: -.. code-block:: nimrod +.. code-block:: nim type TIntArray = array[0..5, int] # an array that is indexed with 0..5 @@ -1149,14 +1149,14 @@ Array access is always bounds checked (at compile-time or at runtime). These checks can be disabled via pragmas or invoking the compiler with the ``--bound_checks:off`` command line switch. -Arrays are value types, like any other Nimrod type. The assignment operator +Arrays are value types, like any other Nim type. The assignment operator copies the whole array contents. The built-in `len `_ proc returns the array's length. `low(a) `_ returns the lowest valid index for the array `a` and `high(a) `_ the highest valid index. -.. code-block:: nimrod +.. code-block:: nim type TDirection = enum north, east, south, west @@ -1175,13 +1175,13 @@ array `a` and `high(a) `_ the highest valid index. The syntax for nested arrays (multidimensional) in other languages is a matter of appending more brackets because usually each dimension is restricted to the -same index type as the others. In nimrod you can have different dimensions with +same index type as the others. In Nim you can have different dimensions with different index types, so the nesting syntax is slightly different. Building on the previous example where a level is defined as an array of enums indexed by yet another enum, we can add the following lines to add a light tower type subdivided in height levels accessed through their integer index: -.. code-block:: nimrod +.. code-block:: nim type TLightTower = array[1..10, TLevelSetting] var @@ -1200,14 +1200,14 @@ length. Another way of defining the ``TLightTower`` to show better its nested nature would be to omit the previous definition of the ``TLevelSetting`` type and instead write it embedded directly as the type of the first dimension: -.. code-block:: nimrod +.. code-block:: nim type TLightTower = array[1..10, array[north..west, TBlinkLights]] It is quite frequent to have arrays start at zero, so there's a shortcut syntax to specify a range from zero to the specified index minus one: -.. code-block:: nimrod +.. code-block:: nim type TIntArray = array[0..5, int] # an array that is indexed with 0..5 TQuickArray = array[6, int] # an array that is indexed with 0..5 @@ -1239,7 +1239,7 @@ A sequence may be passed to an openarray parameter. Example: -.. code-block:: nimrod +.. code-block:: nim var x: seq[int] # a sequence of integers @@ -1261,7 +1261,7 @@ value. Here the ``for`` statement is looping over the results from the `pairs() `_ iterator from the `system `_ module. Examples: -.. code-block:: nimrod +.. code-block:: nim for i in @[3, 4, 5]: echo($i) # --> 3 @@ -1299,7 +1299,7 @@ also a means to implement passing a variable number of arguments to a procedure. The compiler converts the list of arguments to an array automatically: -.. code-block:: nimrod +.. code-block:: nim proc myWriteln(f: TFile, a: varargs[string]) = for s in items(a): write(f, s) @@ -1313,7 +1313,7 @@ This transformation is only done if the varargs parameter is the last parameter in the procedure header. It is also possible to perform type conversions in this context: -.. code-block:: nimrod +.. code-block:: nim proc myWriteln(f: TFile, a: varargs[string, `$`]) = for s in items(a): write(f, s) @@ -1336,10 +1336,10 @@ context. A slice is just an object of type TSlice which contains two bounds, `a` and `b`. By itself a slice is not very useful, but other collection types define operators which accept TSlice objects to define ranges. -.. code-block:: nimrod +.. code-block:: nim var - a = "Nimrod is a progamming language" + a = "Nim is a progamming language" b = "Slices are useless." echo a[10..15] # --> 'a prog' @@ -1366,7 +1366,7 @@ The assignment operator for tuples copies each component. The notation ``t[i]`` to access the ``i``'th field. Here ``i`` needs to be a constant integer. -.. code-block:: nimrod +.. code-block:: nim type TPerson = tuple[name: string, age: int] # type representing a person: @@ -1411,19 +1411,19 @@ use parenthesis around the values you want to assign the unpacking to, otherwise you will be assigning the same value to all the individual variables! Example: -.. code-block:: nimrod +.. code-block:: nim import os let - path = "usr/local/nimrodc.html" + path = "usr/local/nimc.html" (dir, name, ext) = splitFile(path) baddir, badname, badext = splitFile(path) echo dir # outputs `usr/local` - echo name # outputs `nimrodc` + echo name # outputs `nimc` echo ext # outputs `.html` # All the following output the same line: - # `(dir: usr/local, name: nimrodc, ext: .html)` + # `(dir: usr/local, name: nimc, ext: .html)` echo baddir echo badname echo badext @@ -1431,12 +1431,12 @@ variables! Example: Tuple unpacking **only** works in ``var`` or ``let`` blocks. The following code won't compile: -.. code-block:: nimrod +.. code-block:: nim import os var - path = "usr/local/nimrodc.html" + path = "usr/local/nimc.html" dir, name, ext = "" (dir, name, ext) = splitFile(path) @@ -1449,7 +1449,7 @@ References (similar to pointers in other programming languages) are a way to introduce many-to-one relationships. This means different references can point to and modify the same location in memory. -Nimrod distinguishes between `traced`:idx: and `untraced`:idx: references. +Nim distinguishes between `traced`:idx: and `untraced`:idx: references. Untraced references are also called *pointers*. Traced references point to objects of a garbage collected heap, untraced references point to manually allocated objects or to objects somewhere else in memory. Thus @@ -1464,7 +1464,7 @@ meaning to retrieve the item the reference points to. The ``.`` (access a tuple/object field operator) and ``[]`` (array/string/sequence index operator) operators perform implicit dereferencing operations for reference types: -.. code-block:: nimrod +.. code-block:: nim type PNode = ref TNode @@ -1489,12 +1489,12 @@ Procedural type --------------- A procedural type is a (somewhat abstract) pointer to a procedure. ``nil`` is an allowed value for a variable of a procedural type. -Nimrod uses procedural types to achieve `functional`:idx: programming +Nim uses procedural types to achieve `functional`:idx: programming techniques. Example: -.. code-block:: nimrod +.. code-block:: nim proc echoItem(x: int) = echo(x) proc forEach(action: proc (x: int)) = @@ -1513,13 +1513,13 @@ listed in the `manual `_. Modules ======= -Nimrod supports splitting a program into pieces with a module concept. +Nim supports splitting a program into pieces with a module concept. Each module is in its own file. Modules enable `information hiding`:idx: and `separate compilation`:idx:. A module may gain access to symbols of another module by the `import`:idx: statement. Only top-level symbols that are marked with an asterisk (``*``) are exported: -.. code-block:: nimrod +.. code-block:: nim # Module A var x*, y: int @@ -1554,7 +1554,7 @@ The algorithm for compiling modules is: This is best illustrated by an example: -.. code-block:: nimrod +.. code-block:: nim # Module A type T1* = int # Module A exports the type ``T1`` @@ -1565,7 +1565,7 @@ This is best illustrated by an example: main() -.. code-block:: nimrod +.. code-block:: nim # Module B import A # A is not parsed here! Only the already known symbols # of A are imported. @@ -1581,15 +1581,15 @@ the symbol is ambiguous, it even *has* to be qualified. A symbol is ambiguous if it is defined in two (or more) different modules and both modules are imported by a third one: -.. code-block:: nimrod +.. code-block:: nim # Module A var x*: string -.. code-block:: nimrod +.. code-block:: nim # Module B var x*: int -.. code-block:: nimrod +.. code-block:: nim # Module C import A, B write(stdout, x) # error: x is ambiguous @@ -1602,15 +1602,15 @@ imported by a third one: But this rule does not apply to procedures or iterators. Here the overloading rules apply: -.. code-block:: nimrod +.. code-block:: nim # Module A proc x*(a: int): string = result = $a -.. code-block:: nimrod +.. code-block:: nim # Module B proc x*(a: string): string = result = $a -.. code-block:: nimrod +.. code-block:: nim # Module C import A, B write(stdout, x(3)) # no error: A.x is called @@ -1627,7 +1627,7 @@ The normal ``import`` statement will bring in all exported symbols. These can be limited by naming symbols which should be excluded with the ``except`` qualifier. -.. code-block:: nimrod +.. code-block:: nim import mymodule except y @@ -1638,19 +1638,19 @@ We have already seen the simple ``import`` statement that just imports all exported symbols. An alternative that only imports listed symbols is the ``from import`` statement: -.. code-block:: nimrod +.. code-block:: nim from mymodule import x, y, z The ``from`` statement can also force namespace qualification on symbols, thereby making symbols available, but needing to be qualified to be used. -.. code-block:: nimrod +.. code-block:: nim from mymodule import x, y, z x() # use x without any qualification -.. code-block:: nimrod +.. code-block:: nim from mymodule import nil mymodule.x() # must qualify x with the module name as prefix @@ -1660,7 +1660,7 @@ to be used. Since module names are generally long to be descriptive, you can also define a shorter alias to use when qualifying symbols. -.. code-block:: nimrod +.. code-block:: nim from mymodule as m import nil m.x() # m is aliasing mymodule @@ -1672,7 +1672,7 @@ The ``include`` statement does something fundamentally different than importing a module: it merely includes the contents of a file. The ``include`` statement is useful to split up a large module into several files: -.. code-block:: nimrod +.. code-block:: nim include fileA, fileB, fileC **Note**: The documentation generator currently does not follow ``include`` @@ -1683,7 +1683,7 @@ generated documentation. Part 2 ====== -So, now that we are done with the basics, let's see what Nimrod offers apart +So, now that we are done with the basics, let's see what Nim offers apart from a nice syntax for procedural programming: `Part II `_ diff --git a/doc/tut2.txt b/doc/tut2.txt index 2f42bcefc..8cd977a96 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -1,9 +1,9 @@ -========================= -Nimrod Tutorial (Part II) -========================= +====================== +Nim Tutorial (Part II) +====================== :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -15,7 +15,7 @@ Introduction only have originated in California." --Edsger Dijkstra -This document is a tutorial for the advanced constructs of the *Nimrod* +This document is a tutorial for the advanced constructs of the *Nim* programming language. **Note that this document is somewhat obsolete as the** `manual `_ **contains many more examples of the advanced language features.** @@ -24,18 +24,18 @@ features.** Pragmas ======= -Pragmas are Nimrod's method to give the compiler additional information/ +Pragmas are Nim's method to give the compiler additional information/ commands without introducing a massive number of new keywords. Pragmas are enclosed in the special ``{.`` and ``.}`` curly dot brackets. This tutorial does not cover pragmas. See the `manual `_ or `user guide -`_ for a description of the available +`_ for a description of the available pragmas. Object Oriented Programming =========================== -While Nimrod's support for object oriented programming (OOP) is minimalistic, +While Nim's support for object oriented programming (OOP) is minimalistic, powerful OOP technics can be used. OOP is seen as *one* way to design a program, not *the only* way. Often a procedural approach leads to simpler and more efficient code. In particular, prefering composition over inheritance @@ -55,7 +55,7 @@ a *constructor*). Objects have access to their type at runtime. There is an ``of`` operator that can be used to check the object's type: -.. code-block:: nimrod +.. code-block:: nim type TPerson = object of TObject name*: string # the * means that `name` is accessible from other modules @@ -86,20 +86,20 @@ in the GTK wrapper for instance.) **Note**: Composition (*has-a* relation) is often preferable to inheritance (*is-a* relation) for simple code reuse. Since objects are value types in -Nimrod, composition is as efficient as inheritance. +Nim, composition is as efficient as inheritance. Mutually recursive types ------------------------ Objects, tuples and references can model quite complex data structures which -depend on each other; they are *mutually recursive*. In Nimrod +depend on each other; they are *mutually recursive*. In Nim these types can only be declared within a single type section. (Anything else would require arbitrary symbol lookahead which slows down compilation.) Example: -.. code-block:: nimrod +.. code-block:: nim type PNode = ref TNode # a traced reference to a TNode TNode = object @@ -114,7 +114,7 @@ Example: Type conversions ---------------- -Nimrod distinguishes between `type casts`:idx: and `type conversions`:idx:. +Nim distinguishes between `type casts`:idx: and `type conversions`:idx:. Casts are done with the ``cast`` operator and force the compiler to interpret a bit pattern to be of another type. @@ -126,7 +126,7 @@ raised. The syntax for type conversions is ``destination_type(expression_to_convert)`` (like an ordinary call): -.. code-block:: nimrod +.. code-block:: nim proc getID(x: TPerson): int = TStudent(x).id @@ -141,9 +141,9 @@ variant types are needed. An example: -.. code-block:: nimrod +.. code-block:: nim - # This is an example how an abstract syntax tree could be modeled in Nimrod + # This is an example how an abstract syntax tree could be modeled in Nim type TNodeKind = enum # the different node types nkInt, # a leaf with an integer value @@ -183,8 +183,8 @@ bound to a class. This has disadvantages: * Often it is unclear where the method should belong to: is ``join`` a string method or an array method? -Nimrod avoids these problems by not assigning methods to a class. All methods -in Nimrod are multi-methods. As we will see later, multi-methods are +Nim avoids these problems by not assigning methods to a class. All methods +in Nim are multi-methods. As we will see later, multi-methods are distinguished from procs only for dynamic binding purposes. @@ -199,7 +199,7 @@ If there are no remaining arguments, the parentheses can be omitted: This method call syntax is not restricted to objects, it can be used for any type: -.. code-block:: nimrod +.. code-block:: nim echo("abc".len) # is the same as echo(len("abc")) echo("abc".toUpper()) @@ -211,7 +211,7 @@ postfix notation.) So "pure object oriented" code is easy to write: -.. code-block:: nimrod +.. code-block:: nim import strutils stdout.writeln("Give a list of numbers (separated by spaces): ") @@ -221,12 +221,12 @@ So "pure object oriented" code is easy to write: Properties ---------- -As the above example shows, Nimrod has no need for *get-properties*: +As the above example shows, Nim has no need for *get-properties*: Ordinary get-procedures that are called with the *method call syntax* achieve the same. But setting a value is different; for this a special setter syntax is needed: -.. code-block:: nimrod +.. code-block:: nim type TSocket* = object of TObject @@ -252,7 +252,7 @@ is needed: The ``[]`` array access operator can be overloaded to provide `array properties`:idx:\ : -.. code-block:: nimrod +.. code-block:: nim type TVector* = object x, y, z: float @@ -283,7 +283,7 @@ Dynamic dispatch Procedures always use static dispatch. For dynamic dispatch replace the ``proc`` keyword by ``method``: -.. code-block:: nimrod +.. code-block:: nim type PExpr = ref object of TObject ## abstract base class for an expression PLiteral = ref object of PExpr @@ -311,7 +311,7 @@ requires dynamic binding. In a multi-method all parameters that have an object type are used for the dispatching: -.. code-block:: nimrod +.. code-block:: nim type TThing = object of TObject @@ -336,7 +336,7 @@ As the example demonstrates, invocation of a multi-method cannot be ambiguous: Collide 2 is preferred over collide 1 because the resolution works from left to right. Thus ``TUnit, TThing`` is preferred over ``TThing, TUnit``. -**Perfomance note**: Nimrod does not produce a virtual method table, but +**Perfomance note**: Nim does not produce a virtual method table, but generates dispatch trees. This avoids the expensive indirect branch for method calls and enables inlining. However, other optimizations like compile time evaluation or dead code elimination do not work with methods. @@ -345,7 +345,7 @@ evaluation or dead code elimination do not work with methods. Exceptions ========== -In Nimrod exceptions are objects. By convention, exception types are +In Nim exceptions are objects. By convention, exception types are prefixed with an 'E', not 'T'. The `system `_ module defines an exception hierarchy that you might want to stick to. Exceptions derive from E_Base, which provides the common interface. @@ -364,7 +364,7 @@ Raise statement --------------- Raising an exception is done with the ``raise`` statement: -.. code-block:: nimrod +.. code-block:: nim var e: ref EOS new(e) @@ -375,7 +375,7 @@ If the ``raise`` keyword is not followed by an expression, the last exception is *re-raised*. For the purpose of avoiding repeating this common code pattern, the template ``newException`` in the ``system`` module can be used: -.. code-block:: nimrod +.. code-block:: nim raise newException(EOS, "the request to the OS failed") @@ -384,7 +384,7 @@ Try statement The ``try`` statement handles exceptions: -.. code-block:: nimrod +.. code-block:: nim # read the first two lines of a text file that should contain numbers # and tries to add them var @@ -428,7 +428,7 @@ If you need to *access* the actual exception object or message inside an `_ procs from the `system `_ module. Example: -.. code-block:: nimrod +.. code-block:: nim try: doSomethingHere() except: @@ -460,7 +460,7 @@ instance, if you specify that a proc raises ``EIO``, and at some point it (or one of the procs it calls) starts raising a new exception the compiler will prevent that proc from compiling. Usage example: -.. code-block:: nimrod +.. code-block:: nim proc complexProc() {.raises: [EIO, EArithmetic].} = ... @@ -476,21 +476,21 @@ help you locate the offending code which has changed. If you want to add the ``{.raises.}`` pragma to existing code, the compiler can also help you. You can add the ``{.effects.}`` pragma statement to your proc and the compiler will output all inferred effects up to that point (exception -tracking is part of Nimrod's effect system). Another more roundabout way to -find out the list of exceptions raised by a proc is to use the Nimrod ``doc2`` +tracking is part of Nim's effect system). Another more roundabout way to +find out the list of exceptions raised by a proc is to use the Nim ``doc2`` command which generates documentation for a whole module and decorates all -procs with the list of raised exceptions. You can read more about Nimrod's +procs with the list of raised exceptions. You can read more about Nim's `effect system and related pragmas in the manual `_. Generics ======== -Generics are Nimrod's means to parametrize procs, iterators or types +Generics are Nim's means to parametrize procs, iterators or types with `type parameters`:idx:. They are most useful for efficient type safe containers: -.. code-block:: nimrod +.. code-block:: nim type TBinaryTree[T] = object # TBinaryTree is a generic type with # with generic param ``T`` @@ -557,7 +557,7 @@ is not hidden and is used in the ``preorder`` iterator. Templates ========= -Templates are a simple substitution mechanism that operates on Nimrod's +Templates are a simple substitution mechanism that operates on Nim's abstract syntax trees. Templates are processed in the semantic pass of the compiler. They integrate well with the rest of the language and share none of C's preprocessor macros flaws. @@ -566,7 +566,7 @@ To *invoke* a template, call it like a procedure. Example: -.. code-block:: nimrod +.. code-block:: nim template `!=` (a, b: expr): expr = # this definition exists in the System module not (a == b) @@ -585,7 +585,7 @@ for IEEE floating point numbers - NaN breaks basic boolean logic.) Templates are especially useful for lazy evaluation purposes. Consider a simple proc for logging: -.. code-block:: nimrod +.. code-block:: nim const debug = true @@ -602,7 +602,7 @@ evaluation for procedures is *eager*). Turning the ``log`` proc into a template solves this problem: -.. code-block:: nimrod +.. code-block:: nim const debug = true @@ -618,32 +618,11 @@ The parameters' types can be ordinary types or the meta types ``expr`` (stands for *type description*). If the template has no explicit return type, ``stmt`` is used for consistency with procs and methods. -The template body does not open a new scope. To open a new scope use a ``block`` -statement: - -.. code-block:: nimrod - template declareInScope(x: expr, t: typeDesc): stmt {.immediate.} = - var x: t - - template declareInNewScope(x: expr, t: typeDesc): stmt {.immediate.} = - # open a new scope: - block: - var x: t - - declareInScope(a, int) - a = 42 # works, `a` is known here - - declareInNewScope(b, int) - b = 42 # does not work, `b` is unknown - -(The `manual explains `_ why the -``immediate`` pragma is needed for these templates.) - If there is a ``stmt`` parameter it should be the last in the template declaration. The reason is that statements can be passed to a template via a special ``:`` syntax: -.. code-block:: nimrod +.. code-block:: nim template withFile(f: expr, filename: string, mode: TFileMode, body: stmt): stmt {.immediate.} = @@ -672,18 +651,18 @@ Macros ====== Macros enable advanced compile-time code transformations, but they cannot -change Nimrod's syntax. However, this is no real restriction because Nimrod's -syntax is flexible enough anyway. Macros have to be implemented in pure Nimrod +change Nim's syntax. However, this is no real restriction because Nim's +syntax is flexible enough anyway. Macros have to be implemented in pure Nim code if `foreign function interface (FFI) `_ is not enabled in the compiler, but other than that restriction (which at some point in the future will go away) -you can write any kind of Nimrod code and the compiler will run it at compile +you can write any kind of Nim code and the compiler will run it at compile time. -There are two ways to write a macro, either *generating* Nimrod source code and +There are two ways to write a macro, either *generating* Nim source code and letting the compiler parse it, or creating manually an abstract syntax tree (AST) which you feed to the compiler. In order to build the AST one needs to -know how the Nimrod concrete syntax is converted to an abstract syntax tree +know how the Nim concrete syntax is converted to an abstract syntax tree (AST). The AST is documented in the `macros `_ module. Once your macro is finished, there are two ways to invoke it: @@ -698,13 +677,13 @@ Expression Macros The following example implements a powerful ``debug`` command that accepts a variable number of arguments: -.. code-block:: nimrod - # to work with Nimrod syntax trees, we need an API that is defined in the +.. code-block:: nim + # to work with Nim syntax trees, we need an API that is defined in the # ``macros`` module: import macros macro debug(n: varargs[expr]): stmt = - # `n` is a Nimrod AST that contains a list of expressions; + # `n` is a Nim AST that contains a list of expressions; # this macro returns a list of statements: result = newNimNode(nnkStmtList, n) # iterate over any argument that is passed to this macro: @@ -727,7 +706,7 @@ variable number of arguments: The macro call expands to: -.. code-block:: nimrod +.. code-block:: nim write(stdout, "a[0]") write(stdout, ": ") writeln(stdout, a[0]) @@ -751,7 +730,7 @@ invoked by an expression following a colon. The following example outlines a macro that generates a lexical analyzer from regular expressions: -.. code-block:: nimrod +.. code-block:: nim macro case_token(n: stmt): stmt = # creates a lexical analyzer from regular expressions @@ -784,7 +763,7 @@ To give a footstart to writing macros we will show now how to turn your typical dynamic code into something that compiles statically. For the exercise we will use the following snippet of code as the starting point: -.. code-block:: nimrod +.. code-block:: nim import strutils, tables @@ -848,7 +827,7 @@ time string with the *generated source code*, which we then pass to the ``parseStmt`` proc from the `macros module `_. Here is the modified source code implementing the macro: -.. code-block:: nimrod +.. code-block:: nim import macros, strutils macro readCfgAndBuildSource(cfgFilename: string): stmt = @@ -893,13 +872,13 @@ this limitation by using the ``slurp`` proc from the `system module ``gorge`` which executes an external program and captures its output). The interesting thing is that our macro does not return a runtime ``TTable`` -object. Instead, it builds up Nimrod source code into the ``source`` variable. +object. Instead, it builds up Nim source code into the ``source`` variable. For each line of the configuration file a ``const`` variable will be generated. To avoid conflicts we prefix these variables with ``cfg``. In essence, what the compiler is doing is replacing the line calling the macro with the following snippet of code: -.. code-block:: nimrod +.. code-block:: nim const cfgversion= "1.1" const cfglicenseOwner= "Hyori Lee" const cfglicenseKey= "M1Tl3PjBWO2CC48m" @@ -919,14 +898,14 @@ Generating AST by hand ++++++++++++++++++++++ To generate an AST we would need to intimately know the structures used by the -Nimrod compiler exposed in the `macros module `_, which at first +Nim compiler exposed in the `macros module `_, which at first look seems a daunting task. But we can use as helper shortcut the ``dumpTree`` macro, which is used as a statement macro instead of an expression macro. Since we know that we want to generate a bunch of ``const`` symbols we can create the following source file and compile it to see what the compiler *expects* from us: -.. code-block:: nimrod +.. code-block:: nim import macros dumpTree: @@ -969,7 +948,7 @@ identifier, optionally a type (can be an *empty* node) and the value. Armed with this knowledge, let's look at the finished version of the AST building macro: -.. code-block:: nimrod +.. code-block:: nim import macros, strutils macro readCfgAndBuildAST(cfgFilename: string): stmt = diff --git a/examples/htmlrefs.nim b/examples/htmlrefs.nim index 8b668325f..6be28d1ca 100644 --- a/examples/htmlrefs.nim +++ b/examples/htmlrefs.nim @@ -15,7 +15,7 @@ var links = 0 # count the number of links var filename = addFileExt(ParamStr(1), "html") var s = newFileStream(filename, fmRead) if s == nil: quit("cannot open the file " & filename) -var x: TXmlParser +var x: XmlParser open(x, s, filename) next(x) # get first event block mainLoop: diff --git a/examples/htmltitle.nim b/examples/htmltitle.nim index a3280bb13..7e66fabaa 100644 --- a/examples/htmltitle.nim +++ b/examples/htmltitle.nim @@ -10,7 +10,7 @@ if paramCount() < 1: var filename = addFileExt(paramStr(1), "html") var s = newFileStream(filename, fmRead) if s == nil: quit("cannot open the file " & filename) -var x: TXmlParser +var x: XmlParser open(x, s, filename) while true: x.next() diff --git a/lib/pure/actors.nim b/lib/pure/actors.nim index 2d902debe..8a8d8b51b 100644 --- a/lib/pure/actors.nim +++ b/lib/pure/actors.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -21,6 +21,11 @@ ## for i in 0 .. < 300: ## a.spawn(i, proc (x: int) {.thread.} = echo x) ## a.join() +## +## **Note**: This whole module is deprecated. Use `threadpool` and ``spawn`` +## instead. + +{.deprecated.} from os import sleep diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index df94c9eb5..b27ccb93c 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -10,9 +10,12 @@ ## This module implements some common generic algorithms. type - TSortOrder* = enum ## sort order + SortOrder* = enum ## sort order Descending, Ascending +{.deprecated: [TSortOrder: SortOrder].} + + proc `*`*(x: int, order: TSortOrder): int {.inline.} = ## flips `x` if ``order == Descending``; ## if ``order == Ascending`` then `x` is returned. diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 5dfcf4656..194c6ee1b 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -13,7 +13,7 @@ import os, oids, tables, strutils, macros, times import rawsockets, net -export TPort, TSocketFlags +export Port, SocketFlags #{.injectStmt: newGcInvariant().} @@ -36,21 +36,24 @@ export TPort, TSocketFlags # -- Futures type - PFutureBase* = ref object of PObject + FutureBase* = ref object of RootObj cb: proc () {.closure,gcsafe.} finished: bool - error*: ref EBase + error*: ref Exception errorStackTrace*: string when not defined(release): stackTrace: string ## For debugging purposes only. id: int fromProc: string - PFuture*[T] = ref object of PFutureBase + Future*[T] = ref object of FutureBase value: T +{.deprecated: [PFutureBase: FutureBase, PFuture: Future].} + + var currentID* = 0 -proc newFuture*[T](fromProc: string = "unspecified"): PFuture[T] = +proc newFuture*[T](fromProc: string = "unspecified"): Future[T] = ## Creates a new future. ## ## Specifying ``fromProc``, which is a string specifying the name of the proc @@ -63,7 +66,7 @@ proc newFuture*[T](fromProc: string = "unspecified"): PFuture[T] = result.fromProc = fromProc currentID.inc() -proc checkFinished[T](future: PFuture[T]) = +proc checkFinished[T](future: Future[T]) = when not defined(release): if future.finished: echo("<-----> ", future.id, " ", future.fromProc) @@ -76,7 +79,7 @@ proc checkFinished[T](future: PFuture[T]) = echo getStackTrace() assert false -proc complete*[T](future: PFuture[T], val: T) = +proc complete*[T](future: Future[T], val: T) = ## Completes ``future`` with value ``val``. #assert(not future.finished, "Future already finished, cannot finish twice.") checkFinished(future) @@ -86,7 +89,7 @@ proc complete*[T](future: PFuture[T], val: T) = if future.cb != nil: future.cb() -proc complete*(future: PFuture[void]) = +proc complete*(future: Future[void]) = ## Completes a void ``future``. #assert(not future.finished, "Future already finished, cannot finish twice.") checkFinished(future) @@ -95,7 +98,7 @@ proc complete*(future: PFuture[void]) = if future.cb != nil: future.cb() -proc fail*[T](future: PFuture[T], error: ref EBase) = +proc fail*[T](future: Future[T], error: ref Exception) = ## Completes ``future`` with ``error``. #assert(not future.finished, "Future already finished, cannot finish twice.") checkFinished(future) @@ -111,8 +114,9 @@ proc fail*[T](future: PFuture[T], error: ref EBase) = # TODO: This may turn out to be a bad idea. # Turns out this is a bad idea. #raise error + discard -proc `callback=`*(future: PFutureBase, cb: proc () {.closure,gcsafe.}) = +proc `callback=`*(future: FutureBase, cb: proc () {.closure,gcsafe.}) = ## Sets the callback proc to be called when the future completes. ## ## If future has already completed then ``cb`` will be called immediately. @@ -123,23 +127,23 @@ proc `callback=`*(future: PFutureBase, cb: proc () {.closure,gcsafe.}) = if future.finished: future.cb() -proc `callback=`*[T](future: PFuture[T], - cb: proc (future: PFuture[T]) {.closure,gcsafe.}) = +proc `callback=`*[T](future: Future[T], + cb: proc (future: Future[T]) {.closure,gcsafe.}) = ## Sets the callback proc to be called when the future completes. ## ## If future has already completed then ``cb`` will be called immediately. future.callback = proc () = cb(future) -proc echoOriginalStackTrace[T](future: PFuture[T]) = +proc echoOriginalStackTrace[T](future: Future[T]) = # TODO: Come up with something better. when not defined(release): echo("Original stack trace in ", future.fromProc, ":") - if not future.errorStackTrace.isNil() and future.errorStackTrace != "": + if not future.errorStackTrace.isNil and future.errorStackTrace != "": echo(future.errorStackTrace) else: echo("Empty or nil stack trace.") -proc read*[T](future: PFuture[T]): T = +proc read*[T](future: Future[T]): T = ## Retrieves the value of ``future``. Future must be finished otherwise ## this function will fail with a ``EInvalidValue`` exception. ## @@ -154,22 +158,22 @@ proc read*[T](future: PFuture[T]): T = # TODO: Make a custom exception type for this? raise newException(EInvalidValue, "Future still in progress.") -proc readError*[T](future: PFuture[T]): ref EBase = +proc readError*[T](future: Future[T]): ref EBase = if future.error != nil: return future.error else: raise newException(EInvalidValue, "No error in future.") -proc finished*[T](future: PFuture[T]): bool = +proc finished*[T](future: Future[T]): bool = ## Determines whether ``future`` has completed. ## ## ``True`` may indicate an error or a value. Use ``failed`` to distinguish. future.finished -proc failed*(future: PFutureBase): bool = +proc failed*(future: FutureBase): bool = ## Determines whether ``future`` completed with an error. future.error != nil -proc asyncCheck*[T](future: PFuture[T]) = +proc asyncCheck*[T](future: Future[T]) = ## Sets a callback on ``future`` which raises an exception if the future ## finished with an error. ## @@ -180,7 +184,7 @@ proc asyncCheck*[T](future: PFuture[T]) = echoOriginalStackTrace(future) raise future.error -proc `and`*[T, Y](fut1: PFuture[T], fut2: PFuture[Y]): PFuture[void] = +proc `and`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] = ## Returns a future which will complete once both ``fut1`` and ``fut2`` ## complete. var retFuture = newFuture[void]() @@ -192,7 +196,7 @@ proc `and`*[T, Y](fut1: PFuture[T], fut2: PFuture[Y]): PFuture[void] = if fut1.finished: retFuture.complete() return retFuture -proc `or`*[T, Y](fut1: PFuture[T], fut2: PFuture[Y]): PFuture[void] = +proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] = ## Returns a future which will complete once either ``fut1`` or ``fut2`` ## complete. var retFuture = newFuture[void]() @@ -203,7 +207,7 @@ proc `or`*[T, Y](fut1: PFuture[T], fut2: PFuture[Y]): PFuture[void] = type PDispatcherBase = ref object of PObject - timers: seq[tuple[finishAt: float, fut: PFuture[void]]] + timers: seq[tuple[finishAt: float, fut: Future[void]]] proc processTimers(p: PDispatcherBase) = var oldTimers = p.timers @@ -375,10 +379,10 @@ when defined(windows) or defined(nimdoc): RemoteSockaddr, RemoteSockaddrLength) proc connect*(socket: TAsyncFD, address: string, port: TPort, - af = AF_INET): PFuture[void] = + af = AF_INET): Future[void] = ## Connects ``socket`` to server at ``address:port``. ## - ## Returns a ``PFuture`` which will complete when the connection succeeds + ## Returns a ``Future`` which will complete when the connection succeeds ## or an error occurs. verifyPresence(socket) var retFuture = newFuture[void]("connect") @@ -437,7 +441,7 @@ when defined(windows) or defined(nimdoc): return retFuture proc recv*(socket: TAsyncFD, size: int, - flags = {TSocketFlags.SafeDisconn}): PFuture[string] = + flags = {TSocketFlags.SafeDisconn}): Future[string] = ## Reads **up to** ``size`` bytes from ``socket``. Returned future will ## complete once all the data requested is read, a part of the data has been ## read, or the socket has disconnected in which case the future will @@ -525,7 +529,7 @@ when defined(windows) or defined(nimdoc): return retFuture proc send*(socket: TAsyncFD, data: string, - flags = {TSocketFlags.SafeDisconn}): PFuture[void] = + flags = {TSocketFlags.SafeDisconn}): Future[void] = ## Sends ``data`` to ``socket``. The returned future will complete once all ## data has been sent. verifyPresence(socket) @@ -568,7 +572,7 @@ when defined(windows) or defined(nimdoc): return retFuture proc acceptAddr*(socket: TAsyncFD, flags = {TSocketFlags.SafeDisconn}): - PFuture[tuple[address: string, client: TAsyncFD]] = + Future[tuple[address: string, client: TAsyncFD]] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection and the remote address of the client. ## The future will complete when the connection is successfully accepted. @@ -789,7 +793,7 @@ else: processTimers(p) proc connect*(socket: TAsyncFD, address: string, port: TPort, - af = AF_INET): PFuture[void] = + af = AF_INET): Future[void] = var retFuture = newFuture[void]("connect") proc cb(sock: TAsyncFD): bool = @@ -824,7 +828,7 @@ else: return retFuture proc recv*(socket: TAsyncFD, size: int, - flags = {TSocketFlags.SafeDisconn}): PFuture[string] = + flags = {TSocketFlags.SafeDisconn}): Future[string] = var retFuture = newFuture[string]("recv") var readBuffer = newString(size) @@ -855,7 +859,7 @@ else: return retFuture proc send*(socket: TAsyncFD, data: string, - flags = {TSocketFlags.SafeDisconn}): PFuture[void] = + flags = {TSocketFlags.SafeDisconn}): Future[void] = var retFuture = newFuture[void]("send") var written = 0 @@ -887,7 +891,7 @@ else: return retFuture proc acceptAddr*(socket: TAsyncFD, flags = {TSocketFlags.SafeDisconn}): - PFuture[tuple[address: string, client: TAsyncFD]] = + Future[tuple[address: string, client: TAsyncFD]] = var retFuture = newFuture[tuple[address: string, client: TAsyncFD]]("acceptAddr") proc cb(sock: TAsyncFD): bool = @@ -912,7 +916,7 @@ else: addRead(socket, cb) return retFuture -proc sleepAsync*(ms: int): PFuture[void] = +proc sleepAsync*(ms: int): Future[void] = ## Suspends the execution of the current async procedure for the next ## ``ms`` miliseconds. var retFuture = newFuture[void]("sleepAsync") @@ -921,14 +925,14 @@ proc sleepAsync*(ms: int): PFuture[void] = return retFuture proc accept*(socket: TAsyncFD, - flags = {TSocketFlags.SafeDisconn}): PFuture[TAsyncFD] = + flags = {TSocketFlags.SafeDisconn}): Future[TAsyncFD] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection. ## The future will complete when the connection is successfully accepted. var retFut = newFuture[TAsyncFD]("accept") var fut = acceptAddr(socket, flags) fut.callback = - proc (future: PFuture[tuple[address: string, client: TAsyncFD]]) = + proc (future: Future[tuple[address: string, client: TAsyncFD]]) = assert future.finished if future.failed: retFut.fail(future.error) @@ -1111,12 +1115,12 @@ macro async*(prc: stmt): stmt {.immediate.} = hint("Processing " & prc[0].getName & " as an async proc.") let returnType = prc[3][0] - # Verify that the return type is a PFuture[T] + # Verify that the return type is a Future[T] if returnType.kind == nnkIdent: - error("Expected return type of 'PFuture' got '" & $returnType & "'") + error("Expected return type of 'Future' got '" & $returnType & "'") elif returnType.kind == nnkBracketExpr: - if $returnType[0] != "PFuture": - error("Expected return type of 'PFuture' got '" & $returnType[0] & "'") + if $returnType[0] != "Future": + error("Expected return type of 'Future' got '" & $returnType[0] & "'") let subtypeIsVoid = returnType.kind == nnkEmpty or (returnType.kind == nnkBracketExpr and @@ -1137,7 +1141,7 @@ macro async*(prc: stmt): stmt {.immediate.} = subRetType), newLit(prc[0].getName)))) # Get type from return type of this proc - # -> iterator nameIter(): PFutureBase {.closure.} = + # -> iterator nameIter(): FutureBase {.closure.} = # -> var result: T # -> # -> complete(retFuture, result) @@ -1153,7 +1157,7 @@ macro async*(prc: stmt): stmt {.immediate.} = # -> complete(retFuture) procBody.add(newCall(newIdentNode("complete"), retFutureSym)) - var closureIterator = newProc(iteratorNameSym, [newIdentNode("PFutureBase")], + var closureIterator = newProc(iteratorNameSym, [newIdentNode("FutureBase")], procBody, nnkIteratorDef) closureIterator[4] = newNimNode(nnkPragma, prc[6]).add(newIdentNode("closure")) outerProcBody.add(closureIterator) @@ -1176,8 +1180,8 @@ macro async*(prc: stmt): stmt {.immediate.} = if subtypeIsVoid: # Add discardable pragma. if returnType.kind == nnkEmpty: - # Add PFuture[void] - result[3][0] = parseExpr("PFuture[void]") + # Add Future[void] + result[3][0] = parseExpr("Future[void]") result[6] = outerProcBody @@ -1185,7 +1189,7 @@ macro async*(prc: stmt): stmt {.immediate.} = #if prc[0].getName == "processClient": # echo(toStrLit(result)) -proc recvLine*(socket: TAsyncFD): PFuture[string] {.async.} = +proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = ## Reads a line of data from ``socket``. Returned future will complete once ## a full line is read or an error occurs. ## diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 26e3a2a7b..54d0b1b8e 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -13,7 +13,7 @@ import strtabs, asyncnet, asyncdispatch, parseutils, uri, strutils type - TRequest* = object + Request* = object client*: PAsyncSocket # TODO: Separate this into a Response object? reqMethod*: string headers*: PStringTable @@ -22,10 +22,10 @@ type hostname*: string ## The hostname of the client that made the request. body*: string - PAsyncHttpServer* = ref object + AsyncHttpServer* = ref object socket: PAsyncSocket - THttpCode* = enum + HttpCode* = enum Http200 = "200 OK", Http303 = "303 Moved", Http400 = "400 Bad Request", @@ -33,10 +33,13 @@ type Http500 = "500 Internal Server Error", Http502 = "502 Bad Gateway" - THttpVersion* = enum + HttpVersion* = enum HttpVer11, HttpVer10 +{.deprecated: [TRequest: Request, PAsyncHttpServer: AsyncHttpServer, + THttpCode: HttpCode, THttpVersion: HttpVersion].} + proc `==`*(protocol: tuple[orig: string, major, minor: int], ver: THttpVersion): bool = let major = diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 6b67bf4b5..54aa19079 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf, Dominik Picheta # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -10,8 +10,8 @@ include "system/inclrtl" import sockets, os -## This module implements an asynchronous event loop together with asynchronous sockets -## which use this event loop. +## This module implements an asynchronous event loop together with asynchronous +## sockets which use this event loop. ## It is akin to Python's asyncore module. Many modules that use sockets ## have an implementation for this module, those modules should all have a ## ``register`` function which you should use to add the desired objects to a @@ -31,10 +31,10 @@ import sockets, os ## ## Most (if not all) modules that use asyncio provide a userArg which is passed ## on with the events. The type that you set userArg to must be inheriting from -## TObject! +## ``RootObj``! ## ## **Note:** If you want to provide async ability to your module please do not -## use the ``TDelegate`` object, instead use ``PAsyncSocket``. It is possible +## use the ``Delegate`` object, instead use ``AsyncSocket``. It is possible ## that in the future this type's fields will not be exported therefore breaking ## your code. ## @@ -44,10 +44,10 @@ import sockets, os ## Asynchronous sockets ## ==================== ## -## For most purposes you do not need to worry about the ``TDelegate`` type. The -## ``PAsyncSocket`` is what you are after. It's a reference to the ``TAsyncSocket`` -## object. This object defines events which you should overwrite by your own -## procedures. +## For most purposes you do not need to worry about the ``Delegate`` type. The +## ``AsyncSocket`` is what you are after. It's a reference to +## the ``AsyncSocketObj`` object. This object defines events which you should +## overwrite by your own procedures. ## ## For server sockets the only event you need to worry about is the ``handleAccept`` ## event, in your handleAccept proc you should call ``accept`` on the server @@ -57,13 +57,13 @@ import sockets, os ## ## An example ``handleAccept`` follows: ## -## .. code-block:: nimrod +## .. code-block:: nim ## -## var disp: PDispatcher = newDispatcher() +## var disp = newDispatcher() ## ... -## proc handleAccept(s: PAsyncSocket) = +## proc handleAccept(s: AsyncSocket) = ## echo("Accepted client.") -## var client: PAsyncSocket +## var client: AsyncSocket ## new(client) ## s.accept(client) ## client.handleRead = ... @@ -76,29 +76,29 @@ import sockets, os ## the socket has established a connection to a server socket; from that point ## it can be safely written to. ## -## Getting a blocking client from a PAsyncSocket +## Getting a blocking client from an AsyncSocket ## ============================================= ## ## If you need a asynchronous server socket but you wish to process the clients -## synchronously then you can use the ``getSocket`` converter to get a TSocket -## object from the PAsyncSocket object, this can then be combined with ``accept`` -## like so: +## synchronously then you can use the ``getSocket`` converter to get +## a ``Socket`` from the ``AsyncSocket`` object, this can then be combined +## with ``accept`` like so: ## -## .. code-block:: nimrod +## .. code-block:: nim ## -## proc handleAccept(s: PAsyncSocket) = -## var client: TSocket +## proc handleAccept(s: AsyncSocket) = +## var client: Socket ## getSocket(s).accept(client) when defined(windows): - from winlean import TTimeVal, TSocketHandle, TFdSet, FD_ZERO, FD_SET, FD_ISSET, select + from winlean import TimeVal, SocketHandle, FdSet, FD_ZERO, FD_SET, FD_ISSET, select else: - from posix import TTimeVal, TSocketHandle, TFdSet, FD_ZERO, FD_SET, FD_ISSET, select + from posix import TimeVal, SocketHandle, FdSet, FD_ZERO, FD_SET, FD_ISSET, select type - TDelegate* = object - fd*: TSocketHandle - deleVal*: PObject + DelegateObj* = object + fd*: SocketHandle + deleVal*: RootRef handleRead*: proc (h: PObject) {.nimcall, gcsafe.} handleWrite*: proc (h: PObject) {.nimcall, gcsafe.} @@ -107,18 +107,18 @@ type open*: bool task*: proc (h: PObject) {.nimcall, gcsafe.} - mode*: TFileMode + mode*: FileMode - PDelegate* = ref TDelegate + Delegate* = ref DelegateObj - PDispatcher* = ref TDispatcher - TDispatcher = object + Dispatcher* = ref DispatcherObj + DispatcherObj = object delegates: seq[PDelegate] - PAsyncSocket* = ref TAsyncSocket - TAsyncSocket* = object of TObject - socket: TSocket - info: TInfo + AsyncSocket* = ref AsyncSocketObj + AsyncSocketObj* = object of RootObj + socket: Socket + info: SocketStatus handleRead*: proc (s: PAsyncSocket) {.closure, gcsafe.} handleWrite: proc (s: PAsyncSocket) {.closure, gcsafe.} @@ -134,10 +134,17 @@ type proto: TProtocol deleg: PDelegate - TInfo* = enum + SocketStatus* = enum SockIdle, SockConnecting, SockConnected, SockListening, SockClosed, SockUDPBound +{.deprecated: [TDelegate: DelegateObj, PDelegate: Delegate, + TProcessOption: ProcessOption, + TInfo: SocketStatus, PAsyncSocket: AsyncSocket, TAsyncSocket: AsyncSocketObj, + TDispatcher: DispatcherObj, PDispatcher: Dispatcher, + ].} + + proc newDelegate*(): PDelegate = ## Creates a new delegate. new(result) diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 5095d9461..ecaf0b9f9 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -19,9 +19,9 @@ ## ## import asyncnet, asyncdispatch ## -## var clients: seq[PAsyncSocket] = @[] +## var clients: seq[AsyncSocket] = @[] ## -## proc processClient(client: PAsyncSocket) {.async.} = +## proc processClient(client: AsyncSocket) {.async.} = ## while true: ## let line = await client.recvLine() ## for c in clients: @@ -29,7 +29,7 @@ ## ## proc serve() {.async.} = ## var server = newAsyncSocket() -## server.bindAddr(TPort(12345)) +## server.bindAddr(Port(12345)) ## server.listen() ## ## while true: @@ -54,8 +54,10 @@ when defined(ssl): type # TODO: I would prefer to just do: # PAsyncSocket* {.borrow: `.`.} = distinct PSocket. But that doesn't work. - TAsyncSocket {.borrow: `.`.} = distinct TSocketImpl - PAsyncSocket* = ref TAsyncSocket + AsyncSocketDesc {.borrow: `.`.} = distinct TSocketImpl + AsyncSocket* = ref AsyncSocketDesc + +{.deprecated: [PAsyncSocket: AsyncSocket].} # TODO: Save AF, domain etc info and reuse it in procs which need it like connect. diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index 7b3b0e6f5..3d3cea25c 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim index f8391a368..40f59db74 100644 --- a/lib/pure/basic2d.nim +++ b/lib/pure/basic2d.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Robert Persson # # See the file "copying.txt", included in this diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim index 540d53fd9..47856e11d 100644 --- a/lib/pure/basic3d.nim +++ b/lib/pure/basic3d.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Robert Persson # # See the file "copying.txt", included in this diff --git a/lib/pure/browsers.nim b/lib/pure/browsers.nim index 3a8429f81..52035ee48 100644 --- a/lib/pure/browsers.nim +++ b/lib/pure/browsers.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -44,5 +44,5 @@ proc openDefaultBrowser*(url: string) = # we use ``startProcess`` here because we don't want to block! discard startProcess(command=b, args=[url], options={poUseShell}) return - except EOS: + except OSError: discard diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index 0d3231b93..bb7934faa 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -9,7 +9,7 @@ ## This module implements helper procs for CGI applications. Example: ## -## .. code-block:: Nimrod +## .. code-block:: Nim ## ## import strtabs, cgi ## @@ -93,12 +93,14 @@ proc XMLencode*(s: string): string = for i in 0..len(s)-1: addXmlChar(result, s[i]) type - ECgi* = object of IOError ## the exception that is raised, if a CGI error occurs - TRequestMethod* = enum ## the used request method + CgiError* = object of IOError ## exception that is raised if a CGI error occurs + RequestMethod* = enum ## the used request method methodNone, ## no REQUEST_METHOD environment variable methodPost, ## query uses the POST method methodGet ## query uses the GET method +{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError].} + proc cgiError*(msg: string) {.noreturn.} = ## raises an ECgi exception with message `msg`. var e: ref ECgi @@ -377,7 +379,7 @@ proc setCookie*(name, value: string) = write(stdout, "Set-Cookie: ", name, "=", value, "\n") var - gcookies {.threadvar.}: PStringTable + gcookies {.threadvar.}: StringTableRef proc getCookie*(name: string): TaintedString = ## Gets a cookie. If no cookie of `name` exists, "" is returned. diff --git a/lib/pure/collections/LockFreeHash.nim b/lib/pure/collections/LockFreeHash.nim index b94b542ff..57beb83c9 100644 --- a/lib/pure/collections/LockFreeHash.nim +++ b/lib/pure/collections/LockFreeHash.nim @@ -1,8 +1,40 @@ #nimrod c -t:-march=i686 --cpu:amd64 --threads:on -d:release lockfreehash.nim -import baseutils, unsigned, math, hashes +import unsigned, math, hashes +#------------------------------------------------------------------------------ +## Memory Utility Functions +proc newHeap*[T](): ptr T = + result = cast[ptr T](alloc0(sizeof(T))) + +proc copyNew*[T](x: var T): ptr T = + var + size = sizeof(T) + mem = alloc(size) + copyMem(mem, x.addr, size) + return cast[ptr T](mem) + +proc copyTo*[T](val: var T, dest: int) = + copyMem(pointer(dest), val.addr, sizeof(T)) + +proc allocType*[T](): pointer = alloc(sizeof(T)) + +proc newShared*[T](): ptr T = + result = cast[ptr T](allocShared0(sizeof(T))) + +proc copyShared*[T](x: var T): ptr T = + var + size = sizeof(T) + mem = allocShared(size) + copyMem(mem, x.addr, size) + return cast[ptr T](mem) + +#------------------------------------------------------------------------------ +## Pointer arithmetic + +proc `+`*(p: pointer, i: int): pointer {.inline.} = + cast[pointer](cast[int](p) + i) const minTableSize = 8 @@ -194,7 +226,7 @@ proc copySlot[K,V](idx: int, oldTbl: var PConcTable[K,V], newTbl: var PConcTable #Prevent new values from appearing in the old table by priming oldVal = atomic_load_n(oldTbl[idx].value.addr, ATOMIC_RELAXED) while not isPrime(oldVal): - var box = if oldVal == NULL or isTomb(oldVal) : oldVal.setTomb.setPrime + var box = if oldVal == 0 or isTomb(oldVal) : oldVal.setTomb.setPrime else: oldVal.setPrime if atomic_compare_exchange_n(oldTbl[idx].value.addr, oldVal.addr, box, false, ATOMIC_RELAXED, ATOMIC_RELAXED): @@ -209,8 +241,8 @@ proc copySlot[K,V](idx: int, oldTbl: var PConcTable[K,V], newTbl: var PConcTable return false if isTomb(oldVal): echo("oldVal is Tomb!!!, should not happen") - if pop(oldVal) != NULL: - result = setVal(newTbl, pop(oldKey), pop(oldVal), NULL, true) == NULL + if pop(oldVal) != 0: + result = setVal(newTbl, pop(oldKey), pop(oldVal), 0, true) == 0 if result: #echo("Copied a Slot! idx= " & $idx & " key= " & $oldKey & " val= " & $oldVal) else: @@ -323,7 +355,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, idx = idx and (table.len - 1) #echo("try set idx = " & $idx & "for" & $key) var - probedKey = NULL + probedKey = 0 openKey = atomic_compare_exchange_n(table[idx].key.addr, probedKey.addr, key, false, ATOMIC_RELAXED, ATOMIC_RELAXED) if openKey: @@ -339,7 +371,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, if keyEQ[K](probedKey, key): #echo("we found the matching slot") break # We found a matching slot - if (not(expVal != NULL and match)) and (probes >= reProbeLimit or key.isTomb): + if (not(expVal != 0 and match)) and (probes >= reProbeLimit or key.isTomb): if key.isTomb: echo("Key is Tombstone") #if probes >= reProbeLimit: echo("Too much probing " & $probes) #echo("try to resize") @@ -361,7 +393,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, return oldVal nextTable = atomic_load_n(table.next.addr, ATOMIC_SEQ_CST) if nextTable == nil and - ((oldVal == NULL and + ((oldVal == 0 and (probes >= reProbeLimit or table.used / table.len > 0.8)) or (isPrime(oldVal))): if table.used / table.len > 0.8: echo("resize because usage ratio = " & @@ -380,12 +412,12 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int, if atomic_compare_exchange_n(table[idx].value.addr, oldVal.addr, val, false, ATOMIC_RELEASE, ATOMIC_RELAXED): #echo("val set at table " & $cast[int](table)) - if expVal != NULL: - if (oldVal == NULL or isTomb(oldVal)) and not isTomb(val): + if expVal != 0: + if (oldVal == 0 or isTomb(oldVal)) and not isTomb(val): discard atomic_add_fetch(table.active.addr, 1, ATOMIC_RELAXED) - elif not (oldVal == NULL or isTomb(oldVal)) and isTomb(val): + elif not (oldVal == 0 or isTomb(oldVal)) and isTomb(val): discard atomic_add_fetch(table.active.addr, -1, ATOMIC_RELAXED) - if oldVal == NULL and expVal != NULL: + if oldVal == 0 and expVal != 0: return setTomb(oldVal) else: return oldVal if isPrime(oldVal): @@ -415,7 +447,7 @@ proc getVal[K,V](table: var PConcTable[K,V], key: int): int = if not isPrime(val): if isTomb(val): #echo("val was tomb but not prime") - return NULL + return 0 else: #echo("-GotIt- idx = ", idx, " key = ", key, " val ", val ) return val @@ -427,7 +459,7 @@ proc getVal[K,V](table: var PConcTable[K,V], key: int): int = if probes >= reProbeLimit*4 or key.isTomb: if newTable == nil: #echo("too many probes and no new table ", key, " ", idx ) - return NULL + return 0 else: newTable = helpCopy(table) return getVal(newTable, key) @@ -437,10 +469,10 @@ proc getVal[K,V](table: var PConcTable[K,V], key: int): int = #------------------------------------------------------------------------------ #proc set*(table: var PConcTable[TRaw,TRaw], key: TRaw, val: TRaw) = -# discard setVal(table, pack(key), pack(key), NULL, false) +# discard setVal(table, pack(key), pack(key), 0, false) #proc set*[V](table: var PConcTable[TRaw,V], key: TRaw, val: ptr V) = -# discard setVal(table, pack(key), cast[int](val), NULL, false) +# discard setVal(table, pack(key), cast[int](val), 0, false) proc set*[K,V](table: var PConcTable[K,V], key: var K, val: var V) = when not (K is TRaw): @@ -451,10 +483,10 @@ proc set*[K,V](table: var PConcTable[K,V], key: var K, val: var V) = var newVal = cast[int](copyShared(val)) else: var newVal = pack(val) - var oldPtr = pop(setVal(table, newKey, newVal, NULL, false)) + var oldPtr = pop(setVal(table, newKey, newVal, 0, false)) #echo("oldPtr = ", cast[int](oldPtr), " newPtr = ", cast[int](newPtr)) when not (V is TRaw): - if newVal != oldPtr and oldPtr != NULL: + if newVal != oldPtr and oldPtr != 0: deallocShared(cast[ptr V](oldPtr)) @@ -573,10 +605,3 @@ when isMainModule: # echo(i, " = ", hashInt(i) and 8191) deleteConcTable(table) - - - - - - - diff --git a/lib/pure/collections/baseutils.nim b/lib/pure/collections/baseutils.nim deleted file mode 100644 index 565a89ccb..000000000 --- a/lib/pure/collections/baseutils.nim +++ /dev/null @@ -1,41 +0,0 @@ - - - -#------------------------------------------------------------------------------ -## Useful Constants -const NULL* = 0 - - -#------------------------------------------------------------------------------ -## Memory Utility Functions - -proc newHeap*[T](): ptr T = - result = cast[ptr T](alloc0(sizeof(T))) - -proc copyNew*[T](x: var T): ptr T = - var - size = sizeof(T) - mem = alloc(size) - copyMem(mem, x.addr, size) - return cast[ptr T](mem) - -proc copyTo*[T](val: var T, dest: int) = - copyMem(pointer(dest), val.addr, sizeof(T)) - -proc allocType*[T](): pointer = alloc(sizeof(T)) - -proc newShared*[T](): ptr T = - result = cast[ptr T](allocShared0(sizeof(T))) - -proc copyShared*[T](x: var T): ptr T = - var - size = sizeof(T) - mem = allocShared(size) - copyMem(mem, x.addr, size) - return cast[ptr T](mem) - -#------------------------------------------------------------------------------ -## Pointer arithmetic - -proc `+`*(p: pointer, i: int): pointer {.inline.} = - cast[pointer](cast[int](p) + i) \ No newline at end of file diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim index 1fde1f419..8f506409b 100644 --- a/lib/pure/collections/critbits.nim +++ b/lib/pure/collections/critbits.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,30 +12,32 @@ ## by Adam Langley. type - TNode[T] = object {.pure, final, acyclic.} + NodeObj[T] = object {.pure, final, acyclic.} byte: int ## byte index of the difference otherbits: char case isLeaf: bool - of false: child: array[0..1, ref TNode[T]] + of false: child: array[0..1, ref NodeObj[T]] of true: key: string when T isnot void: val: T - PNode[T] = ref TNode[T] - TCritBitTree*[T] = object {. + Node[T] = ref NodeObj[T] + CritBitTree*[T] = object {. pure, final.} ## The crit bit tree can either be used ## as a mapping from strings to ## some type ``T`` or as a set of ## strings if ``T`` is void. - root: PNode[T] + root: Node[T] count: int - -proc len*[T](c: TCritBitTree[T]): int = + +{.deprecated: [TCritBitTree: CritBitTree].} + +proc len*[T](c: CritBitTree[T]): int = ## returns the number of elements in `c` in O(1). result = c.count -proc rawGet[T](c: TCritBitTree[T], key: string): PNode[T] = +proc rawGet[T](c: CritBitTree[T], key: string): Node[T] = var it = c.root while it != nil: if not it.isLeaf: @@ -45,15 +47,15 @@ proc rawGet[T](c: TCritBitTree[T], key: string): PNode[T] = else: return if it.key == key: it else: nil -proc contains*[T](c: TCritBitTree[T], key: string): bool {.inline.} = +proc contains*[T](c: CritBitTree[T], key: string): bool {.inline.} = ## returns true iff `c` contains the given `key`. result = rawGet(c, key) != nil -proc hasKey*[T](c: TCritBitTree[T], key: string): bool {.inline.} = +proc hasKey*[T](c: CritBitTree[T], key: string): bool {.inline.} = ## alias for `contains`. result = rawGet(c, key) != nil -proc rawInsert[T](c: var TCritBitTree[T], key: string): PNode[T] = +proc rawInsert[T](c: var CritBitTree[T], key: string): Node[T] = if c.root == nil: new c.root c.root.isleaf = true @@ -84,7 +86,7 @@ proc rawInsert[T](c: var TCritBitTree[T], key: string): PNode[T] = let ch = it.key[newByte] let dir = (1 + (ord(ch) or newOtherBits)) shr 8 - var inner: PNode[T] + var inner: Node[T] new inner new result result.isLeaf = true @@ -106,7 +108,7 @@ proc rawInsert[T](c: var TCritBitTree[T], key: string): PNode[T] = wherep[] = inner inc c.count -proc containsOrIncl*[T](c: var TCritBitTree[T], key: string, val: T): bool = +proc containsOrIncl*[T](c: var CritBitTree[T], key: string, val: T): bool = ## returns true iff `c` contains the given `key`. If the key does not exist ## ``c[key] = val`` is performed. let oldCount = c.count @@ -115,23 +117,23 @@ proc containsOrIncl*[T](c: var TCritBitTree[T], key: string, val: T): bool = when T isnot void: if not result: n.val = val -proc containsOrIncl*(c: var TCritBitTree[void], key: string): bool = +proc containsOrIncl*(c: var CritBitTree[void], key: string): bool = ## returns true iff `c` contains the given `key`. If the key does not exist ## it is inserted into `c`. let oldCount = c.count var n = rawInsert(c, key) result = c.count == oldCount -proc incl*(c: var TCritBitTree[void], key: string) = +proc incl*(c: var CritBitTree[void], key: string) = ## includes `key` in `c`. discard rawInsert(c, key) -proc `[]=`*[T](c: var TCritBitTree[T], key: string, val: T) = +proc `[]=`*[T](c: var CritBitTree[T], key: string, val: T) = ## puts a (key, value)-pair into `t`. var n = rawInsert(c, key) n.val = val -proc `[]`*[T](c: TCritBitTree[T], key: string): T {.inline.} = +proc `[]`*[T](c: CritBitTree[T], key: string): T {.inline.} = ## retrieves the value at ``c[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key @@ -139,22 +141,22 @@ proc `[]`*[T](c: TCritBitTree[T], key: string): T {.inline.} = let n = rawGet(c, key) if n != nil: result = n.val -proc mget*[T](c: var TCritBitTree[T], key: string): var T {.inline.} = +proc mget*[T](c: var CritBitTree[T], key: string): var T {.inline.} = ## retrieves the value at ``c[key]``. The value can be modified. - ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. + ## If `key` is not in `t`, the ``KeyError`` exception is raised. let n = rawGet(c, key) if n != nil: result = n.val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) -proc excl*[T](c: var TCritBitTree[T], key: string) = +proc excl*[T](c: var CritBitTree[T], key: string) = ## removes `key` (and its associated value) from the set `c`. ## If the `key` does not exist, nothing happens. var p = c.root var wherep = addr(c.root) - var whereq: ptr PNode = nil + var whereq: ptr Node[T] = nil if p == nil: return var dir = 0 - var q: PNode + var q: Node[T] while not p.isLeaf: whereq = wherep q = p @@ -170,7 +172,7 @@ proc excl*[T](c: var TCritBitTree[T], key: string) = whereq[] = q.child[1 - dir] dec c.count -iterator leaves[T](n: PNode[T]): PNode[T] = +iterator leaves[T](n: Node[T]): Node[T] = if n != nil: # XXX actually we could compute the necessary stack size in advance: # it's rougly log2(c.count). @@ -183,33 +185,33 @@ iterator leaves[T](n: PNode[T]): PNode[T] = assert(it != nil) yield it -iterator keys*[T](c: TCritBitTree[T]): string = +iterator keys*[T](c: CritBitTree[T]): string = ## yields all keys in lexicographical order. for x in leaves(c.root): yield x.key -iterator values*[T](c: TCritBitTree[T]): T = +iterator values*[T](c: CritBitTree[T]): T = ## yields all values of `c` in the lexicographical order of the ## corresponding keys. for x in leaves(c.root): yield x.val -iterator mvalues*[T](c: var TCritBitTree[T]): var T = +iterator mvalues*[T](c: var CritBitTree[T]): var T = ## yields all values of `c` in the lexicographical order of the ## corresponding keys. The values can be modified. for x in leaves(c.root): yield x.val -iterator items*[T](c: TCritBitTree[T]): string = +iterator items*[T](c: CritBitTree[T]): string = ## yields all keys in lexicographical order. for x in leaves(c.root): yield x.key -iterator pairs*[T](c: TCritBitTree[T]): tuple[key: string, val: T] = +iterator pairs*[T](c: CritBitTree[T]): tuple[key: string, val: T] = ## yields all (key, value)-pairs of `c`. for x in leaves(c.root): yield (x.key, x.val) -iterator mpairs*[T](c: var TCritBitTree[T]): tuple[key: string, val: var T] = +iterator mpairs*[T](c: var CritBitTree[T]): tuple[key: string, val: var T] = ## yields all (key, value)-pairs of `c`. The yielded values can be modified. for x in leaves(c.root): yield (x.key, x.val) -proc allprefixedAux[T](c: TCritBitTree[T], key: string): PNode[T] = +proc allprefixedAux[T](c: CritBitTree[T], key: string): Node[T] = var p = c.root var top = p if p != nil: @@ -223,42 +225,42 @@ proc allprefixedAux[T](c: TCritBitTree[T], key: string): PNode[T] = if p.key[i] != key[i]: return result = top -iterator itemsWithPrefix*[T](c: TCritBitTree[T], prefix: string): string = +iterator itemsWithPrefix*[T](c: CritBitTree[T], prefix: string): string = ## yields all keys starting with `prefix`. let top = allprefixedAux(c, prefix) for x in leaves(top): yield x.key -iterator keysWithPrefix*[T](c: TCritBitTree[T], prefix: string): string = +iterator keysWithPrefix*[T](c: CritBitTree[T], prefix: string): string = ## yields all keys starting with `prefix`. let top = allprefixedAux(c, prefix) for x in leaves(top): yield x.key -iterator valuesWithPrefix*[T](c: TCritBitTree[T], prefix: string): T = +iterator valuesWithPrefix*[T](c: CritBitTree[T], prefix: string): T = ## yields all values of `c` starting with `prefix` of the ## corresponding keys. let top = allprefixedAux(c, prefix) for x in leaves(top): yield x.val -iterator mvaluesWithPrefix*[T](c: var TCritBitTree[T], prefix: string): var T = +iterator mvaluesWithPrefix*[T](c: var CritBitTree[T], prefix: string): var T = ## yields all values of `c` starting with `prefix` of the ## corresponding keys. The values can be modified. let top = allprefixedAux(c, prefix) for x in leaves(top): yield x.val -iterator pairsWithPrefix*[T](c: TCritBitTree[T], +iterator pairsWithPrefix*[T](c: CritBitTree[T], prefix: string): tuple[key: string, val: T] = ## yields all (key, value)-pairs of `c` starting with `prefix`. let top = allprefixedAux(c, prefix) for x in leaves(top): yield (x.key, x.val) -iterator mpairsWithPrefix*[T](c: var TCritBitTree[T], +iterator mpairsWithPrefix*[T](c: var CritBitTree[T], prefix: string): tuple[key: string, val: var T] = ## yields all (key, value)-pairs of `c` starting with `prefix`. ## The yielded values can be modified. let top = allprefixedAux(c, prefix) for x in leaves(top): yield (x.key, x.val) -proc `$`*[T](c: TCritBitTree[T]): string = +proc `$`*[T](c: CritBitTree[T]): string = ## turns `c` into a string representation. Example outputs: ## ``{keyA: value, keyB: value}``, ``{:}`` ## If `T` is void the outputs look like: @@ -285,7 +287,7 @@ proc `$`*[T](c: TCritBitTree[T]): string = result.add("}") when isMainModule: - var r: TCritBitTree[void] + var r: CritBitTree[void] r.incl "abc" r.incl "xyz" r.incl "def" diff --git a/lib/pure/collections/intsets.nim b/lib/pure/collections/intsets.nim index f1e67fc0e..678c428c1 100644 --- a/lib/pure/collections/intsets.nim +++ b/lib/pure/collections/intsets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -9,7 +9,7 @@ ## The ``intsets`` module implements an efficient int set implemented as a ## sparse bit set. -## **Note**: Since Nimrod currently does not allow the assignment operator to +## **Note**: Since Nim currently does not allow the assignment operator to ## be overloaded, ``=`` for int sets performs some rather meaningless shallow ## copy; use ``assign`` to get a deep copy. @@ -17,7 +17,7 @@ import os, hashes, math type - TBitScalar = int + BitScalar = int const InitIntSetSize = 8 # must be a power of two! @@ -25,8 +25,8 @@ const BitsPerTrunk = 1 shl TrunkShift # needs to be a power of 2 and # divisible by 64 TrunkMask = BitsPerTrunk - 1 - IntsPerTrunk = BitsPerTrunk div (sizeof(TBitScalar) * 8) - IntShift = 5 + ord(sizeof(TBitScalar) == 8) # 5 or 6, depending on int width + IntsPerTrunk = BitsPerTrunk div (sizeof(BitScalar) * 8) + IntShift = 5 + ord(sizeof(BitScalar) == 8) # 5 or 6, depending on int width IntMask = 1 shl IntShift - 1 type @@ -34,15 +34,16 @@ type TTrunk {.final.} = object next: PTrunk # all nodes are connected with this pointer key: int # start address at bit 0 - bits: array[0..IntsPerTrunk - 1, TBitScalar] # a bit vector + bits: array[0..IntsPerTrunk - 1, BitScalar] # a bit vector TTrunkSeq = seq[PTrunk] - TIntSet* {.final.} = object ## an efficient set of 'int' implemented as a - ## sparse bit set + IntSet* = object ## an efficient set of 'int' implemented as a sparse bit set counter, max: int head: PTrunk data: TTrunkSeq +{.deprecated: [TIntSet: IntSet].} + proc mustRehash(length, counter: int): bool {.inline.} = assert(length > counter) result = (length * 2 < counter * 3) or (length - counter < 4) diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim index b8f8d20b5..b7ca5a7af 100644 --- a/lib/pure/collections/lists.nim +++ b/lib/pure/collections/lists.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -15,52 +15,58 @@ when not defined(nimhygiene): {.pragma: dirty.} type - TDoublyLinkedNode* {.pure, - final.}[T] = object ## a node a doubly linked list consists of - next*, prev*: ref TDoublyLinkedNode[T] + DoublyLinkedNodeObj*[T] = object ## a node a doubly linked list consists of + next*, prev*: ref DoublyLinkedNodeObj[T] value*: T - PDoublyLinkedNode*[T] = ref TDoublyLinkedNode[T] + DoublyLinkedNode*[T] = ref DoublyLinkedNodeObj[T] - TSinglyLinkedNode* {.pure, - final.}[T] = object ## a node a singly linked list consists of - next*: ref TSinglyLinkedNode[T] + SinglyLinkedNodeObj*[T] = object ## a node a singly linked list consists of + next*: ref SinglyLinkedNodeObj[T] value*: T - PSinglyLinkedNode*[T] = ref TSinglyLinkedNode[T] + SinglyLinkedNode*[T] = ref SinglyLinkedNodeObj[T] - TSinglyLinkedList* {.pure, final.}[T] = object ## a singly linked list - head*, tail*: PSinglyLinkedNode[T] + SinglyLinkedList*[T] = object ## a singly linked list + head*, tail*: SinglyLinkedNode[T] - TDoublyLinkedList* {.pure, final.}[T] = object ## a doubly linked list - head*, tail*: PDoublyLinkedNode[T] + DoublyLinkedList*[T] = object ## a doubly linked list + head*, tail*: DoublyLinkedNode[T] - TSinglyLinkedRing* {.pure, final.}[T] = object ## a singly linked ring - head*: PSinglyLinkedNode[T] + SinglyLinkedRing*[T] = object ## a singly linked ring + head*: SinglyLinkedNode[T] - TDoublyLinkedRing* {.pure, final.}[T] = object ## a doubly linked ring - head*: PDoublyLinkedNode[T] + DoublyLinkedRing*[T] = object ## a doubly linked ring + head*: DoublyLinkedNode[T] -proc initSinglyLinkedList*[T](): TSinglyLinkedList[T] = +{.deprecated: [TDoublyLinkedNode: DoublyLinkedNodeObj, + PDoublyLinkedNode: DoublyLinkedNode, + TSinglyLinkedNode: SinglyLinkedNodeObj, + PSinglyLinkedNode: SinglyLinkedNode, + TDoublyLinkedList: DoublyLinkedList, + TSinglyLinkedRing: SinglyLinkedRing, + TDoublyLinkedRing: DoublyLinkedRing].} + +proc initSinglyLinkedList*[T](): SinglyLinkedList[T] = ## creates a new singly linked list that is empty. discard -proc initDoublyLinkedList*[T](): TDoublyLinkedList[T] = +proc initDoublyLinkedList*[T](): DoublyLinkedList[T] = ## creates a new doubly linked list that is empty. discard -proc initSinglyLinkedRing*[T](): TSinglyLinkedRing[T] = +proc initSinglyLinkedRing*[T](): SinglyLinkedRing[T] = ## creates a new singly linked ring that is empty. discard -proc initDoublyLinkedRing*[T](): TDoublyLinkedRing[T] = +proc initDoublyLinkedRing*[T](): DoublyLinkedRing[T] = ## creates a new doubly linked ring that is empty. discard -proc newDoublyLinkedNode*[T](value: T): PDoublyLinkedNode[T] = +proc newDoublyLinkedNode*[T](value: T): DoublyLinkedNode[T] = ## creates a new doubly linked node with the given `value`. new(result) result.value = value -proc newSinglyLinkedNode*[T](value: T): PSinglyLinkedNode[T] = +proc newSinglyLinkedNode*[T](value: T): SinglyLinkedNode[T] = ## creates a new singly linked node with the given `value`. new(result) result.value = value @@ -99,38 +105,38 @@ template findImpl() {.dirty.} = for x in nodes(L): if x.value == value: return x -iterator items*[T](L: TDoublyLinkedList[T]): T = +iterator items*[T](L: DoublyLinkedList[T]): T = ## yields every value of `L`. itemsListImpl() -iterator items*[T](L: TSinglyLinkedList[T]): T = +iterator items*[T](L: SinglyLinkedList[T]): T = ## yields every value of `L`. itemsListImpl() -iterator items*[T](L: TSinglyLinkedRing[T]): T = +iterator items*[T](L: SinglyLinkedRing[T]): T = ## yields every value of `L`. itemsRingImpl() -iterator items*[T](L: TDoublyLinkedRing[T]): T = +iterator items*[T](L: DoublyLinkedRing[T]): T = ## yields every value of `L`. itemsRingImpl() -iterator nodes*[T](L: TSinglyLinkedList[T]): PSinglyLinkedNode[T] = +iterator nodes*[T](L: SinglyLinkedList[T]): SinglyLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. nodesListImpl() -iterator nodes*[T](L: TDoublyLinkedList[T]): PDoublyLinkedNode[T] = +iterator nodes*[T](L: DoublyLinkedList[T]): DoublyLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. nodesListImpl() -iterator nodes*[T](L: TSinglyLinkedRing[T]): PSinglyLinkedNode[T] = +iterator nodes*[T](L: SinglyLinkedRing[T]): SinglyLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. nodesRingImpl() -iterator nodes*[T](L: TDoublyLinkedRing[T]): PDoublyLinkedNode[T] = +iterator nodes*[T](L: DoublyLinkedRing[T]): DoublyLinkedNode[T] = ## iterates over every node of `x`. Removing the current node from the ## list during traversal is supported. nodesRingImpl() @@ -142,33 +148,33 @@ template dollarImpl() {.dirty.} = result.add($x.value) result.add("]") -proc `$`*[T](L: TSinglyLinkedList[T]): string = +proc `$`*[T](L: SinglyLinkedList[T]): string = ## turns a list into its string representation. dollarImpl() -proc `$`*[T](L: TDoublyLinkedList[T]): string = +proc `$`*[T](L: DoublyLinkedList[T]): string = ## turns a list into its string representation. dollarImpl() -proc `$`*[T](L: TSinglyLinkedRing[T]): string = +proc `$`*[T](L: SinglyLinkedRing[T]): string = ## turns a list into its string representation. dollarImpl() -proc `$`*[T](L: TDoublyLinkedRing[T]): string = +proc `$`*[T](L: DoublyLinkedRing[T]): string = ## turns a list into its string representation. dollarImpl() -proc find*[T](L: TSinglyLinkedList[T], value: T): PSinglyLinkedNode[T] = +proc find*[T](L: SinglyLinkedList[T], value: T): SinglyLinkedNode[T] = ## searches in the list for a value. Returns nil if the value does not ## exist. findImpl() -proc find*[T](L: TDoublyLinkedList[T], value: T): PDoublyLinkedNode[T] = +proc find*[T](L: DoublyLinkedList[T], value: T): DoublyLinkedNode[T] = ## searches in the list for a value. Returns nil if the value does not ## exist. findImpl() -proc find*[T](L: TSinglyLinkedRing[T], value: T): PSinglyLinkedNode[T] = +proc find*[T](L: SinglyLinkedRing[T], value: T): SinglyLinkedNode[T] = ## searches in the list for a value. Returns nil if the value does not ## exist. findImpl() @@ -300,5 +306,3 @@ proc remove*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = L.head = nil else: L.head = L.head.prev - - diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim index 5481272f0..d1c94868a 100644 --- a/lib/pure/collections/queues.nim +++ b/lib/pure/collections/queues.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,13 +12,15 @@ import math type - TQueue* {.pure, final.}[T] = object ## a queue + Queue*[T] = object ## a queue data: seq[T] rd, wr, count, mask: int - + +{.deprecated: [TQueue: Queue].} + proc initQueue*[T](initialSize=4): TQueue[T] = ## creates a new queue. `initialSize` needs to be a power of 2. - assert IsPowerOfTwo(initialSize) + assert isPowerOfTwo(initialSize) result.mask = initialSize-1 newSeq(result.data, initialSize) diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 2629e9f40..9d22f0c3c 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2011 Alex Mitchell # # See the file "copying.txt", included in this @@ -31,7 +31,7 @@ proc concat*[T](seqs: varargs[seq[T]]): seq[T] = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## s1 = @[1, 2, 3] ## s2 = @[4, 5] @@ -50,7 +50,7 @@ proc concat*[T](seqs: varargs[seq[T]]): seq[T] = proc deduplicate*[T](seq1: seq[T]): seq[T] = ## Returns a new sequence without duplicates. ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4] ## dup2 = @["a", "a", "c", "d", "d"] @@ -69,7 +69,7 @@ proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] = ## fields `a` and `b`. If one sequence is shorter, the remaining items in the ## longer sequence are discarded. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## short = @[1, 2, 3] ## long = @[6, 5, 4, 3, 2, 1] @@ -104,7 +104,7 @@ proc distribute*[T](s: seq[T], num: int, spread = true): seq[seq[T]] = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let numbers = @[1, 2, 3, 4, 5, 6, 7] ## assert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]] ## assert numbers.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]] @@ -155,7 +155,7 @@ iterator filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): T = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let numbers = @[1, 4, 5, 8, 9, 7, 4] ## for n in filter(numbers, proc (x: int): bool = x mod 2 == 0): ## echo($n) @@ -169,7 +169,7 @@ proc filter*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): seq[T] = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## colors = @["red", "yellow", "black"] ## f1 = filter(colors, proc(x: string): bool = x.len < 6) @@ -184,7 +184,7 @@ proc keepIf*[T](seq1: var seq[T], pred: proc(item: T): bool {.closure.}) = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1] ## keepIf(floats, proc(x: float): bool = x > 10) ## assert floats == @[13.0, 12.5, 10.1] @@ -202,7 +202,7 @@ proc delete*[T](s: var seq[T], first=0, last=0) = ## ## Example: ## - ##.. code-block:: nimrod + ##.. code-block:: ## let outcome = @[1,1,1,1,1,1,1,1] ## var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1] ## dest.delete(3, 8) @@ -223,7 +223,7 @@ proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) = ## ## Example: ## - ##.. code-block:: nimrod + ##.. code-block:: ## var dest = @[1,1,1,1,1,1,1,1] ## let ## src = @[2,2,2,2,2,2] @@ -254,7 +254,7 @@ template filterIt*(seq1, pred: expr): expr {.immediate.} = ## the ``it`` variable for testing, like: ``filterIt("abcxyz", it == 'x')``. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## temperatures = @[-272.15, -2.0, 24.5, 44.31, 99.9, -113.44] ## acceptable = filterIt(temperatures, it < 50 and it > -10) @@ -273,7 +273,7 @@ template keepItIf*(varSeq, pred: expr) = ## the ``it`` variable for testing, like: ``keepItIf("abcxyz", it == 'x')``. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var candidates = @["foo", "bar", "baz", "foobar"] ## keepItIf(candidates, it.len == 3 and it[0] == 'b') ## assert candidates == @["bar", "baz"] @@ -292,7 +292,7 @@ template toSeq*(iter: expr): expr {.immediate.} = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## numeric = @[1, 2, 3, 4, 5, 6, 7, 8, 9] ## odd_numbers = toSeq(filter(numeric) do (x: int) -> bool: @@ -318,18 +318,18 @@ template foldl*(sequence, operation: expr): expr = ## the sequence of numbers 1, 2 and 3 will be parenthesized as (((1) - 2) - ## 3). Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## numbers = @[5, 9, 11] ## addition = foldl(numbers, a + b) ## substraction = foldl(numbers, a - b) ## multiplication = foldl(numbers, a * b) - ## words = @["nim", "rod", "is", "cool"] + ## words = @["nim", "is", "cool"] ## concatenation = foldl(words, a & b) ## assert addition == 25, "Addition is (((5)+9)+11)" ## assert substraction == -15, "Substraction is (((5)-9)-11)" ## assert multiplication == 495, "Multiplication is (((5)*9)*11)" - ## assert concatenation == "nimrodiscool" + ## assert concatenation == "nimiscool" assert sequence.len > 0, "Can't fold empty sequences" var result {.gensym.}: type(sequence[0]) result = sequence[0] @@ -354,18 +354,18 @@ template foldr*(sequence, operation: expr): expr = ## the sequence of numbers 1, 2 and 3 will be parenthesized as (1 - (2 - ## (3))). Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## numbers = @[5, 9, 11] ## addition = foldr(numbers, a + b) ## substraction = foldr(numbers, a - b) ## multiplication = foldr(numbers, a * b) - ## words = @["nim", "rod", "is", "cool"] + ## words = @["nim", "is", "cool"] ## concatenation = foldr(words, a & b) ## assert addition == 25, "Addition is (5+(9+(11)))" ## assert substraction == 7, "Substraction is (5-(9-(11)))" ## assert multiplication == 495, "Multiplication is (5*(9*(11)))" - ## assert concatenation == "nimrodiscool" + ## assert concatenation == "nimiscool" assert sequence.len > 0, "Can't fold empty sequences" var result {.gensym.}: type(sequence[0]) result = sequence[sequence.len - 1] @@ -384,7 +384,7 @@ template mapIt*(seq1, typ, pred: expr): expr = ## since the new returned sequence can have a different type than the ## original. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let ## nums = @[1, 2, 3, 4] ## strings = nums.mapIt(string, $(4 * it)) @@ -401,7 +401,7 @@ template mapIt*(varSeq, pred: expr) = ## expression. The expression has to return the same type as the sequence you ## are mutating. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var nums = @[1, 2, 3, 4] ## nums.mapIt(it * 3) ## assert nums[0] + nums[3] == 15 @@ -412,7 +412,7 @@ template mapIt*(varSeq, pred: expr) = template newSeqWith*(len: int, init: expr): expr = ## creates a new sequence, calling `init` to initialize each value. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var seq2D = newSeqWith(20, newSeq[bool](10)) ## seq2D[0][0] = true ## seq2D[1][0] = true @@ -503,12 +503,12 @@ when isMainModule: addition = foldl(numbers, a + b) substraction = foldl(numbers, a - b) multiplication = foldl(numbers, a * b) - words = @["nim", "rod", "is", "cool"] + words = @["nim", "is", "cool"] concatenation = foldl(words, a & b) assert addition == 25, "Addition is (((5)+9)+11)" assert substraction == -15, "Substraction is (((5)-9)-11)" assert multiplication == 495, "Multiplication is (((5)*9)*11)" - assert concatenation == "nimrodiscool" + assert concatenation == "nimiscool" block: # foldr tests let @@ -516,12 +516,12 @@ when isMainModule: addition = foldr(numbers, a + b) substraction = foldr(numbers, a - b) multiplication = foldr(numbers, a * b) - words = @["nim", "rod", "is", "cool"] + words = @["nim", "is", "cool"] concatenation = foldr(words, a & b) assert addition == 25, "Addition is (5+(9+(11)))" assert substraction == 7, "Substraction is (5-(9-(11)))" assert multiplication == 495, "Multiplication is (5*(9*(11)))" - assert concatenation == "nimrodiscool" + assert concatenation == "nimiscool" block: # delete tests let outcome = @[1,1,1,1,1,1,1,1] diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 3adf21a25..1201241f1 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -24,17 +24,19 @@ when not defined(nimhygiene): {.pragma: dirty.} type - TSlotEnum = enum seEmpty, seFilled, seDeleted - TKeyValuePair[A] = tuple[slot: TSlotEnum, key: A] - TKeyValuePairSeq[A] = seq[TKeyValuePair[A]] - TSet* {.final, myShallow.}[A] = object ## \ + SlotEnum = enum seEmpty, seFilled, seDeleted + KeyValuePair[A] = tuple[slot: SlotEnum, key: A] + KeyValuePairSeq[A] = seq[KeyValuePair[A]] + HashSet* {.myShallow.}[A] = object ## \ ## A generic hash set. ## - ## Use `init() <#init,TSet[A],int>`_ or `initSet[type]() <#initSet>`_ + ## Use `init() <#init,HashSet[A],int>`_ or `initSet[type]() <#initSet>`_ ## before calling other procs on it. - data: TKeyValuePairSeq[A] + data: KeyValuePairSeq[A] counter: int +{.deprecated: [TSet: HashSet].} + proc isValid*[A](s: TSet[A]): bool = ## Returns `true` if the set has been initialized with `initSet <#initSet>`_. ## @@ -43,7 +45,7 @@ proc isValid*[A](s: TSet[A]): bool = ## your own procs to verify that sets passed to your procs are correctly ## initialized. Example: ## - ## .. code-block :: nimrod + ## .. code-block :: ## proc savePreferences(options: TSet[string]) = ## assert options.isValid, "Pass an initialized set!" ## # Do stuff here, may crash in release builds! @@ -490,19 +492,20 @@ proc map*[A, B](data: TSet[A], op: proc (x: A): B {.closure.}): TSet[B] = # ------------------------------ ordered set ------------------------------ type - TOrderedKeyValuePair[A] = tuple[ - slot: TSlotEnum, next: int, key: A] - TOrderedKeyValuePairSeq[A] = seq[TOrderedKeyValuePair[A]] - TOrderedSet* {. - final, myShallow.}[A] = object ## \ + OrderedKeyValuePair[A] = tuple[ + slot: SlotEnum, next: int, key: A] + OrderedKeyValuePairSeq[A] = seq[OrderedKeyValuePair[A]] + OrderedSet* {.myShallow.}[A] = object ## \ ## A generic hash set that remembers insertion order. ## - ## Use `init() <#init,TOrderedSet[A],int>`_ or `initOrderedSet[type]() + ## Use `init() <#init,OrderedSet[A],int>`_ or `initOrderedSet[type]() ## <#initOrderedSet>`_ before calling other procs on it. data: TOrderedKeyValuePairSeq[A] counter, first, last: int -proc isValid*[A](s: TOrderedSet[A]): bool = +{.deprecated: [TOrderedSet: OrderedSet].} + +proc isValid*[A](s: OrderedSet[A]): bool = ## Returns `true` if the ordered set has been initialized with `initSet ## <#initOrderedSet>`_. ## @@ -511,13 +514,13 @@ proc isValid*[A](s: TOrderedSet[A]): bool = ## in your own procs to verify that ordered sets passed to your procs are ## correctly initialized. Example: ## - ## .. code-block :: nimrod + ## .. code-block:: ## proc saveTarotCards(cards: TOrderedSet[int]) = ## assert cards.isValid, "Pass an initialized set!" ## # Do stuff here, may crash in release builds! result = not s.data.isNil -proc len*[A](s: TOrderedSet[A]): int {.inline.} = +proc len*[A](s: OrderedSet[A]): int {.inline.} = ## Returns the number of keys in `s`. ## ## Due to an implementation detail you can call this proc on variables which @@ -734,14 +737,14 @@ proc `==`*[A](s, t: TOrderedSet[A]): bool = proc testModule() = ## Internal micro test to validate docstrings and such. block isValidTest: - var options: TSet[string] + var options: HashSet[string] proc savePreferences(options: TSet[string]) = assert options.isValid, "Pass an initialized set!" options = initSet[string]() options.savePreferences block lenTest: - var values: TSet[int] + var values: HashSet[int] assert(not values.isValid) assert values.len == 0 assert values.card == 0 @@ -835,14 +838,14 @@ proc testModule() = assert b == toSet(["1", "2", "3"]) block isValidTest: - var cards: TOrderedSet[string] + var cards: OrderedSet[string] proc saveTarotCards(cards: TOrderedSet[string]) = assert cards.isValid, "Pass an initialized set!" cards = initOrderedSet[string]() cards.saveTarotCards block lenTest: - var values: TOrderedSet[int] + var values: OrderedSet[int] assert(not values.isValid) assert values.len == 0 assert values.card == 0 @@ -879,7 +882,7 @@ proc testModule() = assert(a == b) # https://github.com/Araq/Nimrod/issues/1413 block initBlocks: - var a: TOrderedSet[int] + var a: OrderedSet[int] a.init(4) a.incl(2) a.init diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 95caf9195..320d54111 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -28,7 +28,7 @@ ## you add such a proc for your custom type everything will work. See this ## example: ## -## .. code-block:: nimrod +## .. code-block:: ## type ## Person = object ## firstName, lastName: string @@ -61,13 +61,15 @@ import {.pragma: myShallow.} type - TSlotEnum = enum seEmpty, seFilled, seDeleted - TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] - TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] - TTable* {.final, myShallow.}[A, B] = object ## generic hash table - data: TKeyValuePairSeq[A, B] + SlotEnum = enum seEmpty, seFilled, seDeleted + KeyValuePair[A, B] = tuple[slot: SlotEnum, key: A, val: B] + KeyValuePairSeq[A, B] = seq[KeyValuePair[A, B]] + Table* {.myShallow.}[A, B] = object ## generic hash table + data: KeyValuePairSeq[A, B] counter: int - PTable*[A,B] = ref TTable[A, B] + TableRef*[A,B] = ref Table[A, B] + +{.deprecated: [TTable: Table, PTable: TableRef].} when not defined(nimhygiene): {.pragma: dirty.} @@ -158,12 +160,12 @@ proc hasKey*[A, B](t: TTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], +proc rawInsert[A, B](t: var TTable[A, B], data: var KeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() proc enlarge[A, B](t: var TTable[A, B]) = - var n: TKeyValuePairSeq[A, B] + var n: KeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i].slot == seFilled: rawInsert(t, n, t.data[i].key, t.data[i].val) @@ -347,14 +349,16 @@ proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): PTable[C, B] = # ------------------------------ ordered table ------------------------------ type - TOrderedKeyValuePair[A, B] = tuple[ - slot: TSlotEnum, next: int, key: A, val: B] - TOrderedKeyValuePairSeq[A, B] = seq[TOrderedKeyValuePair[A, B]] - TOrderedTable* {. - final, myShallow.}[A, B] = object ## table that remembers insertion order - data: TOrderedKeyValuePairSeq[A, B] + OrderedKeyValuePair[A, B] = tuple[ + slot: SlotEnum, next: int, key: A, val: B] + OrderedKeyValuePairSeq[A, B] = seq[OrderedKeyValuePair[A, B]] + OrderedTable* {. + myShallow.}[A, B] = object ## table that remembers insertion order + data: OrderedKeyValuePairSeq[A, B] counter, first, last: int - POrderedTable*[A, B] = ref TOrderedTable[A, B] + OrderedTableRef*[A, B] = ref OrderedTable[A, B] + +{.deprecated: [TOrderedTable: OrderedTable, POrderedTable: OrderedTableRef].} proc len*[A, B](t: TOrderedTable[A, B]): int {.inline.} = ## returns the number of keys in `t`. @@ -608,11 +612,13 @@ proc sort*[A, B](t: POrderedTable[A, B], # ------------------------------ count tables ------------------------------- type - TCountTable* {.final, myShallow.}[ + CountTable* {.myShallow.}[ A] = object ## table that counts the number of each key data: seq[tuple[key: A, val: int]] counter: int - PCountTable*[A] = ref TCountTable[A] + CountTableRef*[A] = ref CountTable[A] + +{.deprecated: [TCountTable: CountTable, PCountTable: CountTableRef].} proc len*[A](t: TCountTable[A]): int = ## returns the number of keys in `t`. diff --git a/lib/pure/colors.nim b/lib/pure/colors.nim index 9f824e5de..7942255cb 100644 --- a/lib/pure/colors.nim +++ b/lib/pure/colors.nim @@ -1,5 +1,5 @@ # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,18 +12,20 @@ import strutils type - TColor* = distinct int ## a color stored as RGB + Color* = distinct int ## a color stored as RGB -proc `==` *(a, b: TColor): bool {.borrow.} +{.deprecated: [TColor: Color].} + +proc `==` *(a, b: Color): bool {.borrow.} ## compares two colors. -template extract(a: TColor, r, g, b: expr) {.immediate.}= +template extract(a: Color, r, g, b: expr) {.immediate.}= var r = a.int shr 16 and 0xff var g = a.int shr 8 and 0xff var b = a.int and 0xff template rawRGB(r, g, b: int): expr = - TColor(r shl 16 or g shl 8 or b) + Color(r shl 16 or g shl 8 or b) template colorOp(op: expr) {.immediate.} = extract(a, ar, ag, ab) @@ -38,23 +40,23 @@ proc satMinus(a, b: int): int {.inline.} = result = a -% b if result < 0: result = 0 -proc `+`*(a, b: TColor): TColor = +proc `+`*(a, b: Color): Color = ## adds two colors: This uses saturated artithmetic, so that each color ## component cannot overflow (255 is used as a maximum). colorOp(satPlus) -proc `-`*(a, b: TColor): TColor = +proc `-`*(a, b: Color): Color = ## substracts two colors: This uses saturated artithmetic, so that each color ## component cannot overflow (255 is used as a maximum). colorOp(satMinus) -proc extractRGB*(a: TColor): tuple[r, g, b: range[0..255]] = +proc extractRGB*(a: Color): tuple[r, g, b: range[0..255]] = ## extracts the red/green/blue components of the color `a`. result.r = a.int shr 16 and 0xff result.g = a.int shr 8 and 0xff result.b = a.int and 0xff -proc intensity*(a: TColor, f: float): TColor = +proc intensity*(a: Color, f: float): Color = ## returns `a` with intensity `f`. `f` should be a float from 0.0 (completely ## dark) to 1.0 (full color intensity). var r = toInt(toFloat(a.int shr 16 and 0xff) * f) @@ -65,7 +67,7 @@ proc intensity*(a: TColor, f: float): TColor = if b >% 255: b = 255 result = rawRGB(r, g, b) -template mix*(a, b: TColor, fn: expr): expr = +template mix*(a, b: Color, fn: expr): expr = ## uses `fn` to mix the colors `a` and `b`. `fn` is invoked for each component ## R, G, and B. This is a template because `fn` should be inlined and the ## compiler cannot inline proc pointers yet. If `fn`'s result is not in the @@ -84,146 +86,146 @@ template mix*(a, b: TColor, fn: expr): expr = const - colAliceBlue* = TColor(0xF0F8FF) - colAntiqueWhite* = TColor(0xFAEBD7) - colAqua* = TColor(0x00FFFF) - colAquamarine* = TColor(0x7FFFD4) - colAzure* = TColor(0xF0FFFF) - colBeige* = TColor(0xF5F5DC) - colBisque* = TColor(0xFFE4C4) - colBlack* = TColor(0x000000) - colBlanchedAlmond* = TColor(0xFFEBCD) - colBlue* = TColor(0x0000FF) - colBlueViolet* = TColor(0x8A2BE2) - colBrown* = TColor(0xA52A2A) - colBurlyWood* = TColor(0xDEB887) - colCadetBlue* = TColor(0x5F9EA0) - colChartreuse* = TColor(0x7FFF00) - colChocolate* = TColor(0xD2691E) - colCoral* = TColor(0xFF7F50) - colCornflowerBlue* = TColor(0x6495ED) - colCornsilk* = TColor(0xFFF8DC) - colCrimson* = TColor(0xDC143C) - colCyan* = TColor(0x00FFFF) - colDarkBlue* = TColor(0x00008B) - colDarkCyan* = TColor(0x008B8B) - colDarkGoldenRod* = TColor(0xB8860B) - colDarkGray* = TColor(0xA9A9A9) - colDarkGreen* = TColor(0x006400) - colDarkKhaki* = TColor(0xBDB76B) - colDarkMagenta* = TColor(0x8B008B) - colDarkOliveGreen* = TColor(0x556B2F) - colDarkorange* = TColor(0xFF8C00) - colDarkOrchid* = TColor(0x9932CC) - colDarkRed* = TColor(0x8B0000) - colDarkSalmon* = TColor(0xE9967A) - colDarkSeaGreen* = TColor(0x8FBC8F) - colDarkSlateBlue* = TColor(0x483D8B) - colDarkSlateGray* = TColor(0x2F4F4F) - colDarkTurquoise* = TColor(0x00CED1) - colDarkViolet* = TColor(0x9400D3) - colDeepPink* = TColor(0xFF1493) - colDeepSkyBlue* = TColor(0x00BFFF) - colDimGray* = TColor(0x696969) - colDodgerBlue* = TColor(0x1E90FF) - colFireBrick* = TColor(0xB22222) - colFloralWhite* = TColor(0xFFFAF0) - colForestGreen* = TColor(0x228B22) - colFuchsia* = TColor(0xFF00FF) - colGainsboro* = TColor(0xDCDCDC) - colGhostWhite* = TColor(0xF8F8FF) - colGold* = TColor(0xFFD700) - colGoldenRod* = TColor(0xDAA520) - colGray* = TColor(0x808080) - colGreen* = TColor(0x008000) - colGreenYellow* = TColor(0xADFF2F) - colHoneyDew* = TColor(0xF0FFF0) - colHotPink* = TColor(0xFF69B4) - colIndianRed* = TColor(0xCD5C5C) - colIndigo* = TColor(0x4B0082) - colIvory* = TColor(0xFFFFF0) - colKhaki* = TColor(0xF0E68C) - colLavender* = TColor(0xE6E6FA) - colLavenderBlush* = TColor(0xFFF0F5) - colLawnGreen* = TColor(0x7CFC00) - colLemonChiffon* = TColor(0xFFFACD) - colLightBlue* = TColor(0xADD8E6) - colLightCoral* = TColor(0xF08080) - colLightCyan* = TColor(0xE0FFFF) - colLightGoldenRodYellow* = TColor(0xFAFAD2) - colLightGrey* = TColor(0xD3D3D3) - colLightGreen* = TColor(0x90EE90) - colLightPink* = TColor(0xFFB6C1) - colLightSalmon* = TColor(0xFFA07A) - colLightSeaGreen* = TColor(0x20B2AA) - colLightSkyBlue* = TColor(0x87CEFA) - colLightSlateGray* = TColor(0x778899) - colLightSteelBlue* = TColor(0xB0C4DE) - colLightYellow* = TColor(0xFFFFE0) - colLime* = TColor(0x00FF00) - colLimeGreen* = TColor(0x32CD32) - colLinen* = TColor(0xFAF0E6) - colMagenta* = TColor(0xFF00FF) - colMaroon* = TColor(0x800000) - colMediumAquaMarine* = TColor(0x66CDAA) - colMediumBlue* = TColor(0x0000CD) - colMediumOrchid* = TColor(0xBA55D3) - colMediumPurple* = TColor(0x9370D8) - colMediumSeaGreen* = TColor(0x3CB371) - colMediumSlateBlue* = TColor(0x7B68EE) - colMediumSpringGreen* = TColor(0x00FA9A) - colMediumTurquoise* = TColor(0x48D1CC) - colMediumVioletRed* = TColor(0xC71585) - colMidnightBlue* = TColor(0x191970) - colMintCream* = TColor(0xF5FFFA) - colMistyRose* = TColor(0xFFE4E1) - colMoccasin* = TColor(0xFFE4B5) - colNavajoWhite* = TColor(0xFFDEAD) - colNavy* = TColor(0x000080) - colOldLace* = TColor(0xFDF5E6) - colOlive* = TColor(0x808000) - colOliveDrab* = TColor(0x6B8E23) - colOrange* = TColor(0xFFA500) - colOrangeRed* = TColor(0xFF4500) - colOrchid* = TColor(0xDA70D6) - colPaleGoldenRod* = TColor(0xEEE8AA) - colPaleGreen* = TColor(0x98FB98) - colPaleTurquoise* = TColor(0xAFEEEE) - colPaleVioletRed* = TColor(0xD87093) - colPapayaWhip* = TColor(0xFFEFD5) - colPeachPuff* = TColor(0xFFDAB9) - colPeru* = TColor(0xCD853F) - colPink* = TColor(0xFFC0CB) - colPlum* = TColor(0xDDA0DD) - colPowderBlue* = TColor(0xB0E0E6) - colPurple* = TColor(0x800080) - colRed* = TColor(0xFF0000) - colRosyBrown* = TColor(0xBC8F8F) - colRoyalBlue* = TColor(0x4169E1) - colSaddleBrown* = TColor(0x8B4513) - colSalmon* = TColor(0xFA8072) - colSandyBrown* = TColor(0xF4A460) - colSeaGreen* = TColor(0x2E8B57) - colSeaShell* = TColor(0xFFF5EE) - colSienna* = TColor(0xA0522D) - colSilver* = TColor(0xC0C0C0) - colSkyBlue* = TColor(0x87CEEB) - colSlateBlue* = TColor(0x6A5ACD) - colSlateGray* = TColor(0x708090) - colSnow* = TColor(0xFFFAFA) - colSpringGreen* = TColor(0x00FF7F) - colSteelBlue* = TColor(0x4682B4) - colTan* = TColor(0xD2B48C) - colTeal* = TColor(0x008080) - colThistle* = TColor(0xD8BFD8) - colTomato* = TColor(0xFF6347) - colTurquoise* = TColor(0x40E0D0) - colViolet* = TColor(0xEE82EE) - colWheat* = TColor(0xF5DEB3) - colWhite* = TColor(0xFFFFFF) - colWhiteSmoke* = TColor(0xF5F5F5) - colYellow* = TColor(0xFFFF00) - colYellowGreen* = TColor(0x9ACD32) + colAliceBlue* = Color(0xF0F8FF) + colAntiqueWhite* = Color(0xFAEBD7) + colAqua* = Color(0x00FFFF) + colAquamarine* = Color(0x7FFFD4) + colAzure* = Color(0xF0FFFF) + colBeige* = Color(0xF5F5DC) + colBisque* = Color(0xFFE4C4) + colBlack* = Color(0x000000) + colBlanchedAlmond* = Color(0xFFEBCD) + colBlue* = Color(0x0000FF) + colBlueViolet* = Color(0x8A2BE2) + colBrown* = Color(0xA52A2A) + colBurlyWood* = Color(0xDEB887) + colCadetBlue* = Color(0x5F9EA0) + colChartreuse* = Color(0x7FFF00) + colChocolate* = Color(0xD2691E) + colCoral* = Color(0xFF7F50) + colCornflowerBlue* = Color(0x6495ED) + colCornsilk* = Color(0xFFF8DC) + colCrimson* = Color(0xDC143C) + colCyan* = Color(0x00FFFF) + colDarkBlue* = Color(0x00008B) + colDarkCyan* = Color(0x008B8B) + colDarkGoldenRod* = Color(0xB8860B) + colDarkGray* = Color(0xA9A9A9) + colDarkGreen* = Color(0x006400) + colDarkKhaki* = Color(0xBDB76B) + colDarkMagenta* = Color(0x8B008B) + colDarkOliveGreen* = Color(0x556B2F) + colDarkorange* = Color(0xFF8C00) + colDarkOrchid* = Color(0x9932CC) + colDarkRed* = Color(0x8B0000) + colDarkSalmon* = Color(0xE9967A) + colDarkSeaGreen* = Color(0x8FBC8F) + colDarkSlateBlue* = Color(0x483D8B) + colDarkSlateGray* = Color(0x2F4F4F) + colDarkTurquoise* = Color(0x00CED1) + colDarkViolet* = Color(0x9400D3) + colDeepPink* = Color(0xFF1493) + colDeepSkyBlue* = Color(0x00BFFF) + colDimGray* = Color(0x696969) + colDodgerBlue* = Color(0x1E90FF) + colFireBrick* = Color(0xB22222) + colFloralWhite* = Color(0xFFFAF0) + colForestGreen* = Color(0x228B22) + colFuchsia* = Color(0xFF00FF) + colGainsboro* = Color(0xDCDCDC) + colGhostWhite* = Color(0xF8F8FF) + colGold* = Color(0xFFD700) + colGoldenRod* = Color(0xDAA520) + colGray* = Color(0x808080) + colGreen* = Color(0x008000) + colGreenYellow* = Color(0xADFF2F) + colHoneyDew* = Color(0xF0FFF0) + colHotPink* = Color(0xFF69B4) + colIndianRed* = Color(0xCD5C5C) + colIndigo* = Color(0x4B0082) + colIvory* = Color(0xFFFFF0) + colKhaki* = Color(0xF0E68C) + colLavender* = Color(0xE6E6FA) + colLavenderBlush* = Color(0xFFF0F5) + colLawnGreen* = Color(0x7CFC00) + colLemonChiffon* = Color(0xFFFACD) + colLightBlue* = Color(0xADD8E6) + colLightCoral* = Color(0xF08080) + colLightCyan* = Color(0xE0FFFF) + colLightGoldenRodYellow* = Color(0xFAFAD2) + colLightGrey* = Color(0xD3D3D3) + colLightGreen* = Color(0x90EE90) + colLightPink* = Color(0xFFB6C1) + colLightSalmon* = Color(0xFFA07A) + colLightSeaGreen* = Color(0x20B2AA) + colLightSkyBlue* = Color(0x87CEFA) + colLightSlateGray* = Color(0x778899) + colLightSteelBlue* = Color(0xB0C4DE) + colLightYellow* = Color(0xFFFFE0) + colLime* = Color(0x00FF00) + colLimeGreen* = Color(0x32CD32) + colLinen* = Color(0xFAF0E6) + colMagenta* = Color(0xFF00FF) + colMaroon* = Color(0x800000) + colMediumAquaMarine* = Color(0x66CDAA) + colMediumBlue* = Color(0x0000CD) + colMediumOrchid* = Color(0xBA55D3) + colMediumPurple* = Color(0x9370D8) + colMediumSeaGreen* = Color(0x3CB371) + colMediumSlateBlue* = Color(0x7B68EE) + colMediumSpringGreen* = Color(0x00FA9A) + colMediumTurquoise* = Color(0x48D1CC) + colMediumVioletRed* = Color(0xC71585) + colMidnightBlue* = Color(0x191970) + colMintCream* = Color(0xF5FFFA) + colMistyRose* = Color(0xFFE4E1) + colMoccasin* = Color(0xFFE4B5) + colNavajoWhite* = Color(0xFFDEAD) + colNavy* = Color(0x000080) + colOldLace* = Color(0xFDF5E6) + colOlive* = Color(0x808000) + colOliveDrab* = Color(0x6B8E23) + colOrange* = Color(0xFFA500) + colOrangeRed* = Color(0xFF4500) + colOrchid* = Color(0xDA70D6) + colPaleGoldenRod* = Color(0xEEE8AA) + colPaleGreen* = Color(0x98FB98) + colPaleTurquoise* = Color(0xAFEEEE) + colPaleVioletRed* = Color(0xD87093) + colPapayaWhip* = Color(0xFFEFD5) + colPeachPuff* = Color(0xFFDAB9) + colPeru* = Color(0xCD853F) + colPink* = Color(0xFFC0CB) + colPlum* = Color(0xDDA0DD) + colPowderBlue* = Color(0xB0E0E6) + colPurple* = Color(0x800080) + colRed* = Color(0xFF0000) + colRosyBrown* = Color(0xBC8F8F) + colRoyalBlue* = Color(0x4169E1) + colSaddleBrown* = Color(0x8B4513) + colSalmon* = Color(0xFA8072) + colSandyBrown* = Color(0xF4A460) + colSeaGreen* = Color(0x2E8B57) + colSeaShell* = Color(0xFFF5EE) + colSienna* = Color(0xA0522D) + colSilver* = Color(0xC0C0C0) + colSkyBlue* = Color(0x87CEEB) + colSlateBlue* = Color(0x6A5ACD) + colSlateGray* = Color(0x708090) + colSnow* = Color(0xFFFAFA) + colSpringGreen* = Color(0x00FF7F) + colSteelBlue* = Color(0x4682B4) + colTan* = Color(0xD2B48C) + colTeal* = Color(0x008080) + colThistle* = Color(0xD8BFD8) + colTomato* = Color(0xFF6347) + colTurquoise* = Color(0x40E0D0) + colViolet* = Color(0xEE82EE) + colWheat* = Color(0xF5DEB3) + colWhite* = Color(0xFFFFFF) + colWhiteSmoke* = Color(0xF5F5F5) + colYellow* = Color(0xFFFF00) + colYellowGreen* = Color(0x9ACD32) colorNames = [ ("aliceblue", colAliceBlue), @@ -367,11 +369,11 @@ const ("yellow", colYellow), ("yellowgreen", colYellowGreen)] -proc `$`*(c: TColor): string = +proc `$`*(c: Color): string = ## converts a color into its textual representation. Example: ``#00FF00``. result = '#' & toHex(int(c), 6) -proc binaryStrSearch(x: openarray[tuple[name: string, col: TColor]], +proc binaryStrSearch(x: openArray[tuple[name: string, col: Color]], y: string): int = var a = 0 var b = len(x) - 1 @@ -383,14 +385,14 @@ proc binaryStrSearch(x: openarray[tuple[name: string, col: TColor]], else: return mid result = - 1 -proc parseColor*(name: string): TColor = +proc parseColor*(name: string): Color = ## parses `name` to a color value. If no valid color could be ## parsed ``EInvalidValue`` is raised. if name[0] == '#': - result = TColor(parseHexInt(name)) + result = Color(parseHexInt(name)) else: var idx = binaryStrSearch(colorNames, name) - if idx < 0: raise newException(EInvalidValue, "unkown color: " & name) + if idx < 0: raise newException(ValueError, "unkown color: " & name) result = colorNames[idx][1] proc isColor*(name: string): bool = @@ -403,7 +405,7 @@ proc isColor*(name: string): bool = else: result = binaryStrSearch(colorNames, name) >= 0 -proc rgb*(r, g, b: range[0..255]): TColor = +proc rgb*(r, g, b: range[0..255]): Color = ## constructs a color from RGB values. result = rawRGB(r, g, b) diff --git a/lib/pure/complex.nim b/lib/pure/complex.nim index 1392b73aa..d31d56f83 100644 --- a/lib/pure/complex.nim +++ b/lib/pure/complex.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -25,9 +25,11 @@ const type - TComplex* = tuple[re, im: float] + Complex* = tuple[re, im: float] ## a complex number, consisting of a real and an imaginary part +{.deprecated: [TComplex: Complex].} + proc `==` *(x, y: TComplex): bool = ## Compare two complex numbers `x` and `y` for equality. result = x.re == y.re and x.im == y.im diff --git a/lib/pure/concurrency/cpuload.nim b/lib/pure/concurrency/cpuload.nim index 3cf6a7392..74a639be1 100644 --- a/lib/pure/concurrency/cpuload.nim +++ b/lib/pure/concurrency/cpuload.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index e0a2ac678..dfde610f2 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Implements Nimrod's 'spawn'. +## Implements Nim's 'spawn'. when not compileOption("threads"): {.error: "Threadpool requires --threads:on option.".} diff --git a/lib/pure/cookies.nim b/lib/pure/cookies.nim index 54ca164c7..c85f60915 100644 --- a/lib/pure/cookies.nim +++ b/lib/pure/cookies.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -11,7 +11,7 @@ import strtabs, times -proc parseCookies*(s: string): PStringTable = +proc parseCookies*(s: string): StringTableRef = ## parses cookies into a string table. result = newStringTable(modeCaseInsensitive) var i = 0 @@ -39,7 +39,7 @@ proc setCookie*(key, value: string, domain = "", path = "", if path != "": result.add("; Path=" & path) if expires != "": result.add("; Expires=" & expires) -proc setCookie*(key, value: string, expires: TTimeInfo, +proc setCookie*(key, value: string, expires: TimeInfo, domain = "", path = "", noName = false): string = ## Creates a command in the format of ## ``Set-Cookie: key=value; Domain=...; ...`` @@ -50,7 +50,7 @@ proc setCookie*(key, value: string, expires: TTimeInfo, format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"), noName) when isMainModule: - var tim = TTime(int(getTime()) + 76 * (60 * 60 * 24)) + var tim = Time(int(getTime()) + 76 * (60 * 60 * 24)) echo(setCookie("test", "value", tim.getGMTime())) diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim index 54a553173..77ef20ad9 100644 --- a/lib/pure/dynlib.nim +++ b/lib/pure/dynlib.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,7 +12,9 @@ ## Windows ``LoadLibrary``. type - TLibHandle* = pointer ## a handle to a dynamically loaded library + LibHandle* = pointer ## a handle to a dynamically loaded library + +{.deprecated: [TLibHandle: LibHandle].} proc loadLib*(path: string, global_symbols=false): TLibHandle ## loads a library from `path`. Returns nil if the library could not diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim index 633ea6020..f10c4e40b 100644 --- a/lib/pure/encodings.nim +++ b/lib/pure/encodings.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -14,18 +14,20 @@ import os, parseutils, strutils when not defined(windows): type - TConverter = object - PConverter* = ptr TConverter ## can convert between two character sets + ConverterObj = object + EncodingConverter* = ptr ConverterObj ## can convert between two character sets else: type - TCodePage = distinct int32 - PConverter* = object - dest, src: TCodePage + CodePage = distinct int32 + EncodingConverter* = object + dest, src: CodePage type - EInvalidEncoding* = object of EInvalidValue ## exception that is raised - ## for encoding errors + EncodingError* = object of ValueError ## exception that is raised + ## for encoding errors + +{.deprecated: [EInvalidEncoding: EncodingError, PConverter: EncodingConverter].} when defined(windows): proc eqEncodingNames(a, b: string): bool = @@ -214,26 +216,26 @@ when defined(windows): defaultChar: array[0..1, char] leadByte: array[0..12-1, char] - proc getCPInfo(codePage: TCodePage, lpCPInfo: var TCpInfo): int32 {. + proc getCPInfo(codePage: CodePage, lpCPInfo: var TCpInfo): int32 {. stdcall, importc: "GetCPInfo", dynlib: "kernel32".} - proc nameToCodePage(name: string): TCodePage = + proc nameToCodePage(name: string): CodePage = var nameAsInt: int if parseInt(name, nameAsInt) == 0: nameAsInt = -1 for no, na in items(winEncodings): - if no == nameAsInt or eqEncodingNames(na, name): return TCodePage(no) - result = TCodePage(-1) + if no == nameAsInt or eqEncodingNames(na, name): return CodePage(no) + result = CodePage(-1) - proc codePageToName(c: TCodePage): string = + proc codePageToName(c: CodePage): string = for no, na in items(winEncodings): if no == int(c): return if na.len != 0: na else: $no result = "" - proc getACP(): TCodePage {.stdcall, importc: "GetACP", dynlib: "kernel32".} + proc getACP(): CodePage {.stdcall, importc: "GetACP", dynlib: "kernel32".} proc multiByteToWideChar( - codePage: TCodePage, + codePage: CodePage, dwFlags: int32, lpMultiByteStr: cstring, cbMultiByte: cint, @@ -242,7 +244,7 @@ when defined(windows): stdcall, importc: "MultiByteToWideChar", dynlib: "kernel32".} proc wideCharToMultiByte( - codePage: TCodePage, + codePage: CodePage, dwFlags: int32, lpWideCharStr: cstring, cchWideChar: cint, diff --git a/lib/pure/endians.nim b/lib/pure/endians.nim index 73017464d..6e33d4624 100644 --- a/lib/pure/endians.nim +++ b/lib/pure/endians.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/events.nim b/lib/pure/events.nim index 5830d9109..7868050d1 100644 --- a/lib/pure/events.nim +++ b/lib/pure/events.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2011 Alex Mitchell # # See the file "copying.txt", included in this @@ -14,10 +14,10 @@ ## it was inspired by Python's PyEE module. There are two ways you can use ## events: one is a python-inspired way; the other is more of a C-style way. ## -## .. code-block:: Nimrod +## .. code-block:: Nim ## var ee = initEventEmitter() -## var genericargs: TEventArgs -## proc handleevent(e: TEventArgs) = +## var genericargs: EventArgs +## proc handleevent(e: EventArgs) = ## echo("Handled!") ## ## # Python way @@ -27,21 +27,24 @@ ## # C/Java way ## # Declare a type ## type -## TSomeObject = object of TObject -## SomeEvent: TEventHandler -## var myobj: TSomeObject +## SomeObject = object of RootObj +## SomeEvent: EventHandler +## var myobj: SomeObject ## myobj.SomeEvent = initEventHandler("SomeEvent") ## myobj.SomeEvent.addHandler(handleevent) ## ee.emit(myobj.SomeEvent, genericargs) type - TEventArgs* = object of TObject ## Base object for event arguments that are passed to callback functions. - TEventHandler* = tuple[name: string, handlers: seq[proc(e:TEventArgs) {.closure.}]] ## An eventhandler for an event. + EventArgs* = object of RootObj ## Base object for event arguments that are passed to callback functions. + EventHandler* = tuple[name: string, handlers: seq[proc(e: EventArgs) {.closure.}]] ## An eventhandler for an event. type - TEventEmitter* = object {.pure, final.} ## An object that fires events and holds event handlers for an object. - s: seq[TEventHandler] - EInvalidEvent* = object of EInvalidValue + EventEmitter* = object ## An object that fires events and holds event handlers for an object. + s: seq[EventHandler] + EventError* = object of ValueError + +{.deprecated: [TEventArgs: EventArgs, TEventHandler: EventHandler, + TEventEmitter: EventEmitter, EInvalidEvent: EventError].} proc initEventHandler*(name: string): TEventHandler = ## Initializes an EventHandler with the specified name and returns it. diff --git a/lib/pure/fsmonitor.nim b/lib/pure/fsmonitor.nim index b35466771..cfee8d0ea 100644 --- a/lib/pure/fsmonitor.nim +++ b/lib/pure/fsmonitor.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -25,13 +25,13 @@ else: import inotify, os, asyncio, tables type - PFSMonitor* = ref TFSMonitor - TFSMonitor = object of TObject + FSMonitor* = ref FSMonitorObj + FSMonitorObj = object of RootObj fd: cint - handleEvent: proc (m: PFSMonitor, ev: TMonitorEvent) {.closure.} + handleEvent: proc (m: FSMonitor, ev: MonitorEvent) {.closure.} targets: TTable[cint, string] - TMonitorEventType* = enum ## Monitor event type + MonitorEventType* = enum ## Monitor event type MonitorAccess, ## File was accessed. MonitorAttrib, ## Metadata changed. MonitorCloseWrite, ## Writtable file was closed. @@ -45,8 +45,8 @@ type MonitorOpen, ## File was opened. MonitorAll ## Filter for all event types. - TMonitorEvent* = object - case kind*: TMonitorEventType ## Type of the event. + MonitorEvent* = object + case kind*: MonitorEventType ## Type of the event. of MonitorMoveSelf, MonitorMoved: oldPath*: string ## Old absolute location newPath*: string ## New absolute location @@ -58,6 +58,9 @@ type ## watched. wd*: cint ## Watch descriptor. +{.deprecated: [PFSMonitor: FSMonitor, TFSMonitor: FSMonitorObj, + TMonitorEventType: MonitorEventType, TMonitorEvent: MonitorEvent].} + const MaxEvents = 100 @@ -67,7 +70,7 @@ proc newMonitor*(): PFSMonitor = result.targets = initTable[cint, string]() result.fd = inotifyInit() if result.fd < 0: - OSError(OSLastError()) + raiseOSError(osLastError()) proc add*(monitor: PFSMonitor, target: string, filters = {MonitorAll}): cint {.discardable.} = @@ -101,7 +104,7 @@ proc del*(monitor: PFSMonitor, wd: cint) = ## ## If ``wd`` is not a part of ``monitor`` an EOS error is raised. if inotifyRmWatch(monitor.fd, wd) < 0: - OSError(OSLastError()) + raiseOSError(osLastError()) proc getEvent(m: PFSMonitor, fd: cint): seq[TMonitorEvent] = result = @[] @@ -197,18 +200,19 @@ proc register*(d: PDispatcher, monitor: PFSMonitor, d.register(deleg) when isMainModule: - var disp = newDispatcher() - var monitor = newMonitor() - echo monitor.add("/home/dom/inotifytests/") - disp.register(monitor, - proc (m: PFSMonitor, ev: TMonitorEvent) = - echo("Got event: ", ev.kind) - if ev.kind == MonitorMoved: - echo("From ", ev.oldPath, " to ", ev.newPath) - echo("Name is ", ev.name) - else: - echo("Name ", ev.name, " fullname ", ev.fullName)) - - while true: - if not disp.poll(): break - + proc main = + var disp = newDispatcher() + var monitor = newMonitor() + echo monitor.add("/home/dom/inotifytests/") + disp.register(monitor, + proc (m: PFSMonitor, ev: TMonitorEvent) = + echo("Got event: ", ev.kind) + if ev.kind == MonitorMoved: + echo("From ", ev.oldPath, " to ", ev.newPath) + echo("Name is ", ev.name) + else: + echo("Name ", ev.name, " fullname ", ev.fullName)) + + while true: + if not disp.poll(): break + main() diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim index d4922d1ab..ccb0929f6 100644 --- a/lib/pure/ftpclient.nim +++ b/lib/pure/ftpclient.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -14,8 +14,8 @@ import sockets, strutils, parseutils, times, os, asyncio ## by `RFC 959 `_. ## ## This module provides both a synchronous and asynchronous implementation. -## The asynchronous implementation requires you to use the ``AsyncFTPClient`` -## function. You are then required to register the ``PAsyncFTPClient`` with a +## The asynchronous implementation requires you to use the ``asyncFTPClient`` +## function. You are then required to register the ``AsyncFTPClient`` with a ## asyncio dispatcher using the ``register`` function. Take a look at the ## asyncio module documentation for more information. ## @@ -24,64 +24,63 @@ import sockets, strutils, parseutils, times, os, asyncio ## ## Here is some example usage of this module: ## -## .. code-block:: Nimrod -## var ftp = FTPClient("example.org", user = "user", pass = "pass") +## .. code-block:: Nim +## var ftp = ftpClient("example.org", user = "user", pass = "pass") ## ftp.connect() ## ftp.retrFile("file.ext", "file.ext") ## ## **Warning:** The API of this module is unstable, and therefore is subject ## to change. - type - TFTPClient* = object of TObject + FTPClientObj* = object of RootObj case isAsync: bool of false: - csock: TSocket # Command connection socket - dsock: TSocket # Data connection socket + csock: Socket # Command connection socket + dsock: Socket # Data connection socket else: dummyA, dummyB: pointer # workaround a Nimrod API issue - asyncCSock: PAsyncSocket - asyncDSock: PAsyncSocket - handleEvent*: proc (ftp: PAsyncFTPClient, ev: TFTPEvent){.closure,gcsafe.} - disp: PDispatcher - asyncDSockID: PDelegate + asyncCSock: AsyncSocket + asyncDSock: AsyncSocket + handleEvent*: proc (ftp: AsyncFTPClient, ev: FTPEvent){.closure,gcsafe.} + disp: Dispatcher + asyncDSockID: Delegate user, pass: string address: string - port: TPort + port: Port jobInProgress: bool - job: ref TFTPJob + job: ref FTPJob dsockConnected: bool - PFTPClient* = ref TFTPClient + FTPClient* = ref FTPClientObj FTPJobType* = enum JRetrText, JRetr, JStore - TFTPJob = object + FTPJob = object prc: proc (ftp: PFTPClient, async: bool): bool {.nimcall, gcsafe.} case typ*: FTPJobType of JRetrText: lines: string of JRetr, JStore: - file: TFile + file: File filename: string - total: biggestInt # In bytes. - progress: biggestInt # In bytes. - oneSecond: biggestInt # Bytes transferred in one second. + total: BiggestInt # In bytes. + progress: BiggestInt # In bytes. + oneSecond: BiggestInt # Bytes transferred in one second. lastProgressReport: float # Time toStore: string # Data left to upload (Only used with async) else: nil - PAsyncFTPClient* = ref TAsyncFTPClient ## Async alternative to TFTPClient. - TAsyncFTPClient* = object of TFTPClient + AsyncFTPClient* = ref AsyncFTPClientObj ## Async alternative to TFTPClient. + AsyncFTPClientObj* = object of FTPClientObj FTPEventType* = enum EvTransferProgress, EvLines, EvRetr, EvStore - TFTPEvent* = object ## Event + FTPEvent* = object ## Event filename*: string case typ*: FTPEventType of EvLines: @@ -89,13 +88,19 @@ type of EvRetr, EvStore: ## Retr/Store operation finished. nil of EvTransferProgress: - bytesTotal*: biggestInt ## Bytes total. - bytesFinished*: biggestInt ## Bytes transferred. - speed*: biggestInt ## Speed in bytes/s + bytesTotal*: BiggestInt ## Bytes total. + bytesFinished*: BiggestInt ## Bytes transferred. + speed*: BiggestInt ## Speed in bytes/s currentJob*: FTPJobType ## The current job being performed. - EInvalidReply* = object of ESynch - EFTP* = object of ESynch + ReplyError* = object of IOError + FTPError* = object of IOError + +{.deprecated: [ + TFTPClient: FTPClientObj, TFTPJob: FTPJob, PAsyncFTPClient: AsyncFTPClient, + TAsyncFTPClient: AsyncFTPClientObj, TFTPEvent: FTPEvent, + EInvalidReply: ReplyError, EFTP: FTPError +].} proc ftpClient*(address: string, port = TPort(21), user, pass = ""): PFTPClient = diff --git a/lib/pure/future.nim b/lib/pure/future.nim index b7df05207..c467d2c73 100644 --- a/lib/pure/future.nim +++ b/lib/pure/future.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this diff --git a/lib/pure/gentabs.nim b/lib/pure/gentabs.nim index 617473c14..87a55ea1e 100644 --- a/lib/pure/gentabs.nim +++ b/lib/pure/gentabs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,6 +12,8 @@ ## may be any Nimrod or user defined type. This module supports matching ## of keys in case-sensitive, case-insensitive and style-insensitive modes. +{.deprecated.} + import os, hashes, strutils diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index 740355e55..30daaf2dc 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,13 +8,13 @@ # ## This module implements efficient computations of hash values for diverse -## Nimrod types. All the procs are based on these two building blocks: the `!& +## Nim types. All the procs are based on these two building blocks: the `!& ## proc <#!&>`_ used to start or mix a hash value, and the `!$ proc <#!$>`_ ## used to *finish* the hash value. If you want to implement hash procs for ## your custom types you will end up writing the following kind of skeleton of ## code: ## -## .. code-block:: nimrod +## .. code-block:: Nim ## proc hash(x: Something): THash = ## ## Computes a THash from `x`. ## var h: THash = 0 @@ -29,7 +29,7 @@ ## like for example objects made up of ``strings``, you can simply hash ## together the hash value of the individual fields: ## -## .. code-block:: nimrod +## .. code-block:: Nim ## proc hash(x: Something): THash = ## ## Computes a THash from `x`. ## var h: THash = 0 diff --git a/lib/pure/htmlgen.nim b/lib/pure/htmlgen.nim index b9d6aec7b..a1440b6f4 100644 --- a/lib/pure/htmlgen.nim +++ b/lib/pure/htmlgen.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -18,13 +18,13 @@ ## ## Example: ## -## .. code-block:: nimrod -## var nim = "Nimrod" -## echo h1(a(href="http://nimrod-lang.org", nim)) +## .. code-block:: Nim +## var nim = "Nim" +## echo h1(a(href="http://nim-lang.org", nim)) ## ## Writes the string:: ## -##

Nimrod

+##

Nim

## import @@ -53,8 +53,7 @@ proc delete[T](s: var seq[T], attr: T): bool = setLen(s, L-1) result = true -proc xmlCheckedTag*(e: PNimrodNode, tag: string, - optAttr = "", reqAttr = "", +proc xmlCheckedTag*(e: PNimrodNode, tag: string, optAttr = "", reqAttr = "", isLeaf = false): PNimrodNode {.compileTime.} = ## use this procedure to define a new XML tag @@ -484,7 +483,7 @@ macro `var`*(e: expr): expr {.immediate.} = result = xmlCheckedTag(e, "var", commonAttr) when isMainModule: - var nim = "Nimrod" - echo h1(a(href="http://nimrod-code.org", nim)) + var nim = "Nim" + echo h1(a(href="http://nim-lang.org", nim)) echo form(action="test", `accept-charset` = "Content-Type") diff --git a/lib/pure/htmlparser.nim b/lib/pure/htmlparser.nim index c38eb7063..54e917110 100644 --- a/lib/pure/htmlparser.nim +++ b/lib/pure/htmlparser.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,7 +13,7 @@ ## It can be used to parse a wild HTML document and output it as valid XHTML ## document (well, if you are lucky): ## -## .. code-block:: nimrod +## .. code-block:: Nim ## ## echo loadHtml("mydirty.html") ## @@ -29,7 +29,7 @@ ## and write back the modified version. In this case we look for hyperlinks ## ending with the extension ``.rst`` and convert them to ``.html``. ## -## .. code-block:: nimrod +## .. code-block:: Nim ## ## import htmlparser ## import xmltree # To use '$' for PXmlNode diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 9bacc80d6..3fbb04fc8 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Dominik Picheta, Andreas Rumpf # # See the file "copying.txt", included in this @@ -21,7 +21,7 @@ ## This example uses HTTP GET to retrieve ## ``http://google.com`` ## -## .. code-block:: nimrod +## .. code-block:: Nim ## echo(getContent("http://google.com")) ## ## Using HTTP POST @@ -31,7 +31,7 @@ ## uses ``multipart/form-data`` as the ``Content-Type`` to send the HTML to ## the server. ## -## .. code-block:: nimrod +## .. code-block:: Nim ## var headers: string = "Content-Type: multipart/form-data; boundary=xyz\c\L" ## var body: string = "--xyz\c\L" ## # soap 1.2 output @@ -54,7 +54,7 @@ ## on many operating systems. httpclient will use SSL automatically if you give ## any of the functions a url with the ``https`` schema, for example: ## ``https://github.com/``, you also have to compile with ``ssl`` defined like so: -## ``nimrod c -d:ssl ...``. +## ``nim c -d:ssl ...``. ## ## Timeouts ## ======== @@ -80,34 +80,38 @@ import asyncnet, asyncdispatch import rawsockets type - TResponse* = tuple[ + Response* = tuple[ version: string, status: string, - headers: PStringTable, + headers: StringTableRef, body: string] - PProxy* = ref object + Proxy* = ref object url*: TUrl auth*: string - EInvalidProtocol* = object of ESynch ## exception that is raised when server + ProtocolError* = object of IOError ## exception that is raised when server ## does not conform to the implemented ## protocol - EHttpRequestErr* = object of ESynch ## Thrown in the ``getContent`` proc - ## and ``postContent`` proc, - ## when the server returns an error + HttpRequestError* = object of IOError ## Thrown in the ``getContent`` proc + ## and ``postContent`` proc, + ## when the server returns an error -const defUserAgent* = "Nimrod httpclient/0.1" +{.deprecated: [TResponse: Response, PProxy: Proxy, + EInvalidProtocol: ProtocolError, EHttpRequestErr: HttpRequestError +].} + +const defUserAgent* = "Nim httpclient/0.1" proc httpError(msg: string) = - var e: ref EInvalidProtocol + var e: ref ProtocolError new(e) e.msg = msg raise e proc fileError(msg: string) = - var e: ref EIO + var e: ref IOError new(e) e.msg = msg raise e @@ -232,7 +236,7 @@ proc parseResponse(s: TSocket, getBody: bool, timeout: int): TResponse = result.body = "" type - THttpMethod* = enum ## the requested HttpMethod + HttpMethod* = enum ## the requested HttpMethod httpHEAD, ## Asks for the response identical to the one that would ## correspond to a GET request, but without the response ## body. @@ -250,6 +254,8 @@ type httpCONNECT ## Converts the request connection to a transparent ## TCP/IP tunnel, usually used for proxies. +{.deprecated: [THttpMethod: HttpMethod].} + when not defined(ssl): type PSSLContext = ref object let defaultSSLContext: PSSLContext = nil @@ -288,7 +294,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", add(headers, "\c\L") var s = socket() - if s == InvalidSocket: osError(osLastError()) + if s == InvalidSocket: raiseOSError(osLastError()) var port = sockets.TPort(80) if r.scheme == "https": when defined(ssl): @@ -431,16 +437,18 @@ proc generateHeaders(r: TURL, httpMethod: THttpMethod, add(result, "\c\L") type - PAsyncHttpClient* = ref object - socket: PAsyncSocket + AsyncHttpClient* = ref object + socket: AsyncSocket connected: bool currentURL: TURL ## Where we are currently connected. - headers: PStringTable + headers: StringTableRef maxRedirects: int userAgent: string +{.deprecated: [PAsyncHttpClient: AsyncHttpClient].} + proc newAsyncHttpClient*(userAgent = defUserAgent, - maxRedirects = 5): PAsyncHttpClient = + maxRedirects = 5): AsyncHttpClient = ## Creates a new PAsyncHttpClient instance. ## ## ``userAgent`` specifies the user agent that will be used when making @@ -453,7 +461,7 @@ proc newAsyncHttpClient*(userAgent = defUserAgent, result.userAgent = defUserAgent result.maxRedirects = maxRedirects -proc close*(client: PAsyncHttpClient) = +proc close*(client: AsyncHttpClient) = ## Closes any connections held by the HTTP client. if client.connected: client.socket.close() diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim index 885742b64..a41dc9450 100644 --- a/lib/pure/httpserver.nim +++ b/lib/pure/httpserver.nim @@ -145,7 +145,7 @@ when false: var buf = alloc(contentLength) if recv(client, buf, contentLength) != contentLength: dealloc(buf) - OSError() + raiseOSError() var inp = process.inputStream inp.writeData(buf, contentLength) dealloc(buf) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 383f924ca..b2c0db3d1 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf, Dominik Picheta +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -35,7 +35,7 @@ import hashes, strutils, lexbase, streams, unicode type - TJsonEventKind* = enum ## enumeration of all events that may occur when parsing + JsonEventKind* = enum ## enumeration of all events that may occur when parsing jsonError, ## an error ocurred during parsing jsonEof, ## end of file reached jsonString, ## a string literal @@ -65,7 +65,7 @@ type tkColon, tkComma - TJsonError* = enum ## enumeration that lists all errors that can occur + JsonError* = enum ## enumeration that lists all errors that can occur errNone, ## no error errInvalidToken, ## invalid token errStringExpected, ## string expected @@ -78,20 +78,23 @@ type errEofExpected, ## EOF expected errExprExpected ## expr expected - TParserState = enum + ParserState = enum stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma, stateExpectObjectComma, stateExpectColon, stateExpectValue - TJsonParser* = object of TBaseLexer ## the parser object. + JsonParser* = object of TBaseLexer ## the parser object. a: string tok: TTokKind - kind: TJsonEventKind - err: TJsonError - state: seq[TParserState] + kind: JsonEventKind + err: JsonError + state: seq[ParserState] filename: string + +{.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError, + TJsonParser: JsonParser].} const - errorMessages: array [TJsonError, string] = [ + errorMessages: array [JsonError, string] = [ "no error", "invalid token", "string expected", @@ -116,7 +119,7 @@ const "{", "}", "[", "]", ":", "," ] -proc open*(my: var TJsonParser, input: PStream, filename: string) = +proc open*(my: var JsonParser, input: PStream, filename: string) = ## initializes the parser with an input stream. `Filename` is only used ## for nice error messages. lexbase.open(my, input) @@ -125,49 +128,49 @@ proc open*(my: var TJsonParser, input: PStream, filename: string) = my.kind = jsonError my.a = "" -proc close*(my: var TJsonParser) {.inline.} = +proc close*(my: var JsonParser) {.inline.} = ## closes the parser `my` and its associated input stream. lexbase.close(my) -proc str*(my: TJsonParser): string {.inline.} = +proc str*(my: JsonParser): string {.inline.} = ## returns the character data for the events: ``jsonInt``, ``jsonFloat``, ## ``jsonString`` assert(my.kind in {jsonInt, jsonFloat, jsonString}) return my.a -proc getInt*(my: TJsonParser): BiggestInt {.inline.} = +proc getInt*(my: JsonParser): BiggestInt {.inline.} = ## returns the number for the event: ``jsonInt`` assert(my.kind == jsonInt) return parseBiggestInt(my.a) -proc getFloat*(my: TJsonParser): float {.inline.} = +proc getFloat*(my: JsonParser): float {.inline.} = ## returns the number for the event: ``jsonFloat`` assert(my.kind == jsonFloat) return parseFloat(my.a) -proc kind*(my: TJsonParser): TJsonEventKind {.inline.} = +proc kind*(my: JsonParser): JsonEventKind {.inline.} = ## returns the current event type for the JSON parser return my.kind -proc getColumn*(my: TJsonParser): int {.inline.} = +proc getColumn*(my: JsonParser): int {.inline.} = ## get the current column the parser has arrived at. result = getColNumber(my, my.bufpos) -proc getLine*(my: TJsonParser): int {.inline.} = +proc getLine*(my: JsonParser): int {.inline.} = ## get the current line the parser has arrived at. result = my.lineNumber -proc getFilename*(my: TJsonParser): string {.inline.} = +proc getFilename*(my: JsonParser): string {.inline.} = ## get the filename of the file that the parser processes. result = my.filename -proc errorMsg*(my: TJsonParser): string = +proc errorMsg*(my: JsonParser): string = ## returns a helpful error message for the event ``jsonError`` assert(my.kind == jsonError) result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]] -proc errorMsgExpected*(my: TJsonParser, e: string): string = +proc errorMsgExpected*(my: JsonParser, e: string): string = ## returns an error message "`e` expected" in the same format as the ## other error messages result = "$1($2, $3) Error: $4" % [ @@ -181,7 +184,7 @@ proc handleHexChar(c: char, x: var int): bool = of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10) else: result = false # error -proc parseString(my: var TJsonParser): TTokKind = +proc parseString(my: var JsonParser): TTokKind = result = tkString var pos = my.bufpos + 1 var buf = my.buf @@ -239,7 +242,7 @@ proc parseString(my: var TJsonParser): TTokKind = inc(pos) my.bufpos = pos # store back -proc skip(my: var TJsonParser) = +proc skip(my: var JsonParser) = var pos = my.bufpos var buf = my.buf while true: @@ -297,7 +300,7 @@ proc skip(my: var TJsonParser) = break my.bufpos = pos -proc parseNumber(my: var TJsonParser) = +proc parseNumber(my: var JsonParser) = var pos = my.bufpos var buf = my.buf if buf[pos] == '-': @@ -328,7 +331,7 @@ proc parseNumber(my: var TJsonParser) = inc(pos) my.bufpos = pos -proc parseName(my: var TJsonParser) = +proc parseName(my: var JsonParser) = var pos = my.bufpos var buf = my.buf if buf[pos] in IdentStartChars: @@ -337,7 +340,7 @@ proc parseName(my: var TJsonParser) = inc(pos) my.bufpos = pos -proc getTok(my: var TJsonParser): TTokKind = +proc getTok(my: var JsonParser): TTokKind = setLen(my.a, 0) skip(my) # skip whitespace, comments case my.buf[my.bufpos] @@ -381,7 +384,7 @@ proc getTok(my: var TJsonParser): TTokKind = result = tkError my.tok = result -proc next*(my: var TJsonParser) = +proc next*(my: var JsonParser) = ## retrieves the first/next event. This controls the parser. var tk = getTok(my) var i = my.state.len-1 @@ -529,7 +532,10 @@ type of JArray: elems*: seq[PJsonNode] - EJsonParsingError* = object of ValueError ## is raised for a JSON error + JsonParsingError* = object of ValueError ## is raised for a JSON error + +{.deprecated: [EJsonParsingError: JsonParsingError, TJsonNode: JsonNodeObj, + PJsonNode: JsonNode, TJsonNodeKind: JsonNodeKind].} proc raiseParseErr*(p: TJsonParser, msg: string) {.noinline, noreturn.} = ## raises an `EJsonParsingError` exception. diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim index 0e10b95e4..361374177 100644 --- a/lib/pure/lexbase.nim +++ b/lib/pure/lexbase.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2009 Andreas Rumpf # # See the file "copying.txt", included in this @@ -36,6 +36,8 @@ type lineStart: int # index of last line start in buffer fileOpened: bool +{.deprecated: [TBaseLexer: BaseLexer].} + proc open*(L: var TBaseLexer, input: PStream, bufLen: int = 8192) ## inits the TBaseLexer with a stream to read from diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index 284384b37..a0773f40b 100644 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this @@ -26,7 +26,7 @@ ## The following example demonstrates logging to three different handlers ## simultaneously: ## -## .. code-block:: nimrod +## .. code-block:: nim ## ## var L = newConsoleLogger() ## var fL = newFileLogger("test.log", fmtStr = verboseFmtStr) @@ -42,7 +42,7 @@ import strutils, os, times type - TLevel* = enum ## logging level + Level* = enum ## logging level lvlAll, ## all levels active lvlDebug, ## debug level (and any above) active lvlInfo, ## info level (and any above) active @@ -52,7 +52,7 @@ type lvlNone ## no levels active const - LevelNames*: array [TLevel, string] = [ + LevelNames*: array [Level, string] = [ "DEBUG", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "NONE" ] @@ -60,26 +60,29 @@ const verboseFmtStr* = "$date $time " type - PLogger* = ref object of PObject ## abstract logger; the base type of all loggers - levelThreshold*: TLevel ## only messages of level >= levelThreshold + Logger* = ref object of RootObj ## abstract logger; the base type of all loggers + levelThreshold*: Leve l ## only messages of level >= levelThreshold ## should be processed fmtStr: string ## = defaultFmtStr by default, see substituteLog for $date etc. - PConsoleLogger* = ref object of PLogger ## logger that writes the messages to the - ## console + ConsoleLogger* = ref object of Logger ## logger that writes the messages to the + ## console - PFileLogger* = ref object of PLogger ## logger that writes the messages to a file + FileLogger* = ref object of Logger ## logger that writes the messages to a file f: TFile - PRollingFileLogger* = ref object of PFileLogger ## logger that writes the - ## messages to a file and - ## performs log rotation + RollingFileLogger* = ref object of FileLogger ## logger that writes the + ## messages to a file and + ## performs log rotation maxLines: int # maximum number of lines curLine : int baseName: string # initial filename - baseMode: TFileMode # initial file mode + baseMode: FileMode # initial file mode logFiles: int # how many log files already created, e.g. basename.1, basename.2... +{.deprecated: [TLevel: Level, PLogger: Logger, PConsoleLogger: ConsoleLogger, + PFileLogger: FileLogger, PRollingFileLogger: RollingFileLogger].} + proc substituteLog(frmt: string): string = ## converts $date to the current date ## converts $time to the current time @@ -105,7 +108,7 @@ proc substituteLog(frmt: string): string = of "appdir": result.add(app.splitFile.dir) of "appname": result.add(app.splitFile.name) -method log*(logger: PLogger, level: TLevel, +method log*(logger: Logger, level: Level, frmt: string, args: varargs[string, `$`]) {.raises: [EBase], tags: [FTime, FWriteIO, FReadIO].} = ## Override this method in custom loggers. Default implementation does ## nothing. diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim index 789f6ad76..7857e9a94 100644 --- a/lib/pure/marshal.nim +++ b/lib/pure/marshal.nim @@ -1,20 +1,20 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2013 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # ## This module contains procs for serialization and deseralization of -## arbitrary Nimrod data structures. The serialization format uses JSON. +## arbitrary Nim data structures. The serialization format uses JSON. ## ## **Restriction**: For objects their type is **not** serialized. This means ## essentially that it does not work if the object has some other runtime ## type than its compiletime type: ## -## .. code-block:: nimrod +## .. code-block:: nim ## ## type ## TA = object @@ -211,7 +211,7 @@ proc loadAny(p: var TJsonParser, a: TAny, t: var TTable[biggestInt, pointer]) = raiseParseErr(p, "float expected") of akRange: loadAny(p, a.skipRange, t) -proc loadAny(s: PStream, a: TAny, t: var TTable[biggestInt, pointer]) = +proc loadAny(s: PStream, a: TAny, t: var TTable[BiggestInt, pointer]) = var p: TJsonParser open(p, s, "unknown file") next(p) diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim index 2db7fa660..c3ad7235f 100644 --- a/lib/pure/matchers.nim +++ b/lib/pure/matchers.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -44,7 +44,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect, "aero", "jobs", "museum": return true return false -proc parseInt*(s: string, value: var int, validRange: TSlice[int]) {. +proc parseInt*(s: string, value: var int, validRange: Slice[int]) {. noSideEffect, rtl, extern: "nmatchParseInt".} = ## parses `s` into an integer in the range `validRange`. If successful, ## `value` is modified to contain the result. Otherwise no exception is @@ -53,7 +53,7 @@ proc parseInt*(s: string, value: var int, validRange: TSlice[int]) {. var x = value try: discard parseutils.parseInt(s, x, 0) - except EOverflow: + except OverflowError: discard if x in validRange: value = x diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 99849d98e..c6a0305d2 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -1,7 +1,7 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -9,7 +9,7 @@ ## Constructive mathematics is naturally typed. -- Simon Thompson ## -## Basic math routines for Nimrod. +## Basic math routines for Nim. ## This module is available for the `JavaScript target ## `_. @@ -41,8 +41,8 @@ const ## for Nimrod's ``float`` type. type - TFloatClass* = enum ## describes the class a floating point value belongs to. - ## This is the type that is returned by `classify`. + FloatClass* = enum ## describes the class a floating point value belongs to. + ## This is the type that is returned by `classify`. fcNormal, ## value is an ordinary nonzero floating point value fcSubnormal, ## value is a subnormal (a very small) floating point value fcZero, ## value is zero @@ -51,10 +51,10 @@ type fcInf, ## value is positive infinity fcNegInf ## value is negative infinity -proc classify*(x: float): TFloatClass = +proc classify*(x: float): FloatClass = ## classifies a floating point value. Returns `x`'s class as specified by - ## `TFloatClass`. - + ## `FloatClass`. + # JavaScript and most C compilers have no classify: if x == 0.0: if 1.0/x == Inf: @@ -287,12 +287,14 @@ proc random[T](a: openArray[T]): T = result = a[random(a.low..a.len)] type - TRunningStat* {.pure,final.} = object ## an accumulator for statistical data - n*: int ## number of pushed data - sum*, min*, max*, mean*: float ## self-explaining + RunningStat* = object ## an accumulator for statistical data + n*: int ## number of pushed data + sum*, min*, max*, mean*: float ## self-explaining oldM, oldS, newS: float -proc push*(s: var TRunningStat, x: float) = +{.deprecated: [TFloatClass: FloatClass, TRunningStat: RunningStat].} + +proc push*(s: var RunningStat, x: float) = ## pushes a value `x` for processing inc(s.n) # See Knuth TAOCP vol 2, 3rd edition, page 232 @@ -313,16 +315,16 @@ proc push*(s: var TRunningStat, x: float) = s.oldS = s.newS s.sum = s.sum + x -proc push*(s: var TRunningStat, x: int) = +proc push*(s: var RunningStat, x: int) = ## pushes a value `x` for processing. `x` is simply converted to ``float`` ## and the other push operation is called. push(s, toFloat(x)) -proc variance*(s: TRunningStat): float = +proc variance*(s: RunningStat): float = ## computes the current variance of `s` if s.n > 1: result = s.newS / (toFloat(s.n - 1)) -proc standardDeviation*(s: TRunningStat): float = +proc standardDeviation*(s: RunningStat): float = ## computes the current standard deviation of `s` result = sqrt(variance(s)) diff --git a/lib/pure/md5.nim b/lib/pure/md5.nim index 0328932fd..322dbbe1d 100644 --- a/lib/pure/md5.nim +++ b/lib/pure/md5.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index 5577fa5cf..8712df7f6 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Nimrod Contributors # # See the file "copying.txt", included in this @@ -22,7 +22,7 @@ else: import os type - TMemFile* = object {.pure.} ## represents a memory mapped file + MemFile* = object ## represents a memory mapped file mem*: pointer ## a pointer to the memory mapped file. The pointer ## can be used directly to change the contents of the ## file, if it was opened with write access. @@ -34,8 +34,9 @@ type else: handle: cint +{.deprecated: [TMemFile: MemFile].} -proc mapMem*(m: var TMemFile, mode: FileMode = fmRead, +proc mapMem*(m: var MemFile, mode: FileMode = fmRead, mappedSize = -1, offset = 0): pointer = var readonly = mode == fmRead when defined(windows): @@ -60,27 +61,27 @@ proc mapMem*(m: var TMemFile, mode: FileMode = fmRead, osError(osLastError()) -proc unmapMem*(f: var TMemFile, p: pointer, size: int) = +proc unmapMem*(f: var MemFile, p: pointer, size: int) = ## unmaps the memory region ``(p, ", nodecl.} proc gettime(dummy: ptr cint): cint {.importc: "time", header: "".} @@ -79,12 +81,12 @@ proc genOid*(): TOid = result.fuzz = fuzz bigEndian32(addr result.count, addr(i)) -proc generatedTime*(oid: TOid): TTime = +proc generatedTime*(oid: Oid): Time = ## returns the generated timestamp of the OID. var tmp: int32 var dummy = oid.time bigEndian32(addr(tmp), addr(dummy)) - result = TTime(tmp) + result = Time(tmp) when isMainModule: let xo = genOID() diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 483044d0a..0b4cf24c5 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -29,18 +29,23 @@ else: include "system/ansi_c" type - FReadEnv* = object of ReadIOEffect ## effect that denotes a read - ## from an environment variable - FWriteEnv* = object of WriteIOEffect ## effect that denotes a write - ## to an environment variable + ReadEnvEffect* = object of ReadIOEffect ## effect that denotes a read + ## from an environment variable + WriteEnvEffect* = object of WriteIOEffect ## effect that denotes a write + ## to an environment variable - FReadDir* = object of ReadIOEffect ## effect that denotes a write operation to - ## the directory structure - FWriteDir* = object of WriteIOEffect ## effect that denotes a write operation to - ## the directory structure + ReadDirEffect* = object of ReadIOEffect ## effect that denotes a write + ## operation to the directory structure + WriteDirEffect* = object of WriteIOEffect ## effect that denotes a write operation to + ## the directory structure - TOSErrorCode* = distinct int32 ## Specifies an OS Error Code. + OSErrorCode* = distinct int32 ## Specifies an OS Error Code. +{.deprecated: [FReadEnv: ReadEnvEffect, FWriteEnv: WriteEnvEffect, + FReadDir: ReadDirEffect, + FWriteDir: WriteDirEffect, + TOSErrorCode: OSErrorCode +].} const doslike = defined(windows) or defined(OS2) or defined(DOS) # DOS-like filesystem @@ -204,7 +209,8 @@ proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} = result = $os.strerror(errno) {.push warning[deprecated]: off.} -proc osError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = +proc raiseOSError*(msg: string = "") {.noinline, rtl, extern: "nos$1", + deprecated.} = ## raises an EOS exception with the given message ``msg``. ## If ``msg == ""``, the operating system's error flag ## (``errno``) is converted to a readable error message. On Windows @@ -219,10 +225,12 @@ proc osError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} = raise newException(OSError, msg) {.pop.} -proc `==`*(err1, err2: TOSErrorCode): bool {.borrow.} -proc `$`*(err: TOSErrorCode): string {.borrow.} +{.deprecated: [osError: raiseOSError].} -proc osErrorMsg*(errorCode: TOSErrorCode): string = +proc `==`*(err1, err2: OSErrorCode): bool {.borrow.} +proc `$`*(err: OSErrorCode): string {.borrow.} + +proc osErrorMsg*(errorCode: OSErrorCode): string = ## Converts an OS error code into a human readable string. ## ## The error code can be retrieved using the ``OSLastError`` proc. @@ -249,10 +257,10 @@ proc osErrorMsg*(errorCode: TOSErrorCode): string = result = $msgbuf if msgbuf != nil: localFree(msgbuf) else: - if errorCode != TOSErrorCode(0'i32): + if errorCode != OSErrorCode(0'i32): result = $os.strerror(errorCode.int32) -proc osError*(errorCode: TOSErrorCode) = +proc raiseOSError*(errorCode: OSErrorCode) = ## Raises an ``EOS`` exception. The ``errorCode`` will determine the ## message, ``OSErrorMsg`` will be used to get this message. ## @@ -268,7 +276,7 @@ proc osError*(errorCode: TOSErrorCode) = raise e {.push stackTrace:off.} -proc osLastError*(): TOSErrorCode = +proc osLastError*(): OSErrorCode = ## Retrieves the last operating system error code. ## ## This procedure is useful in the event when an OS call fails. In that case @@ -285,7 +293,7 @@ proc osLastError*(): TOSErrorCode = when defined(windows): result = TOSErrorCode(getLastError()) else: - result = TOSErrorCode(errno) + result = OSErrorCode(errno) {.pop.} proc unixToNativePath*(path: string, drive=""): string {. @@ -371,7 +379,7 @@ when defined(windows): f.cFileName[1].int == dot and f.cFileName[2].int == 0) proc existsFile*(filename: string): bool {.rtl, extern: "nos$1", - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## Returns true if the file exists, false otherwise. when defined(windows): when useWinUnicode: @@ -384,7 +392,7 @@ proc existsFile*(filename: string): bool {.rtl, extern: "nos$1", var res: TStat return stat(filename, res) >= 0'i32 and S_ISREG(res.st_mode) -proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [FReadDir].} = +proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [ReadDirEffect].} = ## Returns true iff the directory `dir` exists. If `dir` is a file, false ## is returned. when defined(windows): @@ -399,7 +407,7 @@ proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [FReadDir].} = return stat(dir, res) >= 0'i32 and S_ISDIR(res.st_mode) proc symlinkExists*(link: string): bool {.rtl, extern: "nos$1", - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## Returns true iff the symlink `link` exists. Will return true ## regardless of whether the link points to a directory or file. when defined(windows): @@ -701,7 +709,7 @@ proc extractFilename*(path: string): string {. result = splitPath(path).tail proc expandFilename*(filename: string): string {.rtl, extern: "nos$1", - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## Returns the full path of `filename`, raises EOS in case of an error. when defined(windows): const bufsize = 3072'i32 @@ -800,7 +808,7 @@ when defined(Windows): ) proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1", - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## Returns True if both pathname arguments refer to the same physical ## file or directory. Raises an exception if any of the files does not ## exist or information about it can not be obtained. @@ -883,7 +891,7 @@ type fpOthersRead ## read access for others proc getFilePermissions*(filename: string): set[TFilePermission] {. - rtl, extern: "nos$1", tags: [FReadDir].} = + rtl, extern: "nos$1", tags: [ReadDirEffect].} = ## retrieves file permissions for `filename`. `OSError` is raised in case of ## an error. On Windows, only the ``readonly`` flag is checked, every other ## permission is available in any case. @@ -915,7 +923,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {. result = {fpUserExec..fpOthersRead} proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. - rtl, extern: "nos$1", tags: [FWriteDir].} = + rtl, extern: "nos$1", tags: [WriteDirEffect].} = ## sets the file permissions for `filename`. `OSError` is raised in case of ## an error. On Windows, only the ``readonly`` flag is changed, depending on ## ``fpUserWrite``. @@ -1014,7 +1022,7 @@ when defined(Windows): template setFileAttributes(file, attrs: expr): expr {.immediate.} = setFileAttributesA(file, attrs) -proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = +proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} = ## Removes the `file`. If this fails, `EOS` is raised. This does not fail ## if the file never existed in the first place. ## On Windows, ignores the read-only attribute. @@ -1076,7 +1084,7 @@ when defined(windows): while true: var eend = strEnd(e) add(environment, $e) - e = cast[WideCString](cast[ByteAddress](eend)+2) + e = cast[WideCString](cast[TAddress](eend)+2) if eend[1].int == 0: break discard freeEnvironmentStringsW(env) else: @@ -1130,7 +1138,7 @@ proc findEnvVar(key: string): int = if startsWith(environment[i], temp): return i return -1 -proc getEnv*(key: string): TaintedString {.tags: [FReadEnv].} = +proc getEnv*(key: string): TaintedString {.tags: [ReadEnvEffect].} = ## Returns the value of the `environment variable`:idx: named `key`. ## ## If the variable does not exist, "" is returned. To distinguish @@ -1144,13 +1152,13 @@ proc getEnv*(key: string): TaintedString {.tags: [FReadEnv].} = if env == nil: return TaintedString("") result = TaintedString($env) -proc existsEnv*(key: string): bool {.tags: [FReadEnv].} = +proc existsEnv*(key: string): bool {.tags: [ReadEnvEffect].} = ## Checks whether the environment variable named `key` exists. ## Returns true if it exists, false otherwise. if c_getenv(key) != nil: return true else: return findEnvVar(key) >= 0 -proc putEnv*(key, val: string) {.tags: [FWriteEnv].} = +proc putEnv*(key, val: string) {.tags: [WriteEnvEffect].} = ## Sets the value of the `environment variable`:idx: named `key` to `val`. ## If an error occurs, `EInvalidEnvVar` is raised. @@ -1175,7 +1183,7 @@ proc putEnv*(key, val: string) {.tags: [FWriteEnv].} = else: if setEnvironmentVariableA(key, val) == 0'i32: osError(osLastError()) -iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [FReadEnv].} = +iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [ReadEnvEffect].} = ## Iterate over all `environments variables`:idx:. In the first component ## of the tuple is the name of the current variable stored, in the second ## its value. @@ -1185,7 +1193,7 @@ iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [FReadEnv].} = yield (TaintedString(substr(environment[i], 0, p-1)), TaintedString(substr(environment[i], p+1))) -iterator walkFiles*(pattern: string): string {.tags: [FReadDir].} = +iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} = ## Iterate over all the files that match the `pattern`. On POSIX this uses ## the `glob`:idx: call. ## @@ -1225,7 +1233,7 @@ type pcLinkToDir ## path refers to a symbolic link to a directory iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## walks over the directory `dir` and yields for each directory or file in ## `dir`. The component type and full path for each item is returned. ## Walking is not recursive. @@ -1278,7 +1286,7 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. discard closedir(d) iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {. - tags: [FReadDir].} = + tags: [ReadDirEffect].} = ## walks over the directory `dir` and yields for each file in `dir`. The ## full path for each file is returned. ## **Warning**: @@ -1318,7 +1326,7 @@ proc rawRemoveDir(dir: string) = if rmdir(dir) != 0'i32 and errno != ENOENT: osError(osLastError()) proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [ - FWriteDir, FReadDir].} = + WriteDirEffect, ReadDirEffect].} = ## Removes the directory `dir` including all subdirectories and files ## in `dir` (recursively). ## @@ -1345,7 +1353,7 @@ proc rawCreateDir(dir: string) = if res == 0'i32 and getLastError() != 183'i32: osError(osLastError()) -proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = +proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} = ## Creates the `directory`:idx: `dir`. ## ## The directory may contain several subdirectories that do not exist yet. @@ -1568,7 +1576,7 @@ proc copyDirWithPermissions*(source, dest: string, proc inclFilePermissions*(filename: string, permissions: set[TFilePermission]) {. - rtl, extern: "nos$1", tags: [FReadDir, FWriteDir].} = + rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} = ## a convenience procedure for: ## ## .. code-block:: nimrod @@ -1577,14 +1585,14 @@ proc inclFilePermissions*(filename: string, proc exclFilePermissions*(filename: string, permissions: set[TFilePermission]) {. - rtl, extern: "nos$1", tags: [FReadDir, FWriteDir].} = + rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} = ## a convenience procedure for: ## ## .. code-block:: nimrod ## setFilePermissions(filename, getFilePermissions(filename)-permissions) setFilePermissions(filename, getFilePermissions(filename)-permissions) -proc getHomeDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = +proc getHomeDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect].} = ## Returns the home directory of the current user. ## ## This proc is wrapped by the expandTilde proc for the convenience of @@ -1592,12 +1600,12 @@ proc getHomeDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = when defined(windows): return string(getEnv("USERPROFILE")) & "\\" else: return string(getEnv("HOME")) & "/" -proc getConfigDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = +proc getConfigDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect].} = ## Returns the config directory of the current user for applications. when defined(windows): return string(getEnv("APPDATA")) & "\\" else: return string(getEnv("HOME")) & "/.config/" -proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = +proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect].} = ## Returns the temporary directory of the current user for applications to ## save temporary files in. when defined(windows): return string(getEnv("TEMP")) & "\\" @@ -1605,7 +1613,7 @@ proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} = when defined(nimdoc): # Common forward declaration docstring block for parameter retrieval procs. - proc paramCount*(): int {.tags: [FReadIO].} = + proc paramCount*(): int {.tags: [ReadIOEffect].} = ## Returns the number of `command line arguments`:idx: given to the ## application. ## @@ -1625,7 +1633,7 @@ when defined(nimdoc): ## else: ## # Do something else! - proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} = + proc paramStr*(i: int): TaintedString {.tags: [ReadIOEffect].} = ## Returns the `i`-th `command line argument`:idx: given to the application. ## ## `i` should be in the range `1..paramCount()`, the `EInvalidIndex` @@ -1826,7 +1834,7 @@ proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1", close(f) else: osError(osLastError()) -proc findExe*(exe: string): string {.tags: [FReadDir, FReadEnv].} = +proc findExe*(exe: string): string {.tags: [ReadDirEffect, ReadEnvEffect].} = ## Searches for `exe` in the current working directory and then ## in directories listed in the ``PATH`` environment variable. ## Returns "" if the `exe` cannot be found. On DOS-like platforms, `exe` @@ -1854,7 +1862,6 @@ proc expandTilde*(path: string): string = ## let configFile = expandTilde("~" / "appname.cfg") ## echo configFile ## # --> C:\Users\amber\appname.cfg - if len(path) > 1 and path[0] == '~' and (path[1] == '/' or path[1] == '\\'): result = getHomeDir() / path[2..len(path)-1] else: @@ -1961,7 +1968,7 @@ proc getFileInfo*(handle: FileHandle): FileInfo = rawToFormalFileInfo(rawInfo, result) proc getFileInfo*(file: File): FileInfo = - result = getFileInfo(file.fileHandle()) + result = getFileInfo(file.getFileHandle()) proc getFileInfo*(path: string, followSymlink = true): FileInfo = ## Retrieves file information for the file object pointed to by `path`. diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index d5ca2f5a5..25782d4f5 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -24,7 +24,7 @@ when defined(linux): import linux type - TProcess = object of RootObj + ProcessObj = object of RootObj when defined(windows): fProcessHandle: THandle inHandle, outHandle, errHandle: FileHandle @@ -35,9 +35,9 @@ type id: TPid exitCode: cint - PProcess* = ref TProcess ## represents an operating system process + Process* = ref ProcessObj ## represents an operating system process - TProcessOption* = enum ## options that can be passed `startProcess` + ProcessOption* = enum ## options that can be passed `startProcess` poEchoCmd, ## echo the command before execution poUsePath, ## Asks system to search for executable using PATH environment ## variable. @@ -47,6 +47,9 @@ type poStdErrToStdOut, ## merge stdout and stderr to the stdout stream poParentStreams ## use the parent's streams +{.deprecated: [TProcess: ProcessObj, PProcess: Process, + TProcessOption: ProcessOption].} + const poUseShell* {.deprecated.} = poUsePath ## Deprecated alias for poUsePath. @@ -125,7 +128,7 @@ proc startProcess*(command: string, args: openArray[string] = [], env: PStringTable = nil, options: set[TProcessOption] = {poStdErrToStdOut}): - PProcess {.rtl, extern: "nosp$1", tags: [ExecIOEffect, FReadEnv].} + PProcess {.rtl, extern: "nosp$1", tags: [ExecIOEffect, ReadEnvEffect].} ## Starts a process. `Command` is the executable file, `workingDir` is the ## process's working directory. If ``workingDir == ""`` the current directory ## is used. `args` are the command line arguments that are passed to the @@ -150,7 +153,7 @@ proc startProcess*(command: string, proc startCmd*(command: string, options: set[TProcessOption] = { poStdErrToStdOut, poUsePath}): PProcess {. - tags: [ExecIOEffect, FReadEnv], deprecated.} = + tags: [ExecIOEffect, ReadEnvEffect], deprecated.} = ## Deprecated - use `startProcess` directly. result = startProcess(command=command, options=options + {poEvalCommand}) @@ -233,7 +236,7 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} = proc execProcesses*(cmds: openArray[string], options = {poStdErrToStdOut, poParentStreams}, n = countProcessors()): int {.rtl, extern: "nosp$1", - tags: [ExecIOEffect, TimeEffect, FReadEnv]} = + tags: [ExecIOEffect, TimeEffect, ReadEnvEffect]} = ## executes the commands `cmds` in parallel. Creates `n` processes ## that execute in parallel. The highest return value of all processes ## is returned. @@ -584,12 +587,12 @@ elif not defined(useNimRtl): when not defined(useFork): proc startProcessAuxSpawn(data: TStartProcessData): TPid {. - tags: [ExecIOEffect, FReadEnv], gcsafe.} + tags: [ExecIOEffect, ReadEnvEffect], gcsafe.} proc startProcessAuxFork(data: TStartProcessData): TPid {. - tags: [ExecIOEffect, FReadEnv], gcsafe.} + tags: [ExecIOEffect, ReadEnvEffect], gcsafe.} {.push stacktrace: off, profiler: off.} proc startProcessAfterFork(data: ptr TStartProcessData) {. - tags: [ExecIOEffect, FReadEnv], cdecl, gcsafe.} + tags: [ExecIOEffect, ReadEnvEffect], cdecl, gcsafe.} {.pop.} proc startProcess(command: string, diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index 1d61a967b..c340bf98b 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -20,24 +20,24 @@ ## The file ``examples/parsecfgex.nim`` demonstrates how to use the ## configuration file parser: ## -## .. code-block:: nimrod +## .. code-block:: nim ## :file: examples/parsecfgex.nim -import +import hashes, strutils, lexbase, streams include "system/inclrtl" -type - TCfgEventKind* = enum ## enumeration of all events that may occur when parsing +type + CfgEventKind* = enum ## enumeration of all events that may occur when parsing cfgEof, ## end of file reached cfgSectionStart, ## a ``[section]`` has been parsed cfgKeyValuePair, ## a ``key=value`` pair has been detected cfgOption, ## a ``--key=value`` command line option cfgError ## an error ocurred during parsing - TCfgEvent* = object of TObject ## describes a parsing event + CfgEvent* = object of RootObj ## describes a parsing event case kind*: TCfgEventKind ## the kind of the event of cfgEof: nil of cfgSectionStart: @@ -53,28 +53,30 @@ type msg*: string ## contains the error message. No exceptions ## are thrown if a parse error occurs. - TTokKind = enum + TokKind = enum tkInvalid, tkEof, tkSymbol, tkEquals, tkColon, tkBracketLe, tkBracketRi, tkDashDash - TToken {.final.} = object # a token - kind: TTokKind # the type of the token + Token = object # a token + kind: TokKind # the type of the token literal: string # the parsed (string) literal - TCfgParser* = object of TBaseLexer ## the parser object. - tok: TToken + CfgParser* = object of BaseLexer ## the parser object. + tok: Token filename: string +{.deprecated: [TCfgEventKind: CfgEventKind, TCfgEvent: CfgEvent, + TTokKind: TokKind, TToken: Token, TCfgParser: CfgParser].} + # implementation const - SymChars: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.', - '/', '\\'} + SymChars: CharSet = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.', + '/', '\\'} -proc rawGetTok(c: var TCfgParser, tok: var TToken) {.gcsafe.} +proc rawGetTok(c: var CfgParser, tok: var Token) {.gcsafe.} -proc open*(c: var TCfgParser, input: PStream, filename: string, - lineOffset = 0) {. - rtl, extern: "npc$1".} = +proc open*(c: var CfgParser, input: PStream, filename: string, + lineOffset = 0) {.rtl, extern: "npc$1".} = ## initializes the parser with an input stream. `Filename` is only used ## for nice error messages. `lineOffset` can be used to influence the line ## number information in the generated error messages. @@ -85,23 +87,23 @@ proc open*(c: var TCfgParser, input: PStream, filename: string, inc(c.lineNumber, lineOffset) rawGetTok(c, c.tok) -proc close*(c: var TCfgParser) {.rtl, extern: "npc$1".} = +proc close*(c: var CfgParser) {.rtl, extern: "npc$1".} = ## closes the parser `c` and its associated input stream. lexbase.close(c) -proc getColumn*(c: TCfgParser): int {.rtl, extern: "npc$1".} = +proc getColumn*(c: CfgParser): int {.rtl, extern: "npc$1".} = ## get the current column the parser has arrived at. result = getColNumber(c, c.bufpos) -proc getLine*(c: TCfgParser): int {.rtl, extern: "npc$1".} = +proc getLine*(c: CfgParser): int {.rtl, extern: "npc$1".} = ## get the current line the parser has arrived at. result = c.lineNumber -proc getFilename*(c: TCfgParser): string {.rtl, extern: "npc$1".} = +proc getFilename*(c: CfgParser): string {.rtl, extern: "npc$1".} = ## get the filename of the file that the parser processes. result = c.filename -proc handleHexChar(c: var TCfgParser, xi: var int) = +proc handleHexChar(c: var CfgParser, xi: var int) = case c.buf[c.bufpos] of '0'..'9': xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) @@ -115,12 +117,12 @@ proc handleHexChar(c: var TCfgParser, xi: var int) = else: discard -proc handleDecChars(c: var TCfgParser, xi: var int) = +proc handleDecChars(c: var CfgParser, xi: var int) = while c.buf[c.bufpos] in {'0'..'9'}: xi = (xi * 10) + (ord(c.buf[c.bufpos]) - ord('0')) inc(c.bufpos) -proc getEscapedChar(c: var TCfgParser, tok: var TToken) = +proc getEscapedChar(c: var CfgParser, tok: var TToken) = inc(c.bufpos) # skip '\' case c.buf[c.bufpos] of 'n', 'N': @@ -169,13 +171,13 @@ proc getEscapedChar(c: var TCfgParser, tok: var TToken) = else: tok.kind = tkInvalid else: tok.kind = tkInvalid -proc handleCRLF(c: var TCfgParser, pos: int): int = +proc handleCRLF(c: var CfgParser, pos: int): int = case c.buf[pos] of '\c': result = lexbase.handleCR(c, pos) of '\L': result = lexbase.handleLF(c, pos) else: result = pos -proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) = +proc getString(c: var CfgParser, tok: var Token, rawMode: bool) = var pos = c.bufpos + 1 # skip " var buf = c.buf # put `buf` in a register tok.kind = tkSymbol @@ -221,7 +223,7 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) = inc(pos) c.bufpos = pos -proc getSymbol(c: var TCfgParser, tok: var TToken) = +proc getSymbol(c: var CfgParser, tok: var Token) = var pos = c.bufpos var buf = c.buf while true: @@ -231,7 +233,7 @@ proc getSymbol(c: var TCfgParser, tok: var TToken) = c.bufpos = pos tok.kind = tkSymbol -proc skip(c: var TCfgParser) = +proc skip(c: var CfgParser) = var pos = c.bufpos var buf = c.buf while true: @@ -247,7 +249,7 @@ proc skip(c: var TCfgParser) = break # EndOfFile also leaves the loop c.bufpos = pos -proc rawGetTok(c: var TCfgParser, tok: var TToken) = +proc rawGetTok(c: var CfgParser, tok: var Token) = tok.kind = tkInvalid setLen(tok.literal, 0) skip(c) @@ -286,19 +288,19 @@ proc rawGetTok(c: var TCfgParser, tok: var TToken) = tok.literal = "[EOF]" else: getSymbol(c, tok) -proc errorStr*(c: TCfgParser, msg: string): string {.rtl, extern: "npc$1".} = +proc errorStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} = ## returns a properly formated error message containing current line and ## column information. result = `%`("$1($2, $3) Error: $4", [c.filename, $getLine(c), $getColumn(c), msg]) -proc warningStr*(c: TCfgParser, msg: string): string {.rtl, extern: "npc$1".} = +proc warningStr*(c: CfgParser, msg: string): string {.rtl, extern: "npc$1".} = ## returns a properly formated warning message containing current line and ## column information. result = `%`("$1($2, $3) Warning: $4", [c.filename, $getLine(c), $getColumn(c), msg]) -proc ignoreMsg*(c: TCfgParser, e: TCfgEvent): string {.rtl, extern: "npc$1".} = +proc ignoreMsg*(c: CfgParser, e: CfgEvent): string {.rtl, extern: "npc$1".} = ## returns a properly formated warning message containing that ## an entry is ignored. case e.kind @@ -309,7 +311,7 @@ proc ignoreMsg*(c: TCfgParser, e: TCfgEvent): string {.rtl, extern: "npc$1".} = of cfgError: result = e.msg of cfgEof: result = "" -proc getKeyValPair(c: var TCfgParser, kind: TCfgEventKind): TCfgEvent = +proc getKeyValPair(c: var CfgParser, kind: CfgEventKind): CfgEvent = if c.tok.kind == tkSymbol: result.kind = kind result.key = c.tok.literal @@ -329,7 +331,7 @@ proc getKeyValPair(c: var TCfgParser, kind: TCfgEventKind): TCfgEvent = result.msg = errorStr(c, "symbol expected, but found: " & c.tok.literal) rawGetTok(c, c.tok) -proc next*(c: var TCfgParser): TCfgEvent {.rtl, extern: "npc$1".} = +proc next*(c: var CfgParser): CfgEvent {.rtl, extern: "npc$1".} = ## retrieves the first/next event. This controls the parser. case c.tok.kind of tkEof: diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim index 4b25babec..d267906a3 100644 --- a/lib/pure/parsecsv.nim +++ b/lib/pure/parsecsv.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2009 Andreas Rumpf # # See the file "copying.txt", included in this @@ -13,16 +13,16 @@ ## Example: How to use the parser ## ============================== ## -## .. code-block:: nimrod +## .. code-block:: nim ## import os, parsecsv, streams -## var s = newFileStream(ParamStr(1), fmRead) -## if s == nil: quit("cannot open the file" & ParamStr(1)) -## var x: TCsvParser -## open(x, s, ParamStr(1)) +## var s = newFileStream(paramStr(1), fmRead) +## if s == nil: quit("cannot open the file" & paramStr(1)) +## var x: CsvParser +## open(x, s, paramStr(1)) ## while readRow(x): -## Echo "new row: " +## echo "new row: " ## for val in items(x.row): -## Echo "##", val, "##" +## echo "##", val, "##" ## close(x) ## @@ -30,28 +30,30 @@ import lexbase, streams type - TCsvRow* = seq[string] ## a row in a CSV file - TCsvParser* = object of TBaseLexer ## the parser object. - row*: TCsvRow ## the current row + CsvRow* = seq[string] ## a row in a CSV file + CsvParser* = object of BaseLexer ## the parser object. + row*: CsvRow ## the current row filename: string sep, quote, esc: char skipWhite: bool currRow: int - EInvalidCsv* = object of EIO ## exception that is raised if - ## a parsing error occurs + CsvError* = object of IOError ## exception that is raised if + ## a parsing error occurs + +{.deprecated: [TCsvRow: CsvRow, TCsvParser: CsvParser, EInvalidCsv: CsvError].} proc raiseEInvalidCsv(filename: string, line, col: int, msg: string) {.noreturn.} = - var e: ref EInvalidCsv + var e: ref CsvError new(e) e.msg = filename & "(" & $line & ", " & $col & ") Error: " & msg raise e -proc error(my: TCsvParser, pos: int, msg: string) = +proc error(my: CsvParser, pos: int, msg: string) = raiseEInvalidCsv(my.filename, my.LineNumber, getColNumber(my, pos), msg) -proc open*(my: var TCsvParser, input: PStream, filename: string, +proc open*(my: var CsvParser, input: Stream, filename: string, separator = ',', quote = '"', escape = '\0', skipInitialSpace = false) = ## initializes the parser with an input stream. `Filename` is only used @@ -75,7 +77,7 @@ proc open*(my: var TCsvParser, input: PStream, filename: string, my.row = @[] my.currRow = 0 -proc parseField(my: var TCsvParser, a: var string) = +proc parseField(my: var CsvParser, a: var string) = var pos = my.bufpos var buf = my.buf if my.skipWhite: @@ -83,7 +85,7 @@ proc parseField(my: var TCsvParser, a: var string) = setLen(a, 0) # reuse memory if buf[pos] == my.quote and my.quote != '\0': inc(pos) - while true: + while true: var c = buf[pos] if c == '\0': my.bufpos = pos # can continue after exception? @@ -121,11 +123,11 @@ proc parseField(my: var TCsvParser, a: var string) = inc(pos) my.bufpos = pos -proc processedRows*(my: var TCsvParser): int = +proc processedRows*(my: var CsvParser): int = ## returns number of the processed rows return my.currRow -proc readRow*(my: var TCsvParser, columns = 0): bool = +proc readRow*(my: var CsvParser, columns = 0): bool = ## reads the next row; if `columns` > 0, it expects the row to have ## exactly this many columns. Returns false if the end of the file ## has been encountered else true. @@ -160,19 +162,19 @@ proc readRow*(my: var TCsvParser, columns = 0): bool = $col & " columns") inc(my.currRow) -proc close*(my: var TCsvParser) {.inline.} = +proc close*(my: var CsvParser) {.inline.} = ## closes the parser `my` and its associated input stream. lexbase.close(my) when isMainModule: import os - var s = newFileStream(ParamStr(1), fmRead) - if s == nil: quit("cannot open the file" & ParamStr(1)) - var x: TCsvParser - open(x, s, ParamStr(1)) + var s = newFileStream(paramStr(1), fmRead) + if s == nil: quit("cannot open the file" & paramStr(1)) + var x: CsvParser + open(x, s, paramStr(1)) while readRow(x): - Echo "new row: " + echo "new row: " for val in items(x.row): - Echo "##", val, "##" + echo "##", val, "##" close(x) diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index d7379a9a9..b325bd1f5 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module provides the standard Nimrod command line parser. +## This module provides the standard Nim command line parser. ## It supports one convenience iterator over all command line options and some ## lower-level features. ## @@ -22,26 +22,28 @@ import os, strutils type - TCmdLineKind* = enum ## the detected command line token + CmdLineKind* = enum ## the detected command line token cmdEnd, ## end of command line reached cmdArgument, ## argument detected cmdLongoption, ## a long option ``--option`` detected cmdShortOption ## a short option ``-c`` detected - TOptParser* = + OptParser* = object of RootObj ## this object implements the command line parser cmd: string pos: int inShortState: bool - kind*: TCmdLineKind ## the dected command line token + kind*: CmdLineKind ## the dected command line token key*, val*: TaintedString ## key and value pair; ``key`` is the option ## or the argument, ``value`` is not "" if ## the option was given a value +{.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].} + when declared(os.paramCount): # we cannot provide this for NimRtl creation on Posix, because we can't # access the command line arguments then! - proc initOptParser*(cmdline = ""): TOptParser = + proc initOptParser*(cmdline = ""): OptParser = ## inits the option parser. If ``cmdline == ""``, the real command line ## (as provided by the ``OS`` module) is taken. result.pos = 0 @@ -57,7 +59,7 @@ when declared(os.paramCount): result.val = TaintedString"" proc parseWord(s: string, i: int, w: var string, - delim: TCharSet = {'\x09', ' ', '\0'}): int = + delim: CharSet = {'\x09', ' ', '\0'}): int = result = i if s[result] == '\"': inc(result) @@ -70,7 +72,7 @@ proc parseWord(s: string, i: int, w: var string, add(w, s[result]) inc(result) -proc handleShortOption(p: var TOptParser) = +proc handleShortOption(p: var OptParser) = var i = p.pos p.kind = cmdShortOption add(p.key.string, p.cmd[i]) @@ -87,8 +89,7 @@ proc handleShortOption(p: var TOptParser) = if p.cmd[i] == '\0': p.inShortState = false p.pos = i -proc next*(p: var TOptParser) {. - rtl, extern: "npo$1".} = +proc next*(p: var OptParser) {.rtl, extern: "npo$1".} = ## parses the first or next option; ``p.kind`` describes what token has been ## parsed. ``p.key`` and ``p.val`` are set accordingly. var i = p.pos @@ -122,14 +123,12 @@ proc next*(p: var TOptParser) {. p.kind = cmdArgument p.pos = parseWord(p.cmd, i, p.key.string) -proc cmdLineRest*(p: TOptParser): TaintedString {. - rtl, extern: "npo$1".} = +proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} = ## retrieves the rest of the command line that has not been parsed yet. result = strip(substr(p.cmd, p.pos, len(p.cmd) - 1)).TaintedString when declared(initOptParser): - - iterator getopt*(): tuple[kind: TCmdLineKind, key, val: TaintedString] = + iterator getopt*(): tuple[kind: CmdLineKind, key, val: TaintedString] = ## This is an convenience iterator for iterating over the command line. ## This uses the TOptParser object. Example: ## diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim index 7638171d1..c283a5edf 100644 --- a/lib/pure/parseopt2.nim +++ b/lib/pure/parseopt2.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library -# (c) Copyright 2012 Andreas Rumpf +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module provides the standard Nimrod command line parser. +## This module provides the standard Nim command line parser. ## It supports one convenience iterator over all command line options and some ## lower-level features. ## @@ -25,22 +25,24 @@ import os, strutils type - TCmdLineKind* = enum ## the detected command line token + CmdLineKind* = enum ## the detected command line token cmdEnd, ## end of command line reached cmdArgument, ## argument detected cmdLongOption, ## a long option ``--option`` detected cmdShortOption ## a short option ``-c`` detected - TOptParser* = + OptParser* = object of TObject ## this object implements the command line parser cmd: seq[string] pos: int remainingShortOptions: string - kind*: TCmdLineKind ## the dected command line token + kind*: CmdLineKind ## the dected command line token key*, val*: TaintedString ## key and value pair; ``key`` is the option ## or the argument, ``value`` is not "" if ## the option was given a value -proc initOptParser*(cmdline: seq[string]): TOptParser {.rtl.} = +{.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].} + +proc initOptParser*(cmdline: seq[string]): OptParser {.rtl.} = ## Initalizes option parses with cmdline. cmdline should not contain ## argument 0 - program name. ## If cmdline == nil default to current command line arguments. @@ -54,7 +56,7 @@ proc initOptParser*(cmdline: seq[string]): TOptParser {.rtl.} = result.cmd = @cmdline -proc initOptParser*(cmdline: string): TOptParser {.rtl, deprecated.} = +proc initOptParser*(cmdline: string): OptParser {.rtl, deprecated.} = ## Initalizes option parses with cmdline. Splits cmdline in on spaces ## and calls initOptParser(openarray[string]) ## Do not use. @@ -64,13 +66,13 @@ proc initOptParser*(cmdline: string): TOptParser {.rtl, deprecated.} = return initOptParser(cmdline.split) when not defined(createNimRtl): - proc initOptParser*(): TOptParser = + proc initOptParser*(): OptParser = ## Initializes option parser from current command line arguments. return initOptParser(commandLineParams()) -proc next*(p: var TOptParser) {.rtl, extern: "npo$1".} +proc next*(p: var OptParser) {.rtl, extern: "npo$1".} -proc nextOption(p: var TOptParser, token: string, allowEmpty: bool) = +proc nextOption(p: var OptParser, token: string, allowEmpty: bool) = for splitchar in [':', '=']: if splitchar in token: let pos = token.find(splitchar) @@ -85,7 +87,7 @@ proc nextOption(p: var TOptParser, token: string, allowEmpty: bool) = p.remainingShortOptions = token[0..token.len-1] p.next() -proc next(p: var TOptParser) = +proc next(p: var OptParser) = if p.remainingShortOptions.len != 0: p.kind = cmdShortOption p.key = TaintedString(p.remainingShortOptions[0..0]) @@ -111,20 +113,22 @@ proc next(p: var TOptParser) = p.key = token p.val = "" -proc cmdLineRest*(p: TOptParser): TaintedString {.rtl, extern: "npo$1", deprecated.} = +proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1", deprecated.} = ## Returns part of command line string that has not been parsed yet. ## Do not use - does not correctly handle whitespace. return p.cmd[p.pos..p.cmd.len-1].join(" ") type - TGetoptResult* = tuple[kind: TCmdLineKind, key, val: TaintedString] + GetoptResult* = tuple[kind: CmdLineKind, key, val: TaintedString] + +{.deprecated: [TGetoptResult: GetoptResult].} when declared(paramCount): - iterator getopt*(): TGetoptResult = + iterator getopt*(): GetoptResult = ## This is an convenience iterator for iterating over the command line. - ## This uses the TOptParser object. Example: + ## This uses the OptParser object. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var ## filename = "" ## for kind, key, val in getopt(): diff --git a/lib/pure/parsesql.nim b/lib/pure/parsesql.nim index bd8836f7c..fcca0aa44 100644 --- a/lib/pure/parsesql.nim +++ b/lib/pure/parsesql.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2009 Andreas Rumpf # # See the file "copying.txt", included in this @@ -10,13 +10,13 @@ ## The ``parsesql`` module implements a high performance SQL file ## parser. It parses PostgreSQL syntax and the SQL ANSI standard. -import +import hashes, strutils, lexbase, streams # ------------------- scanner ------------------------------------------------- type - TTokKind = enum ## enumeration of all SQL tokens + TokKind = enum ## enumeration of all SQL tokens tkInvalid, ## invalid token tkEof, ## end of file reached tkIdentifier, ## abc @@ -38,33 +38,35 @@ type tkBracketRi, ## ']' tkDot ## '.' - TToken {.final.} = object # a token - kind: TTokKind # the type of the token + Token = object # a token + kind: TokKind # the type of the token literal: string # the parsed (string) literal - TSqlLexer* = object of TBaseLexer ## the parser object. + SqlLexer* = object of BaseLexer ## the parser object. filename: string +{.deprecated: [TToken: Token, TSqlLexer: SqlLexer].} + const - tokKindToStr: array[TTokKind, string] = [ + tokKindToStr: array[TokKind, string] = [ "invalid", "[EOF]", "identifier", "quoted identifier", "string constant", "escape string constant", "dollar quoted constant", "bit string constant", "hex string constant", "integer constant", "numeric constant", "operator", ";", ":", ",", "(", ")", "[", "]", "." ] -proc open(L: var TSqlLexer, input: PStream, filename: string) = +proc open(L: var SqlLexer, input: Stream, filename: string) = lexbase.open(L, input) L.filename = filename -proc close(L: var TSqlLexer) = +proc close(L: var SqlLexer) = lexbase.close(L) -proc getColumn(L: TSqlLexer): int = +proc getColumn(L: SqlLexer): int = ## get the current column the parser has arrived at. result = getColNumber(L, L.bufPos) -proc getLine(L: TSqlLexer): int = +proc getLine(L: SqlLexer): int = result = L.linenumber proc handleHexChar(c: var TSqlLexer, xi: var int) = @@ -137,10 +139,10 @@ proc getEscapedChar(c: var TSqlLexer, tok: var TToken) = else: tok.kind = tkInvalid else: tok.kind = tkInvalid -proc HandleCRLF(c: var TSqlLexer, pos: int): int = +proc handleCRLF(c: var TSqlLexer, pos: int): int = case c.buf[pos] - of '\c': result = lexbase.HandleCR(c, pos) - of '\L': result = lexbase.HandleLF(c, pos) + of '\c': result = lexbase.handleCR(c, pos) + of '\L': result = lexbase.handleLF(c, pos) else: result = pos proc skip(c: var TSqlLexer) = @@ -163,7 +165,7 @@ proc skip(c: var TSqlLexer) = case buf[pos] of '\0': break of '\c', '\L': - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf of '*': if buf[pos+1] == '/': @@ -181,13 +183,13 @@ proc skip(c: var TSqlLexer) = else: inc(pos) else: break of '\c', '\L': - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf else: break # EndOfFile also leaves the loop c.bufpos = pos -proc getString(c: var TSqlLexer, tok: var TToken, kind: TTokKind) = +proc getString(c: var TSqlLexer, tok: var TToken, kind: TokKind) = var pos = c.bufPos + 1 var buf = c.buf tok.kind = kind @@ -465,7 +467,7 @@ proc errorStr(L: TSqlLexer, msg: string): string = # :: left PostgreSQL-style typecast # [ ] left array element selection # - right unary minus -# ^ left exponentiation +# ^ left exponentiation # * / % left multiplication, division, modulo # + - left addition, subtraction # IS IS TRUE, IS FALSE, IS UNKNOWN, IS NULL @@ -483,7 +485,7 @@ proc errorStr(L: TSqlLexer, msg: string): string = # OR left logical disjunction type - TSqlNodeKind* = enum ## kind of SQL abstract syntax tree + SqlNodeKind* = enum ## kind of SQL abstract syntax tree nkNone, nkIdent, nkStringLit, @@ -536,79 +538,82 @@ type nkEnumDef type - EInvalidSql* = object of EInvalidValue ## Invalid SQL encountered - PSqlNode* = ref TSqlNode ## an SQL abstract syntax tree node - TSqlNode* = object ## an SQL abstract syntax tree node - case kind*: TSqlNodeKind ## kind of syntax tree + SqlParseError* = object of ValueError ## Invalid SQL encountered + SqlNode* = ref SqlNodeObj ## an SQL abstract syntax tree node + SqlNodeObj* = object ## an SQL abstract syntax tree node + case kind*: SqlNodeKind ## kind of syntax tree of nkIdent, nkStringLit, nkBitStringLit, nkHexStringLit, nkIntegerLit, nkNumericLit: strVal*: string ## AST leaf: the identifier, numeric literal ## string literal, etc. else: - sons*: seq[PSqlNode] ## the node's children + sons*: seq[SqlNode] ## the node's children - TSqlParser* = object of TSqlLexer ## SQL parser object - tok: TToken + SqlParser* = object of SqlLexer ## SQL parser object + tok: Token -proc newNode(k: TSqlNodeKind): PSqlNode = +{.deprecated: [EInvalidSql: SqlParseError, PSqlNode: SqlNode, + TSqlNode: SqlNodeObj, TSqlParser: SqlParser, TSqlNodeKind: SqlNodeKind].} + +proc newNode(k: SqlNodeKind): SqlNode = new(result) result.kind = k -proc newNode(k: TSqlNodeKind, s: string): PSqlNode = +proc newNode(k: SqlNodeKind, s: string): SqlNode = new(result) result.kind = k result.strVal = s -proc len*(n: PSqlNode): int = +proc len*(n: SqlNode): int = if isNil(n.sons): result = 0 else: result = n.sons.len -proc add*(father, n: PSqlNode) = +proc add*(father, n: SqlNode) = if isNil(father.sons): father.sons = @[] add(father.sons, n) -proc getTok(p: var TSqlParser) = +proc getTok(p: var SqlParser) = getTok(p, p.tok) -proc sqlError(p: TSqlParser, msg: string) = - var e: ref EInvalidSql +proc sqlError(p: SqlParser, msg: string) = + var e: ref SqlParseError new(e) e.msg = errorStr(p, msg) raise e -proc isKeyw(p: TSqlParser, keyw: string): bool = +proc isKeyw(p: SqlParser, keyw: string): bool = result = p.tok.kind == tkIdentifier and cmpIgnoreCase(p.tok.literal, keyw) == 0 -proc isOpr(p: TSqlParser, opr: string): bool = +proc isOpr(p: SqlParser, opr: string): bool = result = p.tok.kind == tkOperator and cmpIgnoreCase(p.tok.literal, opr) == 0 -proc optKeyw(p: var TSqlParser, keyw: string) = +proc optKeyw(p: var SqlParser, keyw: string) = if p.tok.kind == tkIdentifier and cmpIgnoreCase(p.tok.literal, keyw) == 0: getTok(p) -proc expectIdent(p: TSqlParser) = +proc expectIdent(p: SqlParser) = if p.tok.kind != tkIdentifier and p.tok.kind != tkQuotedIdentifier: sqlError(p, "identifier expected") -proc expect(p: TSqlParser, kind: TTokKind) = +proc expect(p: SqlParser, kind: TokKind) = if p.tok.kind != kind: sqlError(p, tokKindToStr[kind] & " expected") -proc eat(p: var TSqlParser, kind: TTokKind) = +proc eat(p: var SqlParser, kind: TokKind) = if p.tok.kind == kind: getTok(p) else: sqlError(p, tokKindToStr[kind] & " expected") -proc eat(p: var TSqlParser, keyw: string) = +proc eat(p: var SqlParser, keyw: string) = if isKeyw(p, keyw): getTok(p) else: sqlError(p, keyw.toUpper() & " expected") -proc parseDataType(p: var TSqlParser): PSqlNode = +proc parseDataType(p: var SqlParser): SqlNode = if isKeyw(p, "enum"): result = newNode(nkEnumDef) getTok(p) @@ -636,7 +641,7 @@ proc parseDataType(p: var TSqlParser): PSqlNode = getTok(p) eat(p, tkParRi) -proc getPrecedence(p: TSqlParser): int = +proc getPrecedence(p: SqlParser): int = if isOpr(p, "*") or isOpr(p, "/") or isOpr(p, "%"): result = 6 elif isOpr(p, "+") or isOpr(p, "-"): @@ -655,9 +660,9 @@ proc getPrecedence(p: TSqlParser): int = else: result = - 1 -proc parseExpr(p: var TSqlParser): PSqlNode +proc parseExpr(p: var SqlParser): SqlNode -proc identOrLiteral(p: var TSqlParser): PSqlNode = +proc identOrLiteral(p: var SqlParser): SqlNode = case p.tok.kind of tkIdentifier, tkQuotedIdentifier: result = newNode(nkIdent, p.tok.literal) @@ -685,7 +690,7 @@ proc identOrLiteral(p: var TSqlParser): PSqlNode = sqlError(p, "expression expected") getTok(p) # we must consume a token here to prevend endless loops! -proc primary(p: var TSqlParser): PSqlNode = +proc primary(p: var SqlParser): SqlNode = if p.tok.kind == tkOperator or isKeyw(p, "not"): result = newNode(nkPrefix) result.add(newNode(nkIdent, p.tok.literal)) @@ -723,9 +728,9 @@ proc primary(p: var TSqlParser): PSqlNode = getTok(p) else: break -proc lowestExprAux(p: var TSqlParser, v: var PSqlNode, limit: int): int = +proc lowestExprAux(p: var SqlParser, v: var SqlNode, limit: int): int = var - v2, node, opNode: PSqlNode + v2, node, opNode: SqlNode v = primary(p) # expand while operators have priorities higher than 'limit' var opPred = getPrecedence(p) result = opPred @@ -740,14 +745,14 @@ proc lowestExprAux(p: var TSqlParser, v: var PSqlNode, limit: int): int = v = node opPred = getPrecedence(p) -proc parseExpr(p: var TSqlParser): PSqlNode = +proc parseExpr(p: var SqlParser): SqlNode = discard lowestExprAux(p, result, - 1) -proc parseTableName(p: var TSqlParser): PSqlNode = +proc parseTableName(p: var SqlParser): SqlNode = expectIdent(p) result = primary(p) -proc parseColumnReference(p: var TSqlParser): PSqlNode = +proc parseColumnReference(p: var SqlParser): SqlNode = result = parseTableName(p) if p.tok.kind == tkParLe: getTok(p) @@ -760,12 +765,12 @@ proc parseColumnReference(p: var TSqlParser): PSqlNode = result.add(parseTableName(p)) eat(p, tkParRi) -proc parseCheck(p: var TSqlParser): PSqlNode = +proc parseCheck(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkCheck) result.add(parseExpr(p)) -proc parseConstraint(p: var TSqlParser): PSqlNode = +proc parseConstraint(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkConstraint) expectIdent(p) @@ -774,7 +779,7 @@ proc parseConstraint(p: var TSqlParser): PSqlNode = eat(p, "check") result.add(parseExpr(p)) -proc parseColumnConstraints(p: var TSqlParser, result: PSqlNode) = +proc parseColumnConstraints(p: var SqlParser, result: SqlNode) = while true: if isKeyw(p, "default"): getTok(p) @@ -806,7 +811,7 @@ proc parseColumnConstraints(p: var TSqlParser, result: PSqlNode) = else: break -proc parseColumnDef(p: var TSqlParser): PSqlNode = +proc parseColumnDef(p: var SqlParser): SqlNode = expectIdent(p) result = newNode(nkColumnDef) result.add(newNode(nkIdent, p.tok.literal)) @@ -814,7 +819,7 @@ proc parseColumnDef(p: var TSqlParser): PSqlNode = result.add(parseDataType(p)) parseColumnConstraints(p, result) -proc parseIfNotExists(p: var TSqlParser, k: TSqlNodeKind): PSqlNode = +proc parseIfNotExists(p: var SqlParser, k: TSqlNodeKind): SqlNode = getTok(p) if isKeyw(p, "if"): getTok(p) @@ -824,7 +829,7 @@ proc parseIfNotExists(p: var TSqlParser, k: TSqlNodeKind): PSqlNode = else: result = newNode(k) -proc parseParIdentList(p: var TSqlParser, father: PSqlNode) = +proc parseParIdentList(p: var SqlParser, father: SqlNode) = eat(p, tkParLe) while true: expectIdent(p) @@ -834,7 +839,7 @@ proc parseParIdentList(p: var TSqlParser, father: PSqlNode) = getTok(p) eat(p, tkParRi) -proc parseTableConstraint(p: var TSqlParser): PSqlNode = +proc parseTableConstraint(p: var SqlParser): SqlNode = if isKeyw(p, "primary"): getTok(p) eat(p, "key") @@ -861,7 +866,7 @@ proc parseTableConstraint(p: var TSqlParser): PSqlNode = else: sqlError(p, "column definition expected") -proc parseTableDef(p: var TSqlParser): PSqlNode = +proc parseTableDef(p: var SqlParser): SqlNode = result = parseIfNotExists(p, nkCreateTable) expectIdent(p) result.add(newNode(nkIdent, p.tok.literal)) @@ -876,7 +881,7 @@ proc parseTableDef(p: var TSqlParser): PSqlNode = if p.tok.kind != tkComma: break eat(p, tkParRi) -proc parseTypeDef(p: var TSqlParser): PSqlNode = +proc parseTypeDef(p: var SqlParser): SqlNode = result = parseIfNotExists(p, nkCreateType) expectIdent(p) result.add(newNode(nkIdent, p.tok.literal)) @@ -884,12 +889,12 @@ proc parseTypeDef(p: var TSqlParser): PSqlNode = eat(p, "as") result.add(parseDataType(p)) -proc parseWhere(p: var TSqlParser): PSqlNode = +proc parseWhere(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkWhere) result.add(parseExpr(p)) -proc parseIndexDef(p: var TSqlParser): PSqlNode = +proc parseIndexDef(p: var SqlParser): SqlNode = result = parseIfNotExists(p, nkCreateIndex) if isKeyw(p, "primary"): getTok(p) @@ -914,7 +919,7 @@ proc parseIndexDef(p: var TSqlParser): PSqlNode = getTok(p) eat(p, tkParRi) -proc parseInsert(p: var TSqlParser): PSqlNode = +proc parseInsert(p: var SqlParser): SqlNode = getTok(p) eat(p, "into") expectIdent(p) @@ -941,7 +946,7 @@ proc parseInsert(p: var TSqlParser): PSqlNode = result.add(n) eat(p, tkParRi) -proc parseUpdate(p: var TSqlParser): PSqlNode = +proc parseUpdate(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkUpdate) result.add(primary(p)) @@ -962,7 +967,7 @@ proc parseUpdate(p: var TSqlParser): PSqlNode = else: result.add(nil) -proc parseDelete(p: var TSqlParser): PSqlNode = +proc parseDelete(p: var SqlParser): SqlNode = getTok(p) result = newNode(nkDelete) eat(p, "from") @@ -972,7 +977,7 @@ proc parseDelete(p: var TSqlParser): PSqlNode = else: result.add(nil) -proc parseSelect(p: var TSqlParser): PSqlNode = +proc parseSelect(p: var SqlParser): SqlNode = getTok(p) if isKeyw(p, "distinct"): getTok(p) @@ -1041,7 +1046,7 @@ proc parseSelect(p: var TSqlParser): PSqlNode = getTok(p) result.add(n) -proc parseStmt(p: var TSqlParser): PSqlNode = +proc parseStmt(p: var SqlParser): SqlNode = if isKeyw(p, "create"): getTok(p) optKeyw(p, "cached") @@ -1071,7 +1076,7 @@ proc parseStmt(p: var TSqlParser): PSqlNode = else: sqlError(p, "CREATE expected") -proc open(p: var TSqlParser, input: PStream, filename: string) = +proc open(p: var SqlParser, input: PStream, filename: string) = ## opens the parser `p` and assigns the input stream `input` to it. ## `filename` is only used for error messages. open(TSqlLexer(p), input, filename) @@ -1079,7 +1084,7 @@ proc open(p: var TSqlParser, input: PStream, filename: string) = p.tok.literal = "" getTok(p) -proc parse(p: var TSqlParser): PSqlNode = +proc parse(p: var SqlParser): SqlNode = ## parses the content of `p`'s input stream and returns the SQL AST. ## Syntax errors raise an `EInvalidSql` exception. result = newNode(nkStmtList) @@ -1090,24 +1095,24 @@ proc parse(p: var TSqlParser): PSqlNode = if result.len == 1: result = result.sons[0] -proc close(p: var TSqlParser) = +proc close(p: var SqlParser) = ## closes the parser `p`. The associated input stream is closed too. close(TSqlLexer(p)) -proc parseSQL*(input: PStream, filename: string): PSqlNode = +proc parseSQL*(input: PStream, filename: string): SqlNode = ## parses the SQL from `input` into an AST and returns the AST. ## `filename` is only used for error messages. ## Syntax errors raise an `EInvalidSql` exception. - var p: TSqlParser + var p: SqlParser open(p, input, filename) try: result = parse(p) finally: close(p) -proc ra(n: PSqlNode, s: var string, indent: int) +proc ra(n: SqlNode, s: var string, indent: int) -proc rs(n: PSqlNode, s: var string, indent: int, +proc rs(n: SqlNode, s: var string, indent: int, prefix = "(", suffix = ")", sep = ", ") = if n.len > 0: @@ -1117,7 +1122,7 @@ proc rs(n: PSqlNode, s: var string, indent: int, ra(n.sons[i], s, indent) s.add(suffix) -proc ra(n: PSqlNode, s: var string, indent: int) = +proc ra(n: SqlNode, s: var string, indent: int) = if n == nil: return case n.kind of nkNone: discard @@ -1320,7 +1325,7 @@ proc ra(n: PSqlNode, s: var string, indent: int) = #for x, y, z in db.select(fromm = a, b where = a.name == b.name): # writeln x, y, z -proc renderSQL*(n: PSqlNode): string = +proc renderSQL*(n: SqlNode): string = ## Converts an SQL abstract syntax tree to its string representation. result = "" ra(n, result, 0) diff --git a/lib/pure/parseurl.nim b/lib/pure/parseurl.nim index 67c6de905..2637a879d 100644 --- a/lib/pure/parseurl.nim +++ b/lib/pure/parseurl.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -15,12 +15,14 @@ import strutils type - TUrl* = tuple[ ## represents a *Uniform Resource Locator* (URL) - ## any optional component is "" if it does not exist + Url* = tuple[ ## represents a *Uniform Resource Locator* (URL) + ## any optional component is "" if it does not exist scheme, username, password, hostname, port, path, query, anchor: string] - -proc parseUrl*(url: string): TUrl {.deprecated.} = + +{.deprecated: [TUrl: Url].} + +proc parseUrl*(url: string): Url {.deprecated.} = var i = 0 var scheme, username, password: string = "" @@ -86,7 +88,7 @@ proc parseUrl*(url: string): TUrl {.deprecated.} = return (scheme, username, password, hostname, port, path, query, anchor) -proc `$`*(u: TUrl): string {.deprecated.} = +proc `$`*(u: Url): string {.deprecated.} = ## turns the URL `u` into its string representation. result = "" if u.scheme.len > 0: diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index 0c045bc5a..38a3cbc5e 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -35,7 +35,7 @@ proc parseHex*(s: string, number: var int, start = 0): int {. ## can use this feature to *chain* calls, though the result int will quickly ## overflow. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var value = 0 ## discard parseHex("0x38", value) ## assert value == 56 @@ -332,7 +332,7 @@ proc parseFloat*(s: string, number: var float, start = 0): int {. number = bf type - TInterpolatedKind* = enum ## describes for `interpolatedFragments` + InterpolatedKind* = enum ## describes for `interpolatedFragments` ## which part of the interpolated string is ## yielded; for example in "str$$$var${expr}" ikStr, ## ``str`` part of the interpolated string @@ -340,7 +340,9 @@ type ikVar, ## ``var`` part of the interpolated string ikExpr ## ``expr`` part of the interpolated string -iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, +{.deprecated: [TInterpolatedKind: InterpolatedKind].} + +iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind, value: string] = ## Tokenizes the string `s` into substrings for interpolation purposes. ## @@ -360,7 +362,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, ## (ikString, " ") ## (ikDollar, "$") var i = 0 - var kind: TInterpolatedKind + var kind: InterpolatedKind while true: var j = i if s[j] == '$': diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index 667b8aed6..2d944917f 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -56,7 +56,7 @@ import # xmlElementCloseEnd, ## ``/>`` type - TXmlEventKind* = enum ## enumation of all events that may occur when parsing + XmlEventKind* = enum ## enumation of all events that may occur when parsing xmlError, ## an error ocurred during parsing xmlEof, ## end of file reached xmlCharData, ## character data @@ -72,7 +72,7 @@ type xmlEntity, ## &entity; xmlSpecial ## ```` - TXmlError* = enum ## enumeration that lists all errors that can occur + XmlErrorKind* = enum ## enumeration that lists all errors that can occur errNone, ## no error errEndOfCDataExpected, ## ``]]>`` expected errNameExpected, ## name expected @@ -83,23 +83,26 @@ type errQuoteExpected, ## ``"`` or ``'`` expected errEndOfCommentExpected ## ``-->`` expected - TParserState = enum + ParserState = enum stateStart, stateNormal, stateAttr, stateEmptyElementTag, stateError - TXmlParseOption* = enum ## options for the XML parser + XmlParseOption* = enum ## options for the XML parser reportWhitespace, ## report whitespace reportComments ## report comments - TXmlParser* = object of TBaseLexer ## the parser object. + XmlParser* = object of TBaseLexer ## the parser object. a, b, c: string - kind: TXmlEventKind - err: TXmlError - state: TParserState + kind: XmlEventKind + err: XmlErrorKind + state: ParserState filename: string - options: set[TXmlParseOption] - + options: set[XmlParseOption] + +{.deprecated: [TXmlParser: XmlParser, TXmlParseOptions: XmlParseOptions, + TXmlError: XmlErrorKind, TXmlEventKind: XmlEventKind].} + const - errorMessages: array [TXmlError, string] = [ + errorMessages: array[XmlError, string] = [ "no error", "']]>' expected", "name expected", @@ -111,8 +114,8 @@ const "'-->' expected" ] -proc open*(my: var TXmlParser, input: PStream, filename: string, - options: set[TXmlParseOption] = {}) = +proc open*(my: var XmlParser, input: Stream, filename: string, + options: set[XmlParseOption] = {}) = ## initializes the parser with an input stream. `Filename` is only used ## for nice error messages. The parser's behaviour can be controlled by ## the `options` parameter: If `options` contains ``reportWhitespace`` @@ -127,7 +130,7 @@ proc open*(my: var TXmlParser, input: PStream, filename: string, my.b = "" my.options = options -proc close*(my: var TXmlParser) {.inline.} = +proc close*(my: var XmlParser) {.inline.} = ## closes the parser `my` and its associated input stream. lexbase.close(my) diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index efe169c1d..8bd307c7d 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -32,7 +32,7 @@ const ## can be captured. More subpatterns cannot be captured! type - TPegKind = enum + PegKind = enum pkEmpty, pkAny, ## any character (.) pkAnyRune, ## any Unicode character (_) @@ -67,16 +67,16 @@ type pkRule, ## a <- b pkList, ## a, b pkStartAnchor ## ^ --> Internal DSL: startAnchor() - TNonTerminalFlag = enum + NonTerminalFlag = enum ntDeclared, ntUsed - TNonTerminal {.final.} = object ## represents a non terminal symbol + NonTerminalObj = object ## represents a non terminal symbol name: string ## the name of the symbol line: int ## line the symbol has been declared/used in col: int ## column the symbol has been declared/used in - flags: set[TNonTerminalFlag] ## the nonterminal's flags + flags: set[NonTerminalFlag] ## the nonterminal's flags rule: TNode ## the rule that the symbol refers to - TNode {.final, shallow.} = object - case kind: TPegKind + TNode {.shallow.} = object + case kind: PegKind of pkEmpty..pkWhitespace: nil of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: term: string of pkChar, pkGreedyRepChar: ch: char @@ -84,11 +84,13 @@ type of pkNonTerminal: nt: PNonTerminal of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns] else: sons: seq[TNode] - PNonTerminal* = ref TNonTerminal + NonTerminal* = ref NonTerminalObj - TPeg* = TNode ## type that represents a PEG + Peg* = TNode ## type that represents a PEG -proc term*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1Str".} = +{.deprecated: [TPeg: Peg].} + +proc term*(t: string): Peg {.nosideEffect, rtl, extern: "npegs$1Str".} = ## constructs a PEG from a terminal string if t.len != 1: result.kind = pkTerminal @@ -97,35 +99,35 @@ proc term*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1Str".} = result.kind = pkChar result.ch = t[0] -proc termIgnoreCase*(t: string): TPeg {. +proc termIgnoreCase*(t: string): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG from a terminal string; ignore case for matching result.kind = pkTerminalIgnoreCase result.term = t -proc termIgnoreStyle*(t: string): TPeg {. +proc termIgnoreStyle*(t: string): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG from a terminal string; ignore style for matching result.kind = pkTerminalIgnoreStyle result.term = t -proc term*(t: char): TPeg {.nosideEffect, rtl, extern: "npegs$1Char".} = +proc term*(t: char): Peg {.nosideEffect, rtl, extern: "npegs$1Char".} = ## constructs a PEG from a terminal char assert t != '\0' result.kind = pkChar result.ch = t -proc charSet*(s: set[char]): TPeg {.nosideEffect, rtl, extern: "npegs$1".} = +proc charSet*(s: set[char]): Peg {.nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG from a character set `s` assert '\0' notin s result.kind = pkCharChoice new(result.charChoice) result.charChoice[] = s -proc len(a: TPeg): int {.inline.} = return a.sons.len -proc add(d: var TPeg, s: TPeg) {.inline.} = add(d.sons, s) +proc len(a: Peg): int {.inline.} = return a.sons.len +proc add(d: var Peg, s: Peg) {.inline.} = add(d.sons, s) -proc addChoice(dest: var TPeg, elem: TPeg) = +proc addChoice(dest: var Peg, elem: Peg) = var L = dest.len-1 if L >= 0 and dest.sons[L].kind == pkCharChoice: # caution! Do not introduce false aliasing here! @@ -137,7 +139,7 @@ proc addChoice(dest: var TPeg, elem: TPeg) = else: add(dest, elem) else: add(dest, elem) -template multipleOp(k: TPegKind, localOpt: expr) = +template multipleOp(k: PegKind, localOpt: expr) = result.kind = k result.sons = @[] for x in items(a): @@ -149,12 +151,12 @@ template multipleOp(k: TPegKind, localOpt: expr) = if result.len == 1: result = result.sons[0] -proc `/`*(a: varargs[TPeg]): TPeg {. +proc `/`*(a: varargs[Peg]): Peg {. nosideEffect, rtl, extern: "npegsOrderedChoice".} = ## constructs an ordered choice with the PEGs in `a` multipleOp(pkOrderedChoice, addChoice) -proc addSequence(dest: var TPeg, elem: TPeg) = +proc addSequence(dest: var Peg, elem: Peg) = var L = dest.len-1 if L >= 0 and dest.sons[L].kind == pkTerminal: # caution! Do not introduce false aliasing here! @@ -166,12 +168,12 @@ proc addSequence(dest: var TPeg, elem: TPeg) = else: add(dest, elem) else: add(dest, elem) -proc sequence*(a: varargs[TPeg]): TPeg {. +proc sequence*(a: varargs[Peg]): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a sequence with all the PEGs from `a` multipleOp(pkSequence, addSequence) -proc `?`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsOptional".} = +proc `?`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsOptional".} = ## constructs an optional for the PEG `a` if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar, pkGreedyRepSet}: @@ -182,7 +184,7 @@ proc `?`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsOptional".} = result.kind = pkOption result.sons = @[a] -proc `*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyRep".} = +proc `*`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsGreedyRep".} = ## constructs a "greedy repetition" for the PEG `a` case a.kind of pkGreedyRep, pkGreedyRepChar, pkGreedyRepSet, pkGreedyAny, pkOption: @@ -200,111 +202,99 @@ proc `*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyRep".} = result.kind = pkGreedyRep result.sons = @[a] -proc `!*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsSearch".} = +proc `!*`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsSearch".} = ## constructs a "search" for the PEG `a` result.kind = pkSearch result.sons = @[a] -proc `!*\`*(a: TPeg): TPeg {.noSideEffect, rtl, +proc `!*\`*(a: Peg): Peg {.noSideEffect, rtl, extern: "npgegsCapturedSearch".} = ## constructs a "captured search" for the PEG `a` result.kind = pkCapturedSearch result.sons = @[a] - -when false: - proc contains(a: TPeg, k: TPegKind): bool = - if a.kind == k: return true - case a.kind - of pkEmpty, pkAny, pkAnyRune, pkGreedyAny, pkNewLine, pkTerminal, - pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar, pkGreedyRepChar, - pkCharChoice, pkGreedyRepSet: nil - of pkNonTerminal: return true - else: - for i in 0..a.sons.len-1: - if contains(a.sons[i], k): return true -proc `+`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyPosRep".} = +proc `+`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsGreedyPosRep".} = ## constructs a "greedy positive repetition" with the PEG `a` return sequence(a, *a) -proc `&`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsAndPredicate".} = +proc `&`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsAndPredicate".} = ## constructs an "and predicate" with the PEG `a` result.kind = pkAndPredicate result.sons = @[a] -proc `!`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsNotPredicate".} = +proc `!`*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsNotPredicate".} = ## constructs a "not predicate" with the PEG `a` result.kind = pkNotPredicate result.sons = @[a] -proc any*: TPeg {.inline.} = +proc any*: Peg {.inline.} = ## constructs the PEG `any character`:idx: (``.``) result.kind = pkAny -proc anyRune*: TPeg {.inline.} = +proc anyRune*: Peg {.inline.} = ## constructs the PEG `any rune`:idx: (``_``) result.kind = pkAnyRune -proc newLine*: TPeg {.inline.} = +proc newLine*: Peg {.inline.} = ## constructs the PEG `newline`:idx: (``\n``) result.kind = pkNewline -proc unicodeLetter*: TPeg {.inline.} = +proc unicodeLetter*: Peg {.inline.} = ## constructs the PEG ``\letter`` which matches any Unicode letter. result.kind = pkLetter -proc unicodeLower*: TPeg {.inline.} = +proc unicodeLower*: Peg {.inline.} = ## constructs the PEG ``\lower`` which matches any Unicode lowercase letter. result.kind = pkLower -proc unicodeUpper*: TPeg {.inline.} = +proc unicodeUpper*: Peg {.inline.} = ## constructs the PEG ``\upper`` which matches any Unicode uppercase letter. result.kind = pkUpper -proc unicodeTitle*: TPeg {.inline.} = +proc unicodeTitle*: Peg {.inline.} = ## constructs the PEG ``\title`` which matches any Unicode title letter. result.kind = pkTitle -proc unicodeWhitespace*: TPeg {.inline.} = +proc unicodeWhitespace*: Peg {.inline.} = ## constructs the PEG ``\white`` which matches any Unicode ## whitespace character. result.kind = pkWhitespace -proc startAnchor*: TPeg {.inline.} = +proc startAnchor*: Peg {.inline.} = ## constructs the PEG ``^`` which matches the start of the input. result.kind = pkStartAnchor -proc endAnchor*: TPeg {.inline.} = +proc endAnchor*: Peg {.inline.} = ## constructs the PEG ``$`` which matches the end of the input. result = !any() -proc capture*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsCapture".} = +proc capture*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsCapture".} = ## constructs a capture with the PEG `a` result.kind = pkCapture result.sons = @[a] -proc backref*(index: range[1..MaxSubPatterns]): TPeg {. +proc backref*(index: range[1..MaxSubPatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a back reference of the given `index`. `index` starts counting ## from 1. result.kind = pkBackRef result.index = index-1 -proc backrefIgnoreCase*(index: range[1..MaxSubPatterns]): TPeg {. +proc backrefIgnoreCase*(index: range[1..MaxSubPatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a back reference of the given `index`. `index` starts counting ## from 1. Ignores case for matching. result.kind = pkBackRefIgnoreCase result.index = index-1 -proc backrefIgnoreStyle*(index: range[1..MaxSubPatterns]): TPeg {. +proc backrefIgnoreStyle*(index: range[1..MaxSubPatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".}= ## constructs a back reference of the given `index`. `index` starts counting ## from 1. Ignores style for matching. result.kind = pkBackRefIgnoreStyle result.index = index-1 -proc spaceCost(n: TPeg): int = +proc spaceCost(n: Peg): int = case n.kind of pkEmpty: discard of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar, @@ -319,7 +309,7 @@ proc spaceCost(n: TPeg): int = inc(result, spaceCost(n.sons[i])) if result >= InlineThreshold: break -proc nonterminal*(n: PNonTerminal): TPeg {. +proc nonterminal*(n: PNonTerminal): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG that consists of the nonterminal symbol assert n != nil @@ -415,7 +405,7 @@ proc charSetEsc(cc: set[char]): string = else: result = '[' & charSetEscAux(cc) & ']' -proc toStrAux(r: TPeg, res: var string) = +proc toStrAux(r: Peg, res: var string) = case r.kind of pkEmpty: add(res, "()") of pkAny: add(res, '.') @@ -501,7 +491,7 @@ proc toStrAux(r: TPeg, res: var string) = of pkStartAnchor: add(res, '^') -proc `$` *(r: TPeg): string {.nosideEffect, rtl, extern: "npegsToString".} = +proc `$` *(r: Peg): string {.nosideEffect, rtl, extern: "npegsToString".} = ## converts a PEG to its string representation result = "" toStrAux(r, result) @@ -509,12 +499,14 @@ proc `$` *(r: TPeg): string {.nosideEffect, rtl, extern: "npegsToString".} = # --------------------- core engine ------------------------------------------- type - TCaptures* {.final.} = object ## contains the captured substrings. + Captures* = object ## contains the captured substrings. matches: array[0..maxSubpatterns-1, tuple[first, last: int]] ml: int origStart: int -proc bounds*(c: TCaptures, +{.deprecated: [TCaptures: Captures].} + +proc bounds*(c: Captures, i: range[0..maxSubpatterns-1]): tuple[first, last: int] = ## returns the bounds ``[first..last]`` of the `i`'th capture. result = c.matches[i] @@ -533,7 +525,7 @@ when not useUnicode: proc isTitle(a: char): bool {.inline.} = return false proc isWhiteSpace(a: char): bool {.inline.} = return a in {' ', '\9'..'\13'} -proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. +proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. nosideEffect, rtl, extern: "npegs$1".} = ## low-level matching proc that implements the PEG interpreter. Use this ## for maximum efficiency (every other PEG operation ends up calling this @@ -734,7 +726,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {. of pkBackRef..pkBackRefIgnoreStyle: if p.index >= c.ml: return -1 var (a, b) = c.matches[p.index] - var n: TPeg + var n: Peg n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef)) n.term = s.substr(a, b) result = rawMatch(s, n, start, c) @@ -747,51 +739,51 @@ template fillMatches(s, caps, c: expr) = for k in 0..c.ml-1: caps[k] = substr(s, c.matches[k][0], c.matches[k][1]) -proc match*(s: string, pattern: TPeg, matches: var openArray[string], +proc match*(s: string, pattern: Peg, matches: var openArray[string], start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and ## the captured substrings in the array ``matches``. If it does not ## match, nothing is written into ``matches`` and ``false`` is ## returned. - var c: TCaptures + var c: Captures c.origStart = start result = rawMatch(s, pattern, start, c) == len(s) - start if result: fillMatches(s, matches, c) -proc match*(s: string, pattern: TPeg, +proc match*(s: string, pattern: Peg, start = 0): bool {.nosideEffect, rtl, extern: "npegs$1".} = ## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``. - var c: TCaptures + var c: Captures c.origStart = start result = rawMatch(s, pattern, start, c) == len(s)-start -proc matchLen*(s: string, pattern: TPeg, matches: var openArray[string], +proc matchLen*(s: string, pattern: Peg, matches: var openArray[string], start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. It's possible that a suffix of `s` remains ## that does not belong to the match. - var c: TCaptures + var c: Captures c.origStart = start result = rawMatch(s, pattern, start, c) if result >= 0: fillMatches(s, matches, c) -proc matchLen*(s: string, pattern: TPeg, +proc matchLen*(s: string, pattern: Peg, start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. It's possible that a suffix of `s` remains ## that does not belong to the match. - var c: TCaptures + var c: Captures c.origStart = start result = rawMatch(s, pattern, start, c) -proc find*(s: string, pattern: TPeg, matches: var openArray[string], +proc find*(s: string, pattern: Peg, matches: var openArray[string], start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns the starting position of ``pattern`` in ``s`` and the captured ## substrings in the array ``matches``. If it does not match, nothing ## is written into ``matches`` and -1 is returned. - var c: TCaptures + var c: Captures c.origStart = start for i in start .. s.len-1: c.ml = 0 @@ -801,14 +793,14 @@ proc find*(s: string, pattern: TPeg, matches: var openArray[string], return -1 # could also use the pattern here: (!P .)* P -proc findBounds*(s: string, pattern: TPeg, matches: var openArray[string], +proc findBounds*(s: string, pattern: Peg, matches: var openArray[string], start = 0): tuple[first, last: int] {. nosideEffect, rtl, extern: "npegs$1Capture".} = ## returns the starting position and end position of ``pattern`` in ``s`` ## and the captured ## substrings in the array ``matches``. If it does not match, nothing ## is written into ``matches`` and (-1,0) is returned. - var c: TCaptures + var c: Captures c.origStart = start for i in start .. s.len-1: c.ml = 0 @@ -818,19 +810,19 @@ proc findBounds*(s: string, pattern: TPeg, matches: var openArray[string], return (i, i+L-1) return (-1, 0) -proc find*(s: string, pattern: TPeg, +proc find*(s: string, pattern: Peg, start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} = ## returns the starting position of ``pattern`` in ``s``. If it does not ## match, -1 is returned. - var c: TCaptures + var c: Captures c.origStart = start for i in start .. s.len-1: if rawMatch(s, pattern, i, c) >= 0: return i return -1 -iterator findAll*(s: string, pattern: TPeg, start = 0): string = +iterator findAll*(s: string, pattern: Peg, start = 0): string = ## yields all matching *substrings* of `s` that match `pattern`. - var c: TCaptures + var c: Captures c.origStart = start var i = start while i < s.len: @@ -842,7 +834,7 @@ iterator findAll*(s: string, pattern: TPeg, start = 0): string = yield substr(s, i, i+L-1) inc(i, L) -proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {. +proc findAll*(s: string, pattern: Peg, start = 0): seq[string] {. nosideEffect, rtl, extern: "npegs$1".} = ## returns all matching *substrings* of `s` that match `pattern`. ## If it does not match, @[] is returned. @@ -851,11 +843,11 @@ proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {. when not defined(nimhygiene): {.pragma: inject.} -template `=~`*(s: string, pattern: TPeg): bool = +template `=~`*(s: string, pattern: Peg): bool = ## This calls ``match`` with an implicit declared ``matches`` array that ## can be used in the scope of the ``=~`` call: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}": ## # matches a key=value pair: @@ -876,46 +868,46 @@ template `=~`*(s: string, pattern: TPeg): bool = # ------------------------- more string handling ------------------------------ -proc contains*(s: string, pattern: TPeg, start = 0): bool {. +proc contains*(s: string, pattern: Peg, start = 0): bool {. nosideEffect, rtl, extern: "npegs$1".} = ## same as ``find(s, pattern, start) >= 0`` return find(s, pattern, start) >= 0 -proc contains*(s: string, pattern: TPeg, matches: var openArray[string], +proc contains*(s: string, pattern: Peg, matches: var openArray[string], start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = ## same as ``find(s, pattern, matches, start) >= 0`` return find(s, pattern, matches, start) >= 0 -proc startsWith*(s: string, prefix: TPeg, start = 0): bool {. +proc startsWith*(s: string, prefix: Peg, start = 0): bool {. nosideEffect, rtl, extern: "npegs$1".} = ## returns true if `s` starts with the pattern `prefix` result = matchLen(s, prefix, start) >= 0 -proc endsWith*(s: string, suffix: TPeg, start = 0): bool {. +proc endsWith*(s: string, suffix: Peg, start = 0): bool {. nosideEffect, rtl, extern: "npegs$1".} = ## returns true if `s` ends with the pattern `prefix` - var c: TCaptures + var c: Captures c.origStart = start for i in start .. s.len-1: if rawMatch(s, suffix, i, c) == s.len - i: return true -proc replacef*(s: string, sub: TPeg, by: string): string {. +proc replacef*(s: string, sub: Peg, by: string): string {. nosideEffect, rtl, extern: "npegs$1".} = ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2") ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## "var1<-keykey; val2<-key2key2" result = "" var i = 0 var caps: array[0..maxSubpatterns-1, string] - var c: TCaptures + var c: Captures while i < s.len: c.ml = 0 var x = rawMatch(s, sub, i, c) @@ -928,13 +920,13 @@ proc replacef*(s: string, sub: TPeg, by: string): string {. inc(i, x) add(result, substr(s, i)) -proc replace*(s: string, sub: TPeg, by = ""): string {. +proc replace*(s: string, sub: Peg, by = ""): string {. nosideEffect, rtl, extern: "npegs$1".} = ## Replaces `sub` in `s` by the string `by`. Captures cannot be accessed ## in `by`. result = "" var i = 0 - var c: TCaptures + var c: Captures while i < s.len: var x = rawMatch(s, sub, i, c) if x <= 0: @@ -946,13 +938,13 @@ proc replace*(s: string, sub: TPeg, by = ""): string {. add(result, substr(s, i)) proc parallelReplace*(s: string, subs: varargs[ - tuple[pattern: TPeg, repl: string]]): string {. + tuple[pattern: Peg, repl: string]]): string {. nosideEffect, rtl, extern: "npegs$1".} = ## Returns a modified copy of `s` with the substitutions in `subs` ## applied in parallel. result = "" var i = 0 - var c: TCaptures + var c: Captures var caps: array[0..maxSubpatterns-1, string] while i < s.len: block searchSubs: @@ -970,7 +962,7 @@ proc parallelReplace*(s: string, subs: varargs[ add(result, substr(s, i)) proc transformFile*(infile, outfile: string, - subs: varargs[tuple[pattern: TPeg, repl: string]]) {. + subs: varargs[tuple[pattern: Peg, repl: string]]) {. rtl, extern: "npegs$1".} = ## reads in the file `infile`, performs a parallel replacement (calls ## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an @@ -978,25 +970,25 @@ proc transformFile*(infile, outfile: string, var x = readFile(infile).string writeFile(outfile, x.parallelReplace(subs)) -iterator split*(s: string, sep: TPeg): string = +iterator split*(s: string, sep: Peg): string = ## Splits the string `s` into substrings. ## ## Substrings are separated by the PEG `sep`. ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split("00232this02939is39an22example111", peg"\d+"): ## writeln(stdout, word) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "this" ## "is" ## "an" ## "example" ## - var c: TCaptures + var c: Captures var first = 0 last = 0 @@ -1013,7 +1005,7 @@ iterator split*(s: string, sep: TPeg): string = if first < last: yield substr(s, first, last-1) -proc split*(s: string, sep: TPeg): seq[string] {. +proc split*(s: string, sep: Peg): seq[string] {. nosideEffect, rtl, extern: "npegs$1".} = ## Splits the string `s` into substrings. accumulateResult(split(s, sep)) @@ -1060,7 +1052,7 @@ type charset: set[char] ## if kind == tkCharSet index: int ## if kind == tkBackref - TPegLexer {.inheritable.} = object ## the lexer object. + PegLexer {.inheritable.} = object ## the lexer object. bufpos: int ## the current position within the buffer buf: cstring ## the buffer itself LineNumber: int ## the current line number @@ -1076,20 +1068,20 @@ const "@", "built-in", "escaped", "$", "$", "^" ] -proc handleCR(L: var TPegLexer, pos: int): int = +proc handleCR(L: var PegLexer, pos: int): int = assert(L.buf[pos] == '\c') inc(L.linenumber) result = pos+1 if L.buf[result] == '\L': inc(result) L.lineStart = result -proc handleLF(L: var TPegLexer, pos: int): int = +proc handleLF(L: var PegLexer, pos: int): int = assert(L.buf[pos] == '\L') inc(L.linenumber) result = pos+1 L.lineStart = result -proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) = +proc init(L: var PegLexer, input, filename: string, line = 1, col = 0) = L.buf = input L.bufpos = 0 L.lineNumber = line @@ -1097,18 +1089,18 @@ proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) = L.lineStart = 0 L.filename = filename -proc getColumn(L: TPegLexer): int {.inline.} = +proc getColumn(L: PegLexer): int {.inline.} = result = abs(L.bufpos - L.lineStart) + L.colOffset -proc getLine(L: TPegLexer): int {.inline.} = +proc getLine(L: PegLexer): int {.inline.} = result = L.linenumber -proc errorStr(L: TPegLexer, msg: string, line = -1, col = -1): string = +proc errorStr(L: PegLexer, msg: string, line = -1, col = -1): string = var line = if line < 0: getLine(L) else: line var col = if col < 0: getColumn(L) else: col result = "$1($2, $3) Error: $4" % [L.filename, $line, $col, msg] -proc handleHexChar(c: var TPegLexer, xi: var int) = +proc handleHexChar(c: var PegLexer, xi: var int) = case c.buf[c.bufpos] of '0'..'9': xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) @@ -1121,7 +1113,7 @@ proc handleHexChar(c: var TPegLexer, xi: var int) = inc(c.bufpos) else: discard -proc getEscapedChar(c: var TPegLexer, tok: var TToken) = +proc getEscapedChar(c: var PegLexer, tok: var TToken) = inc(c.bufpos) case c.buf[c.bufpos] of 'r', 'R', 'c', 'C': @@ -1173,7 +1165,7 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) = add(tok.literal, c.buf[c.bufpos]) inc(c.bufpos) -proc skip(c: var TPegLexer) = +proc skip(c: var PegLexer) = var pos = c.bufpos var buf = c.buf while true: @@ -1192,7 +1184,7 @@ proc skip(c: var TPegLexer) = break # EndOfFile also leaves the loop c.bufpos = pos -proc getString(c: var TPegLexer, tok: var TToken) = +proc getString(c: var PegLexer, tok: var TToken) = tok.kind = tkStringLit var pos = c.bufPos + 1 var buf = c.buf @@ -1214,7 +1206,7 @@ proc getString(c: var TPegLexer, tok: var TToken) = inc(pos) c.bufpos = pos -proc getDollar(c: var TPegLexer, tok: var TToken) = +proc getDollar(c: var PegLexer, tok: var TToken) = var pos = c.bufPos + 1 var buf = c.buf if buf[pos] in {'0'..'9'}: @@ -1227,7 +1219,7 @@ proc getDollar(c: var TPegLexer, tok: var TToken) = tok.kind = tkDollar c.bufpos = pos -proc getCharSet(c: var TPegLexer, tok: var TToken) = +proc getCharSet(c: var PegLexer, tok: var TToken) = tok.kind = tkCharSet tok.charset = {} var pos = c.bufPos + 1 @@ -1278,7 +1270,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) = c.bufpos = pos if caret: tok.charset = {'\1'..'\xFF'} - tok.charset -proc getSymbol(c: var TPegLexer, tok: var TToken) = +proc getSymbol(c: var PegLexer, tok: var TToken) = var pos = c.bufpos var buf = c.buf while true: @@ -1288,7 +1280,7 @@ proc getSymbol(c: var TPegLexer, tok: var TToken) = c.bufpos = pos tok.kind = tkIdentifier -proc getBuiltin(c: var TPegLexer, tok: var TToken) = +proc getBuiltin(c: var PegLexer, tok: var TToken) = if c.buf[c.bufpos+1] in strutils.Letters: inc(c.bufpos) getSymbol(c, tok) @@ -1297,7 +1289,7 @@ proc getBuiltin(c: var TPegLexer, tok: var TToken) = tok.kind = tkEscaped getEscapedChar(c, tok) # may set tok.kind to tkInvalid -proc getTok(c: var TPegLexer, tok: var TToken) = +proc getTok(c: var PegLexer, tok: var TToken) = tok.kind = tkInvalid tok.modifier = modNone setLen(tok.literal, 0) @@ -1403,7 +1395,7 @@ proc getTok(c: var TPegLexer, tok: var TToken) = add(tok.literal, c.buf[c.bufpos]) inc(c.bufpos) -proc arrowIsNextTok(c: TPegLexer): bool = +proc arrowIsNextTok(c: PegLexer): bool = # the only look ahead we need var pos = c.bufpos while c.buf[pos] in {'\t', ' '}: inc(pos) @@ -1414,31 +1406,31 @@ proc arrowIsNextTok(c: TPegLexer): bool = type EInvalidPeg* = object of EInvalidValue ## raised if an invalid ## PEG has been detected - TPegParser = object of TPegLexer ## the PEG parser object + PegParser = object of PegLexer ## the PEG parser object tok: TToken nonterms: seq[PNonTerminal] modifier: TModifier captures: int identIsVerbatim: bool - skip: TPeg + skip: Peg -proc pegError(p: TPegParser, msg: string, line = -1, col = -1) = +proc pegError(p: PegParser, msg: string, line = -1, col = -1) = var e: ref EInvalidPeg new(e) e.msg = errorStr(p, msg, line, col) raise e -proc getTok(p: var TPegParser) = +proc getTok(p: var PegParser) = getTok(p, p.tok) if p.tok.kind == tkInvalid: pegError(p, "invalid token") -proc eat(p: var TPegParser, kind: TTokKind) = +proc eat(p: var PegParser, kind: TTokKind) = if p.tok.kind == kind: getTok(p) else: pegError(p, tokKindToStr[kind] & " expected") -proc parseExpr(p: var TPegParser): TPeg +proc parseExpr(p: var PegParser): Peg -proc getNonTerminal(p: var TPegParser, name: string): PNonTerminal = +proc getNonTerminal(p: var PegParser, name: string): PNonTerminal = for i in 0..high(p.nonterms): result = p.nonterms[i] if cmpIgnoreStyle(result.name, name) == 0: return @@ -1446,19 +1438,19 @@ proc getNonTerminal(p: var TPegParser, name: string): PNonTerminal = result = newNonTerminal(name, getLine(p), getColumn(p)) add(p.nonterms, result) -proc modifiedTerm(s: string, m: TModifier): TPeg = +proc modifiedTerm(s: string, m: TModifier): Peg = case m of modNone, modVerbatim: result = term(s) of modIgnoreCase: result = termIgnoreCase(s) of modIgnoreStyle: result = termIgnoreStyle(s) -proc modifiedBackref(s: int, m: TModifier): TPeg = +proc modifiedBackref(s: int, m: TModifier): Peg = case m of modNone, modVerbatim: result = backref(s) of modIgnoreCase: result = backrefIgnoreCase(s) of modIgnoreStyle: result = backrefIgnoreStyle(s) -proc builtin(p: var TPegParser): TPeg = +proc builtin(p: var PegParser): Peg = # do not use "y", "skip" or "i" as these would be ambiguous case p.tok.literal of "n": result = newLine() @@ -1478,11 +1470,11 @@ proc builtin(p: var TPegParser): TPeg = of "white": result = unicodeWhitespace() else: pegError(p, "unknown built-in: " & p.tok.literal) -proc token(terminal: TPeg, p: TPegParser): TPeg = +proc token(terminal: Peg, p: PegParser): Peg = if p.skip.kind == pkEmpty: result = terminal else: result = sequence(p.skip, terminal) -proc primary(p: var TPegParser): TPeg = +proc primary(p: var PegParser): Peg = case p.tok.kind of tkAmp: getTok(p) @@ -1571,7 +1563,7 @@ proc primary(p: var TPegParser): TPeg = getTok(p) else: break -proc seqExpr(p: var TPegParser): TPeg = +proc seqExpr(p: var PegParser): Peg = result = primary(p) while true: case p.tok.kind @@ -1585,13 +1577,13 @@ proc seqExpr(p: var TPegParser): TPeg = else: break else: break -proc parseExpr(p: var TPegParser): TPeg = +proc parseExpr(p: var PegParser): Peg = result = seqExpr(p) while p.tok.kind == tkBar: getTok(p) result = result / seqExpr(p) -proc parseRule(p: var TPegParser): PNonTerminal = +proc parseRule(p: var PegParser): PNonTerminal = if p.tok.kind == tkIdentifier and arrowIsNextTok(p): result = getNonTerminal(p, p.tok.literal) if ntDeclared in result.flags: @@ -1605,7 +1597,7 @@ proc parseRule(p: var TPegParser): PNonTerminal = else: pegError(p, "rule expected, but found: " & p.tok.literal) -proc rawParse(p: var TPegParser): TPeg = +proc rawParse(p: var PegParser): Peg = ## parses a rule or a PEG expression while p.tok.kind == tkBuiltin: case p.tok.literal @@ -1635,12 +1627,12 @@ proc rawParse(p: var TPegParser): TPeg = elif ntUsed notin nt.flags and i > 0: pegError(p, "unused rule: " & nt.name, nt.line, nt.col) -proc parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): TPeg = - ## constructs a TPeg object from `pattern`. `filename`, `line`, `col` are +proc parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): Peg = + ## constructs a Peg object from `pattern`. `filename`, `line`, `col` are ## used for error messages, but they only provide start offsets. `parsePeg` ## keeps track of line and column numbers within `pattern`. - var p: TPegParser - init(TPegLexer(p), pattern, filename, line, col) + var p: PegParser + init(PegLexer(p), pattern, filename, line, col) p.tok.kind = tkInvalid p.tok.modifier = modNone p.tok.literal = "" @@ -1650,8 +1642,8 @@ proc parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): TPeg = getTok(p) result = rawParse(p) -proc peg*(pattern: string): TPeg = - ## constructs a TPeg object from the `pattern`. The short name has been +proc peg*(pattern: string): Peg = + ## constructs a Peg object from the `pattern`. The short name has been ## chosen to encourage its use as a raw string modifier:: ## ## peg"{\ident} \s* '=' \s* {.*}" @@ -1704,7 +1696,7 @@ when isMainModule: expr.rule = sequence(capture(ident), *sequence( nonterminal(ws), term('+'), nonterminal(ws), nonterminal(expr))) - var c: TCaptures + var c: Captures var s = "a+b + c +d+e+f" assert rawMatch(s, expr.rule, 0, c) == len(s) var a = "" diff --git a/lib/pure/poly.nim b/lib/pure/poly.nim index 45e528604..19bed2aca 100644 --- a/lib/pure/poly.nim +++ b/lib/pure/poly.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Robert Persson # # See the file "copying.txt", included in this @@ -12,10 +12,11 @@ import strutils import numeric type - TPoly* = object - cofs:seq[float] + Poly* = object + cofs:seq[float] + +{.deprecated: [TPoly: Poly].} - proc degree*(p:TPoly):int= ## Returns the degree of the polynomial, ## that is the number of coefficients-1 @@ -104,7 +105,7 @@ proc `$` *(p:TPoly):string = result="0" -proc derivative*(p:TPoly):TPoly= +proc derivative*(p: TPoly): TPoly= ## Returns a new polynomial, which is the derivative of `p` newSeq[float](result.cofs,p.degree) for idx in 0..high(result.cofs): @@ -310,10 +311,10 @@ proc getRangeForRoots(p:TPoly):tuple[xmin,xmax:float]= var bound1,bound2:float for i in countup(0,deg): - var c=abs(p.cofs[i]/d) - bound1=max(bound1,c+1.0) - bound2=bound2+c - + var c=abs(p.cofs[i]/d) + bound1=max(bound1,c+1.0) + bound2=bound2+c + bound2=max(1.0,bound2) result.xmax=min(bound1,bound2) result.xmin= -result.xmax diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index fea09dfa2..14a494ecf 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -28,7 +28,7 @@ else: export fcntl, F_GETFL, O_NONBLOCK, F_SETFL, EAGAIN, EWOULDBLOCK, MSG_NOSIGNAL, EINTR, EINPROGRESS, ECONNRESET, EPIPE, ENETRESET -export TSocketHandle, TSockaddr_in, TAddrinfo, INADDR_ANY, TSockAddr, TSockLen, +export SocketHandle, Sockaddr_in, Addrinfo, INADDR_ANY, SockAddr, SockLen, inet_ntoa, recv, `==`, connect, send, accept, recvfrom, sendto export @@ -40,22 +40,22 @@ export MSG_PEEK type - TPort* = distinct uint16 ## port type + Port* = distinct uint16 ## port type - TDomain* = enum ## domain, which specifies the protocol family of the + Domain* = enum ## domain, which specifies the protocol family of the ## created socket. Other domains than those that are listed ## here are unsupported. AF_UNIX, ## for local socket (using a file). Unsupported on Windows. AF_INET = 2, ## for network protocol IPv4 or AF_INET6 = 23 ## for network protocol IPv6. - TType* = enum ## second argument to `socket` proc + SockType* = enum ## second argument to `socket` proc SOCK_STREAM = 1, ## reliable stream-oriented service or Stream Sockets SOCK_DGRAM = 2, ## datagram service or Datagram Sockets SOCK_RAW = 3, ## raw protocols atop the network layer. SOCK_SEQPACKET = 5 ## reliable sequenced packet service - TProtocol* = enum ## third argument to `socket` proc + Protocol* = enum ## third argument to `socket` proc IPPROTO_TCP = 6, ## Transmission control protocol. IPPROTO_UDP = 17, ## User datagram protocol. IPPROTO_IP, ## Internet protocol. Unsupported on Windows. @@ -63,19 +63,22 @@ type IPPROTO_RAW, ## Raw IP Packets Protocol. Unsupported on Windows. IPPROTO_ICMP ## Control message protocol. Unsupported on Windows. - TServent* {.pure, final.} = object ## information about a service + Servent* = object ## information about a service name*: string aliases*: seq[string] - port*: TPort + port*: Port proto*: string - Thostent* {.pure, final.} = object ## information about a given host + Hostent* = object ## information about a given host name*: string aliases*: seq[string] - addrtype*: TDomain + addrtype*: Domain length*: int addrList*: seq[string] +{.deprecated: [TPort: Port, TDomain: Domain, TType: SockType, + TProtocol: Protocol, TServent: Servent, THostent: Hostent].} + when useWinVersion: let osInvalidSocket* = winlean.INVALID_SOCKET @@ -86,37 +89,37 @@ when useWinVersion: FIONBIO* = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or (102 shl 8) or 126 - proc ioctlsocket*(s: TSocketHandle, cmd: clong, + proc ioctlsocket*(s: SocketHandle, cmd: clong, argptr: ptr clong): cint {. stdcall, importc: "ioctlsocket", dynlib: "ws2_32.dll".} else: let osInvalidSocket* = posix.INVALID_SOCKET -proc `==`*(a, b: TPort): bool {.borrow.} +proc `==`*(a, b: Port): bool {.borrow.} ## ``==`` for ports. -proc `$`*(p: TPort): string {.borrow.} +proc `$`*(p: Port): string {.borrow.} ## returns the port number as a string -proc toInt*(domain: TDomain): cint +proc toInt*(domain: Domain): cint ## Converts the TDomain enum to a platform-dependent ``cint``. -proc toInt*(typ: TType): cint +proc toInt*(typ: SockType): cint ## Converts the TType enum to a platform-dependent ``cint``. -proc toInt*(p: TProtocol): cint +proc toInt*(p: Protocol): cint ## Converts the TProtocol enum to a platform-dependent ``cint``. when not useWinVersion: - proc toInt(domain: TDomain): cint = + proc toInt(domain: Domain): cint = case domain of AF_UNIX: result = posix.AF_UNIX of AF_INET: result = posix.AF_INET of AF_INET6: result = posix.AF_INET6 else: discard - proc toInt(typ: TType): cint = + proc toInt(typ: SockType): cint = case typ of SOCK_STREAM: result = posix.SOCK_STREAM of SOCK_DGRAM: result = posix.SOCK_DGRAM @@ -124,7 +127,7 @@ when not useWinVersion: of SOCK_RAW: result = posix.SOCK_RAW else: discard - proc toInt(p: TProtocol): cint = + proc toInt(p: Protocol): cint = case p of IPPROTO_TCP: result = posix.IPPROTO_TCP of IPPROTO_UDP: result = posix.IPPROTO_UDP @@ -135,22 +138,22 @@ when not useWinVersion: else: discard else: - proc toInt(domain: TDomain): cint = + proc toInt(domain: Domain): cint = result = toU16(ord(domain)) - proc toInt(typ: TType): cint = + proc toInt(typ: SockType): cint = result = cint(ord(typ)) - proc toInt(p: TProtocol): cint = + proc toInt(p: Protocol): cint = result = cint(ord(p)) -proc newRawSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP): TSocketHandle = +proc newRawSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP): SocketHandle = ## Creates a new socket; returns `InvalidSocket` if an error occurs. socket(toInt(domain), toInt(typ), toInt(protocol)) -proc close*(socket: TSocketHandle) = +proc close*(socket: SocketHandle) = ## closes a socket. when useWinVersion: discard winlean.closeSocket(socket) @@ -159,10 +162,10 @@ proc close*(socket: TSocketHandle) = # TODO: These values should not be discarded. An EOS should be raised. # http://stackoverflow.com/questions/12463473/what-happens-if-you-call-close-on-a-bsd-socket-multiple-times -proc bindAddr*(socket: TSocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint = +proc bindAddr*(socket: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint = result = bindSocket(socket, name, namelen) -proc listen*(socket: TSocketHandle, backlog = SOMAXCONN): cint {.tags: [FReadIO].} = +proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [FReadIO].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. @@ -171,12 +174,12 @@ proc listen*(socket: TSocketHandle, backlog = SOMAXCONN): cint {.tags: [FReadIO] else: result = posix.listen(socket, cint(backlog)) -proc getAddrInfo*(address: string, port: TPort, af: TDomain = AF_INET, typ: TType = SOCK_STREAM, - prot: TProtocol = IPPROTO_TCP): ptr TAddrInfo = +proc getAddrInfo*(address: string, port: Port, af: Domain = AF_INET, typ: SockType = SOCK_STREAM, + prot: Protocol = IPPROTO_TCP): ptr AddrInfo = ## ## ## **Warning**: The resulting ``ptr TAddrInfo`` must be freed using ``dealloc``! - var hints: TAddrInfo + var hints: AddrInfo result = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(typ) @@ -184,11 +187,11 @@ proc getAddrInfo*(address: string, port: TPort, af: TDomain = AF_INET, typ: TTyp var gaiResult = getAddrInfo(address, $port, addr(hints), result) if gaiResult != 0'i32: when useWinVersion: - osError(osLastError()) + raiseOSError(osLastError()) else: raise newException(EOS, $gai_strerror(gaiResult)) -proc dealloc*(ai: ptr TAddrInfo) = +proc dealloc*(ai: ptr AddrInfo) = freeaddrinfo(ai) proc ntohl*(x: int32): int32 = @@ -220,7 +223,7 @@ proc htons*(x: int16): int16 = ## order, this is a no-op; otherwise, it performs a 2-byte swap operation. result = rawsockets.ntohs(x) -proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} = +proc getServByName*(name, proto: string): Servent {.tags: [FReadIO].} = ## Searches the database from the beginning and finds the first entry for ## which the service name specified by ``name`` matches the s_name member ## and the protocol name specified by ``proto`` matches the s_proto member. @@ -233,10 +236,10 @@ proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} = if s == nil: raise newException(EOS, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) - result.port = TPort(s.s_port) + result.port = Port(s.s_port) result.proto = $s.s_proto -proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = +proc getServByPort*(port: Port, proto: string): Servent {.tags: [FReadIO].} = ## Searches the database from the beginning and finds the first entry for ## which the port specified by ``port`` matches the s_port member and the ## protocol name specified by ``proto`` matches the s_proto member. @@ -249,28 +252,28 @@ proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} = if s == nil: raise newException(EOS, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) - result.port = TPort(s.s_port) + result.port = Port(s.s_port) result.proto = $s.s_proto -proc getHostByAddr*(ip: string): Thostent {.tags: [FReadIO].} = +proc getHostByAddr*(ip: string): Hostent {.tags: [FReadIO].} = ## This function will lookup the hostname of an IP Address. - var myaddr: TInAddr + var myaddr: InAddr myaddr.s_addr = inet_addr(ip) when useWinVersion: var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint, cint(rawsockets.AF_INET)) - if s == nil: osError(osLastError()) + if s == nil: raiseOSError(osLastError()) else: - var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).TSocklen, + var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen, cint(posix.AF_INET)) if s == nil: raise newException(EOS, $hstrerror(h_errno)) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) - when useWinVersion: - result.addrtype = TDomain(s.h_addrtype) + when useWinVersion: + result.addrtype = Domain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: result.addrtype = AF_INET @@ -281,17 +284,17 @@ proc getHostByAddr*(ip: string): Thostent {.tags: [FReadIO].} = result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getHostByName*(name: string): Thostent {.tags: [FReadIO].} = +proc getHostByName*(name: string): Hostent {.tags: [FReadIO].} = ## This function will lookup the IP address of a hostname. when useWinVersion: var s = winlean.gethostbyname(name) else: var s = posix.gethostbyname(name) - if s == nil: osError(osLastError()) + if s == nil: raiseOSError(osLastError()) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) - when useWinVersion: - result.addrtype = TDomain(s.h_addrtype) + when useWinVersion: + result.addrtype = Domain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: result.addrtype = AF_INET @@ -302,69 +305,69 @@ proc getHostByName*(name: string): Thostent {.tags: [FReadIO].} = result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getSockName*(socket: TSocketHandle): TPort = +proc getSockName*(socket: SocketHandle): Port = ## returns the socket's associated port number. - var name: Tsockaddr_in + var name: Sockaddr_in when useWinVersion: name.sin_family = int16(ord(AF_INET)) else: name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).TSocklen - if getsockname(socket, cast[ptr TSockAddr](addr(name)), + var namelen = sizeof(name).Socklen + if getsockname(socket, cast[ptr SockAddr](addr(name)), addr(namelen)) == -1'i32: - osError(osLastError()) - result = TPort(rawsockets.ntohs(name.sin_port)) + raiseOSError(osLastError()) + result = Port(rawsockets.ntohs(name.sin_port)) -proc getSockOptInt*(socket: TSocketHandle, level, optname: int): int {. +proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {. tags: [FReadIO].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).TSocklen + var size = sizeof(res).Socklen if getsockopt(socket, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) result = int(res) -proc setSockOptInt*(socket: TSocketHandle, level, optname, optval: int) {. +proc setSockOptInt*(socket: SocketHandle, level, optname, optval: int) {. tags: [FWriteIO].} = ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket, cint(level), cint(optname), addr(value), - sizeof(value).TSocklen) < 0'i32: - osError(osLastError()) + sizeof(value).Socklen) < 0'i32: + raiseOSError(osLastError()) -proc setBlocking*(s: TSocketHandle, blocking: bool) = +proc setBlocking*(s: SocketHandle, blocking: bool) = ## Sets blocking mode on socket. ## ## Raises EOS on error. when useWinVersion: var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking if ioctlsocket(s, FIONBIO, addr(mode)) == -1: - osError(osLastError()) + raiseOSError(osLastError()) else: # BSD sockets var x: int = fcntl(s, F_GETFL, 0) if x == -1: - osError(osLastError()) + raiseOSError(osLastError()) else: var mode = if blocking: x and not O_NONBLOCK else: x or O_NONBLOCK if fcntl(s, F_SETFL, mode) == -1: - osError(osLastError()) + raiseOSError(osLastError()) -proc timeValFromMilliseconds(timeout = 500): Ttimeval = +proc timeValFromMilliseconds(timeout = 500): Timeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var TFdSet, s: seq[TSocketHandle], m: var int) = +proc createFdSet(fd: var FdSet, s: seq[SocketHandle], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i)) FD_SET(i, fd) -proc pruneSocketSet(s: var seq[TSocketHandle], fd: var TFdSet) = +proc pruneSocketSet(s: var seq[SocketHandle], fd: var FdSet) = var i = 0 var L = s.len while i < L: @@ -375,7 +378,7 @@ proc pruneSocketSet(s: var seq[TSocketHandle], fd: var TFdSet) = inc(i) setLen(s, L) -proc select*(readfds: var seq[TSocketHandle], timeout = 500): int = +proc select*(readfds: var seq[SocketHandle], timeout = 500): int = ## Traditional select function. This function will return the number of ## sockets that are ready to be read from, written to, or which have errors. ## If there are none; 0 is returned. @@ -396,7 +399,7 @@ proc select*(readfds: var seq[TSocketHandle], timeout = 500): int = pruneSocketSet(readfds, (rd)) -proc selectWrite*(writefds: var seq[TSocketHandle], +proc selectWrite*(writefds: var seq[SocketHandle], timeout = 500): int {.tags: [FReadIO].} = ## When a socket in ``writefds`` is ready to be written to then a non-zero ## value will be returned specifying the count of the sockets which can be @@ -405,7 +408,7 @@ proc selectWrite*(writefds: var seq[TSocketHandle], ## ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for ## an unlimited time. - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var wr: TFdSet var m = 0 @@ -419,5 +422,5 @@ proc selectWrite*(writefds: var seq[TSocketHandle], pruneSocketSet(writefds, (wr)) when defined(Windows): - var wsa: TWSADATA - if WSAStartup(0x0101'i16, addr wsa) != 0: osError(osLastError()) + var wsa: WSADATA + if WSAStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) diff --git a/lib/pure/redis.nim b/lib/pure/redis.nim index 959f5c6ef..ab3b81f37 100644 --- a/lib/pure/redis.nim +++ b/lib/pure/redis.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -20,36 +20,40 @@ const redisNil* = "\0\0" type - PPipeline = ref object + Pipeline = ref object enabled: bool buffer: string expected: int ## number of replies expected if pipelined type - TSendMode = enum + SendMode = enum normal, pipelined, multiple type - TRedis* {.pure, final.} = object + Redis* = object socket: TSocket connected: bool - pipeline: PPipeline + pipeline: Pipeline - TRedisStatus* = string - TRedisInteger* = biggestInt - TRedisString* = string ## Bulk reply - TRedisList* = seq[TRedisString] ## Multi-bulk reply + RedisStatus* = string + RedisInteger* = BiggestInt + RedisString* = string ## Bulk reply + RedisList* = seq[RedisString] ## Multi-bulk reply - EInvalidReply* = object of ESynch ## Invalid reply from redis - ERedis* = object of ESynch ## Error in redis + ReplyError* = object of IOError ## Invalid reply from redis + RedisError* = object of IOError ## Error in redis -proc newPipeline(): PPipeline = +{.deprecated: [TSendMode: SendMode, TRedis: Redis, TRedisStatus: RedisStatus, + TRedisInteger: RedisInteger, TRedisString: RedisString, + TRedisList: RedistList, EInvalidReply: ReplyError, ERedis: RedisError].} + +proc newPipeline(): Pipeline = new(result) result.buffer = "" result.enabled = false result.expected = 0 -proc open*(host = "localhost", port = 6379.TPort): TRedis = +proc open*(host = "localhost", port = 6379.Port): Redis = ## Opens a connection to the redis server. result.socket = socket(buffered = false) if result.socket == InvalidSocket: @@ -58,24 +62,24 @@ proc open*(host = "localhost", port = 6379.TPort): TRedis = result.pipeline = newPipeline() proc raiseInvalidReply(expected, got: char) = - raise newException(EInvalidReply, + raise newException(ReplyError, "Expected '$1' at the beginning of a status reply got '$2'" % [$expected, $got]) -proc raiseNoOK(status: string, pipelineEnabled:bool) = +proc raiseNoOK(status: string, pipelineEnabled: bool) = if pipelineEnabled and not (status == "QUEUED" or status == "PIPELINED"): raise newException(EInvalidReply, "Expected \"QUEUED\" or \"PIPELINED\" got \"$1\"" % status) elif not pipelineEnabled and status != "OK": raise newException(EInvalidReply, "Expected \"OK\" got \"$1\"" % status) -template readSocket(r: TRedis, dummyVal:expr): stmt = - var line {.inject.} :TaintedString = "" +template readSocket(r: Redis, dummyVal:expr): stmt = + var line {.inject.}: TaintedString = "" if r.pipeline.enabled: return dummyVal else: readLine(r.socket, line) -proc parseStatus(r: TRedis, line: string = ""): TRedisStatus = +proc parseStatus(r: Redis, line: string = ""): RedisStatus = if r.pipeline.enabled: return "PIPELINED" diff --git a/lib/pure/romans.nim b/lib/pure/romans.nim index dee3226d8..79fb75526 100644 --- a/lib/pure/romans.nim +++ b/lib/pure/romans.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2011 Philippe Lhoste # # See the file "copying.txt", included in this diff --git a/lib/pure/ropes.nim b/lib/pure/ropes.nim index eb3792bce..8205203ba 100644 --- a/lib/pure/ropes.nim +++ b/lib/pure/ropes.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -30,13 +30,15 @@ var cacheEnabled = false type - PRope* = ref TRope ## empty rope is represented by nil - TRope {.acyclic, final, pure.} = object - left, right: PRope + Rope* = ref RopeObj ## empty rope is represented by nil + RopeObj {.acyclic.} = object + left, right: Rope length: int data: string # != nil if a leaf -proc isConc(r: PRope): bool {.inline.} = return isNil(r.data) +{.deprecated: [PRope: Rope].} + +proc isConc(r: Rope): bool {.inline.} = return isNil(r.data) # Note that the left and right pointers are not needed for leafs. # Leaves have relatively high memory overhead (~30 bytes on a 32 @@ -46,25 +48,25 @@ proc isConc(r: PRope): bool {.inline.} = return isNil(r.data) # performance. But for the caching tree we use the leaf's left and right # pointers. -proc len*(a: PRope): int {.rtl, extern: "nro$1".} = +proc len*(a: Rope): int {.rtl, extern: "nro$1".} = ## the rope's length if a == nil: result = 0 else: result = a.length -proc newRope(): PRope = new(result) -proc newRope(data: string): PRope = +proc newRope(): Rope = new(result) +proc newRope(data: string): Rope = new(result) result.length = len(data) result.data = data var - cache {.threadvar.}: PRope # the root of the cache tree - N {.threadvar.}: PRope # dummy rope needed for splay algorithm + cache {.threadvar.}: Rope # the root of the cache tree + N {.threadvar.}: Rope # dummy rope needed for splay algorithm when countCacheMisses: var misses, hits: int -proc splay(s: string, tree: PRope, cmpres: var int): PRope = +proc splay(s: string, tree: Rope, cmpres: var int): Rope = var c: int var t = tree N.left = nil @@ -102,7 +104,7 @@ proc splay(s: string, tree: PRope, cmpres: var int): PRope = t.right = N.left result = t -proc insertInCache(s: string, tree: PRope): PRope = +proc insertInCache(s: string, tree: Rope): Rope = var t = tree if t == nil: result = newRope(s) @@ -128,7 +130,7 @@ proc insertInCache(s: string, tree: PRope): PRope = result.left = t t.right = nil -proc rope*(s: string): PRope {.rtl, extern: "nro$1Str".} = +proc rope*(s: string): Rope {.rtl, extern: "nro$1Str".} = ## Converts a string to a rope. if s.len == 0: result = nil @@ -138,11 +140,11 @@ proc rope*(s: string): PRope {.rtl, extern: "nro$1Str".} = else: result = newRope(s) -proc rope*(i: BiggestInt): PRope {.rtl, extern: "nro$1BiggestInt".} = +proc rope*(i: BiggestInt): Rope {.rtl, extern: "nro$1BiggestInt".} = ## Converts an int to a rope. result = rope($i) -proc rope*(f: BiggestFloat): PRope {.rtl, extern: "nro$1BiggestFloat".} = +proc rope*(f: BiggestFloat): Rope {.rtl, extern: "nro$1BiggestFloat".} = ## Converts a float to a rope. result = rope($f) @@ -156,7 +158,7 @@ proc disableCache*() {.rtl, extern: "nro$1".} = cache = nil cacheEnabled = false -proc `&`*(a, b: PRope): PRope {.rtl, extern: "nroConcRopeRope".} = +proc `&`*(a, b: Rope): Rope {.rtl, extern: "nroConcRopeRope".} = ## the concatenation operator for ropes. if a == nil: result = b @@ -176,27 +178,27 @@ proc `&`*(a, b: PRope): PRope {.rtl, extern: "nroConcRopeRope".} = result.left = a result.right = b -proc `&`*(a: PRope, b: string): PRope {.rtl, extern: "nroConcRopeStr".} = +proc `&`*(a: Rope, b: string): Rope {.rtl, extern: "nroConcRopeStr".} = ## the concatenation operator for ropes. result = a & rope(b) -proc `&`*(a: string, b: PRope): PRope {.rtl, extern: "nroConcStrRope".} = +proc `&`*(a: string, b: Rope): Rope {.rtl, extern: "nroConcStrRope".} = ## the concatenation operator for ropes. result = rope(a) & b -proc `&`*(a: openarray[PRope]): PRope {.rtl, extern: "nroConcOpenArray".} = +proc `&`*(a: openarray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} = ## the concatenation operator for an openarray of ropes. for i in countup(0, high(a)): result = result & a[i] -proc add*(a: var PRope, b: PRope) {.rtl, extern: "nro$1Rope".} = +proc add*(a: var Rope, b: Rope) {.rtl, extern: "nro$1Rope".} = ## adds `b` to the rope `a`. a = a & b -proc add*(a: var PRope, b: string) {.rtl, extern: "nro$1Str".} = +proc add*(a: var Rope, b: string) {.rtl, extern: "nro$1Str".} = ## adds `b` to the rope `a`. a = a & b -proc `[]`*(r: PRope, i: int): char {.rtl, extern: "nroCharAt".} = +proc `[]`*(r: Rope, i: int): char {.rtl, extern: "nroCharAt".} = ## returns the character at position `i` in the rope `r`. This is quite ## expensive! Worst-case: O(n). If ``i >= r.len``, ``\0`` is returned. var x = r @@ -213,7 +215,7 @@ proc `[]`*(r: PRope, i: int): char {.rtl, extern: "nroCharAt".} = x = x.right dec(j, x.len) -iterator leaves*(r: PRope): string = +iterator leaves*(r: Rope): string = ## iterates over any leaf string in the rope `r`. if r != nil: var stack = @[r] @@ -226,16 +228,16 @@ iterator leaves*(r: PRope): string = assert(it.data != nil) yield it.data -iterator items*(r: PRope): char = +iterator items*(r: Rope): char = ## iterates over any character in the rope `r`. for s in leaves(r): for c in items(s): yield c -proc write*(f: TFile, r: PRope) {.rtl, extern: "nro$1".} = +proc write*(f: TFile, r: Rope) {.rtl, extern: "nro$1".} = ## writes a rope to a file. for s in leaves(r): write(f, s) -proc `$`*(r: PRope): string {.rtl, extern: "nroToString".}= +proc `$`*(r: Rope): string {.rtl, extern: "nroToString".}= ## converts a rope back to a string. result = newString(r.len) setLen(result, 0) @@ -245,11 +247,11 @@ when false: # Format string caching seems reasonable: All leaves can be shared and format # string parsing has to be done only once. A compiled format string is stored # as a rope. A negative length is used for the index into the args array. - proc compiledArg(idx: int): PRope = + proc compiledArg(idx: int): Rope = new(result) result.length = -idx - proc compileFrmt(frmt: string): PRope = + proc compileFrmt(frmt: string): Rope = var i = 0 var length = len(frmt) result = nil @@ -289,7 +291,7 @@ when false: if i - 1 >= start: add(result, substr(frmt, start, i-1)) -proc `%`*(frmt: string, args: openarray[PRope]): PRope {. +proc `%`*(frmt: string, args: openarray[Rope]): Rope {. rtl, extern: "nroFormat".} = ## `%` substitution operator for ropes. Does not support the ``$identifier`` ## nor ``${identifier}`` notations. @@ -332,12 +334,12 @@ proc `%`*(frmt: string, args: openarray[PRope]): PRope {. if i - 1 >= start: add(result, substr(frmt, start, i - 1)) -proc addf*(c: var PRope, frmt: string, args: openarray[PRope]) {. +proc addf*(c: var Rope, frmt: string, args: openarray[Rope]) {. rtl, extern: "nro$1".} = ## shortcut for ``add(c, frmt % args)``. add(c, frmt % args) -proc equalsFile*(r: PRope, f: TFile): bool {.rtl, extern: "nro$1File".} = +proc equalsFile*(r: Rope, f: TFile): bool {.rtl, extern: "nro$1File".} = ## returns true if the contents of the file `f` equal `r`. var bufSize = 1024 # reasonable start value var buf = alloc(BufSize) @@ -352,7 +354,7 @@ proc equalsFile*(r: PRope, f: TFile): bool {.rtl, extern: "nro$1File".} = result = readBuffer(f, buf, 1) == 0 # really at the end of file? dealloc(buf) -proc equalsFile*(r: PRope, f: string): bool {.rtl, extern: "nro$1Str".} = +proc equalsFile*(r: Rope, f: string): bool {.rtl, extern: "nro$1Str".} = ## returns true if the contents of the file `f` equal `r`. If `f` does not ## exist, false is returned. var bin: TFile diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim index 45f837833..fa8605a69 100644 --- a/lib/pure/scgi.nim +++ b/lib/pure/scgi.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this @@ -9,13 +9,13 @@ ## This module implements helper procs for SCGI applications. Example: ## -## .. code-block:: Nimrod +## .. code-block:: Nim ## ## import strtabs, sockets, scgi ## ## var counter = 0 -## proc handleRequest(client: TSocket, input: string, -## headers: PStringTable): bool {.procvar.} = +## proc handleRequest(client: Socket, input: string, +## headers: StringTableRef): bool {.procvar.} = ## inc(counter) ## client.writeStatusOkTextContent() ## client.send("Hello for the $#th time." % $counter & "\c\L") @@ -31,11 +31,11 @@ include "system/inclrtl" import sockets, strutils, os, strtabs, asyncio type - EScgi* = object of EIO ## the exception that is raised, if a SCGI error occurs + ScgiError* = object of IOError ## the exception that is raised, if a SCGI error occurs -proc scgiError*(msg: string) {.noreturn.} = - ## raises an EScgi exception with message `msg`. - var e: ref EScgi +proc raiseScgiError*(msg: string) {.noreturn.} = + ## raises an ScgiError exception with message `msg`. + var e: ref ScgiError new(e) e.msg = msg raise e @@ -45,7 +45,7 @@ proc parseWord(inp: string, outp: var string, start: int): int = while inp[result] != '\0': inc(result) outp = substr(inp, start, result-1) -proc parseHeaders(s: string, L: int): PStringTable = +proc parseHeaders(s: string, L: int): StringTableRef = result = newStringTable() var i = 0 while i < L: @@ -54,73 +54,77 @@ proc parseHeaders(s: string, L: int): PStringTable = i = parseWord(s, val, i)+1 result[key] = val if s[i] == ',': inc(i) - else: scgiError("',' after netstring expected") + else: raiseScgiError("',' after netstring expected") -proc recvChar(s: TSocket): char = +proc recvChar(s: Socket): char = var c: char if recv(s, addr(c), sizeof(c)) == sizeof(c): result = c type - TScgiState* = object of TObject ## SCGI state object - server: TSocket + ScgiState* = object of RootObj ## SCGI state object + server: Socket bufLen: int - client*: TSocket ## the client socket to send data to - headers*: PStringTable ## the parsed headers + client*: Socket ## the client socket to send data to + headers*: StringTableRef ## the parsed headers input*: string ## the input buffer # Async - TClientMode = enum + ClientMode = enum ClientReadChar, ClientReadHeaders, ClientReadContent - PAsyncClient = ref object - c: PAsyncSocket - mode: TClientMode + AsyncClient = ref object + c: AsyncSocket + mode: ClientMode dataLen: int headers: PStringTable ## the parsed headers input: string ## the input buffer - TAsyncScgiState = object - handleRequest: proc (client: PAsyncSocket, - input: string, headers: PStringTable) {.closure,gcsafe.} - asyncServer: PAsyncSocket - disp: PDispatcher - PAsyncScgiState* = ref TAsyncScgiState - -proc recvBuffer(s: var TScgiState, L: int) = + AsyncScgiStateObj = object + handleRequest: proc (client: AsyncSocket, + input: string, + headers: StringTableRef) {.closure, gcsafe.} + asyncServer: AsyncSocket + disp: Dispatcher + AsyncScgiState* = ref AsyncScgiStateObj + +{.deprected: [EScgi: ScgiError, TScgiState: ScgiState, + PAsyncScgiState: AsyncScgiState, scgiError: raiseScgiError].} + +proc recvBuffer(s: var ScgiState, L: int) = if L > s.bufLen: s.bufLen = L s.input = newString(L) if L > 0 and recv(s.client, cstring(s.input), L) != L: - scgiError("could not read all data") + raiseScgiError("could not read all data") setLen(s.input, L) -proc open*(s: var TScgiState, port = TPort(4000), address = "127.0.0.1", - reuseAddr = False) = +proc open*(s: var ScgiState, port = Port(4000), address = "127.0.0.1", + reuseAddr = false) = ## opens a connection. s.bufLen = 4000 s.input = newString(s.buflen) # will be reused s.server = socket() - if s.server == InvalidSocket: osError(osLastError()) + if s.server == InvalidSocket: raiseOSError(osLastError()) new(s.client) # Initialise s.client for `next` - if s.server == InvalidSocket: scgiError("could not open socket") + if s.server == InvalidSocket: raiseScgiError("could not open socket") #s.server.connect(connectionName, port) if reuseAddr: s.server.setSockOpt(OptReuseAddr, True) bindAddr(s.server, port, address) listen(s.server) -proc close*(s: var TScgiState) = +proc close*(s: var ScgiState) = ## closes the connection. s.server.close() -proc next*(s: var TScgistate, timeout: int = -1): bool = +proc next*(s: var ScgiState, timeout: int = -1): bool = ## proceed to the first/next request. Waits ``timeout`` miliseconds for a ## request, if ``timeout`` is `-1` then this function will never time out. - ## Returns `True` if a new request has been processed. + ## Returns `true` if a new request has been processed. var rsocks = @[s.server] if select(rsocks, timeout) == 1 and rsocks.len == 1: new(s.client) @@ -132,17 +136,17 @@ proc next*(s: var TScgistate, timeout: int = -1): bool = s.client.close() return false if d notin strutils.digits: - if d != ':': scgiError("':' after length expected") + if d != ':': raiseScgiError("':' after length expected") break L = L * 10 + ord(d) - ord('0') recvBuffer(s, L+1) s.headers = parseHeaders(s.input, L) - if s.headers["SCGI"] != "1": scgiError("SCGI Version 1 expected") + if s.headers["SCGI"] != "1": raiseScgiError("SCGI Version 1 expected") L = parseInt(s.headers["CONTENT_LENGTH"]) recvBuffer(s, L) return True -proc writeStatusOkTextContent*(c: TSocket, contentType = "text/html") = +proc writeStatusOkTextContent*(c: Socket, contentType = "text/html") = ## sends the following string to the socket `c`:: ## ## Status: 200 OK\r\LContent-Type: text/html\r\L\r\L @@ -151,11 +155,11 @@ proc writeStatusOkTextContent*(c: TSocket, contentType = "text/html") = c.send("Status: 200 OK\r\L" & "Content-Type: $1\r\L\r\L" % contentType) -proc run*(handleRequest: proc (client: TSocket, input: string, - headers: PStringTable): bool {.nimcall,gcsafe.}, - port = TPort(4000)) = +proc run*(handleRequest: proc (client: Socket, input: string, + headers: StringTableRef): bool {.nimcall,gcsafe.}, + port = Port(4000)) = ## encapsulates the SCGI object and main loop. - var s: TScgiState + var s: ScgiState s.open(port) var stop = false while not stop: @@ -166,11 +170,11 @@ proc run*(handleRequest: proc (client: TSocket, input: string, # -- AsyncIO start -proc recvBufferAsync(client: PAsyncClient, L: int): TReadLineResult = +proc recvBufferAsync(client: AsyncClient, L: int): ReadLineResult = result = ReadPartialLine var data = "" if L < 1: - scgiError("Cannot read negative or zero length: " & $L) + raiseScgiError("Cannot read negative or zero length: " & $L) let ret = recvAsync(client.c, data, L) if ret == 0 and data == "": client.c.close() @@ -181,16 +185,16 @@ proc recvBufferAsync(client: PAsyncClient, L: int): TReadLineResult = if ret == L: return ReadFullLine -proc checkCloseSocket(client: PAsyncClient) = +proc checkCloseSocket(client: AsyncClient) = if not client.c.isClosed: if client.c.isSendDataBuffered: - client.c.setHandleWrite do (s: PAsyncSocket): + client.c.setHandleWrite do (s: AsyncSocket): if not s.isClosed and not s.isSendDataBuffered: s.close() s.delHandleWrite() else: client.c.close() -proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) = +proc handleClientRead(client: AsyncClient, s: AsyncScgiState) = case client.mode of ClientReadChar: while true: @@ -203,7 +207,7 @@ proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) = if ret == -1: return # No more data available if d[0] notin strutils.digits: - if d[0] != ':': scgiError("':' after length expected") + if d[0] != ':': raiseScgiError("':' after length expected") break client.dataLen = client.dataLen * 10 + ord(d[0]) - ord('0') client.mode = ClientReadHeaders @@ -213,7 +217,7 @@ proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) = case ret of ReadFullLine: client.headers = parseHeaders(client.input, client.input.len-1) - if client.headers["SCGI"] != "1": scgiError("SCGI Version 1 expected") + if client.headers["SCGI"] != "1": raiseScgiError("SCGI Version 1 expected") client.input = "" # For next part let contentLen = parseInt(client.headers["CONTENT_LENGTH"]) @@ -236,50 +240,50 @@ proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) = s.handleRequest(client.c, client.input, client.headers) checkCloseSocket(client) -proc handleAccept(sock: PAsyncSocket, s: PAsyncScgiState) = - var client: PAsyncSocket +proc handleAccept(sock: AsyncSocket, s: AsyncScgiState) = + var client: AsyncSocket new(client) accept(s.asyncServer, client) - var asyncClient = PAsyncClient(c: client, mode: ClientReadChar, dataLen: 0, + var asyncClient = AsyncClient(c: client, mode: ClientReadChar, dataLen: 0, headers: newStringTable(), input: "") client.handleRead = - proc (sock: PAsyncSocket) = + proc (sock: AsyncSocket) = handleClientRead(asyncClient, s) s.disp.register(client) -proc open*(handleRequest: proc (client: PAsyncSocket, - input: string, headers: PStringTable) {. +proc open*(handleRequest: proc (client: AsyncSocket, + input: string, headers: StringTableRef) {. closure, gcsafe.}, - port = TPort(4000), address = "127.0.0.1", - reuseAddr = false): PAsyncScgiState = - ## Creates an ``PAsyncScgiState`` object which serves as a SCGI server. + port = Port(4000), address = "127.0.0.1", + reuseAddr = false): AsyncScgiState = + ## Creates an ``AsyncScgiState`` object which serves as a SCGI server. ## ## After the execution of ``handleRequest`` the client socket will be closed ## automatically unless it has already been closed. - var cres: PAsyncScgiState + var cres: AsyncScgiState new(cres) cres.asyncServer = AsyncSocket() - cres.asyncServer.handleAccept = proc (s: PAsyncSocket) = handleAccept(s, cres) + cres.asyncServer.handleAccept = proc (s: AsyncSocket) = handleAccept(s, cres) if reuseAddr: - cres.asyncServer.setSockOpt(OptReuseAddr, True) + cres.asyncServer.setSockOpt(OptReuseAddr, true) bindAddr(cres.asyncServer, port, address) listen(cres.asyncServer) cres.handleRequest = handleRequest result = cres -proc register*(d: PDispatcher, s: PAsyncScgiState): PDelegate {.discardable.} = +proc register*(d: Dispatcher, s: AsyncScgiState): Delegate {.discardable.} = ## Registers ``s`` with dispatcher ``d``. result = d.register(s.asyncServer) s.disp = d -proc close*(s: PAsyncScgiState) = - ## Closes the ``PAsyncScgiState``. +proc close*(s: AsyncScgiState) = + ## Closes the ``AsyncScgiState``. s.asyncServer.close() when false: var counter = 0 - proc handleRequest(client: TSocket, input: string, - headers: PStringTable): bool {.procvar.} = + proc handleRequest(client: Socket, input: string, + headers: StringTableRef): bool {.procvar.} = inc(counter) client.writeStatusOkTextContent() client.send("Hello for the $#th time." % $counter & "\c\L") diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index bd53c2dbf..33939537a 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -18,57 +18,57 @@ elif defined(windows): else: import posix -proc hash*(x: TSocketHandle): THash {.borrow.} -proc `$`*(x: TSocketHandle): string {.borrow.} +proc hash*(x: SocketHandle): THash {.borrow.} +proc `$`*(x: SocketHandle): string {.borrow.} type - TEvent* = enum + Event* = enum EvRead, EvWrite - PSelectorKey* = ref object - fd*: TSocketHandle - events*: set[TEvent] ## The events which ``fd`` listens for. - data*: PObject ## User object. + SelectorKey* = ref object + fd*: SocketHandle + events*: set[Event] ## The events which ``fd`` listens for. + data*: RootRef ## User object. - TReadyInfo* = tuple[key: PSelectorKey, events: set[TEvent]] + ReadyInfo* = tuple[key: SelectorKey, events: set[Event]] when defined(nimdoc): type - PSelector* = ref object + Selector* = ref object ## An object which holds file descripters to be checked for read/write ## status. - fds: TTable[TSocketHandle, PSelectorKey] + fds: Table[SocketHandle, SelectorKey] - proc register*(s: PSelector, fd: TSocketHandle, events: set[TEvent], - data: PObject): PSelectorKey {.discardable.} = + proc register*(s: Selector, fd: SocketHandle, events: set[Event], + data: RootRef): SelectorKey {.discardable.} = ## Registers file descriptor ``fd`` to selector ``s`` with a set of TEvent ## ``events``. - proc update*(s: PSelector, fd: TSocketHandle, - events: set[TEvent]): PSelectorKey {.discardable.} = + proc update*(s: Selector, fd: SocketHandle, + events: set[Event]): SelectorKey {.discardable.} = ## Updates the events which ``fd`` wants notifications for. - proc select*(s: PSelector, timeout: int): seq[TReadyInfo] = + proc select*(s: Selector, timeout: int): seq[ReadyInfo] = ## The ``events`` field of the returned ``key`` contains the original events ## for which the ``fd`` was bound. This is contrary to the ``events`` field ## of the ``TReadyInfo`` tuple which determines which events are ready ## on the ``fd``. - proc contains*(s: PSelector, fd: TSocketHandle): bool = + proc contains*(s: Selector, fd: SocketHandle): bool = ## Determines whether selector contains a file descriptor. - proc `[]`*(s: PSelector, fd: TSocketHandle): PSelectorKey = + proc `[]`*(s: Selector, fd: SocketHandle): SelectorKey = ## Retrieves the selector key for ``fd``. elif defined(linux): type - PSelector* = ref object + Selector* = ref object epollFD: cint events: array[64, epoll_event] - fds: TTable[TSocketHandle, PSelectorKey] + fds: Table[SocketHandle, SelectorKey] - proc createEventStruct(events: set[TEvent], fd: TSocketHandle): epoll_event = + proc createEventStruct(events: set[Event], fd: SocketHandle): epoll_event = if EvRead in events: result.events = EPOLLIN if EvWrite in events: @@ -76,22 +76,22 @@ elif defined(linux): result.events = result.events or EPOLLRDHUP result.data.fd = fd.cint - proc register*(s: PSelector, fd: TSocketHandle, events: set[TEvent], - data: PObject): PSelectorKey {.discardable.} = + proc register*(s: Selector, fd: SocketHandle, events: set[Event], + data: RootRef): SelectorKey {.discardable.} = ## Registers file descriptor ``fd`` to selector ``s`` with a set of TEvent ## ``events``. var event = createEventStruct(events, fd) if events != {}: if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0: - OSError(OSLastError()) + raiseOSError(osLastError()) - var key = PSelectorKey(fd: fd, events: events, data: data) + var key = SelectorKey(fd: fd, events: events, data: data) s.fds[fd] = key result = key - proc update*(s: PSelector, fd: TSocketHandle, - events: set[TEvent]): PSelectorKey {.discardable.} = + proc update*(s: Selector, fd: SocketHandle, + events: set[Event]): SelectorKey {.discardable.} = ## Updates the events which ``fd`` wants notifications for. if s.fds[fd].events != events: if events == {}: @@ -101,7 +101,7 @@ elif defined(linux): # because its got fds which are waiting for no events and # are therefore constantly ready. (leading to 100% CPU usage). if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0: - OSError(OSLastError()) + raiseOSError(osLastError()) s.fds[fd].events = events else: var event = createEventStruct(events, fd) @@ -109,36 +109,36 @@ elif defined(linux): # This fd is idle. It's not a member of this epoll instance and must # be re-registered. if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0: - OSError(OSLastError()) + raiseOSError(osLastError()) else: if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0: - OSError(OSLastError()) + raiseOSError(osLastError()) s.fds[fd].events = events result = s.fds[fd] - proc unregister*(s: PSelector, fd: TSocketHandle): PSelectorKey {.discardable.} = + proc unregister*(s: Selector, fd: SocketHandle): SelectorKey {.discardable.} = if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0: - let err = OSLastError() + let err = osLastError() if err.cint notin {ENOENT, EBADF}: # TODO: Why do we sometimes get an EBADF? Is this normal? - OSError(err) + raiseOSError(err) result = s.fds[fd] s.fds.del(fd) - proc close*(s: PSelector) = - if s.epollFD.close() != 0: OSError(OSLastError()) + proc close*(s: Selector) = + if s.epollFD.close() != 0: raiseOSError(osLastError()) dealloc(addr s.events) # TODO: Test this - proc epollHasFd(s: PSelector, fd: TSocketHandle): bool = + proc epollHasFd(s: Selector, fd: SocketHandle): bool = result = true var event = createEventStruct(s.fds[fd].events, fd) if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0: let err = osLastError() if err.cint in {ENOENT, EBADF}: return false - OSError(OSLastError()) + raiseOSError(osLastError()) - proc select*(s: PSelector, timeout: int): seq[TReadyInfo] = + proc select*(s: Selector, timeout: int): seq[ReadyInfo] = ## ## The ``events`` field of the returned ``key`` contains the original events ## for which the ``fd`` was bound. This is contrary to the ``events`` field @@ -146,12 +146,12 @@ elif defined(linux): ## on the ``fd``. result = @[] let evNum = epoll_wait(s.epollFD, addr s.events[0], 64.cint, timeout.cint) - if evNum < 0: OSError(OSLastError()) + if evNum < 0: raiseOSError(osLastError()) if evNum == 0: return @[] for i in 0 .. 0 and c == '\L': discard recv(socket, addr(c), 1) - elif n <= 0: socket.socketError() + elif n <= 0: socket.raiseSocketError() addNLIfEmpty() return elif c == '\L': @@ -1357,7 +1367,7 @@ proc readLineAsync*(socket: TSocket, setLen(line.string, 0) template errorOrNone = - socket.socketError(async = true) + socket.raiseSocketError(async = true) return ReadNone while true: @@ -1390,7 +1400,7 @@ proc recv*(socket: TSocket): TaintedString {.tags: [ReadIOEffect], deprecated.} var pos = 0 while true: var bytesRead = recv(socket, addr(string(result)[pos]), bufSize-1) - if bytesRead == -1: osError(osLastError()) + if bytesRead == -1: raiseOSError(osLastError()) setLen(result.string, pos + bytesRead) if bytesRead != bufSize-1: break # increase capacity: @@ -1463,11 +1473,11 @@ proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. when defined(windows): if err.int32 == WSAEWOULDBLOCK: return false - else: osError(err) + else: raiseOSError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: return false - else: osError(err) + else: raiseOSError(err) setLen(s.string, pos + bytesRead) if bytesRead != bufSize-1: break @@ -1516,11 +1526,11 @@ proc recvFromAsync*(socket: TSocket, data: var string, length: int, when defined(windows): if err.int32 == WSAEWOULDBLOCK: return false - else: osError(err) + else: raiseOSError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: return false - else: osError(err) + else: raiseOSError(err) proc skip*(socket: TSocket) {.tags: [ReadIOEffect], deprecated.} = ## skips all the data that is pending for the socket @@ -1570,7 +1580,7 @@ proc send*(socket: TSocket, data: string) {.tags: [WriteIOEffect].} = if socket.isSSL: SSLError() - osError(osLastError()) + raiseOSError(osLastError()) if sent != data.len: raise newException(OSError, "Could not send all data.") @@ -1607,11 +1617,11 @@ proc sendAsync*(socket: TSocket, data: string): int {.tags: [WriteIOEffect].} = when defined(windows): if err.int32 == WSAEINPROGRESS: return 0 - else: osError(err) + else: raiseOSError(err) else: if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK: return 0 - else: osError(err) + else: raiseOSError(err) proc trySend*(socket: TSocket, data: string): bool {.tags: [WriteIOEffect].} = @@ -1667,15 +1677,15 @@ proc setBlocking(s: TSocket, blocking: bool) = when defined(Windows): var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking if ioctlsocket(s.fd, FIONBIO, addr(mode)) == -1: - osError(osLastError()) + raiseOSError(osLastError()) else: # BSD sockets var x: int = fcntl(s.fd, F_GETFL, 0) if x == -1: - osError(osLastError()) + raiseOSError(osLastError()) else: var mode = if blocking: x and not O_NONBLOCK else: x or O_NONBLOCK if fcntl(s.fd, F_SETFL, mode) == -1: - osError(osLastError()) + raiseOSError(osLastError()) s.nonblocking = not blocking discard """ proc setReuseAddr*(s: TSocket) = @@ -1715,6 +1725,6 @@ proc isBlocking*(socket: TSocket): bool = not socket.nonblocking when defined(Windows): var wsa: TWSAData - if wsaStartup(0x0101'i16, addr wsa) != 0: osError(osLastError()) + if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index c4e969f21..bc0f1c540 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,8 +8,8 @@ # ## This module provides a stream interface and two implementations thereof: -## the `PFileStream` and the `PStringStream` which implement the stream -## interface for Nimrod file objects (`TFile`) and strings. Other modules +## the `FileStream` and the `StringStream` which implement the stream +## interface for Nimrod file objects (`File`) and strings. Other modules ## may provide other implementations for this standard stream interface. include "system/inclrtl" @@ -19,81 +19,83 @@ proc newEIO(msg: string): ref IOError = result.msg = msg type - PStream* = ref TStream - TStream* = object of RootObj ## Stream interface that supports - ## writing or reading. Note that these fields - ## here shouldn't be used directly. They are - ## accessible so that a stream implementation - ## can override them. - closeImpl*: proc (s: PStream) {.nimcall, tags: [], gcsafe.} - atEndImpl*: proc (s: PStream): bool {.nimcall, tags: [], gcsafe.} - setPositionImpl*: proc (s: PStream, pos: int) {.nimcall, tags: [], gcsafe.} - getPositionImpl*: proc (s: PStream): int {.nimcall, tags: [], gcsafe.} - readDataImpl*: proc (s: PStream, buffer: pointer, + Stream* = ref StreamObj + StreamObj* = object of RootObj ## Stream interface that supports + ## writing or reading. Note that these fields + ## here shouldn't be used directly. They are + ## accessible so that a stream implementation + ## can override them. + closeImpl*: proc (s: Stream) {.nimcall, tags: [], gcsafe.} + atEndImpl*: proc (s: Stream): bool {.nimcall, tags: [], gcsafe.} + setPositionImpl*: proc (s: Stream, pos: int) {.nimcall, tags: [], gcsafe.} + getPositionImpl*: proc (s: Stream): int {.nimcall, tags: [], gcsafe.} + readDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int {.nimcall, tags: [ReadIOEffect], gcsafe.} - writeDataImpl*: proc (s: PStream, buffer: pointer, bufLen: int) {.nimcall, + writeDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int) {.nimcall, tags: [WriteIOEffect], gcsafe.} - flushImpl*: proc (s: PStream) {.nimcall, tags: [WriteIOEffect], gcsafe.} + flushImpl*: proc (s: Stream) {.nimcall, tags: [WriteIOEffect], gcsafe.} -proc flush*(s: PStream) = +{.deprecated: [PStream: Stream, TStream: StreamObj].} + +proc flush*(s: Stream) = ## flushes the buffers that the stream `s` might use. if not isNil(s.flushImpl): s.flushImpl(s) -proc close*(s: PStream) = +proc close*(s: Stream) = ## closes the stream `s`. if not isNil(s.closeImpl): s.closeImpl(s) -proc close*(s, unused: PStream) {.deprecated.} = +proc close*(s, unused: Stream) {.deprecated.} = ## closes the stream `s`. s.closeImpl(s) -proc atEnd*(s: PStream): bool = +proc atEnd*(s: Stream): bool = ## checks if more data can be read from `f`. Returns true if all data has ## been read. result = s.atEndImpl(s) -proc atEnd*(s, unused: PStream): bool {.deprecated.} = +proc atEnd*(s, unused: Stream): bool {.deprecated.} = ## checks if more data can be read from `f`. Returns true if all data has ## been read. result = s.atEndImpl(s) -proc setPosition*(s: PStream, pos: int) = +proc setPosition*(s: Stream, pos: int) = ## sets the position `pos` of the stream `s`. s.setPositionImpl(s, pos) -proc setPosition*(s, unused: PStream, pos: int) {.deprecated.} = +proc setPosition*(s, unused: Stream, pos: int) {.deprecated.} = ## sets the position `pos` of the stream `s`. s.setPositionImpl(s, pos) -proc getPosition*(s: PStream): int = +proc getPosition*(s: Stream): int = ## retrieves the current position in the stream `s`. result = s.getPositionImpl(s) -proc getPosition*(s, unused: PStream): int {.deprecated.} = +proc getPosition*(s, unused: Stream): int {.deprecated.} = ## retrieves the current position in the stream `s`. result = s.getPositionImpl(s) -proc readData*(s: PStream, buffer: pointer, bufLen: int): int = +proc readData*(s: Stream, buffer: pointer, bufLen: int): int = ## low level proc that reads data into an untyped `buffer` of `bufLen` size. result = s.readDataImpl(s, buffer, bufLen) -proc readData*(s, unused: PStream, buffer: pointer, +proc readData*(s, unused: Stream, buffer: pointer, bufLen: int): int {.deprecated.} = ## low level proc that reads data into an untyped `buffer` of `bufLen` size. result = s.readDataImpl(s, buffer, bufLen) -proc writeData*(s: PStream, buffer: pointer, bufLen: int) = +proc writeData*(s: Stream, buffer: pointer, bufLen: int) = ## low level proc that writes an untyped `buffer` of `bufLen` size ## to the stream `s`. s.writeDataImpl(s, buffer, bufLen) -proc writeData*(s, unused: PStream, buffer: pointer, +proc writeData*(s, unused: Stream, buffer: pointer, bufLen: int) {.deprecated.} = ## low level proc that writes an untyped `buffer` of `bufLen` size ## to the stream `s`. s.writeDataImpl(s, buffer, bufLen) -proc write*[T](s: PStream, x: T) = +proc write*[T](s: Stream, x: T) = ## generic write procedure. Writes `x` to the stream `s`. Implementation: ## ## .. code-block:: Nimrod @@ -103,63 +105,63 @@ proc write*[T](s: PStream, x: T) = shallowCopy(y, x) writeData(s, addr(y), sizeof(y)) -proc write*(s: PStream, x: string) = +proc write*(s: Stream, x: string) = ## writes the string `x` to the the stream `s`. No length field or ## terminating zero is written. writeData(s, cstring(x), x.len) -proc writeln*(s: PStream, args: varargs[string, `$`]) = +proc writeln*(s: Stream, args: varargs[string, `$`]) = ## writes one or more strings to the the stream `s` followed ## by a new line. No length field or terminating zero is written. for str in args: write(s, str) write(s, "\n") -proc read[T](s: PStream, result: var T) = +proc read[T](s: Stream, result: var T) = ## generic read procedure. Reads `result` from the stream `s`. if readData(s, addr(result), sizeof(T)) != sizeof(T): raise newEIO("cannot read from stream") -proc readChar*(s: PStream): char = +proc readChar*(s: Stream): char = ## reads a char from the stream `s`. Raises `EIO` if an error occured. ## Returns '\0' as an EOF marker. if readData(s, addr(result), sizeof(result)) != 1: result = '\0' -proc readBool*(s: PStream): bool = +proc readBool*(s: Stream): bool = ## reads a bool from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readInt8*(s: PStream): int8 = +proc readInt8*(s: Stream): int8 = ## reads an int8 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readInt16*(s: PStream): int16 = +proc readInt16*(s: Stream): int16 = ## reads an int16 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readInt32*(s: PStream): int32 = +proc readInt32*(s: Stream): int32 = ## reads an int32 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readInt64*(s: PStream): int64 = +proc readInt64*(s: Stream): int64 = ## reads an int64 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readFloat32*(s: PStream): float32 = +proc readFloat32*(s: Stream): float32 = ## reads a float32 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readFloat64*(s: PStream): float64 = +proc readFloat64*(s: Stream): float64 = ## reads a float64 from the stream `s`. Raises `EIO` if an error occured. read(s, result) -proc readStr*(s: PStream, length: int): TaintedString = +proc readStr*(s: Stream, length: int): TaintedString = ## reads a string of length `length` from the stream `s`. Raises `EIO` if ## an error occured. result = newString(length).TaintedString var L = readData(s, addr(string(result)[0]), length) if L != length: setLen(result.string, L) -proc readLine*(s: PStream, line: var TaintedString): bool = +proc readLine*(s: Stream, line: var TaintedString): bool = ## reads a line of text from the stream `s` into `line`. `line` must not be ## ``nil``! May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or @@ -179,7 +181,7 @@ proc readLine*(s: PStream, line: var TaintedString): bool = line.string.add(c) result = true -proc readLine*(s: PStream): TaintedString = +proc readLine*(s: Stream): TaintedString = ## Reads a line from a stream `s`. Note: This is not very efficient. Raises ## `EIO` if an error occured. result = TaintedString"" @@ -194,42 +196,44 @@ proc readLine*(s: PStream): TaintedString = result.string.add(c) type - PStringStream* = ref TStringStream ## a stream that encapsulates a string - TStringStream* = object of TStream + StringStream* = ref StringStreamObj ## a stream that encapsulates a string + StringStreamObj* = object of StreamObj data*: string pos: int - -proc ssAtEnd(s: PStream): bool = - var s = PStringStream(s) + +{.deprecated: [PStringStream: StringStream, TStringStream: StringStreamObj].} + +proc ssAtEnd(s: Stream): bool = + var s = StringStream(s) return s.pos >= s.data.len -proc ssSetPosition(s: PStream, pos: int) = - var s = PStringStream(s) +proc ssSetPosition(s: Stream, pos: int) = + var s = StringStream(s) s.pos = clamp(pos, 0, s.data.high) -proc ssGetPosition(s: PStream): int = - var s = PStringStream(s) +proc ssGetPosition(s: Stream): int = + var s = StringStream(s) return s.pos -proc ssReadData(s: PStream, buffer: pointer, bufLen: int): int = - var s = PStringStream(s) +proc ssReadData(s: Stream, buffer: pointer, bufLen: int): int = + var s = StringStream(s) result = min(bufLen, s.data.len - s.pos) if result > 0: copyMem(buffer, addr(s.data[s.pos]), result) inc(s.pos, result) -proc ssWriteData(s: PStream, buffer: pointer, bufLen: int) = - var s = PStringStream(s) +proc ssWriteData(s: Stream, buffer: pointer, bufLen: int) = + var s = StringStream(s) if bufLen > 0: setLen(s.data, s.data.len + bufLen) copyMem(addr(s.data[s.pos]), buffer, bufLen) inc(s.pos, bufLen) -proc ssClose(s: PStream) = - var s = PStringStream(s) +proc ssClose(s: Stream) = + var s = StringStream(s) s.data = nil -proc newStringStream*(s: string = ""): PStringStream = +proc newStringStream*(s: string = ""): StringStream = ## creates a new stream from the string `s`. new(result) result.data = s @@ -244,27 +248,28 @@ proc newStringStream*(s: string = ""): PStringStream = when not defined(js): type - PFileStream* = ref TFileStream ## a stream that encapsulates a `TFile` - TFileStream* = object of TStream + FileStream* = ref FileStreamObj ## a stream that encapsulates a `TFile` + FileStreamObj* = object of Stream f: File + {.deprecated: [PFileStream: FileStream, TFileStream: FileStreamObj].} - proc fsClose(s: PStream) = - if PFileStream(s).f != nil: - close(PFileStream(s).f) - PFileStream(s).f = nil - proc fsFlush(s: PStream) = flushFile(PFileStream(s).f) - proc fsAtEnd(s: PStream): bool = return endOfFile(PFileStream(s).f) - proc fsSetPosition(s: PStream, pos: int) = setFilePos(PFileStream(s).f, pos) - proc fsGetPosition(s: PStream): int = return int(getFilePos(PFileStream(s).f)) + proc fsClose(s: Stream) = + if FileStream(s).f != nil: + close(FileStream(s).f) + FileStream(s).f = nil + proc fsFlush(s: Stream) = flushFile(FileStream(s).f) + proc fsAtEnd(s: Stream): bool = return endOfFile(FileStream(s).f) + proc fsSetPosition(s: Stream, pos: int) = setFilePos(FileStream(s).f, pos) + proc fsGetPosition(s: Stream): int = return int(getFilePos(FileStream(s).f)) - proc fsReadData(s: PStream, buffer: pointer, bufLen: int): int = - result = readBuffer(PFileStream(s).f, buffer, bufLen) + proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int = + result = readBuffer(FileStream(s).f, buffer, bufLen) - proc fsWriteData(s: PStream, buffer: pointer, bufLen: int) = - if writeBuffer(PFileStream(s).f, buffer, bufLen) != bufLen: + proc fsWriteData(s: Stream, buffer: pointer, bufLen: int) = + if writeBuffer(FileStream(s).f, buffer, bufLen) != bufLen: raise newEIO("cannot write to stream") - proc newFileStream*(f: File): PFileStream = + proc newFileStream*(f: File): FileStream = ## creates a new stream from the file `f`. new(result) result.f = f @@ -276,7 +281,7 @@ when not defined(js): result.writeDataImpl = fsWriteData result.flushImpl = fsFlush - proc newFileStream*(filename: string, mode: FileMode): PFileStream = + proc newFileStream*(filename: string, mode: FileMode): FileStream = ## creates a new stream from the file named `filename` with the mode `mode`. ## If the file cannot be opened, nil is returned. See the `system ## `_ module for a list of available TFileMode enums. @@ -288,45 +293,47 @@ when true: discard else: type - TFileHandle* = cint ## Operating system file handle - PFileHandleStream* = ref TFileHandleStream - TFileHandleStream* = object of TStream - handle*: TFileHandle + FileHandleStream* = ref FileHandleStreamObj + FileHandleStreamObj* = object of Stream + handle*: FileHandle pos: int - proc newEOS(msg: string): ref EOS = + {.deprecated: [PFileHandleStream: FileHandleStream, + TFileHandleStream: FileHandleStreamObj].} + + proc newEOS(msg: string): ref OSError = new(result) result.msg = msg - proc hsGetPosition(s: PFileHandleStream): int = + proc hsGetPosition(s: FileHandleStream): int = return s.pos when defined(windows): # do not import windows as this increases compile times: - nil + discard else: import posix - proc hsSetPosition(s: PFileHandleStream, pos: int) = + proc hsSetPosition(s: FileHandleStream, pos: int) = discard lseek(s.handle, pos, SEEK_SET) - proc hsClose(s: PFileHandleStream) = discard close(s.handle) - proc hsAtEnd(s: PFileHandleStream): bool = + proc hsClose(s: FileHandleStream) = discard close(s.handle) + proc hsAtEnd(s: FileHandleStream): bool = var pos = hsGetPosition(s) var theEnd = lseek(s.handle, 0, SEEK_END) result = pos >= theEnd hsSetPosition(s, pos) # set position back - proc hsReadData(s: PFileHandleStream, buffer: pointer, bufLen: int): int = + proc hsReadData(s: FileHandleStream, buffer: pointer, bufLen: int): int = result = posix.read(s.handle, buffer, bufLen) inc(s.pos, result) - proc hsWriteData(s: PFileHandleStream, buffer: pointer, bufLen: int) = + proc hsWriteData(s: FileHandleStream, buffer: pointer, bufLen: int) = if posix.write(s.handle, buffer, bufLen) != bufLen: raise newEIO("cannot write to stream") inc(s.pos, bufLen) - proc newFileHandleStream*(handle: TFileHandle): PFileHandleStream = + proc newFileHandleStream*(handle: FileHandle): FileHandleStream = new(result) result.handle = handle result.pos = 0 @@ -338,9 +345,9 @@ else: result.writeData = hsWriteData proc newFileHandleStream*(filename: string, - mode: TFileMode): PFileHandleStream = - when defined(windows): - nil + mode: FileMode): FileHandleStream = + when defined(windows): + discard else: var flags: cint case mode diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 12621a0fc..71d16192f 100644 --- a/lib/pure/strtabs.nim +++ b/lib/pure/strtabs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -18,20 +18,23 @@ import include "system/inclrtl" type - TStringTableMode* = enum ## describes the tables operation mode + StringTableMode* = enum ## describes the tables operation mode modeCaseSensitive, ## the table is case sensitive modeCaseInsensitive, ## the table is case insensitive modeStyleInsensitive ## the table is style insensitive - TKeyValuePair = tuple[key, val: string] - TKeyValuePairSeq = seq[TKeyValuePair] - TStringTable* = object of RootObj + KeyValuePair = tuple[key, val: string] + KeyValuePairSeq = seq[KeyValuePair] + StringTableObj* = object of RootObj counter: int - data: TKeyValuePairSeq - mode: TStringTableMode + data: KeyValuePairSeq + mode: StringTableMode - PStringTable* = ref TStringTable ## use this type to declare string tables + StringTableRef* = ref StringTableObj ## use this type to declare string tables -proc len*(t: PStringTable): int {.rtl, extern: "nst$1".} = +{.deprecated: [TStringTableMode: StringTableMode, + TStringTable: StringTableObj, PStringTable: StringTableRef].} + +proc len*(t: StringTableRef): int {.rtl, extern: "nst$1".} = ## returns the number of keys in `t`. result = t.counter @@ -54,7 +57,7 @@ iterator values*(t: PStringTable): string = yield t.data[h].val type - TFormatFlag* = enum ## flags for the `%` operator + FormatFlag* = enum ## flags for the `%` operator useEnvironment, ## use environment variable if the ``$key`` ## is not found in the table useEmpty, ## use the empty string as a default, thus it @@ -63,6 +66,8 @@ type useKey ## do not replace ``$key`` if it is not found ## in the table (or in the environment) +{.deprecated: [TFormatFlag: FormatFlag].} + # implementation const diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index cc62ad1ee..82516653c 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -23,7 +23,7 @@ import parseutils include "system/inclrtl" type - TCharSet* = set[char] # for compatibility with Nim + TCharSet* {.deprecated.} = set[char] # for compatibility with Nim const Whitespace* = {' ', '\t', '\v', '\r', '\l', '\f'} @@ -54,7 +54,7 @@ const ## make the `find() proc <#find,string,set[char],int>`_ find **invalid** ## characters in strings. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let invalid = AllChars - Digits ## doAssert "01234".find(invalid) == -1 ## doAssert "01A34".find(invalid) == 2 @@ -205,7 +205,7 @@ iterator split*(s: string, seps: set[char] = Whitespace): string = ## a single split point and leading/trailing separators will be ignored. ## The following example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split(" this is an example "): ## writeln(stdout, word) ## @@ -219,13 +219,13 @@ iterator split*(s: string, seps: set[char] = Whitespace): string = ## ## And the following code: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split(";;this;is;an;;example;;;", {';'}): ## writeln(stdout, word) ## ## ...produces the same output as the first example. The code: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let date = "2012-11-20T22:08:08.398990" ## let separators = {' ', '-', ':', 'T'} ## for number in split(date, separators): @@ -258,7 +258,7 @@ iterator split*(s: string, sep: char): string = ## characters, this proc will not coalesce groups of the ## separator, returning a string for each found character. The code: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split(";;this;is;an;;example;;;", ';'): ## writeln(stdout, word) ## @@ -308,13 +308,13 @@ iterator splitLines*(s: string): string = ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for line in splitLines("\nthis\nis\nan\n\nexample\n"): ## writeln(stdout, line) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "" ## "this" ## "is" @@ -417,7 +417,7 @@ proc parseInt*(s: string): int {.noSideEffect, procvar, rtl, extern: "nsuParseInt".} = ## Parses a decimal integer value contained in `s`. ## - ## If `s` is not a valid integer, `EInvalidValue` is raised. + ## If `s` is not a valid integer, `ValueError` is raised. var L = parseutils.parseInt(s, result, 0) if L != s.len or L == 0: raise newException(ValueError, "invalid integer: " & s) @@ -426,7 +426,7 @@ proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar, rtl, extern: "nsuParseBiggestInt".} = ## Parses a decimal integer value contained in `s`. ## - ## If `s` is not a valid integer, `EInvalidValue` is raised. + ## If `s` is not a valid integer, `ValueError` is raised. var L = parseutils.parseBiggestInt(s, result, 0) if L != s.len or L == 0: raise newException(ValueError, "invalid integer: " & s) @@ -434,7 +434,7 @@ proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar, proc parseFloat*(s: string): float {.noSideEffect, procvar, rtl, extern: "nsuParseFloat".} = ## Parses a decimal floating point value contained in `s`. If `s` is not - ## a valid floating point number, `EInvalidValue` is raised. ``NAN``, + ## a valid floating point number, `ValueError` is raised. ``NAN``, ## ``INF``, ``-INF`` are also supported (case insensitive comparison). var L = parseutils.parseFloat(s, result, 0) if L != s.len or L == 0: @@ -444,7 +444,7 @@ proc parseHexInt*(s: string): int {.noSideEffect, procvar, rtl, extern: "nsuParseHexInt".} = ## Parses a hexadecimal integer value contained in `s`. ## - ## If `s` is not a valid integer, `EInvalidValue` is raised. `s` can have one + ## If `s` is not a valid integer, `ValueError` is raised. `s` can have one ## of the following optional prefixes: ``0x``, ``0X``, ``#``. Underscores ## within `s` are ignored. var i = 0 @@ -471,7 +471,7 @@ proc parseBool*(s: string): bool = ## If ``s`` is one of the following values: ``y, yes, true, 1, on``, then ## returns `true`. If ``s`` is one of the following values: ``n, no, false, ## 0, off``, then returns `false`. If ``s`` is something else a - ## ``EInvalidValue`` exception is raised. + ## ``ValueError`` exception is raised. case normalize(s) of "y", "yes", "true", "1", "on": result = true of "n", "no", "false", "0", "off": result = false @@ -480,7 +480,7 @@ proc parseBool*(s: string): bool = proc parseEnum*[T: enum](s: string): T = ## Parses an enum ``T``. ## - ## Raises ``EInvalidValue`` for an invalid value in `s`. The comparison is + ## Raises ``ValueError`` for an invalid value in `s`. The comparison is ## done in a style insensitive way. for e in low(T)..high(T): if cmpIgnoreStyle(s, $e) == 0: @@ -502,7 +502,7 @@ proc repeatChar*(count: int, c: char = ' '): string {.noSideEffect, ## Returns a string of length `count` consisting only of ## the character `c`. You can use this proc to left align strings. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let ## width = 15 ## text1 = "Hello user!" @@ -527,7 +527,7 @@ proc align*(s: string, count: int, padding = ' '): string {. ## returned unchanged. If you need to left align a string use the `repeatChar ## proc <#repeatChar>`_. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## assert align("abc", 4) == " abc" ## assert align("a", 0) == "a" ## assert align("1232", 6) == " 1232" @@ -547,13 +547,13 @@ iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ ## Substrings are separated by a substring containing only `seps`. ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in tokenize(" this is an example "): ## writeln(stdout, word) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## (" ", true) ## ("this", false) ## (" ", true) @@ -676,7 +676,7 @@ proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, ## ## A shorthand for: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## if dest.len > startLen: add(dest, sep) ## ## This is often useful for generating some code where the items need to @@ -684,7 +684,7 @@ proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, ## `startLen`. The following example creates a string describing ## an array of integers: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var arr = "[" ## for x in items([2, 3, 5, 7, 11]): ## addSep(arr, startLen=len("[")) @@ -692,7 +692,7 @@ proc addSep*(dest: var string, sep = ", ", startLen = 0) {.noSideEffect, ## add(arr, "]") if dest.len > startLen: add(dest, sep) -proc allCharsInSet*(s: string, theSet: TCharSet): bool = +proc allCharsInSet*(s: string, theSet: set[char]): bool = ## Returns true iff each character of `s` is in the set `theSet`. for c in items(s): if c notin theSet: return false @@ -739,14 +739,14 @@ proc join*(a: openArray[string]): string {. result = "" type - TSkipTable = array[char, int] + SkipTable = array[char, int] -proc preprocessSub(sub: string, a: var TSkipTable) = +proc preprocessSub(sub: string, a: var SkipTable) = var m = len(sub) for i in 0..0xff: a[chr(i)] = m+1 for i in 0..m-1: a[sub[i]] = m-i -proc findAux(s, sub: string, start: int, a: TSkipTable): int = +proc findAux(s, sub: string, start: int, a: SkipTable): int = # Fast "quick search" algorithm: var m = len(sub) @@ -762,7 +762,7 @@ proc findAux(s, sub: string, start: int, a: TSkipTable): int = return -1 proc find*(s, sub: string, start: int = 0): int {.noSideEffect, - rtl, extern: "nsuFindStr", operator: 6.} = + rtl, extern: "nsuFindStr".} = ## Searches for `sub` in `s` starting at position `start`. ## ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. @@ -827,9 +827,9 @@ proc contains*(s: string, chars: set[char]): bool {.noSideEffect.} = return find(s, chars) >= 0 proc replace*(s, sub: string, by = ""): string {.noSideEffect, - rtl, extern: "nsuReplaceStr", operator: 1.} = + rtl, extern: "nsuReplaceStr".} = ## Replaces `sub` in `s` by the string `by`. - var a {.noinit.}: TSkipTable + var a {.noinit.}: SkipTable result = "" preprocessSub(sub, a) var i = 0 @@ -862,7 +862,7 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, ## (comparable to ``\\w`` in regular expressions), otherwise it is not ## replaced. const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} - var a {.noinit.}: TSkipTable + var a {.noinit.}: SkipTable result = "" preprocessSub(sub, a) var i = 0 @@ -899,7 +899,7 @@ proc parseOctInt*(s: string): int {.noSideEffect, rtl, extern: "nsuParseOctInt".} = ## Parses an octal integer value contained in `s`. ## - ## If `s` is not a valid integer, `EInvalidValue` is raised. `s` can have one + ## If `s` is not a valid integer, `ValueError` is raised. `s` can have one ## of the following optional prefixes: ``0o``, ``0O``. Underscores within ## `s` are ignored. var i = 0 @@ -999,7 +999,7 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, ## operations. ## ## If `s` does not begin with ``prefix`` and end with ``suffix`` a - ## EInvalidValue exception will be raised. + ## ValueError exception will be raised. result = newStringOfCap(s.len) var i = 0 if s[0 .. prefix.len-1] != prefix: @@ -1138,12 +1138,14 @@ proc c_sprintf(buf, frmt: cstring) {.header: "", importc: "sprintf", varargs, noSideEffect.} type - TFloatFormat* = enum ## the different modes of floating point formating + FloatFormatMode* = enum ## the different modes of floating point formating ffDefault, ## use the shorter floating point notation ffDecimal, ## use decimal floating point notation ffScientific ## use scientific notation (using ``e`` character) -proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, +{.deprecated: [TFloatFormat: FloatFormatMode].} + +proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, precision: range[0..32] = 16): string {. noSideEffect, operator: 2, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. @@ -1174,7 +1176,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, c_sprintf(buf, frmtstr, f) result = $buf -proc formatFloat*(f: float, format: TFloatFormat = ffDefault, +proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, precision: range[0..32] = 16): string {. noSideEffect, operator: 2, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. @@ -1190,7 +1192,7 @@ proc formatFloat*(f: float, format: TFloatFormat = ffDefault, proc formatSize*(bytes: BiggestInt, decimalSep = '.'): string = ## Rounds and formats `bytes`. Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## formatSize(1'i64 shl 31 + 300'i64) == "2.204GB" ## formatSize(4096) == "4KB" @@ -1280,12 +1282,12 @@ proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect, ## ## This is best explained by an example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "$1 eats $2." % ["The cat", "fish"] ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "The cat eats fish." ## ## The substitution variables (the thing after the ``$``) are enumerated @@ -1294,7 +1296,7 @@ proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect, ## The notation ``$#`` can be used to refer to the next substitution ## variable: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "$# eats $#." % ["The cat", "fish"] ## ## Substitution variables can also be words (that is @@ -1302,15 +1304,15 @@ proc `%` *(formatstr: string, a: openArray[string]): string {.noSideEffect, ## indices are keys and with odd indices are the corresponding values. ## An example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "$animal eats $food." % ["animal", "The cat", "food", "fish"] ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "The cat eats fish." ## - ## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is + ## The variables are compared with `cmpIgnoreStyle`. `ValueError` is ## raised if an ill-formed format string has been passed to the `%` operator. result = newStringOfCap(formatstr.len + a.len shl 4) addf(result, formatstr, a) @@ -1350,7 +1352,7 @@ when isMainModule: doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz " doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc" - type TMyEnum = enum enA, enB, enC, enuD, enE - doAssert parseEnum[TMyEnum]("enu_D") == enuD + type MyEnum = enum enA, enB, enC, enuD, enE + doAssert parseEnum[MyEnum]("enu_D") == enuD doAssert parseEnum("invalid enum value", enC) == enC diff --git a/lib/pure/subexes.nim b/lib/pure/subexes.nim index ed87610d6..452978c09 100644 --- a/lib/pure/subexes.nim +++ b/lib/pure/subexes.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Nimrod support for `substitution expressions`:idx: (`subex`:idx:). +## Nim support for `substitution expressions`:idx: (`subex`:idx:). ## ## .. include:: ../doc/subexes.txt ## @@ -28,11 +28,13 @@ proc findNormalized(x: string, inArray: openarray[string]): int = return -1 type - EInvalidSubex* = object of EInvalidValue ## exception that is raised for - ## an invalid subex + SubexError* = object of ValueError ## exception that is raised for + ## an invalid subex + +{.deprecated: [EInvalidSubex: SubexError].} proc raiseInvalidFormat(msg: string) {.noinline.} = - raise newException(EInvalidSubex, "invalid format string: " & msg) + raise newException(SubexError, "invalid format string: " & msg) type TFormatParser = object {.pure, final.} @@ -291,14 +293,16 @@ proc scanDollar(p: var TFormatParser, a: openarray[string], s: var string) = type - TSubex* = distinct string ## string that contains a substitution expression + Subex* = distinct string ## string that contains a substitution expression -proc subex*(s: string): TSubex = +{.deprecated: [TSubex: Subex].} + +proc subex*(s: string): Subex = ## constructs a *substitution expression* from `s`. Currently this performs ## no syntax checking but this may change in later versions. - result = TSubex(s) + result = Subex(s) -proc addf*(s: var string, formatstr: TSubex, a: varargs[string, `$`]) {. +proc addf*(s: var string, formatstr: Subex, a: varargs[string, `$`]) {. noSideEffect, rtl, extern: "nfrmtAddf".} = ## The same as ``add(s, formatstr % a)``, but more efficient. var p: TFormatParser @@ -312,7 +316,7 @@ proc addf*(s: var string, formatstr: TSubex, a: varargs[string, `$`]) {. emitChar(p, s, p.f[i]) inc(i) -proc `%` *(formatstr: TSubex, a: openarray[string]): string {.noSideEffect, +proc `%` *(formatstr: Subex, a: openarray[string]): string {.noSideEffect, rtl, extern: "nfrmtFormatOpenArray".} = ## The `substitution`:idx: operator performs string substitutions in ## `formatstr` and returns a modified `formatstr`. This is often called @@ -321,13 +325,13 @@ proc `%` *(formatstr: TSubex, a: openarray[string]): string {.noSideEffect, result = newStringOfCap(formatstr.string.len + a.len shl 4) addf(result, formatstr, a) -proc `%` *(formatstr: TSubex, a: string): string {.noSideEffect, +proc `%` *(formatstr: Subex, a: string): string {.noSideEffect, rtl, extern: "nfrmtFormatSingleElem".} = ## This is the same as ``formatstr % [a]``. result = newStringOfCap(formatstr.string.len + a.len) addf(result, formatstr, [a]) -proc format*(formatstr: TSubex, a: varargs[string, `$`]): string {.noSideEffect, +proc format*(formatstr: Subex, a: varargs[string, `$`]): string {.noSideEffect, rtl, extern: "nfrmtFormatVarargs".} = ## The `substitution`:idx: operator performs string substitutions in ## `formatstr` and returns a modified `formatstr`. This is often called diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 20f1d0695..0ebe8a39e 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -27,11 +27,11 @@ when defined(windows): var hTemp = GetStdHandle(STD_OUTPUT_HANDLE) if DuplicateHandle(GetCurrentProcess(), hTemp, GetCurrentProcess(), addr(conHandle), 0, 1, DUPLICATE_SAME_ACCESS) == 0: - osError(osLastError()) + raiseOSError(osLastError()) proc getCursorPos(): tuple [x,y: int] = var c: TCONSOLESCREENBUFFERINFO - if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: raiseOSError(osLastError()) return (int(c.dwCursorPosition.x), int(c.dwCursorPosition.y)) proc getAttributes(): int16 = @@ -51,7 +51,7 @@ proc setCursorPos*(x, y: int) = var c: TCOORD c.x = int16(x) c.y = int16(y) - if SetConsoleCursorPosition(conHandle, c) == 0: osError(osLastError()) + if SetConsoleCursorPosition(conHandle, c) == 0: raiseOSError(osLastError()) else: stdout.write("\e[" & $y & ';' & $x & 'f') @@ -61,10 +61,10 @@ proc setCursorXPos*(x: int) = when defined(windows): var scrbuf: TCONSOLESCREENBUFFERINFO var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition origin.x = int16(x) - if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) else: stdout.write("\e[" & $x & 'G') @@ -75,10 +75,10 @@ when defined(windows): when defined(windows): var scrbuf: TCONSOLESCREENBUFFERINFO var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition origin.y = int16(y) - if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) else: discard @@ -155,18 +155,18 @@ proc eraseLine* = var scrbuf: TCONSOLESCREENBUFFERINFO var numwrote: DWORD var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition origin.x = 0'i16 - if SetConsoleCursorPosition(conHandle, origin) == 0: osError(osLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) var ht = scrbuf.dwSize.Y - origin.Y var wt = scrbuf.dwSize.X - origin.X if FillConsoleOutputCharacter(hStdout,' ', ht*wt, origin, addr(numwrote)) == 0: - osError(osLastError()) + raiseOSError(osLastError()) if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, ht * wt, scrbuf.dwCursorPosition, addr(numwrote)) == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: stdout.write("\e[2K") setCursorXPos(0) @@ -178,14 +178,14 @@ proc eraseScreen* = var numwrote: DWORD var origin: TCOORD # is inititalized to 0, 0 var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: osError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) if FillConsoleOutputCharacter(hStdout, ' ', scrbuf.dwSize.X*scrbuf.dwSize.Y, origin, addr(numwrote)) == 0: - osError(osLastError()) + raiseOSError(osLastError()) if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, scrbuf.dwSize.X * scrbuf.dwSize.Y, origin, addr(numwrote)) == 0: - osError(osLastError()) + raiseOSError(osLastError()) setCursorXPos(0) else: stdout.write("\e[2J") @@ -199,7 +199,7 @@ proc resetAttributes* {.noconv.} = stdout.write("\e[0m") type - TStyle* = enum ## different styles for text output + Style* = enum ## different styles for text output styleBright = 1, ## bright text styleDim, ## dim text styleUnknown, ## unknown @@ -208,6 +208,8 @@ type styleReverse = 7, ## unknown styleHidden ## hidden text +{.deprecated: [TStyle: Style].} + when not defined(windows): var # XXX: These better be thread-local @@ -244,7 +246,7 @@ proc writeStyled*(txt: string, style: set[TStyle] = {styleBright}) = stdout.write("\e[" & $ord(gBG) & 'm') type - TForegroundColor* = enum ## terminal's foreground colors + ForegroundColor* = enum ## terminal's foreground colors fgBlack = 30, ## black fgRed, ## red fgGreen, ## green @@ -254,7 +256,7 @@ type fgCyan, ## cyan fgWhite ## white - TBackgroundColor* = enum ## terminal's background colors + BackgroundColor* = enum ## terminal's background colors bgBlack = 40, ## black bgRed, ## red bgGreen, ## green @@ -264,13 +266,16 @@ type bgCyan, ## cyan bgWhite ## white -proc setForegroundColor*(fg: TForegroundColor, bright=false) = +{.deprecated: [TForegroundColor: ForegroundColor, + TBackgroundColor: BackgroundColor].} + +proc setForegroundColor*(fg: ForegroundColor, bright=false) = ## sets the terminal's foreground color when defined(windows): var old = getAttributes() and not 0x0007 if bright: old = old or FOREGROUND_INTENSITY - const lookup: array [TForegroundColor, int] = [ + const lookup: array [ForegroundColor, int] = [ 0, (FOREGROUND_RED), (FOREGROUND_GREEN), @@ -285,13 +290,13 @@ proc setForegroundColor*(fg: TForegroundColor, bright=false) = if bright: inc(gFG, 60) stdout.write("\e[" & $gFG & 'm') -proc setBackgroundColor*(bg: TBackgroundColor, bright=false) = +proc setBackgroundColor*(bg: BackgroundColor, bright=false) = ## sets the terminal's background color when defined(windows): var old = getAttributes() and not 0x0070 if bright: old = old or BACKGROUND_INTENSITY - const lookup: array [TBackgroundColor, int] = [ + const lookup: array [BackgroundColor, int] = [ 0, (BACKGROUND_RED), (BACKGROUND_GREEN), @@ -306,22 +311,22 @@ proc setBackgroundColor*(bg: TBackgroundColor, bright=false) = if bright: inc(gBG, 60) stdout.write("\e[" & $gBG & 'm') -proc isatty*(f: TFile): bool = +proc isatty*(f: File): bool = ## returns true if `f` is associated with a terminal device. when defined(posix): - proc isatty(fildes: TFileHandle): cint {. + proc isatty(fildes: FileHandle): cint {. importc: "isatty", header: "".} else: - proc isatty(fildes: TFileHandle): cint {. + proc isatty(fildes: FileHandle): cint {. importc: "_isatty", header: "".} - result = isatty(fileHandle(f)) != 0'i32 + result = isatty(getFileHandle(f)) != 0'i32 -proc styledEchoProcessArg(s: string) = write stdout, s -proc styledEchoProcessArg(style: TStyle) = setStyle({style}) -proc styledEchoProcessArg(style: set[TStyle]) = setStyle style -proc styledEchoProcessArg(color: TForegroundColor) = setForegroundColor color -proc styledEchoProcessArg(color: TBackgroundColor) = setBackgroundColor color +proc styledEchoProcessArg(s: string) = write stdout, s +proc styledEchoProcessArg(style: Style) = setStyle({style}) +proc styledEchoProcessArg(style: set[Style]) = setStyle style +proc styledEchoProcessArg(color: ForegroundColor) = setForegroundColor color +proc styledEchoProcessArg(color: BackgroundColor) = setBackgroundColor color macro styledEcho*(m: varargs[expr]): stmt = ## to be documented. diff --git a/lib/pure/times.nim b/lib/pure/times.nim index c156a4479..2c09fcc4c 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -21,9 +21,9 @@ import include "system/inclrtl" type - TMonth* = enum ## represents a month + Month* = enum ## represents a month mJan, mFeb, mMar, mApr, mMay, mJun, mJul, mAug, mSep, mOct, mNov, mDec - TWeekDay* = enum ## represents a weekday + WeekDay* = enum ## represents a weekday dMon, dTue, dWed, dThu, dFri, dSat, dSun var @@ -32,12 +32,12 @@ var when defined(posix) and not defined(JS): type - TTimeImpl {.importc: "time_t", header: "".} = int - TTime* = distinct TTimeImpl ## distinct type that represents a time - ## measured as number of seconds since the epoch + TimeImpl {.importc: "time_t", header: "".} = int + Time* = distinct TimeImpl ## distinct type that represents a time + ## measured as number of seconds since the epoch - Ttimeval {.importc: "struct timeval", header: "", - final, pure.} = object ## struct timeval + Timeval {.importc: "struct timeval", + header: "".} = object ## struct timeval tv_sec: int ## Seconds. tv_usec: int ## Microseconds. @@ -45,7 +45,7 @@ when defined(posix) and not defined(JS): # Ok, we could, but I don't want circular dependencies. # And gettimeofday() is not defined in the posix module anyway. Sigh. - proc posix_gettimeofday(tp: var Ttimeval, unused: pointer = nil) {. + proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {. importc: "gettimeofday", header: "".} elif defined(windows): @@ -53,16 +53,16 @@ elif defined(windows): when defined(vcc): # newest version of Visual C++ defines time_t to be of 64 bits - type TTimeImpl {.importc: "time_t", header: "".} = int64 + type TimeImpl {.importc: "time_t", header: "".} = int64 else: - type TTimeImpl {.importc: "time_t", header: "".} = int32 + type TimeImpl {.importc: "time_t", header: "".} = int32 type - TTime* = distinct TTimeImpl + Time* = distinct TimeImpl elif defined(JS): type - TTime* {.final, importc.} = object + Time* {.importc.} = object getDay: proc (): int {.tags: [], raises: [], gcsafe.} getFullYear: proc (): int {.tags: [], raises: [], gcsafe.} getHours: proc (): int {.tags: [], raises: [], gcsafe.} @@ -82,7 +82,7 @@ elif defined(JS): getUTCSeconds: proc (): int {.tags: [], raises: [], gcsafe.} getUTCDay: proc (): int {.tags: [], raises: [], gcsafe.} getYear: proc (): int {.tags: [], raises: [], gcsafe.} - parse: proc (s: cstring): TTime {.tags: [], raises: [], gcsafe.} + parse: proc (s: cstring): Time {.tags: [], raises: [], gcsafe.} setDate: proc (x: int) {.tags: [], raises: [], gcsafe.} setFullYear: proc (x: int) {.tags: [], raises: [], gcsafe.} setHours: proc (x: int) {.tags: [], raises: [], gcsafe.} @@ -103,7 +103,7 @@ elif defined(JS): toLocaleString: proc (): cstring {.tags: [], raises: [], gcsafe.} type - TTimeInfo* = object of RootObj ## represents a time in different parts + TimeInfo* = object of RootObj ## represents a time in different parts second*: range[0..61] ## The number of seconds after the minute, ## normally in the range 0 to 59, but can ## be up to 61 to allow for leap seconds. @@ -112,9 +112,9 @@ type hour*: range[0..23] ## The number of hours past midnight, ## in the range 0 to 23. monthday*: range[1..31] ## The day of the month, in the range 1 to 31. - month*: TMonth ## The current month. + month*: Month ## The current month. year*: range[-10_000..10_000] ## The current year. - weekday*: TWeekDay ## The current day of the week. + weekday*: WeekDay ## The current day of the week. yearday*: range[0..365] ## The number of days since January 1, ## in the range 0 to 365. ## Always 0 if the target is JS. @@ -127,7 +127,7 @@ type ## I make some assumptions about the data in here. Either ## everything should be positive or everything negative. Zero is ## fine too. Mixed signs will lead to unexpected results. - TTimeInterval* {.pure.} = object ## a time interval + TimeInterval* = object ## a time interval miliseconds*: int ## The number of miliseconds seconds*: int ## The number of seconds minutes*: int ## The number of minutes @@ -136,55 +136,58 @@ type months*: int ## The number of months years*: int ## The number of years -proc getTime*(): TTime {.tags: [TimeEffect], gcsafe.} +{.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time, TTimeval: Timeval, + TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].} + +proc getTime*(): Time {.tags: [TimeEffect], gcsafe.} ## gets the current calendar time as a UNIX epoch value (number of seconds ## elapsed since 1970) with integer precission. Use epochTime for higher ## resolution. -proc getLocalTime*(t: TTime): TTimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} +proc getLocalTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} ## converts the calendar time `t` to broken-time representation, ## expressed relative to the user's specified time zone. -proc getGMTime*(t: TTime): TTimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} +proc getGMTime*(t: Time): TimeInfo {.tags: [TimeEffect], raises: [], gcsafe.} ## converts the calendar time `t` to broken-down time representation, ## expressed in Coordinated Universal Time (UTC). -proc timeInfoToTime*(timeInfo: TTimeInfo): TTime {.tags: [], gcsafe.} +proc timeInfoToTime*(timeInfo: TimeInfo): Time {.tags: [], gcsafe.} ## converts a broken-down time structure to ## calendar time representation. The function ignores the specified ## contents of the structure members `weekday` and `yearday` and recomputes ## them from the other information in the broken-down time structure. -proc fromSeconds*(since1970: float): TTime {.tags: [], raises: [], gcsafe.} +proc fromSeconds*(since1970: float): Time {.tags: [], raises: [], gcsafe.} ## Takes a float which contains the number of seconds since the unix epoch and ## returns a time object. -proc fromSeconds*(since1970: int64): TTime {.tags: [], raises: [], gcsafe.} = +proc fromSeconds*(since1970: int64): Time {.tags: [], raises: [], gcsafe.} = ## Takes an int which contains the number of seconds since the unix epoch and ## returns a time object. fromSeconds(float(since1970)) -proc toSeconds*(time: TTime): float {.tags: [], raises: [], gcsafe.} +proc toSeconds*(time: Time): float {.tags: [], raises: [], gcsafe.} ## Returns the time in seconds since the unix epoch. -proc `$` *(timeInfo: TTimeInfo): string {.tags: [], raises: [], gcsafe.} - ## converts a `TTimeInfo` object to a string representation. -proc `$` *(time: TTime): string {.tags: [], raises: [], gcsafe.} +proc `$` *(timeInfo: TimeInfo): string {.tags: [], raises: [], gcsafe.} + ## converts a `TimeInfo` object to a string representation. +proc `$` *(time: Time): string {.tags: [], raises: [], gcsafe.} ## converts a calendar time to a string representation. -proc `-`*(a, b: TTime): int64 {. +proc `-`*(a, b: Time): int64 {. rtl, extern: "ntDiffTime", tags: [], raises: [].} ## computes the difference of two calendar times. Result is in seconds. -proc `<`*(a, b: TTime): bool {. +proc `<`*(a, b: Time): bool {. rtl, extern: "ntLtTime", tags: [], raises: [].} = ## returns true iff ``a < b``, that is iff a happened before b. result = a - b < 0 -proc `<=` * (a, b: TTime): bool {. +proc `<=` * (a, b: Time): bool {. rtl, extern: "ntLeTime", tags: [], raises: [].}= ## returns true iff ``a <= b``. result = a - b <= 0 -proc `==`*(a, b: TTime): bool {. +proc `==`*(a, b: Time): bool {. rtl, extern: "ntEqTime", tags: [], raises: [].} = ## returns true if ``a == b``, that is if both times represent the same value result = a - b == 0 @@ -203,8 +206,8 @@ proc getStartMilsecs*(): int {.deprecated, tags: [TimeEffect], gcsafe.} ## version 0.8.10.** Use ``epochTime`` or ``cpuTime`` instead. proc initInterval*(miliseconds, seconds, minutes, hours, days, months, - years: int = 0): TTimeInterval = - ## creates a new ``TTimeInterval``. + years: int = 0): TimeInterval = + ## creates a new ``TimeInterval``. result.miliseconds = miliseconds result.seconds = seconds result.minutes = minutes @@ -234,7 +237,7 @@ proc getDaysInMonth*(month: TMonth, year: int): int = of mApr, mJun, mSep, mNov: result = 30 else: result = 31 -proc toSeconds(a: TTimeInfo, interval: TTimeInterval): float = +proc toSeconds(a: TimeInfo, interval: TimeInterval): float = ## Calculates how many seconds the interval is worth by adding up ## all the fields @@ -257,7 +260,7 @@ proc toSeconds(a: TTimeInfo, interval: TTimeInterval): float = result += float(newinterv.seconds) result += newinterv.miliseconds / 1000 -proc `+`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = +proc `+`*(a: TimeInfo, interval: TimeInterval): TimeInfo = ## adds ``interval`` time. ## ## **Note:** This has been only briefly tested and it may not be @@ -269,7 +272,7 @@ proc `+`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = else: result = getLocalTime(fromSeconds(t + secs)) -proc `-`*(a: TTimeInfo, interval: TTimeInterval): TTimeInfo = +proc `-`*(a: TimeInfo, interval: TimeInterval): TimeInfo = ## subtracts ``interval`` time. ## ## **Note:** This has been only briefly tested, it is inaccurate especially @@ -314,38 +317,36 @@ when not defined(JS): yearday {.importc: "tm_yday".}, isdst {.importc: "tm_isdst".}: cint - PTimeInfo = ptr StructTM - PTime = ptr TTime + TimeInfoPtr = ptr StructTM + Clock {.importc: "clock_t".} = distinct int - TClock {.importc: "clock_t".} = distinct int - - proc localtime(timer: PTime): PTimeInfo {. + proc localtime(timer: ptr Time): TimeInfoPtr {. importc: "localtime", header: "", tags: [].} - proc gmtime(timer: PTime): PTimeInfo {. + proc gmtime(timer: ptr Time): TimeInfoPtr {. importc: "gmtime", header: "", tags: [].} - proc timec(timer: PTime): TTime {. + proc timec(timer: ptr Time): Time {. importc: "time", header: "", tags: [].} - proc mktime(t: StructTM): TTime {. + proc mktime(t: StructTM): Time {. importc: "mktime", header: "", tags: [].} proc asctime(tblock: StructTM): cstring {. importc: "asctime", header: "", tags: [].} - proc ctime(time: PTime): cstring {. + proc ctime(time: ptr Time): cstring {. importc: "ctime", header: "", tags: [].} # strftime(s: CString, maxsize: int, fmt: CString, t: tm): int {. # importc: "strftime", header: "".} - proc clock(): TClock {.importc: "clock", header: "", tags: [TimeEffect].} - proc difftime(a, b: TTime): float {.importc: "difftime", header: "", + proc getClock(): Clock {.importc: "clock", header: "", tags: [TimeEffect].} + proc difftime(a, b: Time): float {.importc: "difftime", header: "", tags: [].} var clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int # our own procs on top of that: - proc tmToTimeInfo(tm: StructTM, local: bool): TTimeInfo = + proc tmToTimeInfo(tm: StructTM, local: bool): TimeInfo = const - weekDays: array [0..6, TWeekDay] = [ + weekDays: array [0..6, WeekDay] = [ dSun, dMon, dTue, dWed, dThu, dFri, dSat] - TTimeInfo(second: int(tm.second), + TimeInfo(second: int(tm.second), minute: int(tm.minute), hour: int(tm.hour), monthday: int(tm.monthday), @@ -364,9 +365,9 @@ when not defined(JS): timezone: if local: getTimezone() else: 0 ) - proc timeInfoToTM(t: TTimeInfo): StructTM = + proc timeInfoToTM(t: TimeInfo): StructTM = const - weekDays: array [TWeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8] + weekDays: array [WeekDay, int8] = [1'i8,2'i8,3'i8,4'i8,5'i8,6'i8,0'i8] result.second = t.second result.minute = t.minute result.hour = t.hour @@ -378,36 +379,36 @@ when not defined(JS): result.isdst = if t.isDST: 1 else: 0 when not defined(useNimRtl): - proc `-` (a, b: TTime): int64 = + proc `-` (a, b: Time): int64 = return toBiggestInt(difftime(a, b)) proc getStartMilsecs(): int = - #echo "clocks per sec: ", clocksPerSec, "clock: ", int(clock()) - #return clock() div (clocksPerSec div 1000) + #echo "clocks per sec: ", clocksPerSec, "clock: ", int(getClock()) + #return getClock() div (clocksPerSec div 1000) when defined(macosx): - result = toInt(toFloat(int(clock())) / (toFloat(clocksPerSec) / 1000.0)) + result = toInt(toFloat(int(getClock())) / (toFloat(clocksPerSec) / 1000.0)) else: - result = int(clock()) div (clocksPerSec div 1000) + result = int(getClock()) div (clocksPerSec div 1000) when false: - var a: Ttimeval + var a: Timeval posix_gettimeofday(a) result = a.tv_sec * 1000'i64 + a.tv_usec div 1000'i64 #echo "result: ", result - proc getTime(): TTime = return timec(nil) - proc getLocalTime(t: TTime): TTimeInfo = + proc getTime(): Time = return timec(nil) + proc getLocalTime(t: Time): TimeInfo = var a = t result = tmToTimeInfo(localtime(addr(a))[], true) # copying is needed anyway to provide reentrancity; thus # the conversion is not expensive - proc getGMTime(t: TTime): TTimeInfo = + proc getGMTime(t: Time): TimeInfo = var a = t result = tmToTimeInfo(gmtime(addr(a))[], false) # copying is needed anyway to provide reentrancity; thus # the conversion is not expensive - proc timeInfoToTime(timeInfo: TTimeInfo): TTime = + proc timeInfoToTime(timeInfo: TimeInfo): Time = var cTimeInfo = timeInfo # for C++ we have to make a copy, # because the header of mktime is broken in my version of libc return mktime(timeInfoToTM(cTimeInfo)) @@ -419,12 +420,12 @@ when not defined(JS): add(result, p[i]) inc(i) - proc `$`(timeInfo: TTimeInfo): string = + proc `$`(timeInfo: TimeInfo): string = # BUGFIX: asctime returns a newline at the end! var p = asctime(timeInfoToTM(timeInfo)) result = toStringTillNL(p) - proc `$`(time: TTime): string = + proc `$`(time: Time): string = # BUGFIX: ctime returns a newline at the end! var a = time return toStringTillNL(ctime(addr(a))) @@ -433,13 +434,13 @@ when not defined(JS): epochDiff = 116444736000000000'i64 rateDiff = 10000000'i64 # 100 nsecs - proc unixTimeToWinTime*(t: TTime): int64 = - ## converts a UNIX `TTime` (``time_t``) to a Windows file time + proc unixTimeToWinTime*(t: Time): int64 = + ## converts a UNIX `Time` (``time_t``) to a Windows file time result = int64(t) * rateDiff + epochDiff - proc winTimeToUnixTime*(t: int64): TTime = - ## converts a Windows time to a UNIX `TTime` (``time_t``) - result = TTime((t - epochDiff) div rateDiff) + proc winTimeToUnixTime*(t: int64): Time = + ## converts a Windows time to a UNIX `Time` (``time_t``) + result = Time((t - epochDiff) div rateDiff) proc getTzname(): tuple[nonDST, DST: string] = return ($tzname[0], $tzname[1]) @@ -447,9 +448,9 @@ when not defined(JS): proc getTimezone(): int = return timezone - proc fromSeconds(since1970: float): TTime = TTime(since1970) + proc fromSeconds(since1970: float): Time = Time(since1970) - proc toSeconds(time: TTime): float = float(time) + proc toSeconds(time: Time): float = float(time) when not defined(useNimRtl): proc epochTime(): float = @@ -468,15 +469,15 @@ when not defined(JS): {.error: "unknown OS".} proc cpuTime(): float = - result = toFloat(int(clock())) / toFloat(clocksPerSec) + result = toFloat(int(getClock())) / toFloat(clocksPerSec) elif defined(JS): - proc newDate(): TTime {.importc: "new Date".} - proc internGetTime(): TTime {.importc: "new Date", tags: [].} + proc newDate(): Time {.importc: "new Date".} + proc internGetTime(): Time {.importc: "new Date", tags: [].} - proc newDate(value: float): TTime {.importc: "new Date".} - proc newDate(value: string): TTime {.importc: "new Date".} - proc getTime(): TTime = + proc newDate(value: float): Time {.importc: "new Date".} + proc newDate(value: string): Time {.importc: "new Date".} + proc getTime(): Time = # Warning: This is something different in JS. return newDate() @@ -484,7 +485,7 @@ elif defined(JS): weekDays: array [0..6, TWeekDay] = [ dSun, dMon, dTue, dWed, dThu, dFri, dSat] - proc getLocalTime(t: TTime): TTimeInfo = + proc getLocalTime(t: Time): TimeInfo = result.second = t.getSeconds() result.minute = t.getMinutes() result.hour = t.getHours() @@ -494,7 +495,7 @@ elif defined(JS): result.weekday = weekDays[t.getDay()] result.yearday = 0 - proc getGMTime(t: TTime): TTimeInfo = + proc getGMTime(t: Time): TimeInfo = result.second = t.getUTCSeconds() result.minute = t.getUTCMinutes() result.hour = t.getUTCHours() @@ -504,7 +505,7 @@ elif defined(JS): result.weekday = weekDays[t.getUTCDay()] result.yearday = 0 - proc timeInfoToTime*(timeInfo: TTimeInfo): TTime = + proc timeInfoToTime*(timeInfo: TimeInfo): Time = result = internGetTime() result.setSeconds(timeInfo.second) result.setMinutes(timeInfo.minute) @@ -513,10 +514,10 @@ elif defined(JS): result.setFullYear(timeInfo.year) result.setDate(timeInfo.monthday) - proc `$`(timeInfo: TTimeInfo): string = return $(TimeInfoToTIme(timeInfo)) - proc `$`(time: TTime): string = return $time.toLocaleString() + proc `$`(timeInfo: TimeInfo): string = return $(TimeInfoToTIme(timeInfo)) + proc `$`(time: Time): string = return $time.toLocaleString() - proc `-` (a, b: TTime): int64 = + proc `-` (a, b: Time): int64 = return a.getTime() - b.getTime() var @@ -526,11 +527,11 @@ elif defined(JS): ## get the miliseconds from the start of the program return int(getTime() - startMilsecs) - proc valueOf(time: TTime): float {.importcpp: "getTime", tags:[]} + proc valueOf(time: Time): float {.importcpp: "getTime", tags:[]} - proc fromSeconds(since1970: float): TTime = result = newDate(since1970) + proc fromSeconds(since1970: float): Time = result = newDate(since1970) - proc toSeconds(time: TTime): float = result = time.valueOf() / 1000 + proc toSeconds(time: Time): float = result = time.valueOf() / 1000 proc getTimezone(): int = result = newDate().getTimezoneOffset() @@ -546,20 +547,20 @@ proc getClockStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} = result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) & ':' & intToStr(ti.second, 2) -proc `$`*(day: TWeekDay): string = - ## stingify operator for ``TWeekDay``. - const lookup: array[TWeekDay, string] = ["Monday", "Tuesday", "Wednesday", +proc `$`*(day: WeekDay): string = + ## stingify operator for ``WeekDay``. + const lookup: array[WeekDay, string] = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] return lookup[day] -proc `$`*(m: TMonth): string = +proc `$`*(m: Month): string = ## stingify operator for ``TMonth``. - const lookup: array[TMonth, string] = ["January", "February", "March", + const lookup: array[Month, string] = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] return lookup[m] -proc format_token(info: TTimeInfo, token: string, buf: var string) = +proc formatToken(info: TimeInfo, token: string, buf: var string) = ## Helper of the format proc to parse individual tokens. ## ## Pass the found token in the user input string, and the buffer where the @@ -672,7 +673,7 @@ proc format_token(info: TTimeInfo, token: string, buf: var string) = raise newException(ValueError, "Invalid format string: " & token) -proc format*(info: TTimeInfo, f: string): string = +proc format*(info: TimeInfo, f: string): string = ## This function formats `info` as specified by `f`. The following format ## specifiers are available: ## @@ -718,7 +719,7 @@ proc format*(info: TTimeInfo, f: string): string = while true: case f[i] of ' ', '-', '/', ':', '\'', '\0', '(', ')', '[', ']', ',': - format_token(info, currentF, result) + formatToken(info, currentF, result) currentF = "" if f[i] == '\0': break @@ -735,7 +736,7 @@ proc format*(info: TTimeInfo, f: string): string = if currentF.len < 1 or currentF[high(currentF)] == f[i]: currentF.add(f[i]) else: - format_token(info, currentF, result) + formatToken(info, currentF, result) dec(i) # Move position back to re-process the character separately. currentF = "" @@ -764,7 +765,7 @@ when isMainModule: " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == "27 27 Mon Monday 4 04 16 16 6 06 1 01 Jan January 29 29 P PM 5 75 975 1975 01975 0 00 00:00 UTC" - when not defined(JS) and sizeof(TTime) == 8: + when not defined(JS) and sizeof(Time) == 8: var t3 = getGMTime(fromSeconds(889067643645)) # Fri 7 Jun 19:20:45 BST 30143 assert t3.format("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" & " ss t tt y yy yyy yyyy yyyyy z zz zzz ZZZ") == diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index 3203ee699..1180b98f0 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Nimrod Contributors # # See the file "copying.txt", included in this diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index 6e73eea3f..c2eb001f6 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -14,13 +14,15 @@ include "system/inclrtl" type - IRune = int # underlying type of TRune - TRune* = distinct IRune ## type that can hold any Unicode character - TRune16* = distinct int16 ## 16 bit Unicode character + RuneImpl = int # underlying type of Rune + Rune* = distinct RuneImpl ## type that can hold any Unicode character + Rune16* = distinct int16 ## 16 bit Unicode character + +{.deprecated: [TRune: Rune, TRune16: Rune16].} -proc `<=%`*(a, b: TRune): bool = return int(a) <=% int(b) -proc `<%`*(a, b: TRune): bool = return int(a) <% int(b) -proc `==`*(a, b: TRune): bool = return int(a) == int(b) +proc `<=%`*(a, b: Rune): bool = return int(a) <=% int(b) +proc `<%`*(a, b: Rune): bool = return int(a) <% int(b) +proc `==`*(a, b: Rune): bool = return int(a) == int(b) template ones(n: expr): expr = ((1 shl n)-1) @@ -52,17 +54,17 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = ## `i` is incremented by the number of bytes that have been processed. bind ones if ord(s[i]) <=% 127: - result = TRune(ord(s[i])) + result = Rune(ord(s[i])) when doInc: inc(i) elif ord(s[i]) shr 5 == 0b110: # assert(ord(s[i+1]) shr 6 == 0b10) - result = TRune((ord(s[i]) and (ones(5))) shl 6 or - (ord(s[i+1]) and ones(6))) + result = Rune((ord(s[i]) and (ones(5))) shl 6 or + (ord(s[i+1]) and ones(6))) when doInc: inc(i, 2) elif ord(s[i]) shr 4 == 0b1110: # assert(ord(s[i+1]) shr 6 == 0b10) # assert(ord(s[i+2]) shr 6 == 0b10) - result = TRune((ord(s[i]) and ones(4)) shl 12 or + result = Rune((ord(s[i]) and ones(4)) shl 12 or (ord(s[i+1]) and ones(6)) shl 6 or (ord(s[i+2]) and ones(6))) when doInc: inc(i, 3) @@ -70,7 +72,7 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = # assert(ord(s[i+1]) shr 6 == 0b10) # assert(ord(s[i+2]) shr 6 == 0b10) # assert(ord(s[i+3]) shr 6 == 0b10) - result = TRune((ord(s[i]) and ones(3)) shl 18 or + result = Rune((ord(s[i]) and ones(3)) shl 18 or (ord(s[i+1]) and ones(6)) shl 12 or (ord(s[i+2]) and ones(6)) shl 6 or (ord(s[i+3]) and ones(6))) @@ -80,7 +82,7 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = # assert(ord(s[i+2]) shr 6 == 0b10) # assert(ord(s[i+3]) shr 6 == 0b10) # assert(ord(s[i+4]) shr 6 == 0b10) - result = TRune((ord(s[i]) and ones(2)) shl 24 or + result = Rune((ord(s[i]) and ones(2)) shl 24 or (ord(s[i+1]) and ones(6)) shl 18 or (ord(s[i+2]) and ones(6)) shl 12 or (ord(s[i+3]) and ones(6)) shl 6 or @@ -92,7 +94,7 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = # assert(ord(s[i+3]) shr 6 == 0b10) # assert(ord(s[i+4]) shr 6 == 0b10) # assert(ord(s[i+5]) shr 6 == 0b10) - result = TRune((ord(s[i]) and ones(1)) shl 30 or + result = Rune((ord(s[i]) and ones(1)) shl 30 or (ord(s[i+1]) and ones(6)) shl 24 or (ord(s[i+2]) and ones(6)) shl 18 or (ord(s[i+3]) and ones(6)) shl 12 or @@ -100,16 +102,16 @@ template fastRuneAt*(s: string, i: int, result: expr, doInc = true) = (ord(s[i+5]) and ones(6))) when doInc: inc(i, 6) else: - result = TRune(ord(s[i])) + result = Rune(ord(s[i])) when doInc: inc(i) -proc runeAt*(s: string, i: int): TRune = +proc runeAt*(s: string, i: int): Rune = ## returns the unicode character in `s` at byte index `i` fastRuneAt(s, i, result, false) -proc toUTF8*(c: TRune): string {.rtl, extern: "nuc$1".} = +proc toUTF8*(c: Rune): string {.rtl, extern: "nuc$1".} = ## converts a rune into its UTF8 representation - var i = IRune(c) + var i = RuneImpl(c) if i <=% 127: result = newString(1) result[0] = chr(i) @@ -132,11 +134,11 @@ proc toUTF8*(c: TRune): string {.rtl, extern: "nuc$1".} = result = newString(1) result[0] = chr(i) -proc `$`*(rune: TRune): string = +proc `$`*(rune: Rune): string = ## converts a rune to a string rune.toUTF8 -proc `$`*(runes: seq[TRune]): string = +proc `$`*(runes: seq[Rune]): string = ## converts a sequence of runes to a string result = "" for rune in runes: result.add(rune.toUTF8) @@ -1100,7 +1102,7 @@ const 0x01f1, 501, # 0x01f3, 499] # -proc binarySearch(c: IRune, tab: openArray[IRune], len, stride: int): int = +proc binarySearch(c: RuneImpl, tab: openArray[RuneImpl], len, stride: int): int = var n = len var t = 0 while n > 1: @@ -1115,41 +1117,41 @@ proc binarySearch(c: IRune, tab: openArray[IRune], len, stride: int): int = return t return -1 -proc toLower*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = +proc toLower*(c: Rune): Rune {.rtl, extern: "nuc$1", procvar.} = ## Converts `c` into lower case. This works for any Unicode character. ## If possible, prefer `toLower` over `toUpper`. - var c = IRune(c) + var c = RuneImpl(c) var p = binarySearch(c, tolowerRanges, len(tolowerRanges) div 3, 3) if p >= 0 and c >= tolowerRanges[p] and c <= tolowerRanges[p+1]: - return TRune(c + tolowerRanges[p+2] - 500) + return Rune(c + tolowerRanges[p+2] - 500) p = binarySearch(c, tolowerSinglets, len(tolowerSinglets) div 2, 2) if p >= 0 and c == tolowerSinglets[p]: - return TRune(c + tolowerSinglets[p+1] - 500) - return TRune(c) + return Rune(c + tolowerSinglets[p+1] - 500) + return Rune(c) -proc toUpper*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = +proc toUpper*(c: Rune): Rune {.rtl, extern: "nuc$1", procvar.} = ## Converts `c` into upper case. This works for any Unicode character. ## If possible, prefer `toLower` over `toUpper`. - var c = IRune(c) + var c = RuneImpl(c) var p = binarySearch(c, toupperRanges, len(toupperRanges) div 3, 3) if p >= 0 and c >= toupperRanges[p] and c <= toupperRanges[p+1]: - return TRune(c + toupperRanges[p+2] - 500) + return Rune(c + toupperRanges[p+2] - 500) p = binarySearch(c, toupperSinglets, len(toupperSinglets) div 2, 2) if p >= 0 and c == toupperSinglets[p]: - return TRune(c + toupperSinglets[p+1] - 500) - return TRune(c) + return Rune(c + toupperSinglets[p+1] - 500) + return Rune(c) -proc toTitle*(c: TRune): TRune {.rtl, extern: "nuc$1", procvar.} = - var c = IRune(c) +proc toTitle*(c: Rune): Rune {.rtl, extern: "nuc$1", procvar.} = + var c = RuneImpl(c) var p = binarySearch(c, toTitleSinglets, len(toTitleSinglets) div 2, 2) if p >= 0 and c == toTitleSinglets[p]: - return TRune(c + toTitleSinglets[p+1] - 500) - return TRune(c) + return Rune(c + toTitleSinglets[p+1] - 500) + return Rune(c) -proc isLower*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isLower*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a lower case Unicode character ## If possible, prefer `isLower` over `isUpper`. - var c = IRune(c) + var c = RuneImpl(c) # Note: toUpperRanges is correct here! var p = binarySearch(c, toupperRanges, len(toupperRanges) div 3, 3) if p >= 0 and c >= toupperRanges[p] and c <= toupperRanges[p+1]: @@ -1158,10 +1160,10 @@ proc isLower*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = if p >= 0 and c == toupperSinglets[p]: return true -proc isUpper*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isUpper*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a upper case Unicode character ## If possible, prefer `isLower` over `isUpper`. - var c = IRune(c) + var c = RuneImpl(c) # Note: toLowerRanges is correct here! var p = binarySearch(c, tolowerRanges, len(tolowerRanges) div 3, 3) if p >= 0 and c >= tolowerRanges[p] and c <= tolowerRanges[p+1]: @@ -1170,11 +1172,11 @@ proc isUpper*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = if p >= 0 and c == tolowerSinglets[p]: return true -proc isAlpha*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isAlpha*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is an *alpha* Unicode character (i.e. a letter) if isUpper(c) or isLower(c): return true - var c = IRune(c) + var c = RuneImpl(c) var p = binarySearch(c, alphaRanges, len(alphaRanges) div 2, 2) if p >= 0 and c >= alphaRanges[p] and c <= alphaRanges[p+1]: return true @@ -1182,21 +1184,21 @@ proc isAlpha*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = if p >= 0 and c == alphaSinglets[p]: return true -proc isTitle*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isTitle*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = return isUpper(c) and isLower(c) -proc isWhiteSpace*(c: TRune): bool {.rtl, extern: "nuc$1", procvar.} = +proc isWhiteSpace*(c: Rune): bool {.rtl, extern: "nuc$1", procvar.} = ## returns true iff `c` is a Unicode whitespace character - var c = IRune(c) + var c = RuneImpl(c) var p = binarySearch(c, spaceRanges, len(spaceRanges) div 2, 2) if p >= 0 and c >= spaceRanges[p] and c <= spaceRanges[p+1]: return true -iterator runes*(s: string): TRune = +iterator runes*(s: string): Rune = ## iterates over any unicode character of the string `s`. var i = 0 - result: TRune + result: Rune while i < len(s): fastRuneAt(s, i, result, true) yield result @@ -1209,12 +1211,12 @@ proc cmpRunesIgnoreCase*(a, b: string): int {.rtl, extern: "nuc$1", procvar.} = ## | > 0 iff a > b var i = 0 var j = 0 - var ar, br: TRune + var ar, br: Rune while i < a.len and j < b.len: # slow path: fastRuneAt(a, i, ar) fastRuneAt(b, j, br) - result = IRune(toLower(ar)) - IRune(toLower(br)) + result = RuneImpl(toLower(ar)) - RuneImpl(toLower(br)) if result != 0: return result = a.len - b.len diff --git a/lib/pure/unidecode/unidecode.nim b/lib/pure/unidecode/unidecode.nim index 1d36d11b5..798eef5d0 100644 --- a/lib/pure/unidecode/unidecode.nim +++ b/lib/pure/unidecode/unidecode.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -55,7 +55,7 @@ proc unidecode*(s: string): string = ## ## Example: ## - ## ..code-block:: nimrod + ## ..code-block:: nim ## ## unidecode("\x53\x17\x4E\xB0") ## diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 7cc95f0ad..f26d8c3e6 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Nimrod Contributors # # See the file "copying.txt", included in this @@ -26,16 +26,19 @@ when not defined(ECMAScript): import terminal type - TTestStatus* = enum OK, FAILED - TOutputLevel* = enum PRINT_ALL, PRINT_FAILURES, PRINT_NONE + TestStatus* = enum OK, FAILED + OutputLevel* = enum PRINT_ALL, PRINT_FAILURES, PRINT_NONE + +{.deprecated: [TTestStatus: TestStatus, TOutputLevel: OutputLevel]} var - # XXX: These better be thread-local - AbortOnError*: bool - OutputLevel*: TOutputLevel - ColorOutput*: bool + abortOnError* {.threadvar.}: bool + outputLevel* {.threadvar.}: OutputLevel + colorOutput* {.threadvar.}: bool - checkpoints: seq[string] = @[] + checkpoints {.threadvar.}: seq[string] + +checkpoints = @[] template TestSetupIMPL*: stmt {.immediate, dirty.} = discard template TestTeardownIMPL*: stmt {.immediate, dirty.} = discard @@ -53,7 +56,7 @@ template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} = body -proc testDone(name: string, s: TTestStatus) = +proc testDone(name: string, s: TestStatus) = if s == FAILED: program_result += 1 @@ -192,15 +195,15 @@ when declared(stdout): ## Reading settings var envOutLvl = os.getEnv("NIMTEST_OUTPUT_LVL").string - AbortOnError = existsEnv("NIMTEST_ABORT_ON_ERROR") - ColorOutput = not existsEnv("NIMTEST_NO_COLOR") + abortOnError = existsEnv("NIMTEST_ABORT_ON_ERROR") + colorOutput = not existsEnv("NIMTEST_NO_COLOR") else: var envOutLvl = "" # TODO - ColorOutput = false + colorOutput = false if envOutLvl.len > 0: - for opt in countup(low(TOutputLevel), high(TOutputLevel)): + for opt in countup(low(OutputLevel), high(OutputLevel)): if $opt == envOutLvl: - OutputLevel = opt + outputLevel = opt break diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index 7ec823033..ed1059cc2 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # # See the file "copying.txt", included in this @@ -11,12 +11,14 @@ import strutils, parseutils type - TUrl* = distinct string + Url* = distinct string - TUri* = object + Uri* = object scheme*, username*, password*: string hostname*, port*, path*, query*, anchor*: string +{.deprecated: [TUrl: Url, TUri: Uri].} + proc `$`*(url: TUrl): string {.deprecated.} = ## **Deprecated since 0.9.6**: Use ``TUri`` instead. return string(url) @@ -172,7 +174,7 @@ proc combine*(base: TUri, reference: TUri): TUri = ## ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let foo = combine(parseUri("http://example.com/foo/bar"), parseUri("/baz")) ## assert foo.path == "/baz" ## @@ -229,7 +231,7 @@ proc `/`*(x: TUri, path: string): TUri = ## ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: ## let foo = parseUri("http://example.com/foo/bar") / parseUri("/baz") ## assert foo.path == "/foo/bar/baz" ## diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim index d63b6c5dd..afd26a584 100644 --- a/lib/pure/xmldom.nim +++ b/lib/pure/xmldom.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Dominik Picheta # # See the file "copying.txt", included in this @@ -9,7 +9,8 @@ import strutils -## This module implements XML DOM Level 2 Core specification(http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html) +## This module implements XML DOM Level 2 Core +## specification (http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html) #http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html diff --git a/lib/pure/xmldomparser.nim b/lib/pure/xmldomparser.nim index fda46bac0..b92a9600c 100644 --- a/lib/pure/xmldomparser.nim +++ b/lib/pure/xmldomparser.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Dominik Picheta # # See the file "copying.txt", included in this @@ -156,7 +156,7 @@ proc loadXMLFile*(path: string): PDocument = when isMainModule: - var xml = loadXMLFile(r"C:\Users\Dominik\Desktop\Code\Nimrod\xmldom\test.xml") + var xml = loadXMLFile("nim/xmldom/test.xml") #echo(xml.getElementsByTagName("m:test2")[0].namespaceURI) #echo(xml.getElementsByTagName("bla:test")[0].namespaceURI) #echo(xml.getElementsByTagName("test")[0].namespaceURI) diff --git a/lib/pure/xmlparser.nim b/lib/pure/xmlparser.nim index 8b8bb3b03..83bd45e7d 100644 --- a/lib/pure/xmlparser.nim +++ b/lib/pure/xmlparser.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,9 +12,11 @@ import streams, parsexml, strtabs, xmltree type - EInvalidXml* = object of EInvalidValue ## exception that is raised - ## for invalid XML - errors*: seq[string] ## all detected parsing errors + XmlError* = object of ValueError ## exception that is raised + ## for invalid XML + errors*: seq[string] ## all detected parsing errors + +{.deprecated: [EInvalidXml: XmlError].} proc raiseInvalidXml(errors: seq[string]) = var e: ref EInvalidXml @@ -23,12 +25,12 @@ proc raiseInvalidXml(errors: seq[string]) = e.errors = errors raise e -proc addNode(father, son: PXmlNode) = +proc addNode(father, son: XmlNode) = if son != nil: add(father, son) -proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode +proc parse(x: var XmlParser, errors: var seq[string]): XmlNode -proc untilElementEnd(x: var TXmlParser, result: PXmlNode, +proc untilElementEnd(x: var XmlParser, result: XmlNode, errors: var seq[string]) = while true: case x.kind @@ -45,7 +47,7 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode, else: result.addNode(parse(x, errors)) -proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = +proc parse(x: var XmlParser, errors: var seq[string]): XmlNode = case x.kind of xmlComment: result = newComment(x.charData) @@ -98,11 +100,11 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = next(x) of xmlEof: discard -proc parseXml*(s: PStream, filename: string, - errors: var seq[string]): PXmlNode = +proc parseXml*(s: Stream, filename: string, + errors: var seq[string]): XmlNode = ## parses the XML from stream `s` and returns a ``PXmlNode``. Every ## occured parsing error is added to the `errors` sequence. - var x: TXmlParser + var x: XmlParser open(x, s, filename, {reportComments}) while true: x.next() @@ -118,14 +120,14 @@ proc parseXml*(s: PStream, filename: string, break close(x) -proc parseXml*(s: PStream): PXmlNode = +proc parseXml*(s: Stream): XmlNode = ## parses the XTML from stream `s` and returns a ``PXmlNode``. All parsing ## errors are turned into an ``EInvalidXML`` exception. var errors: seq[string] = @[] result = parseXml(s, "unknown_html_doc", errors) if errors.len > 0: raiseInvalidXMl(errors) -proc loadXml*(path: string, errors: var seq[string]): PXmlNode = +proc loadXml*(path: string, errors: var seq[string]): XmlNode = ## Loads and parses XML from file specified by ``path``, and returns ## a ``PXmlNode``. Every occured parsing error is added to the `errors` ## sequence. @@ -133,7 +135,7 @@ proc loadXml*(path: string, errors: var seq[string]): PXmlNode = if s == nil: raise newException(EIO, "Unable to read file: " & path) result = parseXml(s, path, errors) -proc loadXml*(path: string): PXmlNode = +proc loadXml*(path: string): XmlNode = ## Loads and parses XML from file specified by ``path``, and returns ## a ``PXmlNode``. All parsing errors are turned into an ``EInvalidXML`` ## exception. @@ -148,7 +150,7 @@ when isMainModule: var x = loadXml(paramStr(1), errors) for e in items(errors): echo e - var f: TFile + var f: File if open(f, "xmltest.txt", fmWrite): f.write($x) f.close() diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 7392eb470..6007232c5 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,33 +12,36 @@ import macros, strtabs type - PXmlNode* = ref TXmlNode ## an XML tree consists of ``PXmlNode``'s. + XmlNode* = ref TXmlNode ## an XML tree consists of ``PXmlNode``'s. - TXmlNodeKind* = enum ## different kinds of ``PXmlNode``'s + XmlNodeKind* = enum ## different kinds of ``PXmlNode``'s xnText, ## a text element xnElement, ## an element with 0 or more children xnCData, ## a CDATA node xnEntity, ## an entity (like ``&thing;``) xnComment ## an XML comment - PXmlAttributes* = PStringTable ## an alias for a string to string mapping + XmlAttributes* = StringTableRef ## an alias for a string to string mapping - TXmlNode {.pure, final, acyclic.} = object - case k: TXmlNodeKind # private, use the kind() proc to read this field. + XmlNodeObj {.acyclic.} = object + case k: XmlNodeKind # private, use the kind() proc to read this field. of xnText, xnComment, xnCData, xnEntity: fText: string of xnElement: fTag: string - s: seq[PXmlNode] - fAttr: PXmlAttributes + s: seq[XmlNode] + fAttr: XmlAttributes fClientData: int ## for other clients - -proc newXmlNode(kind: TXmlNodeKind): PXmlNode = - ## creates a new ``PXmlNode``. + +{.deprecated: [PXmlNode: XmlNode, TXmlNodeKind: XmlNodeKind, PXmlAttributes: + XmlAttributes, TXmlNode: XmlNodeObj].} + +proc newXmlNode(kind: XmlNodeKind): XmlNode = + ## creates a new ``XmlNode``. new(result) result.k = kind -proc newElement*(tag: string): PXmlNode = +proc newElement*(tag: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnText`` with the given `tag`. result = newXmlNode(xnElement) result.fTag = tag @@ -304,10 +307,10 @@ proc findAll*(n: PXmlNode, tag: string, result: var seq[PXmlNode]) = ## Found nodes satisfying the condition will be appended to the `result` ## sequence, which can't be nil or the proc will crash. Usage example: ## - ## .. code-block:: nimrod + ## .. code-block:: ## var - ## html: PXmlNode - ## tags: seq[PXmlNode] = @[] + ## html: XmlNode + ## tags: seq[XmlNode] = @[] ## ## html = buildHtml() ## findAll(html, "img", tags) @@ -326,8 +329,8 @@ proc findAll*(n: PXmlNode, tag: string, result: var seq[PXmlNode]) = proc findAll*(n: PXmlNode, tag: string): seq[PXmlNode] = ## Shortcut version to assign in let blocks. Example: ## - ## .. code-block:: nimrod - ## var html: PXmlNode + ## .. code-block:: + ## var html: XmlNode ## ## html = buildHtml(html) ## for imgTag in html.findAll("img"): diff --git a/lib/system.nim b/lib/system.nim index ad1cbd423..0e9712c24 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2437,6 +2437,8 @@ when not defined(JS): #and not defined(NimrodVM): ## returns the OS file handle of the file ``f``. This is only useful for ## platform specific programming. + {.deprecated: [fileHandle: getFileHandle].} + proc cstringArrayToSeq*(a: cstringArray, len: int): seq[string] = ## converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be ## of length ``len``. diff --git a/todo.txt b/todo.txt index 68965584b..fef88efc2 100644 --- a/todo.txt +++ b/todo.txt @@ -49,7 +49,6 @@ Bugs - bug: type conversions concerning proc types are weird - compilation of niminst takes way too long. looks like a regression - docgen: sometimes effects are listed twice -- 'result' is not properly cleaned for NRVO --> use uninit checking instead - blocks can "export" an identifier but the CCG generates {} for them ... From df172806ea153c2b058165cc09f836dd79350774 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 00:24:52 +0200 Subject: [PATCH 012/409] big rename --- compiler/cgen.nim | 2 +- lib/posix/posix.nim | 7 +- lib/pure/collections/sets.nim | 10 +-- lib/pure/collections/tables.nim | 4 +- lib/pure/lexbase.nim | 4 +- lib/pure/memfiles.nim | 4 +- lib/pure/os.nim | 124 ++++++++++++++++---------------- lib/pure/osproc.nim | 34 ++++----- lib/pure/strtabs.nim | 6 +- lib/pure/strutils.nim | 4 +- lib/pure/times.nim | 8 +-- lib/windows/winlean.nim | 4 +- 12 files changed, 108 insertions(+), 103 deletions(-) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 315b55801..deccf9ced 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index e1bcd9dfc..43139389b 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -29,7 +29,7 @@ {.deadCodeElim:on.} -from times import TTime +from times import Time const hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays @@ -83,8 +83,11 @@ else: ## A type representing a directory stream. type - TSocketHandle* = distinct cint # The type used to represent socket descriptors + SocketHandle* = distinct cint # The type used to represent socket descriptors +{.deprecated: [TSocketHandle: SocketHandle].} + +type Tdirent* {.importc: "struct dirent", header: "", final, pure.} = object ## dirent_t struct d_ino*: Tino ## File serial number. diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 1201241f1..27f5ef07a 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -149,11 +149,11 @@ proc contains*[A](s: TSet[A], key: A): bool = var index = rawGet(s, key) result = index >= 0 -proc rawInsert[A](s: var TSet[A], data: var TKeyValuePairSeq[A], key: A) = +proc rawInsert[A](s: var TSet[A], data: var KeyValuePairSeq[A], key: A) = rawInsertImpl() proc enlarge[A](s: var TSet[A]) = - var n: TKeyValuePairSeq[A] + var n: KeyValuePairSeq[A] newSeq(n, len(s.data) * growthFactor) for i in countup(0, high(s.data)): if s.data[i].slot == seFilled: rawInsert(s, n, s.data[i].key) @@ -500,7 +500,7 @@ type ## ## Use `init() <#init,OrderedSet[A],int>`_ or `initOrderedSet[type]() ## <#initOrderedSet>`_ before calling other procs on it. - data: TOrderedKeyValuePairSeq[A] + data: OrderedKeyValuePairSeq[A] counter, first, last: int {.deprecated: [TOrderedSet: OrderedSet].} @@ -588,7 +588,7 @@ proc contains*[A](s: TOrderedSet[A], key: A): bool = result = index >= 0 proc rawInsert[A](s: var TOrderedSet[A], - data: var TOrderedKeyValuePairSeq[A], key: A) = + data: var OrderedKeyValuePairSeq[A], key: A) = rawInsertImpl() data[h].next = -1 if s.first < 0: s.first = h @@ -596,7 +596,7 @@ proc rawInsert[A](s: var TOrderedSet[A], s.last = h proc enlarge[A](s: var TOrderedSet[A]) = - var n: TOrderedKeyValuePairSeq[A] + var n: OrderedKeyValuePairSeq[A] newSeq(n, len(s.data) * growthFactor) var h = s.first s.first = -1 diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 320d54111..c6ac01da8 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -422,7 +422,7 @@ proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool = result = rawGet(t, key) >= 0 proc rawInsert[A, B](t: var TOrderedTable[A, B], - data: var TOrderedKeyValuePairSeq[A, B], + data: var OrderedKeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() data[h].next = -1 @@ -431,7 +431,7 @@ proc rawInsert[A, B](t: var TOrderedTable[A, B], t.last = h proc enlarge[A, B](t: var TOrderedTable[A, B]) = - var n: TOrderedKeyValuePairSeq[A, B] + var n: OrderedKeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) var h = t.first t.first = -1 diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim index 361374177..63c2599b9 100644 --- a/lib/pure/lexbase.nim +++ b/lib/pure/lexbase.nim @@ -25,8 +25,8 @@ const # type - TBaseLexer* = object of RootObj ## the base lexer. Inherit your lexer from - ## this object. + BaseLexer* = object of RootObj ## the base lexer. Inherit your lexer from + ## this object. bufpos*: int ## the current position within the buffer buf*: cstring ## the buffer itself bufLen*: int ## length of buffer in characters diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index 8712df7f6..c85c2b498 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -48,7 +48,7 @@ proc mapMem*(m: var MemFile, mode: FileMode = fmRead, if mappedSize == -1: 0 else: mappedSize, nil) if result == nil: - osError(osLastError()) + raiseOSError(osLastError()) else: assert mappedSize > 0 result = mmap( @@ -58,7 +58,7 @@ proc mapMem*(m: var MemFile, mode: FileMode = fmRead, if readonly: (MAP_PRIVATE or MAP_POPULATE) else: (MAP_SHARED or MAP_POPULATE), m.handle, offset) if result == cast[pointer](MAP_FAILED): - osError(osLastError()) + raiseOSError(osLastError()) proc unmapMem*(f: var MemFile, p: pointer, size: int) = diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 0b4cf24c5..76100deba 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -243,7 +243,7 @@ proc osErrorMsg*(errorCode: OSErrorCode): string = ## message. result = "" when defined(Windows): - if errorCode != TOSErrorCode(0'i32): + if errorCode != OSErrorCode(0'i32): when useWinUnicode: var msgbuf: WideCString if formatMessageW(0x00000100 or 0x00001000 or 0x00000200, @@ -291,7 +291,7 @@ proc osLastError*(): OSErrorCode = ## immediately after an OS call fails. On POSIX systems this is not a problem. when defined(windows): - result = TOSErrorCode(getLastError()) + result = OSErrorCode(getLastError()) else: result = OSErrorCode(errno) {.pop.} @@ -429,44 +429,44 @@ proc dirExists*(dir: string): bool {.inline.} = ## Synonym for existsDir existsDir(dir) -proc getLastModificationTime*(file: string): TTime {.rtl, extern: "nos$1".} = +proc getLastModificationTime*(file: string): Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s last modification time. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: osError(osLastError()) + if stat(file, res) < 0'i32: raiseOSError(osLastError()) return res.st_mtime else: var f: TWIN32_FIND_DATA var h = findFirstFile(file, f) - if h == -1'i32: osError(osLastError()) + if h == -1'i32: raiseOSError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime)) findClose(h) -proc getLastAccessTime*(file: string): TTime {.rtl, extern: "nos$1".} = +proc getLastAccessTime*(file: string): Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s last read or write access time. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: osError(osLastError()) + if stat(file, res) < 0'i32: raiseOSError(osLastError()) return res.st_atime else: var f: TWIN32_FIND_DATA var h = findFirstFile(file, f) - if h == -1'i32: osError(osLastError()) + if h == -1'i32: raiseOSError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime)) findClose(h) -proc getCreationTime*(file: string): TTime {.rtl, extern: "nos$1".} = +proc getCreationTime*(file: string): Time {.rtl, extern: "nos$1".} = ## Returns the `file`'s creation time. ## Note that under posix OS's, the returned time may actually be the time at ## which the file's attribute's were last modified. when defined(posix): var res: TStat - if stat(file, res) < 0'i32: osError(osLastError()) + if stat(file, res) < 0'i32: raiseOSError(osLastError()) return res.st_ctime else: var f: TWIN32_FIND_DATA var h = findFirstFile(file, f) - if h == -1'i32: osError(osLastError()) + if h == -1'i32: raiseOSError(osLastError()) result = winTimeToUnixTime(rdFileTime(f.ftCreationTime)) findClose(h) @@ -482,19 +482,19 @@ proc getCurrentDir*(): string {.rtl, extern: "nos$1", tags: [].} = when useWinUnicode: var res = newWideCString("", bufsize) var L = getCurrentDirectoryW(bufsize, res) - if L == 0'i32: osError(osLastError()) + if L == 0'i32: raiseOSError(osLastError()) result = res$L else: result = newString(bufsize) var L = getCurrentDirectoryA(bufsize, result) - if L == 0'i32: osError(osLastError()) + if L == 0'i32: raiseOSError(osLastError()) setLen(result, L) else: result = newString(bufsize) if getcwd(result, bufsize) != nil: setLen(result, c_strlen(result)) else: - osError(osLastError()) + raiseOSError(osLastError()) proc setCurrentDir*(newDir: string) {.inline, tags: [].} = ## Sets the `current working directory`:idx:; `EOS` is raised if @@ -502,11 +502,11 @@ proc setCurrentDir*(newDir: string) {.inline, tags: [].} = when defined(Windows): when useWinUnicode: if setCurrentDirectoryW(newWideCString(newDir)) == 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: - if setCurrentDirectoryA(newDir) == 0'i32: osError(osLastError()) + if setCurrentDirectoryA(newDir) == 0'i32: raiseOSError(osLastError()) else: - if chdir(newDir) != 0'i32: osError(osLastError()) + if chdir(newDir) != 0'i32: raiseOSError(osLastError()) proc joinPath*(head, tail: string): string {. noSideEffect, rtl, extern: "nos$1".} = @@ -718,19 +718,19 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1", var res = newWideCString("", bufsize div 2) var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused) if L <= 0'i32 or L >= bufsize: - osError(osLastError()) + raiseOSError(osLastError()) result = res$L else: var unused: cstring result = newString(bufsize) var L = getFullPathNameA(filename, bufsize, result, unused) - if L <= 0'i32 or L >= bufsize: osError(osLastError()) + if L <= 0'i32 or L >= bufsize: raiseOSError(osLastError()) setLen(result, L) else: # careful, realpath needs to take an allocated buffer according to Posix: result = newString(pathMax) var r = realpath(filename, result) - if r.isNil: osError(osLastError()) + if r.isNil: raiseOSError(osLastError()) setLen(result, c_strlen(result)) proc changeFileExt*(filename, ext: string): string {. @@ -820,7 +820,7 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1", var f1 = openHandle(path1) var f2 = openHandle(path2) - var lastErr: TOSErrorCode + var lastErr: OSErrorCode if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE: var fi1, fi2: TBY_HANDLE_FILE_INFORMATION @@ -839,11 +839,11 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1", discard closeHandle(f1) discard closeHandle(f2) - if not success: osError(lastErr) + if not success: raiseOSError(lastErr) else: var a, b: TStat if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: result = a.st_dev == b.st_dev and a.st_ino == b.st_ino @@ -897,7 +897,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {. ## permission is available in any case. when defined(posix): var a: TStat - if stat(filename, a) < 0'i32: osError(osLastError()) + if stat(filename, a) < 0'i32: raiseOSError(osLastError()) result = {} if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead) if (a.st_mode and S_IWUSR) != 0'i32: result.incl(fpUserWrite) @@ -915,7 +915,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {. wrapUnary(res, getFileAttributesW, filename) else: var res = getFileAttributesA(filename) - if res == -1'i32: osError(osLastError()) + if res == -1'i32: raiseOSError(osLastError()) if (res and FILE_ATTRIBUTE_READONLY) != 0'i32: result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead, fpOthersExec, fpOthersRead} @@ -941,13 +941,13 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. if fpOthersWrite in permissions: p = p or S_IWOTH if fpOthersExec in permissions: p = p or S_IXOTH - if chmod(filename, p) != 0: osError(osLastError()) + if chmod(filename, p) != 0: raiseOSError(osLastError()) else: when useWinUnicode: wrapUnary(res, getFileAttributesW, filename) else: var res = getFileAttributesA(filename) - if res == -1'i32: osError(osLastError()) + if res == -1'i32: raiseOSError(osLastError()) if fpUserWrite in permissions: res = res and not FILE_ATTRIBUTE_READONLY else: @@ -956,7 +956,7 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. wrapBinary(res2, setFileAttributesW, filename, res) else: var res2 = setFileAttributesA(filename, res) - if res2 == - 1'i32: osError(osLastError()) + if res2 == - 1'i32: raiseOSError(osLastError()) proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", tags: [ReadIOEffect, WriteIOEffect].} = @@ -974,17 +974,17 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", when useWinUnicode: let s = newWideCString(source) let d = newWideCString(dest) - if copyFileW(s, d, 0'i32) == 0'i32: osError(osLastError()) + if copyFileW(s, d, 0'i32) == 0'i32: raiseOSError(osLastError()) else: - if copyFileA(source, dest, 0'i32) == 0'i32: osError(osLastError()) + if copyFileA(source, dest, 0'i32) == 0'i32: raiseOSError(osLastError()) else: # generic version of copyFile which works for any platform: const bufSize = 8000 # better for memory manager var d, s: File - if not open(s, source): osError(osLastError()) + if not open(s, source): raiseOSError(osLastError()) if not open(d, dest, fmWrite): close(s) - osError(osLastError()) + raiseOSError(osLastError()) var buf = alloc(bufSize) while true: var bytesread = readBuffer(s, buf, bufSize) @@ -994,7 +994,7 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", dealloc(buf) close(s) close(d) - osError(osLastError()) + raiseOSError(osLastError()) if bytesread != bufSize: break dealloc(buf) close(s) @@ -1034,9 +1034,9 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} if deleteFile(f) == 0: if getLastError() == ERROR_ACCESS_DENIED: if setFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0: - osError(osLastError()) + raiseOSError(osLastError()) if deleteFile(f) == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if c_remove(file) != 0'i32 and errno != ENOENT: raise newException(OSError, $strerror(errno)) @@ -1084,7 +1084,7 @@ when defined(windows): while true: var eend = strEnd(e) add(environment, $e) - e = cast[WideCString](cast[TAddress](eend)+2) + e = cast[WideCString](cast[ByteAddress](eend)+2) if eend[1].int == 0: break discard freeEnvironmentStringsW(env) else: @@ -1095,7 +1095,7 @@ when defined(windows): while true: var eend = strEnd(e) add(environment, $e) - e = cast[cstring](cast[TAddress](eend)+1) + e = cast[cstring](cast[ByteAddress](eend)+1) if eend[1] == '\0': break discard freeEnvironmentStringsA(env) envComputed = true @@ -1174,14 +1174,14 @@ proc putEnv*(key, val: string) {.tags: [WriteEnvEffect].} = indx = high(environment) when defined(unix): if c_putenv(environment[indx]) != 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: when useWinUnicode: var k = newWideCString(key) var v = newWideCString(val) - if setEnvironmentVariableW(k, v) == 0'i32: osError(osLastError()) + if setEnvironmentVariableW(k, v) == 0'i32: raiseOSError(osLastError()) else: - if setEnvironmentVariableA(key, val) == 0'i32: osError(osLastError()) + if setEnvironmentVariableA(key, val) == 0'i32: raiseOSError(osLastError()) iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [ReadEnvEffect].} = ## Iterate over all `environments variables`:idx:. In the first component @@ -1321,9 +1321,9 @@ proc rawRemoveDir(dir: string) = let lastError = osLastError() if res == 0'i32 and lastError.int32 != 3'i32 and lastError.int32 != 18'i32 and lastError.int32 != 2'i32: - osError(lastError) + raiseOSError(lastError) else: - if rmdir(dir) != 0'i32 and errno != ENOENT: osError(osLastError()) + if rmdir(dir) != 0'i32 and errno != ENOENT: raiseOSError(osLastError()) proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [ WriteDirEffect, ReadDirEffect].} = @@ -1341,17 +1341,17 @@ proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [ proc rawCreateDir(dir: string) = when defined(solaris): if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST and errno != ENOSYS: - osError(osLastError()) + raiseOSError(osLastError()) elif defined(unix): if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST: - osError(osLastError()) + raiseOSError(osLastError()) else: when useWinUnicode: wrapUnary(res, createDirectoryW, dir) else: var res = createDirectoryA(dir) if res == 0'i32 and getLastError() != 183'i32: - osError(osLastError()) + raiseOSError(osLastError()) proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].} = ## Creates the `directory`:idx: `dir`. @@ -1403,13 +1403,13 @@ proc createSymlink*(src, dest: string) = var wSrc = newWideCString(src) var wDst = newWideCString(dest) if createSymbolicLinkW(wDst, wSrc, flag) == 0 or getLastError() != 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if createSymbolicLinkA(dest, src, flag) == 0 or getLastError() != 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if symlink(src, dest) != 0: - osError(osLastError()) + raiseOSError(osLastError()) proc createHardlink*(src, dest: string) = ## Create a hard link at `dest` which points to the item specified @@ -1422,13 +1422,13 @@ proc createHardlink*(src, dest: string) = var wSrc = newWideCString(src) var wDst = newWideCString(dest) if createHardLinkW(wDst, wSrc, nil) == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if createHardLinkA(dest, src, nil) == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: if link(src, dest) != 0: - osError(osLastError()) + raiseOSError(osLastError()) proc parseCmdLine*(c: string): seq[string] {. noSideEffect, rtl, extern: "nos$1".} = @@ -1824,7 +1824,7 @@ proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1", when defined(windows): var a: TWIN32_FIND_DATA var resA = findFirstFile(file, a) - if resA == -1: osError(osLastError()) + if resA == -1: raiseOSError(osLastError()) result = rdFileSize(a) findClose(resA) else: @@ -1832,7 +1832,7 @@ proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1", if open(f, file): result = getFileSize(f) close(f) - else: osError(osLastError()) + else: raiseOSError(osLastError()) proc findExe*(exe: string): string {.tags: [ReadDirEffect, ReadEnvEffect].} = ## Searches for `exe` in the current working directory and then @@ -1884,9 +1884,9 @@ type size*: BiggestInt # Size of file. permissions*: set[TFilePermission] # File permissions linkCount*: BiggestInt # Number of hard links the file object has. - lastAccessTime*: TTime # Time file was last accessed. - lastWriteTime*: TTime # Time file was last modified/written to. - creationTime*: TTime # Time file was created. Not supported on all systems! + lastAccessTime*: Time # Time file was last accessed. + lastWriteTime*: Time # Time file was last modified/written to. + creationTime*: Time # Time file was created. Not supported on all systems! template rawToFormalFileInfo(rawInfo, formalInfo): expr = ## Transforms the native file info structure into the one nimrod uses. @@ -1959,12 +1959,12 @@ proc getFileInfo*(handle: FileHandle): FileInfo = # To transform the C file descripter to a native file handle. var realHandle = get_osfhandle(handle) if getFileInformationByHandle(realHandle, addr rawInfo) == 0: - osError(osLastError()) + raiseOSError(osLastError()) rawToFormalFileInfo(rawInfo, result) else: var rawInfo: TStat if fstat(handle, rawInfo) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) rawToFormalFileInfo(rawInfo, result) proc getFileInfo*(file: File): FileInfo = @@ -1989,19 +1989,19 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo = handle = openHandle(path, followSymlink) rawInfo: TBY_HANDLE_FILE_INFORMATION if handle == INVALID_HANDLE_VALUE: - osError(osLastError()) + raiseOSError(osLastError()) if getFileInformationByHandle(handle, addr rawInfo) == 0: - osError(osLastError()) + raiseOSError(osLastError()) rawToFormalFileInfo(rawInfo, result) discard closeHandle(handle) else: var rawInfo: TStat if followSymlink: if lstat(path, rawInfo) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: if stat(path, rawInfo) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) rawToFormalFileInfo(rawInfo, result) proc isHidden*(path: string): bool = diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 25782d4f5..957a91d06 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -334,7 +334,7 @@ when defined(Windows) and not defined(useNimRtl): # TRUE and zero bytes returned (EOF). # TRUE and n (>0) bytes returned (good data). # FALSE and bytes returned undefined (system error). - if a == 0 and br != 0: osError(osLastError()) + if a == 0 and br != 0: raiseOSError(osLastError()) s.atTheEnd = br < bufLen result = br @@ -342,7 +342,7 @@ when defined(Windows) and not defined(useNimRtl): var s = PFileHandleStream(s) var bytesWritten: int32 var a = winlean.writeFile(s.handle, buffer, bufLen.cint, bytesWritten, nil) - if a == 0: osError(osLastError()) + if a == 0: raiseOSError(osLastError()) proc newFileHandleStream(handle: THandle): PFileHandleStream = new(result) @@ -383,7 +383,7 @@ when defined(Windows) and not defined(useNimRtl): piInheritablePipe.lpSecurityDescriptor = nil piInheritablePipe.bInheritHandle = 1 if createPipe(rdHandle, wrHandle, piInheritablePipe, 1024) == 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) proc fileClose(h: THandle) {.inline.} = if h > 4: discard closeHandle(h) @@ -450,7 +450,7 @@ when defined(Windows) and not defined(useNimRtl): fileClose(si.hStdError) if e != nil: dealloc(e) - if success == 0: osError(lastError) + if success == 0: raiseOSError(lastError) # Close the handle now so anyone waiting is woken: discard closeHandle(procInfo.hThread) result.fProcessHandle = procInfo.hProcess @@ -521,7 +521,7 @@ when defined(Windows) and not defined(useNimRtl): var res = winlean.createProcessA(nil, command, nil, nil, 0, NORMAL_PRIORITY_CLASS, nil, nil, si, procInfo) if res == 0: - osError(osLastError()) + raiseOSError(osLastError()) else: process = procInfo.hProcess discard closeHandle(procInfo.hThread) @@ -544,7 +544,7 @@ when defined(Windows) and not defined(useNimRtl): of WAIT_TIMEOUT: return 0 of WAIT_FAILED: - osError(osLastError()) + raiseOSError(osLastError()) else: var i = ret - WAIT_OBJECT_0 readfds.del(i) @@ -607,7 +607,7 @@ elif not defined(useNimRtl): if poParentStreams notin options: if pipe(pStdin) != 0'i32 or pipe(pStdout) != 0'i32 or pipe(pStderr) != 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) var sysCommand: string var sysArgsRaw: seq[string] @@ -683,7 +683,7 @@ elif not defined(useNimRtl): var fops: Tposix_spawn_file_actions template chck(e: expr) = - if e != 0'i32: osError(osLastError()) + if e != 0'i32: raiseOSError(osLastError()) chck posix_spawn_file_actions_init(fops) chck posix_spawnattr_init(attr) @@ -726,7 +726,7 @@ elif not defined(useNimRtl): proc startProcessAuxFork(data: TStartProcessData): TPid = if pipe(data.pErrorPipe) != 0: - osError(osLastError()) + raiseOSError(osLastError()) finally: discard close(data.pErrorPipe[readIdx]) @@ -751,12 +751,12 @@ elif not defined(useNimRtl): exitnow(1) discard close(data.pErrorPipe[writeIdx]) - if pid < 0: osError(osLastError()) + if pid < 0: raiseOSError(osLastError()) var error: cint let sizeRead = read(data.pErrorPipe[readIdx], addr error, sizeof(error)) if sizeRead == sizeof(error): - osError($strerror(error)) + raiseOSError($strerror(error)) return pid @@ -818,10 +818,10 @@ elif not defined(useNimRtl): discard close(p.errHandle) proc suspend(p: PProcess) = - if kill(-p.id, SIGSTOP) != 0'i32: osError(osLastError()) + if kill(-p.id, SIGSTOP) != 0'i32: raiseOSError(osLastError()) proc resume(p: PProcess) = - if kill(-p.id, SIGCONT) != 0'i32: osError(osLastError()) + if kill(-p.id, SIGCONT) != 0'i32: raiseOSError(osLastError()) proc running(p: PProcess): bool = var ret = waitpid(p.id, p.exitCode, WNOHANG) @@ -831,8 +831,8 @@ elif not defined(useNimRtl): proc terminate(p: PProcess) = if kill(-p.id, SIGTERM) == 0'i32: if p.running(): - if kill(-p.id, SIGKILL) != 0'i32: osError(osLastError()) - else: osError(osLastError()) + if kill(-p.id, SIGKILL) != 0'i32: raiseOSError(osLastError()) + else: raiseOSError(osLastError()) proc waitForExit(p: PProcess, timeout: int = -1): int = #if waitPid(p.id, p.exitCode, 0) == int(p.id): @@ -842,7 +842,7 @@ elif not defined(useNimRtl): if p.exitCode != -3: return p.exitCode if waitpid(p.id, p.exitCode, 0) < 0: p.exitCode = -3 - osError(osLastError()) + raiseOSError(osLastError()) result = int(p.exitCode) shr 8 proc peekExitCode(p: PProcess): int = @@ -856,7 +856,7 @@ elif not defined(useNimRtl): proc createStream(stream: var PStream, handle: var FileHandle, fileMode: FileMode) = var f: File - if not open(f, handle, fileMode): osError(osLastError()) + if not open(f, handle, fileMode): raiseOSError(osLastError()) stream = newFileStream(f) proc inputStream(p: PProcess): PStream = diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 71d16192f..e016fc6ad 100644 --- a/lib/pure/strtabs.nim +++ b/lib/pure/strtabs.nim @@ -121,7 +121,7 @@ proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) = +proc rawInsert(t: PStringTable, data: var KeyValuePairSeq, key, val: string) = var h: THash = myhash(t, key) and high(data) while not isNil(data[h].key): h = nextTry(h, high(data)) @@ -129,7 +129,7 @@ proc rawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) = data[h].val = val proc enlarge(t: PStringTable) = - var n: TKeyValuePairSeq + var n: KeyValuePairSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if not isNil(t.data[i].key): rawInsert(t, n, t.data[i].key, t.data[i].val) @@ -182,7 +182,7 @@ proc newStringTable*(keyValuePairs: varargs[string], inc(i, 2) proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]], - mode: TStringTableMode = modeCaseSensitive): PStringTable {. + mode: StringTableMode = modeCaseSensitive): PStringTable {. rtl, extern: "nst$1WithTableConstr".} = ## creates a new string table with given key value pairs. ## Example:: diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 82516653c..2af973b6e 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -766,7 +766,7 @@ proc find*(s, sub: string, start: int = 0): int {.noSideEffect, ## Searches for `sub` in `s` starting at position `start`. ## ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. - var a {.noinit.}: TSkipTable + var a {.noinit.}: SkipTable preprocessSub(sub, a) result = findAux(s, sub, start, a) @@ -1158,7 +1158,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, ## after the decimal point for Nimrod's ``biggestFloat`` type. ## ## If ``precision == 0``, it tries to format it nicely. - const floatFormatToChar: array[TFloatFormat, char] = ['g', 'f', 'e'] + const floatFormatToChar: array[FloatFormatMode, char] = ['g', 'f', 'e'] var frmtstr {.noinit.}: array[0..5, char] buf {.noinit.}: array[0..2500, char] diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 2c09fcc4c..5d92218b3 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -136,7 +136,7 @@ type months*: int ## The number of months years*: int ## The number of years -{.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time, TTimeval: Timeval, +{.deprecated: [TMonth: Month, TWeekDay: WeekDay, TTime: Time, TTimeInterval: TimeInterval, TTimeInfo: TimeInfo].} proc getTime*(): Time {.tags: [TimeEffect], gcsafe.} @@ -228,7 +228,7 @@ proc isLeapYear*(year: int): bool = else: return false -proc getDaysInMonth*(month: TMonth, year: int): int = +proc getDaysInMonth*(month: Month, year: int): int = ## gets the amount of days in a ``month`` of a ``year`` # http://www.dispersiondesign.com/articles/time/number_of_days_in_a_month @@ -350,7 +350,7 @@ when not defined(JS): minute: int(tm.minute), hour: int(tm.hour), monthday: int(tm.monthday), - month: TMonth(tm.month), + month: Month(tm.month), year: tm.year + 1900'i32, weekday: weekDays[int(tm.weekday)], yearday: int(tm.yearday), @@ -455,7 +455,7 @@ when not defined(JS): when not defined(useNimRtl): proc epochTime(): float = when defined(posix): - var a: Ttimeval + var a: Timeval posix_gettimeofday(a) result = toFloat(a.tv_sec) + toFloat(a.tv_usec)*0.00_0001 elif defined(windows): diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 293551bc9..55ae87a1f 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -363,7 +363,9 @@ const proc wsaGetLastError*(): cint {.importc: "WSAGetLastError", dynlib: ws2dll.} type - TSocketHandle* = distinct int + SocketHandle* = distinct int + +{.deprecated: [TSocketHandle: SocketHandle].} type TWSAData* {.pure, final, importc: "WSADATA", header: "Winsock2.h".} = object From 27869b6c7b07e6b42dd1ccef9e37145e200bd39f Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 00:36:14 +0200 Subject: [PATCH 013/409] big rename --- lib/pure/algorithm.nim | 6 +- lib/pure/asyncdispatch.nim | 158 +++++++++++------------ lib/pure/collections/sets.nim | 96 +++++++------- lib/pure/collections/tables.nim | 216 ++++++++++++++++---------------- lib/pure/net.nim | 202 ++++++++++++++--------------- lib/pure/rawsockets.nim | 36 +++--- lib/windows/winlean.nim | 46 +++---- 7 files changed, 380 insertions(+), 380 deletions(-) diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index b27ccb93c..dd9131c05 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -16,7 +16,7 @@ type {.deprecated: [TSortOrder: SortOrder].} -proc `*`*(x: int, order: TSortOrder): int {.inline.} = +proc `*`*(x: int, order: SortOrder): int {.inline.} = ## flips `x` if ``order == Descending``; ## if ``order == Ascending`` then `x` is returned. ## `x` is supposed to be the result of a comparator, ie ``< 0`` for @@ -103,7 +103,7 @@ proc lowerBound*[T](a: openArray[T], key: T, cmp: proc(x,y: T): int {.closure.}) proc lowerBound*[T](a: openArray[T], key: T): int = lowerBound(a, key, cmp[T]) proc merge[T](a, b: var openArray[T], lo, m, hi: int, - cmp: proc (x, y: T): int {.closure.}, order: TSortOrder) = + cmp: proc (x, y: T): int {.closure.}, order: SortOrder) = template `<-` (a, b: expr) = when false: a = b @@ -150,7 +150,7 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int, proc sort*[T](a: var openArray[T], cmp: proc (x, y: T): int {.closure.}, - order = TSortOrder.Ascending) = + order = SortOrder.Ascending) = ## Default Nimrod sort. The sorting is guaranteed to be stable and ## the worst case is guaranteed to be O(n log n). ## The current implementation uses an iterative diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 194c6ee1b..f3875dfa6 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -156,12 +156,12 @@ proc read*[T](future: Future[T]): T = return future.value else: # TODO: Make a custom exception type for this? - raise newException(EInvalidValue, "Future still in progress.") + raise newException(ValueError, "Future still in progress.") -proc readError*[T](future: Future[T]): ref EBase = +proc readError*[T](future: Future[T]): ref Exception = if future.error != nil: return future.error else: - raise newException(EInvalidValue, "No error in future.") + raise newException(ValueError, "No error in future.") proc finished*[T](future: Future[T]): bool = ## Determines whether ``future`` has completed. @@ -206,7 +206,7 @@ proc `or`*[T, Y](fut1: Future[T], fut2: Future[Y]): Future[void] = fut2.callback = cb type - PDispatcherBase = ref object of PObject + PDispatcherBase = ref object of RootRef timers: seq[tuple[finishAt: float, fut: Future[void]]] proc processTimers(p: PDispatcherBase) = @@ -226,11 +226,11 @@ when defined(windows) or defined(nimdoc): TCompletionData* = object sock: TAsyncFD cb: proc (sock: TAsyncFD, bytesTransferred: DWORD, - errcode: TOSErrorCode) {.closure,gcsafe.} + errcode: OSErrorCode) {.closure,gcsafe.} PDispatcher* = ref object of PDispatcherBase ioPort: THandle - handles: TSet[TAsyncFD] + handles: HashSet[TAsyncFD] TCustomOverlapped = object of TOVERLAPPED data*: TCompletionData @@ -245,7 +245,7 @@ when defined(windows) or defined(nimdoc): proc newDispatcher*(): PDispatcher = ## Creates a new Dispatcher instance. new result - result.ioPort = CreateIOCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1) + result.ioPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1) result.handles = initSet[TAsyncFD]() result.timers = @[] @@ -258,16 +258,16 @@ when defined(windows) or defined(nimdoc): proc register*(sock: TAsyncFD) = ## Registers ``sock`` with the dispatcher. let p = getGlobalDispatcher() - if CreateIOCompletionPort(sock.THandle, p.ioPort, + if CreateIoCompletionPort(sock.THandle, p.ioPort, cast[TCompletionKey](sock), 1) == 0: - osError(osLastError()) + raiseOSError(osLastError()) p.handles.incl(sock) proc verifyPresence(sock: TAsyncFD) = ## Ensures that socket has been registered with the dispatcher. let p = getGlobalDispatcher() if sock notin p.handles: - raise newException(EInvalidValue, + raise newException(ValueError, "Operation performed on a socket which has not been registered with" & " the dispatcher yet.") @@ -275,7 +275,7 @@ when defined(windows) or defined(nimdoc): ## Waits for completion events and processes them. let p = getGlobalDispatcher() if p.handles.len == 0 and p.timers.len == 0: - raise newException(EInvalidValue, + raise newException(ValueError, "No handles or timers registered in dispatcher.") let llTimeout = @@ -286,7 +286,7 @@ when defined(windows) or defined(nimdoc): var customOverlapped: PCustomOverlapped let res = GetQueuedCompletionStatus(p.ioPort, addr lpNumberOfBytesTransferred, addr lpCompletionKey, - cast[ptr POverlapped](addr customOverlapped), llTimeout).bool + cast[ptr POVERLAPPED](addr customOverlapped), llTimeout).bool # http://stackoverflow.com/a/12277264/492186 # TODO: http://www.serverframework.com/handling-multiple-pending-socket-read-and-write-operations.html @@ -295,7 +295,7 @@ when defined(windows) or defined(nimdoc): assert customOverlapped.data.sock == lpCompletionKey.TAsyncFD customOverlapped.data.cb(customOverlapped.data.sock, - lpNumberOfBytesTransferred, TOSErrorCode(-1)) + lpNumberOfBytesTransferred, OSErrorCode(-1)) GC_unref(customOverlapped) else: let errCode = osLastError() @@ -308,7 +308,7 @@ when defined(windows) or defined(nimdoc): if errCode.int32 == WAIT_TIMEOUT: # Timed out discard - else: osError(errCode) + else: raiseOSError(errCode) # Timer processing. processTimers(p) @@ -317,9 +317,9 @@ when defined(windows) or defined(nimdoc): var acceptExPtr: pointer = nil var getAcceptExSockAddrsPtr: pointer = nil - proc initPointer(s: TSocketHandle, func: var pointer, guid: var TGUID): bool = + proc initPointer(s: SocketHandle, func: var pointer, guid: var TGUID): bool = # Ref: https://github.com/powdahound/twisted/blob/master/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c - var bytesRet: DWord + var bytesRet: DWORD func = nil result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, addr guid, sizeof(TGUID).dword, addr func, sizeof(pointer).DWORD, @@ -328,34 +328,34 @@ when defined(windows) or defined(nimdoc): proc initAll() = let dummySock = newRawSocket() if not initPointer(dummySock, connectExPtr, WSAID_CONNECTEX): - osError(osLastError()) + raiseOSError(osLastError()) if not initPointer(dummySock, acceptExPtr, WSAID_ACCEPTEX): - osError(osLastError()) + raiseOSError(osLastError()) if not initPointer(dummySock, getAcceptExSockAddrsPtr, WSAID_GETACCEPTEXSOCKADDRS): - osError(osLastError()) + raiseOSError(osLastError()) - proc connectEx(s: TSocketHandle, name: ptr TSockAddr, namelen: cint, + proc connectEx(s: SocketHandle, name: ptr TSockAddr, namelen: cint, lpSendBuffer: pointer, dwSendDataLength: dword, - lpdwBytesSent: PDWORD, lpOverlapped: POverlapped): bool = - if connectExPtr.isNil: raise newException(EInvalidValue, "Need to initialise ConnectEx().") + lpdwBytesSent: PDWORD, lpOverlapped: POVERLAPPED): bool = + if connectExPtr.isNil: raise newException(ValueError, "Need to initialise ConnectEx().") let func = - cast[proc (s: TSocketHandle, name: ptr TSockAddr, namelen: cint, + cast[proc (s: SocketHandle, name: ptr TSockAddr, namelen: cint, lpSendBuffer: pointer, dwSendDataLength: dword, - lpdwBytesSent: PDWORD, lpOverlapped: POverlapped): bool {.stdcall,gcsafe.}](connectExPtr) + lpdwBytesSent: PDWORD, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](connectExPtr) result = func(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped) - proc acceptEx(listenSock, acceptSock: TSocketHandle, lpOutputBuffer: pointer, + proc acceptEx(listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: DWORD, lpdwBytesReceived: PDWORD, - lpOverlapped: POverlapped): bool = - if acceptExPtr.isNil: raise newException(EInvalidValue, "Need to initialise AcceptEx().") + lpOverlapped: POVERLAPPED): bool = + if acceptExPtr.isNil: raise newException(ValueError, "Need to initialise AcceptEx().") let func = - cast[proc (listenSock, acceptSock: TSocketHandle, lpOutputBuffer: pointer, + cast[proc (listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: DWORD, lpdwBytesReceived: PDWORD, - lpOverlapped: POverlapped): bool {.stdcall,gcsafe.}](acceptExPtr) + lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](acceptExPtr) result = func(listenSock, acceptSock, lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived, lpOverlapped) @@ -365,7 +365,7 @@ when defined(windows) or defined(nimdoc): LocalSockaddr: ptr ptr TSockAddr, LocalSockaddrLength: lpint, RemoteSockaddr: ptr ptr TSockAddr, RemoteSockaddrLength: lpint) = if getAcceptExSockAddrsPtr.isNil: - raise newException(EInvalidValue, "Need to initialise getAcceptExSockAddrs().") + raise newException(ValueError, "Need to initialise getAcceptExSockAddrs().") let func = cast[proc (lpOutputBuffer: pointer, @@ -378,7 +378,7 @@ when defined(windows) or defined(nimdoc): dwRemoteAddressLength, LocalSockaddr, LocalSockaddrLength, RemoteSockaddr, RemoteSockaddrLength) - proc connect*(socket: TAsyncFD, address: string, port: TPort, + proc connect*(socket: TAsyncFD, address: string, port: Port, af = AF_INET): Future[void] = ## Connects ``socket`` to server at ``address:port``. ## @@ -391,13 +391,13 @@ when defined(windows) or defined(nimdoc): saddr.sin_family = int16(toInt(af)) saddr.sin_port = 0 saddr.sin_addr.s_addr = INADDR_ANY - if bindAddr(socket.TSocketHandle, cast[ptr TSockAddr](addr(saddr)), + if bindAddr(socket.SocketHandle, cast[ptr TSockAddr](addr(saddr)), sizeof(saddr).TSockLen) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) var aiList = getAddrInfo(address, port, af) var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: # "the OVERLAPPED structure must remain valid until the I/O completes" @@ -405,17 +405,17 @@ when defined(windows) or defined(nimdoc): var ol = PCustomOverlapped() GC_ref(ol) ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) = + proc (sock: TAsyncFD, bytesCount: DWORD, errcode: OSErrorCode) = if not retFuture.finished: - if errcode == TOSErrorCode(-1): + if errcode == OSErrorCode(-1): retFuture.complete() else: - retFuture.fail(newException(EOS, osErrorMsg(errcode))) + retFuture.fail(newException(OSError, osErrorMsg(errcode))) ) - var ret = connectEx(socket.TSocketHandle, it.ai_addr, - sizeof(TSockAddrIn).cint, nil, 0, nil, - cast[POverlapped](ol)) + var ret = connectEx(socket.SocketHandle, it.ai_addr, + sizeof(Tsockaddr_in).cint, nil, 0, nil, + cast[POVERLAPPED](ol)) if ret: # Request to connect completed immediately. success = true @@ -437,11 +437,11 @@ when defined(windows) or defined(nimdoc): dealloc(aiList) if not success: - retFuture.fail(newException(EOS, osErrorMsg(lastError))) + retFuture.fail(newException(OSError, osErrorMsg(lastError))) return retFuture proc recv*(socket: TAsyncFD, size: int, - flags = {TSocketFlags.SafeDisconn}): Future[string] = + flags = {SocketFlag.SafeDisconn}): Future[string] = ## Reads **up to** ``size`` bytes from ``socket``. Returned future will ## complete once all the data requested is read, a part of the data has been ## read, or the socket has disconnected in which case the future will @@ -460,14 +460,14 @@ when defined(windows) or defined(nimdoc): dataBuf.buf = cast[cstring](alloc0(size)) dataBuf.len = size - var bytesReceived: DWord - var flagsio = flags.toOSFlags().DWord + var bytesReceived: DWORD + var flagsio = flags.toOSFlags().DWORD var ol = PCustomOverlapped() GC_ref(ol) ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) = + proc (sock: TAsyncFD, bytesCount: DWORD, errcode: OSErrorCode) = if not retFuture.finished: - if errcode == TOSErrorCode(-1): + if errcode == OSErrorCode(-1): if bytesCount == 0 and dataBuf.buf[0] == '\0': retFuture.complete("") else: @@ -479,14 +479,14 @@ when defined(windows) or defined(nimdoc): if flags.isDisconnectionError(errcode): retFuture.complete("") else: - retFuture.fail(newException(EOS, osErrorMsg(errcode))) + retFuture.fail(newException(OSError, osErrorMsg(errcode))) if dataBuf.buf != nil: dealloc dataBuf.buf dataBuf.buf = nil ) - let ret = WSARecv(socket.TSocketHandle, addr dataBuf, 1, addr bytesReceived, - addr flagsio, cast[POverlapped](ol), nil) + let ret = WSARecv(socket.SocketHandle, addr dataBuf, 1, addr bytesReceived, + addr flagsio, cast[POVERLAPPED](ol), nil) if ret == -1: let err = osLastError() if err.int32 != ERROR_IO_PENDING: @@ -497,7 +497,7 @@ when defined(windows) or defined(nimdoc): if flags.isDisconnectionError(err): retFuture.complete("") else: - retFuture.fail(newException(EOS, osErrorMsg(err))) + retFuture.fail(newException(OSError, osErrorMsg(err))) elif ret == 0 and bytesReceived == 0 and dataBuf.buf[0] == '\0': # We have to ensure that the buffer is empty because WSARecv will tell # us immediatelly when it was disconnected, even when there is still @@ -529,7 +529,7 @@ when defined(windows) or defined(nimdoc): return retFuture proc send*(socket: TAsyncFD, data: string, - flags = {TSocketFlags.SafeDisconn}): Future[void] = + flags = {SocketFlag.SafeDisconn}): Future[void] = ## Sends ``data`` to ``socket``. The returned future will complete once all ## data has been sent. verifyPresence(socket) @@ -539,23 +539,23 @@ when defined(windows) or defined(nimdoc): dataBuf.buf = data # since this is not used in a callback, this is fine dataBuf.len = data.len - var bytesReceived, lowFlags: DWord + var bytesReceived, lowFlags: DWORD var ol = PCustomOverlapped() GC_ref(ol) ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) = + proc (sock: TAsyncFD, bytesCount: DWORD, errcode: OSErrorCode) = if not retFuture.finished: - if errcode == TOSErrorCode(-1): + if errcode == OSErrorCode(-1): retFuture.complete() else: if flags.isDisconnectionError(errcode): retFuture.complete() else: - retFuture.fail(newException(EOS, osErrorMsg(errcode))) + retFuture.fail(newException(OSError, osErrorMsg(errcode))) ) - let ret = WSASend(socket.TSocketHandle, addr dataBuf, 1, addr bytesReceived, - lowFlags, cast[POverlapped](ol), nil) + let ret = WSASend(socket.SocketHandle, addr dataBuf, 1, addr bytesReceived, + lowFlags, cast[POVERLAPPED](ol), nil) if ret == -1: let err = osLastError() if err.int32 != ERROR_IO_PENDING: @@ -563,7 +563,7 @@ when defined(windows) or defined(nimdoc): if flags.isDisconnectionError(err): retFuture.complete() else: - retFuture.fail(newException(EOS, osErrorMsg(err))) + retFuture.fail(newException(OSError, osErrorMsg(err))) else: retFuture.complete() # We don't deallocate ``ol`` here because even though this completed @@ -571,7 +571,7 @@ when defined(windows) or defined(nimdoc): # free ``ol``. return retFuture - proc acceptAddr*(socket: TAsyncFD, flags = {TSocketFlags.SafeDisconn}): + proc acceptAddr*(socket: TAsyncFD, flags = {SocketFlag.SafeDisconn}): Future[tuple[address: string, client: TAsyncFD]] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection and the remote address of the client. @@ -588,21 +588,21 @@ when defined(windows) or defined(nimdoc): var retFuture = newFuture[tuple[address: string, client: TAsyncFD]]("acceptAddr") var clientSock = newRawSocket() - if clientSock == osInvalidSocket: osError(osLastError()) + if clientSock == osInvalidSocket: raiseOSError(osLastError()) const lpOutputLen = 1024 var lpOutputBuf = newString(lpOutputLen) var dwBytesReceived: DWORD let dwReceiveDataLength = 0.DWORD # We don't want any data to be read. - let dwLocalAddressLength = DWORD(sizeof (TSockaddr_in) + 16) - let dwRemoteAddressLength = DWORD(sizeof(TSockaddr_in) + 16) + let dwLocalAddressLength = DWORD(sizeof (Tsockaddr_in) + 16) + let dwRemoteAddressLength = DWORD(sizeof(Tsockaddr_in) + 16) template completeAccept(): stmt {.immediate, dirty.} = var listenSock = socket let setoptRet = setsockopt(clientSock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, addr listenSock, sizeof(listenSock).TSockLen) - if setoptRet != 0: osError(osLastError()) + if setoptRet != 0: raiseOSError(osLastError()) var LocalSockaddr, RemoteSockaddr: ptr TSockAddr var localLen, remoteLen: int32 @@ -627,25 +627,25 @@ when defined(windows) or defined(nimdoc): else: retFuture.complete(newAcceptFut.read) else: - retFuture.fail(newException(EOS, osErrorMsg(errcode))) + retFuture.fail(newException(OSError, osErrorMsg(errcode))) var ol = PCustomOverlapped() GC_ref(ol) ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) = + proc (sock: TAsyncFD, bytesCount: DWORD, errcode: OSErrorCode) = if not retFuture.finished: - if errcode == TOSErrorCode(-1): + if errcode == OSErrorCode(-1): completeAccept() else: failAccept(errcode) ) # http://msdn.microsoft.com/en-us/library/windows/desktop/ms737524%28v=vs.85%29.aspx - let ret = acceptEx(socket.TSocketHandle, clientSock, addr lpOutputBuf[0], + let ret = acceptEx(socket.SocketHandle, clientSock, addr lpOutputBuf[0], dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, - addr dwBytesReceived, cast[POverlapped](ol)) + addr dwBytesReceived, cast[POVERLAPPED](ol)) if not ret: let err = osLastError() @@ -660,17 +660,17 @@ when defined(windows) or defined(nimdoc): return retFuture - proc newAsyncRawSocket*(domain: TDomain = AF_INET, - typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP): TAsyncFD = + proc newAsyncRawSocket*(domain: Domain = AF_INET, + typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP): TAsyncFD = ## Creates a new socket and registers it with the dispatcher implicitly. result = newRawSocket(domain, typ, protocol).TAsyncFD - result.TSocketHandle.setBlocking(false) + result.SocketHandle.setBlocking(false) register(result) proc closeSocket*(socket: TAsyncFD) = ## Closes a socket and ensures that it is unregistered. - socket.TSocketHandle.close() + socket.SocketHandle.close() getGlobalDispatcher().handles.excl(socket) proc unregister*(fd: TAsyncFD) = @@ -925,7 +925,7 @@ proc sleepAsync*(ms: int): Future[void] = return retFuture proc accept*(socket: TAsyncFD, - flags = {TSocketFlags.SafeDisconn}): Future[TAsyncFD] = + flags = {SocketFlag.SafeDisconn}): Future[TAsyncFD] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection. ## The future will complete when the connection is successfully accepted. @@ -1010,14 +1010,14 @@ proc processBody(node, retFutureSym: PNimrodNode, of nnkReturnStmt: result = newNimNode(nnkStmtList, node) if node[0].kind == nnkEmpty: - if not subtypeIsVoid: + if not subTypeIsVoid: result.add newCall(newIdentNode("complete"), retFutureSym, newIdentNode("result")) else: result.add newCall(newIdentNode("complete"), retFutureSym) else: result.add newCall(newIdentNode("complete"), retFutureSym, - node[0].processBody(retFutureSym, subtypeIsVoid, exceptBranch)) + node[0].processBody(retFutureSym, subTypeIsVoid, exceptBranch)) result.add newNimNode(nnkReturnStmt, node).add(newNilLit()) return # Don't process the children of this return stmt @@ -1072,7 +1072,7 @@ proc processBody(node, retFutureSym: PNimrodNode, res: PNimrodNode): bool {.compileTime.} = result = false while i < n[0].len: - var processed = processBody(n[0][i], retFutureSym, subtypeIsVoid, n[1]) + var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n[1]) if processed.kind != n[0][i].kind or processed.len != n[0][i].len: expectKind(processed, nnkStmtList) expectKind(processed[2][1], nnkElse) @@ -1092,7 +1092,7 @@ proc processBody(node, retFutureSym: PNimrodNode, else: discard for i in 0 .. 0 and c == "\L": discard await recv(socket, 1) addNLIfEmpty() diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 27f5ef07a..994023b3f 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -37,7 +37,7 @@ type {.deprecated: [TSet: HashSet].} -proc isValid*[A](s: TSet[A]): bool = +proc isValid*[A](s: HashSet[A]): bool = ## Returns `true` if the set has been initialized with `initSet <#initSet>`_. ## ## Most operations over an uninitialized set will crash at runtime and @@ -51,7 +51,7 @@ proc isValid*[A](s: TSet[A]): bool = ## # Do stuff here, may crash in release builds! result = not s.data.isNil -proc len*[A](s: TSet[A]): int = +proc len*[A](s: HashSet[A]): int = ## Returns the number of keys in `s`. ## ## Due to an implementation detail you can call this proc on variables which @@ -65,14 +65,14 @@ proc len*[A](s: TSet[A]): int = ## assert values.len == 0 result = s.counter -proc card*[A](s: TSet[A]): int = +proc card*[A](s: HashSet[A]): int = ## Alias for `len() <#len,TSet[A]>`_. ## ## Card stands for the `cardinality ## `_ of a set. result = s.counter -iterator items*[A](s: TSet[A]): A = +iterator items*[A](s: HashSet[A]): A = ## Iterates over keys in the set `s`. ## ## If you need a sequence with the keys you can use `sequtils.toSeq() @@ -120,10 +120,10 @@ template rawInsertImpl() {.dirty.} = data[h].key = key data[h].slot = seFilled -proc rawGet[A](s: TSet[A], key: A): int = +proc rawGet[A](s: HashSet[A], key: A): int = rawGetImpl() -proc mget*[A](s: var TSet[A], key: A): var A = +proc mget*[A](s: var HashSet[A], key: A): var A = ## returns the element that is actually stored in 's' which has the same ## value as 'key' or raises the ``EInvalidKey`` exception. This is useful ## when one overloaded 'hash' and '==' but still needs reference semantics @@ -133,7 +133,7 @@ proc mget*[A](s: var TSet[A], key: A): var A = if index >= 0: result = t.data[index].key else: raise newException(KeyError, "key not found: " & $key) -proc contains*[A](s: TSet[A], key: A): bool = +proc contains*[A](s: HashSet[A], key: A): bool = ## Returns true iff `key` is in `s`. ## ## Example: @@ -149,10 +149,10 @@ proc contains*[A](s: TSet[A], key: A): bool = var index = rawGet(s, key) result = index >= 0 -proc rawInsert[A](s: var TSet[A], data: var KeyValuePairSeq[A], key: A) = +proc rawInsert[A](s: var HashSet[A], data: var KeyValuePairSeq[A], key: A) = rawInsertImpl() -proc enlarge[A](s: var TSet[A]) = +proc enlarge[A](s: var HashSet[A]) = var n: KeyValuePairSeq[A] newSeq(n, len(s.data) * growthFactor) for i in countup(0, high(s.data)): @@ -175,7 +175,7 @@ template containsOrInclImpl() {.dirty.} = rawInsert(s, s.data, key) inc(s.counter) -proc incl*[A](s: var TSet[A], key: A) = +proc incl*[A](s: var HashSet[A], key: A) = ## Includes an element `key` in `s`. ## ## This doesn't do anything if `key` is already in `s`. Example: @@ -188,7 +188,7 @@ proc incl*[A](s: var TSet[A], key: A) = assert s.isValid, "The set needs to be initialized." inclImpl() -proc incl*[A](s: var TSet[A], other: TSet[A]) = +proc incl*[A](s: var HashSet[A], other: TSet[A]) = ## Includes all elements from `other` into `s`. ## ## Example: @@ -203,7 +203,7 @@ proc incl*[A](s: var TSet[A], other: TSet[A]) = assert other.isValid, "The set `other` needs to be initialized." for item in other: incl(s, item) -proc excl*[A](s: var TSet[A], key: A) = +proc excl*[A](s: var HashSet[A], key: A) = ## Excludes `key` from the set `s`. ## ## This doesn't do anything if `key` is not found in `s`. Example: @@ -219,7 +219,7 @@ proc excl*[A](s: var TSet[A], key: A) = s.data[index].slot = seDeleted dec(s.counter) -proc excl*[A](s: var TSet[A], other: TSet[A]) = +proc excl*[A](s: var HashSet[A], other: TSet[A]) = ## Excludes everything in `other` from `s`. ## ## Example: @@ -235,7 +235,7 @@ proc excl*[A](s: var TSet[A], other: TSet[A]) = assert other.isValid, "The set `other` needs to be initialized." for item in other: excl(s, item) -proc containsOrIncl*[A](s: var TSet[A], key: A): bool = +proc containsOrIncl*[A](s: var HashSet[A], key: A): bool = ## Includes `key` in the set `s` and tells if `key` was added to `s`. ## ## The difference with regards to the `incl() <#incl,TSet[A],A>`_ proc is @@ -250,7 +250,7 @@ proc containsOrIncl*[A](s: var TSet[A], key: A): bool = assert s.isValid, "The set needs to be initialized." containsOrInclImpl() -proc init*[A](s: var TSet[A], initialSize=64) = +proc init*[A](s: var HashSet[A], initialSize=64) = ## Initializes a hash set. ## ## The `initialSize` parameter needs to be a power of too. You can use @@ -273,7 +273,7 @@ proc init*[A](s: var TSet[A], initialSize=64) = s.counter = 0 newSeq(s.data, initialSize) -proc initSet*[A](initialSize=64): TSet[A] = +proc initSet*[A](initialSize=64): HashSet[A] = ## Wrapper around `init() <#init,TSet[A],int>`_ for initialization of hash ## sets. ## @@ -285,7 +285,7 @@ proc initSet*[A](initialSize=64): TSet[A] = ## a.incl(2) result.init(initialSize) -proc toSet*[A](keys: openArray[A]): TSet[A] = +proc toSet*[A](keys: openArray[A]): HashSet[A] = ## Creates a new hash set that contains the given `keys`. ## ## Example: @@ -304,7 +304,7 @@ template dollarImpl(): stmt {.dirty.} = result.add($key) result.add("}") -proc `$`*[A](s: TSet[A]): string = +proc `$`*[A](s: HashSet[A]): string = ## Converts the set `s` to a string, mostly for logging purposes. ## ## Don't use this proc for serialization, the representation may change at @@ -320,7 +320,7 @@ proc `$`*[A](s: TSet[A]): string = assert s.isValid, "The set needs to be initialized." dollarImpl() -proc union*[A](s1, s2: TSet[A]): TSet[A] = +proc union*[A](s1, s2: HashSet[A]): TSet[A] = ## Returns the union of the sets `s1` and `s2`. ## ## The union of two sets is represented mathematically as *A ∪ B* and is the @@ -337,7 +337,7 @@ proc union*[A](s1, s2: TSet[A]): TSet[A] = result = s1 incl(result, s2) -proc intersection*[A](s1, s2: TSet[A]): TSet[A] = +proc intersection*[A](s1, s2: HashSet[A]): TSet[A] = ## Returns the intersection of the sets `s1` and `s2`. ## ## The intersection of two sets is represented mathematically as *A ∩ B* and @@ -356,7 +356,7 @@ proc intersection*[A](s1, s2: TSet[A]): TSet[A] = for item in s1: if item in s2: incl(result, item) -proc difference*[A](s1, s2: TSet[A]): TSet[A] = +proc difference*[A](s1, s2: HashSet[A]): TSet[A] = ## Returns the difference of the sets `s1` and `s2`. ## ## The difference of two sets is represented mathematically as *A \ B* and is @@ -376,7 +376,7 @@ proc difference*[A](s1, s2: TSet[A]): TSet[A] = if not contains(s2, item): incl(result, item) -proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] = +proc symmetricDifference*[A](s1, s2: HashSet[A]): TSet[A] = ## Returns the symmetric difference of the sets `s1` and `s2`. ## ## The symmetric difference of two sets is represented mathematically as *A △ @@ -395,23 +395,23 @@ proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] = for item in s2: if containsOrIncl(result, item): excl(result, item) -proc `+`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = +proc `+`*[A](s1, s2: HashSet[A]): TSet[A] {.inline.} = ## Alias for `union(s1, s2) <#union>`_. result = union(s1, s2) -proc `*`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = +proc `*`*[A](s1, s2: HashSet[A]): TSet[A] {.inline.} = ## Alias for `intersection(s1, s2) <#intersection>`_. result = intersection(s1, s2) -proc `-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = +proc `-`*[A](s1, s2: HashSet[A]): TSet[A] {.inline.} = ## Alias for `difference(s1, s2) <#difference>`_. result = difference(s1, s2) -proc `-+-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} = +proc `-+-`*[A](s1, s2: HashSet[A]): TSet[A] {.inline.} = ## Alias for `symmetricDifference(s1, s2) <#symmetricDifference>`_. result = symmetricDifference(s1, s2) -proc disjoint*[A](s1, s2: TSet[A]): bool = +proc disjoint*[A](s1, s2: HashSet[A]): bool = ## Returns true iff the sets `s1` and `s2` have no items in common. ## ## Example: @@ -428,7 +428,7 @@ proc disjoint*[A](s1, s2: TSet[A]): bool = if item in s2: return false return true -proc `<`*[A](s, t: TSet[A]): bool = +proc `<`*[A](s, t: HashSet[A]): bool = ## Returns true if `s` is a strict or proper subset of `t`. ## ## A strict or proper subset `s` has all of its members in `t` but `t` has @@ -443,7 +443,7 @@ proc `<`*[A](s, t: TSet[A]): bool = ## assert((a < a) == false) s.counter != t.counter and s <= t -proc `<=`*[A](s, t: TSet[A]): bool = +proc `<=`*[A](s, t: HashSet[A]): bool = ## Returns true if `s` is subset of `t`. ## ## A subset `s` has all of its members in `t` and `t` doesn't necessarily @@ -464,7 +464,7 @@ proc `<=`*[A](s, t: TSet[A]): bool = result = false return -proc `==`*[A](s, t: TSet[A]): bool = +proc `==`*[A](s, t: HashSet[A]): bool = ## Returns true if both `s` and `t` have the same members and set size. ## ## Example: @@ -477,7 +477,7 @@ proc `==`*[A](s, t: TSet[A]): bool = ## assert a == b s.counter == t.counter and s <= t -proc map*[A, B](data: TSet[A], op: proc (x: A): B {.closure.}): TSet[B] = +proc map*[A, B](data: HashSet[A], op: proc (x: A): B {.closure.}): TSet[B] = ## Returns a new set after applying `op` on each of the elements of `data`. ## ## You can use this proc to transform the elements from a set. Example: @@ -534,7 +534,7 @@ proc len*[A](s: OrderedSet[A]): int {.inline.} = ## assert values.len == 0 result = s.counter -proc card*[A](s: TOrderedSet[A]): int {.inline.} = +proc card*[A](s: OrderedSet[A]): int {.inline.} = ## Alias for `len() <#len,TOrderedSet[A]>`_. ## ## Card stands for the `cardinality @@ -548,7 +548,7 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = if s.data[h].slot == seFilled: yieldStmt h = nxt -iterator items*[A](s: TOrderedSet[A]): A = +iterator items*[A](s: OrderedSet[A]): A = ## Iterates over keys in the ordered set `s` in insertion order. ## ## If you need a sequence with the keys you can use `sequtils.toSeq() @@ -570,10 +570,10 @@ iterator items*[A](s: TOrderedSet[A]): A = forAllOrderedPairs: yield s.data[h].key -proc rawGet[A](s: TOrderedSet[A], key: A): int = +proc rawGet[A](s: OrderedSet[A], key: A): int = rawGetImpl() -proc contains*[A](s: TOrderedSet[A], key: A): bool = +proc contains*[A](s: OrderedSet[A], key: A): bool = ## Returns true iff `key` is in `s`. ## ## Example: @@ -587,7 +587,7 @@ proc contains*[A](s: TOrderedSet[A], key: A): bool = var index = rawGet(s, key) result = index >= 0 -proc rawInsert[A](s: var TOrderedSet[A], +proc rawInsert[A](s: var OrderedSet[A], data: var OrderedKeyValuePairSeq[A], key: A) = rawInsertImpl() data[h].next = -1 @@ -595,7 +595,7 @@ proc rawInsert[A](s: var TOrderedSet[A], if s.last >= 0: data[s.last].next = h s.last = h -proc enlarge[A](s: var TOrderedSet[A]) = +proc enlarge[A](s: var OrderedSet[A]) = var n: OrderedKeyValuePairSeq[A] newSeq(n, len(s.data) * growthFactor) var h = s.first @@ -608,7 +608,7 @@ proc enlarge[A](s: var TOrderedSet[A]) = h = nxt swap(s.data, n) -proc incl*[A](s: var TOrderedSet[A], key: A) = +proc incl*[A](s: var OrderedSet[A], key: A) = ## Includes an element `key` in `s`. ## ## This doesn't do anything if `key` is already in `s`. Example: @@ -621,7 +621,7 @@ proc incl*[A](s: var TOrderedSet[A], key: A) = assert s.isValid, "The set needs to be initialized." inclImpl() -proc incl*[A](s: var TSet[A], other: TOrderedSet[A]) = +proc incl*[A](s: var HashSet[A], other: TOrderedSet[A]) = ## Includes all elements from `other` into `s`. ## ## Example: @@ -636,7 +636,7 @@ proc incl*[A](s: var TSet[A], other: TOrderedSet[A]) = assert other.isValid, "The set `other` needs to be initialized." for item in other: incl(s, item) -proc containsOrIncl*[A](s: var TOrderedSet[A], key: A): bool = +proc containsOrIncl*[A](s: var OrderedSet[A], key: A): bool = ## Includes `key` in the set `s` and tells if `key` was added to `s`. ## ## The difference with regards to the `incl() <#incl,TOrderedSet[A],A>`_ proc @@ -651,7 +651,7 @@ proc containsOrIncl*[A](s: var TOrderedSet[A], key: A): bool = assert s.isValid, "The set needs to be initialized." containsOrInclImpl() -proc init*[A](s: var TOrderedSet[A], initialSize=64) = +proc init*[A](s: var OrderedSet[A], initialSize=64) = ## Initializes an ordered hash set. ## ## The `initialSize` parameter needs to be a power of too. You can use @@ -676,7 +676,7 @@ proc init*[A](s: var TOrderedSet[A], initialSize=64) = s.last = -1 newSeq(s.data, initialSize) -proc initOrderedSet*[A](initialSize=64): TOrderedSet[A] = +proc initOrderedSet*[A](initialSize=64): OrderedSet[A] = ## Wrapper around `init() <#init,TOrderedSet[A],int>`_ for initialization of ## ordered hash sets. ## @@ -688,7 +688,7 @@ proc initOrderedSet*[A](initialSize=64): TOrderedSet[A] = ## a.incl(2) result.init(initialSize) -proc toOrderedSet*[A](keys: openArray[A]): TOrderedSet[A] = +proc toOrderedSet*[A](keys: openArray[A]): OrderedSet[A] = ## Creates a new ordered hash set that contains the given `keys`. ## ## Example: @@ -700,7 +700,7 @@ proc toOrderedSet*[A](keys: openArray[A]): TOrderedSet[A] = result = initOrderedSet[A](nextPowerOfTwo(keys.len+10)) for key in items(keys): result.incl(key) -proc `$`*[A](s: TOrderedSet[A]): string = +proc `$`*[A](s: OrderedSet[A]): string = ## Converts the ordered hash set `s` to a string, mostly for logging purposes. ## ## Don't use this proc for serialization, the representation may change at @@ -716,7 +716,7 @@ proc `$`*[A](s: TOrderedSet[A]): string = assert s.isValid, "The set needs to be initialized." dollarImpl() -proc `==`*[A](s, t: TOrderedSet[A]): bool = +proc `==`*[A](s, t: OrderedSet[A]): bool = ## Equality for ordered sets. if s.counter != t.counter: return false var h = s.first @@ -738,7 +738,7 @@ proc testModule() = ## Internal micro test to validate docstrings and such. block isValidTest: var options: HashSet[string] - proc savePreferences(options: TSet[string]) = + proc savePreferences(options: HashSet[string]) = assert options.isValid, "Pass an initialized set!" options = initSet[string]() options.savePreferences @@ -839,7 +839,7 @@ proc testModule() = block isValidTest: var cards: OrderedSet[string] - proc saveTarotCards(cards: TOrderedSet[string]) = + proc saveTarotCards(cards: OrderedSet[string]) = assert cards.isValid, "Pass an initialized set!" cards = initOrderedSet[string]() cards.saveTarotCards @@ -891,7 +891,7 @@ proc testModule() = a.incl(2) assert a.len == 1 - var b: TSet[int] + var b: HashSet[int] b.init(4) b.incl(2) b.init diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index c6ac01da8..41dfdaca6 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -74,32 +74,32 @@ type when not defined(nimhygiene): {.pragma: dirty.} -proc len*[A, B](t: TTable[A, B]): int = +proc len*[A, B](t: Table[A, B]): int = ## returns the number of keys in `t`. result = t.counter -iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] = +iterator pairs*[A, B](t: Table[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A, B](t: var TTable[A, B]): tuple[key: A, val: var B] = +iterator mpairs*[A, B](t: var Table[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t`. The values ## can be modified. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: TTable[A, B]): A = +iterator keys*[A, B](t: Table[A, B]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].key -iterator values*[A, B](t: TTable[A, B]): B = +iterator values*[A, B](t: Table[A, B]): B = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val -iterator mvalues*[A, B](t: var TTable[A, B]): var B = +iterator mvalues*[A, B](t: var Table[A, B]): var B = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val @@ -130,10 +130,10 @@ template rawInsertImpl() {.dirty.} = data[h].val = val data[h].slot = seFilled -proc rawGet[A, B](t: TTable[A, B], key: A): int = +proc rawGet[A, B](t: Table[A, B], key: A): int = rawGetImpl() -proc `[]`*[A, B](t: TTable[A, B], key: A): B = +proc `[]`*[A, B](t: Table[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key @@ -141,14 +141,14 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B = var index = rawGet(t, key) if index >= 0: result = t.data[index].val -proc mget*[A, B](t: var TTable[A, B], key: A): var B = +proc mget*[A, B](t: var Table[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: raise newException(KeyError, "key not found: " & $key) -iterator allValues*[A, B](t: TTable[A, B]; key: A): B = +iterator allValues*[A, B](t: Table[A, B]; key: A): B = ## iterates over any value in the table `t` that belongs to the given `key`. var h: THash = hash(key) and high(t.data) while t.data[h].slot != seEmpty: @@ -156,15 +156,15 @@ iterator allValues*[A, B](t: TTable[A, B]; key: A): B = yield t.data[h].val h = nextTry(h, high(t.data)) -proc hasKey*[A, B](t: TTable[A, B], key: A): bool = +proc hasKey*[A, B](t: Table[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert[A, B](t: var TTable[A, B], data: var KeyValuePairSeq[A, B], +proc rawInsert[A, B](t: var Table[A, B], data: var KeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() -proc enlarge[A, B](t: var TTable[A, B]) = +proc enlarge[A, B](t: var Table[A, B]) = var n: KeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): @@ -196,22 +196,22 @@ when false: inc(t.counter) result = false -proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) = +proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. putImpl() -proc add*[A, B](t: var TTable[A, B], key: A, val: B) = +proc add*[A, B](t: var Table[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. addImpl() -proc del*[A, B](t: var TTable[A, B], key: A) = +proc del*[A, B](t: var Table[A, B], key: A) = ## deletes `key` from hash table `t`. let index = rawGet(t, key) if index >= 0: t.data[index].slot = seDeleted dec(t.counter) -proc initTable*[A, B](initialSize=64): TTable[A, B] = +proc initTable*[A, B](initialSize=64): Table[A, B] = ## creates a new hash table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -222,7 +222,7 @@ proc initTable*[A, B](initialSize=64): TTable[A, B] = newSeq(result.data, initialSize) proc toTable*[A, B](pairs: openArray[tuple[key: A, - val: B]]): TTable[A, B] = + val: B]]): Table[A, B] = ## creates a new hash table that contains the given `pairs`. result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) for key, val in items(pairs): result[key] = val @@ -239,7 +239,7 @@ template dollarImpl(): stmt {.dirty.} = result.add($val) result.add("}") -proc `$`*[A, B](t: TTable[A, B]): string = +proc `$`*[A, B](t: Table[A, B]): string = ## The `$` operator for hash tables. dollarImpl() @@ -253,93 +253,93 @@ template equalsImpl() = if t[key] != val: return false return true -proc `==`*[A, B](s, t: TTable[A, B]): bool = +proc `==`*[A, B](s, t: Table[A, B]): bool = equalsImpl() -proc indexBy*[A, B, C](collection: A, index: proc(x: B): C): TTable[C, B] = +proc indexBy*[A, B, C](collection: A, index: proc(x: B): C): Table[C, B] = ## Index the collection with the proc provided. # TODO: As soon as supported, change collection: A to collection: A[B] result = initTable[C, B]() for item in collection: result[index(item)] = item -proc len*[A, B](t: PTable[A, B]): int = +proc len*[A, B](t: TableRef[A, B]): int = ## returns the number of keys in `t`. result = t.counter -iterator pairs*[A, B](t: PTable[A, B]): tuple[key: A, val: B] = +iterator pairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A, B](t: PTable[A, B]): tuple[key: A, val: var B] = +iterator mpairs*[A, B](t: TableRef[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t`. The values ## can be modified. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: PTable[A, B]): A = +iterator keys*[A, B](t: TableRef[A, B]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].key -iterator values*[A, B](t: PTable[A, B]): B = +iterator values*[A, B](t: TableRef[A, B]): B = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val -iterator mvalues*[A, B](t: PTable[A, B]): var B = +iterator mvalues*[A, B](t: TableRef[A, B]): var B = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val -proc `[]`*[A, B](t: PTable[A, B], key: A): B = +proc `[]`*[A, B](t: TableRef[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. result = t[][key] -proc mget*[A, B](t: PTable[A, B], key: A): var B = +proc mget*[A, B](t: TableRef[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. t[].mget(key) -proc hasKey*[A, B](t: PTable[A, B], key: A): bool = +proc hasKey*[A, B](t: TableRef[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = t[].hasKey(key) -proc `[]=`*[A, B](t: PTable[A, B], key: A, val: B) = +proc `[]=`*[A, B](t: TableRef[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. t[][key] = val -proc add*[A, B](t: PTable[A, B], key: A, val: B) = +proc add*[A, B](t: TableRef[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. t[].add(key, val) -proc del*[A, B](t: PTable[A, B], key: A) = +proc del*[A, B](t: TableRef[A, B], key: A) = ## deletes `key` from hash table `t`. t[].del(key) -proc newTable*[A, B](initialSize=64): PTable[A, B] = +proc newTable*[A, B](initialSize=64): TableRef[A, B] = new(result) result[] = initTable[A, B](initialSize) -proc newTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): PTable[A, B] = +proc newTable*[A, B](pairs: openArray[tuple[key: A, val: B]]): TableRef[A, B] = ## creates a new hash table that contains the given `pairs`. new(result) result[] = toTable[A, B](pairs) -proc `$`*[A, B](t: PTable[A, B]): string = +proc `$`*[A, B](t: TableRef[A, B]): string = ## The `$` operator for hash tables. dollarImpl() -proc `==`*[A, B](s, t: PTable[A, B]): bool = +proc `==`*[A, B](s, t: TableRef[A, B]): bool = if isNil(s): result = isNil(t) elif isNil(t): result = false else: result = equalsImpl() -proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): PTable[C, B] = +proc newTableFrom*[A, B, C](collection: A, index: proc(x: B): C): TableRef[C, B] = ## Index the collection with the proc provided. # TODO: As soon as supported, change collection: A to collection: A[B] result = newTable[C, B]() @@ -360,7 +360,7 @@ type {.deprecated: [TOrderedTable: OrderedTable, POrderedTable: OrderedTableRef].} -proc len*[A, B](t: TOrderedTable[A, B]): int {.inline.} = +proc len*[A, B](t: OrderedTable[A, B]): int {.inline.} = ## returns the number of keys in `t`. result = t.counter @@ -371,38 +371,38 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = if t.data[h].slot == seFilled: yieldStmt h = nxt -iterator pairs*[A, B](t: TOrderedTable[A, B]): tuple[key: A, val: B] = +iterator pairs*[A, B](t: OrderedTable[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t` in insertion ## order. forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A, B](t: var TOrderedTable[A, B]): tuple[key: A, val: var B] = +iterator mpairs*[A, B](t: var OrderedTable[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t` in insertion ## order. The values can be modified. forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: TOrderedTable[A, B]): A = +iterator keys*[A, B](t: OrderedTable[A, B]): A = ## iterates over any key in the table `t` in insertion order. forAllOrderedPairs: yield t.data[h].key -iterator values*[A, B](t: TOrderedTable[A, B]): B = +iterator values*[A, B](t: OrderedTable[A, B]): B = ## iterates over any value in the table `t` in insertion order. forAllOrderedPairs: yield t.data[h].val -iterator mvalues*[A, B](t: var TOrderedTable[A, B]): var B = +iterator mvalues*[A, B](t: var OrderedTable[A, B]): var B = ## iterates over any value in the table `t` in insertion order. The values ## can be modified. forAllOrderedPairs: yield t.data[h].val -proc rawGet[A, B](t: TOrderedTable[A, B], key: A): int = +proc rawGet[A, B](t: OrderedTable[A, B], key: A): int = rawGetImpl() -proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = +proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key @@ -410,18 +410,18 @@ proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = var index = rawGet(t, key) if index >= 0: result = t.data[index].val -proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B = +proc mget*[A, B](t: var OrderedTable[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: raise newException(KeyError, "key not found: " & $key) -proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool = +proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert[A, B](t: var TOrderedTable[A, B], +proc rawInsert[A, B](t: var OrderedTable[A, B], data: var OrderedKeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() @@ -430,7 +430,7 @@ proc rawInsert[A, B](t: var TOrderedTable[A, B], if t.last >= 0: data[t.last].next = h t.last = h -proc enlarge[A, B](t: var TOrderedTable[A, B]) = +proc enlarge[A, B](t: var OrderedTable[A, B]) = var n: OrderedKeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) var h = t.first @@ -443,15 +443,15 @@ proc enlarge[A, B](t: var TOrderedTable[A, B]) = h = nxt swap(t.data, n) -proc `[]=`*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = +proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. putImpl() -proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = +proc add*[A, B](t: var OrderedTable[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. addImpl() -proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = +proc initOrderedTable*[A, B](initialSize=64): OrderedTable[A, B] = ## creates a new ordered hash table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -464,16 +464,16 @@ proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = newSeq(result.data, initialSize) proc toOrderedTable*[A, B](pairs: openArray[tuple[key: A, - val: B]]): TOrderedTable[A, B] = + val: B]]): OrderedTable[A, B] = ## creates a new ordered hash table that contains the given `pairs`. result = initOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) for key, val in items(pairs): result[key] = val -proc `$`*[A, B](t: TOrderedTable[A, B]): string = +proc `$`*[A, B](t: OrderedTable[A, B]): string = ## The `$` operator for ordered hash tables. dollarImpl() -proc sort*[A, B](t: var TOrderedTable[A, B], +proc sort*[A, B](t: var OrderedTable[A, B], cmp: proc (x,y: tuple[key: A, val: B]): int) = ## sorts `t` according to `cmp`. This modifies the internal list ## that kept the insertion order, so insertion order is lost after this @@ -519,7 +519,7 @@ proc sort*[A, B](t: var TOrderedTable[A, B], t.first = list t.last = tail -proc len*[A, B](t: POrderedTable[A, B]): int {.inline.} = +proc len*[A, B](t: OrderedTableRef[A, B]): int {.inline.} = ## returns the number of keys in `t`. result = t.counter @@ -530,59 +530,59 @@ template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = if t.data[h].slot == seFilled: yieldStmt h = nxt -iterator pairs*[A, B](t: POrderedTable[A, B]): tuple[key: A, val: B] = +iterator pairs*[A, B](t: OrderedTableRef[A, B]): tuple[key: A, val: B] = ## iterates over any (key, value) pair in the table `t` in insertion ## order. forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A, B](t: POrderedTable[A, B]): tuple[key: A, val: var B] = +iterator mpairs*[A, B](t: OrderedTableRef[A, B]): tuple[key: A, val: var B] = ## iterates over any (key, value) pair in the table `t` in insertion ## order. The values can be modified. forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) -iterator keys*[A, B](t: POrderedTable[A, B]): A = +iterator keys*[A, B](t: OrderedTableRef[A, B]): A = ## iterates over any key in the table `t` in insertion order. forAllOrderedPairs: yield t.data[h].key -iterator values*[A, B](t: POrderedTable[A, B]): B = +iterator values*[A, B](t: OrderedTableRef[A, B]): B = ## iterates over any value in the table `t` in insertion order. forAllOrderedPairs: yield t.data[h].val -iterator mvalues*[A, B](t: POrderedTable[A, B]): var B = +iterator mvalues*[A, B](t: OrderedTableRef[A, B]): var B = ## iterates over any value in the table `t` in insertion order. The values ## can be modified. forAllOrderedPairs: yield t.data[h].val -proc `[]`*[A, B](t: POrderedTable[A, B], key: A): B = +proc `[]`*[A, B](t: OrderedTableRef[A, B], key: A): B = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. result = t[][key] -proc mget*[A, B](t: POrderedTable[A, B], key: A): var B = +proc mget*[A, B](t: OrderedTableRef[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. result = t[].mget(key) -proc hasKey*[A, B](t: POrderedTable[A, B], key: A): bool = +proc hasKey*[A, B](t: OrderedTableRef[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = t[].hasKey(key) -proc `[]=`*[A, B](t: POrderedTable[A, B], key: A, val: B) = +proc `[]=`*[A, B](t: OrderedTableRef[A, B], key: A, val: B) = ## puts a (key, value)-pair into `t`. t[][key] = val -proc add*[A, B](t: POrderedTable[A, B], key: A, val: B) = +proc add*[A, B](t: OrderedTableRef[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. t[].add(key, val) -proc newOrderedTable*[A, B](initialSize=64): POrderedTable[A, B] = +proc newOrderedTable*[A, B](initialSize=64): OrderedTableRef[A, B] = ## creates a new ordered hash table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -592,16 +592,16 @@ proc newOrderedTable*[A, B](initialSize=64): POrderedTable[A, B] = result[] = initOrderedTable[A, B]() proc newOrderedTable*[A, B](pairs: openArray[tuple[key: A, - val: B]]): POrderedTable[A, B] = + val: B]]): OrderedTableRef[A, B] = ## creates a new ordered hash table that contains the given `pairs`. result = newOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) for key, val in items(pairs): result[key] = val -proc `$`*[A, B](t: POrderedTable[A, B]): string = +proc `$`*[A, B](t: OrderedTableRef[A, B]): string = ## The `$` operator for ordered hash tables. dollarImpl() -proc sort*[A, B](t: POrderedTable[A, B], +proc sort*[A, B](t: OrderedTableRef[A, B], cmp: proc (x,y: tuple[key: A, val: B]): int) = ## sorts `t` according to `cmp`. This modifies the internal list ## that kept the insertion order, so insertion order is lost after this @@ -620,81 +620,81 @@ type {.deprecated: [TCountTable: CountTable, PCountTable: CountTableRef].} -proc len*[A](t: TCountTable[A]): int = +proc len*[A](t: CountTable[A]): int = ## returns the number of keys in `t`. result = t.counter -iterator pairs*[A](t: TCountTable[A]): tuple[key: A, val: int] = +iterator pairs*[A](t: CountTable[A]): tuple[key: A, val: int] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A](t: var TCountTable[A]): tuple[key: A, val: var int] = +iterator mpairs*[A](t: var CountTable[A]): tuple[key: A, val: var int] = ## iterates over any (key, value) pair in the table `t`. The values can ## be modified. for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) -iterator keys*[A](t: TCountTable[A]): A = +iterator keys*[A](t: CountTable[A]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].key -iterator values*[A](t: TCountTable[A]): int = +iterator values*[A](t: CountTable[A]): int = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -iterator mvalues*[A](t: TCountTable[A]): var int = +iterator mvalues*[A](t: CountTable[A]): var int = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -proc rawGet[A](t: TCountTable[A], key: A): int = +proc rawGet[A](t: CountTable[A], key: A): int = var h: THash = hash(key) and high(t.data) # start with real hash value while t.data[h].val != 0: if t.data[h].key == key: return h h = nextTry(h, high(t.data)) result = -1 -proc `[]`*[A](t: TCountTable[A], key: A): int = +proc `[]`*[A](t: CountTable[A], key: A): int = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## 0 is returned. One can check with ``hasKey`` whether the key ## exists. var index = rawGet(t, key) if index >= 0: result = t.data[index].val -proc mget*[A](t: var TCountTable[A], key: A): var int = +proc mget*[A](t: var CountTable[A], key: A): var int = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: raise newException(KeyError, "key not found: " & $key) -proc hasKey*[A](t: TCountTable[A], key: A): bool = +proc hasKey*[A](t: CountTable[A], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], +proc rawInsert[A](t: CountTable[A], data: var seq[tuple[key: A, val: int]], key: A, val: int) = var h: THash = hash(key) and high(data) while data[h].val != 0: h = nextTry(h, high(data)) data[h].key = key data[h].val = val -proc enlarge[A](t: var TCountTable[A]) = +proc enlarge[A](t: var CountTable[A]) = var n: seq[tuple[key: A, val: int]] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i].val != 0: rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) -proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) = +proc `[]=`*[A](t: var CountTable[A], key: A, val: int) = ## puts a (key, value)-pair into `t`. `val` has to be positive. assert val > 0 putImpl() -proc initCountTable*[A](initialSize=64): TCountTable[A] = +proc initCountTable*[A](initialSize=64): CountTable[A] = ## creates a new count table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -704,16 +704,16 @@ proc initCountTable*[A](initialSize=64): TCountTable[A] = result.counter = 0 newSeq(result.data, initialSize) -proc toCountTable*[A](keys: openArray[A]): TCountTable[A] = +proc toCountTable*[A](keys: openArray[A]): CountTable[A] = ## creates a new count table with every key in `keys` having a count of 1. result = initCountTable[A](nextPowerOfTwo(keys.len+10)) for key in items(keys): result[key] = 1 -proc `$`*[A](t: TCountTable[A]): string = +proc `$`*[A](t: CountTable[A]): string = ## The `$` operator for count tables. dollarImpl() -proc inc*[A](t: var TCountTable[A], key: A, val = 1) = +proc inc*[A](t: var CountTable[A], key: A, val = 1) = ## increments `t[key]` by `val`. var index = rawGet(t, key) if index >= 0: @@ -723,7 +723,7 @@ proc inc*[A](t: var TCountTable[A], key: A, val = 1) = rawInsert(t, t.data, key, val) inc(t.counter) -proc smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = +proc smallest*[A](t: CountTable[A]): tuple[key: A, val: int] = ## returns the largest (key,val)-pair. Efficiency: O(n) assert t.len > 0 var minIdx = 0 @@ -732,7 +732,7 @@ proc smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = result.key = t.data[minIdx].key result.val = t.data[minIdx].val -proc largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = +proc largest*[A](t: CountTable[A]): tuple[key: A, val: int] = ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) assert t.len > 0 var maxIdx = 0 @@ -741,7 +741,7 @@ proc largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = result.key = t.data[maxIdx].key result.val = t.data[maxIdx].val -proc sort*[A](t: var TCountTable[A]) = +proc sort*[A](t: var CountTable[A]) = ## sorts the count table so that the entry with the highest counter comes ## first. This is destructive! You must not modify `t` afterwards! ## You can use the iterators `pairs`, `keys`, and `values` to iterate over @@ -762,57 +762,57 @@ proc sort*[A](t: var TCountTable[A]) = if j < h: break if h == 1: break -proc len*[A](t: PCountTable[A]): int = +proc len*[A](t: CountTableRef[A]): int = ## returns the number of keys in `t`. result = t.counter -iterator pairs*[A](t: PCountTable[A]): tuple[key: A, val: int] = +iterator pairs*[A](t: CountTableRef[A]): tuple[key: A, val: int] = ## iterates over any (key, value) pair in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) -iterator mpairs*[A](t: PCountTable[A]): tuple[key: A, val: var int] = +iterator mpairs*[A](t: CountTableRef[A]): tuple[key: A, val: var int] = ## iterates over any (key, value) pair in the table `t`. The values can ## be modified. for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) -iterator keys*[A](t: PCountTable[A]): A = +iterator keys*[A](t: CountTableRef[A]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].key -iterator values*[A](t: PCountTable[A]): int = +iterator values*[A](t: CountTableRef[A]): int = ## iterates over any value in the table `t`. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -iterator mvalues*[A](t: PCountTable[A]): var int = +iterator mvalues*[A](t: CountTableRef[A]): var int = ## iterates over any value in the table `t`. The values can be modified. for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val -proc `[]`*[A](t: PCountTable[A], key: A): int = +proc `[]`*[A](t: CountTableRef[A], key: A): int = ## retrieves the value at ``t[key]``. If `key` is not in `t`, ## 0 is returned. One can check with ``hasKey`` whether the key ## exists. result = t[][key] -proc mget*[A](t: PCountTable[A], key: A): var int = +proc mget*[A](t: CountTableRef[A], key: A): var int = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. result = t[].mget(key) -proc hasKey*[A](t: PCountTable[A], key: A): bool = +proc hasKey*[A](t: CountTableRef[A], key: A): bool = ## returns true iff `key` is in the table `t`. result = t[].hasKey(key) -proc `[]=`*[A](t: PCountTable[A], key: A, val: int) = +proc `[]=`*[A](t: CountTableRef[A], key: A, val: int) = ## puts a (key, value)-pair into `t`. `val` has to be positive. assert val > 0 t[][key] = val -proc newCountTable*[A](initialSize=64): PCountTable[A] = +proc newCountTable*[A](initialSize=64): CountTableRef[A] = ## creates a new count table that is empty. ## ## `initialSize` needs to be a power of two. If you need to accept runtime @@ -821,28 +821,28 @@ proc newCountTable*[A](initialSize=64): PCountTable[A] = new(result) result[] = initCountTable[A](initialSize) -proc newCountTable*[A](keys: openArray[A]): PCountTable[A] = +proc newCountTable*[A](keys: openArray[A]): CountTableRef[A] = ## creates a new count table with every key in `keys` having a count of 1. result = newCountTable[A](nextPowerOfTwo(keys.len+10)) for key in items(keys): result[key] = 1 -proc `$`*[A](t: PCountTable[A]): string = +proc `$`*[A](t: CountTableRef[A]): string = ## The `$` operator for count tables. dollarImpl() -proc inc*[A](t: PCountTable[A], key: A, val = 1) = +proc inc*[A](t: CountTableRef[A], key: A, val = 1) = ## increments `t[key]` by `val`. t[].inc(key, val) -proc smallest*[A](t: PCountTable[A]): tuple[key: A, val: int] = +proc smallest*[A](t: CountTableRef[A]): tuple[key: A, val: int] = ## returns the largest (key,val)-pair. Efficiency: O(n) t[].smallest -proc largest*[A](t: PCountTable[A]): tuple[key: A, val: int] = +proc largest*[A](t: CountTableRef[A]): tuple[key: A, val: int] = ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) t[].largest -proc sort*[A](t: PCountTable[A]) = +proc sort*[A](t: CountTableRef[A]) = ## sorts the count table so that the entry with the highest counter comes ## first. This is destructive! You must not modify `t` afterwards! ## You can use the iterators `pairs`, `keys`, and `values` to iterate over diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 1e17f1d7a..a64294a77 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -94,11 +94,11 @@ proc toOSFlags*(socketFlags: set[SocketFlag]): cint = ## Converts the flags into the underlying OS representation. for f in socketFlags: case f - of TSocketFlags.Peek: + of SocketFlag.Peek: result = result or MSG_PEEK - of TSocketFlags.SafeDisconn: continue + of SocketFlag.SafeDisconn: continue -proc createSocket(fd: TSocketHandle, isBuff: bool): PSocket = +proc createSocket(fd: TSocketHandle, isBuff: bool): Socket = assert fd != osInvalidSocket new(result) result.fd = fd @@ -106,14 +106,14 @@ proc createSocket(fd: TSocketHandle, isBuff: bool): PSocket = if isBuff: result.currPos = 0 -proc newSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP, buffered = true): PSocket = +proc newSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP, buffered = true): Socket = ## Creates a new socket. ## ## If an error occurs EOS will be raised. let fd = newRawSocket(domain, typ, protocol) if fd == osInvalidSocket: - osError(osLastError()) + raiseOSError(osLastError()) result = createSocket(fd, buffered) when defined(ssl): @@ -218,8 +218,8 @@ when defined(ssl): if SSLSetFd(socket.sslHandle, socket.fd) != 1: SSLError() -proc socketError*(socket: PSocket, err: int = -1, async = false, - lastError = (-1).TOSErrorCode) = +proc socketError*(socket: Socket, err: int = -1, async = false, + lastError = (-1).OSErrorCode) = ## Raises an EOS error based on the error code returned by ``SSLGetError`` ## (for SSL sockets) and ``osLastError`` otherwise. ## @@ -254,23 +254,23 @@ proc socketError*(socket: PSocket, err: int = -1, async = false, when useWinVersion: if lastE.int32 == WSAEWOULDBLOCK: return - else: osError(lastE) + else: raiseOSError(lastE) else: if lastE.int32 == EAGAIN or lastE.int32 == EWOULDBLOCK: return else: osError(lastE) - else: osError(lastE) + else: raiseOSError(lastE) -proc listen*(socket: PSocket, backlog = SOMAXCONN) {.tags: [FReadIO].} = +proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. ## ## Raises an EOS error upon failure. - if listen(socket.fd, backlog) < 0'i32: osError(osLastError()) + if listen(socket.fd, backlog) < 0'i32: raiseOSError(osLastError()) -proc bindAddr*(socket: PSocket, port = TPort(0), address = "") {. - tags: [FReadIO].} = +proc bindAddr*(socket: Socket, port = Port(0), address = "") {. + tags: [ReadIOEffect].} = ## Binds ``address``:``port`` to the socket. ## ## If ``address`` is "" then ADDR_ANY will be bound. @@ -285,16 +285,16 @@ proc bindAddr*(socket: PSocket, port = TPort(0), address = "") {. name.sin_addr.s_addr = htonl(INADDR_ANY) if bindAddr(socket.fd, cast[ptr TSockAddr](addr(name)), sizeof(name).TSocklen) < 0'i32: - osError(osLastError()) + raiseOSError(osLastError()) else: var aiList = getAddrInfo(address, port, AF_INET) if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSocklen) < 0'i32: dealloc(aiList) - osError(osLastError()) + raiseOSError(osLastError()) dealloc(aiList) -proc acceptAddr*(server: PSocket, client: var PSocket, address: var string, - flags = {TSocketFlags.SafeDisconn}) {.tags: [FReadIO].} = +proc acceptAddr*(server: Socket, client: var Socket, address: var string, + flags = {SocketFlag.SafeDisconn}) {.tags: [ReadIOEffect].} = ## Blocks until a connection is being made from a client. When a connection ## is made sets ``client`` to the client socket and ``address`` to the address ## of the connecting client. @@ -311,7 +311,7 @@ proc acceptAddr*(server: PSocket, client: var PSocket, address: var string, ## flag is specified then this error will not be raised and instead ## accept will be called again. assert(client != nil) - var sockAddress: Tsockaddr_in + var sockAddress: TSockaddr_in var addrLen = sizeof(sockAddress).TSocklen var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) @@ -320,7 +320,7 @@ proc acceptAddr*(server: PSocket, client: var PSocket, address: var string, let err = osLastError() if flags.isDisconnectionError(err): acceptAddr(server, client, address, flags) - osError(err) + raiseOSError(err) else: client.fd = sock client.isBuffered = server.isBuffered @@ -389,8 +389,8 @@ when false: #defined(ssl): acceptAddrPlain(AcceptNoClient, AcceptSuccess): doHandshake() -proc accept*(server: PSocket, client: var PSocket, - flags = {TSocketFlags.SafeDisconn}) {.tags: [FReadIO].} = +proc accept*(server: Socket, client: var Socket, + flags = {SocketFlag.SafeDisconn}) {.tags: [ReadIOEffect].} = ## Equivalent to ``acceptAddr`` but doesn't return the address, only the ## socket. ## @@ -404,7 +404,7 @@ proc accept*(server: PSocket, client: var PSocket, var addrDummy = "" acceptAddr(server, client, addrDummy, flags) -proc close*(socket: PSocket) = +proc close*(socket: Socket) = ## Closes a socket. socket.fd.close() when defined(ssl): @@ -416,7 +416,7 @@ proc close*(socket: PSocket) = elif res != 1: socketError(socket) -proc toCInt(opt: TSOBool): cint = +proc toCInt(opt: SOBool): cint = case opt of OptAcceptConn: SO_ACCEPTCONN of OptBroadcast: SO_BROADCAST @@ -426,20 +426,20 @@ proc toCInt(opt: TSOBool): cint = of OptOOBInline: SO_OOBINLINE of OptReuseAddr: SO_REUSEADDR -proc getSockOpt*(socket: PSocket, opt: TSOBool, level = SOL_SOCKET): bool {. - tags: [FReadIO].} = +proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {. + tags: [ReadIOEffect].} = ## Retrieves option ``opt`` as a boolean value. - var res = getsockoptint(socket.fd, cint(level), toCInt(opt)) + var res = getSockOptInt(socket.fd, cint(level), toCInt(opt)) result = res != 0 -proc setSockOpt*(socket: PSocket, opt: TSOBool, value: bool, level = SOL_SOCKET) {. - tags: [FWriteIO].} = +proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {. + tags: [WriteIOEffect].} = ## Sets option ``opt`` to a boolean value specified by ``value``. var valuei = cint(if value: 1 else: 0) - setsockoptint(socket.fd, cint(level), toCInt(opt), valuei) + setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei) -proc connect*(socket: PSocket, address: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [FReadIO].} = +proc connect*(socket: Socket, address: string, port = Port(0), + af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## Connects socket to ``address``:``port``. ``Address`` can be an IP address or a ## host name. If ``address`` is a host name, this function will try each IP ## of that host name. ``htons`` is already performed on ``port`` so you must @@ -449,7 +449,7 @@ proc connect*(socket: PSocket, address: string, port = TPort(0), var aiList = getAddrInfo(address, port, af) # try all possibilities: var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) == 0'i32: @@ -459,7 +459,7 @@ proc connect*(socket: PSocket, address: string, port = TPort(0), it = it.ai_next dealloc(aiList) - if not success: osError(lastError) + if not success: raiseOSError(lastError) when defined(ssl): if socket.isSSL: @@ -507,7 +507,7 @@ when defined(ssl): else: SSLError("Socket is not an SSL socket.") -proc hasDataBuffered*(s: PSocket): bool = +proc hasDataBuffered*(s: Socket): bool = ## Determines whether a socket has data buffered. result = false if s.isBuffered: @@ -517,15 +517,15 @@ proc hasDataBuffered*(s: PSocket): bool = if s.isSSL and not result: result = s.sslHasPeekChar -proc select(readfd: PSocket, timeout = 500): int = +proc select(readfd: Socket, timeout = 500): int = ## Used for socket operation timeouts. if readfd.hasDataBuffered: return 1 - var fds = @[readFd.fd] + var fds = @[readfd.fd] result = select(fds, timeout) -proc readIntoBuf(socket: PSocket, flags: int32): int = +proc readIntoBuf(socket: Socket, flags: int32): int = result = 0 when defined(ssl): if socket.isSSL: @@ -549,7 +549,7 @@ template retRead(flags, readBytes: int) {.dirty.} = else: return res -proc recv*(socket: PSocket, data: pointer, size: int): int {.tags: [FReadIO].} = +proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [ReadIOEffect].} = ## Receives data from a socket. ## ## **Note**: This is a low-level function, you may be interested in the higher @@ -590,8 +590,8 @@ proc recv*(socket: PSocket, data: pointer, size: int): int {.tags: [FReadIO].} = else: result = recv(socket.fd, data, size.cint, 0'i32) -proc waitFor(socket: PSocket, waited: var float, timeout, size: int, - funcName: string): int {.tags: [FTime].} = +proc waitFor(socket: Socket, waited: var float, timeout, size: int, + funcName: string): int {.tags: [TimeEffect].} = ## determines the amount of characters that can be read. Result will never ## be larger than ``size``. For unbuffered sockets this will be ``1``. ## For buffered sockets it can be as big as ``BufferSize``. @@ -606,7 +606,7 @@ proc waitFor(socket: PSocket, waited: var float, timeout, size: int, result = min(result, size) else: if timeout - int(waited * 1000.0) < 1: - raise newException(ETimeout, "Call to '" & funcName & "' timed out.") + raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") when defined(ssl): if socket.isSSL: @@ -619,13 +619,13 @@ proc waitFor(socket: PSocket, waited: var float, timeout, size: int, var startTime = epochTime() let selRet = select(socket, timeout - int(waited * 1000.0)) - if selRet < 0: osError(osLastError()) + if selRet < 0: raiseOSError(osLastError()) if selRet != 1: - raise newException(ETimeout, "Call to '" & funcName & "' timed out.") + raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") waited += (epochTime() - startTime) -proc recv*(socket: PSocket, data: pointer, size: int, timeout: int): int {. - tags: [FReadIO, FTime].} = +proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. + tags: [ReadIOEffect, FTime].} = ## overload with a ``timeout`` parameter in miliseconds. var waited = 0.0 # number of seconds already waited @@ -642,8 +642,8 @@ proc recv*(socket: PSocket, data: pointer, size: int, timeout: int): int {. result = read -proc recv*(socket: PSocket, data: var string, size: int, timeout = -1, - flags = {TSocketFlags.SafeDisconn}): int = +proc recv*(socket: Socket, data: var string, size: int, timeout = -1, + flags = {SocketFlag.SafeDisconn}): int = ## Higher-level version of ``recv``. ## ## When 0 is returned the socket's connection has been closed. @@ -666,7 +666,7 @@ proc recv*(socket: PSocket, data: var string, size: int, timeout = -1, socket.socketError(result, lastError = lastError) data.setLen(result) -proc peekChar(socket: PSocket, c: var char): int {.tags: [FReadIO].} = +proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} = if socket.isBuffered: result = 1 if socket.bufLen == 0 or socket.currPos > socket.bufLen-1: @@ -686,9 +686,9 @@ proc peekChar(socket: PSocket, c: var char): int {.tags: [FReadIO].} = return result = recv(socket.fd, addr(c), 1, MSG_PEEK) -proc readLine*(socket: PSocket, line: var TaintedString, timeout = -1, - flags = {TSocketFlags.SafeDisconn}) {. - tags: [FReadIO, FTime].} = +proc readLine*(socket: Socket, line: var TaintedString, timeout = -1, + flags = {SocketFlag.SafeDisconn}) {. + tags: [ReadIOEffect, FTime].} = ## Reads a line of data from ``socket``. ## ## If a full line is read ``\r\L`` is not @@ -735,9 +735,9 @@ proc readLine*(socket: PSocket, line: var TaintedString, timeout = -1, return add(line.string, c) -proc recvFrom*(socket: PSocket, data: var string, length: int, - address: var string, port: var TPort, flags = 0'i32): int {. - tags: [FReadIO].} = +proc recvFrom*(socket: Socket, data: var string, length: int, + address: var string, port: var Port, flags = 0'i32): int {. + tags: [ReadIOEffect].} = ## Receives data from ``socket``. This function should normally be used with ## connection-less sockets (UDP sockets). ## @@ -751,7 +751,7 @@ proc recvFrom*(socket: PSocket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) - var sockAddress: Tsockaddr_in + var sockAddress: TSockaddr_in var addrLen = sizeof(sockAddress).TSocklen result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) @@ -759,11 +759,11 @@ proc recvFrom*(socket: PSocket, data: var string, length: int, if result != -1: data.setLen(result) address = $inet_ntoa(sockAddress.sin_addr) - port = ntohs(sockAddress.sin_port).TPort + port = ntohs(sockAddress.sin_port).Port else: - osError(osLastError()) + raiseOSError(osLastError()) -proc skip*(socket: PSocket, size: int, timeout = -1) = +proc skip*(socket: Socket, size: int, timeout = -1) = ## Skips ``size`` amount of bytes. ## ## An optional timeout can be specified in miliseconds, if skipping the @@ -778,8 +778,8 @@ proc skip*(socket: PSocket, size: int, timeout = -1) = bytesSkipped += recv(socket, dummy, avail) dealloc(dummy) -proc send*(socket: PSocket, data: pointer, size: int): int {. - tags: [FWriteIO].} = +proc send*(socket: Socket, data: pointer, size: int): int {. + tags: [WriteIOEffect].} = ## Sends data to a socket. ## ## **Note**: This is a low-level version of ``send``. You likely should use @@ -795,8 +795,8 @@ proc send*(socket: PSocket, data: pointer, size: int): int {. const MSG_NOSIGNAL = 0 result = send(socket.fd, data, size, int32(MSG_NOSIGNAL)) -proc send*(socket: PSocket, data: string, - flags = {TSocketFlags.SafeDisconn}) {.tags: [FWriteIO].} = +proc send*(socket: Socket, data: string, + flags = {SocketFlag.SafeDisconn}) {.tags: [WriteIOEffect].} = ## sends data to a socket. let sent = send(socket, cstring(data), data.len) if sent < 0: @@ -805,16 +805,16 @@ proc send*(socket: PSocket, data: string, socketError(socket, lastError = lastError) if sent != data.len: - raise newException(EOS, "Could not send all data.") + raise newException(OSError, "Could not send all data.") -proc trySend*(socket: PSocket, data: string): bool {.tags: [FWriteIO].} = +proc trySend*(socket: Socket, data: string): bool {.tags: [WriteIOEffect].} = ## Safe alternative to ``send``. Does not raise an EOS when an error occurs, ## and instead returns ``false`` on failure. result = send(socket, cstring(data), data.len) == data.len -proc sendTo*(socket: PSocket, address: string, port: TPort, data: pointer, - size: int, af: TDomain = AF_INET, flags = 0'i32): int {. - tags: [FWriteIO].} = +proc sendTo*(socket: Socket, address: string, port: Port, data: pointer, + size: int, af: Domain = AF_INET, flags = 0'i32): int {. + tags: [WriteIOEffect].} = ## This proc sends ``data`` to the specified ``address``, ## which may be an IP address or a hostname, if a hostname is specified ## this function will try each IP of that hostname. @@ -839,8 +839,8 @@ proc sendTo*(socket: PSocket, address: string, port: TPort, data: pointer, dealloc(aiList) -proc sendTo*(socket: PSocket, address: string, port: TPort, - data: string): int {.tags: [FWriteIO].} = +proc sendTo*(socket: Socket, address: string, port: Port, + data: string): int {.tags: [WriteIOEffect].} = ## This proc sends ``data`` to the specified ``address``, ## which may be an IP address or a hostname, if a hostname is specified ## this function will try each IP of that hostname. @@ -848,8 +848,8 @@ proc sendTo*(socket: PSocket, address: string, port: TPort, ## This is the high-level version of the above ``sendTo`` function. result = socket.sendTo(address, port, cstring(data), data.len) -proc connectAsync(socket: PSocket, name: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [FReadIO].} = +proc connectAsync(socket: Socket, name: string, port = Port(0), + af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## A variant of ``connect`` for non-blocking sockets. ## ## This procedure will immediatelly return, it will not block until a connection @@ -861,7 +861,7 @@ proc connectAsync(socket: PSocket, name: string, port = TPort(0), var aiList = getAddrInfo(name, port, af) # try all possibilities: var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) @@ -883,10 +883,10 @@ proc connectAsync(socket: PSocket, name: string, port = TPort(0), it = it.ai_next dealloc(aiList) - if not success: osError(lastError) + if not success: raiseOSError(lastError) -proc connect*(socket: PSocket, address: string, port = TPort(0), timeout: int, - af: TDomain = AF_INET) {.tags: [FReadIO, FWriteIO].} = +proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, + af: Domain = AF_INET) {.tags: [ReadIOEffect, FWriteIO].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## ## The ``timeout`` paremeter specifies the time in miliseconds to allow for @@ -896,7 +896,7 @@ proc connect*(socket: PSocket, address: string, port = TPort(0), timeout: int, socket.connectAsync(address, port, af) var s = @[socket.fd] if selectWrite(s, timeout) != 1: - raise newException(ETimeout, "Call to 'connect' timed out.") + raise newException(TimeoutError, "Call to 'connect' timed out.") else: when defined(ssl): if socket.isSSL: @@ -904,10 +904,10 @@ proc connect*(socket: PSocket, address: string, port = TPort(0), timeout: int, doAssert socket.handshake() socket.fd.setBlocking(true) -proc isSSL*(socket: PSocket): bool = return socket.isSSL +proc isSSL*(socket: Socket): bool = return socket.isSSL ## Determines whether ``socket`` is a SSL socket. -proc getFD*(socket: PSocket): TSocketHandle = return socket.fd +proc getFD*(socket: Socket): TSocketHandle = return socket.fd ## Returns the socket's file descriptor type @@ -1042,23 +1042,23 @@ proc parseIPv4Address(address_str: string): TIpAddress = currentByte = currentByte * 10 + cast[uint16](ord(address_str[i]) - ord('0')) if currentByte > 255'u16: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Value is out of range") seperatorValid = true elif address_str[i] == '.': # IPv4 address separator if not seperatorValid or byteCount >= 3: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") result.address_v4[byteCount] = cast[uint8](currentByte) currentByte = 0 byteCount.inc seperatorValid = false else: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains an invalid character") if byteCount != 3 or not seperatorValid: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") result.address_v4[byteCount] = cast[uint8](currentByte) proc parseIPv6Address(address_str: string): TIpAddress = @@ -1066,7 +1066,7 @@ proc parseIPv6Address(address_str: string): TIpAddress = ## Raises EInvalidValue on errors result.family = IpAddressFamily.IPv6 if address_str.len < 2: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") var groupCount = 0 @@ -1081,17 +1081,17 @@ proc parseIPv6Address(address_str: string): TIpAddress = for i,c in address_str: if c == ':': if not seperatorValid: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains an invalid seperator") if lastWasColon: if dualColonGroup != -1: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains more than one \"::\" seperator") dualColonGroup = groupCount seperatorValid = false elif i != 0 and i != high(address_str): if groupCount >= 8: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8) result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF) @@ -1100,17 +1100,17 @@ proc parseIPv6Address(address_str: string): TIpAddress = if dualColonGroup != -1: seperatorValid = false elif i == 0: # only valid if address starts with :: if address_str[1] != ':': - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address may not start with \":\"") else: # i == high(address_str) - only valid if address ends with :: if address_str[high(address_str)-1] != ':': - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address may not end with \":\"") lastWasColon = true currentGroupStart = i + 1 elif c == '.': # Switch to parse IPv4 mode if i < 3 or not seperatorValid or groupCount >= 7: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") v4StartPos = currentGroupStart currentShort = 0 seperatorValid = false @@ -1123,19 +1123,19 @@ proc parseIPv6Address(address_str: string): TIpAddress = else: # Upper case hex currentShort = (currentShort shl 4) + cast[uint32](ord(c) - ord('A')) + 10 if currentShort > 65535'u32: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Value is out of range") lastWasColon = false seperatorValid = true else: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains an invalid character") if v4StartPos == -1: # Don't parse v4. Copy the remaining v6 stuff if seperatorValid: # Copy remaining data if groupCount >= 8: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") result.address_v6[groupCount*2] = cast[uint8](currentShort shr 8) result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF) @@ -1145,32 +1145,32 @@ proc parseIPv6Address(address_str: string): TIpAddress = if c in strutils.Digits: # Character is a number currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0')) if currentShort > 255'u32: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Value is out of range") seperatorValid = true elif c == '.': # IPv4 address separator if not seperatorValid or byteCount >= 3: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort) currentShort = 0 byteCount.inc() seperatorValid = false else: # Invalid character - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. Address contains an invalid character") if byteCount != 3 or not seperatorValid: - raise newException(EInvalidValue, "Invalid IP Address") + raise newException(ValueError, "Invalid IP Address") result.address_v6[groupCount*2 + byteCount] = cast[uint8](currentShort) groupCount += 2 # Shift and fill zeros in case of :: if groupCount > 8: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") elif groupCount < 8: # must fill if dualColonGroup == -1: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too few groups") var toFill = 8 - groupCount # The number of groups to fill var toShift = groupCount - dualColonGroup # Nr of known groups after :: @@ -1179,14 +1179,14 @@ proc parseIPv6Address(address_str: string): TIpAddress = for i in 0..2*toFill-1: # fill with 0s result.address_v6[dualColonGroup*2+i] = 0 elif dualColonGroup != -1: - raise newException(EInvalidValue, + raise newException(ValueError, "Invalid IP Address. The address consists of too many groups") proc parseIpAddress*(address_str: string): TIpAddress = ## Parses an IP address ## Raises EInvalidValue on error if address_str == nil: - raise newException(EInvalidValue, "IP Address string is nil") + raise newException(ValueError, "IP Address string is nil") if address_str.contains(':'): return parseIPv6Address(address_str) else: diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index 14a494ecf..f3517fc3c 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -14,7 +14,7 @@ import unsigned, os -when hostos == "solaris": +when hostOS == "solaris": {.passl: "-lsocket -lnsl".} const useWinVersion = defined(Windows) or defined(nimdoc) @@ -156,7 +156,7 @@ proc newRawSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, proc close*(socket: SocketHandle) = ## closes a socket. when useWinVersion: - discard winlean.closeSocket(socket) + discard winlean.closesocket(socket) else: discard posix.close(socket) # TODO: These values should not be discarded. An EOS should be raised. @@ -165,7 +165,7 @@ proc close*(socket: SocketHandle) = proc bindAddr*(socket: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint = result = bindSocket(socket, name, namelen) -proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [FReadIO].} = +proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. @@ -223,7 +223,7 @@ proc htons*(x: int16): int16 = ## order, this is a no-op; otherwise, it performs a 2-byte swap operation. result = rawsockets.ntohs(x) -proc getServByName*(name, proto: string): Servent {.tags: [FReadIO].} = +proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the service name specified by ``name`` matches the s_name member ## and the protocol name specified by ``proto`` matches the s_proto member. @@ -233,13 +233,13 @@ proc getServByName*(name, proto: string): Servent {.tags: [FReadIO].} = var s = winlean.getservbyname(name, proto) else: var s = posix.getservbyname(name, proto) - if s == nil: raise newException(EOS, "Service not found.") + if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) result.port = Port(s.s_port) result.proto = $s.s_proto -proc getServByPort*(port: Port, proto: string): Servent {.tags: [FReadIO].} = +proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the port specified by ``port`` matches the s_port member and the ## protocol name specified by ``proto`` matches the s_proto member. @@ -249,13 +249,13 @@ proc getServByPort*(port: Port, proto: string): Servent {.tags: [FReadIO].} = var s = winlean.getservbyport(ze(int16(port)).cint, proto) else: var s = posix.getservbyport(ze(int16(port)).cint, proto) - if s == nil: raise newException(EOS, "Service not found.") + if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) result.port = Port(s.s_port) result.proto = $s.s_proto -proc getHostByAddr*(ip: string): Hostent {.tags: [FReadIO].} = +proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} = ## This function will lookup the hostname of an IP Address. var myaddr: InAddr myaddr.s_addr = inet_addr(ip) @@ -284,7 +284,7 @@ proc getHostByAddr*(ip: string): Hostent {.tags: [FReadIO].} = result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getHostByName*(name: string): Hostent {.tags: [FReadIO].} = +proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} = ## This function will lookup the IP address of a hostname. when useWinVersion: var s = winlean.gethostbyname(name) @@ -314,28 +314,28 @@ proc getSockName*(socket: SocketHandle): Port = name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).Socklen + var namelen = sizeof(name).SockLen if getsockname(socket, cast[ptr SockAddr](addr(name)), addr(namelen)) == -1'i32: raiseOSError(osLastError()) result = Port(rawsockets.ntohs(name.sin_port)) proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {. - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).Socklen + var size = sizeof(res).SockLen if getsockopt(socket, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: raiseOSError(osLastError()) result = int(res) proc setSockOptInt*(socket: SocketHandle, level, optname, optval: int) {. - tags: [FWriteIO].} = + tags: [WriteIOEffect].} = ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket, cint(level), cint(optname), addr(value), - sizeof(value).Socklen) < 0'i32: + sizeof(value).SockLen) < 0'i32: raiseOSError(osLastError()) proc setBlocking*(s: SocketHandle, blocking: bool) = @@ -361,13 +361,13 @@ proc timeValFromMilliseconds(timeout = 500): Timeval = result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var FdSet, s: seq[SocketHandle], m: var int) = +proc createFdSet(fd: var FD_SET, s: seq[SocketHandle], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i)) FD_SET(i, fd) -proc pruneSocketSet(s: var seq[SocketHandle], fd: var FdSet) = +proc pruneSocketSet(s: var seq[SocketHandle], fd: var FD_SET) = var i = 0 var L = s.len while i < L: @@ -386,7 +386,7 @@ proc select*(readfds: var seq[SocketHandle], timeout = 500): int = ## ## A socket is removed from the specific ``seq`` when it has data waiting to ## be read/written to or has errors (``exceptfds``). - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) var rd: TFdSet var m = 0 @@ -400,7 +400,7 @@ proc select*(readfds: var seq[SocketHandle], timeout = 500): int = pruneSocketSet(readfds, (rd)) proc selectWrite*(writefds: var seq[SocketHandle], - timeout = 500): int {.tags: [FReadIO].} = + timeout = 500): int {.tags: [ReadIOEffect].} = ## When a socket in ``writefds`` is ready to be written to then a non-zero ## value will be returned specifying the count of the sockets which can be ## written to. The sockets which can be written to will also be removed diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 55ae87a1f..53284cfdc 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -425,7 +425,7 @@ type TFdSet* {.pure, final.} = object fd_count*: cint # unsigned - fd_array*: array[0..FD_SETSIZE-1, TSocketHandle] + fd_array*: array[0..FD_SETSIZE-1, SocketHandle] TTimeval* {.pure, final.} = object tv_sec*, tv_usec*: int32 @@ -444,7 +444,7 @@ type var SOMAXCONN* {.importc, header: "Winsock2.h".}: cint - INVALID_SOCKET* {.importc, header: "Winsock2.h".}: TSocketHandle + INVALID_SOCKET* {.importc, header: "Winsock2.h".}: SocketHandle SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen() @@ -460,7 +460,7 @@ var SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse SO_ERROR* {.importc, header: "Winsock2.h".}: cint -proc `==`*(x, y: TSocketHandle): bool {.borrow.} +proc `==`*(x, y: SocketHandle): bool {.borrow.} proc getservbyname*(name, proto: cstring): ptr TServent {. stdcall, importc: "getservbyname", dynlib: ws2dll.} @@ -474,45 +474,45 @@ proc gethostbyaddr*(ip: ptr TInAddr, len: cuint, theType: cint): ptr Thostent {. proc gethostbyname*(name: cstring): ptr Thostent {. stdcall, importc: "gethostbyname", dynlib: ws2dll.} -proc socket*(af, typ, protocol: cint): TSocketHandle {. +proc socket*(af, typ, protocol: cint): SocketHandle {. stdcall, importc: "socket", dynlib: ws2dll.} -proc closesocket*(s: TSocketHandle): cint {. +proc closesocket*(s: SocketHandle): cint {. stdcall, importc: "closesocket", dynlib: ws2dll.} -proc accept*(s: TSocketHandle, a: ptr TSockAddr, addrlen: ptr TSockLen): TSocketHandle {. +proc accept*(s: SocketHandle, a: ptr TSockAddr, addrlen: ptr TSockLen): SocketHandle {. stdcall, importc: "accept", dynlib: ws2dll.} -proc bindSocket*(s: TSocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. +proc bindSocket*(s: SocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. stdcall, importc: "bind", dynlib: ws2dll.} -proc connect*(s: TSocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. +proc connect*(s: SocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. stdcall, importc: "connect", dynlib: ws2dll.} -proc getsockname*(s: TSocketHandle, name: ptr TSockAddr, +proc getsockname*(s: SocketHandle, name: ptr TSockAddr, namelen: ptr TSockLen): cint {. stdcall, importc: "getsockname", dynlib: ws2dll.} -proc getsockopt*(s: TSocketHandle, level, optname: cint, optval: pointer, +proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer, optlen: ptr TSockLen): cint {. stdcall, importc: "getsockopt", dynlib: ws2dll.} -proc setsockopt*(s: TSocketHandle, level, optname: cint, optval: pointer, +proc setsockopt*(s: SocketHandle, level, optname: cint, optval: pointer, optlen: TSockLen): cint {. stdcall, importc: "setsockopt", dynlib: ws2dll.} -proc listen*(s: TSocketHandle, backlog: cint): cint {. +proc listen*(s: SocketHandle, backlog: cint): cint {. stdcall, importc: "listen", dynlib: ws2dll.} -proc recv*(s: TSocketHandle, buf: pointer, len, flags: cint): cint {. +proc recv*(s: SocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "recv", dynlib: ws2dll.} -proc recvfrom*(s: TSocketHandle, buf: cstring, len, flags: cint, +proc recvfrom*(s: SocketHandle, buf: cstring, len, flags: cint, fromm: ptr TSockAddr, fromlen: ptr TSockLen): cint {. stdcall, importc: "recvfrom", dynlib: ws2dll.} proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet, timeout: ptr TTimeval): cint {. stdcall, importc: "select", dynlib: ws2dll.} -proc send*(s: TSocketHandle, buf: pointer, len, flags: cint): cint {. +proc send*(s: SocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "send", dynlib: ws2dll.} -proc sendto*(s: TSocketHandle, buf: pointer, len, flags: cint, +proc sendto*(s: SocketHandle, buf: pointer, len, flags: cint, to: ptr TSockAddr, tolen: TSockLen): cint {. stdcall, importc: "sendto", dynlib: ws2dll.} -proc shutdown*(s: TSocketHandle, how: cint): cint {. +proc shutdown*(s: SocketHandle, how: cint): cint {. stdcall, importc: "shutdown", dynlib: ws2dll.} proc getnameinfo*(a1: ptr TSockAddr, a2: TSockLen, @@ -523,13 +523,13 @@ proc getnameinfo*(a1: ptr TSockAddr, a2: TSockLen, proc inet_addr*(cp: cstring): int32 {. stdcall, importc: "inet_addr", dynlib: ws2dll.} -proc WSAFDIsSet(s: TSocketHandle, FDSet: var TFdSet): bool {. +proc WSAFDIsSet(s: SocketHandle, FDSet: var TFdSet): bool {. stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll, noSideEffect.} -proc FD_ISSET*(Socket: TSocketHandle, FDSet: var TFdSet): cint = +proc FD_ISSET*(Socket: SocketHandle, FDSet: var TFdSet): cint = result = if WSAFDIsSet(Socket, FDSet): 1'i32 else: 0'i32 -proc FD_SET*(Socket: TSocketHandle, FDSet: var TFdSet) = +proc FD_SET*(Socket: SocketHandle, FDSet: var TFdSet) = if FDSet.fd_count < FD_SETSIZE: FDSet.fd_array[int(FDSet.fd_count)] = Socket inc(FDSet.fd_count) @@ -699,7 +699,7 @@ var WSAID_GETACCEPTEXSOCKADDRS*: TGUID = TGUID(D1: 0xb5367df2'i32, D2: 0xcbac'i16, D3: 0x11cf, D4: [ 0x95'i8, 0xca'i8, 0x00'i8, 0x80'i8, 0x5f'i8, 0x48'i8, 0xa1'i8, 0x92'i8]) -proc WSAIoctl*(s: TSocketHandle, dwIoControlCode: DWORD, lpvInBuffer: pointer, +proc WSAIoctl*(s: SocketHandle, dwIoControlCode: DWORD, lpvInBuffer: pointer, cbInBuffer: DWORD, lpvOutBuffer: pointer, cbOutBuffer: DWORD, lpcbBytesReturned: PDWORD, lpOverlapped: POVERLAPPED, lpCompletionRoutine: POVERLAPPED_COMPLETION_ROUTINE): cint @@ -710,12 +710,12 @@ type len*: ULONG buf*: cstring -proc WSARecv*(s: TSocketHandle, buf: ptr TWSABuf, bufCount: DWORD, +proc WSARecv*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD, bytesReceived, flags: PDWORD, lpOverlapped: POVERLAPPED, completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {. stdcall, importc: "WSARecv", dynlib: "Ws2_32.dll".} -proc WSASend*(s: TSocketHandle, buf: ptr TWSABuf, bufCount: DWORD, +proc WSASend*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD, bytesSent: PDWORD, flags: DWORD, lpOverlapped: POVERLAPPED, completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {. stdcall, importc: "WSASend", dynlib: "Ws2_32.dll".} From fc5153e9b0d9d6236e4c1dda145f68049163d0c3 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 00:37:15 +0200 Subject: [PATCH 014/409] big rename --- lib/pure/collections/sets.nim | 24 ++++++++++++------------ lib/pure/net.nim | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 994023b3f..4a5471417 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -188,7 +188,7 @@ proc incl*[A](s: var HashSet[A], key: A) = assert s.isValid, "The set needs to be initialized." inclImpl() -proc incl*[A](s: var HashSet[A], other: TSet[A]) = +proc incl*[A](s: var HashSet[A], other: HashSet[A]) = ## Includes all elements from `other` into `s`. ## ## Example: @@ -219,7 +219,7 @@ proc excl*[A](s: var HashSet[A], key: A) = s.data[index].slot = seDeleted dec(s.counter) -proc excl*[A](s: var HashSet[A], other: TSet[A]) = +proc excl*[A](s: var HashSet[A], other: HashSet[A]) = ## Excludes everything in `other` from `s`. ## ## Example: @@ -320,7 +320,7 @@ proc `$`*[A](s: HashSet[A]): string = assert s.isValid, "The set needs to be initialized." dollarImpl() -proc union*[A](s1, s2: HashSet[A]): TSet[A] = +proc union*[A](s1, s2: HashSet[A]): HashSet[A] = ## Returns the union of the sets `s1` and `s2`. ## ## The union of two sets is represented mathematically as *A ∪ B* and is the @@ -337,7 +337,7 @@ proc union*[A](s1, s2: HashSet[A]): TSet[A] = result = s1 incl(result, s2) -proc intersection*[A](s1, s2: HashSet[A]): TSet[A] = +proc intersection*[A](s1, s2: HashSet[A]): HashSet[A] = ## Returns the intersection of the sets `s1` and `s2`. ## ## The intersection of two sets is represented mathematically as *A ∩ B* and @@ -356,7 +356,7 @@ proc intersection*[A](s1, s2: HashSet[A]): TSet[A] = for item in s1: if item in s2: incl(result, item) -proc difference*[A](s1, s2: HashSet[A]): TSet[A] = +proc difference*[A](s1, s2: HashSet[A]): HashSet[A] = ## Returns the difference of the sets `s1` and `s2`. ## ## The difference of two sets is represented mathematically as *A \ B* and is @@ -376,7 +376,7 @@ proc difference*[A](s1, s2: HashSet[A]): TSet[A] = if not contains(s2, item): incl(result, item) -proc symmetricDifference*[A](s1, s2: HashSet[A]): TSet[A] = +proc symmetricDifference*[A](s1, s2: HashSet[A]): HashSet[A] = ## Returns the symmetric difference of the sets `s1` and `s2`. ## ## The symmetric difference of two sets is represented mathematically as *A △ @@ -395,19 +395,19 @@ proc symmetricDifference*[A](s1, s2: HashSet[A]): TSet[A] = for item in s2: if containsOrIncl(result, item): excl(result, item) -proc `+`*[A](s1, s2: HashSet[A]): TSet[A] {.inline.} = +proc `+`*[A](s1, s2: HashSet[A]): HashSet[A] {.inline.} = ## Alias for `union(s1, s2) <#union>`_. result = union(s1, s2) -proc `*`*[A](s1, s2: HashSet[A]): TSet[A] {.inline.} = +proc `*`*[A](s1, s2: HashSet[A]): HashSet[A] {.inline.} = ## Alias for `intersection(s1, s2) <#intersection>`_. result = intersection(s1, s2) -proc `-`*[A](s1, s2: HashSet[A]): TSet[A] {.inline.} = +proc `-`*[A](s1, s2: HashSet[A]): HashSet[A] {.inline.} = ## Alias for `difference(s1, s2) <#difference>`_. result = difference(s1, s2) -proc `-+-`*[A](s1, s2: HashSet[A]): TSet[A] {.inline.} = +proc `-+-`*[A](s1, s2: HashSet[A]): HashSet[A] {.inline.} = ## Alias for `symmetricDifference(s1, s2) <#symmetricDifference>`_. result = symmetricDifference(s1, s2) @@ -477,7 +477,7 @@ proc `==`*[A](s, t: HashSet[A]): bool = ## assert a == b s.counter == t.counter and s <= t -proc map*[A, B](data: HashSet[A], op: proc (x: A): B {.closure.}): TSet[B] = +proc map*[A, B](data: HashSet[A], op: proc (x: A): B {.closure.}): HashSet[B] = ## Returns a new set after applying `op` on each of the elements of `data`. ## ## You can use this proc to transform the elements from a set. Example: @@ -621,7 +621,7 @@ proc incl*[A](s: var OrderedSet[A], key: A) = assert s.isValid, "The set needs to be initialized." inclImpl() -proc incl*[A](s: var HashSet[A], other: TOrderedSet[A]) = +proc incl*[A](s: var HashSet[A], other: OrderedSet[A]) = ## Includes all elements from `other` into `s`. ## ## Example: diff --git a/lib/pure/net.nim b/lib/pure/net.nim index a64294a77..ff3c1e683 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -625,7 +625,7 @@ proc waitFor(socket: Socket, waited: var float, timeout, size: int, waited += (epochTime() - startTime) proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. - tags: [ReadIOEffect, FTime].} = + tags: [ReadIOEffect, TimeEffect].} = ## overload with a ``timeout`` parameter in miliseconds. var waited = 0.0 # number of seconds already waited @@ -688,7 +688,7 @@ proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} = proc readLine*(socket: Socket, line: var TaintedString, timeout = -1, flags = {SocketFlag.SafeDisconn}) {. - tags: [ReadIOEffect, FTime].} = + tags: [ReadIOEffect, TimeEffect].} = ## Reads a line of data from ``socket``. ## ## If a full line is read ``\r\L`` is not @@ -886,7 +886,7 @@ proc connectAsync(socket: Socket, name: string, port = Port(0), if not success: raiseOSError(lastError) proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, - af: Domain = AF_INET) {.tags: [ReadIOEffect, FWriteIO].} = + af: Domain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## ## The ``timeout`` paremeter specifies the time in miliseconds to allow for From dcffbb052a88bebf3acfc1b5410a9737f2aa7719 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 01:17:21 +0200 Subject: [PATCH 015/409] big rename --- lib/posix/posix.nim | 157 +++++++++++++++++++++------------------- lib/pure/os.nim | 2 +- lib/pure/rawsockets.nim | 34 ++++----- lib/pure/uri.nim | 2 +- lib/windows/winlean.nim | 109 +++++++++++++++------------- 5 files changed, 158 insertions(+), 146 deletions(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 43139389b..d8f329e34 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -384,12 +384,12 @@ type sched_ss_max_repl*: cint ## Maximum pending replenishments for ## sporadic server. - Ttimeval* {.importc: "struct timeval", header: "", - final, pure.} = object ## struct timeval + Timeval* {.importc: "struct timeval", header: "", + final, pure.} = object ## struct timeval tv_sec*: int ## Seconds. tv_usec*: int ## Microseconds. - TFdSet* {.importc: "fd_set", header: "", - final, pure.} = object + FdSet* {.importc: "fd_set", header: "", + final, pure.} = object Tmcontext* {.importc: "mcontext_t", header: "", final, pure.} = object Tucontext* {.importc: "ucontext_t", header: "", @@ -422,11 +422,11 @@ when hasSpawnH: header: "", final, pure.} = object type - TSocklen* {.importc: "socklen_t", header: "".} = cuint + Socklen* {.importc: "socklen_t", header: "".} = cuint TSa_Family* {.importc: "sa_family_t", header: "".} = cint - TSockAddr* {.importc: "struct sockaddr", header: "", - pure, final.} = object ## struct sockaddr + SockAddr* {.importc: "struct sockaddr", header: "", + pure, final.} = object ## struct sockaddr sa_family*: TSa_Family ## Address family. sa_data*: array [0..255, char] ## Socket address (variable-length data). @@ -474,15 +474,15 @@ type TInAddrT* {.importc: "in_addr_t", pure, final, header: "".} = int32 ## unsigned! - TInAddr* {.importc: "struct in_addr", pure, final, + InAddr* {.importc: "struct in_addr", pure, final, header: "".} = object ## struct in_addr s_addr*: TInAddrScalar - Tsockaddr_in* {.importc: "struct sockaddr_in", pure, final, + Sockaddr_in* {.importc: "struct sockaddr_in", pure, final, header: "".} = object ## struct sockaddr_in sin_family*: TSa_Family ## AF_INET. sin_port*: TInPort ## Port number. - sin_addr*: TInAddr ## IP address. + sin_addr*: InAddr ## IP address. TIn6Addr* {.importc: "struct in6_addr", pure, final, header: "".} = object ## struct in6_addr @@ -501,7 +501,7 @@ type ipv6mr_multiaddr*: TIn6Addr ## IPv6 multicast address. ipv6mr_interface*: cint ## Interface index. - Thostent* {.importc: "struct hostent", pure, final, + Hostent* {.importc: "struct hostent", pure, final, header: "".} = object ## struct hostent h_name*: cstring ## Official name of the host. h_aliases*: cstringArray ## A pointer to an array of pointers to @@ -531,8 +531,8 @@ type ## a null pointer. p_proto*: cint ## The protocol number. - TServent* {.importc: "struct servent", pure, final, - header: "".} = object ## struct servent + Servent* {.importc: "struct servent", pure, final, + header: "".} = object ## struct servent s_name*: cstring ## Official name of the service. s_aliases*: cstringArray ## A pointer to an array of pointers to ## alternative service names, terminated by @@ -542,16 +542,16 @@ type s_proto*: cstring ## The name of the protocol to use when ## contacting the service. - Taddrinfo* {.importc: "struct addrinfo", pure, final, + AddrInfo* {.importc: "struct addrinfo", pure, final, header: "".} = object ## struct addrinfo ai_flags*: cint ## Input flags. ai_family*: cint ## Address family of socket. ai_socktype*: cint ## Socket type. ai_protocol*: cint ## Protocol of socket. - ai_addrlen*: TSocklen ## Length of socket address. - ai_addr*: ptr TSockAddr ## Socket address of socket. + ai_addrlen*: Socklen ## Length of socket address. + ai_addr*: ptr SockAddr ## Socket address of socket. ai_canonname*: cstring ## Canonical name of service location. - ai_next*: ptr Taddrinfo ## Pointer to next in list. + ai_next*: ptr AddrInfo ## Pointer to next in list. TPollfd* {.importc: "struct pollfd", pure, final, header: "".} = object ## struct pollfd @@ -561,6 +561,11 @@ type Tnfds* {.importc: "nfds_t", header: "".} = cint +{.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo, + TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval, + TFdSet: FdSet, Thostent: Hostent, TServent: Servent, + TInAddr: InAddr, Tin6_addr: In6_addr, Tsockaddr_in6: Sockaddr_in6].} + var errno* {.importc, header: "".}: cint ## error variable h_errno* {.importc, header: "".}: cint @@ -1787,18 +1792,18 @@ proc ntohl*(a1: int32): int32 {.importc, header: "".} proc ntohs*(a1: int16): int16 {.importc, header: "".} proc inet_addr*(a1: cstring): TInAddrT {.importc, header: "".} -proc inet_ntoa*(a1: TInAddr): cstring {.importc, header: "".} +proc inet_ntoa*(a1: InAddr): cstring {.importc, header: "".} proc inet_ntop*(a1: cint, a2: pointer, a3: cstring, a4: int32): cstring {. importc, header: "".} proc inet_pton*(a1: cint, a2: cstring, a3: pointer): cint {. importc, header: "".} var - in6addr_any* {.importc, header: "".}: TIn6Addr - in6addr_loopback* {.importc, header: "".}: TIn6Addr + in6addr_any* {.importc, header: "".}: In6_addr + in6addr_loopback* {.importc, header: "".}: In6_addr -proc IN6ADDR_ANY_INIT* (): TIn6Addr {.importc, header: "".} -proc IN6ADDR_LOOPBACK_INIT* (): TIn6Addr {.importc, header: "".} +proc IN6ADDR_ANY_INIT* (): In6_addr {.importc, header: "".} +proc IN6ADDR_LOOPBACK_INIT* (): In6_addr {.importc, header: "".} # dirent.h proc closedir*(a1: ptr TDIR): cint {.importc, header: "".} @@ -1817,7 +1822,7 @@ proc dlopen*(a1: cstring, a2: cint): pointer {.importc, header: "".} proc dlsym*(a1: pointer, a2: cstring): pointer {.importc, header: "".} proc creat*(a1: cstring, a2: TMode): cint {.importc, header: "".} -proc fcntl*(a1: cint | TSocketHandle, a2: cint): cint {.varargs, importc, header: "".} +proc fcntl*(a1: cint | SocketHandle, a2: cint): cint {.varargs, importc, header: "".} proc open*(a1: cstring, a2: cint): cint {.varargs, importc, header: "".} proc posix_fadvise*(a1: cint, a2, a3: TOff, a4: cint): cint {. importc, header: "".} @@ -2095,7 +2100,7 @@ proc access*(a1: cstring, a2: cint): cint {.importc, header: "".} proc alarm*(a1: cint): cint {.importc, header: "".} proc chdir*(a1: cstring): cint {.importc, header: "".} proc chown*(a1: cstring, a2: Tuid, a3: TGid): cint {.importc, header: "".} -proc close*(a1: cint | TSocketHandle): cint {.importc, header: "".} +proc close*(a1: cint | SocketHandle): cint {.importc, header: "".} proc confstr*(a1: cint, a2: cstring, a3: int): int {.importc, header: "".} proc crypt*(a1, a2: cstring): cstring {.importc, header: "".} proc ctermid*(a1: cstring): cstring {.importc, header: "".} @@ -2374,15 +2379,15 @@ proc sched_yield*(): cint {.importc, header: "".} proc strerror*(errnum: cint): cstring {.importc, header: "".} proc hstrerror*(herrnum: cint): cstring {.importc, header: "".} -proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "".} -proc FD_ISSET*(a1: cint | TSocketHandle, a2: var TFdSet): cint {. +proc FD_CLR*(a1: cint, a2: var FdSet) {.importc, header: "".} +proc FD_ISSET*(a1: cint | SocketHandle, a2: var FdSet): cint {. importc, header: "".} -proc FD_SET*(a1: cint | TSocketHandle, a2: var TFdSet) {.importc, header: "".} -proc FD_ZERO*(a1: var TFdSet) {.importc, header: "".} +proc fdSet*(a1: cint | SocketHandle, a2: var FdSet) {.importc, header: "".} +proc FD_ZERO*(a1: var FdSet) {.importc, header: "".} -proc pselect*(a1: cint, a2, a3, a4: ptr TFdSet, a5: ptr Ttimespec, +proc pselect*(a1: cint, a2, a3, a4: ptr FdSet, a5: ptr Ttimespec, a6: var Tsigset): cint {.importc, header: "".} -proc select*(a1: cint | TSocketHandle, a2, a3, a4: ptr TFdSet, a5: ptr Ttimeval): cint {. +proc select*(a1: cint | SocketHandle, a2, a3, a4: ptr FdSet, a5: ptr Timeval): cint {. importc, header: "".} when hasSpawnH: @@ -2458,48 +2463,48 @@ proc CMSG_FIRSTHDR*(mhdr: ptr Tmsghdr): ptr Tcmsghdr {. importc, header: "".} const - INVALID_SOCKET* = TSocketHandle(-1) + INVALID_SOCKET* = SocketHandle(-1) -proc `==`*(x, y: TSocketHandle): bool {.borrow.} +proc `==`*(x, y: SocketHandle): bool {.borrow.} -proc accept*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): TSocketHandle {. +proc accept*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr Socklen): SocketHandle {. importc, header: "".} -proc bindSocket*(a1: TSocketHandle, a2: ptr TSockAddr, a3: TSocklen): cint {. +proc bindSocket*(a1: SocketHandle, a2: ptr SockAddr, a3: Socklen): cint {. importc: "bind", header: "".} ## is Posix's ``bind``, because ``bind`` is a reserved word -proc connect*(a1: TSocketHandle, a2: ptr TSockAddr, a3: TSocklen): cint {. +proc connect*(a1: SocketHandle, a2: ptr SockAddr, a3: Socklen): cint {. importc, header: "".} -proc getpeername*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): cint {. +proc getpeername*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr Socklen): cint {. importc, header: "".} -proc getsockname*(a1: TSocketHandle, a2: ptr TSockAddr, a3: ptr TSocklen): cint {. +proc getsockname*(a1: SocketHandle, a2: ptr SockAddr, a3: ptr Socklen): cint {. importc, header: "".} -proc getsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: ptr TSocklen): cint {. +proc getsockopt*(a1: SocketHandle, a2, a3: cint, a4: pointer, a5: ptr Socklen): cint {. importc, header: "".} -proc listen*(a1: TSocketHandle, a2: cint): cint {. +proc listen*(a1: SocketHandle, a2: cint): cint {. importc, header: "".} -proc recv*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {. +proc recv*(a1: SocketHandle, a2: pointer, a3: int, a4: cint): int {. importc, header: "".} -proc recvfrom*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, - a5: ptr TSockAddr, a6: ptr TSocklen): int {. +proc recvfrom*(a1: SocketHandle, a2: pointer, a3: int, a4: cint, + a5: ptr SockAddr, a6: ptr Socklen): int {. importc, header: "".} -proc recvmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {. +proc recvmsg*(a1: SocketHandle, a2: ptr Tmsghdr, a3: cint): int {. importc, header: "".} -proc send*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint): int {. +proc send*(a1: SocketHandle, a2: pointer, a3: int, a4: cint): int {. importc, header: "".} -proc sendmsg*(a1: TSocketHandle, a2: ptr Tmsghdr, a3: cint): int {. +proc sendmsg*(a1: SocketHandle, a2: ptr Tmsghdr, a3: cint): int {. importc, header: "".} -proc sendto*(a1: TSocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr TSockAddr, - a6: TSocklen): int {. +proc sendto*(a1: SocketHandle, a2: pointer, a3: int, a4: cint, a5: ptr SockAddr, + a6: Socklen): int {. importc, header: "".} -proc setsockopt*(a1: TSocketHandle, a2, a3: cint, a4: pointer, a5: TSocklen): cint {. +proc setsockopt*(a1: SocketHandle, a2, a3: cint, a4: pointer, a5: Socklen): cint {. importc, header: "".} -proc shutdown*(a1: TSocketHandle, a2: cint): cint {. +proc shutdown*(a1: SocketHandle, a2: cint): cint {. importc, header: "".} -proc socket*(a1, a2, a3: cint): TSocketHandle {. +proc socket*(a1, a2, a3: cint): SocketHandle {. importc, header: "".} proc sockatmark*(a1: cint): cint {. importc, header: "".} @@ -2512,40 +2517,40 @@ proc if_indextoname*(a1: cint, a2: cstring): cstring {. proc if_nameindex*(): ptr Tif_nameindex {.importc, header: "".} proc if_freenameindex*(a1: ptr Tif_nameindex) {.importc, header: "".} -proc IN6_IS_ADDR_UNSPECIFIED* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_UNSPECIFIED* (a1: ptr In6_addr): cint {. importc, header: "".} ## Unspecified address. -proc IN6_IS_ADDR_LOOPBACK* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_LOOPBACK* (a1: ptr In6_addr): cint {. importc, header: "".} ## Loopback address. -proc IN6_IS_ADDR_MULTICAST* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_MULTICAST* (a1: ptr In6_addr): cint {. importc, header: "".} ## Multicast address. -proc IN6_IS_ADDR_LINKLOCAL* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_LINKLOCAL* (a1: ptr In6_addr): cint {. importc, header: "".} ## Unicast link-local address. -proc IN6_IS_ADDR_SITELOCAL* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_SITELOCAL* (a1: ptr In6_addr): cint {. importc, header: "".} ## Unicast site-local address. -proc IN6_IS_ADDR_V4MAPPED* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_V4MAPPED* (a1: ptr In6_addr): cint {. importc, header: "".} ## IPv4 mapped address. -proc IN6_IS_ADDR_V4COMPAT* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_V4COMPAT* (a1: ptr In6_addr): cint {. importc, header: "".} ## IPv4-compatible address. -proc IN6_IS_ADDR_MC_NODELOCAL* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_MC_NODELOCAL* (a1: ptr In6_addr): cint {. importc, header: "".} ## Multicast node-local address. -proc IN6_IS_ADDR_MC_LINKLOCAL* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_MC_LINKLOCAL* (a1: ptr In6_addr): cint {. importc, header: "".} ## Multicast link-local address. -proc IN6_IS_ADDR_MC_SITELOCAL* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_MC_SITELOCAL* (a1: ptr In6_addr): cint {. importc, header: "".} ## Multicast site-local address. -proc IN6_IS_ADDR_MC_ORGLOCAL* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_MC_ORGLOCAL* (a1: ptr In6_addr): cint {. importc, header: "".} ## Multicast organization-local address. -proc IN6_IS_ADDR_MC_GLOBAL* (a1: ptr TIn6Addr): cint {. +proc IN6_IS_ADDR_MC_GLOBAL* (a1: ptr In6_addr): cint {. importc, header: "".} ## Multicast global address. @@ -2553,21 +2558,21 @@ proc endhostent*() {.importc, header: "".} proc endnetent*() {.importc, header: "".} proc endprotoent*() {.importc, header: "".} proc endservent*() {.importc, header: "".} -proc freeaddrinfo*(a1: ptr Taddrinfo) {.importc, header: "".} +proc freeaddrinfo*(a1: ptr AddrInfo) {.importc, header: "".} proc gai_strerror*(a1: cint): cstring {.importc, header: "".} -proc getaddrinfo*(a1, a2: cstring, a3: ptr Taddrinfo, - a4: var ptr Taddrinfo): cint {.importc, header: "".} +proc getaddrinfo*(a1, a2: cstring, a3: ptr AddrInfo, + a4: var ptr AddrInfo): cint {.importc, header: "".} -proc gethostbyaddr*(a1: pointer, a2: TSocklen, a3: cint): ptr Thostent {. +proc gethostbyaddr*(a1: pointer, a2: Socklen, a3: cint): ptr Hostent {. importc, header: "".} -proc gethostbyname*(a1: cstring): ptr Thostent {.importc, header: "".} -proc gethostent*(): ptr Thostent {.importc, header: "".} +proc gethostbyname*(a1: cstring): ptr Hostent {.importc, header: "".} +proc gethostent*(): ptr Hostent {.importc, header: "".} -proc getnameinfo*(a1: ptr TSockAddr, a2: TSocklen, - a3: cstring, a4: TSocklen, a5: cstring, - a6: TSocklen, a7: cint): cint {.importc, header: "".} +proc getnameinfo*(a1: ptr SockAddr, a2: Socklen, + a3: cstring, a4: Socklen, a5: cstring, + a6: Socklen, a7: cint): cint {.importc, header: "".} proc getnetbyaddr*(a1: int32, a2: cint): ptr Tnetent {.importc, header: "".} proc getnetbyname*(a1: cstring): ptr Tnetent {.importc, header: "".} @@ -2577,10 +2582,10 @@ proc getprotobyname*(a1: cstring): ptr TProtoent {.importc, header: "". proc getprotobynumber*(a1: cint): ptr TProtoent {.importc, header: "".} proc getprotoent*(): ptr TProtoent {.importc, header: "".} -proc getservbyname*(a1, a2: cstring): ptr TServent {.importc, header: "".} -proc getservbyport*(a1: cint, a2: cstring): ptr TServent {. +proc getservbyname*(a1, a2: cstring): ptr Servent {.importc, header: "".} +proc getservbyport*(a1: cint, a2: cstring): ptr Servent {. importc, header: "".} -proc getservent*(): ptr TServent {.importc, header: "".} +proc getservent*(): ptr Servent {.importc, header: "".} proc sethostent*(a1: cint) {.importc, header: "".} proc setnetent*(a1: cint) {.importc, header: "".} @@ -2593,7 +2598,7 @@ proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: int): cint {. proc realpath*(name, resolved: cstring): cstring {. importc: "realpath", header: "".} -proc utimes*(path: cstring, times: ptr array [2, Ttimeval]): int {. +proc utimes*(path: cstring, times: ptr array [2, Timeval]): int {. importc: "utimes", header: "".} ## Sets file access and modification times. ## diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 76100deba..d348497a9 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1814,7 +1814,7 @@ proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [TimeEffect].} = winlean.sleep(int32(milsecs)) else: var a, b: Ttimespec - a.tv_sec = TTime(milsecs div 1000) + a.tv_sec = Time(milsecs div 1000) a.tv_nsec = (milsecs mod 1000) * 1000 * 1000 discard posix.nanosleep(a, b) diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index f3517fc3c..45634c4ec 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -162,7 +162,7 @@ proc close*(socket: SocketHandle) = # TODO: These values should not be discarded. An EOS should be raised. # http://stackoverflow.com/questions/12463473/what-happens-if-you-call-close-on-a-bsd-socket-multiple-times -proc bindAddr*(socket: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint = +proc bindAddr*(socket: SocketHandle, name: ptr SockAddr, namelen: Socklen): cint = result = bindSocket(socket, name, namelen) proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [ReadIOEffect].} = @@ -184,12 +184,12 @@ proc getAddrInfo*(address: string, port: Port, af: Domain = AF_INET, typ: SockTy hints.ai_family = toInt(af) hints.ai_socktype = toInt(typ) hints.ai_protocol = toInt(prot) - var gaiResult = getAddrInfo(address, $port, addr(hints), result) + var gaiResult = getaddrinfo(address, $port, addr(hints), result) if gaiResult != 0'i32: when useWinVersion: raiseOSError(osLastError()) else: - raise newException(EOS, $gai_strerror(gaiResult)) + raise newException(OSError, $gai_strerror(gaiResult)) proc dealloc*(ai: ptr AddrInfo) = freeaddrinfo(ai) @@ -268,7 +268,7 @@ proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} = var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen, cint(posix.AF_INET)) if s == nil: - raise newException(EOS, $hstrerror(h_errno)) + raise newException(OSError, $hstrerror(h_errno)) result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) @@ -280,7 +280,7 @@ proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} = elif s.h_addrtype == posix.AF_INET6: result.addrtype = AF_INET6 else: - raise newException(EOS, "unknown h_addrtype") + raise newException(OSError, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) @@ -301,7 +301,7 @@ proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} = elif s.h_addrtype == posix.AF_INET6: result.addrtype = AF_INET6 else: - raise newException(EOS, "unknown h_addrtype") + raise newException(OSError, "unknown h_addrtype") result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) @@ -314,7 +314,7 @@ proc getSockName*(socket: SocketHandle): Port = name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).SockLen + var namelen = sizeof(name).Socklen if getsockname(socket, cast[ptr SockAddr](addr(name)), addr(namelen)) == -1'i32: raiseOSError(osLastError()) @@ -324,7 +324,7 @@ proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {. tags: [ReadIOEffect].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).SockLen + var size = sizeof(res).Socklen if getsockopt(socket, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: raiseOSError(osLastError()) @@ -335,7 +335,7 @@ proc setSockOptInt*(socket: SocketHandle, level, optname, optval: int) {. ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket, cint(level), cint(optname), addr(value), - sizeof(value).SockLen) < 0'i32: + sizeof(value).Socklen) < 0'i32: raiseOSError(osLastError()) proc setBlocking*(s: SocketHandle, blocking: bool) = @@ -361,13 +361,13 @@ proc timeValFromMilliseconds(timeout = 500): Timeval = result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var FD_SET, s: seq[SocketHandle], m: var int) = +proc createFdSet(fd: var FdSet, s: seq[SocketHandle], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i)) - FD_SET(i, fd) + fdSet(i, fd) -proc pruneSocketSet(s: var seq[SocketHandle], fd: var FD_SET) = +proc pruneSocketSet(s: var seq[SocketHandle], fd: var FdSet) = var i = 0 var L = s.len while i < L: @@ -386,9 +386,9 @@ proc select*(readfds: var seq[SocketHandle], timeout = 500): int = ## ## A socket is removed from the specific ``seq`` when it has data waiting to ## be read/written to or has errors (``exceptfds``). - var tv {.noInit.}: TTimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd: TFdSet + var rd: FdSet var m = 0 createFdSet((rd), readfds, m) @@ -410,7 +410,7 @@ proc selectWrite*(writefds: var seq[SocketHandle], ## an unlimited time. var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var wr: TFdSet + var wr: FdSet var m = 0 createFdSet((wr), writefds, m) @@ -422,5 +422,5 @@ proc selectWrite*(writefds: var seq[SocketHandle], pruneSocketSet(writefds, (wr)) when defined(Windows): - var wsa: WSADATA - if WSAStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) + var wsa: WSAData + if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index ed1059cc2..2c65d071e 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -70,7 +70,7 @@ proc parsePath(uri: string, i: var int, result: var TUri) = i.inc parseUntil(uri, result.path, {'?', '#'}, i) # The 'mailto' scheme's PATH actually contains the hostname/username - if result.scheme.ToLower() == "mailto": + if result.scheme.toLower == "mailto": parseAuthority(result.path, result) result.path = "" diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 53284cfdc..0da6cb1ff 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -368,45 +368,45 @@ type {.deprecated: [TSocketHandle: SocketHandle].} type - TWSAData* {.pure, final, importc: "WSADATA", header: "Winsock2.h".} = object + WSAData* {.importc: "WSADATA", header: "Winsock2.h".} = object wVersion, wHighVersion: int16 szDescription: array[0..WSADESCRIPTION_LEN, char] szSystemStatus: array[0..WSASYS_STATUS_LEN, char] iMaxSockets, iMaxUdpDg: int16 lpVendorInfo: cstring - TSockAddr* {.pure, final, importc: "SOCKADDR", header: "Winsock2.h".} = object + SockAddr* {.importc: "SOCKADDR", header: "Winsock2.h".} = object sa_family*: int16 # unsigned sa_data: array[0..13, char] - TInAddr* {.pure, final, importc: "IN_ADDR", header: "Winsock2.h".} = object + InAddr* {.importc: "IN_ADDR", header: "Winsock2.h".} = object s_addr*: int32 # IP address - Tsockaddr_in* {.pure, final, importc: "SOCKADDR_IN", + Sockaddr_in* {.importc: "SOCKADDR_IN", header: "Winsock2.h".} = object sin_family*: int16 sin_port*: int16 # unsigned - sin_addr*: TInAddr + sin_addr*: InAddr sin_zero*: array[0..7, char] - Tin6_addr* {.pure, final, importc: "IN6_ADDR", header: "Winsock2.h".} = object + In6_addr* {.importc: "IN6_ADDR", header: "Winsock2.h".} = object bytes*: array[0..15, char] - Tsockaddr_in6* {.pure, final, importc: "SOCKADDR_IN6", + Sockaddr_in6* {.importc: "SOCKADDR_IN6", header: "Winsock2.h".} = object sin6_family*: int16 sin6_port*: int16 # unsigned sin6_flowinfo*: int32 # unsigned - sin6_addr*: Tin6_addr + sin6_addr*: In6_addr sin6_scope_id*: int32 # unsigned - Tsockaddr_in6_old* {.pure, final.} = object + Sockaddr_in6_old* = object sin6_family*: int16 sin6_port*: int16 # unsigned sin6_flowinfo*: int32 # unsigned - sin6_addr*: Tin6_addr + sin6_addr*: In6_addr - TServent* {.pure, final.} = object + Servent* = object s_name*: cstring s_aliases*: cstringArray when defined(cpu64): @@ -416,31 +416,38 @@ type s_port*: int16 s_proto*: cstring - Thostent* {.pure, final.} = object + Hostent* = object h_name*: cstring h_aliases*: cstringArray h_addrtype*: int16 h_length*: int16 h_addr_list*: cstringArray - TFdSet* {.pure, final.} = object + FdSet* = object fd_count*: cint # unsigned fd_array*: array[0..FD_SETSIZE-1, SocketHandle] - TTimeval* {.pure, final.} = object + Timeval* = object tv_sec*, tv_usec*: int32 - TAddrInfo* {.pure, final.} = object + AddrInfo* = object ai_flags*: cint ## Input flags. ai_family*: cint ## Address family of socket. ai_socktype*: cint ## Socket type. ai_protocol*: cint ## Protocol of socket. ai_addrlen*: int ## Length of socket address. ai_canonname*: cstring ## Canonical name of service location. - ai_addr*: ptr TSockAddr ## Socket address of socket. - ai_next*: ptr TAddrInfo ## Pointer to next in list. + ai_addr*: ptr SockAddr ## Socket address of socket. + ai_next*: ptr AddrInfo ## Pointer to next in list. + + SockLen* = cuint + +{.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo, + TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval, + TWSADATA: WSADATA, TFdSet: FdSet, Thostent: Hostent, TServent: Servent, + TInAddr: InAddr, Tin6_addr: In6_addr, Tsockaddr_in6: Sockaddr_in6, + Tsockaddr_in6_old: Sockaddr_in6_old].} - TSockLen* = cuint var SOMAXCONN* {.importc, header: "Winsock2.h".}: cint @@ -462,16 +469,16 @@ var proc `==`*(x, y: SocketHandle): bool {.borrow.} -proc getservbyname*(name, proto: cstring): ptr TServent {. +proc getservbyname*(name, proto: cstring): ptr Servent {. stdcall, importc: "getservbyname", dynlib: ws2dll.} -proc getservbyport*(port: cint, proto: cstring): ptr TServent {. +proc getservbyport*(port: cint, proto: cstring): ptr Servent {. stdcall, importc: "getservbyport", dynlib: ws2dll.} -proc gethostbyaddr*(ip: ptr TInAddr, len: cuint, theType: cint): ptr Thostent {. +proc gethostbyaddr*(ip: ptr InAddr, len: cuint, theType: cint): ptr Hostent {. stdcall, importc: "gethostbyaddr", dynlib: ws2dll.} -proc gethostbyname*(name: cstring): ptr Thostent {. +proc gethostbyname*(name: cstring): ptr Hostent {. stdcall, importc: "gethostbyname", dynlib: ws2dll.} proc socket*(af, typ, protocol: cint): SocketHandle {. @@ -480,20 +487,20 @@ proc socket*(af, typ, protocol: cint): SocketHandle {. proc closesocket*(s: SocketHandle): cint {. stdcall, importc: "closesocket", dynlib: ws2dll.} -proc accept*(s: SocketHandle, a: ptr TSockAddr, addrlen: ptr TSockLen): SocketHandle {. +proc accept*(s: SocketHandle, a: ptr SockAddr, addrlen: ptr SockLen): SocketHandle {. stdcall, importc: "accept", dynlib: ws2dll.} -proc bindSocket*(s: SocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. +proc bindSocket*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {. stdcall, importc: "bind", dynlib: ws2dll.} -proc connect*(s: SocketHandle, name: ptr TSockAddr, namelen: TSockLen): cint {. +proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {. stdcall, importc: "connect", dynlib: ws2dll.} -proc getsockname*(s: SocketHandle, name: ptr TSockAddr, - namelen: ptr TSockLen): cint {. +proc getsockname*(s: SocketHandle, name: ptr SockAddr, + namelen: ptr SockLen): cint {. stdcall, importc: "getsockname", dynlib: ws2dll.} proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer, - optlen: ptr TSockLen): cint {. + optlen: ptr SockLen): cint {. stdcall, importc: "getsockopt", dynlib: ws2dll.} proc setsockopt*(s: SocketHandle, level, optname: cint, optval: pointer, - optlen: TSockLen): cint {. + optlen: SockLen): cint {. stdcall, importc: "setsockopt", dynlib: ws2dll.} proc listen*(s: SocketHandle, backlog: cint): cint {. @@ -501,53 +508,53 @@ proc listen*(s: SocketHandle, backlog: cint): cint {. proc recv*(s: SocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "recv", dynlib: ws2dll.} proc recvfrom*(s: SocketHandle, buf: cstring, len, flags: cint, - fromm: ptr TSockAddr, fromlen: ptr TSockLen): cint {. + fromm: ptr SockAddr, fromlen: ptr SockLen): cint {. stdcall, importc: "recvfrom", dynlib: ws2dll.} -proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet, - timeout: ptr TTimeval): cint {. +proc select*(nfds: cint, readfds, writefds, exceptfds: ptr FdSet, + timeout: ptr Timeval): cint {. stdcall, importc: "select", dynlib: ws2dll.} proc send*(s: SocketHandle, buf: pointer, len, flags: cint): cint {. stdcall, importc: "send", dynlib: ws2dll.} proc sendto*(s: SocketHandle, buf: pointer, len, flags: cint, - to: ptr TSockAddr, tolen: TSockLen): cint {. + to: ptr SockAddr, tolen: SockLen): cint {. stdcall, importc: "sendto", dynlib: ws2dll.} proc shutdown*(s: SocketHandle, how: cint): cint {. stdcall, importc: "shutdown", dynlib: ws2dll.} -proc getnameinfo*(a1: ptr TSockAddr, a2: TSockLen, - a3: cstring, a4: TSockLen, a5: cstring, - a6: TSockLen, a7: cint): cint {. +proc getnameinfo*(a1: ptr SockAddr, a2: SockLen, + a3: cstring, a4: SockLen, a5: cstring, + a6: SockLen, a7: cint): cint {. stdcall, importc: "getnameinfo", dynlib: ws2dll.} proc inet_addr*(cp: cstring): int32 {. stdcall, importc: "inet_addr", dynlib: ws2dll.} -proc WSAFDIsSet(s: SocketHandle, FDSet: var TFdSet): bool {. +proc WSAFDIsSet(s: SocketHandle, set: var FdSet): bool {. stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll, noSideEffect.} -proc FD_ISSET*(Socket: SocketHandle, FDSet: var TFdSet): cint = - result = if WSAFDIsSet(Socket, FDSet): 1'i32 else: 0'i32 +proc FD_ISSET*(Socket: SocketHandle, set: var FdSet): cint = + result = if WSAFDIsSet(Socket, set): 1'i32 else: 0'i32 -proc FD_SET*(Socket: SocketHandle, FDSet: var TFdSet) = - if FDSet.fd_count < FD_SETSIZE: - FDSet.fd_array[int(FDSet.fd_count)] = Socket - inc(FDSet.fd_count) +proc fdSet*(socket: SocketHandle, s: var FdSet) = + if s.fd_count < FD_SETSIZE: + s.fd_array[int(s.fd_count)] = socket + inc(s.fd_count) -proc FD_ZERO*(FDSet: var TFdSet) = - FDSet.fd_count = 0 +proc FD_ZERO*(s: var FdSet) = + s.fd_count = 0 -proc wsaStartup*(wVersionRequired: int16, WSData: ptr TWSAData): cint {. +proc wsaStartup*(wVersionRequired: int16, WSData: ptr WSAData): cint {. stdcall, importc: "WSAStartup", dynlib: ws2dll.} -proc getaddrinfo*(nodename, servname: cstring, hints: ptr TAddrInfo, - res: var ptr TAddrInfo): cint {. +proc getaddrinfo*(nodename, servname: cstring, hints: ptr AddrInfo, + res: var ptr AddrInfo): cint {. stdcall, importc: "getaddrinfo", dynlib: ws2dll.} -proc freeaddrinfo*(ai: ptr TAddrInfo) {. +proc freeaddrinfo*(ai: ptr AddrInfo) {. stdcall, importc: "freeaddrinfo", dynlib: ws2dll.} -proc inet_ntoa*(i: TInAddr): cstring {. +proc inet_ntoa*(i: InAddr): cstring {. stdcall, importc, dynlib: ws2dll.} const From d69e8f4de48320783f1a4aeafb43c452499ffe06 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 01:19:17 +0200 Subject: [PATCH 016/409] updated base64.nim --- lib/pure/base64.nim | 254 ++++++++++++++++++++++---------------------- 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index 3d3cea25c..72c49142d 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -1,127 +1,127 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2010 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module implements a base64 encoder and decoder. - -const - cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - -template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediate.} = - ## encodes `s` into base64 representation. After `lineLen` characters, a - ## `newline` is added. - var total = ((len(s) + 2) div 3) * 4 - var numLines = (total + lineLen - 1) div lineLen - if numLines > 0: inc(total, (numLines-1) * newLine.len) - - result = newString(total) - var i = 0 - var r = 0 - var currLine = 0 - while i < s.len - 2: - var a = ord(s[i]) - var b = ord(s[i+1]) - var c = ord(s[i+2]) - result[r] = cb64[a shr 2] - result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] - result[r+2] = cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)] - result[r+3] = cb64[c and 0x3F] - inc(r, 4) - inc(i, 3) - inc(currLine, 4) - if currLine >= lineLen and i != s.len-2: - for x in items(newLine): - result[r] = x - inc(r) - currLine = 0 - - if i < s.len-1: - var a = ord(s[i]) - var b = ord(s[i+1]) - result[r] = cb64[a shr 2] - result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] - result[r+2] = cb64[((b and 0x0F) shl 2)] - result[r+3] = '=' - if r+4 != result.len: - setLen(result, r+4) - elif i < s.len: - var a = ord(s[i]) - result[r] = cb64[a shr 2] - result[r+1] = cb64[(a and 3) shl 4] - result[r+2] = '=' - result[r+3] = '=' - if r+4 != result.len: - setLen(result, r+4) - else: - #assert(r == result.len) - -proc encode*[T:TInteger|char](s: openarray[T], lineLen = 75, newLine="\13\10"): string = - ## encodes `s` into base64 representation. After `lineLen` characters, a - ## `newline` is added. - encodeInternal(s, lineLen, newLine) - -proc encode*(s: string, lineLen = 75, newLine="\13\10"): string = - ## encodes `s` into base64 representation. After `lineLen` characters, a - ## `newline` is added. - encodeInternal(s, lineLen, newLine) - -proc decodeByte(b: char): int {.inline.} = - case b - of '+': result = ord('>') - of '0'..'9': result = ord(b) + 4 - of 'A'..'Z': result = ord(b) - ord('A') - of 'a'..'z': result = ord(b) - 71 - else: result = 63 - -proc decode*(s: string): string = - ## decodes a string in base64 representation back into its original form. - ## Whitespace is skipped. - const Whitespace = {' ', '\t', '\v', '\r', '\l', '\f'} - var total = ((len(s) + 3) div 4) * 3 - # total is an upper bound, as we will skip arbitrary whitespace: - result = newString(total) - - var i = 0 - var r = 0 - while true: - while s[i] in Whitespace: inc(i) - if i < s.len-3: - var a = s[i].decodeByte - var b = s[i+1].decodeByte - var c = s[i+2].decodeByte - var d = s[i+3].decodeByte - - result[r] = chr((a shl 2) and 0xff or ((b shr 4) and 0x03)) - result[r+1] = chr((b shl 4) and 0xff or ((c shr 2) and 0x0F)) - result[r+2] = chr((c shl 6) and 0xff or (d and 0x3F)) - inc(r, 3) - inc(i, 4) - else: break - assert i == s.len - # adjust the length: - if i > 0 and s[i-1] == '=': - dec(r) - if i > 1 and s[i-2] == '=': dec(r) - setLen(result, r) - -when isMainModule: - assert encode("leasure.") == "bGVhc3VyZS4=" - assert encode("easure.") == "ZWFzdXJlLg==" - assert encode("asure.") == "YXN1cmUu" - assert encode("sure.") == "c3VyZS4=" - - const longText = """Man is distinguished, not only by his reason, but by this - singular passion from other animals, which is a lust of the mind, - that by a perseverance of delight in the continued and indefatigable - generation of knowledge, exceeds the short vehemence of any carnal - pleasure.""" - const tests = ["", "abc", "xyz", "man", "leasure.", "sure.", "easure.", - "asure.", longText] - for t in items(tests): - assert decode(encode(t)) == t - +# +# +# Nim's Runtime Library +# (c) Copyright 2010 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements a base64 encoder and decoder. + +const + cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + +template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediate.} = + ## encodes `s` into base64 representation. After `lineLen` characters, a + ## `newline` is added. + var total = ((len(s) + 2) div 3) * 4 + var numLines = (total + lineLen - 1) div lineLen + if numLines > 0: inc(total, (numLines-1) * newLine.len) + + result = newString(total) + var i = 0 + var r = 0 + var currLine = 0 + while i < s.len - 2: + var a = ord(s[i]) + var b = ord(s[i+1]) + var c = ord(s[i+2]) + result[r] = cb64[a shr 2] + result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] + result[r+2] = cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)] + result[r+3] = cb64[c and 0x3F] + inc(r, 4) + inc(i, 3) + inc(currLine, 4) + if currLine >= lineLen and i != s.len-2: + for x in items(newLine): + result[r] = x + inc(r) + currLine = 0 + + if i < s.len-1: + var a = ord(s[i]) + var b = ord(s[i+1]) + result[r] = cb64[a shr 2] + result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] + result[r+2] = cb64[((b and 0x0F) shl 2)] + result[r+3] = '=' + if r+4 != result.len: + setLen(result, r+4) + elif i < s.len: + var a = ord(s[i]) + result[r] = cb64[a shr 2] + result[r+1] = cb64[(a and 3) shl 4] + result[r+2] = '=' + result[r+3] = '=' + if r+4 != result.len: + setLen(result, r+4) + else: + #assert(r == result.len) + +proc encode*[T:SomeInteger|char](s: openarray[T], lineLen = 75, newLine="\13\10"): string = + ## encodes `s` into base64 representation. After `lineLen` characters, a + ## `newline` is added. + encodeInternal(s, lineLen, newLine) + +proc encode*(s: string, lineLen = 75, newLine="\13\10"): string = + ## encodes `s` into base64 representation. After `lineLen` characters, a + ## `newline` is added. + encodeInternal(s, lineLen, newLine) + +proc decodeByte(b: char): int {.inline.} = + case b + of '+': result = ord('>') + of '0'..'9': result = ord(b) + 4 + of 'A'..'Z': result = ord(b) - ord('A') + of 'a'..'z': result = ord(b) - 71 + else: result = 63 + +proc decode*(s: string): string = + ## decodes a string in base64 representation back into its original form. + ## Whitespace is skipped. + const Whitespace = {' ', '\t', '\v', '\r', '\l', '\f'} + var total = ((len(s) + 3) div 4) * 3 + # total is an upper bound, as we will skip arbitrary whitespace: + result = newString(total) + + var i = 0 + var r = 0 + while true: + while s[i] in Whitespace: inc(i) + if i < s.len-3: + var a = s[i].decodeByte + var b = s[i+1].decodeByte + var c = s[i+2].decodeByte + var d = s[i+3].decodeByte + + result[r] = chr((a shl 2) and 0xff or ((b shr 4) and 0x03)) + result[r+1] = chr((b shl 4) and 0xff or ((c shr 2) and 0x0F)) + result[r+2] = chr((c shl 6) and 0xff or (d and 0x3F)) + inc(r, 3) + inc(i, 4) + else: break + assert i == s.len + # adjust the length: + if i > 0 and s[i-1] == '=': + dec(r) + if i > 1 and s[i-2] == '=': dec(r) + setLen(result, r) + +when isMainModule: + assert encode("leasure.") == "bGVhc3VyZS4=" + assert encode("easure.") == "ZWFzdXJlLg==" + assert encode("asure.") == "YXN1cmUu" + assert encode("sure.") == "c3VyZS4=" + + const longText = """Man is distinguished, not only by his reason, but by this + singular passion from other animals, which is a lust of the mind, + that by a perseverance of delight in the continued and indefatigable + generation of knowledge, exceeds the short vehemence of any carnal + pleasure.""" + const tests = ["", "abc", "xyz", "man", "leasure.", "sure.", "easure.", + "asure.", longText] + for t in items(tests): + assert decode(encode(t)) == t + From a6211058c5b23d1a1985ac8b59989e0f7895949c Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 01:27:36 +0200 Subject: [PATCH 017/409] updated basic2d, basic3d modules --- lib/pure/basic2d.nim | 26 +++++++++++++------------- lib/pure/basic3d.nim | 24 ++++++++++++------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim index 40f59db74..f2fc1566b 100644 --- a/lib/pure/basic2d.nim +++ b/lib/pure/basic2d.nim @@ -92,7 +92,7 @@ proc point2d*(x,y:float):TPoint2d {.noInit,inline.} let IDMATRIX*:TMatrix2d=matrix2d(1.0,0.0,0.0,1.0,0.0,0.0) ## Quick access to an identity matrix - ORIGO*:TPoint2d=Point2d(0.0,0.0) + ORIGO*:TPoint2d=point2d(0.0,0.0) ## Quick acces to point (0,0) XAXIS*:TVector2d=vector2d(1.0,0.0) ## Quick acces to an 2d x-axis unit vector @@ -212,7 +212,7 @@ proc mirror*(v:TVector2d):TMatrix2d {.noInit.} = xy2=v.x*v.y*2.0*nd sqd=nd*(sqx-sqy) - if nd==inf or nd==neginf: + if nd==Inf or nd==NegInf: return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity result.setElements( @@ -231,7 +231,7 @@ proc mirror*(org:TPoint2d,v:TVector2d):TMatrix2d {.noInit.} = xy2=v.x*v.y*2.0*nd sqd=nd*(sqx-sqy) - if nd==inf or nd==neginf: + if nd==Inf or nd==NegInf: return IDMATRIX #mirroring around a zero vector is arbitrary=>just use identity result.setElements( @@ -285,7 +285,7 @@ proc inverse*(m:TMatrix2d):TMatrix2d {.noInit.} = ## will be raised. let d=m.determinant if d==0.0: - raise newException(EDivByZero,"Cannot invert a zero determinant matrix") + raise newException(DivByZeroError,"Cannot invert a zero determinant matrix") result.setElements( m.by/d,-m.ay/d, @@ -360,7 +360,7 @@ proc `len=`*(v:var TVector2d,newlen:float) {.noInit.} = v.y=0.0 return - if fac==inf or fac==neginf: + if fac==Inf or fac==NegInf: #to short for float accuracy #do as good as possible: v.x=newlen @@ -431,7 +431,7 @@ proc normalize*(v:var TVector2d) {.inline.}= ## Modifies `v` to have a length of 1.0, keeping its angle. ## If `v` has zero length, an EDivByZero will be raised. if not tryNormalize(v): - raise newException(EDivByZero,"Cannot normalize zero length vector") + raise newException(DivByZeroError,"Cannot normalize zero length vector") proc transformNorm*(v:var TVector2d,t:TMatrix2d)= ## Applies a normal direction transformation `t` onto `v` in place. @@ -447,7 +447,7 @@ proc transformNorm*(v:var TVector2d,t:TMatrix2d)= # | | 0 0 1 | | let d=t.determinant if(d==0.0): - raise newException(EDivByZero,"Matrix is not invertible") + raise newException(DivByZeroError,"Matrix is not invertible") let newx = (t.by*v.x-t.ay*v.y)/d v.y = (t.ax*v.y-t.bx*v.x)/d v.x = newx @@ -461,7 +461,7 @@ proc transformInv*(v:var TVector2d,t:TMatrix2d)= let d=t.determinant if(d==0.0): - raise newException(EDivByZero,"Matrix is not invertible") + raise newException(DivByZeroError,"Matrix is not invertible") let newx=(t.by*v.x-t.bx*v.y)/d v.y = (t.ax*v.y-t.ay*v.x)/d @@ -531,7 +531,7 @@ proc mirror*(v:var TVector2d,mirrvec:TVector2d)= xy2=mirrvec.x*mirrvec.y*2.0*nd sqd=nd*(sqx-sqy) - if nd==inf or nd==neginf: + if nd==Inf or nd==NegInf: return #mirroring around a zero vector is arbitrary=>keep as is is fastest let newx=xy2*v.y+sqd*v.x @@ -703,7 +703,7 @@ proc transformInv*(p:var TPoint2d,t:TMatrix2d){.inline.}= # | TX TY 1 | let d=t.determinant if d==0.0: - raise newException(EDivByZero,"Cannot invert a zero determinant matrix") + raise newException(DivByZeroError,"Cannot invert a zero determinant matrix") let newx= (t.bx*t.ty-t.by*t.tx+p.x*t.by-p.y*t.bx)/d p.y = -(t.ax*t.ty-t.ay*t.tx+p.x*t.ay-p.y*t.ax)/d @@ -820,11 +820,11 @@ proc closestPoint*(p:TPoint2d,pts:varargs[TPoint2d]):TPoint2d= var bestidx=0 - bestdist=p.sqrdist(pts[0]) + bestdist=p.sqrDist(pts[0]) curdist:float for idx in 1..high(pts): - curdist=p.sqrdist(pts[idx]) + curdist=p.sqrDist(pts[idx]) if curdist Date: Thu, 28 Aug 2014 01:30:12 +0200 Subject: [PATCH 018/409] more modules updated --- lib/pure/cgi.nim | 16 ++++---- lib/pure/complex.nim | 88 ++++++++++++++++++++++---------------------- lib/pure/strtabs.nim | 36 +++++++++--------- 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index bb7934faa..bfa94a238 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -103,12 +103,12 @@ type proc cgiError*(msg: string) {.noreturn.} = ## raises an ECgi exception with message `msg`. - var e: ref ECgi + var e: ref CgiError new(e) e.msg = msg raise e -proc getEncodedData(allowedMethods: set[TRequestMethod]): string = +proc getEncodedData(allowedMethods: set[RequestMethod]): string = case getEnv("REQUEST_METHOD").string of "POST": if methodPost notin allowedMethods: @@ -167,7 +167,7 @@ iterator decodeData*(data: string): tuple[key, value: TaintedString] = elif data[i] == '\0': break else: cgiError("'&' expected") -iterator decodeData*(allowedMethods: set[TRequestMethod] = +iterator decodeData*(allowedMethods: set[RequestMethod] = {methodNone, methodPost, methodGet}): tuple[key, value: TaintedString] = ## Reads and decodes CGI data and yields the (name, value) pairs the ## data consists of. If the client does not use a method listed in the @@ -177,15 +177,15 @@ iterator decodeData*(allowedMethods: set[TRequestMethod] = for key, value in decodeData(data): yield (key, value) -proc readData*(allowedMethods: set[TRequestMethod] = - {methodNone, methodPost, methodGet}): PStringTable = +proc readData*(allowedMethods: set[RequestMethod] = + {methodNone, methodPost, methodGet}): StringTableRef = ## Read CGI data. If the client does not use a method listed in the ## `allowedMethods` set, an `ECgi` exception is raised. result = newStringTable() for name, value in decodeData(allowedMethods): result[name.string] = value.string -proc validateData*(data: PStringTable, validKeys: varargs[string]) = +proc validateData*(data: StringTableRef, validKeys: varargs[string]) = ## validates data; raises `ECgi` if this fails. This checks that each variable ## name of the CGI `data` occurs in the `validKeys` array. for key, val in pairs(data): @@ -393,5 +393,5 @@ proc existsCookie*(name: string): bool = when isMainModule: const test1 = "abc\L+def xyz" - assert UrlEncode(test1) == "abc%0A%2Bdef+xyz" - assert UrlDecode(UrlEncode(test1)) == test1 + assert URLencode(test1) == "abc%0A%2Bdef+xyz" + assert URLdecode(URLencode(test1)) == test1 diff --git a/lib/pure/complex.nim b/lib/pure/complex.nim index d31d56f83..a8709e098 100644 --- a/lib/pure/complex.nim +++ b/lib/pure/complex.nim @@ -30,50 +30,50 @@ type {.deprecated: [TComplex: Complex].} -proc `==` *(x, y: TComplex): bool = +proc `==` *(x, y: Complex): bool = ## Compare two complex numbers `x` and `y` for equality. result = x.re == y.re and x.im == y.im -proc `=~` *(x, y: TComplex): bool = +proc `=~` *(x, y: Complex): bool = ## Compare two complex numbers `x` and `y` approximately. result = abs(x.re-y.re)= 0: result = t.data[index].val else: result = "" -proc mget*(t: PStringTable, key: string): var string {. +proc mget*(t: StringTableRef, key: string): var string {. rtl, extern: "nstTake".} = ## retrieves the location at ``t[key]``. If `key` is not in `t`, the ## ``EInvalidKey`` exception is raised. @@ -117,25 +117,25 @@ proc mget*(t: PStringTable, key: string): var string {. if index >= 0: result = t.data[index].val else: raise newException(KeyError, "key does not exist: " & key) -proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} = +proc hasKey*(t: StringTableRef, key: string): bool {.rtl, extern: "nst$1".} = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc rawInsert(t: PStringTable, data: var KeyValuePairSeq, key, val: string) = +proc rawInsert(t: StringTableRef, data: var KeyValuePairSeq, key, val: string) = var h: THash = myhash(t, key) and high(data) while not isNil(data[h].key): h = nextTry(h, high(data)) data[h].key = key data[h].val = val -proc enlarge(t: PStringTable) = +proc enlarge(t: StringTableRef) = var n: KeyValuePairSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if not isNil(t.data[i].key): rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) -proc `[]=`*(t: PStringTable, key, val: string) {.rtl, extern: "nstPut".} = +proc `[]=`*(t: StringTableRef, key, val: string) {.rtl, extern: "nstPut".} = ## puts a (key, value)-pair into `t`. var index = rawGet(t, key) if index >= 0: @@ -151,7 +151,7 @@ proc raiseFormatException(s: string) = e.msg = "format string: key not found: " & s raise e -proc getValue(t: PStringTable, flags: set[TFormatFlag], key: string): string = +proc getValue(t: StringTableRef, flags: set[FormatFlag], key: string): string = if hasKey(t, key): return t[key] # hm difficult: assume safety in taint mode here. XXX This is dangerous! if useEnvironment in flags: result = os.getEnv(key).string @@ -160,7 +160,7 @@ proc getValue(t: PStringTable, flags: set[TFormatFlag], key: string): string = if useKey in flags: result = '$' & key elif not (useEmpty in flags): raiseFormatException(key) -proc newStringTable*(mode: TStringTableMode): PStringTable {. +proc newStringTable*(mode: StringTableMode): StringTableRef {. rtl, extern: "nst$1".} = ## creates a new string table that is empty. new(result) @@ -169,7 +169,7 @@ proc newStringTable*(mode: TStringTableMode): PStringTable {. newSeq(result.data, startSize) proc newStringTable*(keyValuePairs: varargs[string], - mode: TStringTableMode): PStringTable {. + mode: StringTableMode): StringTableRef {. rtl, extern: "nst$1WithPairs".} = ## creates a new string table with given key value pairs. ## Example:: @@ -182,7 +182,7 @@ proc newStringTable*(keyValuePairs: varargs[string], inc(i, 2) proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]], - mode: StringTableMode = modeCaseSensitive): PStringTable {. + mode: StringTableMode = modeCaseSensitive): StringTableRef {. rtl, extern: "nst$1WithTableConstr".} = ## creates a new string table with given key value pairs. ## Example:: @@ -191,7 +191,7 @@ proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]], result = newStringTable(mode) for key, val in items(keyValuePairs): result[key] = val -proc `%`*(f: string, t: PStringTable, flags: set[TFormatFlag] = {}): string {. +proc `%`*(f: string, t: StringTableRef, flags: set[FormatFlag] = {}): string {. rtl, extern: "nstFormat".} = ## The `%` operator for string tables. const @@ -221,7 +221,7 @@ proc `%`*(f: string, t: PStringTable, flags: set[TFormatFlag] = {}): string {. add(result, f[i]) inc(i) -proc `$`*(t: PStringTable): string {.rtl, extern: "nstDollar".} = +proc `$`*(t: StringTableRef): string {.rtl, extern: "nstDollar".} = ## The `$` operator for string tables. if t.len == 0: result = "{:}" From 12d2a37519abfb490c39a5018ea4eb93eaeb3b29 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 01:39:45 +0200 Subject: [PATCH 019/409] more modules updated --- lib/pure/dynlib.nim | 24 ++++++++--------- lib/pure/encodings.nim | 18 ++++++------- lib/pure/events.nim | 22 ++++++++-------- lib/pure/gentabs.nim | 4 +-- lib/pure/parsexml.nim | 16 ++++++------ lib/pure/xmltree.nim | 58 +++++++++++++++++++++--------------------- 6 files changed, 71 insertions(+), 71 deletions(-) diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim index 77ef20ad9..617fbc66f 100644 --- a/lib/pure/dynlib.nim +++ b/lib/pure/dynlib.nim @@ -16,29 +16,29 @@ type {.deprecated: [TLibHandle: LibHandle].} -proc loadLib*(path: string, global_symbols=false): TLibHandle +proc loadLib*(path: string, global_symbols=false): LibHandle ## loads a library from `path`. Returns nil if the library could not ## be loaded. -proc loadLib*(): TLibHandle +proc loadLib*(): LibHandle ## gets the handle from the current executable. Returns nil if the ## library could not be loaded. -proc unloadLib*(lib: TLibHandle) +proc unloadLib*(lib: LibHandle) ## unloads the library `lib` proc raiseInvalidLibrary*(name: cstring) {.noinline, noreturn.} = ## raises an `EInvalidLibrary` exception. - var e: ref EInvalidLibrary + var e: ref LibraryError new(e) e.msg = "could not find symbol: " & $name raise e -proc symAddr*(lib: TLibHandle, name: cstring): pointer +proc symAddr*(lib: LibHandle, name: cstring): pointer ## retrieves the address of a procedure/variable from `lib`. Returns nil ## if the symbol could not be found. -proc checkedSymAddr*(lib: TLibHandle, name: cstring): pointer = +proc checkedSymAddr*(lib: LibHandle, name: cstring): pointer = ## retrieves the address of a procedure/variable from `lib`. Raises ## `EInvalidLibrary` if the symbol could not be found. result = symAddr(lib, name) @@ -87,13 +87,13 @@ elif defined(windows) or defined(dos): proc getProcAddress(lib: THINSTANCE, name: cstring): pointer {. importc: "GetProcAddress", header: "", stdcall.} - proc loadLib(path: string, global_symbols=false): TLibHandle = - result = cast[TLibHandle](winLoadLibrary(path)) - proc loadLib(): TLibHandle = - result = cast[TLibHandle](winLoadLibrary(nil)) - proc unloadLib(lib: TLibHandle) = FreeLibrary(cast[THINSTANCE](lib)) + proc loadLib(path: string, global_symbols=false): LibHandle = + result = cast[LibHandle](winLoadLibrary(path)) + proc loadLib(): LibHandle = + result = cast[LibHandle](winLoadLibrary(nil)) + proc unloadLib(lib: LibHandle) = FreeLibrary(cast[THINSTANCE](lib)) - proc symAddr(lib: TLibHandle, name: cstring): pointer = + proc symAddr(lib: LibHandle, name: cstring): pointer = result = getProcAddress(cast[THINSTANCE](lib), name) else: diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim index f10c4e40b..8cc668359 100644 --- a/lib/pure/encodings.nim +++ b/lib/pure/encodings.nim @@ -36,7 +36,7 @@ when defined(windows): while i < a.len and j < b.len: if a[i] in {'-', '_'}: inc i if b[j] in {'-', '_'}: inc j - if a[i].tolower != b[j].tolower: return false + if a[i].toLower != b[j].toLower: return false inc i inc j result = i == a.len and j == b.len @@ -295,11 +295,11 @@ else: proc getCurrentEncoding*(): string = ## retrieves the current encoding. On Unix, always "UTF-8" is returned. when defined(windows): - result = codePageToName(GetACP()) + result = codePageToName(getACP()) else: result = "UTF-8" -proc open*(destEncoding = "UTF-8", srcEncoding = "CP1252"): PConverter = +proc open*(destEncoding = "UTF-8", srcEncoding = "CP1252"): EncodingConverter = ## opens a converter that can convert from `srcEncoding` to `destEncoding`. ## Raises `EIO` if it cannot fullfill the request. when not defined(windows): @@ -312,19 +312,19 @@ proc open*(destEncoding = "UTF-8", srcEncoding = "CP1252"): PConverter = result.dest = nameToCodePage(destEncoding) result.src = nameToCodePage(srcEncoding) if int(result.dest) == -1: - raise newException(EInvalidEncoding, + raise newException(EncodingError, "cannot find encoding " & destEncoding) if int(result.src) == -1: - raise newException(EInvalidEncoding, + raise newException(EncodingError, "cannot find encoding " & srcEncoding) -proc close*(c: PConverter) = +proc close*(c: EncodingConverter) = ## frees the resources the converter `c` holds. when not defined(windows): iconvClose(c) when defined(windows): - proc convert*(c: PConverter, s: string): string = + proc convert*(c: EncodingConverter, s: string): string = ## converts `s` to `destEncoding` that was given to the converter `c`. It ## assumed that `s` is in `srcEncoding`. @@ -354,7 +354,7 @@ when defined(windows): cbMultiByte = cint(s.len), lpWideCharStr = cstring(result), cchWideChar = cint(cap)) - if m == 0: osError(osLastError()) + if m == 0: raiseOSError(osLastError()) setLen(result, m*2) elif m <= cap: setLen(result, m*2) @@ -391,7 +391,7 @@ when defined(windows): cchWideChar = cint(result.len div 2), lpMultiByteStr = cstring(res), cbMultiByte = cap.cint) - if m == 0: osError(osLastError()) + if m == 0: raiseOSError(osLastError()) setLen(res, m) result = res elif m <= cap: diff --git a/lib/pure/events.nim b/lib/pure/events.nim index 7868050d1..47dc6ba3f 100644 --- a/lib/pure/events.nim +++ b/lib/pure/events.nim @@ -46,37 +46,37 @@ type {.deprecated: [TEventArgs: EventArgs, TEventHandler: EventHandler, TEventEmitter: EventEmitter, EInvalidEvent: EventError].} -proc initEventHandler*(name: string): TEventHandler = +proc initEventHandler*(name: string): EventHandler = ## Initializes an EventHandler with the specified name and returns it. result.handlers = @[] result.name = name -proc addHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}) = +proc addHandler*(handler: var EventHandler, func: proc(e: EventArgs) {.closure.}) = ## Adds the callback to the specified event handler. handler.handlers.add(func) -proc removeHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}) = +proc removeHandler*(handler: var EventHandler, func: proc(e: EventArgs) {.closure.}) = ## Removes the callback from the specified event handler. for i in countup(0, len(handler.handlers) -1): if func == handler.handlers[i]: handler.handlers.del(i) break -proc containsHandler*(handler: var TEventHandler, func: proc(e: TEventArgs) {.closure.}): bool = +proc containsHandler*(handler: var EventHandler, func: proc(e: EventArgs) {.closure.}): bool = ## Checks if a callback is registered to this event handler. return handler.handlers.contains(func) -proc clearHandlers*(handler: var TEventHandler) = +proc clearHandlers*(handler: var EventHandler) = ## Clears all of the callbacks from the event handler. setLen(handler.handlers, 0) -proc getEventHandler(emitter: var TEventEmitter, event: string): int = +proc getEventHandler(emitter: var EventEmitter, event: string): int = for k in 0..high(emitter.s): if emitter.s[k].name == event: return k return -1 -proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs) {.closure.}) = +proc on*(emitter: var EventEmitter, event: string, func: proc(e: EventArgs) {.closure.}) = ## Assigns a event handler with the specified callback. If the event ## doesn't exist, it will be created. var i = getEventHandler(emitter, event) @@ -87,17 +87,17 @@ proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs) {. else: addHandler(emitter.s[i], func) -proc emit*(emitter: var TEventEmitter, eventhandler: var TEventHandler, - args: TEventArgs) = +proc emit*(emitter: var EventEmitter, eventhandler: var EventHandler, + args: EventArgs) = ## Fires an event handler with specified event arguments. for func in items(eventhandler.handlers): func(args) -proc emit*(emitter: var TEventEmitter, event: string, args: TEventArgs) = +proc emit*(emitter: var EventEmitter, event: string, args: EventArgs) = ## Fires an event handler with specified event arguments. var i = getEventHandler(emitter, event) if i >= 0: emit(emitter, emitter.s[i], args) -proc initEventEmitter*(): TEventEmitter = +proc initEventEmitter*(): EventEmitter = ## Creates and returns a new EventEmitter. result.s = @[] diff --git a/lib/pure/gentabs.nim b/lib/pure/gentabs.nim index 87a55ea1e..c371809a0 100644 --- a/lib/pure/gentabs.nim +++ b/lib/pure/gentabs.nim @@ -25,7 +25,7 @@ type TGenKeyValuePair[T] = tuple[key: string, val: T] TGenKeyValuePairSeq[T] = seq[TGenKeyValuePair[T]] - TGenTable*[T] = object of TObject + TGenTable*[T] = object of RootObj counter: int data: TGenKeyValuePairSeq[T] mode: TGenTableMode @@ -78,7 +78,7 @@ proc RawGet[T](tbl: PGenTable[T], key: string): int = var h: THash h = myhash(tbl, key) and high(tbl.data) # start with real hash value while not isNil(tbl.data[h].key): - if mycmp(tbl, tbl.data[h].key, key): + if myCmp(tbl, tbl.data[h].key, key): return h h = nextTry(h, high(tbl.data)) result = - 1 diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index 2d944917f..cc7575563 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -98,11 +98,11 @@ type filename: string options: set[XmlParseOption] -{.deprecated: [TXmlParser: XmlParser, TXmlParseOptions: XmlParseOptions, +{.deprecated: [TXmlParser: XmlParser, TXmlParseOptions: XmlParseOption, TXmlError: XmlErrorKind, TXmlEventKind: XmlEventKind].} const - errorMessages: array[XmlError, string] = [ + errorMessages: array[XmlErrorKind, string] = [ "no error", "']]>' expected", "name expected", @@ -235,11 +235,11 @@ proc parseCDATA(my: var TXMLParser) = markError(my, errEndOfCDataExpected) break of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.a, '\L') else: @@ -263,11 +263,11 @@ proc parseComment(my: var TXMLParser) = markError(my, errEndOfCommentExpected) break of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf if my.options.contains(reportComments): add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf if my.options.contains(reportComments): add(my.a, '\L') else: @@ -286,11 +286,11 @@ proc parseWhitespace(my: var TXmlParser, skip=False) = Inc(pos) of '\c': # the specification says that CR-LF, CR are to be transformed to LF - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf if not skip: add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf if not skip: add(my.a, '\L') else: diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 6007232c5..c15c2e148 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -12,7 +12,7 @@ import macros, strtabs type - XmlNode* = ref TXmlNode ## an XML tree consists of ``PXmlNode``'s. + XmlNode* = ref XmlNodeObj ## an XML tree consists of ``PXmlNode``'s. XmlNodeKind* = enum ## different kinds of ``PXmlNode``'s xnText, ## a text element @@ -48,43 +48,43 @@ proc newElement*(tag: string): XmlNode = result.s = @[] # init attributes lazily to safe memory -proc newText*(text: string): PXmlNode = +proc newText*(text: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnText`` with the text `text`. result = newXmlNode(xnText) result.fText = text -proc newComment*(comment: string): PXmlNode = +proc newComment*(comment: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `comment`. result = newXmlNode(xnComment) result.fText = comment -proc newCData*(cdata: string): PXmlNode = +proc newCData*(cdata: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnComment`` with the text `cdata`. result = newXmlNode(xnCData) result.fText = cdata -proc newEntity*(entity: string): PXmlNode = +proc newEntity*(entity: string): XmlNode = ## creates a new ``PXmlNode`` of kind ``xnEntity`` with the text `entity`. result = newXmlNode(xnCData) result.fText = entity -proc text*(n: PXmlNode): string {.inline.} = +proc text*(n: XmlNode): string {.inline.} = ## gets the associated text with the node `n`. `n` can be a CDATA, Text, ## comment, or entity node. assert n.k in {xnText, xnComment, xnCData, xnEntity} result = n.fText -proc rawText*(n: PXmlNode): string {.inline.} = +proc rawText*(n: XmlNode): string {.inline.} = ## returns the underlying 'text' string by reference. ## This is only used for speed hacks. shallowCopy(result, n.fText) -proc rawTag*(n: PXmlNode): string {.inline.} = +proc rawTag*(n: XmlNode): string {.inline.} = ## returns the underlying 'tag' string by reference. ## This is only used for speed hacks. shallowCopy(result, n.fTag) -proc innerText*(n: PXmlNode): string = +proc innerText*(n: XmlNode): string = ## gets the inner text of `n`. `n` has to be an ``xnElement`` node. Only ## ``xnText`` and ``xnEntity`` nodes are considered part of `n`'s inner text, ## other child nodes are silently ignored. @@ -93,55 +93,55 @@ proc innerText*(n: PXmlNode): string = for i in 0 .. n.s.len-1: if n.s[i].k in {xnText, xnEntity}: result.add(n.s[i].fText) -proc tag*(n: PXmlNode): string {.inline.} = +proc tag*(n: XmlNode): string {.inline.} = ## gets the tag name of `n`. `n` has to be an ``xnElement`` node. assert n.k == xnElement result = n.fTag -proc add*(father, son: PXmlNode) {.inline.} = +proc add*(father, son: XmlNode) {.inline.} = ## adds the child `son` to `father`. add(father.s, son) -proc len*(n: PXmlNode): int {.inline.} = +proc len*(n: XmlNode): int {.inline.} = ## returns the number `n`'s children. if n.k == xnElement: result = len(n.s) -proc kind*(n: PXmlNode): TXmlNodeKind {.inline.} = +proc kind*(n: XmlNode): XmlNodeKind {.inline.} = ## returns `n`'s kind. result = n.k -proc `[]`* (n: PXmlNode, i: int): PXmlNode {.inline.} = +proc `[]`* (n: XmlNode, i: int): XmlNode {.inline.} = ## returns the `i`'th child of `n`. assert n.k == xnElement result = n.s[i] -iterator items*(n: PXmlNode): PXmlNode {.inline.} = +iterator items*(n: XmlNode): XmlNode {.inline.} = ## iterates over any child of `n`. assert n.k == xnElement for i in 0 .. n.len-1: yield n[i] -proc attrs*(n: PXmlNode): PXmlAttributes {.inline.} = +proc attrs*(n: XmlNode): XmlAttributes {.inline.} = ## gets the attributes belonging to `n`. ## Returns `nil` if attributes have not been initialised for this node. assert n.k == xnElement result = n.fAttr -proc `attrs=`*(n: PXmlNode, attr: PXmlAttributes) {.inline.} = +proc `attrs=`*(n: XmlNode, attr: XmlAttributes) {.inline.} = ## sets the attributes belonging to `n`. assert n.k == xnElement n.fAttr = attr -proc attrsLen*(n: PXmlNode): int {.inline.} = +proc attrsLen*(n: XmlNode): int {.inline.} = ## returns the number of `n`'s attributes. assert n.k == xnElement if not isNil(n.fAttr): result = len(n.fAttr) -proc clientData*(n: PXmlNode): int {.inline.} = +proc clientData*(n: XmlNode): int {.inline.} = ## gets the client data of `n`. The client data field is used by the HTML ## parser and generator. result = n.fClientData -proc `clientData=`*(n: PXmlNode, data: int) {.inline.} = +proc `clientData=`*(n: XmlNode, data: int) {.inline.} = ## sets the client data of `n`. The client data field is used by the HTML ## parser and generator. n.fClientData = data @@ -175,13 +175,13 @@ proc addIndent(result: var string, indent: int) = result.add("\n") for i in 1..indent: result.add(' ') -proc noWhitespace(n: PXmlNode): bool = +proc noWhitespace(n: XmlNode): bool = #for i in 1..n.len-1: # if n[i].kind != n[0].kind: return true for i in 0..n.len-1: if n[i].kind in {xnText, xnEntity}: return true -proc add*(result: var string, n: PXmlNode, indent = 0, indWidth = 2) = +proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) = ## adds the textual representation of `n` to `result`. if n == nil: return case n.k @@ -234,14 +234,14 @@ const xmlHeader* = "\n" ## header to use for complete XML output -proc `$`*(n: PXmlNode): string = +proc `$`*(n: XmlNode): string = ## converts `n` into its string representation. No ``<$xml ...$>`` declaration ## is produced, so that the produced XML fragments are composable. result = "" result.add(n) -proc newXmlTree*(tag: string, children: openArray[PXmlNode], - attributes: PXmlAttributes = nil): PXmlNode = +proc newXmlTree*(tag: string, children: openArray[XmlNode], + attributes: XmlAttributes = nil): XmlNode = ## creates a new XML tree with `tag`, `children` and `attributes` result = newXmlNode(xnElement) result.fTag = tag @@ -285,7 +285,7 @@ macro `<>`*(x: expr): expr {.immediate.} = let x = callsite() result = xmlConstructor(x) -proc child*(n: PXmlNode, name: string): PXmlNode = +proc child*(n: XmlNode, name: string): XmlNode = ## Finds the first child element of `n` with a name of `name`. ## Returns `nil` on failure. assert n.kind == xnElement @@ -294,14 +294,14 @@ proc child*(n: PXmlNode, name: string): PXmlNode = if i.tag == name: return i -proc attr*(n: PXmlNode, name: string): string = +proc attr*(n: XmlNode, name: string): string = ## Finds the first attribute of `n` with a name of `name`. ## Returns "" on failure. assert n.kind == xnElement if n.attrs == nil: return "" return n.attrs[name] -proc findAll*(n: PXmlNode, tag: string, result: var seq[PXmlNode]) = +proc findAll*(n: XmlNode, tag: string, result: var seq[XmlNode]) = ## Iterates over all the children of `n` returning those matching `tag`. ## ## Found nodes satisfying the condition will be appended to the `result` @@ -326,7 +326,7 @@ proc findAll*(n: PXmlNode, tag: string, result: var seq[PXmlNode]) = elif child.k == xnElement: child.findAll(tag, result) -proc findAll*(n: PXmlNode, tag: string): seq[PXmlNode] = +proc findAll*(n: XmlNode, tag: string): seq[XmlNode] = ## Shortcut version to assign in let blocks. Example: ## ## .. code-block:: From e07b8334396b70b9a6ded6adc27ee1bcbc60c7d6 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 01:41:41 +0200 Subject: [PATCH 020/409] more modules updated --- lib/pure/lexbase.nim | 32 ++++++++-------- lib/pure/parsexml.nim | 86 +++++++++++++++++++++---------------------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/lib/pure/lexbase.nim b/lib/pure/lexbase.nim index 63c2599b9..a3a3d7b5c 100644 --- a/lib/pure/lexbase.nim +++ b/lib/pure/lexbase.nim @@ -30,7 +30,7 @@ type bufpos*: int ## the current position within the buffer buf*: cstring ## the buffer itself bufLen*: int ## length of buffer in characters - input: PStream ## the input stream + input: Stream ## the input stream lineNumber*: int ## the current line number sentinel: int lineStart: int # index of last line start in buffer @@ -38,23 +38,23 @@ type {.deprecated: [TBaseLexer: BaseLexer].} -proc open*(L: var TBaseLexer, input: PStream, bufLen: int = 8192) +proc open*(L: var BaseLexer, input: Stream, bufLen: int = 8192) ## inits the TBaseLexer with a stream to read from -proc close*(L: var TBaseLexer) +proc close*(L: var BaseLexer) ## closes the base lexer. This closes `L`'s associated stream too. -proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string +proc getCurrentLine*(L: BaseLexer, marker: bool = true): string ## retrieves the current line. -proc getColNumber*(L: TBaseLexer, pos: int): int +proc getColNumber*(L: BaseLexer, pos: int): int ## retrieves the current column. -proc handleCR*(L: var TBaseLexer, pos: int): int +proc handleCR*(L: var BaseLexer, pos: int): int ## Call this if you scanned over '\c' in the buffer; it returns the the ## position to continue the scanning from. `pos` must be the position ## of the '\c'. -proc handleLF*(L: var TBaseLexer, pos: int): int +proc handleLF*(L: var BaseLexer, pos: int): int ## Call this if you scanned over '\L' in the buffer; it returns the the ## position to continue the scanning from. `pos` must be the position ## of the '\L'. @@ -64,11 +64,11 @@ proc handleLF*(L: var TBaseLexer, pos: int): int const chrSize = sizeof(char) -proc close(L: var TBaseLexer) = +proc close(L: var BaseLexer) = dealloc(L.buf) close(L.input) -proc fillBuffer(L: var TBaseLexer) = +proc fillBuffer(L: var BaseLexer) = var charsRead, toCopy, s: int # all are in characters, # not bytes (in case this @@ -113,7 +113,7 @@ proc fillBuffer(L: var TBaseLexer) = break s = L.bufLen - 1 -proc fillBaseLexer(L: var TBaseLexer, pos: int): int = +proc fillBaseLexer(L: var BaseLexer, pos: int): int = assert(pos <= L.sentinel) if pos < L.sentinel: result = pos + 1 # nothing to do @@ -123,24 +123,24 @@ proc fillBaseLexer(L: var TBaseLexer, pos: int): int = result = 0 L.lineStart = result -proc handleCR(L: var TBaseLexer, pos: int): int = +proc handleCR(L: var BaseLexer, pos: int): int = assert(L.buf[pos] == '\c') inc(L.lineNumber) result = fillBaseLexer(L, pos) if L.buf[result] == '\L': result = fillBaseLexer(L, result) -proc handleLF(L: var TBaseLexer, pos: int): int = +proc handleLF(L: var BaseLexer, pos: int): int = assert(L.buf[pos] == '\L') inc(L.lineNumber) result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result; -proc skipUtf8Bom(L: var TBaseLexer) = +proc skipUtf8Bom(L: var BaseLexer) = if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'): inc(L.bufpos, 3) inc(L.lineStart, 3) -proc open(L: var TBaseLexer, input: PStream, bufLen: int = 8192) = +proc open(L: var BaseLexer, input: Stream, bufLen: int = 8192) = assert(bufLen > 0) assert(input != nil) L.input = input @@ -153,10 +153,10 @@ proc open(L: var TBaseLexer, input: PStream, bufLen: int = 8192) = fillBuffer(L) skipUtf8Bom(L) -proc getColNumber(L: TBaseLexer, pos: int): int = +proc getColNumber(L: BaseLexer, pos: int): int = result = abs(pos - L.lineStart) -proc getCurrentLine(L: TBaseLexer, marker: bool = true): string = +proc getCurrentLine(L: BaseLexer, marker: bool = true): string = var i: int result = "" i = L.lineStart diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index cc7575563..f4f46e4f4 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -90,7 +90,7 @@ type reportWhitespace, ## report whitespace reportComments ## report comments - XmlParser* = object of TBaseLexer ## the parser object. + XmlParser* = object of BaseLexer ## the parser object. a, b, c: string kind: XmlEventKind err: XmlErrorKind @@ -134,93 +134,93 @@ proc close*(my: var XmlParser) {.inline.} = ## closes the parser `my` and its associated input stream. lexbase.close(my) -proc kind*(my: TXmlParser): TXmlEventKind {.inline.} = +proc kind*(my: XmlParser): XmlEventKind {.inline.} = ## returns the current event type for the XML parser return my.kind -proc charData*(my: TXmlParser): string {.inline.} = +proc charData*(my: XmlParser): string {.inline.} = ## returns the character data for the events: ``xmlCharData``, ## ``xmlWhitespace``, ``xmlComment``, ``xmlCData``, ``xmlSpecial`` assert(my.kind in {xmlCharData, xmlWhitespace, xmlComment, xmlCData, xmlSpecial}) return my.a -proc elementName*(my: TXmlParser): string {.inline.} = +proc elementName*(my: XmlParser): string {.inline.} = ## returns the element name for the events: ``xmlElementStart``, ## ``xmlElementEnd``, ``xmlElementOpen`` assert(my.kind in {xmlElementStart, xmlElementEnd, xmlElementOpen}) return my.a -proc entityName*(my: TXmlParser): string {.inline.} = +proc entityName*(my: XmlParser): string {.inline.} = ## returns the entity name for the event: ``xmlEntity`` assert(my.kind == xmlEntity) return my.a -proc attrKey*(my: TXmlParser): string {.inline.} = +proc attrKey*(my: XmlParser): string {.inline.} = ## returns the attribute key for the event ``xmlAttribute`` assert(my.kind == xmlAttribute) return my.a -proc attrValue*(my: TXmlParser): string {.inline.} = +proc attrValue*(my: XmlParser): string {.inline.} = ## returns the attribute value for the event ``xmlAttribute`` assert(my.kind == xmlAttribute) return my.b -proc PIName*(my: TXmlParser): string {.inline.} = +proc PIName*(my: XmlParser): string {.inline.} = ## returns the processing instruction name for the event ``xmlPI`` assert(my.kind == xmlPI) return my.a -proc PIRest*(my: TXmlParser): string {.inline.} = +proc PIRest*(my: XmlParser): string {.inline.} = ## returns the rest of the processing instruction for the event ``xmlPI`` assert(my.kind == xmlPI) return my.b -proc rawData*(my: TXmlParser): string {.inline.} = +proc rawData*(my: XmlParser): string {.inline.} = ## returns the underlying 'data' string by reference. ## This is only used for speed hacks. shallowCopy(result, my.a) -proc rawData2*(my: TXmlParser): string {.inline.} = +proc rawData2*(my: XmlParser): string {.inline.} = ## returns the underlying second 'data' string by reference. ## This is only used for speed hacks. shallowCopy(result, my.b) -proc getColumn*(my: TXmlParser): int {.inline.} = +proc getColumn*(my: XmlParser): int {.inline.} = ## get the current column the parser has arrived at. - result = getColNumber(my, my.bufPos) + result = getColNumber(my, my.bufpos) -proc getLine*(my: TXmlParser): int {.inline.} = +proc getLine*(my: XmlParser): int {.inline.} = ## get the current line the parser has arrived at. - result = my.linenumber + result = my.lineNumber -proc getFilename*(my: TXmlParser): string {.inline.} = +proc getFilename*(my: XmlParser): string {.inline.} = ## get the filename of the file that the parser processes. result = my.filename -proc errorMsg*(my: TXmlParser): string = +proc errorMsg*(my: XmlParser): string = ## returns a helpful error message for the event ``xmlError`` assert(my.kind == xmlError) result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), errorMessages[my.err]] -proc errorMsgExpected*(my: TXmlParser, tag: string): string = +proc errorMsgExpected*(my: XmlParser, tag: string): string = ## returns an error message " expected" in the same format as the ## other error messages result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), "<$1> expected" % tag] -proc errorMsg*(my: TXmlParser, msg: string): string = +proc errorMsg*(my: XmlParser, msg: string): string = ## returns an error message with text `msg` in the same format as the ## other error messages result = "$1($2, $3) Error: $4" % [ my.filename, $getLine(my), $getColumn(my), msg] -proc markError(my: var TXmlParser, kind: TXmlError) {.inline.} = +proc markError(my: var XmlParser, kind: XmlErrorKind) {.inline.} = my.err = kind my.state = stateError -proc parseCDATA(my: var TXMLParser) = +proc parseCDATA(my: var XmlParser) = var pos = my.bufpos + len(" Date: Thu, 28 Aug 2014 01:54:36 +0200 Subject: [PATCH 021/409] more modules updated --- lib/pure/json.nim | 116 +++++++++++++++++++++--------------------- lib/pure/terminal.nim | 4 +- lib/pure/unittest.nim | 4 +- 3 files changed, 62 insertions(+), 62 deletions(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index b2c0db3d1..d90ddebf1 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -82,7 +82,7 @@ type stateEof, stateStart, stateObject, stateArray, stateExpectArrayComma, stateExpectObjectComma, stateExpectColon, stateExpectValue - JsonParser* = object of TBaseLexer ## the parser object. + JsonParser* = object of BaseLexer ## the parser object. a: string tok: TTokKind kind: JsonEventKind @@ -119,7 +119,7 @@ const "{", "}", "[", "]", ":", "," ] -proc open*(my: var JsonParser, input: PStream, filename: string) = +proc open*(my: var JsonParser, input: Stream, filename: string) = ## initializes the parser with an input stream. `Filename` is only used ## for nice error messages. lexbase.open(my, input) @@ -224,7 +224,7 @@ proc parseString(my: var JsonParser): TTokKind = if handleHexChar(buf[pos], r): inc(pos) if handleHexChar(buf[pos], r): inc(pos) if handleHexChar(buf[pos], r): inc(pos) - add(my.a, toUTF8(TRune(r))) + add(my.a, toUTF8(Rune(r))) else: # don't bother with the error add(my.a, buf[pos]) @@ -402,7 +402,7 @@ proc next*(my: var JsonParser) = case tk of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull: my.state[i] = stateEof # expect EOF next! - my.kind = TJsonEventKind(ord(tk)) + my.kind = JsonEventKind(ord(tk)) of tkBracketLe: my.state.add(stateArray) # we expect any my.kind = jsonArrayStart @@ -418,7 +418,7 @@ proc next*(my: var JsonParser) = case tk of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull: my.state.add(stateExpectColon) - my.kind = TJsonEventKind(ord(tk)) + my.kind = JsonEventKind(ord(tk)) of tkBracketLe: my.state.add(stateExpectColon) my.state.add(stateArray) @@ -437,7 +437,7 @@ proc next*(my: var JsonParser) = case tk of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull: my.state.add(stateExpectArrayComma) # expect value next! - my.kind = TJsonEventKind(ord(tk)) + my.kind = JsonEventKind(ord(tk)) of tkBracketLe: my.state.add(stateExpectArrayComma) my.state.add(stateArray) @@ -488,7 +488,7 @@ proc next*(my: var JsonParser) = case tk of tkString, tkInt, tkFloat, tkTrue, tkFalse, tkNull: my.state[i] = stateExpectObjectComma - my.kind = TJsonEventKind(ord(tk)) + my.kind = JsonEventKind(ord(tk)) of tkBracketLe: my.state[i] = stateExpectObjectComma my.state.add(stateArray) @@ -505,7 +505,7 @@ proc next*(my: var JsonParser) = # ------------- higher level interface --------------------------------------- type - TJsonNodeKind* = enum ## possible JSON node types + JsonNodeKind* = enum ## possible JSON node types JNull, JBool, JInt, @@ -514,9 +514,9 @@ type JObject, JArray - PJsonNode* = ref TJsonNode ## JSON node - TJsonNode* {.final, pure, acyclic.} = object - case kind*: TJsonNodeKind + JsonNode* = ref JsonNodeObj ## JSON node + JsonNodeObj* {.acyclic.} = object + case kind*: JsonNodeKind of JString: str*: string of JInt: @@ -528,104 +528,104 @@ type of JNull: nil of JObject: - fields*: seq[tuple[key: string, val: PJsonNode]] + fields*: seq[tuple[key: string, val: JsonNode]] of JArray: - elems*: seq[PJsonNode] + elems*: seq[JsonNode] JsonParsingError* = object of ValueError ## is raised for a JSON error {.deprecated: [EJsonParsingError: JsonParsingError, TJsonNode: JsonNodeObj, PJsonNode: JsonNode, TJsonNodeKind: JsonNodeKind].} -proc raiseParseErr*(p: TJsonParser, msg: string) {.noinline, noreturn.} = +proc raiseParseErr*(p: JsonParser, msg: string) {.noinline, noreturn.} = ## raises an `EJsonParsingError` exception. - raise newException(EJsonParsingError, errorMsgExpected(p, msg)) + raise newException(JsonParsingError, errorMsgExpected(p, msg)) -proc newJString*(s: string): PJsonNode = +proc newJString*(s: string): JsonNode = ## Creates a new `JString PJsonNode`. new(result) result.kind = JString result.str = s -proc newJStringMove(s: string): PJsonNode = +proc newJStringMove(s: string): JsonNode = new(result) result.kind = JString shallowCopy(result.str, s) -proc newJInt*(n: BiggestInt): PJsonNode = +proc newJInt*(n: BiggestInt): JsonNode = ## Creates a new `JInt PJsonNode`. new(result) result.kind = JInt result.num = n -proc newJFloat*(n: float): PJsonNode = +proc newJFloat*(n: float): JsonNode = ## Creates a new `JFloat PJsonNode`. new(result) result.kind = JFloat result.fnum = n -proc newJBool*(b: bool): PJsonNode = +proc newJBool*(b: bool): JsonNode = ## Creates a new `JBool PJsonNode`. new(result) result.kind = JBool result.bval = b -proc newJNull*(): PJsonNode = +proc newJNull*(): JsonNode = ## Creates a new `JNull PJsonNode`. new(result) -proc newJObject*(): PJsonNode = +proc newJObject*(): JsonNode = ## Creates a new `JObject PJsonNode` new(result) result.kind = JObject result.fields = @[] -proc newJArray*(): PJsonNode = +proc newJArray*(): JsonNode = ## Creates a new `JArray PJsonNode` new(result) result.kind = JArray result.elems = @[] -proc `%`*(s: string): PJsonNode = +proc `%`*(s: string): JsonNode = ## Generic constructor for JSON data. Creates a new `JString PJsonNode`. new(result) result.kind = JString result.str = s -proc `%`*(n: BiggestInt): PJsonNode = +proc `%`*(n: BiggestInt): JsonNode = ## Generic constructor for JSON data. Creates a new `JInt PJsonNode`. new(result) result.kind = JInt result.num = n -proc `%`*(n: float): PJsonNode = +proc `%`*(n: float): JsonNode = ## Generic constructor for JSON data. Creates a new `JFloat PJsonNode`. new(result) result.kind = JFloat result.fnum = n -proc `%`*(b: bool): PJsonNode = +proc `%`*(b: bool): JsonNode = ## Generic constructor for JSON data. Creates a new `JBool PJsonNode`. new(result) result.kind = JBool result.bval = b -proc `%`*(keyVals: openArray[tuple[key: string, val: PJsonNode]]): PJsonNode = +proc `%`*(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode = ## Generic constructor for JSON data. Creates a new `JObject PJsonNode` new(result) result.kind = JObject newSeq(result.fields, keyVals.len) for i, p in pairs(keyVals): result.fields[i] = p -proc `%`*(elements: openArray[PJsonNode]): PJsonNode = +proc `%`*(elements: openArray[JsonNode]): JsonNode = ## Generic constructor for JSON data. Creates a new `JArray PJsonNode` new(result) result.kind = JArray newSeq(result.elems, elements.len) for i, p in pairs(elements): result.elems[i] = p -proc `==`* (a,b: PJsonNode): bool = +proc `==`* (a,b: JsonNode): bool = ## Check two nodes for equality if a.isNil: if b.isNil: return true @@ -649,7 +649,7 @@ proc `==`* (a,b: PJsonNode): bool = of JObject: a.fields == b.fields -proc hash* (n:PJsonNode): THash = +proc hash* (n:JsonNode): THash = ## Compute the hash for a JSON node case n.kind of JArray: @@ -667,7 +667,7 @@ proc hash* (n:PJsonNode): THash = of JNull: result = hash(0) -proc len*(n: PJsonNode): int = +proc len*(n: JsonNode): int = ## If `n` is a `JArray`, it returns the number of elements. ## If `n` is a `JObject`, it returns the number of pairs. ## Else it returns 0. @@ -676,7 +676,7 @@ proc len*(n: PJsonNode): int = of JObject: result = n.fields.len else: discard -proc `[]`*(node: PJsonNode, name: string): PJsonNode = +proc `[]`*(node: JsonNode, name: string): JsonNode = ## Gets a field from a `JObject`, which must not be nil. ## If the value at `name` does not exist, returns nil assert(not isNil(node)) @@ -686,35 +686,35 @@ proc `[]`*(node: PJsonNode, name: string): PJsonNode = return item return nil -proc `[]`*(node: PJsonNode, index: int): PJsonNode = +proc `[]`*(node: JsonNode, index: int): JsonNode = ## Gets the node at `index` in an Array. Result is undefined if `index` ## is out of bounds assert(not isNil(node)) assert(node.kind == JArray) return node.elems[index] -proc hasKey*(node: PJsonNode, key: string): bool = +proc hasKey*(node: JsonNode, key: string): bool = ## Checks if `key` exists in `node`. assert(node.kind == JObject) for k, item in items(node.fields): if k == key: return true -proc existsKey*(node: PJsonNode, key: string): bool {.deprecated.} = node.hasKey(key) +proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key) ## Deprecated for `hasKey` -proc add*(father, child: PJsonNode) = +proc add*(father, child: JsonNode) = ## Adds `child` to a JArray node `father`. assert father.kind == JArray father.elems.add(child) -proc add*(obj: PJsonNode, key: string, val: PJsonNode) = +proc add*(obj: JsonNode, key: string, val: JsonNode) = ## Adds ``(key, val)`` pair to the JObject node `obj`. For speed ## reasons no check for duplicate keys is performed! ## But ``[]=`` performs the check. assert obj.kind == JObject obj.fields.add((key, val)) -proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) = +proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) = ## Sets a field from a `JObject`. Performs a check for duplicate keys. assert(obj.kind == JObject) for i in 0..obj.fields.len-1: @@ -723,14 +723,14 @@ proc `[]=`*(obj: PJsonNode, key: string, val: PJsonNode) = return obj.fields.add((key, val)) -proc `{}`*(node: PJsonNode, key: string): PJsonNode = +proc `{}`*(node: JsonNode, key: string): JsonNode = ## Transverses the node and gets the given value. If any of the ## names does not exist, returns nil result = node if isNil(node): return nil result = result[key] -proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) = +proc `{}=`*(node: JsonNode, names: varargs[string], value: JsonNode) = ## Transverses the node and tries to set the value at the given location ## to `value` If any of the names are missing, they are added var node = node @@ -740,7 +740,7 @@ proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) = node = node[names[i]] node[names[names.len-1]] = value -proc delete*(obj: PJsonNode, key: string) = +proc delete*(obj: JsonNode, key: string) = ## Deletes ``obj[key]`` preserving the order of the other (key, value)-pairs. assert(obj.kind == JObject) for i in 0..obj.fields.len-1: @@ -749,7 +749,7 @@ proc delete*(obj: PJsonNode, key: string) = return raise newException(IndexError, "key not in object") -proc copy*(p: PJsonNode): PJsonNode = +proc copy*(p: JsonNode): JsonNode = ## Performs a deep copy of `a`. case p.kind of JString: @@ -800,7 +800,7 @@ proc escapeJson*(s: string): string = result.add(toHex(r, 4)) result.add("\"") -proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = true, +proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true, lstArr = false, currIndent = 0) = case node.kind of JObject: @@ -855,34 +855,34 @@ proc toPretty(result: var string, node: PJsonNode, indent = 2, ml = true, if lstArr: result.indent(currIndent) result.add("null") -proc pretty*(node: PJsonNode, indent = 2): string = +proc pretty*(node: JsonNode, indent = 2): string = ## Converts `node` to its JSON Representation, with indentation and ## on multiple lines. result = "" toPretty(result, node, indent) -proc `$`*(node: PJsonNode): string = +proc `$`*(node: JsonNode): string = ## Converts `node` to its JSON Representation on one line. result = "" toPretty(result, node, 1, false) -iterator items*(node: PJsonNode): PJsonNode = +iterator items*(node: JsonNode): JsonNode = ## Iterator for the items of `node`. `node` has to be a JArray. assert node.kind == JArray for i in items(node.elems): yield i -iterator pairs*(node: PJsonNode): tuple[key: string, val: PJsonNode] = +iterator pairs*(node: JsonNode): tuple[key: string, val: JsonNode] = ## Iterator for the child elements of `node`. `node` has to be a JObject. assert node.kind == JObject for key, val in items(node.fields): yield (key, val) -proc eat(p: var TJsonParser, tok: TTokKind) = +proc eat(p: var JsonParser, tok: TTokKind) = if p.tok == tok: discard getTok(p) else: raiseParseErr(p, tokToStr[tok]) -proc parseJson(p: var TJsonParser): PJsonNode = +proc parseJson(p: var JsonParser): JsonNode = ## Parses JSON from a JSON Parser `p`. case p.tok of tkString: @@ -931,20 +931,20 @@ proc parseJson(p: var TJsonParser): PJsonNode = raiseParseErr(p, "{") when not defined(js): - proc parseJson*(s: PStream, filename: string): PJsonNode = + proc parseJson*(s: Stream, filename: string): JsonNode = ## Parses from a stream `s` into a `PJsonNode`. `filename` is only needed ## for nice error messages. - var p: TJsonParser + var p: JsonParser p.open(s, filename) discard getTok(p) # read first token result = p.parseJson() p.close() - proc parseJson*(buffer: string): PJsonNode = + proc parseJson*(buffer: string): JsonNode = ## Parses JSON from `buffer`. result = parseJson(newStringStream(buffer), "input") - proc parseFile*(filename: string): PJsonNode = + proc parseFile*(filename: string): JsonNode = ## Parses `file` into a `PJsonNode`. var stream = newFileStream(filename, fmRead) if stream == nil: @@ -1062,8 +1062,8 @@ when isMainModule: echo(pretty(parsed2)) try: echo(parsed["key2"][12123]) - raise newException(EInvalidValue, "That line was expected to fail") - except EInvalidIndex: echo() + raise newException(ValueError, "That line was expected to fail") + except IndexError: echo() let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd" }""" # nil passthrough @@ -1075,12 +1075,12 @@ when isMainModule: try: let a = testJson["a"][9] assert(false, "EInvalidIndex not thrown") - except EInvalidIndex: + except IndexError: discard try: let a = testJson["a"][-1] assert(false, "EInvalidIndex not thrown") - except EInvalidIndex: + except IndexError: discard try: assert(testJson["a"][0].num == 1, "Index doesn't correspond to its value") diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 0ebe8a39e..19635ee68 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -216,7 +216,7 @@ when not defined(windows): gFG = 0 gBG = 0 -proc setStyle*(style: set[TStyle]) = +proc setStyle*(style: set[Style]) = ## sets the terminal style when defined(windows): var a = 0'i16 @@ -229,7 +229,7 @@ proc setStyle*(style: set[TStyle]) = for s in items(style): stdout.write("\e[" & $ord(s) & 'm') -proc writeStyled*(txt: string, style: set[TStyle] = {styleBright}) = +proc writeStyled*(txt: string, style: set[Style] = {styleBright}) = ## writes the text `txt` in a given `style`. when defined(windows): var old = getAttributes() diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index f26d8c3e6..372c02f4e 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -58,7 +58,7 @@ template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} = proc testDone(name: string, s: TestStatus) = if s == FAILED: - program_result += 1 + programResult += 1 if OutputLevel != PRINT_NONE and (OutputLevel == PRINT_ALL or s == FAILED): template rawPrint() = echo("[", $s, "] ", name, "\n") @@ -105,7 +105,7 @@ template fail* = when declared(TestStatusIMPL): TestStatusIMPL = FAILED else: - program_result += 1 + programResult += 1 checkpoints = @[] From 42f5a838a396a05c8931c41498ff8026620d4f30 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 02:06:11 +0200 Subject: [PATCH 022/409] more modules updated --- lib/core/typeinfo.nim | 148 +++---- lib/pure/collections/intsets.nim | 26 +- lib/pure/logging.nim | 40 +- lib/pure/marshal.nim | 638 +++++++++++++++---------------- 4 files changed, 426 insertions(+), 426 deletions(-) diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim index 8df1b3dfb..848388c2b 100644 --- a/lib/core/typeinfo.nim +++ b/lib/core/typeinfo.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Dominik Picheta, Andreas Rumpf # # See the file "copying.txt", included in this @@ -68,20 +68,20 @@ type const GenericSeqSize = (2 * sizeof(int)) -proc genericAssign(dest, src: Pointer, mt: PNimType) {.importCompilerProc.} -proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {. +proc genericAssign(dest, src: pointer, mt: PNimType) {.importCompilerProc.} +proc genericShallowAssign(dest, src: pointer, mt: PNimType) {. importCompilerProc.} proc incrSeq(seq: PGenSeq, elemSize: int): PGenSeq {.importCompilerProc.} proc newObj(typ: PNimType, size: int): pointer {.importCompilerProc.} proc newSeq(typ: PNimType, len: int): pointer {.importCompilerProc.} -proc objectInit(dest: Pointer, typ: PNimType) {.importCompilerProc.} +proc objectInit(dest: pointer, typ: PNimType) {.importCompilerProc.} -template `+!!`(a, b: expr): expr = cast[pointer](cast[TAddress](a) + b) +template `+!!`(a, b: expr): expr = cast[pointer](cast[ByteAddress](a) + b) -proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int = +proc getDiscriminant(aa: pointer, n: ptr TNimNode): int = assert(n.kind == nkCase) var d: int - var a = cast[TAddress](aa) + var a = cast[ByteAddress](aa) case n.typ.size of 1: d = ze(cast[ptr int8](a +% n.offset)[]) of 2: d = ze(cast[ptr int16](a +% n.offset)[]) @@ -89,7 +89,7 @@ proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int = else: assert(false) return d -proc selectBranch(aa: Pointer, n: ptr TNimNode): ptr TNimNode = +proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode = var discr = getDiscriminant(aa, n) if discr <% n.len: result = n.sons[discr] @@ -174,14 +174,14 @@ proc `[]`*(x: TAny, i: int): TAny = of tyArray: var bs = x.rawType.base.size if i >=% x.rawType.size div bs: - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") return newAny(x.value +!! i*bs, x.rawType.base) of tySequence: var s = cast[ppointer](x.value)[] - if s == nil: raise newException(EInvalidValue, "sequence is nil") + if s == nil: raise newException(ValueError, "sequence is nil") var bs = x.rawType.base.size if i >=% cast[PGenSeq](s).len: - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") return newAny(s +!! (GenericSeqSize+i*bs), x.rawType.base) else: assert false @@ -191,15 +191,15 @@ proc `[]=`*(x: TAny, i: int, y: TAny) = of tyArray: var bs = x.rawType.base.size if i >=% x.rawType.size div bs: - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") assert y.rawType == x.rawType.base genericAssign(x.value +!! i*bs, y.value, y.rawType) of tySequence: var s = cast[ppointer](x.value)[] - if s == nil: raise newException(EInvalidValue, "sequence is nil") + if s == nil: raise newException(ValueError, "sequence is nil") var bs = x.rawType.base.size if i >=% cast[PGenSeq](s).len: - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") assert y.rawType == x.rawType.base genericAssign(s +!! (GenericSeqSize+i*bs), y.value, y.rawType) else: assert false @@ -276,7 +276,7 @@ proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} = else: result = c var i = 0 var j = 0 - while True: + while true: while a[i] == '_': inc(i) while b[j] == '_': inc(j) # BUGFIX: typo var aa = toLower(a[i]) @@ -311,12 +311,12 @@ proc `[]=`*(x: TAny, fieldName: string, value: TAny) = when false: if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[] assert x.rawType.kind in {tyTuple, tyObject} - var n = getFieldNode(x.value, t.node, fieldname) + var n = getFieldNode(x.value, t.node, fieldName) if n != nil: assert n.typ == value.rawType genericAssign(x.value +!! n.offset, value.value, value.rawType) else: - raise newException(EInvalidValue, "invalid field name: " & fieldName) + raise newException(ValueError, "invalid field name: " & fieldName) proc `[]`*(x: TAny, fieldName: string): TAny = ## gets a field of `x`; `x` represents an object or a tuple. @@ -325,80 +325,80 @@ proc `[]`*(x: TAny, fieldName: string): TAny = when false: if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[] assert x.rawType.kind in {tyTuple, tyObject} - var n = getFieldNode(x.value, t.node, fieldname) + var n = getFieldNode(x.value, t.node, fieldName) if n != nil: result.value = x.value +!! n.offset result.rawType = n.typ else: - raise newException(EInvalidValue, "invalid field name: " & fieldName) + raise newException(ValueError, "invalid field name: " & fieldName) proc `[]`*(x: TAny): TAny = ## dereference operation for the any `x` that represents a ptr or a ref. - assert x.rawtype.kind in {tyRef, tyPtr} + assert x.rawType.kind in {tyRef, tyPtr} result.value = cast[ppointer](x.value)[] result.rawType = x.rawType.base proc `[]=`*(x, y: TAny) = ## dereference operation for the any `x` that represents a ptr or a ref. - assert x.rawtype.kind in {tyRef, tyPtr} + assert x.rawType.kind in {tyRef, tyPtr} assert y.rawType == x.rawType.base genericAssign(cast[ppointer](x.value)[], y.value, y.rawType) proc getInt*(x: TAny): int = ## retrieve the int value out of `x`. `x` needs to represent an int. - assert skipRange(x.rawtype).kind == tyInt + assert skipRange(x.rawType).kind == tyInt result = cast[ptr int](x.value)[] proc getInt8*(x: TAny): int8 = ## retrieve the int8 value out of `x`. `x` needs to represent an int8. - assert skipRange(x.rawtype).kind == tyInt8 + assert skipRange(x.rawType).kind == tyInt8 result = cast[ptr int8](x.value)[] proc getInt16*(x: TAny): int16 = ## retrieve the int16 value out of `x`. `x` needs to represent an int16. - assert skipRange(x.rawtype).kind == tyInt16 + assert skipRange(x.rawType).kind == tyInt16 result = cast[ptr int16](x.value)[] proc getInt32*(x: TAny): int32 = ## retrieve the int32 value out of `x`. `x` needs to represent an int32. - assert skipRange(x.rawtype).kind == tyInt32 + assert skipRange(x.rawType).kind == tyInt32 result = cast[ptr int32](x.value)[] proc getInt64*(x: TAny): int64 = ## retrieve the int64 value out of `x`. `x` needs to represent an int64. - assert skipRange(x.rawtype).kind == tyInt64 + assert skipRange(x.rawType).kind == tyInt64 result = cast[ptr int64](x.value)[] -proc getBiggestInt*(x: TAny): biggestInt = +proc getBiggestInt*(x: TAny): BiggestInt = ## retrieve the integer value out of `x`. `x` needs to represent ## some integer, a bool, a char, an enum or a small enough bit set. - ## The value might be sign-extended to ``biggestInt``. - var t = skipRange(x.rawtype) + ## The value might be sign-extended to ``BiggestInt``. + var t = skipRange(x.rawType) case t.kind - of tyInt: result = biggestInt(cast[ptr int](x.value)[]) - of tyInt8: result = biggestInt(cast[ptr int8](x.value)[]) - of tyInt16: result = biggestInt(cast[ptr int16](x.value)[]) - of tyInt32: result = biggestInt(cast[ptr int32](x.value)[]) - of tyInt64, tyUInt64: result = biggestInt(cast[ptr int64](x.value)[]) - of tyBool: result = biggestInt(cast[ptr bool](x.value)[]) - of tyChar: result = biggestInt(cast[ptr char](x.value)[]) + of tyInt: result = BiggestInt(cast[ptr int](x.value)[]) + of tyInt8: result = BiggestInt(cast[ptr int8](x.value)[]) + of tyInt16: result = BiggestInt(cast[ptr int16](x.value)[]) + of tyInt32: result = BiggestInt(cast[ptr int32](x.value)[]) + of tyInt64, tyUInt64: result = BiggestInt(cast[ptr int64](x.value)[]) + of tyBool: result = BiggestInt(cast[ptr bool](x.value)[]) + of tyChar: result = BiggestInt(cast[ptr char](x.value)[]) of tyEnum, tySet: case t.size of 1: result = ze64(cast[ptr int8](x.value)[]) of 2: result = ze64(cast[ptr int16](x.value)[]) - of 4: result = biggestInt(cast[ptr int32](x.value)[]) - of 8: result = biggestInt(cast[ptr int64](x.value)[]) + of 4: result = BiggestInt(cast[ptr int32](x.value)[]) + of 8: result = BiggestInt(cast[ptr int64](x.value)[]) else: assert false - of tyUInt: result = biggestInt(cast[ptr uint](x.value)[]) - of tyUInt8: result = biggestInt(cast[ptr uint8](x.value)[]) - of tyUInt16: result = biggestInt(cast[ptr uint16](x.value)[]) - of tyUInt32: result = biggestInt(cast[ptr uint32](x.value)[]) + of tyUInt: result = BiggestInt(cast[ptr uint](x.value)[]) + of tyUInt8: result = BiggestInt(cast[ptr uint8](x.value)[]) + of tyUInt16: result = BiggestInt(cast[ptr uint16](x.value)[]) + of tyUInt32: result = BiggestInt(cast[ptr uint32](x.value)[]) else: assert false -proc setBiggestInt*(x: TAny, y: biggestInt) = +proc setBiggestInt*(x: TAny, y: BiggestInt) = ## sets the integer value of `x`. `x` needs to represent ## some integer, a bool, a char, an enum or a small enough bit set. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) case t.kind of tyInt: cast[ptr int](x.value)[] = int(y) of tyInt8: cast[ptr int8](x.value)[] = int8(y) @@ -422,37 +422,37 @@ proc setBiggestInt*(x: TAny, y: biggestInt) = proc getUInt*(x: TAny): uint = ## retrieve the uint value out of `x`, `x` needs to represent an uint. - assert skipRange(x.rawtype).kind == tyUInt + assert skipRange(x.rawType).kind == tyUInt result = cast[ptr uint](x.value)[] proc getUInt8*(x: TAny): uint8 = ## retrieve the uint8 value out of `x`, `x` needs to represent an ## uint8. - assert skipRange(x.rawtype).kind == tyUInt8 + assert skipRange(x.rawType).kind == tyUInt8 result = cast[ptr uint8](x.value)[] proc getUInt16*(x: TAny): uint16 = ## retrieve the uint16 value out of `x`, `x` needs to represent an ## uint16. - assert skipRange(x.rawtype).kind == tyUInt16 + assert skipRange(x.rawType).kind == tyUInt16 result = cast[ptr uint16](x.value)[] proc getUInt32*(x: TAny): uint32 = ## retrieve the uint32 value out of `x`, `x` needs to represent an ## uint32. - assert skipRange(x.rawtype).kind == tyUInt32 + assert skipRange(x.rawType).kind == tyUInt32 result = cast[ptr uint32](x.value)[] proc getUInt64*(x: TAny): uint64 = ## retrieve the uint64 value out of `x`, `x` needs to represent an ## uint64. - assert skipRange(x.rawtype).kind == tyUInt64 + assert skipRange(x.rawType).kind == tyUInt64 result = cast[ptr uint64](x.value)[] proc getBiggestUint*(x: TAny): uint64 = ## retrieve the unsigned integer value out of `x`. `x` needs to ## represent an unsigned integer. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) case t.kind of tyUInt: result = uint64(cast[ptr uint](x.value)[]) of tyUInt8: result = uint64(cast[ptr uint8](x.value)[]) @@ -464,7 +464,7 @@ proc getBiggestUint*(x: TAny): uint64 = proc setBiggestUint*(x: TAny; y: uint64) = ## sets the unsigned integer value of `c`. `c` needs to represent an ## unsigned integer. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) case t.kind: of tyUInt: cast[ptr uint](x.value)[] = uint(y) of tyUInt8: cast[ptr uint8](x.value)[] = uint8(y) @@ -475,13 +475,13 @@ proc setBiggestUint*(x: TAny; y: uint64) = proc getChar*(x: TAny): char = ## retrieve the char value out of `x`. `x` needs to represent a char. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) assert t.kind == tyChar result = cast[ptr char](x.value)[] proc getBool*(x: TAny): bool = ## retrieve the bool value out of `x`. `x` needs to represent a bool. - var t = skipRange(x.rawtype) + var t = skipRange(x.rawType) assert t.kind == tyBool result = cast[ptr bool](x.value)[] @@ -495,7 +495,7 @@ proc getEnumOrdinal*(x: TAny, name: string): int = ## gets the enum field ordinal from `name`. `x` needs to represent an enum ## but is only used to access the type information. In case of an error ## ``low(int)`` is returned. - var typ = skipRange(x.rawtype) + var typ = skipRange(x.rawType) assert typ.kind == tyEnum var n = typ.node var s = n.sons @@ -511,7 +511,7 @@ proc getEnumField*(x: TAny, ordinalValue: int): string = ## gets the enum field name as a string. `x` needs to represent an enum ## but is only used to access the type information. The field name of ## `ordinalValue` is returned. - var typ = skipRange(x.rawtype) + var typ = skipRange(x.rawType) assert typ.kind == tyEnum var e = ordinalValue if ntfEnumHole notin typ.flags: @@ -531,51 +531,51 @@ proc getEnumField*(x: TAny): string = proc getFloat*(x: TAny): float = ## retrieve the float value out of `x`. `x` needs to represent an float. - assert skipRange(x.rawtype).kind == tyFloat + assert skipRange(x.rawType).kind == tyFloat result = cast[ptr float](x.value)[] proc getFloat32*(x: TAny): float32 = ## retrieve the float32 value out of `x`. `x` needs to represent an float32. - assert skipRange(x.rawtype).kind == tyFloat32 + assert skipRange(x.rawType).kind == tyFloat32 result = cast[ptr float32](x.value)[] proc getFloat64*(x: TAny): float64 = ## retrieve the float64 value out of `x`. `x` needs to represent an float64. - assert skipRange(x.rawtype).kind == tyFloat64 + assert skipRange(x.rawType).kind == tyFloat64 result = cast[ptr float64](x.value)[] -proc getBiggestFloat*(x: TAny): biggestFloat = +proc getBiggestFloat*(x: TAny): BiggestFloat = ## retrieve the float value out of `x`. `x` needs to represent - ## some float. The value is extended to ``biggestFloat``. - case skipRange(x.rawtype).kind - of tyFloat: result = biggestFloat(cast[ptr Float](x.value)[]) - of tyFloat32: result = biggestFloat(cast[ptr Float32](x.value)[]) - of tyFloat64: result = biggestFloat(cast[ptr Float64](x.value)[]) + ## some float. The value is extended to ``BiggestFloat``. + case skipRange(x.rawType).kind + of tyFloat: result = BiggestFloat(cast[ptr float](x.value)[]) + of tyFloat32: result = BiggestFloat(cast[ptr float32](x.value)[]) + of tyFloat64: result = BiggestFloat(cast[ptr float64](x.value)[]) else: assert false -proc setBiggestFloat*(x: TAny, y: biggestFloat) = +proc setBiggestFloat*(x: TAny, y: BiggestFloat) = ## sets the float value of `x`. `x` needs to represent ## some float. - case skipRange(x.rawtype).kind - of tyFloat: cast[ptr Float](x.value)[] = y - of tyFloat32: cast[ptr Float32](x.value)[] = y.float32 - of tyFloat64: cast[ptr Float64](x.value)[] = y + case skipRange(x.rawType).kind + of tyFloat: cast[ptr float](x.value)[] = y + of tyFloat32: cast[ptr float32](x.value)[] = y.float32 + of tyFloat64: cast[ptr float64](x.value)[] = y else: assert false proc getString*(x: TAny): string = ## retrieve the string value out of `x`. `x` needs to represent a string. - assert x.rawtype.kind == tyString + assert x.rawType.kind == tyString if not isNil(cast[ptr pointer](x.value)[]): result = cast[ptr string](x.value)[] proc setString*(x: TAny, y: string) = ## sets the string value of `x`. `x` needs to represent a string. - assert x.rawtype.kind == tyString + assert x.rawType.kind == tyString cast[ptr string](x.value)[] = y proc getCString*(x: TAny): cstring = ## retrieve the cstring value out of `x`. `x` needs to represent a cstring. - assert x.rawtype.kind == tyCString + assert x.rawType.kind == tyCString result = cast[ptr cstring](x.value)[] proc assign*(x, y: TAny) = @@ -587,7 +587,7 @@ proc assign*(x, y: TAny) = iterator elements*(x: TAny): int = ## iterates over every element of `x` that represents a Nimrod bitset. assert x.rawType.kind == tySet - var typ = x.rawtype + var typ = x.rawType var p = x.value # "typ.slots.len" field is for sets the "first" field var u: int64 @@ -609,7 +609,7 @@ iterator elements*(x: TAny): int = proc inclSetElement*(x: TAny, elem: int) = ## includes an element `elem` in `x`. `x` needs to represent a Nimrod bitset. assert x.rawType.kind == tySet - var typ = x.rawtype + var typ = x.rawType var p = x.value # "typ.slots.len" field is for sets the "first" field var e = elem - typ.node.len diff --git a/lib/pure/collections/intsets.nim b/lib/pure/collections/intsets.nim index 678c428c1..5d9c3f445 100644 --- a/lib/pure/collections/intsets.nim +++ b/lib/pure/collections/intsets.nim @@ -51,7 +51,7 @@ proc mustRehash(length, counter: int): bool {.inline.} = proc nextTry(h, maxHash: THash): THash {.inline.} = result = ((5 * h) + 1) and maxHash -proc intSetGet(t: TIntSet, key: int): PTrunk = +proc intSetGet(t: IntSet, key: int): PTrunk = var h = key and t.max while t.data[h] != nil: if t.data[h].key == key: @@ -59,7 +59,7 @@ proc intSetGet(t: TIntSet, key: int): PTrunk = h = nextTry(h, t.max) result = nil -proc intSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) = +proc intSetRawInsert(t: IntSet, data: var TTrunkSeq, desc: PTrunk) = var h = desc.key and t.max while data[h] != nil: assert(data[h] != desc) @@ -67,7 +67,7 @@ proc intSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) = assert(data[h] == nil) data[h] = desc -proc intSetEnlarge(t: var TIntSet) = +proc intSetEnlarge(t: var IntSet) = var n: TTrunkSeq var oldMax = t.max t.max = ((t.max + 1) * 2) - 1 @@ -76,7 +76,7 @@ proc intSetEnlarge(t: var TIntSet) = if t.data[i] != nil: intSetRawInsert(t, n, t.data[i]) swap(t.data, n) -proc intSetPut(t: var TIntSet, key: int): PTrunk = +proc intSetPut(t: var IntSet, key: int): PTrunk = var h = key and t.max while t.data[h] != nil: if t.data[h].key == key: @@ -93,7 +93,7 @@ proc intSetPut(t: var TIntSet, key: int): PTrunk = t.head = result t.data[h] = result -proc contains*(s: TIntSet, key: int): bool = +proc contains*(s: IntSet, key: int): bool = ## returns true iff `key` is in `s`. var t = intSetGet(s, `shr`(key, TrunkShift)) if t != nil: @@ -102,14 +102,14 @@ proc contains*(s: TIntSet, key: int): bool = else: result = false -proc incl*(s: var TIntSet, key: int) = +proc incl*(s: var IntSet, key: int) = ## includes an element `key` in `s`. var t = intSetPut(s, `shr`(key, TrunkShift)) var u = key and TrunkMask t.bits[`shr`(u, IntShift)] = t.bits[`shr`(u, IntShift)] or `shl`(1, u and IntMask) -proc excl*(s: var TIntSet, key: int) = +proc excl*(s: var IntSet, key: int) = ## excludes `key` from the set `s`. var t = intSetGet(s, `shr`(key, TrunkShift)) if t != nil: @@ -117,7 +117,7 @@ proc excl*(s: var TIntSet, key: int) = t.bits[`shr`(u, IntShift)] = t.bits[`shr`(u, IntShift)] and not `shl`(1, u and IntMask) -proc containsOrIncl*(s: var TIntSet, key: int): bool = +proc containsOrIncl*(s: var IntSet, key: int): bool = ## returns true if `s` contains `key`, otherwise `key` is included in `s` ## and false is returned. var t = intSetGet(s, `shr`(key, TrunkShift)) @@ -131,14 +131,14 @@ proc containsOrIncl*(s: var TIntSet, key: int): bool = incl(s, key) result = false -proc initIntSet*: TIntSet = +proc initIntSet*: IntSet = ## creates a new int set that is empty. newSeq(result.data, InitIntSetSize) result.max = InitIntSetSize-1 result.counter = 0 result.head = nil -proc assign*(dest: var TIntSet, src: TIntSet) = +proc assign*(dest: var IntSet, src: IntSet) = ## copies `src` to `dest`. `dest` does not need to be initialized by ## `initIntSet`. dest.counter = src.counter @@ -162,7 +162,7 @@ proc assign*(dest: var TIntSet, src: TIntSet) = it = it.next -iterator items*(s: TIntSet): int {.inline.} = +iterator items*(s: IntSet): int {.inline.} = ## iterates over any included element of `s`. var r = s.head while r != nil: @@ -187,11 +187,11 @@ template dollarImpl(): stmt = result.add($key) result.add("}") -proc `$`*(s: TIntSet): string = +proc `$`*(s: IntSet): string = ## The `$` operator for int sets. dollarImpl() -proc empty*(s: TIntSet): bool {.inline.} = +proc empty*(s: IntSet): bool {.inline.} = ## returns true if `s` is empty. This is safe to call even before ## the set has been initialized with `initIntSet`. result = s.counter == 0 diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index a0773f40b..bd5e1bf42 100644 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -61,15 +61,15 @@ const type Logger* = ref object of RootObj ## abstract logger; the base type of all loggers - levelThreshold*: Leve l ## only messages of level >= levelThreshold - ## should be processed + levelThreshold*: Level ## only messages of level >= levelThreshold + ## should be processed fmtStr: string ## = defaultFmtStr by default, see substituteLog for $date etc. ConsoleLogger* = ref object of Logger ## logger that writes the messages to the ## console FileLogger* = ref object of Logger ## logger that writes the messages to a file - f: TFile + f: File RollingFileLogger* = ref object of FileLogger ## logger that writes the ## messages to a file and @@ -109,19 +109,19 @@ proc substituteLog(frmt: string): string = of "appname": result.add(app.splitFile.name) method log*(logger: Logger, level: Level, - frmt: string, args: varargs[string, `$`]) {.raises: [EBase], tags: [FTime, FWriteIO, FReadIO].} = + frmt: string, args: varargs[string, `$`]) {.raises: [Exception], tags: [FTime, FWriteIO, FReadIO].} = ## Override this method in custom loggers. Default implementation does ## nothing. discard -method log*(logger: PConsoleLogger, level: TLevel, +method log*(logger: ConsoleLogger, level: Level, frmt: string, args: varargs[string, `$`]) = ## Logs to the console using ``logger`` only. if level >= logger.levelThreshold: writeln(stdout, LevelNames[level], " ", substituteLog(logger.fmtStr), frmt % args) -method log*(logger: PFileLogger, level: TLevel, +method log*(logger: FileLogger, level: Level, frmt: string, args: varargs[string, `$`]) = ## Logs to a file using ``logger`` only. if level >= logger.levelThreshold: @@ -133,16 +133,16 @@ proc defaultFilename*(): string = var (path, name, ext) = splitFile(getAppFilename()) result = changeFileExt(path / name, "log") -proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr): PConsoleLogger = +proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr): ConsoleLogger = ## Creates a new console logger. This logger logs to the console. new result result.fmtStr = fmtStr result.levelThreshold = levelThreshold proc newFileLogger*(filename = defaultFilename(), - mode: TFileMode = fmAppend, + mode: FileMode = fmAppend, levelThreshold = lvlAll, - fmtStr = defaultFmtStr): PFileLogger = + fmtStr = defaultFmtStr): FileLogger = ## Creates a new file logger. This logger logs to a file. new(result) result.levelThreshold = levelThreshold @@ -151,7 +151,7 @@ proc newFileLogger*(filename = defaultFilename(), # ------ -proc countLogLines(logger: PRollingFileLogger): int = +proc countLogLines(logger: RollingFileLogger): int = result = 0 for line in logger.f.lines(): result.inc() @@ -169,13 +169,13 @@ proc countFiles(filename: string): int = let num = parseInt(numS) if num > result: result = num - except EInvalidValue: discard + except ValueError: discard proc newRollingFileLogger*(filename = defaultFilename(), - mode: TFileMode = fmReadWrite, + mode: FileMode = fmReadWrite, levelThreshold = lvlAll, fmtStr = defaultFmtStr, - maxLines = 1000): PRollingFileLogger = + maxLines = 1000): RollingFileLogger = ## Creates a new rolling file logger. Once a file reaches ``maxLines`` lines ## a new log file will be started and the old will be renamed. new(result) @@ -193,14 +193,14 @@ proc newRollingFileLogger*(filename = defaultFilename(), # We need to get a line count because we will be appending to the file. result.curLine = countLogLines(result) -proc rotate(logger: PRollingFileLogger) = +proc rotate(logger: RollingFileLogger) = let (dir, name, ext) = splitFile(logger.baseName) for i in countdown(logger.logFiles, 0): let srcSuff = if i != 0: ExtSep & $i else: "" moveFile(dir / (name & ext & srcSuff), dir / (name & ext & ExtSep & $(i+1))) -method log*(logger: PRollingFileLogger, level: TLevel, +method log*(logger: RollingFileLogger, level: Level, frmt: string, args: varargs[string, `$`]) = ## Logs to a file using rolling ``logger`` only. if level >= logger.levelThreshold: @@ -218,20 +218,20 @@ method log*(logger: PRollingFileLogger, level: TLevel, var level* = lvlAll ## global log filter - handlers*: seq[PLogger] = @[] ## handlers with their own log levels + handlers*: seq[Logger] = @[] ## handlers with their own log levels -proc logLoop(level: TLevel, frmt: string, args: varargs[string, `$`]) = +proc logLoop(level: Level, frmt: string, args: varargs[string, `$`]) = for logger in items(handlers): if level >= logger.levelThreshold: log(logger, level, frmt, args) -template log*(level: TLevel, frmt: string, args: varargs[string, `$`]) = +template log*(level: Level, frmt: string, args: varargs[string, `$`]) = ## Logs a message to all registered handlers at the given level. bind logLoop bind `%` - bind logging.Level + bind logging.level - if level >= logging.Level: + if level >= logging.level: logLoop(level, frmt, args) template debug*(frmt: string, args: varargs[string, `$`]) = diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim index 7857e9a94..fc63605a9 100644 --- a/lib/pure/marshal.nim +++ b/lib/pure/marshal.nim @@ -1,319 +1,319 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2014 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module contains procs for serialization and deseralization of -## arbitrary Nim data structures. The serialization format uses JSON. -## -## **Restriction**: For objects their type is **not** serialized. This means -## essentially that it does not work if the object has some other runtime -## type than its compiletime type: -## -## .. code-block:: nim -## -## type -## TA = object -## TB = object of TA -## f: int -## -## var -## a: ref TA -## b: ref TB -## -## new(b) -## a = b -## echo($$a[]) # produces "{}", not "{f: 0}" - -import streams, typeinfo, json, intsets, tables - -proc ptrToInt(x: pointer): int {.inline.} = - result = cast[int](x) # don't skip alignment - -proc storeAny(s: PStream, a: TAny, stored: var TIntSet) = - case a.kind - of akNone: assert false - of akBool: s.write($getBool(a)) - of akChar: s.write(escapeJson($getChar(a))) - of akArray, akSequence: - if a.kind == akSequence and isNil(a): s.write("null") - else: - s.write("[") - for i in 0 .. a.len-1: - if i > 0: s.write(", ") - storeAny(s, a[i], stored) - s.write("]") - of akObject, akTuple: - s.write("{") - var i = 0 - for key, val in fields(a): - if i > 0: s.write(", ") - s.write(escapeJson(key)) - s.write(": ") - storeAny(s, val, stored) - inc(i) - s.write("}") - of akSet: - s.write("[") - var i = 0 - for e in elements(a): - if i > 0: s.write(", ") - s.write($e) - inc(i) - s.write("]") - of akRange: storeAny(s, skipRange(a), stored) - of akEnum: s.write(getEnumField(a).escapeJson) - of akPtr, akRef: - var x = a.getPointer - if isNil(x): s.write("null") - elif stored.containsOrIncl(x.ptrToInt): - # already stored, so we simply write out the pointer as an int: - s.write($x.ptrToInt) - else: - # else as a [value, key] pair: - # (reversed order for convenient x[0] access!) - s.write("[") - s.write($x.ptrToInt) - s.write(", ") - storeAny(s, a[], stored) - s.write("]") - of akProc, akPointer, akCString: s.write($a.getPointer.ptrToInt) - of akString: - var x = getString(a) - if IsNil(x): s.write("null") - else: s.write(escapeJson(x)) - of akInt..akInt64, akUInt..akUInt64: s.write($getBiggestInt(a)) - of akFloat..akFloat128: s.write($getBiggestFloat(a)) - -proc loadAny(p: var TJsonParser, a: TAny, t: var TTable[biggestInt, pointer]) = - case a.kind - of akNone: assert false - of akBool: - case p.kind - of jsonFalse: setBiggestInt(a, 0) - of jsonTrue: setBiggestInt(a, 1) - else: raiseParseErr(p, "'true' or 'false' expected for a bool") - next(p) - of akChar: - if p.kind == jsonString: - var x = p.str - if x.len == 1: - setBiggestInt(a, ord(x[0])) - next(p) - return - raiseParseErr(p, "string of length 1 expected for a char") - of akEnum: - if p.kind == jsonString: - setBiggestInt(a, getEnumOrdinal(a, p.str)) - next(p) - return - raiseParseErr(p, "string expected for an enum") - of akArray: - if p.kind != jsonArrayStart: raiseParseErr(p, "'[' expected for an array") - next(p) - var i = 0 - while p.kind != jsonArrayEnd and p.kind != jsonEof: - loadAny(p, a[i], t) - inc(i) - if p.kind == jsonArrayEnd: next(p) - else: raiseParseErr(p, "']' end of array expected") - of akSequence: - case p.kind - of jsonNull: - setPointer(a, nil) - next(p) - of jsonArrayStart: - next(p) - invokeNewSeq(a, 0) - var i = 0 - while p.kind != jsonArrayEnd and p.kind != jsonEof: - extendSeq(a) - loadAny(p, a[i], t) - inc(i) - if p.kind == jsonArrayEnd: next(p) - else: raiseParseErr(p, "") - else: - raiseParseErr(p, "'[' expected for a seq") - of akObject, akTuple: - if a.kind == akObject: setObjectRuntimeType(a) - if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object") - next(p) - while p.kind != jsonObjectEnd and p.kind != jsonEof: - if p.kind != jsonString: - raiseParseErr(p, "string expected for a field name") - var fieldName = p.str - next(p) - loadAny(p, a[fieldName], t) - if p.kind == jsonObjectEnd: next(p) - else: raiseParseErr(p, "'}' end of object expected") - of akSet: - if p.kind != jsonArrayStart: raiseParseErr(p, "'[' expected for a set") - next(p) - while p.kind != jsonArrayEnd and p.kind != jsonEof: - if p.kind != jsonInt: raiseParseErr(p, "int expected for a set") - inclSetElement(a, p.getInt.int) - next(p) - if p.kind == jsonArrayEnd: next(p) - else: raiseParseErr(p, "']' end of array expected") - of akPtr, akRef: - case p.kind - of jsonNull: - setPointer(a, nil) - next(p) - of jsonInt: - setPointer(a, t[p.getInt]) - next(p) - of jsonArrayStart: - next(p) - if a.kind == akRef: invokeNew(a) - else: setPointer(a, alloc0(a.baseTypeSize)) - if p.kind == jsonInt: - t[p.getInt] = getPointer(a) - next(p) - else: raiseParseErr(p, "index for ref type expected") - loadAny(p, a[], t) - if p.kind == jsonArrayEnd: next(p) - else: raiseParseErr(p, "']' end of ref-address pair expected") - else: raiseParseErr(p, "int for pointer type expected") - of akProc, akPointer, akCString: - case p.kind - of jsonNull: - setPointer(a, nil) - next(p) - of jsonInt: - setPointer(a, cast[pointer](p.getInt.int)) - next(p) - else: raiseParseErr(p, "int for pointer type expected") - of akString: - case p.kind - of jsonNull: - setPointer(a, nil) - next(p) - of jsonString: - setString(a, p.str) - next(p) - else: raiseParseErr(p, "string expected") - of akInt..akInt64, akUInt..akUInt64: - if p.kind == jsonInt: - setBiggestInt(a, getInt(p)) - next(p) - return - raiseParseErr(p, "int expected") - of akFloat..akFloat128: - if p.kind == jsonFloat: - setBiggestFloat(a, getFloat(p)) - next(p) - return - raiseParseErr(p, "float expected") - of akRange: loadAny(p, a.skipRange, t) - -proc loadAny(s: PStream, a: TAny, t: var TTable[BiggestInt, pointer]) = - var p: TJsonParser - open(p, s, "unknown file") - next(p) - loadAny(p, a, t) - close(p) - -proc load*[T](s: PStream, data: var T) = - ## loads `data` from the stream `s`. Raises `EIO` in case of an error. - var tab = initTable[biggestInt, pointer]() - loadAny(s, toAny(data), tab) - -proc store*[T](s: PStream, data: T) = - ## stores `data` into the stream `s`. Raises `EIO` in case of an error. - var stored = initIntSet() - var d: T - shallowCopy(d, data) - storeAny(s, toAny(d), stored) - -proc `$$`*[T](x: T): string = - ## returns a string representation of `x`. - var stored = initIntSet() - var d: T - shallowCopy(d, x) - var s = newStringStream() - storeAny(s, toAny(d), stored) - result = s.data - -proc to*[T](data: string): T = - ## reads data and transforms it to a ``T``. - var tab = initTable[biggestInt, pointer]() - loadAny(newStringStream(data), toAny(result), tab) - -when isMainModule: - template testit(x: expr) = echo($$to[type(x)]($$x)) - - var x: array[0..4, array[0..4, string]] = [ - ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], - ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], - ["test", "1", "2", "3", "4"]] - testit(x) - var test2: tuple[name: string, s: uint] = ("tuple test", 56u) - testit(test2) - - type - TE = enum - blah, blah2 - - TestObj = object - test, asd: int - case test2: TE - of blah: - help: string - else: - nil - - PNode = ref TNode - TNode = object - next, prev: PNode - data: string - - proc buildList(): PNode = - new(result) - new(result.next) - new(result.prev) - result.data = "middle" - result.next.data = "next" - result.prev.data = "prev" - result.next.next = result.prev - result.next.prev = result - result.prev.next = result - result.prev.prev = result.next - - var test3: TestObj - test3.test = 42 - test3.test2 = blah - testit(test3) - - var test4: ref tuple[a, b: string] - new(test4) - test4.a = "ref string test: A" - test4.b = "ref string test: B" - testit(test4) - - var test5 = @[(0,1),(2,3),(4,5)] - testit(test5) - - var test6: set[char] = {'A'..'Z', '_'} - testit(test6) - - var test7 = buildList() - echo($$test7) - testit(test7) - - type - TA {.inheritable.} = object - TB = object of TA - f: int - - var - a: ref TA - b: ref TB - new(b) - a = b - echo($$a[]) # produces "{}", not "{f: 0}" - +# +# +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module contains procs for serialization and deseralization of +## arbitrary Nim data structures. The serialization format uses JSON. +## +## **Restriction**: For objects their type is **not** serialized. This means +## essentially that it does not work if the object has some other runtime +## type than its compiletime type: +## +## .. code-block:: nim +## +## type +## TA = object +## TB = object of TA +## f: int +## +## var +## a: ref TA +## b: ref TB +## +## new(b) +## a = b +## echo($$a[]) # produces "{}", not "{f: 0}" + +import streams, typeinfo, json, intsets, tables + +proc ptrToInt(x: pointer): int {.inline.} = + result = cast[int](x) # don't skip alignment + +proc storeAny(s: Stream, a: TAny, stored: var IntSet) = + case a.kind + of akNone: assert false + of akBool: s.write($getBool(a)) + of akChar: s.write(escapeJson($getChar(a))) + of akArray, akSequence: + if a.kind == akSequence and isNil(a): s.write("null") + else: + s.write("[") + for i in 0 .. a.len-1: + if i > 0: s.write(", ") + storeAny(s, a[i], stored) + s.write("]") + of akObject, akTuple: + s.write("{") + var i = 0 + for key, val in fields(a): + if i > 0: s.write(", ") + s.write(escapeJson(key)) + s.write(": ") + storeAny(s, val, stored) + inc(i) + s.write("}") + of akSet: + s.write("[") + var i = 0 + for e in elements(a): + if i > 0: s.write(", ") + s.write($e) + inc(i) + s.write("]") + of akRange: storeAny(s, skipRange(a), stored) + of akEnum: s.write(getEnumField(a).escapeJson) + of akPtr, akRef: + var x = a.getPointer + if isNil(x): s.write("null") + elif stored.containsOrIncl(x.ptrToInt): + # already stored, so we simply write out the pointer as an int: + s.write($x.ptrToInt) + else: + # else as a [value, key] pair: + # (reversed order for convenient x[0] access!) + s.write("[") + s.write($x.ptrToInt) + s.write(", ") + storeAny(s, a[], stored) + s.write("]") + of akProc, akPointer, akCString: s.write($a.getPointer.ptrToInt) + of akString: + var x = getString(a) + if isNil(x): s.write("null") + else: s.write(escapeJson(x)) + of akInt..akInt64, akUInt..akUInt64: s.write($getBiggestInt(a)) + of akFloat..akFloat128: s.write($getBiggestFloat(a)) + +proc loadAny(p: var JsonParser, a: TAny, t: var Table[BiggestInt, pointer]) = + case a.kind + of akNone: assert false + of akBool: + case p.kind + of jsonFalse: setBiggestInt(a, 0) + of jsonTrue: setBiggestInt(a, 1) + else: raiseParseErr(p, "'true' or 'false' expected for a bool") + next(p) + of akChar: + if p.kind == jsonString: + var x = p.str + if x.len == 1: + setBiggestInt(a, ord(x[0])) + next(p) + return + raiseParseErr(p, "string of length 1 expected for a char") + of akEnum: + if p.kind == jsonString: + setBiggestInt(a, getEnumOrdinal(a, p.str)) + next(p) + return + raiseParseErr(p, "string expected for an enum") + of akArray: + if p.kind != jsonArrayStart: raiseParseErr(p, "'[' expected for an array") + next(p) + var i = 0 + while p.kind != jsonArrayEnd and p.kind != jsonEof: + loadAny(p, a[i], t) + inc(i) + if p.kind == jsonArrayEnd: next(p) + else: raiseParseErr(p, "']' end of array expected") + of akSequence: + case p.kind + of jsonNull: + setPointer(a, nil) + next(p) + of jsonArrayStart: + next(p) + invokeNewSeq(a, 0) + var i = 0 + while p.kind != jsonArrayEnd and p.kind != jsonEof: + extendSeq(a) + loadAny(p, a[i], t) + inc(i) + if p.kind == jsonArrayEnd: next(p) + else: raiseParseErr(p, "") + else: + raiseParseErr(p, "'[' expected for a seq") + of akObject, akTuple: + if a.kind == akObject: setObjectRuntimeType(a) + if p.kind != jsonObjectStart: raiseParseErr(p, "'{' expected for an object") + next(p) + while p.kind != jsonObjectEnd and p.kind != jsonEof: + if p.kind != jsonString: + raiseParseErr(p, "string expected for a field name") + var fieldName = p.str + next(p) + loadAny(p, a[fieldName], t) + if p.kind == jsonObjectEnd: next(p) + else: raiseParseErr(p, "'}' end of object expected") + of akSet: + if p.kind != jsonArrayStart: raiseParseErr(p, "'[' expected for a set") + next(p) + while p.kind != jsonArrayEnd and p.kind != jsonEof: + if p.kind != jsonInt: raiseParseErr(p, "int expected for a set") + inclSetElement(a, p.getInt.int) + next(p) + if p.kind == jsonArrayEnd: next(p) + else: raiseParseErr(p, "']' end of array expected") + of akPtr, akRef: + case p.kind + of jsonNull: + setPointer(a, nil) + next(p) + of jsonInt: + setPointer(a, t[p.getInt]) + next(p) + of jsonArrayStart: + next(p) + if a.kind == akRef: invokeNew(a) + else: setPointer(a, alloc0(a.baseTypeSize)) + if p.kind == jsonInt: + t[p.getInt] = getPointer(a) + next(p) + else: raiseParseErr(p, "index for ref type expected") + loadAny(p, a[], t) + if p.kind == jsonArrayEnd: next(p) + else: raiseParseErr(p, "']' end of ref-address pair expected") + else: raiseParseErr(p, "int for pointer type expected") + of akProc, akPointer, akCString: + case p.kind + of jsonNull: + setPointer(a, nil) + next(p) + of jsonInt: + setPointer(a, cast[pointer](p.getInt.int)) + next(p) + else: raiseParseErr(p, "int for pointer type expected") + of akString: + case p.kind + of jsonNull: + setPointer(a, nil) + next(p) + of jsonString: + setString(a, p.str) + next(p) + else: raiseParseErr(p, "string expected") + of akInt..akInt64, akUInt..akUInt64: + if p.kind == jsonInt: + setBiggestInt(a, getInt(p)) + next(p) + return + raiseParseErr(p, "int expected") + of akFloat..akFloat128: + if p.kind == jsonFloat: + setBiggestFloat(a, getFloat(p)) + next(p) + return + raiseParseErr(p, "float expected") + of akRange: loadAny(p, a.skipRange, t) + +proc loadAny(s: Stream, a: TAny, t: var Table[BiggestInt, pointer]) = + var p: JsonParser + open(p, s, "unknown file") + next(p) + loadAny(p, a, t) + close(p) + +proc load*[T](s: Stream, data: var T) = + ## loads `data` from the stream `s`. Raises `EIO` in case of an error. + var tab = initTable[BiggestInt, pointer]() + loadAny(s, toAny(data), tab) + +proc store*[T](s: Stream, data: T) = + ## stores `data` into the stream `s`. Raises `EIO` in case of an error. + var stored = initIntSet() + var d: T + shallowCopy(d, data) + storeAny(s, toAny(d), stored) + +proc `$$`*[T](x: T): string = + ## returns a string representation of `x`. + var stored = initIntSet() + var d: T + shallowCopy(d, x) + var s = newStringStream() + storeAny(s, toAny(d), stored) + result = s.data + +proc to*[T](data: string): T = + ## reads data and transforms it to a ``T``. + var tab = initTable[BiggestInt, pointer]() + loadAny(newStringStream(data), toAny(result), tab) + +when isMainModule: + template testit(x: expr) = echo($$to[type(x)]($$x)) + + var x: array[0..4, array[0..4, string]] = [ + ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], + ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], + ["test", "1", "2", "3", "4"]] + testit(x) + var test2: tuple[name: string, s: uint] = ("tuple test", 56u) + testit(test2) + + type + TE = enum + blah, blah2 + + TestObj = object + test, asd: int + case test2: TE + of blah: + help: string + else: + nil + + PNode = ref TNode + TNode = object + next, prev: PNode + data: string + + proc buildList(): PNode = + new(result) + new(result.next) + new(result.prev) + result.data = "middle" + result.next.data = "next" + result.prev.data = "prev" + result.next.next = result.prev + result.next.prev = result + result.prev.next = result + result.prev.prev = result.next + + var test3: TestObj + test3.test = 42 + test3.test2 = blah + testit(test3) + + var test4: ref tuple[a, b: string] + new(test4) + test4.a = "ref string test: A" + test4.b = "ref string test: B" + testit(test4) + + var test5 = @[(0,1),(2,3),(4,5)] + testit(test5) + + var test6: set[char] = {'A'..'Z', '_'} + testit(test6) + + var test7 = buildList() + echo($$test7) + testit(test7) + + type + TA {.inheritable.} = object + TB = object of TA + f: int + + var + a: ref TA + b: ref TB + new(b) + a = b + echo($$a[]) # produces "{}", not "{f: 0}" + From 00f50f27973ff33217eabe0b5f02cab49a0d8601 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 02:12:49 +0200 Subject: [PATCH 023/409] more modules updated --- lib/pure/matchers.nim | 4 ++-- lib/pure/strutils.nim | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim index c3ad7235f..46fc9985c 100644 --- a/lib/pure/matchers.nim +++ b/lib/pure/matchers.nim @@ -31,8 +31,8 @@ proc validEmailAddress*(s: string): bool {.noSideEffect, inc(i) if s[i] != '@': return false var j = len(s)-1 - if s[j] notin letters: return false - while j >= i and s[j] in letters: dec(j) + if s[j] notin Letters: return false + while j >= i and s[j] in Letters: dec(j) inc(i) # skip '@' while s[i] in {'0'..'9', 'a'..'z', '-', '.'}: inc(i) if s[i] != '\0': return false diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 2af973b6e..5153455e2 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -130,7 +130,7 @@ proc normalize*(s: string): string {.noSideEffect, procvar, if j != s.len: setLen(result, j) proc cmpIgnoreCase*(a, b: string): int {.noSideEffect, - rtl, extern: "nsuCmpIgnoreCase", procvar, operator: 4.} = + rtl, extern: "nsuCmpIgnoreCase", procvar.} = ## Compares two strings in a case insensitive manner. Returns: ## ## | 0 iff a == b @@ -148,7 +148,7 @@ proc cmpIgnoreCase*(a, b: string): int {.noSideEffect, # thus we compile without checks here proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect, - rtl, extern: "nsuCmpIgnoreStyle", procvar, operator: 3.} = + rtl, extern: "nsuCmpIgnoreStyle", procvar.} = ## Compares two strings normalized (i.e. case and ## underscores do not matter). Returns: ## @@ -170,7 +170,7 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect, {.pop.} proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect, - rtl, extern: "nsuStrip", operator: 5.} = + rtl, extern: "nsuStrip".} = ## Strips whitespace from `s` and returns the resulting string. ## ## If `leading` is true, leading whitespace is stripped. @@ -1147,7 +1147,7 @@ type proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, precision: range[0..32] = 16): string {. - noSideEffect, operator: 2, rtl, extern: "nsu$1".} = + noSideEffect, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. ## ## If ``format == ffDecimal`` then precision is the number of digits to @@ -1178,7 +1178,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, precision: range[0..32] = 16): string {. - noSideEffect, operator: 2, rtl, extern: "nsu$1".} = + noSideEffect, rtl, extern: "nsu$1".} = ## Converts a floating point value `f` to a string. ## ## If ``format == ffDecimal`` then precision is the number of digits to From 2b6277c9649fb8672984cc8afc2068afd6c331a1 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 02:14:25 +0200 Subject: [PATCH 024/409] more modules updated --- lib/pure/nimprof.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim index 6b8fe1ce5..3598cdd3a 100644 --- a/lib/pure/nimprof.nim +++ b/lib/pure/nimprof.nim @@ -132,9 +132,9 @@ else: proc hook(st: TStackTrace) {.nimcall.} = if interval == 0: hookAux(st, 1) - elif getticks() - t0 > interval: + elif getTicks() - t0 > interval: hookAux(st, 1) - t0 = getticks() + t0 = getTicks() proc getTotal(x: ptr TProfileEntry): int = result = if isNil(x): 0 else: x.total @@ -150,7 +150,7 @@ proc writeProfile() {.noconv.} = system.profilerHook = nil const filename = "profile_results.txt" echo "writing " & filename & "..." - var f: TFile + var f: File if open(f, filename, fmWrite): sort(profileData, cmpEntries) writeln(f, "total executions of each stack trace:") From bf9764e563c4ec84ad29eaf12112a8f10d336681 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 02:21:49 +0200 Subject: [PATCH 025/409] several modules changed --- lib/pure/oids.nim | 2 +- lib/pure/parsecfg.nim | 9 ++- lib/pure/parsecsv.nim | 2 +- lib/pure/parseopt.nim | 2 +- lib/pure/parseopt2.nim | 6 +- lib/pure/parsesql.nim | 126 ++++++++++++++++++++--------------------- lib/pure/parseurl.nim | 14 ++--- 7 files changed, 80 insertions(+), 81 deletions(-) diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim index c0bfb7c08..7c58a2dda 100644 --- a/lib/pure/oids.nim +++ b/lib/pure/oids.nim @@ -89,5 +89,5 @@ proc generatedTime*(oid: Oid): Time = result = Time(tmp) when isMainModule: - let xo = genOID() + let xo = genOid() echo xo.generatedTime diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index c340bf98b..a45976d86 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -38,7 +38,7 @@ type cfgError ## an error ocurred during parsing CfgEvent* = object of RootObj ## describes a parsing event - case kind*: TCfgEventKind ## the kind of the event + case kind*: CfgEventKind ## the kind of the event of cfgEof: nil of cfgSectionStart: section*: string ## `section` contains the name of the @@ -70,12 +70,11 @@ type # implementation const - SymChars: CharSet = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.', - '/', '\\'} + SymChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.', '/', '\\'} proc rawGetTok(c: var CfgParser, tok: var Token) {.gcsafe.} -proc open*(c: var CfgParser, input: PStream, filename: string, +proc open*(c: var CfgParser, input: Stream, filename: string, lineOffset = 0) {.rtl, extern: "npc$1".} = ## initializes the parser with an input stream. `Filename` is only used ## for nice error messages. `lineOffset` can be used to influence the line @@ -122,7 +121,7 @@ proc handleDecChars(c: var CfgParser, xi: var int) = xi = (xi * 10) + (ord(c.buf[c.bufpos]) - ord('0')) inc(c.bufpos) -proc getEscapedChar(c: var CfgParser, tok: var TToken) = +proc getEscapedChar(c: var CfgParser, tok: var Token) = inc(c.bufpos) # skip '\' case c.buf[c.bufpos] of 'n', 'N': diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim index d267906a3..c8abdca4f 100644 --- a/lib/pure/parsecsv.nim +++ b/lib/pure/parsecsv.nim @@ -155,7 +155,7 @@ proc readRow*(my: var CsvParser, columns = 0): bool = else: error(my, my.bufpos, my.sep & " expected") break - setlen(my.row, col) + setLen(my.row, col) result = col > 0 if result and col != columns and columns > 0: error(my, oldpos+1, $columns & " columns expected, but found " & diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index b325bd1f5..de00bc76d 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -59,7 +59,7 @@ when declared(os.paramCount): result.val = TaintedString"" proc parseWord(s: string, i: int, w: var string, - delim: CharSet = {'\x09', ' ', '\0'}): int = + delim: set[char] = {'\x09', ' ', '\0'}): int = result = i if s[result] == '\"': inc(result) diff --git a/lib/pure/parseopt2.nim b/lib/pure/parseopt2.nim index c283a5edf..5b1f50958 100644 --- a/lib/pure/parseopt2.nim +++ b/lib/pure/parseopt2.nim @@ -31,7 +31,7 @@ type cmdLongOption, ## a long option ``--option`` detected cmdShortOption ## a short option ``-c`` detected OptParser* = - object of TObject ## this object implements the command line parser + object of RootObj ## this object implements the command line parser cmd: seq[string] pos: int remainingShortOptions: string @@ -102,10 +102,10 @@ proc next(p: var OptParser) = let token = p.cmd[p.pos] p.pos += 1 - if token.startswith("--"): + if token.startsWith("--"): p.kind = cmdLongOption nextOption(p, token[2..token.len-1], allowEmpty=true) - elif token.startswith("-"): + elif token.startsWith("-"): p.kind = cmdShortOption nextOption(p, token[1..token.len-1], allowEmpty=true) else: diff --git a/lib/pure/parsesql.nim b/lib/pure/parsesql.nim index fcca0aa44..bb4ede779 100644 --- a/lib/pure/parsesql.nim +++ b/lib/pure/parsesql.nim @@ -64,12 +64,12 @@ proc close(L: var SqlLexer) = proc getColumn(L: SqlLexer): int = ## get the current column the parser has arrived at. - result = getColNumber(L, L.bufPos) + result = getColNumber(L, L.bufpos) proc getLine(L: SqlLexer): int = - result = L.linenumber + result = L.lineNumber -proc handleHexChar(c: var TSqlLexer, xi: var int) = +proc handleHexChar(c: var SqlLexer, xi: var int) = case c.buf[c.bufpos] of '0'..'9': xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) @@ -83,76 +83,76 @@ proc handleHexChar(c: var TSqlLexer, xi: var int) = else: discard -proc handleOctChar(c: var TSqlLexer, xi: var int) = +proc handleOctChar(c: var SqlLexer, xi: var int) = if c.buf[c.bufpos] in {'0'..'7'}: xi = (xi shl 3) or (ord(c.buf[c.bufpos]) - ord('0')) inc(c.bufpos) -proc getEscapedChar(c: var TSqlLexer, tok: var TToken) = +proc getEscapedChar(c: var SqlLexer, tok: var Token) = inc(c.bufpos) case c.buf[c.bufpos] of 'n', 'N': add(tok.literal, '\L') - Inc(c.bufpos) + inc(c.bufpos) of 'r', 'R', 'c', 'C': add(tok.literal, '\c') - Inc(c.bufpos) + inc(c.bufpos) of 'l', 'L': add(tok.literal, '\L') - Inc(c.bufpos) + inc(c.bufpos) of 'f', 'F': add(tok.literal, '\f') inc(c.bufpos) of 'e', 'E': add(tok.literal, '\e') - Inc(c.bufpos) + inc(c.bufpos) of 'a', 'A': add(tok.literal, '\a') - Inc(c.bufpos) + inc(c.bufpos) of 'b', 'B': add(tok.literal, '\b') - Inc(c.bufpos) + inc(c.bufpos) of 'v', 'V': add(tok.literal, '\v') - Inc(c.bufpos) + inc(c.bufpos) of 't', 'T': add(tok.literal, '\t') - Inc(c.bufpos) + inc(c.bufpos) of '\'', '\"': add(tok.literal, c.buf[c.bufpos]) - Inc(c.bufpos) + inc(c.bufpos) of '\\': add(tok.literal, '\\') - Inc(c.bufpos) + inc(c.bufpos) of 'x', 'X': inc(c.bufpos) var xi = 0 handleHexChar(c, xi) handleHexChar(c, xi) - add(tok.literal, Chr(xi)) + add(tok.literal, chr(xi)) of '0'..'7': var xi = 0 handleOctChar(c, xi) handleOctChar(c, xi) handleOctChar(c, xi) - if (xi <= 255): add(tok.literal, Chr(xi)) + if (xi <= 255): add(tok.literal, chr(xi)) else: tok.kind = tkInvalid else: tok.kind = tkInvalid -proc handleCRLF(c: var TSqlLexer, pos: int): int = +proc handleCRLF(c: var SqlLexer, pos: int): int = case c.buf[pos] of '\c': result = lexbase.handleCR(c, pos) of '\L': result = lexbase.handleLF(c, pos) else: result = pos -proc skip(c: var TSqlLexer) = +proc skip(c: var SqlLexer) = var pos = c.bufpos var buf = c.buf var nested = 0 while true: case buf[pos] of ' ', '\t': - Inc(pos) + inc(pos) of '-': if buf[pos+1] == '-': while not (buf[pos] in {'\c', '\L', lexbase.EndOfFile}): inc(pos) @@ -189,8 +189,8 @@ proc skip(c: var TSqlLexer) = break # EndOfFile also leaves the loop c.bufpos = pos -proc getString(c: var TSqlLexer, tok: var TToken, kind: TokKind) = - var pos = c.bufPos + 1 +proc getString(c: var SqlLexer, tok: var Token, kind: TokKind) = + var pos = c.bufpos + 1 var buf = c.buf tok.kind = kind block parseLoop: @@ -208,16 +208,16 @@ proc getString(c: var TSqlLexer, tok: var TToken, kind: TokKind) = tok.kind = tkInvalid break parseLoop elif (ch == '\\') and kind == tkEscapeConstant: - c.bufPos = pos + c.bufpos = pos getEscapedChar(c, tok) - pos = c.bufPos + pos = c.bufpos else: add(tok.literal, ch) - Inc(pos) + inc(pos) c.bufpos = pos - var line = c.linenumber + var line = c.lineNumber skip(c) - if c.linenumber > line: + if c.lineNumber > line: # a new line whitespace has been parsed, so we check if the string # continues after the whitespace: buf = c.buf # may have been reallocated @@ -227,8 +227,8 @@ proc getString(c: var TSqlLexer, tok: var TToken, kind: TokKind) = else: break parseLoop c.bufpos = pos -proc getDollarString(c: var TSqlLexer, tok: var TToken) = - var pos = c.bufPos + 1 +proc getDollarString(c: var SqlLexer, tok: var Token) = + var pos = c.bufpos + 1 var buf = c.buf tok.kind = tkDollarQuotedConstant var tag = "$" @@ -242,7 +242,7 @@ proc getDollarString(c: var TSqlLexer, tok: var TToken) = while true: case buf[pos] of '\c', '\L': - pos = HandleCRLF(c, pos) + pos = handleCRLF(c, pos) buf = c.buf add(tok.literal, "\L") of '\0': @@ -263,19 +263,19 @@ proc getDollarString(c: var TSqlLexer, tok: var TToken) = inc(pos) c.bufpos = pos -proc getSymbol(c: var TSqlLexer, tok: var TToken) = +proc getSymbol(c: var SqlLexer, tok: var Token) = var pos = c.bufpos var buf = c.buf while true: add(tok.literal, buf[pos]) - Inc(pos) + inc(pos) if buf[pos] notin {'a'..'z','A'..'Z','0'..'9','_','$', '\128'..'\255'}: break c.bufpos = pos tok.kind = tkIdentifier -proc getQuotedIdentifier(c: var TSqlLexer, tok: var TToken) = - var pos = c.bufPos + 1 +proc getQuotedIdentifier(c: var SqlLexer, tok: var Token) = + var pos = c.bufpos + 1 var buf = c.buf tok.kind = tkQuotedIdentifier while true: @@ -292,11 +292,11 @@ proc getQuotedIdentifier(c: var TSqlLexer, tok: var TToken) = break else: add(tok.literal, ch) - Inc(pos) + inc(pos) c.bufpos = pos -proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) = - var pos = c.bufPos + 1 +proc getBitHexString(c: var SqlLexer, tok: var Token, validChars: set[char]) = + var pos = c.bufpos + 1 var buf = c.buf block parseLoop: while true: @@ -304,7 +304,7 @@ proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) = var ch = buf[pos] if ch in validChars: add(tok.literal, ch) - Inc(pos) + inc(pos) elif ch == '\'': inc(pos) break @@ -312,9 +312,9 @@ proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) = tok.kind = tkInvalid break parseLoop c.bufpos = pos - var line = c.linenumber + var line = c.lineNumber skip(c) - if c.linenumber > line: + if c.lineNumber > line: # a new line whitespace has been parsed, so we check if the string # continues after the whitespace: buf = c.buf # may have been reallocated @@ -324,9 +324,9 @@ proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) = else: break parseLoop c.bufpos = pos -proc getNumeric(c: var TSqlLexer, tok: var TToken) = +proc getNumeric(c: var SqlLexer, tok: var Token) = tok.kind = tkInteger - var pos = c.bufPos + var pos = c.bufpos var buf = c.buf while buf[pos] in Digits: add(tok.literal, buf[pos]) @@ -355,11 +355,11 @@ proc getNumeric(c: var TSqlLexer, tok: var TToken) = tok.kind = tkInvalid c.bufpos = pos -proc getOperator(c: var TSqlLexer, tok: var TToken) = +proc getOperator(c: var SqlLexer, tok: var Token) = const operators = {'+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%', '^', '&', '|', '`', '?'} tok.kind = tkOperator - var pos = c.bufPos + var pos = c.bufpos var buf = c.buf var trailingPlusMinus = false while true: @@ -381,14 +381,14 @@ proc getOperator(c: var TSqlLexer, tok: var TToken) = inc(pos) c.bufpos = pos -proc getTok(c: var TSqlLexer, tok: var TToken) = +proc getTok(c: var SqlLexer, tok: var Token) = tok.kind = tkInvalid - setlen(tok.literal, 0) + setLen(tok.literal, 0) skip(c) case c.buf[c.bufpos] of ';': - tok.kind = tkSemiColon - inc(c.bufPos) + tok.kind = tkSemicolon + inc(c.bufpos) add(tok.literal, ';') of ',': tok.kind = tkComma @@ -399,19 +399,19 @@ proc getTok(c: var TSqlLexer, tok: var TToken) = inc(c.bufpos) add(tok.literal, ':') of 'e', 'E': - if c.buf[c.bufPos + 1] == '\'': - Inc(c.bufPos) + if c.buf[c.bufpos + 1] == '\'': + inc(c.bufpos) getString(c, tok, tkEscapeConstant) else: getSymbol(c, tok) of 'b', 'B': - if c.buf[c.bufPos + 1] == '\'': + if c.buf[c.bufpos + 1] == '\'': tok.kind = tkBitStringConstant getBitHexString(c, tok, {'0'..'1'}) else: getSymbol(c, tok) of 'x', 'X': - if c.buf[c.bufPos + 1] == '\'': + if c.buf[c.bufpos + 1] == '\'': tok.kind = tkHexStringConstant getBitHexString(c, tok, {'a'..'f','A'..'F','0'..'9'}) else: @@ -423,18 +423,18 @@ proc getTok(c: var TSqlLexer, tok: var TToken) = add(tok.literal, '[') of ']': tok.kind = tkBracketRi - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, ']') of '(': tok.kind = tkParLe - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, '(') of ')': tok.kind = tkParRi - Inc(c.bufpos) + inc(c.bufpos) add(tok.literal, ')') of '.': - if c.buf[c.bufPos + 1] in Digits: + if c.buf[c.bufpos + 1] in Digits: getNumeric(c, tok) else: tok.kind = tkDot @@ -456,7 +456,7 @@ proc getTok(c: var TSqlLexer, tok: var TToken) = add(tok.literal, c.buf[c.bufpos]) inc(c.bufpos) -proc errorStr(L: TSqlLexer, msg: string): string = +proc errorStr(L: SqlLexer, msg: string): string = result = "$1($2, $3) Error: $4" % [L.filename, $getLine(L), $getColumn(L), msg] @@ -819,7 +819,7 @@ proc parseColumnDef(p: var SqlParser): SqlNode = result.add(parseDataType(p)) parseColumnConstraints(p, result) -proc parseIfNotExists(p: var SqlParser, k: TSqlNodeKind): SqlNode = +proc parseIfNotExists(p: var SqlParser, k: SqlNodeKind): SqlNode = getTok(p) if isKeyw(p, "if"): getTok(p) @@ -1076,10 +1076,10 @@ proc parseStmt(p: var SqlParser): SqlNode = else: sqlError(p, "CREATE expected") -proc open(p: var SqlParser, input: PStream, filename: string) = +proc open(p: var SqlParser, input: Stream, filename: string) = ## opens the parser `p` and assigns the input stream `input` to it. ## `filename` is only used for error messages. - open(TSqlLexer(p), input, filename) + open(SqlLexer(p), input, filename) p.tok.kind = tkInvalid p.tok.literal = "" getTok(p) @@ -1090,16 +1090,16 @@ proc parse(p: var SqlParser): SqlNode = result = newNode(nkStmtList) while p.tok.kind != tkEof: var s = parseStmt(p) - eat(p, tkSemiColon) + eat(p, tkSemicolon) result.add(s) if result.len == 1: result = result.sons[0] proc close(p: var SqlParser) = ## closes the parser `p`. The associated input stream is closed too. - close(TSqlLexer(p)) + close(SqlLexer(p)) -proc parseSQL*(input: PStream, filename: string): SqlNode = +proc parseSQL*(input: Stream, filename: string): SqlNode = ## parses the SQL from `input` into an AST and returns the AST. ## `filename` is only used for error messages. ## Syntax errors raise an `EInvalidSql` exception. diff --git a/lib/pure/parseurl.nim b/lib/pure/parseurl.nim index 2637a879d..32e69b89a 100644 --- a/lib/pure/parseurl.nim +++ b/lib/pure/parseurl.nim @@ -31,12 +31,12 @@ proc parseUrl*(url: string): Url {.deprecated.} = var temp = "" if url[i] != '/': # url isn't a relative path - while True: + while true: # Scheme if url[i] == ':': if url[i+1] == '/' and url[i+2] == '/': scheme = temp - temp.setlen(0) + temp.setLen(0) inc(i, 3) # Skip the // # Authority(username, password) if url[i] == '@': @@ -45,7 +45,7 @@ proc parseUrl*(url: string): Url {.deprecated.} = if colon >= 0: password = username.substr(colon+1) username = username.substr(0, colon-1) - temp.setlen(0) + temp.setLen(0) inc(i) #Skip the @ # hostname(subdomain, domain, port) if url[i] == '/' or url[i] == '\0': @@ -55,7 +55,7 @@ proc parseUrl*(url: string): Url {.deprecated.} = port = hostname.substr(colon+1) hostname = hostname.substr(0, colon-1) - temp.setlen(0) + temp.setLen(0) break temp.add(url[i]) @@ -63,16 +63,16 @@ proc parseUrl*(url: string): Url {.deprecated.} = if url[i] == '/': inc(i) # Skip the '/' # Path - while True: + while true: if url[i] == '?': path = temp - temp.setlen(0) + temp.setLen(0) if url[i] == '#': if temp[0] == '?': query = temp else: path = temp - temp.setlen(0) + temp.setLen(0) if url[i] == '\0': if temp[0] == '?': From cca8887ba072f99e52f45d66f2855272817d2123 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 02:26:22 +0200 Subject: [PATCH 026/409] updated pegs module --- lib/pure/pegs.nim | 76 +++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 8bd307c7d..b2d8a2a4f 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -81,7 +81,7 @@ type of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: term: string of pkChar, pkGreedyRepChar: ch: char of pkCharChoice, pkGreedyRepSet: charChoice: ref set[char] - of pkNonTerminal: nt: PNonTerminal + of pkNonTerminal: nt: NonTerminal of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns] else: sons: seq[TNode] NonTerminal* = ref NonTerminalObj @@ -237,7 +237,7 @@ proc anyRune*: Peg {.inline.} = proc newLine*: Peg {.inline.} = ## constructs the PEG `newline`:idx: (``\n``) - result.kind = pkNewline + result.kind = pkNewLine proc unicodeLetter*: Peg {.inline.} = ## constructs the PEG ``\letter`` which matches any Unicode letter. @@ -273,21 +273,21 @@ proc capture*(a: Peg): Peg {.nosideEffect, rtl, extern: "npegsCapture".} = result.kind = pkCapture result.sons = @[a] -proc backref*(index: range[1..MaxSubPatterns]): Peg {. +proc backref*(index: range[1..MaxSubpatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a back reference of the given `index`. `index` starts counting ## from 1. result.kind = pkBackRef result.index = index-1 -proc backrefIgnoreCase*(index: range[1..MaxSubPatterns]): Peg {. +proc backrefIgnoreCase*(index: range[1..MaxSubpatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a back reference of the given `index`. `index` starts counting ## from 1. Ignores case for matching. result.kind = pkBackRefIgnoreCase result.index = index-1 -proc backrefIgnoreStyle*(index: range[1..MaxSubPatterns]): Peg {. +proc backrefIgnoreStyle*(index: range[1..MaxSubpatterns]): Peg {. nosideEffect, rtl, extern: "npegs$1".}= ## constructs a back reference of the given `index`. `index` starts counting ## from 1. Ignores style for matching. @@ -309,7 +309,7 @@ proc spaceCost(n: Peg): int = inc(result, spaceCost(n.sons[i])) if result >= InlineThreshold: break -proc nonterminal*(n: PNonTerminal): Peg {. +proc nonterminal*(n: NonTerminal): Peg {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a PEG that consists of the nonterminal symbol assert n != nil @@ -320,7 +320,7 @@ proc nonterminal*(n: PNonTerminal): Peg {. result.kind = pkNonTerminal result.nt = n -proc newNonTerminal*(name: string, line, column: int): PNonTerminal {. +proc newNonTerminal*(name: string, line, column: int): NonTerminal {. nosideEffect, rtl, extern: "npegs$1".} = ## constructs a nonterminal symbol new(result) @@ -416,7 +416,7 @@ proc toStrAux(r: Peg, res: var string) = of pkTitle: add(res, "\\title") of pkWhitespace: add(res, "\\white") - of pkNewline: add(res, "\\n") + of pkNewLine: add(res, "\\n") of pkTerminal: add(res, singleQuoteEsc(r.term)) of pkTerminalIgnoreCase: add(res, 'i') @@ -500,14 +500,14 @@ proc `$` *(r: Peg): string {.nosideEffect, rtl, extern: "npegsToString".} = type Captures* = object ## contains the captured substrings. - matches: array[0..maxSubpatterns-1, tuple[first, last: int]] + matches: array[0..MaxSubpatterns-1, tuple[first, last: int]] ml: int origStart: int {.deprecated: [TCaptures: Captures].} proc bounds*(c: Captures, - i: range[0..maxSubpatterns-1]): tuple[first, last: int] = + i: range[0..MaxSubpatterns-1]): tuple[first, last: int] = ## returns the bounds ``[first..last]`` of the `i`'th capture. result = c.matches[i] @@ -543,7 +543,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. result = -1 of pkLetter: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isAlpha(a): dec(result, start) @@ -552,7 +552,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. result = -1 of pkLower: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isLower(a): dec(result, start) @@ -561,7 +561,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. result = -1 of pkUpper: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isUpper(a): dec(result, start) @@ -570,7 +570,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. result = -1 of pkTitle: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isTitle(a): dec(result, start) @@ -579,7 +579,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. result = -1 of pkWhitespace: if s[start] != '\0': - var a: TRune + var a: Rune result = start fastRuneAt(s, result, a) if isWhiteSpace(a): dec(result, start) @@ -603,7 +603,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. of pkTerminalIgnoreCase: var i = 0 - a, b: TRune + a, b: Rune result = start while i < len(p.term): fastRuneAt(p.term, i, a) @@ -615,15 +615,15 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. of pkTerminalIgnoreStyle: var i = 0 - a, b: TRune + a, b: Rune result = start while i < len(p.term): while true: fastRuneAt(p.term, i, a) - if a != TRune('_'): break + if a != Rune('_'): break while true: fastRuneAt(s, result, b) - if b != TRune('_'): break + if b != Rune('_'): break if toLower(a) != toLower(b): result = -1 break @@ -674,7 +674,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. while start+result < s.len: var x = rawMatch(s, p.sons[0], start+result, c) if x >= 0: - if idx < maxSubpatterns: + if idx < MaxSubpatterns: c.matches[idx] = (start, start+result-1) #else: silently ignore the capture inc(result, x) @@ -718,7 +718,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {. inc(c.ml) result = rawMatch(s, p.sons[0], start, c) if result >= 0: - if idx < maxSubpatterns: + if idx < MaxSubpatterns: c.matches[idx] = (start, start+result-1) #else: silently ignore the capture else: @@ -861,7 +861,7 @@ template `=~`*(s: string, pattern: Peg): bool = ## else: ## echo("syntax error") ## - bind maxSubpatterns + bind MaxSubpatterns when not declaredInScope(matches): var matches {.inject.}: array[0..MaxSubpatterns-1, string] match(s, pattern, matches) @@ -906,7 +906,7 @@ proc replacef*(s: string, sub: Peg, by: string): string {. ## "var1<-keykey; val2<-key2key2" result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] var c: Captures while i < s.len: c.ml = 0 @@ -945,7 +945,7 @@ proc parallelReplace*(s: string, subs: varargs[ result = "" var i = 0 var c: Captures - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: block searchSubs: for j in 0..high(subs): @@ -1055,7 +1055,7 @@ type PegLexer {.inheritable.} = object ## the lexer object. bufpos: int ## the current position within the buffer buf: cstring ## the buffer itself - LineNumber: int ## the current line number + lineNumber: int ## the current line number lineStart: int ## index of last line start in buffer colOffset: int ## column to add filename: string @@ -1070,14 +1070,14 @@ const proc handleCR(L: var PegLexer, pos: int): int = assert(L.buf[pos] == '\c') - inc(L.linenumber) + inc(L.lineNumber) result = pos+1 if L.buf[result] == '\L': inc(result) L.lineStart = result proc handleLF(L: var PegLexer, pos: int): int = assert(L.buf[pos] == '\L') - inc(L.linenumber) + inc(L.lineNumber) result = pos+1 L.lineStart = result @@ -1093,7 +1093,7 @@ proc getColumn(L: PegLexer): int {.inline.} = result = abs(L.bufpos - L.lineStart) + L.colOffset proc getLine(L: PegLexer): int {.inline.} = - result = L.linenumber + result = L.lineNumber proc errorStr(L: PegLexer, msg: string, line = -1, col = -1): string = var line = if line < 0: getLine(L) else: line @@ -1159,7 +1159,7 @@ proc getEscapedChar(c: var PegLexer, tok: var TToken) = else: tok.kind = tkInvalid of '\0'..'\31': tok.kind = tkInvalid - elif c.buf[c.bufpos] in strutils.letters: + elif c.buf[c.bufpos] in strutils.Letters: tok.kind = tkInvalid else: add(tok.literal, c.buf[c.bufpos]) @@ -1186,7 +1186,7 @@ proc skip(c: var PegLexer) = proc getString(c: var PegLexer, tok: var TToken) = tok.kind = tkStringLit - var pos = c.bufPos + 1 + var pos = c.bufpos + 1 var buf = c.buf var quote = buf[pos-1] while true: @@ -1207,7 +1207,7 @@ proc getString(c: var PegLexer, tok: var TToken) = c.bufpos = pos proc getDollar(c: var PegLexer, tok: var TToken) = - var pos = c.bufPos + 1 + var pos = c.bufpos + 1 var buf = c.buf if buf[pos] in {'0'..'9'}: tok.kind = tkBackref @@ -1222,7 +1222,7 @@ proc getDollar(c: var PegLexer, tok: var TToken) = proc getCharSet(c: var PegLexer, tok: var TToken) = tok.kind = tkCharSet tok.charset = {} - var pos = c.bufPos + 1 + var pos = c.bufpos + 1 var buf = c.buf var caret = false if buf[pos] == '^': @@ -1404,11 +1404,11 @@ proc arrowIsNextTok(c: PegLexer): bool = # ----------------------------- parser ---------------------------------------- type - EInvalidPeg* = object of EInvalidValue ## raised if an invalid + EInvalidPeg* = object of ValueError ## raised if an invalid ## PEG has been detected PegParser = object of PegLexer ## the PEG parser object tok: TToken - nonterms: seq[PNonTerminal] + nonterms: seq[NonTerminal] modifier: TModifier captures: int identIsVerbatim: bool @@ -1430,7 +1430,7 @@ proc eat(p: var PegParser, kind: TTokKind) = proc parseExpr(p: var PegParser): Peg -proc getNonTerminal(p: var PegParser, name: string): PNonTerminal = +proc getNonTerminal(p: var PegParser, name: string): NonTerminal = for i in 0..high(p.nonterms): result = p.nonterms[i] if cmpIgnoreStyle(result.name, name) == 0: return @@ -1567,7 +1567,7 @@ proc seqExpr(p: var PegParser): Peg = result = primary(p) while true: case p.tok.kind - of tkAmp, tkNot, tkAt, tkStringLit, tkCharset, tkParLe, tkCurlyLe, + of tkAmp, tkNot, tkAt, tkStringLit, tkCharSet, tkParLe, tkCurlyLe, tkAny, tkAnyRune, tkBuiltin, tkEscaped, tkDollar, tkBackref, tkHat, tkCurlyAt: result = sequence(result, primary(p)) @@ -1583,7 +1583,7 @@ proc parseExpr(p: var PegParser): Peg = getTok(p) result = result / seqExpr(p) -proc parseRule(p: var PegParser): PNonTerminal = +proc parseRule(p: var PegParser): NonTerminal = if p.tok.kind == tkIdentifier and arrowIsNextTok(p): result = getNonTerminal(p, p.tok.literal) if ntDeclared in result.flags: @@ -1712,7 +1712,7 @@ when isMainModule: assert match("_______ana", peg"A <- 'ana' / . A") assert match("abcs%%%", peg"A <- ..A / .A / '%'") - var matches: array[0..maxSubpatterns-1, string] + var matches: array[0..MaxSubpatterns-1, string] if "abc" =~ peg"{'a'}'bc' 'xyz' / {\ident}": assert matches[0] == "abc" else: From 649dfa09c4fcef2d8174cf4f997aa482600a718e Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 08:50:01 +0200 Subject: [PATCH 027/409] updated poly.nim --- lib/pure/poly.nim | 62 +++++++++++++++++++++---------------------- lib/pure/terminal.nim | 24 +++++++++++------ 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/lib/pure/poly.nim b/lib/pure/poly.nim index 19bed2aca..286e5a8fd 100644 --- a/lib/pure/poly.nim +++ b/lib/pure/poly.nim @@ -17,13 +17,13 @@ type {.deprecated: [TPoly: Poly].} -proc degree*(p:TPoly):int= +proc degree*(p:Poly):int= ## Returns the degree of the polynomial, ## that is the number of coefficients-1 return p.cofs.len-1 -proc eval*(p:TPoly,x:float):float= +proc eval*(p:Poly,x:float):float= ## Evaluates a polynomial function value for `x` ## quickly using Horners method var n=p.degree @@ -33,7 +33,7 @@ proc eval*(p:TPoly,x:float):float= result = result*x+p.cofs[n] dec n -proc `[]` *(p:TPoly;idx:int):float= +proc `[]` *(p:Poly;idx:int):float= ## Gets a coefficient of the polynomial. ## p[2] will returns the quadric term, p[3] the cubic etc. ## Out of bounds index will return 0.0. @@ -41,7 +41,7 @@ proc `[]` *(p:TPoly;idx:int):float= return 0.0 return p.cofs[idx] -proc `[]=` *(p:var TPoly;idx:int,v:float)= +proc `[]=` *(p:var Poly;idx:int,v:float)= ## Sets an coefficient of the polynomial by index. ## p[2] set the quadric term, p[3] the cubic etc. ## If index is out of range for the coefficients, @@ -57,14 +57,14 @@ proc `[]=` *(p:var TPoly;idx:int,v:float)= p.cofs[idx]=v -iterator items*(p:TPoly):float= +iterator items*(p:Poly):float= ## Iterates through the corfficients of the polynomial. var i=p.degree while i>=0: yield p[i] dec i -proc clean*(p:var TPoly;zerotol=0.0)= +proc clean*(p:var Poly;zerotol=0.0)= ## Removes leading zero coefficients of the polynomial. ## An optional tolerance can be given for what's considered zero. var n=p.degree @@ -77,7 +77,7 @@ proc clean*(p:var TPoly;zerotol=0.0)= if relen: p.cofs.setLen(n+1) -proc `$` *(p:TPoly):string = +proc `$` *(p:Poly):string = ## Gets a somewhat reasonable string representation of the polynomial ## The format should be compatible with most online function plotters, ## for example directly in google search @@ -105,13 +105,13 @@ proc `$` *(p:TPoly):string = result="0" -proc derivative*(p: TPoly): TPoly= +proc derivative*(p: Poly): Poly= ## Returns a new polynomial, which is the derivative of `p` newSeq[float](result.cofs,p.degree) for idx in 0..high(result.cofs): result.cofs[idx]=p.cofs[idx+1]*float(idx+1) -proc diff*(p:TPoly,x:float):float= +proc diff*(p:Poly,x:float):float= ## Evaluates the differentiation of a polynomial with ## respect to `x` quickly using a modifed Horners method var n=p.degree @@ -121,7 +121,7 @@ proc diff*(p:TPoly,x:float):float= result = result*x+p[n]*float(n) dec n -proc integral*(p:TPoly):TPoly= +proc integral*(p:Poly):Poly= ## Returns a new polynomial which is the indefinite ## integral of `p`. The constant term is set to 0.0 newSeq(result.cofs,p.cofs.len+1) @@ -130,7 +130,7 @@ proc integral*(p:TPoly):TPoly= result.cofs[i]=p.cofs[i-1]/float(i) -proc integrate*(p:TPoly;xmin,xmax:float):float= +proc integrate*(p:Poly;xmin,xmax:float):float= ## Computes the definite integral of `p` between `xmin` and `xmax` ## quickly using a modified version of Horners method var @@ -148,7 +148,7 @@ proc integrate*(p:TPoly;xmin,xmax:float):float= result=s2*xmax-s1*xmin -proc initPoly*(cofs:varargs[float]):TPoly= +proc initPoly*(cofs:varargs[float]):Poly= ## Initializes a polynomial with given coefficients. ## The most significant coefficient is first, so to create x^2-2x+3: ## intiPoly(1.0,-2.0,3.0) @@ -164,7 +164,7 @@ proc initPoly*(cofs:varargs[float]):TPoly= result.clean #remove leading zero terms -proc divMod*(p,d:TPoly;q,r:var TPoly)= +proc divMod*(p,d:Poly;q,r:var Poly)= ## Divides `p` with `d`, and stores the quotinent in `q` and ## the remainder in `d` var @@ -192,7 +192,7 @@ proc divMod*(p,d:TPoly;q,r:var TPoly)= r.clean # drop zero coefficients in remainder -proc `+` *(p1:TPoly,p2:TPoly):TPoly= +proc `+` *(p1:Poly,p2:Poly):Poly= ## Adds two polynomials var n=max(p1.cofs.len,p2.cofs.len) newSeq(result.cofs,n) @@ -202,7 +202,7 @@ proc `+` *(p1:TPoly,p2:TPoly):TPoly= result.clean # drop zero coefficients in remainder -proc `*` *(p1:TPoly,p2:TPoly):TPoly= +proc `*` *(p1:Poly,p2:Poly):Poly= ## Multiplies the polynomial `p1` with `p2` var d1=p1.degree @@ -219,24 +219,24 @@ proc `*` *(p1:TPoly,p2:TPoly):TPoly= result.clean -proc `*` *(p:TPoly,f:float):TPoly= +proc `*` *(p:Poly,f:float):Poly= ## Multiplies the polynomial `p` with a real number newSeq(result.cofs,p.cofs.len) for i in 0..high(p.cofs): result[i]=p.cofs[i]*f result.clean -proc `*` *(f:float,p:TPoly):TPoly= +proc `*` *(f:float,p:Poly):Poly= ## Multiplies a real number with a polynomial return p*f -proc `-`*(p:TPoly):TPoly= +proc `-`*(p:Poly):Poly= ## Negates a polynomial result=p for i in countup(0, no roots return @[linrt] elif p.degree==2: diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 19635ee68..323b8b216 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -31,7 +31,8 @@ when defined(windows): proc getCursorPos(): tuple [x,y: int] = var c: TCONSOLESCREENBUFFERINFO - if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: raiseOSError(osLastError()) + if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: + raiseOSError(osLastError()) return (int(c.dwCursorPosition.x), int(c.dwCursorPosition.y)) proc getAttributes(): int16 = @@ -61,10 +62,12 @@ proc setCursorXPos*(x: int) = when defined(windows): var scrbuf: TCONSOLESCREENBUFFERINFO var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: + raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition origin.x = int16(x) - if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: + raiseOSError(osLastError()) else: stdout.write("\e[" & $x & 'G') @@ -75,10 +78,12 @@ when defined(windows): when defined(windows): var scrbuf: TCONSOLESCREENBUFFERINFO var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: + raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition origin.y = int16(y) - if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: + raiseOSError(osLastError()) else: discard @@ -155,10 +160,12 @@ proc eraseLine* = var scrbuf: TCONSOLESCREENBUFFERINFO var numwrote: DWORD var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: + raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition origin.x = 0'i16 - if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) + if SetConsoleCursorPosition(conHandle, origin) == 0: + raiseOSError(osLastError()) var ht = scrbuf.dwSize.Y - origin.Y var wt = scrbuf.dwSize.X - origin.X if FillConsoleOutputCharacter(hStdout,' ', ht*wt, @@ -178,7 +185,8 @@ proc eraseScreen* = var numwrote: DWORD var origin: TCOORD # is inititalized to 0, 0 var hStdout = conHandle - if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) + if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: + raiseOSError(osLastError()) if FillConsoleOutputCharacter(hStdout, ' ', scrbuf.dwSize.X*scrbuf.dwSize.Y, origin, addr(numwrote)) == 0: raiseOSError(osLastError()) From 2781fea9e2a67e86f37277f5e2808fc444a1173a Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 09:38:14 +0200 Subject: [PATCH 028/409] Nimrod renamed to Nim --- compiler/aliases.nim | 2 +- compiler/ast.nim | 2 +- compiler/astalgo.nim | 2 +- compiler/babelcmd.nim | 4 ++-- compiler/bitsets.nim | 6 +++--- compiler/canonicalizer.nim | 4 ++-- compiler/ccgcalls.nim | 2 +- compiler/ccgexprs.nim | 8 ++++---- compiler/ccgmerge.nim | 2 +- compiler/ccgstmts.nim | 4 ++-- compiler/ccgthreadvars.nim | 2 +- compiler/ccgtrav.nim | 2 +- compiler/ccgtypes.nim | 2 +- compiler/ccgutils.nim | 2 +- compiler/cgen.nim | 8 ++++---- compiler/cgendata.nim | 4 ++-- compiler/cgmeth.nim | 2 +- compiler/commands.nim | 4 ++-- compiler/condsyms.nim | 2 +- compiler/crc.nim | 2 +- compiler/depends.nim | 2 +- compiler/docgen.nim | 2 +- compiler/docgen2.nim | 2 +- compiler/evalffi.nim | 4 ++-- compiler/evaltempl.nim | 2 +- compiler/extccomp.nim | 2 +- compiler/filter_tmpl.nim | 6 +++--- compiler/filters.nim | 4 ++-- compiler/guards.nim | 2 +- compiler/hlo.nim | 2 +- compiler/idents.nim | 2 +- compiler/idgen.nim | 2 +- compiler/importer.nim | 2 +- compiler/jsgen.nim | 4 ++-- compiler/jstypes.nim | 2 +- compiler/lambdalifting.nim | 2 +- compiler/lexer.nim | 6 +++--- compiler/lists.nim | 2 +- compiler/llstream.nim | 2 +- compiler/lowerings.nim | 2 +- compiler/main.nim | 2 +- compiler/modules.nim | 4 ++-- compiler/msgs.nim | 2 +- compiler/nimconf.nim | 4 ++-- compiler/nimeval.nim | 4 ++-- compiler/nimlexbase.nim | 2 +- compiler/nimrod.ini | 12 ++++++------ compiler/nimrod.nim | 2 +- compiler/nimrod.nimrod.cfg | 2 +- compiler/nimsets.nim | 4 ++-- compiler/nversion.nim | 4 ++-- compiler/options.nim | 4 ++-- compiler/parampatterns.nim | 2 +- compiler/parser.nim | 4 ++-- compiler/passaux.nim | 2 +- compiler/passes.nim | 2 +- compiler/patterns.nim | 2 +- compiler/pbraces.nim | 2 +- compiler/procfind.nim | 2 +- compiler/readme.txt | 4 ++-- compiler/renderer.nim | 4 ++-- compiler/rodread.nim | 2 +- compiler/rodutils.nim | 2 +- compiler/rodwrite.nim | 4 ++-- compiler/ropes.nim | 4 ++-- compiler/saturate.nim | 2 +- compiler/sem.nim | 2 +- compiler/semcall.nim | 2 +- compiler/semdata.nim | 2 +- compiler/semdestruct.nim | 2 +- compiler/semgnrc.nim | 2 +- compiler/seminst.nim | 2 +- compiler/semmacrosanity.nim | 2 +- compiler/semmagic.nim | 2 +- compiler/semparallel.nim | 2 +- compiler/sempass2.nim | 2 +- compiler/semstmts.nim | 2 +- compiler/semtempl.nim | 2 +- compiler/service.nim | 2 +- compiler/sigmatch.nim | 2 +- compiler/suggest.nim | 2 +- compiler/syntaxes.nim | 2 +- compiler/tccgen.nim | 2 +- compiler/transf.nim | 2 +- compiler/trees.nim | 2 +- compiler/treetab.nim | 2 +- compiler/types.nim | 2 +- compiler/vmdeps.nim | 2 +- compiler/wordrecg.nim | 2 +- 89 files changed, 125 insertions(+), 125 deletions(-) diff --git a/compiler/aliases.nim b/compiler/aliases.nim index a26b94303..d68c9360a 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/ast.nim b/compiler/ast.nim index b6878c56e..2ba9cdb2e 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -476,7 +476,7 @@ type # and first phase symbol lookup in generics skConditional, # symbol for the preprocessor (may become obsolete) skDynLib, # symbol represents a dynamic library; this is used - # internally; it does not exist in Nimrod code + # internally; it does not exist in Nim code skParam, # a parameter skGenericParam, # a generic parameter; eq in ``proc x[eq=`==`]()`` skTemp, # a temporary variable (introduced by compiler) diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index e95dbf7c8..ad5393dbd 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/babelcmd.nim b/compiler/babelcmd.nim index 7fa233732..d67b1dab5 100644 --- a/compiler/babelcmd.nim +++ b/compiler/babelcmd.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Implements some helper procs for Babel (Nimrod's package manager) support. +## Implements some helper procs for Babel (Nim's package manager) support. import parseutils, strutils, strtabs, os, options, msgs, lists diff --git a/compiler/bitsets.nim b/compiler/bitsets.nim index 740bdd5ef..a2324f4e2 100644 --- a/compiler/bitsets.nim +++ b/compiler/bitsets.nim @@ -1,14 +1,14 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# this unit handles Nimrod sets; it implements bit sets -# the code here should be reused in the Nimrod standard library +# this unit handles Nim sets; it implements bit sets +# the code here should be reused in the Nim standard library type TBitSet* = seq[int8] # we use byte here to avoid issues with diff --git a/compiler/canonicalizer.nim b/compiler/canonicalizer.nim index 3bc4eb029..14448f0e8 100644 --- a/compiler/canonicalizer.nim +++ b/compiler/canonicalizer.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -370,7 +370,7 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) = # the last entry of a symbol: if s.ast != nil: # we used to attempt to save space here by only storing a dummy AST if - # it is not necessary, but Nimrod's heavy compile-time evaluation features + # it is not necessary, but Nim's heavy compile-time evaluation features # make that unfeasible nowadays: encodeNode(w, s.info, s.ast, result) diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index adcc95e84..753d375af 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index b5817de05..8914ad0de 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -15,7 +15,7 @@ proc intLiteral(i: BiggestInt): PRope = if (i > low(int32)) and (i <= high(int32)): result = toRope(i) elif i == low(int32): - # Nimrod has the same bug for the same reasons :-) + # Nim has the same bug for the same reasons :-) result = ~"(-2147483647 -1)" elif i > low(int64): result = rfmt(nil, "IL64($1)", toRope(i)) @@ -908,7 +908,7 @@ proc gcUsage(n: PNode) = if gSelectedGC == gcNone: message(n.info, warnGcMem, n.renderTree) proc genStrConcat(p: BProc, e: PNode, d: var TLoc) = - # + # # s = 'Hello ' & name & ', how do you feel?' & 'z' # # @@ -951,7 +951,7 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) = gcUsage(e) proc genStrAppend(p: BProc, e: PNode, d: var TLoc) = - # + # # s &= 'Hello ' & name & ', how do you feel?' & 'z' # // BUG: what if s is on the left side too? # diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index 2d27257ce..69c41ff59 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 0c3d35f7b..66bfbba8c 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -547,7 +547,7 @@ proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc, proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc, rangeFormat, eqFormat: TFormatStr, until: int, a: TLoc): TLabel = - # generate a C-if statement for a Nimrod case statement + # generate a C-if statement for a Nim case statement var labId = p.labels for i in 1..until: inc(p.labels) diff --git a/compiler/ccgthreadvars.nim b/compiler/ccgthreadvars.nim index c00b931ef..60bc0fc4b 100644 --- a/compiler/ccgthreadvars.nim +++ b/compiler/ccgthreadvars.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index a5bf9e7a7..16ec564e8 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 0bd96e89f..8c2e99339 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 48fdacf46..54af3c705 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/cgen.nim b/compiler/cgen.nim index deccf9ced..7c694f245 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -917,18 +917,18 @@ proc addIntTypes(result: var PRope) {.inline.} = proc getCopyright(cfilenoext: string): PRope = if optCompileOnly in gGlobalOptions: - result = ropeff("/* Generated by Nimrod Compiler v$1 */$N" & + result = ropeff("/* Generated by Nim Compiler v$1 */$N" & "/* (c) 2014 Andreas Rumpf */$N" & "/* The generated code is subject to the original license. */$N", - "; Generated by Nimrod Compiler v$1$N" & + "; Generated by Nim Compiler v$1$N" & "; (c) 2012 Andreas Rumpf$N", [toRope(VersionAsString)]) else: - result = ropeff("/* Generated by Nimrod Compiler v$1 */$N" & + result = ropeff("/* Generated by Nim Compiler v$1 */$N" & "/* (c) 2014 Andreas Rumpf */$N" & "/* The generated code is subject to the original license. */$N" & "/* Compiled for: $2, $3, $4 */$N" & "/* Command for C compiler:$n $5 */$N", - "; Generated by Nimrod Compiler v$1$N" & + "; Generated by Nim Compiler v$1$N" & "; (c) 2014 Andreas Rumpf$N" & "; Compiled for: $2, $3, $4$N" & "; Command for LLVM compiler:$N $5$N", [toRope(VersionAsString), diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 12041c55b..ea8f32974 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -62,7 +62,7 @@ type frameLen*: int16 TCProc{.final.} = object # represents C proc that is currently generated - prc*: PSym # the Nimrod proc that this C proc belongs to + prc*: PSym # the Nim proc that this C proc belongs to beforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed threadVarAccessed*: bool # true if the proc already accessed some threadvar nestedTryStmts*: seq[PNode] # in how many nested try statements we are diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 948541302..1d0cb82ad 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/commands.nim b/compiler/commands.nim index 712e0e1c5..fff860de9 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -51,7 +51,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) # implementation const - HelpMessage = "Nimrod Compiler Version $1 (" & CompileDate & ") [$2: $3]\n" & + HelpMessage = "Nim Compiler Version $1 (" & CompileDate & ") [$2: $3]\n" & "Copyright (c) 2006-2014 by Andreas Rumpf\n" const diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 6b93b1c12..28288ed39 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/crc.nim b/compiler/crc.nim index 22b1d1b69..a8b61f2a5 100644 --- a/compiler/crc.nim +++ b/compiler/crc.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/depends.nim b/compiler/depends.nim index a43eaf844..115a98f84 100644 --- a/compiler/depends.nim +++ b/compiler/depends.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 7d9a11fbc..5c851118d 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/docgen2.nim b/compiler/docgen2.nim index 1bff89b55..aa832b6df 100644 --- a/compiler/docgen2.nim +++ b/compiler/docgen2.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index f798a43ac..d6b3a1aa5 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This file implements the FFI part of the evaluator for Nimrod code. +## This file implements the FFI part of the evaluator for Nim code. import ast, astalgo, ropes, types, options, tables, dynlib, libffi, msgs, os diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 78cdbb45f..78cc691c0 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 8dc399f43..7a213aea4 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/filter_tmpl.nim b/compiler/filter_tmpl.nim index 0014e9c78..7b975dbaa 100644 --- a/compiler/filter_tmpl.nim +++ b/compiler/filter_tmpl.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# This module implements Nimrod's standard template filter. +# This module implements Nim's standard template filter. import llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, @@ -148,7 +148,7 @@ proc parseLine(p: var TTmplParser) = inc(j) else: if p.x[j] == p.subsChar: - # parse Nimrod expression: + # parse Nim expression: inc(j) case p.x[j] of '{': diff --git a/compiler/filters.nim b/compiler/filters.nim index ce0ffd196..783a320a4 100644 --- a/compiler/filters.nim +++ b/compiler/filters.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# This module implements Nimrod's simple filters and helpers for filters. +# This module implements Nim's simple filters and helpers for filters. import llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, diff --git a/compiler/guards.nim b/compiler/guards.nim index 431de6156..05128f409 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/hlo.nim b/compiler/hlo.nim index c75d6519f..363d100be 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/idents.nim b/compiler/idents.nim index c37d94362..775bffa00 100644 --- a/compiler/idents.nim +++ b/compiler/idents.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/idgen.nim b/compiler/idgen.nim index 7f137b885..3c5669b54 100644 --- a/compiler/idgen.nim +++ b/compiler/idgen.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/importer.nim b/compiler/importer.nim index b4cae017e..538957887 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index dfe498e47..c97adffb1 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -1664,7 +1664,7 @@ proc newModule(module: PSym): BModule = if globals == nil: globals = newGlobals() proc genHeader(): PRope = - result = ropef("/* Generated by the Nimrod Compiler v$1 */$n" & + result = ropef("/* Generated by the Nim Compiler v$1 */$n" & "/* (c) 2014 Andreas Rumpf */$n$n" & "$nvar Globals = this;$n" & "var framePtr = null;$n" & diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index 009fc7935..8b032c3ce 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index c29d20a0a..2a9b1e886 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/lexer.nim b/compiler/lexer.nim index abc491bfe..e0b3b76ce 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -102,7 +102,7 @@ type # so that it is the correct default value base2, base8, base16 - TToken* = object # a Nimrod token + TToken* = object # a Nim token tokType*: TTokType # the type of the token indent*: int # the indentation; != -1 if the token has been # preceeded with indentation @@ -148,7 +148,7 @@ proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") proc isKeyword(kind: TTokType): bool = result = (kind >= tokKeywordLow) and (kind <= tokKeywordHigh) -proc isNimrodIdentifier*(s: string): bool = +proc isNimIdentifier*(s: string): bool = if s[0] in SymStartChars: var i = 1 while i < s.len: diff --git a/compiler/lists.nim b/compiler/lists.nim index 2b3a9f3fc..1b2b91bff 100644 --- a/compiler/lists.nim +++ b/compiler/lists.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/llstream.nim b/compiler/llstream.nim index 8dc3dcea3..be469548d 100644 --- a/compiler/llstream.nim +++ b/compiler/llstream.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index c4155724f..e90ef9376 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/main.nim b/compiler/main.nim index b4af49248..58833f60c 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/modules.nim b/compiler/modules.nim index 65c438cc3..8939afd5a 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -117,7 +117,7 @@ proc newModule(fileIdx: int32): PSym = result.kind = skModule let filename = fileIdx.toFullPath result.name = getIdent(splitFile(filename).name) - if not isNimrodIdentifier(result.name.s): + if not isNimIdentifier(result.name.s): rawMessage(errInvalidModuleName, result.name.s) result.info = newLineInfo(fileIdx, 1, 1) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 00f80a438..43b3b6c8e 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index 136a0d454..d23c7f1be 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -14,7 +14,7 @@ import options, idents, wordrecg # ---------------- configuration file parser ----------------------------- -# we use Nimrod's scanner here to safe space and work +# we use Nim's scanner here to safe space and work proc ppGetTok(L: var TLexer, tok: var TToken) = # simple filter diff --git a/compiler/nimeval.nim b/compiler/nimeval.nim index 0ee108d48..5693cbe91 100644 --- a/compiler/nimeval.nim +++ b/compiler/nimeval.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## exposes the Nimrod VM to clients. +## exposes the Nim VM to clients. import ast, modules, passes, passaux, condsyms, diff --git a/compiler/nimlexbase.nim b/compiler/nimlexbase.nim index cabcac390..e18e1c22a 100644 --- a/compiler/nimlexbase.nim +++ b/compiler/nimlexbase.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/nimrod.ini b/compiler/nimrod.ini index 44e16cec8..8bd00e891 100644 --- a/compiler/nimrod.ini +++ b/compiler/nimrod.ini @@ -1,5 +1,5 @@ [Project] -Name: "Nimrod" +Name: "Nim" Version: "$version" Platforms: """ windows: i386;amd64 @@ -13,15 +13,15 @@ Platforms: """ """ Authors: "Andreas Rumpf" -Description: """This is the Nimrod Compiler. Nimrod is a new statically typed, +Description: """This is the Nim Compiler. Nim is a new statically typed, imperative programming language, that supports procedural, functional, object oriented and generic programming styles while remaining simple and efficient. -A special feature that Nimrod inherited from Lisp is that Nimrod's abstract +A special feature that Nim inherited from Lisp is that Nim's abstract syntax tree (AST) is part of the specification - this allows a powerful macro system which can be used to create domain specific languages. -Nimrod is a compiled, garbage-collected systems programming language -which has an excellent productivity/performance ratio. Nimrod's design +Nim is a compiled, garbage-collected systems programming language +which has an excellent productivity/performance ratio. Nim's design focuses on the 3E: efficiency, expressiveness, elegance (in the order of priority).""" @@ -149,6 +149,6 @@ flags = "-w" [deb] buildDepends: "gcc (>= 4:4.3.2)" pkgDepends: "gcc (>= 4:4.3.2)" -shortDesc: "The Nimrod Compiler" +shortDesc: "The Nim Compiler" licenses: "bin/nimrod,MIT;lib/*,MIT;" diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim index 69cb8bb99..27222ca57 100644 --- a/compiler/nimrod.nim +++ b/compiler/nimrod.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/nimrod.nimrod.cfg b/compiler/nimrod.nimrod.cfg index 2c6e6f249..c9e4b248b 100644 --- a/compiler/nimrod.nimrod.cfg +++ b/compiler/nimrod.nimrod.cfg @@ -1,4 +1,4 @@ -# Special configuration file for the Nimrod project +# Special configuration file for the Nim project mainModule:"nimrod.nim" diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index d65618e0a..aa7686d30 100644 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# this unit handles Nimrod sets; it implements symbolic sets +# this unit handles Nim sets; it implements symbolic sets import ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer diff --git a/compiler/nversion.nim b/compiler/nversion.nim index 3c868ed2a..7f0f93782 100644 --- a/compiler/nversion.nim +++ b/compiler/nversion.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# This module contains Nimrod's version. It is the only place where it needs +# This module contains Nim's version. It is the only place where it needs # to be changed. const diff --git a/compiler/options.nim b/compiler/options.nim index 8acf9e830..e30080e8f 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -68,7 +68,7 @@ type # please make sure we have under 32 options # also: generate header file TGlobalOptions* = set[TGlobalOption] - TCommands* = enum # Nimrod's commands + TCommands* = enum # Nim's commands # **keep binary compatible** cmdNone, cmdCompileToC, cmdCompileToCpp, cmdCompileToOC, cmdCompileToJS, cmdCompileToLLVM, cmdInterpret, cmdPretty, cmdDoc, diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index bbdba8c22..300abea1e 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/parser.nim b/compiler/parser.nim index 548084974..20c037c00 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# This module implements the parser of the standard Nimrod syntax. +# This module implements the parser of the standard Nim syntax. # The parser strictly reflects the grammar ("doc/grammar.txt"); however # it uses several helper routines to keep the parser small. A special # efficient algorithm is used for the precedence levels. The parser here can diff --git a/compiler/passaux.nim b/compiler/passaux.nim index 0ba9f22d0..f754c80e5 100644 --- a/compiler/passaux.nim +++ b/compiler/passaux.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/passes.nim b/compiler/passes.nim index 1af9739bd..a63e29b35 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/patterns.nim b/compiler/patterns.nim index 5e21289b5..3d71aa4d1 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/pbraces.nim b/compiler/pbraces.nim index ce6e0d9a9..cf4dbffc5 100644 --- a/compiler/pbraces.nim +++ b/compiler/pbraces.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/procfind.nim b/compiler/procfind.nim index 0354d585d..e88524634 100644 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/readme.txt b/compiler/readme.txt index 3d3cf4b29..c4934e031 100644 --- a/compiler/readme.txt +++ b/compiler/readme.txt @@ -1,4 +1,4 @@ -This directory contains the Nimrod compiler written in Nimrod. Note that this +This directory contains the Nim compiler written in Nim. Note that this code has been translated from a bootstrapping version written in Pascal, so -the code is **not** a poster child of good Nimrod code. +the code is **not** a poster child of good Nim code. diff --git a/compiler/renderer.nim b/compiler/renderer.nim index e01916920..29f581573 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1,13 +1,13 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -# This module implements the renderer of the standard Nimrod representation. +# This module implements the renderer of the standard Nim representation. import lexer, options, idents, strutils, ast, msgs, lists diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 47020253f..acccc1abb 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim index 09b92cd8a..e0ef3c397 100644 --- a/compiler/rodutils.nim +++ b/compiler/rodutils.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 4948c8fc2..7eacb0883 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -297,7 +297,7 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) = # the last entry of a symbol: if s.ast != nil: # we used to attempt to save space here by only storing a dummy AST if - # it is not necessary, but Nimrod's heavy compile-time evaluation features + # it is not necessary, but Nim's heavy compile-time evaluation features # make that unfeasible nowadays: encodeNode(w, s.info, s.ast, result) when false: diff --git a/compiler/ropes.nim b/compiler/ropes.nim index 6eb3673b4..b14081694 100644 --- a/compiler/ropes.nim +++ b/compiler/ropes.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,7 +12,7 @@ # Ropes are a data structure that represents a very long string # efficiently; especially concatenation is done in O(1) instead of O(N). # Ropes make use a lazy evaluation: They are essentially concatenation -# trees that are only flattened when converting to a native Nimrod +# trees that are only flattened when converting to a native Nim # string or when written to disk. The empty string is represented by a # nil pointer. # A little picture makes everything clear: diff --git a/compiler/saturate.nim b/compiler/saturate.nim index ed197bdd1..f4fe29a20 100644 --- a/compiler/saturate.nim +++ b/compiler/saturate.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/sem.nim b/compiler/sem.nim index 26a59334c..be71ebef8 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 927b23cf2..3ce88651f 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semdata.nim b/compiler/semdata.nim index abecc1b6d..c57ce2c26 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semdestruct.nim b/compiler/semdestruct.nim index 3c30dc1bd..4ce610bf9 100644 --- a/compiler/semdestruct.nim +++ b/compiler/semdestruct.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 224168528..8d8067195 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/seminst.nim b/compiler/seminst.nim index b205eb09a..8ac3849b4 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim index 8106aa179..c685d602d 100644 --- a/compiler/semmacrosanity.nim +++ b/compiler/semmacrosanity.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index f943e7006..7b612c806 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim index 5571d1bed..fe735c9f2 100644 --- a/compiler/semparallel.nim +++ b/compiler/semparallel.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 332b74155..fee70af15 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 583185048..89acb2e98 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index ee8b1ccb8..880e37fef 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/service.nim b/compiler/service.nim index 22f5c6e33..8e1c9cf1b 100644 --- a/compiler/service.nim +++ b/compiler/service.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index e5bf08097..588628c9a 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/suggest.nim b/compiler/suggest.nim index c2bdfc5c3..650e5b3fb 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index 8de6dcd91..61677a641 100644 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/tccgen.nim b/compiler/tccgen.nim index a571d416e..0082dfcbb 100644 --- a/compiler/tccgen.nim +++ b/compiler/tccgen.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/transf.nim b/compiler/transf.nim index 00fe03ab6..bab719ba1 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/trees.nim b/compiler/trees.nim index 35e9334cc..b1edd21f3 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/treetab.nim b/compiler/treetab.nim index ecb8fb083..63f3fc6e2 100644 --- a/compiler/treetab.nim +++ b/compiler/treetab.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/types.nim b/compiler/types.nim index ba796b6c3..c810dc025 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index c0916fbd8..831e2ddce 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 96056eb6f..e3b4b3062 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this From d05df2173b95155a53e9c731f1c78b754eb2410c Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 09:50:51 +0200 Subject: [PATCH 029/409] Nimrod renamed to Nim --- lib/core/locks.nim | 8 ++-- lib/core/macros.nim | 2 +- lib/core/typeinfo.nim | 4 +- lib/core/unsigned.nim | 2 +- lib/impure/db_mysql.nim | 2 +- lib/impure/db_postgres.nim | 2 +- lib/impure/db_sqlite.nim | 2 +- lib/impure/dialogs.nim | 4 +- lib/impure/graphics.nim | 4 +- lib/impure/rdstdin.nim | 2 +- lib/impure/re.nim | 6 +-- lib/impure/ssl.nim | 2 +- lib/impure/web.nim | 2 +- lib/impure/zipfiles.nim | 2 +- lib/js/dom.nim | 2 +- lib/nimrtl.nim | 2 +- lib/packages/docutils/rst.nim | 4 +- lib/packages/docutils/rstast.nim | 2 +- lib/posix/epoll.nim | 2 +- lib/posix/inotify.nim | 2 +- lib/posix/posix.nim | 6 +-- lib/prelude.nim | 2 +- lib/pure/actors.nim | 2 +- lib/pure/algorithm.nim | 4 +- lib/pure/cgi.nim | 8 ++-- lib/pure/concurrency/cpuinfo.nim | 2 +- lib/pure/concurrency/threadpool.nim | 2 +- lib/pure/ftpclient.nim | 2 +- lib/pure/gentabs.nim | 2 +- lib/pure/httpserver.nim | 2 +- lib/pure/math.nim | 6 +-- lib/pure/memfiles.nim | 2 +- lib/pure/os.nim | 4 +- lib/pure/osproc.nim | 2 +- lib/pure/parsecfg.nim | 2 +- lib/pure/ropes.nim | 2 +- lib/pure/streams.nim | 4 +- lib/pure/strutils.nim | 6 +-- lib/pure/typetraits.nim | 2 +- lib/pure/unittest.nim | 2 +- lib/pure/xmltree.nim | 8 ++-- lib/system.nim | 74 ++++++++++++++--------------- lib/windows/mmsystem.nim | 2 +- lib/windows/nb30.nim | 2 +- lib/windows/psapi.nim | 2 +- lib/windows/shellapi.nim | 2 +- lib/windows/shfolder.nim | 2 +- lib/windows/windows.nim | 2 +- lib/windows/winlean.nim | 2 +- lib/wrappers/libsvm.nim | 2 +- lib/wrappers/mysql.nim | 2 +- lib/wrappers/sphinx.nim | 2 +- lib/wrappers/sqlite3.nim | 2 +- lib/wrappers/tinyc.nim | 2 +- lib/wrappers/zip/libzip.nim | 2 +- lib/wrappers/zip/zzip.nim | 2 +- 56 files changed, 116 insertions(+), 116 deletions(-) diff --git a/lib/core/locks.nim b/lib/core/locks.nim index 894965a85..d865c78c5 100644 --- a/lib/core/locks.nim +++ b/lib/core/locks.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module contains Nimrod's support for locks and condition vars. +## This module contains Nim's support for locks and condition vars. ## If the symbol ``preventDeadlocks`` is defined ## (compiled with ``-d:preventDeadlocks``) special logic is added to ## every ``acquire``, ``tryAcquire`` and ``release`` action that ensures at @@ -18,10 +18,10 @@ include "system/syslocks" type - TLock* = TSysLock ## Nimrod lock; whether this is re-entrant + TLock* = TSysLock ## Nim lock; whether this is re-entrant ## or not is unspecified! However, compilation ## in preventDeadlocks-mode guarantees re-entrancy. - TCond* = TSysCond ## Nimrod condition variable + TCond* = TSysCond ## Nim condition variable FLock* = object of TEffect ## effect that denotes that some lock operation ## is performed diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 0acd948fe..41ba030f9 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim index 848388c2b..5ca101919 100644 --- a/lib/core/typeinfo.nim +++ b/lib/core/typeinfo.nim @@ -585,7 +585,7 @@ proc assign*(x, y: TAny) = genericAssign(x.value, y.value, y.rawType) iterator elements*(x: TAny): int = - ## iterates over every element of `x` that represents a Nimrod bitset. + ## iterates over every element of `x` that represents a Nim bitset. assert x.rawType.kind == tySet var typ = x.rawType var p = x.value @@ -607,7 +607,7 @@ iterator elements*(x: TAny): int = yield i+typ.node.len proc inclSetElement*(x: TAny, elem: int) = - ## includes an element `elem` in `x`. `x` needs to represent a Nimrod bitset. + ## includes an element `elem` in `x`. `x` needs to represent a Nim bitset. assert x.rawType.kind == tySet var typ = x.rawType var p = x.value diff --git a/lib/core/unsigned.nim b/lib/core/unsigned.nim index a3ddd4125..7acdf1439 100644 --- a/lib/core/unsigned.nim +++ b/lib/core/unsigned.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index eec4daf00..709e899e8 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index f6ae93303..6658dc0e0 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 809ee7039..844e5d07e 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/impure/dialogs.nim b/lib/impure/dialogs.nim index 00ba2663e..bbed99239 100644 --- a/lib/impure/dialogs.nim +++ b/lib/impure/dialogs.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -8,7 +8,7 @@ # -## This module implements portable dialogs for Nimrod; the implementation +## This module implements portable dialogs for Nim; the implementation ## builds on the GTK interface. On Windows, native dialogs are shown instead. import diff --git a/lib/impure/graphics.nim b/lib/impure/graphics.nim index 2c8e96460..dda7626ba 100644 --- a/lib/impure/graphics.nim +++ b/lib/impure/graphics.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## This module implements graphical output for Nimrod; the current +## This module implements graphical output for Nim; the current ## implementation uses SDL but the interface is meant to support multiple ## backends some day. There is no need to init SDL as this module does that ## implicitly. diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index 1037d3bda..9153d2360 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/impure/re.nim b/lib/impure/re.nim index ac07b2d6b..0624fbf43 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -1,13 +1,13 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Regular expression support for Nimrod. Consider using the pegs module +## Regular expression support for Nim. Consider using the pegs module ## instead. ## This module is implemented by providing a wrapper around the ## `PRCE (Perl-Compatible Regular Expressions) `_ @@ -68,7 +68,7 @@ proc finalizeRegEx(x: TRegex) = pcre.free_substring(cast[cstring](x.e)) proc re*(s: string, flags = {reExtended, reStudy}): TRegex = - ## Constructor of regular expressions. Note that Nimrod's + ## Constructor of regular expressions. Note that Nim's ## extended raw string literals support this syntax ``re"[abc]"`` as ## a short form for ``re(r"[abc]")``. new(result, finalizeRegEx) diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim index 54d524c7b..8a091a0d9 100644 --- a/lib/impure/ssl.nim +++ b/lib/impure/ssl.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this diff --git a/lib/impure/web.nim b/lib/impure/web.nim index 5f04422d1..abd7e2498 100644 --- a/lib/impure/web.nim +++ b/lib/impure/web.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/impure/zipfiles.nim b/lib/impure/zipfiles.nim index 1726449d8..b7df30d89 100644 --- a/lib/impure/zipfiles.nim +++ b/lib/impure/zipfiles.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/js/dom.nim b/lib/js/dom.nim index 951d8e835..2051ef294 100644 --- a/lib/js/dom.nim +++ b/lib/js/dom.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/nimrtl.nim b/lib/nimrtl.nim index 68b7d7bd9..96dab1284 100644 --- a/lib/nimrtl.nim +++ b/lib/nimrtl.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 27d520493..f685a97e1 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -17,7 +17,7 @@ import type TRstParseOption* = enum ## options for the RST parser roSkipPounds, ## skip ``#`` at line beginning (documentation - ## embedded in Nimrod comments) + ## embedded in Nim comments) roSupportSmilies, ## make the RST parser support smilies like ``:)`` roSupportRawDirective, ## support the ``raw`` directive (don't support ## it for sandboxing) diff --git a/lib/packages/docutils/rstast.nim b/lib/packages/docutils/rstast.nim index 8f946d973..7b781ad6a 100644 --- a/lib/packages/docutils/rstast.nim +++ b/lib/packages/docutils/rstast.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/posix/epoll.nim b/lib/posix/epoll.nim index ee04348e8..5565a5ae8 100644 --- a/lib/posix/epoll.nim +++ b/lib/posix/epoll.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Dominik Picheta # # See the file "copying.txt", included in this diff --git a/lib/posix/inotify.nim b/lib/posix/inotify.nim index 852eb12fa..c6f0633ff 100644 --- a/lib/posix/inotify.nim +++ b/lib/posix/inotify.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index d8f329e34..430d82429 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -13,14 +13,14 @@ # net/if, sys/socket, sys/uio, netinet/in, netinet/tcp, netdb ## This is a raw POSIX interface module. It does not not provide any -## convenience: cstrings are used instead of proper Nimrod strings and +## convenience: cstrings are used instead of proper Nim strings and ## return codes indicate errors. If you want exceptions -## and a proper Nimrod-like interface, use the OS module or write a wrapper. +## and a proper Nim-like interface, use the OS module or write a wrapper. ## Coding conventions: ## ALL types are named the same as in the POSIX standard except that they start ## with 'T' or 'P' (if they are pointers) and without the '_t' suffix to be -## consistent with Nimrod conventions. If an identifier is a Nimrod keyword +## consistent with Nim conventions. If an identifier is a Nim keyword ## the \`identifier\` notation is used. ## ## This library relies on the header files of your C compiler. The diff --git a/lib/prelude.nim b/lib/prelude.nim index 50b4d4092..60d9c0925 100644 --- a/lib/prelude.nim +++ b/lib/prelude.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/actors.nim b/lib/pure/actors.nim index 8a8d8b51b..18299d687 100644 --- a/lib/pure/actors.nim +++ b/lib/pure/actors.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -## `Actor`:idx: support for Nimrod. An actor is implemented as a thread with +## `Actor`:idx: support for Nim. An actor is implemented as a thread with ## a channel as its inbox. This module requires the ``--threads:on`` ## command line switch. ## diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index dd9131c05..3993a4172 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -151,11 +151,11 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int, proc sort*[T](a: var openArray[T], cmp: proc (x, y: T): int {.closure.}, order = SortOrder.Ascending) = - ## Default Nimrod sort. The sorting is guaranteed to be stable and + ## Default Nim sort. The sorting is guaranteed to be stable and ## the worst case is guaranteed to be O(n log n). ## The current implementation uses an iterative ## mergesort to achieve this. It uses a temporary sequence of - ## length ``a.len div 2``. Currently Nimrod does not support a + ## length ``a.len div 2``. Currently Nim does not support a ## sensible default argument for ``cmp``, so you have to provide one ## of your own. However, the ``system.cmp`` procs can be used: ## diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index bfa94a238..b30f8dd33 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -325,7 +325,7 @@ proc setTestData*(keysvalues: varargs[string]) = ## This can only simulate the 'GET' request method. `keysvalues` should ## provide embedded (name, value)-pairs. Example: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## setTestData("name", "Hanz", "password", "12345") putEnv("REQUEST_METHOD", "GET") var i = 0 @@ -342,7 +342,7 @@ proc writeContentType*() = ## call this before starting to send your HTML data to `stdout`. This ## implements this part of the CGI protocol: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## write(stdout, "Content-type: text/html\n\n") write(stdout, "Content-type: text/html\n\n") @@ -366,11 +366,11 @@ proc writeErrorMessage*(data: string) = stdout.write(data) proc setStackTraceStdout*() = - ## Makes Nimrod output stacktraces to stdout, instead of server log. + ## Makes Nim output stacktraces to stdout, instead of server log. errorMessageWriter = writeErrorMessage proc setStackTraceNewLine*() {.deprecated.} = - ## Makes Nimrod output stacktraces to stdout, instead of server log. + ## Makes Nim output stacktraces to stdout, instead of server log. ## Depracated alias for setStackTraceStdout. setStackTraceStdout() diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim index dfa819f64..e55786c3e 100644 --- a/lib/pure/concurrency/cpuinfo.nim +++ b/lib/pure/concurrency/cpuinfo.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index dfde610f2..fe08e94fc 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -189,7 +189,7 @@ proc nimFlowVarSignal(fv: FlowVarBase) {.compilerProc.} = proc awaitAndThen*[T](fv: FlowVar[T]; action: proc (x: T) {.closure.}) = ## blocks until the ``fv`` is available and then passes its value - ## to ``action``. Note that due to Nimrod's parameter passing semantics this + ## to ``action``. Note that due to Nim's parameter passing semantics this ## means that ``T`` doesn't need to be copied and so ``awaitAndThen`` can ## sometimes be more efficient than ``^``. await(fv) diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim index ccb0929f6..5a8cf50b2 100644 --- a/lib/pure/ftpclient.nim +++ b/lib/pure/ftpclient.nim @@ -39,7 +39,7 @@ type csock: Socket # Command connection socket dsock: Socket # Data connection socket else: - dummyA, dummyB: pointer # workaround a Nimrod API issue + dummyA, dummyB: pointer # workaround a Nim API issue asyncCSock: AsyncSocket asyncDSock: AsyncSocket handleEvent*: proc (ftp: AsyncFTPClient, ev: FTPEvent){.closure,gcsafe.} diff --git a/lib/pure/gentabs.nim b/lib/pure/gentabs.nim index c371809a0..694bfb542 100644 --- a/lib/pure/gentabs.nim +++ b/lib/pure/gentabs.nim @@ -9,7 +9,7 @@ ## The ``gentabs`` module implements an efficient hash table that is a ## key-value mapping. The keys are required to be strings, but the values -## may be any Nimrod or user defined type. This module supports matching +## may be any Nim or user defined type. This module supports matching ## of keys in case-sensitive, case-insensitive and style-insensitive modes. {.deprecated.} diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim index a41dc9450..4bbdbb5a1 100644 --- a/lib/pure/httpserver.nim +++ b/lib/pure/httpserver.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf, Dominik Picheta # # See the file "copying.txt", included in this diff --git a/lib/pure/math.nim b/lib/pure/math.nim index c6a0305d2..32bae18c2 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -30,15 +30,15 @@ const E* = 2.71828182845904523536028747 ## Euler's number MaxFloat64Precision* = 16 ## maximum number of meaningful digits - ## after the decimal point for Nimrod's + ## after the decimal point for Nim's ## ``float64`` type. MaxFloat32Precision* = 8 ## maximum number of meaningful digits - ## after the decimal point for Nimrod's + ## after the decimal point for Nim's ## ``float32`` type. MaxFloatPrecision* = MaxFloat64Precision ## maximum number of ## meaningful digits ## after the decimal point - ## for Nimrod's ``float`` type. + ## for Nim's ``float`` type. type FloatClass* = enum ## describes the class a floating point value belongs to. diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index c85c2b498..24dbfb6d3 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -1,7 +1,7 @@ # # # Nim's Runtime Library -# (c) Copyright 2014 Nimrod Contributors +# (c) Copyright 2014 Nim Contributors # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/lib/pure/os.nim b/lib/pure/os.nim index d348497a9..ae352c26f 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1245,7 +1245,7 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] {. ## ## and this code: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## for kind, path in walkDir("dirA"): ## echo(path) ## @@ -1657,7 +1657,7 @@ when defined(nimdoc): ## # Do something else! elif defined(windows): - # Since we support GUI applications with Nimrod, we sometimes generate + # Since we support GUI applications with Nim, we sometimes generate # a WinMain entry proc. But a WinMain proc has no access to the parsed # command line arguments. The way to get them differs. Thus we parse them # ourselves. This has the additional benefit that the program's behaviour diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 957a91d06..884774f1f 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -287,7 +287,7 @@ proc execProcesses*(cmds: openArray[string], close(p) proc select*(readfds: var seq[PProcess], timeout = 500): int - ## `select` with a sensible Nimrod interface. `timeout` is in miliseconds. + ## `select` with a sensible Nim interface. `timeout` is in miliseconds. ## Specify -1 for no timeout. Returns the number of processes that are ## ready to read from. The processes that are ready to be read from are ## removed from `readfds`. diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index a45976d86..bb9d2aed2 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -11,7 +11,7 @@ ## parser. The configuration file's syntax is similar to the Windows ``.ini`` ## format, but much more powerful, as it is not a line based parser. String ## literals, raw string literals and triple quoted string literals are supported -## as in the Nimrod programming language. +## as in the Nim programming language. ## This is an example of how a configuration file may look like: ## diff --git a/lib/pure/ropes.nim b/lib/pure/ropes.nim index 8205203ba..8b0661063 100644 --- a/lib/pure/ropes.nim +++ b/lib/pure/ropes.nim @@ -10,7 +10,7 @@ ## This module contains support for a `rope`:idx: data type. ## Ropes can represent very long strings efficiently; especially concatenation ## is done in O(1) instead of O(n). They are essentially concatenation -## trees that are only flattened when converting to a native Nimrod +## trees that are only flattened when converting to a native Nim ## string. The empty string is represented by ``nil``. Ropes are immutable and ## subtrees can be shared without copying. ## Leaves can be cached for better memory efficiency at the cost of diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index bc0f1c540..31aa7497d 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -9,7 +9,7 @@ ## This module provides a stream interface and two implementations thereof: ## the `FileStream` and the `StringStream` which implement the stream -## interface for Nimrod file objects (`File`) and strings. Other modules +## interface for Nim file objects (`File`) and strings. Other modules ## may provide other implementations for this standard stream interface. include "system/inclrtl" @@ -98,7 +98,7 @@ proc writeData*(s, unused: Stream, buffer: pointer, proc write*[T](s: Stream, x: T) = ## generic write procedure. Writes `x` to the stream `s`. Implementation: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## ## s.writeData(s, addr(x), sizeof(x)) var y: T diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 5153455e2..2fdf72011 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -117,7 +117,7 @@ proc normalize*(s: string): string {.noSideEffect, procvar, ## Normalizes the string `s`. ## ## That means to convert it to lower case and remove any '_'. This is needed - ## for Nimrod identifiers for example. + ## for Nim identifiers for example. result = newString(s.len) var j = 0 for i in 0..len(s) - 1: @@ -1155,7 +1155,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault, ## If ``format == ffScientific`` then precision is the maximum number ## of significant digits to be printed. ## `precision`'s default value is the maximum number of meaningful digits - ## after the decimal point for Nimrod's ``biggestFloat`` type. + ## after the decimal point for Nim's ``biggestFloat`` type. ## ## If ``precision == 0``, it tries to format it nicely. const floatFormatToChar: array[FloatFormatMode, char] = ['g', 'f', 'e'] @@ -1186,7 +1186,7 @@ proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, ## If ``format == ffScientific`` then precision is the maximum number ## of significant digits to be printed. ## `precision`'s default value is the maximum number of meaningful digits - ## after the decimal point for Nimrod's ``float`` type. + ## after the decimal point for Nim's ``float`` type. result = formatBiggestFloat(f, format, precision) proc formatSize*(bytes: BiggestInt, decimalSep = '.'): string = diff --git a/lib/pure/typetraits.nim b/lib/pure/typetraits.nim index 1180b98f0..2c3d872df 100644 --- a/lib/pure/typetraits.nim +++ b/lib/pure/typetraits.nim @@ -1,7 +1,7 @@ # # # Nim's Runtime Library -# (c) Copyright 2012 Nimrod Contributors +# (c) Copyright 2012 Nim Contributors # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 372c02f4e..bbd074390 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -1,7 +1,7 @@ # # # Nim's Runtime Library -# (c) Copyright 2012 Nimrod Contributors +# (c) Copyright 2012 Nim Contributors # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index c15c2e148..2caa65023 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -276,11 +276,11 @@ macro `<>`*(x: expr): expr {.immediate.} = ## Constructor macro for XML. Example usage: ## ## .. code-block:: nimrod - ## <>a(href="http://nimrod-code.org", newText("Nimrod rules.")) + ## <>a(href="http://nimrod-code.org", newText("Nim rules.")) ## ## Produces an XML tree for:: ## - ## Nimrod rules. + ## Nim rules. ## let x = callsite() result = xmlConstructor(x) @@ -339,5 +339,5 @@ proc findAll*(n: XmlNode, tag: string): seq[XmlNode] = findAll(n, tag, result) when isMainModule: - assert """Nimrod rules.""" == - $(<>a(href="http://nimrod-code.org", newText("Nimrod rules."))) + assert """Nim rules.""" == + $(<>a(href="http://nimrod-code.org", newText("Nim rules."))) diff --git a/lib/system.nim b/lib/system.nim index 0e9712c24..b07fa76e2 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -103,7 +103,7 @@ proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.} ## `-d:x switch `_ to enable build time ## conditionals: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not defined(release): ## # Do here programmer friendly expensive sanity checks. ## # Put here the normal code @@ -123,7 +123,7 @@ proc declared*(x: expr): bool {.magic: "Defined", noSideEffect.} ## This can be used to check whether a library provides a certain ## feature or not: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not defined(strutils.toUpper): ## # provide our own toUpper proc here, because strutils is ## # missing it. @@ -320,7 +320,7 @@ type ## of an int. This type is often useful for documentation and debugging. RootObj* {.exportc: "TNimObject", inheritable.} = - object ## the root of Nimrod's object hierarchy. Objects should + object ## the root of Nim's object hierarchy. Objects should ## inherit from TObject or one of its descendants. However, ## objects that have no ancestor are allowed. RootRef* = ref RootObj ## reference to RootObj @@ -465,7 +465,7 @@ type ## The operation produced a result that cannot be represented with infinite ## precision -- for example: ``2.0 / 3.0, log(1.1)`` ## - ## **NOTE**: Nimrod currently does not detect these! See the full + ## **NOTE**: Nim currently does not detect these! See the full ## `exception hierarchy`_. DeadThreadError* = object of Exception ## \ ## Raised if it is attempted to send a message to a dead thread. @@ -691,7 +691,7 @@ proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int64): int64 {.magic: "DivI64", noSideEffect.} ## computes the integer division. This is roughly the same as ## ``floor(x/y)``. - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## 1 div 2 == 0 ## 2 div 2 == 1 ## 3 div 2 == 1 @@ -710,7 +710,7 @@ proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.} proc `shr` *(x, y: int64): int64 {.magic: "ShrI64", noSideEffect.} ## computes the `shift right` operation of `x` and `y`. - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## 0b0001_0000'i8 shr 2 == 0b0100_0000'i8 ## 0b1000_0000'i8 shr 2 == 0b0000_0000'i8 ## 0b0000_0001'i8 shr 9 == 0b0000_0000'i8 @@ -849,12 +849,12 @@ proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## One should overload this proc if one wants to overload the ``in`` operator. ## The parameters are in reverse order! ``a in b`` is a template for ## ``contains(b, a)``. - ## This is because the unification algorithm that Nimrod uses for overload + ## This is because the unification algorithm that Nim uses for overload ## resolution works from left to right. ## But for the ``in`` operator that would be the wrong direction for this ## piece of code: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var s: set[range['a'..'z']] = {'a'..'c'} ## writeln(stdout, 'b' in s) ## @@ -868,7 +868,7 @@ proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = ## Checks if `value` is withing the range of `s`; returns true iff ## `value >= s.a and value <= s.b` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert((1..3).contains(1) == true) ## assert((1..3).contains(2) == true) ## assert((1..3).contains(4) == false) @@ -877,20 +877,20 @@ proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = template `in` * (x, y: expr): expr {.immediate.} = contains(y, x) ## Sugar for contains ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 in (1..3) == true) ## assert(5 in (1..3) == false) template `notin` * (x, y: expr): expr {.immediate.} = not contains(y, x) ## Sugar for not containing ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 notin (1..3) == false) ## assert(5 notin (1..3) == true) proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.} ## Checks if T is of the same type as S ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## proc test[T](a: T): int = ## when (T is int): ## return a @@ -905,7 +905,7 @@ template `isnot` *(x, y: expr): expr {.immediate.} = not (x is y) proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.} ## Checks if `x` has a type of `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(EFloatingPoint of EBase) ## assert(EIO of ESystem) ## assert(EDivByZero of EBase) @@ -961,25 +961,25 @@ proc `&` * (x: string, y: char): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` with `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert("ab" & 'c' == "abc") proc `&` * (x: char, y: char): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` and `y` into a string ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert('a' & 'b' == "ab") proc `&` * (x, y: string): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` and `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert("ab" & "cd" == "abcd") proc `&` * (x: char, y: string): string {. magic: "ConStrStr", noSideEffect, merge.} ## Concatenates `x` with `y` ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert('a' & "bc" == "abc") # implementation note: These must all have the same magic value "ConStrStr" so @@ -988,7 +988,7 @@ proc `&` * (x: char, y: string): string {. proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.} ## Appends `y` to `x` in place ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var tmp = "" ## tmp.add('a') ## tmp.add('b') @@ -996,7 +996,7 @@ proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.} proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} ## Concatenates `x` and `y` in place ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## var tmp = "" ## tmp.add("ab") ## tmp.add("cd") @@ -1020,19 +1020,19 @@ const ## ``HH:MM:SS``. This works thanks to compiler magic. NimVersion* {.magic: "NimrodVersion"}: string = "0.0.0" - ## is the version of Nimrod as a string. + ## is the version of Nim as a string. ## This works thanks to compiler magic. NimMajor* {.magic: "NimrodMajor"}: int = 0 - ## is the major number of Nimrod's version. + ## is the major number of Nim's version. ## This works thanks to compiler magic. NimMinor* {.magic: "NimrodMinor"}: int = 0 - ## is the minor number of Nimrod's version. + ## is the minor number of Nim's version. ## This works thanks to compiler magic. NimPatch* {.magic: "NimrodPatch"}: int = 0 - ## is the patch number of Nimrod's version. + ## is the patch number of Nim's version. ## This works thanks to compiler magic. cpuEndian* {.magic: "CpuEndian"}: Endianness = littleEndian @@ -1145,7 +1145,7 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} = ## Generic proc for adding a data item `y` to a container `x`. ## For containers that have an order, `add` means *append*. New generic ## containers should also call their adding proc `add` for consistency. - ## Generic code becomes much easier to write if the Nimrod naming scheme is + ## Generic code becomes much easier to write if the Nim naming scheme is ## respected. let xl = x.len setLen(x, xl + y.len) @@ -1183,7 +1183,7 @@ proc insert*[T](x: var seq[T], item: T, i = 0) {.noSideEffect.} = x[i] = item proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.} - ## takes any Nimrod variable and returns its string representation. It + ## takes any Nim variable and returns its string representation. It ## works even for complex data graphs with cycles. This is a great ## debugging tool. @@ -1193,12 +1193,12 @@ type ## pointers to integer addresses for readability. BiggestInt* = int64 - ## is an alias for the biggest signed integer type the Nimrod compiler + ## is an alias for the biggest signed integer type the Nim compiler ## supports. Currently this is ``int64``, but it is platform-dependant ## in general. BiggestFloat* = float64 - ## is an alias for the biggest floating point type the Nimrod + ## is an alias for the biggest floating point type the Nim ## compiler supports. Currently this is ``float64``, but it is ## platform-dependant in general. @@ -1236,7 +1236,7 @@ type # these work for most platforms: ## This is the same as the type ``double`` in *C*. clongdouble* {.importc: "long double", nodecl.} = BiggestFloat ## This is the same as the type ``long double`` in *C*. - ## This C type is not supported by Nimrod's code generator + ## This C type is not supported by Nim's code generator cuchar* {.importc: "unsigned char", nodecl.} = char ## This is the same as the type ``unsigned char`` in *C*. @@ -1590,7 +1590,7 @@ iterator `||`*[S, T](a: S, b: T, annotation=""): T {. ## Note that the compiler maps that to ## the ``#pragma omp parallel for`` construct of `OpenMP`:idx: and as ## such isn't aware of the parallelism in your code! Be careful! Later - ## versions of ``||`` will get proper support by Nimrod's code generator + ## versions of ``||`` will get proper support by Nim's code generator ## and GC. discard @@ -1642,7 +1642,7 @@ proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} = proc clamp*[T](x, a, b: T): T = ## limits the value ``x`` within the interval [a, b] ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert((1.4).clamp(0.0, 1.0) == 1.0) ## assert((0.5).clamp(0.0, 1.0) == 0.5) if x < a: return a @@ -1746,7 +1746,7 @@ proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} = ## Concatenates two sequences. ## Requires copying of the sequences. ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(@[1, 2, 3, 4] & @[5, 6] == @[1, 2, 3, 4, 5, 6]) newSeq(result, x.len + y.len) for i in 0..x.len-1: @@ -1758,7 +1758,7 @@ proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} = ## Appends element y to the end of the sequence. ## Requires copying of the sequence ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(@[1, 2, 3] & 4 == @[1, 2, 3, 4]) newSeq(result, x.len + 1) for i in 0..x.len-1: @@ -1769,7 +1769,7 @@ proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} = ## Prepends the element x to the beginning of the sequence. ## Requires copying of the sequence ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## assert(1 & @[2, 3, 4] == @[1, 2, 3, 4]) newSeq(result, y.len + 1) result[0] = x @@ -1883,7 +1883,7 @@ iterator fieldPairs*[T: tuple|object](x: T): RootObj {. ## you want to run for each type. To perform the comparison use the `is ## operator `_. Example: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## ## type ## Custom = object @@ -2946,7 +2946,7 @@ when true: template assert*(cond: bool, msg = "") = ## Raises ``EAssertionFailure`` with `msg` if `cond` is false. ## - ## Provides a means to implement `programming by contracts`:idx: in Nimrod. + ## Provides a means to implement `programming by contracts`:idx: in Nim. ## ``assert`` evaluates expression ``cond`` and if ``cond`` is false, it ## raises an ``EAssertionFailure`` exception. However, the compiler may not ## generate any code at all for ``assert`` if it is advised to do so through @@ -3031,7 +3031,7 @@ proc shallow*(s: var string) {.noSideEffect, inline.} = type TNimrodNode {.final.} = object PNimrodNode* {.magic: "PNimrodNode".} = ref TNimrodNode - ## represents a Nimrod AST node. Macros operate on this type. + ## represents a Nim AST node. Macros operate on this type. when false: template eval*(blk: stmt): stmt = @@ -3060,7 +3060,7 @@ proc compiles*(x): bool {.magic: "Compiles", noSideEffect.} = ## without any semantic error. ## This can be used to check whether a type supports some operation: ## - ## .. code-block:: Nimrod + ## .. code-block:: Nim ## when not compiles(3 + 4): ## echo "'+' for integers is available" discard diff --git a/lib/windows/mmsystem.nim b/lib/windows/mmsystem.nim index 91279a5ef..632a6e557 100644 --- a/lib/windows/mmsystem.nim +++ b/lib/windows/mmsystem.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2006 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/windows/nb30.nim b/lib/windows/nb30.nim index a7fd526aa..be4a0616c 100644 --- a/lib/windows/nb30.nim +++ b/lib/windows/nb30.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2006 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/windows/psapi.nim b/lib/windows/psapi.nim index 7d53cf7ca..fd1dcada8 100644 --- a/lib/windows/psapi.nim +++ b/lib/windows/psapi.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2009 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/windows/shellapi.nim b/lib/windows/shellapi.nim index 41f2a60d5..9a280f551 100644 --- a/lib/windows/shellapi.nim +++ b/lib/windows/shellapi.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2006 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/windows/shfolder.nim b/lib/windows/shfolder.nim index 253b1c77a..886d757eb 100644 --- a/lib/windows/shfolder.nim +++ b/lib/windows/shfolder.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2006 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim index 5fd9127b3..32641b8fe 100644 --- a/lib/windows/windows.nim +++ b/lib/windows/windows.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 0da6cb1ff..18a565ffc 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -8,7 +8,7 @@ # ## This module implements a small wrapper for some needed Win API procedures, -## so that the Nimrod compiler does not depend on the huge Windows module. +## so that the Nim compiler does not depend on the huge Windows module. const useWinUnicode* = not defined(useWinAnsi) diff --git a/lib/wrappers/libsvm.nim b/lib/wrappers/libsvm.nim index 8dec05bcf..00d5ac73c 100644 --- a/lib/wrappers/libsvm.nim +++ b/lib/wrappers/libsvm.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim index 84d70287f..9871d4a7a 100644 --- a/lib/wrappers/mysql.nim +++ b/lib/wrappers/mysql.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/wrappers/sphinx.nim b/lib/wrappers/sphinx.nim index b4e127c65..e4a282968 100644 --- a/lib/wrappers/sphinx.nim +++ b/lib/wrappers/sphinx.nim @@ -12,7 +12,7 @@ # did not, you can find it at http://www.gnu.org/ # -## Nimrod wrapper for ``sphinx``. +## Nim wrapper for ``sphinx``. {.deadCodeElim: on.} when defined(windows): diff --git a/lib/wrappers/sqlite3.nim b/lib/wrappers/sqlite3.nim index 7b7f0874e..e817cd9ee 100644 --- a/lib/wrappers/sqlite3.nim +++ b/lib/wrappers/sqlite3.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/wrappers/tinyc.nim b/lib/wrappers/tinyc.nim index f685c714d..ac6cb70f1 100644 --- a/lib/wrappers/tinyc.nim +++ b/lib/wrappers/tinyc.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/wrappers/zip/libzip.nim b/lib/wrappers/zip/libzip.nim index 0b8d2b3ec..ebd74c7fd 100644 --- a/lib/wrappers/zip/libzip.nim +++ b/lib/wrappers/zip/libzip.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/wrappers/zip/zzip.nim b/lib/wrappers/zip/zzip.nim index a656322ee..73fd53c34 100644 --- a/lib/wrappers/zip/zzip.nim +++ b/lib/wrappers/zip/zzip.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2008 Andreas Rumpf # # See the file "copying.txt", included in this From 4523b29d7af0ac88754eec29981306022a0d642b Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 09:59:26 +0200 Subject: [PATCH 030/409] Nimrod renamed to Nim --- lib/core/macros.nim | 20 +++++------ lib/core/typeinfo.nim | 2 +- lib/impure/db_postgres.nim | 4 +-- lib/impure/re.nim | 14 ++++---- lib/impure/ssl.nim | 2 +- lib/impure/web.nim | 2 +- lib/prelude.nim | 4 +-- lib/pure/actors.nim | 2 +- lib/pure/algorithm.nim | 4 +-- lib/pure/asyncnet.nim | 2 +- lib/pure/collections/LockFreeHash.nim | 2 +- lib/pure/future.nim | 4 +-- lib/pure/httpclient.nim | 6 ++-- lib/pure/httpserver.nim | 2 +- lib/pure/json.nim | 4 +-- lib/pure/os.nim | 30 ++++++++-------- lib/pure/osproc.nim | 2 +- lib/pure/parseopt.nim | 2 +- lib/pure/parseutils.nim | 4 +-- lib/pure/parsexml.nim | 4 +-- lib/pure/times.nim | 2 +- lib/pure/xmltree.nim | 10 +++--- lib/system.nim | 52 +++++++++++++-------------- 23 files changed, 90 insertions(+), 90 deletions(-) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 41ba030f9..32e74aebf 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -261,7 +261,7 @@ proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst", noSideE ## Obtains the AST nodes returned from a macro or template invocation. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## macro FooMacro() = ## var ast = getAst(BarTemplate()) @@ -278,7 +278,7 @@ proc quote*(bl: stmt, op = "``"): PNimrodNode {.magic: "QuoteAst", noSideEffect. ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## macro check(ex: expr): stmt = ## # this is a simplified version of the check macro from the @@ -422,7 +422,7 @@ proc lispRepr*(n: PNimrodNode): string {.compileTime.} = add(result, ")") macro dumpTree*(s: stmt): stmt {.immediate.} = echo s.treeRepr - ## Accepts a block of nimrod code and prints the parsed abstract syntax + ## Accepts a block of nim code and prints the parsed abstract syntax ## tree using the `toTree` function. Printing is done *at compile time*. ## ## You can use this as a tool to explore the Nimrod's abstract syntax @@ -430,7 +430,7 @@ macro dumpTree*(s: stmt): stmt {.immediate.} = echo s.treeRepr ## a certain expression/statement. macro dumpLisp*(s: stmt): stmt {.immediate.} = echo s.lispRepr - ## Accepts a block of nimrod code and prints the parsed abstract syntax + ## Accepts a block of nim code and prints the parsed abstract syntax ## tree using the `toLisp` function. Printing is done *at compile time*. ## ## See `dumpTree`. @@ -489,7 +489,7 @@ proc newIdentDefs*(name, kind: PNimrodNode; ## ``let`` or ``var`` blocks may have an empty ``kind`` node if the ## identifier is being assigned a value. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## var varSection = newNimNode(nnkVarSection).add( ## newIdentDefs(ident("a"), ident("string")), @@ -501,7 +501,7 @@ proc newIdentDefs*(name, kind: PNimrodNode; ## If you need to create multiple identifiers you need to use the lower level ## ``newNimNode``: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## result = newNimNode(nnkIdentDefs).add( ## ident("a"), ident("b"), ident("c"), ident("string"), @@ -549,7 +549,7 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: PNimrodNode]]): PNimrodNode {.compiletime.} = ## Constructor for ``if`` statements. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## newIfStmt( ## (Ident, StmtList), @@ -643,7 +643,7 @@ template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {. immediate, dirty.} = ## Find the first child node matching condition (or nil). ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var res = findChild(n, it.kind == nnkPostfix and ## it.basename.ident == !"foo") block: @@ -738,11 +738,11 @@ proc addIdentIfAbsent*(dest: PNimrodNode, ident: string) {.compiletime.} = when not defined(booting): template emit*(e: static[string]): stmt = - ## accepts a single string argument and treats it as nimrod code + ## accepts a single string argument and treats it as nim code ## that should be inserted verbatim in the program ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## emit("echo " & '"' & "hello world".toUpper & '"') ## macro payload: stmt {.gensym.} = diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim index 5ca101919..842a944e1 100644 --- a/lib/core/typeinfo.nim +++ b/lib/core/typeinfo.nim @@ -50,7 +50,7 @@ type akUInt32 = 43, ## any represents an unsigned int32 akUInt64 = 44, ## any represents an unsigned int64 - TAny* = object {.pure.} ## can represent any nimrod value; NOTE: the wrapped + TAny* = object {.pure.} ## can represent any nim value; NOTE: the wrapped ## value can be modified with its wrapper! This means ## that ``TAny`` keeps a non-traced pointer to its ## wrapped value and **must not** live longer than diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index 6658dc0e0..4b7e20d0a 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -186,7 +186,7 @@ proc open*(connection, user, password, database: string): TDbConn {. ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## con = Open("", "", "", "host=localhost port=5432 dbname=mydb") ## @@ -194,7 +194,7 @@ proc open*(connection, user, password, database: string): TDbConn {. ## for more information. ## ## Note that the connection parameter is not used but exists to maintain - ## the nimrod db api. + ## the nim db api. result = PQsetdbLogin(nil, nil, nil, nil, database, user, password) if PQStatus(result) != CONNECTION_OK: dbError(result) # result = nil diff --git a/lib/impure/re.nim b/lib/impure/re.nim index 0624fbf43..a129a5eba 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -228,7 +228,7 @@ template `=~` *(s: string, pattern: TRegex): expr = ## This calls ``match`` with an implicit declared ``matches`` array that ## can be used in the scope of the ``=~`` call: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## if line =~ re"\s*(\w+)\s*\=\s*(\w+)": ## # matches a key=value pair: @@ -271,12 +271,12 @@ proc replace*(s: string, sub: TRegex, by = ""): string = ## Replaces `sub` in `s` by the string `by`. Captures cannot be ## accessed in `by`. Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "var1=key; var2=key2".replace(re"(\w+)'='(\w+)") ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## "; " result = "" @@ -293,12 +293,12 @@ proc replacef*(s: string, sub: TRegex, by: string): string = ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "var1=key; var2=key2".replacef(re"(\w+)'='(\w+)", "$1<-$2$2") ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## "var1<-keykey; val2<-key2key2" result = "" @@ -360,13 +360,13 @@ iterator split*(s: string, sep: TRegex): string = ## Substrings are separated by the regular expression `sep`. ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split("00232this02939is39an22example111", re"\d+"): ## writeln(stdout, word) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "this" ## "is" ## "an" diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim index 8a091a0d9..cae9990b9 100644 --- a/lib/impure/ssl.nim +++ b/lib/impure/ssl.nim @@ -8,7 +8,7 @@ # ## This module provides an easy to use sockets-style -## nimrod interface to the OpenSSL library. +## nim interface to the OpenSSL library. {.deprecated.} diff --git a/lib/impure/web.nim b/lib/impure/web.nim index abd7e2498..f0c19b367 100644 --- a/lib/impure/web.nim +++ b/lib/impure/web.nim @@ -59,5 +59,5 @@ proc URLretrieveString*(url: string): TaintedString = result = stream.data.TaintedString when isMainModule: - echo URLretrieveString("http://nimrod-code.org/") + echo URLretrieveString("http://nim-code.org/") diff --git a/lib/prelude.nim b/lib/prelude.nim index 60d9c0925..940864207 100644 --- a/lib/prelude.nim +++ b/lib/prelude.nim @@ -10,12 +10,12 @@ ## This is an include file that simply imports common modules for your ## convenience: ## -## .. code-block:: nimrod +## .. code-block:: nim ## include prelude ## ## Same as: ## -## .. code-block:: nimrod +## .. code-block:: nim ## import os, strutils, times, parseutils, parseopt, hashes, tables, sets import os, strutils, times, parseutils, parseopt, hashes, tables, sets diff --git a/lib/pure/actors.nim b/lib/pure/actors.nim index 18299d687..f2c50ce4c 100644 --- a/lib/pure/actors.nim +++ b/lib/pure/actors.nim @@ -13,7 +13,7 @@ ## ## Example: ## -## .. code-block:: nimrod +## .. code-block:: nim ## ## var ## a: TActorPool[int, void] diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 3993a4172..0358a9a81 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -159,7 +159,7 @@ proc sort*[T](a: var openArray[T], ## sensible default argument for ``cmp``, so you have to provide one ## of your own. However, the ``system.cmp`` procs can be used: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## sort(myIntArray, system.cmp[int]) ## @@ -170,7 +170,7 @@ proc sort*[T](a: var openArray[T], ## You can inline adhoc comparison procs with the `do notation ## `_. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## people.sort do (x, y: Person) -> int: ## result = cmp(x.surname, y.surname) diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index ecaf0b9f9..695d8c07b 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -15,7 +15,7 @@ ## ## The following example demonstrates a simple chat server. ## -## .. code-block::nimrod +## .. code-block::nim ## ## import asyncnet, asyncdispatch ## diff --git a/lib/pure/collections/LockFreeHash.nim b/lib/pure/collections/LockFreeHash.nim index 57beb83c9..5640838b1 100644 --- a/lib/pure/collections/LockFreeHash.nim +++ b/lib/pure/collections/LockFreeHash.nim @@ -1,4 +1,4 @@ -#nimrod c -t:-march=i686 --cpu:amd64 --threads:on -d:release lockfreehash.nim +#nim c -t:-march=i686 --cpu:amd64 --threads:on -d:release lockfreehash.nim import unsigned, math, hashes diff --git a/lib/pure/future.nim b/lib/pure/future.nim index c467d2c73..7d791e16c 100644 --- a/lib/pure/future.nim +++ b/lib/pure/future.nim @@ -53,7 +53,7 @@ proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} = macro `=>`*(p, b: expr): expr {.immediate.} = ## Syntax sugar for anonymous procedures. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## proc passTwoAndTwo(f: (int, int) -> int): int = ## f(2, 2) @@ -104,7 +104,7 @@ macro `=>`*(p, b: expr): expr {.immediate.} = macro `->`*(p, b: expr): expr {.immediate.} = ## Syntax sugar for procedure types. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## proc pass2(f: (float, float) -> float): float = ## f(2, 2) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 3fbb04fc8..a0e8c6b05 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -656,17 +656,17 @@ when isMainModule: resp = await client.request("http://picheta.me/aboutme.html") echo("Got response: ", resp.status) - resp = await client.request("http://nimrod-lang.org/") + resp = await client.request("http://nim-lang.org/") echo("Got response: ", resp.status) - resp = await client.request("http://nimrod-lang.org/download.html") + resp = await client.request("http://nim-lang.org/download.html") echo("Got response: ", resp.status) asyncCheck main() runForever() else: - #downloadFile("http://force7.de/nimrod/index.html", "nimrodindex.html") + #downloadFile("http://force7.de/nim/index.html", "nimindex.html") #downloadFile("http://www.httpwatch.com/", "ChunkTest.html") #downloadFile("http://validator.w3.org/check?uri=http%3A%2F%2Fgoogle.com", # "validator.html") diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim index 4bbdbb5a1..b850815c9 100644 --- a/lib/pure/httpserver.nim +++ b/lib/pure/httpserver.nim @@ -11,7 +11,7 @@ ## ## Example: ## -## .. code-block:: nimrod +## .. code-block:: nim ## import strutils, sockets, httpserver ## ## var counter = 0 diff --git a/lib/pure/json.nim b/lib/pure/json.nim index d90ddebf1..8bd05ad55 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -16,7 +16,7 @@ ## ## Usage example: ## -## .. code-block:: nimrod +## .. code-block:: nim ## let ## small_json = """{"test": 1.3, "key2": true}""" ## jobj = parseJson(small_json) @@ -26,7 +26,7 @@ ## ## Results in: ## -## .. code-block:: nimrod +## .. code-block:: nim ## ## 1.3000000000000000e+00 ## true diff --git a/lib/pure/os.nim b/lib/pure/os.nim index ae352c26f..c4b694406 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -514,12 +514,12 @@ proc joinPath*(head, tail: string): string {. ## ## For example on Unix: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## joinPath("usr", "lib") ## ## results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "usr/lib" ## ## If head is the empty string, tail is returned. If tail is the empty @@ -528,7 +528,7 @@ proc joinPath*(head, tail: string): string {. ## path separators not located on boundaries won't be modified. More ## examples on Unix: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## assert joinPath("usr", "") == "usr/" ## assert joinPath("", "lib") == "lib" ## assert joinPath("", "/lib") == "/lib" @@ -560,7 +560,7 @@ proc `/` * (head, tail: string): string {.noSideEffect.} = ## ## Here are some examples for Unix: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## assert "usr" / "" == "usr/" ## assert "" / "lib" == "lib" ## assert "" / "/lib" == "/lib" @@ -574,7 +574,7 @@ proc splitPath*(path: string): tuple[head, tail: string] {. ## ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## splitPath("usr/local/bin") -> ("usr/local", "bin") ## splitPath("usr/local/bin/") -> ("usr/local/bin", "") ## splitPath("bin") -> ("", "bin") @@ -674,10 +674,10 @@ proc splitFile*(path: string): tuple[dir, name, ext: string] {. ## ## Example: ## - ## .. code-block:: nimrod - ## var (dir, name, ext) = splitFile("usr/local/nimrodc.html") + ## .. code-block:: nim + ## var (dir, name, ext) = splitFile("usr/local/nimc.html") ## assert dir == "usr/local" - ## assert name == "nimrodc" + ## assert name == "nimc" ## assert ext == ".html" ## ## If `path` has no extension, `ext` is the empty string. @@ -1579,7 +1579,7 @@ proc inclFilePermissions*(filename: string, rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} = ## a convenience procedure for: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## setFilePermissions(filename, getFilePermissions(filename)+permissions) setFilePermissions(filename, getFilePermissions(filename)+permissions) @@ -1588,7 +1588,7 @@ proc exclFilePermissions*(filename: string, rtl, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect].} = ## a convenience procedure for: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## setFilePermissions(filename, getFilePermissions(filename)-permissions) setFilePermissions(filename, getFilePermissions(filename)-permissions) @@ -1627,7 +1627,7 @@ when defined(nimdoc): ## can test for its availability with `declared() `_. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when declared(paramCount): ## # Use paramCount() here ## else: @@ -1650,7 +1650,7 @@ when defined(nimdoc): ## can test for its availability with `declared() `_. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when declared(paramStr): ## # Use paramStr() here ## else: @@ -1703,7 +1703,7 @@ when declared(paramCount) or defined(nimdoc): ## can test for its availability with `declared() `_. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when declared(commandLineParams): ## # Use commandLineParams() here ## else: @@ -1858,7 +1858,7 @@ proc expandTilde*(path: string): string = ## The behaviour of this proc is the same on the Windows platform despite not ## having this convention. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let configFile = expandTilde("~" / "appname.cfg") ## echo configFile ## # --> C:\Users\amber\appname.cfg @@ -1889,7 +1889,7 @@ type creationTime*: Time # Time file was created. Not supported on all systems! template rawToFormalFileInfo(rawInfo, formalInfo): expr = - ## Transforms the native file info structure into the one nimrod uses. + ## Transforms the native file info structure into the one nim uses. ## 'rawInfo' is either a 'TBY_HANDLE_FILE_INFORMATION' structure on Windows, ## or a 'TStat' structure on posix when defined(Windows): diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 884774f1f..5c9cf182f 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -771,7 +771,7 @@ elif not defined(useNimRtl): proc startProcessAfterFork(data: ptr TStartProcessData) = # Warning: no GC here! - # Or anything that touches global structures - all called nimrod procs + # Or anything that touches global structures - all called nim procs # must be marked with stackTrace:off. Inspect C code after making changes. if not data.optionPoParentStreams: discard close(data.pStdin[writeIdx]) diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index de00bc76d..786744600 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -132,7 +132,7 @@ when declared(initOptParser): ## This is an convenience iterator for iterating over the command line. ## This uses the TOptParser object. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var ## filename = "" ## for kind, key, val in getopt(): diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index 38a3cbc5e..8f8ca6ab3 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -348,13 +348,13 @@ iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind, ## ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for k, v in interpolatedFragments(" $this is ${an example} $$"): ## echo "(", k, ", \"", v, "\")" ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## (ikString, " ") ## (ikExpr, "this") ## (ikString, " is ") diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index f4f46e4f4..9b2814b84 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -33,7 +33,7 @@ ## XML parser to accomplish a simple task: To determine the title of an HTML ## document. ## -## .. code-block:: nimrod +## .. code-block:: nim ## :file: examples/htmltitle.nim ## ## @@ -44,7 +44,7 @@ ## XML parser to accomplish another simple task: To determine all the links ## an HTML document contains. ## -## .. code-block:: nimrod +## .. code-block:: nim ## :file: examples/htmlrefs.nim ## diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 5d92218b3..dcc5617fd 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -298,7 +298,7 @@ when not defined(JS): ## To generate useful timing values, take the difference between ## the results of two ``cpuTime`` calls: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var t0 = cpuTime() ## doWork() ## echo "CPU time [s] ", cpuTime() - t0 diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 2caa65023..37f591f1e 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -275,12 +275,12 @@ proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} = macro `<>`*(x: expr): expr {.immediate.} = ## Constructor macro for XML. Example usage: ## - ## .. code-block:: nimrod - ## <>a(href="http://nimrod-code.org", newText("Nim rules.")) + ## .. code-block:: nim + ## <>a(href="http://nim-code.org", newText("Nim rules.")) ## ## Produces an XML tree for:: ## - ## Nim rules. + ## Nim rules. ## let x = callsite() result = xmlConstructor(x) @@ -339,5 +339,5 @@ proc findAll*(n: XmlNode, tag: string): seq[XmlNode] = findAll(n, tag, result) when isMainModule: - assert """Nim rules.""" == - $(<>a(href="http://nimrod-code.org", newText("Nim rules."))) + assert """Nim rules.""" == + $(<>a(href="http://nim-code.org", newText("Nim rules."))) diff --git a/lib/system.nim b/lib/system.nim index b07fa76e2..1de9e23c7 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -100,7 +100,7 @@ proc defined*(x: expr): bool {.magic: "Defined", noSideEffect.} ## Special compile-time procedure that checks whether `x` is ## defined. ## `x` is an external symbol introduced through the compiler's - ## `-d:x switch `_ to enable build time + ## `-d:x switch `_ to enable build time ## conditionals: ## ## .. code-block:: Nim @@ -509,7 +509,7 @@ proc sizeof*[T](x: T): Natural {.magic: "SizeOf", noSideEffect.} proc `<`*[T](x: Ordinal[T]): T {.magic: "UnaryLt", noSideEffect.} ## unary ``<`` that can be used for nice looking excluding ranges: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for i in 0 .. <10: echo i ## ## Semantically this is the same as ``pred``. @@ -544,7 +544,7 @@ proc newSeq*[T](s: var seq[T], len: int) {.magic: "NewSeq", noSideEffect.} ## ``nil``. After the creation of the sequence you should assign entries to ## the sequence instead of adding them. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var inputStrings : seq[string] ## newSeq(inputStrings, 3) ## inputStrings[0] = "The fourth" @@ -560,7 +560,7 @@ proc newSeq*[T](len = 0): seq[T] = ## ``nil``. After the creation of the sequence you should assign entries to ## the sequence instead of adding them. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var inputStrings = newSeq[string](3) ## inputStrings[0] = "The fourth" ## inputStrings[1] = "assignment" @@ -1058,7 +1058,7 @@ proc compileOption*(option: string): bool {. magic: "CompileOption", noSideEffect.} ## can be used to determine an on|off compile-time option. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when compileOption("floatchecks"): ## echo "compiled with floating point NaN and Inf checks" @@ -1066,7 +1066,7 @@ proc compileOption*(option, arg: string): bool {. magic: "CompileOptionArg", noSideEffect.} ## can be used to determine an enum compile-time option. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## when compileOption("opt", "size") and compileOption("gc", "boehm"): ## echo "compiled with optimization for size and uses Boehm's GC" @@ -1123,7 +1123,7 @@ proc quit*(errorcode: int = QuitSuccess) {. ## procedures. It does *not* call the garbage collector to free all the ## memory, unless a quit procedure calls ``GC_collect``. ## - ## The proc ``quit(QuitSuccess)`` is called implicitly when your nimrod + ## The proc ``quit(QuitSuccess)`` is called implicitly when your nim ## program finishes without incident. A raised unhandled exception is ## equivalent to calling ``quit(QuitFailure)``. ## @@ -1840,7 +1840,7 @@ proc map*[T, S](data: openArray[T], op: proc (x: T): S {.closure.}): seq[S] = ## Since the input is not modified you can use this version of ``map`` to ## transform the type of the elements in the input sequence. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let ## a = @[1, 2, 3, 4] ## b = map(a, proc(x: int): string = $x) @@ -1854,7 +1854,7 @@ proc map*[T](data: var openArray[T], op: proc (x: var T) {.closure.}) = ## Note that this version of ``map`` requires your input and output types to ## be the same, since they are modified in-place. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var a = @["1", "2", "3", "4"] ## echo repr(a) ## # --> ["1", "2", "3", "4"] @@ -1945,7 +1945,7 @@ proc `$`*[T: tuple|object](x: T): string = ## generic ``$`` operator for tuples that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## $(23, 45) == "(23, 45)" ## $() == "()" result = "(" @@ -1971,7 +1971,7 @@ proc `$`*[T](x: set[T]): string = ## generic ``$`` operator for sets that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ${23, 45} == "{23, 45}" collectionToString(x, "{", "}") @@ -1979,7 +1979,7 @@ proc `$`*[T](x: seq[T]): string = ## generic ``$`` operator for seqs that is lifted from the components ## of `x`. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## $(@[23, 45]) == "@[23, 45]" collectionToString(x, "@[", "]") @@ -2078,7 +2078,7 @@ var ## writes an error message and terminates the program. `outOfMemHook` can ## be used to raise an exception in case of OOM like so: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## var gOutOfMem: ref EOutOfMemory ## new(gOutOfMem) # need to be allocated *before* OOM really happened! @@ -2576,7 +2576,7 @@ when not defined(JS): #and not defined(NimrodVM): ## If the file does not exist `EIO` is raised. The trailing newline ## character(s) are removed from the iterated lines. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## import strutils ## ## proc transformLetters(filename: string) = @@ -2595,7 +2595,7 @@ when not defined(JS): #and not defined(NimrodVM): ## The trailing newline character(s) are removed from the iterated lines. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## proc countZeros(filename: File): tuple[lines, zeros: int] = ## for line in filename.lines: ## for letter in line: @@ -2645,7 +2645,7 @@ when not defined(JS): #and not defined(NimrodVM): ## platforms this can help the processor predict better which branch is ## going to be run. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for value in inputValues: ## if likely(value <= 100): ## process(value) @@ -2659,7 +2659,7 @@ when not defined(JS): #and not defined(NimrodVM): ## platforms this can help the processor predict better which branch is ## going to be run. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for value in inputValues: ## if unlikely(value > 100): ## echo "Value too big!" @@ -2766,7 +2766,7 @@ when hostOS != "standalone": ## ``b.len`` is not exactly the number of elements that are referred to ## by `x`, a `splice`:idx: is performed: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## var s = "abcdef" ## s[1 .. -2] = "xyz" ## assert s == "axyzf" @@ -2843,7 +2843,7 @@ proc slurp*(filename: string): string {.magic: "Slurp".} proc staticRead*(filename: string): string {.magic: "Slurp".} ## Compile-time ``readFile`` proc for easy `resource`:idx: embedding: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## const myResource = staticRead"mydatafile.bin" ## ## ``slurp`` is an alias for ``staticRead``. @@ -2858,13 +2858,13 @@ proc staticExec*(command: string, input = ""): string {. ## if `input` is not an empty string, it will be passed as a standard input ## to the executed program. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## const buildInfo = "Revision " & staticExec("git rev-parse HEAD") & ## "\nCompiled on " & staticExec("uname -v") ## ## ``gorge`` is an alias for ``staticExec``. Note that you can use this proc - ## inside a pragma like `passC `_ or `passL - ## `_. + ## inside a pragma like `passC `_ or `passL + ## `_. proc `+=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.magic: "Inc", noSideEffect.} ## Increments an ordinal @@ -2906,7 +2906,7 @@ proc instantiationInfo*(index = -1, fullPaths = false): tuple[ ## to retrieve information about the current filename and line number. ## Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## import strutils ## ## template testException(exception, code: expr): stmt = @@ -2951,7 +2951,7 @@ template assert*(cond: bool, msg = "") = ## raises an ``EAssertionFailure`` exception. However, the compiler may not ## generate any code at all for ``assert`` if it is advised to do so through ## the ``-d:release`` or ``--assertions:off`` `command line switches - ## `_. + ## `_. ## ## Use ``assert`` for debugging purposes only. bind instantiationInfo @@ -2994,7 +2994,7 @@ template onFailedAssert*(msg: expr, code: stmt): stmt {.dirty, immediate.} = ## statements following `onFailedAssert` in the current lexical scope. ## Can be defined multiple times in a single function. ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## proc example(x: int): TErrorCode = ## onFailedAssert(msg): @@ -3089,7 +3089,7 @@ proc locals*(): RootObj {.magic: "Locals", noSideEffect.} = ## the official signature says, the return type is not ``TObject`` but a ## tuple of a structure that depends on the current scope. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## proc testLocals() = ## var ## a = "something" From c95e47216f790f8aac9860a8a0deae0369a2a84f Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 10:01:20 +0200 Subject: [PATCH 031/409] Nimrod renamed to Nim --- compiler/semexprs.nim | 2 +- compiler/semfold.nim | 2 +- compiler/semtypes.nim | 2 +- compiler/vm.nim | 2 +- compiler/vmdef.nim | 2 +- compiler/vmgen.nim | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index da12ec08c..b310e0869 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 8e53fd670..6972e3f1c 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 53fe4e266..c3d34f2ba 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/vm.nim b/compiler/vm.nim index e40acca6c..af0b30faa 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index cad48abea..e25fd6392 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 94afbf008..6a6f85d76 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this From 3ea64469008c30682a0cc7b92e3f553a07f30a37 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 22:36:14 +0200 Subject: [PATCH 032/409] Nimrod renamed to Nim --- doc/advopt.txt | 6 +- doc/apis.txt | 2 +- doc/astspec.txt | 112 ++++++++++++++--------------- doc/backends.txt | 162 +++++++++++++++++++++--------------------- doc/basicopt.txt | 4 +- doc/docgen.txt | 60 ++++++++-------- doc/docs.txt | 14 ++-- doc/effects.txt | 4 +- doc/endb.txt | 18 ++--- doc/estp.txt | 20 +++--- doc/filelist.txt | 10 +-- doc/filters.txt | 14 ++-- doc/gc.txt | 10 +-- doc/idetools.txt | 60 ++++++++-------- doc/intern.txt | 72 +++++++++---------- doc/koch.txt | 42 +++++------ doc/nimgrep.txt | 4 +- doc/niminst.txt | 10 +-- doc/overview.txt | 4 +- doc/pegdocs.txt | 8 +-- doc/readme.txt | 4 +- doc/regexprs.txt | 4 +- doc/rst.txt | 22 +++--- doc/sets_fragment.txt | 2 +- doc/spawn.txt | 8 +-- doc/subexes.txt | 2 +- doc/tools.txt | 14 ++-- doc/tut2.txt | 2 +- readme.md | 32 ++++----- readme.txt | 32 ++++----- 30 files changed, 379 insertions(+), 379 deletions(-) diff --git a/doc/advopt.txt b/doc/advopt.txt index 7a11e9041..18cea8a79 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -50,7 +50,7 @@ Advanced options: --os:SYMBOL set the target operating system (cross-compilation) --cpu:SYMBOL set the target processor (cross-compilation) --debuginfo enables debug information - --debugger:on|off turn Embedded Nimrod Debugger on|off + --debugger:on|off turn Embedded Nim Debugger on|off -t, --passC:OPTION pass an option to the C compiler -l, --passL:OPTION pass an option to the linker --cincludes:DIR modify the C compiler header search path @@ -58,7 +58,7 @@ Advanced options: --clib:LIBNAME link an additional C library (you should omit platform-specific extensions) --genMapping generate a mapping file containing - (Nimrod, mangled) identifier pairs + (Nim, mangled) identifier pairs --project document the whole project (doc2) --docSeeSrcUrl:url activate 'see source' for doc and doc2 commands (see doc.item.seesrc in config/nimdoc.cfg) @@ -89,7 +89,7 @@ Advanced options: --listCmd list the commands used to execute external programs --parallelBuild=0|1|... perform a parallel build value = number of processors (0 for auto-detect) - --verbosity:0|1|2|3 set Nimrod's verbosity level (1 is default) + --verbosity:0|1|2|3 set Nim's verbosity level (1 is default) --cs:none|partial set case sensitivity level (default: none); do not use! this setting affects the whole language -v, --version show detailed version information diff --git a/doc/apis.txt b/doc/apis.txt index 9906f6bbc..e0510d85f 100644 --- a/doc/apis.txt +++ b/doc/apis.txt @@ -84,5 +84,5 @@ indentation indent Coding Guidelines ================= -For coding guidelines see the `Internals of the Nimrod Compiler +For coding guidelines see the `Internals of the Nim Compiler `_ documentation. diff --git a/doc/astspec.txt b/doc/astspec.txt index 6b6242614..5c4274093 100644 --- a/doc/astspec.txt +++ b/doc/astspec.txt @@ -1,11 +1,11 @@ -The AST in Nimrod +The AST in Nim ================= -This section describes how the AST is modelled with Nimrod's type system. +This section describes how the AST is modelled with Nim's type system. The AST consists of nodes (``PNimrodNode``) with a variable number of children. Each node has a field named ``kind`` which describes what the node contains: -.. code-block:: nimrod +.. code-block:: nim type TNimrodNodeKind = enum ## kind of a node; only explanatory @@ -39,7 +39,7 @@ contains: For the ``PNimrodNode`` type, the ``[]`` operator has been overloaded: ``n[i]`` is ``n``'s ``i``-th child. -To specify the AST for the different Nimrod constructs, the notation +To specify the AST for the different Nim constructs, the notation ``nodekind(son1, son2, ...)`` or ``nodekind(value)`` or ``nodekind(field=value)`` is used. @@ -53,7 +53,7 @@ A leaf of the AST often corresponds to a terminal symbol in the concrete syntax. ----------------- --------------------------------------------- -Nimrod expression corresponding AST +Nim expression corresponding AST ----------------- --------------------------------------------- ``42`` ``nnkIntLit(intVal = 42)`` ``42'i8`` ``nnkInt8Lit(intVal = 42)`` @@ -87,12 +87,12 @@ Command call Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim echo "abc", "xyz" AST: -.. code-block:: nimrod +.. code-block:: nim nnkCommand(nnkIdent(!"echo"), nnkStrLit("abc"), nnkStrLit("xyz")) @@ -101,12 +101,12 @@ Call with ``()`` Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim echo("abc", "xyz") AST: -.. code-block:: nimrod +.. code-block:: nim nnkCall(nnkIdent(!"echo"), nnkStrLit("abc"), nnkStrLit("xyz")) @@ -115,12 +115,12 @@ Infix operator call Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim "abc" & "xyz" AST: -.. code-block:: nimrod +.. code-block:: nim nnkInfix(nnkIdent(!"&"), nnkStrLit("abc"), nnkStrLit("xyz")) @@ -129,29 +129,29 @@ Prefix operator call Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim ? "xyz" AST: -.. code-block:: nimrod +.. code-block:: nim nnkPrefix(nnkIdent(!"?"), nnkStrLit("abc")) Postfix operator call --------------------- -**Note:** There are no postfix operators in Nimrod. However, the +**Note:** There are no postfix operators in Nim. However, the ``nnkPostfix`` node is used for the *asterisk export marker* ``*``: Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim identifier* AST: -.. code-block:: nimrod +.. code-block:: nim nnkPostfix(nnkIdent(!"*"), nnkIdent(!"identifier")) @@ -160,12 +160,12 @@ Call with named arguments Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim writeln(file=stdout, "hallo") AST: -.. code-block:: nimrod +.. code-block:: nim nnkCall(nnkIdent(!"writeln"), nnkExprEqExpr(nnkIdent(!"file"), nnkIdent(!"stdout")), nnkStrLit("hallo")) @@ -176,12 +176,12 @@ Dereference operator ``^`` Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim x^ AST: -.. code-block:: nimrod +.. code-block:: nim nnkDerefExpr(nnkIdent(!"x")) @@ -190,12 +190,12 @@ Addr operator Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim addr(x) AST: -.. code-block:: nimrod +.. code-block:: nim nnkAddr(nnkIdent(!"x")) @@ -204,12 +204,12 @@ Cast operator Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim cast[T](x) AST: -.. code-block:: nimrod +.. code-block:: nim nnkCast(nnkIdent(!"T"), nnkIdent(!"x")) @@ -218,12 +218,12 @@ Object access operator ``.`` Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim x.y AST: -.. code-block:: nimrod +.. code-block:: nim nnkDotExpr(nnkIdent(!"x"), nnkIdent(!"y")) @@ -232,12 +232,12 @@ Array access operator ``[]`` Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim x[y] AST: -.. code-block:: nimrod +.. code-block:: nim nnkBracketExpr(nnkIdent(!"x"), nnkIdent(!"y")) @@ -249,12 +249,12 @@ are built with the ``nnkPar`` node. Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim (1, 2, (3)) AST: -.. code-block:: nimrod +.. code-block:: nim nnkPar(nnkIntLit(1), nnkIntLit(2), nnkPar(nnkIntLit(3))) @@ -265,12 +265,12 @@ Curly braces are used as the set constructor. Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim {1, 2, 3} AST: -.. code-block:: nimrod +.. code-block:: nim nnkCurly(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3)) @@ -281,12 +281,12 @@ Brackets are used as the array constructor. Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim [1, 2, 3] AST: -.. code-block:: nimrod +.. code-block:: nim nnkBracket(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3)) @@ -297,12 +297,12 @@ Ranges occur in set constructors, case statement branches or array slices. Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim 1..3 AST: -.. code-block:: nimrod +.. code-block:: nim nnkRange(nnkIntLit(1), nnkIntLit(3)) @@ -313,12 +313,12 @@ The representation of the if expression is subtle, but easy to traverse. Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim if cond1: expr1 elif cond2: expr2 else: expr3 AST: -.. code-block:: nimrod +.. code-block:: nim nnkIfExpr( nnkElifExpr(cond1, expr1), nnkElifExpr(cond2, expr2), @@ -337,7 +337,7 @@ there is no ``else`` branch, no ``nnkElse`` child exists. Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim if cond1: stmt1 elif cond2: @@ -349,7 +349,7 @@ Concrete syntax: AST: -.. code-block:: nimrod +.. code-block:: nim nnkIfStmt( nnkElifBranch(cond1, stmt1), nnkElifBranch(cond2, stmt2), @@ -369,12 +369,12 @@ Assignment Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim x = 42 AST: -.. code-block:: nimrod +.. code-block:: nim nnkAsgn(nnkIdent(!"x"), nnkIntLit(42)) @@ -383,14 +383,14 @@ Statement list Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim stmt1 stmt2 stmt3 AST: -.. code-block:: nimrod +.. code-block:: nim nnkStmtList(stmt1, stmt2, stmt3) @@ -399,7 +399,7 @@ Case statement Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim case expr1 of expr2, expr3..expr4: stmt1 @@ -412,7 +412,7 @@ Concrete syntax: AST: -.. code-block:: nimrod +.. code-block:: nim nnkCaseStmt( expr1, nnkOfBranch(expr2, nnkRange(expr3, expr4), stmt1), @@ -429,13 +429,13 @@ While statement Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim while expr1: stmt1 AST: -.. code-block:: nimrod +.. code-block:: nim nnkWhileStmt(expr1, stmt1) @@ -444,13 +444,13 @@ For statement Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim for ident1, ident2 in expr1: stmt1 AST: -.. code-block:: nimrod +.. code-block:: nim nnkForStmt(ident1, ident2, expr1, stmt1) @@ -459,7 +459,7 @@ Try statement Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim try: stmt1 except e1, e2: @@ -473,7 +473,7 @@ Concrete syntax: AST: -.. code-block:: nimrod +.. code-block:: nim nnkTryStmt( stmt1, nnkExceptBranch(e1, e2, stmt2), @@ -488,12 +488,12 @@ Return statement Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim return expr1 AST: -.. code-block:: nimrod +.. code-block:: nim nnkReturnStmt(expr1) @@ -514,12 +514,12 @@ Continue statement Concrete syntax: -.. code-block:: nimrod +.. code-block:: nim continue AST: -.. code-block:: nimrod +.. code-block:: nim nnkContinueStmt() Var section diff --git a/doc/backends.txt b/doc/backends.txt index c2dbb0af6..307f141b2 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -1,9 +1,9 @@ ================================ - Nimrod Backend Integration + Nim Backend Integration ================================ :Author: Puppet Master -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: "Heresy grows from idleness." -- Unknown. @@ -12,20 +12,20 @@ Introduction ============ -The `Nimrod Compiler User Guide `_ documents the typical +The `Nim Compiler User Guide `_ documents the typical compiler invocation, using the ``compile`` or ``c`` command to transform a ``.nim`` file into one or more ``.c`` files which are then compiled with the platform's C compiler into a static binary. However there are other commands to compile to C++, Objective-C or JavaScript. This document tries to concentrate in a single place all the backend and interfacing options. -The Nimrod compiler supports mainly two backend families: the C, C++ and +The Nim compiler supports mainly two backend families: the C, C++ and Objective-C targets and the JavaScript target. `The C like targets`_ creates source files which can be compiled into a library or a final executable. `The JavaScript target`_ can generate a ``.js`` file which you reference from an HTML file or create a `standalone nodejs program `_. -On top of generating libraries or standalone applications, Nimrod offers +On top of generating libraries or standalone applications, Nim offers bidirectional interfacing with the backend targets through generic and specific pragmas. @@ -49,25 +49,25 @@ project. This allows you to take the generated code and place it directly into a project using any of these languages. Here are some typical command line invocations:: - $ nimrod c hallo.nim - $ nimrod cpp hallo.nim - $ nimrod objc hallo.nim + $ nim c hallo.nim + $ nim cpp hallo.nim + $ nim objc hallo.nim The compiler commands select the target backend, but if needed you can `specify additional switches for cross compilation -`_ to select the target CPU, operative system +`_ to select the target CPU, operative system or compiler/linker commands. The JavaScript target --------------------- -Nimrod can also generate `JavaScript`:idx: code through the ``js`` command. +Nim can also generate `JavaScript`:idx: code through the ``js`` command. However, the JavaScript code generator is experimental! -Nimrod targets JavaScript 1.5 which is supported by any widely used browser. +Nim targets JavaScript 1.5 which is supported by any widely used browser. Since JavaScript does not have a portable means to include another module, -Nimrod just generates a long ``.js`` file. +Nim just generates a long ``.js`` file. Features or modules that the JavaScript platform does not support are not available. This includes: @@ -83,35 +83,35 @@ However, the modules `strutils `_, `math `_, and `times `_ are available! To access the DOM, use the `dom `_ module that is only available for the JavaScript platform. -To compile a Nimrod module into a ``.js`` file use the ``js`` command; the +To compile a Nim module into a ``.js`` file use the ``js`` command; the default is a ``.js`` file that is supposed to be referenced in an ``.html`` file. However, you can also run the code with `nodejs`:idx:, a `software platform for easily building fast, scalable network applications `_:: - nimrod js -d:nodejs -r examples/hallo.nim + nim js -d:nodejs -r examples/hallo.nim Interfacing =========== -Nimrod offers bidirectional interfacing with the target backend. This means -that you can call backend code from Nimrod and Nimrod code can be called by +Nim offers bidirectional interfacing with the target backend. This means +that you can call backend code from Nim and Nim code can be called by the backend code. Usually the direction of which calls which depends on your -software architecture (is Nimrod your main program or is Nimrod providing a +software architecture (is Nim your main program or is Nim providing a component?). -Nimrod code calling the backend +Nim code calling the backend -------------------------------- -Nimrod code can interface with the backend through the `Foreign function +Nim code can interface with the backend through the `Foreign function interface `_ mainly through the `importc pragma `_. The ``importc`` pragma is the -*generic* way of making backend symbols available in Nimrod and is available +*generic* way of making backend symbols available in Nim and is available in all the target backends (JavaScript too). The C++ or Objective-C backends -have their respective `ImportCpp `_ and -`ImportObjC `_ pragmas to call methods from +have their respective `ImportCpp `_ and +`ImportObjC `_ pragmas to call methods from classes. Whenever you use any of these pragmas you need to integrate native code into @@ -121,22 +121,22 @@ JavaScript functions which you are importing with ``importc``. However, for the C like targets you need to link external code either statically or dynamically. The preferred way of integrating native code is to -use dynamic linking because it allows you to compile Nimrod programs without +use dynamic linking because it allows you to compile Nim programs without the need for having the related development libraries installed. This is done through the `dynlib pragma for import `_, though more specific control can be gained using the `dynlib module `_. -The `dynlibOverride `_ command line switch allows +The `dynlibOverride `_ command line switch allows to avoid dynamic linking if you need to statically link something instead. -Nimrod wrappers designed to statically link source files can use the `compile -pragma `_ if there are few sources or providing -them along the Nimrod code is easier than using a system library. Libraries +Nim wrappers designed to statically link source files can use the `compile +pragma `_ if there are few sources or providing +them along the Nim code is easier than using a system library. Libraries installed on the host system can be linked in with the `PassL pragma -`_. +`_. To wrap native code, take a look at the `c2nim tool `_ which helps -with the process of scanning and transforming header files into a Nimrod +with the process of scanning and transforming header files into a Nim interface. C invocation example @@ -152,7 +152,7 @@ Create a ``logic.c`` file with the following content: Create a ``calculator.nim`` file with the following content: -.. code-block:: nimrod +.. code-block:: nim {.compile: "logic.c".} proc addTwoIntegers(a, b: cint): cint {.importc.} @@ -160,8 +160,8 @@ Create a ``calculator.nim`` file with the following content: when isMainModule: echo addTwoIntegers(3, 7) -With these two files in place, you can run ``nimrod c -r calculator.nim`` and -the Nimrod compiler will compile the ``logic.c`` file in addition to +With these two files in place, you can run ``nim c -r calculator.nim`` and +the Nim compiler will compile the ``logic.c`` file in addition to ``calculator.nim`` and link both into an executable, which outputs ``10`` when run. Another way to link the C file statically and get the same effect would be remove the line with the ``compile`` pragma and run the following typical @@ -169,7 +169,7 @@ Unix commands:: $ gcc -c logic.c $ ar rvs mylib.a logic.o - $ nimrod c --passL:mylib.a -r calculator.nim + $ nim c --passL:mylib.a -r calculator.nim Just like in this example we pass the path to the ``mylib.a`` library (and we could as well pass ``logic.o``) we could be passing switches to link any other @@ -196,50 +196,50 @@ Create a ``host.html`` file with the following content: Create a ``calculator.nim`` file with the following content (or reuse the one from the previous section): -.. code-block:: nimrod +.. code-block:: nim proc addTwoIntegers(a, b: int): int {.importc.} when isMainModule: echo addTwoIntegers(3, 7) -Compile the Nimrod code to JavaScript with ``nimrod js -o:calculator.js +Compile the Nim code to JavaScript with ``nim js -o:calculator.js calculator.nim`` and open ``host.html`` in a browser. If the browser supports javascript, you should see the value ``10``. In JavaScript the `echo proc `_ will modify the HTML DOM and append the string. Use the `dom module `_ for specific DOM querying and modification procs. -Backend code calling Nimrod +Backend code calling Nim --------------------------- -Backend code can interface with Nimrod code exposed through the `exportc +Backend code can interface with Nim code exposed through the `exportc pragma `_. The ``exportc`` pragma is the *generic* -way of making Nimrod symbols available to the backends. By default the Nimrod -compiler will mangle all the Nimrod symbols to avoid any name collision, so -the most significant thing the ``exportc`` pragma does is maintain the Nimrod +way of making Nim symbols available to the backends. By default the Nim +compiler will mangle all the Nim symbols to avoid any name collision, so +the most significant thing the ``exportc`` pragma does is maintain the Nim symbol name, or if specified, use an alternative symbol for the backend in case the symbol rules don't match. The JavaScript target doesn't have any further interfacing considerations since it also has garbage collection, but the C targets require you to -initialize Nimrod's internals, which is done calling a ``NimMain`` function. +initialize Nim's internals, which is done calling a ``NimMain`` function. Also, C code requires you to specify a forward declaration for functions or the compiler will asume certain types for the return value and parameters which will likely make your program crash at runtime. -The Nimrod compiler can generate a C interface header through the ``--header`` +The Nim compiler can generate a C interface header through the ``--header`` command line switch. The generated header will contain all the exported symbols and the ``NimMain`` proc which you need to call before any other -Nimrod code. +Nim code. -Nimrod invocation example from C +Nim invocation example from C ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create a ``fib.nim`` file with the following content: -.. code-block:: nimrod +.. code-block:: nim proc fib(a: cint): cint {.exportc.} = if a <= 2: @@ -263,34 +263,34 @@ Create a ``maths.c`` file with the following content: } Now you can run the following Unix like commands to first generate C sources -form the Nimrod code, then link them into a static binary along your main C +form the Nim code, then link them into a static binary along your main C program:: - $ nimrod c --noMain --noLinking --header:fib.h fib.nim - $ gcc -o m -Inimcache -Ipath/to/nimrod/lib nimcache/*.c maths.c + $ nim c --noMain --noLinking --header:fib.h fib.nim + $ gcc -o m -Inimcache -Ipath/to/nim/lib nimcache/*.c maths.c -The first command runs the Nimrod compiler with three special options to avoid +The first command runs the Nim compiler with three special options to avoid generating a ``main()`` function in the generated files, avoid linking the object files into a final binary, and explicitly generate a header file for C integration. All the generated files are placed into the ``nimcache`` directory. That's why the next command compiles the ``maths.c`` source plus all the ``.c`` files form ``nimcache``. In addition to this path, you also -have to tell the C compiler where to find Nimrod's ``nimbase.h`` header file. +have to tell the C compiler where to find Nim's ``nimbase.h`` header file. Instead of depending on the generation of the individual ``.c`` files you can -also ask the Nimrod compiler to generate a statically linked library:: +also ask the Nim compiler to generate a statically linked library:: - $ nimrod c --app:staticLib --noMain --header fib.nim - $ gcc -o m -Inimcache -Ipath/to/nimrod/lib libfib.nim.a maths.c + $ nim c --app:staticLib --noMain --header fib.nim + $ gcc -o m -Inimcache -Ipath/to/nim/lib libfib.nim.a maths.c -The Nimrod compiler will handle linking the source files generated in the +The Nim compiler will handle linking the source files generated in the ``nimcache`` directory into the ``libfib.nim.a`` static library, which you can then link into your C program. Note that these commands are generic and will vary for each system. For instance, on Linux systems you will likely need to use ``-ldl`` too to link in required dlopen functionality. -Nimrod invocation example from JavaScript +Nim invocation example from JavaScript ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create a ``mhost.html`` file with the following content: @@ -307,7 +307,7 @@ Create a ``mhost.html`` file with the following content: Create a ``fib.nim`` file with the following content (or reuse the one from the previous section): -.. code-block:: nimrod +.. code-block:: nim proc fib(a: cint): cint {.exportc.} = if a <= 2: @@ -315,11 +315,11 @@ from the previous section): else: result = fib(a - 1) + fib(a - 2) -Compile the Nimrod code to JavaScript with ``nimrod js -o:fib.js fib.nim`` and +Compile the Nim code to JavaScript with ``nim js -o:fib.js fib.nim`` and open ``mhost.html`` in a browser. If the browser supports javascript, you should see an alert box displaying the text ``Fib for 9 is 34``. As mentioned earlier, JavaScript doesn't require an initialisation call to ``NimMain`` or -similar function and you can call the exported Nimrod proc directly. +similar function and you can call the exported Nim proc directly. Nimcache naming logic @@ -328,17 +328,17 @@ Nimcache naming logic The `nimcache`:idx: directory is generated during compilation and will hold either temporary or final files depending on your backend target. The default name for the directory is ``nimcache`` but you can use the ``--nimcache`` -`compiler switch `_ to change it. +`compiler switch `_ to change it. Nimcache and C like targets ~~~~~~~~~~~~~~~~~~~~~~~~~~~ The C like backends will place their temporary ``.c``, ``.cpp`` or ``.m`` files in the ``nimcache`` directory. The naming of these files follows the pattern -``babelPackageName_`` + ``nimrodSource``: +``babelPackageName_`` + ``nimSource``: * Filenames for modules imported from `Babel packages - `_ will end up with + `_ will end up with ``babelPackageName_module.c``. For example, if you import the ``argument_parser`` module from the same name Babel package you will end up with a ``argument_parser_argument_parser.c`` file @@ -375,7 +375,7 @@ Nimcache and the Javascript target Unless you explicitly use the ``-o:filename.js`` switch as mentioned in the previous examples, the compiler will create a ``filename.js`` file in the -``nimcache`` directory using the name of your input nimrod file. There are no +``nimcache`` directory using the name of your input nim file. There are no other temporary files generated, the output is always a single self contained ``.js`` file. @@ -387,38 +387,38 @@ In the previous sections the ``NimMain()`` function reared its head. Since JavaScript already provides automatic memory management, you can freely pass objects between the two language without problems. In C and derivate languages you need to be careful about what you do and how you share memory. The -previous examples only dealt with simple scalar values, but passing a Nimrod -string to C, or reading back a C string in Nimrod already requires you to be +previous examples only dealt with simple scalar values, but passing a Nim +string to C, or reading back a C string in Nim already requires you to be aware of who controls what to avoid crashing. Strings and C strings --------------------- -The manual mentions that `Nimrod strings are implicitly convertible to +The manual mentions that `Nim strings are implicitly convertible to cstrings `_ which makes interaction usually -painless. Most C functions accepting a Nimrod string converted to a +painless. Most C functions accepting a Nim string converted to a ``cstring`` will likely not need to keep this string around and by the time they return the string won't be needed any more. However, for the rare cases -where a Nimrod string has to be preserved and made available to the C backend +where a Nim string has to be preserved and made available to the C backend as a ``cstring``, you will need to manually prevent the string data from being freed with `GC_ref `_ and `GC_unref `_. -A similar thing happens with C code invoking Nimrod code which returns a +A similar thing happens with C code invoking Nim code which returns a ``cstring``. Consider the following proc: -.. code-block:: nimrod +.. code-block:: nim proc gimme(): cstring {.exportc.} = result = "Hey there C code! " & $random(100) -Since Nimrod's garbage collector is not aware of the C code, once the +Since Nim's garbage collector is not aware of the C code, once the ``gimme`` proc has finished it can reclaim the memory of the ``cstring``. However, from a practical standpoint, the C code invoking the ``gimme`` -function directly will be able to use it since Nimrod's garbage collector has +function directly will be able to use it since Nim's garbage collector has not had a chance to run *yet*. This gives you enough time to make a copy for -the C side of the program, as calling any further Nimrod procs *might* trigger +the C side of the program, as calling any further Nim procs *might* trigger garbage collection making the previously returned string garbage. Or maybe you are `triggering yourself the collection `_. @@ -426,35 +426,35 @@ are `triggering yourself the collection `_. Custom data types ----------------- -Just like strings, custom data types that are to be shared between Nimrod and +Just like strings, custom data types that are to be shared between Nim and the backend will need careful consideration of who controlls who. If you want -to hand a Nimrod reference to C code, you will need to use `GC_ref +to hand a Nim reference to C code, you will need to use `GC_ref `_ to mark the reference as used, so it does not get freed. And for the C backend you will need to expose the `GC_unref `_ proc to clean up this memory when it is not required any more. Again, if you are wrapping a library which *mallocs* and *frees* data -structures, you need to expose the appropriate *free* function to Nimrod so +structures, you need to expose the appropriate *free* function to Nim so you can clean it up. And of course, once cleaned you should avoid accessing it -from Nimrod (or C for that matter). Typically C data structures have their own +from Nim (or C for that matter). Typically C data structures have their own ``malloc_structure`` and ``free_structure`` specific functions, so wrapping -these for the Nimrod side should be enough. +these for the Nim side should be enough. Thread coordination ------------------- -When the ``NimMain()`` function is called Nimrod initializes the garbage +When the ``NimMain()`` function is called Nim initializes the garbage collector to the current thread, which is usually the main thread of your -application. If your C code later spawns a different thread and calls Nimrod +application. If your C code later spawns a different thread and calls Nim code, the garbage collector will fail to work properly and you will crash. -As long as you don't use the threadvar emulation Nimrod uses native thread +As long as you don't use the threadvar emulation Nim uses native thread variables, of which you get a fresh version whenever you create a thread. You can then attach a GC to this thread via -.. code-block:: nimrod +.. code-block:: nim setStackBottom(addr(someLocal)) initGC() diff --git a/doc/basicopt.txt b/doc/basicopt.txt index fdb0e36e1..8080e380e 100644 --- a/doc/basicopt.txt +++ b/doc/basicopt.txt @@ -1,11 +1,11 @@ Usage:: - nimrod command [options] [projectfile] [arguments] + nim command [options] [projectfile] [arguments] Command: //compile, c compile project with default code generator (C) //doc generate the documentation for inputfile //doc2 generate the documentation for the whole project - //i start Nimrod in interactive mode (limited) + //i start Nim in interactive mode (limited) Arguments: arguments are passed to the program being run (if --run option is selected) diff --git a/doc/docgen.txt b/doc/docgen.txt index 30d0c6ff2..554f69838 100644 --- a/doc/docgen.txt +++ b/doc/docgen.txt @@ -1,9 +1,9 @@ =================================== - Nimrod DocGen Tools Guide + Nim DocGen Tools Guide =================================== :Author: Erik O'Leary -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -12,7 +12,7 @@ Introduction ============ This document describes the `documentation generation tools`:idx: built into -the `Nimrod compiler `_, which can generate HTML and JSON output +the `Nim compiler `_, which can generate HTML and JSON output from input .nim files and projects, as well as HTML and LaTeX from input RST (reStructuredText) files. The output documentation will include module dependencies (``import``), any top-level documentation comments (##), and @@ -25,12 +25,12 @@ Documentation Comments Any comments which are preceded by a double-hash (##), are interpreted as documentation. Comments are parsed as RST (see `reference `_), providing -Nimrod module authors the ability to easily generate richly formatted +Nim module authors the ability to easily generate richly formatted documentation with only their well-documented code. Example: -.. code-block:: nimrod +.. code-block:: nim type TPerson* = object ## This type contains a description of a person name: string @@ -45,7 +45,7 @@ This type contains a description of a person Field documentation comments can be added to fields like so: -.. code-block:: nimrod +.. code-block:: nim var numValues: int ## \ ## `numValues` stores the number of values @@ -54,15 +54,15 @@ this type would not be generated. Documentation will only be generated for *exported* types/procedures/etc. -Nimrod file input +Nim file input ----------------- The following examples will generate documentation for the below contrived -*Nimrod* module, aptly named 'sample.nim' +*Nim* module, aptly named 'sample.nim' sample.nim: -.. code-block:: nimrod +.. code-block:: nim ## This module is a sample. import strutils @@ -90,7 +90,7 @@ commands. These command take either a single .nim file, outputting a single multiple .html files and, optionally, an index file. The ``doc`` command:: - nimrod doc sample + nim doc sample Partial Output:: ... @@ -99,11 +99,11 @@ Partial Output:: Output can be viewed in full here: `docgen_sample.html `_. The next command, called ``doc2``, is very similar to the ``doc`` command, but -will be run after the compiler performs semantic checking on the input nimrod +will be run after the compiler performs semantic checking on the input nim module(s), which allows it to process macros. The ``doc2`` command:: - nimrod doc2 sample + nim doc2 sample Partial Output:: ... @@ -127,7 +127,7 @@ Note that this tool is built off of the ``doc`` command, and therefore is performed before semantic checking. The ``jsondoc`` command:: - nimrod jsondoc sample + nim jsondoc sample Output:: [ @@ -150,9 +150,9 @@ Project switch -------------- :: - nimrod doc2 --project filename.nim + nim doc2 --project filename.nim -This will recursively generate documentation of all nimrod modules imported +This will recursively generate documentation of all nim modules imported into the input module, including system modules. Be careful with this command, as it may end up sprinkling html files all over your filesystem! @@ -161,15 +161,15 @@ Index switch ------------ :: - nimrod doc2 --index:on filename.nim + nim doc2 --index:on filename.nim -This will generate an index of all the exported symbols in the input Nimrod +This will generate an index of all the exported symbols in the input Nim module, and put it into a neighboring file with the extension of ``.idx``. The index file is line oriented (newlines have to be escaped). Each line represents a tab separated record of several columns, the first two mandatory, the rest optional. See the `Index (idx) file format`_ section for details. -Once index files have been generated for one or more modules, the Nimrod +Once index files have been generated for one or more modules, the Nim compiler command ``buildIndex directory`` can be run to go over all the index files in the specified directory to generate a `theindex.html `_ file. @@ -178,7 +178,7 @@ See source switch ----------------- :: - nimrod doc2 --docSeeSrcUrl:txt filename.nim + nim doc2 --docSeeSrcUrl:txt filename.nim When you pass the ``docSeeSrcUrl`` switch to docgen, after each documented item in your source code the hyper link *See source* will appear pointing to the @@ -191,25 +191,25 @@ hyper link to your own code repository. As you will see by the comments in that file, the value ``txt`` passed on the command line will be used in the HTML template along others like ``$path`` and ``$line``. -In the case of Nimrod's own documentation, the ``txt`` value is just a commit -hash to append to a formatted URL to https://github.com/Araq/Nimrod. The +In the case of Nim's own documentation, the ``txt`` value is just a commit +hash to append to a formatted URL to https://github.com/Araq/Nim. The ``tools/nimweb.nim`` helper queries the current git commit hash during doc generation, but since you might be working on an unpublished repository, it -also allows specifying a ``githash`` value in ``web/nimrod.ini`` to force a +also allows specifying a ``githash`` value in ``web/nim.ini`` to force a specific commit in the output. Other Input Formats =================== -The *Nimrod compiler* also has support for RST (reStructuredText) files with +The *Nim compiler* also has support for RST (reStructuredText) files with the ``rst2html`` and ``rst2tex`` commands. Documents like this one are -initially written in a dialect of RST which adds support for nimrod sourcecode -highlighting with the ``.. code-block:: nimrod`` prefix. ``code-block`` also +initially written in a dialect of RST which adds support for nim sourcecode +highlighting with the ``.. code-block:: nim`` prefix. ``code-block`` also supports highlighting of C++ and some other c-like languages. Usage:: - nimrod rst2html docgen.txt + nim rst2html docgen.txt Output:: You're reading it! @@ -272,8 +272,8 @@ symbols in the `system module `_. `#TSignedInt `_ * ``var globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}`` **=>** `#globalRaiseHook `_ -* ``const NimrodVersion = "0.0.0"`` **=>** - `#NimrodVersion `_ +* ``const NimVersion = "0.0.0"`` **=>** + `#NimVersion `_ * ``proc getTotalMem(): int {.rtl, raises: [], tags: [].}`` **=>** `#getTotalMem, `_ * ``proc len[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}`` **=>** @@ -304,7 +304,7 @@ but can have up to four (additional columns are ignored). The content of these columns is: 1. Mandatory term being indexed. Terms can include quoting according to - Nimrod's rules (eg. \`^\` like in `the actors module + Nim's rules (eg. \`^\` like in `the actors module `_). 2. Base filename plus anchor hyper link (eg. ``algorithm.html#*,int,TSortOrder``). @@ -342,7 +342,7 @@ final index, and TOC entries found in ``.nim`` files are discarded. Additional resources ==================== -`Nimrod Compiler User Guide `_ +`Nim Compiler User Guide `_ `RST Quick Reference `_ diff --git a/doc/docs.txt b/doc/docs.txt index 8126da86c..ecf0cc268 100644 --- a/doc/docs.txt +++ b/doc/docs.txt @@ -1,18 +1,18 @@ The documentation consists of several documents: - | `Tutorial (part I) `_ - | The Nimrod tutorial part one deals with the basics. + | The Nim tutorial part one deals with the basics. - | `Tutorial (part II) `_ - | The Nimrod tutorial part two deals with the advanced language constructs. + | The Nim tutorial part two deals with the advanced language constructs. - | `Language Manual `_ - | The Nimrod manual is a draft that will evolve into a proper specification. + | The Nim manual is a draft that will evolve into a proper specification. - | `Library documentation `_ - | This document describes Nimrod's standard library. + | This document describes Nim's standard library. -- | `Compiler user guide `_ +- | `Compiler user guide `_ | The user guide lists command line arguments, special features of the compiler, etc. @@ -20,11 +20,11 @@ The documentation consists of several documents: | Description of some tools that come with the standard distribution. - | `GC `_ - | Additional documentation about Nimrod's GC and how to operate it in a + | Additional documentation about Nim's GC and how to operate it in a | realtime setting. - | `Source code filters `_ - | The Nimrod compiler supports source code filters as a simple yet powerful + | The Nim compiler supports source code filters as a simple yet powerful builtin templating system. - | `Term rewriting macros `_ diff --git a/doc/effects.txt b/doc/effects.txt index 8084ae17a..4ed1d09f1 100644 --- a/doc/effects.txt +++ b/doc/effects.txt @@ -1,5 +1,5 @@ ===================================================================== - Side effects in Nimrod + Side effects in Nim ===================================================================== Note: Side effects are implicit produced values! Maybe they should be @@ -13,7 +13,7 @@ difficult is the ``newString`` proc: If it is simply wrapped, it should not be evaluated at compile time! On other occasions it can and should be evaluted: -.. code-block:: nimrod +.. code-block:: nim proc toUpper(s: string): string = result = newString(len(s)) for i in 0..len(s) - 1: diff --git a/doc/endb.txt b/doc/endb.txt index e9a01b583..09b22c820 100644 --- a/doc/endb.txt +++ b/doc/endb.txt @@ -1,15 +1,15 @@ ============================================== - Embedded Nimrod Debugger (ENDB) User Guide + Embedded Nim Debugger (ENDB) User Guide ============================================== :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: -Nimrod comes with a platform independent debugger - -the Embedded Nimrod Debugger (ENDB). The debugger is +Nim comes with a platform independent debugger - +the Embedded Nim Debugger (ENDB). The debugger is *embedded* into your executable if it has been compiled with the ``--debugger:on`` command line option. This also defines the conditional symbol ``ENDB`` for you. @@ -20,7 +20,7 @@ available for the debugger. If you start your program the debugger will immediately show a prompt on the console. You can now enter a command. The next sections -deal with the possible commands. As usual in Nimrod in all commands +deal with the possible commands. As usual in Nim in all commands underscores and case do not matter. Optional components of a command are listed in brackets ``[...]`` here. @@ -105,7 +105,7 @@ The ``breakpoint`` pragma The ``breakpoint`` pragma is syntactically a statement. It can be used to mark the *following line* as a breakpoint: -.. code-block:: Nimrod +.. code-block:: Nim write("1") {.breakpoint: "before_write_2".} write("2") @@ -125,7 +125,7 @@ The ``watchpoint`` pragma The ``watchpoint`` pragma is syntactically a statement. It can be used to mark a location as a watchpoint: -.. code-block:: Nimrod +.. code-block:: Nim var a: array [0..20, int] {.watchpoint: a[3].} @@ -141,7 +141,7 @@ is turned on, so you don't need to remove it from your source code after debugging. Due to the primitive implementation watchpoints are even slower than -breakpoints: After *every* executed Nimrod code line it is checked whether the +breakpoints: After *every* executed Nim code line it is checked whether the location changed. @@ -159,7 +159,7 @@ Data Display Commands in the current stack frame, use the ``up`` or ``down`` command. Unfortunately, only inspecting variables is possible at the moment. Maybe - a future version will implement a full-blown Nimrod expression evaluator, + a future version will implement a full-blown Nim expression evaluator, but this is not easy to do and would bloat the debugger's code. Since displaying the whole data structures is often not needed and diff --git a/doc/estp.txt b/doc/estp.txt index 704bc33f2..500ee52a5 100644 --- a/doc/estp.txt +++ b/doc/estp.txt @@ -3,10 +3,10 @@ =================================================== :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| -Nimrod comes with a platform independent profiler - +Nim comes with a platform independent profiler - the Embedded Stack Trace Profiler (ESTP). The profiler is *embedded* into your executable. To activate the profiler you need to do: @@ -49,7 +49,7 @@ Example results file The results file lists stack traces ordered by significance. -The following example file has been generated by profiling the Nimrod compiler +The following example file has been generated by profiling the Nim compiler itself: It shows that in total 5.4% of the runtime has been spent in ``crcFromRope`` or its children. @@ -74,7 +74,7 @@ often remains mysterious. CommandCompileToC MainCommand HandleCmdLine - nimrod + nim Entry: 1/3391 Calls: 46/4160 = 1.1% [sum: 130; 130/4160 = 3.1%] updateCrc32 newCrcFromRopeAux @@ -90,7 +90,7 @@ often remains mysterious. CommandCompileToC MainCommand HandleCmdLine - nimrod + nim Entry: 2/3391 Calls: 41/4160 = 0.99% [sum: 171; 171/4160 = 4.1%] updateCrc32 updateCrc32 @@ -107,7 +107,7 @@ often remains mysterious. CommandCompileToC MainCommand HandleCmdLine - nimrod + nim Entry: 3/3391 Calls: 41/4160 = 0.99% [sum: 212; 212/4160 = 5.1%] crcFromFile writeRopeIfNotEqual @@ -121,7 +121,7 @@ often remains mysterious. CommandCompileToC MainCommand HandleCmdLine - nimrod + nim Entry: 4/3391 Calls: 41/4160 = 0.99% [sum: 253; 253/4160 = 6.1%] updateCrc32 crcFromFile @@ -136,7 +136,7 @@ often remains mysterious. CommandCompileToC MainCommand HandleCmdLine - nimrod + nim Entry: 5/3391 Calls: 32/4160 = 0.77% [sum: 285; 285/4160 = 6.9%] pop newCrcFromRopeAux @@ -152,7 +152,7 @@ often remains mysterious. CommandCompileToC MainCommand HandleCmdLine - nimrod + nim Entry: 6/3391 Calls: 17/4160 = 0.41% [sum: 302; 302/4160 = 7.3%] doOperation forAllChildrenAux @@ -171,7 +171,7 @@ often remains mysterious. MainCommand HandleCmdLine ... - nimrod + nim Entry: 7/3391 Calls: 14/4160 = 0.34% [sum: 316; 316/4160 = 7.6%] Contains isAccessible diff --git a/doc/filelist.txt b/doc/filelist.txt index f71547f86..beff8f6c8 100644 --- a/doc/filelist.txt +++ b/doc/filelist.txt @@ -1,10 +1,10 @@ -Short description of Nimrod's modules +Short description of Nim's modules ------------------------------------- ============== ========================================================== Module Description ============== ========================================================== -nimrod main module: parses the command line and calls +nim main module: parses the command line and calls ``main.MainCommand`` main implements the top-level command dispatching nimconf implements the config file reader @@ -12,8 +12,8 @@ syntaxes dispatcher for the different parsers and filters filter_tmpl standard template filter (``#! stdtempl``) lexbase buffer handling of the lexical analyser lexer lexical analyser -parser Nimrod's parser -renderer Nimrod code renderer (AST back to its textual form) +parser Nim's parser +renderer Nim code renderer (AST back to its textual form) options contains global and local compiler options ast type definitions of the abstract syntax tree (AST) and node constructors @@ -37,7 +37,7 @@ pragmas semantic checking of pragmas idents implements a general mapping from identifiers to an internal representation (``PIdent``) that is used so that a simple - id-comparison suffices to say whether two Nimrod identifiers + id-comparison suffices to say whether two Nim identifiers are equivalent ropes implements long strings represented as trees for lazy evaluation; used mainly by the code generators diff --git a/doc/filters.txt b/doc/filters.txt index 961a0ea49..22df63490 100644 --- a/doc/filters.txt +++ b/doc/filters.txt @@ -40,7 +40,7 @@ Filters can be combined with the ``|`` pipe operator:: Available filters ================= -**Hint:** With ``--verbosity:2`` (or higher) Nimrod lists the processed code +**Hint:** With ``--verbosity:2`` (or higher) Nim lists the processed code after each filter application. Replace filter @@ -79,19 +79,19 @@ Parameters and their defaults: StdTmpl filter -------------- -The stdtmpl filter provides a simple templating engine for Nimrod. The +The stdtmpl filter provides a simple templating engine for Nim. The filter uses a line based parser: Lines prefixed with a *meta character* -(default: ``#``) contain Nimrod code, other lines are verbatim. Because +(default: ``#``) contain Nim code, other lines are verbatim. Because indentation-based parsing is not suited for a templating engine, control flow statements need ``end X`` delimiters. Parameters and their defaults: ``metaChar: char = '#'`` - prefix for a line that contains Nimrod code + prefix for a line that contains Nim code ``subsChar: char = '$'`` - prefix for a Nimrod expression within a template line + prefix for a Nim expression within a template line ``conc: string = " & "`` the operation for concatenation @@ -130,7 +130,7 @@ Example:: The filter transforms this into: -.. code-block:: nimrod +.. code-block:: nim proc generateHTMLPage(title, currentTab, content: string, tabs: openArray[string]): string = result = "" @@ -158,7 +158,7 @@ The filter transforms this into: Each line that does not start with the meta character (ignoring leading whitespace) is converted to a string literal that is added to ``result``. -The substitution character introduces a Nimrod expression *e* within the +The substitution character introduces a Nim expression *e* within the string literal. *e* is converted to a string with the *toString* operation which defaults to ``$``. For strong type checking, set ``toString`` to the empty string. *e* must match this PEG pattern:: diff --git a/doc/gc.txt b/doc/gc.txt index 18fb03b6d..fdb1d1b6c 100644 --- a/doc/gc.txt +++ b/doc/gc.txt @@ -1,9 +1,9 @@ ========================== -Nimrod's Garbage Collector +Nim's Garbage Collector ========================== :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| "The road to hell is paved with good intentions." @@ -37,7 +37,7 @@ it is necessary to help this analysis with the ``acyclic`` pragma (see You can also use the ``acyclic`` pragma for data that is cyclic in reality and then break up the cycles explicitly with ``GC_addCycleRoot``. This can be a -very valuable optimization; the Nimrod compiler itself relies on this +very valuable optimization; the Nim compiler itself relies on this optimization trick to improve performance. Note that ``GC_addCycleRoot`` is a quick operation; the root is only registered for the next run of the cycle collector. @@ -49,7 +49,7 @@ Realtime support To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be defined. With this switch the GC supports the following operations: -.. code-block:: nimrod +.. code-block:: nim proc GC_setMaxPause*(MaxPauseInUs: int) proc GC_step*(us: int, strongAdvice = false) @@ -111,7 +111,7 @@ highly specialized environments or for older hardware. Keeping track of memory ----------------------- -If you need to pass around memory allocated by Nimrod to C, you can use the +If you need to pass around memory allocated by Nim to C, you can use the procs ``GC_ref`` and ``GC_unref`` to mark objects as referenced to avoid them being freed by the GC. Other useful procs from `system `_ you can use to keep track of memory are: diff --git a/doc/idetools.txt b/doc/idetools.txt index 97e110b1d..5429d0c07 100644 --- a/doc/idetools.txt +++ b/doc/idetools.txt @@ -1,9 +1,9 @@ ================================ - Nimrod IDE Integration Guide + Nim IDE Integration Guide ================================ :Author: Britney Spears -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -13,17 +13,17 @@ "yes, I'm the creator" -- Araq, 2013-07-26 19:28:32.

-Nimrod differs from many other compilers in that it is really fast, +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 -``idetools`` command of `the compiler `_, any IDE +``idetools`` command of `the compiler `_, 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 idetools support you can look at the test files found in the `Test suite`_ or `various editor -integrations `_ +integrations `_ already available. @@ -37,11 +37,11 @@ All of the available idetools commands require you to specify a query location through the ``--track`` or ``--trackDirty`` switches. The general idetools invokations are:: - nimrod idetools --track:FILE,LINE,COL proj.nim + nim idetools --track:FILE,LINE,COL proj.nim Or:: - nimrod idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL proj.nim + nim idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL proj.nim ``proj.nim`` This is the main *project* filename. Most of the time you will @@ -97,7 +97,7 @@ 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 Nimrod is implemented in Nimrod, one of the nice things of +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 @@ -118,7 +118,7 @@ includes/imports) and when the user starts typing something a completion box with different options appears. However such features are not context sensitive and work simply on -string matching, which can be problematic in Nimrod especially due +string matching, which can be problematic in Nim especially due to the case insensitiveness of the language (plus underscores as separators!). @@ -179,16 +179,16 @@ in the millisecond range, thus being responsive enough for IDEs. If you want to start the server using stdin/stdout as communication you need to type:: - nimrod serve --server.type:stdin proj.nim + nim serve --server.type:stdin proj.nim If you want to start the server using tcp and a port, you need to type:: - nimrod serve --server.type:tcp --server.port:6000 \ + nim serve --server.type:tcp --server.port:6000 \ --server.address:hostname proj.nim In both cases the server will start up and await further commands. The syntax of the commands you can now send to the server is -practically the same as running the nimrod compiler on the commandline, +practically the same as running the nim compiler on the commandline, you only need to remove the name of the compiler since you are already talking to it. The server will answer with as many lines of text it thinks necessary plus an empty line to indicate the end @@ -242,7 +242,7 @@ skConst | **Fourth column**: the type of the const value. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim const SOME_SEQUENCE = @[1, 2] --> col 2: $MODULE.SOME_SEQUENCE col 3: seq[int] @@ -256,7 +256,7 @@ skEnumField | **Fourth column**: enum type grouping other enum fields. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim Open(filename, fmWrite) --> col 2: system.TFileMode.fmWrite col 3: TFileMode @@ -270,7 +270,7 @@ skForVar | **Fourth column**: type of the var. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim proc looper(filename = "tests.nim") = for letter in filename: echo letter @@ -291,7 +291,7 @@ posterior instances of the iterator. | **Fourth column**: signature of the iterator including return type. | **Docstring**: docstring if available. -.. code-block:: nimrod +.. code-block:: nim let text = "some text" letters = toSeq(runes(text)) @@ -307,7 +307,7 @@ skLabel | **Fourth column**: always the empty string. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim proc test(text: string) = var found = -1 block loops: @@ -323,7 +323,7 @@ skLet | **Fourth column**: the type of the let variable. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim let text = "some text" --> col 2: $MODULE.text @@ -343,7 +343,7 @@ posterior instances of the macro. | **Fourth column**: signature of the macro including return type. | **Docstring**: docstring if available. -.. code-block:: nimrod +.. code-block:: nim proc testMacro() = expect(EArithmetic): --> col 2: idetools_api.expect @@ -379,7 +379,7 @@ This may change in the future. | **Fourth column**: signature of the method including return type. | **Docstring**: docstring if available. -.. code-block:: nimrod +.. code-block:: nim method eval(e: PExpr): int = quit "to override!" method eval(e: PLiteral): int = e.x method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b) @@ -396,7 +396,7 @@ skParam | **Fourth column**: the type of the parameter. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim proc reader(filename = "tests.nim") = let text = readFile(filename) --> col 2: $MODULE.reader.filename @@ -420,7 +420,7 @@ returned by idetools returns also the pragmas for the proc. | **Fourth column**: signature of the proc including return type. | **Docstring**: docstring if available. -.. code-block:: nimrod +.. code-block:: nim Open(filename, fmWrite) --> col 2: system.Open col 3: proc (var TFile, string, TFileMode, int): bool @@ -438,7 +438,7 @@ skResult | **Fourth column**: the type of the result. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim proc getRandomValue() : int = return 4 --> col 2: $MODULE.getRandomValue.result @@ -458,7 +458,7 @@ posterior instances of the template. | **Fourth column**: signature of the template including return type. | **Docstring**: docstring if available. -.. code-block:: nimrod +.. code-block:: nim let text = "some text" letters = toSeq(runes(text)) @@ -469,7 +469,7 @@ posterior instances of the template. Example: - .. code-block:: nimrod + .. code-block:: nim let numeric = @[1, 2, 3, 4, 5, 6, 7, 8, 9] odd_numbers = toSeq(filter(numeric) do (x: int) -> bool: @@ -485,7 +485,7 @@ skType | **Fourth column**: the type. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim proc writeTempFile() = var output: TFile --> col 2: system.TFile @@ -500,7 +500,7 @@ skVar | **Fourth column**: the type of the var. | **Docstring**: always the empty string. -.. code-block:: nimrod +.. code-block:: nim proc writeTempFile() = var output: TFile output.open("/tmp/somefile", fmWrite) @@ -527,8 +527,8 @@ At the moment idetools support is still in development so the test suite is not integrated with the main test suite and you have to run it manually. First you have to compile the tester:: - $ cd my/nimrod/checkout/tests - $ nimrod c testament/caasdriver.nim + $ cd my/nim/checkout/tests + $ nim c testament/caasdriver.nim Running the ``caasdriver`` without parameters will attempt to process all the test cases in all three operation modes. If a test succeeds @@ -540,7 +540,7 @@ parameter ``verbose`` to force all output even on successfull tests. The normal operation mode is called ``ProcRun`` and it involves starting a process for each command or query, similar to running -manually the Nimrod compiler from the commandline. The ``CaasRun`` +manually the Nim compiler from the commandline. The ``CaasRun`` mode starts a server process to answer all queries. The ``SymbolProcRun`` mode is used by compiler developers. This means that running all tests involves processing all ``*.txt`` files three times, which diff --git a/doc/intern.txt b/doc/intern.txt index 1dcf27774..6cd1987aa 100644 --- a/doc/intern.txt +++ b/doc/intern.txt @@ -1,10 +1,10 @@ ========================================= - Internals of the Nimrod Compiler + Internals of the Nim Compiler ========================================= :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -14,23 +14,23 @@ Directory structure =================== -The Nimrod project's directory structure is: +The Nim project's directory structure is: ============ ============================================== Path Purpose ============ ============================================== ``bin`` generated binary files ``build`` generated C code for the installation -``compiler`` the Nimrod compiler itself; note that this +``compiler`` the Nim compiler itself; note that this code has been translated from a bootstrapping version written in Pascal, so the code is **not** - a poster child of good Nimrod code -``config`` configuration files for Nimrod + a poster child of good Nim code +``config`` configuration files for Nim ``dist`` additional packages for the distribution ``doc`` the documentation; it is a bunch of reStructuredText files -``lib`` the Nimrod library -``web`` website of Nimrod; generated by ``nimweb`` +``lib`` the Nim library +``web`` website of Nim; generated by ``nimweb`` from the ``*.txt`` and ``*.tmpl`` files ============ ============================================== @@ -38,26 +38,26 @@ Path Purpose Bootstrapping the compiler ========================== -As of version 0.8.5 the compiler is maintained in Nimrod. (The first versions +As of version 0.8.5 the compiler is maintained in Nim. (The first versions have been implemented in Object Pascal.) The Python-based build system has -been rewritten in Nimrod too. +been rewritten in Nim too. Compiling the compiler is a simple matter of running:: - nimrod c koch.nim + nim c koch.nim ./koch boot For a release version use:: - nimrod c koch.nim + nim c koch.nim ./koch boot -d:release And for a debug version compatible with GDB:: - nimrod c koch.nim + nim c koch.nim ./koch boot --debuginfo --linedir:on -The ``koch`` program is Nimrod's maintenance script. It is a replacement for +The ``koch`` program is Nim's maintenance script. It is a replacement for make and shell scripting with the advantage that it is much more portable. More information about its options can be found in the `koch `_ documentation. @@ -80,13 +80,13 @@ See also the `API naming design `_ document. Porting to new platforms ======================== -Porting Nimrod to a new architecture is pretty easy, since C is the most -portable programming language (within certain limits) and Nimrod generates +Porting Nim to a new architecture is pretty easy, since C is the most +portable programming language (within certain limits) and Nim generates C code, porting the code generator is not necessary. POSIX-compliant systems on conventional hardware are usually pretty easy to port: Add the platform to ``platform`` (if it is not already listed there), -check that the OS, System modules work and recompile Nimrod. +check that the OS, System modules work and recompile Nim. The only case where things aren't as easy is when the garbage collector needs some assembler tweaking to work. The standard @@ -98,7 +98,7 @@ replace this generic code by some assembler code. Runtime type information ======================== -*Runtime type information* (RTTI) is needed for several aspects of the Nimrod +*Runtime type information* (RTTI) is needed for several aspects of the Nim programming language: Garbage collection @@ -108,7 +108,7 @@ Garbage collection Complex assignments Sequences and strings are implemented as - pointers to resizeable buffers, but Nimrod requires copying for + pointers to resizeable buffers, but Nim requires copying for assignments. Apart from RTTI the compiler could generate copy procedures for any type that needs one. However, this would make the code bigger and the RTTI is likely already there for the GC. @@ -121,12 +121,12 @@ Look at the file ``lib/system/hti.nim`` for more information. The compiler's architecture =========================== -Nimrod uses the classic compiler architecture: A lexer/scanner feds tokens to a +Nim uses the classic compiler architecture: A lexer/scanner feds tokens to a parser. The parser builds a syntax tree that is used by the code generator. This syntax tree is the interface between the parser and the code generator. It is essential to understand most of the compiler's code. -In order to compile Nimrod correctly, type-checking has to be separated from +In order to compile Nim correctly, type-checking has to be separated from parsing. Otherwise generics cannot work. .. include:: filelist.txt @@ -172,7 +172,7 @@ Frontend issues Methods and type converters ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Nimrod contains language features that are *global*. The best example for that +Nim contains language features that are *global*. The best example for that are multi methods: Introducing a new method with the same name and some compatible object parameter means that the method's dispatcher needs to take the new method into account. So the dispatching logic is only completely known @@ -181,12 +181,12 @@ after the whole program has been translated! Other features that are *implicitly* triggered cause problems for modularity too. Type converters fall into this category: -.. code-block:: nimrod +.. code-block:: nim # module A converter toBool(x: int): bool = result = x != 0 -.. code-block:: nimrod +.. code-block:: nim # module B import A @@ -254,7 +254,7 @@ turned on". -Debugging Nimrod's memory management +Debugging Nim's memory management ==================================== The following paragraphs are mostly a reminder for myself. Things to keep @@ -262,7 +262,7 @@ in mind: * Segmentation faults can have multiple reasons: One that is frequently forgotten is that *stack overflow* can trigger one! -* If an assertion in Nimrod's memory manager or GC fails, the stack trace +* If an assertion in Nim's memory manager or GC fails, the stack trace keeps allocating memory! Thus a stack overflow may happen, hiding the real issue. * What seem to be C code generation problems is often a bug resulting from @@ -300,7 +300,7 @@ set of pointers - this is called a ``TCellSet`` in the source code. Inserting, deleting and searching are done in constant time. However, modifying a ``TCellSet`` during traversation leads to undefined behaviour. -.. code-block:: Nimrod +.. code-block:: Nim type TCellSet # hidden @@ -340,11 +340,11 @@ Complete traversal is done in this way:: Further complications --------------------- -In Nimrod the compiler cannot always know if a reference +In Nim the compiler cannot always know if a reference is stored on the stack or not. This is caused by var parameters. Consider this example: -.. code-block:: Nimrod +.. code-block:: Nim proc setRef(r: var ref TNode) = new(r) @@ -380,7 +380,7 @@ Code generation for closures is implemented by `lambda lifting`:idx:. Design ------ -A ``closure`` proc var can call ordinary procs of the default Nimrod calling +A ``closure`` proc var can call ordinary procs of the default Nim calling convention. But not the other way round! A closure is implemented as a ``tuple[prc, env]``. ``env`` can be nil implying a call without a closure. This means that a call through a closure generates an ``if`` but the @@ -393,7 +393,7 @@ Tests with GCC on Amd64 showed that it's really beneficical if the Proper thunk generation is harder because the proc that is to wrap could stem from a complex expression: -.. code-block:: nimrod +.. code-block:: nim receivesClosure(returnsDefaultCC[i]) A thunk would need to call 'returnsDefaultCC[i]' somehow and that would require @@ -405,7 +405,7 @@ to pass a proc pointer around via a generic ``ref`` type. Example code: -.. code-block:: nimrod +.. code-block:: nim proc add(x: int): proc (y: int): int {.closure.} = return proc (y: int): int = return x + y @@ -415,7 +415,7 @@ Example code: This should produce roughly this code: -.. code-block:: nimrod +.. code-block:: nim type PEnv = ref object x: int # data @@ -436,7 +436,7 @@ This should produce roughly this code: Beware of nesting: -.. code-block:: nimrod +.. code-block:: nim proc add(x: int): proc (y: int): proc (z: int): int {.closure.} {.closure.} = return lamba (y: int): proc (z: int): int {.closure.} = return lambda (z: int): int = @@ -447,7 +447,7 @@ Beware of nesting: This should produce roughly this code: -.. code-block:: nimrod +.. code-block:: nim type PEnvX = ref object x: int # data @@ -492,7 +492,7 @@ environments. This is however not always possible. Accumulator ----------- -.. code-block:: nimrod +.. code-block:: nim proc GetAccumulator(start: int): proc (): int {.closure} = var i = start return lambda: int = diff --git a/doc/koch.txt b/doc/koch.txt index 032151808..a3b7f0df8 100644 --- a/doc/koch.txt +++ b/doc/koch.txt @@ -1,8 +1,8 @@ =============================== - Nimrod maintenance script + Nim maintenance script =============================== -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -15,10 +15,10 @@ Introduction ============ -The `koch`:idx: program is Nimrod's maintenance script. It is a replacement +The `koch`:idx: program is Nim's maintenance script. It is a replacement for make and shell scripting with the advantage that it is much more portable. The word *koch* means *cook* in German. ``koch`` is used mainly to build the -Nimrod compiler, but it can also be used for other tasks. This document +Nim compiler, but it can also be used for other tasks. This document describes the supported commands and their options. @@ -40,21 +40,21 @@ options: option is not supported on Windows. -d:useGnuReadline Includes the `rdstdin module `_ for `interactive - mode `_ (aka ``nimrod i``). + mode `_ (aka ``nim i``). This is not needed on Windows. On other platforms this may incorporate the GNU readline library. -d:nativeStacktrace Use native stack traces (only for Mac OS X or Linux). -d:noCaas - Builds Nimrod without compiler as a service (CAAS) support. CAAS - support is required for functionality like Nimrod's `idetool + Builds Nim without compiler as a service (CAAS) support. CAAS + support is required for functionality like Nim's `idetool `_ command used to integrate the compiler with - `external IDEs `_. + `external IDEs `_. -d:avoidTimeMachine Only for Mac OS X, activating this switch will force excluding the generated ``nimcache`` directories from Time Machine backups. By default ``nimcache`` directories will be included in backups, - and just for the Nimrod compiler itself it means backing up 20MB + and just for the Nim compiler itself it means backing up 20MB of generated files each time you update the compiler. Using this option will make the compiler invoke the `tmutil `_ @@ -66,18 +66,18 @@ options: $ find . -type d -name nimcache -exec tmutil isexcluded \{\} \; -d:useFFI - Nimrod code can use the `foreign function interface (FFI) + Nim code can use the `foreign function interface (FFI) `_ at runtime, but macros - are limited to pure Nimrod code at compilation time. Enabling - this switch will allow macros to execute non-nimrod code at + are limited to pure Nim code at compilation time. Enabling + this switch will allow macros to execute non-nim code at compilation time (eg. open a file and write to it). --gc:refc|v2|markAndSweep|boehm|none Selects which garbage collection strategy to use for the compiler - and generated code. See the `Nimrod's Garbage Collector `_ + and generated code. See the `Nim's Garbage Collector `_ documentation for more information. -After compilation is finished you will hopefully end up with the nimrod -compiler in the ``bin`` directory. You can add Nimrod's ``bin`` directory to +After compilation is finished you will hopefully end up with the nim +compiler in the ``bin`` directory. You can add Nim's ``bin`` directory to your ``$PATH`` or use the `install command`_ to place it where it will be found. @@ -101,7 +101,7 @@ The `inno`:idx: command builds the `Inno Setup installer for Windows install command --------------- -The `install`:idx: command installs Nimrod to the specified directory, which +The `install`:idx: command installs Nim to the specified directory, which is required as a parameter. For example, on Unix platforms you could run:: $ ./koch install /usr/local/bin @@ -109,8 +109,8 @@ is required as a parameter. For example, on Unix platforms you could run:: temp command ------------ -The temp command builds the Nimrod compiler but with a different final name -(``nimrod_temp``), so it doesn't overwrite your normal compiler. You can use +The temp command builds the Nim compiler but with a different final name +(``nim_temp``), so it doesn't overwrite your normal compiler. You can use this command to test different options, the same you would issue for the `boot command`_. @@ -119,14 +119,14 @@ test command The `test`:idx: command can also be invoked with the alias ``tests``. This command will compile and run ``tests/testament/tester.nim``, which is the main -driver of Nimrod's test suite. You can pass options to the ``test`` command, +driver of Nim's test suite. You can pass options to the ``test`` command, they will be forwarded to the tester. See its source code for available options. update command -------------- -The `update`:idx: command updates nimrod to the latest version from github. +The `update`:idx: command updates nim to the latest version from github. For this command to work you need to have compiled ``koch`` itself with the ``-d:withUpdate`` switch. @@ -136,7 +136,7 @@ web command The `web`:idx: command converts the documentation in the ``doc`` directory from rst to HTML. It also repeats the same operation but places the result in the ``web/upload`` which can be used to update the website at -http://nimrod-lang.org. +http://nim-lang.org. zip command ----------- diff --git a/doc/nimgrep.txt b/doc/nimgrep.txt index 67aaa427e..e2f7b228f 100644 --- a/doc/nimgrep.txt +++ b/doc/nimgrep.txt @@ -10,7 +10,7 @@ Nimgrep is a command line tool for search&replace tasks. It can search for regex or peg patterns and can search whole directories at once. User confirmation for every single replace operation can be requested. -Nimgrep has particularly good support for Nimrod's +Nimgrep has particularly good support for Nim's eccentric *style insensitivity*. Apart from that it is a generic text manipulation tool. @@ -20,7 +20,7 @@ Installation Compile nimgrep with the command:: - nimrod c -d:release tools/nimgrep.nim + nim c -d:release tools/nimgrep.nim And copy the executable somewhere in your ``$PATH``. diff --git a/doc/niminst.txt b/doc/niminst.txt index 8d95d01c9..d743c5187 100644 --- a/doc/niminst.txt +++ b/doc/niminst.txt @@ -3,14 +3,14 @@ ========================= :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: Introduction ============ -niminst is a tool to generate an installer for a Nimrod program. Currently +niminst is a tool to generate an installer for a Nim program. Currently it can create an installer for Windows via `Inno Setup `_ as well as installation/deinstallation scripts for UNIX. Later versions will support @@ -24,7 +24,7 @@ systems. Configuration file ================== -niminst uses the Nimrod `parsecfg `_ module to parse the +niminst uses the Nim `parsecfg `_ module to parse the configuration file. Here's an example of how the syntax looks like: .. include:: doc/mytest.cfg @@ -187,9 +187,9 @@ Key description Real world example ================== -The installers for the Nimrod compiler itself are generated by niminst. Have a +The installers for the Nim compiler itself are generated by niminst. Have a look at its configuration file: -.. include:: compiler/nimrod.ini +.. include:: compiler/nim.ini :literal: diff --git a/doc/overview.txt b/doc/overview.txt index 242039086..5b41752ae 100644 --- a/doc/overview.txt +++ b/doc/overview.txt @@ -1,9 +1,9 @@ ============================= -Nimrod Documentation Overview +Nim Documentation Overview ============================= :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. include:: ../doc/docs.txt diff --git a/doc/pegdocs.txt b/doc/pegdocs.txt index e2f3cdf4b..d22d81a5a 100644 --- a/doc/pegdocs.txt +++ b/doc/pegdocs.txt @@ -171,7 +171,7 @@ The PEG parser implements this grammar (written in PEG syntax):: expression, identifiers are not interpreted as non-terminals, but are interpreted as verbatim string: -.. code-block:: nimrod +.. code-block:: nim abc =~ peg"abc" # is true So it is not necessary to write ``peg" 'abc' "`` in the above example. @@ -182,17 +182,17 @@ Examples Check if `s` matches Nim's "while" keyword: -.. code-block:: nimrod +.. code-block:: nim s =~ peg" y'while'" Exchange (key, val)-pairs: -.. code-block:: nimrod +.. code-block:: nim "key: val; key2: val2".replace(peg"{\ident} \s* ':' \s* {\ident}", "$2: $1") Determine the ``#include``'ed files of a C file: -.. code-block:: nimrod +.. code-block:: nim for line in lines("myfile.c"): if line =~ peg"""s <- ws '#include' ws '"' {[^"]+} '"' ws comment <- '/*' @ '*/' / '//' .* diff --git a/doc/readme.txt b/doc/readme.txt index 7f509bd39..e5d9e2c27 100644 --- a/doc/readme.txt +++ b/doc/readme.txt @@ -1,7 +1,7 @@ ============================ -Nimrod's documenation system +Nim's documenation system ============================ -This folder contains Nimrod's documentation. The documentation +This folder contains Nim's documentation. The documentation is written in a format called *reStructuredText*, a markup language that reads like ASCII and can be converted to HTML automatically! diff --git a/doc/regexprs.txt b/doc/regexprs.txt index 930352948..d912c623e 100644 --- a/doc/regexprs.txt +++ b/doc/regexprs.txt @@ -44,9 +44,9 @@ As the regular expressions supported by this module are enormous, the reader is referred to http://perldoc.perl.org/perlre.html for the full documentation of Perl's regular expressions. -Because the backslash ``\`` is a meta character both in the Nimrod +Because the backslash ``\`` is a meta character both in the Nim programming language and in regular expressions, it is strongly -recommended that one uses the *raw* strings of Nimrod, so that +recommended that one uses the *raw* strings of Nim, so that backslashes are interpreted by the regular expression engine:: r"\S" # matches any character that is not whitespace diff --git a/doc/rst.txt b/doc/rst.txt index 4199598d1..1e858d617 100644 --- a/doc/rst.txt +++ b/doc/rst.txt @@ -1,9 +1,9 @@ =========================================================================== - Nimrod's implementation of |rst| + Nim's implementation of |rst| =========================================================================== :Author: Andreas Rumpf -:Version: |nimrodversion| +:Version: |nimversion| .. contents:: @@ -11,15 +11,15 @@ Introduction ============ This document describes the subset of `Docutils`_' `reStructuredText`_ as it -has been implemented in the Nimrod compiler for generating documentation. +has been implemented in the Nim compiler for generating documentation. Elements of |rst| that are not listed here have not been implemented. -Unfortunately, the specification of |rst| is quite vague, so Nimrod is not as +Unfortunately, the specification of |rst| is quite vague, so Nim is not as compatible to the original implementation as one would like. -Even though Nimrod's |rst| parser does not parse all constructs, it is pretty +Even though Nim's |rst| parser does not parse all constructs, it is pretty usable. The missing features can easily be circumvented. An indication of this -fact is that Nimrod's *whole* documentation itself (including this document) is -processed by Nimrod's |rst| parser. (Which is an order of magnitude faster than +fact is that Nim's *whole* documentation itself (including this document) is +processed by Nim's |rst| parser. (Which is an order of magnitude faster than Docutils' parser.) @@ -65,19 +65,19 @@ Definition lists Save this code to the file "greeting.nim". Now compile and run it: - ``nimrod run greeting.nim`` + ``nim run greeting.nim`` -As you see, with the ``run`` command Nimrod executes the file automatically +As you see, with the ``run`` command Nim executes the file automatically after compilation. You can even give your program command line arguments by appending them after the filename that is to be compiled and run: - ``nimrod run greeting.nim arg1 arg2`` + ``nim run greeting.nim arg1 arg2`` Tables ====== -Nimrod only implements simple tables of the form:: +Nim only implements simple tables of the form:: ================== =============== =================== header 1 header 2 header n diff --git a/doc/sets_fragment.txt b/doc/sets_fragment.txt index fba355269..32dbac1c2 100644 --- a/doc/sets_fragment.txt +++ b/doc/sets_fragment.txt @@ -6,7 +6,7 @@ Sets can be constructed via the set constructor: ``{}`` is the empty set. The empty set is type compatible with any concrete set type. The constructor can also be used to include elements (and ranges of elements): -.. code-block:: nimrod +.. code-block:: nim type TCharSet = set[char] var diff --git a/doc/spawn.txt b/doc/spawn.txt index c5c96ecf8..b2496285f 100644 --- a/doc/spawn.txt +++ b/doc/spawn.txt @@ -2,7 +2,7 @@ Parallel & Spawn ========================================================== -Nimrod has two flavors of parallelism: +Nim has two flavors of parallelism: 1) `Structured`:idx parallelism via the ``parallel`` statement. 2) `Unstructured`:idx: parallelism via the standalone ``spawn`` statement. @@ -24,7 +24,7 @@ Parallel statement Example: -.. code-block:: nimrod +.. code-block:: nim # Compute PI in an inefficient way import strutils, math, threadpool @@ -42,7 +42,7 @@ Example: The parallel statement is the preferred mechanism to introduce parallelism -in a Nimrod program. A subset of the Nimrod language is valid within a +in a Nim program. A subset of the Nim language is valid within a ``parallel`` section. This subset is checked to be free of data races at compile time. A sophisticated `disjoint checker`:idx: ensures that no data races are possible even though shared memory is extensively supported! @@ -77,7 +77,7 @@ the passed expression on the thread pool and returns a `data flow variable`:idx: **blocking**. However, one can use ``awaitAny`` to wait on multiple flow variables at the same time: -.. code-block:: nimrod +.. code-block:: nim import threadpool, ... # wait until 2 out of 3 servers received the update: diff --git a/doc/subexes.txt b/doc/subexes.txt index 3b688fd0a..7cad183b9 100644 --- a/doc/subexes.txt +++ b/doc/subexes.txt @@ -45,7 +45,7 @@ Notation meaning Examples ======== -.. code-block:: nimrod +.. code-block:: nim subex"$1($', '{2..})" % ["f", "a", "b", "c"] == "f(a, b, c)" diff --git a/doc/tools.txt b/doc/tools.txt index 0127bc4a8..7a91ca6d0 100644 --- a/doc/tools.txt +++ b/doc/tools.txt @@ -1,20 +1,20 @@ =========================== -Tools available with Nimrod +Tools available with Nim =========================== The standard distribution ships with the following tools: -- | `Nimrod Installation Generator `_ - | How to generate a nice installer for your Nimrod program. +- | `Nim Installation Generator `_ + | How to generate a nice installer for your Nim program. - | `C2nim `_ - | C to Nimrod source converter. Translates C header files to Nimrod. + | C to Nim source converter. Translates C header files to Nim. - | `nimgrep `_ - | Nimrod search and replace utility. + | Nim search and replace utility. - | `endb `_ - | Nimrod's slow platform independent embedded debugger. + | Nim's slow platform independent embedded debugger. - | `estp `_ - | Nimrod's slow platform independent embedded stack trace profiler. + | Nim's slow platform independent embedded stack trace profiler. diff --git a/doc/tut2.txt b/doc/tut2.txt index 8cd977a96..0c54fa9a1 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -858,7 +858,7 @@ The good news is not much has changed! First, we need to change the handling of the input parameter. In the dynamic version the ``readCfgAtRuntime`` proc receives a string parameter. However, in the macro version it is also declared as string, but this is the *outside* interface of the macro. When the macro is -run, it actually gets a ``PNimrodNode`` object instead of a string, and we have +run, it actually gets a ``PNimNode`` object instead of a string, and we have to call the ``strVal`` proc from the `macros module `_ to obtain the string being passed in to the macro. diff --git a/readme.md b/readme.md index e8c081d4e..83d6ef748 100644 --- a/readme.md +++ b/readme.md @@ -1,15 +1,15 @@ -# Nimrod Compiler -This repo contains the Nimrod compiler, Nimrod's stdlib, tools and +# Nim Compiler +This repo contains the Nim compiler, Nim's stdlib, tools and documentation. ## Compiling -Compiling the Nimrod compiler is quite straightforward. Because -the Nimrod compiler itself is written in the Nimrod programming language +Compiling the Nim compiler is quite straightforward. Because +the Nim compiler itself is written in the Nim programming language the C source of an older version of the compiler are needed to bootstrap the -latest version. The C sources are available in a separate repo [here](http://github.com/nimrod-code/csources). +latest version. The C sources are available in a separate repo [here](http://github.com/nim-code/csources). Pre-compiled snapshots of the compiler are also available on -[Nimbuild](http://build.nimrod-lang.org/). Your platform however may not +[Nimbuild](http://build.nim-lang.org/). Your platform however may not currently be built for. The compiler currently supports the following platform and architecture @@ -30,16 +30,16 @@ To build from source you will need: If you are on a fairly modern *nix system, the following steps should work: ``` -$ git clone git://github.com/Araq/Nimrod.git -$ cd Nimrod -$ git clone --depth 1 git://github.com/nimrod-code/csources +$ git clone git://github.com/Araq/Nim.git +$ cd Nim +$ git clone --depth 1 git://github.com/nim-code/csources $ cd csources && sh build.sh $ cd .. -$ bin/nimrod c koch +$ bin/nim c koch $ ./koch boot -d:release ``` -``koch install [dir]`` may then be used to install Nimrod, or you can simply +``koch install [dir]`` may then be used to install Nim, or you can simply add it to your PATH. More ``koch`` related options are documented in [doc/koch.txt](doc/koch.txt). @@ -48,16 +48,16 @@ The above steps can be performed on Windows in a similar fashion, the instead of ``build.sh``. ## Getting help -A [forum](http://forum.nimrod-lang.org/) is available if you have any +A [forum](http://forum.nim-lang.org/) is available if you have any questions, and you can also get help in the IRC channel on -[Freenode](irc://irc.freenode.net/nimrod) in #nimrod. If you ask questions on -[StackOverflow use the nimrod -tag](http://stackoverflow.com/questions/tagged/nimrod). +[Freenode](irc://irc.freenode.net/nim) in #nim. If you ask questions on +[StackOverflow use the nim +tag](http://stackoverflow.com/questions/tagged/nim). ## License The compiler and the standard library are licensed under the MIT license, except for some modules where the documentation suggests otherwise. This means -that you can use any license for your own programs developed with Nimrod, +that you can use any license for your own programs developed with Nim, allowing you to create commercial applications. Read copying.txt for more details. diff --git a/readme.txt b/readme.txt index 3f6aef05c..21448b71b 100644 --- a/readme.txt +++ b/readme.txt @@ -1,15 +1,15 @@ -# Nimrod Compiler -This repo contains the Nimrod compiler, Nimrod's stdlib, tools and +# Nim Compiler +This repo contains the Nim compiler, Nim's stdlib, tools and documentation. ## Compiling -Compiling the Nimrod compiler is quite straightforward. Because -the Nimrod compiler itself is written in the Nimrod programming language +Compiling the Nim compiler is quite straightforward. Because +the Nim compiler itself is written in the Nim programming language the C source of an older version of the compiler are needed to bootstrap the -latest version. The C sources are available in a separate repo [here](http://github.com/nimrod-code/csources). +latest version. The C sources are available in a separate repo [here](http://github.com/nim-code/csources). Pre-compiled snapshots of the compiler are also available on -[Nimbuild](http://build.nimrod-lang.org/). Your platform however may not +[Nimbuild](http://build.nim-lang.org/). Your platform however may not currently be built for. The compiler currently supports the following platform and architecture @@ -30,16 +30,16 @@ To build from source you will need: If you are on a fairly modern *nix system, the following steps should work: ``` -$ git clone git://github.com/Araq/Nimrod.git -$ cd Nimrod -$ git clone --depth 1 git://github.com/nimrod-code/csources +$ git clone git://github.com/Araq/Nim.git +$ cd Nim +$ git clone --depth 1 git://github.com/nim-code/csources $ cd csources && ./build.sh $ cd .. -$ bin/nimrod c koch +$ bin/nim c koch $ ./koch boot -d:release ``` -``koch install [dir]`` may then be used to install Nimrod, or you can simply +``koch install [dir]`` may then be used to install Nim, or you can simply add it to your PATH. More ``koch`` related options are documented in [doc/koch.txt](doc/koch.txt). @@ -48,16 +48,16 @@ The above steps can be performed on Windows in a similar fashion, the instead of ``build.sh``. ## Getting help -A [forum](http://forum.nimrod-lang.org/) is available if you have any +A [forum](http://forum.nim-lang.org/) is available if you have any questions, and you can also get help in the IRC channel on -[Freenode](irc://irc.freenode.net/nimrod) in #nimrod. If you ask questions on -[StackOverflow use the nimrod -tag](http://stackoverflow.com/questions/tagged/nimrod). +[Freenode](irc://irc.freenode.net/nim) in #nim. If you ask questions on +[StackOverflow use the nim +tag](http://stackoverflow.com/questions/tagged/nim). ## License The compiler and the standard library are licensed under the MIT license, except for some modules where the documentation suggests otherwise. This means -that you can use any license for your own programs developed with Nimrod, +that you can use any license for your own programs developed with Nim, allowing you to create commercial applications. Read copying.txt for more details. From 14468988bafe33feef63362caac8656c3ad1d758 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 22:53:32 +0200 Subject: [PATCH 033/409] udpated osproc.nim --- lib/pure/osproc.nim | 132 ++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 5c9cf182f..db5410517 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -31,7 +31,7 @@ type id: THandle else: inHandle, outHandle, errHandle: FileHandle - inStream, outStream, errStream: PStream + inStream, outStream, errStream: Stream id: TPid exitCode: cint @@ -107,8 +107,8 @@ proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} = proc execProcess*(command: string, args: openArray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut, + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut, poUsePath, poEvalCommand}): TaintedString {. rtl, extern: "nosp$1", @@ -126,9 +126,9 @@ proc execCmd*(command: string): int {.rtl, extern: "nosp$1", tags: [ExecIOEffect proc startProcess*(command: string, workingDir: string = "", args: openArray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut}): - PProcess {.rtl, extern: "nosp$1", tags: [ExecIOEffect, ReadEnvEffect].} + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut}): + Process {.rtl, extern: "nosp$1", tags: [ExecIOEffect, ReadEnvEffect].} ## Starts a process. `Command` is the executable file, `workingDir` is the ## process's working directory. If ``workingDir == ""`` the current directory ## is used. `args` are the command line arguments that are passed to the @@ -151,60 +151,60 @@ proc startProcess*(command: string, ## Return value: The newly created process object. Nil is never returned, ## but ``EOS`` is raised in case of an error. -proc startCmd*(command: string, options: set[TProcessOption] = { - poStdErrToStdOut, poUsePath}): PProcess {. +proc startCmd*(command: string, options: set[ProcessOption] = { + poStdErrToStdOut, poUsePath}): Process {. tags: [ExecIOEffect, ReadEnvEffect], deprecated.} = ## Deprecated - use `startProcess` directly. result = startProcess(command=command, options=options + {poEvalCommand}) -proc close*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} +proc close*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## When the process has finished executing, cleanup related handles -proc suspend*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} +proc suspend*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## Suspends the process `p`. -proc resume*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} +proc resume*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## Resumes the process `p`. -proc terminate*(p: PProcess) {.rtl, extern: "nosp$1", tags: [].} +proc terminate*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## Terminates the process `p`. -proc running*(p: PProcess): bool {.rtl, extern: "nosp$1", tags: [].} +proc running*(p: Process): bool {.rtl, extern: "nosp$1", tags: [].} ## Returns true iff the process `p` is still running. Returns immediately. -proc processID*(p: PProcess): int {.rtl, extern: "nosp$1".} = +proc processID*(p: Process): int {.rtl, extern: "nosp$1".} = ## returns `p`'s process ID. return p.id -proc waitForExit*(p: PProcess, timeout: int = -1): int {.rtl, +proc waitForExit*(p: Process, timeout: int = -1): int {.rtl, extern: "nosp$1", tags: [].} ## waits for the process to finish and returns `p`'s error code. ## ## **Warning**: Be careful when using waitForExit for processes created without ## poParentStreams because they may fill output buffers, causing deadlock. -proc peekExitCode*(p: PProcess): int {.tags: [].} +proc peekExitCode*(p: Process): int {.tags: [].} ## return -1 if the process is still running. Otherwise the process' exit code -proc inputStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} +proc inputStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} ## returns ``p``'s input stream for writing to. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. -proc outputStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} +proc outputStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} ## returns ``p``'s output stream for reading from. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. -proc errorStream*(p: PProcess): PStream {.rtl, extern: "nosp$1", tags: [].} +proc errorStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} ## returns ``p``'s error stream for reading from. ## ## **Warning**: The returned `PStream` should not be closed manually as it ## is closed when closing the PProcess ``p``. -proc inputHandle*(p: PProcess): FileHandle {.rtl, extern: "nosp$1", +proc inputHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s input file handle for writing to. ## @@ -212,7 +212,7 @@ proc inputHandle*(p: PProcess): FileHandle {.rtl, extern: "nosp$1", ## it is closed when closing the PProcess ``p``. result = p.inHandle -proc outputHandle*(p: PProcess): FileHandle {.rtl, extern: "nosp$1", +proc outputHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s output file handle for reading from. ## @@ -220,7 +220,7 @@ proc outputHandle*(p: PProcess): FileHandle {.rtl, extern: "nosp$1", ## it is closed when closing the PProcess ``p``. result = p.outHandle -proc errorHandle*(p: PProcess): FileHandle {.rtl, extern: "nosp$1", +proc errorHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = ## returns ``p``'s error file handle for reading from. ## @@ -246,7 +246,7 @@ proc execProcesses*(cmds: openArray[string], assert n > 0 if n > 1: - var q: seq[PProcess] + var q: seq[Process] newSeq(q, n) var m = min(n, cmds.len) for i in 0..m-1: @@ -286,7 +286,7 @@ proc execProcesses*(cmds: openArray[string], result = max(waitForExit(p), result) close(p) -proc select*(readfds: var seq[PProcess], timeout = 500): int +proc select*(readfds: var seq[Process], timeout = 500): int ## `select` with a sensible Nim interface. `timeout` is in miliseconds. ## Specify -1 for no timeout. Returns the number of processes that are ## ready to read from. The processes that are ready to be read from are @@ -298,8 +298,8 @@ proc select*(readfds: var seq[PProcess], timeout = 500): int when not defined(useNimRtl): proc execProcess(command: string, args: openArray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut, + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut, poUsePath, poEvalCommand}): TaintedString = var p = startProcess(command, args=args, env=env, options=options) @@ -319,14 +319,14 @@ when defined(Windows) and not defined(useNimRtl): # We need to implement a handle stream for Windows: type PFileHandleStream = ref TFileHandleStream - TFileHandleStream = object of TStream + TFileHandleStream = object of StreamObj handle: THandle atTheEnd: bool - proc hsClose(s: PStream) = discard # nothing to do here - proc hsAtEnd(s: PStream): bool = return PFileHandleStream(s).atTheEnd + proc hsClose(s: Stream) = discard # nothing to do here + proc hsAtEnd(s: Stream): bool = return PFileHandleStream(s).atTheEnd - proc hsReadData(s: PStream, buffer: pointer, bufLen: int): int = + proc hsReadData(s: Stream, buffer: pointer, bufLen: int): int = var s = PFileHandleStream(s) if s.atTheEnd: return 0 var br: int32 @@ -338,7 +338,7 @@ when defined(Windows) and not defined(useNimRtl): s.atTheEnd = br < bufLen result = br - proc hsWriteData(s: PStream, buffer: pointer, bufLen: int) = + proc hsWriteData(s: Stream, buffer: pointer, bufLen: int) = var s = PFileHandleStream(s) var bytesWritten: int32 var a = winlean.writeFile(s.handle, buffer, bufLen.cint, bytesWritten, nil) @@ -360,7 +360,7 @@ when defined(Windows) and not defined(useNimRtl): result = cast[cstring](alloc0(res.len+1)) copyMem(result, cstring(res), res.len) - proc buildEnv(env: PStringTable): cstring = + proc buildEnv(env: StringTableRef): cstring = var L = 0 for key, val in pairs(env): inc(L, key.len + val.len + 2) result = cast[cstring](alloc0(L+2)) @@ -391,8 +391,8 @@ when defined(Windows) and not defined(useNimRtl): proc startProcess(command: string, workingDir: string = "", args: openArray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut}): PProcess = + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut}): Process = var si: TSTARTUPINFO procInfo: TPROCESS_INFORMATION @@ -456,7 +456,7 @@ when defined(Windows) and not defined(useNimRtl): result.fProcessHandle = procInfo.hProcess result.id = procInfo.dwProcessId - proc close(p: PProcess) = + proc close(p: Process) = when false: # somehow this does not work on Windows: discard closeHandle(p.inHandle) @@ -464,21 +464,21 @@ when defined(Windows) and not defined(useNimRtl): discard closeHandle(p.errHandle) discard closeHandle(p.FProcessHandle) - proc suspend(p: PProcess) = + proc suspend(p: Process) = discard suspendThread(p.fProcessHandle) - proc resume(p: PProcess) = + proc resume(p: Process) = discard resumeThread(p.fProcessHandle) - proc running(p: PProcess): bool = + proc running(p: Process): bool = var x = waitForSingleObject(p.fProcessHandle, 50) return x == WAIT_TIMEOUT - proc terminate(p: PProcess) = + proc terminate(p: Process) = if running(p): discard terminateProcess(p.fProcessHandle, 0) - proc waitForExit(p: PProcess, timeout: int = -1): int = + proc waitForExit(p: Process, timeout: int = -1): int = discard waitForSingleObject(p.fProcessHandle, timeout.int32) var res: int32 @@ -486,7 +486,7 @@ when defined(Windows) and not defined(useNimRtl): result = res discard closeHandle(p.fProcessHandle) - proc peekExitCode(p: PProcess): int = + proc peekExitCode(p: Process): int = var b = waitForSingleObject(p.fProcessHandle, 50) == WAIT_TIMEOUT if b: result = -1 else: @@ -494,13 +494,13 @@ when defined(Windows) and not defined(useNimRtl): discard getExitCodeProcess(p.fProcessHandle, res) return res - proc inputStream(p: PProcess): PStream = + proc inputStream(p: Process): Stream = result = newFileHandleStream(p.inHandle) - proc outputStream(p: PProcess): PStream = + proc outputStream(p: Process): Stream = result = newFileHandleStream(p.outHandle) - proc errorStream(p: PProcess): PStream = + proc errorStream(p: Process): Stream = result = newFileHandleStream(p.errHandle) proc execCmd(command: string): int = @@ -532,7 +532,7 @@ when defined(Windows) and not defined(useNimRtl): result = -1 discard closeHandle(process) - proc select(readfds: var seq[PProcess], timeout = 500): int = + proc select(readfds: var seq[Process], timeout = 500): int = assert readfds.len <= MAXIMUM_WAIT_OBJECTS var rfds: TWOHandleArray for i in 0..readfds.len()-1: @@ -555,7 +555,7 @@ elif not defined(useNimRtl): readIdx = 0 writeIdx = 1 - proc envToCStringArray(t: PStringTable): cstringArray = + proc envToCStringArray(t: StringTableRef): cstringArray = result = cast[cstringArray](alloc0((t.len + 1) * sizeof(cstring))) var i = 0 for key, val in pairs(t): @@ -598,8 +598,8 @@ elif not defined(useNimRtl): proc startProcess(command: string, workingDir: string = "", args: openArray[string] = [], - env: PStringTable = nil, - options: set[TProcessOption] = {poStdErrToStdOut}): PProcess = + env: StringTableRef = nil, + options: set[ProcessOption] = {poStdErrToStdOut}): Process = var pStdin, pStdout, pStderr: array [0..1, cint] new(result) @@ -809,7 +809,7 @@ elif not defined(useNimRtl): startProcessFail(data) {.pop} - proc close(p: PProcess) = + proc close(p: Process) = if p.inStream != nil: close(p.inStream) if p.outStream != nil: close(p.outStream) if p.errStream != nil: close(p.errStream) @@ -817,24 +817,24 @@ elif not defined(useNimRtl): discard close(p.outHandle) discard close(p.errHandle) - proc suspend(p: PProcess) = + proc suspend(p: Process) = if kill(-p.id, SIGSTOP) != 0'i32: raiseOSError(osLastError()) - proc resume(p: PProcess) = + proc resume(p: Process) = if kill(-p.id, SIGCONT) != 0'i32: raiseOSError(osLastError()) - proc running(p: PProcess): bool = + proc running(p: Process): bool = var ret = waitpid(p.id, p.exitCode, WNOHANG) if ret == 0: return true # Can't establish status. Assume running. result = ret == int(p.id) - proc terminate(p: PProcess) = + proc terminate(p: Process) = if kill(-p.id, SIGTERM) == 0'i32: if p.running(): if kill(-p.id, SIGKILL) != 0'i32: raiseOSError(osLastError()) else: raiseOSError(osLastError()) - proc waitForExit(p: PProcess, timeout: int = -1): int = + proc waitForExit(p: Process, timeout: int = -1): int = #if waitPid(p.id, p.exitCode, 0) == int(p.id): # ``waitPid`` fails if the process is not running anymore. But then # ``running`` probably set ``p.exitCode`` for us. Since ``p.exitCode`` is @@ -845,7 +845,7 @@ elif not defined(useNimRtl): raiseOSError(osLastError()) result = int(p.exitCode) shr 8 - proc peekExitCode(p: PProcess): int = + proc peekExitCode(p: Process): int = if p.exitCode != -3: return p.exitCode var ret = waitpid(p.id, p.exitCode, WNOHANG) var b = ret == int(p.id) @@ -853,23 +853,23 @@ elif not defined(useNimRtl): if p.exitCode == -3: result = -1 else: result = p.exitCode.int shr 8 - proc createStream(stream: var PStream, handle: var FileHandle, + proc createStream(stream: var Stream, handle: var FileHandle, fileMode: FileMode) = var f: File if not open(f, handle, fileMode): raiseOSError(osLastError()) stream = newFileStream(f) - proc inputStream(p: PProcess): PStream = + proc inputStream(p: Process): Stream = if p.inStream == nil: createStream(p.inStream, p.inHandle, fmWrite) return p.inStream - proc outputStream(p: PProcess): PStream = + proc outputStream(p: Process): Stream = if p.outStream == nil: createStream(p.outStream, p.outHandle, fmRead) return p.outStream - proc errorStream(p: PProcess): PStream = + proc errorStream(p: Process): Stream = if p.errStream == nil: createStream(p.errStream, p.errHandle, fmRead) return p.errStream @@ -882,13 +882,13 @@ elif not defined(useNimRtl): else: result = csystem(command) - proc createFdSet(fd: var TFdSet, s: seq[PProcess], m: var int) = + proc createFdSet(fd: var FdSet, s: seq[Process], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.outHandle)) - FD_SET(cint(i.outHandle), fd) + fdSet(cint(i.outHandle), fd) - proc pruneProcessSet(s: var seq[PProcess], fd: var TFdSet) = + proc pruneProcessSet(s: var seq[Process], fd: var FdSet) = var i = 0 var L = s.len while i < L: @@ -899,12 +899,12 @@ elif not defined(useNimRtl): inc(i) setLen(s, L) - proc select(readfds: var seq[PProcess], timeout = 500): int = - var tv: Ttimeval + proc select(readfds: var seq[Process], timeout = 500): int = + var tv: Timeval tv.tv_sec = 0 tv.tv_usec = timeout * 1000 - var rd: TFdSet + var rd: FdSet var m = 0 createFdSet((rd), readfds, m) @@ -916,7 +916,7 @@ elif not defined(useNimRtl): pruneProcessSet(readfds, (rd)) -proc execCmdEx*(command: string, options: set[TProcessOption] = { +proc execCmdEx*(command: string, options: set[ProcessOption] = { poStdErrToStdOut, poUsePath}): tuple[ output: TaintedString, exitCode: int] {.tags: [ExecIOEffect, ReadIOEffect], gcsafe.} = From c68c42a237c09af4a23fcf207aa51f9f12f5e917 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 22:55:47 +0200 Subject: [PATCH 034/409] updated sockets.nim --- lib/pure/sockets.nim | 242 +++++++++++++++++++++---------------------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 6c2ec72f1..157d5837e 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -234,8 +234,8 @@ else: proc toInt(p: Protocol): cint = result = cint(ord(p)) -proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP, buffered = true): TSocket = +proc socket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP, buffered = true): Socket = ## Creates a new socket; returns `InvalidSocket` if an error occurs. # TODO: Perhaps this should just raise EOS when an error occurs. @@ -346,7 +346,7 @@ when defined(ssl): if SSLSetFd(socket.sslHandle, socket.fd) != 1: SSLError() -proc raiseSocketError*(socket: TSocket, err: int = -1, async = false) = +proc raiseSocketError*(socket: Socket, err: int = -1, async = false) = ## Raises proper errors based on return values of ``recv`` functions. ## ## If ``async`` is ``True`` no error will be thrown in the case when the @@ -387,7 +387,7 @@ proc raiseSocketError*(socket: TSocket, err: int = -1, async = false) = else: raiseOSError(lastError) else: raiseOSError(lastError) -proc listen*(socket: TSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = +proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. @@ -434,54 +434,54 @@ template gaiNim(a, p, h, list: expr): stmt = else: raise newException(OSError, $gai_strerror(gaiResult)) -proc bindAddr*(socket: TSocket, port = TPort(0), address = "") {. +proc bindAddr*(socket: Socket, port = Port(0), address = "") {. tags: [ReadIOEffect].} = ## binds an address/port number to a socket. ## Use address string in dotted decimal form like "a.b.c.d" ## or leave "" for any address. if address == "": - var name: Tsockaddr_in + var name: Sockaddr_in when defined(Windows): name.sin_family = int16(ord(AF_INET)) else: name.sin_family = posix.AF_INET name.sin_port = sockets.htons(int16(port)) name.sin_addr.s_addr = sockets.htonl(INADDR_ANY) - if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)), - sizeof(name).TSocklen) < 0'i32: + if bindSocket(socket.fd, cast[ptr SockAddr](addr(name)), + sizeof(name).SockLen) < 0'i32: raiseOSError(osLastError()) else: - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: AddrInfo + var aiList: ptr AddrInfo = nil hints.ai_family = toInt(AF_INET) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) gaiNim(address, port, hints, aiList) - if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSocklen) < 0'i32: + if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32: raiseOSError(osLastError()) -proc getSockName*(socket: TSocket): TPort = +proc getSockName*(socket: Socket): Port = ## returns the socket's associated port number. - var name: Tsockaddr_in + var name: Sockaddr_in when defined(Windows): name.sin_family = int16(ord(AF_INET)) else: name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).TSocklen - if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)), + var namelen = sizeof(name).SockLen + if getsockname(socket.fd, cast[ptr SockAddr](addr(name)), addr(namelen)) == -1'i32: raiseOSError(osLastError()) - result = TPort(sockets.ntohs(name.sin_port)) + result = Port(sockets.ntohs(name.sin_port)) template acceptAddrPlain(noClientRet, successRet: expr, sslImplementation: stmt): stmt {.immediate.} = assert(client != nil) - var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen - var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), + var sockAddress: Sockaddr_in + var addrLen = sizeof(sockAddress).SockLen + var sock = accept(server.fd, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if sock == osInvalidSocket: @@ -515,7 +515,7 @@ template acceptAddrPlain(noClientRet, successRet: expr, else: return successRet -proc acceptAddr*(server: TSocket, client: var TSocket, address: var string) {. +proc acceptAddr*(server: Socket, client: var Socket, address: var string) {. tags: [ReadIOEffect].} = ## Blocks until a connection is being made from a client. When a connection ## is made sets ``client`` to the client socket and ``address`` to the address @@ -556,7 +556,7 @@ proc acceptAddr*(server: TSocket, client: var TSocket, address: var string) {. else: SSLError("Unknown error") -proc setBlocking*(s: TSocket, blocking: bool) {.tags: [], gcsafe.} +proc setBlocking*(s: Socket, blocking: bool) {.tags: [], gcsafe.} ## Sets blocking mode on socket when defined(ssl): @@ -611,7 +611,7 @@ when defined(ssl): acceptAddrPlain(AcceptNoClient, AcceptSuccess): doHandshake() -proc accept*(server: TSocket, client: var TSocket) {.tags: [ReadIOEffect].} = +proc accept*(server: Socket, client: var Socket) {.tags: [ReadIOEffect].} = ## Equivalent to ``acceptAddr`` but doesn't return the address, only the ## socket. ## @@ -621,24 +621,24 @@ proc accept*(server: TSocket, client: var TSocket) {.tags: [ReadIOEffect].} = var addrDummy = "" acceptAddr(server, client, addrDummy) -proc acceptAddr*(server: TSocket): tuple[client: TSocket, address: string] {. +proc acceptAddr*(server: Socket): tuple[client: Socket, address: string] {. deprecated, tags: [ReadIOEffect].} = ## Slightly different version of ``acceptAddr``. ## ## **Deprecated since version 0.9.0:** Please use the function above. - var client: TSocket + var client: Socket new(client) var address = "" acceptAddr(server, client, address) return (client, address) -proc accept*(server: TSocket): TSocket {.deprecated, tags: [ReadIOEffect].} = +proc accept*(server: Socket): Socket {.deprecated, tags: [ReadIOEffect].} = ## **Deprecated since version 0.9.0:** Please use the function above. new(result) var address = "" acceptAddr(server, result, address) -proc close*(socket: TSocket) = +proc close*(socket: Socket) = ## closes a socket. when defined(windows): discard winlean.closesocket(socket.fd) @@ -650,7 +650,7 @@ proc close*(socket: TSocket) = if socket.isSSL: discard SSLShutdown(socket.sslHandle) -proc getServByName*(name, proto: string): TServent {.tags: [ReadIOEffect].} = +proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the service name specified by ``name`` matches the s_name member ## and the protocol name specified by ``proto`` matches the s_proto member. @@ -663,10 +663,10 @@ proc getServByName*(name, proto: string): TServent {.tags: [ReadIOEffect].} = if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) - result.port = TPort(s.s_port) + result.port = Port(s.s_port) result.proto = $s.s_proto -proc getServByPort*(port: TPort, proto: string): TServent {.tags: [ReadIOEffect].} = +proc getServByPort*(port: Port, proto: string): Servent {.tags: [ReadIOEffect].} = ## Searches the database from the beginning and finds the first entry for ## which the port specified by ``port`` matches the s_port member and the ## protocol name specified by ``proto`` matches the s_proto member. @@ -679,12 +679,12 @@ proc getServByPort*(port: TPort, proto: string): TServent {.tags: [ReadIOEffect] if s == nil: raise newException(OSError, "Service not found.") result.name = $s.s_name result.aliases = cstringArrayToSeq(s.s_aliases) - result.port = TPort(s.s_port) + result.port = Port(s.s_port) result.proto = $s.s_proto -proc getHostByAddr*(ip: string): Thostent {.tags: [ReadIOEffect].} = +proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} = ## This function will lookup the hostname of an IP Address. - var myaddr: TInAddr + var myaddr: InAddr myaddr.s_addr = inet_addr(ip) when defined(windows): @@ -692,7 +692,7 @@ proc getHostByAddr*(ip: string): Thostent {.tags: [ReadIOEffect].} = cint(sockets.AF_INET)) if s == nil: raiseOSError(osLastError()) else: - var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).TSocklen, + var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen, cint(posix.AF_INET)) if s == nil: raise newException(OSError, $hstrerror(h_errno)) @@ -700,7 +700,7 @@ proc getHostByAddr*(ip: string): Thostent {.tags: [ReadIOEffect].} = result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) when defined(windows): - result.addrtype = TDomain(s.h_addrtype) + result.addrtype = Domain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: result.addrtype = AF_INET @@ -711,7 +711,7 @@ proc getHostByAddr*(ip: string): Thostent {.tags: [ReadIOEffect].} = result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getHostByName*(name: string): Thostent {.tags: [ReadIOEffect].} = +proc getHostByName*(name: string): Hostent {.tags: [ReadIOEffect].} = ## This function will lookup the IP address of a hostname. when defined(Windows): var s = winlean.gethostbyname(name) @@ -721,7 +721,7 @@ proc getHostByName*(name: string): Thostent {.tags: [ReadIOEffect].} = result.name = $s.h_name result.aliases = cstringArrayToSeq(s.h_aliases) when defined(windows): - result.addrtype = TDomain(s.h_addrtype) + result.addrtype = Domain(s.h_addrtype) else: if s.h_addrtype == posix.AF_INET: result.addrtype = AF_INET @@ -732,25 +732,25 @@ proc getHostByName*(name: string): Thostent {.tags: [ReadIOEffect].} = result.addrList = cstringArrayToSeq(s.h_addr_list) result.length = int(s.h_length) -proc getSockOptInt*(socket: TSocket, level, optname: int): int {. +proc getSockOptInt*(socket: Socket, level, optname: int): int {. tags: [ReadIOEffect].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).TSocklen + var size = sizeof(res).SockLen if getsockopt(socket.fd, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: raiseOSError(osLastError()) result = int(res) -proc setSockOptInt*(socket: TSocket, level, optname, optval: int) {. +proc setSockOptInt*(socket: Socket, level, optname, optval: int) {. tags: [WriteIOEffect].} = ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket.fd, cint(level), cint(optname), addr(value), - sizeof(value).TSocklen) < 0'i32: + sizeof(value).SockLen) < 0'i32: raiseOSError(osLastError()) -proc toCInt(opt: TSOBool): cint = +proc toCInt(opt: SOBool): cint = case opt of OptAcceptConn: SO_ACCEPTCONN of OptBroadcast: SO_BROADCAST @@ -760,34 +760,34 @@ proc toCInt(opt: TSOBool): cint = of OptOOBInline: SO_OOBINLINE of OptReuseAddr: SO_REUSEADDR -proc getSockOpt*(socket: TSocket, opt: TSOBool, level = SOL_SOCKET): bool {. +proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {. tags: [ReadIOEffect].} = ## Retrieves option ``opt`` as a boolean value. var res: cint - var size = sizeof(res).TSocklen + var size = sizeof(res).SockLen if getsockopt(socket.fd, cint(level), toCInt(opt), addr(res), addr(size)) < 0'i32: raiseOSError(osLastError()) result = res != 0 -proc setSockOpt*(socket: TSocket, opt: TSOBool, value: bool, level = SOL_SOCKET) {. +proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {. tags: [WriteIOEffect].} = ## Sets option ``opt`` to a boolean value specified by ``value``. var valuei = cint(if value: 1 else: 0) if setsockopt(socket.fd, cint(level), toCInt(opt), addr(valuei), - sizeof(valuei).TSocklen) < 0'i32: + sizeof(valuei).SockLen) < 0'i32: raiseOSError(osLastError()) -proc connect*(socket: TSocket, address: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [ReadIOEffect].} = +proc connect*(socket: Socket, address: string, port = Port(0), + af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## Connects socket to ``address``:``port``. ``Address`` can be an IP address or a ## host name. If ``address`` is a host name, this function will try each IP ## of that host name. ``htons`` is already performed on ``port`` so you must ## not do it. ## ## If ``socket`` is an SSL socket a handshake will be automatically performed. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: AddrInfo + var aiList: ptr AddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -797,7 +797,7 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), var lastError: OSErrorCode var it = aiList while it != nil: - if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) == 0'i32: + if connect(socket.fd, it.ai_addr, it.ai_addrlen.SockLen) == 0'i32: success = true break else: lastError = osLastError() @@ -839,8 +839,8 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), if connect(socket.fd, cast[ptr TSockAddr](addr(s)), sizeof(s).cint) < 0'i32: OSError() -proc connectAsync*(socket: TSocket, name: string, port = TPort(0), - af: TDomain = AF_INET) {.tags: [ReadIOEffect].} = +proc connectAsync*(socket: Socket, name: string, port = Port(0), + af: Domain = AF_INET) {.tags: [ReadIOEffect].} = ## A variant of ``connect`` for non-blocking sockets. ## ## This procedure will immediatelly return, it will not block until a connection @@ -849,8 +849,8 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), ## ## **Note**: For SSL sockets, the ``handshake`` procedure must be called ## whenever the socket successfully connects to a server. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: AddrInfo + var aiList: ptr AddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -860,7 +860,7 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0), var lastError: OSErrorCode var it = aiList while it != nil: - var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) + var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.SockLen) if ret == 0'i32: success = true break @@ -925,19 +925,19 @@ when defined(ssl): else: SSLError("Socket is not an SSL socket.") -proc timeValFromMilliseconds(timeout = 500): Ttimeval = +proc timeValFromMilliseconds(timeout = 500): Timeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var TFdSet, s: seq[TSocket], m: var int) = +proc createFdSet(fd: var FdSet, s: seq[Socket], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.fd)) - FD_SET(i.fd, fd) + fdSet(i.fd, fd) -proc pruneSocketSet(s: var seq[TSocket], fd: var TFdSet) = +proc pruneSocketSet(s: var seq[Socket], fd: var FdSet) = var i = 0 var L = s.len while i < L: @@ -949,7 +949,7 @@ proc pruneSocketSet(s: var seq[TSocket], fd: var TFdSet) = inc(i) setLen(s, L) -proc hasDataBuffered*(s: TSocket): bool = +proc hasDataBuffered*(s: Socket): bool = ## Determines whether a socket has data buffered. result = false if s.isBuffered: @@ -959,10 +959,10 @@ proc hasDataBuffered*(s: TSocket): bool = if s.isSSL and not result: result = s.sslHasPeekChar -proc checkBuffer(readfds: var seq[TSocket]): int = +proc checkBuffer(readfds: var seq[Socket]): int = ## Checks the buffer of each socket in ``readfds`` to see whether there is data. ## Removes the sockets from ``readfds`` and returns the count of removed sockets. - var res: seq[TSocket] = @[] + var res: seq[Socket] = @[] result = 0 for s in readfds: if hasDataBuffered(s): @@ -971,7 +971,7 @@ proc checkBuffer(readfds: var seq[TSocket]): int = if result > 0: readfds = res -proc select*(readfds, writefds, exceptfds: var seq[TSocket], +proc select*(readfds, writefds, exceptfds: var seq[Socket], timeout = 500): int {.tags: [ReadIOEffect].} = ## Traditional select function. This function will return the number of ## sockets that are ready to be read from, written to, or which have errors. @@ -985,9 +985,9 @@ proc select*(readfds, writefds, exceptfds: var seq[TSocket], if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd, wr, ex: TFdSet + var rd, wr, ex: FdSet var m = 0 createFdSet((rd), readfds, m) createFdSet((wr), writefds, m) @@ -1002,15 +1002,15 @@ proc select*(readfds, writefds, exceptfds: var seq[TSocket], pruneSocketSet(writefds, (wr)) pruneSocketSet(exceptfds, (ex)) -proc select*(readfds, writefds: var seq[TSocket], +proc select*(readfds, writefds: var seq[Socket], timeout = 500): int {.tags: [ReadIOEffect].} = ## Variant of select with only a read and write list. let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd, wr: TFdSet + var rd, wr: FdSet var m = 0 createFdSet((rd), readfds, m) createFdSet((wr), writefds, m) @@ -1023,7 +1023,7 @@ proc select*(readfds, writefds: var seq[TSocket], pruneSocketSet(readfds, (rd)) pruneSocketSet(writefds, (wr)) -proc selectWrite*(writefds: var seq[TSocket], +proc selectWrite*(writefds: var seq[Socket], timeout = 500): int {.tags: [ReadIOEffect].} = ## When a socket in ``writefds`` is ready to be written to then a non-zero ## value will be returned specifying the count of the sockets which can be @@ -1032,9 +1032,9 @@ proc selectWrite*(writefds: var seq[TSocket], ## ## ``timeout`` is specified in miliseconds and ``-1`` can be specified for ## an unlimited time. - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var wr: TFdSet + var wr: FdSet var m = 0 createFdSet((wr), writefds, m) @@ -1045,14 +1045,14 @@ proc selectWrite*(writefds: var seq[TSocket], pruneSocketSet(writefds, (wr)) -proc select*(readfds: var seq[TSocket], timeout = 500): int = +proc select*(readfds: var seq[Socket], timeout = 500): int = ## variant of select with a read list only let buffersFilled = checkBuffer(readfds) if buffersFilled > 0: return buffersFilled - var tv {.noInit.}: Ttimeval = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd: TFdSet + var rd: FdSet var m = 0 createFdSet((rd), readfds, m) @@ -1063,7 +1063,7 @@ proc select*(readfds: var seq[TSocket], timeout = 500): int = pruneSocketSet(readfds, (rd)) -proc readIntoBuf(socket: TSocket, flags: int32): int = +proc readIntoBuf(socket: Socket, flags: int32): int = result = 0 when defined(ssl): if socket.isSSL: @@ -1087,7 +1087,7 @@ template retRead(flags, readBytes: int) {.dirty.} = else: return res -proc recv*(socket: TSocket, data: pointer, size: int): int {.tags: [ReadIOEffect].} = +proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [ReadIOEffect].} = ## Receives data from a socket. ## ## **Note**: This is a low-level function, you may be interested in the higher @@ -1127,7 +1127,7 @@ proc recv*(socket: TSocket, data: pointer, size: int): int {.tags: [ReadIOEffect else: result = recv(socket.fd, data, size.cint, 0'i32) -proc waitFor(socket: TSocket, waited: var float, timeout, size: int, +proc waitFor(socket: Socket, waited: var float, timeout, size: int, funcName: string): int {.tags: [TimeEffect].} = ## determines the amount of characters that can be read. Result will never ## be larger than ``size``. For unbuffered sockets this will be ``1``. @@ -1162,7 +1162,7 @@ proc waitFor(socket: TSocket, waited: var float, timeout, size: int, raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") waited += (epochTime() - startTime) -proc recv*(socket: TSocket, data: pointer, size: int, timeout: int): int {. +proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. tags: [ReadIOEffect, TimeEffect].} = ## overload with a ``timeout`` parameter in miliseconds. var waited = 0.0 # number of seconds already waited @@ -1179,7 +1179,7 @@ proc recv*(socket: TSocket, data: pointer, size: int, timeout: int): int {. result = read -proc recv*(socket: TSocket, data: var string, size: int, timeout = -1): int = +proc recv*(socket: Socket, data: var string, size: int, timeout = -1): int = ## Higher-level version of ``recv``. ## ## When 0 is returned the socket's connection has been closed. @@ -1198,7 +1198,7 @@ proc recv*(socket: TSocket, data: var string, size: int, timeout = -1): int = socket.raiseSocketError(result) data.setLen(result) -proc recvAsync*(socket: TSocket, data: var string, size: int): int = +proc recvAsync*(socket: Socket, data: var string, size: int): int = ## Async version of ``recv``. ## ## When socket is non-blocking and no data is available on the socket, @@ -1213,7 +1213,7 @@ proc recvAsync*(socket: TSocket, data: var string, size: int): int = result = -1 data.setLen(result) -proc peekChar(socket: TSocket, c: var char): int {.tags: [ReadIOEffect].} = +proc peekChar(socket: Socket, c: var char): int {.tags: [ReadIOEffect].} = if socket.isBuffered: result = 1 if socket.bufLen == 0 or socket.currPos > socket.bufLen-1: @@ -1233,7 +1233,7 @@ proc peekChar(socket: TSocket, c: var char): int {.tags: [ReadIOEffect].} = return result = recv(socket.fd, addr(c), 1, MSG_PEEK) -proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. +proc recvLine*(socket: Socket, line: var TaintedString, timeout = -1): bool {. tags: [ReadIOEffect, TimeEffect], deprecated.} = ## Receive a line of data from ``socket``. ## @@ -1280,7 +1280,7 @@ proc recvLine*(socket: TSocket, line: var TaintedString, timeout = -1): bool {. return true add(line.string, c) -proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. +proc readLine*(socket: Socket, line: var TaintedString, timeout = -1) {. tags: [ReadIOEffect, TimeEffect].} = ## Reads a line of data from ``socket``. ## @@ -1321,8 +1321,8 @@ proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {. return add(line.string, c) -proc recvLineAsync*(socket: TSocket, - line: var TaintedString): TRecvLineResult {.tags: [ReadIOEffect], deprecated.} = +proc recvLineAsync*(socket: Socket, + line: var TaintedString): RecvLineResult {.tags: [ReadIOEffect], deprecated.} = ## Similar to ``recvLine`` but designed for non-blocking sockets. ## ## The values of the returned enum should be pretty self explanatory: @@ -1353,8 +1353,8 @@ proc recvLineAsync*(socket: TSocket, elif c == '\L': return RecvFullLine add(line.string, c) -proc readLineAsync*(socket: TSocket, - line: var TaintedString): TReadLineResult {.tags: [ReadIOEffect].} = +proc readLineAsync*(socket: Socket, + line: var TaintedString): ReadLineResult {.tags: [ReadIOEffect].} = ## Similar to ``recvLine`` but designed for non-blocking sockets. ## ## The values of the returned enum should be pretty self explanatory: @@ -1388,7 +1388,7 @@ proc readLineAsync*(socket: TSocket, elif c == '\L': return ReadFullLine add(line.string, c) -proc recv*(socket: TSocket): TaintedString {.tags: [ReadIOEffect], deprecated.} = +proc recv*(socket: Socket): TaintedString {.tags: [ReadIOEffect], deprecated.} = ## receives all the available data from the socket. ## Socket errors will result in an ``EOS`` error. ## If socket is not a connectionless socket and socket is not connected @@ -1420,7 +1420,7 @@ proc recv*(socket: TSocket): TaintedString {.tags: [ReadIOEffect], deprecated.} if bytesRead != bufSize-1: break {.push warning[deprecated]: off.} -proc recvTimeout*(socket: TSocket, timeout: int): TaintedString {. +proc recvTimeout*(socket: Socket, timeout: int): TaintedString {. tags: [ReadIOEffect], deprecated.} = ## overloaded variant to support a ``timeout`` parameter, the ``timeout`` ## parameter specifies the amount of miliseconds to wait for data on the @@ -1430,12 +1430,12 @@ proc recvTimeout*(socket: TSocket, timeout: int): TaintedString {. if socket.bufLen == 0: var s = @[socket] if s.select(timeout) != 1: - raise newException(ETimeout, "Call to recv() timed out.") + raise newException(TimeoutError, "Call to recv() timed out.") return socket.recv {.pop.} -proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. +proc recvAsync*(socket: Socket, s: var TaintedString): bool {. tags: [ReadIOEffect], deprecated.} = ## receives all the data from a non-blocking socket. If socket is non-blocking ## and there are no messages available, `False` will be returned. @@ -1486,8 +1486,8 @@ proc recvAsync*(socket: TSocket, s: var TaintedString): bool {. inc(pos, bytesRead) result = true -proc recvFrom*(socket: TSocket, data: var string, length: int, - address: var string, port: var TPort, flags = 0'i32): int {. +proc recvFrom*(socket: Socket, data: var string, length: int, + address: var string, port: var Port, flags = 0'i32): int {. tags: [ReadIOEffect].} = ## Receives data from ``socket``. This function should normally be used with ## connection-less sockets (UDP sockets). @@ -1502,18 +1502,18 @@ proc recvFrom*(socket: TSocket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) - var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen + var sockAddress: Sockaddr_in + var addrLen = sizeof(sockAddress).SockLen result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, - cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) + cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if result != -1: data.setLen(result) address = $inet_ntoa(sockAddress.sin_addr) - port = ntohs(sockAddress.sin_port).TPort + port = ntohs(sockAddress.sin_port).Port -proc recvFromAsync*(socket: TSocket, data: var string, length: int, - address: var string, port: var TPort, +proc recvFromAsync*(socket: Socket, data: var string, length: int, + address: var string, port: var Port, flags = 0'i32): bool {.tags: [ReadIOEffect].} = ## Variant of ``recvFrom`` for non-blocking sockets. Unlike ``recvFrom``, ## this function will raise an EOS error whenever a socket error occurs. @@ -1532,7 +1532,7 @@ proc recvFromAsync*(socket: TSocket, data: var string, length: int, return false else: raiseOSError(err) -proc skip*(socket: TSocket) {.tags: [ReadIOEffect], deprecated.} = +proc skip*(socket: Socket) {.tags: [ReadIOEffect], deprecated.} = ## skips all the data that is pending for the socket ## ## **Deprecated since version 0.9.2**: This function is not safe for use. @@ -1541,7 +1541,7 @@ proc skip*(socket: TSocket) {.tags: [ReadIOEffect], deprecated.} = while recv(socket, buf, bufSize) == bufSize: discard dealloc(buf) -proc skip*(socket: TSocket, size: int, timeout = -1) = +proc skip*(socket: Socket, size: int, timeout = -1) = ## Skips ``size`` amount of bytes. ## ## An optional timeout can be specified in miliseconds, if skipping the @@ -1556,7 +1556,7 @@ proc skip*(socket: TSocket, size: int, timeout = -1) = bytesSkipped += recv(socket, dummy, avail) dealloc(dummy) -proc send*(socket: TSocket, data: pointer, size: int): int {. +proc send*(socket: Socket, data: pointer, size: int): int {. tags: [WriteIOEffect].} = ## sends data to a socket. when defined(ssl): @@ -1570,7 +1570,7 @@ proc send*(socket: TSocket, data: pointer, size: int): int {. const MSG_NOSIGNAL = 0 result = send(socket.fd, data, size, int32(MSG_NOSIGNAL)) -proc send*(socket: TSocket, data: string) {.tags: [WriteIOEffect].} = +proc send*(socket: Socket, data: string) {.tags: [WriteIOEffect].} = ## sends data to a socket. if socket.nonblocking: raise newException(ValueError, "This function cannot be used on non-blocking sockets.") @@ -1585,7 +1585,7 @@ proc send*(socket: TSocket, data: string) {.tags: [WriteIOEffect].} = if sent != data.len: raise newException(OSError, "Could not send all data.") -proc sendAsync*(socket: TSocket, data: string): int {.tags: [WriteIOEffect].} = +proc sendAsync*(socket: Socket, data: string): int {.tags: [WriteIOEffect].} = ## sends data to a non-blocking socket. ## Returns ``0`` if no data could be sent, if data has been sent ## returns the amount of bytes of ``data`` that was successfully sent. This @@ -1624,21 +1624,21 @@ proc sendAsync*(socket: TSocket, data: string): int {.tags: [WriteIOEffect].} = else: raiseOSError(err) -proc trySend*(socket: TSocket, data: string): bool {.tags: [WriteIOEffect].} = +proc trySend*(socket: Socket, data: string): bool {.tags: [WriteIOEffect].} = ## safe alternative to ``send``. Does not raise an EOS when an error occurs, ## and instead returns ``false`` on failure. result = send(socket, cstring(data), data.len) == data.len -proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, - size: int, af: TDomain = AF_INET, flags = 0'i32): int {. +proc sendTo*(socket: Socket, address: string, port: Port, data: pointer, + size: int, af: Domain = AF_INET, flags = 0'i32): int {. tags: [WriteIOEffect].} = ## low-level sendTo proc. This proc sends ``data`` to the specified ``address``, ## which may be an IP address or a hostname, if a hostname is specified ## this function will try each IP of that hostname. ## ## **Note:** This proc is not available for SSL sockets. - var hints: Taddrinfo - var aiList: ptr Taddrinfo = nil + var hints: AddrInfo + var aiList: ptr AddrInfo = nil hints.ai_family = toInt(af) hints.ai_socktype = toInt(SOCK_STREAM) hints.ai_protocol = toInt(IPPROTO_TCP) @@ -1649,7 +1649,7 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, var it = aiList while it != nil: result = sendto(socket.fd, data, size.cint, flags.cint, it.ai_addr, - it.ai_addrlen.TSocklen) + it.ai_addrlen.SockLen) if result != -1'i32: success = true break @@ -1657,7 +1657,7 @@ proc sendTo*(socket: TSocket, address: string, port: TPort, data: pointer, freeaddrinfo(aiList) -proc sendTo*(socket: TSocket, address: string, port: TPort, +proc sendTo*(socket: Socket, address: string, port: Port, data: string): int {.tags: [WriteIOEffect].} = ## Friendlier version of the low-level ``sendTo``. result = socket.sendTo(address, port, cstring(data), data.len) @@ -1669,11 +1669,11 @@ when defined(Windows): FIONBIO = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or (102 shl 8) or 126 - proc ioctlsocket(s: TSocketHandle, cmd: clong, + proc ioctlsocket(s: SocketHandle, cmd: clong, argptr: ptr clong): cint {. stdcall, importc:"ioctlsocket", dynlib: "ws2_32.dll".} -proc setBlocking(s: TSocket, blocking: bool) = +proc setBlocking(s: Socket, blocking: bool) = when defined(Windows): var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking if ioctlsocket(s.fd, FIONBIO, addr(mode)) == -1: @@ -1694,8 +1694,8 @@ discard """ proc setReuseAddr*(s: TSocket) = if setsockopt(s.fd, SOL_SOCKET, mode, addr blah, TSOcklen(sizeof(int))) == -1: OSError(OSLastError()) """ -proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, - af: TDomain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = +proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, + af: Domain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = ## Connects to server as specified by ``address`` on port specified by ``port``. ## ## The ``timeout`` paremeter specifies the time in miliseconds to allow for @@ -1704,9 +1704,9 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, socket.setBlocking(false) socket.connectAsync(address, port, af) - var s: seq[TSocket] = @[socket] + var s: seq[Socket] = @[socket] if selectWrite(s, timeout) != 1: - raise newException(ETimeout, "Call to 'connect' timed out.") + raise newException(TimeoutError, "Call to 'connect' timed out.") else: when defined(ssl): if socket.isSSL: @@ -1714,17 +1714,17 @@ proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int, doAssert socket.handshake() socket.setBlocking(originalStatus) -proc isSSL*(socket: TSocket): bool = return socket.isSSL +proc isSSL*(socket: Socket): bool = return socket.isSSL ## Determines whether ``socket`` is a SSL socket. -proc getFD*(socket: TSocket): TSocketHandle = return socket.fd +proc getFD*(socket: Socket): SocketHandle = return socket.fd ## Returns the socket's file descriptor -proc isBlocking*(socket: TSocket): bool = not socket.nonblocking +proc isBlocking*(socket: Socket): bool = not socket.nonblocking ## Determines whether ``socket`` is blocking. when defined(Windows): - var wsa: TWSAData + var wsa: WSAData if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) From 5946747970f31742bc58bdd2fbe174b8b5cdc678 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 28 Aug 2014 23:48:42 +0200 Subject: [PATCH 035/409] updated the compiler to use the new symbol names --- compiler/aliases.nim | 6 +- compiler/astalgo.nim | 18 +-- compiler/babelcmd.nim | 4 +- compiler/ccgmerge.nim | 4 +- compiler/ccgtypes.nim | 16 +-- compiler/cgendata.nim | 6 +- compiler/cgmeth.nim | 6 +- compiler/condsyms.nim | 2 +- compiler/docgen.nim | 8 +- compiler/importer.nim | 8 +- compiler/jsgen.nim | 4 +- compiler/lambdalifting.nim | 4 +- compiler/lexer.nim | 12 +- compiler/lookups.nim | 13 +- compiler/msgs.nim | 2 +- compiler/rodread.nim | 2 +- compiler/sem.nim | 2 +- compiler/semasgn.nim | 196 +++++++++++++++++++++++++++++++ compiler/semdata.nim | 6 +- compiler/semexprs.nim | 2 +- compiler/semgnrc.nim | 8 +- compiler/semtempl.nim | 6 +- compiler/semtypes.nim | 14 +-- compiler/service.nim | 4 +- compiler/sigmatch.nim | 2 +- compiler/types.nim | 32 ++--- compiler/vmdeps.nim | 2 +- lib/packages/docutils/rst.nim | 8 +- lib/packages/docutils/rstast.nim | 4 +- lib/packages/docutils/rstgen.nim | 20 ++-- 30 files changed, 307 insertions(+), 114 deletions(-) create mode 100644 compiler/semasgn.nim diff --git a/compiler/aliases.nim b/compiler/aliases.nim index d68c9360a..3f3d45ff7 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -16,9 +16,9 @@ type TAnalysisResult* = enum arNo, arMaybe, arYes -proc isPartOfAux(a, b: PType, marker: var TIntSet): TAnalysisResult +proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult -proc isPartOfAux(n: PNode, b: PType, marker: var TIntSet): TAnalysisResult = +proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult = result = arNo case n.kind of nkRecList: @@ -39,7 +39,7 @@ proc isPartOfAux(n: PNode, b: PType, marker: var TIntSet): TAnalysisResult = result = isPartOfAux(n.sym.typ, b, marker) else: internalError(n.info, "isPartOfAux()") -proc isPartOfAux(a, b: PType, marker: var TIntSet): TAnalysisResult = +proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult = result = arNo if a == nil or b == nil: return if containsOrIncl(marker, a.id): return diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index ad5393dbd..8918888a3 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -245,13 +245,13 @@ proc lineInfoToStr(info: TLineInfo): PRope = toRope(toLinenumber(info)), toRope(toColumn(info))]) -proc treeToYamlAux(n: PNode, marker: var TIntSet, +proc treeToYamlAux(n: PNode, marker: var IntSet, indent, maxRecDepth: int): PRope -proc symToYamlAux(n: PSym, marker: var TIntSet, +proc symToYamlAux(n: PSym, marker: var IntSet, indent, maxRecDepth: int): PRope -proc typeToYamlAux(n: PType, marker: var TIntSet, +proc typeToYamlAux(n: PType, marker: var IntSet, indent, maxRecDepth: int): PRope -proc strTableToYaml(n: TStrTable, marker: var TIntSet, indent: int, +proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int, maxRecDepth: int): PRope = var istr = spaces(indent + 2) result = toRope("[") @@ -277,7 +277,7 @@ proc ropeConstr(indent: int, c: openArray[PRope]): PRope = inc(i, 2) appf(result, "$N$1}", [spaces(indent)]) -proc symToYamlAux(n: PSym, marker: var TIntSet, indent: int, +proc symToYamlAux(n: PSym, marker: var IntSet, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") @@ -298,7 +298,7 @@ proc symToYamlAux(n: PSym, marker: var TIntSet, indent: int, flagsToStr(n.options), toRope("position"), toRope(n.position)]) -proc typeToYamlAux(n: PType, marker: var TIntSet, indent: int, +proc typeToYamlAux(n: PType, marker: var IntSet, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") @@ -326,7 +326,7 @@ proc typeToYamlAux(n: PType, marker: var TIntSet, indent: int, toRope("align"), toRope(n.align), toRope("sons"), result]) -proc treeToYamlAux(n: PNode, marker: var TIntSet, indent: int, +proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") @@ -677,7 +677,7 @@ proc nextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym = ti.h = nextTry(h, high(tab.data)) proc nextIdentExcluding*(ti: var TIdentIter, tab: TStrTable, - excluding: TIntSet): PSym = + excluding: IntSet): PSym = var h: THash = ti.h and high(tab.data) var start = h result = tab.data[h] @@ -693,7 +693,7 @@ proc nextIdentExcluding*(ti: var TIdentIter, tab: TStrTable, if result != nil and contains(excluding, result.id): result = nil proc firstIdentExcluding*(ti: var TIdentIter, tab: TStrTable, s: PIdent, - excluding: TIntSet): PSym = + excluding: IntSet): PSym = ti.h = s.h ti.name = s if tab.counter == 0: result = nil diff --git a/compiler/babelcmd.nim b/compiler/babelcmd.nim index d67b1dab5..b09637330 100644 --- a/compiler/babelcmd.nim +++ b/compiler/babelcmd.nim @@ -43,7 +43,7 @@ proc `<.`(a, b: string): bool = if a[i] == '.': inc i if b[j] == '.': inc j -proc addPackage(packages: PStringTable, p: string) = +proc addPackage(packages: StringTableRef, p: string) = let x = versionSplitPos(p) let name = p.substr(0, x-1) if x < p.len: @@ -53,7 +53,7 @@ proc addPackage(packages: PStringTable, p: string) = else: packages[name] = latest -iterator chosen(packages: PStringTable): string = +iterator chosen(packages: StringTableRef): string = for key, val in pairs(packages): let res = if val == latest: key else: key & '-' & val yield res diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index 69c41ff59..9aca4b0f7 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -83,7 +83,7 @@ proc writeTypeCache(a: TIdTable, s: var string) = inc i s.add('}') -proc writeIntSet(a: TIntSet, s: var string) = +proc writeIntSet(a: IntSet, s: var string) = var i = 0 for x in items(a): if i == 10: @@ -200,7 +200,7 @@ proc readTypeCache(L: var TBaseLexer, result: var TIdTable) = idTablePut(result, newFakeType(key), value.toRope) inc L.bufpos -proc readIntSet(L: var TBaseLexer, result: var TIntSet) = +proc readIntSet(L: var TBaseLexer, result: var IntSet) = if ^L.bufpos != '{': internalError("ccgmerge: '{' expected") inc L.bufpos while ^L.bufpos != '}': diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 8c2e99339..4cb6a9977 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -162,7 +162,7 @@ proc mapReturnType(typ: PType): TCTypeKind = if skipTypes(typ, typedescInst).kind == tyArray: result = ctPtr else: result = mapType(typ) -proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope +proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope proc needsComplexAssignment(typ: PType): bool = result = containsGarbageCollectedRef(typ) @@ -228,7 +228,7 @@ proc fillResult(param: PSym) = incl(param.loc.flags, lfIndirect) param.loc.s = OnUnknown -proc getParamTypeDesc(m: BModule, t: PType, check: var TIntSet): PRope = +proc getParamTypeDesc(m: BModule, t: PType, check: var IntSet): PRope = when false: if t.Kind in {tyRef, tyPtr, tyVar}: var b = skipTypes(t.lastson, typedescInst) @@ -243,7 +243,7 @@ proc paramStorageLoc(param: PSym): TStorageLoc = result = OnUnknown proc genProcParams(m: BModule, t: PType, rettype, params: var PRope, - check: var TIntSet, declareEnvironment=true) = + check: var IntSet, declareEnvironment=true) = params = nil if (t.sons[0] == nil) or isInvalidReturnType(t.sons[0]): rettype = ~"void" @@ -370,7 +370,7 @@ proc mangleRecFieldName(field: PSym, rectype: PType): PRope = proc genRecordFieldsAux(m: BModule, n: PNode, accessExpr: PRope, rectype: PType, - check: var TIntSet): PRope = + check: var IntSet): PRope = var ae, uname, sname, a: PRope k: PNode @@ -419,11 +419,11 @@ proc genRecordFieldsAux(m: BModule, n: PNode, appf(result, "$1 $2;$n", [getTypeDescAux(m, fieldType, check), sname]) else: internalError(n.info, "genRecordFieldsAux()") -proc getRecordFields(m: BModule, typ: PType, check: var TIntSet): PRope = +proc getRecordFields(m: BModule, typ: PType, check: var IntSet): PRope = result = genRecordFieldsAux(m, typ.n, nil, typ, check) proc getRecordDesc(m: BModule, typ: PType, name: PRope, - check: var TIntSet): PRope = + check: var IntSet): PRope = # declare the record: var hasField = false @@ -461,7 +461,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope, app(result, "};" & tnl) proc getTupleDesc(m: BModule, typ: PType, name: PRope, - check: var TIntSet): PRope = + check: var IntSet): PRope = result = ropef("$1 $2 {$n", [structOrUnion(typ), name]) var desc: PRope = nil for i in countup(0, sonsLen(typ) - 1): @@ -474,7 +474,7 @@ proc getTupleDesc(m: BModule, typ: PType, name: PRope, proc pushType(m: BModule, typ: PType) = add(m.typeStack, typ) -proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = +proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope = # returns only the type's name var name, rettype, desc, recdesc: PRope diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index ea8f32974..508f98074 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -101,10 +101,10 @@ type # without extension) typeCache*: TIdTable # cache the generated types forwTypeCache*: TIdTable # cache for forward declarations of types - declaredThings*: TIntSet # things we have declared in this .c file - declaredProtos*: TIntSet # prototypes we have declared in this .c file + declaredThings*: IntSet # things we have declared in this .c file + declaredProtos*: IntSet # prototypes we have declared in this .c file headerFiles*: TLinkedList # needed headers to include - typeInfoMarker*: TIntSet # needed for generating type information + typeInfoMarker*: IntSet # needed for generating type information initProc*: BProc # code for init procedure postInitProc*: BProc # code to be executed after the init proc preInitProc*: BProc # code executed before the init proc diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 1d0cb82ad..6703b1ba5 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -115,7 +115,7 @@ proc relevantCol(methods: TSymSeq, col: int): bool = if not sameType(t2, t): return true -proc cmpSignatures(a, b: PSym, relevantCols: TIntSet): int = +proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int = for col in countup(1, sonsLen(a.typ) - 1): if contains(relevantCols, col): var aa = skipTypes(a.typ.sons[col], skipPtrs) @@ -124,7 +124,7 @@ proc cmpSignatures(a, b: PSym, relevantCols: TIntSet): int = if (d != high(int)): return d -proc sortBucket(a: var TSymSeq, relevantCols: TIntSet) = +proc sortBucket(a: var TSymSeq, relevantCols: IntSet) = # we use shellsort here; fast and simple var n = len(a) var h = 1 @@ -143,7 +143,7 @@ proc sortBucket(a: var TSymSeq, relevantCols: TIntSet) = a[j] = v if h == 1: break -proc genDispatcher(methods: TSymSeq, relevantCols: TIntSet): PSym = +proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym = var base = lastSon(methods[0].ast).sym result = base var paramLen = sonsLen(base.typ) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 28288ed39..938cc5df2 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -14,7 +14,7 @@ import # We need to use a PStringTable here as defined symbols are always guaranteed # to be style insensitive. Otherwise hell would break lose. -var gSymbols: PStringTable +var gSymbols: StringTableRef proc defineSymbol*(symbol: string) = gSymbols[symbol] = "true" diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 5c851118d..4e576867b 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -23,7 +23,7 @@ type id: int # for generating IDs toc, section: TSections indexValFilename: string - seenSymbols: PStringTable # avoids duplicate symbol generation for HTML. + seenSymbols: StringTableRef # avoids duplicate symbol generation for HTML. PDoc* = ref TDocumentor ## Alias to type less. @@ -55,7 +55,7 @@ proc parseRst(text, filename: string, result = rstParse(text, filename, line, column, hasToc, rstOptions, docgenFindFile, compilerMsgHandler) -proc newDocumentor*(filename: string, config: PStringTable): PDoc = +proc newDocumentor*(filename: string, config: StringTableRef): PDoc = new(result) initRstGenerator(result[], (if gCmd != cmdRst2tex: outHtml else: outLatex), options.gConfigVars, filename, {roSupportRawDirective}, @@ -411,7 +411,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = setIndexTerm(d[], symbolOrId, name, linkTitle, xmltree.escape(plainDocstring.docstringSummary)) -proc genJSONItem(d: PDoc, n, nameNode: PNode, k: TSymKind): PJsonNode = +proc genJSONItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonNode = if not isVisible(nameNode): return var name = getName(d, nameNode) @@ -471,7 +471,7 @@ proc generateDoc*(d: PDoc, n: PNode) = of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0]) else: discard -proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode = +proc generateJson(d: PDoc, n: PNode, jArray: JsonNode = nil): JsonNode = case n.kind of nkCommentStmt: if n.comment != nil and startsWith(n.comment, "##"): diff --git a/compiler/importer.nim b/compiler/importer.nim index 538957887..159dfa6a5 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -113,7 +113,7 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) = e = nextIdentIter(it, fromMod.tab) else: rawImportSymbol(c, s) -proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: TIntSet) = +proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) = var i: TTabIter var s = initTabIter(i, fromMod.tab) while s != nil: @@ -126,10 +126,10 @@ proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: TIntSet) = s = nextIter(i, fromMod.tab) proc importAllSymbols*(c: PContext, fromMod: PSym) = - var exceptSet: TIntSet + var exceptSet: IntSet importAllSymbolsExcept(c, fromMod, exceptSet) -proc importForwarded(c: PContext, n: PNode, exceptSet: TIntSet) = +proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet) = if n.isNil: return case n.kind of nkExportStmt: @@ -164,7 +164,7 @@ proc myImportModule(c: PContext, n: PNode): PSym = proc evalImport(c: PContext, n: PNode): PNode = result = n - var emptySet: TIntSet + var emptySet: IntSet for i in countup(0, sonsLen(n) - 1): var m = myImportModule(c, n.sons[i]) if m != nil: diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index c97adffb1..652f439a9 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -71,8 +71,8 @@ type TGlobals = object typeInfo, code: PRope forwarded: seq[PSym] - generatedSyms: TIntSet - typeInfoGenerated: TIntSet + generatedSyms: IntSet + typeInfoGenerated: IntSet PGlobals = ref TGlobals PProc = ref TProc diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 2a9b1e886..b0595a7a7 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -140,12 +140,12 @@ type fn: PSym # function that belongs to this scope; # if up.fn != fn then we cross function boundaries. # This is an important case to consider. - vars: TIntSet # variables belonging to this environment + vars: IntSet # variables belonging to this environment TOuterContext = object fn: PSym # may also be a module! head: PEnv - capturedVars, processed: TIntSet + capturedVars, processed: IntSet localsToAccess: TIdNodeTable lambdasToEnv: TIdTable # PSym->PEnv mapping diff --git a/compiler/lexer.nim b/compiler/lexer.nim index e0b3b76ce..c2587efad 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -21,10 +21,10 @@ import const MaxLineLength* = 80 # lines longer than this lead to a warning - numChars*: TCharSet = {'0'..'9', 'a'..'z', 'A'..'Z'} - SymChars*: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'} - SymStartChars*: TCharSet = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'} - OpChars*: TCharSet = {'+', '-', '*', '/', '\\', '<', '>', '!', '?', '^', '.', + numChars*: set[char] = {'0'..'9', 'a'..'z', 'A'..'Z'} + SymChars*: set[char] = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'} + SymStartChars*: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'} + OpChars*: set[char] = {'+', '-', '*', '/', '\\', '<', '>', '!', '?', '^', '.', '|', '=', '%', '&', '$', '@', '~', ':', '\x80'..'\xFF'} # don't forget to update the 'highlite' module if these charsets should change @@ -229,7 +229,7 @@ proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.fileIdx, L.lineNumber, pos - L.lineStart) msgs.message(info, msg, arg) -proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = +proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: set[char]) = var pos = L.bufpos # use registers for pos, buf var buf = L.buf while true: @@ -246,7 +246,7 @@ proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: TCharSet) = inc(pos) L.bufpos = pos -proc matchTwoChars(L: TLexer, first: char, second: TCharSet): bool = +proc matchTwoChars(L: TLexer, first: char, second: set[char]): bool = result = (L.buf[L.bufpos] == first) and (L.buf[L.bufpos + 1] in second) proc isFloatLiteral(s: string): bool = diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 9fecdba6b..9bad9de91 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -40,11 +40,8 @@ proc considerQuotedIdent*(n: PNode): PIdent = template addSym*(scope: PScope, s: PSym) = strTableAdd(scope.symbols, s) -proc addUniqueSym*(scope: PScope, s: PSym): TResult = - if strTableIncl(scope.symbols, s): - result = Failure - else: - result = Success +proc addUniqueSym*(scope: PScope, s: PSym): bool = + result = not strTableIncl(scope.symbols, s) proc openScope*(c: PContext): PScope {.discardable.} = result = PScope(parent: c.currentScope, @@ -117,7 +114,7 @@ type mode*: TOverloadIterMode symChoiceIndex*: int scope*: PScope - inSymChoice: TIntSet + inSymChoice: IntSet proc getSymRepr*(s: PSym): string = case s.kind @@ -150,14 +147,14 @@ proc wrongRedefinition*(info: TLineInfo, s: string) = localError(info, errAttemptToRedefine, s) proc addDecl*(c: PContext, sym: PSym) = - if c.currentScope.addUniqueSym(sym) == Failure: + if not c.currentScope.addUniqueSym(sym): wrongRedefinition(sym.info, sym.name.s) proc addPrelimDecl*(c: PContext, sym: PSym) = discard c.currentScope.addUniqueSym(sym) proc addDeclAt*(scope: PScope, sym: PSym) = - if scope.addUniqueSym(sym) == Failure: + if not scope.addUniqueSym(sym): wrongRedefinition(sym.info, sym.name.s) proc addInterfaceDeclAux(c: PContext, sym: PSym) = diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 43b3b6c8e..58e12bfed 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -567,7 +567,7 @@ var gErrorMax*: int = 1 # stop after gErrorMax errors when useCaas: - var stdoutSocket*: TSocket + var stdoutSocket*: Socket proc unknownLineInfo*(): TLineInfo = result.line = int16(-1) diff --git a/compiler/rodread.nim b/compiler/rodread.nim index acccc1abb..3cc37fb98 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -137,7 +137,7 @@ type line: int # only used for debugging, but is always in the code moduleID: int syms: TIdTable # already processed symbols - memfile: TMemFile # unfortunately there is no point in time where we + memfile: MemFile # unfortunately there is no point in time where we # can close this! XXX methods*: TSymSeq origFile: string diff --git a/compiler/sem.nim b/compiler/sem.nim index be71ebef8..5f2e77781 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -340,7 +340,7 @@ type TSemGenericFlags = set[TSemGenericFlag] proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags, - ctx: var TIntSet): PNode + ctx: var IntSet): PNode include semtypes, semtempl, semgnrc, semstmts, semexprs diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim new file mode 100644 index 000000000..2c77bff7b --- /dev/null +++ b/compiler/semasgn.nim @@ -0,0 +1,196 @@ +# +# +# The Nim Compiler +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements lifting for assignments and ``deepCopy``. + +# included from sem.nim + +type + TLiftCtx = object + c: PContext + info: TLineInfo # for construction + result: PNode + kind: TTypeAttachedOp + +type + TFieldInstCtx = object # either 'tup[i]' or 'field' is valid + tupleType: PType # if != nil we're traversing a tuple + tupleIndex: int + field: PSym + replaceByFieldName: bool + +proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode = + case n.kind + of nkEmpty..pred(nkIdent), succ(nkIdent)..nkNilLit: result = n + of nkIdent: + result = n + var L = sonsLen(forLoop) + if c.replaceByFieldName: + if n.ident.id == forLoop[0].ident.id: + let fieldName = if c.tupleType.isNil: c.field.name.s + elif c.tupleType.n.isNil: "Field" & $c.tupleIndex + else: c.tupleType.n.sons[c.tupleIndex].sym.name.s + result = newStrNode(nkStrLit, fieldName) + return + # other fields: + for i in ord(c.replaceByFieldName)..L-3: + if n.ident.id == forLoop[i].ident.id: + var call = forLoop.sons[L-2] + var tupl = call.sons[i+1-ord(c.replaceByFieldName)] + if c.field.isNil: + result = newNodeI(nkBracketExpr, n.info) + result.add(tupl) + result.add(newIntNode(nkIntLit, c.tupleIndex)) + else: + result = newNodeI(nkDotExpr, n.info) + result.add(tupl) + result.add(newSymNode(c.field, n.info)) + break + else: + if n.kind == nkContinueStmt: + localError(n.info, errGenerated, + "'continue' not supported in a 'fields' loop") + result = copyNode(n) + newSons(result, sonsLen(n)) + for i in countup(0, sonsLen(n)-1): + result.sons[i] = instFieldLoopBody(c, n.sons[i], forLoop) + +proc liftBodyObj(c: TLiftCtx; typ, x, y: PNode) = + case typ.kind + of nkSym: + var fc: TFieldInstCtx # either 'tup[i]' or 'field' is valid + fc.field = typ.sym + fc.replaceByFieldName = c.m == mFieldPairs + openScope(c.c) + inc c.c.inUnrolledContext + let body = instFieldLoopBody(fc, lastSon(forLoop), forLoop) + father.add(semStmt(c.c, body)) + dec c.c.inUnrolledContext + closeScope(c.c) + of nkNilLit: discard + of nkRecCase: + let L = forLoop.len + let call = forLoop.sons[L-2] + if call.len > 2: + localError(forLoop.info, errGenerated, + "parallel 'fields' iterator does not work for 'case' objects") + return + # iterate over the selector: + asgnForObjectFields(c, typ[0], forLoop, father) + # we need to generate a case statement: + var caseStmt = newNodeI(nkCaseStmt, c.info) + # generate selector: + var access = newNodeI(nkDotExpr, forLoop.info, 2) + access.sons[0] = call.sons[1] + access.sons[1] = newSymNode(typ.sons[0].sym, forLoop.info) + caseStmt.add(semExprWithType(c.c, access)) + # copy the branches over, but replace the fields with the for loop body: + for i in 1 .. 0 if we are in a user-defined type class inGenericContext*: int # > 0 if we are in a generic type @@ -83,10 +83,10 @@ type semInferredLambda*: proc(c: PContext, pt: TIdTable, n: PNode): PNode semGenerateInstance*: proc (c: PContext, fn: PSym, pt: TIdTable, info: TLineInfo): PSym - includedFiles*: TIntSet # used to detect recursive include files + includedFiles*: IntSet # used to detect recursive include files userPragmas*: TStrTable evalContext*: PEvalContext - unknownIdents*: TIntSet # ids of all unknown identifiers to prevent + unknownIdents*: IntSet # ids of all unknown identifiers to prevent # naming it multiple times generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile lastGenericIdx*: int # used for the generics stack diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index b310e0869..e2d05e15d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1816,7 +1816,7 @@ proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = addSonSkipIntLit(typ, n.sons[i].typ) result.typ = typ -proc checkInitialized(n: PNode, ids: TIntSet, info: TLineInfo) = +proc checkInitialized(n: PNode, ids: IntSet, info: TLineInfo) = case n.kind of nkRecList: for i in countup(0, sonsLen(n) - 1): diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 8d8067195..aa811e08c 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -28,7 +28,7 @@ proc getIdentNode(n: PNode): PNode = proc semGenericStmtScope(c: PContext, n: PNode, flags: TSemGenericFlags, - ctx: var TIntSet): PNode = + ctx: var IntSet): PNode = openScope(c) result = semGenericStmt(c, n, flags, ctx) closeScope(c) @@ -67,7 +67,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = else: result = newSymNode(s, n.info) proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags, - ctx: var TIntSet): PNode = + ctx: var IntSet): PNode = result = n let ident = considerQuotedIdent(n) var s = searchInScopes(c, ident).skipAlias(n) @@ -89,7 +89,7 @@ proc newDot(n, b: PNode): PNode = result.add(b) proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, - ctx: var TIntSet): PNode = + ctx: var IntSet): PNode = assert n.kind == nkDotExpr let luf = if withinMixin notin flags: {checkUndeclared} else: {} @@ -114,7 +114,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, result = newDot(result, sym) proc semGenericStmt(c: PContext, n: PNode, - flags: TSemGenericFlags, ctx: var TIntSet): PNode = + flags: TSemGenericFlags, ctx: var IntSet): PNode = result = n if gCmd == cmdIdeTools: suggestStmt(c, n) case n.kind diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 880e37fef..9d81a0771 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -71,7 +71,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode = addSon(result, newSymNode(a, n.info)) a = nextOverloadIter(o, c, n) -proc semBindStmt(c: PContext, n: PNode, toBind: var TIntSet): PNode = +proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode = for i in 0 .. < n.len: var a = n.sons[i] # If 'a' is an overloaded symbol, we used to use the first symbol @@ -91,7 +91,7 @@ proc semBindStmt(c: PContext, n: PNode, toBind: var TIntSet): PNode = illFormedAst(a) result = newNodeI(nkEmpty, n.info) -proc semMixinStmt(c: PContext, n: PNode, toMixin: var TIntSet): PNode = +proc semMixinStmt(c: PContext, n: PNode, toMixin: var IntSet): PNode = for i in 0 .. < n.len: toMixin.incl(considerQuotedIdent(n.sons[i]).id) result = newNodeI(nkEmpty, n.info) @@ -106,7 +106,7 @@ proc replaceIdentBySym(n: var PNode, s: PNode) = type TemplCtx {.pure, final.} = object c: PContext - toBind, toMixin, toInject: TIntSet + toBind, toMixin, toInject: IntSet owner: PSym proc getIdentNode(c: var TemplCtx, n: PNode): PNode = diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index c3d34f2ba..a0fe81db3 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -461,9 +461,9 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, swap(branch.sons[L-2], branch.sons[L-1]) checkForOverlap(c, t, i, branchIndex) -proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, +proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, father: PNode, rectype: PType) -proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int, +proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, father: PNode, rectype: PType) = var a = copyNode(n) checkMinSonsLen(n, 2) @@ -498,7 +498,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int, localError(a.info, errNotAllCasesCovered) addSon(father, a) -proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, +proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, father: PNode, rectype: PType) = if n == nil: return case n.kind @@ -524,7 +524,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, else: illFormedAst(n) if c.inGenericContext > 0: # use a new check intset here for each branch: - var newCheck: TIntSet + var newCheck: IntSet assign(newCheck, check) var newPos = pos var newf = newNodeI(nkRecList, n.info) @@ -578,7 +578,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, of nkEmpty: discard else: illFormedAst(n) -proc addInheritedFieldsAux(c: PContext, check: var TIntSet, pos: var int, +proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, n: PNode) = case n.kind of nkRecCase: @@ -597,7 +597,7 @@ proc addInheritedFieldsAux(c: PContext, check: var TIntSet, pos: var int, inc(pos) else: internalError(n.info, "addInheritedFieldsAux()") -proc addInheritedFields(c: PContext, check: var TIntSet, pos: var int, +proc addInheritedFields(c: PContext, check: var IntSet, pos: var int, obj: PType) = if (sonsLen(obj) > 0) and (obj.sons[0] != nil): addInheritedFields(c, check, pos, obj.sons[0]) @@ -847,7 +847,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, prev: PType, kind: TSymKind): PType = var res: PNode - cl: TIntSet + cl: IntSet checkMinSonsLen(n, 1) result = newOrPrevType(tyProc, prev, c) result.callConv = lastOptionEntry(c).defaultCC diff --git a/compiler/service.nim b/compiler/service.nim index 8e1c9cf1b..f0eeb0ed5 100644 --- a/compiler/service.nim +++ b/compiler/service.nim @@ -84,9 +84,9 @@ proc serve*(action: proc (){.nimcall.}) = of "tcp", "": when useCaas: var server = socket() - if server == invalidSocket: osError(osLastError()) + if server == invalidSocket: raiseOSError(osLastError()) let p = getConfigVar("server.port") - let port = if p.len > 0: parseInt(p).TPort else: 6000.TPort + let port = if p.len > 0: parseInt(p).Port else: 6000.Port server.bindAddr(port, getConfigVar("server.address")) var inp = "".TaintedString server.listen() diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 588628c9a..26277eb50 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1319,7 +1319,7 @@ proc incrIndexType(t: PType) = inc t.sons[0].n.sons[1].intVal proc matchesAux(c: PContext, n, nOrig: PNode, - m: var TCandidate, marker: var TIntSet) = + m: var TCandidate, marker: var IntSet) = template checkConstraint(n: expr) {.immediate, dirty.} = if not formal.constraint.isNil: if matchNodeKinds(formal.constraint, n): diff --git a/compiler/types.nim b/compiler/types.nim index c810dc025..adc03a13e 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -160,9 +160,9 @@ proc enumHasHoles(t: PType): bool = while b.kind in {tyConst, tyMutable, tyRange, tyGenericInst}: b = b.sons[0] result = b.kind == tyEnum and tfEnumHasHoles in b.flags -proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter, +proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter, closure: RootRef): bool -proc iterOverNode(marker: var TIntSet, n: PNode, iter: TTypeIter, +proc iterOverNode(marker: var IntSet, n: PNode, iter: TTypeIter, closure: RootRef): bool = if n != nil: case n.kind @@ -174,7 +174,7 @@ proc iterOverNode(marker: var TIntSet, n: PNode, iter: TTypeIter, result = iterOverNode(marker, n.sons[i], iter, closure) if result: return -proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter, +proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter, closure: RootRef): bool = result = false if t == nil: return @@ -195,10 +195,10 @@ proc iterOverType(t: PType, iter: TTypeIter, closure: RootRef): bool = result = iterOverTypeAux(marker, t, iter, closure) proc searchTypeForAux(t: PType, predicate: TTypePredicate, - marker: var TIntSet): bool + marker: var IntSet): bool proc searchTypeNodeForAux(n: PNode, p: TTypePredicate, - marker: var TIntSet): bool = + marker: var IntSet): bool = result = false case n.kind of nkRecList: @@ -220,7 +220,7 @@ proc searchTypeNodeForAux(n: PNode, p: TTypePredicate, else: internalError(n.info, "searchTypeNodeForAux()") proc searchTypeForAux(t: PType, predicate: TTypePredicate, - marker: var TIntSet): bool = + marker: var IntSet): bool = # iterates over VALUE types! result = false if t == nil: return @@ -256,7 +256,7 @@ proc isObjectWithTypeFieldPredicate(t: PType): bool = tfFinal notin t.flags proc analyseObjectWithTypeFieldAux(t: PType, - marker: var TIntSet): TTypeFieldResult = + marker: var IntSet): TTypeFieldResult = var res: TTypeFieldResult result = frNone if t == nil: return @@ -310,8 +310,8 @@ proc containsHiddenPointer(typ: PType): bool = # that need to be copied deeply) result = searchTypeFor(typ, isHiddenPointer) -proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool -proc canFormAcycleNode(marker: var TIntSet, n: PNode, startId: int): bool = +proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool +proc canFormAcycleNode(marker: var IntSet, n: PNode, startId: int): bool = result = false if n != nil: result = canFormAcycleAux(marker, n.typ, startId) @@ -324,7 +324,7 @@ proc canFormAcycleNode(marker: var TIntSet, n: PNode, startId: int): bool = result = canFormAcycleNode(marker, n.sons[i], startId) if result: return -proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool = +proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool = result = false if typ == nil: return if tfAcyclic in typ.flags: return @@ -353,9 +353,9 @@ proc canFormAcycle(typ: PType): bool = var marker = initIntSet() result = canFormAcycleAux(marker, typ, typ.id) -proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator, +proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator, closure: RootRef): PType -proc mutateNode(marker: var TIntSet, n: PNode, iter: TTypeMutator, +proc mutateNode(marker: var IntSet, n: PNode, iter: TTypeMutator, closure: RootRef): PNode = result = nil if n != nil: @@ -369,7 +369,7 @@ proc mutateNode(marker: var TIntSet, n: PNode, iter: TTypeMutator, for i in countup(0, sonsLen(n) - 1): addSon(result, mutateNode(marker, n.sons[i], iter, closure)) -proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator, +proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator, closure: RootRef): PType = result = nil if t == nil: return @@ -1012,10 +1012,10 @@ type TTypeAllowedFlags = set[TTypeAllowedFlag] -proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, +proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, flags: TTypeAllowedFlags = {}): bool -proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind, +proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind, flags: TTypeAllowedFlags = {}): bool = result = true if n != nil: @@ -1039,7 +1039,7 @@ proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]], a = a.sons[i] result = a.kind == last -proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, +proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, flags: TTypeAllowedFlags = {}): bool = assert(kind in {skVar, skLet, skConst, skParam, skResult}) # if we have already checked the type, return true, because we stop the diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 831e2ddce..acf5277c6 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -9,7 +9,7 @@ import ast, types, msgs, osproc, streams, options -proc readOutput(p: PProcess): string = +proc readOutput(p: Process): string = result = "" var output = p.outputStream discard p.waitForExit diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index f685a97e1..b21d51c93 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -66,8 +66,8 @@ proc getArgument*(n: PRstNode): string # ----------------------------- scanner part -------------------------------- const - SymChars: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'} - SmileyStartChars: TCharSet = {':', ';', '8'} + SymChars: set[char] = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'} + SmileyStartChars: set[char] = {':', ';', '8'} Smilies = { ":D": "icon_e_biggrin", ":-D": "icon_e_biggrin", @@ -111,7 +111,7 @@ const type TTokType = enum tkEof, tkIndent, tkWhite, tkWord, tkAdornment, tkPunct, tkOther - TToken{.final.} = object # a RST token + TToken = object # a RST token kind*: TTokType # the type of the token ival*: int # the indentation or parsed integer value symbol*: string # the parsed symbol as string @@ -125,7 +125,7 @@ type skipPounds*: bool -proc getThing(L: var TLexer, tok: var TToken, s: TCharSet) = +proc getThing(L: var TLexer, tok: var TToken, s: set[char]) = tok.kind = tkWord tok.line = L.line tok.col = L.col diff --git a/lib/packages/docutils/rstast.nim b/lib/packages/docutils/rstast.nim index 7b781ad6a..52af672df 100644 --- a/lib/packages/docutils/rstast.nim +++ b/lib/packages/docutils/rstast.nim @@ -286,7 +286,7 @@ proc renderRstToRst*(n: PRstNode, result: var string) = var d: TRenderContext renderRstToRst(d, n, result) -proc renderRstToJsonNode(node: PRstNode): PJsonNode = +proc renderRstToJsonNode(node: PRstNode): JsonNode = result = %[ (key: "kind", val: %($node.kind)), @@ -295,7 +295,7 @@ proc renderRstToJsonNode(node: PRstNode): PJsonNode = if node.text != nil: result.add("text", %node.text) if node.sons != nil and len(node.sons) > 0: - var accm = newSeq[PJsonNode](len(node.sons)) + var accm = newSeq[JsonNode](len(node.sons)) for i, son in node.sons: accm[i] = renderRstToJsonNode(son) result.add("sons", %accm) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index e1bf1f649..02b0afd2f 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -35,7 +35,7 @@ type outHtml, # output is HTML outLatex # output is Latex - TTocEntry{.final.} = object + TTocEntry = object n*: PRstNode refname*, header*: string @@ -44,7 +44,7 @@ type TRstGenerator* = object of RootObj target*: TOutputTarget - config*: PStringTable + config*: StringTableRef splitAfter*: int # split too long entries in the TOC tocPart*: seq[TTocEntry] hasToc*: bool @@ -57,21 +57,21 @@ type currentSection: string ## \ ## Stores the empty string or the last headline/overline found in the rst ## document, so it can be used as a prettier name for term index generation. - seenIndexTerms: TTable[string, int] ## \ + seenIndexTerms: Table[string, int] ## \ ## Keeps count of same text index terms to generate different identifiers ## for hyperlinks. See renderIndexTerm proc for details. PDoc = var TRstGenerator ## Alias to type less. proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, - config: PStringTable, filename: string, + config: StringTableRef, filename: string, options: TRstParseOptions, findFile: TFindFileHandler, msgHandler: TMsgHandler) = ## Initializes a ``TRstGenerator``. ## ## You need to call this before using a ``TRstGenerator`` with any other - ## procs in this module. Pass a non ``nil`` ``PStringTable`` value as + ## procs in this module. Pass a non ``nil`` ``StringTableRef`` value as ## `config` with parameters used by the HTML output generator. If you don't ## know what to use, pass the results of the `defaultConfig() ## <#defaultConfig>_` proc. @@ -341,13 +341,13 @@ proc renderIndexTerm*(d: PDoc, n: PRstNode, result: var string) = [id, term]) type - TIndexEntry {.pure, final.} = object + TIndexEntry = object keyword: string link: string linkTitle: string ## If not nil, contains a prettier text for the href linkDesc: string ## If not nil, the title attribute of the final href - TIndexedDocs {.pure, final.} = TTable[TIndexEntry, seq[TIndexEntry]] ## \ + TIndexedDocs = Table[TIndexEntry, seq[TIndexEntry]] ## \ ## Contains the index sequences for doc types. ## ## The key is a *fake* TIndexEntry which will contain the title of the @@ -1048,10 +1048,10 @@ proc formatNamedVars*(frmt: string, varnames: openArray[string], if i-1 >= start: add(result, substr(frmt, start, i - 1)) -proc defaultConfig*(): PStringTable = +proc defaultConfig*(): StringTableRef = ## Returns a default configuration for embedded HTML generation. ## - ## The returned ``PStringTable`` contains the paramters used by the HTML + ## The returned ``StringTableRef`` contains the paramters used by the HTML ## engine to build the final output. For information on what these parameters ## are and their purpose, please look up the file ``config/nimdoc.cfg`` ## bundled with the compiler. @@ -1113,7 +1113,7 @@ $content # ---------- forum --------------------------------------------------------- proc rstToHtml*(s: string, options: TRstParseOptions, - config: PStringTable): string = + config: StringTableRef): string = ## Converts an input rst string into embeddable HTML. ## ## This convenience proc parses any input string using rst markup (it doesn't From be813d205f6a2d53334f11b4d2e2d88965a5c13f Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 00:16:12 +0200 Subject: [PATCH 036/409] updated db_sqlite.nim --- lib/impure/db_sqlite.nim | 40 ++++++++++++++++++++-------------------- lib/wrappers/sqlite3.nim | 6 +++--- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 844e5d07e..bc9e0b591 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -16,13 +16,13 @@ type TDbConn* = PSqlite3 ## encapsulates a database connection TRow* = seq[string] ## a row of a dataset. NULL database values will be ## transformed always to the empty string. - EDb* = object of EIO ## exception that is raised if a database error occurs + EDb* = object of IOError ## exception that is raised if a database error occurs TSqlQuery* = distinct string ## an SQL query string - FDb* = object of FIO ## effect that denotes a database operation - FReadDb* = object of FDB ## effect that denotes a read operation - FWriteDb* = object of FDB ## effect that denotes a write operation + FDb* = object of IOEffect ## effect that denotes a database operation + FReadDb* = object of FDb ## effect that denotes a read operation + FWriteDb* = object of FDb ## effect that denotes a write operation proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} = ## constructs a TSqlQuery from the string `query`. This is supposed to be @@ -65,16 +65,16 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string = add(result, c) proc tryExec*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} = + args: varargs[string, `$`]): bool {.tags: [FReadDb, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) - var stmt: sqlite3.PStmt + var stmt: sqlite3.Pstmt if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK: if step(stmt) == SQLITE_DONE: result = finalize(stmt) == SQLITE_OK proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. - tags: [FReadDB, FWriteDb].} = + tags: [FReadDb, FWriteDb].} = ## executes the query and raises EDB if not successful. if not tryExec(db, query, args): dbError(db) @@ -83,11 +83,11 @@ proc newRow(L: int): TRow = for i in 0..L-1: result[i] = "" proc setupQuery(db: TDbConn, query: TSqlQuery, - args: varargs[string]): PStmt = + args: varargs[string]): Pstmt = var q = dbFormat(query, args) if prepare_v2(db, q, q.len.cint, result, nil) != SQLITE_OK: dbError(db) -proc setRow(stmt: PStmt, r: var TRow, cols: cint) = +proc setRow(stmt: Pstmt, r: var TRow, cols: cint) = for col in 0..cols-1: setLen(r[col], column_bytes(stmt, col)) # set capacity setLen(r[col], 0) @@ -95,12 +95,12 @@ proc setRow(stmt: PStmt, r: var TRow, cols: cint) = if not isNil(x): add(r[col], x) iterator fastRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = + args: varargs[string, `$`]): TRow {.tags: [FReadDb].} = ## executes the query and iterates over the result dataset. This is very ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For Sqlite it is safe though. var stmt = setupQuery(db, query, args) - var L = (columnCount(stmt)) + var L = (column_count(stmt)) var result = newRow(L) while step(stmt) == SQLITE_ROW: setRow(stmt, result, L) @@ -108,30 +108,30 @@ iterator fastRows*(db: TDbConn, query: TSqlQuery, if finalize(stmt) != SQLITE_OK: dbError(db) proc getRow*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = + args: varargs[string, `$`]): TRow {.tags: [FReadDb].} = ## retrieves a single row. If the query doesn't return any rows, this proc ## will return a TRow with empty strings for each column. var stmt = setupQuery(db, query, args) - var L = (columnCount(stmt)) + var L = (column_count(stmt)) result = newRow(L) if step(stmt) == SQLITE_ROW: setRow(stmt, result, L) if finalize(stmt) != SQLITE_OK: dbError(db) proc getAllRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = + args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDb].} = ## executes the query and returns the whole result dataset. result = @[] for r in fastRows(db, query, args): result.add(r) iterator rows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = + args: varargs[string, `$`]): TRow {.tags: [FReadDb].} = ## same as `FastRows`, but slower and safe. for r in fastRows(db, query, args): yield r proc getValue*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): string {.tags: [FReadDB].} = + args: varargs[string, `$`]): string {.tags: [FReadDb].} = ## executes the query and returns the first column of the first row of the ## result dataset. Returns "" if the dataset contains no rows or the database ## value is NULL. @@ -153,7 +153,7 @@ proc tryInsertID*(db: TDbConn, query: TSqlQuery, ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. var q = dbFormat(query, args) - var stmt: sqlite3.PStmt + var stmt: sqlite3.Pstmt result = -1 if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK: if step(stmt) == SQLITE_DONE: @@ -172,18 +172,18 @@ proc insertID*(db: TDbConn, query: TSqlQuery, proc execAffectedRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {. - tags: [FReadDB, FWriteDb].} = + tags: [FReadDb, FWriteDb].} = ## executes the query (typically "UPDATE") and returns the ## number of affected rows. exec(db, query, args) result = changes(db) -proc close*(db: TDbConn) {.tags: [FDB].} = +proc close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. if sqlite3.close(db) != SQLITE_OK: dbError(db) proc open*(connection, user, password, database: string): TDbConn {. - tags: [FDB].} = + tags: [FDb].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. Only the ``connection`` parameter is used for ``sqlite``. var db: TDbConn diff --git a/lib/wrappers/sqlite3.nim b/lib/wrappers/sqlite3.nim index e817cd9ee..c8bce712d 100644 --- a/lib/wrappers/sqlite3.nim +++ b/lib/wrappers/sqlite3.nim @@ -178,15 +178,15 @@ proc errcode*(db: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_errcod proc errmsg*(para1: PSqlite3): cstring{.cdecl, dynlib: Lib, importc: "sqlite3_errmsg".} proc errmsg16*(para1: PSqlite3): pointer{.cdecl, dynlib: Lib, importc: "sqlite3_errmsg16".} -proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var PStmt, +proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var Pstmt, pzTail: ptr cstring): int32{.cdecl, dynlib: Lib, importc: "sqlite3_prepare".} -proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var PStmt, +proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var Pstmt, pzTail: ptr cstring): cint {. importc: "sqlite3_prepare_v2", cdecl, dynlib: Lib.} -proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var PStmt, +proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var Pstmt, pzTail: var pointer): int32{.cdecl, dynlib: Lib, importc: "sqlite3_prepare16".} proc bind_blob*(para1: Pstmt, para2: int32, para3: pointer, n: int32, From 6d40288bb832da8b1912a0ddbbc65bf865e28131 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 00:56:34 +0200 Subject: [PATCH 037/409] renamed Byte to byte --- lib/system.nim | 2 +- lib/system/mmdisp.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 1de9e23c7..082b3ad40 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -308,7 +308,7 @@ when not defined(JS) and not defined(NimrodVM): include "system/hti" type - Byte* = uint8 ## this is an alias for ``uint8``, that is an unsigned + byte* = uint8 ## this is an alias for ``uint8``, that is an unsigned ## int 8 bits wide. Natural* = range[0..high(int)] diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 803c1f5c0..62106c7d7 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -34,7 +34,7 @@ const type PPointer = ptr pointer - TByteArray = array[0..1000_0000, Byte] + TByteArray = array[0..1000_0000, byte] PByte = ptr TByteArray PString = ptr string From 051b9ca0cee4ea5ebee78f6fe3c3aa0ff1528ad8 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 00:57:02 +0200 Subject: [PATCH 038/409] made windows.nim compatible with --cs:partial --- lib/windows/windows.nim | 456 ++++++++++++++++++++-------------------- 1 file changed, 228 insertions(+), 228 deletions(-) diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim index 32641b8fe..f5b69402a 100644 --- a/lib/windows/windows.nim +++ b/lib/windows/windows.nim @@ -49,15 +49,15 @@ type # BaseTsd.h -- Type definitions for the basic sized types DWORD64* = int64 PDWORD64* = ptr DWORD64 # int32 on Win32, int64 on Win64 - INT_PTR* = TAddress - UINT_PTR* = TAddress - LONG_PTR* = TAddress - ULONG_PTR* = TAddress - SIZE_T* = TAddress - SSIZE_T* = TAddress - DWORD_PTR* = TAddress + INT_PTR* = ByteAddress + UINT_PTR* = ByteAddress + LONG_PTR* = ByteAddress + ULONG_PTR* = ByteAddress + SIZE_T* = ByteAddress + SSIZE_T* = ByteAddress + DWORD_PTR* = ByteAddress # Thread affinity - KAFFINITY* = TAddress + KAFFINITY* = ByteAddress PKAFFINITY* = ptr KAFFINITY type # WinDef.h -- Basic Windows Type Definitions @@ -74,8 +74,8 @@ type # WinDef.h -- Basic Windows Type Definitions DWORD* = int32 WINBOOL* = int32 WORD* = int16 - # FLOAT* = float - PFLOAT* = ptr FLOAT + #FLOAT* = float + PFLOAT* = ptr float32 PWINBOOL* = ptr WINBOOL LPWINBOOL* = ptr WINBOOL PBYTE* = ptr int8 @@ -383,7 +383,7 @@ type stdcall.} LPCFHOOKPROC* = proc (para1: HWND, para2: WINUINT, para3: WPARAM, para4: LPARAM): WINUINT{. stdcall.} - PTHREAD_START_ROUTINE* = Pointer + PTHREAD_START_ROUTINE* = pointer LPTHREAD_START_ROUTINE* = PTHREAD_START_ROUTINE EDITSTREAMCALLBACK* = proc (para1: DWORD, para2: LPBYTE, para3: LONG, para4: LONG): DWORD{.stdcall.} @@ -8415,34 +8415,34 @@ type # dmDisplayFixedOutput: DWORD; LPDEVMODE* = ptr DEVMODE - devicemode* = DEVMODE - tdevicemode* = DEVMODE - tdevicemodeA* = DEVMODE + Devicemode* = DEVMODE + TDevicemode* = DEVMODE + TDevicemodeA* = DEVMODE PDeviceModeA* = LPDEVMODE PDeviceMode* = LPDEVMODE TDEVMODE* = DEVMODE PDEVMODE* = LPDEVMODE - devmodeW* {.final, pure.} = object + DEVMODEW* {.final, pure.} = object dmDeviceName*: array[0..CCHDEVICENAME - 1, WCHAR] dmSpecVersion*: int16 dmDriverVersion*: int16 dmSize*: int16 dmDriverExtra*: int16 dmFields*: DWORD - dmOrientation*: short - dmPaperSize*: short - dmPaperLength*: short - dmPaperWidth*: short - dmScale*: short - dmCopies*: short - dmDefaultSource*: short - dmPrintQuality*: short - dmColor*: short - dmDuplex*: short - dmYResolution*: short - dmTTOption*: short - dmCollate*: short - dmFormName*: array[0..CCHFORMNAME - 1, wchar] + dmOrientation*: SHORT + dmPaperSize*: SHORT + dmPaperLength*: SHORT + dmPaperWidth*: SHORT + dmScale*: SHORT + dmCopies*: SHORT + dmDefaultSource*: SHORT + dmPrintQuality*: SHORT + dmColor*: SHORT + dmDuplex*: SHORT + dmYResolution*: SHORT + dmTTOption*: SHORT + dmCollate*: SHORT + dmFormName*: array[0..CCHFORMNAME - 1, WCHAR] dmLogPixels*: int16 dmBitsPerPel*: DWORD dmPelsWidth*: DWORD @@ -8459,7 +8459,7 @@ type dmPanningHeight*: DWORD LPDEVMODEW* = ptr DEVMODEW - devicemodeW* = DEVMODEW + DevicemodeW* = DEVMODEW TDeviceModeW* = DEVMODEW PDeviceModeW* = LPDEVMODEW TDEVMODEW* = DEVMODEW @@ -8497,7 +8497,7 @@ type LARGE_INTEGER* = int64 ULARGE_INTEGER* = int64 PLARGE_INTEGER* = ptr LARGE_INTEGER - TLargeInteger* = Int64 + TLargeInteger* = int64 PULARGE_INTEGER* = ptr ULARGE_INTEGER TULargeInteger* = int64 DISK_GEOMETRY* {.final, pure.} = object @@ -10469,7 +10469,7 @@ type ncb_name*: array[0..(NCBNAMSZ) - 1, UCHAR] ncb_rto*: UCHAR ncb_sto*: UCHAR - ncb_post*: proc (para1: p_NCB){.CDECL.} + ncb_post*: proc (para1: p_NCB){.cdecl.} ncb_lana_num*: UCHAR ncb_cmd_cplt*: UCHAR ncb_reserve*: array[0..9, UCHAR] @@ -10681,7 +10681,7 @@ type nErrCode*: int16 Reserved1*: int16 Reserved2*: int16 - szPathName*: array[0..(OFS_MAXPATHNAME) - 1, CHAR] + szPathName*: array[0..(OFS_MAXPATHNAME) - 1, char] LPOFSTRUCT* = ptr OFSTRUCT TOFSTRUCT* = OFSTRUCT @@ -10733,8 +10733,8 @@ type lpfnHook*: LPOFNHOOKPROC lpTemplateName*: LPCTSTR pvReserved*: pointer - dwreserved*: dword - FlagsEx*: dword + dwreserved*: DWORD + FlagsEx*: DWORD LPOPENFILENAME* = ptr TOPENFILENAME POPENFILENAME* = ptr TOPENFILENAME @@ -11280,8 +11280,8 @@ type dwSize*: DWORD hrasconn*: HRASCONN szEntryName*: array[0..(RAS_MaxEntryName + 1) - 1, TCHAR] - szDeviceType*: array[0..(RAS_MaxDeviceType + 1) - 1, CHAR] - szDeviceName*: array[0..(RAS_MaxDeviceName + 1) - 1, CHAR] + szDeviceType*: array[0..(RAS_MaxDeviceType + 1) - 1, char] + szDeviceName*: array[0..(RAS_MaxDeviceName + 1) - 1, char] TRASCONN* = RASCONN PRASCONN* = ptr RASCONN @@ -11344,9 +11344,9 @@ type TRASPPPNBF* = RASPPPNBF PRASPPPNBF* = ptr RASPPPNBF RASTERIZER_STATUS* {.final, pure.} = object - nSize*: short - wFlags*: short - nLanguageID*: short + nSize*: SHORT + wFlags*: SHORT + nLanguageID*: SHORT LPRASTERIZER_STATUS* = ptr RASTERIZER_STATUS TRASTERIZERSTATUS* = RASTERIZER_STATUS @@ -11592,7 +11592,7 @@ type PSTRRET* = ptr STRRET STYLEBUF* {.final, pure.} = object dwStyle*: DWORD - szDescription*: array[0..31, CHAR] + szDescription*: array[0..31, char] LPSTYLEBUF* = ptr STYLEBUF TSTYLEBUF* = STYLEBUF @@ -11801,7 +11801,7 @@ type TTOGGLEKEYS* = TOGGLEKEYS PTOGGLEKEYS* = ptr TOGGLEKEYS TTOKEN_SOURCE* {.final, pure.} = object - SourceName*: array[0..7, CHAR] + SourceName*: array[0..7, char] SourceIdentifier*: LUID PTOKENSOURCE* = ptr TTOKEN_SOURCE @@ -12366,7 +12366,7 @@ type uFlags*: WINUINT uCallbackMessage*: WINUINT hIcon*: HICON - szTip*: array[0..63, Char] + szTip*: array[0..63, char] NOTIFYICONDATA* = NOTIFYICONDATAA NOTIFYICONDATAW* {.final, pure.} = object @@ -13575,7 +13575,7 @@ type TWMSysKeyUp* = TWMKey TWMMenuChar* {.final, pure.} = object Msg*: WINUINT - User*: Char + User*: char MenuFlag*: int16 Menu*: HMENU Result*: LRESULT @@ -14432,19 +14432,19 @@ proc CharNextA*(lpsz: LPCSTR): LPSTR{.stdcall, dynlib: "user32", importc: "CharNextA".} proc CharPrevA*(lpszStart: LPCSTR, lpszCurrent: LPCSTR): LPSTR{.stdcall, dynlib: "user32", importc: "CharPrevA".} -proc IsCharAlphaA*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", +proc IsCharAlphaA*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharAlphaA".} -proc IsCharAlphaNumericA*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", +proc IsCharAlphaNumericA*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharAlphaNumericA".} -proc IsCharUpperA*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", +proc IsCharUpperA*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharUpperA".} -proc IsCharLowerA*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", +proc IsCharLowerA*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharLowerA".} proc GetKeyNameTextA*(lParam: LONG, lpString: LPSTR, nSize: int32): int32{. stdcall, dynlib: "user32", importc: "GetKeyNameTextA".} -proc VkKeyScanA*(ch: CHAR): SHORT{.stdcall, dynlib: "user32", +proc VkKeyScanA*(ch: char): SHORT{.stdcall, dynlib: "user32", importc: "VkKeyScanA".} -proc VkKeyScanExA*(ch: CHAR, dwhkl: HKL): SHORT{.stdcall, dynlib: "user32", +proc VkKeyScanExA*(ch: char, dwhkl: HKL): SHORT{.stdcall, dynlib: "user32", importc: "VkKeyScanExA".} proc MapVirtualKeyA*(uCode: WINUINT, uMapType: WINUINT): WINUINT{.stdcall, dynlib: "user32", importc: "MapVirtualKeyA".} @@ -14772,7 +14772,7 @@ proc DialogBoxA*(hInstance: HINST, lpTemplateName: LPCSTR, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 proc DialogBoxIndirectA*(hInstance: HINST, hDialogTemplate: LPCDLGTEMPLATE, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 -proc CreateDCA*(para1: LPCSTR, para2: LPCSTR, para3: LPCSTR, para4: pDEVMODE): HDC{. +proc CreateDCA*(para1: LPCSTR, para2: LPCSTR, para3: LPCSTR, para4: PDEVMODE): HDC{. stdcall, dynlib: "gdi32", importc: "CreateDCA".} proc VerInstallFileA*(uFlags: DWORD, szSrcFileName: LPSTR, szDestFileName: LPSTR, szSrcDir: LPSTR, szDestDir: LPSTR, @@ -14933,7 +14933,7 @@ proc WriteConsoleOutputCharacterA*(hConsoleOutput: HANDLE, lpCharacter: LPCSTR, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputCharacterA".} -proc FillConsoleOutputCharacterA*(hConsoleOutput: HANDLE, cCharacter: CHAR, +proc FillConsoleOutputCharacterA*(hConsoleOutput: HANDLE, cCharacter: char, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FillConsoleOutputCharacterA".} @@ -15896,7 +15896,7 @@ proc DialogBoxW*(hInstance: HINST, lpTemplate: LPCWSTR, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 proc DialogBoxIndirectW*(hInstance: HINST, lpTemplate: LPCDLGTEMPLATE, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 -proc CreateDCW*(para1: LPCWSTR, para2: LPCWSTR, para3: LPCWSTR, para4: pDEVMODEW): HDC{. +proc CreateDCW*(para1: LPCWSTR, para2: LPCWSTR, para3: LPCWSTR, para4: PDEVMODEW): HDC{. stdcall, dynlib: "gdi32", importc: "CreateDCW".} proc VerInstallFileW*(uFlags: DWORD, szSrcFileName: LPWSTR, szDestFileName: LPWSTR, szSrcDir: LPWSTR, @@ -17038,7 +17038,7 @@ when defined(winUnicode): lpDialogFunc: DLGPROC): int32 proc DialogBoxIndirect*(hInstance: HINST, lpTemplate: LPCDLGTEMPLATE, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 - proc CreateDC*(para1: LPCWSTR, para2: LPCWSTR, para3: LPCWSTR, para4: pDEVMODE): HDC{. + proc CreateDC*(para1: LPCWSTR, para2: LPCWSTR, para3: LPCWSTR, para4: PDEVMODE): HDC{. stdcall, dynlib: "gdi32", importc: "CreateDCW".} proc VerInstallFile*(uFlags: DWORD, szSrcFileName: LPWSTR, szDestFileName: LPWSTR, szSrcDir: LPWSTR, @@ -17825,19 +17825,19 @@ else: importc: "CharNextA".} proc CharPrev*(lpszStart: LPCSTR, lpszCurrent: LPCSTR): LPSTR{.stdcall, dynlib: "user32", importc: "CharPrevA".} - proc IsCharAlpha*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", + proc IsCharAlpha*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharAlphaA".} - proc IsCharAlphaNumeric*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", + proc IsCharAlphaNumeric*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharAlphaNumericA".} - proc IsCharUpper*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", + proc IsCharUpper*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharUpperA".} - proc IsCharLower*(ch: CHAR): WINBOOL{.stdcall, dynlib: "user32", + proc IsCharLower*(ch: char): WINBOOL{.stdcall, dynlib: "user32", importc: "IsCharLowerA".} proc GetKeyNameText*(lParam: LONG, lpString: LPSTR, nSize: int32): int32{. stdcall, dynlib: "user32", importc: "GetKeyNameTextA".} - proc VkKeyScan*(ch: CHAR): SHORT{.stdcall, dynlib: "user32", + proc VkKeyScan*(ch: char): SHORT{.stdcall, dynlib: "user32", importc: "VkKeyScanA".} - proc VkKeyScanEx*(ch: CHAR, dwhkl: HKL): SHORT{.stdcall, dynlib: "user32", + proc VkKeyScanEx*(ch: char, dwhkl: HKL): SHORT{.stdcall, dynlib: "user32", importc: "VkKeyScanExA".} proc MapVirtualKey*(uCode: WINUINT, uMapType: WINUINT): WINUINT{.stdcall, dynlib: "user32", importc: "MapVirtualKeyA".} @@ -18170,7 +18170,7 @@ else: lpDialogFunc: DLGPROC): int32 proc DialogBoxIndirect*(hInstance: HINST, hDialogTemplate: LPCDLGTEMPLATE, hWndParent: HWND, lpDialogFunc: DLGPROC): int32 - proc CreateDC*(para1: LPCSTR, para2: LPCSTR, para3: LPCSTR, para4: pDEVMODE): HDC{. + proc CreateDC*(para1: LPCSTR, para2: LPCSTR, para3: LPCSTR, para4: PDEVMODE): HDC{. stdcall, dynlib: "gdi32", importc: "CreateDCA".} proc VerInstallFile*(uFlags: DWORD, szSrcFileName: LPSTR, szDestFileName: LPSTR, szSrcDir: LPSTR, szDestDir: LPSTR, @@ -18332,7 +18332,7 @@ else: nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputCharacterA".} - proc FillConsoleOutputCharacter*(hConsoleOutput: HANDLE, cCharacter: CHAR, + proc FillConsoleOutputCharacter*(hConsoleOutput: HANDLE, cCharacter: char, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FillConsoleOutputCharacterA".} @@ -18513,9 +18513,9 @@ proc DisableThreadLibraryCalls*(hLibModule: HMODULE): WINBOOL{.stdcall, proc GetProcAddress*(hModule: HINST, lpProcName: LPCSTR): FARPROC{.stdcall, dynlib: "kernel32", importc: "GetProcAddress".} proc GetVersion*(): DWORD{.stdcall, dynlib: "kernel32", importc: "GetVersion".} -proc GlobalAlloc*(uFlags: INT, dwBytes: DWORD): HGLOBAL{.stdcall, +proc GlobalAlloc*(uFlags: int32, dwBytes: DWORD): HGLOBAL{.stdcall, dynlib: "kernel32", importc: "GlobalAlloc".} -proc GlobalReAlloc*(hMem: HGLOBAL, dwBytes: DWORD, uFlags: INT): HGLOBAL{. +proc GlobalReAlloc*(hMem: HGLOBAL, dwBytes: DWORD, uFlags: int32): HGLOBAL{. stdcall, dynlib: "kernel32", importc: "GlobalReAlloc".} proc GlobalSize*(hMem: HGLOBAL): DWORD{.stdcall, dynlib: "kernel32", importc: "GlobalSize".} @@ -19678,7 +19678,7 @@ proc GetSysColor*(nIndex: int32): DWORD{.stdcall, dynlib: "user32", importc: "GetSysColor".} proc GetSysColorBrush*(nIndex: int32): HBRUSH{.stdcall, dynlib: "user32", importc: "GetSysColorBrush".} -proc SetSysColors*(cElements: int32, lpaElements: var wINT, +proc SetSysColors*(cElements: int32, lpaElements: var WINT, lpaRgbValues: var COLORREF): WINBOOL{.stdcall, dynlib: "user32", importc: "SetSysColors".} proc DrawFocusRect*(hDC: HDC, lprc: var RECT): WINBOOL{.stdcall, @@ -19878,7 +19878,7 @@ proc CreatePen*(para1: int32, para2: int32, para3: COLORREF): HPEN{.stdcall, dynlib: "gdi32", importc: "CreatePen".} proc CreatePenIndirect*(para1: var LOGPEN): HPEN{.stdcall, dynlib: "gdi32", importc: "CreatePenIndirect".} -proc CreatePolyPolygonRgn*(para1: var POINT, para2: var wINT, para3: int32, +proc CreatePolyPolygonRgn*(para1: var POINT, para2: var WINT, para3: int32, para4: int32): HRGN{.stdcall, dynlib: "gdi32", importc: "CreatePolyPolygonRgn".} proc CreatePatternBrush*(para1: HBITMAP): HBRUSH{.stdcall, dynlib: "gdi32", @@ -20049,7 +20049,7 @@ proc PlayMetaFile*(para1: HDC, para2: HMETAFILE): WINBOOL{.stdcall, dynlib: "gdi32", importc: "PlayMetaFile".} proc PaintRgn*(para1: HDC, para2: HRGN): WINBOOL{.stdcall, dynlib: "gdi32", importc: "PaintRgn".} -proc PolyPolygon*(para1: HDC, para2: var POINT, para3: var wINT, para4: int32): WINBOOL{. +proc PolyPolygon*(para1: HDC, para2: var POINT, para3: var WINT, para4: int32): WINBOOL{. stdcall, dynlib: "gdi32", importc: "PolyPolygon".} proc PtInRegion*(para1: HRGN, para2: int32, para3: int32): WINBOOL{.stdcall, dynlib: "gdi32", importc: "PtInRegion".} @@ -20165,7 +20165,7 @@ proc GetEnhMetaFilePaletteEntries*(para1: HENHMETAFILE, para2: WINUINT, proc GetEnhMetaFileBits*(para1: HENHMETAFILE, para2: WINUINT, para3: LPBYTE): WINUINT{. stdcall, dynlib: "gdi32", importc: "GetEnhMetaFileBits".} proc GetWinMetaFileBits*(para1: HENHMETAFILE, para2: WINUINT, para3: LPBYTE, - para4: wINT, para5: HDC): WINUINT{.stdcall, + para4: WINT, para5: HDC): WINUINT{.stdcall, dynlib: "gdi32", importc: "GetWinMetaFileBits".} proc PlayEnhMetaFile*(para1: HDC, para2: HENHMETAFILE, para3: RECT): WINBOOL{. stdcall, dynlib: "gdi32", importc: "PlayEnhMetaFile".} @@ -20748,7 +20748,7 @@ proc ListView_GetColumn*(wnd: HWND, iCol: int32, col: var LV_COLUMN): LRESULT proc ListView_GetColumnWidth*(wnd: HWND, iCol: int32): LRESULT proc ListView_GetCountPerPage*(hwndLV: HWND): LRESULT proc ListView_GetEditControl*(hwndLV: HWND): LRESULT -proc ListView_GetImageList*(wnd: HWND, iImageList: wINT): LRESULT +proc ListView_GetImageList*(wnd: HWND, iImageList: WINT): LRESULT proc ListView_GetISearchString*(hwndLV: HWND, lpsz: LPTSTR): LRESULT proc ListView_GetItem*(wnd: HWND, item: var LV_ITEM): LRESULT proc ListView_GetItemCount*(wnd: HWND): LRESULT @@ -20867,13 +20867,13 @@ proc CommDlg_OpenSave_HideControl*(hdlg: HWND, id: int32): LRESULT proc CommDlg_OpenSave_SetDefExt*(hdlg: HWND, pszext: LPSTR): LRESULT proc GetNextWindow*(wnd: HWND, uCmd: WINUINT): HWND{.stdcall, dynlib: "user32", importc: "GetWindow".} -proc GlobalAllocPtr*(flags, cb: DWord): Pointer -proc GlobalFreePtr*(lp: Pointer): Pointer -proc GlobalUnlockPtr*(lp: pointer): Pointer -proc GlobalLockPtr*(lp: pointer): Pointer -proc GlobalReAllocPtr*(lp: Pointer, cbNew, flags: DWord): Pointer -proc GlobalPtrHandle*(lp: pointer): Pointer -proc SetLayeredWindowAttributes*(HWND: hwnd, crKey: COLORREF, bAlpha: int8, +proc GlobalAllocPtr*(flags, cb: DWord): pointer +proc GlobalFreePtr*(lp: pointer): pointer +proc GlobalUnlockPtr*(lp: pointer): pointer +proc GlobalLockPtr*(lp: pointer): pointer +proc GlobalReAllocPtr*(lp: pointer, cbNew, flags: DWord): pointer +proc GlobalPtrHandle*(lp: pointer): pointer +proc SetLayeredWindowAttributes*(hwnd: HWND, crKey: COLORREF, bAlpha: int8, dwFlags: DWORD): WINBOOL{.stdcall, dynlib: "user32", importc: "SetLayeredWindowAttributes".} type @@ -21059,21 +21059,21 @@ proc AllocateAndInitializeSid*(pIdentifierAuthority: TSIDIdentifierAuthority, nSubAuthorityCount: int8, nSubAuthority0, nSubAuthority1: DWORD, nSubAuthority2, nSubAuthority3, nSubAuthority4: DWORD, nSubAuthority5, - nSubAuthority6, nSubAuthority7: DWORD, pSid: var Pointer): WINBOOL{.stdcall, + nSubAuthority6, nSubAuthority7: DWORD, pSid: var pointer): WINBOOL{.stdcall, dynlib: "advapi32", importc: "AllocateAndInitializeSid".} proc AllocateLocallyUniqueId*(Luid: var TLargeInteger): WINBOOL{.stdcall, dynlib: "advapi32", importc: "AllocateLocallyUniqueId".} proc BackupRead*(hFile: THandle, lpBuffer: PByte, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: var DWORD, bAbort: WINBOOL, - bProcessSecurity: WINBOOL, lpContext: var Pointer): WINBOOL{. + bProcessSecurity: WINBOOL, lpContext: var pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "BackupRead".} proc BackupSeek*(hFile: THandle, dwLowBytesToSeek, dwHighBytesToSeek: DWORD, lpdwLowByteSeeked, lpdwHighByteSeeked: var DWORD, - lpContext: Pointer): WINBOOL{.stdcall, dynlib: "kernel32", + lpContext: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "BackupSeek".} proc BackupWrite*(hFile: THandle, lpBuffer: PByte, nNumberOfBytesToWrite: DWORD, lpNumberOfBytesWritten: var DWORD, - bAbort, bProcessSecurity: WINBOOL, lpContext: var Pointer): WINBOOL{. + bAbort, bProcessSecurity: WINBOOL, lpContext: var pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "BackupWrite".} proc BeginPaint*(wnd: HWND, lpPaint: var TPaintStruct): HDC{.stdcall, dynlib: "user32", importc: "BeginPaint".} @@ -21098,18 +21098,18 @@ proc CallMsgFilterA*(lpMsg: var TMsg, nCode: int): WINBOOL{.stdcall, dynlib: "user32", importc: "CallMsgFilterA".} proc CallMsgFilterW*(lpMsg: var TMsg, nCode: int): WINBOOL{.stdcall, dynlib: "user32", importc: "CallMsgFilterW".} -proc CallNamedPipe*(lpNamedPipeName: cstring, lpInBuffer: Pointer, - nInBufferSize: DWORD, lpOutBuffer: Pointer, +proc CallNamedPipe*(lpNamedPipeName: cstring, lpInBuffer: pointer, + nInBufferSize: DWORD, lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesRead: var DWORD, nTimeOut: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "CallNamedPipeA".} -proc CallNamedPipeA*(lpNamedPipeName: LPCSTR, lpInBuffer: Pointer, - nInBufferSize: DWORD, lpOutBuffer: Pointer, +proc CallNamedPipeA*(lpNamedPipeName: LPCSTR, lpInBuffer: pointer, + nInBufferSize: DWORD, lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesRead: var DWORD, nTimeOut: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "CallNamedPipeA".} -proc CallNamedPipeW*(lpNamedPipeName: LPWSTR, lpInBuffer: Pointer, - nInBufferSize: DWORD, lpOutBuffer: Pointer, +proc CallNamedPipeW*(lpNamedPipeName: LPWSTR, lpInBuffer: pointer, + nInBufferSize: DWORD, lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesRead: var DWORD, nTimeOut: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "CallNamedPipeW".} @@ -21122,15 +21122,15 @@ proc ChangeDisplaySettingsA*(lpDevMode: var TDeviceModeA, dwFlags: DWORD): int32 stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsA".} proc ChangeDisplaySettingsEx*(lpszDeviceName: cstring, lpDevMode: var TDeviceMode, wnd: HWND, - dwFlags: DWORD, lParam: Pointer): int32{.stdcall, + dwFlags: DWORD, lParam: pointer): int32{.stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsExA".} proc ChangeDisplaySettingsExA*(lpszDeviceName: LPCSTR, lpDevMode: var TDeviceModeA, wnd: HWND, - dwFlags: DWORD, lParam: Pointer): int32{.stdcall, + dwFlags: DWORD, lParam: pointer): int32{.stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsExA".} proc ChangeDisplaySettingsExW*(lpszDeviceName: LPWSTR, lpDevMode: var TDeviceModeW, wnd: HWND, - dwFlags: DWORD, lParam: Pointer): int32{.stdcall, + dwFlags: DWORD, lParam: pointer): int32{.stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsExW".} proc ChangeDisplaySettingsW*(lpDevMode: var TDeviceModeW, dwFlags: DWORD): int32{. stdcall, dynlib: "user32", importc: "ChangeDisplaySettingsW".} @@ -21184,8 +21184,8 @@ proc CreateDialogIndirectParam*(hInstance: HINST, lpTemplate: TDlgTemplate, #function CreateDialogIndirectParamA(hInstance: HINST; const lpTemplate: TDlgTemplate; hWndParent: HWND; lpDialogFunc: TFNDlgProc; dwInitParam: LPARAM): HWND; stdcall; external 'user32' name 'CreateDialogIndirectParamA'; #function CreateDialogIndirectParamW(hInstance: HINST; const lpTemplate: TDlgTemplate; hWndParent: HWND; lpDialogFunc: TFNDlgProc; dwInitParam: LPARAM): HWND; stdcall; external 'user32' name 'CreateDialogIndirectParamW'; #function CreateDIBitmap(DC: HDC; var InfoHeader: TBitmapInfoHeader; dwUsage: DWORD; InitBits: PChar; var InitInfo: TBitmapInfo; wUsage: WINUINT): HBITMAP; stdcall; external 'gdi32' name 'CreateDIBitmap'; - #function CreateDIBPatternBrushPt(const p1: Pointer; p2: WINUINT): HBRUSH; stdcall; external 'gdi32' name 'CreateDIBPatternBrushPt'; - #function CreateDIBSection(DC: HDC; const p2: TBitmapInfo; p3: WINUINT; var p4: Pointer; p5: THandle; p6: DWORD): HBITMAP; stdcall; external 'gdi32' name 'CreateDIBSection'; + #function CreateDIBPatternBrushPt(const p1: pointer; p2: WINUINT): HBRUSH; stdcall; external 'gdi32' name 'CreateDIBPatternBrushPt'; + #function CreateDIBSection(DC: HDC; const p2: TBitmapInfo; p3: WINUINT; var p4: pointer; p5: THandle; p6: DWORD): HBITMAP; stdcall; external 'gdi32' name 'CreateDIBSection'; #function CreateEllipticRgnIndirect(const p1: TRect): HRGN; stdcall; external 'gdi32' name 'CreateEllipticRgnIndirect'; #function CreateFontIndirect(const p1: TLogFont): HFONT;stdcall; external 'gdi32' name 'CreateFontIndirectA'; #function CreateFontIndirectA(const p1: TLogFontA): HFONT; stdcall; external 'gdi32' name 'CreateFontIndirectA'; @@ -21211,39 +21211,39 @@ proc CreatePolyPolygonRgn*(pPtStructs: pointer, pIntArray: pointer, p3, p4: int) proc CreateProcess*(lpApplicationName: cstring, lpCommandLine: cstring, lpProcessAttributes, lpThreadAttributes: PSecurityAttributes, bInheritHandles: WINBOOL, dwCreationFlags: DWORD, - lpEnvironment: Pointer, lpCurrentDirectory: cstring, + lpEnvironment: pointer, lpCurrentDirectory: cstring, lpStartupInfo: TStartupInfo, lpProcessInformation: var TProcessInformation): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreateProcessA".} proc CreateProcessA*(lpApplicationName: LPCSTR, lpCommandLine: LPCSTR, lpProcessAttributes, lpThreadAttributes: PSecurityAttributes, bInheritHandles: WINBOOL, dwCreationFlags: DWORD, - lpEnvironment: Pointer, lpCurrentDirectory: LPCSTR, + lpEnvironment: pointer, lpCurrentDirectory: LPCSTR, lpStartupInfo: TStartupInfo, lpProcessInformation: var TProcessInformation): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreateProcessA".} #function CreateProcessAsUser(hToken: THandle; lpApplicationName: PChar; lpCommandLine: PChar; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: WINBOOL; dwCreationFlags: DWORD; - # lpEnvironment: Pointer; lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL;stdcall; external 'advapi32' name 'CreateProcessAsUserA'; + # lpEnvironment: pointer; lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL;stdcall; external 'advapi32' name 'CreateProcessAsUserA'; #function CreateProcessAsUserA(hToken: THandle; lpApplicationName: LPCSTR; lpCommandLine: LPCSTR; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: WINBOOL; dwCreationFlags: DWORD; - # lpEnvironment: Pointer; lpCurrentDirectory: LPCSTR; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL; stdcall; external 'advapi32' name 'CreateProcessAsUserA'; + # lpEnvironment: pointer; lpCurrentDirectory: LPCSTR; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL; stdcall; external 'advapi32' name 'CreateProcessAsUserA'; #function CreateProcessAsUserW(hToken: THandle; lpApplicationName: LPWSTR; lpCommandLine: LPWSTR; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: WINBOOL; dwCreationFlags: DWORD; - # lpEnvironment: Pointer; lpCurrentDirectory: LPWSTR; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL; stdcall; external 'advapi32' name 'CreateProcessAsUserW'; + # lpEnvironment: pointer; lpCurrentDirectory: LPWSTR; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): WINBOOL; stdcall; external 'advapi32' name 'CreateProcessAsUserW'; proc CreateProcessW*(lpApplicationName: LPWSTR, lpCommandLine: LPWSTR, lpProcessAttributes, lpThreadAttributes: PSecurityAttributes, bInheritHandles: WINBOOL, dwCreationFlags: DWORD, - lpEnvironment: Pointer, lpCurrentDirectory: LPWSTR, + lpEnvironment: pointer, lpCurrentDirectory: LPWSTR, lpStartupInfo: TStartupInfo, lpProcessInformation: var TProcessInformation): WINBOOL{. stdcall, dynlib: "kernel32", importc: "CreateProcessW".} #function CreateRectRgnIndirect(const p1: TRect): HRGN; stdcall; external 'gdi32' name 'CreateRectRgnIndirect'; -proc CreateRemoteThread*(hProcess: THandle, lpThreadAttributes: Pointer, +proc CreateRemoteThread*(hProcess: THandle, lpThreadAttributes: pointer, dwStackSize: DWORD, lpStartAddress: TFNThreadStartRoutine, - lpParameter: Pointer, dwCreationFlags: DWORD, + lpParameter: pointer, dwCreationFlags: DWORD, lpThreadId: var DWORD): THandle{.stdcall, dynlib: "kernel32", importc: "CreateRemoteThread".} -proc CreateThread*(lpThreadAttributes: Pointer, dwStackSize: DWORD, - lpStartAddress: TFNThreadStartRoutine, lpParameter: Pointer, +proc CreateThread*(lpThreadAttributes: pointer, dwStackSize: DWORD, + lpStartAddress: TFNThreadStartRoutine, lpParameter: pointer, dwCreationFlags: DWORD, lpThreadId: var DWORD): THandle{. stdcall, dynlib: "kernel32", importc: "CreateThread".} proc DdeSetQualityOfService*(hWndClient: HWnd, @@ -21256,8 +21256,8 @@ proc DescribePixelFormat*(DC: HDC, p2: int, p3: WINUINT, dynlib: "gdi32", importc: "DescribePixelFormat".} #function DestroyPrivateObjectSecurity(var ObjectDescriptor: PSecurityDescriptor): WINBOOL; stdcall; external 'advapi32' name 'DestroyPrivateObjectSecurity'; proc DeviceIoControl*(hDevice: THandle, dwIoControlCode: DWORD, - lpInBuffer: Pointer, nInBufferSize: DWORD, - lpOutBuffer: Pointer, nOutBufferSize: DWORD, + lpInBuffer: pointer, nInBufferSize: DWORD, + lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesReturned: var DWORD, lpOverlapped: POverlapped): WINBOOL{. stdcall, dynlib: "kernel32", importc: "DeviceIoControl".} proc DialogBoxIndirectParam*(hInstance: HINST, lpDialogTemplate: TDlgTemplate, @@ -21311,9 +21311,9 @@ proc DrawTextW*(hDC: HDC, lpString: LPWSTR, nCount: int, lpRect: var TRect, # stdcall; external 'advapi32' name 'DuplicateTokenEx'; proc EndPaint*(wnd: HWND, lpPaint: TPaintStruct): WINBOOL{.stdcall, dynlib: "user32", importc: "EndPaint".} - #function EnumDisplayDevices(Unused: Pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDevice; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesA'; - #function EnumDisplayDevicesA(Unused: Pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDeviceA; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesA'; - #function EnumDisplayDevicesW(Unused: Pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDeviceW; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesW'; + #function EnumDisplayDevices(Unused: pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDevice; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesA'; + #function EnumDisplayDevicesA(Unused: pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDeviceA; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesA'; + #function EnumDisplayDevicesW(Unused: pointer; iDevNum: DWORD; var lpDisplayDevice: TDisplayDeviceW; dwFlags: DWORD): WINBOOL;stdcall; external 'user32' name 'EnumDisplayDevicesW'; proc EnumDisplaySettings*(lpszDeviceName: cstring, iModeNum: DWORD, lpDevMode: var TDeviceMode): WINBOOL{.stdcall, dynlib: "user32", importc: "EnumDisplaySettingsA".} @@ -21323,13 +21323,13 @@ proc EnumDisplaySettingsA*(lpszDeviceName: LPCSTR, iModeNum: DWORD, proc EnumDisplaySettingsW*(lpszDeviceName: LPWSTR, iModeNum: DWORD, lpDevMode: var TDeviceModeW): WINBOOL{.stdcall, dynlib: "user32", importc: "EnumDisplaySettingsW".} - #function EnumEnhMetaFile(DC: HDC; p2: HENHMETAFILE; p3: TFNEnhMFEnumProc; p4: Pointer; const p5: TRect): WINBOOL; stdcall; external 'gdi32' name 'EnumEnhMetaFile'; + #function EnumEnhMetaFile(DC: HDC; p2: HENHMETAFILE; p3: TFNEnhMFEnumProc; p4: pointer; const p5: TRect): WINBOOL; stdcall; external 'gdi32' name 'EnumEnhMetaFile'; #function EnumFontFamiliesEx(DC: HDC; var p2: TLogFont; p3: TFNFontEnumProc; p4: LPARAM; p5: DWORD): WINBOOL;stdcall; external 'gdi32' name 'EnumFontFamiliesExA'; #function EnumFontFamiliesExA(DC: HDC; var p2: TLogFontA; p3: TFNFontEnumProcA; p4: LPARAM; p5: DWORD): WINBOOL; stdcall; external 'gdi32' name 'EnumFontFamiliesExA'; #function EnumFontFamiliesExW(DC: HDC; var p2: TLogFontW; p3: TFNFontEnumProcW; p4: LPARAM; p5: DWORD): WINBOOL; stdcall; external 'gdi32' name 'EnumFontFamiliesExW'; #function EqualRect(const lprc1, lprc2: TRect): WINBOOL; stdcall; external 'user32' name 'EqualRect'; proc ExtCreatePen*(PenStyle, Width: DWORD, Brush: TLogBrush, StyleCount: DWORD, - Style: Pointer): HPEN{.stdcall, dynlib: "gdi32", + Style: pointer): HPEN{.stdcall, dynlib: "gdi32", importc: "ExtCreatePen".} proc ExtCreateRegion*(p1: PXForm, p2: DWORD, p3: TRgnData): HRGN{.stdcall, dynlib: "gdi32", importc: "ExtCreateRegion".} @@ -21346,7 +21346,7 @@ proc FillConsoleOutputAttribute*(hConsoleOutput: THandle, wAttribute: int16, nLength: DWORD, dwWriteCoord: TCoord, lpNumberOfAttrsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FillConsoleOutputAttribute".} -proc FillConsoleOutputCharacter*(hConsoleOutput: THandle, cCharacter: Char, +proc FillConsoleOutputCharacter*(hConsoleOutput: THandle, cCharacter: char, nLength: DWORD, dwWriteCoord: TCoord, lpNumberOfCharsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FillConsoleOutputCharacterA".} @@ -21365,18 +21365,18 @@ proc FindFirstFileA*(lpFileName: LPCSTR, lpFindFileData: var TWIN32FindDataA): T stdcall, dynlib: "kernel32", importc: "FindFirstFileA".} proc FindFirstFileW*(lpFileName: LPWSTR, lpFindFileData: var TWIN32FindDataW): THandle{. stdcall, dynlib: "kernel32", importc: "FindFirstFileW".} - #function FindFirstFreeAce(var pAcl: TACL; var pAce: Pointer): WINBOOL; stdcall; external 'advapi32' name 'FindFirstFreeAce'; + #function FindFirstFreeAce(var pAcl: TACL; var pAce: pointer): WINBOOL; stdcall; external 'advapi32' name 'FindFirstFreeAce'; proc FindNextFile*(hFindFile: THandle, lpFindFileData: var TWIN32FindData): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FindNextFileA".} proc FindNextFileA*(hFindFile: THandle, lpFindFileData: var TWIN32FindDataA): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FindNextFileA".} proc FindNextFileW*(hFindFile: THandle, lpFindFileData: var TWIN32FindDataW): WINBOOL{. stdcall, dynlib: "kernel32", importc: "FindNextFileW".} - #function FlushInstructionCache(hProcess: THandle; const lpBaseAddress: Pointer; dwSize: DWORD): WINBOOL; stdcall; external 'kernel32' name 'FlushInstructionCache'; - #function FlushViewOfFile(const lpBaseAddress: Pointer; dwNumberOfBytesToFlush: DWORD): WINBOOL; stdcall; external 'kernel32' name 'FlushViewOfFile'; + #function FlushInstructionCache(hProcess: THandle; const lpBaseAddress: pointer; dwSize: DWORD): WINBOOL; stdcall; external 'kernel32' name 'FlushInstructionCache'; + #function FlushViewOfFile(const lpBaseAddress: pointer; dwNumberOfBytesToFlush: DWORD): WINBOOL; stdcall; external 'kernel32' name 'FlushViewOfFile'; #function FrameRect(hDC: HDC; const lprc: TRect; hbr: HBRUSH): Integer; stdcall; external 'user32' name 'FrameRect'; - #function GetAce(const pAcl: TACL; dwAceIndex: DWORD; var pAce: Pointer): WINBOOL; stdcall; external 'advapi32' name 'GetAce'; - #function GetAclInformation(const pAcl: TACL; pAclInformation: Pointer; nAclInformationLength: DWORD; dwAclInformationClass: TAclInformationClass): WINBOOL; stdcall; external 'advapi32' name 'GetAclInformation'; + #function GetAce(const pAcl: TACL; dwAceIndex: DWORD; var pAce: pointer): WINBOOL; stdcall; external 'advapi32' name 'GetAce'; + #function GetAclInformation(const pAcl: TACL; pAclInformation: pointer; nAclInformationLength: DWORD; dwAclInformationClass: TAclInformationClass): WINBOOL; stdcall; external 'advapi32' name 'GetAclInformation'; #function GetAltTabInfo(wnd: HWND; iItem: Integer; var pati: TAltTabInfo; pszItemText: PChar; cchItemText: WINUINT): WINBOOL;stdcall; external 'user32' name 'GetAltTabInfoA'; #function GetAltTabInfoA(wnd: HWND; iItem: Integer; var pati: TAltTabInfo; pszItemText: LPCSTR; cchItemText: WINUINT): WINBOOL;stdcall; external 'user32' name 'GetAltTabInfoA'; #function GetAltTabInfoW(wnd: HWND; iItem: Integer; var pati: TAltTabInfo; pszItemText: LPWSTR; cchItemText: WINUINT): WINBOOL;stdcall; external 'user32' name 'GetAltTabInfoW'; @@ -21507,7 +21507,7 @@ proc GetDefaultCommConfigW*(lpszName: LPWSTR, lpCC: var TCommConfig, proc GetDIBColorTable*(DC: HDC, p2, p3: WINUINT, RGBQuadStructs: pointer): WINUINT{. stdcall, dynlib: "gdi32", importc: "GetDIBColorTable".} proc GetDIBits*(DC: HDC, Bitmap: HBitmap, StartScan, NumScans: WINUINT, - Bits: Pointer, BitInfo: var TBitmapInfo, Usage: WINUINT): int{. + Bits: pointer, BitInfo: var TBitmapInfo, Usage: WINUINT): int{. stdcall, dynlib: "gdi32", importc: "GetDIBits".} proc GetDiskFreeSpace*(lpRootPathName: cstring, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: var DWORD): WINBOOL{. @@ -21531,13 +21531,13 @@ proc GetDiskFreeSpaceW*(lpRootPathName: LPWSTR, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceW".} proc GetDiskFreeSpaceEx*(lpDirectoryName: cstring, lpFreeBytesAvailableToCaller, - lpTotalNumberOfBytes: pLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. + lpTotalNumberOfBytes: PLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExA".} proc GetDiskFreeSpaceExA*(lpDirectoryName: LPCSTR, lpFreeBytesAvailableToCaller, - lpTotalNumberOfBytes: pLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. + lpTotalNumberOfBytes: PLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExA".} proc GetDiskFreeSpaceExW*(lpDirectoryName: LPWSTR, lpFreeBytesAvailableToCaller, - lpTotalNumberOfBytes: pLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. + lpTotalNumberOfBytes: PLargeInteger, lpTotalNumberOfFreeBytes: PLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExW".} #function GetEnhMetaFilePixelFormat(p1: HENHMETAFILE; p2: Cardinal; var p3: TPixelFormatDescriptor): WINUINT;stdcall; external 'gdi32' name 'GetEnhMetaFilePixelFormat'; proc GetExitCodeProcess*(hProcess: THandle, lpExitCode: var DWORD): WINBOOL{. @@ -21560,13 +21560,13 @@ proc GetFileVersionInfoSizeW*(lptstrFilename: LPWSTR, lpdwHandle: var DWORD): DW # function GetFullPathNameA(lpFileName: LPCSTR; nBufferLength: DWORD; lpBuffer: LPCSTR; var lpFilePart: LPCSTR): DWORD; stdcall; external 'kernel32' name 'GetFullPathNameA'; # function GetFullPathNameW(lpFileName: LPWSTR; nBufferLength: DWORD; lpBuffer: LPWSTR; var lpFilePart: LPWSTR): DWORD; stdcall; external 'kernel32' name 'GetFullPathNameW'; proc GetGlyphOutline*(DC: HDC, p2, p3: WINUINT, p4: TGlyphMetrics, p5: DWORD, - p6: Pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", + p6: pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", importc: "GetGlyphOutlineA".} proc GetGlyphOutlineA*(DC: HDC, p2, p3: WINUINT, p4: TGlyphMetrics, p5: DWORD, - p6: Pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", + p6: pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", importc: "GetGlyphOutlineA".} proc GetGlyphOutlineW*(DC: HDC, p2, p3: WINUINT, p4: TGlyphMetrics, p5: DWORD, - p6: Pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", + p6: pointer, p7: TMat2): DWORD{.stdcall, dynlib: "gdi32", importc: "GetGlyphOutlineW".} #function GetGUIThreadInfo(idThread: DWORD; var pgui: TGUIThreadinfo): WINBOOL;stdcall; external 'user32' name 'GetGUIThreadInfo'; proc GetHandleInformation*(hObject: THandle, lpdwFlags: var DWORD): WINBOOL{. @@ -21600,9 +21600,9 @@ proc GetLogColorSpaceA*(p1: HCOLORSPACE, ColorSpace: var TLogColorSpaceA, Size: DWORD): WINBOOL{.stdcall, dynlib: "gdi32", importc: "GetLogColorSpaceA".} #function GetLogColorSpaceW(p1: HCOLORSPACE; var ColorSpace: TLogColorSpaceW; Size: DWORD): WINBOOL; stdcall; external 'gdi32' name 'GetLogColorSpaceW'; -proc GetMailslotInfo*(hMailslot: THandle, lpMaxMessageSize: Pointer, +proc GetMailslotInfo*(hMailslot: THandle, lpMaxMessageSize: pointer, lpNextSize: var DWORD, - lpMessageCount, lpReadTimeout: Pointer): WINBOOL{.stdcall, + lpMessageCount, lpReadTimeout: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "GetMailslotInfo".} #function GetMenuBarInfo(hend: HWND; idObject, idItem: Longint; var pmbi: TMenuBarInfo): WINBOOL;stdcall; external 'user32' name 'GetMenuBarInfo'; #function GetMenuInfo(menu: HMENU; var lpmi: TMenuInfo): WINBOOL;stdcall; external 'user32' name 'GetMenuInfo'; @@ -21625,7 +21625,7 @@ proc GetMiterLimit*(DC: HDC, Limit: var float32): WINBOOL{.stdcall, dynlib: "gdi32", importc: "GetMiterLimit".} #function GetMouseMovePoints(cbSize: WINUINT; var lppt, lpptBuf: TMouseMovePoint; nBufPoints: Integer; resolution: DWORD): Integer;stdcall; external 'user32' name 'GetMouseMovePoints'; proc GetNamedPipeInfo*(hNamedPipe: THandle, lpFlags: var DWORD, - lpOutBufferSize, lpInBufferSize, lpMaxInstances: Pointer): WINBOOL{. + lpOutBufferSize, lpInBufferSize, lpMaxInstances: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetNamedPipeInfo".} proc GetNumberOfConsoleInputEvents*(hConsoleInput: THandle, lpNumberOfEvents: var DWORD): WINBOOL{. @@ -21738,11 +21738,11 @@ proc GetTabbedTextExtentW*(hDC: HDC, lpString: LPWSTR, lpnTabStopPositions: pointer): DWORD{.stdcall, dynlib: "user32", importc: "GetTabbedTextExtentW".} proc GetTapeParameters*(hDevice: THandle, dwOperation: DWORD, - lpdwSize: var DWORD, lpTapeInformation: Pointer): DWORD{. + lpdwSize: var DWORD, lpTapeInformation: pointer): DWORD{. stdcall, dynlib: "kernel32", importc: "GetTapeParameters".} proc GetTapePosition*(hDevice: THandle, dwPositionType: DWORD, lpdwPartition, lpdwOffsetLow: var DWORD, - lpdwOffsetHigh: Pointer): DWORD{.stdcall, + lpdwOffsetHigh: pointer): DWORD{.stdcall, dynlib: "kernel32", importc: "GetTapePosition".} proc GetTextExtentExPoint*(DC: HDC, p2: cstring, p3, p4: int, p5, p6: PInteger, p7: var TSize): WINBOOL{.stdcall, dynlib: "gdi32", @@ -21784,7 +21784,7 @@ proc GetThreadTimes*(hThread: THandle, lpCreationTime, lpExitTime, lpKernelTime, proc GetTimeZoneInformation*(lpTimeZoneInformation: var TTimeZoneInformation): DWORD{. stdcall, dynlib: "kernel32", importc: "GetTimeZoneInformation".} #function GetTitleBarInfo(wnd: HWND; var pti: TTitleBarInfo): WINBOOL;stdcall; external 'user32' name 'GetTitleBarInfo'; - #function GetTokenInformation(TokenHandle: THandle; TokenInformationClass: TTokenInformationClass; TokenInformation: Pointer; TokenInformationLength: DWORD; var ReturnLength: DWORD): WINBOOL; stdcall; external 'advapi32' name 'GetTokenInformation'; + #function GetTokenInformation(TokenHandle: THandle; TokenInformationClass: TTokenInformationClass; TokenInformation: pointer; TokenInformationLength: DWORD; var ReturnLength: DWORD): WINBOOL; stdcall; external 'advapi32' name 'GetTokenInformation'; proc GetUpdateRect*(wnd: HWND, lpRect: var TRect, bErase: WINBOOL): WINBOOL{. stdcall, dynlib: "user32", importc: "GetUpdateRect".} proc GetUserName*(lpBuffer: cstring, nSize: var DWORD): WINBOOL{.stdcall, @@ -21793,13 +21793,13 @@ proc GetUserNameA*(lpBuffer: LPCSTR, nSize: var DWORD): WINBOOL{.stdcall, dynlib: "advapi32", importc: "GetUserNameA".} proc GetUserNameW*(lpBuffer: LPWSTR, nSize: var DWORD): WINBOOL{.stdcall, dynlib: "advapi32", importc: "GetUserNameW".} -proc GetUserObjectInformation*(hObj: THandle, nIndex: int, pvInfo: Pointer, +proc GetUserObjectInformation*(hObj: THandle, nIndex: int, pvInfo: pointer, nLength: DWORD, lpnLengthNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "user32", importc: "GetUserObjectInformationA".} -proc GetUserObjectInformationA*(hObj: THandle, nIndex: int, pvInfo: Pointer, +proc GetUserObjectInformationA*(hObj: THandle, nIndex: int, pvInfo: pointer, nLength: DWORD, lpnLengthNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "user32", importc: "GetUserObjectInformationA".} -proc GetUserObjectInformationW*(hObj: THandle, nIndex: int, pvInfo: Pointer, +proc GetUserObjectInformationW*(hObj: THandle, nIndex: int, pvInfo: pointer, nLength: DWORD, lpnLengthNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "user32", importc: "GetUserObjectInformationW".} proc GetUserObjectSecurity*(hObj: THandle, pSIRequested: var DWORD, @@ -21845,7 +21845,7 @@ proc GetWindowRect*(wnd: HWND, lpRect: var TRect): WINBOOL{.stdcall, dynlib: "user32", importc: "GetWindowRect".} proc GetWorldTransform*(DC: HDC, p2: var TXForm): WINBOOL{.stdcall, dynlib: "gdi32", importc: "GetWorldTransform".} - #function GradientFill(DC: HDC; var p2: TTriVertex; p3: ULONG; p4: Pointer; p5, p6: ULONG): WINBOOL;stdcall; external 'gdi32' name 'GradientFill'; + #function GradientFill(DC: HDC; var p2: TTriVertex; p3: ULONG; p4: pointer; p5, p6: ULONG): WINBOOL;stdcall; external 'gdi32' name 'GradientFill'; proc GlobalMemoryStatus*(Buffer: var MEMORYSTATUS){.stdcall, dynlib: "kernel32", importc: "GlobalMemoryStatus".} proc HeapWalk*(hHeap: THandle, lpEntry: var TProcessHeapEntry): WINBOOL{. @@ -21856,7 +21856,7 @@ proc InflateRect*(lprc: var TRect, dx, dy: int): WINBOOL{.stdcall, dynlib: "user32", importc: "InflateRect".} proc InitializeAcl*(pAcl: var TACL, nAclLength, dwAclRevision: DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "InitializeAcl".} -proc InitializeSid*(Sid: Pointer, pIdentifierAuthority: TSIDIdentifierAuthority, +proc InitializeSid*(Sid: pointer, pIdentifierAuthority: TSIDIdentifierAuthority, nSubAuthorityCount: int8): WINBOOL{.stdcall, dynlib: "advapi32", importc: "InitializeSid".} proc InsertMenuItemA*(p1: HMENU, p2: WINUINT, p3: WINBOOL, p4: TMenuItemInfoA): WINBOOL{. @@ -21958,7 +21958,7 @@ proc MakeAbsoluteSD*(pSelfRelativeSecurityDescriptor: PSecurityDescriptor, pDacl: var TACL, lpdwDaclSize: var DWORD, pSacl: var TACL, lpdwSaclSize: var DWORD, pOwner: PSID, - lpdwOwnerSize: var DWORD, pPrimaryGroup: Pointer, + lpdwOwnerSize: var DWORD, pPrimaryGroup: pointer, lpdwPrimaryGroupSize: var DWORD): WINBOOL{.stdcall, dynlib: "advapi32", importc: "MakeAbsoluteSD".} proc MakeSelfRelativeSD*(pAbsoluteSecurityDescriptor: PSecurityDescriptor, @@ -21983,7 +21983,7 @@ proc MsgWaitForMultipleObjectsEx*(nCount: DWORD, pHandles: pointer, dwMilliseconds, dwWakeMask, dwFlags: DWORD): DWORD{. stdcall, dynlib: "user32", importc: "MsgWaitForMultipleObjectsEx".} # function MultiByteToWideChar(CodePage: WINUINT; dwFlags: DWORD; const lpMultiByteStr: LPCSTR; cchMultiByte: Integer; lLPWSTRStr: LPWSTR; cchWideChar: Integer): Integer; stdcall; external 'kernel32' name 'MultiByteToWideChar'; -proc ObjectOpenAuditAlarm*(SubsystemName: cstring, HandleId: Pointer, +proc ObjectOpenAuditAlarm*(SubsystemName: cstring, HandleId: pointer, ObjectTypeName: cstring, ObjectName: cstring, pSecurityDescriptor: PSecurityDescriptor, ClientToken: THandle, @@ -21992,7 +21992,7 @@ proc ObjectOpenAuditAlarm*(SubsystemName: cstring, HandleId: Pointer, ObjectCreation, AccessGranted: WINBOOL, GenerateOnClose: var WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectOpenAuditAlarmA".} -proc ObjectOpenAuditAlarmA*(SubsystemName: LPCSTR, HandleId: Pointer, +proc ObjectOpenAuditAlarmA*(SubsystemName: LPCSTR, HandleId: pointer, ObjectTypeName: LPCSTR, ObjectName: LPCSTR, pSecurityDescriptor: PSecurityDescriptor, ClientToken: THandle, @@ -22001,7 +22001,7 @@ proc ObjectOpenAuditAlarmA*(SubsystemName: LPCSTR, HandleId: Pointer, ObjectCreation, AccessGranted: WINBOOL, GenerateOnClose: var WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectOpenAuditAlarmA".} -proc ObjectOpenAuditAlarmW*(SubsystemName: LPWSTR, HandleId: Pointer, +proc ObjectOpenAuditAlarmW*(SubsystemName: LPWSTR, HandleId: pointer, ObjectTypeName: LPWSTR, ObjectName: LPWSTR, pSecurityDescriptor: PSecurityDescriptor, ClientToken: THandle, @@ -22010,17 +22010,17 @@ proc ObjectOpenAuditAlarmW*(SubsystemName: LPWSTR, HandleId: Pointer, ObjectCreation, AccessGranted: WINBOOL, GenerateOnClose: var WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectOpenAuditAlarmW".} -proc ObjectPrivilegeAuditAlarm*(SubsystemName: cstring, HandleId: Pointer, +proc ObjectPrivilegeAuditAlarm*(SubsystemName: cstring, HandleId: pointer, ClientToken: THandle, DesiredAccess: DWORD, Privileges: var TPrivilegeSet, AccessGranted: WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectPrivilegeAuditAlarmA".} -proc ObjectPrivilegeAuditAlarmA*(SubsystemName: LPCSTR, HandleId: Pointer, +proc ObjectPrivilegeAuditAlarmA*(SubsystemName: LPCSTR, HandleId: pointer, ClientToken: THandle, DesiredAccess: DWORD, Privileges: var TPrivilegeSet, AccessGranted: WINBOOL): WINBOOL{.stdcall, dynlib: "advapi32", importc: "ObjectPrivilegeAuditAlarmA".} -proc ObjectPrivilegeAuditAlarmW*(SubsystemName: LPWSTR, HandleId: Pointer, +proc ObjectPrivilegeAuditAlarmW*(SubsystemName: LPWSTR, HandleId: pointer, ClientToken: THandle, DesiredAccess: DWORD, Privileges: var TPrivilegeSet, AccessGranted: WINBOOL): WINBOOL{.stdcall, @@ -22111,21 +22111,21 @@ proc QueryPerformanceCounter*(lpPerformanceCount: var TLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "QueryPerformanceCounter".} proc QueryPerformanceFrequency*(lpFrequency: var TLargeInteger): WINBOOL{. stdcall, dynlib: "kernel32", importc: "QueryPerformanceFrequency".} - #function QueryRecoveryAgents(p1: PChar; var p2: Pointer; var p3: TRecoveryAgentInformation): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsA'; - #function QueryRecoveryAgentsA(p1: LPCSTR; var p2: Pointer; var p3: TRecoveryAgentInformationA): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsA'; - #function QueryRecoveryAgentsW(p1: LPWSTR; var p2: Pointer; var p3: TRecoveryAgentInformationW): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsW'; + #function QueryRecoveryAgents(p1: PChar; var p2: pointer; var p3: TRecoveryAgentInformation): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsA'; + #function QueryRecoveryAgentsA(p1: LPCSTR; var p2: pointer; var p3: TRecoveryAgentInformationA): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsA'; + #function QueryRecoveryAgentsW(p1: LPWSTR; var p2: pointer; var p3: TRecoveryAgentInformationW): DWORD;stdcall; external 'kernel32' name 'QueryRecoveryAgentsW'; proc RaiseException*(dwExceptionCode: DWORD, dwExceptionFlags: DWORD, nNumberOfArguments: DWORD, lpArguments: var DWORD){. stdcall, dynlib: "kernel32", importc: "RaiseException".} proc UnhandledExceptionFilter*(ExceptionInfo: var emptyrecord): LONG{.stdcall, dynlib: "kernel32", importc: "UnhandledExceptionFilter".} -proc ReadConsole*(hConsoleInput: THandle, lpBuffer: Pointer, +proc ReadConsole*(hConsoleInput: THandle, lpBuffer: pointer, nNumberOfCharsToRead: DWORD, lpNumberOfCharsRead: var DWORD, - lpReserved: Pointer): WINBOOL{.stdcall, dynlib: "kernel32", + lpReserved: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleA".} -proc ReadConsoleA*(hConsoleInput: THandle, lpBuffer: Pointer, +proc ReadConsoleA*(hConsoleInput: THandle, lpBuffer: pointer, nNumberOfCharsToRead: DWORD, lpNumberOfCharsRead: var DWORD, - lpReserved: Pointer): WINBOOL{.stdcall, dynlib: "kernel32", + lpReserved: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleA".} proc ReadConsoleInput*(hConsoleInput: THandle, lpBuffer: var TInputRecord, nLength: DWORD, lpNumberOfEventsRead: var DWORD): WINBOOL{. @@ -22136,15 +22136,15 @@ proc ReadConsoleInputA*(hConsoleInput: THandle, lpBuffer: var TInputRecord, proc ReadConsoleInputW*(hConsoleInput: THandle, lpBuffer: var TInputRecord, nLength: DWORD, lpNumberOfEventsRead: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadConsoleInputW".} -proc ReadConsoleOutput*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc ReadConsoleOutput*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpReadRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputA".} -proc ReadConsoleOutputA*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc ReadConsoleOutputA*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpReadRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputA".} -proc ReadConsoleOutputAttribute*(hConsoleOutput: THandle, lpAttribute: Pointer, +proc ReadConsoleOutputAttribute*(hConsoleOutput: THandle, lpAttribute: pointer, nLength: DWORD, dwReadCoord: TCoord, lpNumberOfAttrsRead: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputAttribute".} @@ -22160,31 +22160,31 @@ proc ReadConsoleOutputCharacterW*(hConsoleOutput: THandle, lpCharacter: LPCSTR, nLength: DWORD, dwReadCoord: TCoord, lpNumberOfCharsRead: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputCharacterW".} -proc ReadConsoleOutputW*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc ReadConsoleOutputW*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpReadRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleOutputW".} -proc ReadConsoleW*(hConsoleInput: THandle, lpBuffer: Pointer, +proc ReadConsoleW*(hConsoleInput: THandle, lpBuffer: pointer, nNumberOfCharsToRead: DWORD, lpNumberOfCharsRead: var DWORD, - lpReserved: Pointer): WINBOOL{.stdcall, dynlib: "kernel32", + lpReserved: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadConsoleW".} proc ReadEventLog*(hEventLog: THandle, dwReadFlags, dwRecordOffset: DWORD, - lpBuffer: Pointer, nNumberOfBytesToRead: DWORD, + lpBuffer: pointer, nNumberOfBytesToRead: DWORD, pnBytesRead, pnMinNumberOfBytesNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "ReadEventLogA".} proc ReadEventLogA*(hEventLog: THandle, dwReadFlags, dwRecordOffset: DWORD, - lpBuffer: Pointer, nNumberOfBytesToRead: DWORD, + lpBuffer: pointer, nNumberOfBytesToRead: DWORD, pnBytesRead, pnMinNumberOfBytesNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "ReadEventLogA".} proc ReadEventLogW*(hEventLog: THandle, dwReadFlags, dwRecordOffset: DWORD, - lpBuffer: Pointer, nNumberOfBytesToRead: DWORD, + lpBuffer: pointer, nNumberOfBytesToRead: DWORD, pnBytesRead, pnMinNumberOfBytesNeeded: var DWORD): WINBOOL{. stdcall, dynlib: "advapi32", importc: "ReadEventLogW".} proc ReadFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: var DWORD, lpOverlapped: POverlapped): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadFile".} -proc ReadProcessMemory*(hProcess: THandle, lpBaseAddress: Pointer, - lpBuffer: Pointer, nSize: DWORD, +proc ReadProcessMemory*(hProcess: THandle, lpBaseAddress: pointer, + lpBuffer: pointer, nSize: DWORD, lpNumberOfBytesRead: var DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ReadProcessMemory".} #function RectInRegion(RGN: HRGN; const p2: TRect): WINBOOL; stdcall; external 'gdi32' name 'RectInRegion'; @@ -22217,27 +22217,27 @@ proc RegCreateKeyExW*(key: HKEY, lpSubKey: LPWSTR, Reserved: DWORD, proc RegCreateKeyW*(key: HKEY, lpSubKey: LPWSTR, phkResult: var HKEY): int32{. stdcall, dynlib: "advapi32", importc: "RegCreateKeyW".} proc RegEnumKeyEx*(key: HKEY, dwIndex: DWORD, lpName: cstring, - lpcbName: var DWORD, lpReserved: Pointer, lpClass: cstring, + lpcbName: var DWORD, lpReserved: pointer, lpClass: cstring, lpcbClass: PDWORD, lpftLastWriteTime: PFileTime): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumKeyExA".} proc RegEnumKeyExA*(key: HKEY, dwIndex: DWORD, lpName: LPCSTR, - lpcbName: var DWORD, lpReserved: Pointer, lpClass: LPCSTR, + lpcbName: var DWORD, lpReserved: pointer, lpClass: LPCSTR, lpcbClass: PDWORD, lpftLastWriteTime: PFileTime): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumKeyExA".} proc RegEnumKeyExW*(key: HKEY, dwIndex: DWORD, lpName: LPWSTR, - lpcbName: var DWORD, lpReserved: Pointer, lpClass: LPWSTR, + lpcbName: var DWORD, lpReserved: pointer, lpClass: LPWSTR, lpcbClass: PDWORD, lpftLastWriteTime: PFileTime): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumKeyExW".} proc RegEnumValue*(key: HKEY, dwIndex: DWORD, lpValueName: cstring, - lpcbValueName: var DWORD, lpReserved: Pointer, + lpcbValueName: var DWORD, lpReserved: pointer, lpType: PDWORD, lpData: PByte, lpcbData: PDWORD): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumValueA".} proc RegEnumValueA*(key: HKEY, dwIndex: DWORD, lpValueName: cstring, - lpcbValueName: var DWORD, lpReserved: Pointer, + lpcbValueName: var DWORD, lpReserved: pointer, lpType: PDWORD, lpData: PByte, lpcbData: PDWORD): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumValueA".} proc RegEnumValueW*(key: HKEY, dwIndex: DWORD, lpValueName: cstring, - lpcbValueName: var DWORD, lpReserved: Pointer, + lpcbValueName: var DWORD, lpReserved: pointer, lpType: PDWORD, lpData: PByte, lpcbData: PDWORD): int32{. stdcall, dynlib: "advapi32", importc: "RegEnumValueW".} proc RegGetKeySecurity*(key: HKEY, SecurityInformation: SECURITY_INFORMATION, @@ -22324,10 +22324,10 @@ proc ScrollConsoleScreenBufferW*(hConsoleOutput: THandle, lpFill: var TCharInfo): WINBOOL{.stdcall, dynlib: "kernel32", importc: "ScrollConsoleScreenBufferW".} proc ScrollWindow*(wnd: HWND, XAmount: int32, YAmount: int32, rect: LPRECT, - lpClipRect: lpRECT): WINBOOL{.stdcall, dynlib: "user32", + lpClipRect: LPRECT): WINBOOL{.stdcall, dynlib: "user32", importc: "ScrollWindow".} -proc ScrollWindowEx*(wnd: HWND, dx: int32, dy: int32, prcScroll: lpRECT, - prcClip: lpRECT, hrgnUpdate: HRGN, prcUpdate: LPRECT, +proc ScrollWindowEx*(wnd: HWND, dx: int32, dy: int32, prcScroll: LPRECT, + prcClip: LPRECT, hrgnUpdate: HRGN, prcUpdate: LPRECT, flags: WINUINT): int32{.stdcall, dynlib: "user32", importc: "ScrollWindowEx".} #function ScrollDC(DC: HDC; DX, DY: Integer; var Scroll, Clip: TRect; Rgn: HRGN; Update: PRect): WINBOOL; stdcall; external 'user32' name 'ScrollDC'; @@ -22344,7 +22344,7 @@ proc SendMessageTimeoutA*(wnd: HWND, Msg: WINUINT, wp: WPARAM, lp: LPARAM, proc SendMessageTimeoutW*(wnd: HWND, Msg: WINUINT, wp: WPARAM, lp: LPARAM, fuFlags, uTimeout: WINUINT, lpdwResult: var DWORD): LRESULT{. stdcall, dynlib: "user32", importc: "SendMessageTimeoutW".} - #function SetAclInformation(var pAcl: TACL; pAclInformation: Pointer; nAclInformationLength: DWORD; dwAclInformationClass: TAclInformationClass): WINBOOL; stdcall; external 'advapi32' name 'SetAclInformation'; + #function SetAclInformation(var pAcl: TACL; pAclInformation: pointer; nAclInformationLength: DWORD; dwAclInformationClass: TAclInformationClass): WINBOOL; stdcall; external 'advapi32' name 'SetAclInformation'; #function SetColorAdjustment(DC: HDC; const p2: TColorAdjustment): WINBOOL; stdcall; external 'gdi32' name 'SetColorAdjustment'; proc SetCommConfig*(hCommDev: THandle, lpCC: TCommConfig, dwSize: DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "SetCommConfig".} @@ -22359,9 +22359,9 @@ proc SetConsoleCursorInfo*(hConsoleOutput: THandle, proc SetDIBColorTable*(DC: HDC, p2, p3: WINUINT, RGBQuadSTructs: pointer): WINUINT{. stdcall, dynlib: "gdi32", importc: "SetDIBColorTable".} proc SetDIBits*(DC: HDC, Bitmap: HBITMAP, StartScan, NumScans: WINUINT, - Bits: Pointer, BitsInfo: var TBitmapInfo, Usage: WINUINT): int{. + Bits: pointer, BitsInfo: var TBitmapInfo, Usage: WINUINT): int{. stdcall, dynlib: "gdi32", importc: "SetDIBits".} - #function SetDIBitsToDevice(DC: HDC; DestX, DestY: Integer; Width, Height: DWORD; SrcX, SrcY: Integer; nStartScan, NumScans: WINUINT; Bits: Pointer; var BitsInfo: TBitmapInfo; Usage: WINUINT): Integer; stdcall; external 'gdi32' name 'SetDIBitsToDevice'; + #function SetDIBitsToDevice(DC: HDC; DestX, DestY: Integer; Width, Height: DWORD; SrcX, SrcY: Integer; nStartScan, NumScans: WINUINT; Bits: pointer; var BitsInfo: TBitmapInfo; Usage: WINUINT): Integer; stdcall; external 'gdi32' name 'SetDIBitsToDevice'; proc SetEnhMetaFileBits*(para1: WINUINT, para2: pointer): HENHMETAFILE{.stdcall, dynlib: "gdi32", importc: "SetEnhMetaFileBits".} proc SetFileTime*(hFile: HANDLE, lpCreationTime: var FILETIME, @@ -22378,7 +22378,7 @@ proc SetMenuItemInfoA*(p1: HMENU, p2: WINUINT, p3: WINBOOL, p4: TMenuItemInfoA): proc SetMetaFileBitsEx*(p1: WINUINT, p2: cstring): HMETAFILE{.stdcall, dynlib: "gdi32", importc: "SetMetaFileBitsEx".} proc SetNamedPipeHandleState*(hNamedPipe: THandle, lpMode: var DWORD, - lpMaxCollectionCount, lpCollectDataTimeout: Pointer): WINBOOL{.stdcall, + lpMaxCollectionCount, lpCollectDataTimeout: pointer): WINBOOL{.stdcall, dynlib: "kernel32", importc: "SetNamedPipeHandleState".} proc SetPaletteEntries*(Palette: HPALETTE, StartIndex, NumEntries: WINUINT, PaletteEntries: pointer): WINUINT{.stdcall, @@ -22405,7 +22405,7 @@ proc SetUserObjectSecurity*(hObj: THandle, pSIRequested: var DWORD, dynlib: "user32", importc: "SetUserObjectSecurity".} proc SetWaitableTimer*(hTimer: THandle, lpDueTime: var TLargeInteger, lPeriod: int32, pfnCompletionRoutine: TFNTimerAPCRoutine, - lpArgToCompletionRoutine: Pointer, fResume: WINBOOL): WINBOOL{. + lpArgToCompletionRoutine: pointer, fResume: WINBOOL): WINBOOL{. stdcall, dynlib: "kernel32", importc: "SetWaitableTimer".} proc SetWinMetaFileBits*(p1: WINUINT, p2: cstring, p3: HDC, p4: TMetaFilePict): HENHMETAFILE{. stdcall, dynlib: "gdi32", importc: "SetWinMetaFileBits".} @@ -22415,7 +22415,7 @@ proc StartDoc*(DC: HDC, p2: TDocInfo): int{.stdcall, dynlib: "gdi32", proc StartDocA*(DC: HDC, p2: TDocInfoA): int{.stdcall, dynlib: "gdi32", importc: "StartDocA".} #function StartDocW(DC: HDC; const p2: TDocInfoW): Integer; stdcall; external 'gdi32' name 'StartDocW'; - #function StretchDIBits(DC: HDC; DestX, DestY, DestWidth, DestHegiht, SrcX, SrcY, SrcWidth, SrcHeight: Integer; Bits: Pointer; var BitsInfo: TBitmapInfo; Usage: WINUINT; Rop: DWORD): Integer; stdcall; external 'gdi32' name 'StretchDIBits'; + #function StretchDIBits(DC: HDC; DestX, DestY, DestWidth, DestHegiht, SrcX, SrcY, SrcWidth, SrcHeight: Integer; Bits: pointer; var BitsInfo: TBitmapInfo; Usage: WINUINT; Rop: DWORD): Integer; stdcall; external 'gdi32' name 'StretchDIBits'; proc SubtractRect*(lprcDst: var TRect, lprcSrc1, lprcSrc2: TRect): WINBOOL{. stdcall, dynlib: "user32", importc: "SubtractRect".} proc SystemTimeToFileTime*(lpSystemTime: TSystemTime, lpFileTime: var TFileTime): WINBOOL{. @@ -22446,8 +22446,8 @@ proc TrackMouseEvent*(lpEventTrack: PTrackMouseEvent): WINBOOL{.stdcall, proc TrackPopupMenu*(menu: HMENU, uFlags: WINUINT, x: int32, y: int32, nReserved: int32, wnd: HWND, prcRect: PRect): WINBOOL{. stdcall, dynlib: "user32", importc: "TrackPopupMenu".} -proc TransactNamedPipe*(hNamedPipe: THandle, lpInBuffer: Pointer, - nInBufferSize: DWORD, lpOutBuffer: Pointer, +proc TransactNamedPipe*(hNamedPipe: THandle, lpInBuffer: pointer, + nInBufferSize: DWORD, lpOutBuffer: pointer, nOutBufferSize: DWORD, lpBytesRead: var DWORD, lpOverlapped: POverlapped): WINBOOL{.stdcall, dynlib: "kernel32", importc: "TransactNamedPipe".} @@ -22464,8 +22464,8 @@ proc TranslateMDISysAccel*(hWndClient: HWND, lpMsg: TMsg): WINBOOL{.stdcall, dynlib: "user32", importc: "TranslateMDISysAccel".} proc TranslateMessage*(lpMsg: TMsg): WINBOOL{.stdcall, dynlib: "user32", importc: "TranslateMessage".} - #function TransparentDIBits(DC: HDC; p2, p3, p4, p5: Integer; const p6: Pointer; const p7: PBitmapInfo; p8: WINUINT; p9, p10, p11, p12: Integer; p13: WINUINT): WINBOOL;stdcall; external 'gdi32' name 'TransparentDIBits'; -proc UnhandledExceptionFilter*(ExceptionInfo: TExceptionPointers): int32{. + #function TransparentDIBits(DC: HDC; p2, p3, p4, p5: Integer; const p6: pointer; const p7: PBitmapInfo; p8: WINUINT; p9, p10, p11, p12: Integer; p13: WINUINT): WINBOOL;stdcall; external 'gdi32' name 'TransparentDIBits'; +proc UnhandledExceptionFilter*(ExceptionInfo: TExceptionpointers): int32{. stdcall, dynlib: "kernel32", importc: "UnhandledExceptionFilter".} proc UnionRect*(lprcDst: var TRect, lprcSrc1, lprcSrc2: TRect): WINBOOL{. stdcall, dynlib: "user32", importc: "UnionRect".} @@ -22499,19 +22499,19 @@ proc VerInstallFileW*(uFlags: DWORD, szSrcFileName, szDestFileName, szSrcDir, szDestDir, szCurDir, szTmpFile: LPWSTR, lpuTmpFileLen: var WINUINT): DWORD{.stdcall, dynlib: "version", importc: "VerInstallFileW".} -proc VerQueryValue*(pBlock: Pointer, lpSubBlock: cstring, - lplpBuffer: var Pointer, puLen: var WINUINT): WINBOOL{.stdcall, +proc VerQueryValue*(pBlock: pointer, lpSubBlock: cstring, + lplpBuffer: var pointer, puLen: var WINUINT): WINBOOL{.stdcall, dynlib: "version", importc: "VerQueryValueA".} -proc VerQueryValueA*(pBlock: Pointer, lpSubBlock: LPCSTR, - lplpBuffer: var Pointer, puLen: var WINUINT): WINBOOL{. +proc VerQueryValueA*(pBlock: pointer, lpSubBlock: LPCSTR, + lplpBuffer: var pointer, puLen: var WINUINT): WINBOOL{. stdcall, dynlib: "version", importc: "VerQueryValueA".} -proc VerQueryValueW*(pBlock: Pointer, lpSubBlock: LPWSTR, - lplpBuffer: var Pointer, puLen: var WINUINT): WINBOOL{. +proc VerQueryValueW*(pBlock: pointer, lpSubBlock: LPWSTR, + lplpBuffer: var pointer, puLen: var WINUINT): WINBOOL{. stdcall, dynlib: "version", importc: "VerQueryValueW".} -proc VirtualQuery*(lpAddress: Pointer, lpBuffer: var TMemoryBasicInformation, +proc VirtualQuery*(lpAddress: pointer, lpBuffer: var TMemoryBasicInformation, dwLength: DWORD): DWORD{.stdcall, dynlib: "kernel32", importc: "VirtualQuery".} -proc VirtualQueryEx*(hProcess: THandle, lpAddress: Pointer, +proc VirtualQueryEx*(hProcess: THandle, lpAddress: pointer, lpBuffer: var TMemoryBasicInformation, dwLength: DWORD): DWORD{. stdcall, dynlib: "kernel32", importc: "VirtualQueryEx".} proc WaitCommEvent*(hFile: THandle, lpEvtMask: var DWORD, @@ -22528,7 +22528,7 @@ proc wglSetLayerPaletteEntries*(p1: HDC, p2, p3, p4: int, pcr: pointer): int{. stdcall, dynlib: "opengl32", importc: "wglSetLayerPaletteEntries".} #function wglSwapMultipleBuffers(p1: WINUINT; const p2: PWGLSwap): DWORD;stdcall; external 'opengl32' name 'wglSwapMultipleBuffers'; #function WinSubmitCertificate(var lpCertificate: TWinCertificate): WINBOOL;stdcall; external 'imaghlp' name 'WinSubmitCertificate'; - #function WinVerifyTrust(wnd: HWND; const ActionID: TGUID; ActionData: Pointer): Longint;stdcall; external 'imaghlp' name 'WinVerifyTrust'; + #function WinVerifyTrust(wnd: HWND; const ActionID: TGUID; ActionData: pointer): Longint;stdcall; external 'imaghlp' name 'WinVerifyTrust'; proc WNetAddConnection2*(lpNetResource: var TNetResource, lpPassword, lpUserName: cstring, dwFlags: DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetAddConnection2A".} @@ -22553,13 +22553,13 @@ proc WNetDisconnectDialog1*(lpConnDlgStruct: var TDiscDlgStruct): DWORD{. proc WNetDisconnectDialog1A*(lpConnDlgStruct: var TDiscDlgStructA): DWORD{. stdcall, dynlib: "mpr", importc: "WNetDisconnectDialog1A".} #function WNetDisconnectDialog1W(var lpConnDlgStruct: TDiscDlgStructW): DWORD; stdcall; external 'mpr' name 'WNetDisconnectDialog1W'; -proc WNetEnumResource*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: Pointer, +proc WNetEnumResource*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetEnumResourceA".} -proc WNetEnumResourceA*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: Pointer, +proc WNetEnumResourceA*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetEnumResourceA".} -proc WNetEnumResourceW*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: Pointer, +proc WNetEnumResourceW*(hEnum: THandle, lpcCount: var DWORD, lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetEnumResourceW".} proc WNetGetConnection*(lpLocalName: cstring, lpRemoteName: cstring, @@ -22601,21 +22601,21 @@ proc WNetGetProviderNameA*(dwNetType: DWORD, lpProviderName: LPCSTR, proc WNetGetProviderNameW*(dwNetType: DWORD, lpProviderName: LPWSTR, lpBufferSize: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetGetProviderNameW".} -proc WNetGetResourceParent*(lpNetResource: PNetResource, lpBuffer: Pointer, +proc WNetGetResourceParent*(lpNetResource: PNetResource, lpBuffer: pointer, cbBuffer: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetGetResourceParentA".} -proc WNetGetResourceParentA*(lpNetResource: PNetResourceA, lpBuffer: Pointer, +proc WNetGetResourceParentA*(lpNetResource: PNetResourceA, lpBuffer: pointer, cbBuffer: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetGetResourceParentA".} - #function WNetGetResourceParentW(lpNetResource: PNetResourceW; lpBuffer: Pointer; var cbBuffer: DWORD): DWORD;stdcall; external 'mpr' name 'WNetGetResourceParentW'; + #function WNetGetResourceParentW(lpNetResource: PNetResourceW; lpBuffer: pointer; var cbBuffer: DWORD): DWORD;stdcall; external 'mpr' name 'WNetGetResourceParentW'; proc WNetGetUniversalName*(lpLocalPath: cstring, dwInfoLevel: DWORD, - lpBuffer: Pointer, lpBufferSize: var DWORD): DWORD{. + lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetGetUniversalNameA".} proc WNetGetUniversalNameA*(lpLocalPath: LPCSTR, dwInfoLevel: DWORD, - lpBuffer: Pointer, lpBufferSize: var DWORD): DWORD{. + lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetGetUniversalNameA".} proc WNetGetUniversalNameW*(lpLocalPath: LPWSTR, dwInfoLevel: DWORD, - lpBuffer: Pointer, lpBufferSize: var DWORD): DWORD{. + lpBuffer: pointer, lpBufferSize: var DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetGetUniversalNameW".} proc WNetGetUser*(lpName: cstring, lpUserName: cstring, lpnLength: var DWORD): DWORD{. stdcall, dynlib: "mpr", importc: "WNetGetUserA".} @@ -22641,13 +22641,13 @@ proc WNetUseConnectionA*(hwndOwner: HWND, lpNetResource: var TNetResourceA, lpResult: var DWORD): DWORD{.stdcall, dynlib: "mpr", importc: "WNetUseConnectionA".} #function WNetUseConnectionW(hwndOwner: HWND; var lpNetResource: TNetResourceW; lpUserID: LPWSTR; lpPassword: LPWSTR; dwFlags: DWORD; lpAccessName: LPWSTR; var lpBufferSize: DWORD; var lpResult: DWORD): DWORD; stdcall; external 'mpr' name 'WNetUseConnectionW'; -proc WriteConsole*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsole*(hConsoleOutput: THandle, lpBuffer: pointer, nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: var DWORD, lpReserved: Pointer): WINBOOL{. + lpNumberOfCharsWritten: var DWORD, lpReserved: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleA".} -proc WriteConsoleA*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleA*(hConsoleOutput: THandle, lpBuffer: pointer, nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: var DWORD, lpReserved: Pointer): WINBOOL{. + lpNumberOfCharsWritten: var DWORD, lpReserved: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleA".} proc WriteConsoleInput*(hConsoleInput: THandle, lpBuffer: TInputRecord, nLength: DWORD, lpNumberOfEventsWritten: var DWORD): WINBOOL{. @@ -22658,15 +22658,15 @@ proc WriteConsoleInputA*(hConsoleInput: THandle, lpBuffer: TInputRecord, proc WriteConsoleInputW*(hConsoleInput: THandle, lpBuffer: TInputRecord, nLength: DWORD, lpNumberOfEventsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleInputW".} -proc WriteConsoleOutput*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleOutput*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpWriteRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputA".} -proc WriteConsoleOutputA*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleOutputA*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpWriteRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputA".} -proc WriteConsoleOutputAttribute*(hConsoleOutput: THandle, lpAttribute: Pointer, +proc WriteConsoleOutputAttribute*(hConsoleOutput: THandle, lpAttribute: pointer, nLength: DWORD, dwWriteCoord: TCoord, lpNumberOfAttrsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputAttribute".} @@ -22682,18 +22682,18 @@ proc WriteConsoleOutputCharacterW*(hConsoleOutput: THandle, lpCharacter: LPWSTR, nLength: DWORD, dwWriteCoord: TCoord, lpNumberOfCharsWritten: var DWORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputCharacterW".} -proc WriteConsoleOutputW*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleOutputW*(hConsoleOutput: THandle, lpBuffer: pointer, dwBufferSize, dwBufferCoord: TCoord, lpWriteRegion: var TSmallRect): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteConsoleOutputW".} -proc WriteConsoleW*(hConsoleOutput: THandle, lpBuffer: Pointer, +proc WriteConsoleW*(hConsoleOutput: THandle, lpBuffer: pointer, nNumberOfCharsToWrite: DWORD, - lpNumberOfCharsWritten: var DWORD, lpReserved: Pointer): WINBOOL{. + lpNumberOfCharsWritten: var DWORD, lpReserved: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteConsoleW".} proc WriteFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: DWORD, lpNumberOfBytesWritten: var DWORD, lpOverlapped: POverlapped): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteFile".} -proc WriteFileEx*(hFile: THandle, lpBuffer: Pointer, +proc WriteFileEx*(hFile: THandle, lpBuffer: pointer, nNumberOfBytesToWrite: DWORD, lpOverlapped: TOverlapped, lpCompletionRoutine: FARPROC): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteFileEx".} @@ -22707,8 +22707,8 @@ proc WritePrivateProfileStructW*(lpszSection, lpszKey: LPCWSTR, proc WritePrivateProfileStruct*(lpszSection, lpszKey: LPCTSTR, lpStruct: LPVOID, uSizeStruct: WINUINT, szFile: LPCTSTR): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WritePrivateProfileStructA".} -proc WriteProcessMemory*(hProcess: THandle, lpBaseAddress: Pointer, - lpBuffer: Pointer, nSize: DWORD, +proc WriteProcessMemory*(hProcess: THandle, lpBaseAddress: pointer, + lpBuffer: pointer, nSize: DWORD, lpNumberOfBytesWritten: var DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "WriteProcessMemory".} proc SHFileOperation*(para1: var SHFILEOPSTRUCT): int32{.stdcall, @@ -22821,7 +22821,7 @@ proc INDEXTOSTATEIMAGEMASK*(i: int32): int32 = result = i shl 12'i32 proc MAKEINTATOM*(i: int32): LPTSTR = - result = cast[LPTSTR](cast[ULONG_PTR](ToU16(i))) + result = cast[LPTSTR](cast[ULONG_PTR](toU16(i))) proc MAKELANGID*(p, s: int32): int32 = # return type might be wrong @@ -22849,10 +22849,10 @@ proc MAKEROP4*(fore, back: int32): DWORD = proc MAKEWPARAM*(L, h: int32): WPARAM = result = WPARAM(MAKELONG(L, h)) -proc GET_X_LPARAM*(lp: Windows.LParam): int32 = +proc GET_X_LPARAM*(lp: windows.LParam): int32 = result = LOWORD(lp.int32) -proc GET_Y_LPARAM*(lp: Windows.LParam): int32 = +proc GET_Y_LPARAM*(lp: windows.LParam): int32 = result = HIWORD(lp.int32) proc UNICODE_NULL*(): WCHAR = @@ -23229,10 +23229,10 @@ proc set_fAckReq(a: var DDEUP, fAckReq: int16) = a.flag0 = a.flag0 or ((fAckReq shl bp_DDEUP_fAckReq) and bm_DDEUP_fAckReq) proc CreateWindowA(lpClassName: LPCSTR, lpWindowName: LPCSTR, dwStyle: DWORD, - X: int32, Y: int32, nWidth: int32, nHeight: int32, + X, Y, nWidth, nHeight: int32, hWndParent: HWND, menu: HMENU, hInstance: HINST, lpParam: LPVOID): HWND = - result = CreateWindowExA(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, + result = CreateWindowExA(0, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, menu, hInstance, lpParam) proc CreateDialogA(hInstance: HINST, lpTemplateName: LPCSTR, hWndParent: HWND, @@ -23259,7 +23259,7 @@ proc CreateWindowW(lpClassName: LPCWSTR, lpWindowName: LPCWSTR, dwStyle: DWORD, X: int32, Y: int32, nWidth: int32, nHeight: int32, hWndParent: HWND, menu: HMENU, hInstance: HINST, lpParam: LPVOID): HWND = - result = CreateWindowExW(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, + result = CreateWindowExW(0, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, menu, hInstance, lpParam) proc CreateDialogW(hInstance: HINST, lpName: LPCWSTR, hWndParent: HWND, @@ -23285,7 +23285,7 @@ when defined(winUnicode): X: int32, Y: int32, nWidth: int32, nHeight: int32, hWndParent: HWND, menu: HMENU, hInstance: HINST, lpParam: LPVOID): HWND = - result = CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, + result = CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam) proc CreateDialog(hInstance: HINST, lpName: LPCWSTR, hWndParent: HWND, @@ -23311,7 +23311,7 @@ else: X: int32, Y: int32, nWidth: int32, nHeight: int32, hWndParent: HWND, menu: HMENU, hInstance: HINST, lpParam: LPVOID): HWND = - result = CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, + result = CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, menu, hInstance, lpParam) proc CreateDialog(hInstance: HINST, lpTemplateName: LPCSTR, hWndParent: HWND, @@ -23334,24 +23334,24 @@ else: result = DialogBoxIndirectParam(hInstance, hDialogTemplate, hWndParent, lpDialogFunc, 0) -proc GlobalAllocPtr(flags, cb: DWord): Pointer = +proc GlobalAllocPtr(flags, cb: DWord): pointer = result = GlobalLock(GlobalAlloc(flags, cb)) -proc GlobalFreePtr(lp: Pointer): Pointer = - result = cast[Pointer](GlobalFree(cast[HWND](GlobalUnlockPtr(lp)))) +proc GlobalFreePtr(lp: pointer): pointer = + result = cast[pointer](GlobalFree(cast[HWND](GlobalUnlockPtr(lp)))) -proc GlobalUnlockPtr(lp: pointer): Pointer = +proc GlobalUnlockPtr(lp: pointer): pointer = discard GlobalUnlock(GlobalHandle(lp)) result = lp -proc GlobalLockPtr(lp: pointer): Pointer = +proc GlobalLockPtr(lp: pointer): pointer = result = GlobalLock(GlobalHandle(lp)) -proc GlobalReAllocPtr(lp: Pointer, cbNew, flags: DWord): Pointer = +proc GlobalReAllocPtr(lp: pointer, cbNew, flags: DWord): pointer = result = GlobalLock(GlobalReAlloc(cast[HWND](GlobalUnlockPtr(lp)), cbNew, flags)) -proc GlobalPtrHandle(lp: pointer): Pointer = - result = cast[Pointer](GlobalHandle(lp)) +proc GlobalPtrHandle(lp: pointer): pointer = + result = cast[pointer](GlobalHandle(lp)) proc ImageList_AddIcon(himl: HIMAGELIST, hicon: HICON): int32 = result = ImageList_ReplaceIcon(himl, -1, hicon) @@ -23502,7 +23502,7 @@ proc ListView_GetCountPerPage(hwndLV: HWND): LRESULT = proc ListView_GetEditControl(hwndLV: HWND): LRESULT = result = SendMessage(hwndLV, LVM_GETEDITCONTROL, 0, 0) -proc ListView_GetImageList(wnd: HWND, iImageList: wINT): LRESULT = +proc ListView_GetImageList(wnd: HWND, iImageList: WINT): LRESULT = result = SendMessage(wnd, LVM_GETIMAGELIST, WPARAM(iImageList), 0) proc ListView_GetISearchString(hwndLV: HWND, lpsz: LPTSTR): LRESULT = @@ -23702,7 +23702,7 @@ proc TreeView_SetItem(wnd: HWND, item: var TV_ITEM): LRESULT = result = SendMessage(wnd, TVM_SETITEM, 0, cast[LPARAM](addr(item))) proc TreeView_EditLabel(wnd: HWND, hitem: HTREEITEM): LRESULT = - Result = SendMessage(wnd, TVM_EDITLABEL, 0, cast[LPARAM](hitem)) + result = SendMessage(wnd, TVM_EDITLABEL, 0, cast[LPARAM](hitem)) proc TreeView_GetEditControl(wnd: HWND): LRESULT = result = SendMessage(wnd, TVM_GETEDITCONTROL, 0, 0) @@ -23854,10 +23854,10 @@ proc CommDlg_OpenSave_SetDefExt(hdlg: HWND, pszext: LPSTR): LRESULT = proc InternalGetLargestConsoleWindowSize(hConsoleOutput: HANDLE): DWord{. stdcall, dynlib: "kernel32", importc: "GetLargestConsoleWindowSize".} proc GetLargestConsoleWindowSize(hConsoleOutput: HANDLE): COORD = - var res: dword + var res: DWORD res = InternalGetLargestConsoleWindowSize(hConsoleOutput) - result.y = toU16(res and 0x0000ffff) # XXX: correct? - result.x = toU16(res shr 16) + result.Y = toU16(res and 0x0000ffff) # XXX: correct? + result.X = toU16(res shr 16) proc Succeeded(Status: HRESULT): WINBOOL = result = (Status and 0x80000000).WinBool From 16b15f360a72706c993fa6886a2baa0e28ef661c Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 00:57:21 +0200 Subject: [PATCH 039/409] updated the tester --- tests/testament/specs.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim index 184f07c51..f02b26f5b 100644 --- a/tests/testament/specs.nim +++ b/tests/testament/specs.nim @@ -59,7 +59,7 @@ when not declared(parseCfgBool): case normalize(s) of "y", "yes", "true", "1", "on": result = true of "n", "no", "false", "0", "off": result = false - else: raise newException(EInvalidValue, "cannot interpret as a bool: " & s) + else: raise newException(ValueError, "cannot interpret as a bool: " & s) proc extractSpec(filename: string): string = const tripleQuote = "\"\"\"" @@ -78,7 +78,7 @@ when not defined(nimhygiene): template parseSpecAux(fillResult: stmt) {.immediate.} = var ss = newStringStream(extractSpec(filename)) - var p {.inject.}: TCfgParser + var p {.inject.}: CfgParser open(p, ss, filename, 1) while true: var e {.inject.} = next(p) From 28c3de7d3e73ab682b74e56210851d8925957c84 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 01:02:04 +0200 Subject: [PATCH 040/409] updated terminal.nim --- lib/pure/terminal.nim | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 323b8b216..1c1d973ee 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -33,7 +33,7 @@ when defined(windows): var c: TCONSOLESCREENBUFFERINFO if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: raiseOSError(osLastError()) - return (int(c.dwCursorPosition.x), int(c.dwCursorPosition.y)) + return (int(c.dwCursorPosition.X), int(c.dwCursorPosition.Y)) proc getAttributes(): int16 = var c: TCONSOLESCREENBUFFERINFO @@ -50,8 +50,8 @@ proc setCursorPos*(x, y: int) = ## upper left of the screen. when defined(windows): var c: TCOORD - c.x = int16(x) - c.y = int16(y) + c.X = int16(x) + c.Y = int16(y) if SetConsoleCursorPosition(conHandle, c) == 0: raiseOSError(osLastError()) else: stdout.write("\e[" & $y & ';' & $x & 'f') @@ -65,7 +65,7 @@ proc setCursorXPos*(x: int) = if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition - origin.x = int16(x) + origin.X = int16(x) if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) else: @@ -81,7 +81,7 @@ when defined(windows): if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition - origin.y = int16(y) + origin.Y = int16(y) if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) else: @@ -163,7 +163,7 @@ proc eraseLine* = if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: raiseOSError(osLastError()) var origin = scrbuf.dwCursorPosition - origin.x = 0'i16 + origin.X = 0'i16 if SetConsoleCursorPosition(conHandle, origin) == 0: raiseOSError(osLastError()) var ht = scrbuf.dwSize.Y - origin.Y From 6713ebcd9808f79d9ccdf02c38c58a17cd9eee9c Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 01:12:18 +0200 Subject: [PATCH 041/409] tester compiles again --- tests/actiontable/tactiontable2.nim | 2 +- tests/assert/tassert.nim | 2 +- tests/testament/categories.nim | 20 ++++++++++---------- tests/testament/specs.nim | 2 +- tests/testament/tester.nim | 18 +++++++++--------- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/actiontable/tactiontable2.nim b/tests/actiontable/tactiontable2.nim index bfeb1c169..99bb3dca0 100644 --- a/tests/actiontable/tactiontable2.nim +++ b/tests/actiontable/tactiontable2.nim @@ -1,6 +1,6 @@ discard """ line: 21 - errormsg: "invalid type: 'TTable[string, proc (string){.gcsafe.}]'" + errormsg: "invalid type: 'Table[string, proc (string){.gcsafe.}]'" """ import tables diff --git a/tests/assert/tassert.nim b/tests/assert/tassert.nim index 0ea8d2034..b3df30bd1 100644 --- a/tests/assert/tassert.nim +++ b/tests/assert/tassert.nim @@ -5,7 +5,7 @@ discard """ """ # test assert and exception handling -proc callB() = assert(False) +proc callB() = assert(false) proc callA() = callB() proc callC() = callA() diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 02f7dc1d7..a81e4687a 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -1,6 +1,6 @@ # # -# Nimrod Tester +# Nim Tester # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -20,7 +20,7 @@ const proc delNimCache() = try: removeDir(nimcacheDir) - except EOS: + except OSError: echo "[Warning] could not delete: ", nimcacheDir proc runRodFiles(r: var TResults, cat: Category, options: string) = @@ -71,7 +71,7 @@ proc compileRodFiles(r: var TResults, cat: Category, options: string) = proc safeCopyFile(src, dest: string) = try: copyFile(src, dest) - except EOS: + except OSError: echo "[Warning] could not copy: ", src, " to ", dest proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = @@ -236,8 +236,8 @@ let packageDir = babelDir / "pkgs" packageIndex = babelDir / "packages.json" -proc waitForExitEx(p: PProcess): int = - var outp: PStream = outputStream(p) +proc waitForExitEx(p: Process): int = + var outp = outputStream(p) var line = newStringOfCap(120).TaintedString while true: if outp.readLine(line): @@ -250,7 +250,7 @@ proc waitForExitEx(p: PProcess): int = proc getPackageDir(package: string): string = ## TODO - Replace this with dom's version comparison magic. var commandOutput = execCmdEx("babel path $#" % package) - if commandOutput.exitCode != quitSuccess: + if commandOutput.exitCode != QuitSuccess: return "" else: result = commandOutput[0].string @@ -278,7 +278,7 @@ proc testBabelPackages(r: var TResults, cat: Category, filter: PackageFilter) = echo("[Warning] - Cannot run babel tests: Babel binary not found.") return - if execCmd("$# update" % babelExe) == quitFailure: + if execCmd("$# update" % babelExe) == QuitFailure: echo("[Warning] - Cannot run babel tests: Babel update failed.") return @@ -291,7 +291,7 @@ proc testBabelPackages(r: var TResults, cat: Category, filter: PackageFilter) = installProcess = startProcess(babelExe, "", ["install", "-y", name]) installStatus = waitForExitEx(installProcess) installProcess.close - if installStatus != quitSuccess: + if installStatus != QuitSuccess: r.addResult(test, "", "", reInstallFailed) continue @@ -301,11 +301,11 @@ proc testBabelPackages(r: var TResults, cat: Category, filter: PackageFilter) = buildProcess = startProcess(babelExe, buildPath, ["build"]) buildStatus = waitForExitEx(buildProcess) buildProcess.close - if buildStatus != quitSuccess: + if buildStatus != QuitSuccess: r.addResult(test, "", "", reBuildFailed) r.addResult(test, "", "", reSuccess) r.addResult(packageFileTest, "", "", reSuccess) - except EJsonParsingError: + except JsonParsingError: echo("[Warning] - Cannot run babel tests: Invalid package file.") r.addResult(packageFileTest, "", "", reBuildFailed) diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim index f02b26f5b..b2cccca56 100644 --- a/tests/testament/specs.nim +++ b/tests/testament/specs.nim @@ -1,6 +1,6 @@ # # -# Nimrod Tester +# Nim Tester # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim index fc6b4ff95..732a5e86a 100644 --- a/tests/testament/tester.nim +++ b/tests/testament/tester.nim @@ -1,6 +1,6 @@ # # -# Nimrod Tester +# Nim Tester # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -146,9 +146,9 @@ proc codegenCheck(test: TTest, check: string, given: var TSpec) = let contents = readFile(genFile).string if contents.find(check.peg) < 0: given.err = reCodegenFailure - except EInvalidValue: + except ValueError: given.err = reInvalidPeg - except EIO: + except IOError: given.err = reCodeNotFound proc makeDeterministic(s: string): string = @@ -193,7 +193,7 @@ proc testSpec(r: var TResults, test: TTest) = return var (buf, exitCode) = execCmdEx( (if test.target == targetJS: "nodejs " else: "") & exeFile) - if exitCode != expected.ExitCode: + if exitCode != expected.exitCode: r.addResult(test, "exitcode: " & $expected.exitCode, "exitcode: " & $exitCode, reExitCodesDiffer) else: @@ -246,15 +246,15 @@ proc main() = if p.kind == cmdLongoption: case p.key.string.normalize of "print", "verbose": optPrintResults = true - else: quit usage + else: quit Usage p.next() - if p.kind != cmdArgument: quit usage + if p.kind != cmdArgument: quit Usage var action = p.key.string.normalize p.next() var r = initResults() case action of "all": - let testsDir = "tests" & dirSep + let testsDir = "tests" & DirSep for kind, dir in walkDir(testsDir): assert testsDir.startsWith(testsDir) let cat = dir[testsDir.len .. -1] @@ -272,7 +272,7 @@ proc main() = generateHtml(resultsFile, commit) generateJson(jsonFile, commit) else: - quit usage + quit Usage if optPrintResults: if action == "html": openDefaultBrowser(resultsFile) @@ -280,6 +280,6 @@ proc main() = backend.close() if paramCount() == 0: - quit usage + quit Usage main() From a68f17a9f78e762a8cb77a1fa088e2a507ae44a4 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 01:28:48 +0200 Subject: [PATCH 042/409] posix.nim compiles again --- lib/posix/posix.nim | 68 +++++++++++++++++------------------ tools/cmerge.nim | 8 ++--- tools/detect/detect.nim | 4 +-- tools/nimgrep.nim | 6 ++-- tools/niminst/debcreation.nim | 28 +++++++-------- tools/niminst/niminst.nim | 18 +++++----- tools/nimrepl.nim | 14 ++++---- tools/nimweb.nim | 4 +-- tools/website.tmpl | 2 +- 9 files changed, 76 insertions(+), 76 deletions(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 430d82429..71a75471e 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -267,9 +267,9 @@ type ## For a typed memory object, the length in bytes. ## For other file types, the use of this field is ## unspecified. - st_atime*: TTime ## Time of last access. - st_mtime*: TTime ## Time of last data modification. - st_ctime*: TTime ## Time of last status change. + st_atime*: Time ## Time of last access. + st_mtime*: Time ## Time of last data modification. + st_ctime*: Time ## Time of last status change. st_blksize*: Tblksize ## A file system-specific preferred I/O block size ## for this object. In some file system types, this ## may vary from file to file. @@ -310,7 +310,7 @@ type tm_isdst*: cint ## Daylight Savings flag. Ttimespec* {.importc: "struct timespec", header: "", final, pure.} = object ## struct timespec - tv_sec*: TTime ## Seconds. + tv_sec*: Time ## Seconds. tv_nsec*: int ## Nanoseconds. titimerspec* {.importc: "struct itimerspec", header: "", final, pure.} = object ## struct itimerspec @@ -449,17 +449,17 @@ type Tmsghdr* {.importc: "struct msghdr", pure, final, header: "".} = object ## struct msghdr msg_name*: pointer ## Optional address. - msg_namelen*: TSocklen ## Size of address. + msg_namelen*: Socklen ## Size of address. msg_iov*: ptr TIOVec ## Scatter/gather array. msg_iovlen*: cint ## Members in msg_iov. msg_control*: pointer ## Ancillary data; see below. - msg_controllen*: TSocklen ## Ancillary data buffer len. + msg_controllen*: Socklen ## Ancillary data buffer len. msg_flags*: cint ## Flags on received message. Tcmsghdr* {.importc: "struct cmsghdr", pure, final, header: "".} = object ## struct cmsghdr - cmsg_len*: TSocklen ## Data byte count, including the cmsghdr. + cmsg_len*: Socklen ## Data byte count, including the cmsghdr. cmsg_level*: cint ## Originating protocol. cmsg_type*: cint ## Protocol-specific type. @@ -564,7 +564,7 @@ type {.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo, TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval, TFdSet: FdSet, Thostent: Hostent, TServent: Servent, - TInAddr: InAddr, Tin6_addr: In6_addr, Tsockaddr_in6: Sockaddr_in6].} + TInAddr: InAddr].} var errno* {.importc, header: "".}: cint ## error variable @@ -1799,11 +1799,11 @@ proc inet_pton*(a1: cint, a2: cstring, a3: pointer): cint {. importc, header: "".} var - in6addr_any* {.importc, header: "".}: In6_addr - in6addr_loopback* {.importc, header: "".}: In6_addr + in6addr_any* {.importc, header: "".}: TIn6_addr + in6addr_loopback* {.importc, header: "".}: TIn6_addr -proc IN6ADDR_ANY_INIT* (): In6_addr {.importc, header: "".} -proc IN6ADDR_LOOPBACK_INIT* (): In6_addr {.importc, header: "".} +proc IN6ADDR_ANY_INIT* (): TIn6_addr {.importc, header: "".} +proc IN6ADDR_LOOPBACK_INIT* (): TIn6_addr {.importc, header: "".} # dirent.h proc closedir*(a1: ptr TDIR): cint {.importc, header: "".} @@ -2285,22 +2285,22 @@ proc clock_nanosleep*(a1: TClockId, a2: cint, a3: var Ttimespec, proc clock_settime*(a1: TClockId, a2: var Ttimespec): cint {. importc, header: "".} -proc ctime*(a1: var TTime): cstring {.importc, header: "".} -proc ctime_r*(a1: var TTime, a2: cstring): cstring {.importc, header: "".} -proc difftime*(a1, a2: TTime): cdouble {.importc, header: "".} +proc ctime*(a1: var Time): cstring {.importc, header: "".} +proc ctime_r*(a1: var Time, a2: cstring): cstring {.importc, header: "".} +proc difftime*(a1, a2: Time): cdouble {.importc, header: "".} proc getdate*(a1: cstring): ptr Ttm {.importc, header: "".} -proc gmtime*(a1: var TTime): ptr Ttm {.importc, header: "".} -proc gmtime_r*(a1: var TTime, a2: var Ttm): ptr Ttm {.importc, header: "".} -proc localtime*(a1: var TTime): ptr Ttm {.importc, header: "".} -proc localtime_r*(a1: var TTime, a2: var Ttm): ptr Ttm {.importc, header: "".} -proc mktime*(a1: var Ttm): TTime {.importc, header: "".} -proc timegm*(a1: var Ttm): TTime {.importc, header: "".} +proc gmtime*(a1: var Time): ptr Ttm {.importc, header: "".} +proc gmtime_r*(a1: var Time, a2: var Ttm): ptr Ttm {.importc, header: "".} +proc localtime*(a1: var Time): ptr Ttm {.importc, header: "".} +proc localtime_r*(a1: var Time, a2: var Ttm): ptr Ttm {.importc, header: "".} +proc mktime*(a1: var Ttm): Time {.importc, header: "".} +proc timegm*(a1: var Ttm): Time {.importc, header: "".} proc nanosleep*(a1, a2: var Ttimespec): cint {.importc, header: "".} proc strftime*(a1: cstring, a2: int, a3: cstring, a4: var Ttm): int {.importc, header: "".} proc strptime*(a1, a2: cstring, a3: var Ttm): cstring {.importc, header: "".} -proc time*(a1: var TTime): TTime {.importc, header: "".} +proc time*(a1: var Time): Time {.importc, header: "".} proc timer_create*(a1: var TClockId, a2: var TsigEvent, a3: var Ttimer): cint {.importc, header: "".} proc timer_delete*(a1: var Ttimer): cint {.importc, header: "".} @@ -2517,40 +2517,40 @@ proc if_indextoname*(a1: cint, a2: cstring): cstring {. proc if_nameindex*(): ptr Tif_nameindex {.importc, header: "".} proc if_freenameindex*(a1: ptr Tif_nameindex) {.importc, header: "".} -proc IN6_IS_ADDR_UNSPECIFIED* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_UNSPECIFIED* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Unspecified address. -proc IN6_IS_ADDR_LOOPBACK* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_LOOPBACK* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Loopback address. -proc IN6_IS_ADDR_MULTICAST* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_MULTICAST* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Multicast address. -proc IN6_IS_ADDR_LINKLOCAL* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_LINKLOCAL* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Unicast link-local address. -proc IN6_IS_ADDR_SITELOCAL* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_SITELOCAL* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Unicast site-local address. -proc IN6_IS_ADDR_V4MAPPED* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_V4MAPPED* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## IPv4 mapped address. -proc IN6_IS_ADDR_V4COMPAT* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_V4COMPAT* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## IPv4-compatible address. -proc IN6_IS_ADDR_MC_NODELOCAL* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_MC_NODELOCAL* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Multicast node-local address. -proc IN6_IS_ADDR_MC_LINKLOCAL* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_MC_LINKLOCAL* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Multicast link-local address. -proc IN6_IS_ADDR_MC_SITELOCAL* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_MC_SITELOCAL* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Multicast site-local address. -proc IN6_IS_ADDR_MC_ORGLOCAL* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_MC_ORGLOCAL* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Multicast organization-local address. -proc IN6_IS_ADDR_MC_GLOBAL* (a1: ptr In6_addr): cint {. +proc IN6_IS_ADDR_MC_GLOBAL* (a1: ptr TIn6_addr): cint {. importc, header: "".} ## Multicast global address. diff --git a/tools/cmerge.nim b/tools/cmerge.nim index 003b0e555..d2e540481 100644 --- a/tools/cmerge.nim +++ b/tools/cmerge.nim @@ -3,10 +3,10 @@ import os, sets, pegs type - TProcessResult = enum prSkipIncludeDir, prAddIncludeDir + ProcessResult = enum prSkipIncludeDir, prAddIncludeDir -proc process(dir, infile: string, outfile: TFile, - processed: var TSet[string]): TProcessResult = +proc process(dir, infile: string, outfile: File, + processed: var HashSet[string]): ProcessResult = if processed.containsOrIncl(infile): return prSkipIncludeDir let toProcess = dir / infile if not existsFile(toProcess): @@ -24,7 +24,7 @@ proc process(dir, infile: string, outfile: TFile, writeln(outfile, line) proc main(dir, outfile: string) = - var o: TFile + var o: File if open(o, outfile, fmWrite): var processed = initSet[string]() processed.incl(outfile) diff --git a/tools/detect/detect.nim b/tools/detect/detect.nim index 87b682ad5..77efdaacd 100644 --- a/tools/detect/detect.nim +++ b/tools/detect/detect.nim @@ -1,8 +1,8 @@ # Posix detect program # (c) 2010 Andreas Rumpf -# This program produces a C program that produces a Nimrod include file. -# The Nimrod include file lists the values of each POSIX constant. +# This program produces a C program that produces a Nim include file. +# The Nim include file lists the values of each POSIX constant. # This is needed because POSIX is brain-dead: It only cares for C, any other # language is ignored. It would have been easier had they specified the # concrete values of the constants. Sigh. diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim index 28d92402e..7f9910f78 100644 --- a/tools/nimgrep.nim +++ b/tools/nimgrep.nim @@ -1,6 +1,6 @@ # # -# Nimrod Grep Utility +# Nim Grep Utility # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -12,7 +12,7 @@ import const Version = "0.9" - Usage = "nimgrep - Nimrod Grep Utility Version " & version & """ + Usage = "nimgrep - Nim Grep Utility Version " & version & """ (c) 2012 Andreas Rumpf Usage: @@ -194,7 +194,7 @@ proc processFile(filename: string) = i = t.last+1 if optReplace in options: result.add(substr(buffer, i)) - var f: TFile + var f: File if open(f, filename, fmWrite): f.write(result) f.close() diff --git a/tools/niminst/debcreation.nim b/tools/niminst/debcreation.nim index 1f4a8630e..574f7ea6b 100644 --- a/tools/niminst/debcreation.nim +++ b/tools/niminst/debcreation.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Installation Generator +# The Nim Installation Generator # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -104,7 +104,7 @@ proc createChangelog(pkgName, version, maintainer: string): string = formatDateTime(getGMTime(getTime()), "+0000")) proc createRules(): string = - ## Creates a nimrod application-agnostic rules file for building deb packages. + ## Creates a nim application-agnostic rules file for building deb packages. ## Please note: this assumes the c sources have been built and the ## ``build.sh`` and ``install.sh`` files are available. result = "" @@ -131,9 +131,9 @@ proc createDotInstall(pkgName: string, binaries, config, docs, for c in config: addN(pkgName / c & " " & "etc/") for d in docs: - addN(pkgName / d & " " & "usr/share/doc/nimrod/") + addN(pkgName / d & " " & "usr/share/doc/nim/") for l1 in lib: - addN(pkgName / l1 & " " & "usr/lib/nimrod") + addN(pkgName / l1 & " " & "usr/lib/nim") proc makeMtn(name, email: string): string = return name & " <" & email & ">" @@ -145,7 +145,7 @@ proc prepDeb*(packName, version, mtnName, mtnEmail, shortDesc, desc: string, licenses: seq[tuple[files, license: string]], binaries, config, docs, lib: seq[string], buildDepends, pkgDepends = "") = - ## binaries/config/docs/lib: files relative to nimrod's root, that need to + ## binaries/config/docs/lib: files relative to nim's root, that need to ## be installed. let pkgName = packName.toLower() @@ -212,24 +212,24 @@ proc prepDeb*(packName, version, mtnName, mtnEmail, shortDesc, desc: string, echo("And execute `debuild -us -uc` to build the .deb") when isMainModule: - #var controlFile = createControl("nimrod", "Dominik Picheta ", - # "The Nimrod compiler", "Compiler for the Nimrod programming language", "gcc (>= 4:4.3.2)", "gcc (>= 4:4.3.2)") + #var controlFile = createControl("nim", "Dominik Picheta ", + # "The Nim compiler", "Compiler for the Nim programming language", "gcc (>= 4:4.3.2)", "gcc (>= 4:4.3.2)") #echo(controlFile) - #var copyrightFile = createCopyright("nimrod", "Dominik Picheta", "morfeusz8@a.b", "0.8.14", - # @[("bin/nimrod", "gpl2"), ("lib/*", "lgpl")]) + #var copyrightFile = createCopyright("nim", "Dominik Picheta", "morfeusz8@a.b", "0.8.14", + # @[("bin/nim", "gpl2"), ("lib/*", "lgpl")]) #echo copyrightFile - #var changelogFile = createChangelog("nimrod", "0.8.14", "Dom P ") + #var changelogFile = createChangelog("nim", "0.8.14", "Dom P ") #echo(changelogFile) #echo(createRules()) - prepDeb("nimrod", "0.9.2", "Dominik Picheta", "morfeusz8@gmail.com", - "The Nimrod compiler", "Compiler for the Nimrod programming language", - @[("bin/nimrod", "MIT"), ("lib/*", "MIT")], - @["bin/nimrod"], @["config/*"], @["doc/*"], @["lib/*"], + prepDeb("nim", "0.9.2", "Dominik Picheta", "morfeusz8@gmail.com", + "The Nim compiler", "Compiler for the Nim programming language", + @[("bin/nim", "MIT"), ("lib/*", "MIT")], + @["bin/nim"], @["config/*"], @["doc/*"], @["lib/*"], "gcc (>= 4:4.3.2)", "gcc (>= 4:4.3.2)") diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index bf8a7a84f..686a0bfa3 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -1,7 +1,7 @@ # # -# The Nimrod Installation Generator -# (c) Copyright 2013 Andreas Rumpf +# The Nim Installation Generator +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -60,7 +60,7 @@ type explicitPlatforms: bool vars: PStringTable app: TAppType - nimrodArgs: string + nimArgs: string debOpts: TDebOptions const @@ -85,7 +85,7 @@ proc initConfigData(c: var TConfigData) = c.license = "" c.infile = "" c.outdir = "" - c.nimrodArgs = "" + c.nimArgs = "" c.libpath = "" c.innoSetupFlag = false c.installScript = false @@ -126,7 +126,7 @@ include "deinstall.tmpl" const Version = "0.9" - Usage = "niminst - Nimrod Installation Generator Version " & Version & """ + Usage = "niminst - Nim Installation Generator Version " & Version & """ (c) 2013 Andreas Rumpf Usage: @@ -166,7 +166,7 @@ proc parseCmdLine(c: var TConfigData) = else: quit(Usage) else: c.infile = addFileExt(key.string, "ini") - c.nimrodArgs = cmdLineRest(p).string + c.nimArgs = cmdLineRest(p).string break of cmdLongoption, cmdShortOption: case normalize(key.string) @@ -451,14 +451,14 @@ proc srcdist(c: var TConfigData) = var dir = getOutputDir(c) / buildDir(osA, cpuA) if existsDir(dir): removeDir(dir) createDir(dir) - var cmd = ("nimrod compile -f --symbolfiles:off --compileonly " & + var cmd = ("nim compile -f --symbolfiles:off --compileonly " & "--gen_mapping --cc:gcc --skipUserCfg" & " --os:$# --cpu:$# $# $#") % - [osname, cpuname, c.nimrodArgs, + [osname, cpuname, c.nimArgs, changeFileExt(c.infile, "nim")] echo(cmd) if execShellCmd(cmd) != 0: - quit("Error: call to nimrod compiler failed") + quit("Error: call to nim compiler failed") readCFiles(c, osA, cpuA) for i in 0 .. c.cfiles[osA][cpuA].len-1: let dest = dir / extractFilename(c.cfiles[osA][cpuA][i]) diff --git a/tools/nimrepl.nim b/tools/nimrepl.nim index 4b6379bd5..0c9f94616 100644 --- a/tools/nimrepl.nim +++ b/tools/nimrepl.nim @@ -1,6 +1,6 @@ # # -# Nimrod REPL +# Nim REPL # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -14,8 +14,8 @@ when defined(tinyc): else: const runCmd = "c -r" -var nimExe = findExe("nimrod") -if nimExe.len == 0: nimExe = "../bin" / addFileExt("nimrod", os.exeExt) +var nimExe = findExe("nim") +if nimExe.len == 0: nimExe = "../bin" / addFileExt("nim", os.exeExt) proc execCode(code: string): string = var f: TFile @@ -36,7 +36,7 @@ var OutputTextBuffer: PTextBuffer proc destroy(widget: PWidget, data: pgpointer){.cdecl.} = main_quit() -proc FileOpenClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} = +proc fileOpenClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} = var path = ChooseFileToOpen(w) if path != "": var file = readFile(path) @@ -45,7 +45,7 @@ proc FileOpenClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} = else: error(w, "Unable to read from file") -proc FileSaveClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} = +proc fileSaveClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} = var path = ChooseFileToSave(w) if path == "": return @@ -115,12 +115,12 @@ proc initControls() = append(FileMenu, OpenMenuItem) show(OpenMenuItem) discard signal_connect(OpenMenuItem, "activate", - SIGNAL_FUNC(FileOpenClicked), nil) + SIGNAL_FUNC(fileOpenClicked), nil) var SaveMenuItem = menu_item_new("Save...") append(FileMenu, SaveMenuItem) show(SaveMenuItem) discard signal_connect(SaveMenuItem, "activate", - SIGNAL_FUNC(FileSaveClicked), nil) + SIGNAL_FUNC(fileSaveClicked), nil) var FileMenuItem = menu_item_new("File") diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 9a83a5cca..cd679a299 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -1,6 +1,6 @@ # # -# Nimrod Website Generator +# Nim Website Generator # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this @@ -54,7 +54,7 @@ include "website.tmpl" const Version = "0.7" - Usage = "nimweb - Nimrod Website Generator Version " & version & """ + Usage = "nimweb - Nim Website Generator Version " & version & """ (c) 2012 Andreas Rumpf Usage: diff --git a/tools/website.tmpl b/tools/website.tmpl index 1d6242736..f3cacdb64 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -80,7 +80,7 @@ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - ga('create', 'UA-48159761-1', 'nimrod-lang.org'); + ga('create', 'UA-48159761-1', 'nim-lang.org'); ga('send', 'pageview'); From 0f4567d59e8d0910be344babeef1b5a62f410b14 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 02:23:40 +0200 Subject: [PATCH 043/409] koch now uses nim.exe --- compiler/{nimrod.ini => nim.ini} | 9 +-- compiler/{nimrod.nim => nim.nim} | 0 .../{nimrod.nimrod.cfg => nim.nimrod.cfg} | 0 koch.nim | 78 +++++++++++-------- tests/testament/categories.nim | 2 +- tests/testament/specs.nim | 4 +- 6 files changed, 51 insertions(+), 42 deletions(-) rename compiler/{nimrod.ini => nim.ini} (96%) rename compiler/{nimrod.nim => nim.nim} (100%) rename compiler/{nimrod.nimrod.cfg => nim.nimrod.cfg} (100%) diff --git a/compiler/nimrod.ini b/compiler/nim.ini similarity index 96% rename from compiler/nimrod.ini rename to compiler/nim.ini index 8bd00e891..3833a77cd 100644 --- a/compiler/nimrod.ini +++ b/compiler/nim.ini @@ -58,7 +58,7 @@ Files: "icons/koch.res" Files: "icons/koch_icon.o" Files: "compiler/readme.txt" -Files: "compiler/nimrod.ini" +Files: "compiler/nim.ini" Files: "compiler/nimrod.cfg" Files: "compiler/*.nim" Files: "compiler/c2nim/*.nim" @@ -114,7 +114,7 @@ Files: "examples/*.tmpl" [Windows] -Files: "bin/nimrod.exe" +Files: "bin/nim.exe" Files: "bin/c2nim.exe" Files: "bin/niminst.exe" Files: "bin/nimgrep.exe" @@ -128,7 +128,7 @@ InnoSetup: "Yes" [UnixBin] -Files: "bin/nimrod" +Files: "bin/nim" [Unix] @@ -150,5 +150,4 @@ flags = "-w" buildDepends: "gcc (>= 4:4.3.2)" pkgDepends: "gcc (>= 4:4.3.2)" shortDesc: "The Nim Compiler" -licenses: "bin/nimrod,MIT;lib/*,MIT;" - +licenses: "bin/nim,MIT;lib/*,MIT;" diff --git a/compiler/nimrod.nim b/compiler/nim.nim similarity index 100% rename from compiler/nimrod.nim rename to compiler/nim.nim diff --git a/compiler/nimrod.nimrod.cfg b/compiler/nim.nimrod.cfg similarity index 100% rename from compiler/nimrod.nimrod.cfg rename to compiler/nim.nimrod.cfg diff --git a/koch.nim b/koch.nim index dff6ede98..ad1a4b910 100644 --- a/koch.nim +++ b/koch.nim @@ -1,6 +1,6 @@ # # -# Maintenance program for Nimrod +# Maintenance program for Nim # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this @@ -26,7 +26,7 @@ when defined(haveZipLib): const HelpText = """ +-----------------------------------------------------------------+ -| Maintenance program for Nimrod | +| Maintenance program for Nim | | Version $1| | (c) 2014 Andreas Rumpf | +-----------------------------------------------------------------+ @@ -45,7 +45,7 @@ Possible Commands: zip builds the installation ZIP package inno [options] builds the Inno Setup installer (for Windows) tests [options] run the testsuite - update updates nimrod to the latest version from github + update updates nim to the latest version from github (compile koch with -d:withUpdate to enable) temp options creates a temporary compiler for testing Boot options: @@ -61,13 +61,13 @@ Boot options: proc exe(f: string): string = return addFileExt(f, ExeExt) proc findNim(): string = - var nimrod = "nimrod".exe - result = "bin" / nimrod + var nim = "nim".exe + result = "bin" / nim if existsFile(result): return for dir in split(getEnv("PATH"), PathSep): - if existsFile(dir / nimrod): return dir / nimrod + if existsFile(dir / nim): return dir / nim # assume there is a symlink to the exe or something: - return nimrod + return nim proc exec(cmd: string) = echo(cmd) @@ -81,12 +81,12 @@ const compileNimInst = "-d:useLibzipSrc tools/niminst/niminst" proc csource(args: string) = - exec("$4 cc $1 -r $3 --var:version=$2 csource compiler/nimrod.ini $1" % - [args, NimrodVersion, compileNimInst, findNim()]) + exec("$4 cc $1 -r $3 --var:version=$2 csource compiler/nim.ini $1" % + [args, NimVersion, compileNimInst, findNim()]) proc zip(args: string) = - exec("$3 cc -r $2 --var:version=$1 zip compiler/nimrod.ini" % - [NimrodVersion, compileNimInst, findNim()]) + exec("$3 cc -r $2 --var:version=$1 zip compiler/nim.ini" % + [NimVersion, compileNimInst, findNim()]) proc buildTool(toolname, args: string) = exec("$# cc $# $#" % [findNim(), args, toolname]) @@ -96,50 +96,60 @@ proc inno(args: string) = # make sure we have generated the niminst executables: buildTool("tools/niminst/niminst", args) buildTool("tools/nimgrep", args) - exec("tools" / "niminst" / "niminst --var:version=$# inno compiler/nimrod" % - NimrodVersion) + exec("tools" / "niminst" / "niminst --var:version=$# inno compiler/nim" % + NimVersion) proc install(args: string) = - exec("$# cc -r $# --var:version=$# scripts compiler/nimrod.ini" % - [findNim(), compileNimInst, NimrodVersion]) + exec("$# cc -r $# --var:version=$# scripts compiler/nim.ini" % + [findNim(), compileNimInst, NimVersion]) exec("sh ./install.sh $#" % args) proc web(args: string) = - exec("$# cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" % - [findNim(), NimrodVersion]) + exec("$# cc -r tools/nimweb.nim web/nim --putenv:nimversion=$#" % + [findNim(), NimVersion]) # -------------- boot --------------------------------------------------------- const bootOptions = "" # options to pass to the bootstrap process -proc findStartNimrod: string = +proc findStartNim: string = # we try several things before giving up: + # * bin/nim + # * $PATH/nim # * bin/nimrod # * $PATH/nimrod - # If these fail, we try to build nimrod with the "build.(sh|bat)" script. + # If these fail, we try to build nim with the "build.(sh|bat)" script. + var nim = "nim".exe + result = "bin" / nim + if existsFile(result): return + for dir in split(getEnv("PATH"), PathSep): + if existsFile(dir / nim): return dir / nim + + # try the old "nimrod.exe": var nimrod = "nimrod".exe result = "bin" / nimrod if existsFile(result): return for dir in split(getEnv("PATH"), PathSep): - if existsFile(dir / nimrod): return dir / nimrod + if existsFile(dir / nim): return dir / nimrod + when defined(Posix): const buildScript = "build.sh" if existsFile(buildScript): - if tryExec("./" & buildScript): return "bin" / nimrod + if tryExec("./" & buildScript): return "bin" / nim else: const buildScript = "build.bat" if existsFile(buildScript): - if tryExec(buildScript): return "bin" / nimrod - - echo("Found no nimrod compiler and every attempt to build one failed!") + if tryExec(buildScript): return "bin" / nim + + echo("Found no nim compiler and every attempt to build one failed!") quit("FAILURE") proc safeRemove(filename: string) = if existsFile(filename): removeFile(filename) proc thVersion(i: int): string = - result = ("compiler" / "nimrod" & $i).exe + result = ("compiler" / "nim" & $i).exe proc copyExe(source, dest: string) = safeRemove(dest) @@ -147,13 +157,13 @@ proc copyExe(source, dest: string) = inclFilePermissions(dest, {fpUserExec}) proc boot(args: string) = - var output = "compiler" / "nimrod".exe - var finalDest = "bin" / "nimrod".exe + var output = "compiler" / "nim".exe + var finalDest = "bin" / "nim".exe - copyExe(findStartNimrod(), 0.thVersion) + copyExe(findStartNim(), 0.thVersion) for i in 0..2: echo "iteration: ", i+1 - exec i.thVersion & " c $# $# compiler" / "nimrod.nim" % [bootOptions, args] + exec i.thVersion & " c $# $# compiler" / "nim.nim" % [bootOptions, args] if sameFileContent(output, i.thVersion): copyExe(output, finalDest) echo "executables are equal: SUCCESS!" @@ -171,7 +181,7 @@ const ".idx", ".ilk" ] ignore = [ - ".bzrignore", "nimrod", "nimrod.exe", "koch", "koch.exe", ".gitignore" + ".bzrignore", "nim", "nim.exe", "koch", "koch.exe", ".gitignore" ] proc cleanAux(dir: string) = @@ -275,15 +285,15 @@ template `|`(a, b): expr = (if a.len > 0: a else: b) proc tests(args: string) = # we compile the tester with taintMode:on to have a basic # taint mode test :-) - exec "nimrod cc --taintMode:on tests/testament/tester" + exec "nim cc --taintMode:on tests/testament/tester" let tester = quoteShell(getCurrentDir() / "tests/testament/tester".exe) exec tester & " " & (args|"all") exec tester & " html" proc temp(args: string) = - var output = "compiler" / "nimrod".exe - var finalDest = "bin" / "nimrod_temp".exe - exec("nimrod c compiler" / "nimrod") + var output = "compiler" / "nim".exe + var finalDest = "bin" / "nim_temp".exe + exec("nim c compiler" / "nim") copyExe(output, finalDest) if args.len > 0: exec(finalDest & " " & args) diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index a81e4687a..3f4d663cb 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -87,7 +87,7 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = else: # posix relies on crappy LD_LIBRARY_PATH (ugh!): var libpath = getenv"LD_LIBRARY_PATH".string - if peg"\i '/nimrod' (!'/')* '/lib'" notin libpath: + if peg"\i '/nim' (!'/')* '/lib'" notin libpath: echo "[Warning] insufficient LD_LIBRARY_PATH" var serverDll = DynlibFormat % "server" safeCopyFile("tests/dll" / serverDll, "lib" / serverDll) diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim index b2cccca56..9544fe71a 100644 --- a/tests/testament/specs.nim +++ b/tests/testament/specs.nim @@ -10,7 +10,7 @@ import parseutils, strutils, os, osproc, streams, parsecfg const - cmdTemplate* = r"nimrod $target --hints:on $options $file" + cmdTemplate* = r"nim $target --hints:on $options $file" type TTestAction* = enum @@ -18,7 +18,7 @@ type actionRun = "run" actionReject = "reject" TResultEnum* = enum - reNimrodcCrash, # nimrod compiler seems to have crashed + reNimrodcCrash, # nim compiler seems to have crashed reMsgsDiffer, # error messages differ reFilesDiffer, # expected and given filenames differ reLinesDiffer, # expected and given line numbers differ From cd2c6128d1df471830ea7f842b57aa32aee5deab Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 09:03:00 +0200 Subject: [PATCH 044/409] renamed babelcmd to nimblecmd; config files are now nim.cfg; other renamings --- compiler/commands.nim | 13 +- compiler/{babelcmd.nim => nimblecmd.nim} | 12 +- compiler/nimconf.nim | 9 +- compiler/options.nim | 4 +- config/nim.cfg | 141 ++++++++++++++++++ doc/advopt.txt | 3 +- doc/{nimrodc.txt => nimc.txt} | 0 examples/parsecfgex.nim | 2 +- .../{actors.nimrod.cfg => actors.nim.cfg} | 0 tests/benchmark.nim | 4 +- tests/js.nim | 2 +- .../{ex_wget.nimrod.cfg => ex_wget.nim.cfg} | 0 ...weine.nimrod.cfg => keineschweine.nim.cfg} | 0 .../{nakefile.nimrod.cfg => nakefile.nim.cfg} | 0 .../{main.nimrod.cfg => main.nim.cfg} | 0 ...nflicts.nimrod.cfg => noconflicts.nim.cfg} | 0 .../{barebone.nimrod.cfg => barebone.nim.cfg} | 0 tests/parallel/{nimrod.cfg => nim.cfg} | 0 tests/testament/backend.nim | 2 +- tests/testament/caasdriver.nim | 20 +-- tests/testament/categories.nim | 4 +- tests/testament/tester.nim | 2 +- tests/threads/{nimrod.cfg => nim.cfg} | 0 tools/{nimgrep.nimrod.cfg => nimgrep.nim.cfg} | 0 web/{nimrod.ini => nim.ini} | 12 +- 25 files changed, 187 insertions(+), 43 deletions(-) rename compiler/{babelcmd.nim => nimblecmd.nim} (91%) create mode 100644 config/nim.cfg rename doc/{nimrodc.txt => nimc.txt} (100%) rename lib/pure/{actors.nimrod.cfg => actors.nim.cfg} (100%) rename tests/manyloc/argument_parser/{ex_wget.nimrod.cfg => ex_wget.nim.cfg} (100%) rename tests/manyloc/keineschweine/{keineschweine.nimrod.cfg => keineschweine.nim.cfg} (100%) rename tests/manyloc/nake/{nakefile.nimrod.cfg => nakefile.nim.cfg} (100%) rename tests/manyloc/named_argument_bug/{main.nimrod.cfg => main.nim.cfg} (100%) rename tests/manyloc/packages/{noconflicts.nimrod.cfg => noconflicts.nim.cfg} (100%) rename tests/manyloc/standalone/{barebone.nimrod.cfg => barebone.nim.cfg} (100%) rename tests/parallel/{nimrod.cfg => nim.cfg} (100%) rename tests/threads/{nimrod.cfg => nim.cfg} (100%) rename tools/{nimgrep.nimrod.cfg => nimgrep.nim.cfg} (100%) rename web/{nimrod.ini => nim.ini} (93%) diff --git a/compiler/commands.nim b/compiler/commands.nim index fff860de9..54d2ed6a4 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -26,7 +26,7 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none") import os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists, - wordrecg, parseutils, babelcmd, idents + wordrecg, parseutils, nimblecmd, idents # but some have deps to imported modules. Yay. bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc") @@ -280,14 +280,15 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = of "path", "p": expectArg(switch, arg, pass, info) addPath(processPath(arg), info) - of "babelpath": - if pass in {passCmd2, passPP} and not options.gNoBabelPath: + of "nimblepath", "babelpath": + # keep the old name for compat + if pass in {passCmd2, passPP} and not options.gNoNimblePath: expectArg(switch, arg, pass, info) let path = processPath(arg, notRelativeToProj=true) - babelPath(path, info) - of "nobabelpath": + nimblePath(path, info) + of "nonimblepath", "nobabelpath": expectNoArg(switch, arg, pass, info) - options.gNoBabelPath = true + options.gNoNimblePath = true of "excludepath": expectArg(switch, arg, pass, info) let path = processPath(arg) diff --git a/compiler/babelcmd.nim b/compiler/nimblecmd.nim similarity index 91% rename from compiler/babelcmd.nim rename to compiler/nimblecmd.nim index b09637330..0f73c17bd 100644 --- a/compiler/babelcmd.nim +++ b/compiler/nimblecmd.nim @@ -58,7 +58,7 @@ iterator chosen(packages: StringTableRef): string = let res = if val == latest: key else: key & '-' & val yield res -proc addBabelPath(p: string, info: TLineInfo) = +proc addNimblePath(p: string, info: TLineInfo) = if not contains(options.searchPaths, p): if gVerbosity >= 1: message(info, hintPath, p) lists.prependStr(options.lazyPaths, p) @@ -70,10 +70,10 @@ proc addPathWithNimFiles(p: string, info: TLineInfo) = result = true break if hasNimFile(p): - addBabelPath(p, info) + addNimblePath(p, info) else: for kind, p2 in walkDir(p): - if hasNimFile(p2): addBabelPath(p2, info) + if hasNimFile(p2): addNimblePath(p2, info) proc addPathRec(dir: string, info: TLineInfo) = var packages = newStringTable(modeStyleInsensitive) @@ -83,8 +83,8 @@ proc addPathRec(dir: string, info: TLineInfo) = if k == pcDir and p[pos] != '.': addPackage(packages, p) for p in packages.chosen: - addBabelPath(p, info) + addNimblePath(p, info) -proc babelPath*(path: string, info: TLineInfo) = +proc nimblePath*(path: string, info: TLineInfo) = addPathRec(path, info) - addBabelPath(path, info) + addNimblePath(path, info) diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index d23c7f1be..98fe831d3 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -224,8 +224,8 @@ proc loadConfigs*(cfg: string) = if libpath == "": # choose default libpath: var prefix = getPrefixDir() - if prefix == "/usr": libpath = "/usr/lib/nimrod" - elif prefix == "/usr/local": libpath = "/usr/local/lib/nimrod" + if prefix == "/usr": libpath = "/usr/lib/nim" + elif prefix == "/usr/local": libpath = "/usr/local/lib/nim" else: libpath = joinPath(prefix, "lib") if optSkipConfigFile notin gGlobalOptions: @@ -244,5 +244,6 @@ proc loadConfigs*(cfg: string) = if gProjectName.len != 0: # new project wide config file: - readConfigFile(changeFileExt(gProjectFull, "nimrod.cfg")) - + let projectConfig = changeFileExt(gProjectFull, "nim.cfg") + if fileExists(projectConfig): readConfigFile(projectConfig) + else: readConfigFile(changeFileExt(gProjectFull, "nimrod.cfg")) diff --git a/compiler/options.nim b/compiler/options.nim index e30080e8f..723d912ca 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -114,7 +114,7 @@ var gDirtyBufferIdx* = 0'i32 # indicates the fileIdx of the dirty version of # the tracked source X, saved by the CAAS client. gDirtyOriginalIdx* = 0'i32 # the original source file of the dirtified buffer. - gNoBabelPath* = false + gNoNimblePath* = false proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools} proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc @@ -139,7 +139,7 @@ const JsonExt* = "json" TexExt* = "tex" IniExt* = "ini" - DefaultConfig* = "nimrod.cfg" + DefaultConfig* = "nim.cfg" DocConfig* = "nimdoc.cfg" DocTexConfig* = "nimdoc.tex.cfg" diff --git a/config/nim.cfg b/config/nim.cfg new file mode 100644 index 000000000..6d56bba2c --- /dev/null +++ b/config/nim.cfg @@ -0,0 +1,141 @@ +# Configuration file for the Nim Compiler. +# (c) 2014 Andreas Rumpf + +# Feel free to edit the default values as you need. + +# You may set environment variables with +# @putenv "key" "val" +# Environment variables cannot be used in the options, however! + +cc = gcc + +# example of how to setup a cross-compiler: +arm.linux.gcc.exe = "arm-linux-gcc" +arm.linux.gcc.linkerexe = "arm-linux-gcc" + +cs:partial + +path="$lib/core" +path="$lib/pure" +path="$lib/pure/collections" +path="$lib/pure/concurrency" +path="$lib/impure" +path="$lib/wrappers" +# path="$lib/wrappers/cairo" +# path="$lib/wrappers/gtk" +# path="$lib/wrappers/lua" +# path="$lib/wrappers/opengl" +path="$lib/wrappers/pcre" +path="$lib/wrappers/readline" +path="$lib/wrappers/sdl" +# path="$lib/wrappers/x11" +path="$lib/wrappers/zip" +path="$lib/wrappers/libffi" +path="$lib/windows" +path="$lib/posix" +path="$lib/js" +path="$lib/pure/unidecode" + +@if nimbabel: + babelpath="$home/.babel/pkgs/" +@end + +@if release or quick: + obj_checks:off + field_checks:off + range_checks:off + bound_checks:off + overflow_checks:off + assertions:off + stacktrace:off + linetrace:off + debugger:off + line_dir:off + dead_code_elim:on +@end + +@if release: + opt:speed +@end + +# additional options always passed to the compiler: +--parallel_build: "0" # 0 to auto-detect number of processors + +hint[LineTooLong]=off +#hint[XDeclaredButNotUsed]=off + +@if unix: + @if not bsd: + # -fopenmp + gcc.options.linker = "-ldl" + gpp.options.linker = "-ldl" + clang.options.linker = "-ldl" + tcc.options.linker = "-ldl" + @end + @if bsd or haiku: + # BSD got posix_spawn only recently, so we deactivate it for osproc: + define:useFork + # at least NetBSD has problems with thread local storage: + tlsEmulation:on + @end +@end + +# Configuration for the Intel C/C++ compiler: +@if windows: + icl.options.speed = "/Ox /arch:SSE2" + icl.options.always = "/nologo" +@end + +# Configuration for the GNU C/C++ compiler: +@if windows: + #gcc.path = r"$nimrod\dist\mingw\bin" + @if gcc: + tlsEmulation:on + @end +@end + +@if macosx: + cc = clang + tlsEmulation:on + gcc.options.always = "-w -fasm-blocks" + gpp.options.always = "-w -fasm-blocks -fpermissive" +@else: + gcc.options.always = "-w" + gpp.options.always = "-w -fpermissive" +@end + +gcc.options.speed = "-O3 -fno-strict-aliasing" +gcc.options.size = "-Os" +gcc.options.debug = "-g3 -O0" + +gpp.options.speed = "-O3 -fno-strict-aliasing" +gpp.options.size = "-Os" +gpp.options.debug = "-g3 -O0" +#passl = "-pg" + +# Configuration for the LLVM GCC compiler: +llvm_gcc.options.debug = "-g" +llvm_gcc.options.always = "-w" +llvm_gcc.options.speed = "-O2" +llvm_gcc.options.size = "-Os" + +# Configuration for the LLVM CLang compiler: +clang.options.debug = "-g" +clang.options.always = "-w" +clang.options.speed = "-O3" +clang.options.size = "-Os" + +# Configuration for the Visual C/C++ compiler: +vcc.options.linker = "/DEBUG /Zi /Fd\"$projectName.pdb\" /F33554432" # set the stack size to 8 MB +vcc.options.debug = "/Zi /Fd\"$projectName.pdb\"" +vcc.options.always = "/nologo" +vcc.options.speed = "/Ox /arch:SSE2" +vcc.options.size = "/O1" + +# Configuration for the Digital Mars C/C++ compiler: +@if windows: + dmc.path = r"$nimrod\dist\dm\bin" +@end + +# Configuration for the Tiny C Compiler: +tcc.options.always = "-w" diff --git a/doc/advopt.txt b/doc/advopt.txt index 18cea8a79..370639a60 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -79,7 +79,8 @@ Advanced options: select the GC to use; default is 'refc' --index:on|off turn index file generation on|off --putenv:key=value set an environment variable - --babelPath:PATH add a path for Babel support + --NimblePath:PATH add a path for Nimble support + --noNimblePath deactivate the Nimble path --excludePath:PATH exclude a path from the list of search paths --dynlibOverride:SYMBOL marks SYMBOL so that dynlib:SYMBOL has no effect and can be statically linked instead; diff --git a/doc/nimrodc.txt b/doc/nimc.txt similarity index 100% rename from doc/nimrodc.txt rename to doc/nimc.txt diff --git a/examples/parsecfgex.nim b/examples/parsecfgex.nim index 618ecadd6..0f37a0378 100644 --- a/examples/parsecfgex.nim +++ b/examples/parsecfgex.nim @@ -4,7 +4,7 @@ import var f = newFileStream(paramStr(1), fmRead) if f != nil: - var p: TCfgParser + var p: CfgParser open(p, f, paramStr(1)) while true: var e = next(p) diff --git a/lib/pure/actors.nimrod.cfg b/lib/pure/actors.nim.cfg similarity index 100% rename from lib/pure/actors.nimrod.cfg rename to lib/pure/actors.nim.cfg diff --git a/tests/benchmark.nim b/tests/benchmark.nim index 8dd9cc2e2..0613d1bf9 100644 --- a/tests/benchmark.nim +++ b/tests/benchmark.nim @@ -1,6 +1,6 @@ # # -# Nimrod Benchmark tool +# Nim Benchmark tool # (c) Copyright 2012 Dominik Picheta # # See the file "copying.txt", included in this @@ -15,7 +15,7 @@ type proc compileBench(file: string) = ## Compiles ``file``. - doAssert(execCmdEx("nimrod c -d:release " & file).exitCode == QuitSuccess) + doAssert(execCmdEx("nim c -d:release " & file).exitCode == QuitSuccess) proc runBench(file: string): TBenchResult = ## Runs ``file`` and returns info on how long it took to run. diff --git a/tests/js.nim b/tests/js.nim index becc17834..e5e432366 100644 --- a/tests/js.nim +++ b/tests/js.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nimrod js --hints:on $options $file" + cmd: "nim js --hints:on $options $file" """ # This file tests the JavaScript generator diff --git a/tests/manyloc/argument_parser/ex_wget.nimrod.cfg b/tests/manyloc/argument_parser/ex_wget.nim.cfg similarity index 100% rename from tests/manyloc/argument_parser/ex_wget.nimrod.cfg rename to tests/manyloc/argument_parser/ex_wget.nim.cfg diff --git a/tests/manyloc/keineschweine/keineschweine.nimrod.cfg b/tests/manyloc/keineschweine/keineschweine.nim.cfg similarity index 100% rename from tests/manyloc/keineschweine/keineschweine.nimrod.cfg rename to tests/manyloc/keineschweine/keineschweine.nim.cfg diff --git a/tests/manyloc/nake/nakefile.nimrod.cfg b/tests/manyloc/nake/nakefile.nim.cfg similarity index 100% rename from tests/manyloc/nake/nakefile.nimrod.cfg rename to tests/manyloc/nake/nakefile.nim.cfg diff --git a/tests/manyloc/named_argument_bug/main.nimrod.cfg b/tests/manyloc/named_argument_bug/main.nim.cfg similarity index 100% rename from tests/manyloc/named_argument_bug/main.nimrod.cfg rename to tests/manyloc/named_argument_bug/main.nim.cfg diff --git a/tests/manyloc/packages/noconflicts.nimrod.cfg b/tests/manyloc/packages/noconflicts.nim.cfg similarity index 100% rename from tests/manyloc/packages/noconflicts.nimrod.cfg rename to tests/manyloc/packages/noconflicts.nim.cfg diff --git a/tests/manyloc/standalone/barebone.nimrod.cfg b/tests/manyloc/standalone/barebone.nim.cfg similarity index 100% rename from tests/manyloc/standalone/barebone.nimrod.cfg rename to tests/manyloc/standalone/barebone.nim.cfg diff --git a/tests/parallel/nimrod.cfg b/tests/parallel/nim.cfg similarity index 100% rename from tests/parallel/nimrod.cfg rename to tests/parallel/nim.cfg diff --git a/tests/testament/backend.nim b/tests/testament/backend.nim index 5199bb9d6..c7122e1b2 100644 --- a/tests/testament/backend.nim +++ b/tests/testament/backend.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Tester +# The Nim Tester # (c) Copyright 2014 Andreas Rumpf # # Look at license.txt for more info. diff --git a/tests/testament/caasdriver.nim b/tests/testament/caasdriver.nim index ddfe88273..4754fa342 100644 --- a/tests/testament/caasdriver.nim +++ b/tests/testament/caasdriver.nim @@ -9,7 +9,7 @@ type TRunMode = enum ProcRun, CaasRun, SymbolProcRun - TNimrodSession* = object + NimSession* = object nim: PProcess # Holds the open process for CaasRun sessions, nil otherwise. mode: TRunMode # Stores the type of run mode the session was started with. lastOutput: string # Preserves the last output, needed for ProcRun mode. @@ -26,15 +26,15 @@ const var TesterDir = getAppDir() / ".." - NimrodBin = TesterDir / "../bin/nimrod" + NimBin = TesterDir / "../bin/nim" -proc replaceVars(session: var TNimrodSession, text: string): string = +proc replaceVars(session: var NimSession, text: string): string = result = text.replace(filenameReplaceVar, session.filename) result = result.replace(moduleReplaceVar, session.modname) result = result.replace(silentReplaceVar, silentReplaceText) proc startNimrodSession(project, script: string, mode: TRunMode): - TNimrodSession = + NimSession = let (dir, name, ext) = project.splitFile result.mode = mode result.lastOutput = "" @@ -50,10 +50,10 @@ proc startNimrodSession(project, script: string, mode: TRunMode): removeDir(nimcacheDir / "nimcache") if mode == CaasRun: - result.nim = startProcess(NimrodBin, workingDir = dir, + result.nim = startProcess(NimBin, workingDir = dir, args = ["serve", "--server.type:stdin", name]) -proc doCaasCommand(session: var TNimrodSession, command: string): string = +proc doCaasCommand(session: var NimSession, command: string): string = assert session.mode == CaasRun session.nim.inputStream.write(session.replaceVars(command) & "\n") session.nim.inputStream.flush @@ -69,11 +69,11 @@ proc doCaasCommand(session: var TNimrodSession, command: string): string = result = "FAILED TO EXECUTE: " & command & "\n" & result break -proc doProcCommand(session: var TNimrodSession, command: string): string = +proc doProcCommand(session: var NimSession, command: string): string = assert session.mode == ProcRun or session.mode == SymbolProcRun except: result = "FAILED TO EXECUTE: " & command & "\n" & result var - process = startProcess(NimrodBin, args = session.replaceVars(command).split) + process = startProcess(NimBin, args = session.replaceVars(command).split) stream = outputStream(process) line = TaintedString("") @@ -84,7 +84,7 @@ proc doProcCommand(session: var TNimrodSession, command: string): string = process.close() -proc doCommand(session: var TNimrodSession, command: string) = +proc doCommand(session: var NimSession, command: string) = if session.mode == CaasRun: if not session.nim.running: session.lastOutput = "FAILED TO EXECUTE: " & command & "\n" & @@ -102,7 +102,7 @@ proc doCommand(session: var TNimrodSession, command: string) = session.lastOutput = doProcCommand(session, command & " " & session.filename) -proc close(session: var TNimrodSession) {.destructor.} = +proc close(session: var NimSession) {.destructor.} = if session.mode == CaasRun: session.nim.close diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 3f4d663cb..566a74cab 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -192,9 +192,9 @@ proc jsTests(r: var TResults, cat: Category, options: string) = # testSpec(r, t, options) proc findMainFile(dir: string): string = - # finds the file belonging to ".nimrod.cfg"; if there is no such file + # finds the file belonging to ".nim.cfg"; if there is no such file # it returns the some ".nim" file if there is only one: - const cfgExt = ".nimrod.cfg" + const cfgExt = ".nim.cfg" result = "" var nimFiles = 0 for kind, file in os.walkDir(dir): diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim index 732a5e86a..b74fa99c8 100644 --- a/tests/testament/tester.nim +++ b/tests/testament/tester.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -## This program verifies Nimrod against the testcases. +## This program verifies Nim against the testcases. import parseutils, strutils, pegs, os, osproc, streams, parsecfg, json, diff --git a/tests/threads/nimrod.cfg b/tests/threads/nim.cfg similarity index 100% rename from tests/threads/nimrod.cfg rename to tests/threads/nim.cfg diff --git a/tools/nimgrep.nimrod.cfg b/tools/nimgrep.nim.cfg similarity index 100% rename from tools/nimgrep.nimrod.cfg rename to tools/nimgrep.nim.cfg diff --git a/web/nimrod.ini b/web/nim.ini similarity index 93% rename from web/nimrod.ini rename to web/nim.ini index 64376cd66..d610408f7 100644 --- a/web/nimrod.ini +++ b/web/nim.ini @@ -1,15 +1,15 @@ [Project] -Name: "Nimrod" -Title: "Nimrod Programming Language" +Name: "Nim" +Title: "Nim Programming Language" Logo: "efficient, expressive, elegant" Authors: "Andreas Rumpf and contributors" [Links] # Underscores are replaced with a space. # Everything after ; is the ID -User_Forum: "http://forum.nimrod-code.org;link_forum" +User_Forum: "http://forum.nim-lang.org;link_forum" Aporia_IDE: "https://github.com/nimrod-code/Aporia;link_aporia" -Nimbuild: "http://build.nimrod-code.org;link_nimbuild" +Nimbuild: "http://build.nim-lang.org;link_nimbuild" [Tabs] # Menu entry: filename @@ -36,9 +36,9 @@ UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson.""" [Documentation] -doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview;filters" +doc: "endb;intern;apis;lib;manual;tut1;tut2;nimc;overview;filters" doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt" -pdf: "manual;lib;tut1;tut2;nimrodc;niminst;gc" +pdf: "manual;lib;tut1;tut2;nimc;niminst;gc" srcdoc2: "system.nim;impure/graphics;wrappers/sdl" srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned" srcdoc2: "impure/re;pure/sockets;pure/typetraits" From c6034277fcb597da03d064b773ad4f6823823fa0 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Aug 2014 09:12:12 +0200 Subject: [PATCH 045/409] further adaptations --- tests/async/tasyncawait.nim | 2 +- tests/async/tasynciossl.nim | 2 +- tests/ccgbugs/tcodegenbug1.nim | 2 +- tests/concurrency/tnodeadlocks.nim | 2 +- tests/dll/client.nim | 2 +- tests/dll/server.nim | 2 +- tests/float/tfloat3.nim | 4 ++-- tests/gc/bintrees.nim | 2 +- tests/generics/tcan_alias_generic.nim | 2 +- .../generics/tcan_alias_specialised_generic.nim | 2 +- tests/generics/tcan_inherit_generic.nim | 2 +- tests/generics/tcan_specialise_generic.nim | 2 +- tests/generics/tinferredgenericprocs.nim | 2 +- tests/generics/tmetafield.nim | 2 +- tests/generics/tspecialised_is_equivalent.nim | 2 +- tests/generics/tthread_generic.nim | 2 +- tests/iter/titer2.nim | 2 +- tests/macros/tdebugstmt.nim | 2 +- .../manyloc/argument_parser/argument_parser.nim | 6 +++--- .../dependencies/chipmunk/chipmunk.nim | 12 ++++++------ .../keineschweine/dependencies/nake/nake.nim | 2 +- .../keineschweine/dependencies/nake/nakefile.nim | 2 +- .../keineschweine/enet_server/nakefile.nim | 4 ++-- tests/manyloc/nake/nake.nim | 2 +- tests/manyloc/nake/nakefile.nim | 16 ++++++++-------- tests/metatype/tcompositetypeclasses.nim | 4 ++-- tests/misc/t99bott.nim | 2 +- tests/misc/temit.nim | 4 ++-- tests/misc/thallo.nim | 2 +- tests/misc/tmandelbrot.nim | 4 ++-- tests/objects/tobjcov.nim | 2 +- tests/overflw/toverflw.nim | 2 +- tests/parallel/tflowvar.nim | 2 +- tests/parallel/tsysspawn.nim | 2 +- tests/parallel/tsysspawnbadarg.nim | 2 +- tests/showoff/thtml2.nim | 4 ++-- tests/stdlib/techo.nim | 2 +- tests/stdlib/tircbot.nim | 6 +++--- tests/stdlib/tpegs.nim | 10 +++++----- tests/stdlib/tunidecode.nim | 2 +- tests/stdlib/txmlgen.nim | 6 +++--- tests/stdlib/txmltree.nim | 4 ++-- tests/template/t_otemplates.nim | 6 +++--- tests/testament/caasdriver.nim | 4 ++-- tests/testament/htmlgen.nim | 2 +- tests/testament/specs.nim | 2 +- tests/threads/tthreadanalysis.nim | 2 +- tests/threads/tthreadanalysis2.nim | 2 +- tests/threads/tthreadheapviolation1.nim | 2 +- tests/types/tillegaltyperecursion.nim | 4 ++-- tests/usingstmt/tusingstatement.nim | 2 +- tests/vm/tconsteval.nim | 6 +++--- 52 files changed, 87 insertions(+), 87 deletions(-) diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim index 2d65db4bd..ec05a0386 100644 --- a/tests/async/tasyncawait.nim +++ b/tests/async/tasyncawait.nim @@ -25,7 +25,7 @@ proc launchSwarm(port: TPort) {.async.} = await sendMessages(sock) closeSocket(sock) else: - # Issue #932: https://github.com/Araq/Nimrod/issues/932 + # Issue #932: https://github.com/Araq/Nim/issues/932 var msgFut = sendMessages(sock) msgFut.callback = proc () = diff --git a/tests/async/tasynciossl.nim b/tests/async/tasynciossl.nim index 6b38fcf7b..b0222e4ff 100644 --- a/tests/async/tasynciossl.nim +++ b/tests/async/tasynciossl.nim @@ -1,6 +1,6 @@ discard """ file: "tasynciossl.nim" - cmd: "nimrod $target --hints:on --define:ssl $options $file" + cmd: "nim $target --hints:on --define:ssl $options $file" output: "20000" """ import sockets, asyncio, strutils, times diff --git a/tests/ccgbugs/tcodegenbug1.nim b/tests/ccgbugs/tcodegenbug1.nim index 7d0fc4ad5..9b9771485 100644 --- a/tests/ccgbugs/tcodegenbug1.nim +++ b/tests/ccgbugs/tcodegenbug1.nim @@ -51,7 +51,7 @@ proc `$`*(status: TStatusEnum): string = return "unknown" proc makeCommitPath*(platform, hash: string): string = - return platform / "nimrod_" & hash.substr(0, 11) # 11 Chars. + return platform / "nim_" & hash.substr(0, 11) # 11 Chars. type TFlag = enum diff --git a/tests/concurrency/tnodeadlocks.nim b/tests/concurrency/tnodeadlocks.nim index d44196039..6cbfe64cd 100644 --- a/tests/concurrency/tnodeadlocks.nim +++ b/tests/concurrency/tnodeadlocks.nim @@ -1,6 +1,6 @@ discard """ outputsub: "101" - cmd: "nimrod $target --hints:on --threads:on $options $file" + cmd: "nim $target --hints:on --threads:on $options $file" """ import os, locks diff --git a/tests/dll/client.nim b/tests/dll/client.nim index 45fa8f639..d535e8750 100644 --- a/tests/dll/client.nim +++ b/tests/dll/client.nim @@ -1,6 +1,6 @@ discard """ output: "Done" - cmd: "nimrod $target --debuginfo --hints:on --define:useNimRtl $options $file" + cmd: "nim $target --debuginfo --hints:on --define:useNimRtl $options $file" """ type diff --git a/tests/dll/server.nim b/tests/dll/server.nim index b2fac9ecc..df3223444 100644 --- a/tests/dll/server.nim +++ b/tests/dll/server.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nimrod $target --debuginfo --hints:on --define:useNimRtl --app:lib $options $file" + cmd: "nim $target --debuginfo --hints:on --define:useNimRtl --app:lib $options $file" """ type diff --git a/tests/float/tfloat3.nim b/tests/float/tfloat3.nim index 4382dd3ed..2318c517e 100644 --- a/tests/float/tfloat3.nim +++ b/tests/float/tfloat3.nim @@ -1,6 +1,6 @@ discard """ file: "tfloat3.nim" - output: "Nimrod 3.4368930843, 0.3299290698 C double: 3.4368930843, 0.3299290698" + output: "Nim 3.4368930843, 0.3299290698 C double: 3.4368930843, 0.3299290698" """ import math, strutils @@ -17,7 +17,7 @@ proc c_printf(frmt: CString) {.importc: "printf", header: "", varargs.} proc printFloats {.importc, nodecl.} var x: float = 1.234567890123456789 -c_printf("Nimrod %.10f, %.10f ", exp(x), cos(x)) +c_printf("Nim %.10f, %.10f ", exp(x), cos(x)) printFloats() diff --git a/tests/gc/bintrees.nim b/tests/gc/bintrees.nim index 3f8acee1e..5b65bb437 100644 --- a/tests/gc/bintrees.nim +++ b/tests/gc/bintrees.nim @@ -1,4 +1,4 @@ -# -*- nimrod -*- +# -*- nim -*- import os, strutils diff --git a/tests/generics/tcan_alias_generic.nim b/tests/generics/tcan_alias_generic.nim index e90bdc6d2..780a47841 100644 --- a/tests/generics/tcan_alias_generic.nim +++ b/tests/generics/tcan_alias_generic.nim @@ -1,5 +1,5 @@ ## -## can_alias_generic Nimrod Module +## can_alias_generic Nim Module ## ## Created by Eric Doughty-Papassideris on 2011-02-16. ## Copyright (c) 2011 FWA. All rights reserved. diff --git a/tests/generics/tcan_alias_specialised_generic.nim b/tests/generics/tcan_alias_specialised_generic.nim index 8d4a29abd..a737d3580 100644 --- a/tests/generics/tcan_alias_specialised_generic.nim +++ b/tests/generics/tcan_alias_specialised_generic.nim @@ -3,7 +3,7 @@ discard """ """ ## -## can_alias_specialised_generic Nimrod Module +## can_alias_specialised_generic Nim Module ## ## Created by Eric Doughty-Papassideris on 2011-02-16. ## Copyright (c) 2011 FWA. All rights reserved. diff --git a/tests/generics/tcan_inherit_generic.nim b/tests/generics/tcan_inherit_generic.nim index a6f4d946b..ce2b6452f 100644 --- a/tests/generics/tcan_inherit_generic.nim +++ b/tests/generics/tcan_inherit_generic.nim @@ -1,5 +1,5 @@ ## -## can_inherit_generic Nimrod Module +## can_inherit_generic Nim Module ## ## Created by Eric Doughty-Papassideris on 2011-02-16. ## Copyright (c) 2011 FWA. All rights reserved. diff --git a/tests/generics/tcan_specialise_generic.nim b/tests/generics/tcan_specialise_generic.nim index 64d5f56e3..c510910e8 100644 --- a/tests/generics/tcan_specialise_generic.nim +++ b/tests/generics/tcan_specialise_generic.nim @@ -1,5 +1,5 @@ ## -## can_specialise_generic Nimrod Module +## can_specialise_generic Nim Module ## ## Created by Eric Doughty-Papassideris on 2011-02-16. ## Copyright (c) 2011 FWA. All rights reserved. diff --git a/tests/generics/tinferredgenericprocs.nim b/tests/generics/tinferredgenericprocs.nim index ac445fd32..12adfe965 100644 --- a/tests/generics/tinferredgenericprocs.nim +++ b/tests/generics/tinferredgenericprocs.nim @@ -5,7 +5,7 @@ discard """ 3''' """ -# https://github.com/Araq/Nimrod/issues/797 +# https://github.com/Araq/Nim/issues/797 proc foo[T](s:T):string = $s type IntStringProc = proc(x: int): string diff --git a/tests/generics/tmetafield.nim b/tests/generics/tmetafield.nim index e1bc43ce3..bbfca7e3c 100644 --- a/tests/generics/tmetafield.nim +++ b/tests/generics/tmetafield.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nimrod check $options $file" + cmd: "nim check $options $file" errormsg: "'proc' is not a concrete type" errormsg: "'Foo' is not a concrete type." errormsg: "invalid type: 'TBaseMed'" diff --git a/tests/generics/tspecialised_is_equivalent.nim b/tests/generics/tspecialised_is_equivalent.nim index 60b976e90..ace562862 100644 --- a/tests/generics/tspecialised_is_equivalent.nim +++ b/tests/generics/tspecialised_is_equivalent.nim @@ -1,5 +1,5 @@ ## -## specialised_is_equivalent Nimrod Module +## specialised_is_equivalent Nim Module ## ## Created by Eric Doughty-Papassideris on 2011-02-16. ## Copyright (c) 2011 FWA. All rights reserved. diff --git a/tests/generics/tthread_generic.nim b/tests/generics/tthread_generic.nim index 7109bba18..5887f7db3 100644 --- a/tests/generics/tthread_generic.nim +++ b/tests/generics/tthread_generic.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nimrod $target --hints:on --threads:on $options $file" + cmd: "nim $target --hints:on --threads:on $options $file" """ type diff --git a/tests/iter/titer2.nim b/tests/iter/titer2.nim index 71c7327a7..fbecf7cf9 100644 --- a/tests/iter/titer2.nim +++ b/tests/iter/titer2.nim @@ -1,6 +1,6 @@ discard """ output: '''true''' - cmd: "nimrod $target --gc:none --hints:on --warnings:off $options $file" + cmd: "nim $target --gc:none --hints:on --warnings:off $options $file" """ import hashes diff --git a/tests/macros/tdebugstmt.nim b/tests/macros/tdebugstmt.nim index 865dc436a..00c55ccd8 100644 --- a/tests/macros/tdebugstmt.nim +++ b/tests/macros/tdebugstmt.nim @@ -7,7 +7,7 @@ x: some string''' import macros macro debug(n: varargs[expr]): stmt = - # `n` is a Nimrod AST that contains the whole macro invocation + # `n` is a Nim AST that contains the whole macro invocation # this macro returns a list of statements: result = newNimNode(nnkStmtList, n) # iterate over any argument that is passed to this macro: diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim index 6f4fb650e..29b70a84c 100644 --- a/tests/manyloc/argument_parser/argument_parser.nim +++ b/tests/manyloc/argument_parser/argument_parser.nim @@ -1,7 +1,7 @@ ## Command line parsing module for Nimrod. ## -## `Nimrod `_ provides the `parseopt module -## `_ to parse options from the +## `Nim `_ provides the `parseopt module +## `_ to parse options from the ## commandline. This module tries to provide functionality to prevent you from ## writing commandline parsing and let you concentrate on providing the best ## possible experience for your users. @@ -169,7 +169,7 @@ template new_parsed_parameter*(tkind: Tparam_kind, expr): Tparsed_parameter = ## assign the variable to, and thus you reduce code clutter and may use this ## to initialise single assignments variables in `let` blocks. Example: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## let ## parsed_param1 = new_parsed_parameter(PK_FLOAT, 3.41) ## parsed_param2 = new_parsed_parameter(PK_BIGGEST_INT, 2358123 * 23123) diff --git a/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim b/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim index d9c933939..d079a2e72 100644 --- a/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim +++ b/tests/manyloc/keineschweine/dependencies/chipmunk/chipmunk.nim @@ -21,8 +21,8 @@ const Lib = "libchipmunk.so.6.1.1" -when defined(MoreNimrod): - {.hint: "MoreNimrod defined; some Chipmunk functions replaced in Nimrod".} +when defined(MoreNim): + {.hint: "MoreNim defined; some Chipmunk functions replaced in Nim".} {.deadCodeElim: on.} from math import sqrt, sin, cos, arctan2 when defined(CpUseFloat): @@ -729,7 +729,7 @@ proc isRogue*(body: PBody): Bool {.inline.} = defGetter(PBody, CpFloat, m, Mass) #/ Set the mass of a body. -when defined(MoreNimrod): +when defined(MoreNim): defSetter(PBody, CpFloat, m, Mass) else: proc setMass*(body: PBody; m: CpFloat){. @@ -738,7 +738,7 @@ else: #/ Get the moment of a body. defGetter(PBody, CpFloat, i, Moment) #/ Set the moment of a body. -when defined(MoreNimrod): +when defined(MoreNim): defSetter(PBody, CpFloat, i, Moment) else: proc SetMoment*(body: PBody; i: CpFloat) {. @@ -747,7 +747,7 @@ else: #/ Get the position of a body. defGetter(PBody, TVector, p, Pos) #/ Set the position of a body. -when defined(MoreNimrod): +when defined(MoreNim): defSetter(PBody, TVector, p, Pos) else: proc setPos*(body: PBody; pos: TVector) {. @@ -1088,7 +1088,7 @@ proc getSegmentRadius*(shape: PShape): CpFloat {. #var VersionString*{.importc: "cpVersionString", dynlib: Lib.}: cstring #/ Calculate the moment of inertia for a circle. #/ @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0. -when defined(MoreNimrod): +when defined(MoreNim): proc momentForCircle*(m, r1, r2: CpFloat; offset: TVector): CpFloat {.cdecl.} = result = m * (0.5 * (r1 * r1 + r2 * r2) + lenSq(offset)) else: diff --git a/tests/manyloc/keineschweine/dependencies/nake/nake.nim b/tests/manyloc/keineschweine/dependencies/nake/nake.nim index eade28c70..5828e400c 100644 --- a/tests/manyloc/keineschweine/dependencies/nake/nake.nim +++ b/tests/manyloc/keineschweine/dependencies/nake/nake.nim @@ -58,7 +58,7 @@ when isMainModule: for i in 1..paramCount(): args.add paramStr(i) args.add " " - quit(shell("nimrod", "c", "-r", "nakefile.nim", args)) + quit(shell("nim", "c", "-r", "nakefile.nim", args)) else: addQuitProc(proc() {.noconv.} = var diff --git a/tests/manyloc/keineschweine/dependencies/nake/nakefile.nim b/tests/manyloc/keineschweine/dependencies/nake/nakefile.nim index 24af63d10..bdf2139c9 100644 --- a/tests/manyloc/keineschweine/dependencies/nake/nakefile.nim +++ b/tests/manyloc/keineschweine/dependencies/nake/nakefile.nim @@ -2,7 +2,7 @@ import nake nakeImports task "install", "compile and install nake binary": - if shell("nimrod", "c", "nake") == 0: + if shell("nim", "c", "nake") == 0: let path = getEnv("PATH").split(PathSep) for index, dir in pairs(path): echo " ", index, ". ", dir diff --git a/tests/manyloc/keineschweine/enet_server/nakefile.nim b/tests/manyloc/keineschweine/enet_server/nakefile.nim index 1ca93a340..3764c6271 100644 --- a/tests/manyloc/keineschweine/enet_server/nakefile.nim +++ b/tests/manyloc/keineschweine/enet_server/nakefile.nim @@ -5,9 +5,9 @@ const ServerDefines = "-d:NoSFML --forceBuild" task "server", "build the server": - if shell("nimrod", ServerDefines, "-r", "compile", "enet_server") != 0: + if shell("nim", ServerDefines, "-r", "compile", "enet_server") != 0: quit "Failed to build" task "gui", "build the server GUI mode": - if shell("nimrod", "--app:gui", ServerDefines, "-r", "compile", "enet_server") != 0: + if shell("nim", "--app:gui", ServerDefines, "-r", "compile", "enet_server") != 0: quit "Failed to build" diff --git a/tests/manyloc/nake/nake.nim b/tests/manyloc/nake/nake.nim index 4b1b35662..04b745003 100644 --- a/tests/manyloc/nake/nake.nim +++ b/tests/manyloc/nake/nake.nim @@ -58,7 +58,7 @@ when isMainModule: for i in 1..paramCount(): args.add paramStr(i) args.add " " - quit(shell("nimrod", "c", "-r", "nakefile.nim", args)) + quit(shell("nim", "c", "-r", "nakefile.nim", args)) else: addQuitProc(proc() {.noconv.} = var diff --git a/tests/manyloc/nake/nakefile.nim b/tests/manyloc/nake/nakefile.nim index 700f9ab49..be7398fa0 100644 --- a/tests/manyloc/nake/nakefile.nim +++ b/tests/manyloc/nake/nakefile.nim @@ -9,16 +9,16 @@ const BinLibs = "http://dl.dropbox.com/u/37533467/libs-2012-09-12.zip" ExeName = "keineschweine" ServerDefines = "-d:NoSFML -d:NoChipmunk" - TestBuildDefines = "-d:escapeMenuTest -d:debugWeps -d:showFPS -d:moreNimrod -d:debugKeys -d:foo -d:recordMode --forceBuild" + TestBuildDefines = "-d:escapeMenuTest -d:debugWeps -d:showFPS -d:moreNim -d:debugKeys -d:foo -d:recordMode --forceBuild" ReleaseDefines = "-d:release --deadCodeElim:on" ReleaseTestDefines = "-d:debugWeps -d:debugKeys --forceBuild" task "testprofile", "..": - if shell("nimrod", TestBuildDefines, "--profiler:on", "--stacktrace:on", "compile", ExeName) == 0: + if shell("nim", TestBuildDefines, "--profiler:on", "--stacktrace:on", "compile", ExeName) == 0: shell "."/ExeName, "offline" task "test", "Build with test defines": - if shell("nimrod", TestBuildDefines, "compile", ExeName) != 0: + if shell("nim", TestBuildDefines, "compile", ExeName) != 0: quit "The build failed." task "testrun", "Build with test defines and run": @@ -26,22 +26,22 @@ task "testrun", "Build with test defines and run": shell "."/ExeName task "test2", "Build release test build test release build": - if shell("nimrod", ReleaseDefines, ReleaseTestDefines, "compile", ExeName) == 0: + if shell("nim", ReleaseDefines, ReleaseTestDefines, "compile", ExeName) == 0: shell "."/ExeName discard """task "dirserver", "build the directory server": withDir "server": - if shell("nimrod", ServerDefines, "compile", "dirserver") != 0: + if shell("nim", ServerDefines, "compile", "dirserver") != 0: echo "Failed to build the dirserver" quit 1""" task "zoneserver", "build the zone server": withDir "enet_server": - if shell("nimrod", ServerDefines, "compile", "enet_server") != 0: + if shell("nim", ServerDefines, "compile", "enet_server") != 0: quit "Failed to build the zoneserver" task "zoneserver-gui", "build the zone server, with gui!": withDir "enet_server": - if shell("nimrod", ServerDefines, "--app:gui", "compile", "enet_server") != 0: + if shell("nim", ServerDefines, "--app:gui", "compile", "enet_server") != 0: quit "Failed to build the zoneserver" task "servers", "build the server and directory server": @@ -54,7 +54,7 @@ task "all", "run SERVERS and TEST tasks": runTask "test" task "release", "release build": - let res = shell("nimrod", ReleaseDefines, "compile", ExeName) + let res = shell("nim", ReleaseDefines, "compile", ExeName) if res != 0: echo "The build failed." quit 1 diff --git a/tests/metatype/tcompositetypeclasses.nim b/tests/metatype/tcompositetypeclasses.nim index a2db73769..5ae93795f 100644 --- a/tests/metatype/tcompositetypeclasses.nim +++ b/tests/metatype/tcompositetypeclasses.nim @@ -33,7 +33,7 @@ accept baz(vbaz) reject baz(vnotbaz) reject bar(vfoo) -# https://github.com/Araq/Nimrod/issues/517 +# https://github.com/Araq/Nim/issues/517 type TVecT*[T] = array[0..1, T]|array[0..2, T]|array[0..3, T] TVec2* = array[0..1, float32] @@ -43,7 +43,7 @@ proc f[T](a: TVecT[T], b: TVecT[T]): T = discard var x: float = f([0.0'f32, 0.0'f32], [0.0'f32, 0.0'f32]) var y = f(TVec2([0.0'f32, 0.0'f32]), TVec2([0.0'f32, 0.0'f32])) -# https://github.com/Araq/Nimrod/issues/602 +# https://github.com/Araq/Nim/issues/602 type TTest = object TTest2* = object diff --git a/tests/misc/t99bott.nim b/tests/misc/t99bott.nim index d18cb0d5c..b3b30d296 100644 --- a/tests/misc/t99bott.nim +++ b/tests/misc/t99bott.nim @@ -6,7 +6,7 @@ discard """ """ ## 99 Bottles of Beer ## http://www.99-bottles-of-beer.net/ -## Nimrod version +## Nim version ## Author: Philippe Lhoste http://Phi.Lho.free.fr # 2012-11-25 diff --git a/tests/misc/temit.nim b/tests/misc/temit.nim index ff8df0585..e2a9eaff1 100644 --- a/tests/misc/temit.nim +++ b/tests/misc/temit.nim @@ -10,8 +10,8 @@ static int cvariable = 420; """.} proc embedsC() = - var nimrodVar = 89 - {.emit: """printf("%d\n", cvariable + (int)`nimrodVar`);""".} + var nimVar = 89 + {.emit: """printf("%d\n", cvariable + (int)`nimVar`);""".} embedsC() diff --git a/tests/misc/thallo.nim b/tests/misc/thallo.nim index 7244c27a1..46d21b4da 100644 --- a/tests/misc/thallo.nim +++ b/tests/misc/thallo.nim @@ -37,7 +37,7 @@ macrotest(stdout) #GC_disable() -echo("This was compiled by Nimrod version " & system.nimrodVersion) +echo("This was compiled by Nim version " & system.nimVersion) writeln(stdout, "Hello", " World", "!") echo(["a", "b", "c", "d"].len) diff --git a/tests/misc/tmandelbrot.nim b/tests/misc/tmandelbrot.nim index bb1b46d89..4228b0416 100644 --- a/tests/misc/tmandelbrot.nim +++ b/tests/misc/tmandelbrot.nim @@ -1,8 +1,8 @@ discard """ - cmd: "nimrod $target --hints:on -d:release $options $file" + cmd: "nim $target --hints:on -d:release $options $file" """ -# -*- nimrod -*- +# -*- nim -*- import math import os diff --git a/tests/objects/tobjcov.nim b/tests/objects/tobjcov.nim index fc44edf8e..8391727f2 100644 --- a/tests/objects/tobjcov.nim +++ b/tests/objects/tobjcov.nim @@ -9,7 +9,7 @@ type proc ap(x: var TA) = x.a = -1 proc bp(x: var TB) = x.b[high(x.b)] = -1 -# in Nimrod proc (x: TB) is compatible to proc (x: TA), +# in Nim proc (x: TB) is compatible to proc (x: TA), # but this is not type safe: var f = cast[proc (x: var TA) {.nimcall.}](bp) var a: TA diff --git a/tests/overflw/toverflw.nim b/tests/overflw/toverflw.nim index cd7b65acf..50c405ee1 100644 --- a/tests/overflw/toverflw.nim +++ b/tests/overflw/toverflw.nim @@ -2,7 +2,7 @@ discard """ file: "toverflw.nim" output: "the computation overflowed" """ -# Tests nimrod's ability to detect overflows +# Tests nim's ability to detect overflows {.push overflowChecks: on.} diff --git a/tests/parallel/tflowvar.nim b/tests/parallel/tflowvar.nim index 96d42255d..488c65a91 100644 --- a/tests/parallel/tflowvar.nim +++ b/tests/parallel/tflowvar.nim @@ -2,7 +2,7 @@ discard """ output: '''foobarfoobar bazbearbazbear 1''' - cmd: "nimrod $target --threads:on $options $file" + cmd: "nim $target --threads:on $options $file" """ import threadpool diff --git a/tests/parallel/tsysspawn.nim b/tests/parallel/tsysspawn.nim index fc7921b0e..7244a5ee6 100644 --- a/tests/parallel/tsysspawn.nim +++ b/tests/parallel/tsysspawn.nim @@ -1,7 +1,7 @@ discard """ output: '''4 8''' - cmd: "nimrod $target --threads:on $options $file" + cmd: "nim $target --threads:on $options $file" """ import threadpool diff --git a/tests/parallel/tsysspawnbadarg.nim b/tests/parallel/tsysspawnbadarg.nim index ad798a7d3..2d3ffd241 100644 --- a/tests/parallel/tsysspawnbadarg.nim +++ b/tests/parallel/tsysspawnbadarg.nim @@ -1,7 +1,7 @@ discard """ line: 9 errormsg: "'spawn' takes a call expression" - cmd: "nimrod $target --threads:on $options $file" + cmd: "nim $target --threads:on $options $file" """ import threadpool diff --git a/tests/showoff/thtml2.nim b/tests/showoff/thtml2.nim index 8a451ebf1..faeb4e50d 100644 --- a/tests/showoff/thtml2.nim +++ b/tests/showoff/thtml2.nim @@ -1,5 +1,5 @@ discard """ - output: "now look at this
  • Nimrod is quite capable
" + output: "now look at this
  • Nim is quite capable
" """ import strutils @@ -32,6 +32,6 @@ html mainPage: title "now look at this" body: ul: - li "Nimrod is quite capable" + li "Nim is quite capable" echo mainPage() diff --git a/tests/stdlib/techo.nim b/tests/stdlib/techo.nim index 0fa4b5fe0..9cef9205f 100644 --- a/tests/stdlib/techo.nim +++ b/tests/stdlib/techo.nim @@ -1,3 +1,3 @@ -# Simplest Nimrod program +# Simplest Nim program echo "Hello, World!" diff --git a/tests/stdlib/tircbot.nim b/tests/stdlib/tircbot.nim index f0417c7ac..b91300762 100644 --- a/tests/stdlib/tircbot.nim +++ b/tests/stdlib/tircbot.nim @@ -191,7 +191,7 @@ type const ircServer = "irc.freenode.net" - joinChans = @["#nimrod"] + joinChans = @["#nim"] botNickname = "NimBot" proc setSeen(d: TDb, s: TSeen) = @@ -271,7 +271,7 @@ proc handleWebMessage(state: PState, line: string) = message.add("-" & $commit["removed"].len & "]: ") message.add(limitCommitMsg(commit["message"].str)) - # Send message to #nimrod. + # Send message to #nim. state.ircClient.privmsg(joinChans[0], message) elif json.hasKey("redisinfo"): assert json["redisinfo"].hasKey("port") @@ -420,7 +420,7 @@ proc handleIrc(irc: PAsyncIRC, event: TIRCEvent, state: PState) = seenNick.msg = msg state.database.setSeen(seenNick) of MNick: - createSeen(PSeenNick, event.nick, "#nimrod") + createSeen(PSeenNick, event.nick, "#nim") seenNick.newNick = event.params[0] state.database.setSeen(seenNick) else: diff --git a/tests/stdlib/tpegs.nim b/tests/stdlib/tpegs.nim index 6e488bab4..e5353e4ff 100644 --- a/tests/stdlib/tpegs.nim +++ b/tests/stdlib/tpegs.nim @@ -851,7 +851,7 @@ template `=~`*(s: string, pattern: TPeg): expr = ## This calls ``match`` with an implicit declared ``matches`` array that ## can be used in the scope of the ``=~`` call: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}": ## # matches a key=value pair: @@ -897,12 +897,12 @@ proc replacef*(s: string, sub: TPeg, by: string): string {. ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2") ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## ## "var1<-keykey; val2<-key2key2" result = "" @@ -979,13 +979,13 @@ iterator split*(s: string, sep: TPeg): string = ## Substrings are separated by the PEG `sep`. ## Examples: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## for word in split("00232this02939is39an22example111", peg"\d+"): ## writeln(stdout, word) ## ## Results in: ## - ## .. code-block:: nimrod + ## .. code-block:: nim ## "this" ## "is" ## "an" diff --git a/tests/stdlib/tunidecode.nim b/tests/stdlib/tunidecode.nim index 647858825..689453c76 100644 --- a/tests/stdlib/tunidecode.nim +++ b/tests/stdlib/tunidecode.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nimrod $target --hints:on -d:embedUnidecodeTable $options $file" + cmd: "nim $target --hints:on -d:embedUnidecodeTable $options $file" output: "Ausserst" """ diff --git a/tests/stdlib/txmlgen.nim b/tests/stdlib/txmlgen.nim index 917427abc..fa1dffe56 100644 --- a/tests/stdlib/txmlgen.nim +++ b/tests/stdlib/txmlgen.nim @@ -1,11 +1,11 @@ discard """ file: "txmlgen.nim" - output: "

Nimrod

" + output: "

Nim

" """ import htmlgen -var nim = "Nimrod" -echo h1(a(href="http://force7.de/nimrod", nim)) +var nim = "Nim" +echo h1(a(href="http://force7.de/nim", nim)) diff --git a/tests/stdlib/txmltree.nim b/tests/stdlib/txmltree.nim index 931871f15..bfe2dc94a 100644 --- a/tests/stdlib/txmltree.nim +++ b/tests/stdlib/txmltree.nim @@ -5,9 +5,9 @@ discard """ import xmltree, strtabs -var x = <>a(href="nimrod.de", newText("www.nimrod-test.de")) +var x = <>a(href="nim.de", newText("www.nim-test.de")) -echo($x == "www.nimrod-test.de") +echo($x == "www.nim-test.de") diff --git a/tests/template/t_otemplates.nim b/tests/template/t_otemplates.nim index 7de728ab2..1a9075d20 100644 --- a/tests/template/t_otemplates.nim +++ b/tests/template/t_otemplates.nim @@ -3,8 +3,8 @@ discard """ """ # Ref: -# http://nimrod-lang.org/macros.html -# http://nimrod-lang.org/parseutils.html +# http://nim-lang.org/macros.html +# http://nim-lang.org/parseutils.html # Imports @@ -313,7 +313,7 @@ proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool proc parse_template(node: PNimrodNode, value: string) = ## Parses through entire template, outputing valid - ## Nimrod code into the input `node` AST. + ## Nim code into the input `node` AST. var index = 0 while index < value.len and parse_until_symbol(node, value, index): nil diff --git a/tests/testament/caasdriver.nim b/tests/testament/caasdriver.nim index 4754fa342..8f2eec33b 100644 --- a/tests/testament/caasdriver.nim +++ b/tests/testament/caasdriver.nim @@ -33,7 +33,7 @@ proc replaceVars(session: var NimSession, text: string): string = result = result.replace(moduleReplaceVar, session.modname) result = result.replace(silentReplaceVar, silentReplaceText) -proc startNimrodSession(project, script: string, mode: TRunMode): +proc startNimSession(project, script: string, mode: TRunMode): NimSession = let (dir, name, ext) = project.splitFile result.mode = mode @@ -114,7 +114,7 @@ proc doScenario(script: string, output: PStream, mode: TRunMode, verbose: bool): if f.readLine(project): var - s = startNimrodSession(script.parentDir / project.string, script, mode) + s = startNimSession(script.parentDir / project.string, script, mode) tline = TaintedString("") ln = 1 diff --git a/tests/testament/htmlgen.nim b/tests/testament/htmlgen.nim index b91475aee..d863bd411 100644 --- a/tests/testament/htmlgen.nim +++ b/tests/testament/htmlgen.nim @@ -1,6 +1,6 @@ # # -# Nimrod Tester +# Nim Tester # (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim index 9544fe71a..37fe8cfee 100644 --- a/tests/testament/specs.nim +++ b/tests/testament/specs.nim @@ -18,7 +18,7 @@ type actionRun = "run" actionReject = "reject" TResultEnum* = enum - reNimrodcCrash, # nim compiler seems to have crashed + reNimcCrash, # nim compiler seems to have crashed reMsgsDiffer, # error messages differ reFilesDiffer, # expected and given filenames differ reLinesDiffer, # expected and given line numbers differ diff --git a/tests/threads/tthreadanalysis.nim b/tests/threads/tthreadanalysis.nim index 37369b79c..b222f15a9 100644 --- a/tests/threads/tthreadanalysis.nim +++ b/tests/threads/tthreadanalysis.nim @@ -2,7 +2,7 @@ discard """ outputsub: "101" errormsg: "'threadFunc' is not GC-safe" line: 39 - cmd: "nimrod $target --hints:on --threads:on $options $file" + cmd: "nim $target --hints:on --threads:on $options $file" """ import os diff --git a/tests/threads/tthreadanalysis2.nim b/tests/threads/tthreadanalysis2.nim index bcc09db98..d5b2cd430 100644 --- a/tests/threads/tthreadanalysis2.nim +++ b/tests/threads/tthreadanalysis2.nim @@ -2,7 +2,7 @@ discard """ file: "tthreadanalysis2.nim" line: 37 errormsg: "'threadFunc' is not GC-safe" - cmd: "nimrod $target --hints:on --threads:on $options $file" + cmd: "nim $target --hints:on --threads:on $options $file" """ import os diff --git a/tests/threads/tthreadheapviolation1.nim b/tests/threads/tthreadheapviolation1.nim index e0629ed08..94e1b64db 100644 --- a/tests/threads/tthreadheapviolation1.nim +++ b/tests/threads/tthreadheapviolation1.nim @@ -1,7 +1,7 @@ discard """ line: 11 errormsg: "'horrible' is not GC-safe" - cmd: "nimrod $target --hints:on --threads:on $options $file" + cmd: "nim $target --hints:on --threads:on $options $file" """ var diff --git a/tests/types/tillegaltyperecursion.nim b/tests/types/tillegaltyperecursion.nim index 114e4d08e..ebdbc1d13 100644 --- a/tests/types/tillegaltyperecursion.nim +++ b/tests/types/tillegaltyperecursion.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nimrod $target --threads:on $options $file" + cmd: "nim $target --threads:on $options $file" errormsg: "illegal recursion in type 'TIRC'" line: 16 """ @@ -62,5 +62,5 @@ proc Connect*(irc: var TIRC, nick: string, host: string, port: int = 6667) = when isMainModule: var irc = initIRC() irc.Connect("AmryBot[Nim]","irc.freenode.net",6667) - irc.sendRaw("JOIN #nimrod") + irc.sendRaw("JOIN #nim") os.Sleep(4000) diff --git a/tests/usingstmt/tusingstatement.nim b/tests/usingstmt/tusingstatement.nim index a33aced4c..b58478d74 100644 --- a/tests/usingstmt/tusingstatement.nim +++ b/tests/usingstmt/tusingstatement.nim @@ -9,7 +9,7 @@ import # This macro mimics the using statement from C# # # It's kept only as a test for the macro system -# Nimrod's destructors offer a mechanism for automatic +# Nim's destructors offer a mechanism for automatic # disposal of resources. # macro autoClose(e: expr): stmt {.immediate.} = diff --git a/tests/vm/tconsteval.nim b/tests/vm/tconsteval.nim index 16fd8f4b8..c7932d444 100644 --- a/tests/vm/tconsteval.nim +++ b/tests/vm/tconsteval.nim @@ -6,7 +6,7 @@ import strutils const HelpText = """ +-----------------------------------------------------------------+ -| Maintenance program for Nimrod | +| Maintenance program for Nim | | Version $1| | (c) 2012 Andreas Rumpf | +-----------------------------------------------------------------+ @@ -19,12 +19,12 @@ Options: --help, -h shows this help and quits Possible Commands: boot [options] bootstraps with given command line options - clean cleans Nimrod project; removes generated files + clean cleans Nim project; removes generated files web generates the website csource [options] builds the C sources for installation zip builds the installation ZIP package inno builds the Inno Setup installer -""" % [NimrodVersion & repeatChar(44-len(NimrodVersion)), +""" % [NimVersion & repeatChar(44-len(NimVersion)), CompileDate, CompileTime] echo helpText From cff2a0c0b4db94eb5e95504da0a4e31658bfc160 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 30 Aug 2014 11:59:08 +0100 Subject: [PATCH 046/409] Case fixes for network modules. --- lib/pure/asyncdispatch.nim | 64 +++++++++++++++--------------- lib/pure/asyncftpclient.nim | 78 ++++++++++++++++++------------------- lib/pure/asyncio.nim | 45 ++++++++++----------- lib/pure/asyncnet.nim | 30 +++++++------- lib/pure/net.nim | 38 +++++++++--------- 5 files changed, 129 insertions(+), 126 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index e2a046c9d..7b8ad582f 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -13,7 +13,7 @@ import os, oids, tables, strutils, macros, times import rawsockets, net -export Port, SocketFlags +export Port, SocketFlag #{.injectStmt: newGcInvariant().} @@ -223,11 +223,11 @@ proc processTimers(p: PDispatcherBase) = when defined(windows) or defined(nimdoc): import winlean, sets, hashes type - TCompletionKey = dword + TCompletionKey = Dword TCompletionData* = object sock: TAsyncFD - cb: proc (sock: TAsyncFD, bytesTransferred: DWORD, + cb: proc (sock: TAsyncFD, bytesTransferred: Dword, errcode: OSErrorCode) {.closure,gcsafe.} PDispatcher* = ref object of PDispatcherBase @@ -283,7 +283,7 @@ when defined(windows) or defined(nimdoc): let llTimeout = if timeout == -1: winlean.INFINITE else: timeout.int32 - var lpNumberOfBytesTransferred: DWORD + var lpNumberOfBytesTransferred: Dword var lpCompletionKey: ULONG var customOverlapped: PCustomOverlapped let res = GetQueuedCompletionStatus(p.ioPort, @@ -321,10 +321,10 @@ when defined(windows) or defined(nimdoc): proc initPointer(s: SocketHandle, func: var pointer, guid: var TGUID): bool = # Ref: https://github.com/powdahound/twisted/blob/master/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c - var bytesRet: DWORD + var bytesRet: Dword func = nil result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, addr guid, - sizeof(TGUID).dword, addr func, sizeof(pointer).DWORD, + sizeof(TGUID).Dword, addr func, sizeof(pointer).Dword, addr bytesRet, nil, nil) == 0 proc initAll() = @@ -337,44 +337,44 @@ when defined(windows) or defined(nimdoc): raiseOSError(osLastError()) proc connectEx(s: SocketHandle, name: ptr TSockAddr, namelen: cint, - lpSendBuffer: pointer, dwSendDataLength: dword, - lpdwBytesSent: PDWORD, lpOverlapped: POVERLAPPED): bool = + lpSendBuffer: pointer, dwSendDataLength: Dword, + lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool = if connectExPtr.isNil: raise newException(ValueError, "Need to initialise ConnectEx().") let func = cast[proc (s: SocketHandle, name: ptr TSockAddr, namelen: cint, - lpSendBuffer: pointer, dwSendDataLength: dword, - lpdwBytesSent: PDWORD, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](connectExPtr) + lpSendBuffer: pointer, dwSendDataLength: Dword, + lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](connectExPtr) result = func(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped) proc acceptEx(listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: DWORD, lpdwBytesReceived: PDWORD, + dwRemoteAddressLength: Dword, lpdwBytesReceived: PDword, lpOverlapped: POVERLAPPED): bool = if acceptExPtr.isNil: raise newException(ValueError, "Need to initialise AcceptEx().") let func = cast[proc (listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: DWORD, lpdwBytesReceived: PDWORD, + dwRemoteAddressLength: Dword, lpdwBytesReceived: PDword, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](acceptExPtr) result = func(listenSock, acceptSock, lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived, lpOverlapped) proc getAcceptExSockaddrs(lpOutputBuffer: pointer, - dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: DWORD, - LocalSockaddr: ptr ptr TSockAddr, LocalSockaddrLength: lpint, - RemoteSockaddr: ptr ptr TSockAddr, RemoteSockaddrLength: lpint) = + dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: Dword, + LocalSockaddr: ptr ptr TSockAddr, LocalSockaddrLength: LPInt, + RemoteSockaddr: ptr ptr TSockAddr, RemoteSockaddrLength: LPInt) = if getAcceptExSockAddrsPtr.isNil: raise newException(ValueError, "Need to initialise getAcceptExSockAddrs().") let func = cast[proc (lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: DWORD, LocalSockaddr: ptr ptr TSockAddr, - LocalSockaddrLength: lpint, RemoteSockaddr: ptr ptr TSockAddr, - RemoteSockaddrLength: lpint) {.stdcall,gcsafe.}](getAcceptExSockAddrsPtr) + dwRemoteAddressLength: Dword, LocalSockaddr: ptr ptr TSockAddr, + LocalSockaddrLength: LPInt, RemoteSockaddr: ptr ptr TSockAddr, + RemoteSockaddrLength: LPInt) {.stdcall,gcsafe.}](getAcceptExSockAddrsPtr) func(lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, LocalSockaddr, LocalSockaddrLength, @@ -407,7 +407,7 @@ when defined(windows) or defined(nimdoc): var ol = PCustomOverlapped() GC_ref(ol) ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWORD, errcode: OSErrorCode) = + proc (sock: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): retFuture.complete() @@ -462,12 +462,12 @@ when defined(windows) or defined(nimdoc): dataBuf.buf = cast[cstring](alloc0(size)) dataBuf.len = size - var bytesReceived: DWORD - var flagsio = flags.toOSFlags().DWORD + var bytesReceived: Dword + var flagsio = flags.toOSFlags().Dword var ol = PCustomOverlapped() GC_ref(ol) ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWORD, errcode: OSErrorCode) = + proc (sock: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): if bytesCount == 0 and dataBuf.buf[0] == '\0': @@ -541,11 +541,11 @@ when defined(windows) or defined(nimdoc): dataBuf.buf = data # since this is not used in a callback, this is fine dataBuf.len = data.len - var bytesReceived, lowFlags: DWORD + var bytesReceived, lowFlags: Dword var ol = PCustomOverlapped() GC_ref(ol) ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWORD, errcode: OSErrorCode) = + proc (sock: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): retFuture.complete() @@ -594,10 +594,10 @@ when defined(windows) or defined(nimdoc): const lpOutputLen = 1024 var lpOutputBuf = newString(lpOutputLen) - var dwBytesReceived: DWORD - let dwReceiveDataLength = 0.DWORD # We don't want any data to be read. - let dwLocalAddressLength = DWORD(sizeof (Tsockaddr_in) + 16) - let dwRemoteAddressLength = DWORD(sizeof(Tsockaddr_in) + 16) + var dwBytesReceived: Dword + let dwReceiveDataLength = 0.Dword # We don't want any data to be read. + let dwLocalAddressLength = Dword(sizeof (Tsockaddr_in) + 16) + let dwRemoteAddressLength = Dword(sizeof(Tsockaddr_in) + 16) template completeAccept(): stmt {.immediate, dirty.} = var listenSock = socket @@ -606,12 +606,12 @@ when defined(windows) or defined(nimdoc): sizeof(listenSock).TSockLen) if setoptRet != 0: raiseOSError(osLastError()) - var LocalSockaddr, RemoteSockaddr: ptr TSockAddr + var localSockaddr, remoteSockaddr: ptr TSockAddr var localLen, remoteLen: int32 getAcceptExSockaddrs(addr lpOutputBuf[0], dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, - addr LocalSockaddr, addr localLen, - addr RemoteSockaddr, addr remoteLen) + addr localSockaddr, addr localLen, + addr remoteSockaddr, addr remoteLen) register(clientSock.TAsyncFD) # TODO: IPv6. Check ``sa_family``. http://stackoverflow.com/a/9212542/492186 retFuture.complete( @@ -634,7 +634,7 @@ when defined(windows) or defined(nimdoc): var ol = PCustomOverlapped() GC_ref(ol) ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: DWORD, errcode: OSErrorCode) = + proc (sock: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): completeAccept() diff --git a/lib/pure/asyncftpclient.nim b/lib/pure/asyncftpclient.nim index f1b1d1400..a3d977660 100644 --- a/lib/pure/asyncftpclient.nim +++ b/lib/pure/asyncftpclient.nim @@ -8,21 +8,21 @@ import asyncdispatch, asyncnet, strutils, parseutils, os, times -from ftpclient import TFtpBase, EInvalidReply, TFtpEvent -from net import bufferSize +from ftpclient import FtpBaseObj, ReplyError, FtpEvent +from net import BufferSize type - TAsyncFtpClient* = TFtpBase[PAsyncSocket] - PAsyncFtpClient* = ref TAsyncFtpClient + AsyncFtpClientObj* = FtpBaseObj[AsyncSocket] + AsyncFtpClient* = ref AsyncFtpClientObj ProgressChangedProc* = proc (total, progress: BiggestInt, speed: float): - PFuture[void] {.closure, gcsafe.} + Future[void] {.closure, gcsafe.} -proc expectReply(ftp: PAsyncFtpClient): PFuture[TaintedString] = +proc expectReply(ftp: AsyncFtpClient): Future[TaintedString] = result = ftp.csock.recvLine() -proc send*(ftp: PAsyncFtpClient, m: string): PFuture[TaintedString] {.async.} = +proc send*(ftp: AsyncFtpClient, m: string): Future[TaintedString] {.async.} = ## Send a message to the server, and wait for a primary reply. ## ``\c\L`` is added for you. await ftp.csock.send(m & "\c\L") @@ -31,11 +31,11 @@ proc send*(ftp: PAsyncFtpClient, m: string): PFuture[TaintedString] {.async.} = proc assertReply(received: TaintedString, expected: varargs[string]) = for i in items(expected): if received.string.startsWith(i): return - raise newException(EInvalidReply, + raise newException(ReplyError, "Expected reply '$1' got: $2" % [expected.join("' or '"), received.string]) -proc pasv(ftp: PAsyncFtpClient) {.async.} = +proc pasv(ftp: AsyncFtpClient) {.async.} = ## Negotiate a data connection. ftp.dsock = newAsyncSocket() @@ -46,13 +46,13 @@ proc pasv(ftp: PAsyncFtpClient) {.async.} = var ip = nums[0.. -3] var port = nums[-2.. -1] var properPort = port[0].parseInt()*256+port[1].parseInt() - await ftp.dsock.connect(ip.join("."), TPort(properPort.toU16)) - ftp.dsockConnected = True + await ftp.dsock.connect(ip.join("."), Port(properPort.toU16)) + ftp.dsockConnected = true proc normalizePathSep(path: string): string = return replace(path, '\\', '/') -proc connect*(ftp: PAsyncFtpClient) {.async.} = +proc connect*(ftp: AsyncFtpClient) {.async.} = ## Connect to the FTP server specified by ``ftp``. await ftp.csock.connect(ftp.address, ftp.port) @@ -69,21 +69,21 @@ proc connect*(ftp: PAsyncFtpClient) {.async.} = if ftp.pass != "": assertReply(await(ftp.send("PASS " & ftp.pass)), "230") -proc pwd*(ftp: PAsyncFtpClient): PFuture[TaintedString] {.async.} = +proc pwd*(ftp: AsyncFtpClient): Future[TaintedString] {.async.} = ## Returns the current working directory. let wd = await ftp.send("PWD") assertReply wd, "257" return wd.string.captureBetween('"').TaintedString # " -proc cd*(ftp: PAsyncFtpClient, dir: string) {.async.} = +proc cd*(ftp: AsyncFtpClient, dir: string) {.async.} = ## Changes the current directory on the remote FTP server to ``dir``. assertReply(await(ftp.send("CWD " & dir.normalizePathSep)), "250") -proc cdup*(ftp: PAsyncFtpClient) {.async.} = +proc cdup*(ftp: AsyncFtpClient) {.async.} = ## Changes the current directory to the parent of the current directory. assertReply(await(ftp.send("CDUP")), "200") -proc getLines(ftp: PAsyncFtpClient): PFuture[string] {.async.} = +proc getLines(ftp: AsyncFtpClient): Future[string] {.async.} = ## Downloads text data in ASCII mode result = "" assert ftp.dsockConnected @@ -96,7 +96,7 @@ proc getLines(ftp: PAsyncFtpClient): PFuture[string] {.async.} = assertReply(await(ftp.expectReply()), "226") -proc listDirs*(ftp: PAsyncFtpClient, dir = ""): PFuture[seq[string]] {.async.} = +proc listDirs*(ftp: AsyncFtpClient, dir = ""): Future[seq[string]] {.async.} = ## Returns a list of filenames in the given directory. If ``dir`` is "", ## the current directory is used. If ``async`` is true, this ## function will return immediately and it will be your job to @@ -107,13 +107,13 @@ proc listDirs*(ftp: PAsyncFtpClient, dir = ""): PFuture[seq[string]] {.async.} = result = splitLines(await ftp.getLines()) -proc existsFile*(ftp: PAsyncFtpClient, file: string): PFuture[bool] {.async.} = +proc existsFile*(ftp: AsyncFtpClient, file: string): Future[bool] {.async.} = ## Determines whether ``file`` exists. var files = await ftp.listDirs() for f in items(files): if f.normalizePathSep == file.normalizePathSep: return true -proc createDir*(ftp: PAsyncFtpClient, dir: string, recursive = false){.async.} = +proc createDir*(ftp: AsyncFtpClient, dir: string, recursive = false){.async.} = ## Creates a directory ``dir``. If ``recursive`` is true, the topmost ## subdirectory of ``dir`` will be created first, following the secondmost... ## etc. this allows you to give a full path as the ``dir`` without worrying @@ -123,14 +123,14 @@ proc createDir*(ftp: PAsyncFtpClient, dir: string, recursive = false){.async.} = else: var reply = TaintedString"" var previousDirs = "" - for p in split(dir, {os.dirSep, os.altSep}): + for p in split(dir, {os.DirSep, os.AltSep}): if p != "": previousDirs.add(p) reply = await ftp.send("MKD " & previousDirs) previousDirs.add('/') assertReply reply, "257" -proc chmod*(ftp: PAsyncFtpClient, path: string, +proc chmod*(ftp: AsyncFtpClient, path: string, permissions: set[TFilePermission]) {.async.} = ## Changes permission of ``path`` to ``permissions``. var userOctal = 0 @@ -152,7 +152,7 @@ proc chmod*(ftp: PAsyncFtpClient, path: string, assertReply(await(ftp.send("SITE CHMOD " & perm & " " & path.normalizePathSep)), "200") -proc list*(ftp: PAsyncFtpClient, dir = ""): PFuture[string] {.async.} = +proc list*(ftp: AsyncFtpClient, dir = ""): Future[string] {.async.} = ## Lists all files in ``dir``. If ``dir`` is ``""``, uses the current ## working directory. await ftp.pasv() @@ -162,7 +162,7 @@ proc list*(ftp: PAsyncFtpClient, dir = ""): PFuture[string] {.async.} = result = await ftp.getLines() -proc retrText*(ftp: PAsyncFtpClient, file: string): PFuture[string] {.async.} = +proc retrText*(ftp: AsyncFtpClient, file: string): Future[string] {.async.} = ## Retrieves ``file``. File must be ASCII text. await ftp.pasv() let reply = await ftp.send("RETR " & file.normalizePathSep) @@ -170,13 +170,13 @@ proc retrText*(ftp: PAsyncFtpClient, file: string): PFuture[string] {.async.} = result = await ftp.getLines() -proc getFile(ftp: PAsyncFtpClient, file: TFile, total: BiggestInt, +proc getFile(ftp: AsyncFtpClient, file: TFile, total: BiggestInt, onProgressChanged: ProgressChangedProc) {.async.} = assert ftp.dsockConnected var progress = 0 var progressInSecond = 0 var countdownFut = sleepAsync(1000) - var dataFut = ftp.dsock.recv(bufferSize) + var dataFut = ftp.dsock.recv(BufferSize) while ftp.dsockConnected: await dataFut or countdownFut if countdownFut.finished: @@ -191,20 +191,20 @@ proc getFile(ftp: PAsyncFtpClient, file: TFile, total: BiggestInt, progress.inc(data.len) progressInSecond.inc(data.len) file.write(data) - dataFut = ftp.dsock.recv(bufferSize) + dataFut = ftp.dsock.recv(BufferSize) else: - ftp.dsockConnected = False + ftp.dsockConnected = false assertReply(await(ftp.expectReply()), "226") proc defaultOnProgressChanged*(total, progress: BiggestInt, - speed: float): PFuture[void] {.nimcall,gcsafe.} = + speed: float): Future[void] {.nimcall,gcsafe.} = ## Default FTP ``onProgressChanged`` handler. Does nothing. result = newFuture[void]() #echo(total, " ", progress, " ", speed) result.complete() -proc retrFile*(ftp: PAsyncFtpClient, file, dest: string, +proc retrFile*(ftp: AsyncFtpClient, file, dest: string, onProgressChanged = defaultOnProgressChanged) {.async.} = ## Downloads ``file`` and saves it to ``dest``. ## The ``EvRetr`` event is passed to the specified ``handleEvent`` function @@ -215,14 +215,14 @@ proc retrFile*(ftp: PAsyncFtpClient, file, dest: string, var reply = await ftp.send("RETR " & file.normalizePathSep) assertReply reply, ["125", "150"] if {'(', ')'} notin reply.string: - raise newException(EInvalidReply, "Reply has no file size.") - var fileSize: biggestInt + raise newException(ReplyError, "Reply has no file size.") + var fileSize: BiggestInt if reply.string.captureBetween('(', ')').parseBiggestInt(fileSize) == 0: - raise newException(EInvalidReply, "Reply has no file size.") + raise newException(ReplyError, "Reply has no file size.") await getFile(ftp, destFile, fileSize, onProgressChanged) -proc doUpload(ftp: PAsyncFtpClient, file: TFile, +proc doUpload(ftp: AsyncFtpClient, file: TFile, onProgressChanged: ProgressChangedProc) {.async.} = assert ftp.dsockConnected @@ -231,7 +231,7 @@ proc doUpload(ftp: PAsyncFtpClient, file: TFile, var progress = 0 var progressInSecond = 0 var countdownFut = sleepAsync(1000) - var sendFut: PFuture[void] = nil + var sendFut: Future[void] = nil while ftp.dsockConnected: if sendFut == nil or sendFut.finished: progress.inc(data.len) @@ -255,7 +255,7 @@ proc doUpload(ftp: PAsyncFtpClient, file: TFile, await countdownFut or sendFut -proc storeFile*(ftp: PAsyncFtpClient, file, dest: string, +proc storeFile*(ftp: AsyncFtpClient, file, dest: string, onProgressChanged = defaultOnProgressChanged) {.async.} = ## Uploads ``file`` to ``dest`` on the remote FTP server. Usage of this ## function asynchronously is recommended to view the progress of @@ -271,9 +271,9 @@ proc storeFile*(ftp: PAsyncFtpClient, file, dest: string, await doUpload(ftp, destFile, onProgressChanged) -proc newAsyncFtpClient*(address: string, port = TPort(21), - user, pass = ""): PAsyncFtpClient = - ## Creates a new ``PAsyncFtpClient`` object. +proc newAsyncFtpClient*(address: string, port = Port(21), + user, pass = ""): AsyncFtpClient = + ## Creates a new ``AsyncFtpClient`` object. new result result.user = user result.pass = pass @@ -284,7 +284,7 @@ proc newAsyncFtpClient*(address: string, port = TPort(21), when isMainModule: var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test") - proc main(ftp: PAsyncFtpClient) {.async.} = + proc main(ftp: AsyncFtpClient) {.async.} = await ftp.connect() echo await ftp.pwd() echo await ftp.listDirs() diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 54aa19079..90f1d0b2c 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -91,9 +91,11 @@ import sockets, os ## getSocket(s).accept(client) when defined(windows): - from winlean import TimeVal, SocketHandle, FdSet, FD_ZERO, FD_SET, FD_ISSET, select + from winlean import TimeVal, SocketHandle, FdSet, FD_ZERO, FD_SET, + fdSet, FD_ISSET, select else: - from posix import TimeVal, SocketHandle, FdSet, FD_ZERO, FD_SET, FD_ISSET, select + from posix import TimeVal, SocketHandle, FdSet, FD_ZERO, FD_SET, + fdSet, FD_ISSET, select type DelegateObj* = object @@ -113,33 +115,32 @@ type Dispatcher* = ref DispatcherObj DispatcherObj = object - delegates: seq[PDelegate] + delegates: seq[Delegate] AsyncSocket* = ref AsyncSocketObj AsyncSocketObj* = object of RootObj socket: Socket info: SocketStatus - handleRead*: proc (s: PAsyncSocket) {.closure, gcsafe.} - handleWrite: proc (s: PAsyncSocket) {.closure, gcsafe.} - handleConnect*: proc (s: PAsyncSocket) {.closure, gcsafe.} + handleRead*: proc (s: AsyncSocket) {.closure, gcsafe.} + handleWrite: proc (s: AsyncSocket) {.closure, gcsafe.} + handleConnect*: proc (s: AsyncSocket) {.closure, gcsafe.} - handleAccept*: proc (s: PAsyncSocket) {.closure, gcsafe.} + handleAccept*: proc (s: AsyncSocket) {.closure, gcsafe.} - handleTask*: proc (s: PAsyncSocket) {.closure, gcsafe.} + handleTask*: proc (s: AsyncSocket) {.closure, gcsafe.} lineBuffer: TaintedString ## Temporary storage for ``readLine`` sendBuffer: string ## Temporary storage for ``send`` sslNeedAccept: bool - proto: TProtocol - deleg: PDelegate + proto: Protocol + deleg: Delegate SocketStatus* = enum SockIdle, SockConnecting, SockConnected, SockListening, SockClosed, SockUDPBound {.deprecated: [TDelegate: DelegateObj, PDelegate: Delegate, - TProcessOption: ProcessOption, TInfo: SocketStatus, PAsyncSocket: AsyncSocket, TAsyncSocket: AsyncSocketObj, TDispatcher: DispatcherObj, PDispatcher: Dispatcher, ].} @@ -176,7 +177,7 @@ proc asyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, result = newAsyncSocket() result.socket = socket(domain, typ, protocol, buffered) result.proto = protocol - if result.socket == invalidSocket: osError(osLastError()) + if result.socket == invalidSocket: raiseOSError(osLastError()) result.socket.setBlocking(false) proc toAsyncSocket*(sock: TSocket, state: TInfo = SockConnected): PAsyncSocket = @@ -366,7 +367,7 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, client.sslNeedAccept = false client.info = SockConnected - if c == invalidSocket: socketError(server.socket) + if c == invalidSocket: raiseSocketError(server.socket) c.setBlocking(false) # TODO: Needs to be tested. # deleg.open is set in ``toDelegate``. @@ -490,7 +491,7 @@ proc recvLine*(s: PAsyncSocket, line: var TaintedString): bool {.deprecated.} = of RecvDisconnected: result = true of RecvFail: - s.socketError(async = true) + s.raiseSocketError(async = true) result = false {.pop.} @@ -544,19 +545,19 @@ proc send*(sock: PAsyncSocket, data: string) = sock.sendBuffer.add(data[bytesSent .. -1]) sock.deleg.mode = fmReadWrite -proc timeValFromMilliseconds(timeout = 500): TTimeVal = +proc timeValFromMilliseconds(timeout = 500): TimeVal = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var TFdSet, s: seq[PDelegate], m: var int) = +proc createFdSet(fd: var FdSet, s: seq[Delegate], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.fd)) - FD_SET(i.fd, fd) + fdSet(i.fd, fd) -proc pruneSocketSet(s: var seq[PDelegate], fd: var TFdSet) = +proc pruneSocketSet(s: var seq[Delegate], fd: var FdSet) = var i = 0 var L = s.len while i < L: @@ -569,9 +570,9 @@ proc pruneSocketSet(s: var seq[PDelegate], fd: var TFdSet) = proc select(readfds, writefds, exceptfds: var seq[PDelegate], timeout = 500): int = - var tv {.noInit.}: TTimeVal = timeValFromMilliseconds(timeout) + var tv {.noInit.}: TimeVal = timeValFromMilliseconds(timeout) - var rd, wr, ex: TFdSet + var rd, wr, ex: FdSet var m = 0 createFdSet(rd, readfds, m) createFdSet(wr, writefds, m) @@ -681,7 +682,7 @@ when isMainModule: proc main = var d = newDispatcher() - var s = AsyncSocket() + var s = asyncSocket() s.connect("amber.tenthbit.net", TPort(6667)) s.handleConnect = proc (s: PAsyncSocket) = @@ -691,7 +692,7 @@ when isMainModule: testRead(s, 1) d.register(s) - var server = AsyncSocket() + var server = asyncSocket() server.handleAccept = proc (s: PAsyncSocket) = testAccept(s, d, 78) diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 695d8c07b..8734bab4c 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -64,7 +64,7 @@ type proc newSocket(fd: TAsyncFD, isBuff: bool): PAsyncSocket = assert fd != osInvalidSocket.TAsyncFD new(result.PSocket) - result.fd = fd.TSocketHandle + result.fd = fd.SocketHandle result.isBuffered = isBuff if isBuff: result.currPos = 0 @@ -75,15 +75,15 @@ proc newAsyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) proc connect*(socket: PAsyncSocket, address: string, port: TPort, - af = AF_INET): PFuture[void] = + af = AF_INET): Future[void] = ## Connects ``socket`` to server at ``address:port``. ## - ## Returns a ``PFuture`` which will complete when the connection succeeds + ## Returns a ``Future`` which will complete when the connection succeeds ## or an error occurs. result = connect(socket.fd.TAsyncFD, address, port, af) proc readIntoBuf(socket: PAsyncSocket, - flags: set[TSocketFlags]): PFuture[int] {.async.} = + flags: set[TSocketFlags]): Future[int] {.async.} = var data = await recv(socket.fd.TAsyncFD, BufferSize, flags) if data.len != 0: copyMem(addr socket.buffer[0], addr data[0], data.len) @@ -92,7 +92,7 @@ proc readIntoBuf(socket: PAsyncSocket, result = data.len proc recv*(socket: PAsyncSocket, size: int, - flags = {TSocketFlags.SafeDisconn}): PFuture[string] {.async.} = + flags = {TSocketFlags.SafeDisconn}): Future[string] {.async.} = ## Reads ``size`` bytes from ``socket``. Returned future will complete once ## all of the requested data is read. If socket is disconnected during the ## recv operation then the future may complete with only a part of the @@ -131,21 +131,21 @@ proc recv*(socket: PAsyncSocket, size: int, result = await recv(socket.fd.TAsyncFD, size, flags) proc send*(socket: PAsyncSocket, data: string, - flags = {TSocketFlags.SafeDisconn}): PFuture[void] = + flags = {TSocketFlags.SafeDisconn}): Future[void] = ## Sends ``data`` to ``socket``. The returned future will complete once all ## data has been sent. assert socket != nil result = send(socket.fd.TAsyncFD, data, flags) proc acceptAddr*(socket: PAsyncSocket, flags = {TSocketFlags.SafeDisconn}): - PFuture[tuple[address: string, client: PAsyncSocket]] = + Future[tuple[address: string, client: PAsyncSocket]] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection and the remote address of the client. ## The future will complete when the connection is successfully accepted. var retFuture = newFuture[tuple[address: string, client: PAsyncSocket]]("asyncnet.acceptAddr") var fut = acceptAddr(socket.fd.TAsyncFD, flags) fut.callback = - proc (future: PFuture[tuple[address: string, client: TAsyncFD]]) = + proc (future: Future[tuple[address: string, client: TAsyncFD]]) = assert future.finished if future.failed: retFuture.fail(future.readError) @@ -156,14 +156,14 @@ proc acceptAddr*(socket: PAsyncSocket, flags = {TSocketFlags.SafeDisconn}): return retFuture proc accept*(socket: PAsyncSocket, - flags = {TSocketFlags.SafeDisconn}): PFuture[PAsyncSocket] = + flags = {TSocketFlags.SafeDisconn}): Future[PAsyncSocket] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection. ## The future will complete when the connection is successfully accepted. var retFut = newFuture[PAsyncSocket]("asyncnet.accept") var fut = acceptAddr(socket, flags) fut.callback = - proc (future: PFuture[tuple[address: string, client: PAsyncSocket]]) = + proc (future: Future[tuple[address: string, client: PAsyncSocket]]) = assert future.finished if future.failed: retFut.fail(future.readError) @@ -172,7 +172,7 @@ proc accept*(socket: PAsyncSocket, return retFut proc recvLine*(socket: PAsyncSocket, - flags = {TSocketFlags.SafeDisconn}): PFuture[string] {.async.} = + flags = {TSocketFlags.SafeDisconn}): Future[string] {.async.} = ## Reads a line of data from ``socket``. Returned future will complete once ## a full line is read or an error occurs. ## @@ -282,23 +282,23 @@ when isMainModule: var sock = newAsyncSocket() var f = connect(sock, "irc.freenode.net", TPort(6667)) f.callback = - proc (future: PFuture[void]) = + proc (future: Future[void]) = echo("Connected in future!") for i in 0 .. 50: var recvF = recv(sock, 10) recvF.callback = - proc (future: PFuture[string]) = + proc (future: Future[string]) = echo("Read ", future.read.len, ": ", future.read.repr) elif test == LowServer: var sock = newAsyncSocket() sock.bindAddr(TPort(6667)) sock.listen() - proc onAccept(future: PFuture[PAsyncSocket]) = + proc onAccept(future: Future[PAsyncSocket]) = let client = future.read echo "Accepted ", client.fd.cint var t = send(client, "test\c\L") t.callback = - proc (future: PFuture[void]) = + proc (future: Future[void]) = echo("Send") client.close() diff --git a/lib/pure/net.nim b/lib/pure/net.nim index ff3c1e683..b90e0f5d5 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -35,6 +35,10 @@ when defined(ssl): SSLAcceptResult* = enum AcceptNoClient = 0, AcceptNoHandshake, AcceptSuccess + {.deprecated: [ESSL: SSLError, TSSLCVerifyMode: SSLCVerifyMode, + TSSLProtVersion: SSLProtVersion, PSSLContext: SSLContext, + TSSLAcceptResult: SSLAcceptResult].} + const BufferSize*: int = 4000 ## size of a buffered socket's buffer @@ -74,9 +78,7 @@ type {.deprecated: [TSocketFlags: SocketFlag, ETimeout: TimeoutError, TReadLineResult: ReadLineResult, TSOBool: SOBool, PSocket: Socket, - TSocketImpl: SocketImpl, ESSL: SSLError, TSSLCVerifyMode: SSLCVerifyMode, - TSSLProtVersion: SSLProtVersion, PSSLContext: SSLContext, - TSSLAcceptResult: SSLAcceptResult].} + TSocketImpl: SocketImpl].} proc isDisconnectionError*(flags: set[SocketFlag], lastError: OSErrorCode): bool = @@ -98,7 +100,7 @@ proc toOSFlags*(socketFlags: set[SocketFlag]): cint = result = result or MSG_PEEK of SocketFlag.SafeDisconn: continue -proc createSocket(fd: TSocketHandle, isBuff: bool): Socket = +proc createSocket(fd: SocketHandle, isBuff: bool): Socket = assert fd != osInvalidSocket new(result) result.fd = fd @@ -276,19 +278,19 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {. ## If ``address`` is "" then ADDR_ANY will be bound. if address == "": - var name: TSockaddr_in + var name: Sockaddr_in when useWinVersion: name.sin_family = toInt(AF_INET).int16 else: name.sin_family = toInt(AF_INET) name.sin_port = htons(int16(port)) name.sin_addr.s_addr = htonl(INADDR_ANY) - if bindAddr(socket.fd, cast[ptr TSockAddr](addr(name)), - sizeof(name).TSocklen) < 0'i32: + if bindAddr(socket.fd, cast[ptr SockAddr](addr(name)), + sizeof(name).Socklen) < 0'i32: raiseOSError(osLastError()) else: var aiList = getAddrInfo(address, port, AF_INET) - if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.TSocklen) < 0'i32: + if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32: dealloc(aiList) raiseOSError(osLastError()) dealloc(aiList) @@ -311,9 +313,9 @@ proc acceptAddr*(server: Socket, client: var Socket, address: var string, ## flag is specified then this error will not be raised and instead ## accept will be called again. assert(client != nil) - var sockAddress: TSockaddr_in - var addrLen = sizeof(sockAddress).TSocklen - var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), + var sockAddress: Sockaddr_in + var addrLen = sizeof(sockAddress).Socklen + var sock = accept(server.fd, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if sock == osInvalidSocket: @@ -452,7 +454,7 @@ proc connect*(socket: Socket, address: string, port = Port(0), var lastError: OSErrorCode var it = aiList while it != nil: - if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) == 0'i32: + if connect(socket.fd, it.ai_addr, it.ai_addrlen.SockLen) == 0'i32: success = true break else: lastError = osLastError() @@ -751,10 +753,10 @@ proc recvFrom*(socket: Socket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) - var sockAddress: TSockaddr_in - var addrLen = sizeof(sockAddress).TSocklen + var sockAddress: SockAddrIn + var addrLen = sizeof(sockAddress).SockLen result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, - cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) + cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if result != -1: data.setLen(result) @@ -831,7 +833,7 @@ proc sendTo*(socket: Socket, address: string, port: Port, data: pointer, var it = aiList while it != nil: result = sendto(socket.fd, data, size.cint, flags.cint, it.ai_addr, - it.ai_addrlen.TSocklen) + it.ai_addrlen.SockLen) if result != -1'i32: success = true break @@ -864,7 +866,7 @@ proc connectAsync(socket: Socket, name: string, port = Port(0), var lastError: OSErrorCode var it = aiList while it != nil: - var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSocklen) + var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.SockLen) if ret == 0'i32: success = true break @@ -907,7 +909,7 @@ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, proc isSSL*(socket: Socket): bool = return socket.isSSL ## Determines whether ``socket`` is a SSL socket. -proc getFD*(socket: Socket): TSocketHandle = return socket.fd +proc getFD*(socket: Socket): SocketHandle = return socket.fd ## Returns the socket's file descriptor type From 8446d51a6afa7f97bbef6aa345800c85e7c07a22 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 30 Aug 2014 12:57:04 +0100 Subject: [PATCH 047/409] Winlean and threads case sensitivity fixes. --- lib/system/channels.nim | 46 ++++++++++++++++++++--------------------- lib/system/syslocks.nim | 2 +- lib/system/threads.nim | 8 +++---- lib/windows/winlean.nim | 6 +++--- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/lib/system/channels.nim b/lib/system/channels.nim index 0715d05e5..b3ff61b88 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -13,9 +13,9 @@ ## ## **Note:** The current implementation of message passing is slow and does ## not work with cyclic data structures. - -when not declared(NimString): - {.error: "You must not import this module explicitly".} + +when not declared(NimString): + {.error: "You must not import this module explicitly".} type pbytes = ptr array[0.. 0xffff, byte] @@ -73,11 +73,11 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, d = cast[TAddress](dest) s = cast[TAddress](src) sysAssert(mt != nil, "mt == nil") - case mt.Kind + case mt.kind of tyString: if mode == mStore: - var x = cast[ppointer](dest) - var s2 = cast[ppointer](s)[] + var x = cast[PPointer](dest) + var s2 = cast[PPointer](s)[] if s2 == nil: x[] = nil else: @@ -86,17 +86,17 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, copyMem(ns, ss, ss.len+1 + GenericSeqSize) x[] = ns else: - var x = cast[ppointer](dest) - var s2 = cast[ppointer](s)[] + var x = cast[PPointer](dest) + var s2 = cast[PPointer](s)[] if s2 == nil: unsureAsgnRef(x, s2) else: unsureAsgnRef(x, copyString(cast[NimString](s2))) dealloc(t.region, s2) of tySequence: - var s2 = cast[ppointer](src)[] + var s2 = cast[PPointer](src)[] var seq = cast[PGenericSeq](s2) - var x = cast[ppointer](dest) + var x = cast[PPointer](dest) if s2 == nil: if mode == mStore: x[] = nil @@ -108,13 +108,13 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize) else: unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize)) - var dst = cast[taddress](cast[ppointer](dest)[]) + var dst = cast[TAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: storeAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% GenericSeqSize), - mt.Base, t, mode) + mt.base, t, mode) var dstseq = cast[PGenericSeq](dst) dstseq.len = seq.len dstseq.reserved = seq.len @@ -123,8 +123,8 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, # copy type field: var pint = cast[ptr PNimType](dest) # XXX use dynamic type here! - pint[] = mt - if mt.base != nil: + pint[] = mt + if mt.base != nil: storeAux(dest, src, mt.base, t, mode) storeAux(dest, src, mt.node, t, mode) of tyTuple: @@ -134,8 +134,8 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, storeAux(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base, t, mode) of tyRef: - var s = cast[ppointer](src)[] - var x = cast[ppointer](dest) + var s = cast[PPointer](src)[] + var x = cast[PPointer](dest) if s == nil: if mode == mStore: x[] = nil @@ -225,20 +225,20 @@ proc recv*[TMsg](c: var TChannel[TMsg]): TMsg = acquireSys(q.lock) llRecv(q, addr(result), cast[PNimType](getTypeInfo(result))) releaseSys(q.lock) - -proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvaliable: bool, - msg: TMsg] = - ## try to receives a message from the channel `c` if available. Otherwise - ## it returns ``(false, default(msg))``. + +proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvaliable: bool, + msg: TMsg] = + ## try to receives a message from the channel `c` if available. Otherwise + ## it returns ``(false, default(msg))``. var q = cast[PRawChannel](addr(c)) if q.mask != ChannelDeadMask: lockChannel(q): - llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg))) + llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg))) result.dataAvaliable = true proc peek*[TMsg](c: var TChannel[TMsg]): int = ## returns the current number of messages in the channel `c`. Returns -1 - ## if the channel has been closed. **Note**: This is dangerous to use + ## if the channel has been closed. **Note**: This is dangerous to use ## as it encourages races. It's much better to use ``tryRecv`` instead. var q = cast[PRawChannel](addr(c)) if q.mask != ChannelDeadMask: diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index cff873cf4..8b38f34f3 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -31,7 +31,7 @@ when defined(Windows): ## Tries to acquire the lock `L`. proc tryAcquireSys(L: var TSysLock): bool {.inline.} = - result = TryAcquireSysAux(L) != 0'i32 + result = tryAcquireSysAux(L) != 0'i32 proc acquireSys(L: var TSysLock) {.stdcall, noSideEffect, dynlib: "kernel32", importc: "EnterCriticalSection".} diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 9e945544f..6057b7749 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -190,7 +190,7 @@ var globalsSlot = threadVarAlloc() when emulatedThreadVars: proc GetThreadLocalVars(): pointer {.compilerRtl, inl.} = - result = addr(cast[PGcThread](ThreadVarGetValue(globalsSlot)).tls) + result = addr(cast[PGcThread](threadVarGetValue(globalsSlot)).tls) when useStackMaskHack: proc maskStackPointer(offset: int): pointer {.compilerRtl, inl.} = @@ -210,7 +210,7 @@ when not defined(useNimRtl): initGC() when emulatedThreadVars: - if NimThreadVarsSize() > sizeof(TThreadLocalStorage): + if nimThreadVarsSize() > sizeof(TThreadLocalStorage): echo "too large thread local storage size requested" quit 1 @@ -267,7 +267,7 @@ when not defined(boehmgc) and not hasSharedHeap: proc deallocOsPages() template threadProcWrapperBody(closure: expr) {.immediate.} = - when declared(globalsSlot): ThreadVarSetValue(globalsSlot, closure) + when declared(globalsSlot): threadVarSetValue(globalsSlot, closure) var t = cast[ptr TThread[TArg]](closure) when useStackMaskHack: var tls: TThreadLocalStorage @@ -364,7 +364,7 @@ proc threadId*[TArg](t: var TThread[TArg]): TThreadId[TArg] {.inline.} = proc myThreadId*[TArg](): TThreadId[TArg] = ## returns the thread ID of the thread that calls this proc. This is unsafe ## because the type ``TArg`` is not checked for consistency! - result = cast[TThreadId[TArg]](ThreadVarGetValue(globalsSlot)) + result = cast[TThreadId[TArg]](threadVarGetValue(globalsSlot)) when false: proc mainThreadId*[TArg](): TThreadId[TArg] = diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 18a565ffc..ecf80fcd8 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -199,14 +199,14 @@ else: importc: "GetCurrentDirectoryA", dynlib: "kernel32", stdcall.} proc setCurrentDirectoryA*(lpPathName: cstring): int32 {. importc: "SetCurrentDirectoryA", dynlib: "kernel32", stdcall.} - proc createDirectoryA*(pathName: cstring, security: Pointer=nil): int32 {. + proc createDirectoryA*(pathName: cstring, security: pointer=nil): int32 {. importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.} proc removeDirectoryA*(lpPathName: cstring): int32 {. importc: "RemoveDirectoryA", dynlib: "kernel32", stdcall.} proc setEnvironmentVariableA*(lpName, lpValue: cstring): int32 {. stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableA".} - proc getModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {. + proc getModuleFileNameA*(handle: THandle, buf: cstring, size: int32): int32 {. importc: "GetModuleFileNameA", dynlib: "kernel32", stdcall.} when useWinUnicode: @@ -304,7 +304,7 @@ else: dwFileAttributes: int32): WINBOOL {. stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".} - proc copyFileA*(lpExistingFileName, lpNewFileName: CString, + proc copyFileA*(lpExistingFileName, lpNewFileName: cstring, bFailIfExists: cint): cint {. importc: "CopyFileA", stdcall, dynlib: "kernel32".} From 4a7a47f294314203b66af19b5219ecbb272e3c0b Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 30 Aug 2014 12:57:26 +0100 Subject: [PATCH 048/409] Ftpclient backwards compatibility fixes. --- lib/pure/ftpclient.nim | 43 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim index eb62354d8..07c9b5662 100644 --- a/lib/pure/ftpclient.nim +++ b/lib/pure/ftpclient.nim @@ -120,12 +120,6 @@ proc ftpClient*(address: string, port = TPort(21), result.csock = socket() if result.csock == invalidSocket: raiseOSError(osLastError()) -proc getDSock[T](ftp: FtpBase[T]): TSocket = - return ftp.dsock - -proc getCSock[T](ftp: FtpBase[T]): TSocket = - return ftp.csock - template blockingOperation(sock: TSocket, body: stmt) {.immediate.} = body @@ -136,14 +130,17 @@ template blockingOperation(sock: asyncio.PAsyncSocket, body: stmt) {.immediate.} proc expectReply[T](ftp: FtpBase[T]): TaintedString = result = TaintedString"" - blockingOperation(ftp.getCSock()): - ftp.getCSock().readLine(result) + blockingOperation(ftp.csock): + when T is Socket: + ftp.csock.readLine(result) + else: + discard ftp.csock.readLine(result) proc send*[T](ftp: FtpBase[T], m: string): TaintedString = ## Send a message to the server, and wait for a primary reply. ## ``\c\L`` is added for you. - blockingOperation(ftp.getCSock()): - ftp.getCSock().send(m & "\c\L") + blockingOperation(ftp.csock): + ftp.csock.send(m & "\c\L") return ftp.expectReply() proc assertReply(received: TaintedString, expected: string) = @@ -275,17 +272,17 @@ proc connect*[T](ftp: FtpBase[T]) = if ftp.pass != "": assertReply ftp.send("PASS " & ftp.pass), "230" -proc pwd*(ftp: FtpClient): string = +proc pwd*[T](ftp: FtpBase[T]): string = ## Returns the current working directory. var wd = ftp.send("PWD") assertReply wd, "257" return wd.string.captureBetween('"') # " -proc cd*(ftp: FtpClient, dir: string) = +proc cd*[T](ftp: FtpBase[T], dir: string) = ## Changes the current directory on the remote FTP server to ``dir``. assertReply ftp.send("CWD " & dir.normalizePathSep), "250" -proc cdup*(ftp: FtpClient) = +proc cdup*[T](ftp: FtpBase[T]) = ## Changes the current directory to the parent of the current directory. assertReply ftp.send("CDUP"), "200" @@ -312,10 +309,10 @@ proc getLines[T](ftp: FtpBase[T], async: bool = false): bool = {.fatal: "Incorrect socket instantiation".} if not async: - var readSocks: seq[TSocket] = @[ftp.getCSock()] + var readSocks: seq[TSocket] = @[ftp.csock] # This is only needed here. Asyncio gets this socket... - blockingOperation(ftp.getCSock()): - if readSocks.select(1) != 0 and ftp.getCSock() in readSocks: + blockingOperation(ftp.csock): + if readSocks.select(1) != 0 and ftp.csock in readSocks: assertReply ftp.expectReply(), "226" return true @@ -357,7 +354,7 @@ proc existsFile*(ftp: FtpClient, file: string): bool = for f in items(files): if f.normalizePathSep == file.normalizePathSep: return true -proc createDir*(ftp: FtpClient, dir: string, recursive: bool = false) = +proc createDir*[T](ftp: FtpBase[T], dir: string, recursive: bool = false) = ## Creates a directory ``dir``. If ``recursive`` is true, the topmost ## subdirectory of ``dir`` will be created first, following the secondmost... ## etc. this allows you to give a full path as the ``dir`` without worrying @@ -374,7 +371,7 @@ proc createDir*(ftp: FtpClient, dir: string, recursive: bool = false) = previousDirs.add('/') assertReply reply, "257" -proc chmod*(ftp: FtpClient, path: string, +proc chmod*[T](ftp: FtpBase[T], path: string, permissions: set[TFilePermission]) = ## Changes permission of ``path`` to ``permissions``. var userOctal = 0 @@ -440,7 +437,7 @@ proc getFile[T](ftp: FtpBase[T], async = false): bool = bytesRead = ftp.dsock.recvAsync(r, BufferSize) returned = bytesRead != -1 else: - bytesRead = getDSock(ftp).recv(r, BufferSize) + bytesRead = ftp.dsock.recv(r, BufferSize) returned = true let r2 = r.string if r2 != "": @@ -451,9 +448,9 @@ proc getFile[T](ftp: FtpBase[T], async = false): bool = ftp.dsockConnected = false if not async: - var readSocks: seq[TSocket] = @[ftp.getCSock()] - blockingOperation(ftp.getCSock()): - if readSocks.select(1) != 0 and ftp.getCSock() in readSocks: + var readSocks: seq[TSocket] = @[ftp.csock] + blockingOperation(ftp.csock): + if readSocks.select(1) != 0 and ftp.csock in readSocks: assertReply ftp.expectReply(), "226" return true @@ -508,7 +505,7 @@ proc doUpload[T](ftp: FtpBase[T], async = false): bool = return false if not async: - getDSock(ftp).send(s) + ftp.dsock.send(s) else: let bytesSent = ftp.dsock.sendAsync(s) if bytesSent == 0: From fb4e54442bc9097acd8fbef5023694884aad3ea4 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 30 Aug 2014 12:57:42 +0100 Subject: [PATCH 049/409] Fixed issue with os module in non-unicode mode on Windows. --- lib/pure/os.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index c4b694406..8227c92b2 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -2013,7 +2013,10 @@ proc isHidden*(path: string): bool = ## On Unix-like systems, a file is hidden if it starts with a '.' (period) ## and is not *just* '.' or '..' ' ." when defined(Windows): - wrapUnary(attributes, getFileAttributesW, path) + when useWinUnicode: + wrapUnary(attributes, getFileAttributesW, path) + else: + var attributes = getFileAttributesA(path) if attributes != -1'i32: result = (attributes and FILE_ATTRIBUTE_HIDDEN) != 0'i32 else: From fb688d13605c51f35450f920420d67e884499f39 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 30 Aug 2014 16:28:34 +0200 Subject: [PATCH 050/409] fixed posix.nim --- lib/posix/posix.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 71a75471e..fb617f3c5 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -2382,7 +2382,8 @@ proc hstrerror*(herrnum: cint): cstring {.importc, header: "".} proc FD_CLR*(a1: cint, a2: var FdSet) {.importc, header: "".} proc FD_ISSET*(a1: cint | SocketHandle, a2: var FdSet): cint {. importc, header: "".} -proc fdSet*(a1: cint | SocketHandle, a2: var FdSet) {.importc, header: "".} +proc fdSet*(a1: cint | SocketHandle, a2: var FdSet) {. + importc: "FD_SET", header: "".} proc FD_ZERO*(a1: var FdSet) {.importc, header: "".} proc pselect*(a1: cint, a2, a3, a4: ptr FdSet, a5: ptr Ttimespec, From c40f981e647eef2fb558c462f1df10c61d250a97 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 30 Aug 2014 16:36:57 +0200 Subject: [PATCH 051/409] babel is now nimble --- compiler/options.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/options.nim b/compiler/options.nim index 723d912ca..11c8241ef 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -238,6 +238,9 @@ proc getPackageName*(path: string): string = #echo "from cache ", d, " |", packageCache[d], "|", path.splitFile.name return packageCache[d] inc parents + for file in walkFiles(d / "*.nimble"): + result = file.splitFile.name + break packageSearch for file in walkFiles(d / "*.babel"): result = file.splitFile.name break packageSearch From 1f85b3b5d3f8a9cf84fc5c03604ac3a7ea901d8c Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 30 Aug 2014 16:37:27 +0200 Subject: [PATCH 052/409] VM supports math and a few os procs --- compiler/nimblecmd.nim | 2 +- compiler/pretty.nim | 2 +- compiler/vm.nim | 14 ++++-- compiler/vmdef.nim | 13 +++++- compiler/vmgen.nim | 23 +++++++++- compiler/vmhooks.nim | 45 ++++++++++++++++++++ compiler/vmops.nim | 66 +++++++++++++++++++++++++++++ lib/{stdlib.babel => stdlib.nimble} | 2 +- 8 files changed, 157 insertions(+), 10 deletions(-) create mode 100644 compiler/vmhooks.nim create mode 100644 compiler/vmops.nim rename lib/{stdlib.babel => stdlib.nimble} (71%) diff --git a/compiler/nimblecmd.nim b/compiler/nimblecmd.nim index 0f73c17bd..049b94aa9 100644 --- a/compiler/nimblecmd.nim +++ b/compiler/nimblecmd.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -## Implements some helper procs for Babel (Nim's package manager) support. +## Implements some helper procs for Nimble (Nim's package manager) support. import parseutils, strutils, strtabs, os, options, msgs, lists diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 5f990a658..356399c1c 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -160,7 +160,7 @@ proc check(c: PGen, n: PNode) = check(c, a.sons[L-2]) check(c, a.sons[L-1]) of nkTypeSection, nkConstSection: - for i in countup(0, sonsLen(n) - 1): + for i in countup(0, sonsLen(n) - 1): let a = n.sons[i] if a.kind == nkCommentStmt: continue checkSonsLen(a, 3) diff --git a/compiler/vm.nim b/compiler/vm.nim index af0b30faa..fe2b9c617 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -133,6 +133,8 @@ proc createStrKeepNode(x: var TFullReg) = # cause of bugs like these is that the VM does not properly distinguish # between variable defintions (var foo = e) and variable updates (foo = e). +include vmhooks + template createStr(x) = x.node = newNode(nkStrLit) @@ -801,7 +803,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = let bb = regs[rb].node let isClosure = bb.kind == nkPar let prc = if not isClosure: bb.sym else: bb.sons[0].sym - if sfImportc in prc.flags: + if prc.offset < -1: + # it's a callback: + c.callbacks[-prc.offset-2].value( + VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs))) + elif sfImportc in prc.flags: if allowFFI notin c.features: globalError(c.debug[pc], errGenerated, "VM not allowed to do FFI") # we pass 'tos.slots' instead of 'regs' so that the compiler can keep @@ -832,9 +838,6 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = if isClosure: newFrame.slots[rc].kind = rkNode newFrame.slots[rc].node = regs[rb].node.sons[1] - # allocate the temporaries: - #for i in rc+ord(isClosure) .. = 0: + if s == nil or y[L].cmpIgnoreStyle(s.name.s) != 0: return false + s = s.owner + dec L + result = true + +proc procIsCallback(c: PCtx; s: PSym): bool = + if s.offset < -1: return true + var i = -2 + for key, value in items(c.callbacks): + if s.matches(key): + doAssert s.offset == -1 + s.offset = i + return true + dec i + proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = case n.kind of nkSym: @@ -1499,7 +1519,8 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = genRdVar(c, n, dest, flags) of skProc, skConverter, skMacro, skTemplate, skMethod, skIterators: # 'skTemplate' is only allowed for 'getAst' support: - if sfImportc in s.flags: c.importcSym(n.info, s) + if procIsCallback(c, s): discard + elif sfImportc in s.flags: c.importcSym(n.info, s) genLit(c, n, dest) of skConst: gen(c, s.ast, dest) diff --git a/compiler/vmhooks.nim b/compiler/vmhooks.nim new file mode 100644 index 000000000..cce87d433 --- /dev/null +++ b/compiler/vmhooks.nim @@ -0,0 +1,45 @@ +# +# +# The Nim Compiler +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +template setX(k, field) {.immediate, dirty.} = + var s: seq[TFullReg] + move(s, cast[seq[TFullReg]](a.slots)) + if s[a.ra].kind != k: + myreset(s[a.ra]) + s[a.ra].kind = k + s[a.ra].field = v + +proc setResult*(a: VmArgs; v: BiggestInt) = setX(rkInt, intVal) +proc setResult*(a: VmArgs; v: BiggestFloat) = setX(rkFloat, floatVal) +proc setResult*(a: VmArgs; v: bool) = + let v = v.ord + setX(rkInt, intVal) + +proc setResult*(a: VmArgs; v: string) = + var s: seq[TFullReg] + move(s, cast[seq[TFullReg]](a.slots)) + if s[a.ra].kind != rkNode: + myreset(s[a.ra]) + s[a.ra].kind = rkNode + s[a.ra].node = newNode(nkStrLit) + s[a.ra].node.strVal = v + +template getX(k, field) {.immediate, dirty.} = + doAssert i < a.rc-1 + let s = cast[seq[TFullReg]](a.slots) + doAssert s[i+a.rb+1].kind == k + result = s[i+a.rb+1].field + +proc getInt*(a: VmArgs; i: Natural): BiggestInt = getX(rkInt, intVal) +proc getFloat*(a: VmArgs; i: Natural): BiggestFloat = getX(rkFloat, floatVal) +proc getString*(a: VmArgs; i: Natural): string = + doAssert i < a.rc-1 + let s = cast[seq[TFullReg]](a.slots) + doAssert s[i+a.rb+1].kind == rkNode + result = s[i+a.rb+1].node.strVal diff --git a/compiler/vmops.nim b/compiler/vmops.nim new file mode 100644 index 000000000..8e75cc23a --- /dev/null +++ b/compiler/vmops.nim @@ -0,0 +1,66 @@ +# +# +# The Nim Compiler +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# Unforunately this cannot be a module yet: +#import vmdeps, vm +from math import sqrt, ln, log10, log2, exp, round, arccos, arcsin, + arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc, + floor, ceil, fmod + +from os import getEnv, existsEnv, dirExists, fileExists + +template mathop(op) {.immediate, dirty.} = + registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`) + +template osop(op) {.immediate, dirty.} = + registerCallback(c, "stdlib.os." & astToStr(op), `op Wrapper`) + +template wrap1f(op) {.immediate, dirty.} = + proc `op Wrapper`(a: VmArgs) {.nimcall.} = + setResult(a, op(getFloat(a, 0))) + mathop op + +template wrap2f(op) {.immediate, dirty.} = + proc `op Wrapper`(a: VmArgs) {.nimcall.} = + setResult(a, op(getFloat(a, 0), getFloat(a, 1))) + mathop op + +template wrap1s(op) {.immediate, dirty.} = + proc `op Wrapper`(a: VmArgs) {.nimcall.} = + setResult(a, op(getString(a, 0))) + osop op + +proc registerAdditionalOps*(c: PCtx) = + wrap1f(sqrt) + wrap1f(ln) + wrap1f(log10) + wrap1f(log2) + wrap1f(exp) + wrap1f(round) + wrap1f(arccos) + wrap1f(arcsin) + wrap1f(arctan) + wrap2f(arctan2) + wrap1f(cos) + wrap1f(cosh) + wrap2f(hypot) + wrap1f(sinh) + wrap1f(sin) + wrap1f(tan) + wrap1f(tanh) + wrap2f(pow) + wrap1f(trunc) + wrap1f(floor) + wrap1f(ceil) + wrap2f(fmod) + + wrap1s(getEnv) + wrap1s(existsEnv) + wrap1s(dirExists) + wrap1s(fileExists) diff --git a/lib/stdlib.babel b/lib/stdlib.nimble similarity index 71% rename from lib/stdlib.babel rename to lib/stdlib.nimble index f22598aba..0805ead54 100644 --- a/lib/stdlib.babel +++ b/lib/stdlib.nimble @@ -2,5 +2,5 @@ name = "stdlib" version = "0.9.0" author = "Dominik Picheta" -description = "Nimrod's standard library." +description = "Nim's standard library." license = "MIT" From f6dc76cfe3708ffb2010e9a6152f916337f0396f Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 30 Aug 2014 15:52:04 +0100 Subject: [PATCH 053/409] Case sensitivity fixes for Posix. --- lib/pure/asyncdispatch.nim | 40 +++++++++++++++++++------------------- lib/pure/net.nim | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 7b8ad582f..14b56d1ed 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -720,42 +720,42 @@ else: proc update(sock: TAsyncFD, events: set[TEvent]) = let p = getGlobalDispatcher() - assert sock.TSocketHandle in p.selector - discard p.selector.update(sock.TSocketHandle, events) + assert sock.SocketHandle in p.selector + discard p.selector.update(sock.SocketHandle, events) proc register(sock: TAsyncFD) = let p = getGlobalDispatcher() var data = PData(sock: sock, readCBs: @[], writeCBs: @[]) - p.selector.register(sock.TSocketHandle, {}, data.PObject) + p.selector.register(sock.SocketHandle, {}, data.PObject) proc newAsyncRawSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, protocol: TProtocol = IPPROTO_TCP): TAsyncFD = result = newRawSocket(domain, typ, protocol).TAsyncFD - result.TSocketHandle.setBlocking(false) + result.SocketHandle.setBlocking(false) register(result) proc closeSocket*(sock: TAsyncFD) = let disp = getGlobalDispatcher() - sock.TSocketHandle.close() - disp.selector.unregister(sock.TSocketHandle) + sock.SocketHandle.close() + disp.selector.unregister(sock.SocketHandle) proc unregister*(fd: TAsyncFD) = - getGlobalDispatcher().selector.unregister(fd.TSocketHandle) + getGlobalDispatcher().selector.unregister(fd.SocketHandle) proc addRead(sock: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() - if sock.TSocketHandle notin p.selector: + if sock.SocketHandle notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") - p.selector[sock.TSocketHandle].data.PData.readCBs.add(cb) - update(sock, p.selector[sock.TSocketHandle].events + {EvRead}) + p.selector[sock.SocketHandle].data.PData.readCBs.add(cb) + update(sock, p.selector[sock.SocketHandle].events + {EvRead}) proc addWrite(sock: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() - if sock.TSocketHandle notin p.selector: + if sock.SocketHandle notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") - p.selector[sock.TSocketHandle].data.PData.writeCBs.add(cb) - update(sock, p.selector[sock.TSocketHandle].events + {EvWrite}) + p.selector[sock.SocketHandle].data.PData.writeCBs.add(cb) + update(sock, p.selector[sock.SocketHandle].events + {EvWrite}) proc poll*(timeout = 500) = let p = getGlobalDispatcher() @@ -808,7 +808,7 @@ else: var lastError: TOSErrorCode var it = aiList while it != nil: - var ret = connect(socket.TSocketHandle, it.ai_addr, it.ai_addrlen.TSocklen) + var ret = connect(socket.SocketHandle, it.ai_addr, it.ai_addrlen.Socklen) if ret == 0: # Request to connect completed immediately. success = true @@ -837,7 +837,7 @@ else: proc cb(sock: TAsyncFD): bool = result = true - let res = recv(sock.TSocketHandle, addr readBuffer[0], size.cint, + let res = recv(sock.SocketHandle, addr readBuffer[0], size.cint, flags.toOSFlags()) #echo("recv cb res: ", res) if res < 0: @@ -870,7 +870,7 @@ else: result = true let netSize = data.len-written var d = data.cstring - let res = send(sock.TSocketHandle, addr d[written], netSize.cint, + let res = send(sock.SocketHandle, addr d[written], netSize.cint, MSG_NOSIGNAL) if res < 0: let lastError = osLastError() @@ -898,10 +898,10 @@ else: client: TAsyncFD]]("acceptAddr") proc cb(sock: TAsyncFD): bool = result = true - var sockAddress: Tsockaddr_in - var addrLen = sizeof(sockAddress).TSocklen - var client = accept(sock.TSocketHandle, - cast[ptr TSockAddr](addr(sockAddress)), addr(addrLen)) + var sockAddress: SockAddr_in + var addrLen = sizeof(sockAddress).Socklen + var client = accept(sock.SocketHandle, + cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) if client == osInvalidSocket: let lastError = osLastError() assert lastError.int32 notin {EWOULDBLOCK, EAGAIN} diff --git a/lib/pure/net.nim b/lib/pure/net.nim index b90e0f5d5..5b1f6e7a4 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -260,7 +260,7 @@ proc socketError*(socket: Socket, err: int = -1, async = false, else: if lastE.int32 == EAGAIN or lastE.int32 == EWOULDBLOCK: return - else: osError(lastE) + else: raiseOSError(lastE) else: raiseOSError(lastE) proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = From 29ec7955805b19245f74cde4eb2fe9830cfc78bd Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 30 Aug 2014 18:00:05 +0100 Subject: [PATCH 054/409] Fixes SSL case sensitive issues. --- lib/pure/net.nim | 60 ++++++++++++++++++++-------------------- lib/wrappers/openssl.nim | 16 +++++------ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 5b1f6e7a4..fd485340c 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -125,16 +125,16 @@ when defined(ssl): ErrLoadBioStrings() OpenSSL_add_all_algorithms() - proc SSLError(s = "") = + proc raiseSSLError(s = "") = if s != "": - raise newException(ESSL, s) + raise newException(SSLError, s) let err = ErrPeekLastError() if err == 0: - raise newException(ESSL, "No error reported.") + raise newException(SSLError, "No error reported.") if err == -1: - OSError(OSLastError()) + raiseOSError(osLastError()) var errStr = ErrErrorString(err, nil) - raise newException(ESSL, $errStr) + raise newException(SSLError, $errStr) # http://simplestcodings.blogspot.co.uk/2010/08/secure-server-client-using-openssl-in-c.html proc loadCertificates(ctx: PSSL_CTX, certFile, keyFile: string) = @@ -146,23 +146,23 @@ when defined(ssl): if certFile != "": var ret = SSLCTXUseCertificateChainFile(ctx, certFile) if ret != 1: - SSLError() + raiseSSLError() # TODO: Password? www.rtfm.com/openssl-examples/part1.pdf if keyFile != "": if SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) != 1: - SSLError() + raiseSSLError() if SSL_CTX_check_private_key(ctx) != 1: - SSLError("Verification of private key file failed.") + raiseSSLError("Verification of private key file failed.") - proc newContext*(protVersion = ProtSSLv23, verifyMode = CVerifyPeer, + proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer, certFile = "", keyFile = ""): PSSLContext = ## Creates an SSL context. ## ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are - ## are available with the addition of ``ProtSSLv23`` which allows for + ## are available with the addition of ``protSSLv23`` which allows for ## compatibility with all of them. ## ## There are currently only two options for verify mode; @@ -189,14 +189,14 @@ when defined(ssl): newCTX = SSL_CTX_new(TLSv1_method()) if newCTX.SSLCTXSetCipherList("ALL") != 1: - SSLError() + raiseSSLError() case verifyMode of CVerifyPeer: newCTX.SSLCTXSetVerify(SSLVerifyPeer, nil) of CVerifyNone: newCTX.SSLCTXSetVerify(SSLVerifyNone, nil) if newCTX == nil: - SSLError() + raiseSSLError() discard newCTX.SSLCTXSetMode(SSL_MODE_AUTO_RETRY) newCTX.loadCertificates(certFile, keyFile) @@ -215,10 +215,10 @@ when defined(ssl): socket.sslNoHandshake = false socket.sslHasPeekChar = false if socket.sslHandle == nil: - SSLError() + raiseSSLError() if SSLSetFd(socket.sslHandle, socket.fd) != 1: - SSLError() + raiseSSLError() proc socketError*(socket: Socket, err: int = -1, async = false, lastError = (-1).OSErrorCode) = @@ -235,20 +235,20 @@ proc socketError*(socket: Socket, err: int = -1, async = false, var ret = SSLGetError(socket.sslHandle, err.cint) case ret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: if async: return - else: SSLError("Not enough data on socket.") + else: raiseSSLError("Not enough data on socket.") of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: if async: return - else: SSLError("Not enough data on socket.") + else: raiseSSLError("Not enough data on socket.") of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSSLError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() - else: SSLError("Unknown Error") + raiseSSLError() + else: raiseSSLError("Unknown Error") if err == -1 and not (when defined(ssl): socket.isSSL else: false): let lastE = if lastError.int == -1: osLastError() else: lastError @@ -371,17 +371,17 @@ when false: #defined(ssl): if err != SSL_ERROR_WANT_ACCEPT: case err of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: client.sslNoHandshake = true return AcceptNoHandshake of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSSLError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSSLError() else: - SSLError("Unknown error") + raiseSSLError("Unknown error") client.sslNoHandshake = false if client.isSSL and client.sslNoHandshake: @@ -485,19 +485,19 @@ when defined(ssl): var errret = SSLGetError(socket.sslHandle, ret) case errret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE: return false of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSSLError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSSLError() else: - SSLError("Unknown Error") + raiseSSLError("Unknown Error") socket.sslNoHandshake = false else: - SSLError("Socket is not an SSL socket.") + raiseSSLError("Socket is not an SSL socket.") proc gotHandshake*(socket: PSocket): bool = ## Determines whether a handshake has occurred between a client (``socket``) @@ -507,7 +507,7 @@ when defined(ssl): if socket.isSSL: return not socket.sslNoHandshake else: - SSLError("Socket is not an SSL socket.") + raiseSSLError("Socket is not an SSL socket.") proc hasDataBuffered*(s: Socket): bool = ## Determines whether a socket has data buffered. diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 4dc71bffd..da684eed9 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -246,7 +246,7 @@ proc BIO_get_ssl*(bio: PBIO, ssl: ptr PSSL): int = proc BIO_set_conn_hostname*(bio: PBIO, name: cstring): int = return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, name) proc BIO_do_handshake*(bio: PBIO): int = - return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NIL) + return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, nil) proc BIO_do_connect*(bio: PBIO): int = return BIO_do_handshake(bio) @@ -448,11 +448,11 @@ type {.pragma: ic, importc: "$1".} {.push callconv:cdecl, dynlib:DLLUtilName.} -proc MD5_Init*(c: var MD5_CTX): cint{.ic.} -proc MD5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.ic.} -proc MD5_Final*(md: cstring; c: var MD5_CTX): cint{.ic.} -proc MD5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.ic.} -proc MD5_Transform*(c: var MD5_CTX; b: ptr cuchar){.ic.} +proc md5_Init*(c: var MD5_CTX): cint{.ic.} +proc md5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.ic.} +proc md5_Final*(md: cstring; c: var MD5_CTX): cint{.ic.} +proc md5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.ic.} +proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.ic.} {.pop.} from strutils import toHex,toLower @@ -463,7 +463,7 @@ proc hexStr (buf:cstring): string = for i in 0 .. <16: result.add toHex(buf[i].ord, 2).toLower -proc MD5_File* (file: string): string {.raises:[EIO,Ebase].} = +proc md5_File* (file: string): string {.raises:[EIO,Ebase].} = ## Generate MD5 hash for a file. Result is a 32 character # hex string with lowercase characters (like the output # of `md5sum` @@ -483,7 +483,7 @@ proc MD5_File* (file: string): string {.raises:[EIO,Ebase].} = result = hexStr(buf) -proc MD5_Str* (str:string): string {.raises:[EIO].} = +proc md5_Str* (str:string): string {.raises:[EIO].} = ##Generate MD5 hash for a string. Result is a 32 character #hex string with lowercase characters var From 0257f389fef6492906e47761f7e366921113bba6 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 30 Aug 2014 20:16:35 +0200 Subject: [PATCH 055/409] fixes #1366 --- compiler/semmagic.nim | 2 +- tests/generics/tgeneric0.nim | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 7b612c806..a72a6ab7d 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -126,7 +126,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, result.typ = getSysType(tyString) of mInstantiationInfo: result = semInstantiationInfo(c, n) of mOrd: result = semOrd(c, n) - of mHigh: result = semLowHigh(c, n, mHigh) + of mHigh, mLow: result = semLowHigh(c, n, n[0].sym.magic) of mShallowCopy: result = semShallowCopy(c, n, flags) of mNBindSym: result = semBindSym(c, n) of mLocals: result = semLocals(c, n) diff --git a/tests/generics/tgeneric0.nim b/tests/generics/tgeneric0.nim index 9292b729f..45450ccca 100644 --- a/tests/generics/tgeneric0.nim +++ b/tests/generics/tgeneric0.nim @@ -1,9 +1,9 @@ import tables type - TX = TTable[string, int] + TX = Table[string, int] -proc foo(models: seq[TTable[string, float]]): seq[float] = +proc foo(models: seq[Table[string, float]]): seq[float] = result = @[] for model in models.items: result.add model["foobar"] @@ -16,4 +16,12 @@ proc foo[T](p: TType[T, range[0..1]]) = proc foo[T](p: TType[T, range[0..2]]) = echo "bar" +#bug #1366 + +proc reversed(x) = + for i in countdown(x.low, x.high): + echo i + +reversed(@[-19, 7, -4, 6]) + From c9563d28a8ef3ef74826d4c211cac13301963dd5 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 30 Aug 2014 22:44:33 +0200 Subject: [PATCH 056/409] fixes #1067 --- compiler/ccgstmts.nim | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 66bfbba8c..efa8b0adc 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -37,6 +37,15 @@ proc genVarTuple(p: BProc, n: PNode) = var tup, field: TLoc if n.kind != nkVarTuple: internalError(n.info, "genVarTuple") var L = sonsLen(n) + + # if we have a something that's been captured, use the lowering instead: + var useLowering = false + for i in countup(0, L-3): + if n[i].kind != nkSym: + useLowering = true; break + if useLowering: + genStmts(p, lowerTupleUnpacking(n, p.prc)) + return genLineDir(p, n) initLocExpr(p, n.sons[L-1], tup) var t = tup.t From 09ab1703e1bccfafe25460e1e7b9f332823bd4e9 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 01:07:58 +0200 Subject: [PATCH 057/409] fixes #1444 --- compiler/semgnrc.nim | 20 +++++++++++++------- lib/pure/collections/sets.nim | 2 +- lib/system.nim | 4 ++-- lib/system/embedded.nim | 4 ++-- tests/generics/mdotlookup.nim | 8 ++++++++ tests/generics/tdotlookup.nim | 5 ++++- 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index aa811e08c..2579c1d57 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -36,10 +36,11 @@ proc semGenericStmtScope(c: PContext, n: PNode, template macroToExpand(s: expr): expr = s.kind in {skMacro, skTemplate} and (s.typ.len == 1 or sfImmediate in s.flags) -proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = +proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, + ctx: var IntSet): PNode = incl(s.flags, sfUsed) case s.kind - of skUnknown: + of skUnknown: # Introduced in this pass! Leave it as an identifier. result = n of skProc, skMethod, skIterators, skConverter: @@ -48,11 +49,13 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = if macroToExpand(s): let n = fixImmediateParams(n) result = semTemplateExpr(c, n, s, {efNoSemCheck}) + result = semGenericStmt(c, result, {}, ctx) else: result = symChoice(c, n, s, scOpen) - of skMacro: + of skMacro: if macroToExpand(s): result = semMacroExpr(c, n, n, s, {efNoSemCheck}) + result = semGenericStmt(c, result, {}, ctx) else: result = symChoice(c, n, s, scOpen) of skGenericParam: @@ -80,7 +83,7 @@ proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags, elif s.name.id in ctx: result = symChoice(c, n, s, scForceOpen) else: - result = semGenericStmtSymbol(c, n, s) + result = semGenericStmtSymbol(c, n, s, ctx) # else: leave as nkIdent proc newDot(n, b: PNode): PNode = @@ -95,8 +98,9 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, var s = qualifiedLookUp(c, n, luf) if s != nil: - result = semGenericStmtSymbol(c, n, s) + result = semGenericStmtSymbol(c, n, s, ctx) else: + n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx) result = n let n = n[1] let ident = considerQuotedIdent(n) @@ -107,7 +111,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, elif s.name.id in ctx: result = newDot(result, symChoice(c, n, s, scForceOpen)) else: - let sym = semGenericStmtSymbol(c, n, s) + let sym = semGenericStmtSymbol(c, n, s, ctx) if sym.kind == nkSym: result = newDot(result, symChoice(c, n, s, scForceOpen)) else: @@ -158,13 +162,15 @@ proc semGenericStmt(c: PContext, n: PNode, of skMacro: if macroToExpand(s): result = semMacroExpr(c, n, n, s, {efNoSemCheck}) + result = semGenericStmt(c, result, {}, ctx) else: n.sons[0] = symChoice(c, n.sons[0], s, scOption) result = n - of skTemplate: + of skTemplate: if macroToExpand(s): let n = fixImmediateParams(n) result = semTemplateExpr(c, n, s, {efNoSemCheck}) + result = semGenericStmt(c, result, {}, ctx) else: n.sons[0] = symChoice(c, n.sons[0], s, scOption) result = n diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 4a5471417..92ef3152d 100644 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -130,7 +130,7 @@ proc mget*[A](s: var HashSet[A], key: A): var A = ## for sharing. assert s.isValid, "The set needs to be initialized." var index = rawGet(s, key) - if index >= 0: result = t.data[index].key + if index >= 0: result = s.data[index].key else: raise newException(KeyError, "key not found: " & $key) proc contains*[A](s: HashSet[A], key: A): bool = diff --git a/lib/system.nim b/lib/system.nim index 082b3ad40..2ad5e6af9 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -874,13 +874,13 @@ proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = ## assert((1..3).contains(4) == false) result = s.a <= value and value <= s.b -template `in` * (x, y: expr): expr {.immediate.} = contains(y, x) +template `in` * (x, y: expr): expr {.immediate, dirty.} = contains(y, x) ## Sugar for contains ## ## .. code-block:: Nim ## assert(1 in (1..3) == true) ## assert(5 in (1..3) == false) -template `notin` * (x, y: expr): expr {.immediate.} = not contains(y, x) +template `notin` * (x, y: expr): expr {.immediate, dirty.} = not contains(y, x) ## Sugar for not containing ## ## .. code-block:: Nim diff --git a/lib/system/embedded.nim b/lib/system/embedded.nim index c6db9bca4..9bb25b8dd 100644 --- a/lib/system/embedded.nim +++ b/lib/system/embedded.nim @@ -21,7 +21,7 @@ proc popFrame {.compilerRtl, inl.} = discard proc setFrame(s: PFrame) {.compilerRtl, inl.} = discard proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} = discard proc popSafePoint {.compilerRtl, inl.} = discard -proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} = discard +proc pushCurrentException(e: ref Exception) {.compilerRtl, inl.} = discard proc popCurrentException {.compilerRtl, inl.} = discard # some platforms have native support for stack traces: @@ -32,7 +32,7 @@ const proc quitOrDebug() {.inline.} = quit(1) -proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} = +proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = sysFatal(ENoExceptionToReraise, "exception handling is not available") proc reraiseException() {.compilerRtl.} = diff --git a/tests/generics/mdotlookup.nim b/tests/generics/mdotlookup.nim index 7a5e0ccbf..0c4d0c87c 100644 --- a/tests/generics/mdotlookup.nim +++ b/tests/generics/mdotlookup.nim @@ -6,3 +6,11 @@ type MyObj = object proc foo*(b: any) = var o: MyObj echo b.baz, " ", o.x.baz, " ", b.baz() + +import sets + +var intset = initSet[int]() + +proc func*[T](a: T) = + if a in intset: echo("true") + else: echo("false") diff --git a/tests/generics/tdotlookup.nim b/tests/generics/tdotlookup.nim index b886cd8c9..d3deca7fc 100644 --- a/tests/generics/tdotlookup.nim +++ b/tests/generics/tdotlookup.nim @@ -1,7 +1,10 @@ discard """ - output: '''5 5 5''' + output: '''5 5 5 +false''' """ import mdotlookup foo(7) +# bug #1444 +func(4) From 31db3aeadefb73831b4fa27b1a1118acd5aa6134 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 02:45:32 +0200 Subject: [PATCH 058/409] minor bugfix for void .compileTime procs --- compiler/semexprs.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index e2d05e15d..a397993d8 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -662,7 +662,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = # optimization pass: not necessary for correctness of the semantic pass if {sfNoSideEffect, sfCompileTime} * callee.flags != {} and - {sfForward, sfImportc} * callee.flags == {}: + {sfForward, sfImportc} * callee.flags == {} and n.typ != nil: if sfCompileTime notin callee.flags and optImplicitStatic notin gOptions: return From 8925d0e10335c8ae7671b7fb19f25a6f0a1802d3 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 02:46:13 +0200 Subject: [PATCH 059/409] minor improvement for nim pretty --- compiler/msgs.nim | 7 ++++--- compiler/pretty.nim | 4 ++-- lib/system.nim | 1 + todo.txt | 6 ++++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 58e12bfed..622c64359 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -124,7 +124,7 @@ type hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded, hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled, hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath, - hintConditionAlwaysTrue, hintPattern, + hintConditionAlwaysTrue, hintName, hintPattern, hintUser const @@ -405,6 +405,7 @@ const hintConf: "used config file \'$1\' [Conf]", hintPath: "added path: '$1' [Path]", hintConditionAlwaysTrue: "condition is always true: '$1' [CondTrue]", + hintName: "name should be: '$1' [Name]", hintPattern: "$1 [Pattern]", hintUser: "$1 [User]"] @@ -420,10 +421,10 @@ const "ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit", "GcMem", "User"] - HintsToStr*: array[0..15, string] = ["Success", "SuccessX", "LineTooLong", + HintsToStr*: array[0..16, string] = ["Success", "SuccessX", "LineTooLong", "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", "ExprAlwaysX", "QuitCalled", "Processing", "CodeBegin", "CodeEnd", "Conf", - "Path", "CondTrue", "Pattern", + "Path", "CondTrue", "Name", "Pattern", "User"] const diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 356399c1c..321c19502 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -90,10 +90,10 @@ proc beautifyName(s: string, k: TSymKind): string = result.add s[i] inc i -proc checkStyle*(info: TLineInfo, s: string, k: TSymKind) = +proc checkStyle(info: TLineInfo, s: string, k: TSymKind) = let beau = beautifyName(s, k) if s != beau: - message(info, errGenerated, "name should be: " & beau) + message(info, hintName, beau) proc checkDef*(n: PNode; s: PSym) = # operators stay as they are: diff --git a/lib/system.nim b/lib/system.nim index 2ad5e6af9..0c483f4a9 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -192,6 +192,7 @@ proc high*[T](x: T): T {.magic: "High", noSideEffect.} ## returns the highest possible index of an array, a sequence, a string or ## the highest possible value of an ordinal value `x`. As a special ## semantic rule, `x` may also be a type identifier. + ## ``high(int)`` is Nim's way of writing `INT_MAX`:idx: or `MAX_INT`:idx:. proc low*[T](x: T): T {.magic: "Low", noSideEffect.} ## returns the lowest possible index of an array, a sequence, a string or diff --git a/todo.txt b/todo.txt index fef88efc2..319704925 100644 --- a/todo.txt +++ b/todo.txt @@ -1,3 +1,9 @@ +version 0.10 +============ + +- Test nim pretty on various babel packages + + version 0.9.6 ============= From 8aca51a88d3db5a4faef21f77ea6010178e3469a Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 11:40:09 +0200 Subject: [PATCH 060/409] nim pretty: default is now to overwrite files --- compiler/pretty.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 321c19502..dfc164208 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -23,7 +23,7 @@ var gCheckExtern: bool proc overwriteFiles*() = - let overWrite = options.getConfigVar("pretty.overwrite").normalize == "on" + let overWrite = options.getConfigVar("pretty.overwrite").normalize != "off" let doStrip = options.getConfigVar("pretty.strip").normalize == "on" for i in 0 .. high(gSourceFiles): if not gSourceFiles[i].dirty: continue From 2d1b9d1f9dcd32611a706345277de5a98c4b15cf Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 11:40:25 +0200 Subject: [PATCH 061/409] ENDB compiles again --- lib/system/debugger.nim | 54 ++++++++++++++++++++--------------------- lib/system/endb.nim | 20 +++++++-------- lib/system/excpt.nim | 2 +- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim index 37a7c89f6..7b5169344 100644 --- a/lib/system/debugger.nim +++ b/lib/system/debugger.nim @@ -157,8 +157,8 @@ type oldValue: THash var - Watchpoints: array [0..99, TWatchpoint] - WatchpointsLen: int + watchpoints: array [0..99, TWatchpoint] + watchpointsLen: int proc `!&`(h: THash, val: int): THash {.inline.} = result = h +% val @@ -189,7 +189,7 @@ proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool, h: THash): THash proc genericHashAux(dest: pointer, n: ptr TNimNode, shallow: bool, h: THash): THash = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case n.kind of nkSlot: result = genericHashAux(cast[pointer](d +% n.offset), n.typ, shallow, h) @@ -206,9 +206,9 @@ proc genericHashAux(dest: pointer, n: ptr TNimNode, shallow: bool, proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool, h: THash): THash = sysAssert(mt != nil, "genericHashAux 2") - case mt.Kind + case mt.kind of tyString: - var x = cast[ppointer](dest)[] + var x = cast[PPointer](dest)[] result = h if x != nil: let s = cast[NimString](x) @@ -217,29 +217,29 @@ proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool, else: result = result !& hash(x, s.len) of tySequence: - var x = cast[ppointer](dest) - var dst = cast[taddress](cast[ppointer](dest)[]) + var x = cast[PPointer](dest) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) result = h if dst != 0: when defined(trackGcHeaders): - result = result !& hashGcHeader(cast[ppointer](dest)[]) + result = result !& hashGcHeader(cast[PPointer](dest)[]) else: - for i in 0..cast[pgenericseq](dst).len-1: + for i in 0..cast[PGenericSeq](dst).len-1: result = result !& genericHashAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - mt.Base, shallow, result) + mt.base, shallow, result) of tyObject, tyTuple: # we don't need to copy m_type field for tyObject, as they are equal anyway result = genericHashAux(dest, mt.node, shallow, h) of tyArray, tyArrayConstr: - let d = cast[TAddress](dest) + let d = cast[ByteAddress](dest) result = h for i in 0..(mt.size div mt.base.size)-1: result = result !& genericHashAux(cast[pointer](d +% i*% mt.base.size), mt.base, shallow, result) of tyRef: when defined(trackGcHeaders): - var s = cast[ppointer](dest)[] + var s = cast[PPointer](dest)[] if s != nil: result = result !& hashGcHeader(s) else: @@ -247,7 +247,7 @@ proc genericHashAux(dest: pointer, mt: PNimType, shallow: bool, result = h !& hash(dest, mt.size) else: result = h - var s = cast[ppointer](dest)[] + var s = cast[PPointer](dest)[] if s != nil: result = result !& genericHashAux(s, mt.base, shallow, result) else: @@ -258,23 +258,23 @@ proc genericHash(dest: pointer, mt: PNimType): int = proc dbgRegisterWatchpoint(address: pointer, name: cstring, typ: PNimType) {.compilerproc.} = - let L = WatchpointsLen + let L = watchPointsLen for i in 0.. = watchPoints.high: #debugOut("[Warning] cannot register watchpoint") return - Watchpoints[L].name = name - Watchpoints[L].address = address - Watchpoints[L].typ = typ - Watchpoints[L].oldValue = genericHash(address, typ) - inc WatchpointsLen + watchPoints[L].name = name + watchPoints[L].address = address + watchPoints[L].typ = typ + watchPoints[L].oldValue = genericHash(address, typ) + inc watchPointsLen proc dbgUnregisterWatchpoints*() = - WatchpointsLen = 0 + watchPointsLen = 0 var dbgLineHook*: proc () {.nimcall.} @@ -285,12 +285,12 @@ var dbgWatchpointHook*: proc (watchpointName: cstring) {.nimcall.} proc checkWatchpoints = - let L = WatchpointsLen + let L = watchPointsLen for i in 0.. 0: break @@ -355,7 +355,7 @@ proc dbgWriteStackTrace(f: PFrame) proc commandPrompt() = # if we return from this routine, user code executes again var - again = True + again = true dbgFramePtr = framePtr # for going down and up the stack dbgDown = 0 # how often we did go down dbgTemp: TStaticStr @@ -390,7 +390,7 @@ proc commandPrompt() = dbgHelp() elif ?"q" or ?"quit": dbgState = dbQuiting - dbgAborting = True + dbgAborting = true again = false quit(1) # BUGFIX: quit with error code > 0 elif ?"e" or ?"eval": @@ -402,9 +402,9 @@ proc commandPrompt() = elif ?"w" or ?"where": dbgShowExecutionPoint() elif ?"l" or ?"locals": - ListLocals(stdout, dbgFramePtr) + listLocals(stdout, dbgFramePtr) elif ?"g" or ?"globals": - ListGlobals(stdout) + listGlobals(stdout) elif ?"u" or ?"up": if dbgDown <= 0: debugOut("[Warning] cannot go up any further ") diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index c7e6803d2..c0e99a5e2 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -326,7 +326,7 @@ when not defined(noSignalHandler): template asgn(y: expr) = msg = y processSignal(sig, asgn) showErrorMessage(msg) - when defined(endb): dbgAborting = True + when defined(endb): dbgAborting = true quit(1) # always quit when SIGABRT proc registerSignalHandler() = From dd830d2e7d745b7d2d2697d4fa8d64d90a0097e5 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 11:42:31 +0200 Subject: [PATCH 062/409] added ENDB warning --- doc/endb.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/endb.txt b/doc/endb.txt index 09b22c820..049f9d40d 100644 --- a/doc/endb.txt +++ b/doc/endb.txt @@ -7,6 +7,8 @@ .. contents:: +**WARNING**: ENDB is not maintained anymore! Please help if you're interested +in this tool. Nim comes with a platform independent debugger - the Embedded Nim Debugger (ENDB). The debugger is From ae548a696f7177621fd395182760e86e96849e93 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 12:34:35 +0200 Subject: [PATCH 063/409] made some tests green --- doc/tools.txt | 4 ++-- lib/pure/scgi.nim | 14 +++++++------- lib/pure/unittest.nim | 26 +++++++++++++------------- tests/borrow/tborrow.nim | 2 +- tests/range/tsubrange2.nim | 2 +- tests/range/tsubrange3.nim | 3 +-- tests/table/ttables.nim | 2 +- tests/template/tissue993.nim | 4 ++-- 8 files changed, 28 insertions(+), 29 deletions(-) diff --git a/doc/tools.txt b/doc/tools.txt index 7a91ca6d0..0b39762c6 100644 --- a/doc/tools.txt +++ b/doc/tools.txt @@ -1,6 +1,6 @@ -=========================== +======================== Tools available with Nim -=========================== +======================== The standard distribution ships with the following tools: diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim index fa8605a69..5414c4737 100644 --- a/lib/pure/scgi.nim +++ b/lib/pure/scgi.nim @@ -90,7 +90,7 @@ type disp: Dispatcher AsyncScgiState* = ref AsyncScgiStateObj -{.deprected: [EScgi: ScgiError, TScgiState: ScgiState, +{.deprecated: [EScgi: ScgiError, TScgiState: ScgiState, PAsyncScgiState: AsyncScgiState, scgiError: raiseScgiError].} proc recvBuffer(s: var ScgiState, L: int) = @@ -108,12 +108,12 @@ proc open*(s: var ScgiState, port = Port(4000), address = "127.0.0.1", s.input = newString(s.buflen) # will be reused s.server = socket() - if s.server == InvalidSocket: raiseOSError(osLastError()) + if s.server == invalidSocket: raiseOSError(osLastError()) new(s.client) # Initialise s.client for `next` - if s.server == InvalidSocket: raiseScgiError("could not open socket") + if s.server == invalidSocket: raiseScgiError("could not open socket") #s.server.connect(connectionName, port) if reuseAddr: - s.server.setSockOpt(OptReuseAddr, True) + s.server.setSockOpt(OptReuseAddr, true) bindAddr(s.server, port, address) listen(s.server) @@ -135,7 +135,7 @@ proc next*(s: var ScgiState, timeout: int = -1): bool = if d == '\0': s.client.close() return false - if d notin strutils.digits: + if d notin strutils.Digits: if d != ':': raiseScgiError("':' after length expected") break L = L * 10 + ord(d) - ord('0') @@ -144,7 +144,7 @@ proc next*(s: var ScgiState, timeout: int = -1): bool = if s.headers["SCGI"] != "1": raiseScgiError("SCGI Version 1 expected") L = parseInt(s.headers["CONTENT_LENGTH"]) recvBuffer(s, L) - return True + return true proc writeStatusOkTextContent*(c: Socket, contentType = "text/html") = ## sends the following string to the socket `c`:: @@ -206,7 +206,7 @@ proc handleClientRead(client: AsyncClient, s: AsyncScgiState) = return if ret == -1: return # No more data available - if d[0] notin strutils.digits: + if d[0] notin strutils.Digits: if d[0] != ':': raiseScgiError("':' after length expected") break client.dataLen = client.dataLen * 10 + ord(d[0]) - ord('0') diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index bbd074390..fa2e30ef4 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -40,8 +40,8 @@ var checkpoints = @[] -template TestSetupIMPL*: stmt {.immediate, dirty.} = discard -template TestTeardownIMPL*: stmt {.immediate, dirty.} = discard +template testSetupIMPL*: stmt {.immediate, dirty.} = discard +template testTeardownIMPL*: stmt {.immediate, dirty.} = discard proc shouldRun(testName: string): bool = result = true @@ -49,10 +49,10 @@ proc shouldRun(testName: string): bool = template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} = block: template setup*(setupBody: stmt): stmt {.immediate, dirty.} = - template TestSetupIMPL: stmt {.immediate, dirty.} = setupBody + template testSetupIMPL: stmt {.immediate, dirty.} = setupBody template teardown*(teardownBody: stmt): stmt {.immediate, dirty.} = - template TestTeardownIMPL: stmt {.immediate, dirty.} = teardownBody + template testTeardownIMPL: stmt {.immediate, dirty.} = teardownBody body @@ -60,10 +60,10 @@ proc testDone(name: string, s: TestStatus) = if s == FAILED: programResult += 1 - if OutputLevel != PRINT_NONE and (OutputLevel == PRINT_ALL or s == FAILED): + if outputLevel != PRINT_NONE and (outputLevel == PRINT_ALL or s == FAILED): template rawPrint() = echo("[", $s, "] ", name, "\n") when not defined(ECMAScript): - if ColorOutput and not defined(ECMAScript): + if colorOutput and not defined(ECMAScript): var color = (if s == OK: fgGreen else: fgRed) styledEcho styleBright, color, "[", $s, "] ", fgWhite, name, "\n" else: @@ -76,10 +76,10 @@ template test*(name: expr, body: stmt): stmt {.immediate, dirty.} = if shouldRun(name): checkpoints = @[] - var TestStatusIMPL {.inject.} = OK + var testStatusIMPL {.inject.} = OK try: - TestSetupIMPL() + testSetupIMPL() body except: @@ -87,8 +87,8 @@ template test*(name: expr, body: stmt): stmt {.immediate, dirty.} = fail() finally: - TestTeardownIMPL() - testDone name, TestStatusIMPL + testTeardownIMPL() + testDone name, testStatusIMPL proc checkpoint*(msg: string) = checkpoints.add(msg) @@ -100,10 +100,10 @@ template fail* = echo msg when not defined(ECMAScript): - if AbortOnError: quit(1) + if abortOnError: quit(1) - when declared(TestStatusIMPL): - TestStatusIMPL = FAILED + when declared(testStatusIMPL): + testStatusIMPL = FAILED else: programResult += 1 diff --git a/tests/borrow/tborrow.nim b/tests/borrow/tborrow.nim index 8e6aeba74..d4df5f524 100644 --- a/tests/borrow/tborrow.nim +++ b/tests/borrow/tborrow.nim @@ -18,4 +18,4 @@ proc `++`(x, y: DF): DF {.borrow.} proc `$`(x: DI): string {.borrow.} proc `$`(x: DF): string {.borrow.} -echo 4544.DI ++ 343.di, " ", (4.5.df ++ 0.5.df).float == 5.0 +echo 4544.DI ++ 343.DI, " ", (4.5.DF ++ 0.5.DF).float == 5.0 diff --git a/tests/range/tsubrange2.nim b/tests/range/tsubrange2.nim index d14111bb9..759d16b9c 100644 --- a/tests/range/tsubrange2.nim +++ b/tests/range/tsubrange2.nim @@ -1,6 +1,6 @@ discard """ file: "tsubrange2.nim" - outputsub: "value out of range: 50 [EOutOfRange]" + outputsub: "value out of range: 50 [RangeError]" exitcode: "1" """ diff --git a/tests/range/tsubrange3.nim b/tests/range/tsubrange3.nim index 9afb5018b..600161cfd 100644 --- a/tests/range/tsubrange3.nim +++ b/tests/range/tsubrange3.nim @@ -1,6 +1,6 @@ discard """ file: "tsubrange.nim" - outputsub: "value out of range: 50 [EOutOfRange]" + outputsub: "value out of range: 50 [RangeError]" exitcode: "1" """ @@ -16,4 +16,3 @@ var r = y #p y - diff --git a/tests/table/ttables.nim b/tests/table/ttables.nim index 60446b5a3..de4aaed5e 100644 --- a/tests/table/ttables.nim +++ b/tests/table/ttables.nim @@ -84,7 +84,7 @@ block orderedTableTest1: block countTableTest1: var s = data.toTable var t = initCountTable[string]() - for k in s.Keys: t.inc(k) + for k in s.keys: t.inc(k) for k in t.keys: assert t[k] == 1 t.inc("90", 3) t.inc("12", 2) diff --git a/tests/template/tissue993.nim b/tests/template/tissue993.nim index d39f43942..dae9df683 100644 --- a/tests/template/tissue993.nim +++ b/tests/template/tissue993.nim @@ -1,5 +1,5 @@ -type pnode* = ref object of tobject +type PNode* = ref object of RootObj template litNode (name, ty): stmt = type name* = ref object of PNode @@ -8,7 +8,7 @@ litNode PIntNode, int import json -template withKey*(j: PJsonNode; key: string; varname: expr; +template withKey*(j: JsonNode; key: string; varname: expr; body:stmt): stmt {.immediate.} = if j.hasKey(key): let varname{.inject.}= j[key] From 697789a3134b7923edd3fe1bd14faa23da6be35c Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 12:38:26 +0200 Subject: [PATCH 064/409] prettified some async modules --- lib/pure/asyncio.nim | 160 +++++++++++++-------------- lib/pure/scgi.nim | 6 +- tests/bind/tnicerrorforsymchoice.nim | 2 +- 3 files changed, 84 insertions(+), 84 deletions(-) diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 90f1d0b2c..9299b7370 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -102,13 +102,13 @@ type fd*: SocketHandle deleVal*: RootRef - handleRead*: proc (h: PObject) {.nimcall, gcsafe.} - handleWrite*: proc (h: PObject) {.nimcall, gcsafe.} - handleError*: proc (h: PObject) {.nimcall, gcsafe.} - hasDataBuffered*: proc (h: PObject): bool {.nimcall, gcsafe.} + handleRead*: proc (h: RootRef) {.nimcall, gcsafe.} + handleWrite*: proc (h: RootRef) {.nimcall, gcsafe.} + handleError*: proc (h: RootRef) {.nimcall, gcsafe.} + hasDataBuffered*: proc (h: RootRef): bool {.nimcall, gcsafe.} open*: bool - task*: proc (h: PObject) {.nimcall, gcsafe.} + task*: proc (h: RootRef) {.nimcall, gcsafe.} mode*: FileMode Delegate* = ref DelegateObj @@ -146,32 +146,32 @@ type ].} -proc newDelegate*(): PDelegate = +proc newDelegate*(): Delegate = ## Creates a new delegate. new(result) - result.handleRead = (proc (h: PObject) = discard) - result.handleWrite = (proc (h: PObject) = discard) - result.handleError = (proc (h: PObject) = discard) - result.hasDataBuffered = (proc (h: PObject): bool = return false) - result.task = (proc (h: PObject) = discard) + result.handleRead = (proc (h: RootRef) = discard) + result.handleWrite = (proc (h: RootRef) = discard) + result.handleError = (proc (h: RootRef) = discard) + result.hasDataBuffered = (proc (h: RootRef): bool = return false) + result.task = (proc (h: RootRef) = discard) result.mode = fmRead -proc newAsyncSocket(): PAsyncSocket = +proc newAsyncSocket(): AsyncSocket = new(result) result.info = SockIdle - result.handleRead = (proc (s: PAsyncSocket) = discard) + result.handleRead = (proc (s: AsyncSocket) = discard) result.handleWrite = nil - result.handleConnect = (proc (s: PAsyncSocket) = discard) - result.handleAccept = (proc (s: PAsyncSocket) = discard) - result.handleTask = (proc (s: PAsyncSocket) = discard) + result.handleConnect = (proc (s: AsyncSocket) = discard) + result.handleAccept = (proc (s: AsyncSocket) = discard) + result.handleTask = (proc (s: AsyncSocket) = discard) result.lineBuffer = "".TaintedString result.sendBuffer = "" -proc asyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP, - buffered = true): PAsyncSocket = +proc asyncSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP, + buffered = true): AsyncSocket = ## Initialises an AsyncSocket object. If a socket cannot be initialised ## EOS is raised. result = newAsyncSocket() @@ -180,7 +180,7 @@ proc asyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, if result.socket == invalidSocket: raiseOSError(osLastError()) result.socket.setBlocking(false) -proc toAsyncSocket*(sock: TSocket, state: TInfo = SockConnected): PAsyncSocket = +proc toAsyncSocket*(sock: Socket, state: SocketStatus = SockConnected): PAsyncSocket = ## Wraps an already initialized ``TSocket`` into a PAsyncSocket. ## This is useful if you want to use an already connected TSocket as an ## asynchronous PAsyncSocket in asyncio's event loop. @@ -211,36 +211,36 @@ proc toAsyncSocket*(sock: TSocket, state: TInfo = SockConnected): PAsyncSocket = result.socket.setBlocking(false) result.info = state -proc asyncSockHandleRead(h: PObject) = +proc asyncSockHandleRead(h: RootRef) = when defined(ssl): if PAsyncSocket(h).socket.isSSL and not PAsyncSocket(h).socket.gotHandshake: return - if PAsyncSocket(h).info != SockListening: - if PAsyncSocket(h).info != SockConnecting: - PAsyncSocket(h).handleRead(PAsyncSocket(h)) + if AsyncSocket(h).info != SockListening: + if AsyncSocket(h).info != SockConnecting: + AsyncSocket(h).handleRead(AsyncSocket(h)) else: - PAsyncSocket(h).handleAccept(PAsyncSocket(h)) + AsyncSocket(h).handleAccept(AsyncSocket(h)) -proc close*(sock: PAsyncSocket) {.gcsafe.} -proc asyncSockHandleWrite(h: PObject) = +proc close*(sock: AsyncSocket) {.gcsafe.} +proc asyncSockHandleWrite(h: RootRef) = when defined(ssl): if PAsyncSocket(h).socket.isSSL and not PAsyncSocket(h).socket.gotHandshake: return - if PAsyncSocket(h).info == SockConnecting: - PAsyncSocket(h).handleConnect(PAsyncSocket(h)) - PAsyncSocket(h).info = SockConnected + if AsyncSocket(h).info == SockConnecting: + AsyncSocket(h).handleConnect(AsyncSocket(h)) + AsyncSocket(h).info = SockConnected # Stop receiving write events if there is no handleWrite event. - if PAsyncSocket(h).handleWrite == nil: - PAsyncSocket(h).deleg.mode = fmRead + if AsyncSocket(h).handleWrite == nil: + AsyncSocket(h).deleg.mode = fmRead else: - PAsyncSocket(h).deleg.mode = fmReadWrite + AsyncSocket(h).deleg.mode = fmReadWrite else: - if PAsyncSocket(h).sendBuffer != "": - let sock = PAsyncSocket(h) + if AsyncSocket(h).sendBuffer != "": + let sock = AsyncSocket(h) try: let bytesSent = sock.socket.sendAsync(sock.sendBuffer) if bytesSent == 0: @@ -252,16 +252,16 @@ proc asyncSockHandleWrite(h: PObject) = elif bytesSent == sock.sendBuffer.len: sock.sendBuffer = "" - if PAsyncSocket(h).handleWrite != nil: - PAsyncSocket(h).handleWrite(PAsyncSocket(h)) - except EOS: + if AsyncSocket(h).handleWrite != nil: + AsyncSocket(h).handleWrite(AsyncSocket(h)) + except OSError: # Most likely the socket closed before the full buffer could be sent to it. sock.close() # TODO: Provide a handleError for users? else: - if PAsyncSocket(h).handleWrite != nil: - PAsyncSocket(h).handleWrite(PAsyncSocket(h)) + if AsyncSocket(h).handleWrite != nil: + AsyncSocket(h).handleWrite(AsyncSocket(h)) else: - PAsyncSocket(h).deleg.mode = fmRead + AsyncSocket(h).deleg.mode = fmRead when defined(ssl): proc asyncSockDoHandshake(h: PObject) {.gcsafe.} = @@ -278,13 +278,13 @@ when defined(ssl): discard PAsyncSocket(h).socket.handshake() -proc asyncSockTask(h: PObject) = +proc asyncSockTask(h: RootRef) = when defined(ssl): h.asyncSockDoHandshake() - PAsyncSocket(h).handleTask(PAsyncSocket(h)) + AsyncSocket(h).handleTask(AsyncSocket(h)) -proc toDelegate(sock: PAsyncSocket): PDelegate = +proc toDelegate(sock: AsyncSocket): Delegate = result = newDelegate() result.deleVal = sock result.fd = getFD(sock.socket) @@ -297,8 +297,8 @@ proc toDelegate(sock: PAsyncSocket): PDelegate = #result.handleError = (proc (h: PObject) = assert(false)) result.hasDataBuffered = - proc (h: PObject): bool {.nimcall.} = - return PAsyncSocket(h).socket.hasDataBuffered() + proc (h: RootRef): bool {.nimcall.} = + return AsyncSocket(h).socket.hasDataBuffered() sock.deleg = result if sock.info notin {SockIdle, SockClosed}: @@ -306,22 +306,22 @@ proc toDelegate(sock: PAsyncSocket): PDelegate = else: sock.deleg.open = false -proc connect*(sock: PAsyncSocket, name: string, port = TPort(0), - af: TDomain = AF_INET) = +proc connect*(sock: AsyncSocket, name: string, port = Port(0), + af: Domain = AF_INET) = ## Begins connecting ``sock`` to ``name``:``port``. sock.socket.connectAsync(name, port, af) sock.info = SockConnecting if sock.deleg != nil: sock.deleg.open = true -proc close*(sock: PAsyncSocket) = +proc close*(sock: AsyncSocket) = ## Closes ``sock``. Terminates any current connections. sock.socket.close() sock.info = SockClosed if sock.deleg != nil: sock.deleg.open = false -proc bindAddr*(sock: PAsyncSocket, port = TPort(0), address = "") = +proc bindAddr*(sock: AsyncSocket, port = Port(0), address = "") = ## Equivalent to ``sockets.bindAddr``. sock.socket.bindAddr(port, address) if sock.proto == IPPROTO_UDP: @@ -329,14 +329,14 @@ proc bindAddr*(sock: PAsyncSocket, port = TPort(0), address = "") = if sock.deleg != nil: sock.deleg.open = true -proc listen*(sock: PAsyncSocket) = +proc listen*(sock: AsyncSocket) = ## Equivalent to ``sockets.listen``. sock.socket.listen() sock.info = SockListening if sock.deleg != nil: sock.deleg.open = true -proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, +proc acceptAddr*(server: AsyncSocket, client: var AsyncSocket, address: var string) = ## Equivalent to ``sockets.acceptAddr``. This procedure should be called in ## a ``handleAccept`` event handler **only** once. @@ -344,7 +344,7 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, ## **Note**: ``client`` needs to be initialised. assert(client != nil) client = newAsyncSocket() - var c: TSocket + var c: Socket new(c) when defined(ssl): if server.socket.isSSL: @@ -377,12 +377,12 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket, client.sendBuffer = "" client.info = SockConnected -proc accept*(server: PAsyncSocket, client: var PAsyncSocket) = +proc accept*(server: AsyncSocket, client: var AsyncSocket) = ## Equivalent to ``sockets.accept``. var dummyAddr = "" server.acceptAddr(client, dummyAddr) -proc acceptAddr*(server: PAsyncSocket): tuple[sock: PAsyncSocket, +proc acceptAddr*(server: AsyncSocket): tuple[sock: AsyncSocket, address: string] {.deprecated.} = ## Equivalent to ``sockets.acceptAddr``. ## @@ -392,7 +392,7 @@ proc acceptAddr*(server: PAsyncSocket): tuple[sock: PAsyncSocket, acceptAddr(server, client, address) return (client, address) -proc accept*(server: PAsyncSocket): PAsyncSocket {.deprecated.} = +proc accept*(server: AsyncSocket): AsyncSocket {.deprecated.} = ## Equivalent to ``sockets.accept``. ## ## **Deprecated since version 0.9.0:** Please use the function above. @@ -400,54 +400,54 @@ proc accept*(server: PAsyncSocket): PAsyncSocket {.deprecated.} = var address = "" server.acceptAddr(result, address) -proc newDispatcher*(): PDispatcher = +proc newDispatcher*(): Dispatcher = new(result) result.delegates = @[] -proc register*(d: PDispatcher, deleg: PDelegate) = +proc register*(d: Dispatcher, deleg: Delegate) = ## Registers delegate ``deleg`` with dispatcher ``d``. d.delegates.add(deleg) -proc register*(d: PDispatcher, sock: PAsyncSocket): PDelegate {.discardable.} = +proc register*(d: Dispatcher, sock: AsyncSocket): Delegate {.discardable.} = ## Registers async socket ``sock`` with dispatcher ``d``. result = sock.toDelegate() d.register(result) -proc unregister*(d: PDispatcher, deleg: PDelegate) = +proc unregister*(d: Dispatcher, deleg: Delegate) = ## Unregisters deleg ``deleg`` from dispatcher ``d``. for i in 0..len(d.delegates)-1: if d.delegates[i] == deleg: d.delegates.del(i) return - raise newException(EInvalidIndex, "Could not find delegate.") + raise newException(IndexError, "Could not find delegate.") -proc isWriteable*(s: PAsyncSocket): bool = +proc isWriteable*(s: AsyncSocket): bool = ## Determines whether socket ``s`` is ready to be written to. var writeSock = @[s.socket] return selectWrite(writeSock, 1) != 0 and s.socket notin writeSock -converter getSocket*(s: PAsyncSocket): TSocket = +converter getSocket*(s: AsyncSocket): Socket = return s.socket -proc isConnected*(s: PAsyncSocket): bool = +proc isConnected*(s: AsyncSocket): bool = ## Determines whether ``s`` is connected. return s.info == SockConnected -proc isListening*(s: PAsyncSocket): bool = +proc isListening*(s: AsyncSocket): bool = ## Determines whether ``s`` is listening for incoming connections. return s.info == SockListening -proc isConnecting*(s: PAsyncSocket): bool = +proc isConnecting*(s: AsyncSocket): bool = ## Determines whether ``s`` is connecting. return s.info == SockConnecting -proc isClosed*(s: PAsyncSocket): bool = +proc isClosed*(s: AsyncSocket): bool = ## Determines whether ``s`` has been closed. return s.info == SockClosed -proc isSendDataBuffered*(s: PAsyncSocket): bool = +proc isSendDataBuffered*(s: AsyncSocket): bool = ## Determines whether ``s`` has data waiting to be sent, i.e. whether this ## socket's sendBuffer contains data. return s.sendBuffer.len != 0 -proc setHandleWrite*(s: PAsyncSocket, - handleWrite: proc (s: PAsyncSocket) {.closure, gcsafe.}) = +proc setHandleWrite*(s: AsyncSocket, + handleWrite: proc (s: AsyncSocket) {.closure, gcsafe.}) = ## Setter for the ``handleWrite`` event. ## ## To remove this event you should use the ``delHandleWrite`` function. @@ -457,12 +457,12 @@ proc setHandleWrite*(s: PAsyncSocket, s.deleg.mode = fmReadWrite s.handleWrite = handleWrite -proc delHandleWrite*(s: PAsyncSocket) = +proc delHandleWrite*(s: AsyncSocket) = ## Removes the ``handleWrite`` event handler on ``s``. s.handleWrite = nil {.push warning[deprecated]: off.} -proc recvLine*(s: PAsyncSocket, line: var TaintedString): bool {.deprecated.} = +proc recvLine*(s: AsyncSocket, line: var TaintedString): bool {.deprecated.} = ## Behaves similar to ``sockets.recvLine``, however it handles non-blocking ## sockets properly. This function guarantees that ``line`` is a full line, ## if this function can only retrieve some data; it will save this data and @@ -495,7 +495,7 @@ proc recvLine*(s: PAsyncSocket, line: var TaintedString): bool {.deprecated.} = result = false {.pop.} -proc readLine*(s: PAsyncSocket, line: var TaintedString): bool = +proc readLine*(s: AsyncSocket, line: var TaintedString): bool = ## Behaves similar to ``sockets.readLine``, however it handles non-blocking ## sockets properly. This function guarantees that ``line`` is a full line, ## if this function can only retrieve some data; it will save this data and @@ -525,7 +525,7 @@ proc readLine*(s: PAsyncSocket, line: var TaintedString): bool = of ReadDisconnected: result = true -proc send*(sock: PAsyncSocket, data: string) = +proc send*(sock: AsyncSocket, data: string) = ## Sends ``data`` to socket ``sock``. This is basically a nicer implementation ## of ``sockets.sendAsync``. ## @@ -545,7 +545,7 @@ proc send*(sock: PAsyncSocket, data: string) = sock.sendBuffer.add(data[bytesSent .. -1]) sock.deleg.mode = fmReadWrite -proc timeValFromMilliseconds(timeout = 500): TimeVal = +proc timeValFromMilliseconds(timeout = 500): Timeval = if timeout != -1: var seconds = timeout div 1000 result.tv_sec = seconds.int32 @@ -568,9 +568,9 @@ proc pruneSocketSet(s: var seq[Delegate], fd: var FdSet) = inc(i) setLen(s, L) -proc select(readfds, writefds, exceptfds: var seq[PDelegate], +proc select(readfds, writefds, exceptfds: var seq[Delegate], timeout = 500): int = - var tv {.noInit.}: TimeVal = timeValFromMilliseconds(timeout) + var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) var rd, wr, ex: FdSet var m = 0 @@ -587,7 +587,7 @@ proc select(readfds, writefds, exceptfds: var seq[PDelegate], pruneSocketSet(writefds, (wr)) pruneSocketSet(exceptfds, (ex)) -proc poll*(d: PDispatcher, timeout: int = 500): bool = +proc poll*(d: Dispatcher, timeout: int = 500): bool = ## This function checks for events on all the delegates in the `PDispatcher`. ## It then proceeds to call the correct event handler. ## @@ -600,7 +600,7 @@ proc poll*(d: PDispatcher, timeout: int = 500): bool = ## only be executed after one or more file descriptors becomes readable or ## writeable. result = true - var readDg, writeDg, errorDg: seq[PDelegate] = @[] + var readDg, writeDg, errorDg: seq[Delegate] = @[] var len = d.delegates.len var dc = 0 @@ -648,7 +648,7 @@ proc poll*(d: PDispatcher, timeout: int = 500): bool = for i in items(d.delegates): i.task(i.deleVal) -proc len*(disp: PDispatcher): int = +proc len*(disp: Dispatcher): int = ## Retrieves the amount of delegates in ``disp``. return disp.delegates.len diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim index 5414c4737..58b37833a 100644 --- a/lib/pure/scgi.nim +++ b/lib/pure/scgi.nim @@ -79,7 +79,7 @@ type c: AsyncSocket mode: ClientMode dataLen: int - headers: PStringTable ## the parsed headers + headers: StringTableRef ## the parsed headers input: string ## the input buffer AsyncScgiStateObj = object @@ -105,7 +105,7 @@ proc open*(s: var ScgiState, port = Port(4000), address = "127.0.0.1", reuseAddr = false) = ## opens a connection. s.bufLen = 4000 - s.input = newString(s.buflen) # will be reused + s.input = newString(s.bufLen) # will be reused s.server = socket() if s.server == invalidSocket: raiseOSError(osLastError()) @@ -262,7 +262,7 @@ proc open*(handleRequest: proc (client: AsyncSocket, ## automatically unless it has already been closed. var cres: AsyncScgiState new(cres) - cres.asyncServer = AsyncSocket() + cres.asyncServer = asyncSocket() cres.asyncServer.handleAccept = proc (s: AsyncSocket) = handleAccept(s, cres) if reuseAddr: cres.asyncServer.setSockOpt(OptReuseAddr, true) diff --git a/tests/bind/tnicerrorforsymchoice.nim b/tests/bind/tnicerrorforsymchoice.nim index 4e7a271b3..a0e9091c3 100644 --- a/tests/bind/tnicerrorforsymchoice.nim +++ b/tests/bind/tnicerrorforsymchoice.nim @@ -1,6 +1,6 @@ discard """ line: 18 - errormsg: "type mismatch: got (proc (TScgi) | proc (PAsyncSocket, PStringTable, string){.gcsafe.})" + errormsg: "type mismatch: got (proc (TScgi) | proc (AsyncSocket, StringTableRef, string){.gcsafe.})" """ #bug #442 From 3ba34f1762742682a54dfdc30986818b5c1ecd81 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 13:46:27 +0200 Subject: [PATCH 065/409] prettified re.nim; make some tests green --- lib/impure/re.nim | 115 +++++++++++++++++---------------- lib/pure/collections/lists.nim | 43 ++++++------ tests/misc/tdllvar.nim | 4 +- tests/misc/teventemitter.nim | 24 +++---- tests/misc/thallo.nim | 2 +- tests/misc/tints.nim | 2 +- tests/trmacros/targlist.nim | 2 +- 7 files changed, 98 insertions(+), 94 deletions(-) diff --git a/lib/impure/re.nim b/lib/impure/re.nim index a129a5eba..fc9ed3ce0 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -28,7 +28,7 @@ const ## More subpatterns cannot be captured! type - TRegexFlag* = enum ## options for regular expressions + RegexFlag* = enum ## options for regular expressions reIgnoreCase = 0, ## do caseless matching reMultiLine = 1, ## ``^`` and ``$`` match newlines within data reDotAll = 2, ## ``.`` matches anything including NL @@ -36,17 +36,20 @@ type reStudy = 4 ## study the expression (may be omitted if the ## expression will be used only once) - TRegexDesc {.pure, final.} = object + RegexDesc = object h: PPcre e: ptr TExtra - TRegex* = ref TRegexDesc ## a compiled regular expression + Regex* = ref RegexDesc ## a compiled regular expression - EInvalidRegEx* = object of EInvalidValue + RegexError* = object of ValueError ## is raised if the pattern is no valid regular expression. +{.deprecated: [TRegexFlag: RegexFlag, TRegexDesc: RegexDesc, TRegex: Regex, + EInvalidRegEx: RegexError].} + proc raiseInvalidRegex(msg: string) {.noinline, noreturn.} = - var e: ref EInvalidRegEx + var e: ref RegexError new(e) e.msg = msg raise e @@ -55,11 +58,11 @@ proc rawCompile(pattern: string, flags: cint): PPcre = var msg: cstring offset: cint - result = pcre.Compile(pattern, flags, addr(msg), addr(offset), nil) + result = pcre.compile(pattern, flags, addr(msg), addr(offset), nil) if result == nil: raiseInvalidRegex($msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n") -proc finalizeRegEx(x: TRegex) = +proc finalizeRegEx(x: Regex) = # XXX This is a hack, but PCRE does not export its "free" function properly. # Sigh. The hack relies on PCRE's implementation (see ``pcre_get.c``). # Fortunately the implementation is unlikely to change. @@ -67,7 +70,7 @@ proc finalizeRegEx(x: TRegex) = if not isNil(x.e): pcre.free_substring(cast[cstring](x.e)) -proc re*(s: string, flags = {reExtended, reStudy}): TRegex = +proc re*(s: string, flags = {reExtended, reStudy}): Regex = ## Constructor of regular expressions. Note that Nim's ## extended raw string literals support this syntax ``re"[abc]"`` as ## a short form for ``re(r"[abc]")``. @@ -78,12 +81,12 @@ proc re*(s: string, flags = {reExtended, reStudy}): TRegex = result.e = pcre.study(result.h, 0, msg) if not isNil(msg): raiseInvalidRegex($msg) -proc matchOrFind(s: string, pattern: TRegex, matches: var openArray[string], +proc matchOrFind(s: string, pattern: Regex, matches: var openArray[string], start, flags: cint): cint = var - rawMatches: array[0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] + res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start, flags, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: return res for i in 1..int(res)-1: var a = rawMatches[i * 2] @@ -92,16 +95,16 @@ proc matchOrFind(s: string, pattern: TRegex, matches: var openArray[string], else: matches[i-1] = "" return rawMatches[1] - rawMatches[0] -proc findBounds*(s: string, pattern: TRegex, matches: var openArray[string], +proc findBounds*(s: string, pattern: Regex, matches: var openArray[string], start = 0): tuple[first, last: int] = ## returns the starting position and end position of `pattern` in `s` ## and the captured ## substrings in the array `matches`. If it does not match, nothing ## is written into `matches` and ``(-1,0)`` is returned. var - rawMatches: array[0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] + res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: return (-1, 0) for i in 1..int(res)-1: var a = rawMatches[i * 2] @@ -110,7 +113,7 @@ proc findBounds*(s: string, pattern: TRegex, matches: var openArray[string], else: matches[i-1] = "" return (rawMatches[0].int, rawMatches[1].int - 1) -proc findBounds*(s: string, pattern: TRegex, +proc findBounds*(s: string, pattern: Regex, matches: var openArray[tuple[first, last: int]], start = 0): tuple[first, last: int] = ## returns the starting position and end position of ``pattern`` in ``s`` @@ -118,9 +121,9 @@ proc findBounds*(s: string, pattern: TRegex, ## If it does not match, nothing is written into `matches` and ## ``(-1,0)`` is returned. var - rawMatches: array[0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] + res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: return (-1, 0) for i in 1..int(res)-1: var a = rawMatches[i * 2] @@ -129,25 +132,25 @@ proc findBounds*(s: string, pattern: TRegex, else: matches[i-1] = (-1,0) return (rawMatches[0].int, rawMatches[1].int - 1) -proc findBounds*(s: string, pattern: TRegex, +proc findBounds*(s: string, pattern: Regex, start = 0): tuple[first, last: int] = ## returns the starting position of `pattern` in `s`. If it does not ## match, ``(-1,0)`` is returned. var rawMatches: array[0..3 - 1, cint] - res = pcre.Exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32, + res = pcre.exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32, cast[ptr cint](addr(rawMatches)), 3) if res < 0'i32: return (int(res), 0) return (int(rawMatches[0]), int(rawMatches[1]-1)) -proc matchOrFind(s: string, pattern: TRegex, start, flags: cint): cint = - var rawMatches: array [0..maxSubpatterns * 3 - 1, cint] - result = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start, flags, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) +proc matchOrFind(s: string, pattern: Regex, start, flags: cint): cint = + var rawMatches: array [0..MaxSubpatterns * 3 - 1, cint] + result = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start, flags, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if result >= 0'i32: result = rawMatches[1] - rawMatches[0] -proc match*(s: string, pattern: TRegex, matches: var openArray[string], +proc match*(s: string, pattern: Regex, matches: var openArray[string], start = 0): bool = ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and ## the captured substrings in the array ``matches``. If it does not @@ -156,32 +159,32 @@ proc match*(s: string, pattern: TRegex, matches: var openArray[string], return matchOrFind(s, pattern, matches, start.cint, pcre.ANCHORED) == cint(s.len - start) -proc match*(s: string, pattern: TRegex, start = 0): bool = +proc match*(s: string, pattern: Regex, start = 0): bool = ## returns ``true`` if ``s[start..]`` matches the ``pattern``. return matchOrFind(s, pattern, start.cint, pcre.ANCHORED) == cint(s.len-start) -proc matchLen*(s: string, pattern: TRegex, matches: var openArray[string], +proc matchLen*(s: string, pattern: Regex, matches: var openArray[string], start = 0): int = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. return matchOrFind(s, pattern, matches, start.cint, pcre.ANCHORED) -proc matchLen*(s: string, pattern: TRegex, start = 0): int = +proc matchLen*(s: string, pattern: Regex, start = 0): int = ## the same as ``match``, but it returns the length of the match, ## if there is no match, -1 is returned. Note that a match length ## of zero can happen. return matchOrFind(s, pattern, start.cint, pcre.ANCHORED) -proc find*(s: string, pattern: TRegex, matches: var openArray[string], +proc find*(s: string, pattern: Regex, matches: var openArray[string], start = 0): int = ## returns the starting position of ``pattern`` in ``s`` and the captured ## substrings in the array ``matches``. If it does not match, nothing ## is written into ``matches`` and -1 is returned. var - rawMatches: array[0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] + res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: return res for i in 1..int(res)-1: var a = rawMatches[i * 2] @@ -190,33 +193,33 @@ proc find*(s: string, pattern: TRegex, matches: var openArray[string], else: matches[i-1] = "" return rawMatches[0] -proc find*(s: string, pattern: TRegex, start = 0): int = +proc find*(s: string, pattern: Regex, start = 0): int = ## returns the starting position of ``pattern`` in ``s``. If it does not ## match, -1 is returned. var rawMatches: array[0..3 - 1, cint] - res = pcre.Exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32, + res = pcre.exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32, cast[ptr cint](addr(rawMatches)), 3) if res < 0'i32: return res return rawMatches[0] -iterator findAll*(s: string, pattern: TRegex, start = 0): string = +iterator findAll*(s: string, pattern: Regex, start = 0): string = ## Yields all matching *substrings* of `s` that match `pattern`. ## ## Note that since this is an iterator you should not modify the string you ## are iterating over: bad things could happen. var i = int32(start) - var rawMatches: array[0..maxSubpatterns * 3 - 1, cint] + var rawMatches: array[0..MaxSubpatterns * 3 - 1, cint] while true: - let res = pcre.Exec(pattern.h, pattern.e, s, len(s).cint, i, 0'i32, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) + let res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, i, 0'i32, + cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3) if res < 0'i32: break let a = rawMatches[0] let b = rawMatches[1] yield substr(s, int(a), int(b)-1) i = b -proc findAll*(s: string, pattern: TRegex, start = 0): seq[string] = +proc findAll*(s: string, pattern: Regex, start = 0): seq[string] = ## returns all matching *substrings* of `s` that match `pattern`. ## If it does not match, @[] is returned. accumulateResult(findAll(s, pattern, start)) @@ -224,7 +227,7 @@ proc findAll*(s: string, pattern: TRegex, start = 0): seq[string] = when not defined(nimhygiene): {.pragma: inject.} -template `=~` *(s: string, pattern: TRegex): expr = +template `=~` *(s: string, pattern: Regex): expr = ## This calls ``match`` with an implicit declared ``matches`` array that ## can be used in the scope of the ``=~`` call: ## @@ -242,32 +245,32 @@ template `=~` *(s: string, pattern: TRegex): expr = ## else: ## echo("syntax error") ## - bind maxSubPatterns + bind MaxSubPatterns when not declaredInScope(matches): var matches {.inject.}: array[0..MaxSubpatterns-1, string] match(s, pattern, matches) # ------------------------- more string handling ------------------------------ -proc contains*(s: string, pattern: TRegex, start = 0): bool = +proc contains*(s: string, pattern: Regex, start = 0): bool = ## same as ``find(s, pattern, start) >= 0`` return find(s, pattern, start) >= 0 -proc contains*(s: string, pattern: TRegex, matches: var openArray[string], +proc contains*(s: string, pattern: Regex, matches: var openArray[string], start = 0): bool = ## same as ``find(s, pattern, matches, start) >= 0`` return find(s, pattern, matches, start) >= 0 -proc startsWith*(s: string, prefix: TRegex): bool = +proc startsWith*(s: string, prefix: Regex): bool = ## returns true if `s` starts with the pattern `prefix` result = matchLen(s, prefix) >= 0 -proc endsWith*(s: string, suffix: TRegex): bool = +proc endsWith*(s: string, suffix: Regex): bool = ## returns true if `s` ends with the pattern `prefix` for i in 0 .. s.len-1: if matchLen(s, suffix, i) == s.len - i: return true -proc replace*(s: string, sub: TRegex, by = ""): string = +proc replace*(s: string, sub: Regex, by = ""): string = ## Replaces `sub` in `s` by the string `by`. Captures cannot be ## accessed in `by`. Examples: ## @@ -289,7 +292,7 @@ proc replace*(s: string, sub: TRegex, by = ""): string = prev = match.last + 1 add(result, substr(s, prev)) -proc replacef*(s: string, sub: TRegex, by: string): string = +proc replacef*(s: string, sub: Regex, by: string): string = ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: ## @@ -302,7 +305,7 @@ proc replacef*(s: string, sub: TRegex, by: string): string = ## ## "var1<-keykey; val2<-key2key2" result = "" - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] var prev = 0 while true: var match = findBounds(s, sub, caps, prev) @@ -314,7 +317,7 @@ proc replacef*(s: string, sub: TRegex, by: string): string = when false: result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: var x = matchLen(s, sub, caps, i) if x <= 0: @@ -327,12 +330,12 @@ proc replacef*(s: string, sub: TRegex, by: string): string = add(result, substr(s, i)) proc parallelReplace*(s: string, subs: openArray[ - tuple[pattern: TRegex, repl: string]]): string = + tuple[pattern: Regex, repl: string]]): string = ## Returns a modified copy of `s` with the substitutions in `subs` ## applied in parallel. result = "" var i = 0 - var caps: array[0..maxSubpatterns-1, string] + var caps: array[0..MaxSubpatterns-1, string] while i < s.len: block searchSubs: for j in 0..high(subs): @@ -347,14 +350,14 @@ proc parallelReplace*(s: string, subs: openArray[ add(result, substr(s, i)) proc transformFile*(infile, outfile: string, - subs: openArray[tuple[pattern: TRegex, repl: string]]) = + subs: openArray[tuple[pattern: Regex, repl: string]]) = ## reads in the file `infile`, performs a parallel replacement (calls ## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an ## error occurs. This is supposed to be used for quick scripting. var x = readFile(infile).string writeFile(outfile, x.parallelReplace(subs)) -iterator split*(s: string, sep: TRegex): string = +iterator split*(s: string, sep: Regex): string = ## Splits the string `s` into substrings. ## ## Substrings are separated by the regular expression `sep`. @@ -386,7 +389,7 @@ iterator split*(s: string, sep: TRegex): string = if first < last: yield substr(s, first, last-1) -proc split*(s: string, sep: TRegex): seq[string] = +proc split*(s: string, sep: Regex): seq[string] = ## Splits the string `s` into substrings. accumulateResult(split(s, sep)) diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim index b7ca5a7af..929de5973 100644 --- a/lib/pure/collections/lists.nim +++ b/lib/pure/collections/lists.nim @@ -43,7 +43,8 @@ type PSinglyLinkedNode: SinglyLinkedNode, TDoublyLinkedList: DoublyLinkedList, TSinglyLinkedRing: SinglyLinkedRing, - TDoublyLinkedRing: DoublyLinkedRing].} + TDoublyLinkedRing: DoublyLinkedRing, + TSinglyLinkedList: SinglyLinkedList].} proc initSinglyLinkedList*[T](): SinglyLinkedList[T] = ## creates a new singly linked list that is empty. @@ -179,42 +180,42 @@ proc find*[T](L: SinglyLinkedRing[T], value: T): SinglyLinkedNode[T] = ## exist. findImpl() -proc find*[T](L: TDoublyLinkedRing[T], value: T): PDoublyLinkedNode[T] = +proc find*[T](L: DoublyLinkedRing[T], value: T): DoublyLinkedNode[T] = ## searches in the list for a value. Returns nil if the value does not ## exist. findImpl() -proc contains*[T](L: TSinglyLinkedList[T], value: T): bool {.inline.} = +proc contains*[T](L: SinglyLinkedList[T], value: T): bool {.inline.} = ## searches in the list for a value. Returns false if the value does not ## exist, true otherwise. result = find(L, value) != nil -proc contains*[T](L: TDoublyLinkedList[T], value: T): bool {.inline.} = +proc contains*[T](L: DoublyLinkedList[T], value: T): bool {.inline.} = ## searches in the list for a value. Returns false if the value does not ## exist, true otherwise. result = find(L, value) != nil -proc contains*[T](L: TSinglyLinkedRing[T], value: T): bool {.inline.} = +proc contains*[T](L: SinglyLinkedRing[T], value: T): bool {.inline.} = ## searches in the list for a value. Returns false if the value does not ## exist, true otherwise. result = find(L, value) != nil -proc contains*[T](L: TDoublyLinkedRing[T], value: T): bool {.inline.} = +proc contains*[T](L: DoublyLinkedRing[T], value: T): bool {.inline.} = ## searches in the list for a value. Returns false if the value does not ## exist, true otherwise. result = find(L, value) != nil -proc prepend*[T](L: var TSinglyLinkedList[T], - n: PSinglyLinkedNode[T]) {.inline.} = +proc prepend*[T](L: var SinglyLinkedList[T], + n: SinglyLinkedNode[T]) {.inline.} = ## prepends a node to `L`. Efficiency: O(1). n.next = L.head L.head = n -proc prepend*[T](L: var TSinglyLinkedList[T], value: T) {.inline.} = +proc prepend*[T](L: var SinglyLinkedList[T], value: T) {.inline.} = ## prepends a node to `L`. Efficiency: O(1). prepend(L, newSinglyLinkedNode(value)) -proc append*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = +proc append*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) = ## appends a node `n` to `L`. Efficiency: O(1). n.next = nil n.prev = L.tail @@ -224,11 +225,11 @@ proc append*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = L.tail = n if L.head == nil: L.head = n -proc append*[T](L: var TDoublyLinkedList[T], value: T) = +proc append*[T](L: var DoublyLinkedList[T], value: T) = ## appends a value to `L`. Efficiency: O(1). append(L, newDoublyLinkedNode(value)) -proc prepend*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = +proc prepend*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) = ## prepends a node `n` to `L`. Efficiency: O(1). n.prev = nil n.next = L.head @@ -238,11 +239,11 @@ proc prepend*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = L.head = n if L.tail == nil: L.tail = n -proc prepend*[T](L: var TDoublyLinkedList[T], value: T) = +proc prepend*[T](L: var DoublyLinkedList[T], value: T) = ## prepends a value to `L`. Efficiency: O(1). prepend(L, newDoublyLinkedNode(value)) -proc remove*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = +proc remove*[T](L: var DoublyLinkedList[T], n: DoublyLinkedNode[T]) = ## removes `n` from `L`. Efficiency: O(1). if n == L.tail: L.tail = n.prev if n == L.head: L.head = n.next @@ -250,7 +251,7 @@ proc remove*[T](L: var TDoublyLinkedList[T], n: PDoublyLinkedNode[T]) = if n.prev != nil: n.prev.next = n.next -proc prepend*[T](L: var TSinglyLinkedRing[T], n: PSinglyLinkedNode[T]) = +proc prepend*[T](L: var SinglyLinkedRing[T], n: SinglyLinkedNode[T]) = ## prepends a node `n` to `L`. Efficiency: O(1). if L.head != nil: n.next = L.head @@ -259,11 +260,11 @@ proc prepend*[T](L: var TSinglyLinkedRing[T], n: PSinglyLinkedNode[T]) = n.next = n L.head = n -proc prepend*[T](L: var TSinglyLinkedRing[T], value: T) = +proc prepend*[T](L: var SinglyLinkedRing[T], value: T) = ## prepends a value to `L`. Efficiency: O(1). prepend(L, newSinglyLinkedNode(value)) -proc append*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = +proc append*[T](L: var DoublyLinkedRing[T], n: DoublyLinkedNode[T]) = ## appends a node `n` to `L`. Efficiency: O(1). if L.head != nil: n.next = L.head @@ -275,11 +276,11 @@ proc append*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = n.next = n L.head = n -proc append*[T](L: var TDoublyLinkedRing[T], value: T) = +proc append*[T](L: var DoublyLinkedRing[T], value: T) = ## appends a value to `L`. Efficiency: O(1). append(L, newDoublyLinkedNode(value)) -proc prepend*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = +proc prepend*[T](L: var DoublyLinkedRing[T], n: DoublyLinkedNode[T]) = ## prepends a node `n` to `L`. Efficiency: O(1). if L.head != nil: n.next = L.head @@ -291,11 +292,11 @@ proc prepend*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = n.next = n L.head = n -proc prepend*[T](L: var TDoublyLinkedRing[T], value: T) = +proc prepend*[T](L: var DoublyLinkedRing[T], value: T) = ## prepends a value to `L`. Efficiency: O(1). prepend(L, newDoublyLinkedNode(value)) -proc remove*[T](L: var TDoublyLinkedRing[T], n: PDoublyLinkedNode[T]) = +proc remove*[T](L: var DoublyLinkedRing[T], n: DoublyLinkedNode[T]) = ## removes `n` from `L`. Efficiency: O(1). n.next.prev = n.prev n.prev.next = n.next diff --git a/tests/misc/tdllvar.nim b/tests/misc/tdllvar.nim index ab767770c..5a31dfbbb 100644 --- a/tests/misc/tdllvar.nim +++ b/tests/misc/tdllvar.nim @@ -2,9 +2,9 @@ import os proc getDllName: string = result = "mylib.dll" - if ExistsFile(result): return + if fileExists(result): return result = "mylib2.dll" - if ExistsFile(result): return + if fileExists(result): return quit("could not load dynamic library") proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().} diff --git a/tests/misc/teventemitter.nim b/tests/misc/teventemitter.nim index 9ecf72ea2..bfcf95701 100644 --- a/tests/misc/teventemitter.nim +++ b/tests/misc/teventemitter.nim @@ -5,29 +5,29 @@ discard """ import tables, lists type - TEventArgs = object of TObject - TEventEmitter = object of TObject - events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}]] + EventArgs = object of RootObj + EventEmitter = object of RootObj + events*: Table[string, DoublyLinkedList[proc(e: EventArgs) {.nimcall.}]] -proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) = +proc emit*(emitter: EventEmitter, event: string, args: EventArgs) = for func in nodes(emitter.events[event]): func.value(args) #call function with args. -proc on*(emitter: var TEventEmitter, event: string, - func: proc(e: TEventArgs) {.nimcall.}) = +proc on*(emitter: var EventEmitter, event: string, + func: proc(e: EventArgs) {.nimcall.}) = if not hasKey(emitter.events, event): - var list: TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}] + var list: DoublyLinkedList[proc(e: EventArgs) {.nimcall.}] add(emitter.events, event, list) #if not, add it. append(emitter.events.mget(event), func) -proc initEmitter(emitter: var TEventEmitter) = +proc initEmitter(emitter: var EventEmitter) = emitter.events = initTable[string, - TDoublyLinkedList[proc(e: TEventArgs) {.nimcall.}]]() + DoublyLinkedList[proc(e: EventArgs) {.nimcall.}]]() var - ee: TEventEmitter - args: TEventArgs + ee: EventEmitter + args: EventArgs initEmitter(ee) -ee.on("print", proc(e: TEventArgs) = echo("pie")) +ee.on("print", proc(e: EventArgs) = echo("pie")) ee.emit("print", args) diff --git a/tests/misc/thallo.nim b/tests/misc/thallo.nim index 46d21b4da..cbeb45b97 100644 --- a/tests/misc/thallo.nim +++ b/tests/misc/thallo.nim @@ -37,7 +37,7 @@ macrotest(stdout) #GC_disable() -echo("This was compiled by Nim version " & system.nimVersion) +echo("This was compiled by Nim version " & system.NimVersion) writeln(stdout, "Hello", " World", "!") echo(["a", "b", "c", "d"].len) diff --git a/tests/misc/tints.nim b/tests/misc/tints.nim index fb2852af9..3e413026a 100644 --- a/tests/misc/tints.nim +++ b/tests/misc/tints.nim @@ -41,5 +41,5 @@ test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8) test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64) test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32) -Echo("Success") #OUT Success +echo("Success") #OUT Success diff --git a/tests/trmacros/targlist.nim b/tests/trmacros/targlist.nim index e416edf0a..321b3d5d2 100644 --- a/tests/trmacros/targlist.nim +++ b/tests/trmacros/targlist.nim @@ -3,7 +3,7 @@ discard """ """ proc f(x: varargs[string, `$`]) = discard -template optF{f(X)}(x: varargs[expr]) = +template optF{f(x)}(x: varargs[expr]) = writeln(stdout, x) f 1, 2, false, 3, "ha" From eac71d38d71792166117ab311189a4a39a431956 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 30 Aug 2014 18:18:41 +0100 Subject: [PATCH 066/409] s/storeFile/store/ --- lib/pure/asyncftpclient.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pure/asyncftpclient.nim b/lib/pure/asyncftpclient.nim index a3d977660..d4ac63e75 100644 --- a/lib/pure/asyncftpclient.nim +++ b/lib/pure/asyncftpclient.nim @@ -255,7 +255,7 @@ proc doUpload(ftp: AsyncFtpClient, file: TFile, await countdownFut or sendFut -proc storeFile*(ftp: AsyncFtpClient, file, dest: string, +proc store*(ftp: AsyncFtpClient, file, dest: string, onProgressChanged = defaultOnProgressChanged) {.async.} = ## Uploads ``file`` to ``dest`` on the remote FTP server. Usage of this ## function asynchronously is recommended to view the progress of @@ -288,7 +288,7 @@ when isMainModule: await ftp.connect() echo await ftp.pwd() echo await ftp.listDirs() - await ftp.storeFile("payload.jpg", "payload.jpg") + await ftp.store("payload.jpg", "payload.jpg") await ftp.retrFile("payload.jpg", "payload2.jpg") echo("Finished") From d26d42b88e2abacb74cd3bfedf7b9a0d8d0a7eee Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sun, 31 Aug 2014 11:22:51 +0100 Subject: [PATCH 067/409] Case sensitivity fixes for httpclient and sockets module. --- lib/pure/httpclient.nim | 24 +++++----- lib/pure/sockets.nim | 100 ++++++++++++++++++++-------------------- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 5eff6cfa2..c5e657bab 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -181,7 +181,7 @@ proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.5 if headers["Connection"] == "close": var buf = "" - while True: + while true: buf = newString(4000) let r = s.recv(addr(buf[0]), 4000, timeout) if r == 0: break @@ -194,7 +194,7 @@ proc parseResponse(s: TSocket, getBody: bool, timeout: int): TResponse = var fullyRead = false var line = "" result.headers = newStringTable(modeCaseInsensitive) - while True: + while true: line = "" linei = 0 s.readLine(line, timeout) @@ -294,7 +294,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", add(headers, "\c\L") var s = socket() - if s == InvalidSocket: raiseOSError(osLastError()) + if s == invalidSocket: raiseOSError(osLastError()) var port = sockets.TPort(80) if r.scheme == "https": when defined(ssl): @@ -321,7 +321,7 @@ proc redirection(status: string): bool = const redirectionNRs = ["301", "302", "303", "307"] for i in items(redirectionNRs): if status.startsWith(i): - return True + return true proc getNewLocation(lastUrl: string, headers: PStringTable): string = result = headers["Location"] @@ -467,7 +467,7 @@ proc close*(client: AsyncHttpClient) = client.socket.close() client.connected = false -proc recvFull(socket: PAsyncSocket, size: int): PFuture[string] {.async.} = +proc recvFull(socket: PAsyncSocket, size: int): Future[string] {.async.} = ## Ensures that all the data requested is read and returned. result = "" while true: @@ -476,7 +476,7 @@ proc recvFull(socket: PAsyncSocket, size: int): PFuture[string] {.async.} = if data == "": break # We've been disconnected. result.add data -proc parseChunks(client: PAsyncHttpClient): PFuture[string] {.async.} = +proc parseChunks(client: PAsyncHttpClient): Future[string] {.async.} = result = "" var ri = 0 while true: @@ -509,7 +509,7 @@ proc parseChunks(client: PAsyncHttpClient): PFuture[string] {.async.} = # them: http://tools.ietf.org/html/rfc2616#section-3.6.1 proc parseBody(client: PAsyncHttpClient, - headers: PStringTable): PFuture[string] {.async.} = + headers: PStringTable): Future[string] {.async.} = result = "" if headers["Transfer-Encoding"] == "chunked": result = await parseChunks(client) @@ -532,19 +532,19 @@ proc parseBody(client: PAsyncHttpClient, # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.5 if headers["Connection"] == "close": var buf = "" - while True: + while true: buf = await client.socket.recvFull(4000) if buf == "": break result.add(buf) proc parseResponse(client: PAsyncHttpClient, - getBody: bool): PFuture[TResponse] {.async.} = + getBody: bool): Future[TResponse] {.async.} = var parsedStatus = false var linei = 0 var fullyRead = false var line = "" result.headers = newStringTable(modeCaseInsensitive) - while True: + while true: linei = 0 line = await client.socket.recvLine() if line == "": break # We've been disconnected. @@ -603,7 +603,7 @@ proc newConnection(client: PAsyncHttpClient, url: TURL) {.async.} = client.connected = true proc request*(client: PAsyncHttpClient, url: string, httpMethod = httpGET, - body = ""): PFuture[TResponse] {.async.} = + body = ""): Future[TResponse] {.async.} = ## Connects to the hostname specified by the URL and performs a request ## using the method specified. ## @@ -626,7 +626,7 @@ proc request*(client: PAsyncHttpClient, url: string, httpMethod = httpGET, result = await parseResponse(client, httpMethod != httpHEAD) -proc get*(client: PAsyncHttpClient, url: string): PFuture[TResponse] {.async.} = +proc get*(client: PAsyncHttpClient, url: string): Future[TResponse] {.async.} = ## Connects to the hostname specified by the URL and performs a GET request. ## ## This procedure will follow redirects up to a maximum number of redirects diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 157d5837e..5ac3589a2 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -251,14 +251,14 @@ when defined(ssl): ErrLoadBioStrings() OpenSSL_add_all_algorithms() - proc SSLError(s = "") = + proc raiseSSLError(s = "") = if s != "": raise newException(ESSL, s) let err = ErrPeekLastError() if err == 0: raise newException(ESSL, "No error reported.") if err == -1: - OSError(OSLastError()) + raiseOSError(osLastError()) var errStr = ErrErrorString(err, nil) raise newException(ESSL, $errStr) @@ -272,18 +272,18 @@ when defined(ssl): if certFile != "": var ret = SSLCTXUseCertificateChainFile(ctx, certFile) if ret != 1: - SSLError() + raiseSslError() # TODO: Password? www.rtfm.com/openssl-examples/part1.pdf if keyFile != "": if SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) != 1: - SSLError() + raiseSslError() if SSL_CTX_check_private_key(ctx) != 1: - SSLError("Verification of private key file failed.") + raiseSslError("Verification of private key file failed.") - proc newContext*(protVersion = ProtSSLv23, verifyMode = CVerifyPeer, + proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer, certFile = "", keyFile = ""): PSSLContext = ## Creates an SSL context. ## @@ -308,21 +308,21 @@ when defined(ssl): when not defined(linux) and not defined(OpenBSD): newCTX = SSL_CTX_new(SSLv2_method()) else: - SSLError() + raiseSslError() of protSSLv3: newCTX = SSL_CTX_new(SSLv3_method()) of protTLSv1: newCTX = SSL_CTX_new(TLSv1_method()) if newCTX.SSLCTXSetCipherList("ALL") != 1: - SSLError() + raiseSslError() case verifyMode of CVerifyPeer: newCTX.SSLCTXSetVerify(SSLVerifyPeer, nil) of CVerifyNone: newCTX.SSLCTXSetVerify(SSLVerifyNone, nil) if newCTX == nil: - SSLError() + raiseSslError() discard newCTX.SSLCTXSetMode(SSL_MODE_AUTO_RETRY) newCTX.loadCertificates(certFile, keyFile) @@ -341,10 +341,10 @@ when defined(ssl): socket.sslNoHandshake = false socket.sslHasPeekChar = false if socket.sslHandle == nil: - SSLError() + raiseSslError() if SSLSetFd(socket.sslHandle, socket.fd) != 1: - SSLError() + raiseSslError() proc raiseSocketError*(socket: Socket, err: int = -1, async = false) = ## Raises proper errors based on return values of ``recv`` functions. @@ -359,20 +359,20 @@ proc raiseSocketError*(socket: Socket, err: int = -1, async = false) = var ret = SSLGetError(socket.sslHandle, err.cint) case ret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: if async: return - else: SSLError("Not enough data on socket.") + else: raiseSslError("Not enough data on socket.") of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: if async: return - else: SSLError("Not enough data on socket.") + else: raiseSslError("Not enough data on socket.") of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() - else: SSLError("Unknown Error") + raiseSslError() + else: raiseSslError("Unknown Error") if err == -1 and not (when defined(ssl): socket.isSSL else: false): let lastError = osLastError() @@ -545,16 +545,16 @@ proc acceptAddr*(server: Socket, client: var Socket, address: var string) {. if err != SSL_ERROR_WANT_ACCEPT: case err of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - SSLError("acceptAddrSSL should be used for non-blocking SSL sockets.") + raiseSslError("acceptAddrSSL should be used for non-blocking SSL sockets.") of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSslError() else: - SSLError("Unknown error") + raiseSslError("Unknown error") proc setBlocking*(s: Socket, blocking: bool) {.tags: [], gcsafe.} ## Sets blocking mode on socket @@ -591,17 +591,17 @@ when defined(ssl): if err != SSL_ERROR_WANT_ACCEPT: case err of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: client.sslNoHandshake = true return AcceptNoHandshake of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSslError() else: - SSLError("Unknown error") + raiseSslError("Unknown error") client.sslNoHandshake = false if client.isSSL and client.sslNoHandshake: @@ -813,16 +813,16 @@ proc connect*(socket: Socket, address: string, port = Port(0), let err = SSLGetError(socket.sslHandle, ret) case err of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - SSLError("The operation did not complete. Perhaps you should use connectAsync?") + raiseSslError("The operation did not complete. Perhaps you should use connectAsync?") of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSslError() else: - SSLError("Unknown error") + raiseSslError("Unknown error") when false: var s: TSockAddrIn @@ -901,19 +901,19 @@ when defined(ssl): var errret = SSLGetError(socket.sslHandle, ret) case errret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE: return false of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() + raiseSslError() else: - SSLError("Unknown Error") + raiseSslError("Unknown Error") socket.sslNoHandshake = false else: - SSLError("Socket is not an SSL socket.") + raiseSslError("Socket is not an SSL socket.") proc gotHandshake*(socket: TSocket): bool = ## Determines whether a handshake has occurred between a client (``socket``) @@ -923,7 +923,7 @@ when defined(ssl): if socket.isSSL: return not socket.sslNoHandshake else: - SSLError("Socket is not an SSL socket.") + raiseSslError("Socket is not an SSL socket.") proc timeValFromMilliseconds(timeout = 500): Timeval = if timeout != -1: @@ -1412,7 +1412,7 @@ proc recv*(socket: Socket): TaintedString {.tags: [ReadIOEffect], deprecated.} = while true: var bytesRead = recv(socket, cstring(buf), bufSize-1) # Error - if bytesRead == -1: OSError(OSLastError()) + if bytesRead == -1: OSError(osLastError()) buf[bytesRead] = '\0' # might not be necessary setLen(buf, bytesRead) @@ -1457,16 +1457,16 @@ proc recvAsync*(socket: Socket, s: var TaintedString): bool {. var ret = SSLGetError(socket.sslHandle, bytesRead.cint) case ret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - SSLError("Unexpected error occured.") # This should just not happen. + raiseSslError("Unexpected error occured.") # This should just not happen. of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: return false of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() - else: SSLError("Unknown Error") + raiseSslError() + else: raiseSslError("Unknown Error") if bytesRead == -1 and not (when defined(ssl): socket.isSSL else: false): let err = osLastError() @@ -1578,7 +1578,7 @@ proc send*(socket: Socket, data: string) {.tags: [WriteIOEffect].} = if sent < 0: when defined(ssl): if socket.isSSL: - SSLError() + raiseSslError() raiseOSError(osLastError()) @@ -1600,16 +1600,16 @@ proc sendAsync*(socket: Socket, data: string): int {.tags: [WriteIOEffect].} = let ret = SSLGetError(socket.sslHandle, result.cint) case ret of SSL_ERROR_ZERO_RETURN: - SSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + raiseSslError("TLS/SSL connection failed to initiate, socket closed prematurely.") of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: - SSLError("Unexpected error occured.") # This should just not happen. + raiseSslError("Unexpected error occured.") # This should just not happen. of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: return 0 of SSL_ERROR_WANT_X509_LOOKUP: - SSLError("Function for x509 lookup has been called.") + raiseSslError("Function for x509 lookup has been called.") of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: - SSLError() - else: SSLError("Unknown Error") + raiseSslError() + else: raiseSslError("Unknown Error") else: return if result == -1: @@ -1692,7 +1692,7 @@ discard """ proc setReuseAddr*(s: TSocket) = var blah: int = 1 var mode = SO_REUSEADDR if setsockopt(s.fd, SOL_SOCKET, mode, addr blah, TSOcklen(sizeof(int))) == -1: - OSError(OSLastError()) """ + raiseOSError(osLastError()) """ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, af: Domain = AF_INET) {.tags: [ReadIOEffect, WriteIOEffect].} = From bb1e87ce4d3e3e81e65609354667e5ed860f02c8 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sun, 31 Aug 2014 12:54:43 +0100 Subject: [PATCH 068/409] Async SSL support. --- lib/pure/asyncnet.nim | 174 +++++++++++++++++++++++++++++++++++---- lib/pure/httpclient.nim | 57 ++++++++----- lib/pure/net.nim | 15 ++-- lib/pure/smtp.nim | 5 +- lib/wrappers/openssl.nim | 51 ++++++++---- 5 files changed, 239 insertions(+), 63 deletions(-) diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 8734bab4c..f55442488 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -47,6 +47,7 @@ import asyncdispatch import rawsockets import net +import os when defined(ssl): import openssl @@ -54,7 +55,22 @@ when defined(ssl): type # TODO: I would prefer to just do: # PAsyncSocket* {.borrow: `.`.} = distinct PSocket. But that doesn't work. - AsyncSocketDesc {.borrow: `.`.} = distinct TSocketImpl + AsyncSocketDesc = object + fd*: SocketHandle + case isBuffered*: bool # determines whether this socket is buffered. + of true: + buffer*: array[0..BufferSize, char] + currPos*: int # current index in buffer + bufLen*: int # current length of buffer + of false: nil + case isSsl: bool + of true: + when defined(ssl): + sslHandle: SslPtr + sslContext: SslContext + bioIn: BIO + bioOut: BIO + of false: nil AsyncSocket* = ref AsyncSocketDesc {.deprecated: [PAsyncSocket: AsyncSocket].} @@ -63,7 +79,7 @@ type proc newSocket(fd: TAsyncFD, isBuff: bool): PAsyncSocket = assert fd != osInvalidSocket.TAsyncFD - new(result.PSocket) + new(result) result.fd = fd.SocketHandle result.isBuffered = isBuff if isBuff: @@ -74,22 +90,94 @@ proc newAsyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, ## Creates a new asynchronous socket. result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) +when defined(ssl): + proc getSslError(handle: SslPtr, err: cint): cint = + assert err < 0 + var ret = SSLGetError(handle, err.cint) + case ret + of SSL_ERROR_ZERO_RETURN: + raiseSSLError("TLS/SSL connection failed to initiate, socket closed prematurely.") + of SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: + return ret + of SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_READ: + return ret + of SSL_ERROR_WANT_X509_LOOKUP: + raiseSSLError("Function for x509 lookup has been called.") + of SSL_ERROR_SYSCALL, SSL_ERROR_SSL: + raiseSSLError() + else: raiseSSLError("Unknown Error") + + proc sendPendingSslData(socket: AsyncSocket, + flags: set[TSocketFlags]) {.async.} = + let len = bioCtrlPending(socket.bioOut) + if len > 0: + var data = newStringOfCap(len) + let read = bioRead(socket.bioOut, addr data[0], len) + assert read != 0 + if read < 0: + raiseSslError() + data.setLen(read) + await socket.fd.TAsyncFd.send(data, flags) + + proc appeaseSsl(socket: AsyncSocket, flags: set[TSocketFlags], + sslError: cint) {.async.} = + case sslError + of SSL_ERROR_WANT_WRITE: + await sendPendingSslData(socket, flags) + of SSL_ERROR_WANT_READ: + var data = await recv(socket.fd.TAsyncFD, BufferSize, flags) + let ret = bioWrite(socket.bioIn, addr data[0], data.len.cint) + if ret < 0: + raiseSSLError() + else: + raiseSSLError("Cannot appease SSL.") + + template sslLoop(socket: AsyncSocket, flags: set[TSocketFlags], + op: expr) = + var opResult {.inject.} = -1.cint + while opResult < 0: + opResult = op + # Bit hackish here. + # TODO: Introduce an async template transformation pragma? + yield sendPendingSslData(socket, flags) + if opResult < 0: + let err = getSslError(socket.sslHandle, opResult.cint) + yield appeaseSsl(socket, flags, err.cint) + proc connect*(socket: PAsyncSocket, address: string, port: TPort, - af = AF_INET): Future[void] = + af = AF_INET) {.async.} = ## Connects ``socket`` to server at ``address:port``. ## ## Returns a ``Future`` which will complete when the connection succeeds ## or an error occurs. - result = connect(socket.fd.TAsyncFD, address, port, af) + await connect(socket.fd.TAsyncFD, address, port, af) + let flags = {TSocketFlags.SafeDisconn} + if socket.isSsl: + when defined(ssl): + sslSetConnectState(socket.sslHandle) + sslLoop(socket, flags, sslDoHandshake(socket.sslHandle)) proc readIntoBuf(socket: PAsyncSocket, flags: set[TSocketFlags]): Future[int] {.async.} = var data = await recv(socket.fd.TAsyncFD, BufferSize, flags) if data.len != 0: copyMem(addr socket.buffer[0], addr data[0], data.len) - socket.bufLen = data.len - socket.currPos = 0 - result = data.len + if socket.isSsl: + when defined(ssl): + # SSL mode. + let ret = bioWrite(socket.bioIn, addr socket.buffer[0], data.len.cint) + if ret < 0: + raiseSSLError() + sslLoop(socket, flags, + sslRead(socket.sslHandle, addr socket.buffer[0], BufferSize.cint)) + socket.currPos = 0 + socket.bufLen = opResult # Injected from sslLoop template. + result = opResult + else: + # Not in SSL mode. + socket.bufLen = data.len + socket.currPos = 0 + result = data.len proc recv*(socket: PAsyncSocket, size: int, flags = {TSocketFlags.SafeDisconn}): Future[string] {.async.} = @@ -131,11 +219,18 @@ proc recv*(socket: PAsyncSocket, size: int, result = await recv(socket.fd.TAsyncFD, size, flags) proc send*(socket: PAsyncSocket, data: string, - flags = {TSocketFlags.SafeDisconn}): Future[void] = + flags = {TSocketFlags.SafeDisconn}) {.async.} = ## Sends ``data`` to ``socket``. The returned future will complete once all ## data has been sent. assert socket != nil - result = send(socket.fd.TAsyncFD, data, flags) + if socket.isSsl: + when defined(ssl): + var copy = data + sslLoop(socket, flags, + sslWrite(socket.sslHandle, addr copy[0], copy.len.cint)) + await sendPendingSslData(socket, flags) + else: + await send(socket.fd.TAsyncFD, data, flags) proc acceptAddr*(socket: PAsyncSocket, flags = {TSocketFlags.SafeDisconn}): Future[tuple[address: string, client: PAsyncSocket]] = @@ -240,24 +335,67 @@ proc recvLine*(socket: PAsyncSocket, return add(result.string, c) -proc bindAddr*(socket: PAsyncSocket, port = TPort(0), address = "") = - ## Binds ``address``:``port`` to the socket. - ## - ## If ``address`` is "" then ADDR_ANY will be bound. - socket.PSocket.bindAddr(port, address) - -proc listen*(socket: PAsyncSocket, backlog = SOMAXCONN) = +proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. ## ## Raises an EOS error upon failure. - socket.PSocket.listen(backlog) + if listen(socket.fd, backlog) < 0'i32: raiseOSError(osLastError()) + +proc bindAddr*(socket: Socket, port = Port(0), address = "") {. + tags: [ReadIOEffect].} = + ## Binds ``address``:``port`` to the socket. + ## + ## If ``address`` is "" then ADDR_ANY will be bound. + + if address == "": + var name: Sockaddr_in + when defined(Windows) or defined(nimdoc): + name.sin_family = toInt(AF_INET).int16 + else: + name.sin_family = toInt(AF_INET) + name.sin_port = htons(int16(port)) + name.sin_addr.s_addr = htonl(INADDR_ANY) + if bindAddr(socket.fd, cast[ptr SockAddr](addr(name)), + sizeof(name).Socklen) < 0'i32: + raiseOSError(osLastError()) + else: + var aiList = getAddrInfo(address, port, AF_INET) + if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32: + dealloc(aiList) + raiseOSError(osLastError()) + dealloc(aiList) proc close*(socket: PAsyncSocket) = ## Closes the socket. socket.fd.TAsyncFD.closeSocket() - # TODO SSL + when defined(ssl): + if socket.isSSL: + let res = SslShutdown(socket.sslHandle) + if res == 0: + if SslShutdown(socket.sslHandle) != 1: + raiseSslError() + elif res != 1: + raiseSslError() + +when defined(ssl): + proc wrapSocket*(ctx: SslContext, socket: AsyncSocket) = + ## Wraps a socket in an SSL context. This function effectively turns + ## ``socket`` into an SSL socket. + ## + ## **Disclaimer**: This code is not well tested, may be very unsafe and + ## prone to security vulnerabilities. + socket.isSsl = true + socket.sslContext = ctx + socket.sslHandle = SSLNew(PSSLCTX(socket.sslContext)) + if socket.sslHandle == nil: + raiseSslError() + + socket.bioIn = bioNew(bio_s_mem()) + socket.bioOut = bioNew(bio_s_mem()) + sslSetBio(socket.sslHandle, socket.bioIn, socket.bioOut) + when isMainModule: type diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index c5e657bab..8b19c58f8 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -78,6 +78,7 @@ import sockets, strutils, parseurl, parseutils, strtabs, base64, os import asyncnet, asyncdispatch import rawsockets +from net import nil type Response* = tuple[ @@ -164,16 +165,17 @@ proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = var contentLengthHeader = headers["Content-Length"] if contentLengthHeader != "": var length = contentLengthHeader.parseint() - result = newString(length) - var received = 0 - while true: - if received >= length: break - let r = s.recv(addr(result[received]), length-received, timeout) - if r == 0: break - received += r - if received != length: - httpError("Got invalid content length. Expected: " & $length & - " got: " & $received) + if length > 0: + result = newString(length) + var received = 0 + while true: + if received >= length: break + let r = s.recv(addr(result[received]), length-received, timeout) + if r == 0: break + received += r + if received != length: + httpError("Got invalid content length. Expected: " & $length & + " got: " & $received) else: # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO @@ -444,11 +446,13 @@ type headers: StringTableRef maxRedirects: int userAgent: string + when defined(ssl): + sslContext: net.SslContext {.deprecated: [PAsyncHttpClient: AsyncHttpClient].} proc newAsyncHttpClient*(userAgent = defUserAgent, - maxRedirects = 5): AsyncHttpClient = + maxRedirects = 5, sslContext = defaultSslContext): AsyncHttpClient = ## Creates a new PAsyncHttpClient instance. ## ## ``userAgent`` specifies the user agent that will be used when making @@ -456,10 +460,13 @@ proc newAsyncHttpClient*(userAgent = defUserAgent, ## ## ``maxRedirects`` specifies the maximum amount of redirects to follow, ## default is 5. + ## + ## ``sslContext`` specifies the SSL context to use for HTTPS requests. new result result.headers = newStringTable(modeCaseInsensitive) result.userAgent = defUserAgent result.maxRedirects = maxRedirects + result.sslContext = net.SslContext(sslContext) proc close*(client: AsyncHttpClient) = ## Closes any connections held by the HTTP client. @@ -519,12 +526,13 @@ proc parseBody(client: PAsyncHttpClient, var contentLengthHeader = headers["Content-Length"] if contentLengthHeader != "": var length = contentLengthHeader.parseint() - result = await client.socket.recvFull(length) - if result == "": - httpError("Got disconnected while trying to read body.") - if result.len != length: - httpError("Received length doesn't match expected length. Wanted " & - $length & " got " & $result.len) + if length > 0: + result = await client.socket.recvFull(length) + if result == "": + httpError("Got disconnected while trying to read body.") + if result.len != length: + httpError("Received length doesn't match expected length. Wanted " & + $length & " got " & $result.len) else: # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO @@ -590,14 +598,23 @@ proc newConnection(client: PAsyncHttpClient, url: TURL) {.async.} = client.currentURL.scheme != url.scheme: if client.connected: client.close() client.socket = newAsyncSocket() - if url.scheme == "https": - assert false, "TODO SSL" # TODO: I should be able to write 'net.TPort' here... let port = - if url.port == "": rawsockets.TPort(80) + if url.port == "": + if url.scheme.toLower() == "https": + rawsockets.TPort(443) + else: + rawsockets.TPort(80) else: rawsockets.TPort(url.port.parseInt) + if url.scheme.toLower() == "https": + when defined(ssl): + client.sslContext.wrapSocket(client.socket) + else: + raise newException(EHttpRequestErr, + "SSL support is not available. Cannot connect over SSL.") + await client.socket.connect(url.hostname, port) client.currentURL = url client.connected = true diff --git a/lib/pure/net.nim b/lib/pure/net.nim index fd485340c..5f202f05c 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -22,17 +22,17 @@ when defined(ssl): when defined(ssl): type - SSLError* = object of Exception + SslError* = object of Exception - SSLCVerifyMode* = enum + SslCVerifyMode* = enum CVerifyNone, CVerifyPeer - SSLProtVersion* = enum + SslProtVersion* = enum protSSLv2, protSSLv3, protTLSv1, protSSLv23 - SSLContext* = distinct PSSLCTX + SslContext* = distinct SslCtx - SSLAcceptResult* = enum + SslAcceptResult* = enum AcceptNoClient = 0, AcceptNoHandshake, AcceptSuccess {.deprecated: [ESSL: SSLError, TSSLCVerifyMode: SSLCVerifyMode, @@ -125,7 +125,8 @@ when defined(ssl): ErrLoadBioStrings() OpenSSL_add_all_algorithms() - proc raiseSSLError(s = "") = + proc raiseSSLError*(s = "") = + ## Raises a new SSL error. if s != "": raise newException(SSLError, s) let err = ErrPeekLastError() @@ -161,7 +162,7 @@ when defined(ssl): certFile = "", keyFile = ""): PSSLContext = ## Creates an SSL context. ## - ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are + ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 ## are available with the addition of ``protSSLv23`` which allows for ## compatibility with all of them. ## diff --git a/lib/pure/smtp.nim b/lib/pure/smtp.nim index 83eb60807..dbe2ae203 100644 --- a/lib/pure/smtp.nim +++ b/lib/pure/smtp.nim @@ -44,8 +44,11 @@ type ReplyError* = object of IOError + AsyncSmtp* = ref object + sock: AsyncSocket + {.deprecated: [EInvalidReply: ReplyError, TMessage: Message, TSMTP: Smtp].} - + proc debugSend(smtp: TSMTP, cmd: string) = if smtp.debug: echo("C:" & cmd) diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index da684eed9..7f24507ba 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -63,14 +63,13 @@ type SslStruct {.final, pure.} = object SslPtr* = ptr SslStruct PSslPtr* = ptr SslPtr - PSSL_CTX* = SslPtr - PSSL* = SslPtr + SslCtx* = SslPtr PSSL_METHOD* = SslPtr PX509* = SslPtr PX509_NAME* = SslPtr PEVP_MD* = SslPtr PBIO_METHOD* = SslPtr - PBIO* = SslPtr + BIO* = SslPtr EVP_PKEY* = SslPtr PRSA* = SslPtr PASN1_UTCTIME* = SslPtr @@ -85,6 +84,8 @@ type des_key_schedule* = array[1..16, des_ks_struct] +{.deprecated: [PSSL: SslPtr, PSSL_CTX: SslCtx, PBIO: BIO].} + const EVP_MAX_MD_SIZE* = 16 + 20 SSL_ERROR_NONE* = 0 @@ -282,6 +283,34 @@ proc SSL_CTX_ctrl*(ctx: PSSL_CTX, cmd: cInt, larg: int, parg: pointer): int{. proc SSLCTXSetMode*(ctx: PSSL_CTX, mode: int): int = result = SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, mode, nil) +proc bioNew*(b: PBIO_METHOD): PBIO{.cdecl, dynlib: DLLUtilName, importc: "BIO_new".} +proc bioFreeAll*(b: PBIO){.cdecl, dynlib: DLLUtilName, importc: "BIO_free_all".} +proc bioSMem*(): PBIO_METHOD{.cdecl, dynlib: DLLUtilName, importc: "BIO_s_mem".} +proc bioCtrlPending*(b: PBIO): cInt{.cdecl, dynlib: DLLUtilName, importc: "BIO_ctrl_pending".} +proc bioRead*(b: PBIO, Buf: cstring, length: cInt): cInt{.cdecl, + dynlib: DLLUtilName, importc: "BIO_read".} +proc bioWrite*(b: PBIO, Buf: cstring, length: cInt): cInt{.cdecl, + dynlib: DLLUtilName, importc: "BIO_write".} + +proc sslSetConnectState*(s: SslPtr) {.cdecl, + dynlib: DLLSSLName, importc: "SSL_set_connect_state".} +proc sslSetAcceptState*(s: SslPtr) {.cdecl, + dynlib: DLLSSLName, importc: "SSL_set_accept_state".} + +proc sslRead*(ssl: SslPtr, buf: cstring, num: cInt): cInt{.cdecl, + dynlib: DLLSSLName, importc: "SSL_read".} +proc sslPeek*(ssl: SslPtr, buf: cstring, num: cInt): cInt{.cdecl, + dynlib: DLLSSLName, importc: "SSL_peek".} +proc sslWrite*(ssl: SslPtr, buf: cstring, num: cInt): cInt{.cdecl, + dynlib: DLLSSLName, importc: "SSL_write".} + +proc sslSetBio*(ssl: SslPtr, rbio, wbio: BIO) {.cdecl, + dynlib: DLLSSLName, importc: "SSL_set_bio".} + +proc sslDoHandshake*(ssl: SslPtr): cint {.cdecl, + dynlib: DLLSSLName, importc: "SSL_do_handshake".} + + when true: discard else: @@ -328,12 +357,7 @@ else: proc SslConnect*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} - proc SslRead*(ssl: PSSL, buf: SslPtr, num: cInt): cInt{.cdecl, - dynlib: DLLSSLName, importc.} - proc SslPeek*(ssl: PSSL, buf: SslPtr, num: cInt): cInt{.cdecl, - dynlib: DLLSSLName, importc.} - proc SslWrite*(ssl: PSSL, buf: SslPtr, num: cInt): cInt{.cdecl, - dynlib: DLLSSLName, importc.} + proc SslGetVersion*(ssl: PSSL): cstring{.cdecl, dynlib: DLLSSLName, importc.} proc SslGetPeerCertificate*(ssl: PSSL): PX509{.cdecl, dynlib: DLLSSLName, importc.} @@ -393,14 +417,7 @@ else: proc OPENSSLaddallalgorithms*(){.cdecl, dynlib: DLLUtilName, importc.} proc CRYPTOcleanupAllExData*(){.cdecl, dynlib: DLLUtilName, importc.} proc RandScreen*(){.cdecl, dynlib: DLLUtilName, importc.} - proc BioNew*(b: PBIO_METHOD): PBIO{.cdecl, dynlib: DLLUtilName, importc.} - proc BioFreeAll*(b: PBIO){.cdecl, dynlib: DLLUtilName, importc.} - proc BioSMem*(): PBIO_METHOD{.cdecl, dynlib: DLLUtilName, importc.} - proc BioCtrlPending*(b: PBIO): cInt{.cdecl, dynlib: DLLUtilName, importc.} - proc BioRead*(b: PBIO, Buf: cstring, length: cInt): cInt{.cdecl, - dynlib: DLLUtilName, importc.} - proc BioWrite*(b: PBIO, Buf: cstring, length: cInt): cInt{.cdecl, - dynlib: DLLUtilName, importc.} + proc d2iPKCS12bio*(b: PBIO, Pkcs12: SslPtr): SslPtr{.cdecl, dynlib: DLLUtilName, importc.} proc PKCS12parse*(p12: SslPtr, pass: cstring, pkey, cert, ca: var SslPtr): cint{. From 25e0c26a91c0336694ffbbd64341d623923f9580 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sun, 31 Aug 2014 14:07:20 +0100 Subject: [PATCH 069/409] Added async implementation for smtp module. --- lib/pure/smtp.nim | 122 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 17 deletions(-) diff --git a/lib/pure/smtp.nim b/lib/pure/smtp.nim index dbe2ae203..e088e0bd9 100644 --- a/lib/pure/smtp.nim +++ b/lib/pure/smtp.nim @@ -28,7 +28,8 @@ ## For SSL support this module relies on OpenSSL. If you want to ## enable SSL, compile with ``-d:ssl``. -import sockets, strutils, strtabs, base64, os +import net, strutils, strtabs, base64, os +import asyncnet, asyncdispatch type Smtp* = object @@ -46,6 +47,10 @@ type AsyncSmtp* = ref object sock: AsyncSocket + address: string + port: Port + useSsl: bool + debug: bool {.deprecated: [EInvalidReply: ReplyError, TMessage: Message, TSMTP: Smtp].} @@ -73,19 +78,25 @@ proc checkReply(smtp: var TSMTP, reply: string) = const compiledWithSsl = defined(ssl) -proc connect*(address: string, port = 25, - ssl = false, debug = false): TSMTP = +when not defined(ssl): + type PSSLContext = ref object + let defaultSSLContext: PSSLContext = nil +else: + let defaultSSLContext = newContext(verifyMode = CVerifyNone) + +proc connect*(address: string, port = Port(25), + ssl = false, debug = false, + sslContext = defaultSSLContext): TSMTP = ## Establishes a connection with a SMTP server. ## May fail with EInvalidReply or with a socket error. - result.sock = socket() + result.sock = newSocket() if ssl: when compiledWithSsl: - let ctx = newContext(verifyMode = CVerifyNone) - ctx.wrapSocket(result.sock) + sslContext.wrapSocket(result.sock) else: raise newException(ESystem, "SMTP module compiled without SSL support") - result.sock.connect(address, TPort(port)) + result.sock.connect(address, port) result.debug = debug result.checkReply("220") @@ -165,6 +176,82 @@ proc `$`*(msg: TMessage): string = result.add("\c\L") result.add(msg.msgBody) +proc newAsyncSmtp*(address: string, port: Port, useSsl = false, + sslContext = defaultSslContext): AsyncSmtp = + ## Creates a new ``AsyncSmtp`` instance. + new result + result.address = address + result.port = port + result.useSsl = useSsl + + result.sock = newAsyncSocket() + if useSsl: + when compiledWithSsl: + sslContext.wrapSocket(result.sock) + else: + raise newException(ESystem, + "SMTP module compiled without SSL support") + +proc quitExcpt(smtp: AsyncSmtp, msg: string): PFuture[void] = + var retFuture = newFuture[void]() + var sendFut = smtp.sock.send("QUIT") + sendFut.callback = + proc () = + # TODO: Fix this in async procs. + raise newException(ReplyError, msg) + return retFuture + +proc checkReply(smtp: AsyncSmtp, reply: string) {.async.} = + var line = await smtp.sock.recvLine() + if not line.string.startswith(reply): + await quitExcpt(smtp, "Expected " & reply & " reply, got: " & line.string) + +proc connect*(smtp: AsyncSmtp) {.async.} = + ## Establishes a connection with a SMTP server. + ## May fail with EInvalidReply or with a socket error. + await smtp.sock.connect(smtp.address, smtp.port) + + await smtp.checkReply("220") + await smtp.sock.send("HELO " & smtp.address & "\c\L") + await smtp.checkReply("250") + +proc auth*(smtp: AsyncSmtp, username, password: string) {.async.} = + ## Sends an AUTH command to the server to login as the `username` + ## using `password`. + ## May fail with EInvalidReply. + + await smtp.sock.send("AUTH LOGIN\c\L") + await smtp.checkReply("334") # TODO: Check whether it's asking for the "Username:" + # i.e "334 VXNlcm5hbWU6" + await smtp.sock.send(encode(username) & "\c\L") + await smtp.checkReply("334") # TODO: Same as above, only "Password:" (I think?) + + await smtp.sock.send(encode(password) & "\c\L") + await smtp.checkReply("235") # Check whether the authentification was successful. + +proc sendMail*(smtp: AsyncSmtp, fromAddr: string, + toAddrs: seq[string], msg: string) {.async.} = + ## Sends ``msg`` from ``fromAddr`` to the addresses specified in ``toAddrs``. + ## Messages may be formed using ``createMessage`` by converting the + ## TMessage into a string. + + await smtp.sock.send("MAIL FROM:<" & fromAddr & ">\c\L") + await smtp.checkReply("250") + for address in items(toAddrs): + await smtp.sock.send("RCPT TO:<" & smtp.address & ">\c\L") + await smtp.checkReply("250") + + # Send the message + await smtp.sock.send("DATA " & "\c\L") + await smtp.checkReply("354") + await smtp.sock.send(msg & "\c\L") + await smtp.sock.send(".\c\L") + await smtp.checkReply("250") + +proc close*(smtp: AsyncSmtp) {.async.} = + ## Disconnects from the SMTP server and closes the socket. + await smtp.sock.send("QUIT\c\L") + smtp.sock.close() when isMainModule: #var msg = createMessage("Test subject!", @@ -175,15 +262,16 @@ when isMainModule: #smtp.sendmail("root@localhost", @["dominik@localhost"], $msg) #echo(decode("a17sm3701420wbe.12")) - var msg = createMessage("Hello from Nim's SMTP!", - "Hello!!!!.\n Is this awesome or what?", - @["someone@yahoo.com", "someone@gmail.com"]) - echo(msg) + proc main() {.async.} = + var client = newAsyncSmtp("smtp.gmail.com", Port(465), true) + await client.connect() + await client.auth("johndoe", "foo") + var msg = createMessage("Hello from Nim's SMTP!", + "Hello!!!!.\n Is this awesome or what?", + @["blah@gmail.com"]) + echo(msg) + await client.sendMail("blah@gmail.com", @["blah@gmail.com"], $msg) - var smtp = connect("smtp.gmail.com", 465, True, True) - smtp.auth("someone", "password") - smtp.sendmail("someone@gmail.com", - @["someone@yahoo.com", "someone@gmail.com"], $msg) - smtp.close() + await client.close() - + waitFor main() From 30823c1ce3992d48251069af48ed9d26b1238ba4 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 15:15:26 +0200 Subject: [PATCH 070/409] make tests green --- lib/core/locks.nim | 20 +- lib/pure/gentabs.nim | 16 +- lib/pure/htmlparser.nim | 34 +-- lib/pure/parsexml.nim | 32 +-- lib/pure/ropes.nim | 18 +- lib/system.nim | 4 +- lib/system/atomics.nim | 2 +- lib/system/channels.nim | 16 +- lib/system/gc_ms.nim | 52 ++--- lib/system/jssys.nim | 26 +-- lib/system/threads.nim | 60 ++++-- tests/casestmt/tcasestm.nim | 2 +- tests/concurrency/tnodeadlocks.nim | 52 ++--- tests/constr/tconstr1.nim | 2 +- tests/float/tfloat1.nim | 4 +- tests/float/tfloat2.nim | 4 +- tests/float/tfloat3.nim | 2 +- tests/gc/closureleak.nim | 2 +- tests/generics/texplicitgeneric1.nim | 2 +- tests/generics/tgeneric2.nim | 6 +- tests/generics/tgeneric3.nim | 312 +++++++++++++-------------- tests/generics/tgenericprocvar.nim | 2 +- tests/generics/tgenericvariant.nim | 8 +- tests/iter/titer2.nim | 4 +- tests/iter/titer6.nim | 4 +- tests/iter/titer8.nim | 4 +- tests/lookups/tkoeniglookup.nim | 2 +- tests/misc/tlastmod.nim | 8 +- tests/misc/tloops.nim | 2 +- tests/misc/tnot.nim | 6 +- tests/misc/tpos.nim | 6 +- tests/misc/tprep.nim | 4 +- tests/misc/tradix.nim | 20 +- tests/misc/treadln.nim | 4 +- tests/misc/tsimplesort.nim | 42 ++-- tests/misc/tvarnums.nim | 2 +- tests/objvariant/tyaoption.nim | 12 +- tests/overflw/toverflw.nim | 2 +- tests/overflw/toverflw2.nim | 2 +- tests/procvar/tprocvars.nim | 6 +- tests/types/tforwty2.nim | 2 +- tests/types/tillrec.nim | 2 +- tests/varstmt/tlet.nim | 2 +- tests/vm/tconsteval.nim | 4 +- 44 files changed, 415 insertions(+), 403 deletions(-) diff --git a/lib/core/locks.nim b/lib/core/locks.nim index d865c78c5..42a3aec7b 100644 --- a/lib/core/locks.nim +++ b/lib/core/locks.nim @@ -23,12 +23,14 @@ type ## in preventDeadlocks-mode guarantees re-entrancy. TCond* = TSysCond ## Nim condition variable - FLock* = object of TEffect ## effect that denotes that some lock operation - ## is performed - FAquireLock* = object of FLock ## effect that denotes that some lock is - ## aquired - FReleaseLock* = object of FLock ## effect that denotes that some lock is - ## released + LockEffect* = object of RootEffect ## effect that denotes that some lock operation + ## is performed + AquireEffect* = object of LockEffect ## effect that denotes that some lock is + ## aquired + ReleaseEffect* = object of LockEffect ## effect that denotes that some lock is + ## released +{.deprecated: [FLock: LockEffect, FAquireLock: AquireEffect, + FReleaseLock: ReleaseEffect].} const noDeadlocks = defined(preventDeadlocks) @@ -58,7 +60,7 @@ proc deinitLock*(lock: var TLock) {.inline.} = ## Frees the resources associated with the lock. deinitSys(lock) -proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} = +proc tryAcquire*(lock: var TLock): bool {.tags: [AquireEffect].} = ## Tries to acquire the given lock. Returns `true` on success. result = tryAcquireSys(lock) when noDeadlocks: @@ -90,7 +92,7 @@ proc tryAcquire*(lock: var TLock): bool {.tags: [FAquireLock].} = inc(locksLen) assert orderedLocks() -proc acquire*(lock: var TLock) {.tags: [FAquireLock].} = +proc acquire*(lock: var TLock) {.tags: [AquireEffect].} = ## Acquires the given lock. when nodeadlocks: var p = addr(lock) @@ -135,7 +137,7 @@ proc acquire*(lock: var TLock) {.tags: [FAquireLock].} = else: acquireSys(lock) -proc release*(lock: var TLock) {.tags: [FReleaseLock].} = +proc release*(lock: var TLock) {.tags: [ReleaseEffect].} = ## Releases the given lock. when nodeadlocks: var p = addr(lock) diff --git a/lib/pure/gentabs.nim b/lib/pure/gentabs.nim index 694bfb542..a6128efc9 100644 --- a/lib/pure/gentabs.nim +++ b/lib/pure/gentabs.nim @@ -74,7 +74,7 @@ proc newGenTable*[T](mode: TGenTableMode): PGenTable[T] = proc nextTry(h, maxHash: THash): THash {.inline.} = result = ((5 * h) + 1) and maxHash -proc RawGet[T](tbl: PGenTable[T], key: string): int = +proc rawGet[T](tbl: PGenTable[T], key: string): int = var h: THash h = myhash(tbl, key) and high(tbl.data) # start with real hash value while not isNil(tbl.data[h].key): @@ -83,7 +83,7 @@ proc RawGet[T](tbl: PGenTable[T], key: string): int = h = nextTry(h, high(tbl.data)) result = - 1 -proc RawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T], +proc rawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T], key: string, val: T) = var h: THash h = myhash(tbl, key) and high(data) @@ -92,12 +92,12 @@ proc RawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T], data[h].key = key data[h].val = val -proc Enlarge[T](tbl: PGenTable[T]) = +proc enlarge[T](tbl: PGenTable[T]) = var n: TGenKeyValuePairSeq[T] newSeq(n, len(tbl.data) * growthFactor) for i in countup(0, high(tbl.data)): if not isNil(tbl.data[i].key): - RawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val) + rawInsert[T](tbl, n, tbl.data[i].key, tbl.data[i].val) swap(tbl.data, n) proc hasKey*[T](tbl: PGenTable[T], key: string): bool = @@ -108,17 +108,17 @@ proc `[]`*[T](tbl: PGenTable[T], key: string): T = ## retrieves the value at ``tbl[key]``. If `key` is not in `tbl`, ## default(T) is returned and no exception is raised. One can check ## with ``hasKey`` whether the key exists. - var index = RawGet(tbl, key) + var index = rawGet(tbl, key) if index >= 0: result = tbl.data[index].val proc `[]=`*[T](tbl: PGenTable[T], key: string, val: T) = ## puts a (key, value)-pair into `tbl`. - var index = RawGet(tbl, key) + var index = rawGet(tbl, key) if index >= 0: tbl.data[index].val = val else: - if mustRehash(len(tbl.data), tbl.counter): Enlarge(tbl) - RawInsert(tbl, tbl.data, key, val) + if mustRehash(len(tbl.data), tbl.counter): enlarge(tbl) + rawInsert(tbl, tbl.data, key, val) inc(tbl.counter) diff --git a/lib/pure/htmlparser.nim b/lib/pure/htmlparser.nim index 54e917110..e2cbb4949 100644 --- a/lib/pure/htmlparser.nim +++ b/lib/pure/htmlparser.nim @@ -422,7 +422,7 @@ proc toHtmlTag(s: string): THtmlTag = of "wbr": tagWbr else: tagUnknown -proc htmlTag*(n: PXmlNode): THtmlTag = +proc htmlTag*(n: XmlNode): THtmlTag = ## gets `n`'s tag as a ``THtmlTag``. if n.clientData == 0: n.clientData = toHtmlTag(n.tag).ord @@ -438,24 +438,24 @@ proc entityToUtf8*(entity: string): string = ## converts an HTML entity name like ``Ü`` to its UTF-8 equivalent. ## "" is returned if the entity name is unknown. The HTML parser ## already converts entities to UTF-8. - for name, val in items(entities): - if name == entity: return toUTF8(TRune(val)) + for name, val in items(Entities): + if name == entity: return toUTF8(Rune(val)) result = "" -proc addNode(father, son: PXmlNode) = +proc addNode(father, son: XmlNode) = if son != nil: add(father, son) -proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode +proc parse(x: var XmlParser, errors: var seq[string]): XmlNode -proc expected(x: var TXmlParser, n: PXmlNode): string = +proc expected(x: var XmlParser, n: XmlNode): string = result = errorMsg(x, " expected") template elemName(x: expr): expr = rawData(x) -proc untilElementEnd(x: var TXmlParser, result: PXmlNode, +proc untilElementEnd(x: var XmlParser, result: XmlNode, errors: var seq[string]) = # we parsed e.g. ``
`` and don't really expect a ``
``: - if result.htmlTag in singleTags: + if result.htmlTag in SingleTags: if x.kind != xmlElementEnd or cmpIgnoreCase(x.elemName, result.tag) != 0: return while true: @@ -496,7 +496,7 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode, else: result.addNode(parse(x, errors)) -proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = +proc parse(x: var XmlParser, errors: var seq[string]): XmlNode = case x.kind of xmlComment: result = newComment(x.rawData) @@ -549,11 +549,11 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode = next(x) of xmlEof: discard -proc parseHtml*(s: PStream, filename: string, - errors: var seq[string]): PXmlNode = +proc parseHtml*(s: Stream, filename: string, + errors: var seq[string]): XmlNode = ## parses the XML from stream `s` and returns a ``PXmlNode``. Every ## occured parsing error is added to the `errors` sequence. - var x: TXmlParser + var x: XmlParser open(x, s, filename, {reportComments, reportWhitespace}) next(x) # skip the DOCTYPE: @@ -573,21 +573,21 @@ proc parseHtml*(s: PStream, filename: string, if result.len == 1: result = result[0] -proc parseHtml*(s: PStream): PXmlNode = +proc parseHtml*(s: Stream): XmlNode = ## parses the XTML from stream `s` and returns a ``PXmlNode``. All parsing ## errors are ignored. var errors: seq[string] = @[] result = parseHtml(s, "unknown_html_doc", errors) -proc loadHtml*(path: string, errors: var seq[string]): PXmlNode = +proc loadHtml*(path: string, errors: var seq[string]): XmlNode = ## Loads and parses HTML from file specified by ``path``, and returns ## a ``PXmlNode``. Every occured parsing error is added to ## the `errors` sequence. var s = newFileStream(path, fmRead) - if s == nil: raise newException(EIO, "Unable to read file: " & path) + if s == nil: raise newException(IOError, "Unable to read file: " & path) result = parseHtml(s, path, errors) -proc loadHtml*(path: string): PXmlNode = +proc loadHtml*(path: string): XmlNode = ## Loads and parses HTML from file specified by ``path``, and returns ## a ``PXmlNode``. All parsing errors are ignored. var errors: seq[string] = @[] @@ -600,7 +600,7 @@ when isMainModule: var x = loadHtml(paramStr(1), errors) for e in items(errors): echo e - var f: TFile + var f: File if open(f, "test.txt", fmWrite): f.write($x) f.close() diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index 9b2814b84..66135a971 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -276,14 +276,14 @@ proc parseComment(my: var XmlParser) = my.bufpos = pos my.kind = xmlComment -proc parseWhitespace(my: var XmlParser, skip=False) = +proc parseWhitespace(my: var XmlParser, skip=false) = var pos = my.bufpos var buf = my.buf while true: case buf[pos] of ' ', '\t': if not skip: add(my.a, buf[pos]) - Inc(pos) + inc(pos) of '\c': # the specification says that CR-LF, CR are to be transformed to LF pos = lexbase.handleCR(my, pos) @@ -304,7 +304,7 @@ const proc parseName(my: var XmlParser, dest: var string) = var pos = my.bufpos var buf = my.buf - if buf[pos] in nameStartChar: + if buf[pos] in NameStartChar: while true: add(dest, buf[pos]) inc(pos) @@ -385,11 +385,11 @@ proc parsePI(my: var XmlParser) = inc(pos) of '\c': # the specification says that CR-LF, CR are to be transformed to LF - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.b, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.b, '\L') else: @@ -420,11 +420,11 @@ proc parseSpecial(my: var XmlParser) = inc(pos) add(my.a, '>') of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.a, '\L') else: @@ -441,7 +441,7 @@ proc parseTag(my: var XmlParser) = my.kind = xmlCharData add(my.a, '<') return - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) if my.buf[my.bufpos] in NameStartChar: # an attribute follows: my.kind = xmlElementOpen @@ -461,7 +461,7 @@ proc parseTag(my: var XmlParser) = proc parseEndTag(my: var XmlParser) = inc(my.bufpos, 2) parseName(my, my.a) - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) if my.buf[my.bufpos] == '>': inc(my.bufpos) else: @@ -477,12 +477,12 @@ proc parseAttribute(my: var XmlParser) = if my.a.len == 0: markError(my, errGtExpected) return - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) if my.buf[my.bufpos] != '=': markError(my, errEqExpected) return inc(my.bufpos) - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) var pos = my.bufpos var buf = my.buf @@ -507,11 +507,11 @@ proc parseAttribute(my: var XmlParser) = pendingSpace = true inc(pos) of '\c': - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf pendingSpace = true of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf pendingSpace = true else: @@ -527,7 +527,7 @@ proc parseAttribute(my: var XmlParser) = else: markError(my, errQuoteExpected) my.bufpos = pos - parseWhitespace(my, skip=True) + parseWhitespace(my, skip=true) proc parseCharData(my: var XmlParser) = var pos = my.bufpos @@ -537,11 +537,11 @@ proc parseCharData(my: var XmlParser) = of '\0', '<', '&': break of '\c': # the specification says that CR-LF, CR are to be transformed to LF - pos = lexbase.HandleCR(my, pos) + pos = lexbase.handleCR(my, pos) buf = my.buf add(my.a, '\L') of '\L': - pos = lexbase.HandleLF(my, pos) + pos = lexbase.handleLF(my, pos) buf = my.buf add(my.a, '\L') else: diff --git a/lib/pure/ropes.nim b/lib/pure/ropes.nim index 8b0661063..995dff2aa 100644 --- a/lib/pure/ropes.nim +++ b/lib/pure/ropes.nim @@ -186,7 +186,7 @@ proc `&`*(a: string, b: Rope): Rope {.rtl, extern: "nroConcStrRope".} = ## the concatenation operator for ropes. result = rope(a) & b -proc `&`*(a: openarray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} = +proc `&`*(a: openArray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} = ## the concatenation operator for an openarray of ropes. for i in countup(0, high(a)): result = result & a[i] @@ -233,7 +233,7 @@ iterator items*(r: Rope): char = for s in leaves(r): for c in items(s): yield c -proc write*(f: TFile, r: Rope) {.rtl, extern: "nro$1".} = +proc write*(f: File, r: Rope) {.rtl, extern: "nro$1".} = ## writes a rope to a file. for s in leaves(r): write(f, s) @@ -291,7 +291,7 @@ when false: if i - 1 >= start: add(result, substr(frmt, start, i-1)) -proc `%`*(frmt: string, args: openarray[Rope]): Rope {. +proc `%`*(frmt: string, args: openArray[Rope]): Rope {. rtl, extern: "nroFormat".} = ## `%` substitution operator for ropes. Does not support the ``$identifier`` ## nor ``${identifier}`` notations. @@ -324,9 +324,9 @@ proc `%`*(frmt: string, args: openarray[Rope]): Rope {. j = j * 10 + ord(frmt[i]) - ord('0') inc(i) if frmt[i] == '}': inc(i) - else: raise newException(EInvalidValue, "invalid format string") + else: raise newException(ValueError, "invalid format string") add(result, args[j-1]) - else: raise newException(EInvalidValue, "invalid format string") + else: raise newException(ValueError, "invalid format string") var start = i while i < length: if frmt[i] != '$': inc(i) @@ -334,15 +334,15 @@ proc `%`*(frmt: string, args: openarray[Rope]): Rope {. if i - 1 >= start: add(result, substr(frmt, start, i - 1)) -proc addf*(c: var Rope, frmt: string, args: openarray[Rope]) {. +proc addf*(c: var Rope, frmt: string, args: openArray[Rope]) {. rtl, extern: "nro$1".} = ## shortcut for ``add(c, frmt % args)``. add(c, frmt % args) -proc equalsFile*(r: Rope, f: TFile): bool {.rtl, extern: "nro$1File".} = +proc equalsFile*(r: Rope, f: File): bool {.rtl, extern: "nro$1File".} = ## returns true if the contents of the file `f` equal `r`. var bufSize = 1024 # reasonable start value - var buf = alloc(BufSize) + var buf = alloc(bufSize) for s in leaves(r): if s.len > bufSize: bufSize = max(bufSize * 2, s.len) @@ -357,7 +357,7 @@ proc equalsFile*(r: Rope, f: TFile): bool {.rtl, extern: "nro$1File".} = proc equalsFile*(r: Rope, f: string): bool {.rtl, extern: "nro$1Str".} = ## returns true if the contents of the file `f` equal `r`. If `f` does not ## exist, false is returned. - var bin: TFile + var bin: File result = open(bin, f) if result: result = equalsFile(r, bin) diff --git a/lib/system.nim b/lib/system.nim index 0c483f4a9..9153af16c 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2694,7 +2694,7 @@ elif defined(JS): proc GC_disable() = discard proc GC_enable() = discard proc GC_fullCollect() = discard - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = discard proc GC_disableMarkAndSweep() = discard proc GC_getStatistics(): string = return "" @@ -2706,7 +2706,7 @@ elif defined(JS): proc dealloc(p: pointer) = discard proc alloc(size: int): pointer = discard proc alloc0(size: int): pointer = discard - proc realloc(p: Pointer, newsize: int): pointer = discard + proc realloc(p: pointer, newsize: int): pointer = discard proc allocShared(size: int): pointer = discard proc allocShared0(size: int): pointer = discard diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index d5f9b3599..a6ec288a1 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -31,7 +31,7 @@ when someGcc and hasThreadSupport: ## with acquire loads ## and release stores in all threads. - TAtomType* = TNumber|pointer|ptr|char + TAtomType* = SomeNumber|pointer|ptr|char ## Type Class representing valid types for use with atomic procs proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {. diff --git a/lib/system/channels.nim b/lib/system/channels.nim index b3ff61b88..d7ec2c4af 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -53,8 +53,8 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel, mode: TLoadStoreMode) {.gcsafe.} = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) case n.kind of nkSlot: storeAux(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset), n.typ, t, mode) @@ -70,8 +70,8 @@ proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel, proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, mode: TLoadStoreMode) = var - d = cast[TAddress](dest) - s = cast[TAddress](src) + d = cast[ByteAddress](dest) + s = cast[ByteAddress](src) sysAssert(mt != nil, "mt == nil") case mt.kind of tyString: @@ -108,11 +108,11 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize) else: unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize)) - var dst = cast[TAddress](cast[PPointer](dest)[]) + var dst = cast[ByteAddress](cast[PPointer](dest)[]) for i in 0..seq.len-1: storeAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +% + cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), mt.base, t, mode) var dstseq = cast[PGenericSeq](dst) @@ -192,7 +192,7 @@ template lockChannel(q: expr, action: stmt) {.immediate.} = template sendImpl(q: expr) {.immediate.} = if q.mask == ChannelDeadMask: - sysFatal(EDeadThread, "cannot send message; thread died") + sysFatal(DeadThreadError, "cannot send message; thread died") acquireSys(q.lock) var m: TMsg shallowCopy(m, msg) @@ -215,7 +215,7 @@ proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) = q.ready = false if typ != q.elemType: releaseSys(q.lock) - sysFatal(EInvalidValue, "cannot receive message of wrong type") + sysFatal(ValueError, "cannot receive message of wrong type") rawRecv(q, res, typ) proc recv*[TMsg](c: var TChannel[TMsg]): TMsg = diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index 629219bf7..f90000a1c 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -80,11 +80,11 @@ template gcAssert(cond: bool, msg: string) = proc cellToUsr(cell: PCell): pointer {.inline.} = # convert object (=pointer to refcount) to pointer to userdata - result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell))) + result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell))) proc usrToCell(usr: pointer): PCell {.inline.} = # convert pointer to userdata to object (=pointer to refcount) - result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell))) + result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell))) proc canbeCycleRoot(c: PCell): bool {.inline.} = result = ntfAcyclic notin c.typ.flags @@ -169,7 +169,7 @@ proc initGC() = init(gch.marked) proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) case n.kind of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op) of nkList: @@ -181,7 +181,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} = of nkNone: sysAssert(false, "forAllSlotsAux") proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) = - var d = cast[TAddress](dest) + var d = cast[ByteAddress](dest) if dest == nil: return # nothing to do if ntfNoRefs notin mt.flags: case mt.kind @@ -206,7 +206,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) = of tyRef: # common case forAllChildrenAux(cellToUsr(cell), cell.typ.base, op) of tySequence: - var d = cast[TAddress](cellToUsr(cell)) + var d = cast[ByteAddress](cellToUsr(cell)) var s = cast[PGenericSeq](d) if s != nil: for i in 0..s.len-1: @@ -220,7 +220,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer = gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1") collectCT(gch) var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell))) - gcAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2") + gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2") # now it is buffered in the ZCT res.typ = typ when leakDetector and not hasThreadSupport: @@ -280,9 +280,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize copyMem(res, ol, oldsize + sizeof(TCell)) - zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)), + zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)), newsize-oldsize) - sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3") + sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3") when withBitvectors: excl(gch.allocated, ol) when reallyDealloc: rawDealloc(gch.region, ol) else: @@ -379,7 +379,7 @@ proc markGlobals(gch: var TGcHeap) = proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} = # the addresses are not as cells on the stack, so turn them to cells: var cell = usrToCell(p) - var c = cast[TAddress](cell) + var c = cast[ByteAddress](cell) if c >% PageSize: # fast check: does it look like a cell? var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell)) @@ -404,8 +404,8 @@ when not defined(useNimRtl): # the first init must be the one that defines the stack bottom: if gch.stackBottom == nil: gch.stackBottom = theStackBottom else: - var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2 - var b = cast[TAddress](gch.stackBottom) + var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2 + var b = cast[ByteAddress](gch.stackBottom) #c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom) when stackIncreases: gch.stackBottom = cast[pointer](min(a, b)) @@ -421,9 +421,9 @@ when defined(sparc): # For SPARC architecture. proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var b = cast[TAddress](gch.stackBottom) - var a = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var b = cast[ByteAddress](gch.stackBottom) + var a = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = @@ -440,7 +440,7 @@ when defined(sparc): # For SPARC architecture. # Addresses decrease as the stack grows. while sp <= max: gcMark(gch, sp[]) - sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer)) + sp = cast[ppointer](cast[ByteAddress](sp) +% sizeof(pointer)) elif defined(ELATE): {.error: "stack marking code is to be written for this architecture".} @@ -452,9 +452,9 @@ elif stackIncreases: proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var a = cast[TAddress](gch.stackBottom) - var b = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var a = cast[ByteAddress](gch.stackBottom) + var b = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b var @@ -465,8 +465,8 @@ elif stackIncreases: proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = var registers: C_JmpBuf if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. - var max = cast[TAddress](gch.stackBottom) - var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer) + var max = cast[ByteAddress](gch.stackBottom) + var sp = cast[ByteAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer) # sp will traverse the JMP_BUF as well (jmp_buf size is added, # otherwise sp would be below the registers structure). while sp >=% max: @@ -480,9 +480,9 @@ else: proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var b = cast[TAddress](gch.stackBottom) - var a = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var b = cast[ByteAddress](gch.stackBottom) + var a = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} = @@ -492,8 +492,8 @@ else: type PStackSlice = ptr array [0..7, pointer] var registers {.noinit.}: C_JmpBuf if c_setjmp(registers) == 0'i32: # To fill the C stack with registers. - var max = cast[TAddress](gch.stackBottom) - var sp = cast[TAddress](addr(registers)) + var max = cast[ByteAddress](gch.stackBottom) + var sp = cast[ByteAddress](addr(registers)) # loop unrolled: while sp <% max - 8*sizeof(pointer): gcMark(gch, cast[PStackSlice](sp)[0]) @@ -546,7 +546,7 @@ when not defined(useNimRtl): else: dec(gch.recGcLock) - proc GC_setStrategy(strategy: TGC_Strategy) = discard + proc GC_setStrategy(strategy: GC_Strategy) = discard proc GC_enableMarkAndSweep() = gch.cycleThreshold = InitialThreshold diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 894f259f3..f76c0e515 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -18,7 +18,7 @@ type PSafePoint = ptr TSafePoint TSafePoint {.compilerproc, final.} = object prev: PSafePoint # points to next safe point - exc: ref E_Base + exc: ref Exception PCallFrame = ptr TCallFrame TCallFrame {.importc, nodecl, final.} = object @@ -97,7 +97,7 @@ proc rawWriteStackTrace(): string = else: result = "No stack traceback available\n" -proc raiseException(e: ref E_Base, ename: cstring) {. +proc raiseException(e: ref Exception, ename: cstring) {. compilerproc, asmNoStackFrame.} = e.name = ename if excHandler != nil: @@ -120,24 +120,24 @@ proc raiseException(e: ref E_Base, ename: cstring) {. proc reraiseException() {.compilerproc, asmNoStackFrame.} = if excHandler == nil: - raise newException(ENoExceptionToReraise, "no exception to reraise") + raise newException(ReraiseError, "no exception to reraise") else: asm """throw excHandler.exc;""" proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} = - raise newException(EOverflow, "over- or underflow") + raise newException(OverflowError, "over- or underflow") proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} = - raise newException(EDivByZero, "divison by zero") + raise newException(DivByZeroError, "divison by zero") proc raiseRangeError() {.compilerproc, noreturn.} = - raise newException(EOutOfRange, "value out of range") + raise newException(RangeError, "value out of range") proc raiseIndexError() {.compilerproc, noreturn.} = - raise newException(EInvalidIndex, "index out of bounds") + raise newException(IndexError, "index out of bounds") proc raiseFieldError(f: string) {.compilerproc, noreturn.} = - raise newException(EInvalidField, f & " is not accessible") + raise newException(FieldError, f & " is not accessible") proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} = asm """ @@ -260,7 +260,7 @@ proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} = """ type - TDocument {.importc.} = object of TObject + TDocument {.importc.} = object of RootObj write: proc (text: cstring) {.nimcall.} writeln: proc (text: cstring) {.nimcall.} createAttribute: proc (identifier: cstring): ref TNode {.nimcall.} @@ -283,7 +283,7 @@ type DocumentTypeNode, DocumentFragmentNode, NotationNode - TNode* {.importc.} = object of TObject + TNode* {.importc.} = object of RootObj attributes*: seq[ref TNode] childNodes*: seq[ref TNode] data*: cstring @@ -515,7 +515,7 @@ proc isFatPointer(ti: PNimType): bool = proc nimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.} -proc nimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} = +proc nimCopyAux(dest, src: pointer, n: ptr TNimNode) {.compilerproc.} = case n.kind of nkNone: sysAssert(false, "nimCopyAux") of nkSlot: @@ -566,7 +566,7 @@ proc nimCopy(x: pointer, ti: PNimType): pointer = else: result = x -proc genericReset(x: Pointer, ti: PNimType): pointer {.compilerproc.} = +proc genericReset(x: pointer, ti: PNimType): pointer {.compilerproc.} = case ti.kind of tyPtr, tyRef, tyVar, tyNil: if not isFatPointer(ti): @@ -621,7 +621,7 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} = if x == subclass: return # optimized fast path while x != subclass: if x == nil: - raise newException(EInvalidObjectConversion, "invalid object conversion") + raise newException(ObjectConversionError, "invalid object conversion") x = x.base proc isObj(obj, subclass: PNimType): bool {.compilerproc.} = diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 6057b7749..95fa353dd 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -305,22 +305,26 @@ proc running*[TArg](t: TThread[TArg]): bool {.inline.} = ## returns true if `t` is running. result = t.dataFn != nil -proc joinThread*[TArg](t: TThread[TArg]) {.inline.} = - ## waits for the thread `t` to finish. - when hostOS == "windows": +when hostOS == "windows": + proc joinThread*[TArg](t: TThread[TArg]) {.inline.} = + ## waits for the thread `t` to finish. discard waitForSingleObject(t.sys, -1'i32) - else: - discard pthread_join(t.sys, nil) -proc joinThreads*[TArg](t: varargs[TThread[TArg]]) = - ## waits for every thread in `t` to finish. - when hostOS == "windows": + proc joinThreads*[TArg](t: varargs[TThread[TArg]]) = + ## waits for every thread in `t` to finish. var a: array[0..255, TSysThread] sysAssert a.len >= t.len, "a.len >= t.len" for i in 0..t.high: a[i] = t[i].sys - discard waitForMultipleObjects(t.len.int32, + discard waitForMultipleObjects(t.len.int32, cast[ptr TSysThread](addr(a)), 1, -1) - else: + +else: + proc joinThread*[TArg](t: TThread[TArg]) {.inline.} = + ## waits for the thread `t` to finish. + discard pthread_join(t.sys, nil) + + proc joinThreads*[TArg](t: varargs[TThread[TArg]]) = + ## waits for every thread in `t` to finish. for i in 0..t.high: joinThread(t[i]) when false: @@ -335,27 +339,37 @@ when false: when declared(registerThread): unregisterThread(addr(t)) t.dataFn = nil -proc createThread*[TArg](t: var TThread[TArg], - tp: proc (arg: TArg) {.thread.}, - param: TArg) = - ## creates a new thread `t` and starts its execution. Entry point is the - ## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you - ## don't need to pass any data to the thread. - when TArg isnot void: t.data = param - t.dataFn = tp - when hasSharedHeap: t.stackSize = ThreadStackSize - when hostOS == "windows": +when hostOS == "windows": + proc createThread*[TArg](t: var TThread[TArg], + tp: proc (arg: TArg) {.thread.}, + param: TArg) = + ## creates a new thread `t` and starts its execution. Entry point is the + ## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you + ## don't need to pass any data to the thread. + when TArg isnot void: t.data = param + t.dataFn = tp + when hasSharedHeap: t.stackSize = ThreadStackSize var dummyThreadId: int32 t.sys = createThread(nil, ThreadStackSize, threadProcWrapper[TArg], addr(t), 0'i32, dummyThreadId) if t.sys <= 0: - raise newException(EResourceExhausted, "cannot create thread") - else: + raise newException(ResourceExhaustedError, "cannot create thread") + +else: + proc createThread*[TArg](t: var TThread[TArg], + tp: proc (arg: TArg) {.thread.}, + param: TArg) = + ## creates a new thread `t` and starts its execution. Entry point is the + ## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you + ## don't need to pass any data to the thread. + when TArg isnot void: t.data = param + t.dataFn = tp + when hasSharedHeap: t.stackSize = ThreadStackSize var a {.noinit.}: Tpthread_attr pthread_attr_init(a) pthread_attr_setstacksize(a, ThreadStackSize) if pthread_create(t.sys, a, threadProcWrapper[TArg], addr(t)) != 0: - raise newException(EResourceExhausted, "cannot create thread") + raise newException(ResourceExhaustedError, "cannot create thread") proc threadId*[TArg](t: var TThread[TArg]): TThreadId[TArg] {.inline.} = ## returns the thread ID of `t`. diff --git a/tests/casestmt/tcasestm.nim b/tests/casestmt/tcasestm.nim index b033b98ec..a21b6be0d 100644 --- a/tests/casestmt/tcasestm.nim +++ b/tests/casestmt/tcasestm.nim @@ -5,7 +5,7 @@ discard """ # Test the case statement type - tenum = enum eA, eB, eC + Tenum = enum eA, eB, eC var x: string = "yyy" diff --git a/tests/concurrency/tnodeadlocks.nim b/tests/concurrency/tnodeadlocks.nim index 6cbfe64cd..7a3eedbc2 100644 --- a/tests/concurrency/tnodeadlocks.nim +++ b/tests/concurrency/tnodeadlocks.nim @@ -20,46 +20,46 @@ proc threadFunc(interval: tuple[a, b: int]) {.thread.} = when nodeadlocks: case i mod 6 of 0: - Acquire(L) # lock stdout - Acquire(M) - Acquire(N) + acquire(L) # lock stdout + acquire(M) + acquire(N) of 1: - Acquire(L) - Acquire(N) # lock stdout - Acquire(M) + acquire(L) + acquire(N) # lock stdout + acquire(M) of 2: - Acquire(M) - Acquire(L) - Acquire(N) + acquire(M) + acquire(L) + acquire(N) of 3: - Acquire(M) - Acquire(N) - Acquire(L) + acquire(M) + acquire(N) + acquire(L) of 4: - Acquire(N) - Acquire(M) - Acquire(L) + acquire(N) + acquire(M) + acquire(L) of 5: - Acquire(N) - Acquire(L) - Acquire(M) + acquire(N) + acquire(L) + acquire(M) else: assert false else: - Acquire(L) # lock stdout - Acquire(M) + acquire(L) # lock stdout + acquire(M) echo i os.sleep(10) when nodeadlocks: echo "deadlocks prevented: ", deadlocksPrevented when nodeadlocks: - Release(N) - Release(M) - Release(L) + release(N) + release(M) + release(L) -InitLock(L) -InitLock(M) -InitLock(N) +initLock(L) +initLock(M) +initLock(N) proc main = for i in 0..high(thr): diff --git a/tests/constr/tconstr1.nim b/tests/constr/tconstr1.nim index cb6594213..45e303554 100644 --- a/tests/constr/tconstr1.nim +++ b/tests/constr/tconstr1.nim @@ -10,7 +10,7 @@ type s: string, x, y: int, z: float, - chars: set[Char]] + chars: set[char]] proc testSem = var diff --git a/tests/float/tfloat1.nim b/tests/float/tfloat1.nim index f290fdb57..ed99260ea 100644 --- a/tests/float/tfloat1.nim +++ b/tests/float/tfloat1.nim @@ -1,6 +1,6 @@ discard """ file: "tfloat1.nim" - outputsub: "Error: unhandled exception: FPU operation caused an overflow [EFloatOverflow]" + outputsub: "Error: unhandled exception: FPU operation caused an overflow [FloatOverflowError]" exitcode: "1" """ # Test new floating point exceptions @@ -10,6 +10,6 @@ discard """ var x = 0.8 var y = 0.0 -echo x / y #OUT Error: unhandled exception: FPU operation caused an overflow [EFloatOverflow] +echo x / y #OUT Error: unhandled exception: FPU operation caused an overflow diff --git a/tests/float/tfloat2.nim b/tests/float/tfloat2.nim index 51883674f..b84120fba 100644 --- a/tests/float/tfloat2.nim +++ b/tests/float/tfloat2.nim @@ -1,6 +1,6 @@ discard """ file: "tfloat2.nim" - outputsub: "Error: unhandled exception: FPU operation caused a NaN result [EFloatInvalidOp]" + outputsub: "Error: unhandled exception: FPU operation caused a NaN result [FloatInvalidOpError]" exitcode: "1" """ # Test new floating point exceptions @@ -10,6 +10,6 @@ discard """ var x = 0.0 var y = 0.0 -echo x / y #OUT Error: unhandled exception: FPU operation caused a NaN result [EFloatInvalidOp] +echo x / y #OUT Error: unhandled exception: FPU operation caused a NaN result diff --git a/tests/float/tfloat3.nim b/tests/float/tfloat3.nim index 2318c517e..a3f5a2fc7 100644 --- a/tests/float/tfloat3.nim +++ b/tests/float/tfloat3.nim @@ -13,7 +13,7 @@ void printFloats(void) { } """.} -proc c_printf(frmt: CString) {.importc: "printf", header: "", varargs.} +proc c_printf(frmt: cstring) {.importc: "printf", header: "", varargs.} proc printFloats {.importc, nodecl.} var x: float = 1.234567890123456789 diff --git a/tests/gc/closureleak.nim b/tests/gc/closureleak.nim index 669e05227..38ee1250a 100644 --- a/tests/gc/closureleak.nim +++ b/tests/gc/closureleak.nim @@ -29,5 +29,5 @@ for i in 0 .. <10: f.func = proc = echo f.id -gc_fullcollect() +GC_fullcollect() echo alive_foos.len <= 3 diff --git a/tests/generics/texplicitgeneric1.nim b/tests/generics/texplicitgeneric1.nim index 6cca71ac0..d54044368 100644 --- a/tests/generics/texplicitgeneric1.nim +++ b/tests/generics/texplicitgeneric1.nim @@ -18,7 +18,7 @@ proc newDict*[TKey, TValue](): PDict[TKey, TValue] = proc add*[TKey, TValue](d: PDict[TKey, TValue], k: TKey, v: TValue) = d.data.add((k, v)) -iterator items*[Tkey, tValue](d: PDict[TKey, TValue]): tuple[k: TKey, +iterator items*[Tkey, TValue](d: PDict[TKey, TValue]): tuple[k: TKey, v: TValue] = for k, v in items(d.data): yield (k, v) diff --git a/tests/generics/tgeneric2.nim b/tests/generics/tgeneric2.nim index 56803017a..21eb4693e 100644 --- a/tests/generics/tgeneric2.nim +++ b/tests/generics/tgeneric2.nim @@ -1,7 +1,7 @@ import tables type - TX = TTable[string, int] + TX = Table[string, int] proc foo(models: seq[TX]): seq[int] = result = @[] @@ -9,7 +9,7 @@ proc foo(models: seq[TX]): seq[int] = result.add model["foobar"] type - obj = object - field: TTable[string, string] + Obj = object + field: Table[string, string] var t: Obj discard initTable[type(t.field), string]() diff --git a/tests/generics/tgeneric3.nim b/tests/generics/tgeneric3.nim index 963d0ccfb..6fb929efb 100644 --- a/tests/generics/tgeneric3.nim +++ b/tests/generics/tgeneric3.nim @@ -7,17 +7,17 @@ type value: D node: PNode[T,D] when not (D is string): - val_set: Bool + val_set: bool TItems[T,D] = seq[ref TItem[T,D]] TNode {.acyclic, pure, final, shallow.} [T,D] = object slots: TItems[T,D] left: PNode[T,D] - count: Int32 + count: int32 RPath[T,D] = tuple[ - Xi: Int, + Xi: int, Nd: PNode[T,D] ] const @@ -29,41 +29,41 @@ const cLenMax = 128 cCenter = cLenMax div 2 -proc len[T,D] (n:PNode[T,D]): Int {.inline.} = - return n.Count +proc len[T,D] (n:PNode[T,D]): int {.inline.} = + return n.count -proc clean[T: TOrdinal|TNumber](o: var T) {.inline.} = discard +proc clean[T: SomeOrdinal|SomeNumber](o: var T) {.inline.} = discard proc clean[T: string|seq](o: var T) {.inline.} = o = nil proc clean[T,D] (o: ref TItem[T,D]) {.inline.} = when (D is string) : - o.Value = nil + o.value = nil else : o.val_set = false -proc isClean[T,D] (it: ref TItem[T,D]): Bool {.inline.} = +proc isClean[T,D] (it: ref TItem[T,D]): bool {.inline.} = when (D is string) : - return it.Value == nil + return it.value == nil else : return not it.val_set -proc isClean[T,D] (n: PNode[T,D], x: Int): Bool {.inline.} = - when (D is string) : - return n.slots[x].Value == nil - else : +proc isClean[T,D](n: PNode[T,D], x: int): bool {.inline.} = + when (D is string): + return n.slots[x].value == nil + else: return not n.slots[x].val_set -proc setItem[T,D] (AKey: T, AValue: D, ANode: PNode[T,D]): ref TItem[T,D] {.inline.} = - new(Result) - Result.Key = AKey - Result.Value = AValue - Result.Node = ANode +proc setItem[T,D](Akey: T, Avalue: D, ANode: PNode[T,D]): ref TItem[T,D] {.inline.} = + new(result) + result.key = Akey + result.value = Avalue + result.node = ANode when not (D is string) : - Result.val_set = true + result.val_set = true -proc cmp[T:Int8|Int16|Int32|Int64|Int] (a,b: T): T {.inline.} = +proc cmp[T:int8|int16|int32|int64|int] (a,b: T): T {.inline.} = return a-b template binSearchImpl *(docmp: expr) {.immediate.} = @@ -76,41 +76,41 @@ template binSearchImpl *(docmp: expr) {.immediate.} = if SW < 0: result = I + 1 else: H = I - 1 - if SW == 0 : bFound = True + if SW == 0 : bFound = true if bFound: inc(result) else: result = - result -proc bSearch[T,D] (haystack: PNode[T,D], needle:T): Int {.inline.} = +proc bSearch[T,D] (haystack: PNode[T,D], needle:T): int {.inline.} = binSearchImpl(haystack.slots[I].key.cmp(needle)) -proc DeleteItem[T,D] (n: PNode[T,D], x: Int): PNode[T,D] {.inline.} = +proc DeleteItem[T,D] (n: PNode[T,D], x: int): PNode[T,D] {.inline.} = var w = n.slots[x] - if w.Node != nil : + if w.node != nil : clean(w) return n - dec(n.Count) - if n.Count > 0 : - for i in countup(x, n.Count -1) : n.slots[i] = n.slots[i + 1] - n.slots[n.Count] = nil - case n.Count + dec(n.count) + if n.count > 0 : + for i in countup(x, n.count -1) : n.slots[i] = n.slots[i + 1] + n.slots[n.count] = nil + case n.count of cLen1 : setLen(n.slots, cLen1) of cLen2 : setLen(n.slots, cLen2) of cLen3 : setLen(n.slots, cLen3) of cLenCenter : setLen(n.slots, cLenCenter) of cLen4 : setLen(n.slots, cLen4) else: discard - Result = n + result = n else : - Result = n.Left + result = n.left n.slots = nil - n.Left = nil + n.left = nil -proc InternalDelete[T,D] (ANode: PNode[T,D], key: T, AValue: var D): PNode[T,D] = +proc internalDelete[T,D] (ANode: PNode[T,D], key: T, Avalue: var D): PNode[T,D] = var Path: array[0..20, RPath[T,D]] var n = ANode - Result = n - clean(AValue) + result = n + clean(Avalue) var h = 0 while n != nil: var x = bSearch(n, key) @@ -119,17 +119,17 @@ proc InternalDelete[T,D] (ANode: PNode[T,D], key: T, AValue: var D): PNode[T,D] Path[h].Xi = - x inc(h) if x == 0 : - n = n.Left + n = n.left else : x = (-x) -1 - if x < n.Count : - n = n.slots[x].Node + if x < n.count : + n = n.slots[x].node else : n = nil else : dec(x) if isClean(n, x) : return - AValue = n.slots[x].Value + Avalue = n.slots[x].value var n2 = DeleteItem(n, x) dec(h) while (n2 != n) and (h >=0) : @@ -139,30 +139,30 @@ proc InternalDelete[T,D] (ANode: PNode[T,D], key: T, AValue: var D): PNode[T,D] if x >= 0 : if (n == nil) and isClean(w.Nd, x) : n = w.Nd - n.slots[x].Node = nil + n.slots[x].node = nil n2 = DeleteItem(n, x) else : - w.Nd.slots[x].Node = n + w.Nd.slots[x].node = n return else : - w.Nd.Left = n + w.Nd.left = n return dec(h) if h < 0: - Result = n2 + result = n2 return -proc InternalFind[T,D] (n: PNode[T,D], key: T): ref TItem[T,D] {.inline.} = +proc internalFind[T,D] (n: PNode[T,D], key: T): ref TItem[T,D] {.inline.} = var wn = n while wn != nil : var x = bSearch(wn, key) if x <= 0 : if x == 0 : - wn = wn.Left + wn = wn.left else : x = (-x) -1 - if x < wn.Count : - wn = wn.slots[x].Node + if x < wn.count : + wn = wn.slots[x].node else : return nil @@ -171,32 +171,32 @@ proc InternalFind[T,D] (n: PNode[T,D], key: T): ref TItem[T,D] {.inline.} = return nil proc traceTree[T,D](root: PNode[T,D]) = - proc traceX(x: Int) = + proc traceX(x: int) = write stdout, "(" write stdout, x write stdout, ") " proc traceEl(el: ref TItem[T,D]) = write stdout, " key: " - write stdout, el.Key + write stdout, el.key write stdout, " value: " - write stdout, el.Value + write stdout, el.value proc traceln(space: string) = writeln stdout, "" write stdout, space - proc doTrace(n: PNode[T,D], level: Int) = + proc doTrace(n: PNode[T,D], level: int) = var space = repeatChar(2 * level) traceln(space) write stdout, "node: " if n == nil: writeln stdout, "is empty" return - write stdout, n.Count + write stdout, n.count write stdout, " elements: " - if n.Left != nil: + if n.left != nil: traceln(space) write stdout, "left: " doTrace(n.left, level +1) @@ -204,188 +204,188 @@ proc traceTree[T,D](root: PNode[T,D]) = if el != nil and not isClean(el): traceln(space) traceX(i) - if i >= n.Count: + if i >= n.count: write stdout, "error " else: traceEl(el) - if el.Node != nil: doTrace(el.Node, level +1) + if el.node != nil: doTrace(el.node, level +1) else : write stdout, " empty " - elif i < n.Count : + elif i < n.count : traceln(space) traceX(i) write stdout, "clean: " when T is string : - if el.Key != nil: write stdout, el.Key - else : write stdout, el.Key - if el.Node != nil: doTrace(el.Node, level +1) + if el.key != nil: write stdout, el.key + else : write stdout, el.key + if el.node != nil: doTrace(el.node, level +1) else : write stdout, " empty " writeln stdout,"" doTrace(root, 0) -proc InsertItem[T,D](APath: RPath[T,D], ANode:PNode[T,D], AKey: T, AValue: D) = +proc InsertItem[T,D](APath: RPath[T,D], ANode:PNode[T,D], Akey: T, Avalue: D) = var x = - APath.Xi - inc(APath.Nd.Count) - case APath.Nd.Count + inc(APath.Nd.count) + case APath.Nd.count of cLen1: setLen(APath.Nd.slots, cLen2) of cLen2: setLen(APath.Nd.slots, cLen3) of cLen3: setLen(APath.Nd.slots, cLenCenter) of cLenCenter: setLen(APath.Nd.slots, cLen4) of cLen4: setLen(APath.Nd.slots, cLenMax) else: discard - for i in countdown(APath.Nd.Count.int - 1, x + 1): shallowCopy(APath.Nd.slots[i], APath.Nd.slots[i - 1]) - APath.Nd.slots[x] = setItem(AKey, AValue, ANode) + for i in countdown(APath.Nd.count.int - 1, x + 1): shallowCopy(APath.Nd.slots[i], APath.Nd.slots[i - 1]) + APath.Nd.slots[x] = setItem(Akey, Avalue, ANode) -proc SplitPage[T,D](n, left: PNode[T,D], xi: Int, AKey:var T, AValue:var D): PNode[T,D] = - var x = -Xi +proc SplitPage[T,D](n, left: PNode[T,D], xi: int, Akey:var T, Avalue:var D): PNode[T,D] = + var x = -xi var it1: TItems[T,D] it1.newSeq(cLenCenter) - new(Result) - Result.slots.newSeq(cLenCenter) - Result.Count = cCenter + new(result) + result.slots.newSeq(cLenCenter) + result.count = cCenter if x == cCenter: for i in 0..cCenter -1: shallowCopy(it1[i], left.slots[i]) - for i in 0..cCenter -1: shallowCopy(Result.slots[i], left.slots[cCenter + i]) - Result.Left = n + for i in 0..cCenter -1: shallowCopy(result.slots[i], left.slots[cCenter + i]) + result.left = n else : if x < cCenter : for i in 0..x-1: shallowCopy(it1[i], left.slots[i]) - it1[x] = setItem(AKey, AValue, n) + it1[x] = setItem(Akey, Avalue, n) for i in x+1 .. cCenter -1: shallowCopy(it1[i], left.slots[i-1]) var w = left.slots[cCenter -1] - AKey = w.Key - AValue = w.Value - Result.Left = w.Node - for i in 0..cCenter -1: shallowCopy(Result.slots[i], left.slots[cCenter + i]) + Akey = w.key + Avalue = w.value + result.left = w.node + for i in 0..cCenter -1: shallowCopy(result.slots[i], left.slots[cCenter + i]) else : for i in 0..cCenter -1: shallowCopy(it1[i], left.slots[i]) x = x - (cCenter + 1) - for i in 0..x-1: shallowCopy(Result.slots[i], left.slots[cCenter + i + 1]) - Result.slots[x] = setItem(AKey, AValue, n) - for i in x+1 .. cCenter -1: shallowCopy(Result.slots[i], left.slots[cCenter + i]) + for i in 0..x-1: shallowCopy(result.slots[i], left.slots[cCenter + i + 1]) + result.slots[x] = setItem(Akey, Avalue, n) + for i in x+1 .. cCenter -1: shallowCopy(result.slots[i], left.slots[cCenter + i]) var w = left.slots[cCenter] - AKey = w.Key - AValue = w.Value - Result.Left = w.Node - left.Count = cCenter + Akey = w.key + Avalue = w.value + result.left = w.node + left.count = cCenter shallowCopy(left.slots, it1) -proc InternalPut[T,D](ANode: ref TNode[T,D], AKey: T, AValue: D, OldValue: var D): ref TNode[T,D] = - var h: Int +proc internalPut[T,D](ANode: ref TNode[T,D], Akey: T, Avalue: D, Oldvalue: var D): ref TNode[T,D] = + var h: int var Path: array[0..30, RPath[T,D]] var left: PNode[T,D] var n = ANode - Result = ANode + result = ANode h = 0 while n != nil: - var x = bSearch[T,D](n, AKey) + var x = bSearch[T,D](n, Akey) if x <= 0 : Path[h].Nd = n Path[h].Xi = x inc(h) if x == 0 : - n = n.Left + n = n.left else : x = (-x) -1 - if x < n.Count : - n = n.slots[x].Node + if x < n.count : + n = n.slots[x].node else : n = nil else : var w = n.slots[x - 1] - OldValue = w.Value - w.Value = AValue + Oldvalue = w.value + w.value = Avalue return dec(h) left = nil - var lKey = AKey - var lValue = AValue + var lkey = Akey + var lvalue = Avalue while h >= 0 : - if Path[h].Nd.Count < cLenMax : - InsertItem(Path[h], n, lKey, lValue) + if Path[h].Nd.count < cLenMax : + InsertItem(Path[h], n, lkey, lvalue) return else : left = Path[h].Nd - n = SplitPage(n, left, Path[h].Xi, lKey, lValue) + n = SplitPage(n, left, Path[h].Xi, lkey, lvalue) dec(h) - new(Result) - Result.slots.newSeq(cLen1) - Result.Count = 1 - Result.Left = left - Result.slots[0] = setItem(lKey, lValue, n) + new(result) + result.slots.newSeq(cLen1) + result.count = 1 + result.left = left + result.slots[0] = setItem(lkey, lvalue, n) proc CleanTree[T,D](n: PNode[T,D]): PNode[T,D] = - if n.Left != nil : - n.Left = CleanTree(n.Left) - for i in 0 .. n.Count - 1 : + if n.left != nil : + n.left = CleanTree(n.left) + for i in 0 .. n.count - 1 : var w = n.slots[i] - if w.Node != nil : - w.Node = CleanTree(w.Node) - clean(w.Value) - clean(w.Key) + if w.node != nil : + w.node = CleanTree(w.node) + clean(w.value) + clean(w.key) n.slots = nil return nil proc VisitAllNodes[T,D](n: PNode[T,D], visit: proc(n: PNode[T,D]): PNode[T,D] {.closure.} ): PNode[T,D] = if n != nil : - if n.Left != nil : - n.Left = VisitAllNodes(n.Left, visit) - for i in 0 .. n.Count - 1 : + if n.left != nil : + n.left = VisitAllNodes(n.left, visit) + for i in 0 .. n.count - 1 : var w = n.slots[i] - if w.Node != nil : - w.Node = VisitAllNodes(w.Node, visit) + if w.node != nil : + w.node = VisitAllNodes(w.node, visit) return visit(n) return nil proc VisitAllNodes[T,D](n: PNode[T,D], visit: proc(n: PNode[T,D]) {.closure.} ) = if n != nil: - if n.Left != nil : - VisitAllNodes(n.Left, visit) - for i in 0 .. n.Count - 1 : + if n.left != nil : + VisitAllNodes(n.left, visit) + for i in 0 .. n.count - 1 : var w = n.slots[i] - if w.Node != nil : - VisitAllNodes(w.Node, visit) + if w.node != nil : + VisitAllNodes(w.node, visit) visit(n) -proc VisitAll[T,D](n: PNode[T,D], visit: proc(AKey: T, AValue: D) {.closure.} ) = +proc VisitAll[T,D](n: PNode[T,D], visit: proc(Akey: T, Avalue: D) {.closure.} ) = if n != nil: - if n.Left != nil : - VisitAll(n.Left, visit) - for i in 0 .. n.Count - 1 : + if n.left != nil : + VisitAll(n.left, visit) + for i in 0 .. n.count - 1 : var w = n.slots[i] if not w.isClean : - visit(w.Key, w.Value) - if w.Node != nil : - VisitAll(w.Node, visit) + visit(w.key, w.value) + if w.node != nil : + VisitAll(w.node, visit) -proc VisitAll[T,D](n: PNode[T,D], visit: proc(AKey: T, AValue: var D):Bool {.closure.} ): PNode[T,D] = +proc VisitAll[T,D](n: PNode[T,D], visit: proc(Akey: T, Avalue: var D):bool {.closure.} ): PNode[T,D] = if n != nil: - var n1 = n.Left + var n1 = n.left if n1 != nil : var n2 = VisitAll(n1, visit) if n1 != n2 : - n.Left = n2 + n.left = n2 var i = 0 - while i < n.Count : + while i < n.count : var w = n.slots[i] if not w.isClean : - if visit(w.Key, w.Value) : - Result = DeleteItem(n, i) - if Result == nil : return + if visit(w.key, w.value) : + result = DeleteItem(n, i) + if result == nil : return dec(i) - n1 = w.Node + n1 = w.node if n1 != nil : var n2 = VisitAll(n1, visit) if n1 != n2 : - w.Node = n2 + w.node = n2 inc(i) return n @@ -396,20 +396,20 @@ iterator keys* [T,D] (n: PNode[T,D]): T = var nd = n var i = -1 while true : - if i < nd.Count : + if i < nd.count : Path[level].Nd = nd Path[level].Xi = i if i < 0 : - if nd.Left != nil : - nd = nd.Left + if nd.left != nil : + nd = nd.left inc(level) else : inc(i) else : var w = nd.slots[i] if not w.isClean() : - yield w.Key - if w.Node != nil : - nd = w.Node + yield w.key + if w.node != nil : + nd = w.node i = -1 inc(level) else : inc(i) @@ -424,22 +424,22 @@ iterator keys* [T,D] (n: PNode[T,D]): T = when isMainModule: proc test() = - var oldValue: Int - var root = InternalPut[int, int](nil, 312, 312, oldValue) - var someOtherRoot = InternalPut[string, int](nil, "312", 312, oldValue) - var it1 = InternalFind(root, 312) - echo it1.Value + var oldvalue: int + var root = internalPut[int, int](nil, 312, 312, oldvalue) + var someOtherRoot = internalPut[string, int](nil, "312", 312, oldvalue) + var it1 = internalFind(root, 312) + echo it1.value for i in 1..1_000_000: - root = InternalPut(root, i, i, oldValue) + root = internalPut(root, i, i, oldvalue) var cnt = 0 - oldValue = -1 + oldvalue = -1 when true : # code compiles, when this or the other when is switched to false for k in root.keys : - if k <= oldValue : + if k <= oldvalue : echo k - oldValue = k + oldvalue = k inc(cnt) echo cnt when true : @@ -450,21 +450,21 @@ when isMainModule: root = VisitAll(root, proc(key: int, value: var int): bool = return key mod 2 == 0 ) cnt = 0 - oldValue = -1 + oldvalue = -1 VisitAll(root, proc(key: int, value: int) {.closure.} = - if key <= oldValue : + if key <= oldvalue : echo key - oldValue = key + oldvalue = key inc(cnt) ) echo cnt root = VisitAll(root, proc(key: int, value: var int): bool = return key mod 2 != 0 ) cnt = 0 - oldValue = -1 + oldvalue = -1 VisitAll(root, proc(key: int, value: int) {.closure.} = - if key <= oldValue : + if key <= oldvalue : echo "error ", key - oldValue = key + oldvalue = key inc(cnt) ) echo cnt #traceTree(root) diff --git a/tests/generics/tgenericprocvar.nim b/tests/generics/tgenericprocvar.nim index 1eba81fec..dca9c8538 100644 --- a/tests/generics/tgenericprocvar.nim +++ b/tests/generics/tgenericprocvar.nim @@ -25,7 +25,7 @@ proc filter[T,D](data: seq[T], env:D, pred: TFilterProc[T,D]): seq[T] = for e in data: if pred(e, env): result.add(e) -proc predTest(item: int, value: int): Bool = +proc predTest(item: int, value: int): bool = return item <= value proc test(data: seq[int], value: int): seq[int] = diff --git a/tests/generics/tgenericvariant.nim b/tests/generics/tgenericvariant.nim index 51d01355a..0150cda8d 100644 --- a/tests/generics/tgenericvariant.nim +++ b/tests/generics/tgenericvariant.nim @@ -1,15 +1,15 @@ type TMaybe[T] = object - case empty: Bool - of False: value: T + case empty: bool + of false: value: T else: nil proc Just*[T](val: T): TMaybe[T] = - result.empty = False + result.empty = false result.value = val proc Nothing[T](): TMaybe[T] = - result.empty = True + result.empty = true proc safeReadLine(): TMaybe[string] = var r = stdin.readLine() diff --git a/tests/iter/titer2.nim b/tests/iter/titer2.nim index fbecf7cf9..5c407ebe4 100644 --- a/tests/iter/titer2.nim +++ b/tests/iter/titer2.nim @@ -44,8 +44,8 @@ block Test1: # a non-generic iterator! var t = initTable[int, string]() - for k, v in t.pairs: nil - for k, v in t.pairs: nil + for k, v in t.pairs: discard + for k, v in t.pairs: discard echo "true" diff --git a/tests/iter/titer6.nim b/tests/iter/titer6.nim index dceace0e0..2abfa0860 100644 --- a/tests/iter/titer6.nim +++ b/tests/iter/titer6.nim @@ -21,13 +21,13 @@ iterator tokenize2(s: string, seps: set[char] = Whitespace): tuple[ yield (substr(s, i, j-1), false) i = j -for word, isSep in tokenize2("ta da", whiteSpace): +for word, isSep in tokenize2("ta da", WhiteSpace): var titer2TestVar = 0 stdout.write(titer2TestVar) proc wordWrap2(s: string, maxLineWidth = 80, splitLongWords = true, - seps: set[char] = whitespace, + seps: set[char] = Whitespace, newLine = "\n"): string = result = "" for word, isSep in tokenize2(s, seps): diff --git a/tests/iter/titer8.nim b/tests/iter/titer8.nim index af0e643f1..3bc01122f 100644 --- a/tests/iter/titer8.nim +++ b/tests/iter/titer8.nim @@ -47,7 +47,7 @@ iterator count3(): int {.closure.} = yield 2 yield 3 -for word, isSep in tokenize2("ta da", whiteSpace): +for word, isSep in tokenize2("ta da", WhiteSpace): if not isSep: stdout.write(word) echo "" @@ -56,7 +56,7 @@ proc inProc() = for c in count3(): echo c - for word, isSep in tokenize2("ta da", whiteSpace): + for word, isSep in tokenize2("ta da", WhiteSpace): stdout.write(word) for c in count3(): diff --git a/tests/lookups/tkoeniglookup.nim b/tests/lookups/tkoeniglookup.nim index e6f5c0112..6c42798ae 100644 --- a/tests/lookups/tkoeniglookup.nim +++ b/tests/lookups/tkoeniglookup.nim @@ -2,7 +2,7 @@ discard """ output: '''x: 0 y: 0''' """ -proc ToString*[T](x: T): string = return $x +proc toString*[T](x: T): string = return $x type diff --git a/tests/misc/tlastmod.nim b/tests/misc/tlastmod.nim index 75b047fc8..92ac922f7 100644 --- a/tests/misc/tlastmod.nim +++ b/tests/misc/tlastmod.nim @@ -6,13 +6,13 @@ import proc main() = var a, b: TTime - a = getLastModificationTime(ParamStr(1)) - b = getLastModificationTime(ParamStr(2)) + a = getLastModificationTime(paramStr(1)) + b = getLastModificationTime(paramStr(2)) writeln(stdout, $a) writeln(stdout, $b) if a < b: - Write(stdout, "$2 is newer than $1\n" % [ParamStr(1), ParamStr(2)]) + write(stdout, "$2 is newer than $1\n" % [paramStr(1), paramStr(2)]) else: - Write(stdout, "$1 is newer than $2\n" % [ParamStr(1), ParamStr(2)]) + write(stdout, "$1 is newer than $2\n" % [paramStr(1), paramStr(2)]) main() diff --git a/tests/misc/tloops.nim b/tests/misc/tloops.nim index f6f939769..1aada0298 100644 --- a/tests/misc/tloops.nim +++ b/tests/misc/tloops.nim @@ -31,7 +31,7 @@ proc TestLoops() = break break - while True: + while true: break diff --git a/tests/misc/tnot.nim b/tests/misc/tnot.nim index cd0f538e6..6193e21e1 100644 --- a/tests/misc/tnot.nim +++ b/tests/misc/tnot.nim @@ -5,16 +5,16 @@ discard """ """ # BUG: following compiles, but should not: -proc nodeOfDegree(x: Int): bool = +proc nodeOfDegree(x: int): bool = result = false proc main = for j in 0..2: for i in 0..10: if not nodeOfDegree(1) >= 0: #ERROR_MSG type mismatch - Echo "Yes" + echo "Yes" else: - Echo "No" + echo "No" main() diff --git a/tests/misc/tpos.nim b/tests/misc/tpos.nim index 3d72536dd..5560ef050 100644 --- a/tests/misc/tpos.nim +++ b/tests/misc/tpos.nim @@ -14,10 +14,10 @@ proc mypos(sub, s: string, start: int = 0): int = if i >= N: result = -1 else: - while True: + while true: if s[i] == sub[j]: - Inc(i) - Inc(j) + inc(i) + inc(j) else: i = i - j + 1 j = 0 diff --git a/tests/misc/tprep.nim b/tests/misc/tprep.nim index 4ef9e2543..8f40300d6 100644 --- a/tests/misc/tprep.nim +++ b/tests/misc/tprep.nim @@ -24,7 +24,7 @@ else: var s: string -write(stdout, "compiled at " & system.compileDate & - " " & compileTime & "\n") +write(stdout, "compiled at " & system.CompileDate & + " " & CompileTime & "\n") echo getDateStr() echo getClockStr() diff --git a/tests/misc/tradix.nim b/tests/misc/tradix.nim index e5998ee12..311aa9ccd 100644 --- a/tests/misc/tradix.nim +++ b/tests/misc/tradix.nim @@ -4,7 +4,7 @@ ## We use a radix tree with node compression. ## There are two node kinds: -const bitsPerUnit = 8*sizeof(int) +const BitsPerUnit = 8*sizeof(int) type TRadixNodeKind = enum rnLinear, rnFull, rnLeafBits, rnLeafLinear @@ -42,13 +42,13 @@ proc testBit(w, i: int): bool {.inline.} = result = (w and (1 shl (i %% BitsPerUnit))) != 0 proc setBit(w: var int, i: int) {.inline.} = - w = w or (1 shl (i %% bitsPerUnit)) + w = w or (1 shl (i %% BitsPerUnit)) proc resetBit(w: var int, i: int) {.inline.} = - w = w and not (1 shl (i %% bitsPerUnit)) + w = w and not (1 shl (i %% BitsPerUnit)) proc testOrSetBit(w: var int, i: int): bool {.inline.} = - var x = (1 shl (i %% bitsPerUnit)) + var x = (1 shl (i %% BitsPerUnit)) if (w and x) != 0: return true w = w or x @@ -78,7 +78,7 @@ proc exclLeaf(r: PRadixNode, a: int) = return else: assert(false) -proc contains*(r: PRadixNode, a: TAddress): bool = +proc contains*(r: PRadixNode, a: ByteAddress): bool = if r == nil: return false var x = searchInner(r, a shr 24 and 0xff) if x == nil: return false @@ -88,7 +88,7 @@ proc contains*(r: PRadixNode, a: TAddress): bool = if x == nil: return false return searchLeaf(x, a and 0xff) -proc excl*(r: PRadixNode, a: TAddress): bool = +proc excl*(r: PRadixNode, a: ByteAddress): bool = if r == nil: return false var x = searchInner(r, a shr 24 and 0xff) if x == nil: return false @@ -167,10 +167,10 @@ proc addInner(r: var PRadixNode, a: int, d: int): bool = return addInner(x.b[k], a, d-8) else: assert(false) -proc incl*(r: var PRadixNode, a: TAddress) {.inline.} = +proc incl*(r: var PRadixNode, a: ByteAddress) {.inline.} = discard addInner(r, a, 24) -proc testOrIncl*(r: var PRadixNode, a: TAddress): bool {.inline.} = +proc testOrIncl*(r: var PRadixNode, a: ByteAddress): bool {.inline.} = return addInner(r, a, 24) iterator innerElements(r: PRadixNode): tuple[prefix: int, n: PRadixNode] = @@ -204,7 +204,7 @@ iterator leafElements(r: PRadixNode): int = yield ze(r.keys[i]) else: assert(false) -iterator elements*(r: PRadixNode): TAddress {.inline.} = +iterator elements*(r: PRadixNode): ByteAddress {.inline.} = for p1, n1 in innerElements(r): for p2, n2 in innerElements(n1): for p3, n3 in innerElements(n2): @@ -297,7 +297,7 @@ when false: result = ze(r.keys[i.x]) inc(i.x) - iterator elements(r: PRadixNode): TAddress {.inline.} = + iterator elements(r: PRadixNode): ByteAddress {.inline.} = var a, b, c, d: TRadixIter init(a, r) diff --git a/tests/misc/treadln.nim b/tests/misc/treadln.nim index 1117ab5f9..1edbea992 100644 --- a/tests/misc/treadln.nim +++ b/tests/misc/treadln.nim @@ -2,11 +2,11 @@ # Macintosh, Unix or Windows text format. var - inp: TFile + inp: File line: string if open(inp, "readme.txt"): - while not EndOfFile(inp): + while not endOfFile(inp): line = readLine(inp) echo("#" & line & "#") close(inp) diff --git a/tests/misc/tsimplesort.nim b/tests/misc/tsimplesort.nim index 0167ca78a..c282b3445 100644 --- a/tests/misc/tsimplesort.nim +++ b/tests/misc/tsimplesort.nim @@ -4,11 +4,7 @@ discard """ import hashes, math - -when defined(shallowADT): - {.pragma: myShallow, shallow.} -else: - {.pragma: myShallow.} +{.pragma: myShallow.} type TSlotEnum = enum seEmpty, seFilled, seDeleted @@ -63,7 +59,7 @@ template rawInsertImpl() = data[h].val = val data[h].slot = seFilled -proc RawGet[A, B](t: TTable[A, B], key: A): int = +proc rawGet[A, B](t: TTable[A, B], key: A): int = rawGetImpl() proc `[]`*[A, B](t: TTable[A, B], key: A): B = @@ -71,31 +67,31 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B = ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val proc hasKey*[A, B](t: TTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc RawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], +proc rawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() -proc Enlarge[A, B](t: var TTable[A, B]) = +proc enlarge[A, B](t: var TTable[A, B]) = var n: TKeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): - if t.data[i].slot == seFilled: RawInsert(t, n, t.data[i].key, t.data[i].val) + if t.data[i].slot == seFilled: rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) -template PutImpl() = - var index = RawGet(t, key) +template putImpl() = + var index = rawGet(t, key) if index >= 0: t.data[index].val = val else: - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) + if mustRehash(len(t.data), t.counter): enlarge(t) + rawInsert(t, t.data, key, val) inc(t.counter) proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) = @@ -104,7 +100,7 @@ proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) = proc del*[A, B](t: var TTable[A, B], key: A) = ## deletes `key` from hash table `t`. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: t.data[index].slot = seDeleted dec(t.counter) @@ -183,24 +179,24 @@ proc hasKey*[A](t: TCountTable[A], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc RawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], +proc rawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], key: A, val: int) = var h: THash = hash(key) and high(data) while data[h].val != 0: h = nextTry(h, high(data)) data[h].key = key data[h].val = val -proc Enlarge[A](t: var TCountTable[A]) = +proc enlarge[A](t: var TCountTable[A]) = var n: seq[tuple[key: A, val: int]] newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): - if t.data[i].val != 0: RawInsert(t, n, t.data[i].key, t.data[i].val) + if t.data[i].val != 0: rawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) = ## puts a (key, value)-pair into `t`. `val` has to be positive. assert val > 0 - PutImpl() + putImpl() proc initCountTable*[A](initialSize=64): TCountTable[A] = ## creates a new count table that is empty. `initialSize` needs to be @@ -224,11 +220,11 @@ proc inc*[A](t: var TCountTable[A], key: A, val = 1) = if index >= 0: inc(t.data[index].val, val) else: - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) + if mustRehash(len(t.data), t.counter): enlarge(t) + rawInsert(t, t.data, key, val) inc(t.counter) -proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = +proc smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = ## returns the largest (key,val)-pair. Efficiency: O(n) assert t.len > 0 var minIdx = 0 @@ -237,7 +233,7 @@ proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = result.key = t.data[minIdx].key result.val = t.data[minIdx].val -proc Largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = +proc largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) assert t.len > 0 var maxIdx = 0 diff --git a/tests/misc/tvarnums.nim b/tests/misc/tvarnums.nim index 4f99df8b9..b880cf006 100644 --- a/tests/misc/tvarnums.nim +++ b/tests/misc/tvarnums.nim @@ -74,7 +74,7 @@ proc toNum(b: TBuffer): int32 = while (ze(b[i]) and 128) != 0: inc(i) result = result or ((int32(ze(b[i])) and 127'i32) shl Shift) - Shift = shift + 7'i32 + Shift = Shift + 7'i32 if (ze(b[0]) and (1 shl 6)) != 0: # sign bit set? result = (not result) +% 1'i32 # this is the same as ``- result`` diff --git a/tests/objvariant/tyaoption.nim b/tests/objvariant/tyaoption.nim index 635e60bb8..7a29b8008 100644 --- a/tests/objvariant/tyaoption.nim +++ b/tests/objvariant/tyaoption.nim @@ -7,7 +7,7 @@ some(10)''' import strutils type Option[A] = object - case isDefined*: Bool + case isDefined*: bool of true: value*: A of false: @@ -19,7 +19,7 @@ proc some[A](value: A): Option[A] = proc none[A](): Option[A] = Option[A](isDefined: false) -proc `$`[A](o: Option[A]): String = +proc `$`[A](o: Option[A]): string = if o.isDefined: "some($1)" % [$o.value] else: @@ -27,14 +27,14 @@ proc `$`[A](o: Option[A]): String = let x = some("str") let y = some(5) -let z = none[Int]() +let z = none[int]() echo x, ", ", y, ", ", z -proc intOrString[A : Int | String](o: Option[A]): Option[A] = - when A is Int: +proc intOrString[A : int | string](o: Option[A]): Option[A] = + when A is int: some(o.value + 5) - elif A is String: + elif A is string: some(o.value & "!") else: o diff --git a/tests/overflw/toverflw.nim b/tests/overflw/toverflw.nim index 50c405ee1..fbe0d0a38 100644 --- a/tests/overflw/toverflw.nim +++ b/tests/overflw/toverflw.nim @@ -12,7 +12,7 @@ a = high(int) b = -2 try: writeln(stdout, b - a) -except EOverflow: +except OverflowError: writeln(stdout, "the computation overflowed") {.pop.} # overflow check diff --git a/tests/overflw/toverflw2.nim b/tests/overflw/toverflw2.nim index f7fe3d574..75bd4cdf5 100644 --- a/tests/overflw/toverflw2.nim +++ b/tests/overflw/toverflw2.nim @@ -1,6 +1,6 @@ discard """ file: "toverflw2.nim" - outputsub: "Error: unhandled exception: over- or underflow [EOverflow]" + outputsub: "Error: unhandled exception: over- or underflow [OverflowError]" exitcode: "1" """ var a : int32 = 2147483647 diff --git a/tests/procvar/tprocvars.nim b/tests/procvar/tprocvars.nim index dc7592526..50d5d29f2 100644 --- a/tests/procvar/tprocvars.nim +++ b/tests/procvar/tprocvars.nim @@ -1,6 +1,6 @@ -proc doSomething(v: Int, x: proc(v:Int):Int): Int = return x(v) -proc doSomething(v: Int, x: proc(v:Int)) = x(v) +proc doSomething(v: int, x: proc(v:int):int): int = return x(v) +proc doSomething(v: int, x: proc(v:int)) = x(v) -echo doSomething(10, proc(v: Int): Int = return v div 2) +echo doSomething(10, proc(v: int): int = return v div 2) diff --git a/tests/types/tforwty2.nim b/tests/types/tforwty2.nim index 5d15e112a..a6d899011 100644 --- a/tests/types/tforwty2.nim +++ b/tests/types/tforwty2.nim @@ -6,7 +6,7 @@ type PSDL_semaphore = ptr TSDL_semaphore TSDL_semaphore {.final.} = object - sem: Pointer #PSem_t; + sem: pointer #PSem_t; when not defined(USE_NAMED_SEMAPHORES): sem_data: int when defined(BROKEN_SEMGETVALUE): diff --git a/tests/types/tillrec.nim b/tests/types/tillrec.nim index 1d1ec0622..18757140a 100644 --- a/tests/types/tillrec.nim +++ b/tests/types/tillrec.nim @@ -11,6 +11,6 @@ type kids: seq[TLegal] TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal' - y: Int + y: int x: array[0..3, TIllegal] diff --git a/tests/varstmt/tlet.nim b/tests/varstmt/tlet.nim index ba355c5d8..138f34433 100644 --- a/tests/varstmt/tlet.nim +++ b/tests/varstmt/tlet.nim @@ -10,7 +10,7 @@ proc main = elif name == "name": echo("Very funny, your name is name.") else: - Echo("Hi, ", name, "!") + echo("Hi, ", name, "!") let (x, y) = ("abc", name) echo y, x diff --git a/tests/vm/tconsteval.nim b/tests/vm/tconsteval.nim index c7932d444..96a1bafe8 100644 --- a/tests/vm/tconsteval.nim +++ b/tests/vm/tconsteval.nim @@ -6,7 +6,7 @@ import strutils const HelpText = """ +-----------------------------------------------------------------+ -| Maintenance program for Nim | +| Maintenance program for Nim | | Version $1| | (c) 2012 Andreas Rumpf | +-----------------------------------------------------------------+ @@ -27,5 +27,5 @@ Possible Commands: """ % [NimVersion & repeatChar(44-len(NimVersion)), CompileDate, CompileTime] -echo helpText +echo HelpText From 93eb9c456d4195e4296b0f91d27ba0c3e3ab3f33 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 15:25:54 +0200 Subject: [PATCH 071/409] more stdlib modules work --- lib/pure/md5.nim | 60 ++++---- lib/pure/parsecsv.nim | 2 +- lib/pure/redis.nim | 346 +++++++++++++++++++++--------------------- tests/vm/trgba.nim | 18 +-- 4 files changed, 213 insertions(+), 213 deletions(-) diff --git a/lib/pure/md5.nim b/lib/pure/md5.nim index 322dbbe1d..3b5453957 100644 --- a/lib/pure/md5.nim +++ b/lib/pure/md5.nim @@ -84,14 +84,14 @@ proc decode(dest: var openArray[int8], src: openArray[int32]) = dest[i+3] = toU8(src[j] shr 24'i32 and 0xff'i32) inc(i, 4) -proc transform(Buffer: pointer, State: var MD5State) = +proc transform(buffer: pointer, state: var MD5State) = var myBlock: MD5Block - encode(myBlock, cast[cstring](Buffer)) - var a = State[0] - var b = State[1] - var c = State[2] - var d = State[3] + encode(myBlock, cast[cstring](buffer)) + var a = state[0] + var b = state[1] + var c = state[2] + var d = state[3] FF(a, b, c, d, myBlock[0], 7'i8, 0xD76AA478'i32) FF(d, a, b, c, myBlock[1], 12'i8, 0xE8C7B756'i32) FF(c, d, a, b, myBlock[2], 17'i8, 0x242070DB'i32) @@ -156,52 +156,52 @@ proc transform(Buffer: pointer, State: var MD5State) = II(d, a, b, c, myBlock[11], 10'i8, 0xBD3AF235'i32) II(c, d, a, b, myBlock[2], 15'i8, 0x2AD7D2BB'i32) II(b, c, d, a, myBlock[9], 21'i8, 0xEB86D391'i32) - State[0] = State[0] +% a - State[1] = State[1] +% b - State[2] = State[2] +% c - State[3] = State[3] +% d + state[0] = state[0] +% a + state[1] = state[1] +% b + state[2] = state[2] +% c + state[3] = state[3] +% d proc md5Init*(c: var MD5Context) = ## initializes a MD5Context - c.State[0] = 0x67452301'i32 - c.State[1] = 0xEFCDAB89'i32 - c.State[2] = 0x98BADCFE'i32 - c.State[3] = 0x10325476'i32 - c.Count[0] = 0'i32 - c.Count[1] = 0'i32 - zeroMem(addr(c.Buffer), sizeof(MD5Buffer)) + c.state[0] = 0x67452301'i32 + c.state[1] = 0xEFCDAB89'i32 + c.state[2] = 0x98BADCFE'i32 + c.state[3] = 0x10325476'i32 + c.count[0] = 0'i32 + c.count[1] = 0'i32 + zeroMem(addr(c.buffer), sizeof(MD5buffer)) proc md5Update*(c: var MD5Context, input: cstring, len: int) = ## updates the MD5Context with the `input` data of length `len` var input = input var Index = (c.count[0] shr 3) and 0x3F - c.Count[0] = c.count[0] +% toU32(len shl 3) - if c.Count[0] < (len shl 3): c.Count[1] = c.count[1] +% 1'i32 - c.Count[1] = c.count[1] +% toU32(len shr 29) + c.count[0] = c.count[0] +% toU32(len shl 3) + if c.count[0] < (len shl 3): c.count[1] = c.count[1] +% 1'i32 + c.count[1] = c.count[1] +% toU32(len shr 29) var PartLen = 64 - Index if len >= PartLen: - copyMem(addr(c.Buffer[Index]), input, PartLen) - transform(addr(c.Buffer), c.State) + copyMem(addr(c.buffer[Index]), input, PartLen) + transform(addr(c.buffer), c.state) var i = PartLen while i + 63 < len: - transform(addr(input[i]), c.State) + transform(addr(input[i]), c.state) inc(i, 64) - copyMem(addr(c.Buffer[0]), addr(input[i]), len-i) + copyMem(addr(c.buffer[0]), addr(input[i]), len-i) else: - copyMem(addr(c.Buffer[Index]), addr(input[0]), len) + copyMem(addr(c.buffer[Index]), addr(input[0]), len) proc md5Final*(c: var MD5Context, digest: var MD5Digest) = ## finishes the MD5Context and stores the result in `digest` var Bits: MD5CBits PadLen: int - decode(Bits, c.Count) - var Index = (c.Count[0] shr 3) and 0x3F + decode(Bits, c.count) + var Index = (c.count[0] shr 3) and 0x3F if Index < 56: PadLen = 56 - Index else: PadLen = 120 - Index md5Update(c, padding, PadLen) md5Update(c, cast[cstring](addr(Bits)), 8) - decode(digest, c.State) + decode(digest, c.state) zeroMem(addr(c), sizeof(MD5Context)) proc toMD5*(s: string): MD5Digest = @@ -216,8 +216,8 @@ proc `$`*(D: MD5Digest): string = const digits = "0123456789abcdef" result = "" for i in 0..15: - add(result, Digits[(D[i] shr 4) and 0xF]) - add(result, Digits[D[i] and 0xF]) + add(result, digits[(D[i] shr 4) and 0xF]) + add(result, digits[D[i] and 0xF]) proc getMD5*(s: string): string = ## computes an MD5 value of `s` and returns its string representation diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim index c8abdca4f..f4943ed89 100644 --- a/lib/pure/parsecsv.nim +++ b/lib/pure/parsecsv.nim @@ -51,7 +51,7 @@ proc raiseEInvalidCsv(filename: string, line, col: int, raise e proc error(my: CsvParser, pos: int, msg: string) = - raiseEInvalidCsv(my.filename, my.LineNumber, getColNumber(my, pos), msg) + raiseEInvalidCsv(my.filename, my.lineNumber, getColNumber(my, pos), msg) proc open*(my: var CsvParser, input: Stream, filename: string, separator = ',', quote = '"', escape = '\0', diff --git a/lib/pure/redis.nim b/lib/pure/redis.nim index ab3b81f37..52d81b3a4 100644 --- a/lib/pure/redis.nim +++ b/lib/pure/redis.nim @@ -31,7 +31,7 @@ type type Redis* = object - socket: TSocket + socket: Socket connected: bool pipeline: Pipeline @@ -45,7 +45,7 @@ type {.deprecated: [TSendMode: SendMode, TRedis: Redis, TRedisStatus: RedisStatus, TRedisInteger: RedisInteger, TRedisString: RedisString, - TRedisList: RedistList, EInvalidReply: ReplyError, ERedis: RedisError].} + TRedisList: RedisList, EInvalidReply: ReplyError, ERedis: RedisError].} proc newPipeline(): Pipeline = new(result) @@ -56,8 +56,8 @@ proc newPipeline(): Pipeline = proc open*(host = "localhost", port = 6379.Port): Redis = ## Opens a connection to the redis server. result.socket = socket(buffered = false) - if result.socket == InvalidSocket: - OSError(OSLastError()) + if result.socket == invalidSocket: + raiseOSError(osLastError()) result.socket.connect(host, port) result.pipeline = newPipeline() @@ -68,9 +68,9 @@ proc raiseInvalidReply(expected, got: char) = proc raiseNoOK(status: string, pipelineEnabled: bool) = if pipelineEnabled and not (status == "QUEUED" or status == "PIPELINED"): - raise newException(EInvalidReply, "Expected \"QUEUED\" or \"PIPELINED\" got \"$1\"" % status) + raise newException(ReplyError, "Expected \"QUEUED\" or \"PIPELINED\" got \"$1\"" % status) elif not pipelineEnabled and status != "OK": - raise newException(EInvalidReply, "Expected \"OK\" got \"$1\"" % status) + raise newException(ReplyError, "Expected \"OK\" got \"$1\"" % status) template readSocket(r: Redis, dummyVal:expr): stmt = var line {.inject.}: TaintedString = "" @@ -84,75 +84,75 @@ proc parseStatus(r: Redis, line: string = ""): RedisStatus = return "PIPELINED" if line == "": - raise newException(ERedis, "Server closed connection prematurely") + raise newException(RedisError, "Server closed connection prematurely") if line[0] == '-': - raise newException(ERedis, strip(line)) + raise newException(RedisError, strip(line)) if line[0] != '+': raiseInvalidReply('+', line[0]) return line.substr(1) # Strip '+' -proc readStatus(r:TRedis): TRedisStatus = +proc readStatus(r:Redis): RedisStatus = r.readSocket("PIPELINED") return r.parseStatus(line) -proc parseInteger(r: TRedis, line: string = ""): TRedisInteger = +proc parseInteger(r: Redis, line: string = ""): RedisInteger = if r.pipeline.enabled: return -1 #if line == "+QUEUED": # inside of multi # return -1 if line == "": - raise newException(ERedis, "Server closed connection prematurely") + raise newException(RedisError, "Server closed connection prematurely") if line[0] == '-': - raise newException(ERedis, strip(line)) + raise newException(RedisError, strip(line)) if line[0] != ':': raiseInvalidReply(':', line[0]) # Strip ':' if parseBiggestInt(line, result, 1) == 0: - raise newException(EInvalidReply, "Unable to parse integer.") + raise newException(ReplyError, "Unable to parse integer.") -proc readInteger(r: TRedis): TRedisInteger = +proc readInteger(r: Redis): RedisInteger = r.readSocket(-1) return r.parseInteger(line) -proc recv(sock: TSocket, size: int): TaintedString = +proc recv(sock: Socket, size: int): TaintedString = result = newString(size).TaintedString if sock.recv(cstring(result), size) != size: - raise newException(EInvalidReply, "recv failed") + raise newException(ReplyError, "recv failed") -proc parseSingleString(r: TRedis, line:string, allowMBNil = False): TRedisString = +proc parseSingleString(r: Redis, line:string, allowMBNil = false): RedisString = if r.pipeline.enabled: return "" # Error. if line[0] == '-': - raise newException(ERedis, strip(line)) + raise newException(RedisError, strip(line)) # Some commands return a /bulk/ value or a /multi-bulk/ nil. Odd. if allowMBNil: if line == "*-1": - return RedisNil + return redisNil if line[0] != '$': raiseInvalidReply('$', line[0]) var numBytes = parseInt(line.substr(1)) if numBytes == -1: - return RedisNil + return redisNil var s = r.socket.recv(numBytes+2) result = strip(s.string) -proc readSingleString(r: TRedis): TRedisString = +proc readSingleString(r: Redis): RedisString = r.readSocket("") return r.parseSingleString(line) -proc readNext(r: TRedis): TRedisList +proc readNext(r: Redis): RedisList -proc parseArrayLines(r: TRedis, countLine:string): TRedisList = +proc parseArrayLines(r: Redis, countLine:string): RedisList = if countLine.string[0] != '*': raiseInvalidReply('*', countLine.string[0]) @@ -166,24 +166,24 @@ proc parseArrayLines(r: TRedis, countLine:string): TRedisList = for item in parsed: result.add(item) -proc readArrayLines(r: TRedis): TRedisList = +proc readArrayLines(r: Redis): RedisList = r.readSocket(nil) return r.parseArrayLines(line) -proc parseBulkString(r: TRedis, allowMBNil = False, line:string = ""): TRedisString = +proc parseBulkString(r: Redis, allowMBNil = false, line:string = ""): RedisString = if r.pipeline.enabled: return "" return r.parseSingleString(line, allowMBNil) -proc readBulkString(r: TRedis, allowMBNil = false): TRedisString = +proc readBulkString(r: Redis, allowMBNil = false): RedisString = r.readSocket("") return r.parseBulkString(allowMBNil, line) -proc readArray(r: TRedis): TRedisList = +proc readArray(r: Redis): RedisList = r.readSocket(@[]) return r.parseArrayLines(line) -proc readNext(r: TRedis): TRedisList = +proc readNext(r: Redis): RedisList = r.readSocket(@[]) var res = case line[0] @@ -192,12 +192,12 @@ proc readNext(r: TRedis): TRedisList = of '$': @[r.parseBulkString(true,line)] of '*': r.parseArrayLines(line) else: - raise newException(EInvalidReply, "readNext failed on line: " & line) + raise newException(ReplyError, "readNext failed on line: " & line) nil r.pipeline.expected -= 1 return res -proc flushPipeline*(r: TRedis, wasMulti = false): TRedisList = +proc flushPipeline*(r: Redis, wasMulti = false): RedisList = ## Send buffered commands, clear buffer, return results if r.pipeline.buffer.len > 0: r.socket.send(r.pipeline.buffer) @@ -216,7 +216,7 @@ proc flushPipeline*(r: TRedis, wasMulti = false): TRedisList = r.pipeline.expected = 0 -proc startPipelining*(r: TRedis) = +proc startPipelining*(r: Redis) = ## Enable command pipelining (reduces network roundtrips). ## Note that when enabled, you must call flushPipeline to actually send commands, except ## for multi/exec() which enable and flush the pipeline automatically. @@ -225,7 +225,7 @@ proc startPipelining*(r: TRedis) = r.pipeline.expected = 0 r.pipeline.enabled = true -proc sendCommand(r: TRedis, cmd: string, args: varargs[string]) = +proc sendCommand(r: Redis, cmd: string, args: varargs[string]) = var request = "*" & $(1 + args.len()) & "\c\L" request.add("$" & $cmd.len() & "\c\L") request.add(cmd & "\c\L") @@ -239,7 +239,7 @@ proc sendCommand(r: TRedis, cmd: string, args: varargs[string]) = else: r.socket.send(request) -proc sendCommand(r: TRedis, cmd: string, arg1: string, +proc sendCommand(r: Redis, cmd: string, arg1: string, args: varargs[string]) = var request = "*" & $(2 + args.len()) & "\c\L" request.add("$" & $cmd.len() & "\c\L") @@ -258,68 +258,68 @@ proc sendCommand(r: TRedis, cmd: string, arg1: string, # Keys -proc del*(r: TRedis, keys: varargs[string]): TRedisInteger = +proc del*(r: Redis, keys: varargs[string]): RedisInteger = ## Delete a key or multiple keys r.sendCommand("DEL", keys) return r.readInteger() -proc exists*(r: TRedis, key: string): bool = +proc exists*(r: Redis, key: string): bool = ## Determine if a key exists r.sendCommand("EXISTS", key) return r.readInteger() == 1 -proc expire*(r: TRedis, key: string, seconds: int): bool = +proc expire*(r: Redis, key: string, seconds: int): bool = ## Set a key's time to live in seconds. Returns `false` if the key could ## not be found or the timeout could not be set. r.sendCommand("EXPIRE", key, $seconds) return r.readInteger() == 1 -proc expireAt*(r: TRedis, key: string, timestamp: int): bool = +proc expireAt*(r: Redis, key: string, timestamp: int): bool = ## Set the expiration for a key as a UNIX timestamp. Returns `false` ## if the key could not be found or the timeout could not be set. r.sendCommand("EXPIREAT", key, $timestamp) return r.readInteger() == 1 -proc keys*(r: TRedis, pattern: string): TRedisList = +proc keys*(r: Redis, pattern: string): RedisList = ## Find all keys matching the given pattern r.sendCommand("KEYS", pattern) return r.readArray() -proc move*(r: TRedis, key: string, db: int): bool = +proc move*(r: Redis, key: string, db: int): bool = ## Move a key to another database. Returns `true` on a successful move. r.sendCommand("MOVE", key, $db) return r.readInteger() == 1 -proc persist*(r: TRedis, key: string): bool = +proc persist*(r: Redis, key: string): bool = ## Remove the expiration from a key. ## Returns `true` when the timeout was removed. r.sendCommand("PERSIST", key) return r.readInteger() == 1 -proc randomKey*(r: TRedis): TRedisString = +proc randomKey*(r: Redis): RedisString = ## Return a random key from the keyspace r.sendCommand("RANDOMKEY") return r.readBulkString() -proc rename*(r: TRedis, key, newkey: string): TRedisStatus = +proc rename*(r: Redis, key, newkey: string): RedisStatus = ## Rename a key. ## ## **WARNING:** Overwrites `newkey` if it exists! r.sendCommand("RENAME", key, newkey) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc renameNX*(r: TRedis, key, newkey: string): bool = +proc renameNX*(r: Redis, key, newkey: string): bool = ## Same as ``rename`` but doesn't continue if `newkey` exists. ## Returns `true` if key was renamed. r.sendCommand("RENAMENX", key, newkey) return r.readInteger() == 1 -proc ttl*(r: TRedis, key: string): TRedisInteger = +proc ttl*(r: Redis, key: string): RedisInteger = ## Get the time to live for a key r.sendCommand("TTL", key) return r.readInteger() -proc keyType*(r: TRedis, key: string): TRedisStatus = +proc keyType*(r: Redis, key: string): RedisStatus = ## Determine the type stored at key r.sendCommand("TYPE", key) return r.readStatus() @@ -327,131 +327,131 @@ proc keyType*(r: TRedis, key: string): TRedisStatus = # Strings -proc append*(r: TRedis, key, value: string): TRedisInteger = +proc append*(r: Redis, key, value: string): RedisInteger = ## Append a value to a key r.sendCommand("APPEND", key, value) return r.readInteger() -proc decr*(r: TRedis, key: string): TRedisInteger = +proc decr*(r: Redis, key: string): RedisInteger = ## Decrement the integer value of a key by one r.sendCommand("DECR", key) return r.readInteger() -proc decrBy*(r: TRedis, key: string, decrement: int): TRedisInteger = +proc decrBy*(r: Redis, key: string, decrement: int): RedisInteger = ## Decrement the integer value of a key by the given number r.sendCommand("DECRBY", key, $decrement) return r.readInteger() -proc get*(r: TRedis, key: string): TRedisString = +proc get*(r: Redis, key: string): RedisString = ## Get the value of a key. Returns `redisNil` when `key` doesn't exist. r.sendCommand("GET", key) return r.readBulkString() -proc getBit*(r: TRedis, key: string, offset: int): TRedisInteger = +proc getBit*(r: Redis, key: string, offset: int): RedisInteger = ## Returns the bit value at offset in the string value stored at key r.sendCommand("GETBIT", key, $offset) return r.readInteger() -proc getRange*(r: TRedis, key: string, start, stop: int): TRedisString = +proc getRange*(r: Redis, key: string, start, stop: int): RedisString = ## Get a substring of the string stored at a key r.sendCommand("GETRANGE", key, $start, $stop) return r.readBulkString() -proc getSet*(r: TRedis, key: string, value: string): TRedisString = +proc getSet*(r: Redis, key: string, value: string): RedisString = ## Set the string value of a key and return its old value. Returns `redisNil` ## when key doesn't exist. r.sendCommand("GETSET", key, value) return r.readBulkString() -proc incr*(r: TRedis, key: string): TRedisInteger = +proc incr*(r: Redis, key: string): RedisInteger = ## Increment the integer value of a key by one. r.sendCommand("INCR", key) return r.readInteger() -proc incrBy*(r: TRedis, key: string, increment: int): TRedisInteger = +proc incrBy*(r: Redis, key: string, increment: int): RedisInteger = ## Increment the integer value of a key by the given number r.sendCommand("INCRBY", key, $increment) return r.readInteger() -proc setk*(r: TRedis, key, value: string) = +proc setk*(r: Redis, key, value: string) = ## Set the string value of a key. ## ## NOTE: This function had to be renamed due to a clash with the `set` type. r.sendCommand("SET", key, value) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc setNX*(r: TRedis, key, value: string): bool = +proc setNX*(r: Redis, key, value: string): bool = ## Set the value of a key, only if the key does not exist. Returns `true` ## if the key was set. r.sendCommand("SETNX", key, value) return r.readInteger() == 1 -proc setBit*(r: TRedis, key: string, offset: int, - value: string): TRedisInteger = +proc setBit*(r: Redis, key: string, offset: int, + value: string): RedisInteger = ## Sets or clears the bit at offset in the string value stored at key r.sendCommand("SETBIT", key, $offset, value) return r.readInteger() -proc setEx*(r: TRedis, key: string, seconds: int, value: string): TRedisStatus = +proc setEx*(r: Redis, key: string, seconds: int, value: string): RedisStatus = ## Set the value and expiration of a key r.sendCommand("SETEX", key, $seconds, value) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc setRange*(r: TRedis, key: string, offset: int, - value: string): TRedisInteger = +proc setRange*(r: Redis, key: string, offset: int, + value: string): RedisInteger = ## Overwrite part of a string at key starting at the specified offset r.sendCommand("SETRANGE", key, $offset, value) return r.readInteger() -proc strlen*(r: TRedis, key: string): TRedisInteger = +proc strlen*(r: Redis, key: string): RedisInteger = ## Get the length of the value stored in a key. Returns 0 when key doesn't ## exist. r.sendCommand("STRLEN", key) return r.readInteger() # Hashes -proc hDel*(r: TRedis, key, field: string): bool = +proc hDel*(r: Redis, key, field: string): bool = ## Delete a hash field at `key`. Returns `true` if the field was removed. r.sendCommand("HDEL", key, field) return r.readInteger() == 1 -proc hExists*(r: TRedis, key, field: string): bool = +proc hExists*(r: Redis, key, field: string): bool = ## Determine if a hash field exists. r.sendCommand("HEXISTS", key, field) return r.readInteger() == 1 -proc hGet*(r: TRedis, key, field: string): TRedisString = +proc hGet*(r: Redis, key, field: string): RedisString = ## Get the value of a hash field r.sendCommand("HGET", key, field) return r.readBulkString() -proc hGetAll*(r: TRedis, key: string): TRedisList = +proc hGetAll*(r: Redis, key: string): RedisList = ## Get all the fields and values in a hash r.sendCommand("HGETALL", key) return r.readArray() -proc hIncrBy*(r: TRedis, key, field: string, incr: int): TRedisInteger = +proc hIncrBy*(r: Redis, key, field: string, incr: int): RedisInteger = ## Increment the integer value of a hash field by the given number r.sendCommand("HINCRBY", key, field, $incr) return r.readInteger() -proc hKeys*(r: TRedis, key: string): TRedisList = +proc hKeys*(r: Redis, key: string): RedisList = ## Get all the fields in a hash r.sendCommand("HKEYS", key) return r.readArray() -proc hLen*(r: TRedis, key: string): TRedisInteger = +proc hLen*(r: Redis, key: string): RedisInteger = ## Get the number of fields in a hash r.sendCommand("HLEN", key) return r.readInteger() -proc hMGet*(r: TRedis, key: string, fields: varargs[string]): TRedisList = +proc hMGet*(r: Redis, key: string, fields: varargs[string]): RedisList = ## Get the values of all the given hash fields r.sendCommand("HMGET", key, fields) return r.readArray() -proc hMSet*(r: TRedis, key: string, - fieldValues: openarray[tuple[field, value: string]]) = +proc hMSet*(r: Redis, key: string, + fieldValues: openArray[tuple[field, value: string]]) = ## Set multiple hash fields to multiple values var args = @[key] for field, value in items(fieldValues): @@ -460,24 +460,24 @@ proc hMSet*(r: TRedis, key: string, r.sendCommand("HMSET", args) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc hSet*(r: TRedis, key, field, value: string): TRedisInteger = +proc hSet*(r: Redis, key, field, value: string): RedisInteger = ## Set the string value of a hash field r.sendCommand("HSET", key, field, value) return r.readInteger() -proc hSetNX*(r: TRedis, key, field, value: string): TRedisInteger = +proc hSetNX*(r: Redis, key, field, value: string): RedisInteger = ## Set the value of a hash field, only if the field does **not** exist r.sendCommand("HSETNX", key, field, value) return r.readInteger() -proc hVals*(r: TRedis, key: string): TRedisList = +proc hVals*(r: Redis, key: string): RedisList = ## Get all the values in a hash r.sendCommand("HVALS", key) return r.readArray() # Lists -proc bLPop*(r: TRedis, keys: varargs[string], timeout: int): TRedisList = +proc bLPop*(r: Redis, keys: varargs[string], timeout: int): RedisList = ## Remove and get the *first* element in a list, or block until ## one is available var args: seq[string] = @[] @@ -486,7 +486,7 @@ proc bLPop*(r: TRedis, keys: varargs[string], timeout: int): TRedisList = r.sendCommand("BLPOP", args) return r.readArray() -proc bRPop*(r: TRedis, keys: varargs[string], timeout: int): TRedisList = +proc bRPop*(r: Redis, keys: varargs[string], timeout: int): RedisList = ## Remove and get the *last* element in a list, or block until one ## is available. var args: seq[string] = @[] @@ -495,8 +495,8 @@ proc bRPop*(r: TRedis, keys: varargs[string], timeout: int): TRedisList = r.sendCommand("BRPOP", args) return r.readArray() -proc bRPopLPush*(r: TRedis, source, destination: string, - timeout: int): TRedisString = +proc bRPopLPush*(r: Redis, source, destination: string, + timeout: int): RedisString = ## Pop a value from a list, push it to another list and return it; or ## block until one is available. ## @@ -504,32 +504,32 @@ proc bRPopLPush*(r: TRedis, source, destination: string, r.sendCommand("BRPOPLPUSH", source, destination, $timeout) return r.readBulkString(true) # Multi-Bulk nil allowed. -proc lIndex*(r: TRedis, key: string, index: int): TRedisString = +proc lIndex*(r: Redis, key: string, index: int): RedisString = ## Get an element from a list by its index r.sendCommand("LINDEX", key, $index) return r.readBulkString() -proc lInsert*(r: TRedis, key: string, before: bool, pivot, value: string): - TRedisInteger = +proc lInsert*(r: Redis, key: string, before: bool, pivot, value: string): + RedisInteger = ## Insert an element before or after another element in a list var pos = if before: "BEFORE" else: "AFTER" r.sendCommand("LINSERT", key, pos, pivot, value) return r.readInteger() -proc lLen*(r: TRedis, key: string): TRedisInteger = +proc lLen*(r: Redis, key: string): RedisInteger = ## Get the length of a list r.sendCommand("LLEN", key) return r.readInteger() -proc lPop*(r: TRedis, key: string): TRedisString = +proc lPop*(r: Redis, key: string): RedisString = ## Remove and get the first element in a list r.sendCommand("LPOP", key) return r.readBulkString() -proc lPush*(r: TRedis, key, value: string, create: bool = True): TRedisInteger = +proc lPush*(r: Redis, key, value: string, create: bool = true): RedisInteger = ## Prepend a value to a list. Returns the length of the list after the push. ## The ``create`` param specifies whether a list should be created if it - ## doesn't exist at ``key``. More specifically if ``create`` is True, `LPUSH` + ## doesn't exist at ``key``. More specifically if ``create`` is true, `LPUSH` ## will be used, otherwise `LPUSHX`. if create: r.sendCommand("LPUSH", key, value) @@ -537,42 +537,42 @@ proc lPush*(r: TRedis, key, value: string, create: bool = True): TRedisInteger = r.sendCommand("LPUSHX", key, value) return r.readInteger() -proc lRange*(r: TRedis, key: string, start, stop: int): TRedisList = +proc lRange*(r: Redis, key: string, start, stop: int): RedisList = ## Get a range of elements from a list. Returns `nil` when `key` ## doesn't exist. r.sendCommand("LRANGE", key, $start, $stop) return r.readArray() -proc lRem*(r: TRedis, key: string, value: string, count: int = 0): TRedisInteger = +proc lRem*(r: Redis, key: string, value: string, count: int = 0): RedisInteger = ## Remove elements from a list. Returns the number of elements that have been ## removed. r.sendCommand("LREM", key, $count, value) return r.readInteger() -proc lSet*(r: TRedis, key: string, index: int, value: string) = +proc lSet*(r: Redis, key: string, index: int, value: string) = ## Set the value of an element in a list by its index r.sendCommand("LSET", key, $index, value) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc lTrim*(r: TRedis, key: string, start, stop: int) = +proc lTrim*(r: Redis, key: string, start, stop: int) = ## Trim a list to the specified range r.sendCommand("LTRIM", key, $start, $stop) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc rPop*(r: TRedis, key: string): TRedisString = +proc rPop*(r: Redis, key: string): RedisString = ## Remove and get the last element in a list r.sendCommand("RPOP", key) return r.readBulkString() -proc rPopLPush*(r: TRedis, source, destination: string): TRedisString = +proc rPopLPush*(r: Redis, source, destination: string): RedisString = ## Remove the last element in a list, append it to another list and return it r.sendCommand("RPOPLPUSH", source, destination) return r.readBulkString() -proc rPush*(r: TRedis, key, value: string, create: bool = True): TRedisInteger = +proc rPush*(r: Redis, key, value: string, create: bool = true): RedisInteger = ## Append a value to a list. Returns the length of the list after the push. ## The ``create`` param specifies whether a list should be created if it - ## doesn't exist at ``key``. More specifically if ``create`` is True, `RPUSH` + ## doesn't exist at ``key``. More specifically if ``create`` is true, `RPUSH` ## will be used, otherwise `RPUSHX`. if create: r.sendCommand("RPUSH", key, value) @@ -582,106 +582,106 @@ proc rPush*(r: TRedis, key, value: string, create: bool = True): TRedisInteger = # Sets -proc sadd*(r: TRedis, key: string, member: string): TRedisInteger = +proc sadd*(r: Redis, key: string, member: string): RedisInteger = ## Add a member to a set r.sendCommand("SADD", key, member) return r.readInteger() -proc scard*(r: TRedis, key: string): TRedisInteger = +proc scard*(r: Redis, key: string): RedisInteger = ## Get the number of members in a set r.sendCommand("SCARD", key) return r.readInteger() -proc sdiff*(r: TRedis, keys: varargs[string]): TRedisList = +proc sdiff*(r: Redis, keys: varargs[string]): RedisList = ## Subtract multiple sets r.sendCommand("SDIFF", keys) return r.readArray() -proc sdiffstore*(r: TRedis, destination: string, - keys: varargs[string]): TRedisInteger = +proc sdiffstore*(r: Redis, destination: string, + keys: varargs[string]): RedisInteger = ## Subtract multiple sets and store the resulting set in a key r.sendCommand("SDIFFSTORE", destination, keys) return r.readInteger() -proc sinter*(r: TRedis, keys: varargs[string]): TRedisList = +proc sinter*(r: Redis, keys: varargs[string]): RedisList = ## Intersect multiple sets r.sendCommand("SINTER", keys) return r.readArray() -proc sinterstore*(r: TRedis, destination: string, - keys: varargs[string]): TRedisInteger = +proc sinterstore*(r: Redis, destination: string, + keys: varargs[string]): RedisInteger = ## Intersect multiple sets and store the resulting set in a key r.sendCommand("SINTERSTORE", destination, keys) return r.readInteger() -proc sismember*(r: TRedis, key: string, member: string): TRedisInteger = +proc sismember*(r: Redis, key: string, member: string): RedisInteger = ## Determine if a given value is a member of a set r.sendCommand("SISMEMBER", key, member) return r.readInteger() -proc smembers*(r: TRedis, key: string): TRedisList = +proc smembers*(r: Redis, key: string): RedisList = ## Get all the members in a set r.sendCommand("SMEMBERS", key) return r.readArray() -proc smove*(r: TRedis, source: string, destination: string, - member: string): TRedisInteger = +proc smove*(r: Redis, source: string, destination: string, + member: string): RedisInteger = ## Move a member from one set to another r.sendCommand("SMOVE", source, destination, member) return r.readInteger() -proc spop*(r: TRedis, key: string): TRedisString = +proc spop*(r: Redis, key: string): RedisString = ## Remove and return a random member from a set r.sendCommand("SPOP", key) return r.readBulkString() -proc srandmember*(r: TRedis, key: string): TRedisString = +proc srandmember*(r: Redis, key: string): RedisString = ## Get a random member from a set r.sendCommand("SRANDMEMBER", key) return r.readBulkString() -proc srem*(r: TRedis, key: string, member: string): TRedisInteger = +proc srem*(r: Redis, key: string, member: string): RedisInteger = ## Remove a member from a set r.sendCommand("SREM", key, member) return r.readInteger() -proc sunion*(r: TRedis, keys: varargs[string]): TRedisList = +proc sunion*(r: Redis, keys: varargs[string]): RedisList = ## Add multiple sets r.sendCommand("SUNION", keys) return r.readArray() -proc sunionstore*(r: TRedis, destination: string, - key: varargs[string]): TRedisInteger = +proc sunionstore*(r: Redis, destination: string, + key: varargs[string]): RedisInteger = ## Add multiple sets and store the resulting set in a key r.sendCommand("SUNIONSTORE", destination, key) return r.readInteger() # Sorted sets -proc zadd*(r: TRedis, key: string, score: int, member: string): TRedisInteger = +proc zadd*(r: Redis, key: string, score: int, member: string): RedisInteger = ## Add a member to a sorted set, or update its score if it already exists r.sendCommand("ZADD", key, $score, member) return r.readInteger() -proc zcard*(r: TRedis, key: string): TRedisInteger = +proc zcard*(r: Redis, key: string): RedisInteger = ## Get the number of members in a sorted set r.sendCommand("ZCARD", key) return r.readInteger() -proc zcount*(r: TRedis, key: string, min: string, max: string): TRedisInteger = +proc zcount*(r: Redis, key: string, min: string, max: string): RedisInteger = ## Count the members in a sorted set with scores within the given values r.sendCommand("ZCOUNT", key, min, max) return r.readInteger() -proc zincrby*(r: TRedis, key: string, increment: string, - member: string): TRedisString = +proc zincrby*(r: Redis, key: string, increment: string, + member: string): RedisString = ## Increment the score of a member in a sorted set r.sendCommand("ZINCRBY", key, increment, member) return r.readBulkString() -proc zinterstore*(r: TRedis, destination: string, numkeys: string, - keys: openarray[string], weights: openarray[string] = [], - aggregate: string = ""): TRedisInteger = +proc zinterstore*(r: Redis, destination: string, numkeys: string, + keys: openArray[string], weights: openArray[string] = [], + aggregate: string = ""): RedisInteger = ## Intersect multiple sorted sets and store the resulting sorted set in ## a new key var args = @[destination, numkeys] @@ -698,8 +698,8 @@ proc zinterstore*(r: TRedis, destination: string, numkeys: string, return r.readInteger() -proc zrange*(r: TRedis, key: string, start: string, stop: string, - withScores: bool): TRedisList = +proc zrange*(r: Redis, key: string, start: string, stop: string, + withScores: bool): RedisList = ## Return a range of members in a sorted set, by index if not withScores: r.sendCommand("ZRANGE", key, start, stop) @@ -707,9 +707,9 @@ proc zrange*(r: TRedis, key: string, start: string, stop: string, r.sendCommand("ZRANGE", "WITHSCORES", key, start, stop) return r.readArray() -proc zrangebyscore*(r: TRedis, key: string, min: string, max: string, - withScore: bool = false, limit: bool = False, - limitOffset: int = 0, limitCount: int = 0): TRedisList = +proc zrangebyscore*(r: Redis, key: string, min: string, max: string, + withScore: bool = false, limit: bool = false, + limitOffset: int = 0, limitCount: int = 0): RedisList = ## Return a range of members in a sorted set, by score var args = @[key, min, max] @@ -722,30 +722,30 @@ proc zrangebyscore*(r: TRedis, key: string, min: string, max: string, r.sendCommand("ZRANGEBYSCORE", args) return r.readArray() -proc zrank*(r: TRedis, key: string, member: string): TRedisString = +proc zrank*(r: Redis, key: string, member: string): RedisString = ## Determine the index of a member in a sorted set r.sendCommand("ZRANK", key, member) return r.readBulkString() -proc zrem*(r: TRedis, key: string, member: string): TRedisInteger = +proc zrem*(r: Redis, key: string, member: string): RedisInteger = ## Remove a member from a sorted set r.sendCommand("ZREM", key, member) return r.readInteger() -proc zremrangebyrank*(r: TRedis, key: string, start: string, - stop: string): TRedisInteger = +proc zremrangebyrank*(r: Redis, key: string, start: string, + stop: string): RedisInteger = ## Remove all members in a sorted set within the given indexes r.sendCommand("ZREMRANGEBYRANK", key, start, stop) return r.readInteger() -proc zremrangebyscore*(r: TRedis, key: string, min: string, - max: string): TRedisInteger = +proc zremrangebyscore*(r: Redis, key: string, min: string, + max: string): RedisInteger = ## Remove all members in a sorted set within the given scores r.sendCommand("ZREMRANGEBYSCORE", key, min, max) return r.readInteger() -proc zrevrange*(r: TRedis, key: string, start: string, stop: string, - withScore: bool): TRedisList = +proc zrevrange*(r: Redis, key: string, start: string, stop: string, + withScore: bool): RedisList = ## Return a range of members in a sorted set, by index, ## with scores ordered from high to low if withScore: @@ -753,9 +753,9 @@ proc zrevrange*(r: TRedis, key: string, start: string, stop: string, else: r.sendCommand("ZREVRANGE", key, start, stop) return r.readArray() -proc zrevrangebyscore*(r: TRedis, key: string, min: string, max: string, - withScore: bool = false, limit: bool = False, - limitOffset: int = 0, limitCount: int = 0): TRedisList = +proc zrevrangebyscore*(r: Redis, key: string, min: string, max: string, + withScore: bool = false, limit: bool = false, + limitOffset: int = 0, limitCount: int = 0): RedisList = ## Return a range of members in a sorted set, by score, with ## scores ordered from high to low var args = @[key, min, max] @@ -769,20 +769,20 @@ proc zrevrangebyscore*(r: TRedis, key: string, min: string, max: string, r.sendCommand("ZREVRANGEBYSCORE", args) return r.readArray() -proc zrevrank*(r: TRedis, key: string, member: string): TRedisString = +proc zrevrank*(r: Redis, key: string, member: string): RedisString = ## Determine the index of a member in a sorted set, with ## scores ordered from high to low r.sendCommand("ZREVRANK", key, member) return r.readBulkString() -proc zscore*(r: TRedis, key: string, member: string): TRedisString = +proc zscore*(r: Redis, key: string, member: string): RedisString = ## Get the score associated with the given member in a sorted set r.sendCommand("ZSCORE", key, member) return r.readBulkString() -proc zunionstore*(r: TRedis, destination: string, numkeys: string, - keys: openarray[string], weights: openarray[string] = [], - aggregate: string = ""): TRedisInteger = +proc zunionstore*(r: Redis, destination: string, numkeys: string, + keys: openArray[string], weights: openArray[string] = [], + aggregate: string = ""): RedisInteger = ## Add multiple sorted sets and store the resulting sorted set in a new key var args = @[destination, numkeys] for i in items(keys): args.add(i) @@ -832,12 +832,12 @@ proc unsubscribe*(r: TRedis, [channel: openarray[string], : string): ???? = # Transactions -proc discardMulti*(r: TRedis) = +proc discardMulti*(r: Redis) = ## Discard all commands issued after MULTI r.sendCommand("DISCARD") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc exec*(r: TRedis): TRedisList = +proc exec*(r: Redis): RedisList = ## Execute all commands issued after MULTI r.sendCommand("EXEC") r.pipeline.enabled = false @@ -846,106 +846,106 @@ proc exec*(r: TRedis): TRedisList = return r.flushPipeline(true) -proc multi*(r: TRedis) = +proc multi*(r: Redis) = ## Mark the start of a transaction block r.startPipelining() r.sendCommand("MULTI") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc unwatch*(r: TRedis) = +proc unwatch*(r: Redis) = ## Forget about all watched keys r.sendCommand("UNWATCH") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc watch*(r: TRedis, key: varargs[string]) = +proc watch*(r: Redis, key: varargs[string]) = ## Watch the given keys to determine execution of the MULTI/EXEC block r.sendCommand("WATCH", key) raiseNoOK(r.readStatus(), r.pipeline.enabled) # Connection -proc auth*(r: TRedis, password: string) = +proc auth*(r: Redis, password: string) = ## Authenticate to the server r.sendCommand("AUTH", password) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc echoServ*(r: TRedis, message: string): TRedisString = +proc echoServ*(r: Redis, message: string): RedisString = ## Echo the given string r.sendCommand("ECHO", message) return r.readBulkString() -proc ping*(r: TRedis): TRedisStatus = +proc ping*(r: Redis): RedisStatus = ## Ping the server r.sendCommand("PING") return r.readStatus() -proc quit*(r: TRedis) = +proc quit*(r: Redis) = ## Close the connection r.sendCommand("QUIT") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc select*(r: TRedis, index: int): TRedisStatus = +proc select*(r: Redis, index: int): RedisStatus = ## Change the selected database for the current connection r.sendCommand("SELECT", $index) return r.readStatus() # Server -proc bgrewriteaof*(r: TRedis) = +proc bgrewriteaof*(r: Redis) = ## Asynchronously rewrite the append-only file r.sendCommand("BGREWRITEAOF") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc bgsave*(r: TRedis) = +proc bgsave*(r: Redis) = ## Asynchronously save the dataset to disk r.sendCommand("BGSAVE") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc configGet*(r: TRedis, parameter: string): TRedisList = +proc configGet*(r: Redis, parameter: string): RedisList = ## Get the value of a configuration parameter r.sendCommand("CONFIG", "GET", parameter) return r.readArray() -proc configSet*(r: TRedis, parameter: string, value: string) = +proc configSet*(r: Redis, parameter: string, value: string) = ## Set a configuration parameter to the given value r.sendCommand("CONFIG", "SET", parameter, value) raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc configResetStat*(r: TRedis) = +proc configResetStat*(r: Redis) = ## Reset the stats returned by INFO r.sendCommand("CONFIG", "RESETSTAT") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc dbsize*(r: TRedis): TRedisInteger = +proc dbsize*(r: Redis): RedisInteger = ## Return the number of keys in the selected database r.sendCommand("DBSIZE") return r.readInteger() -proc debugObject*(r: TRedis, key: string): TRedisStatus = +proc debugObject*(r: Redis, key: string): RedisStatus = ## Get debugging information about a key r.sendCommand("DEBUG", "OBJECT", key) return r.readStatus() -proc debugSegfault*(r: TRedis) = +proc debugSegfault*(r: Redis) = ## Make the server crash r.sendCommand("DEBUG", "SEGFAULT") -proc flushall*(r: TRedis): TRedisStatus = +proc flushall*(r: Redis): RedisStatus = ## Remove all keys from all databases r.sendCommand("FLUSHALL") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc flushdb*(r: TRedis): TRedisStatus = +proc flushdb*(r: Redis): RedisStatus = ## Remove all keys from the current database r.sendCommand("FLUSHDB") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc info*(r: TRedis): TRedisString = +proc info*(r: Redis): RedisString = ## Get information and statistics about the server r.sendCommand("INFO") return r.readBulkString() -proc lastsave*(r: TRedis): TRedisInteger = +proc lastsave*(r: Redis): RedisInteger = ## Get the UNIX time stamp of the last successful save to disk r.sendCommand("LASTSAVE") return r.readInteger() @@ -957,24 +957,24 @@ proc monitor*(r: TRedis) = raiseNoOK(r.readStatus(), r.pipeline.enabled) """ -proc save*(r: TRedis) = +proc save*(r: Redis) = ## Synchronously save the dataset to disk r.sendCommand("SAVE") raiseNoOK(r.readStatus(), r.pipeline.enabled) -proc shutdown*(r: TRedis) = +proc shutdown*(r: Redis) = ## Synchronously save the dataset to disk and then shut down the server r.sendCommand("SHUTDOWN") var s = "".TaintedString r.socket.readLine(s) - if s.string.len != 0: raise newException(ERedis, s.string) + if s.string.len != 0: raise newException(RedisError, s.string) -proc slaveof*(r: TRedis, host: string, port: string) = +proc slaveof*(r: Redis, host: string, port: string) = ## Make the server a slave of another instance, or promote it as master r.sendCommand("SLAVEOF", host, port) raiseNoOK(r.readStatus(), r.pipeline.enabled) -iterator hPairs*(r: TRedis, key: string): tuple[key, value: string] = +iterator hPairs*(r: Redis, key: string): tuple[key, value: string] = ## Iterator for keys and values in a hash. var contents = r.hGetAll(key) @@ -986,7 +986,7 @@ iterator hPairs*(r: TRedis, key: string): tuple[key, value: string] = yield (k, i) k = "" -proc someTests(r: TRedis, how: TSendMode):seq[string] = +proc someTests(r: Redis, how: SendMode):seq[string] = var list:seq[string] = @[] if how == pipelined: @@ -1007,10 +1007,10 @@ proc someTests(r: TRedis, how: TSendMode):seq[string] = for r in res: list.add(r) list.add(r.get("invalid_key")) - list.add($(r.lpush("mylist","itema"))) - list.add($(r.lpush("mylist","itemb"))) - r.ltrim("mylist",0,1) - var p = r.lrange("mylist", 0, -1) + list.add($(r.lPush("mylist","itema"))) + list.add($(r.lPush("mylist","itemb"))) + r.lTrim("mylist",0,1) + var p = r.lRange("mylist", 0, -1) for i in items(p): if not isNil(i): diff --git a/tests/vm/trgba.nim b/tests/vm/trgba.nim index b1d94702f..22eec4d6e 100644 --- a/tests/vm/trgba.nim +++ b/tests/vm/trgba.nim @@ -6,20 +6,20 @@ discard """ #bug #1009 type - TAggRgba8* = array[4, Byte] + TAggRgba8* = array[4, byte] -template R*(self: TAggRgba8): Byte = self[0] -template G*(self: TAggRgba8): Byte = self[1] -template B*(self: TAggRgba8): Byte = self[2] -template A*(self: TAggRgba8): Byte = self[3] +template R*(self: TAggRgba8): byte = self[0] +template G*(self: TAggRgba8): byte = self[1] +template B*(self: TAggRgba8): byte = self[2] +template A*(self: TAggRgba8): byte = self[3] -template `R=`*(self: TAggRgba8, val: Byte) = +template `R=`*(self: TAggRgba8, val: byte) = self[0] = val -template `G=`*(self: TAggRgba8, val: Byte) = +template `G=`*(self: TAggRgba8, val: byte) = self[1] = val -template `B=`*(self: TAggRgba8, val: Byte) = +template `B=`*(self: TAggRgba8, val: byte) = self[2] = val -template `A=`*(self: TAggRgba8, val: Byte) = +template `A=`*(self: TAggRgba8, val: byte) = self[3] = val proc ABGR* (val: int| int64): TAggRgba8 = From d7d059a68695c10b7fe93f8f452d4aceb90857eb Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 17:23:35 +0200 Subject: [PATCH 072/409] more tests green --- lib/posix/posix.nim | 32 +++++++++++++++--------------- lib/pure/encodings.nim | 24 +++++++++++----------- lib/pure/xmlparser.nim | 8 ++++---- tests/ccgbugs/tccgen1.nim | 2 +- tests/closure/tclosure.nim | 2 +- tests/closure/tclosurebug2.nim | 28 +++++++++++++------------- tests/destructor/tdictdestruct.nim | 2 +- tests/effects/teffects1.nim | 8 ++++---- tests/effects/teffects2.nim | 8 ++++---- tests/exception/texcpt1.nim | 4 ++-- tests/exception/tnestedreturn.nim | 10 +++++----- tests/exception/tnestedreturn2.nim | 10 +++++----- tests/exception/tunhandledexc.nim | 6 +++--- tests/exception/twrongexc.nim | 6 +++--- tests/let/tlet.nim | 4 ++-- tests/typerel/tnoargopenarray.nim | 4 ++-- 16 files changed, 79 insertions(+), 79 deletions(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index fb617f3c5..e7d9b1cc8 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -1799,11 +1799,11 @@ proc inet_pton*(a1: cint, a2: cstring, a3: pointer): cint {. importc, header: "".} var - in6addr_any* {.importc, header: "".}: TIn6_addr - in6addr_loopback* {.importc, header: "".}: TIn6_addr + in6addr_any* {.importc, header: "".}: TIn6Addr + in6addr_loopback* {.importc, header: "".}: TIn6Addr -proc IN6ADDR_ANY_INIT* (): TIn6_addr {.importc, header: "".} -proc IN6ADDR_LOOPBACK_INIT* (): TIn6_addr {.importc, header: "".} +proc IN6ADDR_ANY_INIT* (): TIn6Addr {.importc, header: "".} +proc IN6ADDR_LOOPBACK_INIT* (): TIn6Addr {.importc, header: "".} # dirent.h proc closedir*(a1: ptr TDIR): cint {.importc, header: "".} @@ -2518,40 +2518,40 @@ proc if_indextoname*(a1: cint, a2: cstring): cstring {. proc if_nameindex*(): ptr Tif_nameindex {.importc, header: "".} proc if_freenameindex*(a1: ptr Tif_nameindex) {.importc, header: "".} -proc IN6_IS_ADDR_UNSPECIFIED* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_UNSPECIFIED* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Unspecified address. -proc IN6_IS_ADDR_LOOPBACK* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_LOOPBACK* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Loopback address. -proc IN6_IS_ADDR_MULTICAST* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_MULTICAST* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Multicast address. -proc IN6_IS_ADDR_LINKLOCAL* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_LINKLOCAL* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Unicast link-local address. -proc IN6_IS_ADDR_SITELOCAL* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_SITELOCAL* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Unicast site-local address. -proc IN6_IS_ADDR_V4MAPPED* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_V4MAPPED* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## IPv4 mapped address. -proc IN6_IS_ADDR_V4COMPAT* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_V4COMPAT* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## IPv4-compatible address. -proc IN6_IS_ADDR_MC_NODELOCAL* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_MC_NODELOCAL* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Multicast node-local address. -proc IN6_IS_ADDR_MC_LINKLOCAL* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_MC_LINKLOCAL* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Multicast link-local address. -proc IN6_IS_ADDR_MC_SITELOCAL* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_MC_SITELOCAL* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Multicast site-local address. -proc IN6_IS_ADDR_MC_ORGLOCAL* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_MC_ORGLOCAL* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Multicast organization-local address. -proc IN6_IS_ADDR_MC_GLOBAL* (a1: ptr TIn6_addr): cint {. +proc IN6_IS_ADDR_MC_GLOBAL* (a1: ptr TIn6Addr): cint {. importc, header: "".} ## Multicast global address. diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim index 8cc668359..958a4133b 100644 --- a/lib/pure/encodings.nim +++ b/lib/pure/encodings.nim @@ -262,7 +262,7 @@ else: else: const iconvDll = "(libc.so.6|libiconv.so)" - when defined(macosx) and defined(powerpc32): + when defined(macosx) and defined(powerpc): const prefix = "lib" else: const prefix = "" @@ -281,14 +281,14 @@ else: var errno {.importc, header: "".}: cint - proc iconvOpen(tocode, fromcode: cstring): PConverter {. + proc iconvOpen(tocode, fromcode: cstring): EncodingConverter {. importc: prefix & "iconv_open", cdecl, dynlib: iconvDll.} - proc iconvClose(c: PConverter) {. + proc iconvClose(c: EncodingConverter) {. importc: prefix & "iconv_close", cdecl, dynlib: iconvDll.} - proc iconv(c: PConverter, inbuf: var cstring, inbytesLeft: var int, + proc iconv(c: EncodingConverter, inbuf: var cstring, inbytesLeft: var int, outbuf: var cstring, outbytesLeft: var int): int {. importc: prefix & "iconv", cdecl, dynlib: iconvDll.} - proc iconv(c: PConverter, inbuf: pointer, inbytesLeft: pointer, + proc iconv(c: EncodingConverter, inbuf: pointer, inbytesLeft: pointer, outbuf: var cstring, outbytesLeft: var int): int {. importc: prefix & "iconv", cdecl, dynlib: iconvDll.} @@ -305,7 +305,7 @@ proc open*(destEncoding = "UTF-8", srcEncoding = "CP1252"): EncodingConverter = when not defined(windows): result = iconvOpen(destEncoding, srcEncoding) if result == nil: - raise newException(EInvalidEncoding, + raise newException(EncodingError, "cannot create encoding converter from " & srcEncoding & " to " & destEncoding) else: @@ -401,7 +401,7 @@ when defined(windows): assert(false) # cannot happen else: - proc convert*(c: PConverter, s: string): string = + proc convert*(c: EncodingConverter, s: string): string = result = newString(s.len) var inLen = len(s) var outLen = len(result) @@ -414,7 +414,7 @@ else: var lerr = errno if lerr == EILSEQ or lerr == EINVAL: # unknown char, skip - Dst[0] = Src[0] + dst[0] = src[0] src = cast[cstring](cast[int](src) + 1) dst = cast[cstring](cast[int](dst) + 1) dec(inLen) @@ -426,19 +426,19 @@ else: dst = cast[cstring](cast[int](cstring(result)) + offset) outLen = len(result) - offset else: - osError(lerr.TOSErrorCode) + raiseOSError(lerr.OSErrorCode) # iconv has a buffer that needs flushing, specially if the last char is # not '\0' - discard iconv(c, nil, nil, dst, outlen) + discard iconv(c, nil, nil, dst, outLen) if iconvres == cint(-1) and errno == E2BIG: var offset = cast[int](dst) - cast[int](cstring(result)) setLen(result, len(result)+inLen*2+5) # 5 is minimally one utf-8 char dst = cast[cstring](cast[int](cstring(result)) + offset) outLen = len(result) - offset - discard iconv(c, nil, nil, dst, outlen) + discard iconv(c, nil, nil, dst, outLen) # trim output buffer - setLen(result, len(result) - outlen) + setLen(result, len(result) - outLen) proc convert*(s: string, destEncoding = "UTF-8", srcEncoding = "CP1252"): string = diff --git a/lib/pure/xmlparser.nim b/lib/pure/xmlparser.nim index 83bd45e7d..8591e894c 100644 --- a/lib/pure/xmlparser.nim +++ b/lib/pure/xmlparser.nim @@ -19,7 +19,7 @@ type {.deprecated: [EInvalidXml: XmlError].} proc raiseInvalidXml(errors: seq[string]) = - var e: ref EInvalidXml + var e: ref XmlError new(e) e.msg = errors[0] e.errors = errors @@ -125,14 +125,14 @@ proc parseXml*(s: Stream): XmlNode = ## errors are turned into an ``EInvalidXML`` exception. var errors: seq[string] = @[] result = parseXml(s, "unknown_html_doc", errors) - if errors.len > 0: raiseInvalidXMl(errors) + if errors.len > 0: raiseInvalidXml(errors) proc loadXml*(path: string, errors: var seq[string]): XmlNode = ## Loads and parses XML from file specified by ``path``, and returns ## a ``PXmlNode``. Every occured parsing error is added to the `errors` ## sequence. var s = newFileStream(path, fmRead) - if s == nil: raise newException(EIO, "Unable to read file: " & path) + if s == nil: raise newException(IOError, "Unable to read file: " & path) result = parseXml(s, path, errors) proc loadXml*(path: string): XmlNode = @@ -141,7 +141,7 @@ proc loadXml*(path: string): XmlNode = ## exception. var errors: seq[string] = @[] result = loadXml(path, errors) - if errors.len > 0: raiseInvalidXMl(errors) + if errors.len > 0: raiseInvalidXml(errors) when isMainModule: import os diff --git a/tests/ccgbugs/tccgen1.nim b/tests/ccgbugs/tccgen1.nim index 137dd545d..9234bbd6c 100644 --- a/tests/ccgbugs/tccgen1.nim +++ b/tests/ccgbugs/tccgen1.nim @@ -45,7 +45,7 @@ type PText* = ref Text Text = object of CharacterData - PComment* = ref comment + PComment* = ref Comment Comment = object of CharacterData PCDataSection* = ref CDataSection diff --git a/tests/closure/tclosure.nim b/tests/closure/tclosure.nim index 764aaa97d..445a99b6d 100644 --- a/tests/closure/tclosure.nim +++ b/tests/closure/tclosure.nim @@ -36,7 +36,7 @@ myData.each do (x: int): type ITest = tuple[ - setter: proc(v: Int), + setter: proc(v: int), getter: proc(): int] proc getInterf(): ITest = diff --git a/tests/closure/tclosurebug2.nim b/tests/closure/tclosurebug2.nim index ec4f0045b..12e4e3509 100644 --- a/tests/closure/tclosurebug2.nim +++ b/tests/closure/tclosurebug2.nim @@ -38,17 +38,17 @@ template rawInsertImpl() {.dirty.} = data[h].val = val data[h].slot = seFilled -template AddImpl() {.dirty.} = - if mustRehash(len(t.data), t.counter): Enlarge(t) - RawInsert(t, t.data, key, val) +template addImpl() {.dirty.} = + if mustRehash(len(t.data), t.counter): enlarge(t) + rawInsert(t, t.data, key, val) inc(t.counter) -template PutImpl() {.dirty.} = - var index = RawGet(t, key) +template putImpl() {.dirty.} = + var index = rawGet(t, key) if index >= 0: t.data[index].val = val else: - AddImpl() + addImpl() proc len*[A, B](t: TOrderedTable[A, B]): int {.inline.} = ## returns the number of keys in `t`. @@ -89,7 +89,7 @@ iterator mvalues*[A, B](t: var TOrderedTable[A, B]): var B = forAllOrderedPairs: yield t.data[h].val -proc RawGet[A, B](t: TOrderedTable[A, B], key: A): int = +proc rawGet[A, B](t: TOrderedTable[A, B], key: A): int = rawGetImpl() proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = @@ -97,21 +97,21 @@ proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = ## default empty value for the type `B` is returned ## and no exception is raised. One can check with ``hasKey`` whether the key ## exists. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B = ## retrieves the value at ``t[key]``. The value can be modified. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. - var index = RawGet(t, key) + var index = rawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidKey, "key not found: " & $key) + else: raise newException(KeyError, "key not found: " & $key) proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 -proc RawInsert[A, B](t: var TOrderedTable[A, B], +proc rawInsert[A, B](t: var TOrderedTable[A, B], data: var TOrderedKeyValuePairSeq[A, B], key: A, val: B) = rawInsertImpl() @@ -120,7 +120,7 @@ proc RawInsert[A, B](t: var TOrderedTable[A, B], if t.last >= 0: data[t.last].next = h t.last = h -proc Enlarge[A, B](t: var TOrderedTable[A, B]) = +proc enlarge[A, B](t: var TOrderedTable[A, B]) = var n: TOrderedKeyValuePairSeq[A, B] newSeq(n, len(t.data) * growthFactor) var h = t.first @@ -129,7 +129,7 @@ proc Enlarge[A, B](t: var TOrderedTable[A, B]) = while h >= 0: var nxt = t.data[h].next if t.data[h].slot == seFilled: - RawInsert(t, n, t.data[h].key, t.data[h].val) + rawInsert(t, n, t.data[h].key, t.data[h].val) h = nxt swap(t.data, n) @@ -139,7 +139,7 @@ proc `[]=`*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. - AddImpl() + addImpl() proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = ## creates a new ordered hash table that is empty. `initialSize` needs to be diff --git a/tests/destructor/tdictdestruct.nim b/tests/destructor/tdictdestruct.nim index b7043f7b7..17ded4853 100644 --- a/tests/destructor/tdictdestruct.nim +++ b/tests/destructor/tdictdestruct.nim @@ -11,7 +11,7 @@ proc fakeNew[T](x: var ref T, destroy: proc (a: ref T) {.nimcall.}) = proc destroyDict[TK, TV](a: PDict[TK, TV]) = return proc newDict[TK, TV](a: TK, b: TV): PDict[TK, TV] = - Fakenew(result, destroyDict[TK, TV]) + fakeNew(result, destroyDict[TK, TV]) # Problem: destroyDict is not instantiated when newDict is instantiated! diff --git a/tests/effects/teffects1.nim b/tests/effects/teffects1.nim index f73230ff9..bbae857ea 100644 --- a/tests/effects/teffects1.nim +++ b/tests/effects/teffects1.nim @@ -1,7 +1,7 @@ discard """ line: 2136 file: "system.nim" - errormsg: "can raise an unlisted exception: ref EIO" + errormsg: "can raise an unlisted exception: ref IOError" """ type @@ -9,13 +9,13 @@ type TObjB = object of TObj a, b, c: string - EIO2 = ref object of EIO + IO2Error = ref object of IOError proc forw: int {. .} -proc lier(): int {.raises: [EIO2].} = +proc lier(): int {.raises: [IO2Error].} = writeln stdout, "arg" proc forw: int = - raise newException(EIO, "arg") + raise newException(IOError, "arg") diff --git a/tests/effects/teffects2.nim b/tests/effects/teffects2.nim index 7e6b17c36..89ad16edc 100644 --- a/tests/effects/teffects2.nim +++ b/tests/effects/teffects2.nim @@ -1,6 +1,6 @@ discard """ line: 19 - errormsg: "can raise an unlisted exception: ref EIO" + errormsg: "can raise an unlisted exception: ref IOError" """ type @@ -8,13 +8,13 @@ type TObjB = object of TObj a, b, c: string - EIO2 = ref object of EIO + EIO2 = ref object of IOError proc forw: int {.raises: [].} -proc lier(): int {.raises: [EIO].} = +proc lier(): int {.raises: [IOError].} = writeln stdout, "arg" proc forw: int = - raise newException(EIO, "arg") + raise newException(IOError, "arg") diff --git a/tests/exception/texcpt1.nim b/tests/exception/texcpt1.nim index ec74c9470..50a95eeec 100644 --- a/tests/exception/texcpt1.nim +++ b/tests/exception/texcpt1.nim @@ -2,8 +2,8 @@ discard """ outputsub: "-6" """ type - ESomething = object of E_Base - ESomeOtherErr = object of E_Base + ESomething = object of Exception + ESomeOtherErr = object of Exception proc genErrors(s: string) = if s == "error!": diff --git a/tests/exception/tnestedreturn.nim b/tests/exception/tnestedreturn.nim index b9f7843f6..591638f0e 100644 --- a/tests/exception/tnestedreturn.nim +++ b/tests/exception/tnestedreturn.nim @@ -10,8 +10,8 @@ proc test1() = finally: echo "A" try: - raise newException(EOS, "Problem") - except EOS: + raise newException(OSError, "Problem") + except OSError: return test1() @@ -23,7 +23,7 @@ proc test2() = try: return - except EOS: + except OSError: discard test2() @@ -31,8 +31,8 @@ test2() proc test3() = try: try: - raise newException(EOS, "Problem") - except EOS: + raise newException(OSError, "Problem") + except OSError: return finally: echo "C" diff --git a/tests/exception/tnestedreturn2.nim b/tests/exception/tnestedreturn2.nim index 14a2dab92..4bd2d535d 100644 --- a/tests/exception/tnestedreturn2.nim +++ b/tests/exception/tnestedreturn2.nim @@ -1,14 +1,14 @@ discard """ - file: "tnestedreturn.nim" - outputsub: "Error: unhandled exception: Problem [EOS]" + file: "tnestedreturn2.nim" + outputsub: "Error: unhandled exception: Problem [OSError]" exitcode: "1" """ proc test4() = try: try: - raise newException(EOS, "Problem") - except EOS: + raise newException(OSError, "Problem") + except OSError: return finally: discard @@ -17,4 +17,4 @@ proc test4() = # but could cause segmentation fault if # exceptions are not handled properly. test4() -raise newException(EOS, "Problem") +raise newException(OSError, "Problem") diff --git a/tests/exception/tunhandledexc.nim b/tests/exception/tunhandledexc.nim index f24881aef..aa9d61236 100644 --- a/tests/exception/tunhandledexc.nim +++ b/tests/exception/tunhandledexc.nim @@ -4,8 +4,8 @@ discard """ exitcode: "1" """ type - ESomething = object of E_Base - ESomeOtherErr = object of E_Base + ESomething = object of Exception + ESomeOtherErr = object of Exception proc genErrors(s: string) = if s == "error!": @@ -13,7 +13,7 @@ proc genErrors(s: string) = else: raise newException(EsomeotherErr, "bla") -when True: +when true: try: genErrors("errssor!") except ESomething: diff --git a/tests/exception/twrongexc.nim b/tests/exception/twrongexc.nim index 755f7d979..4e921b8a3 100644 --- a/tests/exception/twrongexc.nim +++ b/tests/exception/twrongexc.nim @@ -1,11 +1,11 @@ discard """ file: "twrongexc.nim" - outputsub: "Error: unhandled exception: [EInvalidValue]" + outputsub: "Error: unhandled exception: [ValueError]" exitcode: "1" """ try: - raise newException(EInvalidValue, "") -except EOverflow: + raise newException(ValueError, "") +except OverflowError: echo("Error caught") diff --git a/tests/let/tlet.nim b/tests/let/tlet.nim index 3d36432fb..6703ba254 100644 --- a/tests/let/tlet.nim +++ b/tests/let/tlet.nim @@ -3,9 +3,9 @@ discard """ errormsg: "'name' cannot be assigned to" """ -Echo("What's your name? ") +echo("What's your name? ") let name = readLine(stdin) while name == "": - Echo("Please tell me your name: ") + echo("Please tell me your name: ") name = readLine(stdin) diff --git a/tests/typerel/tnoargopenarray.nim b/tests/typerel/tnoargopenarray.nim index 872ec86d2..20ebe5ecc 100644 --- a/tests/typerel/tnoargopenarray.nim +++ b/tests/typerel/tnoargopenarray.nim @@ -1,7 +1,7 @@ import db_sqlite -var db: TDbConn -Exec(db, sql"create table blabla()") +var db: DbConn +exec(db, sql"create table blabla()") From ac01ed5812db159d2467cfdab0d9073784708dd3 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sun, 31 Aug 2014 20:14:49 +0100 Subject: [PATCH 073/409] Fix net module on Linux. --- lib/pure/net.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 5f202f05c..55ddf4bc2 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -183,7 +183,7 @@ when defined(ssl): when not defined(linux): newCTX = SSL_CTX_new(SSLv2_method()) else: - SSLError() + raiseSslError() of protSSLv3: newCTX = SSL_CTX_new(SSLv3_method()) of protTLSv1: From 41c7cde61f021682899390c550671d93a9bca370 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 31 Aug 2014 22:55:51 +0200 Subject: [PATCH 074/409] updated iup.nim; made tests green --- compiler/vm.nim | 4 +- examples/iupex1.nim | 44 +- examples/sdlex.nim | 20 +- examples/statcsv.nim | 6 +- lib/windows/mmsystem.nim | 589 ++++++++++++------------ lib/windows/nb30.nim | 78 ++-- lib/windows/shellapi.nim | 246 +++++----- lib/wrappers/iup.nim | 964 +++++++++++++++++++-------------------- lib/wrappers/sdl/sdl.nim | 162 +++---- 9 files changed, 1055 insertions(+), 1058 deletions(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index fe2b9c617..5ef4576ec 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1036,8 +1036,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = internalError(c.debug[pc], "too implement") of opcNarrowS: decodeB(rkInt) - let min = -(1 shl (rb-1)) - let max = (1 shl (rb-1))-1 + let min = -(1.BiggestInt shl (rb-1)) + let max = (1.BiggestInt shl (rb-1))-1 if regs[ra].intVal < min or regs[ra].intVal > max: stackTrace(c, tos, pc, errGenerated, msgKindToString(errUnhandledExceptionX) % "value out of range") diff --git a/examples/iupex1.nim b/examples/iupex1.nim index bf7ed2f1c..f768fb23f 100644 --- a/examples/iupex1.nim +++ b/examples/iupex1.nim @@ -1,37 +1,37 @@ # Example IUP program -# IupTabs: Creates a IupTabs control. +# iupTabs: Creates a iupTabs control. import iup -discard iup.Open(nil, nil) +discard iup.open(nil, nil) -var vbox1 = Iup.Vbox(Iup.Label("Inside Tab A"), Iup.Button("Button A", ""), nil) -var vbox2 = Iup.Vbox(Iup.Label("Inside Tab B"), Iup.Button("Button B", ""), nil) +var vbox1 = iup.vbox(iup.label("Inside Tab A"), iup.button("Button A", ""), nil) +var vbox2 = iup.vbox(iup.label("Inside Tab B"), iup.button("Button B", ""), nil) -Iup.SetAttribute(vbox1, "TABTITLE", "Tab A") -Iup.SetAttribute(vbox2, "TABTITLE", "Tab B") +iup.setAttribute(vbox1, "TABTITLE", "Tab A") +iup.setAttribute(vbox2, "TABTITLE", "Tab B") -var tabs1 = Iup.Tabs(vbox1, vbox2, nil) +var tabs1 = iup.tabs(vbox1, vbox2, nil) -vbox1 = Iup.Vbox(Iup.Label("Inside Tab C"), Iup.Button("Button C", ""), nil) -vbox2 = Iup.Vbox(Iup.Label("Inside Tab D"), Iup.Button("Button D", ""), nil) +vbox1 = iup.vbox(iup.label("Inside Tab C"), iup.button("Button C", ""), nil) +vbox2 = iup.vbox(iup.label("Inside Tab D"), iup.button("Button D", ""), nil) -Iup.SetAttribute(vbox1, "TABTITLE", "Tab C") -Iup.SetAttribute(vbox2, "TABTITLE", "Tab D") +iup.setAttribute(vbox1, "TABTITLE", "Tab C") +iup.setAttribute(vbox2, "TABTITLE", "Tab D") -var tabs2 = Iup.Tabs(vbox1, vbox2, nil) -Iup.SetAttribute(tabs2, "TABTYPE", "LEFT") +var tabs2 = iup.tabs(vbox1, vbox2, nil) +iup.setAttribute(tabs2, "TABTYPE", "LEFT") -var box = Iup.Hbox(tabs1, tabs2, nil) -Iup.SetAttribute(box, "MARGIN", "10x10") -Iup.SetAttribute(box, "GAP", "10") +var box = iup.hbox(tabs1, tabs2, nil) +iup.setAttribute(box, "MARGIN", "10x10") +iup.setAttribute(box, "GAP", "10") -var dlg = Iup.Dialog(box) -Iup.SetAttribute(dlg, "TITLE", "IupTabs") -Iup.SetAttribute(dlg, "SIZE", "200x100") +var dlg = iup.dialog(box) +iup.setAttribute(dlg, "TITLE", "iupTabs") +iup.setAttribute(dlg, "SIZE", "200x100") -discard ShowXY(dlg, IUP_CENTER, IUP_CENTER) -discard MainLoop() -Close() +discard showXY(dlg, IUP_CENTER, IUP_CENTER) +discard mainLoop() +close() diff --git a/examples/sdlex.nim b/examples/sdlex.nim index 2c1a413e9..665affff8 100644 --- a/examples/sdlex.nim +++ b/examples/sdlex.nim @@ -9,21 +9,21 @@ var event: TEvent bgColor = colChocolate.int32 -if init(INIT_VIDEO) != 0: +if Init(INIT_VIDEO) != 0: quit "SDL failed to initialize!" screen = SetVideoMode(640, 480, 16, SWSURFACE or ANYFORMAT) if screen.isNil: - quit($sdl.getError()) + quit($sdl.GetError()) greeting = IMG_load("tux.png") if greeting.isNil: echo "Failed to load tux.png" else: ## convert the image to alpha and free the old one - var s = greeting.displayFormatAlpha() + var s = greeting.DisplayFormatAlpha() swap(greeting, s) - s.freeSurface() + s.FreeSurface() r.x = 0 r.y = 0 @@ -31,7 +31,7 @@ r.y = 0 block game_loop: while true: - while pollEvent(addr event) > 0: + while PollEvent(addr event) > 0: case event.kind of QUITEV: break game_loop @@ -41,12 +41,12 @@ block game_loop: else: discard - discard fillRect(screen, nil, bgColor) - discard blitSurface(greeting, nil, screen, addr r) - discard flip(screen) + discard FillRect(screen, nil, bgColor) + discard BlitSurface(greeting, nil, screen, addr r) + discard Flip(screen) -greeting.freeSurface() -screen.freeSurface() +greeting.FreeSurface() +screen.FreeSurface() sdl.Quit() ## fowl wuz here 10/2012 \ No newline at end of file diff --git a/examples/statcsv.nim b/examples/statcsv.nim index 48c4ea0cc..cd1de62af 100644 --- a/examples/statcsv.nim +++ b/examples/statcsv.nim @@ -8,14 +8,14 @@ import os, streams, parsecsv, strutils, math if paramCount() < 1: quit("Usage: statcsv filename[.csv]") -var filename = addFileExt(ParamStr(1), "csv") +var filename = addFileExt(paramStr(1), "csv") var s = newFileStream(filename, fmRead) if s == nil: quit("cannot open the file " & filename) var - x: TCsvParser + x: CsvParser header: seq[string] - res: seq[TRunningStat] + res: seq[RunningStat] open(x, s, filename, separator=';', skipInitialSpace = true) while readRow(x): if processedRows(x) == 1: diff --git a/lib/windows/mmsystem.nim b/lib/windows/mmsystem.nim index 632a6e557..45613d8e2 100644 --- a/lib/windows/mmsystem.nim +++ b/lib/windows/mmsystem.nim @@ -27,15 +27,15 @@ import windows type - MMRESULT* = UINT - MMVERSION* = UINT + MMRESULT* = uint32 + MMVERSION* = uint32 HWAVEOUT* = THandle LPHWAVEOUT* = ptr HWAVEOUT HWAVEIN* = THandle LPHWAVEIN* = ptr HWAVEOUT HWAVE* = THandle LPHWAVE* = ptr THandle - LPUINT* = ptr UINT + LPUINT* = ptr uint32 const MAXPNAMELEN* = 32 @@ -178,18 +178,18 @@ const DRV_MCI_LAST* = (DRV_RESERVED + 0x00000FFF) type - PDRVCALLBACK* = proc (hdrvr: tHandle, uMsg: UINT, dwUser, dw1, dw2: DWORD){. + PDRVCALLBACK* = proc (hdrvr: THandle, uMsg: uint32, dwUser, dw1, dw2: DWORD){. stdcall.} -proc sndPlaySoundA*(Name: LPCSTR, flags: UINT): BOOL{.stdcall, +proc sndPlaySoundA*(Name: LPCSTR, flags: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "sndPlaySoundA".} -proc sndPlaySoundW*(Name: LPCWSTR, flags: UINT): BOOL{.stdcall, +proc sndPlaySoundW*(Name: LPCWSTR, flags: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "sndPlaySoundW".} when defined(winUNICODE): - proc sndPlaySound*(Name: cstring, flags: UINT): BOOL{.stdcall, + proc sndPlaySound*(Name: cstring, flags: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "sndPlaySoundW".} else: - proc sndPlaySound*(Name: cstring, flags: UINT): BOOL{.stdcall, + proc sndPlaySound*(Name: cstring, flags: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "sndPlaySoundA".} const SND_NODEFAULT* = 2 @@ -225,12 +225,12 @@ const WIM_OPEN* = MM_WIM_OPEN WIM_CLOSE* = MM_WIM_CLOSE WIM_DATA* = MM_WIM_DATA - WAVE_MAPPER* = UINT(- 1) + WAVE_MAPPER* = uint32(- 1) WAVE_FORMAT_QUERY* = 1 WAVE_ALLOWSYNC* = 2 WAVE_MAPPED* = 4 WAVE_FORMAT_DIRECT* = 8 - WAVE_FORMAT_DIRECT_QUERY* = (WAVE_FORMAT_QUERY Or WAVE_FORMAT_DIRECT) + WAVE_FORMAT_DIRECT_QUERY* = (WAVE_FORMAT_QUERY or WAVE_FORMAT_DIRECT) MIM_OPEN* = MM_MIM_OPEN MIM_CLOSE* = MM_MIM_CLOSE MIM_DATA* = MM_MIM_DATA @@ -242,7 +242,7 @@ const MOM_DONE* = MM_MOM_DONE MIM_MOREDATA* = MM_MIM_MOREDATA MOM_POSITIONCB* = MM_MOM_POSITIONCB - MIDIMAPPER* = UINT(- 1) + MIDIMAPPER* = uint32(- 1) MIDI_IO_STATUS* = 32 MIDI_CACHE_ALL* = 1 MIDI_CACHE_BESTFIT* = 2 @@ -364,53 +364,53 @@ const MIXERCONTROL_CT_UNITS_DECIBELS* = 0x00040000 MIXERCONTROL_CT_UNITS_PERCENT* = 0x00050000 MIXERCONTROL_CONTROLTYPE_CUSTOM* = ( - MIXERCONTROL_CT_CLASS_CUSTOM Or MIXERCONTROL_CT_UNITS_CUSTOM) - MIXERCONTROL_CONTROLTYPE_BOOLEANMETER* = (MIXERCONTROL_CT_CLASS_METER Or - MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_BOOLEAN) - MIXERCONTROL_CONTROLTYPE_SIGNEDMETER* = (MIXERCONTROL_CT_CLASS_METER Or - MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_SIGNED) + MIXERCONTROL_CT_CLASS_CUSTOM or MIXERCONTROL_CT_UNITS_CUSTOM) + MIXERCONTROL_CONTROLTYPE_BOOLEANMETER* = (MIXERCONTROL_CT_CLASS_METER or + MIXERCONTROL_CT_SC_METER_POLLED or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_SIGNEDMETER* = (MIXERCONTROL_CT_CLASS_METER or + MIXERCONTROL_CT_SC_METER_POLLED or MIXERCONTROL_CT_UNITS_SIGNED) MIXERCONTROL_CONTROLTYPE_PEAKMETER* = ( MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1) - MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER* = (MIXERCONTROL_CT_CLASS_METER Or - MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_UNSIGNED) - MIXERCONTROL_CONTROLTYPE_BOOLEAN* = (MIXERCONTROL_CT_CLASS_SWITCH Or - MIXERCONTROL_CT_SC_SWITCH_BOOLEAN Or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER* = (MIXERCONTROL_CT_CLASS_METER or + MIXERCONTROL_CT_SC_METER_POLLED or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CONTROLTYPE_BOOLEAN* = (MIXERCONTROL_CT_CLASS_SWITCH or + MIXERCONTROL_CT_SC_SWITCH_BOOLEAN or MIXERCONTROL_CT_UNITS_BOOLEAN) MIXERCONTROL_CONTROLTYPE_ONOFF* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1) MIXERCONTROL_CONTROLTYPE_MUTE* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2) MIXERCONTROL_CONTROLTYPE_MONO* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3) MIXERCONTROL_CONTROLTYPE_LOUDNESS* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4) MIXERCONTROL_CONTROLTYPE_STEREOENH* = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5) - MIXERCONTROL_CONTROLTYPE_BUTTON* = (MIXERCONTROL_CT_CLASS_SWITCH Or - MIXERCONTROL_CT_SC_SWITCH_BUTTON Or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_BUTTON* = (MIXERCONTROL_CT_CLASS_SWITCH or + MIXERCONTROL_CT_SC_SWITCH_BUTTON or MIXERCONTROL_CT_UNITS_BOOLEAN) MIXERCONTROL_CONTROLTYPE_DECIBELS* = ( - MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_DECIBELS) + MIXERCONTROL_CT_CLASS_NUMBER or MIXERCONTROL_CT_UNITS_DECIBELS) MIXERCONTROL_CONTROLTYPE_SIGNED* = ( - MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_SIGNED) + MIXERCONTROL_CT_CLASS_NUMBER or MIXERCONTROL_CT_UNITS_SIGNED) MIXERCONTROL_CONTROLTYPE_UNSIGNED* = ( - MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CT_CLASS_NUMBER or MIXERCONTROL_CT_UNITS_UNSIGNED) MIXERCONTROL_CONTROLTYPE_PERCENT* = ( - MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_PERCENT) + MIXERCONTROL_CT_CLASS_NUMBER or MIXERCONTROL_CT_UNITS_PERCENT) MIXERCONTROL_CONTROLTYPE_SLIDER* = ( - MIXERCONTROL_CT_CLASS_SLIDER Or MIXERCONTROL_CT_UNITS_SIGNED) + MIXERCONTROL_CT_CLASS_SLIDER or MIXERCONTROL_CT_UNITS_SIGNED) MIXERCONTROL_CONTROLTYPE_PAN* = (MIXERCONTROL_CONTROLTYPE_SLIDER + 1) MIXERCONTROL_CONTROLTYPE_QSOUNDPAN* = (MIXERCONTROL_CONTROLTYPE_SLIDER + 2) MIXERCONTROL_CONTROLTYPE_FADER* = ( - MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CT_CLASS_FADER or MIXERCONTROL_CT_UNITS_UNSIGNED) MIXERCONTROL_CONTROLTYPE_VOLUME* = (MIXERCONTROL_CONTROLTYPE_FADER + 1) MIXERCONTROL_CONTROLTYPE_BASS* = (MIXERCONTROL_CONTROLTYPE_FADER + 2) MIXERCONTROL_CONTROLTYPE_TREBLE* = (MIXERCONTROL_CONTROLTYPE_FADER + 3) MIXERCONTROL_CONTROLTYPE_EQUALIZER* = (MIXERCONTROL_CONTROLTYPE_FADER + 4) - MIXERCONTROL_CONTROLTYPE_SINGLESELECT* = (MIXERCONTROL_CT_CLASS_LIST Or - MIXERCONTROL_CT_SC_LIST_SINGLE Or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_SINGLESELECT* = (MIXERCONTROL_CT_CLASS_LIST or + MIXERCONTROL_CT_SC_LIST_SINGLE or MIXERCONTROL_CT_UNITS_BOOLEAN) MIXERCONTROL_CONTROLTYPE_MUX* = (MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1) - MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT* = (MIXERCONTROL_CT_CLASS_LIST Or - MIXERCONTROL_CT_SC_LIST_MULTIPLE Or MIXERCONTROL_CT_UNITS_BOOLEAN) + MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT* = (MIXERCONTROL_CT_CLASS_LIST or + MIXERCONTROL_CT_SC_LIST_MULTIPLE or MIXERCONTROL_CT_UNITS_BOOLEAN) MIXERCONTROL_CONTROLTYPE_MIXER* = (MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1) - MIXERCONTROL_CONTROLTYPE_MICROTIME* = (MIXERCONTROL_CT_CLASS_TIME Or - MIXERCONTROL_CT_SC_TIME_MICROSECS Or MIXERCONTROL_CT_UNITS_UNSIGNED) - MIXERCONTROL_CONTROLTYPE_MILLITIME* = (MIXERCONTROL_CT_CLASS_TIME Or - MIXERCONTROL_CT_SC_TIME_MILLISECS Or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CONTROLTYPE_MICROTIME* = (MIXERCONTROL_CT_CLASS_TIME or + MIXERCONTROL_CT_SC_TIME_MICROSECS or MIXERCONTROL_CT_UNITS_UNSIGNED) + MIXERCONTROL_CONTROLTYPE_MILLITIME* = (MIXERCONTROL_CT_CLASS_TIME or + MIXERCONTROL_CT_SC_TIME_MILLISECS or MIXERCONTROL_CT_UNITS_UNSIGNED) MIXER_SHORT_NAME_CHARS* = 16 MIXER_LONG_NAME_CHARS* = 64 MIXERR_INVALLINE* = (MIXERR_BASE + 0) @@ -419,15 +419,15 @@ const MIXERR_LASTERROR* = (MIXERR_BASE + 2) MIXER_OBJECTF_HANDLE* = 0x80000000 MIXER_OBJECTF_MIXER* = 0 - MIXER_OBJECTF_HMIXER* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIXER) + MIXER_OBJECTF_HMIXER* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_MIXER) MIXER_OBJECTF_WAVEOUT* = 0x10000000 - MIXER_OBJECTF_HWAVEOUT* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEOUT) + MIXER_OBJECTF_HWAVEOUT* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_WAVEOUT) MIXER_OBJECTF_WAVEIN* = 0x20000000 - MIXER_OBJECTF_HWAVEIN* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEIN) + MIXER_OBJECTF_HWAVEIN* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_WAVEIN) MIXER_OBJECTF_MIDIOUT* = 0x30000000 - MIXER_OBJECTF_HMIDIOUT* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIOUT) + MIXER_OBJECTF_HMIDIOUT* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_MIDIOUT) MIXER_OBJECTF_MIDIIN* = 0x40000000 - MIXER_OBJECTF_HMIDIIN* = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIIN) + MIXER_OBJECTF_HMIDIIN* = (MIXER_OBJECTF_HANDLE or MIXER_OBJECTF_MIDIIN) MIXER_OBJECTF_AUX* = 0x50000000 MIXER_GETCONTROLDETAILSF_VALUE* = 0 MIXER_GETCONTROLDETAILSF_LISTTEXT* = 1 @@ -492,8 +492,8 @@ const JOY_RETURNPOVCTS* = 512 JOY_RETURNCENTERED* = 0x00000400 JOY_USEDEADZONE* = 0x00000800 - JOY_RETURNALL* = (JOY_RETURNX Or JOY_RETURNY Or JOY_RETURNZ Or JOY_RETURNR Or - JOY_RETURNU Or JOY_RETURNV Or JOY_RETURNPOV Or JOY_RETURNBUTTONS) + JOY_RETURNALL* = (JOY_RETURNX or JOY_RETURNY or JOY_RETURNZ or JOY_RETURNR or + JOY_RETURNU or JOY_RETURNV or JOY_RETURNPOV or JOY_RETURNBUTTONS) JOY_CAL_READALWAYS* = 0x00010000 JOY_CAL_READXYONLY* = 0x00020000 JOY_CAL_READ3* = 0x00040000 @@ -982,17 +982,17 @@ const #///////////////////////////////////////////////////////// type - mmtime* {.final.} = object - wType*: UINT + MMTIME* {.final.} = object + wType*: uint32 hour*, min*, sec*, frame*, fps*, dummy*: int8 pad*: array[0..1, int8] - PMMTIME* = ptr mmtime - NPMMTIME* = ptr mmtime - LPMMTIME* = ptr mmtime - PWAVEHDR* = ptr wavehdr - TMMTime* = mmtime - wavehdr* {.final.} = object + PMMTIME* = ptr MMTIME + NPMMTIME* = ptr MMTIME + LPMMTIME* = ptr MMTIME + PWAVEHDR* = ptr WAVEHDR + TMMTime* = MMTIME + WAVEHDR* {.final.} = object lpData*: cstring dwBufferLength*: DWORD dwBytesRecorded*: DWORD @@ -1003,13 +1003,13 @@ type reserved*: DWORD TWAVEHDR* = WAVEHDR - NPWAVEHDR* = ptr wavehdr - LPWAVEHDR* = ptr wavehdr + NPWAVEHDR* = ptr WAVEHDR + LPWAVEHDR* = ptr WAVEHDR WAVEOUTCAPSA* {.final.} = object wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] dwFormats*: DWORD wChannels*: int16 wReserved1*: int16 @@ -1023,7 +1023,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), WCHAR] dwFormats*: DWORD wChannels*: int16 wReserved1*: int16 @@ -1052,7 +1052,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] dwFormats*: DWORD wChannels*: int16 wReserved1*: int16 @@ -1065,7 +1065,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), WCHAR] dwFormats*: DWORD wChannels*: int16 wReserved1*: int16 @@ -1089,29 +1089,29 @@ else: LPWAVEINCAPS* = LPWAVEINCAPSA type TWAVEINCAPS* = WAVEINCAPS - waveformat* {.final.} = object + WAVEFORMAT* {.final.} = object wFormatTag*: int16 nChannels*: int16 nSamplesPerSec*: DWORD nAvgBytesPerSec*: DWORD nBlockAlign*: int16 - PWAVEFORMAT* = ptr waveformat - NPWAVEFORMAT* = ptr waveformat - LPWAVEFORMAT* = ptr waveformat - TWAVEFORMAT* = waveformat + PWAVEFORMAT* = ptr WAVEFORMAT + NPWAVEFORMAT* = ptr WAVEFORMAT + LPWAVEFORMAT* = ptr WAVEFORMAT + TWAVEFORMAT* = WAVEFORMAT const WAVE_FORMAT_PCM* = 1 type - pcmwaveformat* {.final.} = object + PCMWAVEFORMAT* {.final.} = object wf*: WAVEFORMAT wBitsPerSample*: int16 - PPCMWAVEFORMAT* = ptr pcmwaveformat - NPPCMWAVEFORMAT* = ptr pcmwaveformat - LPPCMWAVEFORMAT* = ptr pcmwaveformat + PPCMWAVEFORMAT* = ptr PCMWAVEFORMAT + NPPCMWAVEFORMAT* = ptr PCMWAVEFORMAT + LPPCMWAVEFORMAT* = ptr PCMWAVEFORMAT TPCMWAVEFORMAT* = PCMWAVEFORMAT WAVEFORMATEX* {.final.} = object wFormatTag*: int16 @@ -1141,15 +1141,15 @@ const MIDIPATCHSIZE* = 128 type - PATCHARRAY* = array[0..Pred(MIDIPATCHSIZE), int16] + PATCHARRAY* = array[0..pred(MIDIPATCHSIZE), int16] LPPATCHARRAY* = ptr int16 - KEYARRAY* = array[0..Pred(MIDIPATCHSIZE), int16] + KEYARRAY* = array[0..pred(MIDIPATCHSIZE), int16] LPKEYARRAY* = ptr int16 MIDIOUTCAPSA* {.final.} = object wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] wTechnology*: int16 wVoices*: int16 wNotes*: int16 @@ -1164,7 +1164,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), Wchar] wTechnology*: int16 wVoices*: int16 wNotes*: int16 @@ -1179,7 +1179,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] dwSupport*: DWORD PMIDIINCAPSA* = ptr MIDIINCAPSA @@ -1190,7 +1190,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), Wchar] dwSupport*: DWORD PMIDIINCAPSW* = ptr MIDIINCAPSW @@ -1220,8 +1220,8 @@ else: LPMIDIINCAPS* = LPMIDIINCAPSA type TMIDIINCAPS* = MIDIINCAPS - PMIDIHDR* = ptr midihdr - midihdr* {.final.} = object + PMIDIHDR* = ptr MIDIHDR + MIDIHDR* {.final.} = object lpData*: cstring dwBufferLength*: DWORD dwBytesRecorded*: DWORD @@ -1230,19 +1230,19 @@ type lpNext*: PMIDIHDR reserved*: DWORD dwOffset*: DWORD - dwReserved*: array[0..Pred(8), DWORD] + dwReserved*: array[0..pred(8), DWORD] - NPMIDIHDR* = ptr midihdr - LPMIDIHDR* = ptr midihdr + NPMIDIHDR* = ptr MIDIHDR + LPMIDIHDR* = ptr MIDIHDR TMIDIHDR* = MIDIHDR - midievent* {.final.} = object + MIDIEVENT* {.final.} = object dwDeltaTime*: DWORD dwStreamID*: DWORD dwEvent*: DWORD - dwParms*: array[0..Pred(1), DWORD] + dwParms*: array[0..pred(1), DWORD] TMIDIEVENT* = MIDIEVENT - midistrmbuffver* {.final.} = object + MIDISTRMBUFFVER* {.final.} = object dwVersion*: DWORD dwMid*: DWORD dwOEMVersion*: DWORD @@ -1262,7 +1262,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] wTechnology*: int16 wReserved1*: int16 dwSupport*: DWORD @@ -1275,7 +1275,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), Wchar] wTechnology*: int16 wReserved1*: int16 dwSupport*: DWORD @@ -1304,14 +1304,14 @@ type HMIXER* = THandle LPHMIXER* = ptr HMIXER -proc mixerGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc mixerGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "mixerGetNumDevs".} type MIXERCAPSA* {.final.} = object wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] fdwSupport*: DWORD cDestinations*: DWORD @@ -1322,7 +1322,7 @@ type wMid*: int16 wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), Wchar] fdwSupport*: DWORD cDestinations*: DWORD @@ -1353,12 +1353,12 @@ type cChannels*: DWORD cConnections*: DWORD cControls*: DWORD - szShortName*: array[0..Pred(MIXER_SHORT_NAME_CHARS), CHAR] - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR] + szShortName*: array[0..pred(MIXER_SHORT_NAME_CHARS), char] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), char] dwType*, dwDeviceID*: DWORD wMid*, wPid*: int16 vDriverVersion*: MMVERSION - szPname*: array[0..pred(MAXPNAMELEN), Char] + szPname*: array[0..pred(MAXPNAMELEN), char] PMIXERLINEA* = ptr MIXERLINEA LPMIXERLINEA* = ptr MIXERLINEA @@ -1374,8 +1374,8 @@ type cChannels*: DWORD cConnections*: DWORD cControls*: DWORD - szShortName*: array[0..Pred(MIXER_SHORT_NAME_CHARS), WCHAR] - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR] + szShortName*: array[0..pred(MIXER_SHORT_NAME_CHARS), WCHAR] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), WCHAR] dwType*, dwDeviceID*: DWORD wMid*, wPid*: int16 vDriverVersion*: MMVERSION @@ -1403,8 +1403,8 @@ type dwControlType*: DWORD fdwControl*: DWORD cMultipleItems*: DWORD - szShortName*: array[0..Pred(MIXER_SHORT_NAME_CHARS), CHAR] - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR] + szShortName*: array[0..pred(MIXER_SHORT_NAME_CHARS), char] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), char] dwMinimum*, dwMaximum*: DWORD dwReserved*: array[0..3, DWORD] cSteps*: DWORD @@ -1419,8 +1419,8 @@ type dwControlType*: DWORD fdwControl*: DWORD cMultipleItems*: DWORD - szShortName*: array[0..Pred(MIXER_SHORT_NAME_CHARS), WCHAR] - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR] + szShortName*: array[0..pred(MIXER_SHORT_NAME_CHARS), WCHAR] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), WCHAR] dwMinimum*, dwMaximum*: DWORD dwReserved*: array[0..3, DWORD] cSteps*: DWORD @@ -1478,15 +1478,15 @@ type dwControlID*: DWORD cChannels*: DWORD cMultipleItems*, cbDetails*: DWORD - paDetails*: Pointer + paDetails*: pointer - MIXERCONTROLDETAILS* = tMIXERCONTROLDETAILS - PMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS - LPMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS + MIXERCONTROLDETAILS* = TMIXERCONTROLDETAILS + PMIXERCONTROLDETAILS* = ptr TMIXERCONTROLDETAILS + LPMIXERCONTROLDETAILS* = ptr TMIXERCONTROLDETAILS MIXERCONTROLDETAILS_LISTTEXTA* {.final.} = object dwParam1*: DWORD dwParam2*: DWORD - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), char] PMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA LPMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA @@ -1494,7 +1494,7 @@ type MIXERCONTROLDETAILS_LISTTEXTW* {.final.} = object dwParam1*: DWORD dwParam2*: DWORD - szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR] + szName*: array[0..pred(MIXER_LONG_NAME_CHARS), WCHAR] PMIXERCONTROLDETAILS_LISTTEXTW* = ptr MIXERCONTROLDETAILS_LISTTEXTW LPMIXERCONTROLDETAILS_LISTTEXTW* = ptr MIXERCONTROLDETAILS_LISTTEXTW @@ -1530,42 +1530,42 @@ type PMIXERCONTROLDETAILS_UNSIGNED* = ptr MIXERCONTROLDETAILS_UNSIGNED LPMIXERCONTROLDETAILS_UNSIGNED* = ptr MIXERCONTROLDETAILS_UNSIGNED TMIXERCONTROLDETAILS_UNSIGNED* = MIXERCONTROLDETAILS_UNSIGNED - LPTIMECALLBACK* = proc (uTimerID, uMsg: UINT, dwUser, dw1, dw2: DWORD){. + LPTIMECALLBACK* = proc (uTimerID, uMsg: uint32, dwUser, dw1, dw2: DWORD){. stdcall.} TTIMECALLBACK* = LPTIMECALLBACK - timecaps* {.final.} = object - wPeriodMin*: UINT - wPeriodMax*: UINT + TIMECAPS* {.final.} = object + wPeriodMin*: uint32 + wPeriodMax*: uint32 - PTIMECAPS* = ptr timecaps - NPTIMECAPS* = ptr timecaps - LPTIMECAPS* = ptr timecaps + PTIMECAPS* = ptr TIMECAPS + NPTIMECAPS* = ptr TIMECAPS + LPTIMECAPS* = ptr TIMECAPS TTIMECAS* = TIMECAPS JOYCAPSA* {.final.} = object wMid*: int16 wPid*: int16 - szPname*: array[0..Pred(MAXPNAMELEN), CHAR] - wXmin*: UINT - wXmax*: UINT - wYmin*: UINT - wYmax*: UINT - wZmin*: UINT - wZmax*: UINT - wNumButtons*: UINT - wPeriodMin*: UINT - wPeriodMax*: UINT - wRmin*: UINT - wRmax*: UINT - wUmin*: UINT - wUmax*: UINT - wVmin*: UINT - wVmax*: UINT - wCaps*: UINT - wMaxAxes*: UINT - wNumAxes*: UINT - wMaxButtons*: UINT - szRegKey*: array[0..Pred(MAXPNAMELEN), CHAR] - szOEMVxD*: array[0..Pred(MAX_JOYSTICKOEMVXDNAME), CHAR] + szPname*: array[0..pred(MAXPNAMELEN), char] + wXmin*: uint32 + wXmax*: uint32 + wYmin*: uint32 + wYmax*: uint32 + wZmin*: uint32 + wZmax*: uint32 + wNumButtons*: uint32 + wPeriodMin*: uint32 + wPeriodMax*: uint32 + wRmin*: uint32 + wRmax*: uint32 + wUmin*: uint32 + wUmax*: uint32 + wVmin*: uint32 + wVmax*: uint32 + wCaps*: uint32 + wMaxAxes*: uint32 + wNumAxes*: uint32 + wMaxButtons*: uint32 + szRegKey*: array[0..pred(MAXPNAMELEN), char] + szOEMVxD*: array[0..pred(MAX_JOYSTICKOEMVXDNAME), char] PJOYCAPSA* = ptr JOYCAPSA NPJOYCAPSA* = ptr JOYCAPSA @@ -1574,28 +1574,28 @@ type JOYCAPSW* {.final.} = object wMid*: int16 wPid*: int16 - szPname*: array[0..Pred(MAXPNAMELEN), WCHAR] - wXmin*: UINT - wXmax*: UINT - wYmin*: UINT - wYmax*: UINT - wZmin*: UINT - wZmax*: UINT - wNumButtons*: UINT - wPeriodMin*: UINT - wPeriodMax*: UINT - wRmin*: UINT - wRmax*: UINT - wUmin*: UINT - wUmax*: UINT - wVmin*: UINT - wVmax*: UINT - wCaps*: UINT - wMaxAxes*: UINT - wNumAxes*: UINT - wMaxButtons*: UINT - szRegKey*: array[0..Pred(MAXPNAMELEN), WCHAR] - szOEMVxD*: array[0..Pred(MAX_JOYSTICKOEMVXDNAME), WCHAR] + szPname*: array[0..pred(MAXPNAMELEN), WCHAR] + wXmin*: uint32 + wXmax*: uint32 + wYmin*: uint32 + wYmax*: uint32 + wZmin*: uint32 + wZmax*: uint32 + wNumButtons*: uint32 + wPeriodMin*: uint32 + wPeriodMax*: uint32 + wRmin*: uint32 + wRmax*: uint32 + wUmin*: uint32 + wUmax*: uint32 + wVmin*: uint32 + wVmax*: uint32 + wCaps*: uint32 + wMaxAxes*: uint32 + wNumAxes*: uint32 + wMaxButtons*: uint32 + szRegKey*: array[0..pred(MAXPNAMELEN), WCHAR] + szOEMVxD*: array[0..pred(MAX_JOYSTICKOEMVXDNAME), WCHAR] PJOYCAPSW* = ptr JOYCAPSW NPJOYCAPSW* = ptr JOYCAPSW @@ -1616,45 +1616,45 @@ else: LPJOYCAPS* = LPJOYCAPSA type TJOYCAPS* = JOYCAPS - joyinfo* {.final.} = object - wXpos*: UINT - wYpos*: UINT - wZpos*: UINT - wButtons*: UINT + JOYINFO* {.final.} = object + wXpos*: uint32 + wYpos*: uint32 + wZpos*: uint32 + wButtons*: uint32 - PJOYINFO* = ptr joyinfo - NPJOYINFO* = ptr joyinfo - LPJOYINFO* = ptr joyinfo + PJOYINFO* = ptr JOYINFO + NPJOYINFO* = ptr JOYINFO + LPJOYINFO* = ptr JOYINFO TJOYINFO* = JOYINFO - joyinfoex* {.final.} = object + JOYINFOEX* {.final.} = object dwSize*: DWORD dwFlags*: DWORD - wXpos*: UINT - wYpos*: UINT - wZpos*: UINT + wXpos*: uint32 + wYpos*: uint32 + wZpos*: uint32 dwRpos*: DWORD dwUpos*: DWORD dwVpos*: DWORD - wButtons*: UINT + wButtons*: uint32 dwButtonNumber*: DWORD dwPOV*: DWORD dwReserved1*: DWORD dwReserved2*: DWORD - PJOYINFOEX* = ptr joyinfoex - NPJOYINFOEX* = ptr joyinfoex - LPJOYINFOEX* = ptr joyinfoex + PJOYINFOEX* = ptr JOYINFOEX + NPJOYINFOEX* = ptr JOYINFOEX + LPJOYINFOEX* = ptr JOYINFOEX TJOYINFOEX* = JOYINFOEX FOURCC* = DWORD HPSTR* = cstring HMMIO* = THandle - LPMMIOPROC* = proc (x1: LPSTR, x2: UINT, x3, x4: LPARAM): LRESULT{.stdcall.} + LPMMIOPROC* = proc (x1: LPSTR, x2: uint32, x3, x4: LPARAM): LRESULT{.stdcall.} TMMIOPROC* = LPMMIOPROC MMIOINFO* {.final.} = object dwFlags*: DWORD fccIOProc*: FOURCC pIOProc*: LPMMIOPROC - wErrorRet*: UINT + wErrorRet*: uint32 htask*: HTASK cchBuffer*: int32 pchBuffer*: HPSTR @@ -1663,7 +1663,7 @@ type pchEndWrite*: HPSTR lBufOffset*: int32 lDiskOffset*: int32 - adwInfo*: array[0..Pred(3), DWORD] + adwInfo*: array[0..pred(3), DWORD] dwReserved1*: DWORD dwReserved2*: DWORD hmmio*: HMMIO @@ -1686,8 +1686,8 @@ type LPCMMCKINFO* = ptr MMCKINFO TMMCKINFO* = MMCKINFO MCIERROR* = DWORD - MCIDEVICEID* = UINT - YIELDPROC* = proc (mciId: MCIDEVICEID, dwYieldData: DWORD): UINT{.stdcall.} + MCIDEVICEID* = uint32 + YIELDPROC* = proc (mciId: MCIDEVICEID, dwYieldData: DWORD): uint32{.stdcall.} TYIELDPROC* = YIELDPROC MCI_GENERIC_PARMS* {.final.} = object dwCallback*: DWORD @@ -1790,7 +1790,7 @@ type lpstrReturn*: cstring dwRetSize*: DWORD dwNumber*: DWORD - wDeviceType*: UINT + wDeviceType*: uint32 PMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA LPMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA @@ -1800,7 +1800,7 @@ type lpstrReturn*: LPWSTR dwRetSize*: DWORD dwNumber*: DWORD - wDeviceType*: UINT + wDeviceType*: uint32 PMCI_SYSINFO_PARMSW* = ptr MCI_SYSINFO_PARMSW LPMCI_SYSINFO_PARMSW* = ptr MCI_SYSINFO_PARMSW @@ -1984,8 +1984,8 @@ type dwCallback*: DWORD dwTimeFormat*: DWORD dwAudio*: DWORD - wInput*: UINT - wOutput*: UINT + wInput*: uint32 + wOutput*: uint32 wFormatTag*: int16 wReserved2*: int16 nChannels*: int16 @@ -2052,7 +2052,7 @@ type MCI_ANIM_WINDOW_PARMSW* {.final.} = object dwCallback*: DWORD hWnd*: HWND - nCmdShow*: UINT + nCmdShow*: uint32 lpstrText*: LPCWSTR PMCI_ANIM_WINDOW_PARMSW* = ptr MCI_ANIM_WINDOW_PARMSW @@ -2068,7 +2068,7 @@ type MCI_ANIM_WINDOW_PARMSA* {.final.} = object dwCallback*: DWORD hWnd*: HWND - nCmdShow*: UINT + nCmdShow*: uint32 lpstrText*: LPCSTR PMCI_ANIM_WINDOW_PARMSA* = ptr MCI_ANIM_WINDOW_PARMSA @@ -2149,7 +2149,7 @@ type MCI_OVLY_WINDOW_PARMSA* {.final.} = object dwCallback*: DWORD hWnd*: HWND - nCmdShow*: UINT + nCmdShow*: uint32 lpstrText*: LPCSTR PMCI_OVLY_WINDOW_PARMSA* = ptr MCI_OVLY_WINDOW_PARMSA @@ -2158,7 +2158,7 @@ type MCI_OVLY_WINDOW_PARMSW* {.final.} = object dwCallback*: DWORD hWnd*: HWND - nCmdShow*: UINT + nCmdShow*: uint32 lpstrText*: LPCWSTR PMCI_OVLY_WINDOW_PARMSW* = ptr MCI_OVLY_WINDOW_PARMSW @@ -2243,14 +2243,11 @@ else: type TMCI_OVLY_LOAD_PARMS* = MCI_OVLY_LOAD_PARMS -type - pcmwaveformat_tag* = PCMWAVEFORMAT - -proc mmioStringToFOURCCA*(x1: LPCSTR, x2: UINT): FOURCC{.stdcall, +proc mmioStringToFOURCCA*(x1: LPCSTR, x2: uint32): FOURCC{.stdcall, dynlib: "winmm.dll", importc: "mmioStringToFOURCCA".} -proc mmioStringToFOURCCW*(x1: LPCWSTR, x2: UINT): FOURCC{.stdcall, +proc mmioStringToFOURCCW*(x1: LPCWSTR, x2: uint32): FOURCC{.stdcall, dynlib: "winmm.dll", importc: "mmioStringToFOURCCW".} -proc mmioStringToFOURCC*(x1: cstring, x2: UINT): FOURCC{.stdcall, +proc mmioStringToFOURCC*(x1: cstring, x2: uint32): FOURCC{.stdcall, dynlib: "winmm.dll", importc: "mmioStringToFOURCCA".} proc mmioInstallIOProcA*(x1: FOURCC, x2: LPMMIOPROC, x3: DWORD): LPMMIOPROC{. stdcall, dynlib: "winmm.dll", importc: "mmioInstallIOProcA".} @@ -2270,7 +2267,7 @@ proc mmioRenameW*(x1: LPCWSTR, x2: LPCWSTR, x3: LPCMMIOINFO, x4: DWORD): MMRESUL stdcall, dynlib: "winmm.dll", importc: "mmioRenameW".} proc mmioRename*(x1: cstring, x2: cstring, x3: LPCMMIOINFO, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mmioRenameA".} -proc mmioClose*(x1: HMMIO, x2: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc mmioClose*(x1: HMMIO, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioClose".} proc mmioRead*(x1: HMMIO, x2: HPSTR, x3: LONG): LONG{.stdcall, dynlib: "winmm.dll", importc: "mmioRead".} @@ -2278,35 +2275,35 @@ proc mmioWrite*(x1: HMMIO, x2: cstring, x3: LONG): LONG{.stdcall, dynlib: "winmm.dll", importc: "mmioWrite".} proc mmioSeek*(x1: HMMIO, x2: LONG, x3: WINT): LONG{.stdcall, dynlib: "winmm.dll", importc: "mmioSeek".} -proc mmioGetInfo*(x1: HMMIO, x2: LPMMIOINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioGetInfo*(x1: HMMIO, x2: LPMMIOINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioGetInfo".} -proc mmioSetInfo*(x1: HMMIO, x2: LPCMMIOINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioSetInfo*(x1: HMMIO, x2: LPCMMIOINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioSetInfo".} -proc mmioSetBuffer*(x1: HMMIO, x2: LPSTR, x3: LONG, x4: UINT): MMRESULT{. +proc mmioSetBuffer*(x1: HMMIO, x2: LPSTR, x3: LONG, x4: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mmioSetBuffer".} -proc mmioFlush*(x1: HMMIO, x2: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc mmioFlush*(x1: HMMIO, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioFlush".} -proc mmioAdvance*(x1: HMMIO, x2: LPMMIOINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioAdvance*(x1: HMMIO, x2: LPMMIOINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioAdvance".} -proc mmioSendMessage*(x1: HMMIO, x2: UINT, x3: LPARAM, x4: LPARAM): LRESULT{. +proc mmioSendMessage*(x1: HMMIO, x2: uint32, x3: LPARAM, x4: LPARAM): LRESULT{. stdcall, dynlib: "winmm.dll", importc: "mmioSendMessage".} -proc mmioDescend*(x1: HMMIO, x2: LPMMCKINFO, x3: PMMCKINFO, x4: UINT): MMRESULT{. +proc mmioDescend*(x1: HMMIO, x2: LPMMCKINFO, x3: PMMCKINFO, x4: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mmioDescend".} -proc mmioAscend*(x1: HMMIO, x2: LPMMCKINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioAscend*(x1: HMMIO, x2: LPMMCKINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioAscend".} -proc mmioCreateChunk*(x1: HMMIO, x2: LPMMCKINFO, x3: UINT): MMRESULT{.stdcall, +proc mmioCreateChunk*(x1: HMMIO, x2: LPMMCKINFO, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mmioCreateChunk".} -proc mciSendCommandA*(x1: MCIDEVICEID, x2: UINT, x3: DWORD, x4: DWORD): MCIERROR{. +proc mciSendCommandA*(x1: MCIDEVICEID, x2: uint32, x3: DWORD, x4: DWORD): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendCommandA".} -proc mciSendCommandW*(x1: MCIDEVICEID, x2: UINT, x3: DWORD, x4: DWORD): MCIERROR{. +proc mciSendCommandW*(x1: MCIDEVICEID, x2: uint32, x3: DWORD, x4: DWORD): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendCommandW".} -proc mciSendCommand*(x1: MCIDEVICEID, x2: UINT, x3: DWORD, x4: DWORD): MCIERROR{. +proc mciSendCommand*(x1: MCIDEVICEID, x2: uint32, x3: DWORD, x4: DWORD): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendCommandA".} -proc mciSendStringA*(x1: LPCSTR, x2: LPSTR, x3: UINT, x4: HWND): MCIERROR{. +proc mciSendStringA*(x1: LPCSTR, x2: LPSTR, x3: uint32, x4: HWND): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendStringA".} -proc mciSendStringW*(x1: LPCWSTR, x2: LPWSTR, x3: UINT, x4: HWND): MCIERROR{. +proc mciSendStringW*(x1: LPCWSTR, x2: LPWSTR, x3: uint32, x4: HWND): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendStringW".} -proc mciSendString*(x1: cstring, x2: cstring, x3: UINT, x4: HWND): MCIERROR{. +proc mciSendString*(x1: cstring, x2: cstring, x3: uint32, x4: HWND): MCIERROR{. stdcall, dynlib: "winmm.dll", importc: "mciSendStringA".} proc mciGetDeviceIDA*(x1: LPCSTR): MCIDEVICEID{.stdcall, dynlib: "winmm.dll", importc: "mciGetDeviceIDA".} @@ -2320,60 +2317,60 @@ proc mciGetDeviceIDFromElementIDW*(x1: DWORD, x2: LPCWSTR): MCIDEVICEID{. stdcall, dynlib: "winmm.dll", importc: "mciGetDeviceIDFromElementIDW".} proc mciGetDeviceIDFromElementID*(x1: DWORD, x2: cstring): MCIDEVICEID{.stdcall, dynlib: "winmm.dll", importc: "mciGetDeviceIDFromElementIDA".} -proc mciGetErrorStringA*(x1: MCIERROR, x2: LPSTR, x3: UINT): BOOL{.stdcall, +proc mciGetErrorStringA*(x1: MCIERROR, x2: LPSTR, x3: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "mciGetErrorStringA".} -proc mciGetErrorStringW*(x1: MCIERROR, x2: LPWSTR, x3: UINT): BOOL{.stdcall, +proc mciGetErrorStringW*(x1: MCIERROR, x2: LPWSTR, x3: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "mciGetErrorStringW".} -proc mciGetErrorString*(x1: MCIERROR, x2: cstring, x3: UINT): BOOL{.stdcall, +proc mciGetErrorString*(x1: MCIERROR, x2: cstring, x3: uint32): bool{.stdcall, dynlib: "winmm.dll", importc: "mciGetErrorStringA".} -proc mciSetYieldProc*(x1: MCIDEVICEID, x2: YIELDPROC, x3: DWORD): BOOL{.stdcall, +proc mciSetYieldProc*(x1: MCIDEVICEID, x2: YIELDPROC, x3: DWORD): bool{.stdcall, dynlib: "winmm.dll", importc: "mciSetYieldProc".} proc mciGetCreatorTask*(x1: MCIDEVICEID): HTASK{.stdcall, dynlib: "winmm.dll", importc: "mciGetCreatorTask".} proc mciGetYieldProc*(x1: MCIDEVICEID, x2: LPDWORD): YIELDPROC{.stdcall, dynlib: "winmm.dll", importc: "mciGetYieldProc".} -proc mciExecute*(x1: LPCSTR): BOOL{.stdcall, dynlib: "winmm.dll", +proc mciExecute*(x1: LPCSTR): bool{.stdcall, dynlib: "winmm.dll", importc: "mciExecute".} -proc joyGetPos*(x1: UINT, x2: LPJOYINFO): MMRESULT{.stdcall, +proc joyGetPos*(x1: uint32, x2: LPJOYINFO): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetPos".} -proc joyGetPosEx*(x1: UINT, x2: LPJOYINFOEX): MMRESULT{.stdcall, +proc joyGetPosEx*(x1: uint32, x2: LPJOYINFOEX): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetPosEx".} -proc joyGetThreshold*(x1: UINT, x2: LPUINT): MMRESULT{.stdcall, +proc joyGetThreshold*(x1: uint32, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetThreshold".} -proc joyReleaseCapture*(x1: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc joyReleaseCapture*(x1: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyReleaseCapture".} -proc joySetCapture*(x1: HWND, x2: UINT, x3: UINT, x4: BOOL): MMRESULT{.stdcall, +proc joySetCapture*(x1: HWND, x2: uint32, x3: uint32, x4: bool): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joySetCapture".} -proc joySetThreshold*(x1: UINT, x2: UINT): MMRESULT{.stdcall, +proc joySetThreshold*(x1: uint32, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joySetThreshold".} -proc waveOutGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc waveOutGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "waveOutGetNumDevs".} -proc waveOutGetDevCapsA*(x1: UINT, x2: LPWAVEOUTCAPSA, x3: UINT): MMRESULT{. +proc waveOutGetDevCapsA*(x1: uint32, x2: LPWAVEOUTCAPSA, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetDevCapsA".} -proc waveOutGetDevCapsW*(x1: UINT, x2: LPWAVEOUTCAPSW, x3: UINT): MMRESULT{. +proc waveOutGetDevCapsW*(x1: uint32, x2: LPWAVEOUTCAPSW, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetDevCapsW".} -proc waveOutGetDevCaps*(x1: UINT, x2: LPWAVEOUTCAPS, x3: UINT): MMRESULT{. +proc waveOutGetDevCaps*(x1: uint32, x2: LPWAVEOUTCAPS, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetDevCapsA".} proc waveOutGetVolume*(x1: HWAVEOUT, x2: LPDWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutGetVolume".} proc waveOutSetVolume*(x1: HWAVEOUT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutSetVolume".} -proc waveOutGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: UINT): MMRESULT{. +proc waveOutGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetErrorTextA".} -proc waveOutGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: UINT): MMRESULT{. +proc waveOutGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetErrorTextW".} -proc waveOutGetErrorText*(x1: MMRESULT, x2: cstring, x3: UINT): MMRESULT{. +proc waveOutGetErrorText*(x1: MMRESULT, x2: cstring, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetErrorTextA".} -proc waveOutOpen*(x1: LPHWAVEOUT, x2: UINT, x3: LPCWAVEFORMATEX, x4: DWORD, +proc waveOutOpen*(x1: LPHWAVEOUT, x2: uint32, x3: LPCWAVEFORMATEX, x4: DWORD, x5: DWORD, x6: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutOpen".} proc waveOutClose*(x1: HWAVEOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutClose".} -proc waveOutPrepareHeader*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: UINT): MMRESULT{. +proc waveOutPrepareHeader*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutPrepareHeader".} -proc waveOutUnprepareHeader*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: UINT): MMRESULT{. +proc waveOutUnprepareHeader*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutUnprepareHeader".} -proc waveOutWrite*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: UINT): MMRESULT{.stdcall, +proc waveOutWrite*(x1: HWAVEOUT, x2: LPWAVEHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutWrite".} proc waveOutPause*(x1: HWAVEOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutPause".} @@ -2383,7 +2380,7 @@ proc waveOutReset*(x1: HWAVEOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutReset".} proc waveOutBreakLoop*(x1: HWAVEOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutBreakLoop".} -proc waveOutGetPosition*(x1: HWAVEOUT, x2: LPMMTIME, x3: UINT): MMRESULT{. +proc waveOutGetPosition*(x1: HWAVEOUT, x2: LPMMTIME, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutGetPosition".} proc waveOutGetPitch*(x1: HWAVEOUT, x2: LPDWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutGetPitch".} @@ -2395,32 +2392,32 @@ proc waveOutSetPlaybackRate*(x1: HWAVEOUT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutSetPlaybackRate".} proc waveOutGetID*(x1: HWAVEOUT, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveOutGetID".} -proc waveOutMessage*(x1: HWAVEOUT, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc waveOutMessage*(x1: HWAVEOUT, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveOutMessage".} -proc waveInGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc waveInGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "waveInGetNumDevs".} -proc waveInGetDevCapsA*(x1: UINT, x2: LPWAVEINCAPSA, x3: UINT): MMRESULT{. +proc waveInGetDevCapsA*(x1: uint32, x2: LPWAVEINCAPSA, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInGetDevCapsA".} -proc waveInGetDevCapsW*(x1: UINT, x2: LPWAVEINCAPSW, x3: UINT): MMRESULT{. +proc waveInGetDevCapsW*(x1: uint32, x2: LPWAVEINCAPSW, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInGetDevCapsW".} -proc waveInGetDevCaps*(x1: UINT, x2: LPWAVEINCAPS, x3: UINT): MMRESULT{.stdcall, +proc waveInGetDevCaps*(x1: uint32, x2: LPWAVEINCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInGetDevCapsA".} -proc waveInGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: UINT): MMRESULT{.stdcall, +proc waveInGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInGetErrorTextA".} -proc waveInGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: UINT): MMRESULT{. +proc waveInGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInGetErrorTextW".} -proc waveInGetErrorText*(x1: MMRESULT, x2: cstring, x3: UINT): MMRESULT{. +proc waveInGetErrorText*(x1: MMRESULT, x2: cstring, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInGetErrorTextA".} -proc waveInOpen*(x1: LPHWAVEIN, x2: UINT, x3: LPCWAVEFORMATEX, x4: DWORD, +proc waveInOpen*(x1: LPHWAVEIN, x2: uint32, x3: LPCWAVEFORMATEX, x4: DWORD, x5: DWORD, x6: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInOpen".} proc waveInClose*(x1: HWAVEIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInClose".} -proc waveInPrepareHeader*(x1: HWAVEIN, x2: LPWAVEHDR, x3: UINT): MMRESULT{. +proc waveInPrepareHeader*(x1: HWAVEIN, x2: LPWAVEHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInPrepareHeader".} -proc waveInUnprepareHeader*(x1: HWAVEIN, x2: LPWAVEHDR, x3: UINT): MMRESULT{. +proc waveInUnprepareHeader*(x1: HWAVEIN, x2: LPWAVEHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInUnprepareHeader".} -proc waveInAddBuffer*(x1: HWAVEIN, x2: LPWAVEHDR, x3: UINT): MMRESULT{.stdcall, +proc waveInAddBuffer*(x1: HWAVEIN, x2: LPWAVEHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInAddBuffer".} proc waveInStart*(x1: HWAVEIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInStart".} @@ -2428,11 +2425,11 @@ proc waveInStop*(x1: HWAVEIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInStop".} proc waveInReset*(x1: HWAVEIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInReset".} -proc waveInGetPosition*(x1: HWAVEIN, x2: LPMMTIME, x3: UINT): MMRESULT{.stdcall, +proc waveInGetPosition*(x1: HWAVEIN, x2: LPMMTIME, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInGetPosition".} proc waveInGetID*(x1: HWAVEIN, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "waveInGetID".} -proc waveInMessage*(x1: HWAVEIN, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc waveInMessage*(x1: HWAVEIN, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "waveInMessage".} proc mixerGetLineControlsA*(x1: HMIXEROBJ, x2: LPMIXERLINECONTROLSA, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineControlsA".} @@ -2440,13 +2437,13 @@ proc mixerGetLineControlsW*(x1: HMIXEROBJ, x2: LPMIXERLINECONTROLSW, x3: DWORD): stdcall, dynlib: "winmm.dll", importc: "mixerGetLineControlsW".} proc mixerGetLineControls*(x1: HMIXEROBJ, x2: LPMIXERLINECONTROLS, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineControlsA".} -proc joyGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc joyGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "joyGetNumDevs".} -proc joyGetDevCapsA*(x1: UINT, x2: LPJOYCAPSA, x3: UINT): MMRESULT{.stdcall, +proc joyGetDevCapsA*(x1: uint32, x2: LPJOYCAPSA, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetDevCapsA".} -proc joyGetDevCapsW*(x1: UINT, x2: LPJOYCAPSW, x3: UINT): MMRESULT{.stdcall, +proc joyGetDevCapsW*(x1: uint32, x2: LPJOYCAPSW, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetDevCapsW".} -proc joyGetDevCaps*(x1: UINT, x2: LPJOYCAPS, x3: UINT): MMRESULT{.stdcall, +proc joyGetDevCaps*(x1: uint32, x2: LPJOYCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "joyGetDevCapsA".} proc mixerGetControlDetailsA*(x1: HMIXEROBJ, x2: LPMIXERCONTROLDETAILS, x3: DWORD): MMRESULT{.stdcall, @@ -2456,46 +2453,46 @@ proc mixerGetControlDetailsW*(x1: HMIXEROBJ, x2: LPMIXERCONTROLDETAILS, dynlib: "winmm.dll", importc: "mixerGetControlDetailsW".} proc mixerGetControlDetails*(x1: HMIXEROBJ, x2: LPMIXERCONTROLDETAILS, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetControlDetailsA".} -proc timeGetSystemTime*(x1: LPMMTIME, x2: UINT): MMRESULT{.stdcall, +proc timeGetSystemTime*(x1: LPMMTIME, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeGetSystemTime".} proc timeGetTime*(): DWORD{.stdcall, dynlib: "winmm.dll", importc: "timeGetTime".} -proc timeSetEvent*(x1: UINT, x2: UINT, x3: LPTIMECALLBACK, x4: DWORD, x5: UINT): MMRESULT{. +proc timeSetEvent*(x1: uint32, x2: uint32, x3: LPTIMECALLBACK, x4: DWORD, x5: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "timeSetEvent".} -proc timeKillEvent*(x1: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc timeKillEvent*(x1: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeKillEvent".} -proc timeGetDevCaps*(x1: LPTIMECAPS, x2: UINT): MMRESULT{.stdcall, +proc timeGetDevCaps*(x1: LPTIMECAPS, x2: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeGetDevCaps".} -proc timeBeginPeriod*(x1: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc timeBeginPeriod*(x1: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeBeginPeriod".} -proc timeEndPeriod*(x1: UINT): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc timeEndPeriod*(x1: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "timeEndPeriod".} -proc mixerGetDevCapsA*(x1: UINT, x2: LPMIXERCAPSA, x3: UINT): MMRESULT{.stdcall, +proc mixerGetDevCapsA*(x1: uint32, x2: LPMIXERCAPSA, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerGetDevCapsA".} -proc mixerGetDevCapsW*(x1: UINT, x2: LPMIXERCAPSW, x3: UINT): MMRESULT{.stdcall, +proc mixerGetDevCapsW*(x1: uint32, x2: LPMIXERCAPSW, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerGetDevCapsW".} -proc mixerGetDevCaps*(x1: UINT, x2: LPMIXERCAPS, x3: UINT): MMRESULT{.stdcall, +proc mixerGetDevCaps*(x1: uint32, x2: LPMIXERCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerGetDevCapsA".} -proc mixerOpen*(x1: LPHMIXER, x2: UINT, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. +proc mixerOpen*(x1: LPHMIXER, x2: uint32, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerOpen".} proc mixerClose*(x1: HMIXER): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerClose".} -proc mixerMessage*(x1: HMIXER, x2: UINT, x3: DWORD, x4: DWORD): DWORD{.stdcall, +proc mixerMessage*(x1: HMIXER, x2: uint32, x3: DWORD, x4: DWORD): DWORD{.stdcall, dynlib: "winmm.dll", importc: "mixerMessage".} -proc auxGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc auxGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "auxGetNumDevs".} -proc auxGetDevCapsA*(x1: UINT, x2: LPAUXCAPSA, x3: UINT): MMRESULT{.stdcall, +proc auxGetDevCapsA*(x1: uint32, x2: LPAUXCAPSA, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxGetDevCapsA".} -proc auxGetDevCapsW*(x1: UINT, x2: LPAUXCAPSW, x3: UINT): MMRESULT{.stdcall, +proc auxGetDevCapsW*(x1: uint32, x2: LPAUXCAPSW, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxGetDevCapsW".} -proc auxGetDevCaps*(x1: UINT, x2: LPAUXCAPS, x3: UINT): MMRESULT{.stdcall, +proc auxGetDevCaps*(x1: uint32, x2: LPAUXCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxGetDevCapsA".} -proc auxSetVolume*(x1: UINT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", +proc auxSetVolume*(x1: uint32, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxSetVolume".} -proc auxGetVolume*(x1: UINT, x2: LPDWORD): MMRESULT{.stdcall, +proc auxGetVolume*(x1: uint32, x2: LPDWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "auxGetVolume".} -proc auxOutMessage*(x1: UINT, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc auxOutMessage*(x1: uint32, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "auxOutMessage".} -proc midiOutGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc midiOutGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "midiOutGetNumDevs".} proc midiStreamOpen*(x1: LPHMIDISTRM, x2: LPUINT, x3: DWORD, x4: DWORD, x5: DWORD, x6: DWORD): MMRESULT{.stdcall, @@ -2504,9 +2501,9 @@ proc midiStreamClose*(x1: HMIDISTRM): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiStreamClose".} proc midiStreamProperty*(x1: HMIDISTRM, x2: LPBYTE, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiStreamProperty".} -proc midiStreamPosition*(x1: HMIDISTRM, x2: LPMMTIME, x3: UINT): MMRESULT{. +proc midiStreamPosition*(x1: HMIDISTRM, x2: LPMMTIME, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiStreamPosition".} -proc midiStreamOut*(x1: HMIDISTRM, x2: LPMIDIHDR, x3: UINT): MMRESULT{.stdcall, +proc midiStreamOut*(x1: HMIDISTRM, x2: LPMIDIHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiStreamOut".} proc midiStreamPause*(x1: HMIDISTRM): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiStreamPause".} @@ -2518,67 +2515,67 @@ proc midiConnect*(x1: HMIDI, x2: HMIDIOUT, x3: pointer): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiConnect".} proc midiDisconnect*(x1: HMIDI, x2: HMIDIOUT, x3: pointer): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiDisconnect".} -proc midiOutGetDevCapsA*(x1: UINT, x2: LPMIDIOUTCAPSA, x3: UINT): MMRESULT{. +proc midiOutGetDevCapsA*(x1: uint32, x2: LPMIDIOUTCAPSA, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetDevCapsA".} -proc midiOutGetDevCapsW*(x1: UINT, x2: LPMIDIOUTCAPSW, x3: UINT): MMRESULT{. +proc midiOutGetDevCapsW*(x1: uint32, x2: LPMIDIOUTCAPSW, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetDevCapsW".} -proc midiOutGetDevCaps*(x1: UINT, x2: LPMIDIOUTCAPS, x3: UINT): MMRESULT{. +proc midiOutGetDevCaps*(x1: uint32, x2: LPMIDIOUTCAPS, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetDevCapsA".} proc midiOutGetVolume*(x1: HMIDIOUT, x2: LPDWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutGetVolume".} proc midiOutSetVolume*(x1: HMIDIOUT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutSetVolume".} -proc midiOutGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: UINT): MMRESULT{. +proc midiOutGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetErrorTextA".} -proc midiOutGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: UINT): MMRESULT{. +proc midiOutGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetErrorTextW".} -proc midiOutGetErrorText*(x1: MMRESULT, x2: cstring, x3: UINT): MMRESULT{. +proc midiOutGetErrorText*(x1: MMRESULT, x2: cstring, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutGetErrorTextA".} -proc midiOutOpen*(x1: LPHMIDIOUT, x2: UINT, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. +proc midiOutOpen*(x1: LPHMIDIOUT, x2: uint32, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutOpen".} proc midiOutClose*(x1: HMIDIOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutClose".} -proc midiOutPrepareHeader*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: UINT): MMRESULT{. +proc midiOutPrepareHeader*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutPrepareHeader".} -proc midiOutUnprepareHeader*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: UINT): MMRESULT{. +proc midiOutUnprepareHeader*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutUnprepareHeader".} proc midiOutShortMsg*(x1: HMIDIOUT, x2: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutShortMsg".} -proc midiOutLongMsg*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: UINT): MMRESULT{.stdcall, +proc midiOutLongMsg*(x1: HMIDIOUT, x2: LPMIDIHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutLongMsg".} proc midiOutReset*(x1: HMIDIOUT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutReset".} -proc midiOutCachePatches*(x1: HMIDIOUT, x2: UINT, x3: LPWORD, x4: UINT): MMRESULT{. +proc midiOutCachePatches*(x1: HMIDIOUT, x2: uint32, x3: LPWORD, x4: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutCachePatches".} -proc midiOutCacheDrumPatches*(x1: HMIDIOUT, x2: UINT, x3: LPWORD, x4: UINT): MMRESULT{. +proc midiOutCacheDrumPatches*(x1: HMIDIOUT, x2: uint32, x3: LPWORD, x4: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutCacheDrumPatches".} proc midiOutGetID*(x1: HMIDIOUT, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiOutGetID".} -proc midiOutMessage*(x1: HMIDIOUT, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc midiOutMessage*(x1: HMIDIOUT, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiOutMessage".} -proc midiInGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll", +proc midiInGetNumDevs*(): uint32{.stdcall, dynlib: "winmm.dll", importc: "midiInGetNumDevs".} -proc midiInGetDevCapsA*(x1: UINT, x2: LPMIDIINCAPSA, x3: UINT): MMRESULT{. +proc midiInGetDevCapsA*(x1: uint32, x2: LPMIDIINCAPSA, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInGetDevCapsA".} -proc midiInGetDevCapsW*(x1: UINT, x2: LPMIDIINCAPSW, x3: UINT): MMRESULT{. +proc midiInGetDevCapsW*(x1: uint32, x2: LPMIDIINCAPSW, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInGetDevCapsW".} -proc midiInGetDevCaps*(x1: UINT, x2: LPMIDIINCAPS, x3: UINT): MMRESULT{.stdcall, +proc midiInGetDevCaps*(x1: uint32, x2: LPMIDIINCAPS, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInGetDevCapsA".} -proc midiInGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: UINT): MMRESULT{.stdcall, +proc midiInGetErrorTextA*(x1: MMRESULT, x2: LPSTR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInGetErrorTextA".} -proc midiInGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: UINT): MMRESULT{. +proc midiInGetErrorTextW*(x1: MMRESULT, x2: LPWSTR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInGetErrorTextW".} -proc midiInGetErrorText*(x1: MMRESULT, x2: cstring, x3: UINT): MMRESULT{. +proc midiInGetErrorText*(x1: MMRESULT, x2: cstring, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInGetErrorTextA".} -proc midiInOpen*(x1: LPHMIDIIN, x2: UINT, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. +proc midiInOpen*(x1: LPHMIDIIN, x2: uint32, x3: DWORD, x4: DWORD, x5: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInOpen".} proc midiInClose*(x1: HMIDIIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInClose".} -proc midiInPrepareHeader*(x1: HMIDIIN, x2: LPMIDIHDR, x3: UINT): MMRESULT{. +proc midiInPrepareHeader*(x1: HMIDIIN, x2: LPMIDIHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInPrepareHeader".} -proc midiInUnprepareHeader*(x1: HMIDIIN, x2: LPMIDIHDR, x3: UINT): MMRESULT{. +proc midiInUnprepareHeader*(x1: HMIDIIN, x2: LPMIDIHDR, x3: uint32): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInUnprepareHeader".} -proc midiInAddBuffer*(x1: HMIDIIN, x2: LPMIDIHDR, x3: UINT): MMRESULT{.stdcall, +proc midiInAddBuffer*(x1: HMIDIIN, x2: LPMIDIHDR, x3: uint32): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInAddBuffer".} proc midiInStart*(x1: HMIDIIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInStart".} @@ -2588,7 +2585,7 @@ proc midiInReset*(x1: HMIDIIN): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInReset".} proc midiInGetID*(x1: HMIDIIN, x2: LPUINT): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "midiInGetID".} -proc midiInMessage*(x1: HMIDIIN, x2: UINT, x3: DWORD, x4: DWORD): MMRESULT{. +proc midiInMessage*(x1: HMIDIIN, x2: uint32, x3: DWORD, x4: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "midiInMessage".} proc mixerGetLineInfoA*(x1: HMIXEROBJ, x2: LPMIXERLINEA, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineInfoA".} @@ -2596,13 +2593,13 @@ proc mixerGetLineInfoW*(x1: HMIXEROBJ, x2: LPMIXERLINEW, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineInfoW".} proc mixerGetLineInfo*(x1: HMIXEROBJ, x2: LPMIXERLINE, x3: DWORD): MMRESULT{. stdcall, dynlib: "winmm.dll", importc: "mixerGetLineInfoA".} -proc mixerGetID*(x1: HMIXEROBJ, x2: var UINT, x3: DWORD): MMRESULT{.stdcall, +proc mixerGetID*(x1: HMIXEROBJ, x2: var uint32, x3: DWORD): MMRESULT{.stdcall, dynlib: "winmm.dll", importc: "mixerGetID".} -proc PlaySoundA*(x1: LPCSTR, x2: HMODULE, x3: DWORD): BOOL{.stdcall, +proc PlaySoundA*(x1: LPCSTR, x2: HMODULE, x3: DWORD): bool{.stdcall, dynlib: "winmm.dll", importc: "PlaySoundA".} -proc PlaySoundW*(x1: LPCWSTR, x2: HMODULE, x3: DWORD): BOOL{.stdcall, +proc PlaySoundW*(x1: LPCWSTR, x2: HMODULE, x3: DWORD): bool{.stdcall, dynlib: "winmm.dll", importc: "PlaySoundW".} -proc PlaySound*(x1: cstring, x2: HMODULE, x3: DWORD): BOOL{.stdcall, +proc PlaySound*(x1: cstring, x2: HMODULE, x3: DWORD): bool{.stdcall, dynlib: "winmm.dll", importc: "PlaySoundA".} # implementation @@ -2610,7 +2607,7 @@ proc MEVT_EVENTTYPE(x: int8): int8 = result = toU8(x shr 24) proc MEVT_EVENTPARM(x: DWORD): DWORD = - result = x And 0x00FFFFFF + result = x and 0x00FFFFFF proc MCI_MSF_MINUTE(msf: int32): int8 = result = toU8(msf and 0xff) @@ -2648,8 +2645,8 @@ proc MCI_MAKE_HMS(h, m, s: int8): int32 = proc MCI_TMSF_FRAME(tmsf: int32): int8 = result = toU8(tmsf shr 24) -proc mci_Make_TMSF(t, m, s, f: int8): int32 = +proc MCI_MAKE_TMSF(t, m, s, f: int8): int32 = result = (ze(t) or ze(m) shl 8 or ze(s) shl 16 or ze(f) shl 24).int32 proc DIBINDEX(n: int32): int32 = - result = n Or 0x000010FF'i32 shl 16'i32 + result = n or 0x000010FF'i32 shl 16'i32 diff --git a/lib/windows/nb30.nim b/lib/windows/nb30.nim index be4a0616c..2e0c679ae 100644 --- a/lib/windows/nb30.nim +++ b/lib/windows/nb30.nim @@ -13,7 +13,7 @@ {.deadCodeElim: on.} import # Data structure templates - Windows + windows const NCBNAMSZ* = 16 # absolute length of a net name @@ -24,20 +24,20 @@ type # Network Control Block TNCBPostProc* = proc (P: PNCB) {.stdcall.} TNCB* {.final.} = object # Structure returned to the NCB command NCBASTAT is ADAPTER_STATUS followed # by an array of NAME_BUFFER structures. - ncb_command*: Char # command code - ncb_retcode*: Char # return code - ncb_lsn*: Char # local session number - ncb_num*: Char # number of our network name + ncb_command*: char # command code + ncb_retcode*: char # return code + ncb_lsn*: char # local session number + ncb_num*: char # number of our network name ncb_buffer*: cstring # address of message buffer ncb_length*: int16 # size of message buffer ncb_callname*: array[0..NCBNAMSZ - 1, char] # blank-padded name of remote ncb_name*: array[0..NCBNAMSZ - 1, char] # our blank-padded netname - ncb_rto*: Char # rcv timeout/retry count - ncb_sto*: Char # send timeout/sys timeout + ncb_rto*: char # rcv timeout/retry count + ncb_sto*: char # send timeout/sys timeout ncb_post*: TNCBPostProc # POST routine address - ncb_lana_num*: Char # lana (adapter) number - ncb_cmd_cplt*: Char # 0xff => commmand pending - ncb_reserve*: array[0..9, Char] # reserved, used by BIOS + ncb_lana_num*: char # lana (adapter) number + ncb_cmd_cplt*: char # 0xff => commmand pending + ncb_reserve*: array[0..9, char] # reserved, used by BIOS ncb_event*: THandle # HANDLE to Win32 event which # will be set to the signalled # state when an ASYNCH command @@ -45,11 +45,11 @@ type # Network Control Block PAdapterStatus* = ptr TAdapterStatus TAdapterStatus* {.final.} = object - adapter_address*: array[0..5, Char] - rev_major*: Char - reserved0*: Char - adapter_type*: Char - rev_minor*: Char + adapter_address*: array[0..5, char] + rev_major*: char + reserved0*: char + adapter_type*: char + rev_minor*: char duration*: int16 frmr_recv*: int16 frmr_xmit*: int16 @@ -75,9 +75,9 @@ type # Network Control Block PNameBuffer* = ptr TNameBuffer TNameBuffer* {.final.} = object - name*: array[0..NCBNAMSZ - 1, Char] - name_num*: Char - name_flags*: Char + name*: array[0..NCBNAMSZ - 1, char] + name_num*: char + name_flags*: char const # values for name_flags bits. @@ -96,19 +96,19 @@ type # Structure returned to the NCB command NCBSSTAT is SESSION_HEADER followed # status for all names. PSessionHeader* = ptr TSessionHeader TSessionHeader* {.final.} = object - sess_name*: Char - num_sess*: Char - rcv_dg_outstanding*: Char - rcv_any_outstanding*: Char + sess_name*: char + num_sess*: char + rcv_dg_outstanding*: char + rcv_any_outstanding*: char PSessionBuffer* = ptr TSessionBuffer TSessionBuffer* {.final.} = object - lsn*: Char - state*: Char - local_name*: array[0..NCBNAMSZ - 1, Char] - remote_name*: array[0..NCBNAMSZ - 1, Char] - rcvs_outstanding*: Char - sends_outstanding*: Char + lsn*: char + state*: char + local_name*: array[0..NCBNAMSZ - 1, char] + remote_name*: array[0..NCBNAMSZ - 1, char] + rcvs_outstanding*: char + sends_outstanding*: char const # Values for state @@ -125,24 +125,24 @@ type # Structure returned to the NCB command NCBENUM. PLanaEnum* = ptr TLanaEnum TLanaEnum* {.final.} = object # Structure returned to the NCB command NCBFINDNAME is FIND_NAME_HEADER followed # by an array of FIND_NAME_BUFFER structures. - len*: Char # Number of valid entries in lana[] - lana*: array[0..MAX_LANA, Char] + len*: char # Number of valid entries in lana[] + lana*: array[0..MAX_LANA, char] PFindNameHeader* = ptr TFindNameHeader TFindNameHeader* {.final.} = object node_count*: int16 - reserved*: Char - unique_group*: Char + reserved*: char + unique_group*: char PFindNameBuffer* = ptr TFindNameBuffer TFindNameBuffer* {.final.} = object # Structure provided with NCBACTION. The purpose of NCBACTION is to provide # transport specific extensions to netbios. - len*: Char - access_control*: Char - frame_control*: Char - destination_addr*: array[0..5, Char] - source_addr*: array[0..5, Char] - routing_info*: array[0..17, Char] + len*: char + access_control*: char + frame_control*: char + destination_addr*: array[0..5, char] + source_addr*: array[0..5, char] + routing_info*: array[0..17, char] PActionHeader* = ptr TActionHeader TActionHeader* {.final.} = object @@ -227,6 +227,6 @@ const # NCB Command codes # main user entry point for NetBIOS 3.0 # Usage: Result = Netbios( pncb ); -proc Netbios*(P: PNCB): Char{.stdcall, dynlib: "netapi32.dll", +proc Netbios*(P: PNCB): char{.stdcall, dynlib: "netapi32.dll", importc: "Netbios".} # implementation diff --git a/lib/windows/shellapi.nim b/lib/windows/shellapi.nim index 9a280f551..079257680 100644 --- a/lib/windows/shellapi.nim +++ b/lib/windows/shellapi.nim @@ -28,14 +28,14 @@ # Copyright (c) Microsoft Corporation. All rights reserved. import - Windows + windows type HDROP* = THandle - UINT_PTR* = ptr UINT + UINT_PTR* = ptr uint32 DWORD_PTR* = ptr DWORD - pHICON* = ptr HICON - pBool* = ptr BOOL + PHICON* = ptr HICON + PBool* = ptr bool STARTUPINFOW* {.final.} = object # a guess. Omission should get fixed in Windows. cb*: DWORD lpReserved*: LPTSTR @@ -60,27 +60,27 @@ type TSTARTUPINFOW* = STARTUPINFOW PSTARTUPINFOW* = ptr STARTUPINFOW #unicode -proc DragQueryFileA*(arg1: HDROP, arg2: UINT, arg3: LPSTR, arg4: UINT): UINT{. +proc DragQueryFileA*(arg1: HDROP, arg2: uint32, arg3: LPSTR, arg4: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "DragQueryFileA".} -proc DragQueryFileW*(arg1: HDROP, arg2: UINT, arg3: LPWSTR, arg4: UINT): UINT{. +proc DragQueryFileW*(arg1: HDROP, arg2: uint32, arg3: LPWSTR, arg4: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "DragQueryFileW".} -proc DragQueryFile*(arg1: HDROP, arg2: UINT, arg3: LPSTR, arg4: UINT): UINT{. +proc DragQueryFile*(arg1: HDROP, arg2: uint32, arg3: LPSTR, arg4: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "DragQueryFileA".} -proc DragQueryFile*(arg1: HDROP, arg2: UINT, arg3: LPWSTR, arg4: UINT): UINT{. +proc DragQueryFile*(arg1: HDROP, arg2: uint32, arg3: LPWSTR, arg4: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "DragQueryFileW".} -proc DragQueryPoint*(arg1: HDROP, arg2: LPPOINT): BOOL{.stdcall, +proc DragQueryPoint*(arg1: HDROP, arg2: LPPOINT): bool{.stdcall, dynlib: "shell32.dll", importc: "DragQueryPoint".} proc DragFinish*(arg1: HDROP){.stdcall, dynlib: "shell32.dll", importc: "DragFinish".} -proc DragAcceptFiles*(hwnd: HWND, arg2: BOOL){.stdcall, dynlib: "shell32.dll", +proc DragAcceptFiles*(hwnd: HWND, arg2: bool){.stdcall, dynlib: "shell32.dll", importc: "DragAcceptFiles".} -proc ShellExecuteA*(HWND: hwnd, lpOperation: LPCSTR, lpFile: LPCSTR, +proc ShellExecuteA*(hwnd: HWND, lpOperation: LPCSTR, lpFile: LPCSTR, lpParameters: LPCSTR, lpDirectory: LPCSTR, nShowCmd: int32): HInst{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} proc ShellExecuteW*(hwnd: HWND, lpOperation: LPCWSTR, lpFile: LPCWSTR, lpParameters: LPCWSTR, lpDirectory: LPCWSTR, nShowCmd: int32): HInst{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".} -proc ShellExecute*(HWND: hwnd, lpOperation: LPCSTR, lpFile: LPCSTR, +proc ShellExecute*(hwnd: HWND, lpOperation: LPCSTR, lpFile: LPCSTR, lpParameters: LPCSTR, lpDirectory: LPCSTR, nShowCmd: int32): HInst{. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} proc ShellExecute*(hwnd: HWND, lpOperation: LPCWSTR, lpFile: LPCWSTR, @@ -94,16 +94,16 @@ proc FindExecutable*(lpFile: LPCSTR, lpDirectory: LPCSTR, lpResult: LPSTR): HIns stdcall, dynlib: "shell32.dll", importc: "FindExecutableA".} proc FindExecutable*(lpFile: LPCWSTR, lpDirectory: LPCWSTR, lpResult: LPWSTR): HInst{. stdcall, dynlib: "shell32.dll", importc: "FindExecutableW".} -proc CommandLineToArgvW*(lpCmdLine: LPCWSTR, pNumArgs: ptr int32): pLPWSTR{. +proc CommandLineToArgvW*(lpCmdLine: LPCWSTR, pNumArgs: ptr int32): PLPWSTR{. stdcall, dynlib: "shell32.dll", importc: "CommandLineToArgvW".} -proc ShellAboutA*(HWND: hWnd, szApp: LPCSTR, szOtherStuff: LPCSTR, HICON: hIcon): int32{. +proc ShellAboutA*(hwnd: HWND, szApp: LPCSTR, szOtherStuff: LPCSTR, hIcon: HICON): int32{. stdcall, dynlib: "shell32.dll", importc: "ShellAboutA".} -proc ShellAboutW*(HWND: hWnd, szApp: LPCWSTR, szOtherStuff: LPCWSTR, - HICON: hIcon): int32{.stdcall, dynlib: "shell32.dll", +proc ShellAboutW*(hwnd: HWND, szApp: LPCWSTR, szOtherStuff: LPCWSTR, + hIcon: HICON): int32{.stdcall, dynlib: "shell32.dll", importc: "ShellAboutW".} -proc ShellAbout*(HWND: hWnd, szApp: LPCSTR, szOtherStuff: LPCSTR, HICON: hIcon): int32{. +proc ShellAbout*(hwnd: HWND, szApp: LPCSTR, szOtherStuff: LPCSTR, hIcon: HICON): int32{. stdcall, dynlib: "shell32.dll", importc: "ShellAboutA".} -proc ShellAbout*(HWND: hWnd, szApp: LPCWSTR, szOtherStuff: LPCWSTR, HICON: hIcon): int32{. +proc ShellAbout*(hwnd: HWND, szApp: LPCWSTR, szOtherStuff: LPCWSTR, hIcon: HICON): int32{. stdcall, dynlib: "shell32.dll", importc: "ShellAboutW".} proc DuplicateIcon*(inst: HINST, icon: HICON): HIcon{.stdcall, dynlib: "shell32.dll", importc: "DuplicateIcon".} @@ -115,29 +115,29 @@ proc ExtractAssociatedIcon*(hInst: HINST, lpIconPath: LPSTR, lpiIcon: LPWORD): H stdcall, dynlib: "shell32.dll", importc: "ExtractAssociatedIconA".} proc ExtractAssociatedIcon*(hInst: HINST, lpIconPath: LPWSTR, lpiIcon: LPWORD): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractAssociatedIconW".} -proc ExtractIconA*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: UINT): HICON{. +proc ExtractIconA*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: uint32): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconA".} -proc ExtractIconW*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: UINT): HICON{. +proc ExtractIconW*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: uint32): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".} -proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: UINT): HICON{. +proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: uint32): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconA".} -proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: UINT): HICON{. +proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: uint32): HICON{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".} # if(WINVER >= 0x0400) type # init with sizeof(DRAGINFO) DRAGINFOA* {.final.} = object - uSize*: UINT + uSize*: uint32 pt*: POINT - fNC*: BOOL + fNC*: bool lpFileList*: LPSTR grfKeyState*: DWORD TDRAGINFOA* = DRAGINFOA LPDRAGINFOA* = ptr DRAGINFOA # init with sizeof(DRAGINFO) DRAGINFOW* {.final.} = object - uSize*: UINT + uSize*: uint32 pt*: POINT - fNC*: BOOL + fNC*: bool lpFileList*: LPWSTR grfKeyState*: DWORD @@ -184,8 +184,8 @@ type AppBarData* {.final.} = object cbSize*: DWORD hWnd*: HWND - uCallbackMessage*: UINT - uEdge*: UINT + uCallbackMessage*: uint32 + uEdge*: uint32 rc*: RECT lParam*: LPARAM # message specific @@ -197,41 +197,41 @@ proc SHAppBarMessage*(dwMessage: DWORD, pData: APPBARDATA): UINT_PTR{.stdcall, # # EndAppBar # -proc DoEnvironmentSubstA*(szString: LPSTR, cchString: UINT): DWORD{.stdcall, +proc DoEnvironmentSubstA*(szString: LPSTR, cchString: uint32): DWORD{.stdcall, dynlib: "shell32.dll", importc: "DoEnvironmentSubstA".} -proc DoEnvironmentSubstW*(szString: LPWSTR, cchString: UINT): DWORD{.stdcall, +proc DoEnvironmentSubstW*(szString: LPWSTR, cchString: uint32): DWORD{.stdcall, dynlib: "shell32.dll", importc: "DoEnvironmentSubstW".} -proc DoEnvironmentSubst*(szString: LPSTR, cchString: UINT): DWORD{.stdcall, +proc DoEnvironmentSubst*(szString: LPSTR, cchString: uint32): DWORD{.stdcall, dynlib: "shell32.dll", importc: "DoEnvironmentSubstA".} -proc DoEnvironmentSubst*(szString: LPWSTR, cchString: UINT): DWORD{.stdcall, +proc DoEnvironmentSubst*(szString: LPWSTR, cchString: uint32): DWORD{.stdcall, dynlib: "shell32.dll", importc: "DoEnvironmentSubstW".} #Macro proc EIRESID*(x: int32): int32 -proc ExtractIconExA*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: pHICON, - phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall, +proc ExtractIconExA*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: PHICON, + phiconSmall: PHICON, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExA".} -proc ExtractIconExW*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: pHICON, - phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall, +proc ExtractIconExW*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: PHICON, + phiconSmall: PHICON, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".} proc ExtractIconExA*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: var HICON, phiconSmall: var HIcon, - nIcons: UINT): UINT{.stdcall, dynlib: "shell32.dll", + nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExA".} proc ExtractIconExW*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: var HICON, phiconSmall: var HIcon, - nIcons: UINT): UINT{.stdcall, dynlib: "shell32.dll", + nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".} -proc ExtractIconEx*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: pHICON, - phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall, +proc ExtractIconEx*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: PHICON, + phiconSmall: PHICON, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExA".} -proc ExtractIconEx*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: pHICON, - phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall, +proc ExtractIconEx*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: PHICON, + phiconSmall: PHICON, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".} proc ExtractIconEx*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: var HICON, - phiconSmall: var HIcon, nIcons: UINT): UINT{.stdcall, + phiconSmall: var HIcon, nIcons: uint32): uint32{.stdcall, dynlib: "shell32.dll", importc: "ExtractIconExA".} proc ExtractIconEx*(lpszFile: LPCWSTR, nIconIndex: int32, - phiconLarge: var HICON, phiconSmall: var HIcon, nIcons: UINT): UINT{. + phiconLarge: var HICON, phiconSmall: var HIcon, nIcons: uint32): uint32{. stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".} # # Shell File Operations @@ -291,11 +291,11 @@ type type SHFILEOPSTRUCTA* {.final.} = object hwnd*: HWND - wFunc*: UINT + wFunc*: uint32 pFrom*: LPCSTR pTo*: LPCSTR fFlags*: FILEOP_FLAGS - fAnyOperationsAborted*: BOOL + fAnyOperationsAborted*: bool hNameMappings*: LPVOID lpszProgressTitle*: LPCSTR # only used if FOF_SIMPLEPROGRESS @@ -303,11 +303,11 @@ type LPSHFILEOPSTRUCTA* = ptr SHFILEOPSTRUCTA SHFILEOPSTRUCTW* {.final.} = object hwnd*: HWND - wFunc*: UINT + wFunc*: uint32 pFrom*: LPCWSTR pTo*: LPCWSTR fFlags*: FILEOP_FLAGS - fAnyOperationsAborted*: BOOL + fAnyOperationsAborted*: bool hNameMappings*: LPVOID lpszProgressTitle*: LPCWSTR @@ -430,10 +430,10 @@ type cbSize*: DWORD fMask*: ULONG hwnd*: HWND - lpVerb*: lpcwstr - lpFile*: lpcwstr - lpParameters*: lpcwstr - lpDirectory*: lpcwstr + lpVerb*: LPCWSTR + lpFile*: LPCWSTR + lpParameters*: LPCWSTR + lpDirectory*: LPCWSTR nShow*: int32 hInstApp*: HINST lpIDList*: LPVOID @@ -456,24 +456,24 @@ else: SHELLEXECUTEINFO* = SHELLEXECUTEINFOA TSHELLEXECUTEINFO* = SHELLEXECUTEINFOA LPSHELLEXECUTEINFO* = LPSHELLEXECUTEINFOA -proc ShellExecuteExA*(lpExecInfo: LPSHELLEXECUTEINFOA): Bool{.stdcall, +proc ShellExecuteExA*(lpExecInfo: LPSHELLEXECUTEINFOA): bool{.stdcall, dynlib: "shell32.dll", importc: "ShellExecuteExA".} -proc ShellExecuteExW*(lpExecInfo: LPSHELLEXECUTEINFOW): Bool{.stdcall, +proc ShellExecuteExW*(lpExecInfo: LPSHELLEXECUTEINFOW): bool{.stdcall, dynlib: "shell32.dll", importc: "ShellExecuteExW".} -proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOA): Bool{.stdcall, +proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOA): bool{.stdcall, dynlib: "shell32.dll", importc: "ShellExecuteExA".} -proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOW): Bool{.stdcall, +proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOW): bool{.stdcall, dynlib: "shell32.dll", importc: "ShellExecuteExW".} -proc WinExecErrorA*(HWND: hwnd, error: int32, lpstrFileName: LPCSTR, +proc WinExecErrorA*(hwnd: HWND, error: int32, lpstrFileName: LPCSTR, lpstrTitle: LPCSTR){.stdcall, dynlib: "shell32.dll", importc: "WinExecErrorA".} -proc WinExecErrorW*(HWND: hwnd, error: int32, lpstrFileName: LPCWSTR, +proc WinExecErrorW*(hwnd: HWND, error: int32, lpstrFileName: LPCWSTR, lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll", importc: "WinExecErrorW".} -proc WinExecError*(HWND: hwnd, error: int32, lpstrFileName: LPCSTR, +proc WinExecError*(hwnd: HWND, error: int32, lpstrFileName: LPCSTR, lpstrTitle: LPCSTR){.stdcall, dynlib: "shell32.dll", importc: "WinExecErrorA".} -proc WinExecError*(HWND: hwnd, error: int32, lpstrFileName: LPCWSTR, +proc WinExecError*(hwnd: HWND, error: int32, lpstrFileName: LPCWSTR, lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll", importc: "WinExecErrorW".} type @@ -487,7 +487,7 @@ type hUserToken*: HANDLE lpProcessAttributes*: LPSECURITY_ATTRIBUTES lpThreadAttributes*: LPSECURITY_ATTRIBUTES - bInheritHandles*: BOOL + bInheritHandles*: bool dwCreationFlags*: DWORD lpStartupInfo*: LPSTARTUPINFOW lpProcessInformation*: LPPROCESS_INFORMATION @@ -495,7 +495,7 @@ type TSHCREATEPROCESSINFOW* = SHCREATEPROCESSINFOW PSHCREATEPROCESSINFOW* = ptr SHCREATEPROCESSINFOW -proc SHCreateProcessAsUserW*(pscpi: PSHCREATEPROCESSINFOW): Bool{.stdcall, +proc SHCreateProcessAsUserW*(pscpi: PSHCREATEPROCESSINFOW): bool{.stdcall, dynlib: "shell32.dll", importc: "SHCreateProcessAsUserW".} # # End ShellExecuteEx and family } @@ -544,16 +544,16 @@ type NOTIFYICONDATAA* {.final.} = object cbSize*: DWORD hWnd*: HWND - uID*: UINT - uFlags*: UINT - uCallbackMessage*: UINT + uID*: uint32 + uFlags*: uint32 + uCallbackMessage*: uint32 hIcon*: HICON - szTip*: array[0..127, CHAR] + szTip*: array[0..127, char] dwState*: DWORD dwStateMask*: DWORD - szInfo*: array[0..255, CHAR] - uTimeout*: UINT # also: uVersion - szInfoTitle*: array[0..63, CHAR] + szInfo*: array[0..255, char] + uTimeout*: uint32 # also: uVersion + szInfoTitle*: array[0..63, char] dwInfoFlags*: DWORD guidItem*: TGUID @@ -562,16 +562,16 @@ type NOTIFYICONDATAW* {.final.} = object cbSize*: DWORD hWnd*: HWND - uID*: UINT - uFlags*: UINT - uCallbackMessage*: UINT + uID*: uint32 + uFlags*: uint32 + uCallbackMessage*: uint32 hIcon*: HICON - szTip*: array[0..127, WCHAR] + szTip*: array[0..127, Wchar] dwState*: DWORD dwStateMask*: DWORD - szInfo*: array[0..255, WCHAR] - uTimeout*: UINT # also uVersion : UINT - szInfoTitle*: array[0..63, CHAR] + szInfo*: array[0..255, Wchar] + uTimeout*: uint32 # also uVersion : UINT + szInfoTitle*: array[0..63, char] dwInfoFlags*: DWORD guidItem*: TGUID @@ -619,13 +619,13 @@ const NIIF_ICON_MASK* = 0x0000000F NIIF_NOSOUND* = 0x00000010 -proc Shell_NotifyIconA*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): Bool{. +proc Shell_NotifyIconA*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): bool{. stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconA".} -proc Shell_NotifyIconW*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): Bool{. +proc Shell_NotifyIconW*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): bool{. stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconW".} -proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): Bool{. +proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): bool{. stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconA".} -proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): Bool{. +proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): bool{. stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconW".} # # The SHGetFileInfo API provides an easy way to get attributes @@ -652,20 +652,20 @@ type hIcon*: HICON # out: icon iIcon*: int32 # out: icon index dwAttributes*: DWORD # out: SFGAO_ flags - szDisplayName*: array[0..(MAX_PATH) - 1, CHAR] # out: display name (or path) - szTypeName*: array[0..79, CHAR] # out: type name + szDisplayName*: array[0..(MAX_PATH) - 1, char] # out: display name (or path) + szTypeName*: array[0..79, char] # out: type name TSHFILEINFOA* = SHFILEINFOA - pSHFILEINFOA* = ptr SHFILEINFOA + PSHFILEINFOA* = ptr SHFILEINFOA SHFILEINFOW* {.final.} = object hIcon*: HICON # out: icon iIcon*: int32 # out: icon index dwAttributes*: DWORD # out: SFGAO_ flags - szDisplayName*: array[0..(MAX_PATH) - 1, WCHAR] # out: display name (or path) - szTypeName*: array[0..79, WCHAR] # out: type name + szDisplayName*: array[0..(MAX_PATH) - 1, Wchar] # out: display name (or path) + szTypeName*: array[0..79, Wchar] # out: type name TSHFILEINFOW* = SHFILEINFOW - pSHFILEINFOW* = ptr SHFILEINFOW + PSHFILEINFOW* = ptr SHFILEINFOW when defined(UNICODE): type @@ -701,67 +701,67 @@ const # in the upper 8 bits of the iIcon proc SHGetFileInfoA*(pszPath: LPCSTR, dwFileAttributes: DWORD, - psfi: pSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{. + psfi: PSHFILEINFOA, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".} proc SHGetFileInfoW*(pszPath: LPCWSTR, dwFileAttributes: DWORD, - psfi: pSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{. + psfi: PSHFILEINFOW, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".} proc SHGetFileInfo*(pszPath: LPCSTR, dwFileAttributes: DWORD, - psfi: pSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{. + psfi: PSHFILEINFOA, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".} proc SHGetFileInfoA*(pszPath: LPCSTR, dwFileAttributes: DWORD, - psfi: var TSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{. + psfi: var TSHFILEINFOA, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".} proc SHGetFileInfoW*(pszPath: LPCWSTR, dwFileAttributes: DWORD, - psfi: var TSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{. + psfi: var TSHFILEINFOW, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".} proc SHGetFileInfo*(pszPath: LPCSTR, dwFileAttributes: DWORD, - psfi: var TSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{. + psfi: var TSHFILEINFOA, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".} proc SHGetFileInfo*(pszPath: LPCWSTR, dwFileAttributes: DWORD, - psfi: var TSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{. + psfi: var TSHFILEINFOW, cbFileInfo, UFlags: uint32): DWORD{. stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".} proc SHGetDiskFreeSpaceExA*(pszDirectoryName: LPCSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".} proc SHGetDiskFreeSpaceExW*(pszDirectoryName: LPCWSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".} proc SHGetDiskFreeSpaceEx*(pszDirectoryName: LPCSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".} proc SHGetDiskFreeSpace*(pszDirectoryName: LPCSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".} proc SHGetDiskFreeSpaceEx*(pszDirectoryName: LPCWSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".} proc SHGetDiskFreeSpace*(pszDirectoryName: LPCWSTR, - pulFreeBytesAvailableToCaller: pULARGE_INTEGER, - pulTotalNumberOfBytes: pULARGE_INTEGER, - pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{. + pulFreeBytesAvailableToCaller: PULARGE_INTEGER, + pulTotalNumberOfBytes: PULARGE_INTEGER, + pulTotalNumberOfFreeBytes: PULARGE_INTEGER): bool{. stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".} proc SHGetNewLinkInfoA*(pszLinkTo: LPCSTR, pszDir: LPCSTR, pszName: LPSTR, - pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall, + pfMustCopy: PBool, uFlags: uint32): bool{.stdcall, dynlib: "shell32.dll", importc: "SHGetNewLinkInfoA".} proc SHGetNewLinkInfoW*(pszLinkTo: LPCWSTR, pszDir: LPCWSTR, pszName: LPWSTR, - pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall, + pfMustCopy: PBool, uFlags: uint32): bool{.stdcall, dynlib: "shell32.dll", importc: "SHGetNewLinkInfoW".} proc SHGetNewLinkInfo*(pszLinkTo: LPCSTR, pszDir: LPCSTR, pszName: LPSTR, - pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall, + pfMustCopy: PBool, uFlags: uint32): bool{.stdcall, dynlib: "shell32.dll", importc: "SHGetNewLinkInfoA".} proc SHGetNewLinkInfo*(pszLinkTo: LPCWSTR, pszDir: LPCWSTR, pszName: LPWSTR, - pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall, + pfMustCopy: PBool, uFlags: uint32): bool{.stdcall, dynlib: "shell32.dll", importc: "SHGetNewLinkInfoW".} const SHGNLI_PIDL* = 0x00000001 # pszLinkTo is a pidl @@ -777,17 +777,17 @@ const PRINTACTION_DOCUMENTDEFAULTS* = 6 PRINTACTION_SERVERPROPERTIES* = 7 -proc SHInvokePrinterCommandA*(HWND: hwnd, uAction: UINT, lpBuf1: LPCSTR, - lpBuf2: LPCSTR, fModal: Bool): Bool{.stdcall, +proc SHInvokePrinterCommandA*(hwnd: HWND, uAction: uint32, lpBuf1: LPCSTR, + lpBuf2: LPCSTR, fModal: bool): bool{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandA".} -proc SHInvokePrinterCommandW*(HWND: hwnd, uAction: UINT, lpBuf1: LPCWSTR, - lpBuf2: LPCWSTR, fModal: Bool): Bool{.stdcall, +proc SHInvokePrinterCommandW*(hwnd: HWND, uAction: uint32, lpBuf1: LPCWSTR, + lpBuf2: LPCWSTR, fModal: bool): bool{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".} -proc SHInvokePrinterCommand*(HWND: hwnd, uAction: UINT, lpBuf1: LPCSTR, - lpBuf2: LPCSTR, fModal: Bool): Bool{.stdcall, +proc SHInvokePrinterCommand*(hwnd: HWND, uAction: uint32, lpBuf1: LPCSTR, + lpBuf2: LPCSTR, fModal: bool): bool{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandA".} -proc SHInvokePrinterCommand*(HWND: hwnd, uAction: UINT, lpBuf1: LPCWSTR, - lpBuf2: LPCWSTR, fModal: Bool): Bool{.stdcall, +proc SHInvokePrinterCommand*(hwnd: HWND, uAction: uint32, lpBuf1: LPCWSTR, + lpBuf2: LPCWSTR, fModal: bool): bool{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".} proc SHLoadNonloadedIconOverlayIdentifiers*(): HResult{.stdcall, dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".} diff --git a/lib/wrappers/iup.nim b/lib/wrappers/iup.nim index 2ee1ca3ee..dd98b84b8 100644 --- a/lib/wrappers/iup.nim +++ b/lib/wrappers/iup.nim @@ -46,44 +46,44 @@ const constIUP_VERSION_DATE* = "2009/07/18" type - Ihandle {.pure.} = object + Ihandle = object PIhandle* = ptr Ihandle Icallback* = proc (arg: PIhandle): cint {.cdecl.} -# pre-definided dialogs -proc FileDlg*: PIhandle {.importc: "IupFileDlg", dynlib: dllname, cdecl.} -proc MessageDlg*: PIhandle {.importc: "IupMessageDlg", dynlib: dllname, cdecl.} -proc ColorDlg*: PIhandle {.importc: "IupColorDlg", dynlib: dllname, cdecl.} -proc FontDlg*: PIhandle {.importc: "IupFontDlg", dynlib: dllname, cdecl.} +# pre-defineded dialogs +proc fileDlg*: PIhandle {.importc: "IupFileDlg", dynlib: dllname, cdecl.} +proc messageDlg*: PIhandle {.importc: "IupMessageDlg", dynlib: dllname, cdecl.} +proc colorDlg*: PIhandle {.importc: "IupColorDlg", dynlib: dllname, cdecl.} +proc fontDlg*: PIhandle {.importc: "IupFontDlg", dynlib: dllname, cdecl.} -proc GetFile*(arq: cstring): cint {. +proc getFile*(arq: cstring): cint {. importc: "IupGetFile", dynlib: dllname, cdecl.} -proc Message*(title, msg: cstring) {. +proc message*(title, msg: cstring) {. importc: "IupMessage", dynlib: dllname, cdecl.} -proc Messagef*(title, format: cstring) {. +proc messagef*(title, format: cstring) {. importc: "IupMessagef", dynlib: dllname, cdecl, varargs.} -proc Alarm*(title, msg, b1, b2, b3: cstring): cint {. +proc alarm*(title, msg, b1, b2, b3: cstring): cint {. importc: "IupAlarm", dynlib: dllname, cdecl.} -proc Scanf*(format: cstring): cint {. +proc scanf*(format: cstring): cint {. importc: "IupScanf", dynlib: dllname, cdecl, varargs.} -proc ListDialog*(theType: cint, title: cstring, size: cint, +proc listDialog*(theType: cint, title: cstring, size: cint, list: cstringArray, op, max_col, max_lin: cint, marks: ptr cint): cint {. importc: "IupListDialog", dynlib: dllname, cdecl.} -proc GetText*(title, text: cstring): cint {. +proc getText*(title, text: cstring): cint {. importc: "IupGetText", dynlib: dllname, cdecl.} -proc GetColor*(x, y: cint, r, g, b: var byte): cint {. +proc getColor*(x, y: cint, r, g, b: var byte): cint {. importc: "IupGetColor", dynlib: dllname, cdecl.} type Iparamcb* = proc (dialog: PIhandle, param_index: cint, user_data: pointer): cint {.cdecl.} -proc GetParam*(title: cstring, action: Iparamcb, user_data: pointer, +proc getParam*(title: cstring, action: Iparamcb, user_data: pointer, format: cstring): cint {. importc: "IupGetParam", cdecl, varargs, dynlib: dllname.} -proc GetParamv*(title: cstring, action: Iparamcb, user_data: pointer, +proc getParamv*(title: cstring, action: Iparamcb, user_data: pointer, format: cstring, param_count, param_extra: cint, param_data: pointer): cint {. importc: "IupGetParamv", cdecl, dynlib: dllname.} @@ -91,276 +91,276 @@ proc GetParamv*(title: cstring, action: Iparamcb, user_data: pointer, # Functions -proc Open*(argc: ptr cint, argv: ptr cstringArray): cint {. +proc open*(argc: ptr cint, argv: ptr cstringArray): cint {. importc: "IupOpen", cdecl, dynlib: dllname.} -proc Close*() {.importc: "IupClose", cdecl, dynlib: dllname.} -proc ImageLibOpen*() {.importc: "IupImageLibOpen", cdecl, dynlib: dllname.} +proc close*() {.importc: "IupClose", cdecl, dynlib: dllname.} +proc imageLibOpen*() {.importc: "IupImageLibOpen", cdecl, dynlib: dllname.} -proc MainLoop*(): cint {.importc: "IupMainLoop", cdecl, dynlib: dllname, +proc mainLoop*(): cint {.importc: "IupMainLoop", cdecl, dynlib: dllname, discardable.} -proc LoopStep*(): cint {.importc: "IupLoopStep", cdecl, dynlib: dllname, +proc loopStep*(): cint {.importc: "IupLoopStep", cdecl, dynlib: dllname, discardable.} -proc MainLoopLevel*(): cint {.importc: "IupMainLoopLevel", cdecl, +proc mainLoopLevel*(): cint {.importc: "IupMainLoopLevel", cdecl, dynlib: dllname, discardable.} -proc Flush*() {.importc: "IupFlush", cdecl, dynlib: dllname.} -proc ExitLoop*() {.importc: "IupExitLoop", cdecl, dynlib: dllname.} +proc flush*() {.importc: "IupFlush", cdecl, dynlib: dllname.} +proc exitLoop*() {.importc: "IupExitLoop", cdecl, dynlib: dllname.} -proc Update*(ih: PIhandle) {.importc: "IupUpdate", cdecl, dynlib: dllname.} -proc UpdateChildren*(ih: PIhandle) {.importc: "IupUpdateChildren", cdecl, dynlib: dllname.} -proc Redraw*(ih: PIhandle, children: cint) {.importc: "IupRedraw", cdecl, dynlib: dllname.} -proc Refresh*(ih: PIhandle) {.importc: "IupRefresh", cdecl, dynlib: dllname.} +proc update*(ih: PIhandle) {.importc: "IupUpdate", cdecl, dynlib: dllname.} +proc updateChildren*(ih: PIhandle) {.importc: "IupUpdateChildren", cdecl, dynlib: dllname.} +proc redraw*(ih: PIhandle, children: cint) {.importc: "IupRedraw", cdecl, dynlib: dllname.} +proc refresh*(ih: PIhandle) {.importc: "IupRefresh", cdecl, dynlib: dllname.} -proc MapFont*(iupfont: cstring): cstring {.importc: "IupMapFont", cdecl, dynlib: dllname.} -proc UnMapFont*(driverfont: cstring): cstring {.importc: "IupUnMapFont", cdecl, dynlib: dllname.} -proc Help*(url: cstring): cint {.importc: "IupHelp", cdecl, dynlib: dllname.} -proc Load*(filename: cstring): cstring {.importc: "IupLoad", cdecl, dynlib: dllname.} +proc mapFont*(iupfont: cstring): cstring {.importc: "IupMapFont", cdecl, dynlib: dllname.} +proc unMapFont*(driverfont: cstring): cstring {.importc: "IupUnMapFont", cdecl, dynlib: dllname.} +proc help*(url: cstring): cint {.importc: "IupHelp", cdecl, dynlib: dllname.} +proc load*(filename: cstring): cstring {.importc: "IupLoad", cdecl, dynlib: dllname.} -proc IupVersion*(): cstring {.importc: "IupVersion", cdecl, dynlib: dllname.} -proc IupVersionDate*(): cstring {.importc: "IupVersionDate", cdecl, dynlib: dllname.} -proc IupVersionNumber*(): cint {.importc: "IupVersionNumber", cdecl, dynlib: dllname.} -proc SetLanguage*(lng: cstring) {.importc: "IupSetLanguage", cdecl, dynlib: dllname.} -proc GetLanguage*(): cstring {.importc: "IupGetLanguage", cdecl, dynlib: dllname.} +proc iupVersion*(): cstring {.importc: "IupVersion", cdecl, dynlib: dllname.} +proc iupVersionDate*(): cstring {.importc: "IupVersionDate", cdecl, dynlib: dllname.} +proc iupVersionNumber*(): cint {.importc: "IupVersionNumber", cdecl, dynlib: dllname.} +proc setLanguage*(lng: cstring) {.importc: "IupSetLanguage", cdecl, dynlib: dllname.} +proc getLanguage*(): cstring {.importc: "IupGetLanguage", cdecl, dynlib: dllname.} -proc Destroy*(ih: PIhandle) {.importc: "IupDestroy", cdecl, dynlib: dllname.} -proc Detach*(child: PIhandle) {.importc: "IupDetach", cdecl, dynlib: dllname.} -proc Append*(ih, child: PIhandle): PIhandle {. +proc destroy*(ih: PIhandle) {.importc: "IupDestroy", cdecl, dynlib: dllname.} +proc detach*(child: PIhandle) {.importc: "IupDetach", cdecl, dynlib: dllname.} +proc append*(ih, child: PIhandle): PIhandle {. importc: "IupAppend", cdecl, dynlib: dllname, discardable.} -proc Insert*(ih, ref_child, child: PIhandle): PIhandle {. +proc insert*(ih, ref_child, child: PIhandle): PIhandle {. importc: "IupInsert", cdecl, dynlib: dllname, discardable.} -proc GetChild*(ih: PIhandle, pos: cint): PIhandle {. +proc getChild*(ih: PIhandle, pos: cint): PIhandle {. importc: "IupGetChild", cdecl, dynlib: dllname.} -proc GetChildPos*(ih, child: PIhandle): cint {. +proc getChildPos*(ih, child: PIhandle): cint {. importc: "IupGetChildPos", cdecl, dynlib: dllname.} -proc GetChildCount*(ih: PIhandle): cint {. +proc getChildCount*(ih: PIhandle): cint {. importc: "IupGetChildCount", cdecl, dynlib: dllname.} -proc GetNextChild*(ih, child: PIhandle): PIhandle {. +proc getNextChild*(ih, child: PIhandle): PIhandle {. importc: "IupGetNextChild", cdecl, dynlib: dllname.} -proc GetBrother*(ih: PIhandle): PIhandle {. +proc getBrother*(ih: PIhandle): PIhandle {. importc: "IupGetBrother", cdecl, dynlib: dllname.} -proc GetParent*(ih: PIhandle): PIhandle {. +proc getParent*(ih: PIhandle): PIhandle {. importc: "IupGetParent", cdecl, dynlib: dllname.} -proc GetDialog*(ih: PIhandle): PIhandle {. +proc getDialog*(ih: PIhandle): PIhandle {. importc: "IupGetDialog", cdecl, dynlib: dllname.} -proc GetDialogChild*(ih: PIhandle, name: cstring): PIhandle {. +proc getDialogChild*(ih: PIhandle, name: cstring): PIhandle {. importc: "IupGetDialogChild", cdecl, dynlib: dllname.} -proc Reparent*(ih, new_parent: PIhandle): cint {. +proc reparent*(ih, new_parent: PIhandle): cint {. importc: "IupReparent", cdecl, dynlib: dllname.} -proc Popup*(ih: PIhandle, x, y: cint): cint {. +proc popup*(ih: PIhandle, x, y: cint): cint {. importc: "IupPopup", cdecl, dynlib: dllname, discardable.} -proc Show*(ih: PIhandle): cint {. +proc show*(ih: PIhandle): cint {. importc: "IupShow", cdecl, dynlib: dllname, discardable.} -proc ShowXY*(ih: PIhandle, x, y: cint): cint {. +proc showXY*(ih: PIhandle, x, y: cint): cint {. importc: "IupShowXY", cdecl, dynlib: dllname, discardable.} -proc Hide*(ih: PIhandle): cint {. +proc hide*(ih: PIhandle): cint {. importc: "IupHide", cdecl, dynlib: dllname, discardable.} -proc Map*(ih: PIhandle): cint {. +proc map*(ih: PIhandle): cint {. importc: "IupMap", cdecl, dynlib: dllname, discardable.} -proc Unmap*(ih: PIhandle) {. +proc unmap*(ih: PIhandle) {. importc: "IupUnmap", cdecl, dynlib: dllname, discardable.} -proc SetAttribute*(ih: PIhandle, name, value: cstring) {. +proc setAttribute*(ih: PIhandle, name, value: cstring) {. importc: "IupSetAttribute", cdecl, dynlib: dllname.} -proc StoreAttribute*(ih: PIhandle, name, value: cstring) {. +proc storeAttribute*(ih: PIhandle, name, value: cstring) {. importc: "IupStoreAttribute", cdecl, dynlib: dllname.} -proc SetAttributes*(ih: PIhandle, str: cstring): PIhandle {. +proc setAttributes*(ih: PIhandle, str: cstring): PIhandle {. importc: "IupSetAttributes", cdecl, dynlib: dllname.} -proc GetAttribute*(ih: PIhandle, name: cstring): cstring {. +proc getAttribute*(ih: PIhandle, name: cstring): cstring {. importc: "IupGetAttribute", cdecl, dynlib: dllname.} -proc GetAttributes*(ih: PIhandle): cstring {. +proc getAttributes*(ih: PIhandle): cstring {. importc: "IupGetAttributes", cdecl, dynlib: dllname.} -proc GetInt*(ih: PIhandle, name: cstring): cint {. +proc getInt*(ih: PIhandle, name: cstring): cint {. importc: "IupGetInt", cdecl, dynlib: dllname.} -proc GetInt2*(ih: PIhandle, name: cstring): cint {. +proc getInt2*(ih: PIhandle, name: cstring): cint {. importc: "IupGetInt2", cdecl, dynlib: dllname.} -proc GetIntInt*(ih: PIhandle, name: cstring, i1, i2: var cint): cint {. +proc getIntInt*(ih: PIhandle, name: cstring, i1, i2: var cint): cint {. importc: "IupGetIntInt", cdecl, dynlib: dllname.} -proc GetFloat*(ih: PIhandle, name: cstring): cfloat {. +proc getFloat*(ih: PIhandle, name: cstring): cfloat {. importc: "IupGetFloat", cdecl, dynlib: dllname.} -proc SetfAttribute*(ih: PIhandle, name, format: cstring) {. +proc setfAttribute*(ih: PIhandle, name, format: cstring) {. importc: "IupSetfAttribute", cdecl, dynlib: dllname, varargs.} -proc GetAllAttributes*(ih: PIhandle, names: cstringArray, n: cint): cint {. +proc getAllAttributes*(ih: PIhandle, names: cstringArray, n: cint): cint {. importc: "IupGetAllAttributes", cdecl, dynlib: dllname.} -proc SetAtt*(handle_name: cstring, ih: PIhandle, name: cstring): PIhandle {. +proc setAtt*(handle_name: cstring, ih: PIhandle, name: cstring): PIhandle {. importc: "IupSetAtt", cdecl, dynlib: dllname, varargs, discardable.} -proc SetGlobal*(name, value: cstring) {. +proc setGlobal*(name, value: cstring) {. importc: "IupSetGlobal", cdecl, dynlib: dllname.} -proc StoreGlobal*(name, value: cstring) {. +proc storeGlobal*(name, value: cstring) {. importc: "IupStoreGlobal", cdecl, dynlib: dllname.} -proc GetGlobal*(name: cstring): cstring {. +proc getGlobal*(name: cstring): cstring {. importc: "IupGetGlobal", cdecl, dynlib: dllname.} -proc SetFocus*(ih: PIhandle): PIhandle {. +proc setFocus*(ih: PIhandle): PIhandle {. importc: "IupSetFocus", cdecl, dynlib: dllname.} -proc GetFocus*(): PIhandle {. +proc getFocus*(): PIhandle {. importc: "IupGetFocus", cdecl, dynlib: dllname.} -proc PreviousField*(ih: PIhandle): PIhandle {. +proc previousField*(ih: PIhandle): PIhandle {. importc: "IupPreviousField", cdecl, dynlib: dllname.} -proc NextField*(ih: PIhandle): PIhandle {. +proc nextField*(ih: PIhandle): PIhandle {. importc: "IupNextField", cdecl, dynlib: dllname.} -proc GetCallback*(ih: PIhandle, name: cstring): Icallback {. +proc getCallback*(ih: PIhandle, name: cstring): Icallback {. importc: "IupGetCallback", cdecl, dynlib: dllname.} -proc SetCallback*(ih: PIhandle, name: cstring, func: Icallback): Icallback {. +proc setCallback*(ih: PIhandle, name: cstring, func: Icallback): Icallback {. importc: "IupSetCallback", cdecl, dynlib: dllname, discardable.} -proc SetCallbacks*(ih: PIhandle, name: cstring, func: Icallback): PIhandle {. +proc setCallbacks*(ih: PIhandle, name: cstring, func: Icallback): PIhandle {. importc: "IupSetCallbacks", cdecl, dynlib: dllname, varargs, discardable.} -proc GetFunction*(name: cstring): Icallback {. +proc getFunction*(name: cstring): Icallback {. importc: "IupGetFunction", cdecl, dynlib: dllname.} -proc SetFunction*(name: cstring, func: Icallback): Icallback {. +proc setFunction*(name: cstring, func: Icallback): Icallback {. importc: "IupSetFunction", cdecl, dynlib: dllname, discardable.} -proc GetActionName*(): cstring {. +proc getActionName*(): cstring {. importc: "IupGetActionName", cdecl, dynlib: dllname.} -proc GetHandle*(name: cstring): PIhandle {. +proc getHandle*(name: cstring): PIhandle {. importc: "IupGetHandle", cdecl, dynlib: dllname.} -proc SetHandle*(name: cstring, ih: PIhandle): PIhandle {. +proc setHandle*(name: cstring, ih: PIhandle): PIhandle {. importc: "IupSetHandle", cdecl, dynlib: dllname.} -proc GetAllNames*(names: cstringArray, n: cint): cint {. +proc getAllNames*(names: cstringArray, n: cint): cint {. importc: "IupGetAllNames", cdecl, dynlib: dllname.} -proc GetAllDialogs*(names: cstringArray, n: cint): cint {. +proc getAllDialogs*(names: cstringArray, n: cint): cint {. importc: "IupGetAllDialogs", cdecl, dynlib: dllname.} -proc GetName*(ih: PIhandle): cstring {. +proc getName*(ih: PIhandle): cstring {. importc: "IupGetName", cdecl, dynlib: dllname.} -proc SetAttributeHandle*(ih: PIhandle, name: cstring, ih_named: PIhandle) {. +proc setAttributeHandle*(ih: PIhandle, name: cstring, ih_named: PIhandle) {. importc: "IupSetAttributeHandle", cdecl, dynlib: dllname.} -proc GetAttributeHandle*(ih: PIhandle, name: cstring): PIhandle {. +proc getAttributeHandle*(ih: PIhandle, name: cstring): PIhandle {. importc: "IupGetAttributeHandle", cdecl, dynlib: dllname.} -proc GetClassName*(ih: PIhandle): cstring {. +proc getClassName*(ih: PIhandle): cstring {. importc: "IupGetClassName", cdecl, dynlib: dllname.} -proc GetClassType*(ih: PIhandle): cstring {. +proc getClassType*(ih: PIhandle): cstring {. importc: "IupGetClassType", cdecl, dynlib: dllname.} -proc GetClassAttributes*(classname: cstring, names: cstringArray, +proc getClassAttributes*(classname: cstring, names: cstringArray, n: cint): cint {. importc: "IupGetClassAttributes", cdecl, dynlib: dllname.} -proc SaveClassAttributes*(ih: PIhandle) {. +proc saveClassAttributes*(ih: PIhandle) {. importc: "IupSaveClassAttributes", cdecl, dynlib: dllname.} -proc SetClassDefaultAttribute*(classname, name, value: cstring) {. +proc setClassDefaultAttribute*(classname, name, value: cstring) {. importc: "IupSetClassDefaultAttribute", cdecl, dynlib: dllname.} -proc Create*(classname: cstring): PIhandle {. +proc create*(classname: cstring): PIhandle {. importc: "IupCreate", cdecl, dynlib: dllname.} -proc Createv*(classname: cstring, params: pointer): PIhandle {. +proc createv*(classname: cstring, params: pointer): PIhandle {. importc: "IupCreatev", cdecl, dynlib: dllname.} -proc Createp*(classname: cstring, first: pointer): PIhandle {. +proc createp*(classname: cstring, first: pointer): PIhandle {. importc: "IupCreatep", cdecl, dynlib: dllname, varargs.} -proc Fill*(): PIhandle {.importc: "IupFill", cdecl, dynlib: dllname.} -proc Radio*(child: PIhandle): PIhandle {. +proc fill*(): PIhandle {.importc: "IupFill", cdecl, dynlib: dllname.} +proc radio*(child: PIhandle): PIhandle {. importc: "IupRadio", cdecl, dynlib: dllname.} -proc Vbox*(child: PIhandle): PIhandle {. +proc vbox*(child: PIhandle): PIhandle {. importc: "IupVbox", cdecl, dynlib: dllname, varargs.} -proc Vboxv*(children: ptr PIhandle): PIhandle {. +proc vboxv*(children: ptr PIhandle): PIhandle {. importc: "IupVboxv", cdecl, dynlib: dllname.} -proc Zbox*(child: PIhandle): PIhandle {. +proc zbox*(child: PIhandle): PIhandle {. importc: "IupZbox", cdecl, dynlib: dllname, varargs.} -proc Zboxv*(children: ptr PIhandle): PIhandle {. +proc zboxv*(children: ptr PIhandle): PIhandle {. importc: "IupZboxv", cdecl, dynlib: dllname.} -proc Hbox*(child: PIhandle): PIhandle {. +proc hbox*(child: PIhandle): PIhandle {. importc: "IupHbox", cdecl, dynlib: dllname, varargs.} -proc Hboxv*(children: ptr PIhandle): PIhandle {. +proc hboxv*(children: ptr PIhandle): PIhandle {. importc: "IupHboxv", cdecl, dynlib: dllname.} -proc Normalizer*(ih_first: PIhandle): PIhandle {. +proc normalizer*(ih_first: PIhandle): PIhandle {. importc: "IupNormalizer", cdecl, dynlib: dllname, varargs.} -proc Normalizerv*(ih_list: ptr PIhandle): PIhandle {. +proc normalizerv*(ih_list: ptr PIhandle): PIhandle {. importc: "IupNormalizerv", cdecl, dynlib: dllname.} -proc Cbox*(child: PIhandle): PIhandle {. +proc cbox*(child: PIhandle): PIhandle {. importc: "IupCbox", cdecl, dynlib: dllname, varargs.} -proc Cboxv*(children: ptr PIhandle): PIhandle {. +proc cboxv*(children: ptr PIhandle): PIhandle {. importc: "IupCboxv", cdecl, dynlib: dllname.} -proc Sbox*(child: PIhandle): PIhandle {. +proc sbox*(child: PIhandle): PIhandle {. importc: "IupSbox", cdecl, dynlib: dllname.} -proc Frame*(child: PIhandle): PIhandle {. +proc frame*(child: PIhandle): PIhandle {. importc: "IupFrame", cdecl, dynlib: dllname.} -proc Image*(width, height: cint, pixmap: pointer): PIhandle {. +proc image*(width, height: cint, pixmap: pointer): PIhandle {. importc: "IupImage", cdecl, dynlib: dllname.} -proc ImageRGB*(width, height: cint, pixmap: pointer): PIhandle {. +proc imageRGB*(width, height: cint, pixmap: pointer): PIhandle {. importc: "IupImageRGB", cdecl, dynlib: dllname.} -proc ImageRGBA*(width, height: cint, pixmap: pointer): PIhandle {. +proc imageRGBA*(width, height: cint, pixmap: pointer): PIhandle {. importc: "IupImageRGBA", cdecl, dynlib: dllname.} -proc Item*(title, action: cstring): PIhandle {. +proc item*(title, action: cstring): PIhandle {. importc: "IupItem", cdecl, dynlib: dllname.} -proc Submenu*(title: cstring, child: PIhandle): PIhandle {. +proc submenu*(title: cstring, child: PIhandle): PIhandle {. importc: "IupSubmenu", cdecl, dynlib: dllname.} -proc Separator*(): PIhandle {. +proc separator*(): PIhandle {. importc: "IupSeparator", cdecl, dynlib: dllname.} -proc Menu*(child: PIhandle): PIhandle {. +proc menu*(child: PIhandle): PIhandle {. importc: "IupMenu", cdecl, dynlib: dllname, varargs.} -proc Menuv*(children: ptr PIhandle): PIhandle {. +proc menuv*(children: ptr PIhandle): PIhandle {. importc: "IupMenuv", cdecl, dynlib: dllname.} -proc Button*(title, action: cstring): PIhandle {. +proc button*(title, action: cstring): PIhandle {. importc: "IupButton", cdecl, dynlib: dllname.} -proc Canvas*(action: cstring): PIhandle {. +proc canvas*(action: cstring): PIhandle {. importc: "IupCanvas", cdecl, dynlib: dllname.} -proc Dialog*(child: PIhandle): PIhandle {. +proc dialog*(child: PIhandle): PIhandle {. importc: "IupDialog", cdecl, dynlib: dllname.} -proc User*(): PIhandle {. +proc user*(): PIhandle {. importc: "IupUser", cdecl, dynlib: dllname.} -proc Label*(title: cstring): PIhandle {. +proc label*(title: cstring): PIhandle {. importc: "IupLabel", cdecl, dynlib: dllname.} -proc List*(action: cstring): PIhandle {. +proc list*(action: cstring): PIhandle {. importc: "IupList", cdecl, dynlib: dllname.} -proc Text*(action: cstring): PIhandle {. +proc text*(action: cstring): PIhandle {. importc: "IupText", cdecl, dynlib: dllname.} -proc MultiLine*(action: cstring): PIhandle {. +proc multiLine*(action: cstring): PIhandle {. importc: "IupMultiLine", cdecl, dynlib: dllname.} -proc Toggle*(title, action: cstring): PIhandle {. +proc toggle*(title, action: cstring): PIhandle {. importc: "IupToggle", cdecl, dynlib: dllname.} -proc Timer*(): PIhandle {. +proc timer*(): PIhandle {. importc: "IupTimer", cdecl, dynlib: dllname.} -proc ProgressBar*(): PIhandle {. +proc progressBar*(): PIhandle {. importc: "IupProgressBar", cdecl, dynlib: dllname.} -proc Val*(theType: cstring): PIhandle {. +proc val*(theType: cstring): PIhandle {. importc: "IupVal", cdecl, dynlib: dllname.} -proc Tabs*(child: PIhandle): PIhandle {. +proc tabs*(child: PIhandle): PIhandle {. importc: "IupTabs", cdecl, dynlib: dllname, varargs.} -proc Tabsv*(children: ptr PIhandle): PIhandle {. +proc tabsv*(children: ptr PIhandle): PIhandle {. importc: "IupTabsv", cdecl, dynlib: dllname.} -proc Tree*(): PIhandle {.importc: "IupTree", cdecl, dynlib: dllname.} +proc tree*(): PIhandle {.importc: "IupTree", cdecl, dynlib: dllname.} -proc Spin*(): PIhandle {.importc: "IupSpin", cdecl, dynlib: dllname.} -proc Spinbox*(child: PIhandle): PIhandle {. +proc spin*(): PIhandle {.importc: "IupSpin", cdecl, dynlib: dllname.} +proc spinbox*(child: PIhandle): PIhandle {. importc: "IupSpinbox", cdecl, dynlib: dllname.} # IupText utilities -proc TextConvertLinColToPos*(ih: PIhandle, lin, col: cint, pos: var cint) {. +proc textConvertLinColToPos*(ih: PIhandle, lin, col: cint, pos: var cint) {. importc: "IupTextConvertLinColToPos", cdecl, dynlib: dllname.} -proc TextConvertPosToLinCol*(ih: PIhandle, pos: cint, lin, col: var cint) {. +proc textConvertPosToLinCol*(ih: PIhandle, pos: cint, lin, col: var cint) {. importc: "IupTextConvertPosToLinCol", cdecl, dynlib: dllname.} -proc ConvertXYToPos*(ih: PIhandle, x, y: cint): cint {. +proc convertXYToPos*(ih: PIhandle, x, y: cint): cint {. importc: "IupConvertXYToPos", cdecl, dynlib: dllname.} # IupTree utilities -proc TreeSetUserId*(ih: PIhandle, id: cint, userid: pointer): cint {. +proc treeSetUserId*(ih: PIhandle, id: cint, userid: pointer): cint {. importc: "IupTreeSetUserId", cdecl, dynlib: dllname, discardable.} -proc TreeGetUserId*(ih: PIhandle, id: cint): pointer {. +proc treeGetUserId*(ih: PIhandle, id: cint): pointer {. importc: "IupTreeGetUserId", cdecl, dynlib: dllname.} -proc TreeGetId*(ih: PIhandle, userid: pointer): cint {. +proc treeGetId*(ih: PIhandle, userid: pointer): cint {. importc: "IupTreeGetId", cdecl, dynlib: dllname.} -proc TreeSetAttribute*(ih: PIhandle, name: cstring, id: cint, value: cstring) {. +proc treeSetAttribute*(ih: PIhandle, name: cstring, id: cint, value: cstring) {. importc: "IupTreeSetAttribute", cdecl, dynlib: dllname.} -proc TreeStoreAttribute*(ih: PIhandle, name: cstring, id: cint, value: cstring) {. +proc treeStoreAttribute*(ih: PIhandle, name: cstring, id: cint, value: cstring) {. importc: "IupTreeStoreAttribute", cdecl, dynlib: dllname.} -proc TreeGetAttribute*(ih: PIhandle, name: cstring, id: cint): cstring {. +proc treeGetAttribute*(ih: PIhandle, name: cstring, id: cint): cstring {. importc: "IupTreeGetAttribute", cdecl, dynlib: dllname.} -proc TreeGetInt*(ih: PIhandle, name: cstring, id: cint): cint {. +proc treeGetInt*(ih: PIhandle, name: cstring, id: cint): cint {. importc: "IupTreeGetInt", cdecl, dynlib: dllname.} -proc TreeGetFloat*(ih: PIhandle, name: cstring, id: cint): cfloat {. +proc treeGetFloat*(ih: PIhandle, name: cstring, id: cint): cfloat {. importc: "IupTreeGetFloat", cdecl, dynlib: dllname.} -proc TreeSetfAttribute*(ih: PIhandle, name: cstring, id: cint, format: cstring) {. +proc treeSetfAttribute*(ih: PIhandle, name: cstring, id: cint, format: cstring) {. importc: "IupTreeSetfAttribute", cdecl, dynlib: dllname, varargs.} @@ -552,360 +552,360 @@ proc isCtrlXkey*(c: cint): bool = return c > 512 and c < 768 proc isAltXkey*(c: cint): bool = return c > 768 and c < 1024 proc isSysXkey*(c: cint): bool = return c > 1024 and c < 1280 -proc IUPxCODE*(c: cint): cint = return c + cint(128) # Normal (must be above 128) -proc IUPsxCODE*(c: cint): cint = +proc iUPxCODE*(c: cint): cint = return c + cint(128) # Normal (must be above 128) +proc iUPsxCODE*(c: cint): cint = return c + cint(256) # Shift (must have range to include the standard keys and the normal # extended keys, so must be above 256 -proc IUPcxCODE*(c: cint): cint = return c + cint(512) # Ctrl -proc IUPmxCODE*(c: cint): cint = return c + cint(768) # Alt -proc IUPyxCODE*(c: cint): cint = return c + cint(1024) # Sys (Win or Apple) +proc iUPcxCODE*(c: cint): cint = return c + cint(512) # Ctrl +proc iUPmxCODE*(c: cint): cint = return c + cint(768) # Alt +proc iUPyxCODE*(c: cint): cint = return c + cint(1024) # Sys (Win or Apple) const IUP_NUMMAXCODES* = 1280 ## 5*256=1280 Normal+Shift+Ctrl+Alt+Sys - K_HOME* = IUPxCODE(1) - K_UP* = IUPxCODE(2) - K_PGUP* = IUPxCODE(3) - K_LEFT* = IUPxCODE(4) - K_MIDDLE* = IUPxCODE(5) - K_RIGHT* = IUPxCODE(6) - K_END* = IUPxCODE(7) - K_DOWN* = IUPxCODE(8) - K_PGDN* = IUPxCODE(9) - K_INS* = IUPxCODE(10) - K_DEL* = IUPxCODE(11) - K_PAUSE* = IUPxCODE(12) - K_ESC* = IUPxCODE(13) - K_ccedilla* = IUPxCODE(14) - K_F1* = IUPxCODE(15) - K_F2* = IUPxCODE(16) - K_F3* = IUPxCODE(17) - K_F4* = IUPxCODE(18) - K_F5* = IUPxCODE(19) - K_F6* = IUPxCODE(20) - K_F7* = IUPxCODE(21) - K_F8* = IUPxCODE(22) - K_F9* = IUPxCODE(23) - K_F10* = IUPxCODE(24) - K_F11* = IUPxCODE(25) - K_F12* = IUPxCODE(26) - K_Print* = IUPxCODE(27) - K_Menu* = IUPxCODE(28) + K_HOME* = iupxCODE(1) + K_UP* = iupxCODE(2) + K_PGUP* = iupxCODE(3) + K_LEFT* = iupxCODE(4) + K_MIDDLE* = iupxCODE(5) + K_RIGHT* = iupxCODE(6) + K_END* = iupxCODE(7) + K_DOWN* = iupxCODE(8) + K_PGDN* = iupxCODE(9) + K_INS* = iupxCODE(10) + K_DEL* = iupxCODE(11) + K_PAUSE* = iupxCODE(12) + K_ESC* = iupxCODE(13) + K_ccedilla* = iupxCODE(14) + K_F1* = iupxCODE(15) + K_F2* = iupxCODE(16) + K_F3* = iupxCODE(17) + K_F4* = iupxCODE(18) + K_F5* = iupxCODE(19) + K_F6* = iupxCODE(20) + K_F7* = iupxCODE(21) + K_F8* = iupxCODE(22) + K_F9* = iupxCODE(23) + K_F10* = iupxCODE(24) + K_F11* = iupxCODE(25) + K_F12* = iupxCODE(26) + K_Print* = iupxCODE(27) + K_Menu* = iupxCODE(28) - K_acute* = IUPxCODE(29) # no Shift/Ctrl/Alt + K_acute* = iupxCODE(29) # no Shift/Ctrl/Alt - K_sHOME* = IUPsxCODE(K_HOME) - K_sUP* = IUPsxCODE(K_UP) - K_sPGUP* = IUPsxCODE(K_PGUP) - K_sLEFT* = IUPsxCODE(K_LEFT) - K_sMIDDLE* = IUPsxCODE(K_MIDDLE) - K_sRIGHT* = IUPsxCODE(K_RIGHT) - K_sEND* = IUPsxCODE(K_END) - K_sDOWN* = IUPsxCODE(K_DOWN) - K_sPGDN* = IUPsxCODE(K_PGDN) - K_sINS* = IUPsxCODE(K_INS) - K_sDEL* = IUPsxCODE(K_DEL) - K_sSP* = IUPsxCODE(K_SP) - K_sTAB* = IUPsxCODE(K_TAB) - K_sCR* = IUPsxCODE(K_CR) - K_sBS* = IUPsxCODE(K_BS) - K_sPAUSE* = IUPsxCODE(K_PAUSE) - K_sESC* = IUPsxCODE(K_ESC) - K_sCcedilla* = IUPsxCODE(K_ccedilla) - K_sF1* = IUPsxCODE(K_F1) - K_sF2* = IUPsxCODE(K_F2) - K_sF3* = IUPsxCODE(K_F3) - K_sF4* = IUPsxCODE(K_F4) - K_sF5* = IUPsxCODE(K_F5) - K_sF6* = IUPsxCODE(K_F6) - K_sF7* = IUPsxCODE(K_F7) - K_sF8* = IUPsxCODE(K_F8) - K_sF9* = IUPsxCODE(K_F9) - K_sF10* = IUPsxCODE(K_F10) - K_sF11* = IUPsxCODE(K_F11) - K_sF12* = IUPsxCODE(K_F12) - K_sPrint* = IUPsxCODE(K_Print) - K_sMenu* = IUPsxCODE(K_Menu) + K_sHOME* = iUPsxCODE(K_HOME) + K_sUP* = iUPsxCODE(K_UP) + K_sPGUP* = iUPsxCODE(K_PGUP) + K_sLEFT* = iUPsxCODE(K_LEFT) + K_sMIDDLE* = iUPsxCODE(K_MIDDLE) + K_sRIGHT* = iUPsxCODE(K_RIGHT) + K_sEND* = iUPsxCODE(K_END) + K_sDOWN* = iUPsxCODE(K_DOWN) + K_sPGDN* = iUPsxCODE(K_PGDN) + K_sINS* = iUPsxCODE(K_INS) + K_sDEL* = iUPsxCODE(K_DEL) + K_sSP* = iUPsxCODE(K_SP) + K_sTAB* = iUPsxCODE(K_TAB) + K_sCR* = iUPsxCODE(K_CR) + K_sBS* = iUPsxCODE(K_BS) + K_sPAUSE* = iUPsxCODE(K_PAUSE) + K_sESC* = iUPsxCODE(K_ESC) + K_sCcedilla* = iUPsxCODE(K_ccedilla) + K_sF1* = iUPsxCODE(K_F1) + K_sF2* = iUPsxCODE(K_F2) + K_sF3* = iUPsxCODE(K_F3) + K_sF4* = iUPsxCODE(K_F4) + K_sF5* = iUPsxCODE(K_F5) + K_sF6* = iUPsxCODE(K_F6) + K_sF7* = iUPsxCODE(K_F7) + K_sF8* = iUPsxCODE(K_F8) + K_sF9* = iUPsxCODE(K_F9) + K_sF10* = iUPsxCODE(K_F10) + K_sF11* = iUPsxCODE(K_F11) + K_sF12* = iUPsxCODE(K_F12) + K_sPrint* = iUPsxCODE(K_Print) + K_sMenu* = iUPsxCODE(K_Menu) - K_cHOME* = IUPcxCODE(K_HOME) - K_cUP* = IUPcxCODE(K_UP) - K_cPGUP* = IUPcxCODE(K_PGUP) - K_cLEFT* = IUPcxCODE(K_LEFT) - K_cMIDDLE* = IUPcxCODE(K_MIDDLE) - K_cRIGHT* = IUPcxCODE(K_RIGHT) - K_cEND* = IUPcxCODE(K_END) - K_cDOWN* = IUPcxCODE(K_DOWN) - K_cPGDN* = IUPcxCODE(K_PGDN) - K_cINS* = IUPcxCODE(K_INS) - K_cDEL* = IUPcxCODE(K_DEL) - K_cSP* = IUPcxCODE(K_SP) - K_cTAB* = IUPcxCODE(K_TAB) - K_cCR* = IUPcxCODE(K_CR) - K_cBS* = IUPcxCODE(K_BS) - K_cPAUSE* = IUPcxCODE(K_PAUSE) - K_cESC* = IUPcxCODE(K_ESC) - K_cCcedilla* = IUPcxCODE(K_ccedilla) - K_cF1* = IUPcxCODE(K_F1) - K_cF2* = IUPcxCODE(K_F2) - K_cF3* = IUPcxCODE(K_F3) - K_cF4* = IUPcxCODE(K_F4) - K_cF5* = IUPcxCODE(K_F5) - K_cF6* = IUPcxCODE(K_F6) - K_cF7* = IUPcxCODE(K_F7) - K_cF8* = IUPcxCODE(K_F8) - K_cF9* = IUPcxCODE(K_F9) - K_cF10* = IUPcxCODE(K_F10) - K_cF11* = IUPcxCODE(K_F11) - K_cF12* = IUPcxCODE(K_F12) - K_cPrint* = IUPcxCODE(K_Print) - K_cMenu* = IUPcxCODE(K_Menu) + K_cHOME* = iUPcxCODE(K_HOME) + K_cUP* = iUPcxCODE(K_UP) + K_cPGUP* = iUPcxCODE(K_PGUP) + K_cLEFT* = iUPcxCODE(K_LEFT) + K_cMIDDLE* = iUPcxCODE(K_MIDDLE) + K_cRIGHT* = iUPcxCODE(K_RIGHT) + K_cEND* = iUPcxCODE(K_END) + K_cDOWN* = iUPcxCODE(K_DOWN) + K_cPGDN* = iUPcxCODE(K_PGDN) + K_cINS* = iUPcxCODE(K_INS) + K_cDEL* = iUPcxCODE(K_DEL) + K_cSP* = iUPcxCODE(K_SP) + K_cTAB* = iUPcxCODE(K_TAB) + K_cCR* = iUPcxCODE(K_CR) + K_cBS* = iUPcxCODE(K_BS) + K_cPAUSE* = iUPcxCODE(K_PAUSE) + K_cESC* = iUPcxCODE(K_ESC) + K_cCcedilla* = iUPcxCODE(K_ccedilla) + K_cF1* = iUPcxCODE(K_F1) + K_cF2* = iUPcxCODE(K_F2) + K_cF3* = iUPcxCODE(K_F3) + K_cF4* = iUPcxCODE(K_F4) + K_cF5* = iUPcxCODE(K_F5) + K_cF6* = iUPcxCODE(K_F6) + K_cF7* = iUPcxCODE(K_F7) + K_cF8* = iUPcxCODE(K_F8) + K_cF9* = iUPcxCODE(K_F9) + K_cF10* = iUPcxCODE(K_F10) + K_cF11* = iUPcxCODE(K_F11) + K_cF12* = iUPcxCODE(K_F12) + K_cPrint* = iUPcxCODE(K_Print) + K_cMenu* = iUPcxCODE(K_Menu) - K_mHOME* = IUPmxCODE(K_HOME) - K_mUP* = IUPmxCODE(K_UP) - K_mPGUP* = IUPmxCODE(K_PGUP) - K_mLEFT* = IUPmxCODE(K_LEFT) - K_mMIDDLE* = IUPmxCODE(K_MIDDLE) - K_mRIGHT* = IUPmxCODE(K_RIGHT) - K_mEND* = IUPmxCODE(K_END) - K_mDOWN* = IUPmxCODE(K_DOWN) - K_mPGDN* = IUPmxCODE(K_PGDN) - K_mINS* = IUPmxCODE(K_INS) - K_mDEL* = IUPmxCODE(K_DEL) - K_mSP* = IUPmxCODE(K_SP) - K_mTAB* = IUPmxCODE(K_TAB) - K_mCR* = IUPmxCODE(K_CR) - K_mBS* = IUPmxCODE(K_BS) - K_mPAUSE* = IUPmxCODE(K_PAUSE) - K_mESC* = IUPmxCODE(K_ESC) - K_mCcedilla* = IUPmxCODE(K_ccedilla) - K_mF1* = IUPmxCODE(K_F1) - K_mF2* = IUPmxCODE(K_F2) - K_mF3* = IUPmxCODE(K_F3) - K_mF4* = IUPmxCODE(K_F4) - K_mF5* = IUPmxCODE(K_F5) - K_mF6* = IUPmxCODE(K_F6) - K_mF7* = IUPmxCODE(K_F7) - K_mF8* = IUPmxCODE(K_F8) - K_mF9* = IUPmxCODE(K_F9) - K_mF10* = IUPmxCODE(K_F10) - K_mF11* = IUPmxCODE(K_F11) - K_mF12* = IUPmxCODE(K_F12) - K_mPrint* = IUPmxCODE(K_Print) - K_mMenu* = IUPmxCODE(K_Menu) + K_mHOME* = iUPmxCODE(K_HOME) + K_mUP* = iUPmxCODE(K_UP) + K_mPGUP* = iUPmxCODE(K_PGUP) + K_mLEFT* = iUPmxCODE(K_LEFT) + K_mMIDDLE* = iUPmxCODE(K_MIDDLE) + K_mRIGHT* = iUPmxCODE(K_RIGHT) + K_mEND* = iUPmxCODE(K_END) + K_mDOWN* = iUPmxCODE(K_DOWN) + K_mPGDN* = iUPmxCODE(K_PGDN) + K_mINS* = iUPmxCODE(K_INS) + K_mDEL* = iUPmxCODE(K_DEL) + K_mSP* = iUPmxCODE(K_SP) + K_mTAB* = iUPmxCODE(K_TAB) + K_mCR* = iUPmxCODE(K_CR) + K_mBS* = iUPmxCODE(K_BS) + K_mPAUSE* = iUPmxCODE(K_PAUSE) + K_mESC* = iUPmxCODE(K_ESC) + K_mCcedilla* = iUPmxCODE(K_ccedilla) + K_mF1* = iUPmxCODE(K_F1) + K_mF2* = iUPmxCODE(K_F2) + K_mF3* = iUPmxCODE(K_F3) + K_mF4* = iUPmxCODE(K_F4) + K_mF5* = iUPmxCODE(K_F5) + K_mF6* = iUPmxCODE(K_F6) + K_mF7* = iUPmxCODE(K_F7) + K_mF8* = iUPmxCODE(K_F8) + K_mF9* = iUPmxCODE(K_F9) + K_mF10* = iUPmxCODE(K_F10) + K_mF11* = iUPmxCODE(K_F11) + K_mF12* = iUPmxCODE(K_F12) + K_mPrint* = iUPmxCODE(K_Print) + K_mMenu* = iUPmxCODE(K_Menu) - K_yHOME* = IUPyxCODE(K_HOME) - K_yUP* = IUPyxCODE(K_UP) - K_yPGUP* = IUPyxCODE(K_PGUP) - K_yLEFT* = IUPyxCODE(K_LEFT) - K_yMIDDLE* = IUPyxCODE(K_MIDDLE) - K_yRIGHT* = IUPyxCODE(K_RIGHT) - K_yEND* = IUPyxCODE(K_END) - K_yDOWN* = IUPyxCODE(K_DOWN) - K_yPGDN* = IUPyxCODE(K_PGDN) - K_yINS* = IUPyxCODE(K_INS) - K_yDEL* = IUPyxCODE(K_DEL) - K_ySP* = IUPyxCODE(K_SP) - K_yTAB* = IUPyxCODE(K_TAB) - K_yCR* = IUPyxCODE(K_CR) - K_yBS* = IUPyxCODE(K_BS) - K_yPAUSE* = IUPyxCODE(K_PAUSE) - K_yESC* = IUPyxCODE(K_ESC) - K_yCcedilla* = IUPyxCODE(K_ccedilla) - K_yF1* = IUPyxCODE(K_F1) - K_yF2* = IUPyxCODE(K_F2) - K_yF3* = IUPyxCODE(K_F3) - K_yF4* = IUPyxCODE(K_F4) - K_yF5* = IUPyxCODE(K_F5) - K_yF6* = IUPyxCODE(K_F6) - K_yF7* = IUPyxCODE(K_F7) - K_yF8* = IUPyxCODE(K_F8) - K_yF9* = IUPyxCODE(K_F9) - K_yF10* = IUPyxCODE(K_F10) - K_yF11* = IUPyxCODE(K_F11) - K_yF12* = IUPyxCODE(K_F12) - K_yPrint* = IUPyxCODE(K_Print) - K_yMenu* = IUPyxCODE(K_Menu) + K_yHOME* = iUPyxCODE(K_HOME) + K_yUP* = iUPyxCODE(K_UP) + K_yPGUP* = iUPyxCODE(K_PGUP) + K_yLEFT* = iUPyxCODE(K_LEFT) + K_yMIDDLE* = iUPyxCODE(K_MIDDLE) + K_yRIGHT* = iUPyxCODE(K_RIGHT) + K_yEND* = iUPyxCODE(K_END) + K_yDOWN* = iUPyxCODE(K_DOWN) + K_yPGDN* = iUPyxCODE(K_PGDN) + K_yINS* = iUPyxCODE(K_INS) + K_yDEL* = iUPyxCODE(K_DEL) + K_ySP* = iUPyxCODE(K_SP) + K_yTAB* = iUPyxCODE(K_TAB) + K_yCR* = iUPyxCODE(K_CR) + K_yBS* = iUPyxCODE(K_BS) + K_yPAUSE* = iUPyxCODE(K_PAUSE) + K_yESC* = iUPyxCODE(K_ESC) + K_yCcedilla* = iUPyxCODE(K_ccedilla) + K_yF1* = iUPyxCODE(K_F1) + K_yF2* = iUPyxCODE(K_F2) + K_yF3* = iUPyxCODE(K_F3) + K_yF4* = iUPyxCODE(K_F4) + K_yF5* = iUPyxCODE(K_F5) + K_yF6* = iUPyxCODE(K_F6) + K_yF7* = iUPyxCODE(K_F7) + K_yF8* = iUPyxCODE(K_F8) + K_yF9* = iUPyxCODE(K_F9) + K_yF10* = iUPyxCODE(K_F10) + K_yF11* = iUPyxCODE(K_F11) + K_yF12* = iUPyxCODE(K_F12) + K_yPrint* = iUPyxCODE(K_Print) + K_yMenu* = iUPyxCODE(K_Menu) - K_sPlus* = IUPsxCODE(K_plus) - K_sComma* = IUPsxCODE(K_comma) - K_sMinus* = IUPsxCODE(K_minus) - K_sPeriod* = IUPsxCODE(K_period) - K_sSlash* = IUPsxCODE(K_slash) - K_sAsterisk* = IUPsxCODE(K_asterisk) + K_sPlus* = iUPsxCODE(K_plus) + K_sComma* = iUPsxCODE(K_comma) + K_sMinus* = iUPsxCODE(K_minus) + K_sPeriod* = iUPsxCODE(K_period) + K_sSlash* = iUPsxCODE(K_slash) + K_sAsterisk* = iUPsxCODE(K_asterisk) - K_cupperA* = IUPcxCODE(K_upperA) - K_cupperB* = IUPcxCODE(K_upperB) - K_cupperC* = IUPcxCODE(K_upperC) - K_cupperD* = IUPcxCODE(K_upperD) - K_cupperE* = IUPcxCODE(K_upperE) - K_cupperF* = IUPcxCODE(K_upperF) - K_cupperG* = IUPcxCODE(K_upperG) - K_cupperH* = IUPcxCODE(K_upperH) - K_cupperI* = IUPcxCODE(K_upperI) - K_cupperJ* = IUPcxCODE(K_upperJ) - K_cupperK* = IUPcxCODE(K_upperK) - K_cupperL* = IUPcxCODE(K_upperL) - K_cupperM* = IUPcxCODE(K_upperM) - K_cupperN* = IUPcxCODE(K_upperN) - K_cupperO* = IUPcxCODE(K_upperO) - K_cupperP* = IUPcxCODE(K_upperP) - K_cupperQ* = IUPcxCODE(K_upperQ) - K_cupperR* = IUPcxCODE(K_upperR) - K_cupperS* = IUPcxCODE(K_upperS) - K_cupperT* = IUPcxCODE(K_upperT) - K_cupperU* = IUPcxCODE(K_upperU) - K_cupperV* = IUPcxCODE(K_upperV) - K_cupperW* = IUPcxCODE(K_upperW) - K_cupperX* = IUPcxCODE(K_upperX) - K_cupperY* = IUPcxCODE(K_upperY) - K_cupperZ* = IUPcxCODE(K_upperZ) - K_c1* = IUPcxCODE(K_1) - K_c2* = IUPcxCODE(K_2) - K_c3* = IUPcxCODE(K_3) - K_c4* = IUPcxCODE(K_4) - K_c5* = IUPcxCODE(K_5) - K_c6* = IUPcxCODE(K_6) - K_c7* = IUPcxCODE(K_7) - K_c8* = IUPcxCODE(K_8) - K_c9* = IUPcxCODE(K_9) - K_c0* = IUPcxCODE(K_0) - K_cPlus* = IUPcxCODE(K_plus) - K_cComma* = IUPcxCODE(K_comma) - K_cMinus* = IUPcxCODE(K_minus) - K_cPeriod* = IUPcxCODE(K_period) - K_cSlash* = IUPcxCODE(K_slash) - K_cSemicolon* = IUPcxCODE(K_semicolon) - K_cEqual* = IUPcxCODE(K_equal) - K_cBracketleft* = IUPcxCODE(K_bracketleft) - K_cBracketright* = IUPcxCODE(K_bracketright) - K_cBackslash* = IUPcxCODE(K_backslash) - K_cAsterisk* = IUPcxCODE(K_asterisk) + K_cupperA* = iUPcxCODE(K_upperA) + K_cupperB* = iUPcxCODE(K_upperB) + K_cupperC* = iUPcxCODE(K_upperC) + K_cupperD* = iUPcxCODE(K_upperD) + K_cupperE* = iUPcxCODE(K_upperE) + K_cupperF* = iUPcxCODE(K_upperF) + K_cupperG* = iUPcxCODE(K_upperG) + K_cupperH* = iUPcxCODE(K_upperH) + K_cupperI* = iUPcxCODE(K_upperI) + K_cupperJ* = iUPcxCODE(K_upperJ) + K_cupperK* = iUPcxCODE(K_upperK) + K_cupperL* = iUPcxCODE(K_upperL) + K_cupperM* = iUPcxCODE(K_upperM) + K_cupperN* = iUPcxCODE(K_upperN) + K_cupperO* = iUPcxCODE(K_upperO) + K_cupperP* = iUPcxCODE(K_upperP) + K_cupperQ* = iUPcxCODE(K_upperQ) + K_cupperR* = iUPcxCODE(K_upperR) + K_cupperS* = iUPcxCODE(K_upperS) + K_cupperT* = iUPcxCODE(K_upperT) + K_cupperU* = iUPcxCODE(K_upperU) + K_cupperV* = iUPcxCODE(K_upperV) + K_cupperW* = iUPcxCODE(K_upperW) + K_cupperX* = iUPcxCODE(K_upperX) + K_cupperY* = iUPcxCODE(K_upperY) + K_cupperZ* = iUPcxCODE(K_upperZ) + K_c1* = iUPcxCODE(K_1) + K_c2* = iUPcxCODE(K_2) + K_c3* = iUPcxCODE(K_3) + K_c4* = iUPcxCODE(K_4) + K_c5* = iUPcxCODE(K_5) + K_c6* = iUPcxCODE(K_6) + K_c7* = iUPcxCODE(K_7) + K_c8* = iUPcxCODE(K_8) + K_c9* = iUPcxCODE(K_9) + K_c0* = iUPcxCODE(K_0) + K_cPlus* = iUPcxCODE(K_plus) + K_cComma* = iUPcxCODE(K_comma) + K_cMinus* = iUPcxCODE(K_minus) + K_cPeriod* = iUPcxCODE(K_period) + K_cSlash* = iUPcxCODE(K_slash) + K_cSemicolon* = iUPcxCODE(K_semicolon) + K_cEqual* = iUPcxCODE(K_equal) + K_cBracketleft* = iUPcxCODE(K_bracketleft) + K_cBracketright* = iUPcxCODE(K_bracketright) + K_cBackslash* = iUPcxCODE(K_backslash) + K_cAsterisk* = iUPcxCODE(K_asterisk) - K_mupperA* = IUPmxCODE(K_upperA) - K_mupperB* = IUPmxCODE(K_upperB) - K_mupperC* = IUPmxCODE(K_upperC) - K_mupperD* = IUPmxCODE(K_upperD) - K_mupperE* = IUPmxCODE(K_upperE) - K_mupperF* = IUPmxCODE(K_upperF) - K_mupperG* = IUPmxCODE(K_upperG) - K_mupperH* = IUPmxCODE(K_upperH) - K_mupperI* = IUPmxCODE(K_upperI) - K_mupperJ* = IUPmxCODE(K_upperJ) - K_mupperK* = IUPmxCODE(K_upperK) - K_mupperL* = IUPmxCODE(K_upperL) - K_mupperM* = IUPmxCODE(K_upperM) - K_mupperN* = IUPmxCODE(K_upperN) - K_mupperO* = IUPmxCODE(K_upperO) - K_mupperP* = IUPmxCODE(K_upperP) - K_mupperQ* = IUPmxCODE(K_upperQ) - K_mupperR* = IUPmxCODE(K_upperR) - K_mupperS* = IUPmxCODE(K_upperS) - K_mupperT* = IUPmxCODE(K_upperT) - K_mupperU* = IUPmxCODE(K_upperU) - K_mupperV* = IUPmxCODE(K_upperV) - K_mupperW* = IUPmxCODE(K_upperW) - K_mupperX* = IUPmxCODE(K_upperX) - K_mupperY* = IUPmxCODE(K_upperY) - K_mupperZ* = IUPmxCODE(K_upperZ) - K_m1* = IUPmxCODE(K_1) - K_m2* = IUPmxCODE(K_2) - K_m3* = IUPmxCODE(K_3) - K_m4* = IUPmxCODE(K_4) - K_m5* = IUPmxCODE(K_5) - K_m6* = IUPmxCODE(K_6) - K_m7* = IUPmxCODE(K_7) - K_m8* = IUPmxCODE(K_8) - K_m9* = IUPmxCODE(K_9) - K_m0* = IUPmxCODE(K_0) - K_mPlus* = IUPmxCODE(K_plus) - K_mComma* = IUPmxCODE(K_comma) - K_mMinus* = IUPmxCODE(K_minus) - K_mPeriod* = IUPmxCODE(K_period) - K_mSlash* = IUPmxCODE(K_slash) - K_mSemicolon* = IUPmxCODE(K_semicolon) - K_mEqual* = IUPmxCODE(K_equal) - K_mBracketleft* = IUPmxCODE(K_bracketleft) - K_mBracketright* = IUPmxCODE(K_bracketright) - K_mBackslash* = IUPmxCODE(K_backslash) - K_mAsterisk* = IUPmxCODE(K_asterisk) + K_mupperA* = iUPmxCODE(K_upperA) + K_mupperB* = iUPmxCODE(K_upperB) + K_mupperC* = iUPmxCODE(K_upperC) + K_mupperD* = iUPmxCODE(K_upperD) + K_mupperE* = iUPmxCODE(K_upperE) + K_mupperF* = iUPmxCODE(K_upperF) + K_mupperG* = iUPmxCODE(K_upperG) + K_mupperH* = iUPmxCODE(K_upperH) + K_mupperI* = iUPmxCODE(K_upperI) + K_mupperJ* = iUPmxCODE(K_upperJ) + K_mupperK* = iUPmxCODE(K_upperK) + K_mupperL* = iUPmxCODE(K_upperL) + K_mupperM* = iUPmxCODE(K_upperM) + K_mupperN* = iUPmxCODE(K_upperN) + K_mupperO* = iUPmxCODE(K_upperO) + K_mupperP* = iUPmxCODE(K_upperP) + K_mupperQ* = iUPmxCODE(K_upperQ) + K_mupperR* = iUPmxCODE(K_upperR) + K_mupperS* = iUPmxCODE(K_upperS) + K_mupperT* = iUPmxCODE(K_upperT) + K_mupperU* = iUPmxCODE(K_upperU) + K_mupperV* = iUPmxCODE(K_upperV) + K_mupperW* = iUPmxCODE(K_upperW) + K_mupperX* = iUPmxCODE(K_upperX) + K_mupperY* = iUPmxCODE(K_upperY) + K_mupperZ* = iUPmxCODE(K_upperZ) + K_m1* = iUPmxCODE(K_1) + K_m2* = iUPmxCODE(K_2) + K_m3* = iUPmxCODE(K_3) + K_m4* = iUPmxCODE(K_4) + K_m5* = iUPmxCODE(K_5) + K_m6* = iUPmxCODE(K_6) + K_m7* = iUPmxCODE(K_7) + K_m8* = iUPmxCODE(K_8) + K_m9* = iUPmxCODE(K_9) + K_m0* = iUPmxCODE(K_0) + K_mPlus* = iUPmxCODE(K_plus) + K_mComma* = iUPmxCODE(K_comma) + K_mMinus* = iUPmxCODE(K_minus) + K_mPeriod* = iUPmxCODE(K_period) + K_mSlash* = iUPmxCODE(K_slash) + K_mSemicolon* = iUPmxCODE(K_semicolon) + K_mEqual* = iUPmxCODE(K_equal) + K_mBracketleft* = iUPmxCODE(K_bracketleft) + K_mBracketright* = iUPmxCODE(K_bracketright) + K_mBackslash* = iUPmxCODE(K_backslash) + K_mAsterisk* = iUPmxCODE(K_asterisk) - K_yA* = IUPyxCODE(K_upperA) - K_yB* = IUPyxCODE(K_upperB) - K_yC* = IUPyxCODE(K_upperC) - K_yD* = IUPyxCODE(K_upperD) - K_yE* = IUPyxCODE(K_upperE) - K_yF* = IUPyxCODE(K_upperF) - K_yG* = IUPyxCODE(K_upperG) - K_yH* = IUPyxCODE(K_upperH) - K_yI* = IUPyxCODE(K_upperI) - K_yJ* = IUPyxCODE(K_upperJ) - K_yK* = IUPyxCODE(K_upperK) - K_yL* = IUPyxCODE(K_upperL) - K_yM* = IUPyxCODE(K_upperM) - K_yN* = IUPyxCODE(K_upperN) - K_yO* = IUPyxCODE(K_upperO) - K_yP* = IUPyxCODE(K_upperP) - K_yQ* = IUPyxCODE(K_upperQ) - K_yR* = IUPyxCODE(K_upperR) - K_yS* = IUPyxCODE(K_upperS) - K_yT* = IUPyxCODE(K_upperT) - K_yU* = IUPyxCODE(K_upperU) - K_yV* = IUPyxCODE(K_upperV) - K_yW* = IUPyxCODE(K_upperW) - K_yX* = IUPyxCODE(K_upperX) - K_yY* = IUPyxCODE(K_upperY) - K_yZ* = IUPyxCODE(K_upperZ) - K_y1* = IUPyxCODE(K_1) - K_y2* = IUPyxCODE(K_2) - K_y3* = IUPyxCODE(K_3) - K_y4* = IUPyxCODE(K_4) - K_y5* = IUPyxCODE(K_5) - K_y6* = IUPyxCODE(K_6) - K_y7* = IUPyxCODE(K_7) - K_y8* = IUPyxCODE(K_8) - K_y9* = IUPyxCODE(K_9) - K_y0* = IUPyxCODE(K_0) - K_yPlus* = IUPyxCODE(K_plus) - K_yComma* = IUPyxCODE(K_comma) - K_yMinus* = IUPyxCODE(K_minus) - K_yPeriod* = IUPyxCODE(K_period) - K_ySlash* = IUPyxCODE(K_slash) - K_ySemicolon* = IUPyxCODE(K_semicolon) - K_yEqual* = IUPyxCODE(K_equal) - K_yBracketleft* = IUPyxCODE(K_bracketleft) - K_yBracketright* = IUPyxCODE(K_bracketright) - K_yBackslash* = IUPyxCODE(K_backslash) - K_yAsterisk* = IUPyxCODE(K_asterisk) + K_yA* = iUPyxCODE(K_upperA) + K_yB* = iUPyxCODE(K_upperB) + K_yC* = iUPyxCODE(K_upperC) + K_yD* = iUPyxCODE(K_upperD) + K_yE* = iUPyxCODE(K_upperE) + K_yF* = iUPyxCODE(K_upperF) + K_yG* = iUPyxCODE(K_upperG) + K_yH* = iUPyxCODE(K_upperH) + K_yI* = iUPyxCODE(K_upperI) + K_yJ* = iUPyxCODE(K_upperJ) + K_yK* = iUPyxCODE(K_upperK) + K_yL* = iUPyxCODE(K_upperL) + K_yM* = iUPyxCODE(K_upperM) + K_yN* = iUPyxCODE(K_upperN) + K_yO* = iUPyxCODE(K_upperO) + K_yP* = iUPyxCODE(K_upperP) + K_yQ* = iUPyxCODE(K_upperQ) + K_yR* = iUPyxCODE(K_upperR) + K_yS* = iUPyxCODE(K_upperS) + K_yT* = iUPyxCODE(K_upperT) + K_yU* = iUPyxCODE(K_upperU) + K_yV* = iUPyxCODE(K_upperV) + K_yW* = iUPyxCODE(K_upperW) + K_yX* = iUPyxCODE(K_upperX) + K_yY* = iUPyxCODE(K_upperY) + K_yZ* = iUPyxCODE(K_upperZ) + K_y1* = iUPyxCODE(K_1) + K_y2* = iUPyxCODE(K_2) + K_y3* = iUPyxCODE(K_3) + K_y4* = iUPyxCODE(K_4) + K_y5* = iUPyxCODE(K_5) + K_y6* = iUPyxCODE(K_6) + K_y7* = iUPyxCODE(K_7) + K_y8* = iUPyxCODE(K_8) + K_y9* = iUPyxCODE(K_9) + K_y0* = iUPyxCODE(K_0) + K_yPlus* = iUPyxCODE(K_plus) + K_yComma* = iUPyxCODE(K_comma) + K_yMinus* = iUPyxCODE(K_minus) + K_yPeriod* = iUPyxCODE(K_period) + K_ySlash* = iUPyxCODE(K_slash) + K_ySemicolon* = iUPyxCODE(K_semicolon) + K_yEqual* = iUPyxCODE(K_equal) + K_yBracketleft* = iUPyxCODE(K_bracketleft) + K_yBracketright* = iUPyxCODE(K_bracketright) + K_yBackslash* = iUPyxCODE(K_backslash) + K_yAsterisk* = iUPyxCODE(K_asterisk) -proc ControlsOpen*(): cint {.cdecl, importc: "IupControlsOpen", dynlib: dllname.} -proc ControlsClose*() {.cdecl, importc: "IupControlsClose", dynlib: dllname.} +proc controlsOpen*(): cint {.cdecl, importc: "IupControlsOpen", dynlib: dllname.} +proc controlsClose*() {.cdecl, importc: "IupControlsClose", dynlib: dllname.} -proc OldValOpen*() {.cdecl, importc: "IupOldValOpen", dynlib: dllname.} -proc OldTabsOpen*() {.cdecl, importc: "IupOldTabsOpen", dynlib: dllname.} +proc oldValOpen*() {.cdecl, importc: "IupOldValOpen", dynlib: dllname.} +proc oldTabsOpen*() {.cdecl, importc: "IupOldTabsOpen", dynlib: dllname.} -proc Colorbar*(): PIhandle {.cdecl, importc: "IupColorbar", dynlib: dllname.} -proc Cells*(): PIhandle {.cdecl, importc: "IupCells", dynlib: dllname.} -proc ColorBrowser*(): PIhandle {.cdecl, importc: "IupColorBrowser", dynlib: dllname.} -proc Gauge*(): PIhandle {.cdecl, importc: "IupGauge", dynlib: dllname.} -proc Dial*(theType: cstring): PIhandle {.cdecl, importc: "IupDial", dynlib: dllname.} -proc Matrix*(action: cstring): PIhandle {.cdecl, importc: "IupMatrix", dynlib: dllname.} +proc colorbar*(): PIhandle {.cdecl, importc: "IupColorbar", dynlib: dllname.} +proc cells*(): PIhandle {.cdecl, importc: "IupCells", dynlib: dllname.} +proc colorBrowser*(): PIhandle {.cdecl, importc: "IupColorBrowser", dynlib: dllname.} +proc gauge*(): PIhandle {.cdecl, importc: "IupGauge", dynlib: dllname.} +proc dial*(theType: cstring): PIhandle {.cdecl, importc: "IupDial", dynlib: dllname.} +proc matrix*(action: cstring): PIhandle {.cdecl, importc: "IupMatrix", dynlib: dllname.} # IupMatrix utilities -proc MatSetAttribute*(ih: PIhandle, name: cstring, lin, col: cint, +proc matSetAttribute*(ih: PIhandle, name: cstring, lin, col: cint, value: cstring) {. cdecl, importc: "IupMatSetAttribute", dynlib: dllname.} -proc MatStoreAttribute*(ih: PIhandle, name: cstring, lin, col: cint, +proc matStoreAttribute*(ih: PIhandle, name: cstring, lin, col: cint, value: cstring) {.cdecl, importc: "IupMatStoreAttribute", dynlib: dllname.} -proc MatGetAttribute*(ih: PIhandle, name: cstring, lin, col: cint): cstring {. +proc matGetAttribute*(ih: PIhandle, name: cstring, lin, col: cint): cstring {. cdecl, importc: "IupMatGetAttribute", dynlib: dllname.} -proc MatGetInt*(ih: PIhandle, name: cstring, lin, col: cint): cint {. +proc matGetInt*(ih: PIhandle, name: cstring, lin, col: cint): cint {. cdecl, importc: "IupMatGetInt", dynlib: dllname.} -proc MatGetFloat*(ih: PIhandle, name: cstring, lin, col: cint): cfloat {. +proc matGetFloat*(ih: PIhandle, name: cstring, lin, col: cint): cfloat {. cdecl, importc: "IupMatGetFloat", dynlib: dllname.} -proc MatSetfAttribute*(ih: PIhandle, name: cstring, lin, col: cint, +proc matSetfAttribute*(ih: PIhandle, name: cstring, lin, col: cint, format: cstring) {.cdecl, importc: "IupMatSetfAttribute", dynlib: dllname, varargs.} @@ -916,34 +916,34 @@ const IUP_SECONDARY* = -2 # Initialize PPlot widget class -proc PPlotOpen*() {.cdecl, importc: "IupPPlotOpen", dynlib: dllname.} +proc pPlotOpen*() {.cdecl, importc: "IupPPlotOpen", dynlib: dllname.} # Create an PPlot widget instance -proc PPlot*: PIhandle {.cdecl, importc: "IupPPlot", dynlib: dllname.} +proc pPlot*: PIhandle {.cdecl, importc: "IupPPlot", dynlib: dllname.} # Add dataset to plot -proc PPlotBegin*(ih: PIhandle, strXdata: cint) {. +proc pPlotBegin*(ih: PIhandle, strXdata: cint) {. cdecl, importc: "IupPPlotBegin", dynlib: dllname.} -proc PPlotAdd*(ih: PIhandle, x, y: cfloat) {. +proc pPlotAdd*(ih: PIhandle, x, y: cfloat) {. cdecl, importc: "IupPPlotAdd", dynlib: dllname.} -proc PPlotAddStr*(ih: PIhandle, x: cstring, y: cfloat) {. +proc pPlotAddStr*(ih: PIhandle, x: cstring, y: cfloat) {. cdecl, importc: "IupPPlotAddStr", dynlib: dllname.} -proc PPlotEnd*(ih: PIhandle): cint {. +proc pPlotEnd*(ih: PIhandle): cint {. cdecl, importc: "IupPPlotEnd", dynlib: dllname.} -proc PPlotInsertStr*(ih: PIhandle, index, sample_index: cint, x: cstring, +proc pPlotInsertStr*(ih: PIhandle, index, sample_index: cint, x: cstring, y: cfloat) {.cdecl, importc: "IupPPlotInsertStr", dynlib: dllname.} -proc PPlotInsert*(ih: PIhandle, index, sample_index: cint, +proc pPlotInsert*(ih: PIhandle, index, sample_index: cint, x, y: cfloat) {. cdecl, importc: "IupPPlotInsert", dynlib: dllname.} # convert from plot coordinates to pixels -proc PPlotTransform*(ih: PIhandle, x, y: cfloat, ix, iy: var cint) {. +proc pPlotTransform*(ih: PIhandle, x, y: cfloat, ix, iy: var cint) {. cdecl, importc: "IupPPlotTransform", dynlib: dllname.} # Plot on the given device. Uses a "cdCanvas*". -proc PPlotPaintTo*(ih: PIhandle, cnv: pointer) {. +proc pPlotPaintTo*(ih: PIhandle, cnv: pointer) {. cdecl, importc: "IupPPlotPaintTo", dynlib: dllname.} diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim index 1c88bc14e..753796274 100644 --- a/lib/wrappers/sdl/sdl.nim +++ b/lib/wrappers/sdl/sdl.nim @@ -250,14 +250,14 @@ # SDL_GL_MULTISAMPLESAMPLES # # Add DLL/Shared object functions -# function SDL_LoadObject( const sofile : PChar ) : Pointer; +# function SDL_LoadObject( const sofile : PChar ) : pointer; # -# function SDL_LoadFunction( handle : Pointer; const name : PChar ) : Pointer; +# function SDL_LoadFunction( handle : pointer; const name : PChar ) : pointer; # -# procedure SDL_UnloadObject( handle : Pointer ); +# procedure SDL_UnloadObject( handle : pointer ); # # Added function to create RWops from const memory: SDL_RWFromConstMem() -# function SDL_RWFromConstMem(const mem: Pointer; size: Integer) : PSDL_RWops; +# function SDL_RWFromConstMem(const mem: pointer; size: Integer) : PSDL_RWops; # # Ported SDL_cpuinfo.h so Now you can test for Specific CPU types. # @@ -756,9 +756,9 @@ type sdlFALSE, sdlTRUE PUInt8Array* = ptr TUInt8Array TUInt8Array* = array[0..high(int) shr 1, byte] - PUInt16* = ptr UInt16 - PUInt32* = ptr UInt32 - PUInt64* = ptr UInt64 + PUInt16* = ptr uInt16 + PUInt32* = ptr uInt32 + PUInt64* = ptr uInt64 UInt64*{.final.} = object hi*: int32 lo*: int32 @@ -790,8 +790,8 @@ type args*: array[0..ERR_MAX_ARGS - 1, TArg] TStdio*{.final.} = object - autoclose*: int # FILE * is only defined in Kylix so we use a simple Pointer - fp*: Pointer + autoclose*: int # FILE * is only defined in Kylix so we use a simple pointer + fp*: pointer TMem*{.final.} = object base*: ptr byte @@ -800,9 +800,9 @@ type PRWops* = ptr TRWops # now the pointer to function types TSeek* = proc (context: PRWops, offset: int, whence: int): int{.cdecl.} - TRead* = proc (context: PRWops, thePtr: Pointer, size: int, maxnum: int): int{. + TRead* = proc (context: PRWops, thePtr: pointer, size: int, maxnum: int): int{. cdecl.} - TWrite* = proc (context: PRWops, thePtr: Pointer, size: int, num: int): int{. + TWrite* = proc (context: PRWops, thePtr: pointer, size: int, num: int): int{. cdecl.} TClose* = proc (context: PRWops): int{.cdecl.} # the variant record itself TRWops*{.final.} = object @@ -817,27 +817,27 @@ type RWops* = TRWops # SDL_timer.h types # Function prototype for the timer callback function TTimerCallback* = proc (interval: int32): int32{.cdecl.} - TNewTimerCallback* = proc (interval: int32, param: Pointer): int32{.cdecl.} + TNewTimerCallback* = proc (interval: int32, param: pointer): int32{.cdecl.} PTimerID* = ptr TTimerID TTimerID*{.final.} = object interval*: int32 callback*: TNewTimerCallback - param*: Pointer + param*: pointer last_alarm*: int32 next*: PTimerID - TAudioSpecCallback* = proc (userdata: Pointer, stream: ptr byte, length: int){. + TAudioSpecCallback* = proc (userdata: pointer, stream: ptr byte, length: int){. cdecl.} # SDL_audio.h types # The calculated values in this structure are calculated by SDL_OpenAudio() PAudioSpec* = ptr TAudioSpec TAudioSpec*{.final.} = object # A structure to hold a set of audio conversion filters and buffers freq*: int # DSP frequency -- samples per second - format*: UInt16 # Audio data format + format*: uInt16 # Audio data format channels*: byte # Number of channels: 1 mono, 2 stereo silence*: byte # Audio buffer silence value (calculated) - samples*: UInt16 # Audio buffer size in samples - padding*: UInt16 # Necessary for some compile environments + samples*: uInt16 # Audio buffer size in samples + padding*: uInt16 # Necessary for some compile environments size*: int32 # Audio buffer size in bytes (calculated) # This function is called when the audio device needs more data. # 'stream' is a pointer to the audio data buffer @@ -845,20 +845,20 @@ type # Once the callback returns, the buffer will no longer be valid. # Stereo samples are stored in a LRLRLR ordering. callback*: TAudioSpecCallback - userdata*: Pointer + userdata*: pointer PAudioCVT* = ptr TAudioCVT PAudioCVTFilter* = ptr TAudioCVTFilter TAudioCVTFilter*{.final.} = object cvt*: PAudioCVT - format*: UInt16 + format*: uint16 PAudioCVTFilterArray* = ptr TAudioCVTFilterArray TAudioCVTFilterArray* = array[0..9, PAudioCVTFilter] TAudioCVT*{.final.} = object needed*: int # Set to 1 if conversion possible - src_format*: UInt16 # Source audio format - dst_format*: UInt16 # Target audio format + src_format*: uint16 # Source audio format + dst_format*: uint16 # Target audio format rate_incr*: float64 # Rate conversion increment buf*: ptr byte # Buffer to hold entire audio data length*: int # Length of original audio buffer @@ -876,7 +876,7 @@ type TCDTrack*{.final.} = object # This structure is only current as of the last call to SDL_CDStatus() id*: byte # Track number theType*: byte # Data or audio track - unused*: UInt16 + unused*: uint16 len*: int32 # Length, in frames, of this track offset*: int32 # Offset, in frames, from start of disk @@ -945,7 +945,7 @@ type scancode*: byte # hardware specific scancode sym*: TKey # SDL virtual keysym modifier*: TMod # current key modifiers - unicode*: UInt16 # translated character + unicode*: uint16 # translated character TEventAction* = enum # Application visibility event structure ADDEVENT, PEEKEVENT, GETEVENT @@ -971,7 +971,7 @@ type kind*: TEventKind which*: byte # The mouse device index state*: byte # The current button state - x*, y*: UInt16 # The X/Y coordinates of the mouse + x*, y*: uint16 # The X/Y coordinates of the mouse xrel*: int16 # The relative motion in the X direction yrel*: int16 # The relative motion in the Y direction @@ -982,8 +982,8 @@ type which*: byte # The mouse device index button*: byte # The mouse button index state*: byte # SDL_PRESSED or SDL_RELEASED - x*: UInt16 # The X coordinates of the mouse at press time - y*: UInt16 # The Y coordinates of the mouse at press time + x*: uint16 # The X coordinates of the mouse at press time + y*: uint16 # The Y coordinates of the mouse at press time PJoyAxisEvent* = ptr TJoyAxisEvent TJoyAxisEvent*{.final.} = object # SDL_JOYAXISMOTION @@ -1036,8 +1036,8 @@ type TUserEvent*{.final.} = object # SDL_USEREVENT through SDL_NUMEVENTS-1 kind*: TEventKind code*: cint # User defined event code - data1*: Pointer # User defined data pointer - data2*: Pointer # User defined data pointer + data1*: pointer # User defined data pointer + data2*: pointer # User defined data pointer when defined(Unix): @@ -1090,8 +1090,8 @@ elif defined(Unix): # any X11 functions using the display variable. # They lock the event thread, so should not be # called around event functions or from event filters. - lock_func*: Pointer - unlock_func*: Pointer # Introduced in SDL 1.0.2 + lock_func*: pointer + unlock_func*: pointer # Introduced in SDL 1.0.2 fswindow*: TWindow # The X11 fullscreen window wmwindow*: TWindow # The X11 managed input window @@ -1135,7 +1135,7 @@ type PRect* = ptr TRect TRect*{.final.} = object x*, y*: int16 - w*, h*: UInt16 + w*, h*: uint16 Rect* = TRect PColor* = ptr TColor @@ -1182,7 +1182,7 @@ type d_width*: int d_height*: int d_skip*: int - aux_data*: Pointer + aux_data*: pointer src*: PPixelFormat table*: ptr byte dst*: PPixelFormat @@ -1194,17 +1194,17 @@ type flags*: int32 # Read-only format*: PPixelFormat # Read-only w*, h*: cint # Read-only - pitch*: UInt16 # Read-only - pixels*: Pointer # Read-write + pitch*: uint16 # Read-only + pixels*: pointer # Read-write offset*: cint # Private - hwdata*: Pointer #TPrivate_hwdata; Hardware-specific surface info + hwdata*: pointer #TPrivate_hwdata; Hardware-specific surface info # clipping information: clip_rect*: TRect # Read-only unused1*: int32 # for binary compatibility # Allow recursive locks locked*: int32 # Private # info for fast blit mapping to other surfaces - Blitmap*: Pointer # PSDL_BlitMap; // Private + Blitmap*: pointer # PSDL_BlitMap; // Private # format version, bumped at every change to invalidate blit maps format_version*: cint # Private refcount*: cint @@ -1241,7 +1241,7 @@ type data*: ptr byte # B/W cursor data mask*: ptr byte # B/W cursor mask save*: array[1..2, ptr byte] # Place to save cursor area - wm_cursor*: Pointer # Window-manager cursor + wm_cursor*: pointer # Window-manager cursor type @@ -1268,7 +1268,7 @@ type # This is the system-independent thread info struc handle*: TSYS_ThreadHandle status*: int errbuf*: TError - data*: Pointer + data*: pointer PKeyStateArr* = ptr TKeyStateArr TKeyStateArr* = array[0..65000, byte] # Types required so we don't need to use Windows.pas @@ -1326,7 +1326,7 @@ proc WasInit*(flags: int32): int32{.cdecl, importc: "SDL_WasInit", proc Quit*(){.cdecl, importc: "SDL_Quit", dynlib: LibName.} when defined(WINDOWS): # This should be called from your WinMain() function, if any - proc RegisterApp*(name: cstring, style: int32, h_Inst: Pointer): int{.cdecl, + proc RegisterApp*(name: cstring, style: int32, h_Inst: pointer): int{.cdecl, importc: "SDL_RegisterApp", dynlib: LibName.} proc TableSize*(table: cstring): int #------------------------------------------------------------------------------ @@ -1347,17 +1347,17 @@ proc RWFromFile*(filename, mode: cstring): PRWops{.cdecl, importc: "SDL_RWFromFile", dynlib: LibName.} proc FreeRW*(area: PRWops){.cdecl, importc: "SDL_FreeRW", dynlib: LibName.} #fp is FILE *fp ??? -proc RWFromFP*(fp: Pointer, autoclose: int): PRWops{.cdecl, +proc RWFromFP*(fp: pointer, autoclose: int): PRWops{.cdecl, importc: "SDL_RWFromFP", dynlib: LibName.} -proc RWFromMem*(mem: Pointer, size: int): PRWops{.cdecl, +proc RWFromMem*(mem: pointer, size: int): PRWops{.cdecl, importc: "SDL_RWFromMem", dynlib: LibName.} -proc RWFromConstMem*(mem: Pointer, size: int): PRWops{.cdecl, +proc RWFromConstMem*(mem: pointer, size: int): PRWops{.cdecl, importc: "SDL_RWFromConstMem", dynlib: LibName.} proc AllocRW*(): PRWops{.cdecl, importc: "SDL_AllocRW", dynlib: LibName.} proc RWSeek*(context: PRWops, offset: int, whence: int): int proc RWTell*(context: PRWops): int -proc RWRead*(context: PRWops, theptr: Pointer, size: int, n: int): int -proc RWWrite*(context: PRWops, theptr: Pointer, size: int, n: int): int +proc RWRead*(context: PRWops, theptr: pointer, size: int, n: int): int +proc RWWrite*(context: PRWops, theptr: pointer, size: int, n: int): int proc RWClose*(context: PRWops): int #------------------------------------------------------------------------------ # time-handling @@ -1369,7 +1369,7 @@ proc GetTicks*(): int32{.cdecl, importc: "SDL_GetTicks", dynlib: LibName.} proc Delay*(msec: int32){.cdecl, importc: "SDL_Delay", dynlib: LibName.} # Add a new timer to the pool of timers already running. # Returns a timer ID, or NULL when an error occurs. -proc AddTimer*(interval: int32, callback: TNewTimerCallback, param: Pointer): PTimerID{. +proc AddTimer*(interval: int32, callback: TNewTimerCallback, param: pointer): PTimerID{. cdecl, importc: "SDL_AddTimer", dynlib: LibName.} # Remove one of the multiple timers knowing its ID. # Returns a boolean value indicating success. @@ -1387,7 +1387,7 @@ proc AudioInit*(driver_name: cstring): int{.cdecl, importc: "SDL_AudioInit", dynlib: LibName.} proc AudioQuit*(){.cdecl, importc: "SDL_AudioQuit", dynlib: LibName.} # This function fills the given character buffer with the name of the - # current audio driver, and returns a Pointer to it if the audio driver has + # current audio driver, and returns a pointer to it if the audio driver has # been initialized. It returns NULL if no driver has been initialized. proc AudioDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, importc: "SDL_AudioDriverName", dynlib: LibName.} @@ -1470,8 +1470,8 @@ proc FreeWAV*(audio_buf: ptr byte){.cdecl, importc: "SDL_FreeWAV", dynlib: LibNa # by SDL_ConvertAudio() to convert a buffer of audio data from one format # to the other. # This function returns 0, or -1 if there was an error. -proc BuildAudioCVT*(cvt: PAudioCVT, src_format: UInt16, src_channels: byte, - src_rate: int, dst_format: UInt16, dst_channels: byte, +proc BuildAudioCVT*(cvt: PAudioCVT, src_format: uint16, src_channels: byte, + src_rate: int, dst_format: uint16, dst_channels: byte, dst_rate: int): int{.cdecl, importc: "SDL_BuildAudioCVT", dynlib: LibName.} # Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT(), @@ -1937,12 +1937,12 @@ proc AllocSurface*(flags: int32, width, height, depth: int, proc CreateRGBSurface*(flags: int32, width, height, depth: int, RMask, GMask, BMask, AMask: int32): PSurface{.cdecl, importc: "SDL_CreateRGBSurface", dynlib: LibName.} -proc CreateRGBSurfaceFrom*(pixels: Pointer, width, height, depth, pitch: int, +proc CreateRGBSurfaceFrom*(pixels: pointer, width, height, depth, pitch: int, RMask, GMask, BMask, AMask: int32): PSurface{.cdecl, importc: "SDL_CreateRGBSurfaceFrom", dynlib: LibName.} proc FreeSurface*(surface: PSurface){.cdecl, importc: "SDL_FreeSurface", dynlib: LibName.} -proc MustLock*(Surface: PSurface): bool +proc MustLock*(surface: PSurface): bool # SDL_LockSurface() sets up a surface for directly accessing the pixels. # Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write # to and read from 'surface->pixels', using the pixel format stored in @@ -2178,7 +2178,7 @@ proc FreeYUVOverlay*(Overlay: POverlay){.cdecl, importc: "SDL_FreeYUVOverlay", proc GL_LoadLibrary*(filename: cstring): int{.cdecl, importc: "SDL_GL_LoadLibrary", dynlib: LibName.} # Get the address of a GL function (for extension functions) -proc GL_GetProcAddress*(procname: cstring): Pointer{.cdecl, +proc GL_GetProcAddress*(procname: cstring): pointer{.cdecl, importc: "SDL_GL_GetProcAddress", dynlib: LibName.} # Set an attribute of the OpenGL subsystem before intialization. proc GL_SetAttribute*(attr: TGLAttr, value: int): int{.cdecl, @@ -2255,7 +2255,7 @@ proc GetMouseState*(x: var int, y: var int): byte{.cdecl, proc GetRelativeMouseState*(x: var int, y: var int): byte{.cdecl, importc: "SDL_GetRelativeMouseState", dynlib: LibName.} # Set the position of the mouse cursor (generates a mouse motion event) -proc WarpMouse*(x, y: UInt16){.cdecl, importc: "SDL_WarpMouse", dynlib: LibName.} +proc WarpMouse*(x, y: uint16){.cdecl, importc: "SDL_WarpMouse", dynlib: LibName.} # Create a cursor using the specified data and mask (in MSB format). # The cursor width must be a multiple of 8 bits. # @@ -2402,7 +2402,7 @@ proc CondWaitTimeout*(cond: Pcond, mut: Pmutex, ms: int32): int{.cdecl, # Condition variable functions # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Create a thread -proc CreateThread*(fn, data: Pointer): PThread{.cdecl, +proc CreateThread*(fn, data: pointer): PThread{.cdecl, importc: "SDL_CreateThread", dynlib: LibName.} # Get the 32-bit thread identifier for the current thread proc ThreadID*(): int32{.cdecl, importc: "SDL_ThreadID", dynlib: LibName.} @@ -2435,16 +2435,16 @@ proc GetWMInfo*(info: PSysWMinfo): int{.cdecl, importc: "SDL_GetWMInfo", # * to the object handle (or NULL if there was an error). # * The 'sofile' parameter is a system dependent name of the object file. # * -proc LoadObject*(sofile: cstring): Pointer{.cdecl, importc: "SDL_LoadObject", +proc LoadObject*(sofile: cstring): pointer{.cdecl, importc: "SDL_LoadObject", dynlib: LibName.} #* Given an object handle, this function looks up the address of the # * named function in the shared object and returns it. This address # * is no longer valid after calling SDL_UnloadObject(). # * -proc LoadFunction*(handle: Pointer, name: cstring): Pointer{.cdecl, +proc LoadFunction*(handle: pointer, name: cstring): pointer{.cdecl, importc: "SDL_LoadFunction", dynlib: LibName.} #* Unload a shared object from memory * -proc UnloadObject*(handle: Pointer){.cdecl, importc: "SDL_UnloadObject", +proc UnloadObject*(handle: pointer){.cdecl, importc: "SDL_UnloadObject", dynlib: LibName.} #------------------------------------------------------------------------------ proc Swap32*(D: int32): int32 @@ -2455,32 +2455,32 @@ proc TurnBitOff*(value: int, bit: int8): int # implementation proc TABLESIZE(table: cstring): int = - Result = SizeOf(table) div SizeOf(table[0]) + result = sizeOf(table) div sizeOf(table[0]) proc OutOfMemory() = when not (defined(WINDOWS)): Error(ENOMEM) proc RWSeek(context: PRWops, offset: int, whence: int): int = - Result = context.seek(context, offset, whence) + result = context.seek(context, offset, whence) proc RWTell(context: PRWops): int = - Result = context.seek(context, 0, 1) + result = context.seek(context, 0, 1) -proc RWRead(context: PRWops, theptr: Pointer, size: int, n: int): int = - Result = context.read(context, theptr, size, n) +proc RWRead(context: PRWops, theptr: pointer, size: int, n: int): int = + result = context.read(context, theptr, size, n) -proc RWWrite(context: PRWops, theptr: Pointer, size: int, n: int): int = - Result = context.write(context, theptr, size, n) +proc RWWrite(context: PRWops, theptr: pointer, size: int, n: int): int = + result = context.write(context, theptr, size, n) proc RWClose(context: PRWops): int = - Result = context.closeFile(context) + result = context.closeFile(context) proc LoadWAV(filename: cstring, spec: PAudioSpec, audio_buf: ptr byte, audiolen: PUInt32): PAudioSpec = - Result = LoadWAV_RW(RWFromFile(filename, "rb"), 1, spec, audio_buf, audiolen) + result = LoadWAV_RW(RWFromFile(filename, "rb"), 1, spec, audio_buf, audiolen) proc CDInDrive(status: TCDStatus): bool = - Result = ord(status) > ord(CD_ERROR) + result = ord(status) > ord(CD_ERROR) proc FRAMES_TO_MSF(frames: int, M: var int, S: var int, F: var int) = var value: int @@ -2492,7 +2492,7 @@ proc FRAMES_TO_MSF(frames: int, M: var int, S: var int, F: var int) = M = value proc MSF_TO_FRAMES(M: int, S: int, F: int): int = - Result = M * 60 * CD_FPS + S * CD_FPS + F + result = M * 60 * CD_FPS + S * CD_FPS + F proc VERSION(X: var TVersion) = X.major = MAJOR_VERSION @@ -2500,43 +2500,43 @@ proc VERSION(X: var TVersion) = X.patch = PATCHLEVEL proc VERSIONNUM(X, Y, Z: int): int = - Result = X * 1000 + Y * 100 + Z + result = X * 1000 + Y * 100 + Z proc COMPILEDVERSION(): int = - Result = VERSIONNUM(MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL) + result = VERSIONNUM(MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL) proc VERSION_ATLEAST(X, Y, Z: int): bool = - Result = (COMPILEDVERSION() >= VERSIONNUM(X, Y, Z)) + result = (COMPILEDVERSION() >= VERSIONNUM(X, Y, Z)) proc LoadBMP(filename: cstring): PSurface = - Result = LoadBMP_RW(RWFromFile(filename, "rb"), 1) + result = LoadBMP_RW(RWFromFile(filename, "rb"), 1) proc SaveBMP(surface: PSurface, filename: cstring): int = - Result = SaveBMP_RW(surface, RWFromFile(filename, "wb"), 1) + result = SaveBMP_RW(surface, RWFromFile(filename, "wb"), 1) proc BlitSurface(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int = - Result = UpperBlit(src, srcrect, dst, dstrect) + result = UpperBlit(src, srcrect, dst, dstrect) proc AllocSurface(flags: int32, width, height, depth: int, RMask, GMask, BMask, AMask: int32): PSurface = - Result = CreateRGBSurface(flags, width, height, depth, RMask, GMask, BMask, + result = CreateRGBSurface(flags, width, height, depth, RMask, GMask, BMask, AMask) -proc MustLock(Surface: PSurface): bool = - Result = ((surface[].offset != 0) or - ((surface[].flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0)) +proc MustLock(surface: PSurface): bool = + result = ((surface.offset != 0) or + ((surface.flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0)) proc LockMutex(mutex: Pmutex): int = - Result = mutexP(mutex) + result = mutexP(mutex) proc UnlockMutex(mutex: Pmutex): int = - Result = mutexV(mutex) + result = mutexV(mutex) proc BUTTON(Button: int): int = - Result = PRESSED shl (Button - 1) + result = PRESSED shl (Button - 1) proc Swap32(D: int32): int32 = - Result = ((D shl 24) or ((D shl 8) and 0x00FF0000) or + result = ((D shl 24) or ((D shl 8) and 0x00FF0000) or ((D shr 8) and 0x0000FF00) or (D shr 24)) proc IsBitOn(value: int, bit: int8): bool = From 6e321f799aee6e9e9581714484fa3aa32626d727 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Mon, 1 Sep 2014 21:21:13 +0100 Subject: [PATCH 075/409] Fixes asynchttpserver. --- lib/pure/asynchttpserver.nim | 12 ++++++------ lib/pure/asyncnet.nim | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index e2e9e1881..70a865ed5 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -58,7 +58,7 @@ proc addHeaders(msg: var string, headers: PStringTable) = for k, v in headers: msg.add(k & ": " & v & "\c\L") -proc sendHeaders*(req: TRequest, headers: PStringTable): PFuture[void] = +proc sendHeaders*(req: TRequest, headers: PStringTable): Future[void] = ## Sends the specified headers to the requesting client. var msg = "" addHeaders(msg, headers) @@ -96,12 +96,12 @@ proc parseProtocol(protocol: string): tuple[orig: string, major, minor: int] = i.inc # Skip . i.inc protocol.parseInt(result.minor, i) -proc sendStatus(client: PAsyncSocket, status: string): PFuture[void] = +proc sendStatus(client: PAsyncSocket, status: string): Future[void] = client.send("HTTP/1.1 " & status & "\c\L") proc processClient(client: PAsyncSocket, address: string, callback: proc (request: TRequest): - PFuture[void] {.closure, gcsafe.}) {.async.} = + Future[void] {.closure, gcsafe.}) {.async.} = while true: # GET /path HTTP/1.1 # Header: val @@ -187,8 +187,8 @@ proc processClient(client: PAsyncSocket, address: string, request.client.close() break -proc serve*(server: PAsyncHttpServer, port: TPort, - callback: proc (request: TRequest): PFuture[void] {.closure,gcsafe.}, +proc serve*(server: PAsyncHttpServer, port: Port, + callback: proc (request: TRequest): Future[void] {.closure,gcsafe.}, address = "") {.async.} = ## Starts the process of listening for incoming HTTP connections on the ## specified address and port. @@ -220,6 +220,6 @@ when isMainModule: "Content-type": "text/plain; charset=utf-8"} await req.respond(Http200, "Hello World", headers.newStringTable()) - asyncCheck server.serve(TPort(5555), cb) + asyncCheck server.serve(Port(5555), cb) runForever() main() diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index f55442488..ea7432404 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -335,7 +335,7 @@ proc recvLine*(socket: PAsyncSocket, return add(result.string, c) -proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = +proc listen*(socket: PAsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. @@ -343,7 +343,7 @@ proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Raises an EOS error upon failure. if listen(socket.fd, backlog) < 0'i32: raiseOSError(osLastError()) -proc bindAddr*(socket: Socket, port = Port(0), address = "") {. +proc bindAddr*(socket: PAsyncSocket, port = Port(0), address = "") {. tags: [ReadIOEffect].} = ## Binds ``address``:``port`` to the socket. ## From 201a08e9a54cf129aca33d43d57cadd29e564149 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 3 Sep 2014 19:45:04 +0200 Subject: [PATCH 076/409] fixes #903, fixes #1513 --- compiler/commands.nim | 34 ++++++- compiler/main.nim | 6 -- compiler/nim.nim | 6 +- compiler/pretty.nim | 12 ++- compiler/service.nim | 30 +----- compiler/vmgen.nim | 25 +++-- lib/pure/asynchttpserver.nim | 2 +- tests/vm/tasmparser.nim | 174 +++++++++++++++++++++++++++++++++ tests/vm/tcompiletimetable.nim | 11 +-- todo.txt | 4 +- 10 files changed, 249 insertions(+), 55 deletions(-) create mode 100644 tests/vm/tasmparser.nim diff --git a/compiler/commands.nim b/compiler/commands.nim index 54d2ed6a4..2a2e0c4ee 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -26,7 +26,7 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none") import os, msgs, options, nversion, condsyms, strutils, extccomp, platform, lists, - wordrecg, parseutils, nimblecmd, idents + wordrecg, parseutils, nimblecmd, idents, parseopt # but some have deps to imported modules. Yay. bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc") @@ -43,7 +43,7 @@ type TCmdLinePass* = enum passCmd1, # first pass over the command line passCmd2, # second pass over the command line - passPP # preprocessor called ProcessCommand() + passPP # preprocessor called processCommand() proc processCommand*(switch: string, pass: TCmdLinePass) proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) @@ -573,3 +573,33 @@ proc processCommand(switch: string, pass: TCmdLinePass) = var cmd, arg: string splitSwitch(switch, cmd, arg, pass, gCmdLineInfo) processSwitch(cmd, arg, pass, gCmdLineInfo) + + +var + arguments* = "" + # the arguments to be passed to the program that + # should be run + +proc processSwitch*(pass: TCmdLinePass; p: OptParser) = + # hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off") + # we fix this here + var bracketLe = strutils.find(p.key, '[') + if bracketLe >= 0: + var key = substr(p.key, 0, bracketLe - 1) + var val = substr(p.key, bracketLe + 1) & ':' & p.val + processSwitch(key, val, pass, gCmdLineInfo) + else: + processSwitch(p.key, p.val, pass, gCmdLineInfo) + +proc processArgument*(pass: TCmdLinePass; p: OptParser; + argsCount: var int): bool = + if argsCount == 0: + options.command = p.key + else: + if pass == passCmd1: options.commandArgs.add p.key + if argsCount == 1: + # support UNIX style filenames anywhere for portable build scripts: + options.gProjectName = unixToNativePath(p.key) + arguments = cmdLineRest(p) + result = true + inc argsCount diff --git a/compiler/main.nim b/compiler/main.nim index 58833f60c..0bb057df5 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -164,12 +164,6 @@ proc commandEval(exp: string) = var echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")" evalNim(echoExp.parseString, makeStdinModule()) -proc commandPrettyOld = - var projectFile = addFileExt(mainCommandArg(), NimExt) - var module = parseFile(projectFile.fileInfoIdx) - if module != nil: - renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt)) - proc commandPretty = msgs.gErrorMax = high(int) # do not stop after first error semanticPasses() diff --git a/compiler/nim.nim b/compiler/nim.nim index 27222ca57..a87e0a1ac 100644 --- a/compiler/nim.nim +++ b/compiler/nim.nim @@ -58,7 +58,7 @@ proc handleCmdLine() = if msgs.gErrorCounter == 0: when hasTinyCBackend: if gCmd == cmdRun: - tccgen.run(service.arguments) + tccgen.run(commands.arguments) if optRun in gGlobalOptions: if gCmd == cmdCompileToJS: var ex: string @@ -67,7 +67,7 @@ proc handleCmdLine() = else: ex = quoteShell( completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir)) - execExternalProgram("node " & ex & ' ' & service.arguments) + execExternalProgram("node " & ex & ' ' & commands.arguments) else: var binPath: string if options.outFile.len > 0: @@ -77,7 +77,7 @@ proc handleCmdLine() = # Figure out ourselves a valid binary name. binPath = changeFileExt(gProjectFull, ExeExt).prependCurDir var ex = quoteShell(binPath) - execExternalProgram(ex & ' ' & service.arguments) + execExternalProgram(ex & ' ' & commands.arguments) when declared(GC_setMaxPause): GC_setMaxPause 2_000 diff --git a/compiler/pretty.nim b/compiler/pretty.nim index dfc164208..6ee931951 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -14,14 +14,20 @@ import strutils, os, options, ast, astalgo, msgs, ropes, idents, passes, intsets, strtabs, semdata, prettybase + +type + StyleCheck* {.pure.} = enum None, Confirm, Auto + +var + gOverWrite* = true + gStyleCheck*: StyleCheck + gCheckExtern*: bool + type TGen = object of TPassContext module*: PSym PGen = ref TGen -var - gCheckExtern: bool - proc overwriteFiles*() = let overWrite = options.getConfigVar("pretty.overwrite").normalize != "off" let doStrip = options.getConfigVar("pretty.strip").normalize == "on" diff --git a/compiler/service.nim b/compiler/service.nim index f0eeb0ed5..4a1b296cd 100644 --- a/compiler/service.nim +++ b/compiler/service.nim @@ -25,39 +25,17 @@ var lastCaasCmd* = "" # in caas mode, the list of defines and options will be given at start-up? # it's enough to check that the previous compilation command is the same? - arguments* = "" - # the arguments to be passed to the program that - # should be run proc processCmdLine*(pass: TCmdLinePass, cmd: string) = var p = parseopt.initOptParser(cmd) var argsCount = 0 - while true: + while true: parseopt.next(p) case p.kind - of cmdEnd: break - of cmdLongoption, cmdShortOption: - # hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off") - # we fix this here - var bracketLe = strutils.find(p.key, '[') - if bracketLe >= 0: - var key = substr(p.key, 0, bracketLe - 1) - var val = substr(p.key, bracketLe + 1) & ':' & p.val - processSwitch(key, val, pass, gCmdLineInfo) - else: - processSwitch(p.key, p.val, pass, gCmdLineInfo) + of cmdEnd: break + of cmdLongoption, cmdShortOption: processSwitch(pass, p) of cmdArgument: - if argsCount == 0: - options.command = p.key - else: - if pass == passCmd1: options.commandArgs.add p.key - if argsCount == 1: - # support UNIX style filenames anywhere for portable build scripts: - options.gProjectName = unixToNativePath(p.key) - arguments = cmdLineRest(p) - break - inc argsCount - + if processArgument(pass, p, argsCount): break if pass == passCmd2: if optRun notin gGlobalOptions and arguments != "" and options.command.normalize != "run": rawMessage(errArgsNeedRunOption, []) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 05c894ee3..718c07243 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -43,18 +43,19 @@ type proc debugInfo(info: TLineInfo): string = result = info.toFilename.splitFile.name & ":" & $info.line -proc codeListing(c: PCtx, result: var string, start=0) = +proc codeListing(c: PCtx, result: var string, start=0; last = -1) = # first iteration: compute all necessary labels: var jumpTargets = initIntSet() - - for i in start.. < c.code.len: + + let last = if last < 0: c.code.len-1 else: min(last, c.code.len-1) + for i in start..last: let x = c.code[i] if x.opcode in relativeJumps: jumpTargets.incl(i+x.regBx-wordExcess) # for debugging purposes var i = start - while i < c.code.len: + while i <= last: if i in jumpTargets: result.addf("L$1:\n", i) let x = c.code[i] @@ -82,9 +83,9 @@ proc codeListing(c: PCtx, result: var string, start=0) = result.add("\n") inc i -proc echoCode*(c: PCtx, start=0) {.deprecated.} = +proc echoCode*(c: PCtx; start=0; last = -1) {.deprecated.} = var buf = "" - codeListing(c, buf, start) + codeListing(c, buf, start, last) echo buf proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) = @@ -495,6 +496,7 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) = c.freeTempRange(x, n.len) template isGlobal(s: PSym): bool = sfGlobal in s.flags and s.kind != skForVar +proc isGlobal(n: PNode): bool = n.kind == nkSym and isGlobal(n.sym) proc needsAsgnPatch(n: PNode): bool = n.kind in {nkBracketExpr, nkDotExpr, nkCheckedFieldExpr, @@ -637,8 +639,10 @@ proc genBinaryStmt(c: PCtx; n: PNode; opc: TOpcode) = c.freeTemp(tmp) proc genBinaryStmtVar(c: PCtx; n: PNode; opc: TOpcode) = + var x = n.sons[1] + if x.kind in {nkAddr, nkHiddenAddr}: x = x.sons[0] let - dest = c.genx(n.sons[1], {gfAddrOf}) + dest = c.genx(x) tmp = c.genx(n.sons[2]) c.gABC(n, opc, dest, tmp, 0) #c.genAsgnPatch(n.sons[1], dest) @@ -1053,6 +1057,8 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; # nkAddr we must not use 'unneededIndirection', but for deref we use it. if not isAddr and unneededIndirection(n.sons[0]): gen(c, n.sons[0], dest, newflags) + elif isGlobal(n.sons[0]): + gen(c, n.sons[0], dest, flags+{gfAddrOf}) else: let tmp = c.genx(n.sons[0], newflags) if dest < 0: dest = c.getTemp(n.typ) @@ -1062,6 +1068,9 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; c.gABC(n, opcNodeToReg, dest, dest) elif c.prc.slots[tmp].kind >= slotTempUnknown: gABC(c, n, opcAddrNode, dest, tmp) + # XXX this can still be wrong sometimes; hopefully it's only generated + # in call contexts, where it is safe + #message(n.info, warnUser, "suspicious opcode used") else: gABC(c, n, opcAddrReg, dest, tmp) c.freeTemp(tmp) @@ -1247,6 +1256,8 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) = c.gABx(n, opcLdGlobal, cc, s.position) c.gABC(n, opcNodeToReg, dest, cc) c.freeTemp(cc) + elif gfAddrOf in flags: + c.gABx(n, opcLdGlobalAddr, dest, s.position) else: c.gABx(n, opcLdGlobal, dest, s.position) else: diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index e2e9e1881..c2cb7e15c 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -187,7 +187,7 @@ proc processClient(client: PAsyncSocket, address: string, request.client.close() break -proc serve*(server: PAsyncHttpServer, port: TPort, +proc serve*(server: PAsyncHttpServer, port: Port, callback: proc (request: TRequest): PFuture[void] {.closure,gcsafe.}, address = "") {.async.} = ## Starts the process of listening for incoming HTTP connections on the diff --git a/tests/vm/tasmparser.nim b/tests/vm/tasmparser.nim new file mode 100644 index 000000000..24ccb2ec8 --- /dev/null +++ b/tests/vm/tasmparser.nim @@ -0,0 +1,174 @@ + +# bug #1513 + +import os, parseutils, strutils, ropes, macros + +var + code {.compileTime.} = "" + start {.compileTime.} = 0 + line {.compileTime.} = 1 + cpp {.compileTime.} = "" + token {.compileTime.} = "" + +proc log (msg: string) {.compileTime.} = + echo msg + +proc asmx64 () {.compileTime} = + + #log "code = $1" % code + + const asmx64pre = "{.emit: \"\"\"{x64asm& x= *x64asm_ptr(`asm0`); try {" + const asmx64post = "} catch (Xbyak::Error e) { printf (\"asmx64 error: %s\\n\", e.what ()); }}\"\"\".} " + + const xp = "x." + + const symbolStart = { '_', 'a'..'z', 'A' .. 'Z' } + const symbol = { '0'..'9' } + symbolStart + const eolComment = { ';' } + const endOfLine = { '\l', '\r' } + const leadingWhiteSpace = { ' ' } + + const end_or_comment = endOfLine + eolComment + { '\0' } + + const passthrough_start = { '{', '`' } + const passthrough_end = { '}', '`', '\0' } + + const end_or_symbol_or_comment_or_passthrough = symbolStart + end_or_comment + passthrough_start + + + proc abortAsmParse (err:string) = + # + + let codeLen = code.len + #let codeEnd = codeLen-1 + cpp.add asmx64pre + + #log "{$1}\n" % [code] + + type asmParseState = enum leading, mnemonic, betweenArguments, arguments, endCmd, skipToEndOfLine + + var state:asmParseState = leading + + proc checkEnd (err:string) = + let ch = code [start] + if int (ch) == 0: + abortAsmParse (err) + + proc get_passthrough () = + inc start + let prev_start = start + let prev_token = token + start += code.parseUntil (token, passthrough_end, start) + checkEnd ("Failed to find passthrough end delimiter from offset $1 for:$2\n$3" % [$prev_start, $(code [prev_start-prev_token.len..prev_start]), token[1..token.len-1]]) + inc start + cpp.add "`" + cpp.add token + cpp.add "`" + + var inparse = true + + proc checkCmdEnd () = + if codeLen == start: + state = endCmd + inparse = false + + while inparse: + checkCmdEnd () + + log ("state=$1 start=$2" % [$state, $start]) + + case state: + of leading: + + echo "b100 ", start + start += code.skipWhile (leadingWhiteSpace, start) + echo "b200 ", start + let ch = code [start] + if ch in endOfLine: + inc (line) + #echo "c100 ", start, ' ', code + start += code.skipWhile (endOfline, start) + #echo "c200 ", start, ' ', code + continue + elif ch in symbolStart: + state = mnemonic + elif ch in eolComment: + state = skipToEndOfLine + elif ch in passthrough_start: + get_passthrough () + echo "d100 ", start + start += code.parseUntil (token, end_or_symbol_or_comment_or_passthrough, start) + echo "d200 ", start + cpp.add token + state = mnemonic + elif int (ch) == 0: + break + else: + abortAsmParse ("after '$3' illegal character at offset $1: $2" % [$start, $(int (ch)), token]) + + of mnemonic: + echo "e100 ", start + start += code.parseWhile (token, symbol, start) + echo "e200 ", start + cpp.add xp + cpp.add token + cpp.add "(" + state = betweenArguments + + of betweenArguments: + let tmp = start + let rcode = code + start += rcode.parseUntil (token, end_or_symbol_or_comment_or_passthrough, tmp) + cpp.add token + + if codeLen <= start: + state = endCmd + continue + + let ch = code [start] + if ch in passthrough_start: + get_passthrough () + continue + if (ch in {'x', 'X'}) and ('0' == code [start-1]): + token = $(code [start]) + cpp.add token + inc start + continue + state = arguments + + of arguments: + if code [start] in end_or_comment: + state = endCmd + continue + start += code.parseWhile (token, symbol, start) + cpp.add xp + cpp.add token + state = betweenArguments + + of endCmd: + cpp.add ");\n" + state = skipToEndOfLine + + of skipToEndOfLine: + echo "a100 ", start + start += code.skipUntil (endOfLine, start) + echo "a200 ", start + start += code.skipWhile (endOfline, start) + echo "a300 ", start + inc line + state = leading + + cpp.add asmx64post + + echo ($cpp) + +macro asmx64x (code_in:expr) : stmt = + code = $code_in + echo ("code.len = $1, code = >>>$2<<<" % [$code.len, code]) + asmx64 () + discard result + +asmx64x """ + mov rax, {m} + ret +""" diff --git a/tests/vm/tcompiletimetable.nim b/tests/vm/tcompiletimetable.nim index f1d3ecd4e..df6ead56f 100644 --- a/tests/vm/tcompiletimetable.nim +++ b/tests/vm/tcompiletimetable.nim @@ -2,18 +2,19 @@ discard """ msg: '''2 3 4:2 - ''' +Got Hi +Got Hey''' """ # bug #404 -import macros, tables +import macros, tables, strtabs var ZOOT{.compileTime.} = initTable[int, int](2) var iii {.compiletime.} = 1 macro zoo:stmt= - zoot[iii] = iii*2 + ZOOT[iii] = iii*2 inc iii echo iii @@ -29,9 +30,7 @@ tupleUnpack # bug #903 -import strtabs - -var x {.compileTime.}: PStringTable +var x {.compileTime.}: StringTableRef macro addStuff(stuff, body: expr): stmt {.immediate.} = result = newNimNode(nnkStmtList) diff --git a/todo.txt b/todo.txt index 319704925..acdec7547 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,9 @@ version 0.10 ============ -- Test nim pretty on various babel packages +- Write new nimfix tool +- Test nimfix on various babel packages +- Pegs do not work at compile-time version 0.9.6 From e093f45756e847f097d06511d91d76f549ee6644 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 3 Sep 2014 19:54:20 +0200 Subject: [PATCH 077/409] fixes #1511 --- compiler/semstmts.nim | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 89acb2e98..28d062392 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -22,21 +22,24 @@ proc semDiscard(c: PContext, n: PNode): PNode = proc semBreakOrContinue(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1) - if n.sons[0].kind != nkEmpty: - var s: PSym - case n.sons[0].kind - of nkIdent: s = lookUp(c, n.sons[0]) - of nkSym: s = n.sons[0].sym - else: illFormedAst(n) - if s.kind == skLabel and s.owner.id == c.p.owner.id: - var x = newSymNode(s) - x.info = n.info - incl(s.flags, sfUsed) - n.sons[0] = x - suggestSym(x.info, s) + if n.sons[0].kind != nkEmpty: + if n.kind != nkContinueStmt: + var s: PSym + case n.sons[0].kind + of nkIdent: s = lookUp(c, n.sons[0]) + of nkSym: s = n.sons[0].sym + else: illFormedAst(n) + if s.kind == skLabel and s.owner.id == c.p.owner.id: + var x = newSymNode(s) + x.info = n.info + incl(s.flags, sfUsed) + n.sons[0] = x + suggestSym(x.info, s) + else: + localError(n.info, errInvalidControlFlowX, s.name.s) else: - localError(n.info, errInvalidControlFlowX, s.name.s) - elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0): + localError(n.info, errGenerated, "'continue' cannot have a label") + elif (c.p.nestedLoopCounter <= 0) and (c.p.nestedBlockCounter <= 0): localError(n.info, errInvalidControlFlowX, renderTree(n, {renderNoComments})) From 4c870fc29374b89b1b61f0437c69166b7c400dfe Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 3 Sep 2014 22:00:23 +0200 Subject: [PATCH 078/409] fixes recently introduced regression --- compiler/vmgen.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 718c07243..d7af7c2e2 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1057,7 +1057,7 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; # nkAddr we must not use 'unneededIndirection', but for deref we use it. if not isAddr and unneededIndirection(n.sons[0]): gen(c, n.sons[0], dest, newflags) - elif isGlobal(n.sons[0]): + elif isAddr and isGlobal(n.sons[0]): gen(c, n.sons[0], dest, flags+{gfAddrOf}) else: let tmp = c.genx(n.sons[0], newflags) @@ -1137,6 +1137,9 @@ proc isTemp(c: PCtx; dest: TDest): bool = template needsAdditionalCopy(n): expr = not c.isTemp(dest) and not fitsRegister(n.typ) +proc skipDeref(n: PNode): PNode = + result = if n.kind in {nkDerefExpr, nkHiddenDeref}: n.sons[0] else n + proc preventFalseAlias(c: PCtx; n: PNode; opc: TOpcode; dest, idx, value: TRegister) = # opcLdObj et al really means "load address". We sometimes have to create a From 9a3963f51b6e5ed25befa766270b1bbf5155e090 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Thu, 4 Sep 2014 23:50:00 +0300 Subject: [PATCH 079/409] fix #959 Variable declarations using a type class will be subject to type inference similar to the one already present in type coercions and the return type inference. --- compiler/semstmts.nim | 11 ++++++++--- doc/manual.txt | 11 ++++++++--- tests/metatype/typeclassinference.nim | 11 +++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 28d062392..93a1994a7 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -350,9 +350,14 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var def: PNode if a.sons[length-1].kind != nkEmpty: def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) - # BUGFIX: ``fitNode`` is needed here! - # check type compability between def.typ and typ: - if typ != nil: def = fitNode(c, typ, def) + if typ != nil: + if typ.isMetaType: + def = inferWithMetaType(c, typ, def) + typ = def.typ + else: + # BUGFIX: ``fitNode`` is needed here! + # check type compability between def.typ and typ + def = fitNode(c, typ, def) else: typ = skipIntLit(def.typ) if typ.kind in {tySequence, tyArray, tySet} and diff --git a/doc/manual.txt b/doc/manual.txt index 10fe78336..144a3b2c0 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -3671,8 +3671,8 @@ once for each tested type and any static code included within them will also be executed once. -Return Type Inference ---------------------- +Type inference with type classes +-------------------------------- If a type class is used as the return type of a proc and it won't be bound to a concrete type by some of the proc params, Nim will infer the return type @@ -3681,13 +3681,18 @@ from the proc body. This is usually used with the ``auto`` type class: .. code-block:: nim proc makePair(a, b): auto = (first: a, second: b) -The return type will be treated as additional generic param and can be +The return type will be treated as an additional generic param and can be explicitly specified at call sites as any other generic param. Future versions of Nim may also support overloading based on the return type of the overloads. In such settings, the expected result type at call sites may also influence the inferred return type. +Likewise, if a type class is used in another position where Nim expects a +concrete type (e.g. a variable declaration or a type coercion), Nim will try to +infer the concrete type by applying the sane matching algorithm also used in +overload resolution. + Symbol lookup in generics ------------------------- diff --git a/tests/metatype/typeclassinference.nim b/tests/metatype/typeclassinference.nim index 72b5aca96..2ac037ac5 100644 --- a/tests/metatype/typeclassinference.nim +++ b/tests/metatype/typeclassinference.nim @@ -1,3 +1,8 @@ +discard """ + errormsg: "type mismatch: got (string) but expected 'ptr'" + line: 20 +""" + import typetraits type @@ -8,3 +13,9 @@ var x = Vec([1, 2, 3]) static: assert x.type.name == "Vec[static[int](3), int]" +var str1: string = "hello, world!" +var ptr1: ptr = addr(str1) + +var str2: string = "hello, world!" +var ptr2: ptr = str2 + From 7d5e387a488200113664a3ffa60e5c63ec32c54b Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Fri, 5 Sep 2014 01:02:46 +0300 Subject: [PATCH 080/409] mostly fixes #1339 The compiler hangs were caused by the interaction of tyError and the instantiation caches. For procs, the cache wasn't able to find previously compiled proc featuring tyError in the signature. For types, the unresolved type parameters leading to tyError were not replaced everywhere leading to endless replaceTypeVarsT recursion for cyclic types. The fix is still not perfect, because the handling of tyError in other places in the compiler doesn't seem to be complete and the first test case now results in internal error (still, much better than a hang blocking your IDE). --- compiler/semtypinst.nim | 8 ++++++-- compiler/types.nim | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 9484bbe90..4563dc8d4 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -216,12 +216,16 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = result.typ = replaceTypeVarsT(cl, s.typ) result.ast = replaceTypeVarsN(cl, s.ast) -proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType = +proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType = result = PType(idTableGet(cl.typeMap, t)) if result == nil: if cl.allowMetaTypes or tfRetType in t.flags: return localError(t.sym.info, errCannotInstantiateX, typeToString(t)) result = errorType(cl.c) + # In order to prevent endless recursions, we must remember + # this bad lookup and replace it with errorType everywhere. + # These code paths are only active in nimrod check + idTablePut(cl.typeMap, t, result) elif result.kind == tyGenericParam and not cl.allowMetaTypes: internalError(cl.info, "substitution with generic parameter") @@ -353,7 +357,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = of tyGenericBody: localError(cl.info, errCannotInstantiateX, typeToString(t)) - result = t + result = errorType(cl.c) #result = replaceTypeVarsT(cl, lastSon(t)) of tyFromExpr: diff --git a/compiler/types.nim b/compiler/types.nim index adc03a13e..7b59fbf20 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -913,9 +913,11 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = result = sameTypeAux(a.sons[0], b.sons[0], c) else: result = sameTypeAux(a.sons[0], b.sons[0], c) and sameFlags(a, b) - of tyEnum, tyForward, tyProxy: + of tyEnum, tyForward: # XXX generic enums do not make much sense, but require structural checking result = a.id == b.id and sameFlags(a, b) + of tyError: + result = b.kind == tyError of tyTuple: cycleCheck() result = sameTuple(a, b, c) and sameFlags(a, b) From bf557a7cdb8f31aabca17d5b147a90ec155eaf23 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 5 Sep 2014 01:16:48 +0200 Subject: [PATCH 081/409] added nimfix tool --- compiler/cgen.nim | 6 +-- compiler/lookups.nim | 27 +++++++++++- compiler/nim.nimrod.cfg | 1 + compiler/nimfix.nim | 97 +++++++++++++++++++++++++++++++++++++++++ compiler/nimfix.nim.cfg | 16 +++++++ compiler/prettybase.nim | 11 +++-- compiler/sigmatch.nim | 3 ++ compiler/vmgen.nim | 2 +- config/nim.cfg | 4 +- 9 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 compiler/nimfix.nim create mode 100644 compiler/nimfix.nim.cfg diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 7c694f245..490aeec4b 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -139,7 +139,7 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope = if i - 1 >= start: app(result, substr(frmt, start, i - 1)) -const compileTimeRopeFmt = not defined(booting) +const compileTimeRopeFmt = false when compileTimeRopeFmt: import macros @@ -186,7 +186,7 @@ when compileTimeRopeFmt: while s[i] in IdentChars: inc i yield (kind: ffSym, value: substr(s, j, i-1), intValue: 0) start = i - else: nil + else: discard while i < length: if s[i] != '$' and s[i] != '#': inc i @@ -201,7 +201,7 @@ when compileTimeRopeFmt: ## the compilation of nimrod itself or will the macro execution time ## offset the gains? result = newCall(bindSym"ropeConcat") - for frag in fmtStringFragments(fmt.strVal): + for frag in fmtStringFragments(fmt): case frag.kind of ffSym: result.add(newCall(bindSym"cgsym", m, newStrLitNode(frag.value))) diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 9bad9de91..466ac824a 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -171,7 +171,7 @@ proc addOverloadableSymAt*(scope: PScope, fn: PSym) = if fn.kind notin OverloadableSyms: internalError(fn.info, "addOverloadableSymAt") return - var check = strTableGet(scope.symbols, fn.name) + let check = strTableGet(scope.symbols, fn.name) if check != nil and check.kind notin OverloadableSyms: wrongRedefinition(fn.info, fn.name.s) else: @@ -187,12 +187,32 @@ proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) = addOverloadableSymAt(scope, sym) addInterfaceDeclAux(c, sym) +when defined(nimfix): + import strutils + + # when we cannot find the identifier, retry with a changed identifer: + proc altSpelling(x: PIdent): PIdent = + case x.s[0] + of 'A'..'Z': result = getIdent(toLower(x.s[0]) & x.s.substr(1)) + of 'a'..'z': result = getIdent(toLower(x.s[0]) & x.s.substr(1)) + else: result = x + + template fixSpelling(n: PNode; ident: PIdent; op: expr) = + let alt = ident.altSpelling + result = op(c, alt).skipAlias(n) + if result != nil: + prettybase.replaceDeprecated(n.info, ident, alt) + return result +else: + template fixSpelling(n: PNode; ident: PIdent; op: expr) = discard + proc lookUp*(c: PContext, n: PNode): PSym = # Looks up a symbol. Generates an error in case of nil. case n.kind of nkIdent: result = searchInScopes(c, n.ident).skipAlias(n) if result == nil: + fixSpelling(n, n.ident, searchInScopes) localError(n.info, errUndeclaredIdentifier, n.ident.s) result = errorSym(c, n) of nkSym: @@ -201,6 +221,7 @@ proc lookUp*(c: PContext, n: PNode): PSym = var ident = considerQuotedIdent(n) result = searchInScopes(c, ident).skipAlias(n) if result == nil: + fixSpelling(n, ident, searchInScopes) localError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) else: @@ -214,12 +235,13 @@ type TLookupFlag* = enum checkAmbiguity, checkUndeclared -proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = +proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = case n.kind of nkIdent, nkAccQuoted: var ident = considerQuotedIdent(n) result = searchInScopes(c, ident).skipAlias(n) if result == nil and checkUndeclared in flags: + fixSpelling(n, ident, searchInScopes) localError(n.info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n) elif checkAmbiguity in flags and result != nil and @@ -244,6 +266,7 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = else: result = strTableGet(m.tab, ident).skipAlias(n) if result == nil and checkUndeclared in flags: + fixSpelling(n.sons[1], ident, searchInScopes) localError(n.sons[1].info, errUndeclaredIdentifier, ident.s) result = errorSym(c, n.sons[1]) elif n.sons[1].kind == nkSym: diff --git a/compiler/nim.nimrod.cfg b/compiler/nim.nimrod.cfg index c9e4b248b..5a892bad0 100644 --- a/compiler/nim.nimrod.cfg +++ b/compiler/nim.nimrod.cfg @@ -21,3 +21,4 @@ define:useStdoutAsStdmsg cs:partial #define:useNodeIds +symbol:nimfix diff --git a/compiler/nimfix.nim b/compiler/nimfix.nim new file mode 100644 index 000000000..3fbf27e54 --- /dev/null +++ b/compiler/nimfix.nim @@ -0,0 +1,97 @@ +# +# +# The Nim Compiler +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Nimfix is a tool that helps to convert old-style Nimrod code to Nim code. + +import strutils, os, parseopt +import options, commands, modules, sem, passes, passaux, pretty, msgs, nimconf, + extccomp, condsyms + +const Usage = """ +Nimfix - Tool to patch Nim code +Usage: + nimfix [options] projectflie.nim + +Options: + --overwriteFiles:on|off overwrite the original nim files. + DEFAULT is ON! + --checkExtern:on|off style check also extern names + --styleCheck:none|confirm|auto performs style checking for identifiers + and suggests an alternative spelling. If + 'auto', it automatically corrects the + spelling. If 'confirm' it asks the user. + +In addition, all command line options of Nim are supported. +""" + +proc mainCommand = + #msgs.gErrorMax = high(int) # do not stop after first error + registerPass verbosePass + registerPass semPass + registerPass prettyPass + gCmd = cmdPretty + compileProject() + pretty.overwriteFiles() + +proc processCmdLine*(pass: TCmdLinePass, cmd: string) = + var p = parseopt.initOptParser(cmd) + var argsCount = 0 + while true: + parseopt.next(p) + case p.kind + of cmdEnd: break + of cmdLongoption, cmdShortOption: + case p.key.normalize + of "overwritefiles": + case p.val.normalize + of "on": gOverWrite = true + of "off": gOverWrite = false + else: localError(gCmdLineInfo, errOnOrOffExpected) + of "checkextern": + case p.val.normalize + of "on": gCheckExtern = true + of "off": gCheckExtern = false + else: localError(gCmdLineInfo, errOnOrOffExpected) + of "stylecheck": + case p.val.normalize + of "none": gStyleCheck = StyleCheck.None + of "confirm": gStyleCheck = StyleCheck.Confirm + of "auto": gStyleCheck = StyleCheck.Auto + else: localError(gCmdLineInfo, errGenerated, + "'none', 'confirm' or 'auto' expected") + else: + processSwitch(pass, p) + of cmdArgument: + if processArgument(pass, p, argsCount): break + +proc handleCmdLine() = + if paramCount() == 0: + stdout.writeln(Usage) + else: + processCmdLine(passCmd1, "") + if gProjectName != "": + try: + gProjectFull = canonicalizePath(gProjectName) + except OSError: + gProjectFull = gProjectName + var p = splitFile(gProjectFull) + gProjectPath = p.dir + gProjectName = p.name + else: + gProjectPath = getCurrentDir() + loadConfigs(DefaultConfig) # load all config files + # now process command line arguments again, because some options in the + # command line can overwite the config file's settings + extccomp.initVars() + processCmdLine(passCmd2, "") + mainCommand() + +condsyms.initDefines() +defineSymbol "nimfix" +handleCmdline() diff --git a/compiler/nimfix.nim.cfg b/compiler/nimfix.nim.cfg new file mode 100644 index 000000000..61df6742e --- /dev/null +++ b/compiler/nimfix.nim.cfg @@ -0,0 +1,16 @@ +# Special configuration file for the Nim project +# gc:markAndSweep + +hint[XDeclaredButNotUsed]:off +path:"$projectPath/.." + +path:"$lib/packages/docutils" + +define:useStdoutAsStdmsg +symbol:nimfix +define:nimfix + +cs:partial +#define:useNodeIds +define:booting +define:noDocgen diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim index baf2484e4..dca6bcdaa 100644 --- a/compiler/prettybase.nim +++ b/compiler/prettybase.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -import ast, msgs, strutils +import ast, msgs, strutils, idents type TSourceFile* = object @@ -41,7 +41,7 @@ proc differ*(line: string, a, b: int, x: string): bool = let y = line[a..b] result = cmpIgnoreStyle(y, x) == 0 and y != x -proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = +proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) = loadFile(info) let line = gSourceFiles[info.fileIndex].lines[info.line-1] @@ -53,7 +53,10 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = if line[first] == '`': inc first let last = first+identLen(line, first)-1 - if cmpIgnoreStyle(line[first..last], oldSym.name.s) == 0: - var x = line.substr(0, first-1) & newSym.name.s & line.substr(last+1) + if cmpIgnoreStyle(line[first..last], oldSym.s) == 0: + var x = line.substr(0, first-1) & newSym.s & line.substr(last+1) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true + +proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = + replaceDeprecated(info, oldSym.name, newSym.name) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 26277eb50..d7b397af6 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1482,6 +1482,9 @@ proc argtypeMatches*(c: PContext, f, a: PType): bool = include suggest +when not declared(tests): + template tests(s: stmt) {.immediate.} = discard + tests: var dummyOwner = newSym(skModule, getIdent("test_module"), nil, UnknownLineInfo()) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index d7af7c2e2..3921a69fe 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1138,7 +1138,7 @@ template needsAdditionalCopy(n): expr = not c.isTemp(dest) and not fitsRegister(n.typ) proc skipDeref(n: PNode): PNode = - result = if n.kind in {nkDerefExpr, nkHiddenDeref}: n.sons[0] else n + result = if n.kind in {nkDerefExpr, nkHiddenDeref}: n.sons[0] else: n proc preventFalseAlias(c: PCtx; n: PNode; opc: TOpcode; dest, idx, value: TRegister) = diff --git a/config/nim.cfg b/config/nim.cfg index 6d56bba2c..b0a1ff81b 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -13,7 +13,9 @@ cc = gcc arm.linux.gcc.exe = "arm-linux-gcc" arm.linux.gcc.linkerexe = "arm-linux-gcc" -cs:partial +@if not nimfix: + cs:partial +@end path="$lib/core" path="$lib/pure" From 33e924a35c4a748b649e02584c149eceafa4ac0e Mon Sep 17 00:00:00 2001 From: Philip Witte Date: Thu, 4 Sep 2014 21:38:45 -0700 Subject: [PATCH 082/409] fixed poxix dynlib names for bigbreak --- lib/pure/dynlib.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim index 617fbc66f..c6794be67 100644 --- a/lib/pure/dynlib.nim +++ b/lib/pure/dynlib.nim @@ -57,19 +57,19 @@ when defined(posix): RTLD_NOW {.importc: "RTLD_NOW", header: "".}: int RTLD_GLOBAL {.importc: "RTLD_GLOBAL", header: "".}: int - proc dlclose(lib: TLibHandle) {.importc, header: "".} - proc dlopen(path: CString, mode: int): TLibHandle {. + proc dlclose(lib: LibHandle) {.importc, header: "".} + proc dlopen(path: cstring, mode: int): LibHandle {. importc, header: "".} - proc dlsym(lib: TLibHandle, name: cstring): pointer {. + proc dlsym(lib: LibHandle, name: cstring): pointer {. importc, header: "".} - proc loadLib(path: string, global_symbols=false): TLibHandle = + proc loadLib(path: string, global_symbols=false): LibHandle = var flags = RTLD_NOW if global_symbols: flags = flags or RTLD_GLOBAL return dlopen(path, flags) - proc loadLib(): TLibHandle = return dlopen(nil, RTLD_NOW) - proc unloadLib(lib: TLibHandle) = dlclose(lib) - proc symAddr(lib: TLibHandle, name: cstring): pointer = + proc loadLib(): LibHandle = return dlopen(nil, RTLD_NOW) + proc unloadLib(lib: LibHandle) = dlclose(lib) + proc symAddr(lib: LibHandle, name: cstring): pointer = return dlsym(lib, name) elif defined(windows) or defined(dos): From 0f3025e320f5d7dc960d6464b8b32b5bc4e1c9dd Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 5 Sep 2014 17:36:16 +0100 Subject: [PATCH 083/409] Added Windows asyncfile implementation. --- lib/pure/asyncdispatch.nim | 17 ++++++++--------- lib/windows/winlean.nim | 24 ++++++++++++++++-------- tests/async/tasyncfile.nim | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 tests/async/tasyncfile.nim diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 14b56d1ed..e5402f0d5 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -226,8 +226,8 @@ when defined(windows) or defined(nimdoc): TCompletionKey = Dword TCompletionData* = object - sock: TAsyncFD - cb: proc (sock: TAsyncFD, bytesTransferred: Dword, + sock*: TAsyncFD # TODO: Rename this. + cb*: proc (sock: TAsyncFD, bytesTransferred: Dword, errcode: OSErrorCode) {.closure,gcsafe.} PDispatcher* = ref object of PDispatcherBase @@ -237,7 +237,7 @@ when defined(windows) or defined(nimdoc): TCustomOverlapped = object of TOVERLAPPED data*: TCompletionData - PCustomOverlapped = ref TCustomOverlapped + PCustomOverlapped* = ref TCustomOverlapped TAsyncFD* = distinct int @@ -247,7 +247,7 @@ when defined(windows) or defined(nimdoc): proc newDispatcher*(): PDispatcher = ## Creates a new Dispatcher instance. new result - result.ioPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1) + result.ioPort = createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1) result.handles = initSet[TAsyncFD]() result.timers = @[] @@ -260,7 +260,7 @@ when defined(windows) or defined(nimdoc): proc register*(sock: TAsyncFD) = ## Registers ``sock`` with the dispatcher. let p = getGlobalDispatcher() - if CreateIoCompletionPort(sock.THandle, p.ioPort, + if createIoCompletionPort(sock.THandle, p.ioPort, cast[TCompletionKey](sock), 1) == 0: raiseOSError(osLastError()) p.handles.incl(sock) @@ -286,7 +286,7 @@ when defined(windows) or defined(nimdoc): var lpNumberOfBytesTransferred: Dword var lpCompletionKey: ULONG var customOverlapped: PCustomOverlapped - let res = GetQueuedCompletionStatus(p.ioPort, + let res = getQueuedCompletionStatus(p.ioPort, addr lpNumberOfBytesTransferred, addr lpCompletionKey, cast[ptr POVERLAPPED](addr customOverlapped), llTimeout).bool @@ -1231,10 +1231,9 @@ proc runForever*() = while true: poll() -proc waitFor*[T](fut: PFuture[T]) = +proc waitFor*[T](fut: PFuture[T]): T = ## **Blocks** the current thread until the specified future completes. while not fut.finished: poll() - if fut.failed: - raise fut.error + fut.read diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index ecf80fcd8..014215066 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -104,11 +104,11 @@ proc closeHandle*(hObject: THandle): WINBOOL {.stdcall, dynlib: "kernel32", importc: "CloseHandle".} proc readFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: int32, - lpNumberOfBytesRead: var int32, lpOverlapped: pointer): WINBOOL{. + lpNumberOfBytesRead: ptr int32, lpOverlapped: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "ReadFile".} proc writeFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: int32, - lpNumberOfBytesWritten: var int32, + lpNumberOfBytesWritten: ptr int32, lpOverlapped: pointer): WINBOOL{. stdcall, dynlib: "kernel32", importc: "WriteFile".} @@ -573,12 +573,14 @@ proc waitForMultipleObjects*(nCount: DWORD, lpHandles: PWOHandleArray, const GENERIC_READ* = 0x80000000'i32 + GENERIC_WRITE* = 0x40000000'i32 GENERIC_ALL* = 0x10000000'i32 FILE_SHARE_READ* = 1'i32 FILE_SHARE_DELETE* = 4'i32 FILE_SHARE_WRITE* = 2'i32 CREATE_ALWAYS* = 2'i32 + CREATE_NEW* = 1'i32 OPEN_EXISTING* = 3'i32 FILE_BEGIN* = 0'i32 INVALID_SET_FILE_POINTER* = -1'i32 @@ -595,6 +597,7 @@ const # Error Constants const ERROR_ACCESS_DENIED* = 5 + ERROR_HANDLE_EOF* = 38 when useWinUnicode: proc createFileW*(lpFileName: WideCString, dwDesiredAccess, dwShareMode: DWORD, @@ -649,10 +652,10 @@ proc unmapViewOfFile*(lpBaseAddress: pointer): WINBOOL {.stdcall, type TOVERLAPPED* {.pure, inheritable.} = object - Internal*: PULONG - InternalHigh*: PULONG - Offset*: DWORD - OffsetHigh*: DWORD + internal*: PULONG + internalHigh*: PULONG + offset*: DWORD + offsetHigh*: DWORD hEvent*: THandle POVERLAPPED* = ptr TOVERLAPPED @@ -668,6 +671,7 @@ type const ERROR_IO_PENDING* = 997 # a.k.a WSA_IO_PENDING + FILE_FLAG_OVERLAPPED* = 1073741824 WSAECONNABORTED* = 10053 WSAECONNRESET* = 10054 WSAEDISCON* = 10101 @@ -675,17 +679,21 @@ const WSAETIMEDOUT* = 10060 ERROR_NETNAME_DELETED* = 64 -proc CreateIoCompletionPort*(FileHandle: THandle, ExistingCompletionPort: THandle, +proc createIoCompletionPort*(FileHandle: THandle, ExistingCompletionPort: THandle, CompletionKey: DWORD, NumberOfConcurrentThreads: DWORD): THandle{.stdcall, dynlib: "kernel32", importc: "CreateIoCompletionPort".} -proc GetQueuedCompletionStatus*(CompletionPort: THandle, +proc getQueuedCompletionStatus*(CompletionPort: THandle, lpNumberOfBytesTransferred: PDWORD, lpCompletionKey: PULONG, lpOverlapped: ptr POVERLAPPED, dwMilliseconds: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "GetQueuedCompletionStatus".} +proc getOverlappedResult*(hFile: THandle, lpOverlapped: TOverlapped, + lpNumberOfBytesTransferred: var DWORD, bWait: WINBOOL): WINBOOL{. + stdcall, dynlib: "kernel32", importc: "GetOverlappedResult".} + const IOC_OUT* = 0x40000000 IOC_IN* = 0x80000000 diff --git a/tests/async/tasyncfile.nim b/tests/async/tasyncfile.nim new file mode 100644 index 000000000..9433f07ff --- /dev/null +++ b/tests/async/tasyncfile.nim @@ -0,0 +1,14 @@ +discard """ + file: "tasyncexceptions.nim" + exitcode: 0 +""" +import asyncfile, asyncdispatch, os + +proc main() {.async.} = + var file = openAsync(getTempDir() / "foobar.txt", fmReadWrite) + await file.write("test") + file.setFilePos(0) + let data = await file.readAll() + doAssert data == "test" + +waitFor main() From 31deee5142a0f2d7a4e0c6f24f614b2d50573461 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 5 Sep 2014 17:39:14 +0100 Subject: [PATCH 084/409] Add asyncfile module. --- lib/pure/asyncfile.nim | 256 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 lib/pure/asyncfile.nim diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim new file mode 100644 index 000000000..f74769a7d --- /dev/null +++ b/lib/pure/asyncfile.nim @@ -0,0 +1,256 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2014 Dominik Picheta +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements asynchronous file handling. +## +## .. code-block:: Nim +## import asyncfile, asyncdispatch, os +## +## proc main() {.async.} = +## var file = openAsync(getTempDir() / "foobar.txt", fmReadWrite) +## await file.write("test") +## file.setFilePos(0) +## let data = await file.readAll() +## doAssert data == "test" +## file.close() +## +## waitFor main() + +import asyncdispatch, os + +when defined(windows): + import winlean +else: + import posix + {.fatal: "Posix not yet supported".} + +type + AsyncFile = ref object + fd: TAsyncFd + offset: int64 + +when defined(windows): + proc getDesiredAccess(mode: TFileMode): int32 = + case mode + of fmRead: + result = GENERIC_READ + of fmWrite, fmAppend: + result = GENERIC_WRITE + of fmReadWrite, fmReadWriteExisting: + result = GENERIC_READ or GENERIC_WRITE + + proc getCreationDisposition(mode: TFileMode, filename: string): int32 = + case mode + of fmRead, fmReadWriteExisting: + OPEN_EXISTING + of fmAppend, fmReadWrite, fmWrite: + if fileExists(filename): + OPEN_EXISTING + else: + CREATE_NEW +else: + proc getPosixFlags(mode: TFileMode): cint = + case mode + of fmRead: + result = O_RDONLY + of fmWrite, fmAppend: + result = O_WRONLY or O_CREAT + of fmReadWrite: + result = O_RDWR or O_CREAT + of fmReadWriteExisting: + result = O_RDWR + +proc getFileSize*(f: AsyncFile): int64 = + ## Retrieves the specified file's size. + when defined(windows): + var high: DWord + let low = getFileSize(f.fd.THandle, addr high) + if low == INVALID_FILE_SIZE: + raiseOSError() + return (high shl 32) or low + +proc openAsync*(filename: string, mode = fmRead): AsyncFile = + ## Opens a file specified by the path in ``filename`` using + ## the specified ``mode`` asynchronously. + new result + when defined(windows): + let flags = FILE_FLAG_OVERLAPPED or FILE_ATTRIBUTE_NORMAL + let desiredAccess = getDesiredAccess(mode) + let creationDisposition = getCreationDisposition(mode, filename) + when useWinUnicode: + result.fd = createFileW(newWideCString(filename), desiredAccess, + FILE_SHARE_READ, + nil, creationDisposition, flags, 0).TAsyncFd + else: + result.fd = createFileA(filename, desiredAccess, + FILE_SHARE_READ, + nil, creationDisposition, flags, 0).TAsyncFd + + if result.fd.THandle == INVALID_HANDLE_VALUE: + raiseOSError() + + register(result.fd) + + if mode == fmAppend: + result.offset = getFileSize(result) + + else: + let flags = getPosixFlags(mode) + +proc read*(f: AsyncFile, size: int): Future[string] = + ## Read ``size`` bytes from the specified file asynchronously starting at + ## the current position of the file pointer. + ## + ## If the file pointer is past the end of the file then an empty string is + ## returned. + var retFuture = newFuture[string]("asyncfile.read") + + when defined(windows): + var buffer = alloc0(size) + + var ol = PCustomOverlapped() + GC_ref(ol) + ol.data = TCompletionData(sock: f.fd, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + if not retFuture.finished: + if errcode == OSErrorCode(-1): + assert bytesCount > 0 + assert bytesCount <= size + var data = newString(bytesCount) + copyMem(addr data[0], buffer, bytesCount) + f.offset.inc bytesCount + retFuture.complete($data) + else: + if errcode.int32 == ERROR_HANDLE_EOF: + retFuture.complete("") + else: + retFuture.fail(newException(OSError, osErrorMsg(errcode))) + if buffer != nil: + dealloc buffer + buffer = nil + ) + ol.offset = DWord(f.offset and 0xffffffff) + ol.offsetHigh = DWord(f.offset shr 32) + + # According to MSDN we're supposed to pass nil to lpNumberOfBytesRead. + let ret = readFile(f.fd.THandle, buffer, size.int32, nil, + cast[POVERLAPPED](ol)) + if not ret.bool: + let err = osLastError() + if err.int32 != ERROR_IO_PENDING: + if buffer != nil: + dealloc buffer + buffer = nil + GC_unref(ol) + retFuture.fail(newException(OSError, osErrorMsg(err))) + else: + # Request completed immediately. + var bytesRead: DWord + let overlappedRes = getOverlappedResult(f.fd.THandle, + cast[POverlapped](ol)[], bytesRead, false.WinBool) + if not overlappedRes.bool: + let err = osLastError() + if err.int32 == ERROR_HANDLE_EOF: + retFuture.complete("") + else: + retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) + else: + assert bytesRead > 0 + assert bytesRead <= size + var data = newString(bytesRead) + copyMem(addr data[0], buffer, bytesRead) + f.offset.inc bytesRead + retFuture.complete($data) + return retFuture + +proc getFilePos*(f: AsyncFile): int64 = + ## Retrieves the current position of the file pointer that is + ## used to read from the specified file. The file's first byte has the + ## index zero. + f.offset + +proc setFilePos*(f: AsyncFile, pos: int64) = + ## Sets the position of the file pointer that is used for read/write + ## operations. The file's first byte has the index zero. + f.offset = pos + +proc readAll*(f: AsyncFile): Future[string] {.async.} = + ## Reads all data from the specified file. + result = "" + while true: + let data = await read(f, 4000) + if data.len == 0: + return + result.add data + +proc write*(f: AsyncFile, data: string): Future[void] = + ## Writes ``data`` to the file specified asynchronously. + ## + ## The returned Future will complete once all data has been written to the + ## specified file. + var retFuture = newFuture[void]("asyncfile.write") + var copy = data + when defined(windows): + var buffer = alloc0(data.len) + copyMem(buffer, addr copy[0], data.len) + + var ol = PCustomOverlapped() + GC_ref(ol) + ol.data = TCompletionData(sock: f.fd, cb: + proc (fd: TAsyncFD, bytesCount: DWord, errcode: OSErrorCode) = + if not retFuture.finished: + if errcode == OSErrorCode(-1): + assert bytesCount == data.len.int32 + f.offset.inc(data.len) + retFuture.complete() + else: + retFuture.fail(newException(OSError, osErrorMsg(errcode))) + if buffer != nil: + dealloc buffer + buffer = nil + ) + ol.offset = DWord(f.offset and 0xffffffff) + ol.offsetHigh = DWord(f.offset shr 32) + + # According to MSDN we're supposed to pass nil to lpNumberOfBytesWritten. + let ret = writeFile(f.fd.THandle, buffer, data.len.int32, nil, + cast[POVERLAPPED](ol)) + if not ret.bool: + let err = osLastError() + if err.int32 != ERROR_IO_PENDING: + if buffer != nil: + dealloc buffer + buffer = nil + GC_unref(ol) + retFuture.fail(newException(OSError, osErrorMsg(err))) + else: + # Request completed immediately. + var bytesWritten: DWord + let overlappedRes = getOverlappedResult(f.fd.THandle, + cast[POverlapped](ol)[], bytesWritten, false.WinBool) + if not overlappedRes.bool: + retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) + else: + assert bytesWritten == data.len.int32 + f.offset.inc(data.len) + retFuture.complete() + return retFuture + +proc close*(f: AsyncFile) = + ## Closes the file specified. + when defined(windows): + if not closeHandle(f.fd.THandle).bool: + raiseOSError() + + + + + + + From 52c16a1a79063d5dfe03cc3ecbcc6685fc15f8e7 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 5 Sep 2014 21:14:18 +0100 Subject: [PATCH 085/409] Implemented asyncfile for Posix. --- lib/pure/asyncdispatch.nim | 7 ++-- lib/pure/asyncfile.nim | 72 +++++++++++++++++++++++++++++++++----- tests/async/tasyncfile.nim | 32 ++++++++++++++--- 3 files changed, 95 insertions(+), 16 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index e5402f0d5..052de6f3a 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -143,6 +143,7 @@ proc echoOriginalStackTrace[T](future: Future[T]) = echo(future.errorStackTrace) else: echo("Empty or nil stack trace.") + echo("Continuing...") proc read*[T](future: Future[T]): T = ## Retrieves the value of ``future``. Future must be finished otherwise @@ -723,7 +724,7 @@ else: assert sock.SocketHandle in p.selector discard p.selector.update(sock.SocketHandle, events) - proc register(sock: TAsyncFD) = + proc register*(sock: TAsyncFD) = let p = getGlobalDispatcher() var data = PData(sock: sock, readCBs: @[], writeCBs: @[]) p.selector.register(sock.SocketHandle, {}, data.PObject) @@ -743,14 +744,14 @@ else: proc unregister*(fd: TAsyncFD) = getGlobalDispatcher().selector.unregister(fd.SocketHandle) - proc addRead(sock: TAsyncFD, cb: TCallback) = + proc addRead*(sock: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() if sock.SocketHandle notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") p.selector[sock.SocketHandle].data.PData.readCBs.add(cb) update(sock, p.selector[sock.SocketHandle].events + {EvRead}) - proc addWrite(sock: TAsyncFD, cb: TCallback) = + proc addWrite*(sock: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() if sock.SocketHandle notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim index f74769a7d..009485ed9 100644 --- a/lib/pure/asyncfile.nim +++ b/lib/pure/asyncfile.nim @@ -28,7 +28,6 @@ when defined(windows): import winlean else: import posix - {.fatal: "Posix not yet supported".} type AsyncFile = ref object @@ -59,12 +58,15 @@ else: case mode of fmRead: result = O_RDONLY - of fmWrite, fmAppend: + of fmWrite: result = O_WRONLY or O_CREAT + of fmAppend: + result = O_WRONLY or O_CREAT or O_APPEND of fmReadWrite: result = O_RDWR or O_CREAT of fmReadWriteExisting: result = O_RDWR + result = result or O_NONBLOCK proc getFileSize*(f: AsyncFile): int64 = ## Retrieves the specified file's size. @@ -102,6 +104,13 @@ proc openAsync*(filename: string, mode = fmRead): AsyncFile = else: let flags = getPosixFlags(mode) + # RW (Owner), RW (Group), R (Other) + let perm = S_IRUSR or S_IWUSR or S_IRGRP or S_IWGRP or S_IROTH + result.fd = open(filename, flags, perm).TAsyncFD + if result.fd.cint == -1: + raiseOSError() + + register(result.fd) proc read*(f: AsyncFile, size: int): Future[string] = ## Read ``size`` bytes from the specified file asynchronously starting at @@ -167,6 +176,29 @@ proc read*(f: AsyncFile, size: int): Future[string] = copyMem(addr data[0], buffer, bytesRead) f.offset.inc bytesRead retFuture.complete($data) + else: + var readBuffer = newString(size) + + proc cb(fd: TAsyncFD): bool = + result = true + let res = read(fd.cint, addr readBuffer[0], size.cint) + if res < 0: + let lastError = osLastError() + if lastError.int32 != EAGAIN: + retFuture.fail(newException(EOS, osErrorMsg(lastError))) + else: + result = false # We still want this callback to be called. + elif res == 0: + # EOF + retFuture.complete("") + else: + readBuffer.setLen(res) + f.offset.inc(res) + retFuture.complete(readBuffer) + + if not cb(f.fd): + addRead(f.fd, cb) + return retFuture proc getFilePos*(f: AsyncFile): int64 = @@ -179,6 +211,10 @@ proc setFilePos*(f: AsyncFile, pos: int64) = ## Sets the position of the file pointer that is used for read/write ## operations. The file's first byte has the index zero. f.offset = pos + when not defined(windows): + let ret = lseek(f.fd.cint, pos, SEEK_SET) + if ret == -1: + raiseOSError() proc readAll*(f: AsyncFile): Future[string] {.async.} = ## Reads all data from the specified file. @@ -240,6 +276,29 @@ proc write*(f: AsyncFile, data: string): Future[void] = assert bytesWritten == data.len.int32 f.offset.inc(data.len) retFuture.complete() + else: + var written = 0 + + proc cb(fd: TAsyncFD): bool = + result = true + let remainderSize = data.len-written + let res = write(fd.cint, addr copy[written], remainderSize.cint) + if res < 0: + let lastError = osLastError() + if lastError.int32 != EAGAIN: + retFuture.fail(newException(EOS, osErrorMsg(lastError))) + else: + result = false # We still want this callback to be called. + else: + written.inc res + f.offset.inc res + if res != remainderSize: + result = false # We still have data to write. + else: + retFuture.complete() + + if not cb(f.fd): + addWrite(f.fd, cb) return retFuture proc close*(f: AsyncFile) = @@ -247,10 +306,7 @@ proc close*(f: AsyncFile) = when defined(windows): if not closeHandle(f.fd.THandle).bool: raiseOSError() - - - - - - + else: + if close(f.fd.cint) == -1: + raiseOSError() diff --git a/tests/async/tasyncfile.nim b/tests/async/tasyncfile.nim index 9433f07ff..78738de4e 100644 --- a/tests/async/tasyncfile.nim +++ b/tests/async/tasyncfile.nim @@ -5,10 +5,32 @@ discard """ import asyncfile, asyncdispatch, os proc main() {.async.} = - var file = openAsync(getTempDir() / "foobar.txt", fmReadWrite) - await file.write("test") - file.setFilePos(0) - let data = await file.readAll() - doAssert data == "test" + let fn = getTempDir() / "foobar.txt" + removeFile(fn) + # Simple write/read test. + block: + var file = openAsync(fn, fmReadWrite) + await file.write("test") + file.setFilePos(0) + await file.write("foo") + file.setFilePos(0) + let data = await file.readAll() + doAssert data == "foot" + file.close() + + # Append test + block: + var file = openAsync(fn, fmAppend) + await file.write("\ntest2") + let errorTest = file.readAll() + await errorTest + doAssert errorTest.failed + file.close() + file = openAsync(fn, fmRead) + let data = await file.readAll() + + doAssert data == "foot\ntest2" + file.close() + waitFor main() From 7f7b13a45f73c6d9dcca3ce8388833189d77426c Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 6 Sep 2014 00:50:53 +0200 Subject: [PATCH 086/409] nimfix handles helloworld --- compiler/astalgo.nim | 8 +++++++- compiler/commands.nim | 3 +-- compiler/main.nim | 37 +------------------------------------ compiler/modules.nim | 11 ++++++++++- compiler/nim.nimrod.cfg | 2 -- compiler/nimfix.nim | 10 ++++++++-- compiler/options.nim | 1 - doc/advopt.txt | 1 - todo.txt | 3 ++- 9 files changed, 29 insertions(+), 47 deletions(-) diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 8918888a3..110b0c26e 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -626,6 +626,12 @@ proc strTableAdd(t: var TStrTable, n: PSym) = strTableRawInsert(t.data, n) inc(t.counter) +proc reallySameIdent(a, b: string): bool {.inline.} = + when defined(nimfix): + result = a[0] == b[0] + else: + result = true + proc strTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} = # returns true if n is already in the string table: # It is essential that `n` is written nevertheless! @@ -635,7 +641,7 @@ proc strTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} = while true: var it = t.data[h] if it == nil: break - if it.name.id == n.name.id: + if it.name.id == n.name.id and reallySameIdent(it.name.s, n.name.s): t.data[h] = n # overwrite it with newer definition! return true # found it h = nextTry(h, high(t.data)) diff --git a/compiler/commands.nim b/compiler/commands.nim index 2a2e0c4ee..596cdafba 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -308,8 +308,7 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = expectArg(switch, arg, pass, info) options.docSeeSrcUrl = arg of "mainmodule", "m": - expectArg(switch, arg, pass, info) - optMainModule = arg + discard "allow for backwards compatibility, but don't do anything" of "define", "d": expectArg(switch, arg, pass, info) defineSymbol(arg) diff --git a/compiler/main.nim b/compiler/main.nim index 0bb057df5..47da96a03 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -211,25 +211,6 @@ proc commandSuggest = else: gProjectMainIdx compileProject(projFile) -proc wantMainModule = - if gProjectFull.len == 0: - if optMainModule.len == 0: - fatal(gCmdLineInfo, errCommandExpectsFilename) - else: - gProjectName = optMainModule - gProjectFull = gProjectPath / gProjectName - - gProjectMainIdx = addFileExt(gProjectFull, NimExt).fileInfoIdx - -proc requireMainModuleOption = - if optMainModule.len == 0: - fatal(gCmdLineInfo, errMainModuleMustBeSpecified) - else: - gProjectName = optMainModule - gProjectFull = gProjectPath / gProjectName - - gProjectMainIdx = addFileExt(gProjectFull, NimExt).fileInfoIdx - proc resetMemory = resetCompilationLists() ccgutils.resetCaches() @@ -293,30 +274,24 @@ proc mainCommand* = # current path is always looked first for modules prependStr(searchPaths, gProjectPath) setId(100) - passes.gIncludeFile = includeModule - passes.gImportModule = importModule case command.normalize of "c", "cc", "compile", "compiletoc": # compile means compileToC currently gCmd = cmdCompileToC - wantMainModule() commandCompileToC() of "cpp", "compiletocpp": extccomp.cExt = ".cpp" gCmd = cmdCompileToCpp if cCompiler == ccGcc: setCC("gcc") - wantMainModule() defineSymbol("cpp") commandCompileToC() of "objc", "compiletooc": extccomp.cExt = ".m" gCmd = cmdCompileToOC - wantMainModule() defineSymbol("objc") commandCompileToC() of "run": gCmd = cmdRun - wantMainModule() when hasTinyCBackend: extccomp.setCC("tcc") commandCompileToC() @@ -324,39 +299,32 @@ proc mainCommand* = rawMessage(errInvalidCommandX, command) of "js", "compiletojs": gCmd = cmdCompileToJS - wantMainModule() commandCompileToJS() of "compiletollvm": gCmd = cmdCompileToLLVM - wantMainModule() when hasLLVM_Backend: CommandCompileToLLVM() else: rawMessage(errInvalidCommandX, command) of "pretty": gCmd = cmdPretty - wantMainModule() commandPretty() of "doc": gCmd = cmdDoc loadConfigs(DocConfig) - wantMainModule() commandDoc() of "doc2": gCmd = cmdDoc loadConfigs(DocConfig) - wantMainModule() defineSymbol("nimdoc") commandDoc2() of "rst2html": gCmd = cmdRst2html loadConfigs(DocConfig) - wantMainModule() commandRst2Html() of "rst2tex": gCmd = cmdRst2tex loadConfigs(DocTexConfig) - wantMainModule() commandRst2TeX() of "jsondoc": gCmd = cmdDoc @@ -370,12 +338,11 @@ proc mainCommand* = commandBuildIndex() of "gendepend": gCmd = cmdGenDepend - wantMainModule() commandGenDepend() of "dump": gCmd = cmdDump if getConfigVar("dump.format") == "json": - requireMainModuleOption() + wantMainModule() var definedSymbols = newJArray() for s in definedSymbolNames(): definedSymbols.elems.add(%s) @@ -399,7 +366,6 @@ proc mainCommand* = for it in iterSearchPath(searchPaths): msgWriteln(it) of "check": gCmd = cmdCheck - wantMainModule() commandCheck() of "parse": gCmd = cmdParse @@ -423,7 +389,6 @@ proc mainCommand* = if gEvalExpr != "": commandEval(gEvalExpr) else: - wantMainModule() commandSuggest() of "serve": isServing = true diff --git a/compiler/modules.nim b/compiler/modules.nim index 8939afd5a..dd8ccedb1 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -185,8 +185,17 @@ proc compileSystemModule* = systemFileIdx = fileInfoIdx(options.libpath/"system.nim") discard compileModule(systemFileIdx, {sfSystemModule}) -proc compileProject*(projectFile = gProjectMainIdx) = +proc wantMainModule* = + if gProjectFull.len == 0: + fatal(gCmdLineInfo, errCommandExpectsFilename) + gProjectMainIdx = addFileExt(gProjectFull, NimExt).fileInfoIdx + +proc compileProject*(projectFileIdx = -1'i32) = + wantMainModule() + passes.gIncludeFile = includeModule + passes.gImportModule = importModule let systemFileIdx = fileInfoIdx(options.libpath / "system.nim") + let projectFile = if projectFileIdx < 0: gProjectMainIdx else: projectFileIdx if projectFile == systemFileIdx: discard compileModule(projectFile, {sfMainModule, sfSystemModule}) else: diff --git a/compiler/nim.nimrod.cfg b/compiler/nim.nimrod.cfg index 5a892bad0..ba7697c4c 100644 --- a/compiler/nim.nimrod.cfg +++ b/compiler/nim.nimrod.cfg @@ -1,7 +1,5 @@ # Special configuration file for the Nim project -mainModule:"nimrod.nim" - # gc:markAndSweep hint[XDeclaredButNotUsed]:off diff --git a/compiler/nimfix.nim b/compiler/nimfix.nim index 3fbf27e54..60ebb48e5 100644 --- a/compiler/nimfix.nim +++ b/compiler/nimfix.nim @@ -11,7 +11,7 @@ import strutils, os, parseopt import options, commands, modules, sem, passes, passaux, pretty, msgs, nimconf, - extccomp, condsyms + extccomp, condsyms, lists const Usage = """ Nimfix - Tool to patch Nim code @@ -36,6 +36,11 @@ proc mainCommand = registerPass semPass registerPass prettyPass gCmd = cmdPretty + appendStr(searchPaths, options.libpath) + if gProjectFull.len != 0: + # current path is always looked first for modules + prependStr(searchPaths, gProjectPath) + compileProject() pretty.overwriteFiles() @@ -68,7 +73,8 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) = else: processSwitch(pass, p) of cmdArgument: - if processArgument(pass, p, argsCount): break + options.gProjectName = unixToNativePath(p.key) + # if processArgument(pass, p, argsCount): break proc handleCmdLine() = if paramCount() == 0: diff --git a/compiler/options.nim b/compiler/options.nim index 11c8241ef..cb2173554 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -152,7 +152,6 @@ var gProjectPath* = "" # holds a path like /home/alice/projects/nimrod/compiler/ gProjectFull* = "" # projectPath/projectName gProjectMainIdx*: int32 # the canonical path id of the main module - optMainModule* = "" # the main module that should be used for idetools commands nimcacheDir* = "" command* = "" # the main command (e.g. cc, check, scan, etc) commandArgs*: seq[string] = @[] # any arguments after the main command diff --git a/doc/advopt.txt b/doc/advopt.txt index 370639a60..0febf778f 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -28,7 +28,6 @@ Advanced commands: --server.address:HOST binds to that address, by default "" Advanced options: - -m, --mainmodule:FILE set the project main module -o, --out:FILE set the output filename --stdout output to stdout --listFullPaths list full paths in messages diff --git a/todo.txt b/todo.txt index acdec7547..f29e97a21 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ version 0.10 ============ -- Write new nimfix tool - Test nimfix on various babel packages - Pegs do not work at compile-time @@ -10,6 +9,8 @@ version 0.9.6 ============= - fix tflowvar codegen test +- allow simple read accesses to global variables --> difficult to ensure that + no data races happen - split idetools into separate tool - split docgen into separate tool - .benign pragma From cda457c865aaab854c7d59bd1117250f73c944fe Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 6 Sep 2014 12:15:31 +0100 Subject: [PATCH 087/409] Fixes osproc on Windows. --- lib/pure/osproc.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index db5410517..52d0c56a6 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -330,7 +330,7 @@ when defined(Windows) and not defined(useNimRtl): var s = PFileHandleStream(s) if s.atTheEnd: return 0 var br: int32 - var a = winlean.readFile(s.handle, buffer, bufLen.cint, br, nil) + var a = winlean.readFile(s.handle, buffer, bufLen.cint, addr br, nil) # TRUE and zero bytes returned (EOF). # TRUE and n (>0) bytes returned (good data). # FALSE and bytes returned undefined (system error). @@ -341,7 +341,8 @@ when defined(Windows) and not defined(useNimRtl): proc hsWriteData(s: Stream, buffer: pointer, bufLen: int) = var s = PFileHandleStream(s) var bytesWritten: int32 - var a = winlean.writeFile(s.handle, buffer, bufLen.cint, bytesWritten, nil) + var a = winlean.writeFile(s.handle, buffer, bufLen.cint, + addr bytesWritten, nil) if a == 0: raiseOSError(osLastError()) proc newFileHandleStream(handle: THandle): PFileHandleStream = From bd542ebea3ec01eb269fe6fa118a8648d63f7097 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 6 Sep 2014 15:29:38 +0100 Subject: [PATCH 088/409] Fixes httpclient SSL issue. Implements unbuffered SSL recv. Ref #1487. --- lib/pure/asyncdispatch.nim | 4 +++ lib/pure/asyncnet.nim | 54 +++++++++++++++++++++++--------------- lib/pure/httpclient.nim | 3 ++- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 052de6f3a..e521b8e64 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -449,6 +449,8 @@ when defined(windows) or defined(nimdoc): ## complete once all the data requested is read, a part of the data has been ## read, or the socket has disconnected in which case the future will ## complete with a value of ``""``. + ## + ## **Warning**: The ``Peek`` socket flag is not supported on Windows. # Things to note: @@ -458,6 +460,8 @@ when defined(windows) or defined(nimdoc): # '\0' in the message currently signifies a socket disconnect. Who # knows what will happen when someone sends that to our socket. verifyPresence(socket) + assert SocketFlag.Peek notin flags, "Peek not supported on Windows." + var retFuture = newFuture[string]("recv") var dataBuf: TWSABuf dataBuf.buf = cast[cstring](alloc0(size)) diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index ea7432404..4539dfdcb 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -157,34 +157,43 @@ proc connect*(socket: PAsyncSocket, address: string, port: TPort, sslSetConnectState(socket.sslHandle) sslLoop(socket, flags, sslDoHandshake(socket.sslHandle)) -proc readIntoBuf(socket: PAsyncSocket, - flags: set[TSocketFlags]): Future[int] {.async.} = - var data = await recv(socket.fd.TAsyncFD, BufferSize, flags) - if data.len != 0: - copyMem(addr socket.buffer[0], addr data[0], data.len) +proc readInto(buf: cstring, size: int, socket: PAsyncSocket, + flags: set[TSocketFlags]): Future[int] {.async.} = if socket.isSsl: when defined(ssl): # SSL mode. - let ret = bioWrite(socket.bioIn, addr socket.buffer[0], data.len.cint) - if ret < 0: - raiseSSLError() sslLoop(socket, flags, - sslRead(socket.sslHandle, addr socket.buffer[0], BufferSize.cint)) - socket.currPos = 0 - socket.bufLen = opResult # Injected from sslLoop template. + sslRead(socket.sslHandle, buf, size.cint)) result = opResult else: + var data = await recv(socket.fd.TAsyncFD, size, flags) + if data.len != 0: + copyMem(buf, addr data[0], data.len) # Not in SSL mode. - socket.bufLen = data.len - socket.currPos = 0 result = data.len +proc readIntoBuf(socket: PAsyncSocket, + flags: set[TSocketFlags]): Future[int] {.async.} = + result = await readInto(addr socket.buffer[0], BufferSize, socket, flags) + socket.currPos = 0 + socket.bufLen = result + proc recv*(socket: PAsyncSocket, size: int, flags = {TSocketFlags.SafeDisconn}): Future[string] {.async.} = - ## Reads ``size`` bytes from ``socket``. Returned future will complete once - ## all of the requested data is read. If socket is disconnected during the + ## Reads **up to** ``size`` bytes from ``socket``. + ## + ## For buffered sockets this function will attempt to read all the requested + ## data. It will read this data in ``BufferSize`` chunks. + ## + ## For unbuffered sockets this function makes no effort to read + ## all the data requested. It will return as much data as the operating system + ## gives it. + ## + ## If socket is disconnected during the ## recv operation then the future may complete with only a part of the - ## requested data read. If socket is disconnected and no data is available + ## requested data. + ## + ## If socket is disconnected and no data is available ## to be read then the future will complete with a value of ``""``. if socket.isBuffered: result = newString(size) @@ -216,7 +225,9 @@ proc recv*(socket: PAsyncSocket, size: int, socket.currPos = originalBufPos result.setLen(read) else: - result = await recv(socket.fd.TAsyncFD, size, flags) + result = newString(size) + let read = await readInto(addr result[0], size, socket, flags) + result.setLen(read) proc send*(socket: PAsyncSocket, data: string, flags = {TSocketFlags.SafeDisconn}) {.async.} = @@ -282,6 +293,9 @@ proc recvLine*(socket: PAsyncSocket, ## The partial line **will be lost**. ## ## **Warning**: The ``Peek`` flag is not yet implemented. + ## + ## **Warning**: ``recvLine`` on unbuffered sockets assumes that the protocol + ## uses ``\r\L`` to delimit a new line. template addNLIfEmpty(): stmt = if result.len == 0: result.add("\c\L") @@ -324,10 +338,8 @@ proc recvLine*(socket: PAsyncSocket, if c.len == 0: return "" if c == "\r": - c = await recv(socket, 1, flags + {TSocketFlags.Peek}) - if c.len > 0 and c == "\L": - let dummy = await recv(socket, 1, flags) - assert dummy == "\L" + c = await recv(socket, 1, flags) # Skip \L + assert c == "\L" addNLIfEmpty() return elif c == "\L": diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 8b19c58f8..1548cf231 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -466,7 +466,8 @@ proc newAsyncHttpClient*(userAgent = defUserAgent, result.headers = newStringTable(modeCaseInsensitive) result.userAgent = defUserAgent result.maxRedirects = maxRedirects - result.sslContext = net.SslContext(sslContext) + when defined(ssl): + result.sslContext = net.SslContext(sslContext) proc close*(client: AsyncHttpClient) = ## Closes any connections held by the HTTP client. From cb8a25b3d1ed5ca873b4b19f157b84e7289ccf9b Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 6 Sep 2014 19:50:11 +0100 Subject: [PATCH 089/409] Added asyncfile.readLine and async stdin/out/err. Ref #1487. --- lib/pure/asyncfile.nim | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim index 009485ed9..6c8a87184 100644 --- a/lib/pure/asyncfile.nim +++ b/lib/pure/asyncfile.nim @@ -34,7 +34,26 @@ type fd: TAsyncFd offset: int64 +# TODO: These will be nil in other threads? +var + asyncStdin* {.threadvar.}: AsyncFile ## Asynchronous stdin handle + asyncStdout* {.threadvar.}: AsyncFile ## Asynchronous stdout handle + asyncStderr* {.threadvar.}: AsyncFile ## Asynchronous stderr handle + when defined(windows): + asyncStdin = AsyncFile( + fd: getStdHandle(STD_INPUT_HANDLE).TAsyncFd, + offset: 0 + ) + asyncStdout = AsyncFile( + fd: getStdHandle(STD_OUTPUT_HANDLE).TAsyncFd, + offset: 0 + ) + asyncStderr = AsyncFile( + fd: getStdHandle(STD_ERROR_HANDLE).TAsyncFd, + offset: 0 + ) + proc getDesiredAccess(mode: TFileMode): int32 = case mode of fmRead: @@ -54,6 +73,19 @@ when defined(windows): else: CREATE_NEW else: + asyncStdin = AsyncFile( + fd: STDIN_FILENO.TAsyncFd, + offset: 0 + ) + asyncStdout = AsyncFile( + fd: STDOUT_FILENO.TAsyncFd, + offset: 0 + ) + asyncStderr = AsyncFile( + fd: STDERR_FILENO.TAsyncFd, + offset: 0 + ) + proc getPosixFlags(mode: TFileMode): cint = case mode of fmRead: @@ -201,6 +233,19 @@ proc read*(f: AsyncFile, size: int): Future[string] = return retFuture +proc readLine*(f: AsyncFile): Future[string] {.async.} = + ## Reads a single line from the specified file asynchronously. + result = "" + while true: + var c = await read(f, 1) + if c[0] == '\c': + c = await read(f, 1) + break + if c[0] == '\L' or c == "": + break + else: + result.add(c) + proc getFilePos*(f: AsyncFile): int64 = ## Retrieves the current position of the file pointer that is ## used to read from the specified file. The file's first byte has the From 1cdb8022d00c4a17f5f411ed6d74bcc28f863b30 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 7 Sep 2014 00:58:31 +0200 Subject: [PATCH 090/409] changed comment handling (breaking change) --- compiler/lexer.nim | 47 +++++++++++++++++++++++++++++----------------- doc/manual.txt | 35 +++++++++++----------------------- doc/tut1.txt | 47 ++++++++-------------------------------------- 3 files changed, 49 insertions(+), 80 deletions(-) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index c2587efad..5e15b5c5e 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -482,7 +482,7 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) = add(tok.literal, VT) inc(L.bufpos) of 't', 'T': - add(tok.literal, Tabulator) + add(tok.literal, '\t') inc(L.bufpos) of '\'', '\"': add(tok.literal, L.buf[L.bufpos]) @@ -659,28 +659,29 @@ proc getOperator(L: var TLexer, tok: var TToken) = if buf[pos] in {CR, LF, nimlexbase.EndOfFile}: tok.strongSpaceB = -1 -proc scanComment(L: var TLexer, tok: var TToken) = +proc scanComment(L: var TLexer, tok: var TToken) = var pos = L.bufpos - var buf = L.buf - # a comment ends if the next line does not start with the # on the same - # column after only whitespace + when not defined(nimfix): assert buf[pos+1] == '#' + var buf = L.buf tok.tokType = tkComment # iNumber contains the number of '\n' in the token tok.iNumber = 0 - var col = getColNumber(L, pos) + when defined(nimfix): + var col = getColNumber(L, pos) while true: var lastBackslash = -1 while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}: if buf[pos] == '\\': lastBackslash = pos+1 add(tok.literal, buf[pos]) inc(pos) - if lastBackslash > 0: - # a backslash is a continuation character if only followed by spaces - # plus a newline: - while buf[lastBackslash] == ' ': inc(lastBackslash) - if buf[lastBackslash] notin {CR, LF, nimlexbase.EndOfFile}: - # false positive: - lastBackslash = -1 + when defined(nimfix): + if lastBackslash > 0: + # a backslash is a continuation character if only followed by spaces + # plus a newline: + while buf[lastBackslash] == ' ': inc(lastBackslash) + if buf[lastBackslash] notin {CR, LF, nimlexbase.EndOfFile}: + # false positive: + lastBackslash = -1 pos = handleCRLF(L, pos) buf = L.buf @@ -688,9 +689,16 @@ proc scanComment(L: var TLexer, tok: var TToken) = while buf[pos] == ' ': inc(pos) inc(indent) - if buf[pos] == '#' and (col == indent or lastBackslash > 0): + + when defined(nimfix): + template doContinue(): expr = + buf[pos] == '#' and (col == indent or lastBackslash > 0) + else: + template doContinue(): expr = + buf[pos] == '#' and buf[pos+1] == '#' + if doContinue(): tok.literal.add "\n" - col = indent + when defined(nimfix): col = indent inc tok.iNumber else: if buf[pos] > ' ': @@ -707,7 +715,7 @@ proc skip(L: var TLexer, tok: var TToken) = of ' ': inc(pos) inc(tok.strongSpaceA) - of Tabulator: + of '\t': lexMessagePos(L, errTabulatorsAreNotAllowed, pos) inc(pos) of CR, LF: @@ -718,7 +726,12 @@ proc skip(L: var TLexer, tok: var TToken) = inc(pos) inc(indent) tok.strongSpaceA = 0 - if buf[pos] > ' ': + when defined(nimfix): + template doBreak(): expr = buf[pos] > ' ' + else: + template doBreak(): expr = + buf[pos] > ' ' and (buf[pos] != '#' or buf[pos+1] == '#') + if doBreak(): tok.indent = indent L.currLineIndent = indent break diff --git a/doc/manual.txt b/doc/manual.txt index 144a3b2c0..f0f50e373 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -156,33 +156,20 @@ Comments start anywhere outside a string or character literal with the hash character ``#``. Comments consist of a concatenation of `comment pieces`:idx:. A comment piece starts with ``#`` and runs until the end of the line. The end of line characters -belong to the piece. If the next line only consists of a comment piece which is -aligned to the preceding one, it does not start a new comment: +belong to the piece. If the next line only consists of a comment piece with +no other tokens between it and the preceding one, it does not start a new +comment: + .. code-block:: nim - - i = 0 # This is a single comment over multiple lines belonging to the - # assignment statement. The scanner merges these two pieces. - # This is a new comment belonging to the current block, but to no particular - # statement. - i = i + 1 # This a new comment that is NOT - echo(i) # continued here, because this comment refers to the echo statement + i = 0 # This is a single comment over multiple lines. + # The scanner merges these two pieces. + # The comment continues here. -The alignment requirement does not hold if the preceding comment piece ends in -a backslash (followed by optional whitespace): - -.. code-block:: nim - type - TMyObject {.final, pure, acyclic.} = object # comment continues: \ - # we have lots of space here to comment 'TMyObject'. - # This line belongs to the comment as it's properly aligned. - -Comments are tokens; they are only allowed at certain places in the input file -as they belong to the syntax tree! This feature enables perfect source-to-source -transformations (such as pretty-printing) and superior documentation generators. -A nice side-effect is that the human reader of the code always knows exactly -which code snippet the comment refers to. +`Documentation comments`:idx: are comments that start with two ``##``. +Documentation comments are tokens; they are only allowed at certain places in +the input file as they belong to the syntax tree! Identifiers & Keywords @@ -5804,7 +5791,7 @@ Spawn Nim has a builtin thread pool that can be used for CPU intensive tasks. For IO intensive tasks the upcoming ``async`` and ``await`` features should be -used instead. `spawn`:idx: is used to pass a task to the thread pool: +used. `spawn`:idx: is used to pass a task to the thread pool: .. code-block:: nim proc processLine(line: string) = diff --git a/doc/tut1.txt b/doc/tut1.txt index 73d90b008..b90736bd0 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -112,50 +112,19 @@ Comments -------- Comments start anywhere outside a string or character literal with the -hash character ``#``. Documentation comments start with ``##``. Multiline -comments need to be aligned at the same column: +hash character ``#``. Documentation comments start with ``##``: .. code-block:: nim - - i = 0 # This is a single comment over multiple lines belonging to the - # assignment statement. - # This is a new comment belonging to the current block, but to no particular - # statement. - i = i + 1 # This a new comment that is NOT - echo(i) # continued here, because this comment refers to the echo statement + # A comment. + + var myVariable: int ## a documentation comment -The alignment requirement does not hold if the preceding comment piece ends in -a backslash: +Documentation comments are tokens; they are only allowed at certain places in +the input file as they belong to the syntax tree! This feature enables simpler +documentation generators. -.. code-block:: nim - type - TMyObject {.final, pure, acyclic.} = object # comment continues: \ - # we have lots of space here to comment 'TMyObject'. - # This line belongs to the comment as it's properly aligned. - - -Comments are tokens; they are only allowed at certain places in the input file -as they belong to the syntax tree! This feature enables perfect source-to-source -transformations (such as pretty-printing) and simpler documentation generators. -A nice side-effect is that the human reader of the code always knows exactly -which code snippet the comment refers to. Since comments are a proper part of -the syntax, watch their indentation: - -.. code-block:: - echo("Hello!") - # comment has the same indentation as above statement -> fine - echo("Hi!") - # comment has not the correct indentation level -> syntax error! - -**Note**: To comment out a large piece of code, it is often better to use a -``when false:`` statement. - -.. code-block:: nim - when false: - brokenCode() - -Another option is to use the `discard statement`_ together with *long string +You can also use the `discard statement`_ together with *long string literals* to create block comments: .. code-block:: nim From 428ee0c02264dcf76e1dd06311fce00841c43143 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 7 Sep 2014 01:47:16 +0200 Subject: [PATCH 091/409] changed comment handling (breaking change); part 2 --- compiler/lexer.nim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 5e15b5c5e..40524564e 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -661,8 +661,8 @@ proc getOperator(L: var TLexer, tok: var TToken) = proc scanComment(L: var TLexer, tok: var TToken) = var pos = L.bufpos - when not defined(nimfix): assert buf[pos+1] == '#' var buf = L.buf + when not defined(nimfix): assert buf[pos+1] == '#' tok.tokType = tkComment # iNumber contains the number of '\n' in the token tok.iNumber = 0 @@ -735,6 +735,13 @@ proc skip(L: var TLexer, tok: var TToken) = tok.indent = indent L.currLineIndent = indent break + of '#': + when defined(nimfix): + break + else: + # do not skip documentation comment: + if buf[pos+1] == '#': break + while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}: inc(pos) else: break # EndOfFile also leaves the loop L.bufpos = pos From ae53d1ecc8b14daf04a8163fb78cbc3a1f108897 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 7 Sep 2014 02:52:15 +0200 Subject: [PATCH 092/409] nimgrep compiles again --- compiler/nimfix.nim | 3 +++ tools/nimgrep.nim | 16 ++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/compiler/nimfix.nim b/compiler/nimfix.nim index 60ebb48e5..ffab2717a 100644 --- a/compiler/nimfix.nim +++ b/compiler/nimfix.nim @@ -98,6 +98,9 @@ proc handleCmdLine() = processCmdLine(passCmd2, "") mainCommand() +when compileOption("gc", "v2") or compileOption("gc", "refc"): + GC_disableMarkAndSweep() + condsyms.initDefines() defineSymbol "nimfix" handleCmdline() diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim index 7f9910f78..42db2dafc 100644 --- a/tools/nimgrep.nim +++ b/tools/nimgrep.nim @@ -12,7 +12,7 @@ import const Version = "0.9" - Usage = "nimgrep - Nim Grep Utility Version " & version & """ + Usage = "nimgrep - Nim Grep Utility Version " & Version & """ (c) 2012 Andreas Rumpf Usage: @@ -58,7 +58,7 @@ proc ask(msg: string): string = stdout.write(msg) result = stdin.readLine() -proc Confirm: TConfirmEnum = +proc confirm: TConfirmEnum = while true: case normalize(ask(" [a]bort; [y]es, a[l]l, [n]o, non[e]: ")) of "a", "abort": return ceAbort @@ -81,20 +81,20 @@ proc countLines(s: string, first, last: int): int = proc beforePattern(s: string, first: int): int = result = first-1 while result >= 0: - if s[result] in newlines: break + if s[result] in Newlines: break dec(result) inc(result) proc afterPattern(s: string, last: int): int = result = last+1 while result < s.len: - if s[result] in newlines: break + if s[result] in Newlines: break inc(result) dec(result) proc writeColored(s: string) = if useWriteStyled: - terminal.WriteStyled(s, {styleUnderscore, styleBright}) + terminal.writeStyled(s, {styleUnderscore, styleBright}) else: stdout.write(s) @@ -171,7 +171,7 @@ proc processFile(filename: string) = r = replace(wholeMatch, rep, replacement % matches) if optConfirm in options: highlight(buffer, wholeMatch, r, t, line, showRepl=true) - case Confirm() + case confirm() of ceAbort: quit(0) of ceYes: reallyReplace = true of ceAll: @@ -234,8 +234,8 @@ proc styleInsensitive(s: string): string = while s[i] != '>' and s[i] != '\0': addx() of '\\': addx() - if s[i] in strutils.digits: - while s[i] in strutils.digits: addx() + if s[i] in strutils.Digits: + while s[i] in strutils.Digits: addx() else: addx() else: addx() From a90f73ca4c61c7a74808aa805820db2a8b6deb00 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Sep 2014 00:58:29 +0200 Subject: [PATCH 093/409] nimfix can fix obsolete statement comments --- compiler/prettybase.nim | 13 ++++++++++++- compiler/sem.nim | 3 +++ compiler/semstmts.nim | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim index dca6bcdaa..eb0cf983d 100644 --- a/compiler/prettybase.nim +++ b/compiler/prettybase.nim @@ -54,9 +54,20 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) = let last = first+identLen(line, first)-1 if cmpIgnoreStyle(line[first..last], oldSym.s) == 0: - var x = line.substr(0, first-1) & newSym.s & line.substr(last+1) + var x = line.substr(0, first-1) & newSym.s & line.substr(last+1) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = replaceDeprecated(info, oldSym.name, newSym.name) + +proc replaceComment*(info: TLineInfo) = + loadFile(info) + + let line = gSourceFiles[info.fileIndex].lines[info.line-1] + var first = info.col.int + if line[first] != '#': inc first + + var x = line.substr(0, first-1) & "discard " & line.substr(first+1).escape + system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) + gSourceFiles[info.fileIndex].dirty = true diff --git a/compiler/sem.nim b/compiler/sem.nim index 5f2e77781..71e60f0b6 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -18,6 +18,9 @@ import evaltempl, patterns, parampatterns, sempass2, pretty, semmacrosanity, semparallel, lowerings +when defined(nimfix): + import prettybase + # implementation proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.procvar.} diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 93a1994a7..cb5bcdde8 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1398,6 +1398,11 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = else: discard if result.len == 1: result = result.sons[0] + when defined(nimfix): + if result.kind == nkCommentStmt and not result.comment.isNil and + not (result.comment[0] == '#' and result.comment[1] == '#'): + # it is an old-style comment statement: we replace it with 'discard ""': + prettybase.replaceComment(result.info) when false: # a statement list (s; e) has the type 'e': if result.kind == nkStmtList and result.len > 0: From 7333237be6abe3f170fe440e887ae83707fd748f Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Sep 2014 08:46:35 +0200 Subject: [PATCH 094/409] 'nimfix' improvements; FdSet is TFdSet again --- compiler/nimfix.nim | 14 +++++--------- compiler/pretty.nim | 5 ++--- lib/posix/posix.nim | 16 ++++++++-------- lib/pure/asyncftpclient.nim | 2 +- lib/pure/asyncio.nim | 10 +++++----- lib/pure/osproc.nim | 6 +++--- lib/pure/rawsockets.nim | 8 ++++---- lib/pure/selectors.nim | 6 +++--- lib/pure/sockets.nim | 12 ++++++------ lib/windows/winlean.nim | 16 ++++++++-------- todo.txt | 5 +---- 11 files changed, 46 insertions(+), 54 deletions(-) diff --git a/compiler/nimfix.nim b/compiler/nimfix.nim index ffab2717a..5cdcc65db 100644 --- a/compiler/nimfix.nim +++ b/compiler/nimfix.nim @@ -22,10 +22,8 @@ Options: --overwriteFiles:on|off overwrite the original nim files. DEFAULT is ON! --checkExtern:on|off style check also extern names - --styleCheck:none|confirm|auto performs style checking for identifiers - and suggests an alternative spelling. If - 'auto', it automatically corrects the - spelling. If 'confirm' it asks the user. + --styleCheck:on|off performs style checking for identifiers + and suggests an alternative spelling. In addition, all command line options of Nim are supported. """ @@ -65,11 +63,9 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) = else: localError(gCmdLineInfo, errOnOrOffExpected) of "stylecheck": case p.val.normalize - of "none": gStyleCheck = StyleCheck.None - of "confirm": gStyleCheck = StyleCheck.Confirm - of "auto": gStyleCheck = StyleCheck.Auto - else: localError(gCmdLineInfo, errGenerated, - "'none', 'confirm' or 'auto' expected") + of "off": gStyleCheck = StyleCheck.None + of "on": gStyleCheck = StyleCheck.Auto + else: localError(gCmdLineInfo, errOnOrOffExpected) else: processSwitch(pass, p) of cmdArgument: diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 6ee931951..b7265b946 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -29,11 +29,10 @@ type PGen = ref TGen proc overwriteFiles*() = - let overWrite = options.getConfigVar("pretty.overwrite").normalize != "off" let doStrip = options.getConfigVar("pretty.strip").normalize == "on" for i in 0 .. high(gSourceFiles): if not gSourceFiles[i].dirty: continue - let newFile = if overWrite: gSourceFiles[i].fullpath + let newFile = if gOverWrite: gSourceFiles[i].fullpath else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim") try: var f = open(newFile, fmWrite) @@ -102,6 +101,7 @@ proc checkStyle(info: TLineInfo, s: string, k: TSymKind) = message(info, hintName, beau) proc checkDef*(n: PNode; s: PSym) = + if gStyleCheck == StyleCheck.None: return # operators stay as they are: if s.kind in {skResult, skTemp} or s.name.s[0] notin prettybase.Letters: return @@ -184,7 +184,6 @@ proc myOpen(module: PSym): PPassContext = var g: PGen new(g) g.module = module - gCheckExtern = options.getConfigVar("pretty.checkextern").normalize == "on" result = g const prettyPass* = makePass(open = myOpen, process = processSym) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index e7d9b1cc8..c3085f0fb 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -388,7 +388,7 @@ type final, pure.} = object ## struct timeval tv_sec*: int ## Seconds. tv_usec*: int ## Microseconds. - FdSet* {.importc: "fd_set", header: "", + TFdSet* {.importc: "fd_set", header: "", final, pure.} = object Tmcontext* {.importc: "mcontext_t", header: "", final, pure.} = object @@ -563,7 +563,7 @@ type {.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo, TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval, - TFdSet: FdSet, Thostent: Hostent, TServent: Servent, + Thostent: Hostent, TServent: Servent, TInAddr: InAddr].} var @@ -2379,16 +2379,16 @@ proc sched_yield*(): cint {.importc, header: "".} proc strerror*(errnum: cint): cstring {.importc, header: "".} proc hstrerror*(herrnum: cint): cstring {.importc, header: "".} -proc FD_CLR*(a1: cint, a2: var FdSet) {.importc, header: "".} -proc FD_ISSET*(a1: cint | SocketHandle, a2: var FdSet): cint {. +proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "".} +proc FD_ISSET*(a1: cint | SocketHandle, a2: var TFdSet): cint {. importc, header: "".} -proc fdSet*(a1: cint | SocketHandle, a2: var FdSet) {. +proc fdSet*(a1: cint | SocketHandle, a2: var TFdSet) {. importc: "FD_SET", header: "".} -proc FD_ZERO*(a1: var FdSet) {.importc, header: "".} +proc FD_ZERO*(a1: var TFdSet) {.importc, header: "".} -proc pselect*(a1: cint, a2, a3, a4: ptr FdSet, a5: ptr Ttimespec, +proc pselect*(a1: cint, a2, a3, a4: ptr TFdSet, a5: ptr Ttimespec, a6: var Tsigset): cint {.importc, header: "".} -proc select*(a1: cint | SocketHandle, a2, a3, a4: ptr FdSet, a5: ptr Timeval): cint {. +proc select*(a1: cint | SocketHandle, a2, a3, a4: ptr TFdSet, a5: ptr Timeval): cint {. importc, header: "".} when hasSpawnH: diff --git a/lib/pure/asyncftpclient.nim b/lib/pure/asyncftpclient.nim index d4ac63e75..c5a97adfc 100644 --- a/lib/pure/asyncftpclient.nim +++ b/lib/pure/asyncftpclient.nim @@ -1,6 +1,6 @@ # # -# Nimrod's Runtime Library +# Nim's Runtime Library # (c) Copyright 2014 Dominik Picheta # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 9299b7370..5e757a03b 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -91,10 +91,10 @@ import sockets, os ## getSocket(s).accept(client) when defined(windows): - from winlean import TimeVal, SocketHandle, FdSet, FD_ZERO, FD_SET, + from winlean import TimeVal, SocketHandle, TFdSet, FD_ZERO, FD_SET, fdSet, FD_ISSET, select else: - from posix import TimeVal, SocketHandle, FdSet, FD_ZERO, FD_SET, + from posix import TimeVal, SocketHandle, TFdSet, FD_ZERO, FD_SET, fdSet, FD_ISSET, select type @@ -551,13 +551,13 @@ proc timeValFromMilliseconds(timeout = 500): Timeval = result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var FdSet, s: seq[Delegate], m: var int) = +proc createFdSet(fd: var TFdSet, s: seq[Delegate], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.fd)) fdSet(i.fd, fd) -proc pruneSocketSet(s: var seq[Delegate], fd: var FdSet) = +proc pruneSocketSet(s: var seq[Delegate], fd: var TFdSet) = var i = 0 var L = s.len while i < L: @@ -572,7 +572,7 @@ proc select(readfds, writefds, exceptfds: var seq[Delegate], timeout = 500): int = var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd, wr, ex: FdSet + var rd, wr, ex: TFdSet var m = 0 createFdSet(rd, readfds, m) createFdSet(wr, writefds, m) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 52d0c56a6..f47df73ca 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -883,13 +883,13 @@ elif not defined(useNimRtl): else: result = csystem(command) - proc createFdSet(fd: var FdSet, s: seq[Process], m: var int) = + proc createFdSet(fd: var TFdSet, s: seq[Process], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.outHandle)) fdSet(cint(i.outHandle), fd) - proc pruneProcessSet(s: var seq[Process], fd: var FdSet) = + proc pruneProcessSet(s: var seq[Process], fd: var TFdSet) = var i = 0 var L = s.len while i < L: @@ -905,7 +905,7 @@ elif not defined(useNimRtl): tv.tv_sec = 0 tv.tv_usec = timeout * 1000 - var rd: FdSet + var rd: TFdSet var m = 0 createFdSet((rd), readfds, m) diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index 45634c4ec..7e293f490 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -361,13 +361,13 @@ proc timeValFromMilliseconds(timeout = 500): Timeval = result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var FdSet, s: seq[SocketHandle], m: var int) = +proc createFdSet(fd: var TFdSet, s: seq[SocketHandle], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i)) fdSet(i, fd) -proc pruneSocketSet(s: var seq[SocketHandle], fd: var FdSet) = +proc pruneSocketSet(s: var seq[SocketHandle], fd: var TFdSet) = var i = 0 var L = s.len while i < L: @@ -388,7 +388,7 @@ proc select*(readfds: var seq[SocketHandle], timeout = 500): int = ## be read/written to or has errors (``exceptfds``). var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd: FdSet + var rd: TFdSet var m = 0 createFdSet((rd), readfds, m) @@ -410,7 +410,7 @@ proc selectWrite*(writefds: var seq[SocketHandle], ## an unlimited time. var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var wr: FdSet + var wr: TFdSet var m = 0 createFdSet((wr), writefds, m) diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index 33939537a..1c988c609 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -218,7 +218,7 @@ elif not defined(nimdoc): result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 - proc createFdSet(rd, wr: var FdSet, fds: Table[SocketHandle, SelectorKey], + proc createFdSet(rd, wr: var TFdSet, fds: Table[SocketHandle, SelectorKey], m: var int) = FD_ZERO(rd); FD_ZERO(wr) for k, v in pairs(fds): @@ -229,7 +229,7 @@ elif not defined(nimdoc): m = max(m, int(k)) FD_SET(k, wr) - proc getReadyFDs(rd, wr: var FdSet, fds: Table[SocketHandle, SelectorKey]): + proc getReadyFDs(rd, wr: var TFdSet, fds: Table[SocketHandle, SelectorKey]): seq[ReadyInfo] = result = @[] for k, v in pairs(fds): @@ -244,7 +244,7 @@ elif not defined(nimdoc): seq[ReadyInfo] = var tv {.noInit.}: TimeVal = timeValFromMilliseconds(timeout) - var rd, wr: FdSet + var rd, wr: TFdSet var m = 0 createFdSet(rd, wr, fds, m) diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 5ac3589a2..33f4e8144 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -931,13 +931,13 @@ proc timeValFromMilliseconds(timeout = 500): Timeval = result.tv_sec = seconds.int32 result.tv_usec = ((timeout - seconds * 1000) * 1000).int32 -proc createFdSet(fd: var FdSet, s: seq[Socket], m: var int) = +proc createFdSet(fd: var TFdSet, s: seq[Socket], m: var int) = FD_ZERO(fd) for i in items(s): m = max(m, int(i.fd)) fdSet(i.fd, fd) -proc pruneSocketSet(s: var seq[Socket], fd: var FdSet) = +proc pruneSocketSet(s: var seq[Socket], fd: var TFdSet) = var i = 0 var L = s.len while i < L: @@ -987,7 +987,7 @@ proc select*(readfds, writefds, exceptfds: var seq[Socket], var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd, wr, ex: FdSet + var rd, wr, ex: TFdSet var m = 0 createFdSet((rd), readfds, m) createFdSet((wr), writefds, m) @@ -1010,7 +1010,7 @@ proc select*(readfds, writefds: var seq[Socket], return buffersFilled var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd, wr: FdSet + var rd, wr: TFdSet var m = 0 createFdSet((rd), readfds, m) createFdSet((wr), writefds, m) @@ -1034,7 +1034,7 @@ proc selectWrite*(writefds: var seq[Socket], ## an unlimited time. var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var wr: FdSet + var wr: TFdSet var m = 0 createFdSet((wr), writefds, m) @@ -1052,7 +1052,7 @@ proc select*(readfds: var seq[Socket], timeout = 500): int = return buffersFilled var tv {.noInit.}: Timeval = timeValFromMilliseconds(timeout) - var rd: FdSet + var rd: TFdSet var m = 0 createFdSet((rd), readfds, m) diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 014215066..1ac82d84a 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -423,7 +423,7 @@ type h_length*: int16 h_addr_list*: cstringArray - FdSet* = object + TFdSet* = object fd_count*: cint # unsigned fd_array*: array[0..FD_SETSIZE-1, SocketHandle] @@ -444,7 +444,7 @@ type {.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo, TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval, - TWSADATA: WSADATA, TFdSet: FdSet, Thostent: Hostent, TServent: Servent, + TWSADATA: WSADATA, Thostent: Hostent, TServent: Servent, TInAddr: InAddr, Tin6_addr: In6_addr, Tsockaddr_in6: Sockaddr_in6, Tsockaddr_in6_old: Sockaddr_in6_old].} @@ -510,7 +510,7 @@ proc recv*(s: SocketHandle, buf: pointer, len, flags: cint): cint {. proc recvfrom*(s: SocketHandle, buf: cstring, len, flags: cint, fromm: ptr SockAddr, fromlen: ptr SockLen): cint {. stdcall, importc: "recvfrom", dynlib: ws2dll.} -proc select*(nfds: cint, readfds, writefds, exceptfds: ptr FdSet, +proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet, timeout: ptr Timeval): cint {. stdcall, importc: "select", dynlib: ws2dll.} proc send*(s: SocketHandle, buf: pointer, len, flags: cint): cint {. @@ -530,18 +530,18 @@ proc getnameinfo*(a1: ptr SockAddr, a2: SockLen, proc inet_addr*(cp: cstring): int32 {. stdcall, importc: "inet_addr", dynlib: ws2dll.} -proc WSAFDIsSet(s: SocketHandle, set: var FdSet): bool {. +proc WSAFDIsSet(s: SocketHandle, set: var TFdSet): bool {. stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll, noSideEffect.} -proc FD_ISSET*(Socket: SocketHandle, set: var FdSet): cint = - result = if WSAFDIsSet(Socket, set): 1'i32 else: 0'i32 +proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint = + result = if WSAFDIsSet(socket, set): 1'i32 else: 0'i32 -proc fdSet*(socket: SocketHandle, s: var FdSet) = +proc fdSet*(socket: SocketHandle, s: var TFdSet) = if s.fd_count < FD_SETSIZE: s.fd_array[int(s.fd_count)] = socket inc(s.fd_count) -proc FD_ZERO*(s: var FdSet) = +proc FD_ZERO*(s: var TFdSet) = s.fd_count = 0 proc wsaStartup*(wVersionRequired: int16, WSData: ptr WSAData): cint {. diff --git a/todo.txt b/todo.txt index f29e97a21..66f47a1d8 100644 --- a/todo.txt +++ b/todo.txt @@ -41,9 +41,8 @@ Misc - fix the bug that keeps 'defer' template from working - make '--implicitStatic:on' the default -- fix the tuple unpacking in lambda bug - make tuple unpacking work in a non-var/let context -- special rule for ``[]=`` +- special rule for ``[]=``, items, pairs - built-in 'getImpl' - type API for macros; make 'spawn' a macro - markAndSweepGC should expose an API for fibers @@ -172,8 +171,6 @@ Not essential for 1.0.0 - implement "closure tuple consists of a single 'ref'" optimization - new feature: ``distinct T with operations`` - arglist as a type (iterator chaining); variable length type lists for generics -- implement marker procs for message passing -- implement closures that support nesting of *procs* > 1 - object constructors: static check for fields if discriminator is known at compile time - prove array accesses From c53a27f0dc4e867701955e97b607aab2b66a0740 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Sep 2014 09:18:09 +0200 Subject: [PATCH 095/409] nimfix supports specialized '.nimfix' modules --- compiler/options.nim | 10 ++++++++++ compiler/pretty.nim | 28 ++++++++++++++-------------- compiler/prettybase.nim | 6 ++++-- lib/pure/os.nim | 5 +++-- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/compiler/options.nim b/compiler/options.nim index cb2173554..69067b7c4 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -337,6 +337,16 @@ proc findFile*(f: string): string {.procvar.} = proc findModule*(modulename, currentModule: string): string = # returns path to module + when defined(nimfix): + # '.nimfix' modules are preferred over '.nim' modules so that specialized + # versions can be kept for 'nimfix'. + block: + let m = addFileExt(modulename, "nimfix") + let currentPath = currentModule.splitFile.dir + result = currentPath / m + if not existsFile(result): + result = findFile(m) + if existsFile(result): return result let m = addFileExt(modulename, NimExt) let currentPath = currentModule.splitFile.dir result = currentPath / m diff --git a/compiler/pretty.nim b/compiler/pretty.nim index b7265b946..436181bbc 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -31,20 +31,20 @@ type proc overwriteFiles*() = let doStrip = options.getConfigVar("pretty.strip").normalize == "on" for i in 0 .. high(gSourceFiles): - if not gSourceFiles[i].dirty: continue - let newFile = if gOverWrite: gSourceFiles[i].fullpath - else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim") - try: - var f = open(newFile, fmWrite) - for line in gSourceFiles[i].lines: - if doStrip: - f.write line.strip(leading = false, trailing = true) - else: - f.write line - f.write("\L") - f.close - except IOError: - rawMessage(errCannotOpenFile, newFile) + if gSourceFiles[i].dirty and not gSourceFiles[i].isNimfixFile: + let newFile = if gOverWrite: gSourceFiles[i].fullpath + else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim") + try: + var f = open(newFile, fmWrite) + for line in gSourceFiles[i].lines: + if doStrip: + f.write line.strip(leading = false, trailing = true) + else: + f.write line + f.write("\L") + f.close + except IOError: + rawMessage(errCannotOpenFile, newFile) proc `=~`(s: string, a: openArray[string]): bool = for x in a: diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim index eb0cf983d..e3c1e6ae9 100644 --- a/compiler/prettybase.nim +++ b/compiler/prettybase.nim @@ -8,11 +8,12 @@ # import ast, msgs, strutils, idents +from os import splitFile type TSourceFile* = object lines*: seq[string] - dirty*: bool + dirty*, isNimfixFile*: bool fullpath*: string var @@ -26,7 +27,8 @@ proc loadFile*(info: TLineInfo) = gSourceFiles[i].lines = @[] let path = info.toFullPath gSourceFiles[i].fullpath = path - # we want to die here for EIO: + gSourceFiles[i].isNimfixFile = path.splitFile.ext == "nimfix" + # we want to die here for IOError: for line in lines(path): gSourceFiles[i].lines.add(line) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 8227c92b2..6b3ee6e6d 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -187,7 +187,7 @@ proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} = ## On Windows ``GetLastError`` is checked before ``errno``. ## Returns "" if no error occured. ## - ## **Deprecated since version 0.9.4**: use the other ``OSErrorMsg`` proc. + ## **Deprecated since version 0.9.4**: use the other ``osErrorMsg`` proc. result = "" when defined(Windows): @@ -225,7 +225,8 @@ proc raiseOSError*(msg: string = "") {.noinline, rtl, extern: "nos$1", raise newException(OSError, msg) {.pop.} -{.deprecated: [osError: raiseOSError].} +when not defined(nimfix): + {.deprecated: [osError: raiseOSError].} proc `==`*(err1, err2: OSErrorCode): bool {.borrow.} proc `$`*(err: OSErrorCode): string {.borrow.} From 952de51170b060a41067abf267dcd61d37d7d8c2 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Mon, 8 Sep 2014 16:48:09 +0100 Subject: [PATCH 096/409] Removed async console FDs. --- lib/pure/asyncfile.nim | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim index 6c8a87184..e861c6e48 100644 --- a/lib/pure/asyncfile.nim +++ b/lib/pure/asyncfile.nim @@ -34,26 +34,7 @@ type fd: TAsyncFd offset: int64 -# TODO: These will be nil in other threads? -var - asyncStdin* {.threadvar.}: AsyncFile ## Asynchronous stdin handle - asyncStdout* {.threadvar.}: AsyncFile ## Asynchronous stdout handle - asyncStderr* {.threadvar.}: AsyncFile ## Asynchronous stderr handle - when defined(windows): - asyncStdin = AsyncFile( - fd: getStdHandle(STD_INPUT_HANDLE).TAsyncFd, - offset: 0 - ) - asyncStdout = AsyncFile( - fd: getStdHandle(STD_OUTPUT_HANDLE).TAsyncFd, - offset: 0 - ) - asyncStderr = AsyncFile( - fd: getStdHandle(STD_ERROR_HANDLE).TAsyncFd, - offset: 0 - ) - proc getDesiredAccess(mode: TFileMode): int32 = case mode of fmRead: @@ -73,19 +54,6 @@ when defined(windows): else: CREATE_NEW else: - asyncStdin = AsyncFile( - fd: STDIN_FILENO.TAsyncFd, - offset: 0 - ) - asyncStdout = AsyncFile( - fd: STDOUT_FILENO.TAsyncFd, - offset: 0 - ) - asyncStderr = AsyncFile( - fd: STDERR_FILENO.TAsyncFd, - offset: 0 - ) - proc getPosixFlags(mode: TFileMode): cint = case mode of fmRead: @@ -100,7 +68,7 @@ else: result = O_RDWR result = result or O_NONBLOCK -proc getFileSize*(f: AsyncFile): int64 = +proc getFileSize(f: AsyncFile): int64 = ## Retrieves the specified file's size. when defined(windows): var high: DWord From 6689fa68f5ee3868b128b308cb237be5c4aa5d98 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Mon, 8 Sep 2014 22:04:09 +0100 Subject: [PATCH 097/409] Multiple exception idents in except for async. Ref #1487. --- lib/pure/asyncdispatch.nim | 63 +++++++++++++++++++++++--------------- tests/async/tasyncfile.nim | 2 +- tests/async/tasynctry.nim | 51 ++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 25 deletions(-) create mode 100644 tests/async/tasynctry.nim diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index e521b8e64..1cf54b922 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -972,29 +972,44 @@ template createCb*(retFutureSym, iteratorNameSym, cb() #{.pop.} proc generateExceptionCheck(futSym, - exceptBranch, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} = - if exceptBranch == nil: + tryStmt, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} = + if tryStmt.len == 1: result = rootReceiver else: - if exceptBranch[0].kind == nnkStmtList: - result = newIfStmt( - (newDotExpr(futSym, newIdentNode("failed")), - exceptBranch[0] - ) - ) - else: - expectKind(exceptBranch[1], nnkStmtList) - result = newIfStmt( - (newDotExpr(futSym, newIdentNode("failed")), - newIfStmt( - (infix(newDotExpr(futSym, newIdentNode("error")), "of", exceptBranch[0]), - exceptBranch[1]) - ) - ) - ) + var exceptionChecks: seq[tuple[cond, body: PNimrodNode]] = @[] + let errorNode = newDotExpr(futSym, newIdentNode("error")) + for i in 1 .. -> else: raise futSym.error + exceptionChecks.add((newIdentNode("true"), + newNimNode(nnkRaiseStmt).add(errorNode))) + # Read the future if there is no error. + # -> else: futSym.read let elseNode = newNimNode(nnkElse, fromNode) elseNode.add newNimNode(nnkStmtList, fromNode) elseNode[0].add rootReceiver + result = newIfStmt( + (newDotExpr(futSym, newIdentNode("failed")), newIfStmt(exceptionChecks)) + ) result.add elseNode template createVar(result: var PNimrodNode, futSymName: string, @@ -1006,11 +1021,11 @@ template createVar(result: var PNimrodNode, futSymName: string, result.add newVarStmt(futSym, asyncProc) # -> var future = y result.add newNimNode(nnkYieldStmt, fromNode).add(futSym) # -> yield future valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future.read - result.add generateExceptionCheck(futSym, exceptBranch, rootReceiver, fromNode) + result.add generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode) proc processBody(node, retFutureSym: PNimrodNode, subTypeIsVoid: bool, - exceptBranch: PNimrodNode): PNimrodNode {.compileTime.} = + tryStmt: PNimrodNode): PNimrodNode {.compileTime.} = #echo(node.treeRepr) result = node case node.kind @@ -1024,7 +1039,7 @@ proc processBody(node, retFutureSym: PNimrodNode, result.add newCall(newIdentNode("complete"), retFutureSym) else: result.add newCall(newIdentNode("complete"), retFutureSym, - node[0].processBody(retFutureSym, subTypeIsVoid, exceptBranch)) + node[0].processBody(retFutureSym, subTypeIsVoid, tryStmt)) result.add newNimNode(nnkReturnStmt, node).add(newNilLit()) return # Don't process the children of this return stmt @@ -1079,7 +1094,7 @@ proc processBody(node, retFutureSym: PNimrodNode, res: PNimrodNode): bool {.compileTime.} = result = false while i < n[0].len: - var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n[1]) + var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n) if processed.kind != n[0][i].kind or processed.len != n[0][i].len: expectKind(processed, nnkStmtList) expectKind(processed[2][1], nnkElse) @@ -1099,7 +1114,7 @@ proc processBody(node, retFutureSym: PNimrodNode, else: discard for i in 0 .. Date: Tue, 9 Sep 2014 01:16:28 +0100 Subject: [PATCH 098/409] Implements getCurrentException for try in async procs. Ref #1487. --- lib/pure/asyncdispatch.nim | 17 ++++++++++++----- lib/system.nim | 6 ++++++ tests/async/tasynctry.nim | 4 ++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 1cf54b922..f3d37f9d2 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -973,7 +973,7 @@ template createCb*(retFutureSym, iteratorNameSym, #{.pop.} proc generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} = - if tryStmt.len == 1: + if tryStmt.kind == nnkNilLit: result = rootReceiver else: var exceptionChecks: seq[tuple[cond, body: PNimrodNode]] = @[] @@ -1007,8 +1007,14 @@ proc generateExceptionCheck(futSym, let elseNode = newNimNode(nnkElse, fromNode) elseNode.add newNimNode(nnkStmtList, fromNode) elseNode[0].add rootReceiver + + let ifBody = newStmtList() + ifBody.add newCall(newIdentNode("setCurrentException"), errorNode) + ifBody.add newIfStmt(exceptionChecks) + ifBody.add newCall(newIdentNode("setCurrentException"), newNilLit()) + result = newIfStmt( - (newDotExpr(futSym, newIdentNode("failed")), newIfStmt(exceptionChecks)) + (newDotExpr(futSym, newIdentNode("failed")), ifBody) ) result.add elseNode @@ -1224,6 +1230,8 @@ proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = ## If the socket is disconnected in the middle of a line (before ``\r\L`` ## is read) then line will be set to ``""``. ## The partial line **will be lost**. + ## + ## **Warning**: This assumes that lines are delimited by ``\r\l``. template addNLIfEmpty(): stmt = if result.len == 0: @@ -1236,9 +1244,8 @@ proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = if c.len == 0: return "" if c == "\r": - c = await recv(socket, 1, {SocketFlag.SafeDisconn, SocketFlag.Peek}) - if c.len > 0 and c == "\L": - discard await recv(socket, 1) + c = await recv(socket, 1) + assert c == "\l" addNLIfEmpty() return elif c == "\L": diff --git a/lib/system.nim b/lib/system.nim index 9153af16c..ad99306ad 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2630,6 +2630,12 @@ when not defined(JS): #and not defined(NimrodVM): excHandler.hasRaiseAction = true excHandler.raiseAction = action + proc setCurrentException*(exc: ref Exception) {.inline, gcsafe.} = + ## sets the current exception. + ## + ## **Warning**: Only use this if you know what you are doing. + currException = exc + {.push stack_trace: off, profiler:off.} when defined(endb) and not defined(NimrodVM): include "system/debugger" diff --git a/tests/async/tasynctry.nim b/tests/async/tasynctry.nim index aa7be0b68..66ea40d49 100644 --- a/tests/async/tasynctry.nim +++ b/tests/async/tasynctry.nim @@ -2,7 +2,7 @@ discard """ file: "tasynctry.nim" exitcode: 0 output: ''' -Generic except +Generic except: Test Specific except Multiple idents in except Multiple except branches @@ -22,7 +22,7 @@ proc catch() {.async.} = try: await foobar() except: - echo("Generic except") + echo("Generic except: ", getCurrentExceptionMsg()) try: await foobar() From 56f11e2c955b710000374d7eb20a3e1fe3a075f7 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Tue, 9 Sep 2014 01:17:07 +0100 Subject: [PATCH 099/409] Fixes async tests. --- tests/async/tasyncawait.nim | 10 +++++----- tests/async/tasyncexceptions.nim | 6 +++--- tests/async/tnestedpfuturetypeparam.nim | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim index ec05a0386..efb6f0c25 100644 --- a/tests/async/tasyncawait.nim +++ b/tests/async/tasyncawait.nim @@ -47,18 +47,18 @@ proc readMessages(client: TAsyncFD) {.async.} = proc createServer(port: TPort) {.async.} = var server = newAsyncRawSocket() block: - var name: TSockaddr_in + var name: Sockaddr_in when defined(windows): name.sin_family = toInt(AF_INET).int16 else: name.sin_family = toInt(AF_INET) name.sin_port = htons(int16(port)) name.sin_addr.s_addr = htonl(INADDR_ANY) - if bindAddr(server.TSocketHandle, cast[ptr TSockAddr](addr(name)), - sizeof(name).TSocklen) < 0'i32: - osError(osLastError()) + if bindAddr(server.SocketHandle, cast[ptr SockAddr](addr(name)), + sizeof(name).Socklen) < 0'i32: + raiseOSError(osLastError()) - discard server.TSocketHandle.listen() + discard server.SocketHandle.listen() while true: var client = await accept(server) asyncCheck readMessages(client) diff --git a/tests/async/tasyncexceptions.nim b/tests/async/tasyncexceptions.nim index ca73c6a3d..30ef41756 100644 --- a/tests/async/tasyncexceptions.nim +++ b/tests/async/tasyncexceptions.nim @@ -1,15 +1,15 @@ discard """ file: "tasyncexceptions.nim" exitcode: 1 - outputsub: "Error: unhandled exception: foobar [E_Base]" + outputsub: "Error: unhandled exception: foobar [Exception]" """ import asyncdispatch -proc accept(): PFuture[int] {.async.} = +proc accept(): Future[int] {.async.} = await sleepAsync(100) result = 4 -proc recvLine(fd: int): PFuture[string] {.async.} = +proc recvLine(fd: int): Future[string] {.async.} = await sleepAsync(100) return "get" diff --git a/tests/async/tnestedpfuturetypeparam.nim b/tests/async/tnestedpfuturetypeparam.nim index 1db442170..bf346ff8e 100644 --- a/tests/async/tnestedpfuturetypeparam.nim +++ b/tests/async/tnestedpfuturetypeparam.nim @@ -1,8 +1,8 @@ import asyncdispatch, asyncnet proc main {.async.} = - proc f: PFuture[seq[int]] {.async.} = - await newAsyncSocket().connect("www.google.com", TPort(80)) + proc f: Future[seq[int]] {.async.} = + await newAsyncSocket().connect("www.google.com", Port(80)) let x = await f() asyncCheck main() From 4db65350250c3350351298d9962a9e66404b3ef6 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Tue, 9 Sep 2014 11:43:54 +0100 Subject: [PATCH 100/409] Fixes for new comment handling. --- lib/pure/asyncdispatch.nim | 1 + lib/pure/asyncio.nim | 1 + tests/vm/tasmparser.nim | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index f3d37f9d2..5363d8862 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -796,6 +796,7 @@ else: else: # FD no longer a part of the selector. Likely been closed # (e.g. socket disconnected). + discard processTimers(p) diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 9299b7370..10be5e409 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -247,6 +247,7 @@ proc asyncSockHandleWrite(h: RootRef) = # Apparently the socket cannot be written to. Even though select # just told us that it can be... This used to be an assert. Just # do nothing instead. + discard elif bytesSent != sock.sendBuffer.len: sock.sendBuffer = sock.sendBuffer[bytesSent .. -1] elif bytesSent == sock.sendBuffer.len: diff --git a/tests/vm/tasmparser.nim b/tests/vm/tasmparser.nim index 24ccb2ec8..67313c858 100644 --- a/tests/vm/tasmparser.nim +++ b/tests/vm/tasmparser.nim @@ -37,7 +37,7 @@ proc asmx64 () {.compileTime} = proc abortAsmParse (err:string) = - # + discard let codeLen = code.len #let codeEnd = codeLen-1 From 4fc8fcf37c61529e2c9ad2827df18254a0fc8fd2 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Tue, 9 Sep 2014 11:44:19 +0100 Subject: [PATCH 101/409] Mentioned new comment handling in news.txt. --- web/news.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/news.txt b/web/news.txt index 3b48140e5..98d703cfd 100644 --- a/web/news.txt +++ b/web/news.txt @@ -31,7 +31,8 @@ News will disappear soon! - ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to prevent name conflicts with the new type ``FileHandle``. - + - Comments are now not part of the AST, as such you cannot use them in place + of ``discard``. Language Additions ------------------ From 00b6a144894945d92fe3747fdf9bad32a4aec8d8 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Tue, 9 Sep 2014 15:58:44 +0100 Subject: [PATCH 102/409] More empty stmt fixes. --- lib/pure/asynchttpserver.nim | 1 + tests/async/tasyncawait.nim | 11 ++--------- tests/async/tasyncdiscard.nim | 4 ++-- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 70a865ed5..931a0c15a 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -183,6 +183,7 @@ proc processClient(client: PAsyncSocket, address: string, # header states otherwise. # In HTTP 1.0 we assume that the connection should not be persistent. # Unless the connection header states otherwise. + discard else: request.client.close() break diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim index efb6f0c25..5165b0f06 100644 --- a/tests/async/tasyncawait.nim +++ b/tests/async/tasyncawait.nim @@ -21,15 +21,8 @@ proc launchSwarm(port: TPort) {.async.} = var sock = newAsyncRawSocket() await connect(sock, "localhost", port) - when true: - await sendMessages(sock) - closeSocket(sock) - else: - # Issue #932: https://github.com/Araq/Nim/issues/932 - var msgFut = sendMessages(sock) - msgFut.callback = - proc () = - closeSocket(sock) + await sendMessages(sock) + closeSocket(sock) proc readMessages(client: TAsyncFD) {.async.} = while true: diff --git a/tests/async/tasyncdiscard.nim b/tests/async/tasyncdiscard.nim index 966851acc..71aba29e2 100644 --- a/tests/async/tasyncdiscard.nim +++ b/tests/async/tasyncdiscard.nim @@ -13,7 +13,7 @@ discard """ import asyncio, asyncdispatch, asyncnet proc main {.async.} = - proc f: PFuture[int] {.async.} = + proc f: Future[int] {.async.} = discard echo 1 discard @@ -24,7 +24,7 @@ proc main {.async.} = echo x echo 3 - proc g: PFuture[int] {.async.} = + proc g: Future[int] {.async.} = discard echo 4 discard From fce0a89aa0786782f466e4998bd7798de3da007b Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Tue, 9 Sep 2014 16:19:52 +0100 Subject: [PATCH 103/409] Added more information to the news. --- web/news.txt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/web/news.txt b/web/news.txt index 98d703cfd..0b4c98b73 100644 --- a/web/news.txt +++ b/web/news.txt @@ -14,8 +14,12 @@ News ``threadpool``. - The symbol binding rules in generics changed: ``bar`` in ``foo.bar`` is now considered for implicit early binding. - - ``c2nim`` moved into its own repository and is now a Babel package. - - ``pas2nim`` moved into its own repository and is now a Babel package. + - ``c2nim`` moved into its own + `repository `_ + and is now a Nimble package. + - ``pas2nim`` moved into its own + `repository `_ + and is now a Nimble package. - ``system.$`` for floating point types now produces a human friendly string representation. - ``uri.TUrl`` as well as the ``parseurl`` module are now deprecated in favour @@ -33,6 +37,13 @@ News prevent name conflicts with the new type ``FileHandle``. - Comments are now not part of the AST, as such you cannot use them in place of ``discard``. + - The ``irc`` module has been moved into its own + `repository `_ + and is now a Nimble package. + - Many wrappers have been moved into their own repositories and are now + Nimble packages including ``lua``, ``opengl``, ``x11``, ``nim-zmq``, + ``gtk2``, ``mongo``, ``cairo``, ``tcl`` and ``python``. They can be + found under the `nim-code `_ organisation. Language Additions ------------------ From 46cfff019fea904f119d21b0f9995da08269f359 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 9 Sep 2014 20:34:40 +0200 Subject: [PATCH 104/409] pegs.nimfix compiles --- lib/pure/pegs.nimfix | 1770 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1770 insertions(+) create mode 100644 lib/pure/pegs.nimfix diff --git a/lib/pure/pegs.nimfix b/lib/pure/pegs.nimfix new file mode 100644 index 000000000..8dd172a48 --- /dev/null +++ b/lib/pure/pegs.nimfix @@ -0,0 +1,1770 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2012 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Simple PEG (Parsing expression grammar) matching. Uses no memorization, but +## uses superoperators and symbol inlining to improve performance. Note: +## Matching performance is hopefully competitive with optimized regular +## expression engines. +## +## .. include:: ../doc/pegdocs.txt +## + +include "system/inclrtl" + +const + useUnicode = true ## change this to deactivate proper UTF-8 support + +import + strutils + +when useUnicode: + import unicode + +const + InlineThreshold = 5 ## number of leaves; -1 to disable inlining + MaxSubpatterns* = 10 ## defines the maximum number of subpatterns that + ## can be captured. More subpatterns cannot be captured! + +type + PegKind = enum + pkEmpty, + pkAny, ## any character (.) + pkAnyRune, ## any Unicode character (_) + pkNewLine, ## CR-LF, LF, CR + pkLetter, ## Unicode letter + pkLower, ## Unicode lower case letter + pkUpper, ## Unicode upper case letter + pkTitle, ## Unicode title character + pkWhitespace, ## Unicode whitespace character + pkTerminal, + pkTerminalIgnoreCase, + pkTerminalIgnoreStyle, + pkChar, ## single character to match + pkCharChoice, + pkNonTerminal, + pkSequence, ## a b c ... --> Internal DSL: peg(a, b, c) + pkOrderedChoice, ## a / b / ... --> Internal DSL: a / b or /[a, b, c] + pkGreedyRep, ## a* --> Internal DSL: *a + ## a+ --> (a a*) + pkGreedyRepChar, ## x* where x is a single character (superop) + pkGreedyRepSet, ## [set]* (superop) + pkGreedyAny, ## .* or _* (superop) + pkOption, ## a? --> Internal DSL: ?a + pkAndPredicate, ## &a --> Internal DSL: &a + pkNotPredicate, ## !a --> Internal DSL: !a + pkCapture, ## {a} --> Internal DSL: capture(a) + pkBackRef, ## $i --> Internal DSL: backref(i) + pkBackRefIgnoreCase, + pkBackRefIgnoreStyle, + pkSearch, ## @a --> Internal DSL: !*a + pkCapturedSearch, ## {@} a --> Internal DSL: !*\a + pkRule, ## a <- b + pkList, ## a, b + pkStartAnchor ## ^ --> Internal DSL: startAnchor() + NonTerminalFlag = enum + ntDeclared, ntUsed + NonTerminalObj = object ## represents a non terminal symbol + name: string ## the name of the symbol + line: int ## line the symbol has been declared/used in + col: int ## column the symbol has been declared/used in + flags: set[NonTerminalFlag] ## the nonterminal's flags + rule: TNode ## the rule that the symbol refers to + TNode {.shallow.} = object + case kind: PegKind + of pkEmpty..pkWhitespace: nil + of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: term: string + of pkChar, pkGreedyRepChar: ch: char + of pkCharChoice, pkGreedyRepSet: charChoice: ref set[char] + of pkNonTerminal: nt: PNonTerminal + of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns] + else: sons: seq[TNode] + PNonTerminal* = ref NonTerminalObj + TPeg* = TNode + +block: + type + Peg = TNode + NonTerminal = PNonTerminal + {.deprecated: [TPeg: Peg, PNonTerminal: NonTerminal].} + +proc term*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1Str".} = + ## constructs a PEG from a terminal string + if t.len != 1: + result.kind = pkTerminal + result.term = t + else: + result.kind = pkChar + result.ch = t[0] + +proc termIgnoreCase*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a PEG from a terminal string; ignore case for matching + result.kind = pkTerminalIgnoreCase + result.term = t + +proc termIgnoreStyle*(t: string): TPeg {.nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a PEG from a terminal string; ignore style for matching + result.kind = pkTerminalIgnoreStyle + result.term = t + +proc term*(t: char): TPeg {.nosideEffect, rtl, extern: "npegs$1Char".} = + ## constructs a PEG from a terminal char + assert t != '\0' + result.kind = pkChar + result.ch = t + +proc charSet*(s: set[char]): TPeg {.nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a PEG from a character set `s` + assert '\0' notin s + result.kind = pkCharChoice + new(result.charChoice) + result.charChoice[] = s + +proc len(a: TPeg): int {.inline.} = return a.sons.len +proc add(d: var TPeg, s: TPeg) {.inline.} = add(d.sons, s) + +proc addChoice(dest: var TPeg, elem: TPeg) = + var L = dest.len-1 + if L >= 0 and dest.sons[L].kind == pkCharChoice: + # caution! Do not introduce false aliasing here! + case elem.kind + of pkCharChoice: + dest.sons[L] = charSet(dest.sons[L].charChoice[] + elem.charChoice[]) + of pkChar: + dest.sons[L] = charSet(dest.sons[L].charChoice[] + {elem.ch}) + else: add(dest, elem) + else: add(dest, elem) + +template multipleOp(k: PegKind, localOpt: expr) = + result.kind = k + result.sons = @[] + for x in items(a): + if x.kind == k: + for y in items(x.sons): + localOpt(result, y) + else: + localOpt(result, x) + if result.len == 1: + result = result.sons[0] + +proc `/`*(a: varargs[TPeg]): TPeg {. + nosideEffect, rtl, extern: "npegsOrderedChoice".} = + ## constructs an ordered choice with the PEGs in `a` + multipleOp(pkOrderedChoice, addChoice) + +proc addSequence(dest: var TPeg, elem: TPeg) = + var L = dest.len-1 + if L >= 0 and dest.sons[L].kind == pkTerminal: + # caution! Do not introduce false aliasing here! + case elem.kind + of pkTerminal: + dest.sons[L] = term(dest.sons[L].term & elem.term) + of pkChar: + dest.sons[L] = term(dest.sons[L].term & elem.ch) + else: add(dest, elem) + else: add(dest, elem) + +proc sequence*(a: varargs[TPeg]): TPeg {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a sequence with all the PEGs from `a` + multipleOp(pkSequence, addSequence) + +proc `?`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsOptional".} = + ## constructs an optional for the PEG `a` + if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar, + pkGreedyRepSet}: + # a* ? --> a* + # a? ? --> a? + result = a + else: + result.kind = pkOption + result.sons = @[a] + +proc `*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyRep".} = + ## constructs a "greedy repetition" for the PEG `a` + case a.kind + of pkGreedyRep, pkGreedyRepChar, pkGreedyRepSet, pkGreedyAny, pkOption: + assert false + # produces endless loop! + of pkChar: + result.kind = pkGreedyRepChar + result.ch = a.ch + of pkCharChoice: + result.kind = pkGreedyRepSet + result.charChoice = a.charChoice # copying a reference suffices! + of pkAny, pkAnyRune: + result.kind = pkGreedyAny + else: + result.kind = pkGreedyRep + result.sons = @[a] + +proc `!*`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsSearch".} = + ## constructs a "search" for the PEG `a` + result.kind = pkSearch + result.sons = @[a] + +proc `!*\`*(a: TPeg): TPeg {.noSideEffect, rtl, + extern: "npgegsCapturedSearch".} = + ## constructs a "captured search" for the PEG `a` + result.kind = pkCapturedSearch + result.sons = @[a] + +proc `+`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsGreedyPosRep".} = + ## constructs a "greedy positive repetition" with the PEG `a` + return sequence(a, *a) + +proc `&`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsAndPredicate".} = + ## constructs an "and predicate" with the PEG `a` + result.kind = pkAndPredicate + result.sons = @[a] + +proc `!`*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsNotPredicate".} = + ## constructs a "not predicate" with the PEG `a` + result.kind = pkNotPredicate + result.sons = @[a] + +proc any*: TPeg {.inline.} = + ## constructs the PEG `any character`:idx: (``.``) + result.kind = pkAny + +proc anyRune*: TPeg {.inline.} = + ## constructs the PEG `any rune`:idx: (``_``) + result.kind = pkAnyRune + +proc newLine*: TPeg {.inline.} = + ## constructs the PEG `newline`:idx: (``\n``) + result.kind = pkNewLine + +proc unicodeLetter*: TPeg {.inline.} = + ## constructs the PEG ``\letter`` which matches any Unicode letter. + result.kind = pkLetter + +proc unicodeLower*: TPeg {.inline.} = + ## constructs the PEG ``\lower`` which matches any Unicode lowercase letter. + result.kind = pkLower + +proc unicodeUpper*: TPeg {.inline.} = + ## constructs the PEG ``\upper`` which matches any Unicode uppercase letter. + result.kind = pkUpper + +proc unicodeTitle*: TPeg {.inline.} = + ## constructs the PEG ``\title`` which matches any Unicode title letter. + result.kind = pkTitle + +proc unicodeWhitespace*: TPeg {.inline.} = + ## constructs the PEG ``\white`` which matches any Unicode + ## whitespace character. + result.kind = pkWhitespace + +proc startAnchor*: TPeg {.inline.} = + ## constructs the PEG ``^`` which matches the start of the input. + result.kind = pkStartAnchor + +proc endAnchor*: TPeg {.inline.} = + ## constructs the PEG ``$`` which matches the end of the input. + result = !any() + +proc capture*(a: TPeg): TPeg {.nosideEffect, rtl, extern: "npegsCapture".} = + ## constructs a capture with the PEG `a` + result.kind = pkCapture + result.sons = @[a] + +proc backref*(index: range[1..MaxSubpatterns]): TPeg {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a back reference of the given `index`. `index` starts counting + ## from 1. + result.kind = pkBackRef + result.index = index-1 + +proc backrefIgnoreCase*(index: range[1..MaxSubpatterns]): TPeg {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a back reference of the given `index`. `index` starts counting + ## from 1. Ignores case for matching. + result.kind = pkBackRefIgnoreCase + result.index = index-1 + +proc backrefIgnoreStyle*(index: range[1..MaxSubpatterns]): TPeg {. + nosideEffect, rtl, extern: "npegs$1".}= + ## constructs a back reference of the given `index`. `index` starts counting + ## from 1. Ignores style for matching. + result.kind = pkBackRefIgnoreStyle + result.index = index-1 + +proc spaceCost(n: TPeg): int = + case n.kind + of pkEmpty: discard + of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar, + pkGreedyRepChar, pkCharChoice, pkGreedyRepSet, + pkAny..pkWhitespace, pkGreedyAny: + result = 1 + of pkNonTerminal: + # we cannot inline a rule with a non-terminal + result = InlineThreshold+1 + else: + for i in 0..n.len-1: + inc(result, spaceCost(n.sons[i])) + if result >= InlineThreshold: break + +proc nonterminal*(n: PNonTerminal): TPeg {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a PEG that consists of the nonterminal symbol + assert n != nil + if ntDeclared in n.flags and spaceCost(n.rule) < InlineThreshold: + when false: echo "inlining symbol: ", n.name + result = n.rule # inlining of rule enables better optimizations + else: + result.kind = pkNonTerminal + result.nt = n + +proc newNonTerminal*(name: string, line, column: int): PNonTerminal {. + nosideEffect, rtl, extern: "npegs$1".} = + ## constructs a nonterminal symbol + new(result) + result.name = name + result.line = line + result.col = column + +template letters*: expr = + ## expands to ``charset({'A'..'Z', 'a'..'z'})`` + charSet({'A'..'Z', 'a'..'z'}) + +template digits*: expr = + ## expands to ``charset({'0'..'9'})`` + charSet({'0'..'9'}) + +template whitespace*: expr = + ## expands to ``charset({' ', '\9'..'\13'})`` + charSet({' ', '\9'..'\13'}) + +template identChars*: expr = + ## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})`` + charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'}) + +template identStartChars*: expr = + ## expands to ``charset({'A'..'Z', 'a'..'z', '_'})`` + charSet({'a'..'z', 'A'..'Z', '_'}) + +template ident*: expr = + ## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier + sequence(charSet({'a'..'z', 'A'..'Z', '_'}), + *charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})) + +template natural*: expr = + ## same as ``\d+`` + +digits + +# ------------------------- debugging ----------------------------------------- + +proc esc(c: char, reserved = {'\0'..'\255'}): string = + case c + of '\b': result = "\\b" + of '\t': result = "\\t" + of '\c': result = "\\c" + of '\L': result = "\\l" + of '\v': result = "\\v" + of '\f': result = "\\f" + of '\e': result = "\\e" + of '\a': result = "\\a" + of '\\': result = "\\\\" + of 'a'..'z', 'A'..'Z', '0'..'9', '_': result = $c + elif c < ' ' or c >= '\128': result = '\\' & $ord(c) + elif c in reserved: result = '\\' & c + else: result = $c + +proc singleQuoteEsc(c: char): string = return "'" & esc(c, {'\''}) & "'" + +proc singleQuoteEsc(str: string): string = + result = "'" + for c in items(str): add result, esc(c, {'\''}) + add result, '\'' + +proc charSetEscAux(cc: set[char]): string = + const reserved = {'^', '-', ']'} + result = "" + var c1 = 0 + while c1 <= 0xff: + if chr(c1) in cc: + var c2 = c1 + while c2 < 0xff and chr(succ(c2)) in cc: inc(c2) + if c1 == c2: + add result, esc(chr(c1), reserved) + elif c2 == succ(c1): + add result, esc(chr(c1), reserved) & esc(chr(c2), reserved) + else: + add result, esc(chr(c1), reserved) & '-' & esc(chr(c2), reserved) + c1 = c2 + inc(c1) + +proc charSetEsc(cc: set[char]): string = + if card(cc) >= 128+64: + result = "[^" & charSetEscAux({'\1'..'\xFF'} - cc) & ']' + else: + result = '[' & charSetEscAux(cc) & ']' + +proc toStrAux(r: TPeg, res: var string) = + case r.kind + of pkEmpty: add(res, "()") + of pkAny: add(res, '.') + of pkAnyRune: add(res, '_') + of pkLetter: add(res, "\\letter") + of pkLower: add(res, "\\lower") + of pkUpper: add(res, "\\upper") + of pkTitle: add(res, "\\title") + of pkWhitespace: add(res, "\\white") + + of pkNewLine: add(res, "\\n") + of pkTerminal: add(res, singleQuoteEsc(r.term)) + of pkTerminalIgnoreCase: + add(res, 'i') + add(res, singleQuoteEsc(r.term)) + of pkTerminalIgnoreStyle: + add(res, 'y') + add(res, singleQuoteEsc(r.term)) + of pkChar: add(res, singleQuoteEsc(r.ch)) + of pkCharChoice: add(res, charSetEsc(r.charChoice[])) + of pkNonTerminal: add(res, r.nt.name) + of pkSequence: + add(res, '(') + toStrAux(r.sons[0], res) + for i in 1 .. high(r.sons): + add(res, ' ') + toStrAux(r.sons[i], res) + add(res, ')') + of pkOrderedChoice: + add(res, '(') + toStrAux(r.sons[0], res) + for i in 1 .. high(r.sons): + add(res, " / ") + toStrAux(r.sons[i], res) + add(res, ')') + of pkGreedyRep: + toStrAux(r.sons[0], res) + add(res, '*') + of pkGreedyRepChar: + add(res, singleQuoteEsc(r.ch)) + add(res, '*') + of pkGreedyRepSet: + add(res, charSetEsc(r.charChoice[])) + add(res, '*') + of pkGreedyAny: + add(res, ".*") + of pkOption: + toStrAux(r.sons[0], res) + add(res, '?') + of pkAndPredicate: + add(res, '&') + toStrAux(r.sons[0], res) + of pkNotPredicate: + add(res, '!') + toStrAux(r.sons[0], res) + of pkSearch: + add(res, '@') + toStrAux(r.sons[0], res) + of pkCapturedSearch: + add(res, "{@}") + toStrAux(r.sons[0], res) + of pkCapture: + add(res, '{') + toStrAux(r.sons[0], res) + add(res, '}') + of pkBackRef: + add(res, '$') + add(res, $r.index) + of pkBackRefIgnoreCase: + add(res, "i$") + add(res, $r.index) + of pkBackRefIgnoreStyle: + add(res, "y$") + add(res, $r.index) + of pkRule: + toStrAux(r.sons[0], res) + add(res, " <- ") + toStrAux(r.sons[1], res) + of pkList: + for i in 0 .. high(r.sons): + toStrAux(r.sons[i], res) + add(res, "\n") + of pkStartAnchor: + add(res, '^') + +proc `$` *(r: TPeg): string {.nosideEffect, rtl, extern: "npegsToString".} = + ## converts a PEG to its string representation + result = "" + toStrAux(r, result) + +# --------------------- core engine ------------------------------------------- + +type + Captures* = object ## contains the captured substrings. + matches: array[0..MaxSubpatterns-1, tuple[first, last: int]] + ml: int + origStart: int + +{.deprecated: [TCaptures: Captures].} + +proc bounds*(c: Captures, + i: range[0..MaxSubpatterns-1]): tuple[first, last: int] = + ## returns the bounds ``[first..last]`` of the `i`'th capture. + result = c.matches[i] + +when not useUnicode: + type + TRune = char + template fastRuneAt(s, i, ch: expr) = + ch = s[i] + inc(i) + template runeLenAt(s, i: expr): expr = 1 + + proc isAlpha(a: char): bool {.inline.} = return a in {'a'..'z','A'..'Z'} + proc isUpper(a: char): bool {.inline.} = return a in {'A'..'Z'} + proc isLower(a: char): bool {.inline.} = return a in {'a'..'z'} + proc isTitle(a: char): bool {.inline.} = return false + proc isWhiteSpace(a: char): bool {.inline.} = return a in {' ', '\9'..'\13'} + +proc rawMatch*(s: string, p: TPeg, start: int, c: var Captures): int {. + nosideEffect, rtl, extern: "npegs$1".} = + ## low-level matching proc that implements the PEG interpreter. Use this + ## for maximum efficiency (every other PEG operation ends up calling this + ## proc). + ## Returns -1 if it does not match, else the length of the match + case p.kind + of pkEmpty: result = 0 # match of length 0 + of pkAny: + if s[start] != '\0': result = 1 + else: result = -1 + of pkAnyRune: + if s[start] != '\0': + result = runeLenAt(s, start) + else: + result = -1 + of pkLetter: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isAlpha(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkLower: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isLower(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkUpper: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isUpper(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkTitle: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isTitle(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkWhitespace: + if s[start] != '\0': + var a: Rune + result = start + fastRuneAt(s, result, a) + if isWhiteSpace(a): dec(result, start) + else: result = -1 + else: + result = -1 + of pkGreedyAny: + result = len(s) - start + of pkNewLine: + if s[start] == '\L': result = 1 + elif s[start] == '\C': + if s[start+1] == '\L': result = 2 + else: result = 1 + else: result = -1 + of pkTerminal: + result = len(p.term) + for i in 0..result-1: + if p.term[i] != s[start+i]: + result = -1 + break + of pkTerminalIgnoreCase: + var + i = 0 + a, b: Rune + result = start + while i < len(p.term): + fastRuneAt(p.term, i, a) + fastRuneAt(s, result, b) + if toLower(a) != toLower(b): + result = -1 + break + dec(result, start) + of pkTerminalIgnoreStyle: + var + i = 0 + a, b: Rune + result = start + while i < len(p.term): + while true: + fastRuneAt(p.term, i, a) + if a != Rune('_'): break + while true: + fastRuneAt(s, result, b) + if b != Rune('_'): break + if toLower(a) != toLower(b): + result = -1 + break + dec(result, start) + of pkChar: + if p.ch == s[start]: result = 1 + else: result = -1 + of pkCharChoice: + if contains(p.charChoice[], s[start]): result = 1 + else: result = -1 + of pkNonTerminal: + var oldMl = c.ml + when false: echo "enter: ", p.nt.name + result = rawMatch(s, p.nt.rule, start, c) + when false: echo "leave: ", p.nt.name + if result < 0: c.ml = oldMl + of pkSequence: + var oldMl = c.ml + result = 0 + for i in 0..high(p.sons): + var x = rawMatch(s, p.sons[i], start+result, c) + if x < 0: + c.ml = oldMl + result = -1 + break + else: inc(result, x) + of pkOrderedChoice: + var oldMl = c.ml + for i in 0..high(p.sons): + result = rawMatch(s, p.sons[i], start, c) + if result >= 0: break + c.ml = oldMl + of pkSearch: + var oldMl = c.ml + result = 0 + while start+result < s.len: + var x = rawMatch(s, p.sons[0], start+result, c) + if x >= 0: + inc(result, x) + return + inc(result) + result = -1 + c.ml = oldMl + of pkCapturedSearch: + var idx = c.ml # reserve a slot for the subpattern + inc(c.ml) + result = 0 + while start+result < s.len: + var x = rawMatch(s, p.sons[0], start+result, c) + if x >= 0: + if idx < MaxSubpatterns: + c.matches[idx] = (start, start+result-1) + #else: silently ignore the capture + inc(result, x) + return + inc(result) + result = -1 + c.ml = idx + of pkGreedyRep: + result = 0 + while true: + var x = rawMatch(s, p.sons[0], start+result, c) + # if x == 0, we have an endless loop; so the correct behaviour would be + # not to break. But endless loops can be easily introduced: + # ``(comment / \w*)*`` is such an example. Breaking for x == 0 does the + # expected thing in this case. + if x <= 0: break + inc(result, x) + of pkGreedyRepChar: + result = 0 + var ch = p.ch + while ch == s[start+result]: inc(result) + of pkGreedyRepSet: + result = 0 + while contains(p.charChoice[], s[start+result]): inc(result) + of pkOption: + result = max(0, rawMatch(s, p.sons[0], start, c)) + of pkAndPredicate: + var oldMl = c.ml + result = rawMatch(s, p.sons[0], start, c) + if result >= 0: result = 0 # do not consume anything + else: c.ml = oldMl + of pkNotPredicate: + var oldMl = c.ml + result = rawMatch(s, p.sons[0], start, c) + if result < 0: result = 0 + else: + c.ml = oldMl + result = -1 + of pkCapture: + var idx = c.ml # reserve a slot for the subpattern + inc(c.ml) + result = rawMatch(s, p.sons[0], start, c) + if result >= 0: + if idx < MaxSubpatterns: + c.matches[idx] = (start, start+result-1) + #else: silently ignore the capture + else: + c.ml = idx + of pkBackRef..pkBackRefIgnoreStyle: + if p.index >= c.ml: return -1 + var (a, b) = c.matches[p.index] + var n: TPeg + n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef)) + n.term = s.substr(a, b) + result = rawMatch(s, n, start, c) + of pkStartAnchor: + if c.origStart == start: result = 0 + else: result = -1 + of pkRule, pkList: assert false + +template fillMatches(s, caps, c: expr) = + for k in 0..c.ml-1: + caps[k] = substr(s, c.matches[k][0], c.matches[k][1]) + +proc match*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = + ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and + ## the captured substrings in the array ``matches``. If it does not + ## match, nothing is written into ``matches`` and ``false`` is + ## returned. + var c: Captures + c.origStart = start + result = rawMatch(s, pattern, start, c) == len(s) - start + if result: fillMatches(s, matches, c) + +proc match*(s: string, pattern: TPeg, + start = 0): bool {.nosideEffect, rtl, extern: "npegs$1".} = + ## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``. + var c: Captures + c.origStart = start + result = rawMatch(s, pattern, start, c) == len(s)-start + +proc matchLen*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = + ## the same as ``match``, but it returns the length of the match, + ## if there is no match, -1 is returned. Note that a match length + ## of zero can happen. It's possible that a suffix of `s` remains + ## that does not belong to the match. + var c: Captures + c.origStart = start + result = rawMatch(s, pattern, start, c) + if result >= 0: fillMatches(s, matches, c) + +proc matchLen*(s: string, pattern: TPeg, + start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} = + ## the same as ``match``, but it returns the length of the match, + ## if there is no match, -1 is returned. Note that a match length + ## of zero can happen. It's possible that a suffix of `s` remains + ## that does not belong to the match. + var c: Captures + c.origStart = start + result = rawMatch(s, pattern, start, c) + +proc find*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): int {.nosideEffect, rtl, extern: "npegs$1Capture".} = + ## returns the starting position of ``pattern`` in ``s`` and the captured + ## substrings in the array ``matches``. If it does not match, nothing + ## is written into ``matches`` and -1 is returned. + var c: Captures + c.origStart = start + for i in start .. s.len-1: + c.ml = 0 + if rawMatch(s, pattern, i, c) >= 0: + fillMatches(s, matches, c) + return i + return -1 + # could also use the pattern here: (!P .)* P + +proc findBounds*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): tuple[first, last: int] {. + nosideEffect, rtl, extern: "npegs$1Capture".} = + ## returns the starting position and end position of ``pattern`` in ``s`` + ## and the captured + ## substrings in the array ``matches``. If it does not match, nothing + ## is written into ``matches`` and (-1,0) is returned. + var c: Captures + c.origStart = start + for i in start .. s.len-1: + c.ml = 0 + var L = rawMatch(s, pattern, i, c) + if L >= 0: + fillMatches(s, matches, c) + return (i, i+L-1) + return (-1, 0) + +proc find*(s: string, pattern: TPeg, + start = 0): int {.nosideEffect, rtl, extern: "npegs$1".} = + ## returns the starting position of ``pattern`` in ``s``. If it does not + ## match, -1 is returned. + var c: Captures + c.origStart = start + for i in start .. s.len-1: + if rawMatch(s, pattern, i, c) >= 0: return i + return -1 + +iterator findAll*(s: string, pattern: TPeg, start = 0): string = + ## yields all matching *substrings* of `s` that match `pattern`. + var c: Captures + c.origStart = start + var i = start + while i < s.len: + c.ml = 0 + var L = rawMatch(s, pattern, i, c) + if L < 0: + inc(i, 1) + else: + yield substr(s, i, i+L-1) + inc(i, L) + +proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {. + nosideEffect, rtl, extern: "npegs$1".} = + ## returns all matching *substrings* of `s` that match `pattern`. + ## If it does not match, @[] is returned. + accumulateResult(findAll(s, pattern, start)) + +when not defined(nimhygiene): + {.pragma: inject.} + +template `=~`*(s: string, pattern: TPeg): bool = + ## This calls ``match`` with an implicit declared ``matches`` array that + ## can be used in the scope of the ``=~`` call: + ## + ## .. code-block:: nim + ## + ## if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}": + ## # matches a key=value pair: + ## echo("Key: ", matches[0]) + ## echo("Value: ", matches[1]) + ## elif line =~ peg"\s*{'#'.*}": + ## # matches a comment + ## # note that the implicit ``matches`` array is different from the + ## # ``matches`` array of the first branch + ## echo("comment: ", matches[0]) + ## else: + ## echo("syntax error") + ## + bind MaxSubpatterns + when not declaredInScope(matches): + var matches {.inject.}: array[0..MaxSubpatterns-1, string] + match(s, pattern, matches) + +# ------------------------- more string handling ------------------------------ + +proc contains*(s: string, pattern: TPeg, start = 0): bool {. + nosideEffect, rtl, extern: "npegs$1".} = + ## same as ``find(s, pattern, start) >= 0`` + return find(s, pattern, start) >= 0 + +proc contains*(s: string, pattern: TPeg, matches: var openArray[string], + start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} = + ## same as ``find(s, pattern, matches, start) >= 0`` + return find(s, pattern, matches, start) >= 0 + +proc startsWith*(s: string, prefix: TPeg, start = 0): bool {. + nosideEffect, rtl, extern: "npegs$1".} = + ## returns true if `s` starts with the pattern `prefix` + result = matchLen(s, prefix, start) >= 0 + +proc endsWith*(s: string, suffix: TPeg, start = 0): bool {. + nosideEffect, rtl, extern: "npegs$1".} = + ## returns true if `s` ends with the pattern `prefix` + var c: Captures + c.origStart = start + for i in start .. s.len-1: + if rawMatch(s, suffix, i, c) == s.len - i: return true + +proc replacef*(s: string, sub: TPeg, by: string): string {. + nosideEffect, rtl, extern: "npegs$1".} = + ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by` + ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples: + ## + ## .. code-block:: nim + ## "var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2") + ## + ## Results in: + ## + ## .. code-block:: nim + ## + ## "var1<-keykey; val2<-key2key2" + result = "" + var i = 0 + var caps: array[0..MaxSubpatterns-1, string] + var c: Captures + while i < s.len: + c.ml = 0 + var x = rawMatch(s, sub, i, c) + if x <= 0: + add(result, s[i]) + inc(i) + else: + fillMatches(s, caps, c) + addf(result, by, caps) + inc(i, x) + add(result, substr(s, i)) + +proc replace*(s: string, sub: TPeg, by = ""): string {. + nosideEffect, rtl, extern: "npegs$1".} = + ## Replaces `sub` in `s` by the string `by`. Captures cannot be accessed + ## in `by`. + result = "" + var i = 0 + var c: Captures + while i < s.len: + var x = rawMatch(s, sub, i, c) + if x <= 0: + add(result, s[i]) + inc(i) + else: + add(result, by) + inc(i, x) + add(result, substr(s, i)) + +proc parallelReplace*(s: string, subs: varargs[ + tuple[pattern: TPeg, repl: string]]): string {. + nosideEffect, rtl, extern: "npegs$1".} = + ## Returns a modified copy of `s` with the substitutions in `subs` + ## applied in parallel. + result = "" + var i = 0 + var c: Captures + var caps: array[0..MaxSubpatterns-1, string] + while i < s.len: + block searchSubs: + for j in 0..high(subs): + c.ml = 0 + var x = rawMatch(s, subs[j][0], i, c) + if x > 0: + fillMatches(s, caps, c) + addf(result, subs[j][1], caps) + inc(i, x) + break searchSubs + add(result, s[i]) + inc(i) + # copy the rest: + add(result, substr(s, i)) + +proc transformFile*(infile, outfile: string, + subs: varargs[tuple[pattern: TPeg, repl: string]]) {. + rtl, extern: "npegs$1".} = + ## reads in the file `infile`, performs a parallel replacement (calls + ## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an + ## error occurs. This is supposed to be used for quick scripting. + var x = readFile(infile).string + writeFile(outfile, x.parallelReplace(subs)) + +iterator split*(s: string, sep: TPeg): string = + ## Splits the string `s` into substrings. + ## + ## Substrings are separated by the PEG `sep`. + ## Examples: + ## + ## .. code-block:: nim + ## for word in split("00232this02939is39an22example111", peg"\d+"): + ## writeln(stdout, word) + ## + ## Results in: + ## + ## .. code-block:: nim + ## "this" + ## "is" + ## "an" + ## "example" + ## + var c: Captures + var + first = 0 + last = 0 + while last < len(s): + c.ml = 0 + var x = rawMatch(s, sep, last, c) + if x > 0: inc(last, x) + first = last + while last < len(s): + inc(last) + c.ml = 0 + x = rawMatch(s, sep, last, c) + if x > 0: break + if first < last: + yield substr(s, first, last-1) + +proc split*(s: string, sep: TPeg): seq[string] {. + nosideEffect, rtl, extern: "npegs$1".} = + ## Splits the string `s` into substrings. + accumulateResult(split(s, sep)) + +# ------------------- scanner ------------------------------------------------- + +type + TModifier = enum + modNone, + modVerbatim, + modIgnoreCase, + modIgnoreStyle + TTokKind = enum ## enumeration of all tokens + tkInvalid, ## invalid token + tkEof, ## end of file reached + tkAny, ## . + tkAnyRune, ## _ + tkIdentifier, ## abc + tkStringLit, ## "abc" or 'abc' + tkCharSet, ## [^A-Z] + tkParLe, ## '(' + tkParRi, ## ')' + tkCurlyLe, ## '{' + tkCurlyRi, ## '}' + tkCurlyAt, ## '{@}' + tkArrow, ## '<-' + tkBar, ## '/' + tkStar, ## '*' + tkPlus, ## '+' + tkAmp, ## '&' + tkNot, ## '!' + tkOption, ## '?' + tkAt, ## '@' + tkBuiltin, ## \identifier + tkEscaped, ## \\ + tkBackref, ## '$' + tkDollar, ## '$' + tkHat ## '^' + + TToken {.final.} = object ## a token + kind: TTokKind ## the type of the token + modifier: TModifier + literal: string ## the parsed (string) literal + charset: set[char] ## if kind == tkCharSet + index: int ## if kind == tkBackref + + PegLexer {.inheritable.} = object ## the lexer object. + bufpos: int ## the current position within the buffer + buf: cstring ## the buffer itself + lineNumber: int ## the current line number + lineStart: int ## index of last line start in buffer + colOffset: int ## column to add + filename: string + +const + tokKindToStr: array[TTokKind, string] = [ + "invalid", "[EOF]", ".", "_", "identifier", "string literal", + "character set", "(", ")", "{", "}", "{@}", + "<-", "/", "*", "+", "&", "!", "?", + "@", "built-in", "escaped", "$", "$", "^" + ] + +proc handleCR(L: var PegLexer, pos: int): int = + assert(L.buf[pos] == '\c') + inc(L.lineNumber) + result = pos+1 + if L.buf[result] == '\L': inc(result) + L.lineStart = result + +proc handleLF(L: var PegLexer, pos: int): int = + assert(L.buf[pos] == '\L') + inc(L.lineNumber) + result = pos+1 + L.lineStart = result + +proc init(L: var PegLexer, input, filename: string, line = 1, col = 0) = + L.buf = input + L.bufpos = 0 + L.lineNumber = line + L.colOffset = col + L.lineStart = 0 + L.filename = filename + +proc getColumn(L: PegLexer): int {.inline.} = + result = abs(L.bufpos - L.lineStart) + L.colOffset + +proc getLine(L: PegLexer): int {.inline.} = + result = L.lineNumber + +proc errorStr(L: PegLexer, msg: string, line = -1, col = -1): string = + var line = if line < 0: getLine(L) else: line + var col = if col < 0: getColumn(L) else: col + result = "$1($2, $3) Error: $4" % [L.filename, $line, $col, msg] + +proc handleHexChar(c: var PegLexer, xi: var int) = + case c.buf[c.bufpos] + of '0'..'9': + xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0')) + inc(c.bufpos) + of 'a'..'f': + xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('a') + 10) + inc(c.bufpos) + of 'A'..'F': + xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10) + inc(c.bufpos) + else: discard + +proc getEscapedChar(c: var PegLexer, tok: var TToken) = + inc(c.bufpos) + case c.buf[c.bufpos] + of 'r', 'R', 'c', 'C': + add(tok.literal, '\c') + inc(c.bufpos) + of 'l', 'L': + add(tok.literal, '\L') + inc(c.bufpos) + of 'f', 'F': + add(tok.literal, '\f') + inc(c.bufpos) + of 'e', 'E': + add(tok.literal, '\e') + inc(c.bufpos) + of 'a', 'A': + add(tok.literal, '\a') + inc(c.bufpos) + of 'b', 'B': + add(tok.literal, '\b') + inc(c.bufpos) + of 'v', 'V': + add(tok.literal, '\v') + inc(c.bufpos) + of 't', 'T': + add(tok.literal, '\t') + inc(c.bufpos) + of 'x', 'X': + inc(c.bufpos) + var xi = 0 + handleHexChar(c, xi) + handleHexChar(c, xi) + if xi == 0: tok.kind = tkInvalid + else: add(tok.literal, chr(xi)) + of '0'..'9': + var val = ord(c.buf[c.bufpos]) - ord('0') + inc(c.bufpos) + var i = 1 + while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}): + val = val * 10 + ord(c.buf[c.bufpos]) - ord('0') + inc(c.bufpos) + inc(i) + if val > 0 and val <= 255: add(tok.literal, chr(val)) + else: tok.kind = tkInvalid + of '\0'..'\31': + tok.kind = tkInvalid + elif c.buf[c.bufpos] in strutils.Letters: + tok.kind = tkInvalid + else: + add(tok.literal, c.buf[c.bufpos]) + inc(c.bufpos) + +proc skip(c: var PegLexer) = + var pos = c.bufpos + var buf = c.buf + while true: + case buf[pos] + of ' ', '\t': + inc(pos) + of '#': + while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos) + of '\c': + pos = handleCR(c, pos) + buf = c.buf + of '\L': + pos = handleLF(c, pos) + buf = c.buf + else: + break # EndOfFile also leaves the loop + c.bufpos = pos + +proc getString(c: var PegLexer, tok: var TToken) = + tok.kind = tkStringLit + var pos = c.bufpos + 1 + var buf = c.buf + var quote = buf[pos-1] + while true: + case buf[pos] + of '\\': + c.bufpos = pos + getEscapedChar(c, tok) + pos = c.bufpos + of '\c', '\L', '\0': + tok.kind = tkInvalid + break + elif buf[pos] == quote: + inc(pos) + break + else: + add(tok.literal, buf[pos]) + inc(pos) + c.bufpos = pos + +proc getDollar(c: var PegLexer, tok: var TToken) = + var pos = c.bufpos + 1 + var buf = c.buf + if buf[pos] in {'0'..'9'}: + tok.kind = tkBackref + tok.index = 0 + while buf[pos] in {'0'..'9'}: + tok.index = tok.index * 10 + ord(buf[pos]) - ord('0') + inc(pos) + else: + tok.kind = tkDollar + c.bufpos = pos + +proc getCharSet(c: var PegLexer, tok: var TToken) = + tok.kind = tkCharSet + tok.charset = {} + var pos = c.bufpos + 1 + var buf = c.buf + var caret = false + if buf[pos] == '^': + inc(pos) + caret = true + while true: + var ch: char + case buf[pos] + of ']': + inc(pos) + break + of '\\': + c.bufpos = pos + getEscapedChar(c, tok) + pos = c.bufpos + ch = tok.literal[tok.literal.len-1] + of '\C', '\L', '\0': + tok.kind = tkInvalid + break + else: + ch = buf[pos] + inc(pos) + incl(tok.charset, ch) + if buf[pos] == '-': + if buf[pos+1] == ']': + incl(tok.charset, '-') + inc(pos) + else: + inc(pos) + var ch2: char + case buf[pos] + of '\\': + c.bufpos = pos + getEscapedChar(c, tok) + pos = c.bufpos + ch2 = tok.literal[tok.literal.len-1] + of '\C', '\L', '\0': + tok.kind = tkInvalid + break + else: + ch2 = buf[pos] + inc(pos) + for i in ord(ch)+1 .. ord(ch2): + incl(tok.charset, chr(i)) + c.bufpos = pos + if caret: tok.charset = {'\1'..'\xFF'} - tok.charset + +proc getSymbol(c: var PegLexer, tok: var TToken) = + var pos = c.bufpos + var buf = c.buf + while true: + add(tok.literal, buf[pos]) + inc(pos) + if buf[pos] notin strutils.IdentChars: break + c.bufpos = pos + tok.kind = tkIdentifier + +proc getBuiltin(c: var PegLexer, tok: var TToken) = + if c.buf[c.bufpos+1] in strutils.Letters: + inc(c.bufpos) + getSymbol(c, tok) + tok.kind = tkBuiltin + else: + tok.kind = tkEscaped + getEscapedChar(c, tok) # may set tok.kind to tkInvalid + +proc getTok(c: var PegLexer, tok: var TToken) = + tok.kind = tkInvalid + tok.modifier = modNone + setLen(tok.literal, 0) + skip(c) + case c.buf[c.bufpos] + of '{': + inc(c.bufpos) + if c.buf[c.bufpos] == '@' and c.buf[c.bufpos+1] == '}': + tok.kind = tkCurlyAt + inc(c.bufpos, 2) + add(tok.literal, "{@}") + else: + tok.kind = tkCurlyLe + add(tok.literal, '{') + of '}': + tok.kind = tkCurlyRi + inc(c.bufpos) + add(tok.literal, '}') + of '[': + getCharSet(c, tok) + of '(': + tok.kind = tkParLe + inc(c.bufpos) + add(tok.literal, '(') + of ')': + tok.kind = tkParRi + inc(c.bufpos) + add(tok.literal, ')') + of '.': + tok.kind = tkAny + inc(c.bufpos) + add(tok.literal, '.') + of '_': + tok.kind = tkAnyRune + inc(c.bufpos) + add(tok.literal, '_') + of '\\': + getBuiltin(c, tok) + of '\'', '"': getString(c, tok) + of '$': getDollar(c, tok) + of '\0': + tok.kind = tkEof + tok.literal = "[EOF]" + of 'a'..'z', 'A'..'Z', '\128'..'\255': + getSymbol(c, tok) + if c.buf[c.bufpos] in {'\'', '"'} or + c.buf[c.bufpos] == '$' and c.buf[c.bufpos+1] in {'0'..'9'}: + case tok.literal + of "i": tok.modifier = modIgnoreCase + of "y": tok.modifier = modIgnoreStyle + of "v": tok.modifier = modVerbatim + else: discard + setLen(tok.literal, 0) + if c.buf[c.bufpos] == '$': + getDollar(c, tok) + else: + getString(c, tok) + if tok.modifier == modNone: tok.kind = tkInvalid + of '+': + tok.kind = tkPlus + inc(c.bufpos) + add(tok.literal, '+') + of '*': + tok.kind = tkStar + inc(c.bufpos) + add(tok.literal, '+') + of '<': + if c.buf[c.bufpos+1] == '-': + inc(c.bufpos, 2) + tok.kind = tkArrow + add(tok.literal, "<-") + else: + add(tok.literal, '<') + of '/': + tok.kind = tkBar + inc(c.bufpos) + add(tok.literal, '/') + of '?': + tok.kind = tkOption + inc(c.bufpos) + add(tok.literal, '?') + of '!': + tok.kind = tkNot + inc(c.bufpos) + add(tok.literal, '!') + of '&': + tok.kind = tkAmp + inc(c.bufpos) + add(tok.literal, '!') + of '@': + tok.kind = tkAt + inc(c.bufpos) + add(tok.literal, '@') + if c.buf[c.bufpos] == '@': + tok.kind = tkCurlyAt + inc(c.bufpos) + add(tok.literal, '@') + of '^': + tok.kind = tkHat + inc(c.bufpos) + add(tok.literal, '^') + else: + add(tok.literal, c.buf[c.bufpos]) + inc(c.bufpos) + +proc arrowIsNextTok(c: PegLexer): bool = + # the only look ahead we need + var pos = c.bufpos + while c.buf[pos] in {'\t', ' '}: inc(pos) + result = c.buf[pos] == '<' and c.buf[pos+1] == '-' + +# ----------------------------- parser ---------------------------------------- + +type + EInvalidPeg* = object of ValueError ## raised if an invalid + ## PEG has been detected + PegParser = object of PegLexer ## the PEG parser object + tok: TToken + nonterms: seq[PNonTerminal] + modifier: TModifier + captures: int + identIsVerbatim: bool + skip: TPeg + +proc pegError(p: PegParser, msg: string, line = -1, col = -1) = + var e: ref EInvalidPeg + new(e) + e.msg = errorStr(p, msg, line, col) + raise e + +proc getTok(p: var PegParser) = + getTok(p, p.tok) + if p.tok.kind == tkInvalid: pegError(p, "invalid token") + +proc eat(p: var PegParser, kind: TTokKind) = + if p.tok.kind == kind: getTok(p) + else: pegError(p, tokKindToStr[kind] & " expected") + +proc parseExpr(p: var PegParser): TPeg + +proc getNonTerminal(p: var PegParser, name: string): PNonTerminal = + for i in 0..high(p.nonterms): + result = p.nonterms[i] + if cmpIgnoreStyle(result.name, name) == 0: return + # forward reference: + result = newNonTerminal(name, getLine(p), getColumn(p)) + add(p.nonterms, result) + +proc modifiedTerm(s: string, m: TModifier): TPeg = + case m + of modNone, modVerbatim: result = term(s) + of modIgnoreCase: result = termIgnoreCase(s) + of modIgnoreStyle: result = termIgnoreStyle(s) + +proc modifiedBackref(s: int, m: TModifier): TPeg = + case m + of modNone, modVerbatim: result = backref(s) + of modIgnoreCase: result = backrefIgnoreCase(s) + of modIgnoreStyle: result = backrefIgnoreStyle(s) + +proc builtin(p: var PegParser): TPeg = + # do not use "y", "skip" or "i" as these would be ambiguous + case p.tok.literal + of "n": result = newLine() + of "d": result = charSet({'0'..'9'}) + of "D": result = charSet({'\1'..'\xff'} - {'0'..'9'}) + of "s": result = charSet({' ', '\9'..'\13'}) + of "S": result = charSet({'\1'..'\xff'} - {' ', '\9'..'\13'}) + of "w": result = charSet({'a'..'z', 'A'..'Z', '_', '0'..'9'}) + of "W": result = charSet({'\1'..'\xff'} - {'a'..'z','A'..'Z','_','0'..'9'}) + of "a": result = charSet({'a'..'z', 'A'..'Z'}) + of "A": result = charSet({'\1'..'\xff'} - {'a'..'z', 'A'..'Z'}) + of "ident": result = pegs.ident + of "letter": result = unicodeLetter() + of "upper": result = unicodeUpper() + of "lower": result = unicodeLower() + of "title": result = unicodeTitle() + of "white": result = unicodeWhitespace() + else: pegError(p, "unknown built-in: " & p.tok.literal) + +proc token(terminal: TPeg, p: PegParser): TPeg = + if p.skip.kind == pkEmpty: result = terminal + else: result = sequence(p.skip, terminal) + +proc primary(p: var PegParser): TPeg = + case p.tok.kind + of tkAmp: + getTok(p) + return &primary(p) + of tkNot: + getTok(p) + return !primary(p) + of tkAt: + getTok(p) + return !*primary(p) + of tkCurlyAt: + getTok(p) + return !*\primary(p).token(p) + else: discard + case p.tok.kind + of tkIdentifier: + if p.identIsVerbatim: + var m = p.tok.modifier + if m == modNone: m = p.modifier + result = modifiedTerm(p.tok.literal, m).token(p) + getTok(p) + elif not arrowIsNextTok(p): + var nt = getNonTerminal(p, p.tok.literal) + incl(nt.flags, ntUsed) + result = nonterminal(nt).token(p) + getTok(p) + else: + pegError(p, "expression expected, but found: " & p.tok.literal) + of tkStringLit: + var m = p.tok.modifier + if m == modNone: m = p.modifier + result = modifiedTerm(p.tok.literal, m).token(p) + getTok(p) + of tkCharSet: + if '\0' in p.tok.charset: + pegError(p, "binary zero ('\\0') not allowed in character class") + result = charSet(p.tok.charset).token(p) + getTok(p) + of tkParLe: + getTok(p) + result = parseExpr(p) + eat(p, tkParRi) + of tkCurlyLe: + getTok(p) + result = capture(parseExpr(p)).token(p) + eat(p, tkCurlyRi) + inc(p.captures) + of tkAny: + result = any().token(p) + getTok(p) + of tkAnyRune: + result = anyRune().token(p) + getTok(p) + of tkBuiltin: + result = builtin(p).token(p) + getTok(p) + of tkEscaped: + result = term(p.tok.literal[0]).token(p) + getTok(p) + of tkDollar: + result = endAnchor() + getTok(p) + of tkHat: + result = startAnchor() + getTok(p) + of tkBackref: + var m = p.tok.modifier + if m == modNone: m = p.modifier + result = modifiedBackref(p.tok.index, m).token(p) + if p.tok.index < 0 or p.tok.index > p.captures: + pegError(p, "invalid back reference index: " & $p.tok.index) + getTok(p) + else: + pegError(p, "expression expected, but found: " & p.tok.literal) + getTok(p) # we must consume a token here to prevent endless loops! + while true: + case p.tok.kind + of tkOption: + result = ?result + getTok(p) + of tkStar: + result = *result + getTok(p) + of tkPlus: + result = +result + getTok(p) + else: break + +proc seqExpr(p: var PegParser): TPeg = + result = primary(p) + while true: + case p.tok.kind + of tkAmp, tkNot, tkAt, tkStringLit, tkCharSet, tkParLe, tkCurlyLe, + tkAny, tkAnyRune, tkBuiltin, tkEscaped, tkDollar, tkBackref, + tkHat, tkCurlyAt: + result = sequence(result, primary(p)) + of tkIdentifier: + if not arrowIsNextTok(p): + result = sequence(result, primary(p)) + else: break + else: break + +proc parseExpr(p: var PegParser): TPeg = + result = seqExpr(p) + while p.tok.kind == tkBar: + getTok(p) + result = result / seqExpr(p) + +proc parseRule(p: var PegParser): PNonTerminal = + if p.tok.kind == tkIdentifier and arrowIsNextTok(p): + result = getNonTerminal(p, p.tok.literal) + if ntDeclared in result.flags: + pegError(p, "attempt to redefine: " & result.name) + result.line = getLine(p) + result.col = getColumn(p) + getTok(p) + eat(p, tkArrow) + result.rule = parseExpr(p) + incl(result.flags, ntDeclared) # NOW inlining may be attempted + else: + pegError(p, "rule expected, but found: " & p.tok.literal) + +proc rawParse(p: var PegParser): TPeg = + ## parses a rule or a PEG expression + while p.tok.kind == tkBuiltin: + case p.tok.literal + of "i": + p.modifier = modIgnoreCase + getTok(p) + of "y": + p.modifier = modIgnoreStyle + getTok(p) + of "skip": + getTok(p) + p.skip = ?primary(p) + else: break + if p.tok.kind == tkIdentifier and arrowIsNextTok(p): + result = parseRule(p).rule + while p.tok.kind != tkEof: + discard parseRule(p) + else: + p.identIsVerbatim = true + result = parseExpr(p) + if p.tok.kind != tkEof: + pegError(p, "EOF expected, but found: " & p.tok.literal) + for i in 0..high(p.nonterms): + var nt = p.nonterms[i] + if ntDeclared notin nt.flags: + pegError(p, "undeclared identifier: " & nt.name, nt.line, nt.col) + elif ntUsed notin nt.flags and i > 0: + pegError(p, "unused rule: " & nt.name, nt.line, nt.col) + +proc parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): TPeg = + ## constructs a Peg object from `pattern`. `filename`, `line`, `col` are + ## used for error messages, but they only provide start offsets. `parsePeg` + ## keeps track of line and column numbers within `pattern`. + var p: PegParser + init(PegLexer(p), pattern, filename, line, col) + p.tok.kind = tkInvalid + p.tok.modifier = modNone + p.tok.literal = "" + p.tok.charset = {} + p.nonterms = @[] + p.identIsVerbatim = false + getTok(p) + result = rawParse(p) + +proc peg*(pattern: string): TPeg = + ## constructs a Peg object from the `pattern`. The short name has been + ## chosen to encourage its use as a raw string modifier:: + ## + ## peg"{\ident} \s* '=' \s* {.*}" + result = parsePeg(pattern, "pattern") + +proc escapePeg*(s: string): string = + ## escapes `s` so that it is matched verbatim when used as a peg. + result = "" + var inQuote = false + for c in items(s): + case c + of '\0'..'\31', '\'', '"', '\\': + if inQuote: + result.add('\'') + inQuote = false + result.add("\\x") + result.add(toHex(ord(c), 2)) + else: + if not inQuote: + result.add('\'') + inQuote = true + result.add(c) + if inQuote: result.add('\'') + +when isMainModule: + assert escapePeg("abc''def'") == r"'abc'\x27\x27'def'\x27" + assert match("(a b c)", peg"'(' @ ')'") + assert match("W_HI_Le", peg"\y 'while'") + assert(not match("W_HI_L", peg"\y 'while'")) + assert(not match("W_HI_Le", peg"\y v'while'")) + assert match("W_HI_Le", peg"y'while'") + + assert($ +digits == $peg"\d+") + assert "0158787".match(peg"\d+") + assert "ABC 0232".match(peg"\w+\s+\d+") + assert "ABC".match(peg"\d+ / \w+") + + for word in split("00232this02939is39an22example111", peg"\d+"): + writeln(stdout, word) + + assert matchLen("key", ident) == 3 + + var pattern = sequence(ident, *whitespace, term('='), *whitespace, ident) + assert matchLen("key1= cal9", pattern) == 11 + + var ws = newNonTerminal("ws", 1, 1) + ws.rule = *whitespace + + var expr = newNonTerminal("expr", 1, 1) + expr.rule = sequence(capture(ident), *sequence( + nonterminal(ws), term('+'), nonterminal(ws), nonterminal(expr))) + + var c: Captures + var s = "a+b + c +d+e+f" + assert rawMatch(s, expr.rule, 0, c) == len(s) + var a = "" + for i in 0..c.ml-1: + a.add(substr(s, c.matches[i][0], c.matches[i][1])) + assert a == "abcdef" + #echo expr.rule + + #const filename = "lib/devel/peg/grammar.txt" + #var grammar = parsePeg(newFileStream(filename, fmRead), filename) + #echo "a <- [abc]*?".match(grammar) + assert find("_____abc_______", term("abc"), 2) == 5 + assert match("_______ana", peg"A <- 'ana' / . A") + assert match("abcs%%%", peg"A <- ..A / .A / '%'") + + var matches: array[0..MaxSubpatterns-1, string] + if "abc" =~ peg"{'a'}'bc' 'xyz' / {\ident}": + assert matches[0] == "abc" + else: + assert false + + var g2 = peg"""S <- A B / C D + A <- 'a'+ + B <- 'b'+ + C <- 'c'+ + D <- 'd'+ + """ + assert($g2 == "((A B) / (C D))") + assert match("cccccdddddd", g2) + assert("var1=key; var2=key2".replacef(peg"{\ident}'='{\ident}", "$1<-$2$2") == + "var1<-keykey; var2<-key2key2") + assert("var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2") == + "$1<-$2$2; $1<-$2$2") + assert "var1=key; var2=key2".endsWith(peg"{\ident}'='{\ident}") + + if "aaaaaa" =~ peg"'aa' !. / ({'a'})+": + assert matches[0] == "a" + else: + assert false + + if match("abcdefg", peg"c {d} ef {g}", matches, 2): + assert matches[0] == "d" + assert matches[1] == "g" + else: + assert false + + for x in findAll("abcdef", peg".", 3): + echo x + + for x in findAll("abcdef", peg"^{.}", 3): + assert x == "d" + + if "f(a, b)" =~ peg"{[0-9]+} / ({\ident} '(' {@} ')')": + assert matches[0] == "f" + assert matches[1] == "a, b" + else: + assert false + + assert match("eine übersicht und außerdem", peg"(\letter \white*)+") + # ß is not a lower cased letter?! + assert match("eine übersicht und auerdem", peg"(\lower \white*)+") + assert match("EINE ÜBERSICHT UND AUSSERDEM", peg"(\upper \white*)+") + assert(not match("456678", peg"(\letter)+")) + + assert("var1 = key; var2 = key2".replacef( + peg"\skip(\s*) {\ident}'='{\ident}", "$1<-$2$2") == + "var1<-keykey;var2<-key2key2") + + assert match("prefix/start", peg"^start$", 7) + From 12796b6c86444e253c5ba8ae9ec05e26bc0b4285 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 9 Sep 2014 20:40:24 +0200 Subject: [PATCH 105/409] nimfix cannot handle fileHandle vs FileHandle --- lib/system.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index 9153af16c..fe94ce95d 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2438,7 +2438,8 @@ when not defined(JS): #and not defined(NimrodVM): ## returns the OS file handle of the file ``f``. This is only useful for ## platform specific programming. - {.deprecated: [fileHandle: getFileHandle].} + when not defined(nimfix): + {.deprecated: [fileHandle: getFileHandle].} proc cstringArrayToSeq*(a: cstringArray, len: int): seq[string] = ## converts a ``cstringArray`` to a ``seq[string]``. `a` is supposed to be From 490371977e8ff61ccebe505b33edada0d674ac25 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 9 Sep 2014 21:31:34 +0200 Subject: [PATCH 106/409] some improvements for nimfix --- compiler/lookups.nim | 10 ++++++++++ compiler/main.nim | 3 --- compiler/pretty.nim | 2 +- compiler/prettybase.nim | 20 +++++++++++++++++--- compiler/semexprs.nim | 6 +++--- compiler/semtypes.nim | 7 ++++++- doc/advopt.txt | 1 - lib/windows/winlean.nim | 2 +- 8 files changed, 38 insertions(+), 13 deletions(-) diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 466ac824a..dbd03c87d 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -376,3 +376,13 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = n.sons[0].sym.name, o.inSymChoice).skipAlias(n) if result != nil and result.kind == skStub: loadStub(result) + +proc pickSym*(c: PContext, n: PNode; kind: TSymKind; + flags: TSymFlags = {}): PSym = + var o: TOverloadIter + var a = initOverloadIter(o, c, n) + while a != nil: + if a.kind == kind and flags <= a.flags: + incl(a.flags, sfUsed) + return a + a = nextOverloadIter(o, c, n) diff --git a/compiler/main.nim b/compiler/main.nim index 47da96a03..5e4a0da76 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -306,9 +306,6 @@ proc mainCommand* = CommandCompileToLLVM() else: rawMessage(errInvalidCommandX, command) - of "pretty": - gCmd = cmdPretty - commandPretty() of "doc": gCmd = cmdDoc loadConfigs(DocConfig) diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 436181bbc..e6d2d7b70 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -41,7 +41,7 @@ proc overwriteFiles*() = f.write line.strip(leading = false, trailing = true) else: f.write line - f.write("\L") + f.write(gSourceFiles[i].newline) f.close except IOError: rawMessage(errCannotOpenFile, newFile) diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim index e3c1e6ae9..467f3d402 100644 --- a/compiler/prettybase.nim +++ b/compiler/prettybase.nim @@ -7,14 +7,14 @@ # distribution, for details about the copyright. # -import ast, msgs, strutils, idents +import ast, msgs, strutils, idents, lexbase, streams from os import splitFile type TSourceFile* = object lines*: seq[string] dirty*, isNimfixFile*: bool - fullpath*: string + fullpath*, newline*: string var gSourceFiles*: seq[TSourceFile] = @[] @@ -27,10 +27,24 @@ proc loadFile*(info: TLineInfo) = gSourceFiles[i].lines = @[] let path = info.toFullPath gSourceFiles[i].fullpath = path - gSourceFiles[i].isNimfixFile = path.splitFile.ext == "nimfix" + gSourceFiles[i].isNimfixFile = path.splitFile.ext == ".nimfix" # we want to die here for IOError: for line in lines(path): gSourceFiles[i].lines.add(line) + # extract line ending of the file: + var lex: BaseLexer + open(lex, newFileStream(path)) + var pos = lex.bufpos + while true: + case lex.buf[pos] + of '\c': + gSourceFiles[i].newline = "\c\L" + break + of '\L', '\0': + gSourceFiles[i].newline = "\L" + break + inc pos + close(lex) const Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'} diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index a397993d8..9b850bd86 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2014,9 +2014,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = checkMinSonsLen(n, 1) let mode = if nfDotField in n.flags: {} else: {checkUndeclared} var s = qualifiedLookUp(c, n.sons[0], mode) - if s != nil: - if gCmd == cmdPretty and n.sons[0].kind == nkDotExpr: - pretty.checkUse(n.sons[0].sons[1].info, s) + if s != nil: + #if gCmd == cmdPretty and n.sons[0].kind == nkDotExpr: + # pretty.checkUse(n.sons[0].sons[1].info, s) case s.kind of skMacro: if sfImmediate notin s.flags: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index a0fe81db3..9a2a64a9e 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -279,7 +279,12 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = if n.kind == nkSym: result = n.sym else: - result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) + when defined(nimfix): + result = pickSym(c, n, skType) + if result.isNil: + result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) + else: + result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) if result != nil: markUsed(n.info, result) if result.kind == skParam and result.typ.kind == tyTypeDesc: diff --git a/doc/advopt.txt b/doc/advopt.txt index 0febf778f..2ddba12e8 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -12,7 +12,6 @@ Advanced commands: module dependency graph //dump dump all defined conditionals and search paths //check checks the project for syntax and semantic - //pretty homogenizes source code style //idetools compiler support for IDEs: possible options: --track:FILE,LINE,COL track a file/cursor position --trackDirty:DIRTY_FILE,ORIG_FILE,LINE,COL diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 1ac82d84a..cc633d90b 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -690,7 +690,7 @@ proc getQueuedCompletionStatus*(CompletionPort: THandle, dwMilliseconds: DWORD): WINBOOL{.stdcall, dynlib: "kernel32", importc: "GetQueuedCompletionStatus".} -proc getOverlappedResult*(hFile: THandle, lpOverlapped: TOverlapped, +proc getOverlappedResult*(hFile: THandle, lpOverlapped: TOVERLAPPED, lpNumberOfBytesTransferred: var DWORD, bWait: WINBOOL): WINBOOL{. stdcall, dynlib: "kernel32", importc: "GetOverlappedResult".} From 205b765fdd570bf90faf2c78db892d977244b9bd Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 10 Sep 2014 00:01:32 +0100 Subject: [PATCH 107/409] Fixes case in cgi module. --- lib/pure/cgi.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index b30f8dd33..14c7c56b5 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -31,7 +31,7 @@ import strutils, os, strtabs, cookies -proc URLencode*(s: string): string = +proc urlEncode*(s: string): string = ## Encodes a value to be HTTP safe: This means that characters in the set ## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result, ## a space is converted to ``'+'`` and every other character is encoded as @@ -52,7 +52,7 @@ proc handleHexChar(c: char, x: var int) {.inline.} = of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10) else: assert(false) -proc URLdecode*(s: string): string = +proc urlDecode*(s: string): string = ## Decodes a value from its HTTP representation: This means that a ``'+'`` ## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal ## value) is converted to the character with ordinal number ``xx``, and @@ -82,7 +82,7 @@ proc addXmlChar(dest: var string, c: char) {.inline.} = of '\"': add(dest, """) else: add(dest, c) -proc XMLencode*(s: string): string = +proc xmlEncode*(s: string): string = ## Encodes a value to be XML safe: ## * ``"`` is replaced by ``"`` ## * ``<`` is replaced by ``<`` @@ -331,9 +331,9 @@ proc setTestData*(keysvalues: varargs[string]) = var i = 0 var query = "" while i < keysvalues.len: - add(query, URLencode(keysvalues[i])) + add(query, urlEncode(keysvalues[i])) add(query, '=') - add(query, URLencode(keysvalues[i+1])) + add(query, urlEncode(keysvalues[i+1])) add(query, '&') inc(i, 2) putEnv("QUERY_STRING", query) From 6cc443712b65a4865ee0d4e4a28d22a947c7d77e Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 10 Sep 2014 00:04:07 +0100 Subject: [PATCH 108/409] Changes source build recommendations on website. --- web/download.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/download.txt b/web/download.txt index 557788217..6d860b332 100644 --- a/web/download.txt +++ b/web/download.txt @@ -121,8 +121,8 @@ Bleeding edge binaries are available from the `Nimrod build farm `_ branch:: +Use the following commands to build the compiler from source. +Change the branch to suit your needs:: git clone -b master git://github.com/Araq/Nimrod.git cd Nimrod From 4d2ff282f625efa0607b30b448cf0909799bf18b Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 10 Sep 2014 00:09:59 +0100 Subject: [PATCH 109/409] Fix case issues in compiler/docgen. --- compiler/docgen.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 4e576867b..c34332b57 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -374,11 +374,11 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = cleanPlainSymbol = renderPlainSymbolName(nameNode) complexSymbol = complexName(k, n, cleanPlainSymbol) plainSymbolRope = toRope(cleanPlainSymbol) - plainSymbolEncRope = toRope(URLencode(cleanPlainSymbol)) + plainSymbolEncRope = toRope(urlEncode(cleanPlainSymbol)) itemIDRope = toRope(d.id) symbolOrId = d.newUniquePlainSymbol(complexSymbol) symbolOrIdRope = symbolOrId.toRope - symbolOrIdEncRope = URLencode(symbolOrId).toRope + symbolOrIdEncRope = urlEncode(symbolOrId).toRope var seeSrcRope: PRope = nil let docItemSeeSrc = getConfigVar("doc.item.seesrc") From 0b229fae77b17ef5e9f1622d9992da27ec1a5c61 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 10 Sep 2014 00:17:29 +0100 Subject: [PATCH 110/409] Fixes tester. --- tests/testament/htmlgen.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testament/htmlgen.nim b/tests/testament/htmlgen.nim index d863bd411..b9eda5383 100644 --- a/tests/testament/htmlgen.nim +++ b/tests/testament/htmlgen.nim @@ -107,7 +107,7 @@ div.tabContent.hide { display: none; } HtmlEnd = "" proc td(s: string): string = - result = "" & s.substr(0, 200).XMLEncode & "" + result = "" & s.substr(0, 200).xmlEncode & "" proc getCommit(db: TDbConn, c: int): string = var commit = c From 055ed5149fba025f210022acea5a0b31b221b521 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 10 Sep 2014 00:42:40 +0100 Subject: [PATCH 111/409] Add depraction warnings for URLencode/decode. --- lib/pure/cgi.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index 14c7c56b5..d5690bf51 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -99,7 +99,8 @@ type methodPost, ## query uses the POST method methodGet ## query uses the GET method -{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError].} +{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError, + URLencode: urlEncode, XMLencode: xmlEncode, URLdecode: urlDecode].} proc cgiError*(msg: string) {.noreturn.} = ## raises an ECgi exception with message `msg`. From 569fbe8c37d99a3adf966527b2650369dfec2dd0 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Sep 2014 02:19:46 +0200 Subject: [PATCH 112/409] 'pretty' command does not exist anymore; improvements for nimfix --- compiler/lookups.nim | 1 - compiler/main.nim | 10 +----- compiler/nimfix.nim | 1 - compiler/pretty.nim | 70 +++++------------------------------------ compiler/prettybase.nim | 3 +- compiler/semexprs.nim | 1 + compiler/semgnrc.nim | 45 +++++++++++++++++--------- compiler/semstmts.nim | 3 ++ compiler/semtempl.nim | 16 +++++++++- compiler/semtypes.nim | 10 +++--- compiler/suggest.nim | 2 +- todo.txt | 1 + 12 files changed, 69 insertions(+), 94 deletions(-) diff --git a/compiler/lookups.nim b/compiler/lookups.nim index dbd03c87d..07ac43f38 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -383,6 +383,5 @@ proc pickSym*(c: PContext, n: PNode; kind: TSymKind; var a = initOverloadIter(o, c, n) while a != nil: if a.kind == kind and flags <= a.flags: - incl(a.flags, sfUsed) return a a = nextOverloadIter(o, c, n) diff --git a/compiler/main.nim b/compiler/main.nim index 5e4a0da76..e73654a4b 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -15,8 +15,7 @@ import wordrecg, sem, semdata, idents, passes, docgen, extccomp, cgen, jsgen, json, nversion, platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen, - tables, docgen2, service, parser, modules, ccgutils, sigmatch, ropes, lists, - pretty + tables, docgen2, service, parser, modules, ccgutils, sigmatch, ropes, lists from magicsys import systemModule, resetSysTypes @@ -164,13 +163,6 @@ proc commandEval(exp: string) = var echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")" evalNim(echoExp.parseString, makeStdinModule()) -proc commandPretty = - msgs.gErrorMax = high(int) # do not stop after first error - semanticPasses() - registerPass(prettyPass) - compileProject() - pretty.overwriteFiles() - proc commandScan = var f = addFileExt(mainCommandArg(), NimExt) var stream = llStreamOpen(f, fmRead) diff --git a/compiler/nimfix.nim b/compiler/nimfix.nim index 5cdcc65db..7e546fe0f 100644 --- a/compiler/nimfix.nim +++ b/compiler/nimfix.nim @@ -32,7 +32,6 @@ proc mainCommand = #msgs.gErrorMax = high(int) # do not stop after first error registerPass verbosePass registerPass semPass - registerPass prettyPass gCmd = cmdPretty appendStr(searchPaths, options.libpath) if gProjectFull.len != 0: diff --git a/compiler/pretty.nim b/compiler/pretty.nim index e6d2d7b70..2d8d79ce1 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -11,10 +11,9 @@ ## to convert Nim code into a consistent style. import - strutils, os, options, ast, astalgo, msgs, ropes, idents, passes, + strutils, os, options, ast, astalgo, msgs, ropes, idents, intsets, strtabs, semdata, prettybase - type StyleCheck* {.pure.} = enum None, Confirm, Auto @@ -23,11 +22,6 @@ var gStyleCheck*: StyleCheck gCheckExtern*: bool -type - TGen = object of TPassContext - module*: PSym - PGen = ref TGen - proc overwriteFiles*() = let doStrip = options.getConfigVar("pretty.strip").normalize == "on" for i in 0 .. high(gSourceFiles): @@ -100,21 +94,20 @@ proc checkStyle(info: TLineInfo, s: string, k: TSymKind) = if s != beau: message(info, hintName, beau) -proc checkDef*(n: PNode; s: PSym) = +proc styleCheckDef*(info: TLineInfo; s: PSym; k: TSymKind) = if gStyleCheck == StyleCheck.None: return # operators stay as they are: - if s.kind in {skResult, skTemp} or s.name.s[0] notin prettybase.Letters: + if k in {skResult, skTemp} or s.name.s[0] notin prettybase.Letters: return - if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return + if k in {skType, skGenericParam} and sfAnon in s.flags: return if {sfImportc, sfExportc} * s.flags == {} or gCheckExtern: - checkStyle(n.info, s.name.s, s.kind) + checkStyle(info, s.name.s, k) -proc checkDef(c: PGen; n: PNode) = - if n.kind != nkSym: return - checkDef(n, n.sym) +proc styleCheckDef*(info: TLineInfo; s: PSym) = styleCheckDef(info, s, s.kind) +proc styleCheckDef*(s: PSym) = styleCheckDef(s.info, s, s.kind) -proc checkUse*(info: TLineInfo; s: PSym) = +proc styleCheckUse*(info: TLineInfo; s: PSym) = if info.fileIndex < 0: return # we simply convert it to what it looks like in the definition # for consistency @@ -141,50 +134,3 @@ proc checkUse*(info: TLineInfo; s: PSym) = var x = line.substr(0, first-1) & newName & line.substr(last+1) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true - -proc check(c: PGen, n: PNode) = - case n.kind - of nkSym: checkUse(n.info, n.sym) - of nkBlockStmt, nkBlockExpr, nkBlockType: - checkDef(c, n[0]) - check(c, n.sons[1]) - of nkForStmt, nkParForStmt: - let L = n.len - for i in countup(0, L-3): - checkDef(c, n[i]) - check(c, n[L-2]) - check(c, n[L-1]) - of nkProcDef, nkLambdaKinds, nkMethodDef, nkIteratorDef, nkTemplateDef, - nkMacroDef, nkConverterDef: - checkDef(c, n[namePos]) - for i in namePos+1 .. MaxSetElements: @@ -363,7 +364,7 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = else: addSon(result.n, newSymNode(field)) addSonSkipIntLit(result, typ) - if gCmd == cmdPretty: checkDef(a.sons[j], field) + if gCmd == cmdPretty: styleCheckDef(a.sons[j].info, field) proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym = @@ -399,7 +400,7 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, else: discard else: result = semIdentVis(c, kind, n, allowed) - if gCmd == cmdPretty: checkDef(n, result) + if gCmd == cmdPretty: styleCheckDef(n.info, result) proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) = let ex = t[branchIndex][currentEx].skipConv @@ -579,6 +580,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, localError(n.sons[i].info, errAttemptToRedefine, f.name.s) if a.kind == nkEmpty: addSon(father, newSymNode(f)) else: addSon(a, newSymNode(f)) + styleCheckDef(f) if a.kind != nkEmpty: addSon(father, a) of nkEmpty: discard else: illFormedAst(n) @@ -918,7 +920,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, addSon(result.n, newSymNode(arg)) rawAddSon(result, finalType) addParamOrResult(c, arg, kind) - if gCmd == cmdPretty: checkDef(a.sons[j], arg) + if gCmd == cmdPretty: styleCheckDef(a.sons[j].info, arg) var r: PType if n.sons[0].kind != nkEmpty: diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 650e5b3fb..99e0e93c1 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -331,7 +331,7 @@ proc markUsed(info: TLineInfo; s: PSym) = if sfDeprecated in s.flags: message(info, warnDeprecated, s.name.s) if sfError in s.flags: localError(info, errWrongSymbolX, s.name.s) suggestSym(info, s) - if gCmd == cmdPretty: checkUse(info, s) + if gCmd == cmdPretty: styleCheckUse(info, s) proc useSym*(sym: PSym): PNode = result = newSymNode(sym) diff --git a/todo.txt b/todo.txt index 66f47a1d8..2785e4d2e 100644 --- a/todo.txt +++ b/todo.txt @@ -3,6 +3,7 @@ version 0.10 - Test nimfix on various babel packages - Pegs do not work at compile-time +- rename cgi.URLencode to encodeUrl version 0.9.6 From c5dbcb548fe5b005594d3e6d1c266d3ec7eb13a2 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Sep 2014 09:48:18 +0200 Subject: [PATCH 113/409] improvements for nimfix --- compiler/pretty.nim | 18 +++++++++++------- compiler/prettybase.nim | 1 + compiler/sem.nim | 1 + compiler/semasgn.nim | 1 + compiler/semcall.nim | 2 ++ compiler/semexprs.nim | 16 ++++++++++++++-- compiler/semtypes.nim | 3 +++ compiler/sigmatch.nim | 4 +++- compiler/suggest.nim | 3 +-- 9 files changed, 37 insertions(+), 12 deletions(-) diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 2d8d79ce1..d6b593318 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -94,18 +94,21 @@ proc checkStyle(info: TLineInfo, s: string, k: TSymKind) = if s != beau: message(info, hintName, beau) -proc styleCheckDef*(info: TLineInfo; s: PSym; k: TSymKind) = - if gStyleCheck == StyleCheck.None: return +proc styleCheckDefImpl(info: TLineInfo; s: PSym; k: TSymKind) = # operators stay as they are: - if k in {skResult, skTemp} or s.name.s[0] notin prettybase.Letters: - return + if k in {skResult, skTemp} or s.name.s[0] notin prettybase.Letters: return if k in {skType, skGenericParam} and sfAnon in s.flags: return - if {sfImportc, sfExportc} * s.flags == {} or gCheckExtern: checkStyle(info, s.name.s, k) -proc styleCheckDef*(info: TLineInfo; s: PSym) = styleCheckDef(info, s, s.kind) -proc styleCheckDef*(s: PSym) = styleCheckDef(s.info, s, s.kind) +template styleCheckDef*(info: TLineInfo; s: PSym; k: TSymKind) = + when defined(nimfix): + if gStyleCheck != StyleCheck.None: styleCheckDefImpl(info, s, k) + +template styleCheckDef*(info: TLineInfo; s: PSym) = + styleCheckDef(info, s, s.kind) +template styleCheckDef*(s: PSym) = + styleCheckDef(s.info, s, s.kind) proc styleCheckUse*(info: TLineInfo; s: PSym) = if info.fileIndex < 0: return @@ -134,3 +137,4 @@ proc styleCheckUse*(info: TLineInfo; s: PSym) = var x = line.substr(0, first-1) & newName & line.substr(last+1) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true + if newName == "File": writeStackTrace() diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim index 24bc601e3..e2679f456 100644 --- a/compiler/prettybase.nim +++ b/compiler/prettybase.nim @@ -74,6 +74,7 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) = var x = line.substr(0, first-1) & newSym.s & line.substr(last+1) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true + if newSym.s == "File": writeStackTrace() proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = replaceDeprecated(info, oldSym.name, newSym.name) diff --git a/compiler/sem.nim b/compiler/sem.nim index 71e60f0b6..1b6e6fe2e 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -311,6 +311,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, pushInfoContext(nOrig.info) markUsed(n.info, sym) + styleCheckUse(n.info, sym) if sym == c.p.owner: globalError(n.info, errRecursiveDependencyX, sym.name.s) diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index 2c77bff7b..483d36bf3 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -126,6 +126,7 @@ proc considerOverloadedOp(c: TLiftCtx; t: PType; x, y: PNode): bool = let op = t.attachedOps[c.kind] if op != nil: markUsed(c.info, op) + styleCheckUse(c.info, op) case c.kind of attachedDestructor: c.result.add newDestructorCall(op, x) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 3ce88651f..6f92a75a6 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -254,6 +254,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = assert x.state == csMatch var finalCallee = x.calleeSym markUsed(n.sons[0].info, finalCallee) + styleCheckUse(n.sons[0].info, finalCallee) if finalCallee.ast == nil: internalError(n.info, "calleeSym.ast is nil") # XXX: remove this check! if finalCallee.ast.sons[genericParamsPos].kind != nkEmpty: @@ -286,6 +287,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = initCandidate(c, m, s, n) var newInst = generateInstance(c, s, m.bindings, n.info) markUsed(n.info, s) + styleCheckUse(n.info, s) result = newSymNode(newInst, n.info) proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 95a60ef23..0034c3718 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -13,6 +13,7 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym, flags: TExprFlags = {}): PNode = markUsed(n.info, s) + styleCheckUse(n.info, s) pushInfoContext(n.info) result = evalTemplate(n, s, getCurrOwner()) if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags) @@ -79,6 +80,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = case s.kind of skConst: markUsed(n.info, s) + styleCheckUse(n.info, s) case skipTypes(s.typ, abstractInst-{tyTypeDesc}).kind of tyNil, tyChar, tyInt..tyInt64, tyFloat..tyFloat128, tyTuple, tySet, tyUInt..tyUInt64: @@ -103,6 +105,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of skTemplate: result = semTemplateExpr(c, n, s, flags) of skVar, skLet, skResult, skParam, skForVar: markUsed(n.info, s) + styleCheckUse(n.info, s) # if a proc accesses a global variable, it is not side effect free: if sfGlobal in s.flags: incl(c.p.owner.flags, sfSideEffect) @@ -115,6 +118,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = # var len = 0 # but won't be called # genericThatUsesLen(x) # marked as taking a closure? of skGenericParam: + styleCheckUse(n.info, s) if s.typ.kind == tyStatic: result = newSymNode(s, n.info) result.typ = s.typ @@ -125,12 +129,14 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = return n of skType: markUsed(n.info, s) + styleCheckUse(n.info, s) if s.typ.kind == tyStatic and s.typ.n != nil: return s.typ.n result = newSymNode(s, n.info) result.typ = makeTypeDesc(c, s.typ) else: markUsed(n.info, s) + styleCheckUse(n.info, s) result = newSymNode(s, n.info) type @@ -259,6 +265,7 @@ proc semConv(c: PContext, n: PNode): PNode = let status = checkConvertible(c, result.typ, it.typ) if status in {convOK, convNotNeedeed}: markUsed(n.info, it.sym) + styleCheckUse(n.info, it.sym) markIndirect(c, it.sym) return it localError(n.info, errUseQualifier, op.sons[0].sym.name.s) @@ -981,6 +988,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) if s != nil: markUsed(n.sons[1].info, s) + styleCheckUse(n.sons[1].info, s) return semSym(c, n, s, flags) n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType}) @@ -1004,6 +1012,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result.info = n.info result.typ = ty markUsed(n.info, f) + styleCheckUse(n.info, f) return of tyTypeParamsHolders: return readTypeParameter(c, ty, i, n.info) @@ -1036,12 +1045,13 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = if fieldVisible(c, f): # is the access to a public field or in the same module or in a friend? markUsed(n.sons[1].info, f) + styleCheckUse(n.sons[1].info, f) n.sons[0] = makeDeref(n.sons[0]) n.sons[1] = newSymNode(f) # we now have the correct field n.typ = f.typ - if check == nil: + if check == nil: result = n - else: + else: check.sons[0] = n check.typ = n.typ result = check @@ -1049,6 +1059,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = f = getSymFromList(ty.n, i) if f != nil: markUsed(n.sons[1].info, f) + styleCheckUse(n.sons[1].info, s) n.sons[0] = makeDeref(n.sons[0]) n.sons[1] = newSymNode(f) n.typ = f.typ @@ -1465,6 +1476,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode = macroCall.sons[0] = newSymNode(expandedSym, macroCall.info) markUsed(n.info, expandedSym) + styleCheckUse(n.info, expandedSym) for i in countup(1, macroCall.len-1): macroCall.sons[i] = semExprWithType(c, macroCall[i], {}) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 6f80cbffe..4badf8f4e 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -288,6 +288,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) if result != nil: markUsed(n.info, result) + styleCheckUse(n.info, result) if result.kind == skParam and result.typ.kind == tyTypeDesc: # This is a typedesc param. is it already bound? # it's not bound when it's used multiple times in the @@ -835,6 +836,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, of tyGenericParam: markUsed(info, paramType.sym) + styleCheckUse(info, paramType.sym) if tfWildcard in paramType.flags: paramType.flags.excl tfWildcard paramType.sym.kind = skType @@ -1195,6 +1197,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = assignType(prev, t) result = prev markUsed(n.info, n.sym) + styleCheckUse(n.info, n.sym) else: if n.sym.kind != skError: localError(n.info, errTypeExpected) result = newOrPrevType(tyError, prev, c) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index d7b397af6..51ae4e8f5 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -12,7 +12,8 @@ import intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, - magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees + magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees, + pretty when not defined(noDocgen): import docgen @@ -1272,6 +1273,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType, else: # only one valid interpretation found: markUsed(arg.info, arg.sons[best].sym) + styleCheckUse(arg.info, arg.sons[best].sym) result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best], argOrig) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 99e0e93c1..c700db323 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -11,7 +11,7 @@ # included from sigmatch.nim -import algorithm, sequtils, pretty +import algorithm, sequtils const sep = '\t' @@ -331,7 +331,6 @@ proc markUsed(info: TLineInfo; s: PSym) = if sfDeprecated in s.flags: message(info, warnDeprecated, s.name.s) if sfError in s.flags: localError(info, errWrongSymbolX, s.name.s) suggestSym(info, s) - if gCmd == cmdPretty: styleCheckUse(info, s) proc useSym*(sym: PSym): PNode = result = newSymNode(sym) From 22fb9db8459063def6e04259f6222affec177c5c Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Sep 2014 20:34:33 +0200 Subject: [PATCH 114/409] nimfix improvements --- compiler/condsyms.nim | 2 +- compiler/pretty.nim | 2 +- compiler/prettybase.nim | 2 +- compiler/semexprs.nim | 2 +- compiler/semtempl.nim | 6 ++---- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 938cc5df2..d87275063 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -60,7 +60,7 @@ const quick release debug useWinAnsi useFork useNimRtl useMalloc useRealtimeGC ssl memProfiler - nodejs kwin + nodejs kwin nimfix usesysassert usegcassert tinyC useFFI useStdoutAsStdmsg createNimRtl diff --git a/compiler/pretty.nim b/compiler/pretty.nim index d6b593318..9f2074a0b 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -137,4 +137,4 @@ proc styleCheckUse*(info: TLineInfo; s: PSym) = var x = line.substr(0, first-1) & newName & line.substr(last+1) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true - if newName == "File": writeStackTrace() + #if newName == "File": writeStackTrace() diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim index e2679f456..21613396a 100644 --- a/compiler/prettybase.nim +++ b/compiler/prettybase.nim @@ -74,7 +74,7 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) = var x = line.substr(0, first-1) & newSym.s & line.substr(last+1) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true - if newSym.s == "File": writeStackTrace() + #if newSym.s == "File": writeStackTrace() proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = replaceDeprecated(info, oldSym.name, newSym.name) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 0034c3718..11215ae68 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1059,7 +1059,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = f = getSymFromList(ty.n, i) if f != nil: markUsed(n.sons[1].info, f) - styleCheckUse(n.sons[1].info, s) + styleCheckUse(n.sons[1].info, f) n.sons[0] = makeDeref(n.sons[0]) n.sons[1] = newSymNode(f) n.typ = f.typ diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index adb2c9009..0a647a65d 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -191,6 +191,8 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode = incl(s.flags, sfUsed) + # we do not call styleCheckUse here, as the identifier is not really + # resolved here. We will fixup the used identifiers later. case s.kind of skUnknown: # Introduced in this pass! Leave it as an identifier. @@ -199,19 +201,15 @@ proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode = result = symChoice(c, n, s, scOpen) of skGenericParam: result = newSymNodeTypeDesc(s, n.info) - styleCheckUse(n.info, s) of skParam: result = n - styleCheckUse(n.info, s) of skType: if (s.typ != nil) and (s.typ.kind != tyGenericParam): result = newSymNodeTypeDesc(s, n.info) else: result = n - styleCheckUse(n.info, s) else: result = newSymNode(s, n.info) - styleCheckUse(n.info, s) proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode = result = n From 63c9c2877e48b14f8981366d6e110f913a8b604a Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Sep 2014 22:27:07 +0200 Subject: [PATCH 115/409] updated nimgrep tool --- lib/pure/parseopt.nim | 2 +- tools/nimgrep.nim | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index 786744600..8af6920c1 100644 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -25,7 +25,7 @@ type CmdLineKind* = enum ## the detected command line token cmdEnd, ## end of command line reached cmdArgument, ## argument detected - cmdLongoption, ## a long option ``--option`` detected + cmdLongOption, ## a long option ``--option`` detected cmdShortOption ## a short option ``-c`` detected OptParser* = object of RootObj ## this object implements the command line parser diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim index 42db2dafc..a38f2a88f 100644 --- a/tools/nimgrep.nim +++ b/tools/nimgrep.nim @@ -81,14 +81,14 @@ proc countLines(s: string, first, last: int): int = proc beforePattern(s: string, first: int): int = result = first-1 while result >= 0: - if s[result] in Newlines: break + if s[result] in NewLines: break dec(result) inc(result) proc afterPattern(s: string, last: int): int = result = last+1 while result < s.len: - if s[result] in Newlines: break + if s[result] in NewLines: break inc(result) dec(result) @@ -125,12 +125,12 @@ proc processFile(filename: string) = var buffer: string try: buffer = system.readFile(filename) - except EIO: + except IOError: echo "cannot open file: ", filename return if optVerbose in options: stdout.writeln(filename) var pegp: TPeg - var rep: TRegex + var rep: Regex var result: string if optRegex in options: @@ -267,7 +267,7 @@ proc checkOptions(subset: TOptions, a, b: string) = for kind, key, val in getopt(): case kind of cmdArgument: - if options.contains(optStdIn): + if options.contains(optStdin): filenames.add(key) elif pattern.len == 0: pattern = key @@ -275,7 +275,7 @@ for kind, key, val in getopt(): replacement = key else: filenames.add(key) - of cmdLongOption, cmdShortOption: + of cmdLongoption, cmdShortOption: case normalize(key) of "find", "f": incl(options, optFind) of "replace", "r": incl(options, optReplace) From 950078003767de36132f179ca00d8c81dbcc162a Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Sep 2014 23:25:29 +0200 Subject: [PATCH 116/409] renamed URLencode to encodeUrl --- compiler/docgen.nim | 4 ++-- lib/pure/cgi.nim | 16 +++++++++------- todo.txt | 1 - 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index c34332b57..273fcb7f3 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -374,11 +374,11 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = cleanPlainSymbol = renderPlainSymbolName(nameNode) complexSymbol = complexName(k, n, cleanPlainSymbol) plainSymbolRope = toRope(cleanPlainSymbol) - plainSymbolEncRope = toRope(urlEncode(cleanPlainSymbol)) + plainSymbolEncRope = toRope(encodeUrl(cleanPlainSymbol)) itemIDRope = toRope(d.id) symbolOrId = d.newUniquePlainSymbol(complexSymbol) symbolOrIdRope = symbolOrId.toRope - symbolOrIdEncRope = urlEncode(symbolOrId).toRope + symbolOrIdEncRope = encodeUrl(symbolOrId).toRope var seeSrcRope: PRope = nil let docItemSeeSrc = getConfigVar("doc.item.seesrc") diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index d5690bf51..e8977b80b 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -31,7 +31,7 @@ import strutils, os, strtabs, cookies -proc urlEncode*(s: string): string = +proc encodeUrl*(s: string): string = ## Encodes a value to be HTTP safe: This means that characters in the set ## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result, ## a space is converted to ``'+'`` and every other character is encoded as @@ -52,7 +52,7 @@ proc handleHexChar(c: char, x: var int) {.inline.} = of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10) else: assert(false) -proc urlDecode*(s: string): string = +proc decodeUrl*(s: string): string = ## Decodes a value from its HTTP representation: This means that a ``'+'`` ## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal ## value) is converted to the character with ordinal number ``xx``, and @@ -74,6 +74,8 @@ proc urlDecode*(s: string): string = inc(j) setLen(result, j) +{.deprecated: [URLDecode: decodeUrl, URLEncode: encodeUrl].} + proc addXmlChar(dest: var string, c: char) {.inline.} = case c of '&': add(dest, "&") @@ -100,7 +102,7 @@ type methodGet ## query uses the GET method {.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError, - URLencode: urlEncode, XMLencode: xmlEncode, URLdecode: urlDecode].} + XMLencode: xmlEncode].} proc cgiError*(msg: string) {.noreturn.} = ## raises an ECgi exception with message `msg`. @@ -332,9 +334,9 @@ proc setTestData*(keysvalues: varargs[string]) = var i = 0 var query = "" while i < keysvalues.len: - add(query, urlEncode(keysvalues[i])) + add(query, encodeUrl(keysvalues[i])) add(query, '=') - add(query, urlEncode(keysvalues[i+1])) + add(query, encodeUrl(keysvalues[i+1])) add(query, '&') inc(i, 2) putEnv("QUERY_STRING", query) @@ -394,5 +396,5 @@ proc existsCookie*(name: string): bool = when isMainModule: const test1 = "abc\L+def xyz" - assert URLencode(test1) == "abc%0A%2Bdef+xyz" - assert URLdecode(URLencode(test1)) == test1 + assert encodeUrl(test1) == "abc%0A%2Bdef+xyz" + assert decodeUrl(encodeUrl(test1)) == test1 diff --git a/todo.txt b/todo.txt index 2785e4d2e..66f47a1d8 100644 --- a/todo.txt +++ b/todo.txt @@ -3,7 +3,6 @@ version 0.10 - Test nimfix on various babel packages - Pegs do not work at compile-time -- rename cgi.URLencode to encodeUrl version 0.9.6 From 6f155af802bec7dc1b4b8ff31e0135dd6692a93c Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 12 Sep 2014 22:54:02 +0100 Subject: [PATCH 117/409] Lots of documentation improvements for asyncdispatch. Ref #1487. --- lib/pure/asyncdispatch.nim | 140 ++++++++++++++++++++++++++++++----- lib/pure/asyncftpclient.nim | 18 +++++ lib/pure/asynchttpserver.nim | 16 +++- lib/pure/asyncnet.nim | 18 ++++- lib/pure/ftpclient.nim | 2 +- lib/pure/httpclient.nim | 13 ++++ lib/pure/os.nim | 2 +- 7 files changed, 183 insertions(+), 26 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 5363d8862..cac98e160 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -18,42 +18,137 @@ export Port, SocketFlag #{.injectStmt: newGcInvariant().} ## AsyncDispatch -## ------------- +## ************* ## -## This module implements a brand new dispatcher based on Futures. -## On Windows IOCP is used and on other operating systems the ``selectors`` -## module is used instead. +## This module implements asynchronous IO. This includes a dispatcher, +## a ``Future`` type implementation, and an ``async`` macro which allows +## asynchronous code to be written in a synchronous style with the ``await`` +## keyword. ## -## **Note:** This module is still largely experimental. +## The dispatcher acts as a kind of event loop. You must call ``poll`` on it +## (or a function which does so for you such as ``waitFor`` or ``runForever``) +## in order to poll for any outstanding events. The underlying implementation +## is based on epoll on Linux, IO Completion Ports on Windows and select on +## other operating systems. +## +## The ``poll`` function will not, on its own, return any events. Instead +## an appropriate ``Future`` object will be completed. A ``Future`` is a +## type which holds a value which is not yet available, but which *may* be +## available in the future. You can check whether a future is finished +## by using the ``finished`` function. When a future is finished it means that +## either the value that it holds is now available or it holds an error instead. +## The latter situation occurs when the operation to complete a future fails +## with an exception. You can distinguish between the two situations with the +## ``failed`` function. +## +## Future objects can also store a callback procedure which will be called +## automatically once the future completes. +## +## Futures therefore can be thought of as an implementation of the proactor +## pattern. In this +## pattern you make a request for an action, and once that action is fulfilled +## a future is completed with the result of that action. Requests can be +## made by calling the appropriate functions. For example: calling the ``recv`` +## function will create a request for some data to be read from a socket. The +## future which the ``recv`` function returns will then complete once the +## requested amount of data is read **or** an exception occurs. +## +## Code to read some data from a socket may look something like this: +## +## .. code-block::nim +## var future = socket.recv(100) +## future.callback = +## proc () = +## echo(future.read) +## +## All asynchronous functions returning a ``Future`` will not block. They +## will not however return immediately. An asynchronous function will have +## code which will be executed before an asynchronous request is made, in most +## cases this code sets up the request. +## +## In the above example, the ``recv`` function will return a brand new +## ``Future`` instance once the request for data to be read from the socket +## is made. This ``Future`` instance will complete once the requested amount +## of data is read, in this case it is 100 bytes. The second line sets a +## callback on this future which will be called once the future completes. +## All the callback does is write the data stored in the future to ``stdout``. +## The ``read`` function is used for this and it checks whether the future +## completes with an error for you (if it did it will simply raise the +## error), if there is no error however it returns the value of the future. +## +## Asynchronous procedures +## ----------------------- +## +## Asynchronous procedures remove the pain of working with callbacks. They do +## this by allowing you to write asynchronous code the same way as you would +## write synchronous code. +## +## An asynchronous procedure is marked using the ``{.async.}`` pragma. +## When marking a procedure with the ``{.async.}`` pragma it must have a +## ``Future[T]`` return type or no return type at all. If you do not specify +## a return type then ``Future[void]`` is assumed. +## +## Inside asynchronous procedures ``await`` can be used to call any +## procedures which return a +## ``Future``; this includes asynchronous procedures. When a procedure is +## "awaited", the asynchronous procedure it is awaited in will +## suspend its execution +## until the awaited procedure's Future completes. At which point the +## asynchronous procedure will resume its execution. During the period +## when an asynchronous procedure is suspended other asynchronous procedures +## will be run by the dispatcher. +## +## The ``await`` call may be used in many contexts. It can be used on the right +## hand side of a variable declaration: ``var data = await socket.recv(100)``, +## in which case the variable will be set to the value of the future +## automatically. It can be used to await a ``Future`` object, and it can +## be used to await a procedure returning a ``Future[void]``: +## ``await socket.send("foobar")``. +## +## Discarding futures +## ------------------ +## +## Futures should **never** be discarded. This is because they may contain +## errors. If you do not care for the result of a Future then you should +## use the ``asyncCheck`` procedure instead of the ``discard`` keyword. +## +## Examples +## -------- +## +## For examples take a look at the documentation for the modules implementing +## asynchronous IO. A good place to start is the +## `asyncnet module `_. +## +## Limitations/Bugs +## ---------------- +## +## * ``except`` statement (without `try`) does not work inside async procedures. +## * The effect system (``raises: []``) does not work with async procedures. +## * Can't await in a ``except`` body -# TODO: ``except`` statement (without `try`) does not work. -# TODO: Multiple exception names in a ``except`` don't work. -# TODO: The effect system (raises: []) has trouble with my try transformation. -# TODO: Can't await in a 'except' body -# TODO: getCurrentException(Msg) don't work # TODO: Check if yielded future is nil and throw a more meaningful exception # -- Futures type - FutureBase* = ref object of RootObj + FutureBase* = ref object of RootObj ## Untyped future. cb: proc () {.closure,gcsafe.} finished: bool - error*: ref Exception + error*: ref Exception ## Stored exception errorStackTrace*: string when not defined(release): stackTrace: string ## For debugging purposes only. id: int fromProc: string - Future*[T] = ref object of FutureBase - value: T + Future*[T] = ref object of FutureBase ## Typed future. + value: T ## Stored value {.deprecated: [PFutureBase: FutureBase, PFuture: Future].} -var currentID* = 0 +var currentID = 0 proc newFuture*[T](fromProc: string = "unspecified"): Future[T] = ## Creates a new future. ## @@ -161,6 +256,10 @@ proc read*[T](future: Future[T]): T = raise newException(ValueError, "Future still in progress.") proc readError*[T](future: Future[T]): ref Exception = + ## Retrieves the exception stored in ``future``. + ## + ## An ``ValueError`` exception will be thrown if no exception exists + ## in the specified Future. if future.error != nil: return future.error else: raise newException(ValueError, "No error in future.") @@ -173,7 +272,7 @@ proc finished*[T](future: Future[T]): bool = proc failed*(future: FutureBase): bool = ## Determines whether ``future`` completed with an error. - future.error != nil + return future.error != nil proc asyncCheck*[T](future: Future[T]) = ## Sets a callback on ``future`` which raises an exception if the future @@ -950,7 +1049,7 @@ proc accept*(socket: TAsyncFD, # -- Await Macro -template createCb*(retFutureSym, iteratorNameSym, +template createCb(retFutureSym, iteratorNameSym, name: expr): stmt {.immediate.} = var nameIterVar = iteratorNameSym #{.push stackTrace: off.} @@ -1193,7 +1292,7 @@ macro async*(prc: stmt): stmt {.immediate.} = # -> createCb(retFuture) var cbName = newIdentNode("cb") - var procCb = newCall("createCb", retFutureSym, iteratorNameSym, + var procCb = newCall(bindSym"createCb", retFutureSym, iteratorNameSym, newStrLitNode(prc[0].getName)) outerProcBody.add procCb @@ -1232,7 +1331,10 @@ proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = ## is read) then line will be set to ``""``. ## The partial line **will be lost**. ## - ## **Warning**: This assumes that lines are delimited by ``\r\l``. + ## **Warning**: This assumes that lines are delimited by ``\r\L``. + ## + ## **Note**: This procedure is mostly used for testing. You likely want to + ## use ``asyncnet.recvLine`` instead. template addNLIfEmpty(): stmt = if result.len == 0: diff --git a/lib/pure/asyncftpclient.nim b/lib/pure/asyncftpclient.nim index c5a97adfc..fc38dc31a 100644 --- a/lib/pure/asyncftpclient.nim +++ b/lib/pure/asyncftpclient.nim @@ -6,6 +6,24 @@ # distribution, for details about the copyright. # +## This module implement an asynchronous FTP client. +## +## Examples +## -------- +## +## .. code-block::nim +## +## var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test") +## proc main(ftp: AsyncFtpClient) {.async.} = +## await ftp.connect() +## echo await ftp.pwd() +## echo await ftp.listDirs() +## await ftp.store("payload.jpg", "payload.jpg") +## await ftp.retrFile("payload.jpg", "payload2.jpg") +## echo("Finished") +## +## waitFor main(ftp) + import asyncdispatch, asyncnet, strutils, parseutils, os, times from ftpclient import FtpBaseObj, ReplyError, FtpEvent diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 931a0c15a..9de0a6268 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -9,7 +9,20 @@ ## This module implements a high performance asynchronous HTTP server. ## -## **Note:** This module is still largely experimental. +## Examples +## -------- +## +## This example will create an HTTP server on port 8080. The server will +## respond to all requests with a ``200 OK`` response code and "Hello World" +## as the response body. +## +## .. code-block::nim +## var server = newAsyncHttpServer() +## proc cb(req: TRequest) {.async.} = +## await req.respond(Http200, "Hello World") +## +## asyncCheck server.serve(Port(8080), cb) +## runForever() import strtabs, asyncnet, asyncdispatch, parseutils, uri, strutils type @@ -52,6 +65,7 @@ proc `==`*(protocol: tuple[orig: string, major, minor: int], result = protocol.major == major and protocol.minor == minor proc newAsyncHttpServer*(): PAsyncHttpServer = + ## Creates a new ``AsyncHttpServer`` instance. new result proc addHeaders(msg: var string, headers: PStringTable) = diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 4539dfdcb..a16111349 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -10,8 +10,20 @@ ## This module implements a high-level asynchronous sockets API based on the ## asynchronous dispatcher defined in the ``asyncdispatch`` module. ## -## Example -## ======= +## SSL +## --- +## +## SSL can be enabled by compiling with the ``-d:ssl`` flag. +## +## You must create a new SSL context with the ``newContext`` function defined +## in the ``net`` module. You may then call ``wrapSocket`` on your socket using +## the newly created SSL context to get an SSL socket. +## +## Examples +## -------- +## +## Chat server +## ^^^^^^^^^^^ ## ## The following example demonstrates a simple chat server. ## @@ -41,8 +53,6 @@ ## asyncCheck serve() ## runForever() ## -## -## **Note:** This module is still largely experimental. import asyncdispatch import rawsockets diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim index 07c9b5662..37b25871d 100644 --- a/lib/pure/ftpclient.nim +++ b/lib/pure/ftpclient.nim @@ -1,7 +1,7 @@ # # # Nim's Runtime Library -# (c) Copyright 2012 Dominik Picheta +# (c) Copyright 2014 Dominik Picheta # See the file "copying.txt", included in this # distribution, for details about the copyright. # diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 1548cf231..892ddac40 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -48,6 +48,19 @@ ## ## echo(postContent("http://validator.w3.org/check", headers, body)) ## +## Asynchronous HTTP requests +## ========================== +## +## You simply have to create a new instance of the ``AsyncHttpClient`` object. +## You may then use ``await`` on the functions defined for that object. +## Keep in mind that the following code needs to be inside an asynchronous +## procedure. +## +## .. code-block::nim +## +## var client = newAsyncHttpClient() +## var resp = await client.request("http://google.com") +## ## SSL/TLS support ## =============== ## This requires the OpenSSL library, fortunately it's widely used and installed diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 6b3ee6e6d..c08297b7c 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -80,7 +80,7 @@ when defined(Nimdoc): # only for proper documentation: ## search patch components (as in PATH), such as ':' for POSIX or ';' for ## Windows. - FileSystemCaseSensitive* = True + FileSystemCaseSensitive* = true ## True if the file system is case sensitive, false otherwise. Used by ## `cmpPaths` to compare filenames properly. From 37149dcf86873fd4f932bf34d18e94abd050bc63 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 12 Sep 2014 23:16:51 +0100 Subject: [PATCH 118/409] Fixes fdSet CS problems in asyncio. --- lib/pure/asyncio.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 3de947dca..bb0d29fc4 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -91,10 +91,10 @@ import sockets, os ## getSocket(s).accept(client) when defined(windows): - from winlean import TimeVal, SocketHandle, TFdSet, FD_ZERO, FD_SET, + from winlean import TimeVal, SocketHandle, fdSet, FD_ZERO, TFdSet, fdSet, FD_ISSET, select else: - from posix import TimeVal, SocketHandle, TFdSet, FD_ZERO, FD_SET, + from posix import TimeVal, SocketHandle, fdSet, FD_ZERO, TFdSet, fdSet, FD_ISSET, select type From 69d4eb14bc34ce05e21a40e28817e9a832ddd282 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 13 Sep 2014 15:35:09 +0100 Subject: [PATCH 119/409] Some docgen fixes. --- lib/js/dom.nim | 6 +++--- lib/pure/base64.nim | 1 + tools/nimweb.nim | 32 ++++++++++++++++---------------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/js/dom.nim b/lib/js/dom.nim index 2051ef294..b07666dd1 100644 --- a/lib/js/dom.nim +++ b/lib/js/dom.nim @@ -446,7 +446,7 @@ proc unescape*(uri: cstring): cstring {.importc, nodecl.} proc decodeURIComponent*(uri: cstring): cstring {.importc, nodecl.} proc encodeURIComponent*(uri: cstring): cstring {.importc, nodecl.} -proc isFinite*(x: biggestFloat): bool {.importc, nodecl.} -proc isNaN*(x: biggestFloat): bool {.importc, nodecl.} -proc parseFloat*(s: cstring): biggestFloat {.importc, nodecl.} +proc isFinite*(x: BiggestFloat): bool {.importc, nodecl.} +proc isNaN*(x: BiggestFloat): bool {.importc, nodecl.} +proc parseFloat*(s: cstring): BiggestFloat {.importc, nodecl.} proc parseInt*(s: cstring): int {.importc, nodecl.} diff --git a/lib/pure/base64.nim b/lib/pure/base64.nim index 72c49142d..41d19dc0f 100644 --- a/lib/pure/base64.nim +++ b/lib/pure/base64.nim @@ -59,6 +59,7 @@ template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediat setLen(result, r+4) else: #assert(r == result.len) + discard proc encode*[T:SomeInteger|char](s: openarray[T], lineLen = 75, newLine="\13\10"): string = ## encodes `s` into base64 representation. After `lineLen` characters, a diff --git a/tools/nimweb.nim b/tools/nimweb.nim index cd679a299..1a5721075 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -53,8 +53,8 @@ include "website.tmpl" # ------------------------- configuration file ------------------------------- const - Version = "0.7" - Usage = "nimweb - Nim Website Generator Version " & version & """ + version = "0.7" + usage = "nimweb - Nim Website Generator Version " & version & """ (c) 2012 Andreas Rumpf Usage: @@ -115,19 +115,19 @@ proc parseCmdLine(c: var TConfigData) = of cmdLongOption, cmdShortOption: case normalize(key) of "help", "h": - stdout.write(Usage) + stdout.write(usage) quit(0) of "version", "v": - stdout.write(Version & "\n") + stdout.write(version & "\n") quit(0) of "o", "output": c.outdir = val of "var": var idx = val.find('=') if idx < 0: quit("invalid command line") c.vars[substr(val, 0, idx-1)] = substr(val, idx+1) - else: quit(Usage) + else: quit(usage) of cmdEnd: break - if c.infile.len == 0: quit(Usage) + if c.infile.len == 0: quit(usage) proc walkDirRecursively(s: var seq[string], root, ext: string) = for k, f in walkDir(root): @@ -222,33 +222,33 @@ proc buildDocSamples(c: var TConfigData, destPath: string) = ## it didn't make much sense to integrate into the existing generic ## documentation builders. const src = "doc"/"docgen_sample.nim" - exec("nimrod doc $# -o:$# $#" % + exec("nim doc $# -o:$# $#" % [c.nimrodArgs, destPath / "docgen_sample.html", src]) - exec("nimrod doc2 $# -o:$# $#" % + exec("nim doc2 $# -o:$# $#" % [c.nimrodArgs, destPath / "docgen_sample2.html", src]) proc buildDoc(c: var TConfigData, destPath: string) = # call nim for the documentation: for d in items(c.doc): - exec("nimrod rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" % + exec("nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" % [c.nimrodArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d]) for d in items(c.srcdoc): - exec("nimrod doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" % + exec("nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" % [c.nimrodArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d]) for d in items(c.srcdoc2): - exec("nimrod doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" % + exec("nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" % [c.nimrodArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d]) - exec("nimrod buildIndex -o:$1/theindex.html $1" % [destPath]) + exec("nim buildIndex -o:$1/theindex.html $1" % [destPath]) proc buildPdfDoc(c: var TConfigData, destPath: string) = if os.execShellCmd("pdflatex -version") != 0: echo "pdflatex not found; no PDF documentation generated" else: for d in items(c.pdf): - exec("nimrod rst2tex $# $#" % [c.nimrodArgs, d]) + exec("nim rst2tex $# $#" % [c.nimrodArgs, d]) # call LaTeX twice to get cross references right: exec("pdflatex " & changeFileExt(d, "tex")) exec("pdflatex " & changeFileExt(d, "tex")) @@ -265,7 +265,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) = proc buildAddDoc(c: var TConfigData, destPath: string) = # build additional documentation (without the index): for d in items(c.webdoc): - exec("nimrod doc $# --docSeeSrcUrl:$# -o:$# $#" % + exec("nim doc $# --docSeeSrcUrl:$# -o:$# $#" % [c.nimrodArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d]) @@ -349,12 +349,12 @@ proc buildNewsRss(c: var TConfigData, destPath: string) = generateRss(destFilename, parseNewsTitles(srcFilename)) proc buildJS(destPath: string) = - exec("nimrod js -d:release --out:$1 web/babelpkglist.nim" % + exec("nim js -d:release --out:$1 web/babelpkglist.nim" % [destPath / "babelpkglist.js"]) proc main(c: var TConfigData) = const - cmd = "nimrod rst2html --compileonly $1 -o:web/$2.temp web/$2.txt" + cmd = "nim rst2html --compileonly $1 -o:web/$2.temp web/$2.txt" if c.ticker.len > 0: try: c.ticker = readFile("web" / c.ticker) From d28088f0f5619c566a9d13362c9289edc7119fcf Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 13 Sep 2014 16:09:54 +0100 Subject: [PATCH 120/409] Fix 'doc' command. --- compiler/main.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/main.nim b/compiler/main.nim index e73654a4b..c80c9a873 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -299,6 +299,7 @@ proc mainCommand* = else: rawMessage(errInvalidCommandX, command) of "doc": + wantMainModule() gCmd = cmdDoc loadConfigs(DocConfig) commandDoc() @@ -316,6 +317,7 @@ proc mainCommand* = loadConfigs(DocTexConfig) commandRst2TeX() of "jsondoc": + wantMainModule() gCmd = cmdDoc loadConfigs(DocConfig) wantMainModule() From 0047172274a73c681f619f5cd60aaad7109f694d Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 13 Sep 2014 16:45:07 +0100 Subject: [PATCH 121/409] More docgen fixes. --- lib/impure/db_mysql.nim | 50 +++++----- lib/impure/db_postgres.nim | 58 ++++++------ lib/impure/web.nim | 63 ------------- lib/pure/httpserver.nim | 22 ++--- lib/wrappers/mysql.nim | 12 +-- lib/wrappers/postgres.nim | 182 ++++++++++++++++++------------------- lib/wrappers/sqlite3.nim | 4 +- web/news.txt | 5 +- web/nim.ini | 8 +- 9 files changed, 171 insertions(+), 233 deletions(-) delete mode 100644 lib/impure/web.nim diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 709e899e8..d57e8d641 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -78,17 +78,17 @@ proc tryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool { tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) - return mysql.RealQuery(db, q, q.len) == 0'i32 + return mysql.realQuery(db, q, q.len) == 0'i32 proc rawExec(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) = var q = dbFormat(query, args) - if mysql.RealQuery(db, q, q.len) != 0'i32: dbError(db) + if mysql.realQuery(db, q, q.len) != 0'i32: dbError(db) proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. var q = dbFormat(query, args) - if mysql.RealQuery(db, q, q.len) != 0'i32: dbError(db) + if mysql.realQuery(db, q, q.len) != 0'i32: dbError(db) proc newRow(L: int): TRow = newSeq(result, L) @@ -96,8 +96,8 @@ proc newRow(L: int): TRow = proc properFreeResult(sqlres: mysql.PRES, row: cstringArray) = if row != nil: - while mysql.FetchRow(sqlres) != nil: discard - mysql.FreeResult(sqlres) + while mysql.fetchRow(sqlres) != nil: discard + mysql.freeResult(sqlres) iterator fastRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = @@ -105,13 +105,13 @@ iterator fastRows*(db: TDbConn, query: TSqlQuery, ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For MySQL this is the case!. rawExec(db, query, args) - var sqlres = mysql.UseResult(db) + var sqlres = mysql.useResult(db) if sqlres != nil: - var L = int(mysql.NumFields(sqlres)) + var L = int(mysql.numFields(sqlres)) var result = newRow(L) var row: cstringArray while true: - row = mysql.FetchRow(sqlres) + row = mysql.fetchRow(sqlres) if row == nil: break for i in 0..L-1: setLen(result[i], 0) @@ -124,11 +124,11 @@ proc getRow*(db: TDbConn, query: TSqlQuery, ## retrieves a single row. If the query doesn't return any rows, this proc ## will return a TRow with empty strings for each column. rawExec(db, query, args) - var sqlres = mysql.UseResult(db) + var sqlres = mysql.useResult(db) if sqlres != nil: - var L = int(mysql.NumFields(sqlres)) + var L = int(mysql.numFields(sqlres)) result = newRow(L) - var row = mysql.FetchRow(sqlres) + var row = mysql.fetchRow(sqlres) if row != nil: for i in 0..L-1: setLen(result[i], 0) @@ -140,24 +140,24 @@ proc getAllRows*(db: TDbConn, query: TSqlQuery, ## executes the query and returns the whole result dataset. result = @[] rawExec(db, query, args) - var sqlres = mysql.UseResult(db) + var sqlres = mysql.useResult(db) if sqlres != nil: - var L = int(mysql.NumFields(sqlres)) + var L = int(mysql.numFields(sqlres)) var row: cstringArray var j = 0 while true: - row = mysql.FetchRow(sqlres) + row = mysql.fetchRow(sqlres) if row == nil: break setLen(result, j+1) newSeq(result[j], L) for i in 0..L-1: result[j][i] = $row[i] inc(j) - mysql.FreeResult(sqlres) + mysql.freeResult(sqlres) iterator rows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = - ## same as `FastRows`, but slower and safe. - for r in items(GetAllRows(db, query, args)): yield r + ## same as `fastRows`, but slower and safe. + for r in items(getAllRows(db, query, args)): yield r proc getValue*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): string {.tags: [FReadDB].} = @@ -165,7 +165,7 @@ proc getValue*(db: TDbConn, query: TSqlQuery, ## result dataset. Returns "" if the dataset contains no rows or the database ## value is NULL. result = "" - for row in FastRows(db, query, args): + for row in fastRows(db, query, args): result = row[0] break @@ -174,16 +174,16 @@ proc tryInsertId*(db: TDbConn, query: TSqlQuery, ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. var q = dbFormat(query, args) - if mysql.RealQuery(db, q, q.len) != 0'i32: + if mysql.realQuery(db, q, q.len) != 0'i32: result = -1'i64 else: - result = mysql.InsertId(db) + result = mysql.insertId(db) proc insertId*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row. - result = TryInsertID(db, query, args) + result = tryInsertID(db, query, args) if result < 0: dbError(db) proc execAffectedRows*(db: TDbConn, query: TSqlQuery, @@ -192,7 +192,7 @@ proc execAffectedRows*(db: TDbConn, query: TSqlQuery, ## runs the query (typically "UPDATE") and returns the ## number of affected rows rawExec(db, query, args) - result = mysql.AffectedRows(db) + result = mysql.affectedRows(db) proc close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. @@ -202,7 +202,7 @@ proc open*(connection, user, password, database: string): TDbConn {. tags: [FDb].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. - result = mysql.Init(nil) + result = mysql.init(nil) if result == nil: dbError("could not open database connection") let colonPos = connection.find(':') @@ -210,9 +210,9 @@ proc open*(connection, user, password, database: string): TDbConn {. else: substr(connection, 0, colonPos-1) port: int32 = if colonPos < 0: 0'i32 else: substr(connection, colonPos+1).parseInt.int32 - if mysql.RealConnect(result, host, user, password, database, + if mysql.realConnect(result, host, user, password, database, port, nil, 0) == nil: var errmsg = $mysql.error(result) - db_mysql.Close(result) + db_mysql.close(result) dbError(errmsg) diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index 4b7e20d0a..116356489 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -37,7 +37,7 @@ proc dbError(db: TDbConn) {.noreturn.} = ## raises an EDb exception. var e: ref EDb new(e) - e.msg = $PQerrorMessage(db) + e.msg = $pqErrorMessage(db) raise e proc dbError*(msg: string) {.noreturn.} = @@ -68,17 +68,17 @@ proc tryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) - var res = PQExec(db, q) - result = PQresultStatus(res) == PGRES_COMMAND_OK - PQclear(res) + var res = pqExec(db, q) + result = pqresultStatus(res) == PGRES_COMMAND_OK + pqclear(res) proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. var q = dbFormat(query, args) - var res = PQExec(db, q) - if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db) - PQclear(res) + var res = pqExec(db, q) + if pqresultStatus(res) != PGRES_COMMAND_OK: dbError(db) + pqclear(res) proc newRow(L: int): TRow = newSeq(result, L) @@ -87,13 +87,13 @@ proc newRow(L: int): TRow = proc setupQuery(db: TDbConn, query: TSqlQuery, args: varargs[string]): PPGresult = var q = dbFormat(query, args) - result = PQExec(db, q) - if PQresultStatus(result) != PGRES_TUPLES_OK: dbError(db) + result = pqExec(db, q) + if pqresultStatus(result) != PGRES_TUPLES_OK: dbError(db) proc setRow(res: PPGresult, r: var TRow, line, cols: int32) = for col in 0..cols-1: setLen(r[col], 0) - var x = PQgetvalue(res, line, col) + var x = pqgetvalue(res, line, col) add(r[col], x) iterator fastRows*(db: TDbConn, query: TSqlQuery, @@ -102,41 +102,41 @@ iterator fastRows*(db: TDbConn, query: TSqlQuery, ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For Postgres it is safe though. var res = setupQuery(db, query, args) - var L = PQnfields(res) + var L = pqnfields(res) var result = newRow(L) - for i in 0..PQntuples(res)-1: + for i in 0..pqntuples(res)-1: setRow(res, result, i, L) yield result - PQclear(res) + pqclear(res) proc getRow*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## retrieves a single row. If the query doesn't return any rows, this proc ## will return a TRow with empty strings for each column. var res = setupQuery(db, query, args) - var L = PQnfields(res) + var L = pqnfields(res) result = newRow(L) setRow(res, result, 0, L) - PQclear(res) + pqclear(res) proc getAllRows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the query and returns the whole result dataset. result = @[] - for r in FastRows(db, query, args): + for r in fastRows(db, query, args): result.add(r) iterator rows*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = - ## same as `FastRows`, but slower and safe. - for r in items(GetAllRows(db, query, args)): yield r + ## same as `fastRows`, but slower and safe. + for r in items(getAllRows(db, query, args)): yield r proc getValue*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): string {.tags: [FReadDB].} = ## executes the query and returns the first column of the first row of the ## result dataset. Returns "" if the dataset contains no rows or the database ## value is NULL. - var x = PQgetvalue(setupQuery(db, query, args), 0, 0) + var x = pqgetvalue(setupQuery(db, query, args), 0, 0) result = if isNil(x): "" else: $x proc tryInsertID*(db: TDbConn, query: TSqlQuery, @@ -145,10 +145,10 @@ proc tryInsertID*(db: TDbConn, query: TSqlQuery, ## generated ID for the row or -1 in case of an error. For Postgre this adds ## ``RETURNING id`` to the query, so it only works if your primary key is ## named ``id``. - var x = PQgetvalue(setupQuery(db, TSqlQuery(string(query) & " RETURNING id"), + var x = pqgetvalue(setupQuery(db, TSqlQuery(string(query) & " RETURNING id"), args), 0, 0) if not isNil(x): - result = ParseBiggestInt($x) + result = parseBiggestInt($x) else: result = -1 @@ -158,7 +158,7 @@ proc insertID*(db: TDbConn, query: TSqlQuery, ## generated ID for the row. For Postgre this adds ## ``RETURNING id`` to the query, so it only works if your primary key is ## named ``id``. - result = TryInsertID(db, query, args) + result = tryInsertID(db, query, args) if result < 0: dbError(db) proc execAffectedRows*(db: TDbConn, query: TSqlQuery, @@ -167,14 +167,14 @@ proc execAffectedRows*(db: TDbConn, query: TSqlQuery, ## executes the query (typically "UPDATE") and returns the ## number of affected rows. var q = dbFormat(query, args) - var res = PQExec(db, q) - if PQresultStatus(res) != PGRES_COMMAND_OK: dbError(db) - result = parseBiggestInt($PQcmdTuples(res)) - PQclear(res) + var res = pqExec(db, q) + if pqresultStatus(res) != PGRES_COMMAND_OK: dbError(db) + result = parseBiggestInt($pqcmdTuples(res)) + pqclear(res) proc close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. - if db != nil: PQfinish(db) + if db != nil: pqfinish(db) proc open*(connection, user, password, database: string): TDbConn {. tags: [FDb].} = @@ -195,7 +195,7 @@ proc open*(connection, user, password, database: string): TDbConn {. ## ## Note that the connection parameter is not used but exists to maintain ## the nim db api. - result = PQsetdbLogin(nil, nil, nil, nil, database, user, password) - if PQStatus(result) != CONNECTION_OK: dbError(result) # result = nil + result = pqsetdbLogin(nil, nil, nil, nil, database, user, password) + if pqStatus(result) != CONNECTION_OK: dbError(result) # result = nil diff --git a/lib/impure/web.nim b/lib/impure/web.nim deleted file mode 100644 index f0c19b367..000000000 --- a/lib/impure/web.nim +++ /dev/null @@ -1,63 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2012 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module contains simple high-level procedures for dealing with the -## web. Use cases: -## -## * requesting URLs -## * sending and retrieving emails -## * sending and retrieving files from an FTP server -## -## Currently only requesting URLs is implemented. The implementation depends -## on the libcurl library! -## -## **Deprecated since version 0.8.8:** Use the -## `httpclient `_ module instead. -## - -{.deprecated.} - -import libcurl, streams - -proc curlwrapperWrite(p: pointer, size, nmemb: int, - data: pointer): int {.cdecl.} = - var stream = cast[PStream](data) - stream.writeData(p, size*nmemb) - return size*nmemb - -proc URLretrieveStream*(url: string): PStream = - ## retrieves the given `url` and returns a stream which one can read from to - ## obtain the contents. Returns nil if an error occurs. - result = newStringStream() - var hCurl = easy_init() - if hCurl == nil: return nil - if easy_setopt(hCurl, OPT_URL, url) != E_OK: return nil - if easy_setopt(hCurl, OPT_WRITEFUNCTION, - curlwrapperWrite) != E_OK: return nil - if easy_setopt(hCurl, OPT_WRITEDATA, result) != E_OK: return nil - if easy_perform(hCurl) != E_OK: return nil - easy_cleanup(hCurl) - -proc URLretrieveString*(url: string): TaintedString = - ## retrieves the given `url` and returns the contents. Returns nil if an - ## error occurs. - var stream = newStringStream() - var hCurl = easy_init() - if hCurl == nil: return - if easy_setopt(hCurl, OPT_URL, url) != E_OK: return - if easy_setopt(hCurl, OPT_WRITEFUNCTION, - curlwrapperWrite) != E_OK: return - if easy_setopt(hCurl, OPT_WRITEDATA, stream) != E_OK: return - if easy_perform(hCurl) != E_OK: return - easy_cleanup(hCurl) - result = stream.data.TaintedString - -when isMainModule: - echo URLretrieveString("http://nim-code.org/") - diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim index b850815c9..dc6db4738 100644 --- a/lib/pure/httpserver.nim +++ b/lib/pure/httpserver.nim @@ -22,8 +22,6 @@ ## ## run(handleRequest, TPort(80)) ## -## **Warning:** The API of this module is unstable, and therefore is subject -## to change. import parseutils, strutils, os, osproc, strtabs, streams, sockets, asyncio @@ -90,14 +88,14 @@ proc serveFile*(client: TSocket, filename: string) = headers(client, filename) const bufSize = 8000 # != 8K might be good for memory manager var buf = alloc(bufsize) - while True: + while true: var bytesread = readBuffer(f, buf, bufsize) if bytesread > 0: var byteswritten = send(client, buf, bytesread) if bytesread != bytesWritten: dealloc(buf) close(f) - OSError(OSLastError()) + raiseOSError(osLastError()) if bytesread != bufSize: break dealloc(buf) close(f) @@ -228,9 +226,9 @@ proc open*(s: var TServer, port = TPort(80), reuseAddr = false) = ## creates a new server at port `port`. If ``port == 0`` a free port is ## acquired that can be accessed later by the ``port`` proc. s.socket = socket(AF_INET) - if s.socket == InvalidSocket: OSError(OSLastError()) + if s.socket == invalidSocket: raiseOSError(osLastError()) if reuseAddr: - s.socket.setSockOpt(OptReuseAddr, True) + s.socket.setSockOpt(OptReuseAddr, true) bindAddr(s.socket, port) listen(s.socket) @@ -238,7 +236,7 @@ proc open*(s: var TServer, port = TPort(80), reuseAddr = false) = s.port = getSockName(s.socket) else: s.port = port - s.client = InvalidSocket + s.client = invalidSocket s.reqMethod = "" s.body = "" s.path = "" @@ -346,7 +344,7 @@ proc next*(s: var TServer) = # XXX we ignore "HTTP/1.1" etc. for now here var query = 0 var last = i - while last < data.len and data[last] notin whitespace: + while last < data.len and data[last] notin Whitespace: if data[last] == '?' and query == 0: query = last inc(last) if query > 0: @@ -466,7 +464,7 @@ proc nextAsync(s: PAsyncHTTPServer) = # XXX we ignore "HTTP/1.1" etc. for now here var query = 0 var last = i - while last < data.len and data[last] notin whitespace: + while last < data.len and data[last] notin Whitespace: if data[last] == '?' and query == 0: query = last inc(last) if query > 0: @@ -483,7 +481,7 @@ proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSo ## Creates an Asynchronous HTTP server at ``port``. var capturedRet: PAsyncHTTPServer new(capturedRet) - capturedRet.asyncSocket = AsyncSocket() + capturedRet.asyncSocket = asyncSocket() capturedRet.asyncSocket.handleAccept = proc (s: PAsyncSocket) = nextAsync(capturedRet) @@ -491,7 +489,7 @@ proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSo capturedRet.query) if quit: capturedRet.asyncSocket.close() if reuseAddr: - capturedRet.asyncSocket.setSockOpt(OptReuseAddr, True) + capturedRet.asyncSocket.setSockOpt(OptReuseAddr, true) capturedRet.asyncSocket.bindAddr(port, address) capturedRet.asyncSocket.listen() @@ -500,7 +498,7 @@ proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSo else: capturedRet.port = port - capturedRet.client = InvalidSocket + capturedRet.client = invalidSocket capturedRet.reqMethod = "" capturedRet.body = "" capturedRet.path = "" diff --git a/lib/wrappers/mysql.nim b/lib/wrappers/mysql.nim index 9871d4a7a..945e09ecf 100644 --- a/lib/wrappers/mysql.nim +++ b/lib/wrappers/mysql.nim @@ -729,7 +729,7 @@ type len*: int # output length pointer is_null*: Pmy_bool # Pointer to null indicator buffer*: pointer # buffer to get/put data - error*: pmy_bool # set this if you want to track data truncations happened during fetch + error*: PMy_bool # set this if you want to track data truncations happened during fetch buffer_type*: Tenum_field_types # buffer type buffer_length*: int # buffer length, must be set for str/binary # Following are for internal use. Set by mysql_stmt_bind_param @@ -904,7 +904,7 @@ proc shutdown*(MySQL: PMySQL, shutdown_level: Tenum_shutdown_level): cint{.stdca dynlib: lib, importc: "mysql_shutdown".} proc dump_debug_info*(MySQL: PMySQL): cint{.stdcall, dynlib: lib, importc: "mysql_dump_debug_info".} -proc refresh*(MySQL: PMySQL, refresh_options: cuint): cint{.stdcall, dynlib: lib, +proc refresh*(sql: PMySQL, refresh_options: cuint): cint{.stdcall, dynlib: lib, importc: "mysql_refresh".} proc kill*(MySQL: PMySQL, pid: int): cint{.stdcall, dynlib: lib, importc: "mysql_kill".} proc set_server_option*(MySQL: PMySQL, option: Tenum_mysql_set_option): cint{.stdcall, @@ -1040,7 +1040,7 @@ const NO_DATA* = 100 DATA_TRUNCATED* = 101 -proc reload*(MySQL: PMySQL): cint +proc reload*(x: PMySQL): cint when defined(USE_OLD_FUNCTIONS): proc connect*(MySQL: PMySQL, host: cstring, user: cstring, passwd: cstring): PMySQL{.stdcall, dynlib: lib, importc: "mysql_connect".} @@ -1059,7 +1059,7 @@ proc IS_NOT_NULL(n: int32): bool = proc IS_BLOB(n: int32): bool = result = (n and BLOB_FLAG) != 0 -proc IS_NUM_FIELD(f: pst_mysql_field): bool = +proc IS_NUM_FIELD(f: Pst_mysql_field): bool = result = (f.flags and NUM_FLAG) != 0 proc IS_NUM(t: Tenum_field_types): bool = @@ -1071,7 +1071,7 @@ proc INTERNAL_NUM_FIELD(f: Pst_mysql_field): bool = ((f.ftype != FIELD_TYPE_TIMESTAMP) or (f.len == 14) or (f.len == 8)) or (f.ftype == FIELD_TYPE_YEAR) -proc reload(mysql: PMySQL): cint = - result = refresh(mysql, REFRESH_GRANT) +proc reload(x: PMySQL): cint = + result = refresh(x, REFRESH_GRANT) {.pop.} diff --git a/lib/wrappers/postgres.nim b/lib/wrappers/postgres.nim index d99e5651c..b69c34f3a 100644 --- a/lib/wrappers/postgres.nim +++ b/lib/wrappers/postgres.nim @@ -145,182 +145,182 @@ type p*: pointer -proc PQconnectStart*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName, +proc pqconnectStart*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName, importc: "PQconnectStart".} -proc PQconnectPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl, +proc pqconnectPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl, dynlib: dllName, importc: "PQconnectPoll".} -proc PQconnectdb*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName, +proc pqconnectdb*(conninfo: cstring): PPGconn{.cdecl, dynlib: dllName, importc: "PQconnectdb".} -proc PQsetdbLogin*(pghost: cstring, pgport: cstring, pgoptions: cstring, +proc pqsetdbLogin*(pghost: cstring, pgport: cstring, pgoptions: cstring, pgtty: cstring, dbName: cstring, login: cstring, pwd: cstring): PPGconn{. cdecl, dynlib: dllName, importc: "PQsetdbLogin".} -proc PQsetdb*(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): ppgconn -proc PQfinish*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQfinish".} -proc PQconndefaults*(): PPQconninfoOption{.cdecl, dynlib: dllName, +proc pqsetdb*(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): Ppgconn +proc pqfinish*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQfinish".} +proc pqconndefaults*(): PPQconninfoOption{.cdecl, dynlib: dllName, importc: "PQconndefaults".} -proc PQconninfoFree*(connOptions: PPQconninfoOption){.cdecl, dynlib: dllName, +proc pqconninfoFree*(connOptions: PPQconninfoOption){.cdecl, dynlib: dllName, importc: "PQconninfoFree".} -proc PQresetStart*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqresetStart*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQresetStart".} -proc PQresetPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl, +proc pqresetPoll*(conn: PPGconn): PostgresPollingStatusType{.cdecl, dynlib: dllName, importc: "PQresetPoll".} -proc PQreset*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQreset".} -proc PQrequestCancel*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqreset*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQreset".} +proc pqrequestCancel*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQrequestCancel".} -proc PQdb*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQdb".} -proc PQuser*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQuser".} -proc PQpass*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQpass".} -proc PQhost*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQhost".} -proc PQport*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQport".} -proc PQtty*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQtty".} -proc PQoptions*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, +proc pqdb*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQdb".} +proc pquser*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQuser".} +proc pqpass*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQpass".} +proc pqhost*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQhost".} +proc pqport*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQport".} +proc pqtty*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQtty".} +proc pqoptions*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQoptions".} -proc PQstatus*(conn: PPGconn): TConnStatusType{.cdecl, dynlib: dllName, +proc pqstatus*(conn: PPGconn): TConnStatusType{.cdecl, dynlib: dllName, importc: "PQstatus".} -proc PQtransactionStatus*(conn: PPGconn): PGTransactionStatusType{.cdecl, +proc pqtransactionStatus*(conn: PPGconn): PGTransactionStatusType{.cdecl, dynlib: dllName, importc: "PQtransactionStatus".} -proc PQparameterStatus*(conn: PPGconn, paramName: cstring): cstring{.cdecl, +proc pqparameterStatus*(conn: PPGconn, paramName: cstring): cstring{.cdecl, dynlib: dllName, importc: "PQparameterStatus".} -proc PQprotocolVersion*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqprotocolVersion*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQprotocolVersion".} -proc PQerrorMessage*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, +proc pqerrorMessage*(conn: PPGconn): cstring{.cdecl, dynlib: dllName, importc: "PQerrorMessage".} -proc PQsocket*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqsocket*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQsocket".} -proc PQbackendPID*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqbackendPID*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQbackendPID".} -proc PQclientEncoding*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqclientEncoding*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQclientEncoding".} -proc PQsetClientEncoding*(conn: PPGconn, encoding: cstring): int32{.cdecl, +proc pqsetClientEncoding*(conn: PPGconn, encoding: cstring): int32{.cdecl, dynlib: dllName, importc: "PQsetClientEncoding".} when defined(USE_SSL): # Get the SSL structure associated with a connection - proc PQgetssl*(conn: PPGconn): PSSL{.cdecl, dynlib: dllName, + proc pqgetssl*(conn: PPGconn): PSSL{.cdecl, dynlib: dllName, importc: "PQgetssl".} -proc PQsetErrorVerbosity*(conn: PPGconn, verbosity: PGVerbosity): PGVerbosity{. +proc pqsetErrorVerbosity*(conn: PPGconn, verbosity: PGVerbosity): PGVerbosity{. cdecl, dynlib: dllName, importc: "PQsetErrorVerbosity".} -proc PQtrace*(conn: PPGconn, debug_port: TFile){.cdecl, dynlib: dllName, +proc pqtrace*(conn: PPGconn, debug_port: TFile){.cdecl, dynlib: dllName, importc: "PQtrace".} -proc PQuntrace*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQuntrace".} -proc PQsetNoticeReceiver*(conn: PPGconn, theProc: PQnoticeReceiver, arg: pointer): PQnoticeReceiver{. +proc pquntrace*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQuntrace".} +proc pqsetNoticeReceiver*(conn: PPGconn, theProc: PQnoticeReceiver, arg: pointer): PQnoticeReceiver{. cdecl, dynlib: dllName, importc: "PQsetNoticeReceiver".} -proc PQsetNoticeProcessor*(conn: PPGconn, theProc: PQnoticeProcessor, +proc pqsetNoticeProcessor*(conn: PPGconn, theProc: PQnoticeProcessor, arg: pointer): PQnoticeProcessor{.cdecl, dynlib: dllName, importc: "PQsetNoticeProcessor".} -proc PQexec*(conn: PPGconn, query: cstring): PPGresult{.cdecl, dynlib: dllName, +proc pqexec*(conn: PPGconn, query: cstring): PPGresult{.cdecl, dynlib: dllName, importc: "PQexec".} -proc PQexecParams*(conn: PPGconn, command: cstring, nParams: int32, +proc pqexecParams*(conn: PPGconn, command: cstring, nParams: int32, paramTypes: POid, paramValues: cstringArray, paramLengths, paramFormats: ptr int32, resultFormat: int32): PPGresult{. cdecl, dynlib: dllName, importc: "PQexecParams".} -proc PQexecPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, +proc pqexecPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, paramValues: cstringArray, paramLengths, paramFormats: ptr int32, resultFormat: int32): PPGresult{. cdecl, dynlib: dllName, importc: "PQexecPrepared".} -proc PQsendQuery*(conn: PPGconn, query: cstring): int32{.cdecl, dynlib: dllName, +proc pqsendQuery*(conn: PPGconn, query: cstring): int32{.cdecl, dynlib: dllName, importc: "PQsendQuery".} -proc PQsendQueryParams*(conn: PPGconn, command: cstring, nParams: int32, +proc pqsendQueryParams*(conn: PPGconn, command: cstring, nParams: int32, paramTypes: POid, paramValues: cstringArray, paramLengths, paramFormats: ptr int32, resultFormat: int32): int32{.cdecl, dynlib: dllName, importc: "PQsendQueryParams".} -proc PQsendQueryPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, +proc pqsendQueryPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, paramValues: cstringArray, paramLengths, paramFormats: ptr int32, resultFormat: int32): int32{.cdecl, dynlib: dllName, importc: "PQsendQueryPrepared".} -proc PQgetResult*(conn: PPGconn): PPGresult{.cdecl, dynlib: dllName, +proc pqgetResult*(conn: PPGconn): PPGresult{.cdecl, dynlib: dllName, importc: "PQgetResult".} -proc PQisBusy*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqisBusy*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQisBusy".} -proc PQconsumeInput*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqconsumeInput*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQconsumeInput".} -proc PQnotifies*(conn: PPGconn): PPGnotify{.cdecl, dynlib: dllName, +proc pqnotifies*(conn: PPGconn): PPGnotify{.cdecl, dynlib: dllName, importc: "PQnotifies".} -proc PQputCopyData*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{. +proc pqputCopyData*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{. cdecl, dynlib: dllName, importc: "PQputCopyData".} -proc PQputCopyEnd*(conn: PPGconn, errormsg: cstring): int32{.cdecl, +proc pqputCopyEnd*(conn: PPGconn, errormsg: cstring): int32{.cdecl, dynlib: dllName, importc: "PQputCopyEnd".} -proc PQgetCopyData*(conn: PPGconn, buffer: cstringArray, async: int32): int32{. +proc pqgetCopyData*(conn: PPGconn, buffer: cstringArray, async: int32): int32{. cdecl, dynlib: dllName, importc: "PQgetCopyData".} -proc PQgetline*(conn: PPGconn, str: cstring, len: int32): int32{.cdecl, +proc pqgetline*(conn: PPGconn, str: cstring, len: int32): int32{.cdecl, dynlib: dllName, importc: "PQgetline".} -proc PQputline*(conn: PPGconn, str: cstring): int32{.cdecl, dynlib: dllName, +proc pqputline*(conn: PPGconn, str: cstring): int32{.cdecl, dynlib: dllName, importc: "PQputline".} -proc PQgetlineAsync*(conn: PPGconn, buffer: cstring, bufsize: int32): int32{. +proc pqgetlineAsync*(conn: PPGconn, buffer: cstring, bufsize: int32): int32{. cdecl, dynlib: dllName, importc: "PQgetlineAsync".} -proc PQputnbytes*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{.cdecl, +proc pqputnbytes*(conn: PPGconn, buffer: cstring, nbytes: int32): int32{.cdecl, dynlib: dllName, importc: "PQputnbytes".} -proc PQendcopy*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqendcopy*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQendcopy".} -proc PQsetnonblocking*(conn: PPGconn, arg: int32): int32{.cdecl, +proc pqsetnonblocking*(conn: PPGconn, arg: int32): int32{.cdecl, dynlib: dllName, importc: "PQsetnonblocking".} -proc PQisnonblocking*(conn: PPGconn): int32{.cdecl, dynlib: dllName, +proc pqisnonblocking*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQisnonblocking".} -proc PQflush*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQflush".} -proc PQfn*(conn: PPGconn, fnid: int32, result_buf, result_len: ptr int32, +proc pqflush*(conn: PPGconn): int32{.cdecl, dynlib: dllName, importc: "PQflush".} +proc pqfn*(conn: PPGconn, fnid: int32, result_buf, result_len: ptr int32, result_is_int: int32, args: PPQArgBlock, nargs: int32): PPGresult{. cdecl, dynlib: dllName, importc: "PQfn".} -proc PQresultStatus*(res: PPGresult): TExecStatusType{.cdecl, dynlib: dllName, +proc pqresultStatus*(res: PPGresult): TExecStatusType{.cdecl, dynlib: dllName, importc: "PQresultStatus".} -proc PQresStatus*(status: TExecStatusType): cstring{.cdecl, dynlib: dllName, +proc pqresStatus*(status: TExecStatusType): cstring{.cdecl, dynlib: dllName, importc: "PQresStatus".} -proc PQresultErrorMessage*(res: PPGresult): cstring{.cdecl, dynlib: dllName, +proc pqresultErrorMessage*(res: PPGresult): cstring{.cdecl, dynlib: dllName, importc: "PQresultErrorMessage".} -proc PQresultErrorField*(res: PPGresult, fieldcode: int32): cstring{.cdecl, +proc pqresultErrorField*(res: PPGresult, fieldcode: int32): cstring{.cdecl, dynlib: dllName, importc: "PQresultErrorField".} -proc PQntuples*(res: PPGresult): int32{.cdecl, dynlib: dllName, +proc pqntuples*(res: PPGresult): int32{.cdecl, dynlib: dllName, importc: "PQntuples".} -proc PQnfields*(res: PPGresult): int32{.cdecl, dynlib: dllName, +proc pqnfields*(res: PPGresult): int32{.cdecl, dynlib: dllName, importc: "PQnfields".} -proc PQbinaryTuples*(res: PPGresult): int32{.cdecl, dynlib: dllName, +proc pqbinaryTuples*(res: PPGresult): int32{.cdecl, dynlib: dllName, importc: "PQbinaryTuples".} -proc PQfname*(res: PPGresult, field_num: int32): cstring{.cdecl, +proc pqfname*(res: PPGresult, field_num: int32): cstring{.cdecl, dynlib: dllName, importc: "PQfname".} -proc PQfnumber*(res: PPGresult, field_name: cstring): int32{.cdecl, +proc pqfnumber*(res: PPGresult, field_name: cstring): int32{.cdecl, dynlib: dllName, importc: "PQfnumber".} -proc PQftable*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName, +proc pqftable*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName, importc: "PQftable".} -proc PQftablecol*(res: PPGresult, field_num: int32): int32{.cdecl, +proc pqftablecol*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, importc: "PQftablecol".} -proc PQfformat*(res: PPGresult, field_num: int32): int32{.cdecl, +proc pqfformat*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, importc: "PQfformat".} -proc PQftype*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName, +proc pqftype*(res: PPGresult, field_num: int32): Oid{.cdecl, dynlib: dllName, importc: "PQftype".} -proc PQfsize*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, +proc pqfsize*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, importc: "PQfsize".} -proc PQfmod*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, +proc pqfmod*(res: PPGresult, field_num: int32): int32{.cdecl, dynlib: dllName, importc: "PQfmod".} -proc PQcmdStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName, +proc pqcmdStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName, importc: "PQcmdStatus".} -proc PQoidStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName, +proc pqoidStatus*(res: PPGresult): cstring{.cdecl, dynlib: dllName, importc: "PQoidStatus".} -proc PQoidValue*(res: PPGresult): Oid{.cdecl, dynlib: dllName, +proc pqoidValue*(res: PPGresult): Oid{.cdecl, dynlib: dllName, importc: "PQoidValue".} -proc PQcmdTuples*(res: PPGresult): cstring{.cdecl, dynlib: dllName, +proc pqcmdTuples*(res: PPGresult): cstring{.cdecl, dynlib: dllName, importc: "PQcmdTuples".} -proc PQgetvalue*(res: PPGresult, tup_num: int32, field_num: int32): cstring{. +proc pqgetvalue*(res: PPGresult, tup_num: int32, field_num: int32): cstring{. cdecl, dynlib: dllName, importc: "PQgetvalue".} -proc PQgetlength*(res: PPGresult, tup_num: int32, field_num: int32): int32{. +proc pqgetlength*(res: PPGresult, tup_num: int32, field_num: int32): int32{. cdecl, dynlib: dllName, importc: "PQgetlength".} -proc PQgetisnull*(res: PPGresult, tup_num: int32, field_num: int32): int32{. +proc pqgetisnull*(res: PPGresult, tup_num: int32, field_num: int32): int32{. cdecl, dynlib: dllName, importc: "PQgetisnull".} -proc PQclear*(res: PPGresult){.cdecl, dynlib: dllName, importc: "PQclear".} -proc PQfreemem*(p: pointer){.cdecl, dynlib: dllName, importc: "PQfreemem".} -proc PQmakeEmptyPGresult*(conn: PPGconn, status: TExecStatusType): PPGresult{. +proc pqclear*(res: PPGresult){.cdecl, dynlib: dllName, importc: "PQclear".} +proc pqfreemem*(p: pointer){.cdecl, dynlib: dllName, importc: "PQfreemem".} +proc pqmakeEmptyPGresult*(conn: PPGconn, status: TExecStatusType): PPGresult{. cdecl, dynlib: dllName, importc: "PQmakeEmptyPGresult".} -proc PQescapeString*(till, `from`: cstring, len: int): int{.cdecl, +proc pqescapeString*(till, `from`: cstring, len: int): int{.cdecl, dynlib: dllName, importc: "PQescapeString".} -proc PQescapeBytea*(bintext: cstring, binlen: int, bytealen: var int): cstring{. +proc pqescapeBytea*(bintext: cstring, binlen: int, bytealen: var int): cstring{. cdecl, dynlib: dllName, importc: "PQescapeBytea".} -proc PQunescapeBytea*(strtext: cstring, retbuflen: var int): cstring{.cdecl, +proc pqunescapeBytea*(strtext: cstring, retbuflen: var int): cstring{.cdecl, dynlib: dllName, importc: "PQunescapeBytea".} -proc PQprint*(fout: TFile, res: PPGresult, ps: PPQprintOpt){.cdecl, +proc pqprint*(fout: TFile, res: PPGresult, ps: PPQprintOpt){.cdecl, dynlib: dllName, importc: "PQprint".} -proc PQdisplayTuples*(res: PPGresult, fp: TFile, fillAlign: int32, +proc pqdisplayTuples*(res: PPGresult, fp: TFile, fillAlign: int32, fieldSep: cstring, printHeader: int32, quiet: int32){. cdecl, dynlib: dllName, importc: "PQdisplayTuples".} -proc PQprintTuples*(res: PPGresult, fout: TFile, printAttName: int32, +proc pqprintTuples*(res: PPGresult, fout: TFile, printAttName: int32, terseOutput: int32, width: int32){.cdecl, dynlib: dllName, importc: "PQprintTuples".} proc lo_open*(conn: PPGconn, lobjId: Oid, mode: int32): int32{.cdecl, @@ -343,8 +343,8 @@ proc lo_import*(conn: PPGconn, filename: cstring): Oid{.cdecl, dynlib: dllName, importc: "lo_import".} proc lo_export*(conn: PPGconn, lobjId: Oid, filename: cstring): int32{.cdecl, dynlib: dllName, importc: "lo_export".} -proc PQmblen*(s: cstring, encoding: int32): int32{.cdecl, dynlib: dllName, +proc pqmblen*(s: cstring, encoding: int32): int32{.cdecl, dynlib: dllName, importc: "PQmblen".} -proc PQenv2encoding*(): int32{.cdecl, dynlib: dllName, importc: "PQenv2encoding".} -proc PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): ppgconn = - result = PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, "", "") +proc pqenv2encoding*(): int32{.cdecl, dynlib: dllName, importc: "PQenv2encoding".} +proc pqsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME: cstring): PPgConn = + result = pqSetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, "", "") diff --git a/lib/wrappers/sqlite3.nim b/lib/wrappers/sqlite3.nim index c8bce712d..e3a3fa0b8 100644 --- a/lib/wrappers/sqlite3.nim +++ b/lib/wrappers/sqlite3.nim @@ -88,8 +88,8 @@ const SQLITE_REINDEX* = 27 SQLITE_DENY* = 1 SQLITE_IGNORE* = 2 # Original from sqlite3.h: - ##define SQLITE_STATIC ((void(*)(void *))0) - ##define SQLITE_TRANSIENT ((void(*)(void *))-1) + #define SQLITE_STATIC ((void(*)(void *))0) + #define SQLITE_TRANSIENT ((void(*)(void *))-1) SQLITE_DETERMINISTIC* = 0x800 const diff --git a/web/news.txt b/web/news.txt index 0b4c98b73..2c6ef4196 100644 --- a/web/news.txt +++ b/web/news.txt @@ -42,8 +42,11 @@ News and is now a Nimble package. - Many wrappers have been moved into their own repositories and are now Nimble packages including ``lua``, ``opengl``, ``x11``, ``nim-zmq``, - ``gtk2``, ``mongo``, ``cairo``, ``tcl`` and ``python``. They can be + ``gtk2``, ``mongo``, ``cairo``, ``tcl``, ``python`` and + `more `_. They can be found under the `nim-code `_ organisation. + - Removed the deprecated ``web`` module, the ``httpclient`` module should + be used instead. Language Additions ------------------ diff --git a/web/nim.ini b/web/nim.ini index d610408f7..a5efbaf2a 100644 --- a/web/nim.ini +++ b/web/nim.ini @@ -39,7 +39,7 @@ UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson.""" doc: "endb;intern;apis;lib;manual;tut1;tut2;nimc;overview;filters" doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt" pdf: "manual;lib;tut1;tut2;nimc;niminst;gc" -srcdoc2: "system.nim;impure/graphics;wrappers/sdl" +srcdoc2: "system.nim" srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned" srcdoc2: "impure/re;pure/sockets;pure/typetraits" srcdoc: "system/threads.nim;system/channels.nim;js/dom" @@ -47,7 +47,7 @@ srcdoc2: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm" srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib" srcdoc2: "pure/parseopt;pure/parseopt2;pure/hashes;pure/strtabs;pure/lexbase" srcdoc2: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql" -srcdoc2: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode" +srcdoc2: "pure/streams;pure/terminal;pure/cgi;pure/unicode" srcdoc2: "impure/zipfiles;pure/htmlgen;pure/parseutils;pure/browsers" srcdoc2: "impure/db_postgres;impure/db_mysql;impure/db_sqlite" srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl;pure/fsmonitor" @@ -67,14 +67,14 @@ srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors;pure/futu srcdoc2: "wrappers/expat;wrappers/readline/history" srcdoc2: "wrappers/libsvm.nim;wrappers/libuv" srcdoc2: "wrappers/zip/zlib;wrappers/zip/libzip" -srcdoc2: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup" +srcdoc2: "pure/md5;wrappers/mysql;wrappers/iup" srcdoc2: "posix/posix;wrappers/odbcsql" srcdoc2: "wrappers/tre;wrappers/openssl;wrappers/pcre" srcdoc2: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc" srcdoc2: "wrappers/readline/readline;wrappers/readline/rltypedefs" srcdoc2: "wrappers/joyent_http_parser" -webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup" +webdoc: "pure/md5;wrappers/mysql;wrappers/iup" webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc" webdoc: "wrappers/expat;wrappers/pcre" webdoc: "wrappers/tre;wrappers/openssl" From e24996de7c7ef1b1e1bc7fe44b977e655a36864f Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 13 Sep 2014 17:53:35 +0200 Subject: [PATCH 122/409] minor changes to manual.txt --- compiler/semstmts.nim | 2 +- doc/manual.txt | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index aaddc84d0..5cb2eabf8 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -354,7 +354,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) if typ != nil: if typ.isMetaType: - def = inferWithMetaType(c, typ, def) + def = inferWithMetatype(c, typ, def) typ = def.typ else: # BUGFIX: ``fitNode`` is needed here! diff --git a/doc/manual.txt b/doc/manual.txt index f0f50e373..3d14ef488 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -596,7 +596,7 @@ Ordinal types Ordinal types have the following characteristics: - Ordinal types are countable and ordered. This property allows - the operation of functions as ``Inc``, ``Ord``, ``Dec`` on ordinal types to + the operation of functions as ``inc``, ``ord``, ``dec`` on ordinal types to be defined. - Ordinal values have a smallest possible value. Trying to count further down than the smallest value gives a checked runtime or static error. @@ -699,11 +699,11 @@ lowest and highest value of the type: .. code-block:: nim type - TSubrange = range[0..5] + Subrange = range[0..5] -``TSubrange`` is a subrange of an integer which can only hold the values 0 -to 5. Assigning any other value to a variable of type ``TSubrange`` is a +``Subrange`` is a subrange of an integer which can only hold the values 0 +to 5. Assigning any other value to a variable of type ``Subrange`` is a checked runtime error (or static error if it can be statically determined). Assignments from the base type to one of its subrange types (and vice versa) are allowed. @@ -791,6 +791,10 @@ turned off as default. The only operations that are affected by the ``floatChecks`` pragma are the ``+``, ``-``, ``*``, ``/`` operators for floating point types. +An implementation should always use the maximum precision available to evaluate +floating pointer values at compile time; this means expressions like +``0.09'f32 + 0.01'f32 == 0.09'f64 + 0.01'f64`` are true. + Boolean type ------------ @@ -3675,10 +3679,11 @@ Future versions of Nim may also support overloading based on the return type of the overloads. In such settings, the expected result type at call sites may also influence the inferred return type. -Likewise, if a type class is used in another position where Nim expects a -concrete type (e.g. a variable declaration or a type coercion), Nim will try to -infer the concrete type by applying the sane matching algorithm also used in -overload resolution. +.. + Likewise, if a type class is used in another position where Nim expects a + concrete type (e.g. a variable declaration or a type coercion), Nim will try + to infer the concrete type by applying the matching algorithm that also used + in overload resolution. Symbol lookup in generics From 8b8841a6c1bbabebdfa8394f5fd3bd5f36202017 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 13 Sep 2014 20:39:18 +0100 Subject: [PATCH 123/409] NimFix on net and rawsockets modules. --- lib/pure/net.nim | 8 ++++---- lib/pure/rawsockets.nim | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 55ddf4bc2..886ed792f 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -287,11 +287,11 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {. name.sin_port = htons(int16(port)) name.sin_addr.s_addr = htonl(INADDR_ANY) if bindAddr(socket.fd, cast[ptr SockAddr](addr(name)), - sizeof(name).Socklen) < 0'i32: + sizeof(name).SockLen) < 0'i32: raiseOSError(osLastError()) else: var aiList = getAddrInfo(address, port, AF_INET) - if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32: + if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32: dealloc(aiList) raiseOSError(osLastError()) dealloc(aiList) @@ -315,7 +315,7 @@ proc acceptAddr*(server: Socket, client: var Socket, address: var string, ## accept will be called again. assert(client != nil) var sockAddress: Sockaddr_in - var addrLen = sizeof(sockAddress).Socklen + var addrLen = sizeof(sockAddress).SockLen var sock = accept(server.fd, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) @@ -754,7 +754,7 @@ proc recvFrom*(socket: Socket, data: var string, length: int, # TODO: Buffered sockets data.setLen(length) - var sockAddress: SockAddrIn + var sockAddress: Sockaddr_in var addrLen = sizeof(sockAddress).SockLen result = recvfrom(socket.fd, cstring(data), length.cint, flags.cint, cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index 7e293f490..c76e99fcb 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -162,7 +162,7 @@ proc close*(socket: SocketHandle) = # TODO: These values should not be discarded. An EOS should be raised. # http://stackoverflow.com/questions/12463473/what-happens-if-you-call-close-on-a-bsd-socket-multiple-times -proc bindAddr*(socket: SocketHandle, name: ptr SockAddr, namelen: Socklen): cint = +proc bindAddr*(socket: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint = result = bindSocket(socket, name, namelen) proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [ReadIOEffect].} = @@ -314,7 +314,7 @@ proc getSockName*(socket: SocketHandle): Port = name.sin_family = posix.AF_INET #name.sin_port = htons(cint16(port)) #name.sin_addr.s_addr = htonl(INADDR_ANY) - var namelen = sizeof(name).Socklen + var namelen = sizeof(name).SockLen if getsockname(socket, cast[ptr SockAddr](addr(name)), addr(namelen)) == -1'i32: raiseOSError(osLastError()) @@ -324,7 +324,7 @@ proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {. tags: [ReadIOEffect].} = ## getsockopt for integer options. var res: cint - var size = sizeof(res).Socklen + var size = sizeof(res).SockLen if getsockopt(socket, cint(level), cint(optname), addr(res), addr(size)) < 0'i32: raiseOSError(osLastError()) @@ -335,7 +335,7 @@ proc setSockOptInt*(socket: SocketHandle, level, optname, optval: int) {. ## setsockopt for integer options. var value = cint(optval) if setsockopt(socket, cint(level), cint(optname), addr(value), - sizeof(value).Socklen) < 0'i32: + sizeof(value).SockLen) < 0'i32: raiseOSError(osLastError()) proc setBlocking*(s: SocketHandle, blocking: bool) = From 05f09fafcffb8578b03fb719e7f8f0cdbae7ed99 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 14 Sep 2014 11:27:14 +0200 Subject: [PATCH 124/409] fixed 'system.open' bug --- lib/system/sysio.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index 56de5e6e8..7908fbe4d 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -215,13 +215,13 @@ proc open(f: var File, filename: string, mode: FileMode = fmRead, bufSize: int = -1): bool = var p: pointer = fopen(filename, FormatOpen[mode]) - result = (p != nil) - f = cast[File](p) - if bufSize > 0 and bufSize <= high(cint).int: - if setvbuf(f, nil, IOFBF, bufSize.cint) != 0'i32: - sysFatal(OutOfMemError, "out of memory") - elif bufSize == 0: - discard setvbuf(f, nil, IONBF, 0) + if p != nil: + result = true + f = cast[File](p) + if bufSize > 0 and bufSize <= high(cint).int: + discard setvbuf(f, nil, IOFBF, bufSize.cint) + elif bufSize == 0: + discard setvbuf(f, nil, IONBF, 0) proc reopen(f: File, filename: string, mode: FileMode = fmRead): bool = var p: pointer = freopen(filename, FormatOpen[mode], f) From d330a72a4565353bd3ad54ade0580d53cd9d5a5d Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 14 Sep 2014 11:34:06 +0200 Subject: [PATCH 125/409] fixes documentation generator --- compiler/msgs.nim | 2 +- compiler/options.nim | 5 +++-- compiler/pretty.nim | 6 +++++- compiler/vm.nim | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 622c64359..da2fe122d 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -442,7 +442,7 @@ type TNoteKinds* = set[TNoteKind] TFileInfo*{.final.} = object - fullPath*: string # This is a canonical full filesystem path + fullPath: string # This is a canonical full filesystem path projPath*: string # This is relative to the project's root shortName*: string # short name of the module quotedName*: PRope # cached quoted short name for codegen diff --git a/compiler/options.nim b/compiler/options.nim index 69067b7c4..9d7df2f2b 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -188,8 +188,9 @@ proc getPrefixDir*(): string = result = splitPath(getAppDir()).head proc canonicalizePath*(path: string): string = - result = path.expandFilename - when not FileSystemCaseSensitive: result = result.toLower + #result = path.expandFilename + when not FileSystemCaseSensitive: result = path.toLower + else: result = path proc shortenDir*(dir: string): string = ## returns the interesting part of a dir diff --git a/compiler/pretty.nim b/compiler/pretty.nim index 9f2074a0b..ec9322309 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -110,7 +110,7 @@ template styleCheckDef*(info: TLineInfo; s: PSym) = template styleCheckDef*(s: PSym) = styleCheckDef(s.info, s, s.kind) -proc styleCheckUse*(info: TLineInfo; s: PSym) = +proc styleCheckUseImpl(info: TLineInfo; s: PSym) = if info.fileIndex < 0: return # we simply convert it to what it looks like in the definition # for consistency @@ -138,3 +138,7 @@ proc styleCheckUse*(info: TLineInfo; s: PSym) = system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) gSourceFiles[info.fileIndex].dirty = true #if newName == "File": writeStackTrace() + +template styleCheckUse*(info: TLineInfo; s: PSym) = + when defined(nimfix): + if gStyleCheck != StyleCheck.None: styleCheckUseImpl(info, s) diff --git a/compiler/vm.nim b/compiler/vm.nim index 5ef4576ec..f74f2e0d7 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1135,14 +1135,14 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcParseExprToAst: decodeB(rkNode) # c.debug[pc].line.int - countLines(regs[rb].strVal) ? - let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFilename, + let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, c.debug[pc].line.int) if sonsLen(ast) != 1: globalError(c.debug[pc], errExprExpected, "multiple statements") regs[ra].node = ast.sons[0] of opcParseStmtToAst: decodeB(rkNode) - let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFilename, + let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, c.debug[pc].line.int) regs[ra].node = ast of opcCallSite: From 1c241e17fe807f9876950731a834f502d3b87804 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 14 Sep 2014 14:29:35 +0200 Subject: [PATCH 126/409] nimweb compiles again --- tools/nimweb.nim | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tools/nimweb.nim b/tools/nimweb.nim index c6602d884..8744a250e 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -300,14 +300,9 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) = proc buildAddDoc(c: var TConfigData, destPath: string) = # build additional documentation (without the index): -<<<<<<< HEAD var commands = newSeq[string](c.webdoc.len) for i, doc in pairs(c.webdoc): - commands[i] = "nimrod doc $# --docSeeSrcUrl:$# -o:$# $#" % -======= - for d in items(c.webdoc): - exec("nim doc $# --docSeeSrcUrl:$# -o:$# $#" % ->>>>>>> 0047172274a73c681f619f5cd60aaad7109f694d + commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# $#" % [c.nimrodArgs, c.gitCommit, destPath / changeFileExt(splitFile(doc).name, "html"), doc] mexec(commands, c.numProcessors) From 113a1c450c40478e532b616778b6f2f8377bfd37 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 14 Sep 2014 14:38:11 +0200 Subject: [PATCH 127/409] generic proc type works again --- compiler/semtypes.nim | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 4badf8f4e..83cbca50f 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -819,13 +819,14 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result.shouldHaveMeta of tyGenericInvokation: - for i in 1 .. Date: Sun, 14 Sep 2014 18:45:12 +0100 Subject: [PATCH 128/409] Fix build instructions in readme. --- readme.md | 6 +++--- readme.txt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/readme.md b/readme.md index 83d6ef748..7c6fc8e45 100644 --- a/readme.md +++ b/readme.md @@ -30,9 +30,9 @@ To build from source you will need: If you are on a fairly modern *nix system, the following steps should work: ``` -$ git clone git://github.com/Araq/Nim.git -$ cd Nim -$ git clone --depth 1 git://github.com/nim-code/csources +$ git clone git://github.com/Araq/Nimrod.git +$ cd Nimrod +$ git clone --depth 1 git://github.com/nimrod-code/csources $ cd csources && sh build.sh $ cd .. $ bin/nim c koch diff --git a/readme.txt b/readme.txt index 21448b71b..7c6fc8e45 100644 --- a/readme.txt +++ b/readme.txt @@ -30,10 +30,10 @@ To build from source you will need: If you are on a fairly modern *nix system, the following steps should work: ``` -$ git clone git://github.com/Araq/Nim.git -$ cd Nim -$ git clone --depth 1 git://github.com/nim-code/csources -$ cd csources && ./build.sh +$ git clone git://github.com/Araq/Nimrod.git +$ cd Nimrod +$ git clone --depth 1 git://github.com/nimrod-code/csources +$ cd csources && sh build.sh $ cd .. $ bin/nim c koch $ ./koch boot -d:release From efca06c71c47eb636aacefe97e5816dc2e1082ff Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Tue, 16 Sep 2014 16:37:53 +0100 Subject: [PATCH 129/409] Add bool to determine if socket has been closed. --- lib/pure/asynchttpserver.nim | 2 +- lib/pure/asyncnet.nim | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 9de0a6268..257fbaeb5 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -116,7 +116,7 @@ proc sendStatus(client: PAsyncSocket, status: string): Future[void] = proc processClient(client: PAsyncSocket, address: string, callback: proc (request: TRequest): Future[void] {.closure, gcsafe.}) {.async.} = - while true: + while not client.closed: # GET /path HTTP/1.1 # Header: val # \n diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index a16111349..c6918517e 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -67,7 +67,8 @@ type # PAsyncSocket* {.borrow: `.`.} = distinct PSocket. But that doesn't work. AsyncSocketDesc = object fd*: SocketHandle - case isBuffered*: bool # determines whether this socket is buffered. + closed*: bool ## determines whether this socket has been closed + case isBuffered*: bool ## determines whether this socket is buffered. of true: buffer*: array[0..BufferSize, char] currPos*: int # current index in buffer @@ -400,6 +401,7 @@ proc close*(socket: PAsyncSocket) = raiseSslError() elif res != 1: raiseSslError() + socket.closed = true # TODO: Add extra debugging checks for this. when defined(ssl): proc wrapSocket*(ctx: SslContext, socket: AsyncSocket) = From 297647affeca558e19899191089af35ba31db8ac Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 16 Sep 2014 22:49:10 +0200 Subject: [PATCH 130/409] fixes a recently introduced regression --- compiler/options.nim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/options.nim b/compiler/options.nim index 9d7df2f2b..838f99f8e 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -188,9 +188,8 @@ proc getPrefixDir*(): string = result = splitPath(getAppDir()).head proc canonicalizePath*(path: string): string = - #result = path.expandFilename - when not FileSystemCaseSensitive: result = path.toLower - else: result = path + when not FileSystemCaseSensitive: result = path.expandFilename.toLower + else: result = path.expandFilename proc shortenDir*(dir: string): string = ## returns the interesting part of a dir From 344488fa0d44b27f0b73fc5b4d27c2860e448257 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Sep 2014 01:35:46 +0200 Subject: [PATCH 131/409] ttypeclasses works again --- compiler/semtypes.nim | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 83cbca50f..559bf2e06 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -819,11 +819,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result.shouldHaveMeta of tyGenericInvokation: + for i in 1 .. Date: Wed, 17 Sep 2014 01:45:27 +0200 Subject: [PATCH 132/409] improvements for nimfix --- compiler/nimfix.nim | 10 +++++--- compiler/pretty.nim | 56 +++++++++++++++++++++++------------------ compiler/prettybase.nim | 2 ++ 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/compiler/nimfix.nim b/compiler/nimfix.nim index 7e546fe0f..15174fd48 100644 --- a/compiler/nimfix.nim +++ b/compiler/nimfix.nim @@ -21,9 +21,11 @@ Usage: Options: --overwriteFiles:on|off overwrite the original nim files. DEFAULT is ON! + --onlyMainfile overwrite only the main file. --checkExtern:on|off style check also extern names - --styleCheck:on|off performs style checking for identifiers - and suggests an alternative spelling. + --styleCheck:on|off|auto performs style checking for identifiers + and suggests an alternative spelling; + 'auto' corrects the spelling. In addition, all command line options of Nim are supported. """ @@ -63,8 +65,10 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) = of "stylecheck": case p.val.normalize of "off": gStyleCheck = StyleCheck.None - of "on": gStyleCheck = StyleCheck.Auto + of "on": gStyleCheck = StyleCheck.Warn + of "auto": gStyleCheck = StyleCheck.Auto else: localError(gCmdLineInfo, errOnOrOffExpected) + of "onlymainfile": gOnlyMainfile = true else: processSwitch(pass, p) of cmdArgument: diff --git a/compiler/pretty.nim b/compiler/pretty.nim index ec9322309..acac574af 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -15,17 +15,18 @@ import intsets, strtabs, semdata, prettybase type - StyleCheck* {.pure.} = enum None, Confirm, Auto + StyleCheck* {.pure.} = enum None, Warn, Auto var gOverWrite* = true gStyleCheck*: StyleCheck - gCheckExtern*: bool + gCheckExtern*, gOnlyMainfile*: bool proc overwriteFiles*() = let doStrip = options.getConfigVar("pretty.strip").normalize == "on" for i in 0 .. high(gSourceFiles): - if gSourceFiles[i].dirty and not gSourceFiles[i].isNimfixFile: + if gSourceFiles[i].dirty and not gSourceFiles[i].isNimfixFile and + (not gOnlyMainfile or gSourceFiles[i].fileIdx == gProjectMainIdx): let newFile = if gOverWrite: gSourceFiles[i].fullpath else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim") try: @@ -89,17 +90,39 @@ proc beautifyName(s: string, k: TSymKind): string = result.add s[i] inc i -proc checkStyle(info: TLineInfo, s: string, k: TSymKind) = +proc replaceInFile(info: TLineInfo; newName: string) = + loadFile(info) + + let line = gSourceFiles[info.fileIndex].lines[info.line-1] + var first = min(info.col.int, line.len) + if first < 0: return + #inc first, skipIgnoreCase(line, "proc ", first) + while first > 0 and line[first-1] in prettybase.Letters: dec first + if first < 0: return + if line[first] == '`': inc first + + let last = first+identLen(line, first)-1 + if differ(line, first, last, newName): + # last-first+1 != newName.len or + var x = line.substr(0, first-1) & newName & line.substr(last+1) + system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) + gSourceFiles[info.fileIndex].dirty = true + +proc checkStyle(info: TLineInfo, s: string, k: TSymKind; sym: PSym) = let beau = beautifyName(s, k) if s != beau: - message(info, hintName, beau) + if gStyleCheck == StyleCheck.Auto: + sym.name = getIdent(beau) + replaceInFile(info, beau) + else: + message(info, hintName, beau) proc styleCheckDefImpl(info: TLineInfo; s: PSym; k: TSymKind) = # operators stay as they are: if k in {skResult, skTemp} or s.name.s[0] notin prettybase.Letters: return if k in {skType, skGenericParam} and sfAnon in s.flags: return if {sfImportc, sfExportc} * s.flags == {} or gCheckExtern: - checkStyle(info, s.name.s, k) + checkStyle(info, s.name.s, k, s) template styleCheckDef*(info: TLineInfo; s: PSym; k: TSymKind) = when defined(nimfix): @@ -120,24 +143,9 @@ proc styleCheckUseImpl(info: TLineInfo; s: PSym) = return if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return let newName = s.name.s - - loadFile(info) - - let line = gSourceFiles[info.fileIndex].lines[info.line-1] - var first = min(info.col.int, line.len) - if first < 0: return - #inc first, skipIgnoreCase(line, "proc ", first) - while first > 0 and line[first-1] in prettybase.Letters: dec first - if first < 0: return - if line[first] == '`': inc first - - let last = first+identLen(line, first)-1 - if differ(line, first, last, newName): - # last-first+1 != newName.len or - var x = line.substr(0, first-1) & newName & line.substr(last+1) - system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) - gSourceFiles[info.fileIndex].dirty = true - #if newName == "File": writeStackTrace() + + replaceInFile(info, newName) + #if newName == "File": writeStackTrace() template styleCheckUse*(info: TLineInfo; s: PSym) = when defined(nimfix): diff --git a/compiler/prettybase.nim b/compiler/prettybase.nim index 21613396a..225b78479 100644 --- a/compiler/prettybase.nim +++ b/compiler/prettybase.nim @@ -15,6 +15,7 @@ type lines*: seq[string] dirty*, isNimfixFile*: bool fullpath*, newline*: string + fileIdx*: int32 var gSourceFiles*: seq[TSourceFile] = @[] @@ -24,6 +25,7 @@ proc loadFile*(info: TLineInfo) = if i >= gSourceFiles.len: gSourceFiles.setLen(i+1) if gSourceFiles[i].lines.isNil: + gSourceFiles[i].fileIdx = info.fileIndex gSourceFiles[i].lines = @[] let path = info.toFullPath gSourceFiles[i].fullpath = path From 0c25f7e2027121b2184b6e993b0d78631296b777 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Sep 2014 02:37:05 +0200 Subject: [PATCH 133/409] support nimrod as an alias for nim for compatibility (nimforum!) --- lib/packages/docutils/highlite.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index c3e54e67d..d4bd94e5e 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -31,11 +31,11 @@ type state: TTokenClass TSourceLanguage* = enum - langNone, langNim, langCpp, langCsharp, langC, langJava + langNone, langNim, langNimrod, langCpp, langCsharp, langC, langJava const - sourceLanguageToStr*: array[TSourceLanguage, string] = ["none", "Nim", - "C++", "C#", "C", "Java"] + sourceLanguageToStr*: array[TSourceLanguage, string] = ["none", + "Nim", "Nimrod", "C++", "C#", "C", "Java"] tokenClassToStr*: array[TTokenClass, string] = ["Eof", "None", "Whitespace", "DecNumber", "BinNumber", "HexNumber", "OctNumber", "FloatNumber", "Identifier", "Keyword", "StringLit", "LongStringLit", "CharLit", @@ -542,7 +542,7 @@ proc javaNextToken(g: var TGeneralTokenizer) = proc getNextToken*(g: var TGeneralTokenizer, lang: TSourceLanguage) = case lang of langNone: assert false - of langNim: nimNextToken(g) + of langNim, langNimrod: nimNextToken(g) of langCpp: cppNextToken(g) of langCsharp: csharpNextToken(g) of langC: cNextToken(g) From 17ce01c3e1268a6bdcc4504aa2d0591e6047bd7f Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Sep 2014 10:04:36 +0200 Subject: [PATCH 134/409] some progress on documentation building --- koch.nim | 13 ++- lib/impure/ssl.nim | 32 +++---- lib/wrappers/openssl.nim | 4 +- tests/metatype/ttypeclasses.nim | 15 +++ tools/nimweb.nim | 160 ++++++++++++++++---------------- web/news.txt | 4 +- 6 files changed, 119 insertions(+), 109 deletions(-) diff --git a/koch.nim b/koch.nim index ad1a4b910..b7a32a1b4 100644 --- a/koch.nim +++ b/koch.nim @@ -40,7 +40,7 @@ Possible Commands: boot [options] bootstraps with given command line options install [dir] installs to given directory clean cleans Nimrod project; removes generated files - web generates the website + web [options] generates the website csource [options] builds the C sources for installation zip builds the installation ZIP package inno [options] builds the Inno Setup installer (for Windows) @@ -105,8 +105,8 @@ proc install(args: string) = exec("sh ./install.sh $#" % args) proc web(args: string) = - exec("$# cc -r tools/nimweb.nim web/nim --putenv:nimversion=$#" % - [findNim(), NimVersion]) + exec("$# cc -r tools/nimweb.nim $# web/nim --putenv:nimversion=$#" % + [findNim(), args, NimVersion]) # -------------- boot --------------------------------------------------------- @@ -298,7 +298,7 @@ proc temp(args: string) = if args.len > 0: exec(finalDest & " " & args) proc showHelp() = - quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)), + quit(HelpText % [NimVersion & repeatChar(44-len(NimVersion)), CompileDate, CompileTime]) var op = initOptParser() @@ -306,7 +306,7 @@ op.next() case op.kind of cmdLongOption, cmdShortOption: showHelp() of cmdArgument: - case normalize(op.key) + case normalize(op.key) of "boot": boot(op.cmdLineRest) of "clean": clean(op.cmdLineRest) of "web": web(op.cmdLineRest) @@ -315,7 +315,7 @@ of cmdArgument: of "inno": inno(op.cmdLineRest) of "install": install(op.cmdLineRest) of "test", "tests": tests(op.cmdLineRest) - of "update": + of "update": when defined(withUpdate): update(op.cmdLineRest) else: @@ -323,4 +323,3 @@ of cmdArgument: of "temp": temp(op.cmdLineRest) else: showHelp() of cmdEnd: showHelp() - diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim index cae9990b9..bb7cfc0d3 100644 --- a/lib/impure/ssl.nim +++ b/lib/impure/ssl.nim @@ -15,24 +15,24 @@ import openssl, strutils, os type - TSecureSocket* {.final.} = object - ssl: PSSL - bio: PBIO + TSecureSocket* = object + ssl: SslPtr + bio: BIO proc connect*(sock: var TSecureSocket, address: string, - port: int): Int = + port: int): int = ## Connects to the specified `address` on the specified `port`. ## Returns the result of the certificate validation. SslLoadErrorStrings() ERR_load_BIO_strings() if SSL_library_init() != 1: - OSError() + raiseOSError(osLastError()) var ctx = SSL_CTX_new(SSLv23_client_method()) if ctx == nil: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) #if SSL_CTX_load_verify_locations(ctx, # "/tmp/openssl-0.9.8e/certs/vsign1.pem", NIL) == 0: @@ -41,14 +41,14 @@ proc connect*(sock: var TSecureSocket, address: string, sock.bio = BIO_new_ssl_connect(ctx) if BIO_get_ssl(sock.bio, addr(sock.ssl)) == 0: - OSError() + raiseOSError(osLastError()) if BIO_set_conn_hostname(sock.bio, address & ":" & $port) != 1: - OSError() + raiseOSError(osLastError()) if BIO_do_connect(sock.bio) <= 0: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) result = SSL_get_verify_result(sock.ssl) @@ -57,30 +57,30 @@ proc recvLine*(sock: TSecureSocket, line: var TaintedString): bool = ## Returns false when no data is available to be read. ## `Line` must be initialized and not nil! setLen(line.string, 0) - while True: + while true: var c: array[0..0, char] var n = BIO_read(sock.bio, c, c.len.cint) - if n <= 0: return False + if n <= 0: return false if c[0] == '\r': n = BIO_read(sock.bio, c, c.len.cint) if n > 0 and c[0] == '\L': - return True + return true elif n <= 0: - return False - elif c[0] == '\L': return True + return false + elif c[0] == '\L': return true add(line.string, c) proc send*(sock: TSecureSocket, data: string) = ## Writes `data` to the socket. if BIO_write(sock.bio, data, data.len.cint) <= 0: - OSError() + raiseOSError(osLastError()) proc close*(sock: TSecureSocket) = ## Closes the socket if BIO_free(sock.bio) <= 0: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) when isMainModule: var s: TSecureSocket diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 7f24507ba..a668f3526 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -480,7 +480,7 @@ proc hexStr (buf:cstring): string = for i in 0 .. <16: result.add toHex(buf[i].ord, 2).toLower -proc md5_File* (file: string): string {.raises:[EIO,Ebase].} = +proc md5_File* (file: string): string {.raises: [IOError,Exception].} = ## Generate MD5 hash for a file. Result is a 32 character # hex string with lowercase characters (like the output # of `md5sum` @@ -500,7 +500,7 @@ proc md5_File* (file: string): string {.raises:[EIO,Ebase].} = result = hexStr(buf) -proc md5_Str* (str:string): string {.raises:[EIO].} = +proc md5_Str* (str:string): string {.raises:[IOError].} = ##Generate MD5 hash for a string. Result is a 32 character #hex string with lowercase characters var diff --git a/tests/metatype/ttypeclasses.nim b/tests/metatype/ttypeclasses.nim index 677229868..db9db7713 100644 --- a/tests/metatype/ttypeclasses.nim +++ b/tests/metatype/ttypeclasses.nim @@ -1,3 +1,18 @@ +discard """ + output: '''12 +1xxx +true0 +12 +testtest +1010 +11string +testtest1 +seq +seq +seq +foo seq +foo of numeric'''""" + type TFoo[T] = object val: T diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 8744a250e..a98a27a13 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -1,7 +1,7 @@ # # # Nim Website Generator -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -13,14 +13,14 @@ import type TKeyValPair = tuple[key, id, val: string] - TConfigData = object of TObject + TConfigData = object of RootObj tabs, links: seq[TKeyValPair] doc, srcdoc, srcdoc2, webdoc, pdf: seq[string] authors, projectName, projectTitle, logo, infile, outdir, ticker: string - vars: PStringTable - nimrodArgs: string + vars: StringTableRef + nimArgs: string gitCommit: string - quotations: TTable[string, tuple[quote, author: string]] + quotations: Table[string, tuple[quote, author: string]] numProcessors: int # Set by parallelBuild:n, only works for values > 0. TRssItem = object year, month, day, title: string @@ -35,7 +35,7 @@ proc initConfigData(c: var TConfigData) = c.pdf = @[] c.infile = "" c.outdir = "" - c.nimrodArgs = "--hint[Conf]:off " + c.nimArgs = "--hint[Conf]:off " c.authors = "" c.projectTitle = "" c.projectName = "" @@ -58,7 +58,7 @@ const version = "0.7" usage = "nimweb - Nim Website Generator Version " & version & """ - (c) 2012 Andreas Rumpf + (c) 2014 Andreas Rumpf Usage: nimweb [options] ini-file[.ini] [compile_options] Options: @@ -112,7 +112,7 @@ proc parseCmdLine(c: var TConfigData) = case kind of cmdArgument: c.infile = addFileExt(key, "ini") - c.nimrodArgs.add(cmdLineRest(p)) + c.nimArgs.add(cmdLineRest(p)) break of cmdLongOption, cmdShortOption: case normalize(key) @@ -127,7 +127,7 @@ proc parseCmdLine(c: var TConfigData) = try: let num = parseInt(val) if num != 0: c.numProcessors = num - except EInvalidValue: + except ValueError: quit("invalid numeric value for --parallelBuild") of "var": var idx = val.find('=') @@ -155,68 +155,65 @@ proc addFiles(s: var seq[string], dir, ext: string, patterns: seq[string]) = proc parseIniFile(c: var TConfigData) = var - p: TCfgParser + p: CfgParser section: string # current section var input = newFileStream(c.infile, fmRead) - if input != nil: - open(p, input, c.infile) - while true: - var k = next(p) - case k.kind - of cfgEof: break - of cfgSectionStart: - section = normalize(k.section) - case section - of "project", "links", "tabs", "ticker", "documentation", "var": discard - else: echo("[Warning] Skipping unknown section: " & section) + if input == nil: quit("cannot open: " & c.infile) + open(p, input, c.infile) + while true: + var k = next(p) + case k.kind + of cfgEof: break + of cfgSectionStart: + section = normalize(k.section) + case section + of "project", "links", "tabs", "ticker", "documentation", "var": discard + else: echo("[Warning] Skipping unknown section: " & section) - of cfgKeyValuePair: - var v = k.value % c.vars - c.vars[k.key] = v + of cfgKeyValuePair: + var v = k.value % c.vars + c.vars[k.key] = v - case section - of "project": - case normalize(k.key) - of "name": c.projectName = v - of "title": c.projectTitle = v - of "logo": c.logo = v - of "authors": c.authors = v - else: quit(errorStr(p, "unknown variable: " & k.key)) - of "var": discard - of "links": - let valID = v.split(';') - add(c.links, (k.key.replace('_', ' '), valID[1], valID[0])) - of "tabs": add(c.tabs, (k.key, "", v)) - of "ticker": c.ticker = v - of "documentation": - case normalize(k.key) - of "doc": addFiles(c.doc, "doc", ".txt", split(v, {';'})) - of "pdf": addFiles(c.pdf, "doc", ".txt", split(v, {';'})) - of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'})) - of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'})) - of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'})) - of "parallelbuild": - try: - let num = parseInt(v) - if num != 0: c.numProcessors = num - except EInvalidValue: - quit("invalid numeric value for --parallelBuild in config") - else: quit(errorStr(p, "unknown variable: " & k.key)) - of "quotations": - let vSplit = v.split('-') - doAssert vSplit.len == 2 - c.quotations[k.key.normalize] = (vSplit[0], vSplit[1]) - else: discard - - of cfgOption: quit(errorStr(p, "syntax error")) - of cfgError: quit(errorStr(p, k.msg)) - close(p) - if c.projectName.len == 0: - c.projectName = changeFileExt(extractFilename(c.infile), "") - if c.outdir.len == 0: - c.outdir = splitFile(c.infile).dir - else: - quit("cannot open: " & c.infile) + case section + of "project": + case normalize(k.key) + of "name": c.projectName = v + of "title": c.projectTitle = v + of "logo": c.logo = v + of "authors": c.authors = v + else: quit(errorStr(p, "unknown variable: " & k.key)) + of "var": discard + of "links": + let valID = v.split(';') + add(c.links, (k.key.replace('_', ' '), valID[1], valID[0])) + of "tabs": add(c.tabs, (k.key, "", v)) + of "ticker": c.ticker = v + of "documentation": + case normalize(k.key) + of "doc": addFiles(c.doc, "doc", ".txt", split(v, {';'})) + of "pdf": addFiles(c.pdf, "doc", ".txt", split(v, {';'})) + of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'})) + of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'})) + of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'})) + of "parallelbuild": + try: + let num = parseInt(v) + if num != 0: c.numProcessors = num + except ValueError: + quit("invalid numeric value for --parallelBuild in config") + else: quit(errorStr(p, "unknown variable: " & k.key)) + of "quotations": + let vSplit = v.split('-') + doAssert vSplit.len == 2 + c.quotations[k.key.normalize] = (vSplit[0], vSplit[1]) + else: discard + of cfgOption: quit(errorStr(p, "syntax error")) + of cfgError: quit(errorStr(p, k.msg)) + close(p) + if c.projectName.len == 0: + c.projectName = changeFileExt(extractFilename(c.infile), "") + if c.outdir.len == 0: + c.outdir = splitFile(c.infile).dir # Ugly hack to override git command output when building private repo. if c.vars.hasKey("githash"): let githash = c.vars["githash"].strip @@ -238,8 +235,7 @@ proc mexec(cmds: openarray[string], processors: int) = if processors < 2: sexec(cmds) return - - if 0 != execProcesses(cmds, {poStdErrToStdOut, poParentStreams, poEchoCmd}): + if execProcesses(cmds, {poStdErrToStdOut, poParentStreams, poEchoCmd}) != 0: echo "external program failed, retrying serial work queue for logs!" sexec(cmds) @@ -251,9 +247,9 @@ proc buildDocSamples(c: var TConfigData, destPath: string) = ## documentation builders. const src = "doc"/"docgen_sample.nim" exec("nim doc $# -o:$# $#" % - [c.nimrodArgs, destPath / "docgen_sample.html", src]) + [c.nimArgs, destPath / "docgen_sample.html", src]) exec("nim doc2 $# -o:$# $#" % - [c.nimrodArgs, destPath / "docgen_sample2.html", src]) + [c.nimArgs, destPath / "docgen_sample2.html", src]) proc buildDoc(c: var TConfigData, destPath: string) = # call nim for the documentation: @@ -262,17 +258,17 @@ proc buildDoc(c: var TConfigData, destPath: string) = i = 0 for d in items(c.doc): commands[i] = "nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" % - [c.nimrodArgs, c.gitCommit, + [c.nimArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc): commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" % - [c.nimrodArgs, c.gitCommit, + [c.nimArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc2): commands[i] = "nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" % - [c.nimrodArgs, c.gitCommit, + [c.nimArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc @@ -284,7 +280,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) = echo "pdflatex not found; no PDF documentation generated" else: for d in items(c.pdf): - exec("nim rst2tex $# $#" % [c.nimrodArgs, d]) + exec("nim rst2tex $# $#" % [c.nimArgs, d]) # call LaTeX twice to get cross references right: exec("pdflatex " & changeFileExt(d, "tex")) exec("pdflatex " & changeFileExt(d, "tex")) @@ -303,7 +299,7 @@ proc buildAddDoc(c: var TConfigData, destPath: string) = var commands = newSeq[string](c.webdoc.len) for i, doc in pairs(c.webdoc): commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# $#" % - [c.nimrodArgs, c.gitCommit, + [c.nimArgs, c.gitCommit, destPath / changeFileExt(splitFile(doc).name, "html"), doc] mexec(commands, c.numProcessors) @@ -311,7 +307,7 @@ proc parseNewsTitles(inputFilename: string): seq[TRssItem] = # parses the file for titles and returns them as TRssItem blocks. let reYearMonthDayTitle = re(rYearMonthDayTitle) var - input: TFile + input: File line = "" result = @[] @@ -347,7 +343,7 @@ proc genNewsLink(title: string): string = proc generateRss(outputFilename: string, news: seq[TRssItem]) = # Given a list of rss items generates an rss overwriting destination. var - output: TFile + output: File if not open(output, outputFilename, mode = fmWrite): quit("Could not write to $1 for rss generation" % [outputFilename]) @@ -396,19 +392,19 @@ proc main(c: var TConfigData) = if c.ticker.len > 0: try: c.ticker = readFile("web" / c.ticker) - except EIO: + except IOError: quit("[Error] cannot open: " & c.ticker) for i in 0..c.tabs.len-1: var file = c.tabs[i].val let rss = if file in ["news", "index"]: extractFilename(rssUrl) else: "" - exec(cmd % [c.nimrodArgs, file]) + exec(cmd % [c.nimArgs, file]) var temp = "web" / changeFileExt(file, "temp") var content: string try: content = readFile(temp) - except EIO: + except IOError: quit("[Error] cannot open: " & temp) - var f: TFile + var f: File var outfile = "web/upload/$#.html" % file if not existsDir("web/upload"): createDir("web/upload") diff --git a/web/news.txt b/web/news.txt index 2c6ef4196..93cb71f94 100644 --- a/web/news.txt +++ b/web/news.txt @@ -104,7 +104,7 @@ the use of an ``await`` macro which behaves similar to C#'s await. The following is a very simple chat server demonstrating Nimrod's new async capabilities. -.. code-block::nimrod +.. code-block::nim import asyncnet, asyncdispatch var clients: seq[PAsyncSocket] = @[] @@ -137,7 +137,7 @@ Syntactic sugar for anonymous procedures has also been introduced. It too has been implemented as a macro. The following shows some simple usage of the new syntax: -.. code-block::nimrod +.. code-block::nim import future var s = @[1, 2, 3, 4, 5] From 804df3c504682aea19d3a8efc86587863f63ceb7 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 17 Sep 2014 22:00:58 +0100 Subject: [PATCH 135/409] CS fixes for zlib.nim --- lib/wrappers/zip/zlib.nim | 144 +++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/lib/wrappers/zip/zlib.nim b/lib/wrappers/zip/zlib.nim index cb61783d2..e3530d566 100644 --- a/lib/wrappers/zip/zlib.nim +++ b/lib/wrappers/zip/zlib.nim @@ -14,32 +14,32 @@ type Ulong* = int Ulongf* = int Pulongf* = ptr Ulongf - z_off_t* = int32 - pbyte* = cstring - pbytef* = cstring - TAllocfunc* = proc (p: pointer, items: uInt, size: uInt): pointer{.cdecl.} + ZOffT* = int32 + Pbyte* = cstring + Pbytef* = cstring + TAllocfunc* = proc (p: pointer, items: Uint, size: Uint): pointer{.cdecl.} TFreeFunc* = proc (p: pointer, address: pointer){.cdecl.} TInternalState*{.final, pure.} = object - PInternalState* = ptr TInternalstate + PInternalState* = ptr TInternalState TZStream*{.final, pure.} = object - next_in*: pbytef - avail_in*: uInt - total_in*: uLong - next_out*: pbytef - avail_out*: uInt - total_out*: uLong - msg*: pbytef + nextIn*: Pbytef + availIn*: Uint + totalIn*: Ulong + nextOut*: Pbytef + availOut*: Uint + totalOut*: Ulong + msg*: Pbytef state*: PInternalState - zalloc*: TAllocFunc + zalloc*: TAllocfunc zfree*: TFreeFunc opaque*: pointer - data_type*: int32 - adler*: uLong - reserved*: uLong + dataType*: int32 + adler*: Ulong + reserved*: Ulong TZStreamRec* = TZStream PZstream* = ptr TZStream - gzFile* = pointer + GzFile* = pointer const Z_NO_FLUSH* = 0 @@ -78,79 +78,79 @@ proc inflate*(strm: var TZStream, flush: int32): int32{.cdecl, dynlib: libz, importc: "inflate".} proc inflateEnd*(strm: var TZStream): int32{.cdecl, dynlib: libz, importc: "inflateEnd".} -proc deflateSetDictionary*(strm: var TZStream, dictionary: pbytef, - dictLength: uInt): int32{.cdecl, dynlib: libz, +proc deflateSetDictionary*(strm: var TZStream, dictionary: Pbytef, + dictLength: Uint): int32{.cdecl, dynlib: libz, importc: "deflateSetDictionary".} -proc deflateCopy*(dest, source: var TZstream): int32{.cdecl, dynlib: libz, +proc deflateCopy*(dest, source: var TZStream): int32{.cdecl, dynlib: libz, importc: "deflateCopy".} proc deflateReset*(strm: var TZStream): int32{.cdecl, dynlib: libz, importc: "deflateReset".} proc deflateParams*(strm: var TZStream, level: int32, strategy: int32): int32{. cdecl, dynlib: libz, importc: "deflateParams".} -proc inflateSetDictionary*(strm: var TZStream, dictionary: pbytef, - dictLength: uInt): int32{.cdecl, dynlib: libz, +proc inflateSetDictionary*(strm: var TZStream, dictionary: Pbytef, + dictLength: Uint): int32{.cdecl, dynlib: libz, importc: "inflateSetDictionary".} proc inflateSync*(strm: var TZStream): int32{.cdecl, dynlib: libz, importc: "inflateSync".} proc inflateReset*(strm: var TZStream): int32{.cdecl, dynlib: libz, importc: "inflateReset".} -proc compress*(dest: pbytef, destLen: puLongf, source: pbytef, sourceLen: uLong): cint{. +proc compress*(dest: Pbytef, destLen: Pulongf, source: Pbytef, sourceLen: Ulong): cint{. cdecl, dynlib: libz, importc: "compress".} -proc compress2*(dest: pbytef, destLen: puLongf, source: pbytef, - sourceLen: uLong, level: cint): cint{.cdecl, dynlib: libz, +proc compress2*(dest: Pbytef, destLen: Pulongf, source: Pbytef, + sourceLen: Ulong, level: cint): cint{.cdecl, dynlib: libz, importc: "compress2".} -proc uncompress*(dest: pbytef, destLen: puLongf, source: pbytef, - sourceLen: uLong): cint{.cdecl, dynlib: libz, +proc uncompress*(dest: Pbytef, destLen: Pulongf, source: Pbytef, + sourceLen: Ulong): cint{.cdecl, dynlib: libz, importc: "uncompress".} -proc compressBound*(sourceLen: uLong): uLong {.cdecl, dynlib: libz, importc.} -proc gzopen*(path: cstring, mode: cstring): gzFile{.cdecl, dynlib: libz, +proc compressBound*(sourceLen: Ulong): Ulong {.cdecl, dynlib: libz, importc.} +proc gzopen*(path: cstring, mode: cstring): GzFile{.cdecl, dynlib: libz, importc: "gzopen".} -proc gzdopen*(fd: int32, mode: cstring): gzFile{.cdecl, dynlib: libz, +proc gzdopen*(fd: int32, mode: cstring): GzFile{.cdecl, dynlib: libz, importc: "gzdopen".} -proc gzsetparams*(thefile: gzFile, level: int32, strategy: int32): int32{.cdecl, +proc gzsetparams*(thefile: GzFile, level: int32, strategy: int32): int32{.cdecl, dynlib: libz, importc: "gzsetparams".} -proc gzread*(thefile: gzFile, buf: pointer, length: int): int32{.cdecl, +proc gzread*(thefile: GzFile, buf: pointer, length: int): int32{.cdecl, dynlib: libz, importc: "gzread".} -proc gzwrite*(thefile: gzFile, buf: pointer, length: int): int32{.cdecl, +proc gzwrite*(thefile: GzFile, buf: pointer, length: int): int32{.cdecl, dynlib: libz, importc: "gzwrite".} -proc gzprintf*(thefile: gzFile, format: pbytef): int32{.varargs, cdecl, +proc gzprintf*(thefile: GzFile, format: Pbytef): int32{.varargs, cdecl, dynlib: libz, importc: "gzprintf".} -proc gzputs*(thefile: gzFile, s: pbytef): int32{.cdecl, dynlib: libz, +proc gzputs*(thefile: GzFile, s: Pbytef): int32{.cdecl, dynlib: libz, importc: "gzputs".} -proc gzgets*(thefile: gzFile, buf: pbytef, length: int32): pbytef{.cdecl, +proc gzgets*(thefile: GzFile, buf: Pbytef, length: int32): Pbytef{.cdecl, dynlib: libz, importc: "gzgets".} -proc gzputc*(thefile: gzFile, c: char): char{.cdecl, dynlib: libz, +proc gzputc*(thefile: GzFile, c: char): char{.cdecl, dynlib: libz, importc: "gzputc".} -proc gzgetc*(thefile: gzFile): char{.cdecl, dynlib: libz, importc: "gzgetc".} -proc gzflush*(thefile: gzFile, flush: int32): int32{.cdecl, dynlib: libz, +proc gzgetc*(thefile: GzFile): char{.cdecl, dynlib: libz, importc: "gzgetc".} +proc gzflush*(thefile: GzFile, flush: int32): int32{.cdecl, dynlib: libz, importc: "gzflush".} -proc gzseek*(thefile: gzFile, offset: z_off_t, whence: int32): z_off_t{.cdecl, +proc gzseek*(thefile: GzFile, offset: ZOffT, whence: int32): ZOffT{.cdecl, dynlib: libz, importc: "gzseek".} -proc gzrewind*(thefile: gzFile): int32{.cdecl, dynlib: libz, importc: "gzrewind".} -proc gztell*(thefile: gzFile): z_off_t{.cdecl, dynlib: libz, importc: "gztell".} -proc gzeof*(thefile: gzFile): int {.cdecl, dynlib: libz, importc: "gzeof".} -proc gzclose*(thefile: gzFile): int32{.cdecl, dynlib: libz, importc: "gzclose".} -proc gzerror*(thefile: gzFile, errnum: var int32): pbytef{.cdecl, dynlib: libz, +proc gzrewind*(thefile: GzFile): int32{.cdecl, dynlib: libz, importc: "gzrewind".} +proc gztell*(thefile: GzFile): ZOffT{.cdecl, dynlib: libz, importc: "gztell".} +proc gzeof*(thefile: GzFile): int {.cdecl, dynlib: libz, importc: "gzeof".} +proc gzclose*(thefile: GzFile): int32{.cdecl, dynlib: libz, importc: "gzclose".} +proc gzerror*(thefile: GzFile, errnum: var int32): Pbytef{.cdecl, dynlib: libz, importc: "gzerror".} -proc adler32*(adler: uLong, buf: pbytef, length: uInt): uLong{.cdecl, +proc adler32*(adler: Ulong, buf: Pbytef, length: Uint): Ulong{.cdecl, dynlib: libz, importc: "adler32".} ## **Warning**: Adler-32 requires at least a few hundred bytes to get rolling. -proc crc32*(crc: uLong, buf: pbytef, length: uInt): uLong{.cdecl, dynlib: libz, +proc crc32*(crc: Ulong, buf: Pbytef, length: Uint): Ulong{.cdecl, dynlib: libz, importc: "crc32".} proc deflateInitu*(strm: var TZStream, level: int32, version: cstring, - stream_size: int32): int32{.cdecl, dynlib: libz, + streamSize: int32): int32{.cdecl, dynlib: libz, importc: "deflateInit_".} proc inflateInitu*(strm: var TZStream, version: cstring, - stream_size: int32): int32 {. + streamSize: int32): int32 {. cdecl, dynlib: libz, importc: "inflateInit_".} proc deflateInit*(strm: var TZStream, level: int32): int32 proc inflateInit*(strm: var TZStream): int32 proc deflateInit2u*(strm: var TZStream, level: int32, `method`: int32, windowBits: int32, memLevel: int32, strategy: int32, - version: cstring, stream_size: int32): int32 {.cdecl, + version: cstring, streamSize: int32): int32 {.cdecl, dynlib: libz, importc: "deflateInit2_".} proc inflateInit2u*(strm: var TZStream, windowBits: int32, version: cstring, - stream_size: int32): int32{.cdecl, dynlib: libz, + streamSize: int32): int32{.cdecl, dynlib: libz, importc: "inflateInit2_".} proc deflateInit2*(strm: var TZStream, level, `method`, windowBits, memLevel, @@ -159,29 +159,29 @@ proc inflateInit2*(strm: var TZStream, windowBits: int32): int32 proc zError*(err: int32): cstring{.cdecl, dynlib: libz, importc: "zError".} proc inflateSyncPoint*(z: PZstream): int32{.cdecl, dynlib: libz, importc: "inflateSyncPoint".} -proc get_crc_table*(): pointer{.cdecl, dynlib: libz, importc: "get_crc_table".} +proc getCrcTable*(): pointer{.cdecl, dynlib: libz, importc: "get_crc_table".} proc deflateInit(strm: var TZStream, level: int32): int32 = - result = deflateInitu(strm, level, ZLIB_VERSION(), sizeof(TZStream).cint) + result = deflateInitu(strm, level, zlibVersion(), sizeof(TZStream).cint) proc inflateInit(strm: var TZStream): int32 = - result = inflateInitu(strm, ZLIB_VERSION(), sizeof(TZStream).cint) + result = inflateInitu(strm, zlibVersion(), sizeof(TZStream).cint) proc deflateInit2(strm: var TZStream, level, `method`, windowBits, memLevel, strategy: int32): int32 = result = deflateInit2u(strm, level, `method`, windowBits, memLevel, - strategy, ZLIB_VERSION(), sizeof(TZStream).cint) + strategy, zlibVersion(), sizeof(TZStream).cint) proc inflateInit2(strm: var TZStream, windowBits: int32): int32 = - result = inflateInit2u(strm, windowBits, ZLIB_VERSION(), + result = inflateInit2u(strm, windowBits, zlibVersion(), sizeof(TZStream).cint) -proc zlibAllocMem*(AppData: Pointer, Items, Size: int): Pointer {.cdecl.} = - result = Alloc(Items * Size) +proc zlibAllocMem*(appData: pointer, items, size: int): pointer {.cdecl.} = + result = alloc(items * size) -proc zlibFreeMem*(AppData, `Block`: Pointer) {.cdecl.} = - dealloc(`Block`) +proc zlibFreeMem*(appData, `block`: pointer) {.cdecl.} = + dealloc(`block`) proc uncompress*(sourceBuf: cstring, sourceLen: int): string = ## Given a deflated cstring returns its inflated version. @@ -202,7 +202,7 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = var z: TZStream # Initialize input. - z.next_in = sourceBuf + z.nextIn = sourceBuf # Input left to decompress. var left = zlib.Uint(sourceLen) @@ -220,12 +220,12 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = var decompressed = newStringOfCap(space) # Initialize output. - z.next_out = addr(decompressed[0]) + z.nextOut = addr(decompressed[0]) # Output generated so far. var have = 0 # Set up for gzip decoding. - z.avail_in = 0; + z.availIn = 0; var status = inflateInit2(z, (15+16)) if status != Z_OK: # Out of memory. @@ -241,10 +241,10 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = discard inflateReset(z) # Provide input for inflate. - if z.avail_in == 0: + if z.availIn == 0: # This only makes sense in the C version using unsigned values. - z.avail_in = left - left -= z.avail_in + z.availIn = left + left -= z.availIn # Decompress the available input. while true: @@ -260,15 +260,15 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = # Increase space. decompressed.setLen(space) # Update output pointer (might have moved). - z.next_out = addr(decompressed[have]) + z.nextOut = addr(decompressed[have]) # Provide output space for inflate. - z.avail_out = zlib.Uint(space - have) - have += z.avail_out; + z.availOut = zlib.Uint(space - have) + have += z.availOut; # Inflate and update the decompressed size. status = inflate(z, Z_SYNC_FLUSH); - have -= z.avail_out; + have -= z.availOut; # Bail out if any errors. if status != Z_OK and status != Z_BUF_ERROR and status != Z_STREAM_END: @@ -279,10 +279,10 @@ proc uncompress*(sourceBuf: cstring, sourceLen: int): string = # Repeat until all output is generated from provided input (note # that even if z.avail_in is zero, there may still be pending # output -- we're not done until the output buffer isn't filled) - if z.avail_out != 0: + if z.availOut != 0: break # Continue until all input consumed. - if left == 0 and z.avail_in == 0: + if left == 0 and z.availIn == 0: break # Verify that the input is a valid gzip stream. From 1ce17c7aaada713755698ef49af7861a05dc333b Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Sep 2014 23:12:54 +0200 Subject: [PATCH 136/409] xmldom adheres to the new style --- lib/pure/xmldom.nim | 498 ++++++++++++++++++++++---------------------- 1 file changed, 249 insertions(+), 249 deletions(-) diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim index afd26a584..660932d92 100644 --- a/lib/pure/xmldom.nim +++ b/lib/pure/xmldom.nim @@ -17,7 +17,7 @@ import strutils #Exceptions type - EDOMException* = object of EInvalidValue ## Base exception object for all DOM Exceptions + EDOMException* = object of ValueError ## Base exception object for all DOM Exceptions EDOMStringSizeErr* = object of EDOMException ## If the specified range of text does not fit into a DOMString ## Currently not used(Since DOMString is just string) EHierarchyRequestErr* = object of EDOMException ## If any node is inserted somewhere it doesn't belong @@ -56,24 +56,24 @@ type Feature = tuple[name: string, version: string] PDOMImplementation* = ref DOMImplementation DOMImplementation = object - Features: seq[Feature] # Read-Only + features: seq[Feature] # Read-Only PNode* = ref Node - Node = object of TObject + Node = object of RootObj attributes*: seq[PAttr] childNodes*: seq[PNode] - FLocalName: string # Read-only - FNamespaceURI: string # Read-only - FNodeName: string # Read-only + fLocalName: string # Read-only + fNamespaceURI: string # Read-only + fNodeName: string # Read-only nodeValue*: string - FNodeType: int # Read-only - FOwnerDocument: PDocument # Read-Only - FParentNode: PNode # Read-Only + fNodeType: int # Read-only + fOwnerDocument: PDocument # Read-Only + fParentNode: PNode # Read-Only prefix*: string # Setting this should change some values... TODO! PElement* = ref Element Element = object of Node - FTagName: string # Read-only + fTagName: string # Read-only PCharacterData* = ref CharacterData CharacterData = object of Node @@ -81,15 +81,15 @@ type PDocument* = ref Document Document = object of Node - FImplementation: PDOMImplementation # Read-only - FDocumentElement: PElement # Read-only + fImplementation: PDOMImplementation # Read-only + fDocumentElement: PElement # Read-only PAttr* = ref Attr Attr = object of Node - FName: string # Read-only - FSpecified: bool # Read-only + fName: string # Read-only + fSpecified: bool # Read-only value*: string - FOwnerElement: PElement # Read-only + fOwnerElement: PElement # Read-only PDocumentFragment* = ref DocumentFragment DocumentFragment = object of Node @@ -97,7 +97,7 @@ type PText* = ref Text Text = object of CharacterData - PComment* = ref comment + PComment* = ref Comment Comment = object of CharacterData PCDataSection* = ref CDataSection @@ -106,13 +106,13 @@ type PProcessingInstruction* = ref ProcessingInstruction ProcessingInstruction = object of Node data*: string - FTarget: string # Read-only + fTarget: string # Read-only # DOMImplementation proc getDOM*(): PDOMImplementation = ## Returns a DOMImplementation new(result) - result.Features = @[(name: "core", version: "2.0"), + result.features = @[(name: "core", version: "2.0"), (name: "core", version: "1.0"), (name: "XML", version: "2.0")] @@ -120,15 +120,15 @@ proc createDocument*(dom: PDOMImplementation, namespaceURI: string, qualifiedNam ## Creates an XML Document object of the specified type with its document element. var doc: PDocument new(doc) - doc.FNamespaceURI = namespaceURI - doc.FImplementation = dom + doc.fNamespaceURI = namespaceURI + doc.fImplementation = dom var elTag: PElement new(elTag) - elTag.FTagName = qualifiedName - elTag.FNodeName = qualifiedName - doc.FDocumentElement = elTag - doc.FNodeType = DocumentNode + elTag.fTagName = qualifiedName + elTag.fNodeName = qualifiedName + doc.fDocumentElement = elTag + doc.fNodeType = DocumentNode return doc @@ -138,32 +138,32 @@ proc createDocument*(dom: PDOMImplementation, n: PElement): PDocument = # This procedure is not in the specification, it's provided for the parser. var doc: PDocument new(doc) - doc.FDocumentElement = n - doc.FImplementation = dom - doc.FNodeType = DocumentNode + doc.fDocumentElement = n + doc.fImplementation = dom + doc.fNodeType = DocumentNode return doc proc hasFeature*(dom: PDOMImplementation, feature: string, version: string = ""): bool = ## Returns ``true`` if this ``version`` of the DomImplementation implements ``feature``, otherwise ``false`` - for iName, iVersion in items(dom.Features): + for iName, iVersion in items(dom.features): if iName == feature: if version == "": - return True + return true else: if iVersion == version: - return True - return False + return true + return false # Document # Attributes proc implementation*(doc: PDocument): PDOMImplementation = - return doc.FImplementation + return doc.fImplementation proc documentElement*(doc: PDocument): PElement = - return doc.FDocumentElement + return doc.fDocumentElement # Internal procedures proc findNodes(nl: PNode, name: string): seq[PNode] = @@ -173,8 +173,8 @@ proc findNodes(nl: PNode, name: string): seq[PNode] = if nl.childNodes.len() == 0: return @[] for i in items(nl.childNodes): - if i.FNodeType == ElementNode: - if i.FNodeName == name or name == "*": + if i.fNodeType == ElementNode: + if i.fNodeName == name or name == "*": r.add(i) if not isNil(i.childNodes): @@ -190,8 +190,8 @@ proc findNodesNS(nl: PNode, namespaceURI: string, localName: string): seq[PNode] if nl.childNodes.len() == 0: return @[] for i in items(nl.childNodes): - if i.FNodeType == ElementNode: - if (i.FNamespaceURI == namespaceURI or namespaceURI == "*") and (i.FLocalName == localName or localName == "*"): + if i.fNodeType == ElementNode: + if (i.fNamespaceURI == namespaceURI or namespaceURI == "*") and (i.fLocalName == localName or localName == "*"): r.add(i) if not isNil(i.childNodes): @@ -210,16 +210,16 @@ proc createAttribute*(doc: PDocument, name: string): PAttr = if illegalChars in name: raise newException(EInvalidCharacterErr, "Invalid character") - var AttrNode: PAttr - new(AttrNode) - AttrNode.FName = name - AttrNode.FNodeName = name - AttrNode.FLocalName = nil - AttrNode.prefix = nil - AttrNode.FNamespaceURI = nil - AttrNode.value = "" - AttrNode.FSpecified = False - return AttrNode + var attrNode: PAttr + new(attrNode) + attrNode.fName = name + attrNode.fNodeName = name + attrNode.fLocalName = nil + attrNode.prefix = nil + attrNode.fNamespaceURI = nil + attrNode.value = "" + attrNode.fSpecified = false + return attrNode proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PAttr = ## Creates an attribute of the given qualified name and namespace URI @@ -238,48 +238,48 @@ proc createAttributeNS*(doc: PDocument, namespaceURI: string, qualifiedName: str raise newException(ENamespaceErr, "When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"") - var AttrNode: PAttr - new(AttrNode) - AttrNode.FName = qualifiedName - AttrNode.FNodeName = qualifiedName - AttrNode.FSpecified = False - AttrNode.FNamespaceURI = namespaceURI + var attrNode: PAttr + new(attrNode) + attrNode.fName = qualifiedName + attrNode.fNodeName = qualifiedName + attrNode.fSpecified = false + attrNode.fNamespaceURI = namespaceURI if qualifiedName.contains(':'): - AttrNode.prefix = qualifiedName.split(':')[0] - AttrNode.FLocalName = qualifiedName.split(':')[1] + attrNode.prefix = qualifiedName.split(':')[0] + attrNode.fLocalName = qualifiedName.split(':')[1] else: - AttrNode.prefix = nil - AttrNode.FLocalName = qualifiedName - AttrNode.value = "" + attrNode.prefix = nil + attrNode.fLocalName = qualifiedName + attrNode.value = "" - AttrNode.FNodeType = AttributeNode - return AttrNode + attrNode.fNodeType = AttributeNode + return attrNode -proc createCDATASection*(doc: PDocument, data: string): PCDATASection = +proc createCDATASection*(doc: PDocument, data: string): PCDataSection = ## Creates a CDATASection node whose value is the specified string. - var CData: PCDATASection - new(CData) - CData.data = data - CData.nodeValue = data - CData.FNodeName = "#text" # Not sure about this, but this is technically a TextNode - CData.FNodeType = CDataSectionNode - return CData + var cData: PCDataSection + new(cData) + cData.data = data + cData.nodeValue = data + cData.fNodeName = "#text" # Not sure about this, but this is technically a TextNode + cData.fNodeType = CDataSectionNode + return cData proc createComment*(doc: PDocument, data: string): PComment = ## Creates a Comment node given the specified string. - var Comm: PComment - new(Comm) - Comm.data = data - Comm.nodeValue = data + var comm: PComment + new(comm) + comm.data = data + comm.nodeValue = data - Comm.FNodeType = CommentNode - return Comm + comm.fNodeType = CommentNode + return comm proc createDocumentFragment*(doc: PDocument): PDocumentFragment = ## Creates an empty DocumentFragment object. - var DF: PDocumentFragment - new(DF) - return DF + var df: PDocumentFragment + new(df) + return df proc createElement*(doc: PDocument, tagName: string): PElement = ## Creates an element of the type specified. @@ -290,22 +290,22 @@ proc createElement*(doc: PDocument, tagName: string): PElement = var elNode: PElement new(elNode) - elNode.FTagName = tagName - elNode.FNodeName = tagName - elNode.FLocalName = nil + elNode.fTagName = tagName + elNode.fNodeName = tagName + elNode.fLocalName = nil elNode.prefix = nil - elNode.FNamespaceURI = nil + elNode.fNamespaceURI = nil elNode.childNodes = @[] elNode.attributes = @[] - elNode.FNodeType = ElementNode + elNode.fNodeType = ElementNode return elNode proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: string): PElement = ## Creates an element of the given qualified name and namespace URI. if qualifiedName.contains(':'): - if isNIl(namespaceURI): + if isNil(namespaceURI): raise newException(ENamespaceErr, "When qualifiedName contains a prefix namespaceURI cannot be nil") elif qualifiedName.split(':')[0].toLower() == "xml" and namespaceURI != "http://www.w3.org/XML/1998/namespace": raise newException(ENamespaceErr, @@ -317,19 +317,19 @@ proc createElementNS*(doc: PDocument, namespaceURI: string, qualifiedName: strin var elNode: PElement new(elNode) - elNode.FTagName = qualifiedName - elNode.FNodeName = qualifiedName + elNode.fTagName = qualifiedName + elNode.fNodeName = qualifiedName if qualifiedName.contains(':'): elNode.prefix = qualifiedName.split(':')[0] - elNode.FLocalName = qualifiedName.split(':')[1] + elNode.fLocalName = qualifiedName.split(':')[1] else: elNode.prefix = nil - elNode.FLocalName = qualifiedName - elNode.FNamespaceURI = namespaceURI + elNode.fLocalName = qualifiedName + elNode.fNamespaceURI = namespaceURI elNode.childNodes = @[] elNode.attributes = @[] - elNode.FNodeType = ElementNode + elNode.fNodeType = ElementNode return elNode @@ -340,12 +340,12 @@ proc createProcessingInstruction*(doc: PDocument, target: string, data: string): if illegalChars in target: raise newException(EInvalidCharacterErr, "Invalid character") - var PI: PProcessingInstruction - new(PI) - PI.FTarget = target - PI.data = data - PI.FNodeType = ProcessingInstructionNode - return PI + var pi: PProcessingInstruction + new(pi) + pi.fTarget = target + pi.data = data + pi.fNodeType = ProcessingInstructionNode + return pi proc createTextNode*(doc: PDocument, data: string): PText = #Propably TextNode ## Creates a Text node given the specified string. @@ -353,9 +353,9 @@ proc createTextNode*(doc: PDocument, data: string): PText = #Propably TextNode new(txtNode) txtNode.data = data txtNode.nodeValue = data - txtNode.FNodeName = "#text" + txtNode.fNodeName = "#text" - txtNode.FNodeType = TextNode + txtNode.fNodeType = TextNode return txtNode discard """proc getElementById*(doc: PDocument, elementId: string): PElement = @@ -366,42 +366,42 @@ proc getElementsByTagName*(doc: PDocument, tagName: string): seq[PNode] = ## Returns a NodeList of all the Elements with a given tag name in ## the order in which they are encountered in a preorder traversal of the Document tree. var result: seq[PNode] = @[] - if doc.FDocumentElement.FNodeName == tagName or tagName == "*": - result.add(doc.FDocumentElement) + if doc.fDocumentElement.fNodeName == tagName or tagName == "*": + result.add(doc.fDocumentElement) - result.add(doc.FDocumentElement.findNodes(tagName)) + result.add(doc.fDocumentElement.findNodes(tagName)) return result proc getElementsByTagNameNS*(doc: PDocument, namespaceURI: string, localName: string): seq[PNode] = ## Returns a NodeList of all the Elements with a given localName and namespaceURI ## in the order in which they are encountered in a preorder traversal of the Document tree. var result: seq[PNode] = @[] - if doc.FDocumentElement.FLocalName == localName or localName == "*": - if doc.FDocumentElement.FNamespaceURI == namespaceURI or namespaceURI == "*": - result.add(doc.FDocumentElement) + if doc.fDocumentElement.fLocalName == localName or localName == "*": + if doc.fDocumentElement.fNamespaceURI == namespaceURI or namespaceURI == "*": + result.add(doc.fDocumentElement) - result.add(doc.FDocumentElement.findNodesNS(namespaceURI, localName)) + result.add(doc.fDocumentElement.findNodesNS(namespaceURI, localName)) return result proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode = ## Imports a node from another document to this document - case importedNode.FNodeType + case importedNode.fNodeType of AttributeNode: var nAttr: PAttr = PAttr(importedNode) - nAttr.FOwnerDocument = doc - nAttr.FParentNode = nil - nAttr.FOwnerElement = nil - nAttr.FSpecified = True + nAttr.fOwnerDocument = doc + nAttr.fParentNode = nil + nAttr.fOwnerElement = nil + nAttr.fSpecified = true return nAttr of DocumentFragmentNode: var n: PNode new(n) n = importedNode - n.FOwnerDocument = doc - n.FParentNode = nil + n.fOwnerDocument = doc + n.fParentNode = nil - n.FOwnerDocument = doc - n.FParentNode = nil + n.fOwnerDocument = doc + n.fParentNode = nil var tmp: seq[PNode] = n.childNodes n.childNodes = @[] if deep: @@ -413,8 +413,8 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode = var n: PNode new(n) n = importedNode - n.FOwnerDocument = doc - n.FParentNode = nil + n.fOwnerDocument = doc + n.fParentNode = nil var tmpA: seq[PAttr] = n.attributes n.attributes = @[] @@ -433,8 +433,8 @@ proc importNode*(doc: PDocument, importedNode: PNode, deep: bool): PNode = var n: PNode new(n) n = importedNode - n.FOwnerDocument = doc - n.FParentNode = nil + n.fOwnerDocument = doc + n.fParentNode = nil return n else: raise newException(ENotSupportedErr, "The type of node being imported is not supported") @@ -462,58 +462,58 @@ proc lastChild*(n: PNode): PNode = proc localName*(n: PNode): string = ## Returns this nodes local name - return n.FLocalName + return n.fLocalName proc namespaceURI*(n: PNode): string = ## Returns this nodes namespace URI - return n.FNamespaceURI + return n.fNamespaceURI proc `namespaceURI=`*(n: PNode, value: string) = - n.FNamespaceURI = value + n.fNamespaceURI = value proc nextSibling*(n: PNode): PNode = ## Returns the next sibling of this node - if isNil(n.FParentNode) or isNil(n.FParentNode.childNodes): + if isNil(n.fParentNode) or isNil(n.fParentNode.childNodes): return nil - var nLow: int = low(n.FParentNode.childNodes) - var nHigh: int = high(n.FParentNode.childNodes) + var nLow: int = low(n.fParentNode.childNodes) + var nHigh: int = high(n.fParentNode.childNodes) for i in nLow..nHigh: - if n.FParentNode.childNodes[i] == n: - return n.FParentNode.childNodes[i + 1] + if n.fParentNode.childNodes[i] == n: + return n.fParentNode.childNodes[i + 1] return nil proc nodeName*(n: PNode): string = ## Returns the name of this node - return n.FNodeName + return n.fNodeName proc nodeType*(n: PNode): int = ## Returns the type of this node - return n.FNodeType + return n.fNodeType proc ownerDocument*(n: PNode): PDocument = ## Returns the owner document of this node - return n.FOwnerDocument + return n.fOwnerDocument proc parentNode*(n: PNode): PNode = ## Returns the parent node of this node - return n.FParentNode + return n.fParentNode proc previousSibling*(n: PNode): PNode = ## Returns the previous sibling of this node - if isNil(n.FParentNode) or isNil(n.FParentNode.childNodes): + if isNil(n.fParentNode) or isNil(n.fParentNode.childNodes): return nil - var nLow: int = low(n.FParentNode.childNodes) - var nHigh: int = high(n.FParentNode.childNodes) + var nLow: int = low(n.fParentNode.childNodes) + var nHigh: int = high(n.fParentNode.childNodes) for i in nLow..nHigh: - if n.FParentNode.childNodes[i] == n: - return n.FParentNode.childNodes[i - 1] + if n.fParentNode.childNodes[i] == n: + return n.fParentNode.childNodes[i - 1] return nil proc `prefix=`*(n: PNode, value: string) = @@ -524,25 +524,25 @@ proc `prefix=`*(n: PNode, value: string) = if illegalChars in value: raise newException(EInvalidCharacterErr, "Invalid character") - if isNil(n.FNamespaceURI): + if isNil(n.fNamespaceURI): raise newException(ENamespaceErr, "namespaceURI cannot be nil") - elif value.toLower() == "xml" and n.FNamespaceURI != "http://www.w3.org/XML/1998/namespace": + elif value.toLower() == "xml" and n.fNamespaceURI != "http://www.w3.org/XML/1998/namespace": raise newException(ENamespaceErr, "When the namespace prefix is \"xml\" namespaceURI has to be \"http://www.w3.org/XML/1998/namespace\"") - elif value.toLower() == "xmlns" and n.FNamespaceURI != "http://www.w3.org/2000/xmlns/": + elif value.toLower() == "xmlns" and n.fNamespaceURI != "http://www.w3.org/2000/xmlns/": raise newException(ENamespaceErr, "When the namespace prefix is \"xmlns\" namespaceURI has to be \"http://www.w3.org/2000/xmlns/\"") - elif value.toLower() == "xmlns" and n.FNodeType == AttributeNode: + elif value.toLower() == "xmlns" and n.fNodeType == AttributeNode: raise newException(ENamespaceErr, "An AttributeNode cannot have a prefix of \"xmlns\"") - n.FNodeName = value & ":" & n.FLocalName + n.fNodeName = value & ":" & n.fLocalName if n.nodeType == ElementNode: var el: PElement = PElement(n) - el.FTagName = value & ":" & n.FLocalName + el.fTagName = value & ":" & n.fLocalName elif n.nodeType == AttributeNode: var attr: PAttr = PAttr(n) - attr.FName = value & ":" & n.FLocalName + attr.fName = value & ":" & n.fLocalName # Procedures proc appendChild*(n: PNode, newChild: PNode) = @@ -556,7 +556,7 @@ proc appendChild*(n: PNode, newChild: PNode) = raise newException(EHierarchyRequestErr, "The node to append is already in this nodes children.") # Check if newChild is from this nodes document - if n.FOwnerDocument != newChild.FOwnerDocument: + if n.fOwnerDocument != newChild.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") if n == newChild: @@ -567,7 +567,7 @@ proc appendChild*(n: PNode, newChild: PNode) = if isNil(n.childNodes): n.childNodes = @[] - newChild.FParentNode = n + newChild.fParentNode = n for i in low(n.childNodes)..high(n.childNodes): if n.childNodes[i] == newChild: n.childNodes[i] = newChild @@ -576,13 +576,13 @@ proc appendChild*(n: PNode, newChild: PNode) = proc cloneNode*(n: PNode, deep: bool): PNode = ## Returns a duplicate of this node, if ``deep`` is `true`, Element node's children are copied - case n.FNodeType + case n.fNodeType of AttributeNode: var newNode: PAttr new(newNode) newNode = PAttr(n) - newNode.FSpecified = True - newNode.FOwnerElement = nil + newNode.fSpecified = true + newNode.fOwnerElement = nil return newNode of ElementNode: var newNode: PElement @@ -614,32 +614,32 @@ proc insertBefore*(n: PNode, newChild: PNode, refChild: PNode): PNode = ## If ``refChild`` is nil, insert ``newChild`` at the end of the list of children. # Check if newChild is from this nodes document - if n.FOwnerDocument != newChild.FOwnerDocument: + if n.fOwnerDocument != newChild.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") if isNil(n.childNodes): - n.ChildNodes = @[] + n.childNodes = @[] for i in low(n.childNodes)..high(n.childNodes): if n.childNodes[i] == refChild: n.childNodes.insert(newChild, i - 1) return - n.ChildNodes.add(newChild) + n.childNodes.add(newChild) proc isSupported*(n: PNode, feature: string, version: string): bool = ## Tests whether the DOM implementation implements a specific ## feature and that feature is supported by this node. - return n.FOwnerDocument.FImplementation.hasFeature(feature, version) + return n.fOwnerDocument.fImplementation.hasFeature(feature, version) proc isEmpty(s: string): bool = if isNil(s) or s == "": - return True + return true for i in items(s): if i != ' ': - return False - return True + return false + return true proc normalize*(n: PNode) = ## Merges all seperated TextNodes together, and removes any empty TextNodes @@ -647,7 +647,7 @@ proc normalize*(n: PNode) = var i: int = 0 var newChildNodes: seq[PNode] = @[] - while True: + while true: if isNil(n.childNodes) or i >= n.childNodes.len: break if n.childNodes[i].nodeType == TextNode: @@ -685,7 +685,7 @@ proc replaceChild*(n: PNode, newChild: PNode, oldChild: PNode): PNode = ## Replaces the child node ``oldChild`` with ``newChild`` in the list of children, and returns the ``oldChild`` node. # Check if newChild is from this nodes document - if n.FOwnerDocument != newChild.FOwnerDocument: + if n.fOwnerDocument != newChild.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") if not isNil(n.childNodes): @@ -699,159 +699,159 @@ proc replaceChild*(n: PNode, newChild: PNode, oldChild: PNode): PNode = # NamedNodeMap -proc getNamedItem*(NList: seq[PNode], name: string): PNode = +proc getNamedItem*(nList: seq[PNode], name: string): PNode = ## Retrieves a node specified by ``name``. If this node cannot be found returns ``nil`` - for i in items(NList): + for i in items(nList): if i.nodeName() == name: return i return nil -proc getNamedItem*(NList: seq[PAttr], name: string): PAttr = +proc getNamedItem*(nList: seq[PAttr], name: string): PAttr = ## Retrieves a node specified by ``name``. If this node cannot be found returns ``nil`` - for i in items(NList): + for i in items(nList): if i.nodeName() == name: return i return nil -proc getNamedItemNS*(NList: seq[PNode], namespaceURI: string, localName: string): PNode = +proc getNamedItemNS*(nList: seq[PNode], namespaceURI: string, localName: string): PNode = ## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil`` - for i in items(NList): + for i in items(nList): if i.namespaceURI() == namespaceURI and i.localName() == localName: return i return nil -proc getNamedItemNS*(NList: seq[PAttr], namespaceURI: string, localName: string): PAttr = +proc getNamedItemNS*(nList: seq[PAttr], namespaceURI: string, localName: string): PAttr = ## Retrieves a node specified by ``localName`` and ``namespaceURI``. If this node cannot be found returns ``nil`` - for i in items(NList): - if i.NamespaceURI() == namespaceURI and i.LocalName() == localName: + for i in items(nList): + if i.namespaceURI() == namespaceURI and i.localName() == localName: return i return nil -proc item*(NList: seq[PNode], index: int): PNode = +proc item*(nList: seq[PNode], index: int): PNode = ## Returns the ``index`` th item in the map. ## If ``index`` is greater than or equal to the number of nodes in this map, this returns ``nil``. - if index >= NList.len(): return nil - else: return NList[index] + if index >= nList.len(): return nil + else: return nList[index] -proc removeNamedItem*(NList: var seq[PNode], name: string): PNode = +proc removeNamedItem*(nList: var seq[PNode], name: string): PNode = ## Removes a node specified by ``name`` ## Raises the ``ENotFoundErr`` exception, if the node was not found - for i in low(NList)..high(NList): - if NList[i].FNodeName == name: - result = NList[i] - NList.delete(i) + for i in low(nList)..high(nList): + if nList[i].fNodeName == name: + result = nList[i] + nList.delete(i) return result raise newException(ENotFoundErr, "Node not found") -proc removeNamedItemNS*(NList: var seq[PNode], namespaceURI: string, localName: string): PNode = +proc removeNamedItemNS*(nList: var seq[PNode], namespaceURI: string, localName: string): PNode = ## Removes a node specified by local name and namespace URI - for i in low(NList)..high(NList): - if NList[i].FLocalName == localName and NList[i].FNamespaceURI == namespaceURI: - result = NList[i] - NList.delete(i) + for i in low(nList)..high(nList): + if nList[i].fLocalName == localName and nList[i].fNamespaceURI == namespaceURI: + result = nList[i] + nList.delete(i) return result raise newException(ENotFoundErr, "Node not found") -proc setNamedItem*(NList: var seq[PNode], arg: PNode): PNode = +proc setNamedItem*(nList: var seq[PNode], arg: PNode): PNode = ## Adds ``arg`` as a ``Node`` to the ``NList`` ## If a node with the same name is already present in this map, it is replaced by the new one. - if not isNil(NList): - if NList.len() > 0: + if not isNil(nList): + if nList.len() > 0: #Check if newChild is from this nodes document - if NList[0].FOwnerDocument != arg.FOwnerDocument: + if nList[0].fOwnerDocument != arg.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") #Exceptions End - var item: PNode = NList.getNamedItem(arg.NodeName()) + var item: PNode = nList.getNamedItem(arg.nodeName()) if isNil(item): - NList.add(arg) + nList.add(arg) return nil else: # Node with the same name exists var index: int = 0 - for i in low(NList)..high(NList): - if NList[i] == item: + for i in low(nList)..high(nList): + if nList[i] == item: index = i break - NList[index] = arg + nList[index] = arg return item # Return the replaced node -proc setNamedItem*(NList: var seq[PAttr], arg: PAttr): PAttr = +proc setNamedItem*(nList: var seq[PAttr], arg: PAttr): PAttr = ## Adds ``arg`` as a ``Node`` to the ``NList`` ## If a node with the same name is already present in this map, it is replaced by the new one. - if not isNil(NList): - if NList.len() > 0: + if not isNil(nList): + if nList.len() > 0: # Check if newChild is from this nodes document - if NList[0].FOwnerDocument != arg.FOwnerDocument: + if nList[0].fOwnerDocument != arg.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") - if not isNil(arg.FOwnerElement): + if not isNil(arg.fOwnerElement): raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode") # Exceptions end - var item: PAttr = NList.getNamedItem(arg.nodeName()) + var item: PAttr = nList.getNamedItem(arg.nodeName()) if isNil(item): - NList.add(arg) + nList.add(arg) return nil else: # Node with the same name exists var index: int = 0 - for i in low(NList)..high(NList): - if NList[i] == item: + for i in low(nList)..high(nList): + if nList[i] == item: index = i break - NList[index] = arg + nList[index] = arg return item # Return the replaced node -proc setNamedItemNS*(NList: var seq[PNode], arg: PNode): PNode = +proc setNamedItemNS*(nList: var seq[PNode], arg: PNode): PNode = ## Adds a node using its ``namespaceURI`` and ``localName`` - if not isNil(NList): - if NList.len() > 0: + if not isNil(nList): + if nList.len() > 0: # Check if newChild is from this nodes document - if NList[0].FOwnerDocument != arg.FOwnerDocument: + if nList[0].fOwnerDocument != arg.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") #Exceptions end - var item: PNode = NList.getNamedItemNS(arg.namespaceURI(), arg.localName()) + var item: PNode = nList.getNamedItemNS(arg.namespaceURI(), arg.localName()) if isNil(item): - NList.add(arg) + nList.add(arg) return nil else: # Node with the same name exists var index: int = 0 - for i in low(NList)..high(NList): - if NList[i] == item: + for i in low(nList)..high(nList): + if nList[i] == item: index = i break - NList[index] = arg + nList[index] = arg return item # Return the replaced node -proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr = +proc setNamedItemNS*(nList: var seq[PAttr], arg: PAttr): PAttr = ## Adds a node using its ``namespaceURI`` and ``localName`` - if not isNil(NList): - if NList.len() > 0: + if not isNil(nList): + if nList.len() > 0: # Check if newChild is from this nodes document - if NList[0].FOwnerDocument != arg.FOwnerDocument: + if nList[0].fOwnerDocument != arg.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") - if not isNil(arg.FOwnerElement): + if not isNil(arg.fOwnerElement): raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode") # Exceptions end - var item: PAttr = NList.getNamedItemNS(arg.namespaceURI(), arg.localName()) + var item: PAttr = nList.getNamedItemNS(arg.namespaceURI(), arg.localName()) if isNil(item): - NList.add(arg) + nList.add(arg) return nil else: # Node with the same name exists var index: int = 0 - for i in low(NList)..high(NList): - if NList[i] == item: + for i in low(nList)..high(nList): + if nList[i] == item: index = i break - NList[index] = arg + nList[index] = arg return item # Return the replaced node # CharacterData - Decided to implement this, @@ -862,17 +862,17 @@ proc setNamedItemNS*(NList: var seq[PAttr], arg: PAttr): PAttr = proc name*(a: PAttr): string = ## Returns the name of the Attribute - return a.FName + return a.fName proc specified*(a: PAttr): bool = ## Specifies whether this attribute was specified in the original document - return a.FSpecified + return a.fSpecified proc ownerElement*(a: PAttr): PElement = ## Returns this Attributes owner element - return a.FOwnerElement + return a.fOwnerElement # Element # Attributes @@ -880,7 +880,7 @@ proc ownerElement*(a: PAttr): PElement = proc tagName*(el: PElement): string = ## Returns the Element Tag Name - return el.FTagName + return el.fTagName # Procedures proc getAttribute*(el: PElement, name: string): string = @@ -946,15 +946,15 @@ proc removeAttribute*(el: PElement, name: string) = ## Removes an attribute by ``name`` if not isNil(el.attributes): for i in low(el.attributes)..high(el.attributes): - if el.attributes[i].FName == name: + if el.attributes[i].fName == name: el.attributes.delete(i) proc removeAttributeNS*(el: PElement, namespaceURI: string, localName: string) = ## Removes an attribute by ``localName`` and ``namespaceURI`` if not isNil(el.attributes): for i in low(el.attributes)..high(el.attributes): - if el.attributes[i].FNamespaceURI == namespaceURI and - el.attributes[i].FLocalName == localName: + if el.attributes[i].fNamespaceURI == namespaceURI and + el.attributes[i].fLocalName == localName: el.attributes.delete(i) proc removeAttributeNode*(el: PElement, oldAttr: PAttr): PAttr = @@ -975,11 +975,11 @@ proc setAttributeNode*(el: PElement, newAttr: PAttr): PAttr = ## returned, otherwise ``nil`` is returned. # Check if newAttr is from this nodes document - if el.FOwnerDocument != newAttr.FOwnerDocument: + if el.fOwnerDocument != newAttr.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") - if not isNil(newAttr.FOwnerElement): + if not isNil(newAttr.fOwnerElement): raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode") # Exceptions end @@ -993,11 +993,11 @@ proc setAttributeNodeNS*(el: PElement, newAttr: PAttr): PAttr = ## and the replaced attribute is returned, otherwise ``nil`` is returned. # Check if newAttr is from this nodes document - if el.FOwnerDocument != newAttr.FOwnerDocument: + if el.fOwnerDocument != newAttr.fOwnerDocument: raise newException(EWrongDocumentErr, "This node belongs to a different document, use importNode.") - if not isNil(newAttr.FOwnerElement): + if not isNil(newAttr.fOwnerElement): raise newException(EInuseAttributeErr, "This attribute is in use by another element, use cloneNode") # Exceptions end @@ -1011,17 +1011,17 @@ proc setAttribute*(el: PElement, name: string, value: string) = ## value is changed to be that of the value parameter ## Raises the EInvalidCharacterErr if the specified ``name`` contains ## illegal characters - var AttrNode = el.FOwnerDocument.createAttribute(name) + var attrNode = el.fOwnerDocument.createAttribute(name) # Check if name contains illegal characters if illegalChars in name: raise newException(EInvalidCharacterErr, "Invalid character") - discard el.setAttributeNode(AttrNode) + discard el.setAttributeNode(attrNode) # Set the info later, the setAttributeNode checks # if FOwnerElement is nil, and if it isn't it raises an exception - AttrNode.FOwnerElement = el - AttrNode.FSpecified = True - AttrNode.value = value + attrNode.fOwnerElement = el + attrNode.fSpecified = true + attrNode.value = value proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) = ## Adds a new attribute, as specified by ``namespaceURI``, ``localName`` @@ -1031,43 +1031,43 @@ proc setAttributeNS*(el: PElement, namespaceURI, localName, value: string) = if illegalChars in namespaceURI or illegalChars in localName: raise newException(EInvalidCharacterErr, "Invalid character") - var AttrNode = el.FOwnerDocument.createAttributeNS(namespaceURI, localName) + var attrNode = el.fOwnerDocument.createAttributeNS(namespaceURI, localName) - discard el.setAttributeNodeNS(AttrNode) + discard el.setAttributeNodeNS(attrNode) # Set the info later, the setAttributeNode checks # if FOwnerElement is nil, and if it isn't it raises an exception - AttrNode.FOwnerElement = el - AttrNode.FSpecified = True - AttrNode.value = value + attrNode.fOwnerElement = el + attrNode.fSpecified = true + attrNode.value = value # Text -proc splitData*(TextNode: PText, offset: int): PText = +proc splitData*(textNode: PText, offset: int): PText = ## Breaks this node into two nodes at the specified offset, ## keeping both in the tree as siblings. - if offset > TextNode.data.len(): + if offset > textNode.data.len(): raise newException(EIndexSizeErr, "Index out of bounds") - var left: string = TextNode.data.substr(0, offset) - TextNode.data = left - var right: string = TextNode.data.substr(offset, TextNode.data.len()) + var left: string = textNode.data.substr(0, offset) + textNode.data = left + var right: string = textNode.data.substr(offset, textNode.data.len()) - if not isNil(TextNode.FParentNode) and not isNil(TextNode.FParentNode.childNodes): - for i in low(TextNode.FParentNode.childNodes)..high(TextNode.FParentNode.childNodes): - if TextNode.FParentNode.childNodes[i] == TextNode: - var newNode: PText = TextNode.FOwnerDocument.createTextNode(right) - TextNode.FParentNode.childNodes.insert(newNode, i) + if not isNil(textNode.fParentNode) and not isNil(textNode.fParentNode.childNodes): + for i in low(textNode.fParentNode.childNodes)..high(textNode.fParentNode.childNodes): + if textNode.fParentNode.childNodes[i] == textNode: + var newNode: PText = textNode.fOwnerDocument.createTextNode(right) + textNode.fParentNode.childNodes.insert(newNode, i) return newNode else: - var newNode: PText = TextNode.FOwnerDocument.createTextNode(right) + var newNode: PText = textNode.fOwnerDocument.createTextNode(right) return newNode # ProcessingInstruction -proc target*(PI: PProcessingInstruction): string = +proc target*(pi: PProcessingInstruction): string = ## Returns the Processing Instructions target - return PI.FTarget + return pi.fTarget # --Other stuff-- From 02c076f9b42e0d65d1b4416e671a8f9cfae6d9b1 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Sep 2014 23:13:38 +0200 Subject: [PATCH 137/409] more robust for nim check --- compiler/types.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/types.nim b/compiler/types.nim index 7b59fbf20..7a9b6bb85 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -969,6 +969,7 @@ proc inheritanceDiff*(a, b: PType): int = # | returns: -x iff `a` is the x'th direct superclass of `b` # | returns: +x iff `a` is the x'th direct subclass of `b` # | returns: `maxint` iff `a` and `b` are not compatible at all + if a == b or a.kind == tyError or b.kind == tyError: return 0 assert a.kind == tyObject assert b.kind == tyObject var x = a From 3fcf6f430d4898bef292b33cd824893e81044298 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Sep 2014 23:13:58 +0200 Subject: [PATCH 138/409] updated fsmonitor --- lib/pure/fsmonitor.nim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pure/fsmonitor.nim b/lib/pure/fsmonitor.nim index cfee8d0ea..bf4aef61c 100644 --- a/lib/pure/fsmonitor.nim +++ b/lib/pure/fsmonitor.nim @@ -96,7 +96,7 @@ proc add*(monitor: PFSMonitor, target: string, result = inotifyAddWatch(monitor.fd, target, INFilter.uint32) if result < 0: - OSError(OSLastError()) + raiseOSError(osLastError()) monitor.targets.add(result, target) proc del*(monitor: PFSMonitor, wd: cint) = @@ -113,8 +113,7 @@ proc getEvent(m: PFSMonitor, fd: cint): seq[TMonitorEvent] = let le = read(fd, addr(buffer[0]), size) - var movedFrom: TTable[cint, tuple[wd: cint, old: string]] = - initTable[cint, tuple[wd: cint, old: string]]() + var movedFrom = initTable[cint, tuple[wd: cint, old: string]]() var i = 0 while i < le: From 45accd613bd523c0635ca2ffe946b27b531e40ab Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 18 Sep 2014 09:56:13 +0200 Subject: [PATCH 139/409] 'nim i' should work again --- compiler/modules.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/modules.nim b/compiler/modules.nim index dd8ccedb1..05b795473 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -190,10 +190,11 @@ proc wantMainModule* = fatal(gCmdLineInfo, errCommandExpectsFilename) gProjectMainIdx = addFileExt(gProjectFull, NimExt).fileInfoIdx +passes.gIncludeFile = includeModule +passes.gImportModule = importModule + proc compileProject*(projectFileIdx = -1'i32) = wantMainModule() - passes.gIncludeFile = includeModule - passes.gImportModule = importModule let systemFileIdx = fileInfoIdx(options.libpath / "system.nim") let projectFile = if projectFileIdx < 0: gProjectMainIdx else: projectFileIdx if projectFile == systemFileIdx: From 03744be67ec6e48527ccfa9f5b631ee7ed8b32c3 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 18 Sep 2014 09:59:11 +0200 Subject: [PATCH 140/409] updated xml modules --- lib/pure/parsexml.nim | 6 +++--- lib/pure/xmldomparser.nim | 38 +++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index 66135a971..39dead3c0 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -166,12 +166,12 @@ proc attrValue*(my: XmlParser): string {.inline.} = assert(my.kind == xmlAttribute) return my.b -proc PIName*(my: XmlParser): string {.inline.} = +proc piName*(my: XmlParser): string {.inline.} = ## returns the processing instruction name for the event ``xmlPI`` assert(my.kind == xmlPI) return my.a -proc PIRest*(my: XmlParser): string {.inline.} = +proc piRest*(my: XmlParser): string {.inline.} = ## returns the rest of the processing instruction for the event ``xmlPI`` assert(my.kind == xmlPI) return my.b @@ -641,7 +641,7 @@ when isMainModule: of xmlCharData: echo(x.charData) of xmlWhitespace: echo("|$1|" % x.charData) of xmlComment: echo("" % x.charData) - of xmlPI: echo("" % [x.PIName, x.PIRest]) + of xmlPI: echo("" % [x.piName, x.piRest]) of xmlElementStart: echo("<$1>" % x.elementName) of xmlElementEnd: echo("" % x.elementName) diff --git a/lib/pure/xmldomparser.nim b/lib/pure/xmldomparser.nim index b92a9600c..7f34d72a8 100644 --- a/lib/pure/xmldomparser.nim +++ b/lib/pure/xmldomparser.nim @@ -15,13 +15,13 @@ import xmldom, os, streams, parsexml, strutils type # Parsing errors - EMismatchedTag* = object of EInvalidValue ## Raised when a tag is not properly closed - EParserError* = object of EInvalidValue ## Raised when an unexpected XML Parser event occurs + EMismatchedTag* = object of ValueError ## Raised when a tag is not properly closed + EParserError* = object of ValueError ## Raised when an unexpected XML Parser event occurs # For namespaces - xmlnsAttr = tuple[name, value: string, ownerElement: PElement] + XmlnsAttr = tuple[name, value: string, ownerElement: PElement] -var nsList: seq[xmlnsAttr] = @[] # Used for storing namespaces +var nsList: seq[XmlnsAttr] = @[] # Used for storing namespaces proc getNS(prefix: string): string = var defaultNS: seq[string] = @[] @@ -43,13 +43,13 @@ proc getNS(prefix: string): string = return "" -proc parseText(x: var TXmlParser, doc: var PDocument): PText = +proc parseText(x: var XmlParser, doc: var PDocument): PText = result = doc.createTextNode(x.charData()) -proc parseElement(x: var TXmlParser, doc: var PDocument): PElement = +proc parseElement(x: var XmlParser, doc: var PDocument): PElement = var n = doc.createElement("") - while True: + while true: case x.kind() of xmlEof: break @@ -102,10 +102,10 @@ proc parseElement(x: var TXmlParser, doc: var PDocument): PElement = of xmlComment: n.appendChild(doc.createComment(x.charData())) of xmlPI: - n.appendChild(doc.createProcessingInstruction(x.PIName(), x.PIRest())) + n.appendChild(doc.createProcessingInstruction(x.piName(), x.piRest())) of xmlWhitespace, xmlElementClose, xmlEntity, xmlSpecial: - # Unused 'events' + discard " Unused \'events\'" else: raise newException(EParserError, "Unexpected XML Parser event") @@ -114,30 +114,30 @@ proc parseElement(x: var TXmlParser, doc: var PDocument): PElement = raise newException(EMismatchedTag, "Mismatched tag at line " & $x.getLine() & " column " & $x.getColumn) -proc loadXMLStream*(stream: PStream): PDocument = +proc loadXMLStream*(stream: Stream): PDocument = ## Loads and parses XML from a stream specified by ``stream``, and returns ## a ``PDocument`` - var x: TXmlParser + var x: XmlParser open(x, stream, nil, {reportComments}) - var XmlDoc: PDocument - var DOM: PDOMImplementation = getDOM() + var xmlDoc: PDocument + var dom: PDOMImplementation = getDOM() - while True: + while true: x.next() case x.kind() of xmlEof: break of xmlElementStart, xmlElementOpen: - var el: PElement = parseElement(x, XmlDoc) - XmlDoc = dom.createDocument(el) + var el: PElement = parseElement(x, xmlDoc) + xmlDoc = dom.createDocument(el) of xmlWhitespace, xmlElementClose, xmlEntity, xmlSpecial: - # Unused 'events' + discard " Unused \'events\'" else: raise newException(EParserError, "Unexpected XML Parser event") - return XmlDoc + return xmlDoc proc loadXML*(xml: string): PDocument = ## Loads and parses XML from a string specified by ``xml``, and returns @@ -151,7 +151,7 @@ proc loadXMLFile*(path: string): PDocument = ## a ``PDocument`` var s = newFileStream(path, fmRead) - if s == nil: raise newException(EIO, "Unable to read file " & path) + if s == nil: raise newException(IOError, "Unable to read file " & path) return loadXMLStream(s) From 867dfbfbfa68c61a2b65d46af7c22aa47857fa21 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Thu, 18 Sep 2014 17:01:44 +0100 Subject: [PATCH 141/409] Adds socket creation for arbitrary domain, type and protocol. --- lib/pure/asyncdispatch.nim | 11 +++++++++++ lib/pure/asyncnet.nim | 4 ++++ lib/pure/net.nim | 9 +++++++++ lib/pure/rawsockets.nim | 7 +++++++ 4 files changed, 31 insertions(+) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index cac98e160..fb0023292 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -766,6 +766,12 @@ when defined(windows) or defined(nimdoc): return retFuture + proc newAsyncRawSocket*(domain, typ, protocol: cint): TAsyncFD = + ## Creates a new socket and registers it with the dispatcher implicitly. + result = newRawSocket(domain, typ, protocol).TAsyncFD + result.SocketHandle.setBlocking(false) + register(result) + proc newAsyncRawSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, protocol: Protocol = IPPROTO_TCP): TAsyncFD = @@ -832,6 +838,11 @@ else: var data = PData(sock: sock, readCBs: @[], writeCBs: @[]) p.selector.register(sock.SocketHandle, {}, data.PObject) + proc newAsyncRawSocket*(domain: cint, typ: cint, protocol: cint): TAsyncFD = + result = newRawSocket(domain, typ, protocol).TAsyncFD + result.SocketHandle.setBlocking(false) + register(result) + proc newAsyncRawSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, protocol: TProtocol = IPPROTO_TCP): TAsyncFD = diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index c6918517e..cc7f096eb 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -101,6 +101,10 @@ proc newAsyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, ## Creates a new asynchronous socket. result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) +proc newAsyncSocket*(domain, typ, protocol: cint, buffered = true): PAsyncSocket = + ## Creates a new asynchronous socket. + result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) + when defined(ssl): proc getSslError(handle: SslPtr, err: cint): cint = assert err < 0 diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 886ed792f..60298ec88 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -108,6 +108,15 @@ proc createSocket(fd: SocketHandle, isBuff: bool): Socket = if isBuff: result.currPos = 0 +proc newSocket*(domain, typ, protocol: cint, buffered = true): Socket = + ## Creates a new socket. + ## + ## If an error occurs EOS will be raised. + let fd = newRawSocket(domain, typ, protocol) + if fd == osInvalidSocket: + raiseOSError(osLastError()) + result = createSocket(fd, buffered) + proc newSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, protocol: Protocol = IPPROTO_TCP, buffered = true): Socket = ## Creates a new socket. diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim index c76e99fcb..5756ca23d 100644 --- a/lib/pure/rawsockets.nim +++ b/lib/pure/rawsockets.nim @@ -153,6 +153,13 @@ proc newRawSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, ## Creates a new socket; returns `InvalidSocket` if an error occurs. socket(toInt(domain), toInt(typ), toInt(protocol)) +proc newRawSocket*(domain: cint, typ: cint, protocol: cint): SocketHandle = + ## Creates a new socket; returns `InvalidSocket` if an error occurs. + ## + ## Use this overload if one of the enums specified above does + ## not contain what you need. + socket(domain, typ, protocol) + proc close*(socket: SocketHandle) = ## closes a socket. when useWinVersion: From 83e26cc4fa68f5af26301a75be9781bf007663c1 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Thu, 18 Sep 2014 18:04:07 +0100 Subject: [PATCH 142/409] Fixes asyncnet example. --- lib/pure/asyncnet.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index cc7f096eb..72fe51a7e 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -31,7 +31,7 @@ ## ## import asyncnet, asyncdispatch ## -## var clients: seq[AsyncSocket] = @[] +## var clients {.threadvar.}: seq[AsyncSocket] ## ## proc processClient(client: AsyncSocket) {.async.} = ## while true: @@ -40,6 +40,7 @@ ## await c.send(line & "\c\L") ## ## proc serve() {.async.} = +## clients = @[] ## var server = newAsyncSocket() ## server.bindAddr(Port(12345)) ## server.listen() From e7140f290b0f427ec6bd81cb75b555cdd672f9f0 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 18 Sep 2014 23:08:55 +0200 Subject: [PATCH 143/409] updated SDL wrapper --- lib/wrappers/sdl/sdl.nim | 627 ++++++++++++------------- lib/wrappers/sdl/sdl_gfx.nim | 156 +++--- lib/wrappers/sdl/sdl_image.nim | 74 +-- lib/wrappers/sdl/sdl_mixer.nim | 168 +++---- lib/wrappers/sdl/sdl_mixer_nosmpeg.nim | 166 +++---- lib/wrappers/sdl/sdl_net.nim | 115 +++-- lib/wrappers/sdl/sdl_ttf.nim | 94 ++-- lib/wrappers/sdl/smpeg.nim | 79 ++-- 8 files changed, 732 insertions(+), 747 deletions(-) diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim index 753796274..e09dfd59a 100644 --- a/lib/wrappers/sdl/sdl.nim +++ b/lib/wrappers/sdl/sdl.nim @@ -752,13 +752,13 @@ const # Enumeration of valid key mods (possibly OR'd tog type THandle* = int #SDL_types.h types # Basic data types - TBool* = enum + TBool* = enum sdlFALSE, sdlTRUE PUInt8Array* = ptr TUInt8Array TUInt8Array* = array[0..high(int) shr 1, byte] - PUInt16* = ptr uInt16 - PUInt32* = ptr uInt32 - PUInt64* = ptr uInt64 + PUInt16* = ptr uint16 + PUInt32* = ptr uint32 + PUInt64* = ptr UInt64 UInt64*{.final.} = object hi*: int32 lo*: int32 @@ -771,12 +771,12 @@ type TGrabMode* = int32 # SDL_error.h types Terrorcode* = enum ENOMEM, EFREAD, EFWRITE, EFSEEK, LASTERROR - errorcode* = Terrorcode + Errorcode* = Terrorcode TArg*{.final.} = object buf*: array[0..ERR_MAX_STRLEN - 1, int8] Perror* = ptr Terror - Terror*{.final.} = object # This is a numeric value corresponding to the current error + TError*{.final.} = object # This is a numeric value corresponding to the current error # SDL_rwops.h types # This is the read/write operation structure -- very basic # some helper types to handle the unions @@ -824,7 +824,7 @@ type interval*: int32 callback*: TNewTimerCallback param*: pointer - last_alarm*: int32 + lastAlarm*: int32 next*: PTimerID TAudioSpecCallback* = proc (userdata: pointer, stream: ptr byte, length: int){. @@ -833,11 +833,11 @@ type PAudioSpec* = ptr TAudioSpec TAudioSpec*{.final.} = object # A structure to hold a set of audio conversion filters and buffers freq*: int # DSP frequency -- samples per second - format*: uInt16 # Audio data format + format*: uint16 # Audio data format channels*: byte # Number of channels: 1 mono, 2 stereo silence*: byte # Audio buffer silence value (calculated) - samples*: uInt16 # Audio buffer size in samples - padding*: uInt16 # Necessary for some compile environments + samples*: uint16 # Audio buffer size in samples + padding*: uint16 # Necessary for some compile environments size*: int32 # Audio buffer size in bytes (calculated) # This function is called when the audio device needs more data. # 'stream' is a pointer to the audio data buffer @@ -857,16 +857,16 @@ type TAudioCVTFilterArray* = array[0..9, PAudioCVTFilter] TAudioCVT*{.final.} = object needed*: int # Set to 1 if conversion possible - src_format*: uint16 # Source audio format - dst_format*: uint16 # Target audio format - rate_incr*: float64 # Rate conversion increment + srcFormat*: uint16 # Source audio format + dstFormat*: uint16 # Target audio format + rateIncr*: float64 # Rate conversion increment buf*: ptr byte # Buffer to hold entire audio data length*: int # Length of original audio buffer - len_cvt*: int # Length of converted audio buffer - len_mult*: int # buffer must be len*len_mult big - len_ratio*: float64 # Given len, final size is len*len_ratio + lenCvt*: int # Length of converted audio buffer + lenMult*: int # buffer must be len*len_mult big + lenRatio*: float64 # Given len, final size is len*len_ratio filters*: TAudioCVTFilterArray - filter_index*: int # Current audio conversion function + filterIndex*: int # Current audio conversion function TAudiostatus* = enum # SDL_cdrom.h types AUDIO_STOPPED, AUDIO_PLAYING, AUDIO_PAUSED @@ -886,8 +886,8 @@ type status*: TCDStatus # Current drive status # The rest of this structure is only valid if there's a CD in drive numtracks*: int # Number of tracks on disk - cur_track*: int # Current track position - cur_frame*: int # Current frame offset within current track + curTrack*: int # Current track position + curFrame*: int # Current frame offset within current track track*: array[0..MAX_TRACKS, TCDTrack] PTransAxis* = ptr TTransAxis @@ -895,7 +895,7 @@ type offset*: int scale*: float32 - PJoystick_hwdata* = ptr TJoystick_hwdata + PJoystickHwdata* = ptr TJoystickHwdata TJoystick_hwdata*{.final.} = object # joystick ID id*: int # values used to translate device-specific coordinates into SDL-standard ranges transaxis*: array[0..5, TTransAxis] @@ -918,8 +918,8 @@ type balls*: PBallDelta # Current ball motion deltas nbuttons*: int # Number of buttons on the joystick buttons*: ptr byte # Current button states - hwdata*: PJoystick_hwdata # Driver dependent information - ref_count*: int # Reference count for multiple opens + hwdata*: PJoystickHwdata # Driver dependent information + refCount*: int # Reference count for multiple opens Pversion* = ptr Tversion Tversion*{.final.} = object # SDL_keyboard.h types @@ -1051,7 +1051,7 @@ when defined(WINDOWS): version*: Tversion hwnd*: THandle # The window for the message msg*: int # The type of message - w_Param*: int32 # WORD message parameter + wParam*: int32 # WORD message parameter lParam*: int32 # LONG message parameter elif defined(Unix): @@ -1155,34 +1155,34 @@ type PPixelFormat* = ptr TPixelFormat TPixelFormat*{.final.} = object # The structure passed to the low level blit functions palette*: PPalette - BitsPerPixel*: byte - BytesPerPixel*: byte - Rloss*: byte - Gloss*: byte - Bloss*: byte - Aloss*: byte - Rshift*: byte - Gshift*: byte - Bshift*: byte - Ashift*: byte - RMask*: int32 - GMask*: int32 - BMask*: int32 - AMask*: int32 + bitsPerPixel*: byte + bytesPerPixel*: byte + rloss*: byte + gloss*: byte + bloss*: byte + aloss*: byte + rshift*: byte + gshift*: byte + bshift*: byte + ashift*: byte + rMask*: int32 + gMask*: int32 + bMask*: int32 + aMask*: int32 colorkey*: int32 # RGB color key information alpha*: byte # Alpha value information (per-surface alpha) PBlitInfo* = ptr TBlitInfo TBlitInfo*{.final.} = object # typedef for private surface blitting functions - s_pixels*: ptr byte - s_width*: int - s_height*: int - s_skip*: int - d_pixels*: ptr byte - d_width*: int - d_height*: int - d_skip*: int - aux_data*: pointer + sPixels*: ptr byte + sWidth*: int + sHeight*: int + sSkip*: int + dPixels*: ptr byte + dWidth*: int + dHeight*: int + dSkip*: int + auxData*: pointer src*: PPixelFormat table*: ptr byte dst*: PPixelFormat @@ -1199,25 +1199,25 @@ type offset*: cint # Private hwdata*: pointer #TPrivate_hwdata; Hardware-specific surface info # clipping information: - clip_rect*: TRect # Read-only + clipRect*: TRect # Read-only unused1*: int32 # for binary compatibility # Allow recursive locks locked*: int32 # Private # info for fast blit mapping to other surfaces - Blitmap*: pointer # PSDL_BlitMap; // Private + blitmap*: pointer # PSDL_BlitMap; // Private # format version, bumped at every change to invalidate blit maps - format_version*: cint # Private + formatVersion*: cint # Private refcount*: cint PVideoInfo* = ptr TVideoInfo TVideoInfo*{.final.} = object # The YUV hardware video overlay - hw_available*: byte - blit_hw*: byte - UnusedBits3*: byte # Unused at this point - video_mem*: int32 # The total amount of video memory (in K) + hwAvailable*: byte + blitHw*: byte + unusedBits3*: byte # Unused at this point + videoMem*: int32 # The total amount of video memory (in K) vfmt*: PPixelFormat # Value: The format of the video surface - current_w*: int32 # Value: The current video mode width - current_h*: int32 # Value: The current video mode height + currentW*: int32 # Value: The current video mode width + currentH*: int32 # Value: The current video mode height POverlay* = ptr TOverlay TOverlay*{.final.} = object # Public enumeration for setting the OpenGL window attributes. @@ -1226,7 +1226,7 @@ type planes*: int # Number of planes in the overlay. Usually either 1 or 3 pitches*: PUInt16 # An array of pitches, one for each plane. Pitch is the length of a row in bytes. pixels*: ptr ptr byte # An array of pointers to the data of each plane. The overlay should be locked before these pointers are used. - hw_overlay*: int32 # This will be set to 1 if the overlay is hardware accelerated. + hwOverlay*: int32 # This will be set to 1 if the overlay is hardware accelerated. TGLAttr* = enum GL_RED_SIZE, GL_GREEN_SIZE, GL_BLUE_SIZE, GL_ALPHA_SIZE, GL_BUFFER_SIZE, @@ -1237,11 +1237,11 @@ type PCursor* = ptr TCursor TCursor*{.final.} = object # SDL_mutex.h types area*: TRect # The area of the mouse cursor - hot_x*, hot_y*: int16 # The "tip" of the cursor + hotX*, hot_y*: int16 # The "tip" of the cursor data*: ptr byte # B/W cursor data mask*: ptr byte # B/W cursor mask save*: array[1..2, ptr byte] # Place to save cursor area - wm_cursor*: pointer # Window-manager cursor + wmCursor*: pointer # Window-manager cursor type @@ -1250,7 +1250,7 @@ type Psemaphore* = ptr Tsemaphore Tsemaphore*{.final.} = object PSem* = ptr TSem - TSem* = TSemaphore + TSem* = Tsemaphore PCond* = ptr TCond TCond*{.final.} = object # SDL_thread.h types @@ -1267,7 +1267,7 @@ type # This is the system-independent thread info struc threadid*: int32 handle*: TSYS_ThreadHandle status*: int - errbuf*: TError + errbuf*: Terror data*: pointer PKeyStateArr* = ptr TKeyStateArr @@ -1282,7 +1282,7 @@ type # This is the system-independent thread info struc TWordArray* = array[0..16383, int16] # Generic procedure pointer type TEventSeq = set[TEventKind] -template evconv(procName: expr, ptrName: typeDesc, assertions: TEventSeq): stmt {.immediate.} = +template evconv(procName: expr, ptrName: typedesc, assertions: TEventSeq): stmt {.immediate.} = proc `procName`*(event: PEvent): ptrName = assert(contains(assertions, event.kind)) result = cast[ptrName](event) @@ -1309,73 +1309,72 @@ evconv(EvSysWM, PSysWMEvent, {SYSWMEVENT}) # Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup # signal handlers for some commonly ignored fatal signals (like SIGSEGV) -proc Init*(flags: int32): int{.cdecl, importc: "SDL_Init", dynlib: LibName.} +proc init*(flags: int32): int{.cdecl, importc: "SDL_Init", dynlib: LibName.} # This function initializes specific SDL subsystems -proc InitSubSystem*(flags: int32): int{.cdecl, importc: "SDL_InitSubSystem", +proc initSubSystem*(flags: int32): int{.cdecl, importc: "SDL_InitSubSystem", dynlib: LibName.} # This function cleans up specific SDL subsystems -proc QuitSubSystem*(flags: int32){.cdecl, importc: "SDL_QuitSubSystem", +proc quitSubSystem*(flags: int32){.cdecl, importc: "SDL_QuitSubSystem", dynlib: LibName.} # This function returns mask of the specified subsystems which have # been initialized. # If 'flags' is 0, it returns a mask of all initialized subsystems. -proc WasInit*(flags: int32): int32{.cdecl, importc: "SDL_WasInit", +proc wasInit*(flags: int32): int32{.cdecl, importc: "SDL_WasInit", dynlib: LibName.} # This function cleans up all initialized subsystems and unloads the # dynamically linked library. You should call it upon all exit conditions. -proc Quit*(){.cdecl, importc: "SDL_Quit", dynlib: LibName.} +proc quit*(){.cdecl, importc: "SDL_Quit", dynlib: LibName.} when defined(WINDOWS): # This should be called from your WinMain() function, if any - proc RegisterApp*(name: cstring, style: int32, h_Inst: pointer): int{.cdecl, + proc registerApp*(name: cstring, style: int32, hInst: pointer): int{.cdecl, importc: "SDL_RegisterApp", dynlib: LibName.} -proc TableSize*(table: cstring): int +proc tableSize*(table: cstring): int #------------------------------------------------------------------------------ # error-handling #------------------------------------------------------------------------------ # Public functions -proc GetError*(): cstring{.cdecl, importc: "SDL_GetError", dynlib: LibName.} -proc SetError*(fmt: cstring){.cdecl, importc: "SDL_SetError", dynlib: LibName.} -proc ClearError*(){.cdecl, importc: "SDL_ClearError", dynlib: LibName.} -when not (defined(WINDOWS)): - proc Error*(Code: Terrorcode){.cdecl, importc: "SDL_Error", dynlib: LibName.} -proc OutOfMemory*() +proc getError*(): cstring{.cdecl, importc: "SDL_GetError", dynlib: LibName.} +proc setError*(fmt: cstring){.cdecl, importc: "SDL_SetError", dynlib: LibName.} +proc clearError*(){.cdecl, importc: "SDL_ClearError", dynlib: LibName.} +when not (defined(WINDOWS)): + proc error*(Code: Terrorcode){.cdecl, importc: "SDL_Error", dynlib: LibName.} #------------------------------------------------------------------------------ # io handling #------------------------------------------------------------------------------ # Functions to create SDL_RWops structures from various data sources -proc RWFromFile*(filename, mode: cstring): PRWops{.cdecl, +proc rwFromFile*(filename, mode: cstring): PRWops{.cdecl, importc: "SDL_RWFromFile", dynlib: LibName.} -proc FreeRW*(area: PRWops){.cdecl, importc: "SDL_FreeRW", dynlib: LibName.} +proc freeRW*(area: PRWops){.cdecl, importc: "SDL_FreeRW", dynlib: LibName.} #fp is FILE *fp ??? -proc RWFromFP*(fp: pointer, autoclose: int): PRWops{.cdecl, +proc rwFromFP*(fp: pointer, autoclose: int): PRWops{.cdecl, importc: "SDL_RWFromFP", dynlib: LibName.} -proc RWFromMem*(mem: pointer, size: int): PRWops{.cdecl, +proc rwFromMem*(mem: pointer, size: int): PRWops{.cdecl, importc: "SDL_RWFromMem", dynlib: LibName.} -proc RWFromConstMem*(mem: pointer, size: int): PRWops{.cdecl, +proc rwFromConstMem*(mem: pointer, size: int): PRWops{.cdecl, importc: "SDL_RWFromConstMem", dynlib: LibName.} -proc AllocRW*(): PRWops{.cdecl, importc: "SDL_AllocRW", dynlib: LibName.} -proc RWSeek*(context: PRWops, offset: int, whence: int): int -proc RWTell*(context: PRWops): int -proc RWRead*(context: PRWops, theptr: pointer, size: int, n: int): int -proc RWWrite*(context: PRWops, theptr: pointer, size: int, n: int): int -proc RWClose*(context: PRWops): int +proc allocRW*(): PRWops{.cdecl, importc: "SDL_AllocRW", dynlib: LibName.} +proc rwSeek*(context: PRWops, offset: int, whence: int): int +proc rwTell*(context: PRWops): int +proc rwRead*(context: PRWops, theptr: pointer, size: int, n: int): int +proc rwWrite*(context: PRWops, theptr: pointer, size: int, n: int): int +proc rwClose*(context: PRWops): int #------------------------------------------------------------------------------ # time-handling #------------------------------------------------------------------------------ # Get the number of milliseconds since the SDL library initialization. # Note that this value wraps if the program runs for more than ~49 days. -proc GetTicks*(): int32{.cdecl, importc: "SDL_GetTicks", dynlib: LibName.} +proc getTicks*(): int32{.cdecl, importc: "SDL_GetTicks", dynlib: LibName.} # Wait a specified number of milliseconds before returning -proc Delay*(msec: int32){.cdecl, importc: "SDL_Delay", dynlib: LibName.} +proc delay*(msec: int32){.cdecl, importc: "SDL_Delay", dynlib: LibName.} # Add a new timer to the pool of timers already running. # Returns a timer ID, or NULL when an error occurs. -proc AddTimer*(interval: int32, callback: TNewTimerCallback, param: pointer): PTimerID{. +proc addTimer*(interval: int32, callback: TNewTimerCallback, param: pointer): PTimerID{. cdecl, importc: "SDL_AddTimer", dynlib: LibName.} # Remove one of the multiple timers knowing its ID. # Returns a boolean value indicating success. -proc RemoveTimer*(t: PTimerID): TBool{.cdecl, importc: "SDL_RemoveTimer", +proc removeTimer*(t: PTimerID): TBool{.cdecl, importc: "SDL_RemoveTimer", dynlib: LibName.} -proc SetTimer*(interval: int32, callback: TTimerCallback): int{.cdecl, +proc setTimer*(interval: int32, callback: TTimerCallback): int{.cdecl, importc: "SDL_SetTimer", dynlib: LibName.} #------------------------------------------------------------------------------ # audio-routines @@ -1383,13 +1382,13 @@ proc SetTimer*(interval: int32, callback: TTimerCallback): int{.cdecl, # These functions are used internally, and should not be used unless you # have a specific need to specify the audio driver you want to use. # You should normally use SDL_Init() or SDL_InitSubSystem(). -proc AudioInit*(driver_name: cstring): int{.cdecl, importc: "SDL_AudioInit", +proc audioInit*(driverName: cstring): int{.cdecl, importc: "SDL_AudioInit", dynlib: LibName.} -proc AudioQuit*(){.cdecl, importc: "SDL_AudioQuit", dynlib: LibName.} +proc audioQuit*(){.cdecl, importc: "SDL_AudioQuit", dynlib: LibName.} # This function fills the given character buffer with the name of the # current audio driver, and returns a pointer to it if the audio driver has # been initialized. It returns NULL if no driver has been initialized. -proc AudioDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, +proc audioDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, importc: "SDL_AudioDriverName", dynlib: LibName.} # This function opens the audio device with the desired parameters, and # returns 0 if successful, placing the actual hardware parameters in the @@ -1430,17 +1429,17 @@ proc AudioDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, # for your audio callback function to be called. Since the audio driver # may modify the requested size of the audio buffer, you should allocate # any local mixing buffers after you open the audio device. -proc OpenAudio*(desired, obtained: PAudioSpec): int{.cdecl, +proc openAudio*(desired, obtained: PAudioSpec): int{.cdecl, importc: "SDL_OpenAudio", dynlib: LibName.} # Get the current audio state: -proc GetAudioStatus*(): TAudiostatus{.cdecl, importc: "SDL_GetAudioStatus", +proc getAudioStatus*(): TAudiostatus{.cdecl, importc: "SDL_GetAudioStatus", dynlib: LibName.} # This function pauses and unpauses the audio callback processing. # It should be called with a parameter of 0 after opening the audio # device to start playing sound. This is so you can safely initialize # data for your callback function after opening the audio device. # Silence will be written to the audio device during the pause. -proc PauseAudio*(pause_on: int){.cdecl, importc: "SDL_PauseAudio", +proc pauseAudio*(pauseOn: int){.cdecl, importc: "SDL_PauseAudio", dynlib: LibName.} # This function loads a WAVE from the data source, automatically freeing # that source if 'freesrc' is non-zero. For example, to load a WAVE file, @@ -1457,22 +1456,22 @@ proc PauseAudio*(pause_on: int){.cdecl, importc: "SDL_PauseAudio", # This function returns NULL and sets the SDL error message if the # wave file cannot be opened, uses an unknown data format, or is # corrupt. Currently raw and MS-ADPCM WAVE files are supported. -proc LoadWAV_RW*(src: PRWops, freesrc: int, spec: PAudioSpec, audio_buf: ptr byte, +proc loadWAV_RW*(src: PRWops, freesrc: int, spec: PAudioSpec, audioBuf: ptr byte, audiolen: PUInt32): PAudioSpec{.cdecl, importc: "SDL_LoadWAV_RW", dynlib: LibName.} # Compatibility convenience function -- loads a WAV from a file -proc LoadWAV*(filename: cstring, spec: PAudioSpec, audio_buf: ptr byte, +proc loadWAV*(filename: cstring, spec: PAudioSpec, audioBuf: ptr byte, audiolen: PUInt32): PAudioSpec # This function frees data previously allocated with SDL_LoadWAV_RW() -proc FreeWAV*(audio_buf: ptr byte){.cdecl, importc: "SDL_FreeWAV", dynlib: LibName.} +proc freeWAV*(audioBuf: ptr byte){.cdecl, importc: "SDL_FreeWAV", dynlib: LibName.} # This function takes a source format and rate and a destination format # and rate, and initializes the 'cvt' structure with information needed # by SDL_ConvertAudio() to convert a buffer of audio data from one format # to the other. # This function returns 0, or -1 if there was an error. -proc BuildAudioCVT*(cvt: PAudioCVT, src_format: uint16, src_channels: byte, - src_rate: int, dst_format: uint16, dst_channels: byte, - dst_rate: int): int{.cdecl, importc: "SDL_BuildAudioCVT", +proc buildAudioCVT*(cvt: PAudioCVT, srcFormat: uint16, srcChannels: byte, + srcRate: int, dstFormat: uint16, dstChannels: byte, + dstRate: int): int{.cdecl, importc: "SDL_BuildAudioCVT", dynlib: LibName.} # Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT(), # created an audio buffer cvt->buf, and filled it with cvt->len bytes of @@ -1481,45 +1480,45 @@ proc BuildAudioCVT*(cvt: PAudioCVT, src_format: uint16, src_channels: byte, # The data conversion may expand the size of the audio data, so the buffer # cvt->buf should be allocated after the cvt structure is initialized by # SDL_BuildAudioCVT(), and should be cvt->len*cvt->len_mult bytes long. -proc ConvertAudio*(cvt: PAudioCVT): int{.cdecl, importc: "SDL_ConvertAudio", +proc convertAudio*(cvt: PAudioCVT): int{.cdecl, importc: "SDL_ConvertAudio", dynlib: LibName.} # This takes two audio buffers of the playing audio format and mixes # them, performing addition, volume adjustment, and overflow clipping. # The volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME # for full audio volume. Note this does not change hardware volume. # This is provided for convenience -- you can mix your own audio data. -proc MixAudio*(dst, src: ptr byte, length: int32, volume: int){.cdecl, +proc mixAudio*(dst, src: ptr byte, length: int32, volume: int){.cdecl, importc: "SDL_MixAudio", dynlib: LibName.} # The lock manipulated by these functions protects the callback function. # During a LockAudio/UnlockAudio pair, you can be guaranteed that the # callback function is not running. Do not call these from the callback # function or you will cause deadlock. -proc LockAudio*(){.cdecl, importc: "SDL_LockAudio", dynlib: LibName.} -proc UnlockAudio*(){.cdecl, importc: "SDL_UnlockAudio", dynlib: LibName.} +proc lockAudio*(){.cdecl, importc: "SDL_LockAudio", dynlib: LibName.} +proc unlockAudio*(){.cdecl, importc: "SDL_UnlockAudio", dynlib: LibName.} # This function shuts down audio processing and closes the audio device. -proc CloseAudio*(){.cdecl, importc: "SDL_CloseAudio", dynlib: LibName.} +proc closeAudio*(){.cdecl, importc: "SDL_CloseAudio", dynlib: LibName.} #------------------------------------------------------------------------------ # CD-routines #------------------------------------------------------------------------------ # Returns the number of CD-ROM drives on the system, or -1 if # SDL_Init() has not been called with the SDL_INIT_CDROM flag. -proc CDNumDrives*(): int{.cdecl, importc: "SDL_CDNumDrives", dynlib: LibName.} +proc cdNumDrives*(): int{.cdecl, importc: "SDL_CDNumDrives", dynlib: LibName.} # Returns a human-readable, system-dependent identifier for the CD-ROM. # Example: # "/dev/cdrom" # "E:" # "/dev/disk/ide/1/master" -proc CDName*(drive: int): cstring{.cdecl, importc: "SDL_CDName", dynlib: LibName.} +proc cdName*(drive: int): cstring{.cdecl, importc: "SDL_CDName", dynlib: LibName.} # Opens a CD-ROM drive for access. It returns a drive handle on success, # or NULL if the drive was invalid or busy. This newly opened CD-ROM # becomes the default CD used when other CD functions are passed a NULL # CD-ROM handle. # Drives are numbered starting with 0. Drive 0 is the system default CD-ROM. -proc CDOpen*(drive: int): PCD{.cdecl, importc: "SDL_CDOpen", dynlib: LibName.} +proc cdOpen*(drive: int): PCD{.cdecl, importc: "SDL_CDOpen", dynlib: LibName.} # This function returns the current status of the given drive. # If the drive has a CD in it, the table of contents of the CD and current # play position of the CD will be stored in the SDL_CD structure. -proc CDStatus*(cdrom: PCD): TCDStatus{.cdecl, importc: "SDL_CDStatus", +proc cdStatus*(cdrom: PCD): TCDStatus{.cdecl, importc: "SDL_CDStatus", dynlib: LibName.} # Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks' # tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play @@ -1542,95 +1541,89 @@ proc CDStatus*(cdrom: PCD): TCDStatus{.cdecl, importc: "SDL_CDStatus", # SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); # # This function returns 0, or -1 if there was an error. -proc CDPlayTracks*(cdrom: PCD, start_track: int, start_frame: int, ntracks: int, +proc cdPlayTracks*(cdrom: PCD, startTrack: int, startFrame: int, ntracks: int, nframes: int): int{.cdecl, importc: "SDL_CDPlayTracks", dynlib: LibName.} # Play the given CD starting at 'start' frame for 'length' frames. # It returns 0, or -1 if there was an error. -proc CDPlay*(cdrom: PCD, start: int, len: int): int{.cdecl, +proc cdPlay*(cdrom: PCD, start: int, len: int): int{.cdecl, importc: "SDL_CDPlay", dynlib: LibName.} # Pause play -- returns 0, or -1 on error -proc CDPause*(cdrom: PCD): int{.cdecl, importc: "SDL_CDPause", dynlib: LibName.} +proc cdPause*(cdrom: PCD): int{.cdecl, importc: "SDL_CDPause", dynlib: LibName.} # Resume play -- returns 0, or -1 on error -proc CDResume*(cdrom: PCD): int{.cdecl, importc: "SDL_CDResume", dynlib: LibName.} +proc cdResume*(cdrom: PCD): int{.cdecl, importc: "SDL_CDResume", dynlib: LibName.} # Stop play -- returns 0, or -1 on error -proc CDStop*(cdrom: PCD): int{.cdecl, importc: "SDL_CDStop", dynlib: LibName.} +proc cdStop*(cdrom: PCD): int{.cdecl, importc: "SDL_CDStop", dynlib: LibName.} # Eject CD-ROM -- returns 0, or -1 on error -proc CDEject*(cdrom: PCD): int{.cdecl, importc: "SDL_CDEject", dynlib: LibName.} +proc cdEject*(cdrom: PCD): int{.cdecl, importc: "SDL_CDEject", dynlib: LibName.} # Closes the handle for the CD-ROM drive -proc CDClose*(cdrom: PCD){.cdecl, importc: "SDL_CDClose", dynlib: LibName.} +proc cdClose*(cdrom: PCD){.cdecl, importc: "SDL_CDClose", dynlib: LibName.} # Given a status, returns true if there's a disk in the drive -proc CDInDrive*(status: TCDStatus): bool - # Conversion functions from frames to Minute/Second/Frames and vice versa -proc FRAMES_TO_MSF*(frames: int, M: var int, S: var int, F: var int) -proc MSF_TO_FRAMES*(M: int, S: int, F: int): int - #------------------------------------------------------------------------------ - # JoyStick-routines - #------------------------------------------------------------------------------ - # Count the number of joysticks attached to the system -proc NumJoysticks*(): int{.cdecl, importc: "SDL_NumJoysticks", dynlib: LibName.} +proc cdInDrive*(status: TCDStatus): bool + +proc numJoysticks*(): int{.cdecl, importc: "SDL_NumJoysticks", dynlib: LibName.} # Get the implementation dependent name of a joystick. # This can be called before any joysticks are opened. # If no name can be found, this function returns NULL. -proc JoystickName*(index: int): cstring{.cdecl, importc: "SDL_JoystickName", +proc joystickName*(index: int): cstring{.cdecl, importc: "SDL_JoystickName", dynlib: LibName.} # Open a joystick for use - the index passed as an argument refers to # the N'th joystick on the system. This index is the value which will # identify this joystick in future joystick events. # # This function returns a joystick identifier, or NULL if an error occurred. -proc JoystickOpen*(index: int): PJoystick{.cdecl, importc: "SDL_JoystickOpen", +proc joystickOpen*(index: int): PJoystick{.cdecl, importc: "SDL_JoystickOpen", dynlib: LibName.} # Returns 1 if the joystick has been opened, or 0 if it has not. -proc JoystickOpened*(index: int): int{.cdecl, importc: "SDL_JoystickOpened", +proc joystickOpened*(index: int): int{.cdecl, importc: "SDL_JoystickOpened", dynlib: LibName.} # Get the device index of an opened joystick. -proc JoystickIndex*(joystick: PJoystick): int{.cdecl, +proc joystickIndex*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickIndex", dynlib: LibName.} # Get the number of general axis controls on a joystick -proc JoystickNumAxes*(joystick: PJoystick): int{.cdecl, +proc joystickNumAxes*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickNumAxes", dynlib: LibName.} # Get the number of trackballs on a joystick # Joystick trackballs have only relative motion events associated # with them and their state cannot be polled. -proc JoystickNumBalls*(joystick: PJoystick): int{.cdecl, +proc joystickNumBalls*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickNumBalls", dynlib: LibName.} # Get the number of POV hats on a joystick -proc JoystickNumHats*(joystick: PJoystick): int{.cdecl, +proc joystickNumHats*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickNumHats", dynlib: LibName.} # Get the number of buttons on a joystick -proc JoystickNumButtons*(joystick: PJoystick): int{.cdecl, +proc joystickNumButtons*(joystick: PJoystick): int{.cdecl, importc: "SDL_JoystickNumButtons", dynlib: LibName.} # Update the current state of the open joysticks. # This is called automatically by the event loop if any joystick # events are enabled. -proc JoystickUpdate*(){.cdecl, importc: "SDL_JoystickUpdate", dynlib: LibName.} +proc joystickUpdate*(){.cdecl, importc: "SDL_JoystickUpdate", dynlib: LibName.} # Enable/disable joystick event polling. # If joystick events are disabled, you must call SDL_JoystickUpdate() # yourself and check the state of the joystick when you want joystick # information. # The state can be one of SDL_QUERY, SDL_ENABLE or SDL_IGNORE. -proc JoystickEventState*(state: int): int{.cdecl, +proc joystickEventState*(state: int): int{.cdecl, importc: "SDL_JoystickEventState", dynlib: LibName.} # Get the current state of an axis control on a joystick # The state is a value ranging from -32768 to 32767. # The axis indices start at index 0. -proc JoystickGetAxis*(joystick: PJoystick, axis: int): int16{.cdecl, +proc joystickGetAxis*(joystick: PJoystick, axis: int): int16{.cdecl, importc: "SDL_JoystickGetAxis", dynlib: LibName.} # The hat indices start at index 0. -proc JoystickGetHat*(joystick: PJoystick, hat: int): byte{.cdecl, +proc joystickGetHat*(joystick: PJoystick, hat: int): byte{.cdecl, importc: "SDL_JoystickGetHat", dynlib: LibName.} # Get the ball axis change since the last poll # This returns 0, or -1 if you passed it invalid parameters. # The ball indices start at index 0. -proc JoystickGetBall*(joystick: PJoystick, ball: int, dx: var int, dy: var int): int{. +proc joystickGetBall*(joystick: PJoystick, ball: int, dx: var int, dy: var int): int{. cdecl, importc: "SDL_JoystickGetBall", dynlib: LibName.} # Get the current state of a button on a joystick # The button indices start at index 0. -proc JoystickGetButton*(joystick: PJoystick, Button: int): byte{.cdecl, +proc joystickGetButton*(joystick: PJoystick, button: int): byte{.cdecl, importc: "SDL_JoystickGetButton", dynlib: LibName.} # Close a joystick previously opened with SDL_JoystickOpen() -proc JoystickClose*(joystick: PJoystick){.cdecl, importc: "SDL_JoystickClose", +proc joystickClose*(joystick: PJoystick){.cdecl, importc: "SDL_JoystickClose", dynlib: LibName.} #------------------------------------------------------------------------------ # event-handling @@ -1638,7 +1631,7 @@ proc JoystickClose*(joystick: PJoystick){.cdecl, importc: "SDL_JoystickClose", # Pumps the event loop, gathering events from the input devices. # This function updates the event queue and internal input device state. # This should only be run in the thread that sets the video mode. -proc PumpEvents*(){.cdecl, importc: "SDL_PumpEvents", dynlib: LibName.} +proc pumpEvents*(){.cdecl, importc: "SDL_PumpEvents", dynlib: LibName.} # Checks the event queue for messages and optionally returns them. # If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to # the back of the event queue. @@ -1650,20 +1643,20 @@ proc PumpEvents*(){.cdecl, importc: "SDL_PumpEvents", dynlib: LibName.} # removed from the queue. # This function returns the number of events actually stored, or -1 # if there was an error. This function is thread-safe. -proc PeepEvents*(events: PEvent, numevents: int, action: Teventaction, +proc peepEvents*(events: PEvent, numevents: int, action: TEventAction, mask: int32): int{.cdecl, importc: "SDL_PeepEvents", dynlib: LibName.} # Polls for currently pending events, and returns 1 if there are any pending # events, or 0 if there are none available. If 'event' is not NULL, the next # event is removed from the queue and stored in that area. -proc PollEvent*(event: PEvent): int{.cdecl, importc: "SDL_PollEvent", +proc pollEvent*(event: PEvent): int{.cdecl, importc: "SDL_PollEvent", dynlib: LibName.} # Waits indefinitely for the next available event, returning 1, or 0 if there # was an error while waiting for events. If 'event' is not NULL, the next # event is removed from the queue and stored in that area. -proc WaitEvent*(event: PEvent): int{.cdecl, importc: "SDL_WaitEvent", +proc waitEvent*(event: PEvent): int{.cdecl, importc: "SDL_WaitEvent", dynlib: LibName.} -proc PushEvent*(event: PEvent): int{.cdecl, importc: "SDL_PushEvent", +proc pushEvent*(event: PEvent): int{.cdecl, importc: "SDL_PushEvent", dynlib: LibName.} # If the filter returns 1, then the event will be added to the internal queue. # If it returns 0, then the event will be dropped from the queue, but the @@ -1679,11 +1672,11 @@ proc PushEvent*(event: PEvent): int{.cdecl, importc: "SDL_PushEvent", # be closed, otherwise the window will remain open if possible. # If the quit event is generated by an interrupt signal, it will bypass the # internal queue and be delivered to the application at the next event poll. -proc SetEventFilter*(filter: TEventFilter){.cdecl, +proc setEventFilter*(filter: TEventFilter){.cdecl, importc: "SDL_SetEventFilter", dynlib: LibName.} # Return the current event filter - can be used to "chain" filters. # If there is no event filter set, this function returns NULL. -proc GetEventFilter*(): TEventFilter{.cdecl, importc: "SDL_GetEventFilter", +proc getEventFilter*(): TEventFilter{.cdecl, importc: "SDL_GetEventFilter", dynlib: LibName.} # This function allows you to set the state of processing certain events. # If 'state' is set to SDL_IGNORE, that event will be automatically dropped @@ -1691,26 +1684,26 @@ proc GetEventFilter*(): TEventFilter{.cdecl, importc: "SDL_GetEventFilter", # If 'state' is set to SDL_ENABLE, that event will be processed normally. # If 'state' is set to SDL_QUERY, SDL_EventState() will return the # current processing state of the specified event. -proc EventState*(theType: byte, state: int): byte{.cdecl, +proc eventState*(theType: byte, state: int): byte{.cdecl, importc: "SDL_EventState", dynlib: LibName.} #------------------------------------------------------------------------------ # Version Routines #------------------------------------------------------------------------------ # This macro can be used to fill a version structure with the compile-time # version of the SDL library. -proc VERSION*(X: var TVersion) +proc version*(x: var Tversion) # This macro turns the version numbers into a numeric value: # (1,2,3) -> (1203) # This assumes that there will never be more than 100 patchlevels -proc VERSIONNUM*(X, Y, Z: int): int +proc versionnum*(x, y, z: int): int # This is the version number macro for the current SDL version -proc COMPILEDVERSION*(): int +proc compiledversion*(): int # This macro will evaluate to true if compiled with SDL at least X.Y.Z -proc VERSION_ATLEAST*(X: int, Y: int, Z: int): bool +proc versionAtleast*(x, y, z: int): bool # This function gets the version of the dynamically linked SDL library. # it should NOT be used to fill a version structure, instead you should # use the SDL_Version() macro. -proc Linked_Version*(): Pversion{.cdecl, importc: "SDL_Linked_Version", +proc linkedVersion*(): PVersion{.cdecl, importc: "SDL_Linked_Version", dynlib: LibName.} #------------------------------------------------------------------------------ # video @@ -1727,25 +1720,25 @@ proc Linked_Version*(): Pversion{.cdecl, importc: "SDL_Linked_Version", # If you use both sound and video in your application, you need to call # SDL_Init() before opening the sound device, otherwise under Win32 DirectX, # you won't be able to set full-screen display modes. -proc VideoInit*(driver_name: cstring, flags: int32): int{.cdecl, +proc videoInit*(driverName: cstring, flags: int32): int{.cdecl, importc: "SDL_VideoInit", dynlib: LibName.} -proc VideoQuit*(){.cdecl, importc: "SDL_VideoQuit", dynlib: LibName.} +proc videoQuit*(){.cdecl, importc: "SDL_VideoQuit", dynlib: LibName.} # This function fills the given character buffer with the name of the # video driver, and returns a pointer to it if the video driver has # been initialized. It returns NULL if no driver has been initialized. -proc VideoDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, +proc videoDriverName*(namebuf: cstring, maxlen: int): cstring{.cdecl, importc: "SDL_VideoDriverName", dynlib: LibName.} # This function returns a pointer to the current display surface. # If SDL is doing format conversion on the display surface, this # function returns the publicly visible surface, not the real video # surface. -proc GetVideoSurface*(): PSurface{.cdecl, importc: "SDL_GetVideoSurface", +proc getVideoSurface*(): PSurface{.cdecl, importc: "SDL_GetVideoSurface", dynlib: LibName.} # This function returns a read-only pointer to information about the # video hardware. If this is called before SDL_SetVideoMode(), the 'vfmt' # member of the returned structure will contain the pixel format of the # "best" video mode. -proc GetVideoInfo*(): PVideoInfo{.cdecl, importc: "SDL_GetVideoInfo", +proc getVideoInfo*(): PVideoInfo{.cdecl, importc: "SDL_GetVideoInfo", dynlib: LibName.} # Check to see if a particular video mode is supported. # It returns 0 if the requested mode is not supported under any bit depth, @@ -1756,7 +1749,7 @@ proc GetVideoInfo*(): PVideoInfo{.cdecl, importc: "SDL_GetVideoInfo", # # The arguments to SDL_VideoModeOK() are the same ones you would pass to # SDL_SetVideoMode() -proc VideoModeOK*(width, height, bpp: int, flags: int32): int{.cdecl, +proc videoModeOK*(width, height, bpp: int, flags: int32): int{.cdecl, importc: "SDL_VideoModeOK", importc: "SDL_VideoModeOK", dynlib: LibName.} # Return a pointer to an array of available screen dimensions for the # given format and video flags, sorted largest to smallest. Returns @@ -1765,7 +1758,7 @@ proc VideoModeOK*(width, height, bpp: int, flags: int32): int{.cdecl, # # if 'format' is NULL, the mode list will be for the format given # by SDL_GetVideoInfo( ) - > vfmt -proc ListModes*(format: PPixelFormat, flags: int32): PPSDL_Rect{.cdecl, +proc listModes*(format: PPixelFormat, flags: int32): PPSDL_Rect{.cdecl, importc: "SDL_ListModes", dynlib: LibName.} # Set up a video mode with the specified width, height and bits-per-pixel. # @@ -1808,15 +1801,15 @@ proc ListModes*(format: PPixelFormat, flags: int32): PPSDL_Rect{.cdecl, # applications that redraw the entire screen on every update. # # This function returns the video framebuffer surface, or NULL if it fails. -proc SetVideoMode*(width, height, bpp: int, flags: uint32): PSurface{.cdecl, +proc setVideoMode*(width, height, bpp: int, flags: uint32): PSurface{.cdecl, importc: "SDL_SetVideoMode", dynlib: LibName.} # Makes sure the given list of rectangles is updated on the given screen. # If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire # screen. # These functions should not be called while 'screen' is locked. -proc UpdateRects*(screen: PSurface, numrects: int, rects: PRect){.cdecl, +proc updateRects*(screen: PSurface, numrects: int, rects: PRect){.cdecl, importc: "SDL_UpdateRects", dynlib: LibName.} -proc UpdateRect*(screen: PSurface, x, y: int32, w, h: int32){.cdecl, +proc updateRect*(screen: PSurface, x, y: int32, w, h: int32){.cdecl, importc: "SDL_UpdateRect", dynlib: LibName.} # On hardware that supports double-buffering, this function sets up a flip # and returns. The hardware will wait for vertical retrace, and then swap @@ -1826,14 +1819,14 @@ proc UpdateRect*(screen: PSurface, x, y: int32, w, h: int32){.cdecl, # The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode() when # setting the video mode for this function to perform hardware flipping. # This function returns 0 if successful, or -1 if there was an error. -proc Flip*(screen: PSurface): int{.cdecl, importc: "SDL_Flip", dynlib: LibName.} +proc flip*(screen: PSurface): int{.cdecl, importc: "SDL_Flip", dynlib: LibName.} # Set the gamma correction for each of the color channels. # The gamma values range (approximately) between 0.1 and 10.0 # # If this function isn't supported directly by the hardware, it will # be emulated using gamma ramps, if available. If successful, this # function returns 0, otherwise it returns -1. -proc SetGamma*(redgamma: float32, greengamma: float32, bluegamma: float32): int{. +proc setGamma*(redgamma: float32, greengamma: float32, bluegamma: float32): int{. cdecl, importc: "SDL_SetGamma", dynlib: LibName.} # Set the gamma translation table for the red, green, and blue channels # of the video hardware. Each table is an array of 256 16-bit quantities, @@ -1845,7 +1838,7 @@ proc SetGamma*(redgamma: float32, greengamma: float32, bluegamma: float32): int{ # If the call succeeds, it will return 0. If the display driver or # hardware does not support gamma translation, or otherwise fails, # this function will return -1. -proc SetGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): int{. +proc setGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): int{. cdecl, importc: "SDL_SetGammaRamp", dynlib: LibName.} # Retrieve the current values of the gamma translation tables. # @@ -1854,7 +1847,7 @@ proc SetGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): # If the call succeeds, it will return 0. If the display driver or # hardware does not support gamma translation, or otherwise fails, # this function will return -1. -proc GetGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): int{. +proc getGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): int{. cdecl, importc: "SDL_GetGammaRamp", dynlib: LibName.} # Sets a portion of the colormap for the given 8-bit surface. If 'surface' # is not a palettized surface, this function does nothing, returning 0. @@ -1869,7 +1862,7 @@ proc GetGammaRamp*(redtable: PUInt16, greentable: PUInt16, bluetable: PUInt16): # will always return 1, and the palette is guaranteed to be set the way # you desire, even if the window colormap has to be warped or run under # emulation. -proc SetColors*(surface: PSurface, colors: PColor, firstcolor: int, ncolors: int): int{. +proc setColors*(surface: PSurface, colors: PColor, firstcolor: int, ncolors: int): int{. cdecl, importc: "SDL_SetColors", dynlib: LibName.} # Sets a portion of the colormap for a given 8-bit surface. # 'flags' is one or both of: @@ -1885,20 +1878,20 @@ proc SetColors*(surface: PSurface, colors: PColor, firstcolor: int, ncolors: int # # SDL_SetColors() is equivalent to calling this function with # flags = (SDL_LOGPAL or SDL_PHYSPAL). -proc SetPalette*(surface: PSurface, flags: int, colors: PColor, firstcolor: int, +proc setPalette*(surface: PSurface, flags: int, colors: PColor, firstcolor: int, ncolors: int): int{.cdecl, importc: "SDL_SetPalette", dynlib: LibName.} # Maps an RGB triple to an opaque pixel value for a given pixel format -proc MapRGB*(format: PPixelFormat, r: byte, g: byte, b: byte): int32{.cdecl, +proc mapRGB*(format: PPixelFormat, r: byte, g: byte, b: byte): int32{.cdecl, importc: "SDL_MapRGB", dynlib: LibName.} # Maps an RGBA quadruple to a pixel value for a given pixel format -proc MapRGBA*(format: PPixelFormat, r: byte, g: byte, b: byte, a: byte): int32{. +proc mapRGBA*(format: PPixelFormat, r: byte, g: byte, b: byte, a: byte): int32{. cdecl, importc: "SDL_MapRGBA", dynlib: LibName.} # Maps a pixel value into the RGB components for a given pixel format -proc GetRGB*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr byte){. +proc getRGB*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr byte){. cdecl, importc: "SDL_GetRGB", dynlib: LibName.} # Maps a pixel value into the RGBA components for a given pixel format -proc GetRGBA*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr byte, +proc getRGBA*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr byte, a: ptr byte){.cdecl, importc: "SDL_GetRGBA", dynlib: LibName.} # Allocate and free an RGB surface (must be called after SDL_SetVideoMode) # If the depth is 4 or 8 bits, an empty palette is allocated for the surface. @@ -1932,17 +1925,17 @@ proc GetRGBA*(pixel: int32, fmt: PPixelFormat, r: ptr byte, g: ptr byte, b: ptr # will be set in the flags member of the returned surface. If for some # reason the surface could not be placed in video memory, it will not have # the SDL_HWSURFACE flag set, and will be created in system memory instead. -proc AllocSurface*(flags: int32, width, height, depth: int, - RMask, GMask, BMask, AMask: int32): PSurface -proc CreateRGBSurface*(flags: int32, width, height, depth: int, - RMask, GMask, BMask, AMask: int32): PSurface{.cdecl, +proc allocSurface*(flags: int32, width, height, depth: int, + rMask, gMask, bMask, aMask: int32): PSurface +proc createRGBSurface*(flags: int32, width, height, depth: int, + rMask, gMask, bMask, aMask: int32): PSurface{.cdecl, importc: "SDL_CreateRGBSurface", dynlib: LibName.} -proc CreateRGBSurfaceFrom*(pixels: pointer, width, height, depth, pitch: int, - RMask, GMask, BMask, AMask: int32): PSurface{.cdecl, +proc createRGBSurfaceFrom*(pixels: pointer, width, height, depth, pitch: int, + rMask, gMask, bMask, aMask: int32): PSurface{.cdecl, importc: "SDL_CreateRGBSurfaceFrom", dynlib: LibName.} -proc FreeSurface*(surface: PSurface){.cdecl, importc: "SDL_FreeSurface", +proc freeSurface*(surface: PSurface){.cdecl, importc: "SDL_FreeSurface", dynlib: LibName.} -proc MustLock*(surface: PSurface): bool +proc mustLock*(surface: PSurface): bool # SDL_LockSurface() sets up a surface for directly accessing the pixels. # Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write # to and read from 'surface->pixels', using the pixel format stored in @@ -1959,25 +1952,25 @@ proc MustLock*(surface: PSurface): bool # pairs, as critical system locks may be held during this time. # # SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked. -proc LockSurface*(surface: PSurface): int{.cdecl, importc: "SDL_LockSurface", +proc lockSurface*(surface: PSurface): int{.cdecl, importc: "SDL_LockSurface", dynlib: LibName.} -proc UnlockSurface*(surface: PSurface){.cdecl, importc: "SDL_UnlockSurface", +proc unlockSurface*(surface: PSurface){.cdecl, importc: "SDL_UnlockSurface", dynlib: LibName.} # Load a surface from a seekable SDL data source (memory or file.) # If 'freesrc' is non-zero, the source will be closed after being read. # Returns the new surface, or NULL if there was an error. # The new surface should be freed with SDL_FreeSurface(). -proc LoadBMP_RW*(src: PRWops, freesrc: int): PSurface{.cdecl, +proc loadBMP_RW*(src: PRWops, freesrc: int): PSurface{.cdecl, importc: "SDL_LoadBMP_RW", dynlib: LibName.} # Convenience macro -- load a surface from a file -proc LoadBMP*(filename: cstring): PSurface +proc loadBMP*(filename: cstring): PSurface # Save a surface to a seekable SDL data source (memory or file.) # If 'freedst' is non-zero, the source will be closed after being written. # Returns 0 if successful or -1 if there was an error. -proc SaveBMP_RW*(surface: PSurface, dst: PRWops, freedst: int): int{.cdecl, +proc saveBMP_RW*(surface: PSurface, dst: PRWops, freedst: int): int{.cdecl, importc: "SDL_SaveBMP_RW", dynlib: LibName.} # Convenience macro -- save a surface to a file -proc SaveBMP*(surface: PSurface, filename: cstring): int +proc saveBMP*(surface: PSurface, filename: cstring): int # Sets the color key (transparent pixel) in a blittable surface. # If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), # 'key' will be the transparent pixel in the source image of a blit. @@ -1985,7 +1978,7 @@ proc SaveBMP*(surface: PSurface, filename: cstring): int # and removes RLE acceleration if absent. # If 'flag' is 0, this function clears any current color key. # This function returns 0, or -1 if there was an error. -proc SetColorKey*(surface: PSurface, flag, key: int32): int{.cdecl, +proc setColorKey*(surface: PSurface, flag, key: int32): int{.cdecl, importc: "SDL_SetColorKey", dynlib: LibName.} # This function sets the alpha value for the entire surface, as opposed to # using the alpha component of each pixel. This value measures the range @@ -1998,7 +1991,7 @@ proc SetColorKey*(surface: PSurface, flag, key: int32): int{.cdecl, # If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface. # OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the # surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed. -proc SetAlpha*(surface: PSurface, flag: int32, alpha: byte): int{.cdecl, +proc setAlpha*(surface: PSurface, flag: int32, alpha: byte): int{.cdecl, importc: "SDL_SetAlpha", dynlib: LibName.} # Sets the clipping rectangle for the destination surface in a blit. # @@ -2010,12 +2003,12 @@ proc SetAlpha*(surface: PSurface, flag: int32, alpha: byte): int{.cdecl, # # Note that blits are automatically clipped to the edges of the source # and destination surfaces. -proc SetClipRect*(surface: PSurface, rect: PRect){.cdecl, +proc setClipRect*(surface: PSurface, rect: PRect){.cdecl, importc: "SDL_SetClipRect", dynlib: LibName.} # Gets the clipping rectangle for the destination surface in a blit. # 'rect' must be a pointer to a valid rectangle which will be filled # with the correct values. -proc GetClipRect*(surface: PSurface, rect: PRect){.cdecl, +proc getClipRect*(surface: PSurface, rect: PRect){.cdecl, importc: "SDL_GetClipRect", dynlib: LibName.} # Creates a new surface of the specified format, and then copies and maps # the given surface to it so the blit of the converted surface will be as @@ -2027,7 +2020,7 @@ proc GetClipRect*(surface: PSurface, rect: PRect){.cdecl, # surface. # # This function is used internally by SDL_DisplayFormat(). -proc ConvertSurface*(src: PSurface, fmt: PPixelFormat, flags: int32): PSurface{. +proc convertSurface*(src: PSurface, fmt: PPixelFormat, flags: int32): PSurface{. cdecl, importc: "SDL_ConvertSurface", dynlib: LibName.} # # This performs a fast blit from the source surface to the destination @@ -2098,14 +2091,14 @@ proc ConvertSurface*(src: PSurface, fmt: PPixelFormat, flags: int32): PSurface{. # to the video memory again. # You should call SDL_BlitSurface() unless you know exactly how SDL # blitting works internally and how to use the other blit functions. -proc BlitSurface*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int +proc blitSurface*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int # This is the public blit function, SDL_BlitSurface(), and it performs # rectangle validation and clipping before passing it to SDL_LowerBlit() -proc UpperBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{. +proc upperBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{. cdecl, importc: "SDL_UpperBlit", dynlib: LibName.} # This is a semi-private blit function and it performs low-level surface # blitting only. -proc LowerBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{. +proc lowerBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{. cdecl, importc: "SDL_LowerBlit", dynlib: LibName.} # This function performs a fast fill of the given rectangle with 'color' # The given rectangle is clipped to the destination surface clip area @@ -2114,7 +2107,7 @@ proc LowerBlit*(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): i # The color should be a pixel of the format used by the surface, and # can be generated by the SDL_MapRGB() function. # This function returns 0 on success, or -1 on error. -proc FillRect*(dst: PSurface, dstrect: PRect, color: int32): int{.cdecl, +proc fillRect*(dst: PSurface, dstrect: PRect, color: int32): int{.cdecl, importc: "SDL_FillRect", dynlib: LibName.} # This function takes a surface and copies it to a new surface of the # pixel format and colors of the video framebuffer, suitable for fast @@ -2125,7 +2118,7 @@ proc FillRect*(dst: PSurface, dstrect: PRect, color: int32): int{.cdecl, # calling this function. # # If the conversion fails or runs out of memory, it returns NULL -proc DisplayFormat*(surface: PSurface): PSurface{.cdecl, +proc displayFormat*(surface: PSurface): PSurface{.cdecl, importc: "SDL_DisplayFormat", dynlib: LibName.} # This function takes a surface and copies it to a new surface of the # pixel format and colors of the video framebuffer (if possible), @@ -2137,7 +2130,7 @@ proc DisplayFormat*(surface: PSurface): PSurface{.cdecl, # calling this function. # # If the conversion fails or runs out of memory, it returns NULL -proc DisplayFormatAlpha*(surface: PSurface): PSurface{.cdecl, +proc displayFormatAlpha*(surface: PSurface): PSurface{.cdecl, importc: "SDL_DisplayFormatAlpha", dynlib: LibName.} #* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #* YUV video surface overlay functions */ @@ -2146,23 +2139,23 @@ proc DisplayFormatAlpha*(surface: PSurface): PSurface{.cdecl, # Calling the returned surface an overlay is something of a misnomer because # the contents of the display surface underneath the area where the overlay # is shown is undefined - it may be overwritten with the converted YUV data. -proc CreateYUVOverlay*(width: int, height: int, format: int32, +proc createYUVOverlay*(width: int, height: int, format: int32, display: PSurface): POverlay{.cdecl, importc: "SDL_CreateYUVOverlay", dynlib: LibName.} # Lock an overlay for direct access, and unlock it when you are done -proc LockYUVOverlay*(Overlay: POverlay): int{.cdecl, +proc lockYUVOverlay*(overlay: POverlay): int{.cdecl, importc: "SDL_LockYUVOverlay", dynlib: LibName.} -proc UnlockYUVOverlay*(Overlay: POverlay){.cdecl, +proc unlockYUVOverlay*(overlay: POverlay){.cdecl, importc: "SDL_UnlockYUVOverlay", dynlib: LibName.} # Blit a video overlay to the display surface. # The contents of the video surface underneath the blit destination are # not defined. # The width and height of the destination rectangle may be different from # that of the overlay, but currently only 2x scaling is supported. -proc DisplayYUVOverlay*(Overlay: POverlay, dstrect: PRect): int{.cdecl, +proc displayYUVOverlay*(overlay: POverlay, dstrect: PRect): int{.cdecl, importc: "SDL_DisplayYUVOverlay", dynlib: LibName.} # Free a video overlay -proc FreeYUVOverlay*(Overlay: POverlay){.cdecl, importc: "SDL_FreeYUVOverlay", +proc freeYUVOverlay*(overlay: POverlay){.cdecl, importc: "SDL_FreeYUVOverlay", dynlib: LibName.} #------------------------------------------------------------------------------ # OpenGL Routines @@ -2175,13 +2168,13 @@ proc FreeYUVOverlay*(Overlay: POverlay){.cdecl, importc: "SDL_FreeYUVOverlay", # your program from the dynamic library using SDL_GL_GetProcAddress(). # # This is disabled in default builds of SDL. -proc GL_LoadLibrary*(filename: cstring): int{.cdecl, +proc glLoadLibrary*(filename: cstring): int{.cdecl, importc: "SDL_GL_LoadLibrary", dynlib: LibName.} # Get the address of a GL function (for extension functions) -proc GL_GetProcAddress*(procname: cstring): pointer{.cdecl, +proc glGetProcAddress*(procname: cstring): pointer{.cdecl, importc: "SDL_GL_GetProcAddress", dynlib: LibName.} # Set an attribute of the OpenGL subsystem before intialization. -proc GL_SetAttribute*(attr: TGLAttr, value: int): int{.cdecl, +proc glSetAttribute*(attr: TGLAttr, value: int): int{.cdecl, importc: "SDL_GL_SetAttribute", dynlib: LibName.} # Get an attribute of the OpenGL subsystem from the windowing # interface, such as glX. This is of course different from getting @@ -2190,34 +2183,34 @@ proc GL_SetAttribute*(attr: TGLAttr, value: int): int{.cdecl, # # Developers should track the values they pass into SDL_GL_SetAttribute # themselves if they want to retrieve these values. -proc GL_GetAttribute*(attr: TGLAttr, value: var int): int{.cdecl, +proc glGetAttribute*(attr: TGLAttr, value: var int): int{.cdecl, importc: "SDL_GL_GetAttribute", dynlib: LibName.} # Swap the OpenGL buffers, if double-buffering is supported. -proc GL_SwapBuffers*(){.cdecl, importc: "SDL_GL_SwapBuffers", dynlib: LibName.} +proc glSwapBuffers*(){.cdecl, importc: "SDL_GL_SwapBuffers", dynlib: LibName.} # Internal functions that should not be called unless you have read # and understood the source code for these functions. -proc GL_UpdateRects*(numrects: int, rects: PRect){.cdecl, +proc glUpdateRects*(numrects: int, rects: PRect){.cdecl, importc: "SDL_GL_UpdateRects", dynlib: LibName.} -proc GL_Lock*(){.cdecl, importc: "SDL_GL_Lock", dynlib: LibName.} -proc GL_Unlock*(){.cdecl, importc: "SDL_GL_Unlock", dynlib: LibName.} +proc glLock*(){.cdecl, importc: "SDL_GL_Lock", dynlib: LibName.} +proc glUnlock*(){.cdecl, importc: "SDL_GL_Unlock", dynlib: LibName.} #* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #* These functions allow interaction with the window manager, if any. * #* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Sets/Gets the title and icon text of the display window -proc WM_GetCaption*(title: var cstring, icon: var cstring){.cdecl, +proc wmGetCaption*(title: var cstring, icon: var cstring){.cdecl, importc: "SDL_WM_GetCaption", dynlib: LibName.} -proc WM_SetCaption*(title: cstring, icon: cstring){.cdecl, +proc wmSetCaption*(title: cstring, icon: cstring){.cdecl, importc: "SDL_WM_SetCaption", dynlib: LibName.} # Sets the icon for the display window. # This function must be called before the first call to SDL_SetVideoMode(). # It takes an icon surface, and a mask in MSB format. # If 'mask' is NULL, the entire icon surface will be used as the icon. -proc WM_SetIcon*(icon: PSurface, mask: byte){.cdecl, importc: "SDL_WM_SetIcon", +proc wmSetIcon*(icon: PSurface, mask: byte){.cdecl, importc: "SDL_WM_SetIcon", dynlib: LibName.} # This function iconifies the window, and returns 1 if it succeeded. # If the function succeeds, it generates an SDL_APPACTIVE loss event. # This function is a noop and returns 0 in non-windowed environments. -proc WM_IconifyWindow*(): int{.cdecl, importc: "SDL_WM_IconifyWindow", +proc wmIconifyWindow*(): int{.cdecl, importc: "SDL_WM_IconifyWindow", dynlib: LibName.} # Toggle fullscreen mode without changing the contents of the screen. # If the display surface does not require locking before accessing @@ -2232,12 +2225,12 @@ proc WM_IconifyWindow*(): int{.cdecl, importc: "SDL_WM_IconifyWindow", # set, then the display will be windowed by default where supported. # # This is currently only implemented in the X11 video driver. -proc WM_ToggleFullScreen*(surface: PSurface): int{.cdecl, +proc wmToggleFullScreen*(surface: PSurface): int{.cdecl, importc: "SDL_WM_ToggleFullScreen", dynlib: LibName.} # Grabbing means that the mouse is confined to the application window, # and nearly all keyboard input is passed directly to the application, # and not interpreted by a window manager, if any. -proc WM_GrabInput*(mode: TGrabMode): TGrabMode{.cdecl, +proc wmGrabInput*(mode: TGrabMode): TGrabMode{.cdecl, importc: "SDL_WM_GrabInput", dynlib: LibName.} #------------------------------------------------------------------------------ # mouse-routines @@ -2246,16 +2239,16 @@ proc WM_GrabInput*(mode: TGrabMode): TGrabMode{.cdecl, # The current button state is returned as a button bitmask, which can # be tested using the SDL_BUTTON(X) macros, and x and y are set to the # current mouse cursor position. You can pass NULL for either x or y. -proc GetMouseState*(x: var int, y: var int): byte{.cdecl, +proc getMouseState*(x: var int, y: var int): byte{.cdecl, importc: "SDL_GetMouseState", dynlib: LibName.} # Retrieve the current state of the mouse. # The current button state is returned as a button bitmask, which can # be tested using the SDL_BUTTON(X) macros, and x and y are set to the # mouse deltas since the last call to SDL_GetRelativeMouseState(). -proc GetRelativeMouseState*(x: var int, y: var int): byte{.cdecl, +proc getRelativeMouseState*(x: var int, y: var int): byte{.cdecl, importc: "SDL_GetRelativeMouseState", dynlib: LibName.} # Set the position of the mouse cursor (generates a mouse motion event) -proc WarpMouse*(x, y: uint16){.cdecl, importc: "SDL_WarpMouse", dynlib: LibName.} +proc warpMouse*(x, y: uint16){.cdecl, importc: "SDL_WarpMouse", dynlib: LibName.} # Create a cursor using the specified data and mask (in MSB format). # The cursor width must be a multiple of 8 bits. # @@ -2267,26 +2260,26 @@ proc WarpMouse*(x, y: uint16){.cdecl, importc: "SDL_WarpMouse", dynlib: LibName. # 1 0 Inverted color if possible, black if not. # # Cursors created with this function must be freed with SDL_FreeCursor(). -proc CreateCursor*(data, mask: ptr byte, w, h, hot_x, hot_y: int): PCursor{.cdecl, +proc createCursor*(data, mask: ptr byte, w, h, hotX, hotY: int): PCursor{.cdecl, importc: "SDL_CreateCursor", dynlib: LibName.} # Set the currently active cursor to the specified one. # If the cursor is currently visible, the change will be immediately # represented on the display. -proc SetCursor*(cursor: PCursor){.cdecl, importc: "SDL_SetCursor", +proc setCursor*(cursor: PCursor){.cdecl, importc: "SDL_SetCursor", dynlib: LibName.} # Returns the currently active cursor. -proc GetCursor*(): PCursor{.cdecl, importc: "SDL_GetCursor", dynlib: LibName.} +proc getCursor*(): PCursor{.cdecl, importc: "SDL_GetCursor", dynlib: LibName.} # Deallocates a cursor created with SDL_CreateCursor(). -proc FreeCursor*(cursor: PCursor){.cdecl, importc: "SDL_FreeCursor", +proc freeCursor*(cursor: PCursor){.cdecl, importc: "SDL_FreeCursor", dynlib: LibName.} # Toggle whether or not the cursor is shown on the screen. # The cursor start off displayed, but can be turned off. # SDL_ShowCursor() returns 1 if the cursor was being displayed # before the call, or 0 if it was not. You can query the current # state by passing a 'toggle' value of -1. -proc ShowCursor*(toggle: int): int{.cdecl, importc: "SDL_ShowCursor", +proc showCursor*(toggle: int): int{.cdecl, importc: "SDL_ShowCursor", dynlib: LibName.} -proc BUTTON*(Button: int): int +proc button*(b: int): int #------------------------------------------------------------------------------ # Keyboard-routines #------------------------------------------------------------------------------ @@ -2296,12 +2289,12 @@ proc BUTTON*(Button: int): int # If 'enable' is 0, translation is disabled. # If 'enable' is -1, the translation state is not changed. # It returns the previous state of keyboard translation. -proc EnableUNICODE*(enable: int): int{.cdecl, importc: "SDL_EnableUNICODE", +proc enableUNICODE*(enable: int): int{.cdecl, importc: "SDL_EnableUNICODE", dynlib: LibName.} # If 'delay' is set to 0, keyboard repeat is disabled. -proc EnableKeyRepeat*(delay: int, interval: int): int{.cdecl, +proc enableKeyRepeat*(delay: int, interval: int): int{.cdecl, importc: "SDL_EnableKeyRepeat", dynlib: LibName.} -proc GetKeyRepeat*(delay: PInteger, interval: PInteger){.cdecl, +proc getKeyRepeat*(delay: PInteger, interval: PInteger){.cdecl, importc: "SDL_GetKeyRepeat", dynlib: LibName.} # Get a snapshot of the current state of the keyboard. # Returns an array of keystates, indexed by the SDLK_* syms. @@ -2309,16 +2302,16 @@ proc GetKeyRepeat*(delay: PInteger, interval: PInteger){.cdecl, # # byte *keystate = SDL_GetKeyState(NULL); # if ( keystate[SDLK_RETURN] ) ... is pressed -proc GetKeyState*(numkeys: pointer): ptr byte{.cdecl, importc: "SDL_GetKeyState", +proc getKeyState*(numkeys: pointer): ptr byte{.cdecl, importc: "SDL_GetKeyState", dynlib: LibName.} # Get the current key modifier state -proc GetModState*(): TMod{.cdecl, importc: "SDL_GetModState", dynlib: LibName.} +proc getModState*(): TMod{.cdecl, importc: "SDL_GetModState", dynlib: LibName.} # Set the current key modifier state # This does not change the keyboard state, only the key modifier flags. -proc SetModState*(modstate: TMod){.cdecl, importc: "SDL_SetModState", +proc setModState*(modstate: TMod){.cdecl, importc: "SDL_SetModState", dynlib: LibName.} # Get the name of an SDL virtual keysym -proc GetKeyName*(key: TKey): cstring{.cdecl, importc: "SDL_GetKeyName", +proc getKeyName*(key: TKey): cstring{.cdecl, importc: "SDL_GetKeyName", dynlib: LibName.} #------------------------------------------------------------------------------ # Active Routines @@ -2327,96 +2320,96 @@ proc GetKeyName*(key: TKey): cstring{.cdecl, importc: "SDL_GetKeyName", # bitwise combination of SDL_APPMOUSEFOCUS, SDL_APPINPUTFOCUS, and # SDL_APPACTIVE. If SDL_APPACTIVE is set, then the user is able to # see your application, otherwise it has been iconified or disabled. -proc GetAppState*(): byte{.cdecl, importc: "SDL_GetAppState", dynlib: LibName.} +proc getAppState*(): byte{.cdecl, importc: "SDL_GetAppState", dynlib: LibName.} # Mutex functions # Create a mutex, initialized unlocked -proc CreateMutex*(): PMutex{.cdecl, importc: "SDL_CreateMutex", dynlib: LibName.} +proc createMutex*(): PMutex{.cdecl, importc: "SDL_CreateMutex", dynlib: LibName.} # Lock the mutex (Returns 0, or -1 on error) -proc mutexP*(mutex: Pmutex): int{.cdecl, importc: "SDL_mutexP", dynlib: LibName.} -proc LockMutex*(mutex: Pmutex): int +proc mutexP*(mutex: PMutex): int{.cdecl, importc: "SDL_mutexP", dynlib: LibName.} +proc lockMutex*(mutex: PMutex): int # Unlock the mutex (Returns 0, or -1 on error) -proc mutexV*(mutex: Pmutex): int{.cdecl, importc: "SDL_mutexV", dynlib: LibName.} -proc UnlockMutex*(mutex: Pmutex): int +proc mutexV*(mutex: PMutex): int{.cdecl, importc: "SDL_mutexV", dynlib: LibName.} +proc unlockMutex*(mutex: PMutex): int # Destroy a mutex -proc DestroyMutex*(mutex: Pmutex){.cdecl, importc: "SDL_DestroyMutex", +proc destroyMutex*(mutex: PMutex){.cdecl, importc: "SDL_DestroyMutex", dynlib: LibName.} # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Semaphore functions # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Create a semaphore, initialized with value, returns NULL on failure. -proc CreateSemaphore*(initial_value: int32): PSem{.cdecl, +proc createSemaphore*(initialValue: int32): PSem{.cdecl, importc: "SDL_CreateSemaphore", dynlib: LibName.} # Destroy a semaphore -proc DestroySemaphore*(sem: Psem){.cdecl, importc: "SDL_DestroySemaphore", +proc destroySemaphore*(sem: PSem){.cdecl, importc: "SDL_DestroySemaphore", dynlib: LibName.} # This function suspends the calling thread until the semaphore pointed # to by sem has a positive count. It then atomically decreases the semaphore # count. -proc SemWait*(sem: Psem): int{.cdecl, importc: "SDL_SemWait", dynlib: LibName.} +proc semWait*(sem: PSem): int{.cdecl, importc: "SDL_SemWait", dynlib: LibName.} # Non-blocking variant of SDL_SemWait(), returns 0 if the wait succeeds, # SDL_MUTEX_TIMEDOUT if the wait would block, and -1 on error. -proc SemTryWait*(sem: Psem): int{.cdecl, importc: "SDL_SemTryWait", +proc semTryWait*(sem: PSem): int{.cdecl, importc: "SDL_SemTryWait", dynlib: LibName.} # Variant of SDL_SemWait() with a timeout in milliseconds, returns 0 if # the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait does not succeed in # the allotted time, and -1 on error. # On some platforms this function is implemented by looping with a delay # of 1 ms, and so should be avoided if possible. -proc SemWaitTimeout*(sem: Psem, ms: int32): int{.cdecl, +proc semWaitTimeout*(sem: PSem, ms: int32): int{.cdecl, importc: "SDL_SemWaitTimeout", dynlib: LibName.} # Atomically increases the semaphore's count (not blocking), returns 0, # or -1 on error. -proc SemPost*(sem: Psem): int{.cdecl, importc: "SDL_SemPost", dynlib: LibName.} +proc semPost*(sem: PSem): int{.cdecl, importc: "SDL_SemPost", dynlib: LibName.} # Returns the current count of the semaphore -proc SemValue*(sem: Psem): int32{.cdecl, importc: "SDL_SemValue", +proc semValue*(sem: PSem): int32{.cdecl, importc: "SDL_SemValue", dynlib: LibName.} # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Condition variable functions # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Create a condition variable -proc CreateCond*(): PCond{.cdecl, importc: "SDL_CreateCond", dynlib: LibName.} +proc createCond*(): PCond{.cdecl, importc: "SDL_CreateCond", dynlib: LibName.} # Destroy a condition variable -proc DestroyCond*(cond: PCond){.cdecl, importc: "SDL_DestroyCond", +proc destroyCond*(cond: PCond){.cdecl, importc: "SDL_DestroyCond", dynlib: LibName.} # Restart one of the threads that are waiting on the condition variable, # returns 0 or -1 on error. -proc CondSignal*(cond: Pcond): int{.cdecl, importc: "SDL_CondSignal", +proc condSignal*(cond: PCond): int{.cdecl, importc: "SDL_CondSignal", dynlib: LibName.} # Restart all threads that are waiting on the condition variable, # returns 0 or -1 on error. -proc CondBroadcast*(cond: Pcond): int{.cdecl, importc: "SDL_CondBroadcast", +proc condBroadcast*(cond: PCond): int{.cdecl, importc: "SDL_CondBroadcast", dynlib: LibName.} # Wait on the condition variable, unlocking the provided mutex. # The mutex must be locked before entering this function! # Returns 0 when it is signaled, or -1 on error. -proc CondWait*(cond: Pcond, mut: Pmutex): int{.cdecl, importc: "SDL_CondWait", +proc condWait*(cond: PCond, mut: PMutex): int{.cdecl, importc: "SDL_CondWait", dynlib: LibName.} # Waits for at most 'ms' milliseconds, and returns 0 if the condition # variable is signaled, SDL_MUTEX_TIMEDOUT if the condition is not # signaled in the allotted time, and -1 on error. # On some platforms this function is implemented by looping with a delay # of 1 ms, and so should be avoided if possible. -proc CondWaitTimeout*(cond: Pcond, mut: Pmutex, ms: int32): int{.cdecl, +proc condWaitTimeout*(cond: PCond, mut: PMutex, ms: int32): int{.cdecl, importc: "SDL_CondWaitTimeout", dynlib: LibName.} # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Condition variable functions # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * # Create a thread -proc CreateThread*(fn, data: pointer): PThread{.cdecl, +proc createThread*(fn, data: pointer): PThread{.cdecl, importc: "SDL_CreateThread", dynlib: LibName.} # Get the 32-bit thread identifier for the current thread -proc ThreadID*(): int32{.cdecl, importc: "SDL_ThreadID", dynlib: LibName.} +proc threadID*(): int32{.cdecl, importc: "SDL_ThreadID", dynlib: LibName.} # Get the 32-bit thread identifier for the specified thread, # equivalent to SDL_ThreadID() if the specified thread is NULL. -proc GetThreadID*(thread: PThread): int32{.cdecl, importc: "SDL_GetThreadID", +proc getThreadID*(thread: PThread): int32{.cdecl, importc: "SDL_GetThreadID", dynlib: LibName.} # Wait for a thread to finish. # The return code for the thread function is placed in the area # pointed to by 'status', if 'status' is not NULL. -proc WaitThread*(thread: PThread, status: var int){.cdecl, +proc waitThread*(thread: PThread, status: var int){.cdecl, importc: "SDL_WaitThread", dynlib: LibName.} # Forcefully kill a thread without worrying about its state -proc KillThread*(thread: PThread){.cdecl, importc: "SDL_KillThread", +proc killThread*(thread: PThread){.cdecl, importc: "SDL_KillThread", dynlib: LibName.} #------------------------------------------------------------------------------ # Get Environment Routines @@ -2427,7 +2420,7 @@ proc KillThread*(thread: PThread){.cdecl, importc: "SDL_KillThread", # * returns 1 if the function is implemented. If it's not implemented, or # * the version member of the 'info' structure is invalid, it returns 0. # * -proc GetWMInfo*(info: PSysWMinfo): int{.cdecl, importc: "SDL_GetWMInfo", +proc getWMInfo*(info: PSysWMinfo): int{.cdecl, importc: "SDL_GetWMInfo", dynlib: LibName.} #------------------------------------------------------------------------------ #SDL_loadso.h @@ -2435,115 +2428,111 @@ proc GetWMInfo*(info: PSysWMinfo): int{.cdecl, importc: "SDL_GetWMInfo", # * to the object handle (or NULL if there was an error). # * The 'sofile' parameter is a system dependent name of the object file. # * -proc LoadObject*(sofile: cstring): pointer{.cdecl, importc: "SDL_LoadObject", +proc loadObject*(sofile: cstring): pointer{.cdecl, importc: "SDL_LoadObject", dynlib: LibName.} #* Given an object handle, this function looks up the address of the # * named function in the shared object and returns it. This address # * is no longer valid after calling SDL_UnloadObject(). # * -proc LoadFunction*(handle: pointer, name: cstring): pointer{.cdecl, +proc loadFunction*(handle: pointer, name: cstring): pointer{.cdecl, importc: "SDL_LoadFunction", dynlib: LibName.} #* Unload a shared object from memory * -proc UnloadObject*(handle: pointer){.cdecl, importc: "SDL_UnloadObject", +proc unloadObject*(handle: pointer){.cdecl, importc: "SDL_UnloadObject", dynlib: LibName.} #------------------------------------------------------------------------------ -proc Swap32*(D: int32): int32 +proc swap32*(d: int32): int32 # Bitwise Checking functions -proc IsBitOn*(value: int, bit: int8): bool -proc TurnBitOn*(value: int, bit: int8): int -proc TurnBitOff*(value: int, bit: int8): int +proc isBitOn*(value: int, bit: int8): bool +proc turnBitOn*(value: int, bit: int8): int +proc turnBitOff*(value: int, bit: int8): int # implementation -proc TABLESIZE(table: cstring): int = +proc tablesize(table: cstring): int = result = sizeOf(table) div sizeOf(table[0]) -proc OutOfMemory() = - when not (defined(WINDOWS)): Error(ENOMEM) - -proc RWSeek(context: PRWops, offset: int, whence: int): int = +proc rwSeek(context: PRWops, offset: int, whence: int): int = result = context.seek(context, offset, whence) -proc RWTell(context: PRWops): int = +proc rwTell(context: PRWops): int = result = context.seek(context, 0, 1) -proc RWRead(context: PRWops, theptr: pointer, size: int, n: int): int = +proc rwRead(context: PRWops, theptr: pointer, size: int, n: int): int = result = context.read(context, theptr, size, n) -proc RWWrite(context: PRWops, theptr: pointer, size: int, n: int): int = +proc rwWrite(context: PRWops, theptr: pointer, size: int, n: int): int = result = context.write(context, theptr, size, n) -proc RWClose(context: PRWops): int = +proc rwClose(context: PRWops): int = result = context.closeFile(context) -proc LoadWAV(filename: cstring, spec: PAudioSpec, audio_buf: ptr byte, +proc loadWAV(filename: cstring, spec: PAudioSpec, audioBuf: ptr byte, audiolen: PUInt32): PAudioSpec = - result = LoadWAV_RW(RWFromFile(filename, "rb"), 1, spec, audio_buf, audiolen) + result = loadWAV_RW(rWFromFile(filename, "rb"), 1, spec, audioBuf, audiolen) -proc CDInDrive(status: TCDStatus): bool = +proc cdInDrive(status: TCDStatus): bool = result = ord(status) > ord(CD_ERROR) -proc FRAMES_TO_MSF(frames: int, M: var int, S: var int, F: var int) = - var value: int - value = frames - F = value mod CD_FPS +proc framesToMsf*(frames: int; m, s, f: var int) = + var value = frames + f = value mod CD_FPS value = value div CD_FPS - S = value mod 60 + s = value mod 60 value = value div 60 - M = value + m = value -proc MSF_TO_FRAMES(M: int, S: int, F: int): int = - result = M * 60 * CD_FPS + S * CD_FPS + F +proc msfToFrames*(m, s, f: int): int = + result = m * 60 * CD_FPS + s * CD_FPS + f -proc VERSION(X: var TVersion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version(x: var Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc VERSIONNUM(X, Y, Z: int): int = - result = X * 1000 + Y * 100 + Z +proc versionnum(x, y, z: int): int = + result = x * 1000 + y * 100 + z -proc COMPILEDVERSION(): int = - result = VERSIONNUM(MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL) +proc compiledversion(): int = + result = versionnum(MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL) -proc VERSION_ATLEAST(X, Y, Z: int): bool = - result = (COMPILEDVERSION() >= VERSIONNUM(X, Y, Z)) +proc versionAtleast(x, y, z: int): bool = + result = (compiledversion() >= versionnum(x, y, z)) -proc LoadBMP(filename: cstring): PSurface = - result = LoadBMP_RW(RWFromFile(filename, "rb"), 1) +proc loadBMP(filename: cstring): PSurface = + result = loadBMP_RW(rWFromFile(filename, "rb"), 1) -proc SaveBMP(surface: PSurface, filename: cstring): int = - result = SaveBMP_RW(surface, RWFromFile(filename, "wb"), 1) +proc saveBMP(surface: PSurface, filename: cstring): int = + result = saveBMP_RW(surface, rWFromFile(filename, "wb"), 1) -proc BlitSurface(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int = - result = UpperBlit(src, srcrect, dst, dstrect) +proc blitSurface(src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int = + result = upperBlit(src, srcrect, dst, dstrect) -proc AllocSurface(flags: int32, width, height, depth: int, - RMask, GMask, BMask, AMask: int32): PSurface = - result = CreateRGBSurface(flags, width, height, depth, RMask, GMask, BMask, - AMask) +proc allocSurface(flags: int32, width, height, depth: int, + rMask, gMask, bMask, aMask: int32): PSurface = + result = createRGBSurface(flags, width, height, depth, rMask, gMask, bMask, + aMask) -proc MustLock(surface: PSurface): bool = +proc mustLock(surface: PSurface): bool = result = ((surface.offset != 0) or ((surface.flags and (HWSURFACE or ASYNCBLIT or RLEACCEL)) != 0)) -proc LockMutex(mutex: Pmutex): int = +proc lockMutex(mutex: PMutex): int = result = mutexP(mutex) -proc UnlockMutex(mutex: Pmutex): int = +proc unlockMutex(mutex: PMutex): int = result = mutexV(mutex) -proc BUTTON(Button: int): int = - result = PRESSED shl (Button - 1) +proc button(b: int): int = + result = PRESSED shl (b - 1) -proc Swap32(D: int32): int32 = - result = ((D shl 24) or ((D shl 8) and 0x00FF0000) or - ((D shr 8) and 0x0000FF00) or (D shr 24)) +proc swap32(d: int32): int32 = + result = ((d shl 24) or ((d shl 8) and 0x00FF0000) or + ((d shr 8) and 0x0000FF00) or (d shr 24)) -proc IsBitOn(value: int, bit: int8): bool = +proc isBitOn(value: int, bit: int8): bool = result = ((value and (1 shl ze(bit))) != 0) -proc TurnBitOn(value: int, bit: int8): int = +proc turnBitOn(value: int, bit: int8): int = result = (value or (1 shl ze(bit))) -proc TurnBitOff(value: int, bit: int8): int = +proc turnBitOff(value: int, bit: int8): int = result = (value and not (1 shl ze(bit))) diff --git a/lib/wrappers/sdl/sdl_gfx.nim b/lib/wrappers/sdl/sdl_gfx.nim index cf36c4989..5523ad0a2 100644 --- a/lib/wrappers/sdl/sdl_gfx.nim +++ b/lib/wrappers/sdl/sdl_gfx.nim @@ -39,10 +39,10 @@ const # Some rates in Hz type PFPSmanager* = ptr TFPSmanager TFPSmanager*{.final.} = object # ---- Structures - framecount*: Uint32 + framecount*: uint32 rateticks*: float32 - lastticks*: Uint32 - rate*: Uint32 + lastticks*: uint32 + rate*: uint32 PColorRGBA* = ptr TColorRGBA TColorRGBA*{.final.} = object @@ -79,102 +79,102 @@ proc framerateDelay*(manager: PFPSmanager){.cdecl, # # Note: all ___Color routines expect the color to be in format 0xRRGGBBAA # Pixel -proc pixelColor*(dst: PSurface, x: int16, y: int16, color: Uint32): cint{. +proc pixelColor*(dst: PSurface, x: int16, y: int16, color: uint32): cint{. cdecl, importc: "pixelColor", dynlib: gfxLibName.} proc pixelRGBA*(dst: PSurface, x: int16, y: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "pixelRGBA", dynlib: gfxLibName.} # Horizontal line -proc hlineColor*(dst: PSurface, x1: int16, x2: int16, y: int16, color: Uint32): cint{. +proc hlineColor*(dst: PSurface, x1: int16, x2: int16, y: int16, color: uint32): cint{. cdecl, importc: "hlineColor", dynlib: gfxLibName.} proc hlineRGBA*(dst: PSurface, x1: int16, x2: int16, y: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "hlineRGBA", dynlib: gfxLibName.} # Vertical line -proc vlineColor*(dst: PSurface, x: int16, y1: int16, y2: int16, color: Uint32): cint{. +proc vlineColor*(dst: PSurface, x: int16, y1: int16, y2: int16, color: uint32): cint{. cdecl, importc: "vlineColor", dynlib: gfxLibName.} proc vlineRGBA*(dst: PSurface, x: int16, y1: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "vlineRGBA", dynlib: gfxLibName.} # Rectangle proc rectangleColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, - y2: int16, color: Uint32): cint{.cdecl, + y2: int16, color: uint32): cint{.cdecl, importc: "rectangleColor", dynlib: gfxLibName.} proc rectangleRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{. cdecl, importc: "rectangleRGBA", dynlib: gfxLibName.} # Filled rectangle (Box) proc boxColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, - color: Uint32): cint{.cdecl, importc: "boxColor", + color: uint32): cint{.cdecl, importc: "boxColor", dynlib: gfxLibName.} proc boxRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "boxRGBA", dynlib: gfxLibName.} # Line proc lineColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, - color: Uint32): cint{.cdecl, importc: "lineColor", + color: uint32): cint{.cdecl, importc: "lineColor", dynlib: gfxLibName.} proc lineRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "lineRGBA", dynlib: gfxLibName.} # AA Line proc aalineColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, - color: Uint32): cint{.cdecl, importc: "aalineColor", + color: uint32): cint{.cdecl, importc: "aalineColor", dynlib: gfxLibName.} proc aalineRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "aalineRGBA", dynlib: gfxLibName.} # Circle -proc circleColor*(dst: PSurface, x: int16, y: int16, r: int16, color: Uint32): cint{. +proc circleColor*(dst: PSurface, x: int16, y: int16, r: int16, color: uint32): cint{. cdecl, importc: "circleColor", dynlib: gfxLibName.} proc circleRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "circleRGBA", dynlib: gfxLibName.} # AA Circle proc aacircleColor*(dst: PSurface, x: int16, y: int16, r: int16, - color: Uint32): cint{.cdecl, importc: "aacircleColor", + color: uint32): cint{.cdecl, importc: "aacircleColor", dynlib: gfxLibName.} proc aacircleRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "aacircleRGBA", dynlib: gfxLibName.} # Filled Circle proc filledCircleColor*(dst: PSurface, x: int16, y: int16, r: int16, - color: Uint32): cint{.cdecl, + color: uint32): cint{.cdecl, importc: "filledCircleColor", dynlib: gfxLibName.} proc filledCircleRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "filledCircleRGBA", dynlib: gfxLibName.} # Ellipse proc ellipseColor*(dst: PSurface, x: int16, y: int16, rx: int16, ry: int16, - color: Uint32): cint{.cdecl, importc: "ellipseColor", + color: uint32): cint{.cdecl, importc: "ellipseColor", dynlib: gfxLibName.} proc ellipseRGBA*(dst: PSurface, x: int16, y: int16, rx: int16, ry: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "ellipseRGBA", dynlib: gfxLibName.} # AA Ellipse proc aaellipseColor*(dst: PSurface, xc: int16, yc: int16, rx: int16, - ry: int16, color: Uint32): cint{.cdecl, + ry: int16, color: uint32): cint{.cdecl, importc: "aaellipseColor", dynlib: gfxLibName.} proc aaellipseRGBA*(dst: PSurface, x: int16, y: int16, rx: int16, ry: int16, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "aaellipseRGBA", dynlib: gfxLibName.} # Filled Ellipse proc filledEllipseColor*(dst: PSurface, x: int16, y: int16, rx: int16, - ry: int16, color: Uint32): cint{.cdecl, + ry: int16, color: uint32): cint{.cdecl, importc: "filledEllipseColor", dynlib: gfxLibName.} proc filledEllipseRGBA*(dst: PSurface, x: int16, y: int16, rx: int16, ry: int16, r: byte, g: byte, b: byte, a: byte): cint{. cdecl, importc: "filledEllipseRGBA", dynlib: gfxLibName.} # Pie proc pieColor*(dst: PSurface, x: int16, y: int16, rad: int16, start: int16, - finish: int16, color: Uint32): cint{.cdecl, importc: "pieColor", + finish: int16, color: uint32): cint{.cdecl, importc: "pieColor", dynlib: gfxLibName.} proc pieRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, start: int16, finish: int16, r: byte, g: byte, b: byte, a: byte): cint{. cdecl, importc: "pieRGBA", dynlib: gfxLibName.} # Filled Pie proc filledPieColor*(dst: PSurface, x: int16, y: int16, rad: int16, - start: int16, finish: int16, color: Uint32): cint{.cdecl, + start: int16, finish: int16, color: uint32): cint{.cdecl, importc: "filledPieColor", dynlib: gfxLibName.} proc filledPieRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, start: int16, finish: int16, r: byte, g: byte, b: byte, @@ -182,14 +182,14 @@ proc filledPieRGBA*(dst: PSurface, x: int16, y: int16, rad: int16, dynlib: gfxLibName.} # Trigon proc trigonColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, - x3: int16, y3: int16, color: Uint32): cint{.cdecl, + x3: int16, y3: int16, color: uint32): cint{.cdecl, importc: "trigonColor", dynlib: gfxLibName.} proc trigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, x3: int16, y3: int16, r: byte, g: byte, b: byte, a: byte): cint{. cdecl, importc: "trigonRGBA", dynlib: gfxLibName.} # AA-Trigon proc aatrigonColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, - y2: int16, x3: int16, y3: int16, color: Uint32): cint{. + y2: int16, x3: int16, y3: int16, color: uint32): cint{. cdecl, importc: "aatrigonColor", dynlib: gfxLibName.} proc aatrigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, x3: int16, y3: int16, r: byte, g: byte, @@ -197,7 +197,7 @@ proc aatrigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, dynlib: gfxLibName.} # Filled Trigon proc filledTrigonColor*(dst: PSurface, x1: int16, y1: int16, x2: int16, - y2: int16, x3: int16, y3: int16, color: Uint32): cint{. + y2: int16, x3: int16, y3: int16, color: uint32): cint{. cdecl, importc: "filledTrigonColor", dynlib: gfxLibName.} proc filledTrigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, y2: int16, x3: int16, y3: int16, r: byte, g: byte, @@ -205,21 +205,21 @@ proc filledTrigonRGBA*(dst: PSurface, x1: int16, y1: int16, x2: int16, importc: "filledTrigonRGBA", dynlib: gfxLibName.} # Polygon proc polygonColor*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, - color: Uint32): cint{.cdecl, importc: "polygonColor", + color: uint32): cint{.cdecl, importc: "polygonColor", dynlib: gfxLibName.} proc polygonRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "polygonRGBA", dynlib: gfxLibName.} # AA-Polygon proc aapolygonColor*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, - color: Uint32): cint{.cdecl, importc: "aapolygonColor", + color: uint32): cint{.cdecl, importc: "aapolygonColor", dynlib: gfxLibName.} proc aapolygonRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "aapolygonRGBA", dynlib: gfxLibName.} # Filled Polygon proc filledPolygonColor*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, - color: Uint32): cint{.cdecl, + color: uint32): cint{.cdecl, importc: "filledPolygonColor", dynlib: gfxLibName.} proc filledPolygonRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, @@ -227,23 +227,23 @@ proc filledPolygonRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, # Bezier # s = number of steps proc bezierColor*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, s: cint, - color: Uint32): cint{.cdecl, importc: "bezierColor", + color: uint32): cint{.cdecl, importc: "bezierColor", dynlib: gfxLibName.} proc bezierRGBA*(dst: PSurface, vx: ptr int16, vy: ptr int16, n: cint, s: cint, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "bezierRGBA", dynlib: gfxLibName.} # Characters/Strings -proc characterColor*(dst: PSurface, x: int16, y: int16, c: char, color: Uint32): cint{. +proc characterColor*(dst: PSurface, x: int16, y: int16, c: char, color: uint32): cint{. cdecl, importc: "characterColor", dynlib: gfxLibName.} proc characterRGBA*(dst: PSurface, x: int16, y: int16, c: char, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "characterRGBA", dynlib: gfxLibName.} -proc stringColor*(dst: PSurface, x: int16, y: int16, c: cstring, color: Uint32): cint{. +proc stringColor*(dst: PSurface, x: int16, y: int16, c: cstring, color: uint32): cint{. cdecl, importc: "stringColor", dynlib: gfxLibName.} proc stringRGBA*(dst: PSurface, x: int16, y: int16, c: cstring, r: byte, g: byte, b: byte, a: byte): cint{.cdecl, importc: "stringRGBA", dynlib: gfxLibName.} -proc gfxPrimitivesSetFont*(fontdata: Pointer, cw: cint, ch: cint){.cdecl, +proc gfxPrimitivesSetFont*(fontdata: pointer, cw: cint, ch: cint){.cdecl, importc: "gfxPrimitivesSetFont", dynlib: gfxLibName.} # # @@ -271,132 +271,132 @@ proc imageFilterMMXon*(){.cdecl, importc: "SDL_imageFilterMMXon", # -1 Error (internal error, parameter error) # # SDL_imageFilterAdd: D = saturation255(S1 + S2) -proc imageFilterAdd*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterAdd*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterAdd", dynlib: gfxLibName.} # SDL_imageFilterMean: D = S1/2 + S2/2 -proc imageFilterMean*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterMean*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterMean", dynlib: gfxLibName.} # SDL_imageFilterSub: D = saturation0(S1 - S2) -proc imageFilterSub*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterSub*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterSub", dynlib: gfxLibName.} # SDL_imageFilterAbsDiff: D = | S1 - S2 | -proc imageFilterAbsDiff*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterAbsDiff*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterAbsDiff", dynlib: gfxLibName.} # SDL_imageFilterMult: D = saturation(S1 * S2) -proc imageFilterMult*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterMult*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterMult", dynlib: gfxLibName.} # SDL_imageFilterMultNor: D = S1 * S2 (non-MMX) -proc imageFilterMultNor*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterMultNor*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterMultNor", dynlib: gfxLibName.} # SDL_imageFilterMultDivby2: D = saturation255(S1/2 * S2) -proc imageFilterMultDivby2*(Src1: cstring, Src2: cstring, Dest: cstring, +proc imageFilterMultDivby2*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{.cdecl, importc: "SDL_imageFilterMultDivby2", dynlib: gfxLibName.} # SDL_imageFilterMultDivby4: D = saturation255(S1/2 * S2/2) -proc imageFilterMultDivby4*(Src1: cstring, Src2: cstring, Dest: cstring, +proc imageFilterMultDivby4*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{.cdecl, importc: "SDL_imageFilterMultDivby4", dynlib: gfxLibName.} # SDL_imageFilterBitAnd: D = S1 & S2 -proc imageFilterBitAnd*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterBitAnd*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterBitAnd", dynlib: gfxLibName.} # SDL_imageFilterBitOr: D = S1 | S2 -proc imageFilterBitOr*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterBitOr*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterBitOr", dynlib: gfxLibName.} # SDL_imageFilterDiv: D = S1 / S2 (non-MMX) -proc imageFilterDiv*(Src1: cstring, Src2: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterDiv*(src1: cstring, src2: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterDiv", dynlib: gfxLibName.} # SDL_imageFilterBitNegation: D = !S -proc imageFilterBitNegation*(Src1: cstring, Dest: cstring, len: cint): cint{. +proc imageFilterBitNegation*(src1: cstring, dest: cstring, len: cint): cint{. cdecl, importc: "SDL_imageFilterBitNegation", dynlib: gfxLibName.} # SDL_imageFilterAddByte: D = saturation255(S + C) -proc imageFilterAddByte*(Src1: cstring, Dest: cstring, len: cint, C: char): cint{. +proc imageFilterAddByte*(src1: cstring, dest: cstring, len: cint, c: char): cint{. cdecl, importc: "SDL_imageFilterAddByte", dynlib: gfxLibName.} # SDL_imageFilterAddUint: D = saturation255(S + (uint)C) -proc imageFilterAddUint*(Src1: cstring, Dest: cstring, len: cint, C: cint): cint{. +proc imageFilterAddUint*(src1: cstring, dest: cstring, len: cint, c: cint): cint{. cdecl, importc: "SDL_imageFilterAddUint", dynlib: gfxLibName.} # SDL_imageFilterAddByteToHalf: D = saturation255(S/2 + C) -proc imageFilterAddByteToHalf*(Src1: cstring, Dest: cstring, len: cint, C: char): cint{. +proc imageFilterAddByteToHalf*(src1: cstring, dest: cstring, len: cint, c: char): cint{. cdecl, importc: "SDL_imageFilterAddByteToHalf", dynlib: gfxLibName.} # SDL_imageFilterSubByte: D = saturation0(S - C) -proc imageFilterSubByte*(Src1: cstring, Dest: cstring, len: cint, C: char): cint{. +proc imageFilterSubByte*(src1: cstring, dest: cstring, len: cint, c: char): cint{. cdecl, importc: "SDL_imageFilterSubByte", dynlib: gfxLibName.} # SDL_imageFilterSubUint: D = saturation0(S - (uint)C) -proc imageFilterSubUint*(Src1: cstring, Dest: cstring, len: cint, C: cint): cint{. +proc imageFilterSubUint*(src1: cstring, dest: cstring, len: cint, c: cint): cint{. cdecl, importc: "SDL_imageFilterSubUint", dynlib: gfxLibName.} # SDL_imageFilterShiftRight: D = saturation0(S >> N) -proc imageFilterShiftRight*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftRight*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftRight", dynlib: gfxLibName.} # SDL_imageFilterShiftRightUint: D = saturation0((uint)S >> N) -proc imageFilterShiftRightUint*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftRightUint*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftRightUint", dynlib: gfxLibName.} # SDL_imageFilterMultByByte: D = saturation255(S * C) -proc imageFilterMultByByte*(Src1: cstring, Dest: cstring, len: cint, C: char): cint{. +proc imageFilterMultByByte*(src1: cstring, dest: cstring, len: cint, c: char): cint{. cdecl, importc: "SDL_imageFilterMultByByte", dynlib: gfxLibName.} # SDL_imageFilterShiftRightAndMultByByte: D = saturation255((S >> N) * C) -proc imageFilterShiftRightAndMultByByte*(Src1: cstring, Dest: cstring, len: cint, - N: char, C: char): cint{.cdecl, +proc imageFilterShiftRightAndMultByByte*(src1: cstring, dest: cstring, len: cint, + n: char, c: char): cint{.cdecl, importc: "SDL_imageFilterShiftRightAndMultByByte", dynlib: gfxLibName.} # SDL_imageFilterShiftLeftByte: D = (S << N) -proc imageFilterShiftLeftByte*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftLeftByte*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftLeftByte", dynlib: gfxLibName.} # SDL_imageFilterShiftLeftUint: D = ((uint)S << N) -proc imageFilterShiftLeftUint*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftLeftUint*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftLeftUint", dynlib: gfxLibName.} # SDL_imageFilterShiftLeft: D = saturation255(S << N) -proc imageFilterShiftLeft*(Src1: cstring, Dest: cstring, len: cint, N: char): cint{. +proc imageFilterShiftLeft*(src1: cstring, dest: cstring, len: cint, n: char): cint{. cdecl, importc: "SDL_imageFilterShiftLeft", dynlib: gfxLibName.} # SDL_imageFilterBinarizeUsingThreshold: D = S >= T ? 255:0 -proc imageFilterBinarizeUsingThreshold*(Src1: cstring, Dest: cstring, len: cint, - T: char): cint{.cdecl, +proc imageFilterBinarizeUsingThreshold*(src1: cstring, dest: cstring, len: cint, + t: char): cint{.cdecl, importc: "SDL_imageFilterBinarizeUsingThreshold", dynlib: gfxLibName.} # SDL_imageFilterClipToRange: D = (S >= Tmin) & (S <= Tmax) 255:0 -proc imageFilterClipToRange*(Src1: cstring, Dest: cstring, len: cint, Tmin: int8, - Tmax: int8): cint{.cdecl, +proc imageFilterClipToRange*(src1: cstring, dest: cstring, len: cint, tmin: int8, + tmax: int8): cint{.cdecl, importc: "SDL_imageFilterClipToRange", dynlib: gfxLibName.} # SDL_imageFilterNormalizeLinear: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin) -proc imageFilterNormalizeLinear*(Src1: cstring, Dest: cstring, len: cint, - Cmin: cint, Cmax: cint, Nmin: cint, Nmax: cint): cint{. +proc imageFilterNormalizeLinear*(src1: cstring, dest: cstring, len: cint, + cmin: cint, cmax: cint, nmin: cint, nmax: cint): cint{. cdecl, importc: "SDL_imageFilterNormalizeLinear", dynlib: gfxLibName.} # !!! NO C-ROUTINE FOR THESE FUNCTIONS YET !!! # SDL_imageFilterConvolveKernel3x3Divide: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel3x3Divide*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, Kernel: pointer, Divisor: int8): cint{.cdecl, +proc imageFilterConvolveKernel3x3Divide*(src: cstring, dest: cstring, rows: cint, + columns: cint, kernel: pointer, divisor: int8): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel3x3Divide", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel5x5Divide: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel5x5Divide*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, Kernel: pointer, Divisor: int8): cint{.cdecl, +proc imageFilterConvolveKernel5x5Divide*(src: cstring, dest: cstring, rows: cint, + columns: cint, kernel: pointer, divisor: int8): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel5x5Divide", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel7x7Divide: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel7x7Divide*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, Kernel: pointer, Divisor: int8): cint{.cdecl, +proc imageFilterConvolveKernel7x7Divide*(src: cstring, dest: cstring, rows: cint, + columns: cint, kernel: pointer, divisor: int8): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel7x7Divide", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel9x9Divide: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel9x9Divide*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, Kernel: pointer, Divisor: int8): cint{.cdecl, +proc imageFilterConvolveKernel9x9Divide*(src: cstring, dest: cstring, rows: cint, + columns: cint, kernel: pointer, divisor: int8): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel9x9Divide", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel3x3ShiftRight: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel3x3ShiftRight*(Src: cstring, Dest: cstring, - rows: cint, columns: cint, Kernel: pointer, NRightShift: char): cint{.cdecl, +proc imageFilterConvolveKernel3x3ShiftRight*(src: cstring, dest: cstring, + rows: cint, columns: cint, kernel: pointer, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel3x3ShiftRight", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel5x5ShiftRight: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel5x5ShiftRight*(Src: cstring, Dest: cstring, - rows: cint, columns: cint, Kernel: pointer, NRightShift: char): cint{.cdecl, +proc imageFilterConvolveKernel5x5ShiftRight*(src: cstring, dest: cstring, + rows: cint, columns: cint, kernel: pointer, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel5x5ShiftRight", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel7x7ShiftRight: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel7x7ShiftRight*(Src: cstring, Dest: cstring, - rows: cint, columns: cint, Kernel: pointer, NRightShift: char): cint{.cdecl, +proc imageFilterConvolveKernel7x7ShiftRight*(src: cstring, dest: cstring, + rows: cint, columns: cint, kernel: pointer, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel7x7ShiftRight", dynlib: gfxLibName.} # SDL_imageFilterConvolveKernel9x9ShiftRight: Dij = saturation0and255( ... ) -proc imageFilterConvolveKernel9x9ShiftRight*(Src: cstring, Dest: cstring, - rows: cint, columns: cint, Kernel: pointer, NRightShift: char): cint{.cdecl, +proc imageFilterConvolveKernel9x9ShiftRight*(src: cstring, dest: cstring, + rows: cint, columns: cint, kernel: pointer, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterConvolveKernel9x9ShiftRight", dynlib: gfxLibName.} # SDL_imageFilterSobelX: Dij = saturation255( ... ) -proc imageFilterSobelX*(Src: cstring, Dest: cstring, rows: cint, columns: cint): cint{. +proc imageFilterSobelX*(src: cstring, dest: cstring, rows: cint, columns: cint): cint{. cdecl, importc: "SDL_imageFilterSobelX", dynlib: gfxLibName.} # SDL_imageFilterSobelXShiftRight: Dij = saturation255( ... ) -proc imageFilterSobelXShiftRight*(Src: cstring, Dest: cstring, rows: cint, - columns: cint, NRightShift: char): cint{.cdecl, +proc imageFilterSobelXShiftRight*(src: cstring, dest: cstring, rows: cint, + columns: cint, nRightShift: char): cint{.cdecl, importc: "SDL_imageFilterSobelXShiftRight", dynlib: gfxLibName.} # Align/restore stack to 32 byte boundary -- Functionality untested! -- proc imageFilterAlignStack*(){.cdecl, importc: "SDL_imageFilterAlignStack", diff --git a/lib/wrappers/sdl/sdl_image.nim b/lib/wrappers/sdl/sdl_image.nim index 2bd731506..9c56e6a46 100644 --- a/lib/wrappers/sdl/sdl_image.nim +++ b/lib/wrappers/sdl/sdl_image.nim @@ -148,13 +148,13 @@ const # This macro can be used to fill a version structure with the compile-time # version of the SDL_image library. -proc IMAGE_VERSION*(X: var TVersion) +proc imageVersion*(x: var Tversion) # This function gets the version of the dynamically linked SDL_image library. # it should NOT be used to fill a version structure, instead you should # use the SDL_IMAGE_VERSION() macro. # -proc IMG_Linked_Version*(): Pversion{.importc: "IMG_Linked_Version", - dynlib: ImageLibName.} +proc imgLinkedVersion*(): Pversion{.importc: "IMG_Linked_Version", + dynlib: ImageLibName.} # Load an image from an SDL data source. # The 'type' may be one of: "BMP", "GIF", "PNG", etc. # @@ -170,74 +170,74 @@ const IMG_INIT_TIF* = 0x00000004 IMG_INIT_WEBP* = 0x00000008 -proc IMG_Init*(flags: cint): int {.cdecl, importc: "IMG_Init", +proc imgInit*(flags: cint): int {.cdecl, importc: "IMG_Init", dynlib: ImageLibName.} -proc IMG_Quit*() {.cdecl, importc: "IMG_Quit", +proc imgQuit*() {.cdecl, importc: "IMG_Quit", dynlib: ImageLibName.} -proc IMG_LoadTyped_RW*(src: PRWops, freesrc: cint, theType: cstring): PSurface{. +proc imgLoadTypedRW*(src: PRWops, freesrc: cint, theType: cstring): PSurface{. cdecl, importc: "IMG_LoadTyped_RW", dynlib: ImageLibName.} # Convenience functions -proc IMG_Load*(theFile: cstring): PSurface{.cdecl, importc: "IMG_Load", +proc imgLoad*(theFile: cstring): PSurface{.cdecl, importc: "IMG_Load", dynlib: ImageLibName.} -proc IMG_Load_RW*(src: PRWops, freesrc: cint): PSurface{.cdecl, +proc imgLoadRW*(src: PRWops, freesrc: cint): PSurface{.cdecl, importc: "IMG_Load_RW", dynlib: ImageLibName.} # Invert the alpha of a surface for use with OpenGL # This function is now a no-op, and only provided for backwards compatibility. -proc IMG_InvertAlpha*(theOn: cint): cint{.cdecl, importc: "IMG_InvertAlpha", +proc imgInvertAlpha*(theOn: cint): cint{.cdecl, importc: "IMG_InvertAlpha", dynlib: ImageLibName.} # Functions to detect a file type, given a seekable source -proc IMG_isBMP*(src: PRWops): cint{.cdecl, importc: "IMG_isBMP", +proc imgIsBMP*(src: PRWops): cint{.cdecl, importc: "IMG_isBMP", dynlib: ImageLibName.} -proc IMG_isGIF*(src: PRWops): cint{.cdecl, importc: "IMG_isGIF", +proc imgIsGIF*(src: PRWops): cint{.cdecl, importc: "IMG_isGIF", dynlib: ImageLibName.} -proc IMG_isJPG*(src: PRWops): cint{.cdecl, importc: "IMG_isJPG", +proc imgIsJPG*(src: PRWops): cint{.cdecl, importc: "IMG_isJPG", dynlib: ImageLibName.} -proc IMG_isLBM*(src: PRWops): cint{.cdecl, importc: "IMG_isLBM", +proc imgIsLBM*(src: PRWops): cint{.cdecl, importc: "IMG_isLBM", dynlib: ImageLibName.} -proc IMG_isPCX*(src: PRWops): cint{.cdecl, importc: "IMG_isPCX", +proc imgIsPCX*(src: PRWops): cint{.cdecl, importc: "IMG_isPCX", dynlib: ImageLibName.} -proc IMG_isPNG*(src: PRWops): cint{.cdecl, importc: "IMG_isPNG", +proc imgIsPNG*(src: PRWops): cint{.cdecl, importc: "IMG_isPNG", dynlib: ImageLibName.} -proc IMG_isPNM*(src: PRWops): cint{.cdecl, importc: "IMG_isPNM", +proc imgIsPNM*(src: PRWops): cint{.cdecl, importc: "IMG_isPNM", dynlib: ImageLibName.} -proc IMG_isTIF*(src: PRWops): cint{.cdecl, importc: "IMG_isTIF", +proc imgIsTIF*(src: PRWops): cint{.cdecl, importc: "IMG_isTIF", dynlib: ImageLibName.} -proc IMG_isXCF*(src: PRWops): cint{.cdecl, importc: "IMG_isXCF", +proc imgIsXCF*(src: PRWops): cint{.cdecl, importc: "IMG_isXCF", dynlib: ImageLibName.} -proc IMG_isXPM*(src: PRWops): cint{.cdecl, importc: "IMG_isXPM", +proc imgIsXPM*(src: PRWops): cint{.cdecl, importc: "IMG_isXPM", dynlib: ImageLibName.} -proc IMG_isXV*(src: PRWops): cint{.cdecl, importc: "IMG_isXV", +proc imgIsXV*(src: PRWops): cint{.cdecl, importc: "IMG_isXV", dynlib: ImageLibName.} # Individual loading functions -proc IMG_LoadBMP_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadBMP_RW", +proc imgLoadBMP_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadBMP_RW", dynlib: ImageLibName.} -proc IMG_LoadGIF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadGIF_RW", +proc imgLoadGIF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadGIF_RW", dynlib: ImageLibName.} -proc IMG_LoadJPG_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadJPG_RW", +proc imgLoadJPG_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadJPG_RW", dynlib: ImageLibName.} -proc IMG_LoadLBM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadLBM_RW", +proc imgLoadLBM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadLBM_RW", dynlib: ImageLibName.} -proc IMG_LoadPCX_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPCX_RW", +proc imgLoadPCX_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPCX_RW", dynlib: ImageLibName.} -proc IMG_LoadPNM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPNM_RW", +proc imgLoadPNM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPNM_RW", dynlib: ImageLibName.} -proc IMG_LoadPNG_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPNG_RW", +proc imgLoadPNG_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadPNG_RW", dynlib: ImageLibName.} -proc IMG_LoadTGA_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadTGA_RW", +proc imgLoadTGA_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadTGA_RW", dynlib: ImageLibName.} -proc IMG_LoadTIF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadTIF_RW", +proc imgLoadTIF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadTIF_RW", dynlib: ImageLibName.} -proc IMG_LoadXCF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXCF_RW", +proc imgLoadXCF_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXCF_RW", dynlib: ImageLibName.} -proc IMG_LoadXPM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXPM_RW", +proc imgLoadXPM_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXPM_RW", dynlib: ImageLibName.} -proc IMG_LoadXV_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXV_RW", +proc imgLoadXV_RW*(src: PRWops): PSurface{.cdecl, importc: "IMG_LoadXV_RW", dynlib: ImageLibName.} -proc IMG_ReadXPMFromArray*(xpm: cstringArray): PSurface{.cdecl, +proc imgReadXPMFromArray*(xpm: cstringArray): PSurface{.cdecl, importc: "IMG_ReadXPMFromArray", dynlib: ImageLibName.} -proc IMAGE_VERSION(X: var TVersion) = - X.major = IMAGE_MAJOR_VERSION - X.minor = IMAGE_MINOR_VERSION - X.patch = IMAGE_PATCHLEVEL +proc imageVersion(x: var Tversion) = + x.major = IMAGE_MAJOR_VERSION + x.minor = IMAGE_MINOR_VERSION + x.patch = IMAGE_PATCHLEVEL diff --git a/lib/wrappers/sdl/sdl_mixer.nim b/lib/wrappers/sdl/sdl_mixer.nim index 9199a9271..33a71508a 100644 --- a/lib/wrappers/sdl/sdl_mixer.nim +++ b/lib/wrappers/sdl/sdl_mixer.nim @@ -196,7 +196,7 @@ type #music_cmd.h types PWAVStream* = ptr TWAVStream TWAVStream*{.final.} = object #playmidi.h types - wavefp*: Pointer + wavefp*: pointer start*: int32 stop*: int32 cvt*: TAudioCVT @@ -223,8 +223,8 @@ type #music_cmd.h types volume*: int32 #vf: OggVorbis_File; section*: int32 cvt*: TAudioCVT - len_available*: int32 - snd_available*: pointer + lenAvailable*: int32 + sndAvailable*: pointer TErrorEnum* = enum MMERR_OPENING_FILE, MMERR_OUT_OF_MEMORY, MMERR_DYNAMIC_LINKING, @@ -255,7 +255,7 @@ type #music_cmd.h types TChunk*{.final.} = object allocated*: cint abuf*: pointer - alen*: Uint32 + alen*: uint32 volume*: byte # Per-sample volume, 0-128 TFading* = enum @@ -272,18 +272,18 @@ type #music_cmd.h types # fade_steps : integer; # error : integer; - TMixFunction* = proc (udata, stream: pointer, length: cint): Pointer{. + TMixFunction* = proc (udata, stream: pointer, length: cint): pointer{. cdecl.} # This macro can be used to fill a version structure with the compile-time # version of the SDL_mixer library. -proc VERSION*(X: var sdl.TVersion) +proc version*(x: var sdl.Tversion) # This function gets the version of the dynamically linked SDL_mixer library. # It should NOT be used to fill a version structure, instead you should use the # SDL_MIXER_VERSION() macro. -proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "Mix_Linked_Version", +proc linkedVersion*(): sdl.Pversion{.cdecl, importc: "Mix_Linked_Version", dynlib: MixerLibName.} # Open the mixer with a certain audio format -proc OpenAudio*(frequency: cint, format: Uint16, channels: cint, +proc openAudio*(frequency: cint, format: uint16, channels: cint, chunksize: cint): cint{.cdecl, importc: "Mix_OpenAudio", dynlib: MixerLibName.} # Dynamically change the number of channels managed by the mixer. @@ -291,194 +291,194 @@ proc OpenAudio*(frequency: cint, format: Uint16, channels: cint, # stopped. # This function returns the new number of allocated channels. # -proc AllocateChannels*(numchannels: cint): cint{.cdecl, +proc allocateChannels*(numchannels: cint): cint{.cdecl, importc: "Mix_AllocateChannels", dynlib: MixerLibName.} # Find out what the actual audio device parameters are. # This function returns 1 if the audio has been opened, 0 otherwise. # -proc QuerySpec*(frequency: var cint, format: var Uint16, channels: var cint): cint{. +proc querySpec*(frequency: var cint, format: var uint16, channels: var cint): cint{. cdecl, importc: "Mix_QuerySpec", dynlib: MixerLibName.} # Load a wave file or a music (.mod .s3m .it .xm) file -proc LoadWAV_RW*(src: PRWops, freesrc: cint): PChunk{.cdecl, +proc loadWAV_RW*(src: PRWops, freesrc: cint): PChunk{.cdecl, importc: "Mix_LoadWAV_RW", dynlib: MixerLibName.} -proc LoadWAV*(filename: cstring): PChunk -proc LoadMUS*(filename: cstring): PMusic{.cdecl, importc: "Mix_LoadMUS", +proc loadWAV*(filename: cstring): PChunk +proc loadMUS*(filename: cstring): PMusic{.cdecl, importc: "Mix_LoadMUS", dynlib: MixerLibName.} # Load a wave file of the mixer format from a memory buffer -proc QuickLoad_WAV*(mem: pointer): PChunk{.cdecl, +proc quickLoadWAV*(mem: pointer): PChunk{.cdecl, importc: "Mix_QuickLoad_WAV", dynlib: MixerLibName.} # Free an audio chunk previously loaded -proc FreeChunk*(chunk: PChunk){.cdecl, importc: "Mix_FreeChunk", +proc freeChunk*(chunk: PChunk){.cdecl, importc: "Mix_FreeChunk", dynlib: MixerLibName.} -proc FreeMusic*(music: PMusic){.cdecl, importc: "Mix_FreeMusic", +proc freeMusic*(music: PMusic){.cdecl, importc: "Mix_FreeMusic", dynlib: MixerLibName.} # Find out the music format of a mixer music, or the currently playing # music, if 'music' is NULL. -proc GetMusicType*(music: PMusic): TMusicType{.cdecl, +proc getMusicType*(music: PMusic): TMusicType{.cdecl, importc: "Mix_GetMusicType", dynlib: MixerLibName.} # Set a function that is called after all mixing is performed. # This can be used to provide real-time visual display of the audio stream # or add a custom mixer filter for the stream data. # -proc SetPostMix*(mix_func: TMixFunction, arg: Pointer){.cdecl, +proc setPostMix*(mixFunc: TMixFunction, arg: pointer){.cdecl, importc: "Mix_SetPostMix", dynlib: MixerLibName.} # Add your own music player or additional mixer function. # If 'mix_func' is NULL, the default music player is re-enabled. # -proc HookMusic*(mix_func: TMixFunction, arg: Pointer){.cdecl, +proc hookMusic*(mixFunc: TMixFunction, arg: pointer){.cdecl, importc: "Mix_HookMusic", dynlib: MixerLibName.} # Add your own callback when the music has finished playing. # -proc HookMusicFinished*(music_finished: Pointer){.cdecl, +proc hookMusicFinished*(musicFinished: pointer){.cdecl, importc: "Mix_HookMusicFinished", dynlib: MixerLibName.} # Get a pointer to the user data for the current music hook -proc GetMusicHookData*(): Pointer{.cdecl, importc: "Mix_GetMusicHookData", +proc getMusicHookData*(): pointer{.cdecl, importc: "Mix_GetMusicHookData", dynlib: MixerLibName.} #* Add your own callback when a channel has finished playing. NULL # * to disable callback.* type - TChannel_finished* = proc (channel: cint){.cdecl.} + TChannelFinished* = proc (channel: cint){.cdecl.} -proc ChannelFinished*(channel_finished: TChannel_finished){.cdecl, +proc channelFinished*(channelFinished: TChannelFinished){.cdecl, importc: "Mix_ChannelFinished", dynlib: MixerLibName.} const CHANNEL_POST* = - 2 type - TEffectFunc* = proc (chan: cint, stream: Pointer, length: cint, - udata: Pointer): Pointer{.cdecl.} - TEffectDone* = proc (chan: cint, udata: Pointer): Pointer{.cdecl.} -proc RegisterEffect*(chan: cint, f: TEffectFunc, d: TEffectDone, - arg: Pointer): cint{.cdecl, + TEffectFunc* = proc (chan: cint, stream: pointer, length: cint, + udata: pointer): pointer{.cdecl.} + TEffectDone* = proc (chan: cint, udata: pointer): pointer{.cdecl.} +proc registerEffect*(chan: cint, f: TEffectFunc, d: TEffectDone, + arg: pointer): cint{.cdecl, importc: "Mix_RegisterEffect", dynlib: MixerLibName.} -proc UnregisterEffect*(channel: cint, f: TEffectFunc): cint{.cdecl, +proc unregisterEffect*(channel: cint, f: TEffectFunc): cint{.cdecl, importc: "Mix_UnregisterEffect", dynlib: MixerLibName.} -proc UnregisterAllEffects*(channel: cint): cint{.cdecl, +proc unregisterAllEffects*(channel: cint): cint{.cdecl, importc: "Mix_UnregisterAllEffects", dynlib: MixerLibName.} const EFFECTSMAXSPEED* = "MIX_EFFECTSMAXSPEED" -proc SetPanning*(channel: cint, left: byte, right: byte): cint{.cdecl, +proc setPanning*(channel: cint, left: byte, right: byte): cint{.cdecl, importc: "Mix_SetPanning", dynlib: MixerLibName.} -proc SetPosition*(channel: cint, angle: int16, distance: byte): cint{.cdecl, +proc setPosition*(channel: cint, angle: int16, distance: byte): cint{.cdecl, importc: "Mix_SetPosition", dynlib: MixerLibName.} -proc SetDistance*(channel: cint, distance: byte): cint{.cdecl, +proc setDistance*(channel: cint, distance: byte): cint{.cdecl, importc: "Mix_SetDistance", dynlib: MixerLibName.} -proc SetReverseStereo*(channel: cint, flip: cint): cint{.cdecl, +proc setReverseStereo*(channel: cint, flip: cint): cint{.cdecl, importc: "Mix_SetReverseStereo", dynlib: MixerLibName.} -proc ReserveChannels*(num: cint): cint{.cdecl, importc: "Mix_ReserveChannels", +proc reserveChannels*(num: cint): cint{.cdecl, importc: "Mix_ReserveChannels", dynlib: MixerLibName.} -proc GroupChannel*(which: cint, tag: cint): cint{.cdecl, +proc groupChannel*(which: cint, tag: cint): cint{.cdecl, importc: "Mix_GroupChannel", dynlib: MixerLibName.} -proc GroupChannels*(`from`: cint, `to`: cint, tag: cint): cint{.cdecl, +proc groupChannels*(`from`: cint, `to`: cint, tag: cint): cint{.cdecl, importc: "Mix_GroupChannels", dynlib: MixerLibName.} -proc GroupAvailable*(tag: cint): cint{.cdecl, importc: "Mix_GroupAvailable", +proc groupAvailable*(tag: cint): cint{.cdecl, importc: "Mix_GroupAvailable", dynlib: MixerLibName.} -proc GroupCount*(tag: cint): cint{.cdecl, importc: "Mix_GroupCount", +proc groupCount*(tag: cint): cint{.cdecl, importc: "Mix_GroupCount", dynlib: MixerLibName.} -proc GroupOldest*(tag: cint): cint{.cdecl, importc: "Mix_GroupOldest", +proc groupOldest*(tag: cint): cint{.cdecl, importc: "Mix_GroupOldest", dynlib: MixerLibName.} -proc GroupNewer*(tag: cint): cint{.cdecl, importc: "Mix_GroupNewer", +proc groupNewer*(tag: cint): cint{.cdecl, importc: "Mix_GroupNewer", dynlib: MixerLibName.} -proc PlayChannelTimed*(channel: cint, chunk: PChunk, loops: cint, +proc playChannelTimed*(channel: cint, chunk: PChunk, loops: cint, ticks: cint): cint{.cdecl, importc: "Mix_PlayChannelTimed", dynlib: MixerLibName.} -proc PlayChannel*(channel: cint, chunk: PChunk, loops: cint): cint -proc PlayMusic*(music: PMusic, loops: cint): cint{.cdecl, +proc playChannel*(channel: cint, chunk: PChunk, loops: cint): cint +proc playMusic*(music: PMusic, loops: cint): cint{.cdecl, importc: "Mix_PlayMusic", dynlib: MixerLibName.} -proc FadeInMusic*(music: PMusic, loops: cint, ms: cint): cint{.cdecl, +proc fadeInMusic*(music: PMusic, loops: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeInMusic", dynlib: MixerLibName.} -proc FadeInChannelTimed*(channel: cint, chunk: PChunk, loops: cint, +proc fadeInChannelTimed*(channel: cint, chunk: PChunk, loops: cint, ms: cint, ticks: cint): cint{.cdecl, importc: "Mix_FadeInChannelTimed", dynlib: MixerLibName.} -proc FadeInChannel*(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint +proc fadeInChannel*(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint -proc Volume*(channel: cint, volume: cint): cint{.cdecl, importc: "Mix_Volume", +proc volume*(channel: cint, volume: cint): cint{.cdecl, importc: "Mix_Volume", dynlib: MixerLibName.} -proc VolumeChunk*(chunk: PChunk, volume: cint): cint{.cdecl, +proc volumeChunk*(chunk: PChunk, volume: cint): cint{.cdecl, importc: "Mix_VolumeChunk", dynlib: MixerLibName.} -proc VolumeMusic*(volume: cint): cint{.cdecl, importc: "Mix_VolumeMusic", +proc volumeMusic*(volume: cint): cint{.cdecl, importc: "Mix_VolumeMusic", dynlib: MixerLibName.} -proc HaltChannel*(channel: cint): cint{.cdecl, importc: "Mix_HaltChannel", +proc haltChannel*(channel: cint): cint{.cdecl, importc: "Mix_HaltChannel", dynlib: MixerLibName.} -proc HaltGroup*(tag: cint): cint{.cdecl, importc: "Mix_HaltGroup", +proc haltGroup*(tag: cint): cint{.cdecl, importc: "Mix_HaltGroup", dynlib: MixerLibName.} -proc HaltMusic*(): cint{.cdecl, importc: "Mix_HaltMusic", +proc haltMusic*(): cint{.cdecl, importc: "Mix_HaltMusic", dynlib: MixerLibName.} # Change the expiration delay for a particular channel. # The sample will stop playing after the 'ticks' milliseconds have elapsed, # or remove the expiration if 'ticks' is -1 # -proc ExpireChannel*(channel: cint, ticks: cint): cint{.cdecl, +proc expireChannel*(channel: cint, ticks: cint): cint{.cdecl, importc: "Mix_ExpireChannel", dynlib: MixerLibName.} # Halt a channel, fading it out progressively till it's silent # The ms parameter indicates the number of milliseconds the fading # will take. # -proc FadeOutChannel*(which: cint, ms: cint): cint{.cdecl, +proc fadeOutChannel*(which: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeOutChannel", dynlib: MixerLibName.} -proc FadeOutGroup*(tag: cint, ms: cint): cint{.cdecl, +proc fadeOutGroup*(tag: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeOutGroup", dynlib: MixerLibName.} -proc FadeOutMusic*(ms: cint): cint{.cdecl, importc: "Mix_FadeOutMusic", +proc fadeOutMusic*(ms: cint): cint{.cdecl, importc: "Mix_FadeOutMusic", dynlib: MixerLibName.} # Query the fading status of a channel -proc FadingMusic*(): TFading{.cdecl, importc: "Mix_FadingMusic", +proc fadingMusic*(): TFading{.cdecl, importc: "Mix_FadingMusic", dynlib: MixerLibName.} -proc FadingChannel*(which: cint): TFading{.cdecl, +proc fadingChannel*(which: cint): TFading{.cdecl, importc: "Mix_FadingChannel", dynlib: MixerLibName.} -proc Pause*(channel: cint){.cdecl, importc: "Mix_Pause", dynlib: MixerLibName.} -proc Resume*(channel: cint){.cdecl, importc: "Mix_Resume", +proc pause*(channel: cint){.cdecl, importc: "Mix_Pause", dynlib: MixerLibName.} +proc resume*(channel: cint){.cdecl, importc: "Mix_Resume", dynlib: MixerLibName.} -proc Paused*(channel: cint): cint{.cdecl, importc: "Mix_Paused", +proc paused*(channel: cint): cint{.cdecl, importc: "Mix_Paused", dynlib: MixerLibName.} -proc PauseMusic*(){.cdecl, importc: "Mix_PauseMusic", dynlib: MixerLibName.} -proc ResumeMusic*(){.cdecl, importc: "Mix_ResumeMusic", dynlib: MixerLibName.} -proc RewindMusic*(){.cdecl, importc: "Mix_RewindMusic", dynlib: MixerLibName.} -proc PausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", +proc pauseMusic*(){.cdecl, importc: "Mix_PauseMusic", dynlib: MixerLibName.} +proc resumeMusic*(){.cdecl, importc: "Mix_ResumeMusic", dynlib: MixerLibName.} +proc rewindMusic*(){.cdecl, importc: "Mix_RewindMusic", dynlib: MixerLibName.} +proc pausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", dynlib: MixerLibName.} -proc SetMusicPosition*(position: float64): cint{.cdecl, +proc setMusicPosition*(position: float64): cint{.cdecl, importc: "Mix_SetMusicPosition", dynlib: MixerLibName.} -proc Playing*(channel: cint): cint{.cdecl, importc: "Mix_Playing", +proc playing*(channel: cint): cint{.cdecl, importc: "Mix_Playing", dynlib: MixerLibName.} -proc PlayingMusic*(): cint{.cdecl, importc: "Mix_PlayingMusic", +proc playingMusic*(): cint{.cdecl, importc: "Mix_PlayingMusic", dynlib: MixerLibName.} -proc SetMusicCMD*(command: cstring): cint{.cdecl, importc: "Mix_SetMusicCMD", +proc setMusicCMD*(command: cstring): cint{.cdecl, importc: "Mix_SetMusicCMD", dynlib: MixerLibName.} -proc SetSynchroValue*(value: cint): cint{.cdecl, +proc setSynchroValue*(value: cint): cint{.cdecl, importc: "Mix_SetSynchroValue", dynlib: MixerLibName.} -proc GetSynchroValue*(): cint{.cdecl, importc: "Mix_GetSynchroValue", +proc getSynchroValue*(): cint{.cdecl, importc: "Mix_GetSynchroValue", dynlib: MixerLibName.} -proc GetChunk*(channel: cint): PChunk{.cdecl, importc: "Mix_GetChunk", +proc getChunk*(channel: cint): PChunk{.cdecl, importc: "Mix_GetChunk", dynlib: MixerLibName.} -proc CloseAudio*(){.cdecl, importc: "Mix_CloseAudio", dynlib: MixerLibName.} +proc closeAudio*(){.cdecl, importc: "Mix_CloseAudio", dynlib: MixerLibName.} -proc VERSION(X: var sdl.Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version(x: var sdl.Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc LoadWAV(filename: cstring): PChunk = - result = LoadWAV_RW(RWFromFile(filename, "rb"), 1) +proc loadWAV(filename: cstring): PChunk = + result = loadWAV_RW(rWFromFile(filename, "rb"), 1) -proc PlayChannel(channel: cint, chunk: PChunk, loops: cint): cint = - result = PlayChannelTimed(channel, chunk, loops, - 1) +proc playChannel(channel: cint, chunk: PChunk, loops: cint): cint = + result = playChannelTimed(channel, chunk, loops, - 1) -proc FadeInChannel(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint = - result = FadeInChannelTimed(channel, chunk, loops, ms, - 1) +proc fadeInChannel(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint = + result = fadeInChannelTimed(channel, chunk, loops, ms, - 1) diff --git a/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim b/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim index 11f00e0a7..7a8c41af1 100644 --- a/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim +++ b/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim @@ -48,7 +48,7 @@ type #music_cmd.h types PWAVStream* = ptr TWAVStream TWAVStream*{.final.} = object #playmidi.h types - wavefp*: Pointer + wavefp*: pointer start*: int32 stop*: int32 cvt*: TAudioCVT @@ -75,8 +75,8 @@ type #music_cmd.h types volume*: cint #vf: OggVorbis_File; section*: cint cvt*: TAudioCVT - len_available*: cint - snd_available*: pointer + lenAvailable*: cint + sndAvailable*: pointer TErrorEnum* = enum MMERR_OPENING_FILE, MMERR_OUT_OF_MEMORY, MMERR_DYNAMIC_LINKING, @@ -107,7 +107,7 @@ type #music_cmd.h types TChunk*{.final.} = object allocated*: cint abuf*: pointer - alen*: Uint32 + alen*: uint32 volume*: byte # Per-sample volume, 0-128 TFading* = enum @@ -118,18 +118,18 @@ type #music_cmd.h types TMusic*{.final.} = object typ*: TMusicType - TMixFunction* = proc (udata, stream: pointer, length: cint): Pointer{. + TMixFunction* = proc (udata, stream: pointer, length: cint): pointer{. cdecl.} # This macro can be used to fill a version structure with the compile-time # version of the SDL_mixer library. -proc VERSION*(X: var sdl.TVersion) +proc version*(x: var sdl.Tversion) # This function gets the version of the dynamically linked SDL_mixer library. # It should NOT be used to fill a version structure, instead you should use the # SDL_MIXER_VERSION() macro. -proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "Mix_Linked_Version", +proc linkedVersion*(): sdl.Pversion{.cdecl, importc: "Mix_Linked_Version", dynlib: MixerLibName.} # Open the mixer with a certain audio format -proc OpenAudio*(frequency: cint, format: Uint16, channels: cint, +proc openAudio*(frequency: cint, format: uint16, channels: cint, chunksize: cint): cint{.cdecl, importc: "Mix_OpenAudio", dynlib: MixerLibName.} # Dynamically change the number of channels managed by the mixer. @@ -137,170 +137,170 @@ proc OpenAudio*(frequency: cint, format: Uint16, channels: cint, # stopped. # This function returns the new number of allocated channels. # -proc AllocateChannels*(numchannels: cint): cint{.cdecl, +proc allocateChannels*(numchannels: cint): cint{.cdecl, importc: "Mix_AllocateChannels", dynlib: MixerLibName.} # Find out what the actual audio device parameters are. # This function returns 1 if the audio has been opened, 0 otherwise. # -proc QuerySpec*(frequency: var cint, format: var Uint16, channels: var cint): cint{. +proc querySpec*(frequency: var cint, format: var uint16, channels: var cint): cint{. cdecl, importc: "Mix_QuerySpec", dynlib: MixerLibName.} # Load a wave file or a music (.mod .s3m .it .xm) file proc LoadWAV_RW*(src: PRWops, freesrc: cint): PChunk{.cdecl, importc: "Mix_LoadWAV_RW", dynlib: MixerLibName.} -proc LoadWAV*(filename: cstring): PChunk -proc LoadMUS*(filename: cstring): PMusic{.cdecl, importc: "Mix_LoadMUS", +proc loadWAV*(filename: cstring): PChunk +proc loadMUS*(filename: cstring): PMusic{.cdecl, importc: "Mix_LoadMUS", dynlib: MixerLibName.} # Load a wave file of the mixer format from a memory buffer -proc QuickLoad_WAV*(mem: pointer): PChunk{.cdecl, +proc quickLoadWAV*(mem: pointer): PChunk{.cdecl, importc: "Mix_QuickLoad_WAV", dynlib: MixerLibName.} # Free an audio chunk previously loaded -proc FreeChunk*(chunk: PChunk){.cdecl, importc: "Mix_FreeChunk", +proc freeChunk*(chunk: PChunk){.cdecl, importc: "Mix_FreeChunk", dynlib: MixerLibName.} -proc FreeMusic*(music: PMusic){.cdecl, importc: "Mix_FreeMusic", +proc freeMusic*(music: PMusic){.cdecl, importc: "Mix_FreeMusic", dynlib: MixerLibName.} # Find out the music format of a mixer music, or the currently playing # music, if 'music' is NULL. -proc GetMusicType*(music: PMusic): TMusicType{.cdecl, +proc getMusicType*(music: PMusic): TMusicType{.cdecl, importc: "Mix_GetMusicType", dynlib: MixerLibName.} # Set a function that is called after all mixing is performed. # This can be used to provide real-time visual display of the audio stream # or add a custom mixer filter for the stream data. # -proc SetPostMix*(mixfunc: TMixFunction, arg: Pointer){.cdecl, +proc setPostMix*(mixfunc: TMixFunction, arg: pointer){.cdecl, importc: "Mix_SetPostMix", dynlib: MixerLibName.} # Add your own music player or additional mixer function. # If 'mix_func' is NULL, the default music player is re-enabled. # -proc HookMusic*(mix_func: TMixFunction, arg: Pointer){.cdecl, +proc hookMusic*(mixFunc: TMixFunction, arg: pointer){.cdecl, importc: "Mix_HookMusic", dynlib: MixerLibName.} # Add your own callback when the music has finished playing. # -proc HookMusicFinished*(music_finished: Pointer){.cdecl, +proc hookMusicFinished*(musicFinished: pointer){.cdecl, importc: "Mix_HookMusicFinished", dynlib: MixerLibName.} # Get a pointer to the user data for the current music hook -proc GetMusicHookData*(): Pointer{.cdecl, importc: "Mix_GetMusicHookData", +proc getMusicHookData*(): pointer{.cdecl, importc: "Mix_GetMusicHookData", dynlib: MixerLibName.} #* Add your own callback when a channel has finished playing. NULL # * to disable callback.* type - TChannel_finished* = proc (channel: cint){.cdecl.} + TChannelFinished* = proc (channel: cint){.cdecl.} -proc ChannelFinished*(channel_finished: TChannel_finished){.cdecl, +proc channelFinished*(channelFinished: TChannelFinished){.cdecl, importc: "Mix_ChannelFinished", dynlib: MixerLibName.} const CHANNEL_POST* = - 2 type - TEffectFunc* = proc (chan: cint, stream: Pointer, length: cint, - udata: Pointer): Pointer{.cdecl.} - TEffectDone* = proc (chan: cint, udata: Pointer): Pointer{.cdecl.} + TEffectFunc* = proc (chan: cint, stream: pointer, length: cint, + udata: pointer): pointer{.cdecl.} + TEffectDone* = proc (chan: cint, udata: pointer): pointer{.cdecl.} -proc RegisterEffect*(chan: cint, f: TEffectFunc, d: TEffectDone, - arg: Pointer): cint{.cdecl, +proc registerEffect*(chan: cint, f: TEffectFunc, d: TEffectDone, + arg: pointer): cint{.cdecl, importc: "Mix_RegisterEffect", dynlib: MixerLibName.} -proc UnregisterEffect*(channel: cint, f: TEffectFunc): cint{.cdecl, +proc unregisterEffect*(channel: cint, f: TEffectFunc): cint{.cdecl, importc: "Mix_UnregisterEffect", dynlib: MixerLibName.} -proc UnregisterAllEffects*(channel: cint): cint{.cdecl, +proc unregisterAllEffects*(channel: cint): cint{.cdecl, importc: "Mix_UnregisterAllEffects", dynlib: MixerLibName.} const EFFECTSMAXSPEED* = "MIX_EFFECTSMAXSPEED" -proc SetPanning*(channel: cint, left: byte, right: byte): cint{.cdecl, +proc setPanning*(channel: cint, left: byte, right: byte): cint{.cdecl, importc: "Mix_SetPanning", dynlib: MixerLibName.} -proc SetPosition*(channel: cint, angle: int16, distance: byte): cint{.cdecl, +proc setPosition*(channel: cint, angle: int16, distance: byte): cint{.cdecl, importc: "Mix_SetPosition", dynlib: MixerLibName.} -proc SetDistance*(channel: cint, distance: byte): cint{.cdecl, +proc setDistance*(channel: cint, distance: byte): cint{.cdecl, importc: "Mix_SetDistance", dynlib: MixerLibName.} -proc SetReverseStereo*(channel: cint, flip: cint): cint{.cdecl, +proc setReverseStereo*(channel: cint, flip: cint): cint{.cdecl, importc: "Mix_SetReverseStereo", dynlib: MixerLibName.} -proc ReserveChannels*(num: cint): cint{.cdecl, importc: "Mix_ReserveChannels", +proc reserveChannels*(num: cint): cint{.cdecl, importc: "Mix_ReserveChannels", dynlib: MixerLibName.} -proc GroupChannel*(which: cint, tag: cint): cint{.cdecl, +proc groupChannel*(which: cint, tag: cint): cint{.cdecl, importc: "Mix_GroupChannel", dynlib: MixerLibName.} # Assign several consecutive channels to a group -proc GroupChannels*(`from`: cint, `to`: cint, tag: cint): cint{.cdecl, +proc groupChannels*(`from`: cint, `to`: cint, tag: cint): cint{.cdecl, importc: "Mix_GroupChannels", dynlib: MixerLibName.} # Finds the first available channel in a group of channels -proc GroupAvailable*(tag: cint): cint{.cdecl, importc: "Mix_GroupAvailable", +proc groupAvailable*(tag: cint): cint{.cdecl, importc: "Mix_GroupAvailable", dynlib: MixerLibName.} # Returns the number of channels in a group. This is also a subtle # way to get the total number of channels when 'tag' is -1 # -proc GroupCount*(tag: cint): cint{.cdecl, importc: "Mix_GroupCount", +proc groupCount*(tag: cint): cint{.cdecl, importc: "Mix_GroupCount", dynlib: MixerLibName.} # Finds the "oldest" sample playing in a group of channels -proc GroupOldest*(tag: cint): cint{.cdecl, importc: "Mix_GroupOldest", +proc groupOldest*(tag: cint): cint{.cdecl, importc: "Mix_GroupOldest", dynlib: MixerLibName.} # Finds the "most recent" (i.e. last) sample playing in a group of channels -proc GroupNewer*(tag: cint): cint{.cdecl, importc: "Mix_GroupNewer", +proc groupNewer*(tag: cint): cint{.cdecl, importc: "Mix_GroupNewer", dynlib: MixerLibName.} # The same as above, but the sound is played at most 'ticks' milliseconds -proc PlayChannelTimed*(channel: cint, chunk: PChunk, loops: cint, +proc playChannelTimed*(channel: cint, chunk: PChunk, loops: cint, ticks: cint): cint{.cdecl, importc: "Mix_PlayChannelTimed", dynlib: MixerLibName.} -proc PlayChannel*(channel: cint, chunk: PChunk, loops: cint): cint -proc PlayMusic*(music: PMusic, loops: cint): cint{.cdecl, +proc playChannel*(channel: cint, chunk: PChunk, loops: cint): cint +proc playMusic*(music: PMusic, loops: cint): cint{.cdecl, importc: "Mix_PlayMusic", dynlib: MixerLibName.} # Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions -proc FadeInMusic*(music: PMusic, loops: cint, ms: cint): cint{.cdecl, +proc fadeInMusic*(music: PMusic, loops: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeInMusic", dynlib: MixerLibName.} -proc FadeInChannelTimed*(channel: cint, chunk: PChunk, loops: cint, +proc fadeInChannelTimed*(channel: cint, chunk: PChunk, loops: cint, ms: cint, ticks: cint): cint{.cdecl, importc: "Mix_FadeInChannelTimed", dynlib: MixerLibName.} -proc FadeInChannel*(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint +proc fadeInChannel*(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint # Set the volume in the range of 0-128 of a specific channel or chunk. # If the specified channel is -1, set volume for all channels. # Returns the original volume. # If the specified volume is -1, just return the current volume. # -proc Volume*(channel: cint, volume: cint): cint{.cdecl, importc: "Mix_Volume", +proc volume*(channel: cint, volume: cint): cint{.cdecl, importc: "Mix_Volume", dynlib: MixerLibName.} -proc VolumeChunk*(chunk: PChunk, volume: cint): cint{.cdecl, +proc volumeChunk*(chunk: PChunk, volume: cint): cint{.cdecl, importc: "Mix_VolumeChunk", dynlib: MixerLibName.} -proc VolumeMusic*(volume: cint): cint{.cdecl, importc: "Mix_VolumeMusic", +proc volumeMusic*(volume: cint): cint{.cdecl, importc: "Mix_VolumeMusic", dynlib: MixerLibName.} # Halt playing of a particular channel -proc HaltChannel*(channel: cint): cint{.cdecl, importc: "Mix_HaltChannel", +proc haltChannel*(channel: cint): cint{.cdecl, importc: "Mix_HaltChannel", dynlib: MixerLibName.} -proc HaltGroup*(tag: cint): cint{.cdecl, importc: "Mix_HaltGroup", +proc haltGroup*(tag: cint): cint{.cdecl, importc: "Mix_HaltGroup", dynlib: MixerLibName.} -proc HaltMusic*(): cint{.cdecl, importc: "Mix_HaltMusic", +proc haltMusic*(): cint{.cdecl, importc: "Mix_HaltMusic", dynlib: MixerLibName.} -proc ExpireChannel*(channel: cint, ticks: cint): cint{.cdecl, +proc expireChannel*(channel: cint, ticks: cint): cint{.cdecl, importc: "Mix_ExpireChannel", dynlib: MixerLibName.} -proc FadeOutChannel*(which: cint, ms: cint): cint{.cdecl, +proc fadeOutChannel*(which: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeOutChannel", dynlib: MixerLibName.} -proc FadeOutGroup*(tag: cint, ms: cint): cint{.cdecl, +proc fadeOutGroup*(tag: cint, ms: cint): cint{.cdecl, importc: "Mix_FadeOutGroup", dynlib: MixerLibName.} -proc FadeOutMusic*(ms: cint): cint{.cdecl, importc: "Mix_FadeOutMusic", +proc fadeOutMusic*(ms: cint): cint{.cdecl, importc: "Mix_FadeOutMusic", dynlib: MixerLibName.} # Query the fading status of a channel -proc FadingMusic*(): TFading{.cdecl, importc: "Mix_FadingMusic", +proc fadingMusic*(): TFading{.cdecl, importc: "Mix_FadingMusic", dynlib: MixerLibName.} -proc FadingChannel*(which: cint): TFading{.cdecl, +proc fadingChannel*(which: cint): TFading{.cdecl, importc: "Mix_FadingChannel", dynlib: MixerLibName.} # Pause/Resume a particular channel -proc Pause*(channel: cint){.cdecl, importc: "Mix_Pause", dynlib: MixerLibName.} -proc Resume*(channel: cint){.cdecl, importc: "Mix_Resume", +proc pause*(channel: cint){.cdecl, importc: "Mix_Pause", dynlib: MixerLibName.} +proc resume*(channel: cint){.cdecl, importc: "Mix_Resume", dynlib: MixerLibName.} -proc Paused*(channel: cint): cint{.cdecl, importc: "Mix_Paused", +proc paused*(channel: cint): cint{.cdecl, importc: "Mix_Paused", dynlib: MixerLibName.} # Pause/Resume the music stream -proc PauseMusic*(){.cdecl, importc: "Mix_PauseMusic", dynlib: MixerLibName.} -proc ResumeMusic*(){.cdecl, importc: "Mix_ResumeMusic", dynlib: MixerLibName.} -proc RewindMusic*(){.cdecl, importc: "Mix_RewindMusic", dynlib: MixerLibName.} -proc PausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", +proc pauseMusic*(){.cdecl, importc: "Mix_PauseMusic", dynlib: MixerLibName.} +proc resumeMusic*(){.cdecl, importc: "Mix_ResumeMusic", dynlib: MixerLibName.} +proc rewindMusic*(){.cdecl, importc: "Mix_RewindMusic", dynlib: MixerLibName.} +proc pausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", dynlib: MixerLibName.} # Set the current position in the music stream. # This returns 0 if successful, or -1 if it failed or isn't implemented. @@ -308,44 +308,44 @@ proc PausedMusic*(): cint{.cdecl, importc: "Mix_PausedMusic", # order number) and for OGG music (set position in seconds), at the # moment. # -proc SetMusicPosition*(position: float64): cint{.cdecl, +proc setMusicPosition*(position: float64): cint{.cdecl, importc: "Mix_SetMusicPosition", dynlib: MixerLibName.} # Check the status of a specific channel. # If the specified channel is -1, check all channels. # -proc Playing*(channel: cint): cint{.cdecl, importc: "Mix_Playing", +proc playing*(channel: cint): cint{.cdecl, importc: "Mix_Playing", dynlib: MixerLibName.} -proc PlayingMusic*(): cint{.cdecl, importc: "Mix_PlayingMusic", +proc playingMusic*(): cint{.cdecl, importc: "Mix_PlayingMusic", dynlib: MixerLibName.} # Stop music and set external music playback command -proc SetMusicCMD*(command: cstring): cint{.cdecl, importc: "Mix_SetMusicCMD", +proc setMusicCMD*(command: cstring): cint{.cdecl, importc: "Mix_SetMusicCMD", dynlib: MixerLibName.} # Synchro value is set by MikMod from modules while playing -proc SetSynchroValue*(value: cint): cint{.cdecl, +proc setSynchroValue*(value: cint): cint{.cdecl, importc: "Mix_SetSynchroValue", dynlib: MixerLibName.} -proc GetSynchroValue*(): cint{.cdecl, importc: "Mix_GetSynchroValue", +proc getSynchroValue*(): cint{.cdecl, importc: "Mix_GetSynchroValue", dynlib: MixerLibName.} # # Get the Mix_Chunk currently associated with a mixer channel # Returns nil if it's an invalid channel, or there's no chunk associated. # -proc GetChunk*(channel: cint): PChunk{.cdecl, importc: "Mix_GetChunk", +proc getChunk*(channel: cint): PChunk{.cdecl, importc: "Mix_GetChunk", dynlib: MixerLibName.} # Close the mixer, halting all playing audio -proc CloseAudio*(){.cdecl, importc: "Mix_CloseAudio", dynlib: MixerLibName.} +proc closeAudio*(){.cdecl, importc: "Mix_CloseAudio", dynlib: MixerLibName.} # We'll use SDL for reporting errors -proc VERSION(X: var Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version(x: var Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc LoadWAV(filename: cstring): PChunk = - result = LoadWAV_RW(RWFromFile(filename, "rb"), 1) +proc loadWAV(filename: cstring): PChunk = + result = LoadWAV_RW(rWFromFile(filename, "rb"), 1) -proc PlayChannel(channel: cint, chunk: PChunk, loops: cint): cint = - result = PlayChannelTimed(channel, chunk, loops, - 1) +proc playChannel(channel: cint, chunk: PChunk, loops: cint): cint = + result = playChannelTimed(channel, chunk, loops, - 1) -proc FadeInChannel(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint = - result = FadeInChannelTimed(channel, chunk, loops, ms, - 1) +proc fadeInChannel(channel: cint, chunk: PChunk, loops: cint, ms: cint): cint = + result = fadeInChannelTimed(channel, chunk, loops, ms, - 1) diff --git a/lib/wrappers/sdl/sdl_net.nim b/lib/wrappers/sdl/sdl_net.nim index 742a59314..1ffdb5cca 100644 --- a/lib/wrappers/sdl/sdl_net.nim +++ b/lib/wrappers/sdl/sdl_net.nim @@ -145,15 +145,15 @@ type # SDL_net.h types #*********************************************************************** PIPAddress* = ptr TIPAddress TIPAddress*{.final.} = object #* TCP network API - host*: Uint32 # 32-bit IPv4 host address */ - port*: Uint16 # 16-bit protocol port */ + host*: uint32 # 32-bit IPv4 host address */ + port*: uint16 # 16-bit protocol port */ PTCPSocket* = ptr TTCPSocket TTCPSocket*{.final.} = object # UDP network API ready*: int channel*: int - remoteAddress*: TIPaddress - localAddress*: TIPaddress + remoteAddress*: TIPAddress + localAddress*: TIPAddress sflag*: int PUDP_Channel* = ptr TUDP_Channel @@ -196,27 +196,27 @@ type # SDL_net.h types ready*: int -proc VERSION*(X: var Tversion) +proc version*(x: var Tversion) #* Initialize/Cleanup the network API # SDL must be initialized before calls to functions in this library, # because this library uses utility functions from the SDL library. #* -proc Init*(): int{.cdecl, importc: "SDLNet_Init", dynlib: NetLibName.} -proc Quit*(){.cdecl, importc: "SDLNet_Quit", dynlib: NetLibName.} +proc init*(): int{.cdecl, importc: "SDLNet_Init", dynlib: NetLibName.} +proc quit*(){.cdecl, importc: "SDLNet_Quit", dynlib: NetLibName.} #* Resolve a host name and port to an IP address in network form. # If the function succeeds, it will return 0. # If the host couldn't be resolved, the host portion of the returned # address will be INADDR_NONE, and the function will return -1. # If 'host' is NULL, the resolved host will be set to INADDR_ANY. # * -proc ResolveHost*(address: var TIPaddress, host: cstring, port: Uint16): int{. +proc resolveHost*(address: var TIPAddress, host: cstring, port: uint16): int{. cdecl, importc: "SDLNet_ResolveHost", dynlib: NetLibName.} #* Resolve an ip address to a host name in canonical form. # If the ip couldn't be resolved, this function returns NULL, # otherwise a pointer to a static buffer containing the hostname # is returned. Note that this function is not thread-safe. #* -proc ResolveIP*(ip: var TIPaddress): cstring{.cdecl, +proc resolveIP*(ip: var TIPAddress): cstring{.cdecl, importc: "SDLNet_ResolveIP", dynlib: NetLibName.} #*********************************************************************** #* TCP network API * @@ -229,24 +229,24 @@ proc ResolveIP*(ip: var TIPaddress): cstring{.cdecl, # in the correct form). # The newly created socket is returned, or NULL if there was an error. #* -proc TCP_Open*(ip: var TIPaddress): PTCPSocket{.cdecl, +proc tcpOpen*(ip: var TIPAddress): PTCPSocket{.cdecl, importc: "SDLNet_TCP_Open", dynlib: NetLibName.} #* Accept an incoming connection on the given server socket. # The newly created socket is returned, or NULL if there was an error. #* -proc TCP_Accept*(server: PTCPsocket): PTCPSocket{.cdecl, +proc tcpAccept*(server: PTCPSocket): PTCPSocket{.cdecl, importc: "SDLNet_TCP_Accept", dynlib: NetLibName.} #* Get the IP address of the remote system associated with the socket. # If the socket is a server socket, this function returns NULL. #* -proc TCP_GetPeerAddress*(sock: PTCPsocket): PIPAddress{.cdecl, +proc tcpGetPeerAddress*(sock: PTCPSocket): PIPAddress{.cdecl, importc: "SDLNet_TCP_GetPeerAddress", dynlib: NetLibName.} #* Send 'len' bytes of 'data' over the non-server socket 'sock' # This function returns the actual amount of data sent. If the return value # is less than the amount of data sent, then either the remote connection was # closed, or an unknown socket error occurred. #* -proc TCP_Send*(sock: PTCPsocket, data: Pointer, length: int): int{.cdecl, +proc tcpSend*(sock: PTCPSocket, data: pointer, length: int): int{.cdecl, importc: "SDLNet_TCP_Send", dynlib: NetLibName.} #* Receive up to 'maxlen' bytes of data over the non-server socket 'sock', # and store them in the buffer pointed to by 'data'. @@ -254,10 +254,10 @@ proc TCP_Send*(sock: PTCPsocket, data: Pointer, length: int): int{.cdecl, # value is less than or equal to zero, then either the remote connection was # closed, or an unknown socket error occurred. #* -proc TCP_Recv*(sock: PTCPsocket, data: Pointer, maxlen: int): int{.cdecl, +proc tcpRecv*(sock: PTCPSocket, data: pointer, maxlen: int): int{.cdecl, importc: "SDLNet_TCP_Recv", dynlib: NetLibName.} #* Close a TCP network socket * -proc TCP_Close*(sock: PTCPsocket){.cdecl, importc: "SDLNet_TCP_Close", +proc tcpClose*(sock: PTCPSocket){.cdecl, importc: "SDLNet_TCP_Close", dynlib: NetLibName.} #*********************************************************************** #* UDP network API * @@ -265,26 +265,26 @@ proc TCP_Close*(sock: PTCPsocket){.cdecl, importc: "SDLNet_TCP_Close", #* Allocate/resize/free a single UDP packet 'size' bytes long. # The new packet is returned, or NULL if the function ran out of memory. # * -proc AllocPacket*(size: int): PUDPpacket{.cdecl, +proc allocPacket*(size: int): PUDPpacket{.cdecl, importc: "SDLNet_AllocPacket", dynlib: NetLibName.} -proc ResizePacket*(packet: PUDPpacket, newsize: int): int{.cdecl, +proc resizePacket*(packet: PUDPpacket, newsize: int): int{.cdecl, importc: "SDLNet_ResizePacket", dynlib: NetLibName.} -proc FreePacket*(packet: PUDPpacket){.cdecl, importc: "SDLNet_FreePacket", +proc freePacket*(packet: PUDPpacket){.cdecl, importc: "SDLNet_FreePacket", dynlib: NetLibName.} #* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets, # each 'size' bytes long. # A pointer to the first packet in the array is returned, or NULL if the # function ran out of memory. # * -proc AllocPacketV*(howmany: int, size: int): PUDPpacket{.cdecl, +proc allocPacketV*(howmany: int, size: int): PUDPpacket{.cdecl, importc: "SDLNet_AllocPacketV", dynlib: NetLibName.} -proc FreePacketV*(packetV: PUDPpacket){.cdecl, +proc freePacketV*(packetV: PUDPpacket){.cdecl, importc: "SDLNet_FreePacketV", dynlib: NetLibName.} #* Open a UDP network socket # If 'port' is non-zero, the UDP socket is bound to a local port. # This allows other systems to send to this socket via a known port. #* -proc UDP_Open*(port: Uint16): PUDPsocket{.cdecl, importc: "SDLNet_UDP_Open", +proc udpOpen*(port: uint16): PUDPSocket{.cdecl, importc: "SDLNet_UDP_Open", dynlib: NetLibName.} #* Bind the address 'address' to the requested channel on the UDP socket. # If the channel is -1, then the first unbound channel will be bound with @@ -295,10 +295,10 @@ proc UDP_Open*(port: Uint16): PUDPsocket{.cdecl, importc: "SDLNet_UDP_Open", # address, to which all outbound packets on the channel are sent. # This function returns the channel which was bound, or -1 on error. #* -proc UDP_Bind*(sock: PUDPsocket, channel: int, address: var TIPaddress): int{. +proc udpBind*(sock: PUDPSocket, channel: int, address: var TIPAddress): int{. cdecl, importc: "SDLNet_UDP_Bind", dynlib: NetLibName.} #* Unbind all addresses from the given channel * -proc UDP_Unbind*(sock: PUDPsocket, channel: int){.cdecl, +proc udpUnbind*(sock: PUDPSocket, channel: int){.cdecl, importc: "SDLNet_UDP_Unbind", dynlib: NetLibName.} #* Get the primary IP address of the remote system associated with the # socket and channel. If the channel is -1, then the primary IP port @@ -306,7 +306,7 @@ proc UDP_Unbind*(sock: PUDPsocket, channel: int){.cdecl, # opened with a specific port. # If the channel is not bound and not -1, this function returns NULL. # * -proc UDP_GetPeerAddress*(sock: PUDPsocket, channel: int): PIPAddress{.cdecl, +proc udpGetPeerAddress*(sock: PUDPSocket, channel: int): PIPAddress{.cdecl, importc: "SDLNet_UDP_GetPeerAddress", dynlib: NetLibName.} #* Send a vector of packets to the the channels specified within the packet. # If the channel specified in the packet is -1, the packet will be sent to @@ -315,7 +315,7 @@ proc UDP_GetPeerAddress*(sock: PUDPsocket, channel: int): PIPAddress{.cdecl, # been sent, -1 if the packet send failed. # This function returns the number of packets sent. #* -proc UDP_SendV*(sock: PUDPsocket, packets: PPUDPpacket, npackets: int): int{. +proc udpSendV*(sock: PUDPSocket, packets: PPUDPpacket, npackets: int): int{. cdecl, importc: "SDLNet_UDP_SendV", dynlib: NetLibName.} #* Send a single packet to the specified channel. # If the channel specified in the packet is -1, the packet will be sent to @@ -324,7 +324,7 @@ proc UDP_SendV*(sock: PUDPsocket, packets: PPUDPpacket, npackets: int): int{. # been sent. # This function returns 1 if the packet was sent, or 0 on error. #* -proc UDP_Send*(sock: PUDPsocket, channel: int, packet: PUDPpacket): int{. +proc udpSend*(sock: PUDPSocket, channel: int, packet: PUDPpacket): int{. cdecl, importc: "SDLNet_UDP_Send", dynlib: NetLibName.} #* Receive a vector of pending packets from the UDP socket. # The returned packets contain the source address and the channel they arrived @@ -336,7 +336,7 @@ proc UDP_Send*(sock: PUDPsocket, channel: int, packet: PUDPpacket): int{. # This function returns the number of packets read from the network, or -1 # on error. This function does not block, so can return 0 packets pending. #* -proc UDP_RecvV*(sock: PUDPsocket, packets: PPUDPpacket): int{.cdecl, +proc udpRecvV*(sock: PUDPSocket, packets: PPUDPpacket): int{.cdecl, importc: "SDLNet_UDP_RecvV", dynlib: NetLibName.} #* Receive a single packet from the UDP socket. # The returned packet contains the source address and the channel it arrived @@ -348,10 +348,10 @@ proc UDP_RecvV*(sock: PUDPsocket, packets: PPUDPpacket): int{.cdecl, # This function returns the number of packets read from the network, or -1 # on error. This function does not block, so can return 0 packets pending. #* -proc UDP_Recv*(sock: PUDPsocket, packet: PUDPpacket): int{.cdecl, +proc udpRecv*(sock: PUDPSocket, packet: PUDPpacket): int{.cdecl, importc: "SDLNet_UDP_Recv", dynlib: NetLibName.} #* Close a UDP network socket * -proc UDP_Close*(sock: PUDPsocket){.cdecl, importc: "SDLNet_UDP_Close", +proc udpClose*(sock: PUDPSocket){.cdecl, importc: "SDLNet_UDP_Close", dynlib: NetLibName.} #*********************************************************************** #* Hooks for checking sockets for available data * @@ -360,19 +360,19 @@ proc UDP_Close*(sock: PUDPsocket){.cdecl, importc: "SDLNet_UDP_Close", # This returns a socket set for up to 'maxsockets' sockets, or NULL if # the function ran out of memory. # * -proc AllocSocketSet*(maxsockets: int): PSocketSet{.cdecl, +proc allocSocketSet*(maxsockets: int): PSocketSet{.cdecl, importc: "SDLNet_AllocSocketSet", dynlib: NetLibName.} #* Add a socket to a set of sockets to be checked for available data * -proc AddSocket*(theSet: PSocketSet, sock: PGenericSocket): int{. +proc addSocket*(theSet: PSocketSet, sock: PGenericSocket): int{. cdecl, importc: "SDLNet_AddSocket", dynlib: NetLibName.} -proc TCP_AddSocket*(theSet: PSocketSet, sock: PTCPSocket): int -proc UDP_AddSocket*(theSet: PSocketSet, sock: PUDPSocket): int +proc tcpAddSocket*(theSet: PSocketSet, sock: PTCPSocket): int +proc udpAddSocket*(theSet: PSocketSet, sock: PUDPSocket): int #* Remove a socket from a set of sockets to be checked for available data * -proc DelSocket*(theSet: PSocketSet, sock: PGenericSocket): int{. +proc delSocket*(theSet: PSocketSet, sock: PGenericSocket): int{. cdecl, importc: "SDLNet_DelSocket", dynlib: NetLibName.} -proc TCP_DelSocket*(theSet: PSocketSet, sock: PTCPSocket): int +proc tcpDelSocket*(theSet: PSocketSet, sock: PTCPSocket): int # SDLNet_DelSocket(set, (SDLNet_GenericSocket)sock) -proc UDP_DelSocket*(theSet: PSocketSet, sock: PUDPSocket): int +proc udpDelSocket*(theSet: PSocketSet, sock: PUDPSocket): int #SDLNet_DelSocket(set, (SDLNet_GenericSocket)sock) #* This function checks to see if data is available for reading on the # given set of sockets. If 'timeout' is 0, it performs a quick poll, @@ -381,47 +381,46 @@ proc UDP_DelSocket*(theSet: PSocketSet, sock: PUDPSocket): int # first. This function returns the number of sockets ready for reading, # or -1 if there was an error with the select() system call. #* -proc CheckSockets*(theSet: PSocketSet, timeout: int32): int{.cdecl, +proc checkSockets*(theSet: PSocketSet, timeout: int32): int{.cdecl, importc: "SDLNet_CheckSockets", dynlib: NetLibName.} #* After calling SDLNet_CheckSockets(), you can use this function on a # socket that was in the socket set, to find out if data is available # for reading. #* -proc SocketReady*(sock: PGenericSocket): bool +proc socketReady*(sock: PGenericSocket): bool #* Free a set of sockets allocated by SDL_NetAllocSocketSet() * -proc FreeSocketSet*(theSet: PSocketSet){.cdecl, +proc freeSocketSet*(theSet: PSocketSet){.cdecl, importc: "SDLNet_FreeSocketSet", dynlib: NetLibName.} #*********************************************************************** #* Platform-independent data conversion functions * #*********************************************************************** #* Write a 16/32 bit value to network packet buffer * -proc Write16*(value: Uint16, area: Pointer){.cdecl, +proc write16*(value: uint16, area: pointer){.cdecl, importc: "SDLNet_Write16", dynlib: NetLibName.} -proc Write32*(value: Uint32, area: Pointer){.cdecl, +proc write32*(value: uint32, area: pointer){.cdecl, importc: "SDLNet_Write32", dynlib: NetLibName.} #* Read a 16/32 bit value from network packet buffer * -proc Read16*(area: Pointer): Uint16{.cdecl, importc: "SDLNet_Read16", +proc read16*(area: pointer): uint16{.cdecl, importc: "SDLNet_Read16", dynlib: NetLibName.} -proc Read32*(area: Pointer): Uint32{.cdecl, importc: "SDLNet_Read32", +proc read32*(area: pointer): uint32{.cdecl, importc: "SDLNet_Read32", dynlib: NetLibName.} -proc VERSION(X: var Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version(x: var Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc TCP_AddSocket(theSet: PSocketSet, sock: PTCPSocket): int = - result = AddSocket(theSet, cast[PGenericSocket](sock)) +proc tcpAddSocket(theSet: PSocketSet, sock: PTCPSocket): int = + result = addSocket(theSet, cast[PGenericSocket](sock)) -proc UDP_AddSocket(theSet: PSocketSet, sock: PUDPSocket): int = - result = AddSocket(theSet, cast[PGenericSocket](sock)) +proc udpAddSocket(theSet: PSocketSet, sock: PUDPSocket): int = + result = addSocket(theSet, cast[PGenericSocket](sock)) -proc TCP_DelSocket(theSet: PSocketSet, sock: PTCPSocket): int = - result = DelSocket(theSet, cast[PGenericSocket](sock)) +proc tcpDelSocket(theSet: PSocketSet, sock: PTCPSocket): int = + result = delSocket(theSet, cast[PGenericSocket](sock)) -proc UDP_DelSocket(theSet: PSocketSet, sock: PUDPSocket): int = - result = DelSocket(theSet, cast[PGenericSocket](sock)) - -proc SocketReady(sock: PGenericSocket): bool = - result = ((sock != nil) and (sock.ready == 1)) +proc udpDelSocket(theSet: PSocketSet, sock: PUDPSocket): int = + result = delSocket(theSet, cast[PGenericSocket](sock)) +proc socketReady(sock: PGenericSocket): bool = + result = sock != nil and sock.ready == 1 diff --git a/lib/wrappers/sdl/sdl_ttf.nim b/lib/wrappers/sdl/sdl_ttf.nim index 45247df4d..e0410c798 100644 --- a/lib/wrappers/sdl/sdl_ttf.nim +++ b/lib/wrappers/sdl/sdl_ttf.nim @@ -177,78 +177,78 @@ const UNICODE_BOM_SWAPPED* = 0x0000FFFE type - PFont* = ptr Tfont - TFont{.final.} = object + PFont* = ptr TFont + TFont = object # This macro can be used to fill a version structure with the compile-time # version of the SDL_ttf library. -proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "TTF_Linked_Version", +proc linkedVersion*(): sdl.Pversion{.cdecl, importc: "TTF_Linked_Version", dynlib: ttfLibName.} # This function tells the library whether UNICODE text is generally # byteswapped. A UNICODE BOM character in a string will override # this setting for the remainder of that string. # -proc ByteSwappedUNICODE*(swapped: cint){.cdecl, +proc byteSwappedUNICODE*(swapped: cint){.cdecl, importc: "TTF_ByteSwappedUNICODE", dynlib: ttfLibName.} #returns 0 on succes, -1 if error occurs -proc Init*(): cint{.cdecl, importc: "TTF_Init", dynlib: ttfLibName.} +proc init*(): cint{.cdecl, importc: "TTF_Init", dynlib: ttfLibName.} # # Open a font file and create a font of the specified point size. # Some .fon fonts will have several sizes embedded in the file, so the # point size becomes the index of choosing which size. If the value # is too high, the last indexed size will be the default. # -proc OpenFont*(filename: cstring, ptsize: cint): PFont{.cdecl, +proc openFont*(filename: cstring, ptsize: cint): PFont{.cdecl, importc: "TTF_OpenFont", dynlib: ttfLibName.} -proc OpenFontIndex*(filename: cstring, ptsize: cint, index: int32): PFont{. +proc openFontIndex*(filename: cstring, ptsize: cint, index: int32): PFont{. cdecl, importc: "TTF_OpenFontIndex", dynlib: ttfLibName.} -proc OpenFontRW*(src: PRWops, freesrc: cint, ptsize: cint): PFont{.cdecl, +proc openFontRW*(src: PRWops, freesrc: cint, ptsize: cint): PFont{.cdecl, importc: "TTF_OpenFontRW", dynlib: ttfLibName.} -proc OpenFontIndexRW*(src: PRWops, freesrc: cint, ptsize: cint, index: int32): PFont{. +proc openFontIndexRW*(src: PRWops, freesrc: cint, ptsize: cint, index: int32): PFont{. cdecl, importc: "TTF_OpenFontIndexRW", dynlib: ttfLibName.} -proc GetFontStyle*(font: PFont): cint{.cdecl, +proc getFontStyle*(font: PFont): cint{.cdecl, importc: "TTF_GetFontStyle", dynlib: ttfLibName.} -proc SetFontStyle*(font: PFont, style: cint){.cdecl, +proc setFontStyle*(font: PFont, style: cint){.cdecl, importc: "TTF_SetFontStyle", dynlib: ttfLibName.} # Get the total height of the font - usually equal to point size -proc FontHeight*(font: PFont): cint{.cdecl, importc: "TTF_FontHeight", +proc fontHeight*(font: PFont): cint{.cdecl, importc: "TTF_FontHeight", dynlib: ttfLibName.} # Get the offset from the baseline to the top of the font # This is a positive value, relative to the baseline. # -proc FontAscent*(font: PFont): cint{.cdecl, importc: "TTF_FontAscent", +proc fontAscent*(font: PFont): cint{.cdecl, importc: "TTF_FontAscent", dynlib: ttfLibName.} # Get the offset from the baseline to the bottom of the font # This is a negative value, relative to the baseline. # -proc FontDescent*(font: PFont): cint{.cdecl, importc: "TTF_FontDescent", +proc fontDescent*(font: PFont): cint{.cdecl, importc: "TTF_FontDescent", dynlib: ttfLibName.} # Get the recommended spacing between lines of text for this font -proc FontLineSkip*(font: PFont): cint{.cdecl, +proc fontLineSkip*(font: PFont): cint{.cdecl, importc: "TTF_FontLineSkip", dynlib: ttfLibName.} # Get the number of faces of the font -proc FontFaces*(font: PFont): int32{.cdecl, importc: "TTF_FontFaces", +proc fontFaces*(font: PFont): int32{.cdecl, importc: "TTF_FontFaces", dynlib: ttfLibName.} # Get the font face attributes, if any -proc FontFaceIsFixedWidth*(font: PFont): cint{.cdecl, +proc fontFaceIsFixedWidth*(font: PFont): cint{.cdecl, importc: "TTF_FontFaceIsFixedWidth", dynlib: ttfLibName.} -proc FontFaceFamilyName*(font: PFont): cstring{.cdecl, +proc fontFaceFamilyName*(font: PFont): cstring{.cdecl, importc: "TTF_FontFaceFamilyName", dynlib: ttfLibName.} -proc FontFaceStyleName*(font: PFont): cstring{.cdecl, +proc fontFaceStyleName*(font: PFont): cstring{.cdecl, importc: "TTF_FontFaceStyleName", dynlib: ttfLibName.} # Get the metrics (dimensions) of a glyph -proc GlyphMetrics*(font: PFont, ch: Uint16, minx: var cint, +proc glyphMetrics*(font: PFont, ch: uint16, minx: var cint, maxx: var cint, miny: var cint, maxy: var cint, advance: var cint): cint{.cdecl, importc: "TTF_GlyphMetrics", dynlib: ttfLibName.} # Get the dimensions of a rendered string of text -proc SizeText*(font: PFont, text: cstring, w: var cint, y: var cint): cint{. +proc sizeText*(font: PFont, text: cstring, w: var cint, y: var cint): cint{. cdecl, importc: "TTF_SizeText", dynlib: ttfLibName.} -proc SizeUTF8*(font: PFont, text: cstring, w: var cint, y: var cint): cint{. +proc sizeUTF8*(font: PFont, text: cstring, w: var cint, y: var cint): cint{. cdecl, importc: "TTF_SizeUTF8", dynlib: ttfLibName.} -proc SizeUNICODE*(font: PFont, text: PUint16, w: var cint, y: var cint): cint{. +proc sizeUNICODE*(font: PFont, text: PUInt16, w: var cint, y: var cint): cint{. cdecl, importc: "TTF_SizeUNICODE", dynlib: ttfLibName.} # Create an 8-bit palettized surface and render the given text at # fast quality with the given font and color. The 0 pixel is the @@ -256,9 +256,9 @@ proc SizeUNICODE*(font: PFont, text: PUint16, w: var cint, y: var cint): cint{. # to the text color. # This function returns the new surface, or NULL if there was an error. # -proc RenderUTF8_Solid*(font: PFont, text: cstring, fg: TColor): PSurface{. +proc renderUTF8Solid*(font: PFont, text: cstring, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderUTF8_Solid", dynlib: ttfLibName.} -proc RenderUNICODE_Solid*(font: PFont, text: PUint16, fg: TColor): PSurface{. +proc renderUNICODE_Solid*(font: PFont, text: PUInt16, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderUNICODE_Solid", dynlib: ttfLibName.} # #Create an 8-bit palettized surface and render the given glyph at @@ -268,20 +268,20 @@ proc RenderUNICODE_Solid*(font: PFont, text: PUint16, fg: TColor): PSurface{. # centering in the X direction, and aligned normally in the Y direction. # This function returns the new surface, or NULL if there was an error. # -proc RenderGlyph_Solid*(font: PFont, ch: Uint16, fg: TColor): PSurface{. +proc renderGlyphSolid*(font: PFont, ch: uint16, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderGlyph_Solid", dynlib: ttfLibName.} # Create an 8-bit palettized surface and render the given text at # high quality with the given font and colors. The 0 pixel is background, # while other pixels have varying degrees of the foreground color. # This function returns the new surface, or NULL if there was an error. # -proc RenderText_Shaded*(font: PFont, text: cstring, fg: TColor, +proc renderTextShaded*(font: PFont, text: cstring, fg: TColor, bg: TColor): PSurface{.cdecl, importc: "TTF_RenderText_Shaded", dynlib: ttfLibName.} -proc RenderUTF8_Shaded*(font: PFont, text: cstring, fg: TColor, +proc renderUTF8Shaded*(font: PFont, text: cstring, fg: TColor, bg: TColor): PSurface{.cdecl, importc: "TTF_RenderUTF8_Shaded", dynlib: ttfLibName.} -proc RenderUNICODE_Shaded*(font: PFont, text: PUint16, fg: TColor, +proc renderUNICODE_Shaded*(font: PFont, text: PUInt16, fg: TColor, bg: TColor): PSurface{.cdecl, importc: "TTF_RenderUNICODE_Shaded", dynlib: ttfLibName.} # Create an 8-bit palettized surface and render the given glyph at @@ -291,17 +291,17 @@ proc RenderUNICODE_Shaded*(font: PFont, text: PUint16, fg: TColor, # direction, and aligned normally in the Y direction. # This function returns the new surface, or NULL if there was an error. # -proc RenderGlyph_Shaded*(font: PFont, ch: Uint16, fg: TColor, bg: TColor): PSurface{. +proc renderGlyphShaded*(font: PFont, ch: uint16, fg: TColor, bg: TColor): PSurface{. cdecl, importc: "TTF_RenderGlyph_Shaded", dynlib: ttfLibName.} # Create a 32-bit ARGB surface and render the given text at high quality, # using alpha blending to dither the font with the given color. # This function returns the new surface, or NULL if there was an error. # -proc RenderText_Blended*(font: PFont, text: cstring, fg: TColor): PSurface{. +proc renderTextBlended*(font: PFont, text: cstring, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderText_Blended", dynlib: ttfLibName.} -proc RenderUTF8_Blended*(font: PFont, text: cstring, fg: TColor): PSurface{. +proc renderUTF8Blended*(font: PFont, text: cstring, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderUTF8_Blended", dynlib: ttfLibName.} -proc RenderUNICODE_Blended*(font: PFont, text: PUint16, fg: TColor): PSurface{. +proc RenderUNICODE_Blended*(font: PFont, text: PUInt16, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderUNICODE_Blended", dynlib: ttfLibName.} # Create a 32-bit ARGB surface and render the given glyph at high quality, # using alpha blending to dither the font with the given color. @@ -309,29 +309,29 @@ proc RenderUNICODE_Blended*(font: PFont, text: PUint16, fg: TColor): PSurface{. # direction, and aligned normally in the Y direction. # This function returns the new surface, or NULL if there was an error. # -proc RenderGlyph_Blended*(font: PFont, ch: Uint16, fg: TColor): PSurface{. +proc renderGlyphBlended*(font: PFont, ch: uint16, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderGlyph_Blended", dynlib: ttfLibName.} # For compatibility with previous versions, here are the old functions - ##define TTF_RenderText(font, text, fg, bg) + # #define TTF_RenderText(font, text, fg, bg) # TTF_RenderText_Shaded(font, text, fg, bg) - ##define TTF_RenderUTF8(font, text, fg, bg) + # #define TTF_RenderUTF8(font, text, fg, bg) # TTF_RenderUTF8_Shaded(font, text, fg, bg) - ##define TTF_RenderUNICODE(font, text, fg, bg) + # #define TTF_RenderUNICODE(font, text, fg, bg) # TTF_RenderUNICODE_Shaded(font, text, fg, bg) - # Close an opened font file -proc CloseFont*(font: PFont){.cdecl, importc: "TTF_CloseFont", + # Close an opened font file +proc closeFont*(font: PFont){.cdecl, importc: "TTF_CloseFont", dynlib: ttfLibName.} - #De-initialize TTF engine -proc Quit*(){.cdecl, importc: "TTF_Quit", dynlib: ttfLibName.} + # De-initialize TTF engine +proc quit*(){.cdecl, importc: "TTF_Quit", dynlib: ttfLibName.} # Check if the TTF engine is initialized -proc WasInit*(): cint{.cdecl, importc: "TTF_WasInit", dynlib: ttfLibName.} +proc wasInit*(): cint{.cdecl, importc: "TTF_WasInit", dynlib: ttfLibName.} -proc VERSION*(X: var sdl.Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL +proc version*(x: var sdl.Tversion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL -proc RenderText_Solid*(font: PFont, text: cstring, fg: TColor): PSurface{. +proc renderTextSolid*(font: PFont, text: cstring, fg: TColor): PSurface{. cdecl, importc: "TTF_RenderText_Solid", dynlib: ttfLibName.} diff --git a/lib/wrappers/sdl/smpeg.nim b/lib/wrappers/sdl/smpeg.nim index 33f317631..318c0b3df 100644 --- a/lib/wrappers/sdl/smpeg.nim +++ b/lib/wrappers/sdl/smpeg.nim @@ -125,7 +125,7 @@ # #****************************************************************************** -import +import sdl when defined(windows): @@ -143,29 +143,29 @@ const type TFilterInfo*{.final.} = object - yuv_mb_square_error*: PUint16 - yuv_pixel_square_error*: PUint16 + yuvMbSquareError*: PUInt16 + yuvPixelSquareError*: PUInt16 PFilterInfo* = ptr TFilterInfo # MPEG filter definition PFilter* = ptr TFilter # Callback functions for the filter TFilterCallback* = proc (dest, source: POverlay, region: PRect, - filter_info: PFilterInfo, data: Pointer): Pointer{. + filterInfo: PFilterInfo, data: pointer): pointer{. cdecl.} - TFilterDestroy* = proc (Filter: PFilter): Pointer{.cdecl.} # The filter definition itself + TFilterDestroy* = proc (filter: PFilter): pointer{.cdecl.} # The filter definition itself TFilter*{.final.} = object # The null filter (default). It simply copies the source rectangle to the video overlay. - flags*: Uint32 - data*: Pointer + flags*: uint32 + data*: pointer callback*: TFilterCallback destroy*: TFilterDestroy -proc filter_null*(): PFilter{.cdecl, importc: "SMPEGfilter_null", +proc filterNull*(): PFilter{.cdecl, importc: "SMPEGfilter_null", dynlib: SmpegLibName.} # The bilinear filter. A basic low-pass filter that will produce a smoother image. -proc filter_bilinear*(): PFilter{.cdecl, +proc filterBilinear*(): PFilter{.cdecl, importc: "SMPEGfilter_bilinear", dynlib: SmpegLibName.} # The deblocking filter. It filters block borders and non-intra coded blocks to reduce blockiness -proc filter_deblocking*(): PFilter{.cdecl, +proc filterDeblocking*(): PFilter{.cdecl, importc: "SMPEGfilter_deblocking", dynlib: SmpegLibName.} #------------------------------------------------------------------------------ # SMPEG.h @@ -175,28 +175,28 @@ const MINOR_VERSION* = 4 PATCHLEVEL* = 2 -type - TVersion*{.final.} = object +type + TVersion* = object major*: byte minor*: byte patch*: byte - Pversion* = ptr Tversion # This is the actual SMPEG object - TSMPEG*{.final.} = object + Pversion* = ptr TVersion # This is the actual SMPEG object + TSMPEG* = object PSMPEG* = ptr TSMPEG # Used to get information about the SMPEG object - TInfo*{.final.} = object - has_audio*: int32 - has_video*: int32 + TInfo* = object + hasAudio*: int32 + hasVideo*: int32 width*: int32 height*: int32 - current_frame*: int32 - current_fps*: float64 - audio_string*: array[0..79, char] - audio_current_frame*: int32 - current_offset*: UInt32 - total_size*: UInt32 - current_time*: float64 - total_time*: float64 + currentFrame*: int32 + currentFps*: float64 + audioString*: array[0..79, char] + audioCurrentFrame*: int32 + currentOffset*: uint32 + totalSize*: uint32 + currentTime*: float64 + totalTime*: float64 PInfo* = ptr TInfo # Possible MPEG status codes @@ -208,7 +208,7 @@ const type Tstatus* = int32 Pstatus* = ptr int32 # Matches the declaration of SDL_UpdateRect() - TDisplayCallback* = proc (dst: PSurface, x, y: int, w, h: int): Pointer{. + TDisplayCallback* = proc (dst: PSurface, x, y: int, w, h: int): pointer{. cdecl.} # Create a new SMPEG object from an MPEG file. # On return, if 'info' is not NULL, it will be filled with information # about the MPEG object. @@ -218,15 +218,15 @@ type # subsystem. If not, you will have to use the playaudio() function below # to extract the decoded data. -proc SMPEG_new*(theFile: cstring, info: PInfo, audio: int): PSMPEG{.cdecl, +proc new*(theFile: cstring, info: PInfo, audio: int): PSMPEG{.cdecl, importc: "SMPEG_new", dynlib: SmpegLibName.} # The same as above for a file descriptor -proc new_descr*(theFile: int, info: PInfo, audio: int): PSMPEG{. +proc newDescr*(theFile: int, info: PInfo, audio: int): PSMPEG{. cdecl, importc: "SMPEG_new_descr", dynlib: SmpegLibName.} # The same as above but for a raw chunk of data. SMPEG makes a copy of the # data, so the application is free to delete after a successful call to this # function. -proc new_data*(data: Pointer, size: int, info: PInfo, audio: int): PSMPEG{. +proc newData*(data: pointer, size: int, info: PInfo, audio: int): PSMPEG{. cdecl, importc: "SMPEG_new_data", dynlib: SmpegLibName.} # Get current information about an SMPEG object proc getinfo*(mpeg: PSMPEG, info: PInfo){.cdecl, @@ -247,13 +247,13 @@ proc status*(mpeg: PSMPEG): Tstatus{.cdecl, importc: "SMPEG_status", dynlib: SmpegLibName.} # status # Set the audio volume of an MPEG stream, in the range 0-100 -proc setvolume*(mpeg: PSMPEG, volume: int){.cdecl, +proc setVolume*(mpeg: PSMPEG, volume: int){.cdecl, importc: "SMPEG_setvolume", dynlib: SmpegLibName.} # Set the destination surface for MPEG video playback # 'surfLock' is a mutex used to synchronize access to 'dst', and can be NULL. # 'callback' is a function called when an area of 'dst' needs to be updated. # If 'callback' is NULL, the default function (SDL_UpdateRect) will be used. -proc setdisplay*(mpeg: PSMPEG, dst: PSurface, surfLock: Pmutex, +proc setDisplay*(mpeg: PSMPEG, dst: PSurface, surfLock: PMutex, callback: TDisplayCallback){.cdecl, importc: "SMPEG_setdisplay", dynlib: SmpegLibName.} # Set or clear looping play on an SMPEG object @@ -264,12 +264,12 @@ proc scaleXY*(mpeg: PSMPEG, width, height: int){.cdecl, importc: "SMPEG_scaleXY", dynlib: SmpegLibName.} proc scale*(mpeg: PSMPEG, scale: int){.cdecl, importc: "SMPEG_scale", dynlib: SmpegLibName.} -proc Double*(mpeg: PSMPEG, doubleit: bool) +proc double*(mpeg: PSMPEG, doubleit: bool) # Move the video display area within the destination surface proc move*(mpeg: PSMPEG, x, y: int){.cdecl, importc: "SMPEG_move", dynlib: SmpegLibName.} # Set the region of the video to be shown -proc setdisplayregion*(mpeg: PSMPEG, x, y, w, h: int){.cdecl, +proc setDisplayRegion*(mpeg: PSMPEG, x, y, w, h: int){.cdecl, importc: "SMPEG_setdisplayregion", dynlib: SmpegLibName.} # Play an SMPEG object proc play*(mpeg: PSMPEG){.cdecl, importc: "SMPEG_play", @@ -312,7 +312,7 @@ proc error*(mpeg: PSMPEG): cstring{.cdecl, importc: "SMPEG_error", proc playAudio*(mpeg: PSMPEG, stream: pointer, length: int): int{.cdecl, importc: "SMPEG_playAudio", dynlib: SmpegLibName.} # Wrapper for playAudio() that can be passed to SDL and SDL_mixer -proc playAudioSDL*(mpeg: Pointer, stream: pointer, length: int){.cdecl, +proc playAudioSDL*(mpeg: pointer, stream: pointer, length: int){.cdecl, importc: "SMPEG_playAudioSDL", dynlib: SmpegLibName.} # Get the best SDL audio spec for the audio stream proc wantedSpec*(mpeg: PSMPEG, wanted: PAudioSpec): int{.cdecl, @@ -322,14 +322,11 @@ proc actualSpec*(mpeg: PSMPEG, spec: PAudioSpec){.cdecl, importc: "SMPEG_actualSpec", dynlib: SmpegLibName.} # This macro can be used to fill a version structure with the compile-time # version of the SDL library. -proc GETVERSION*(X: var Tversion) -# implementation +proc getversion*(x: var TVersion) = + x.major = MAJOR_VERSION + x.minor = MINOR_VERSION + x.patch = PATCHLEVEL proc double(mpeg: PSMPEG, doubleit: bool) = if doubleit: scale(mpeg, 2) else: scale(mpeg, 1) - -proc GETVERSION(X: var Tversion) = - X.major = MAJOR_VERSION - X.minor = MINOR_VERSION - X.patch = PATCHLEVEL From 4367fb26adf3111aac8a9b4078c0126a8e215077 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 18 Sep 2014 23:35:08 +0200 Subject: [PATCH 144/409] updated graphics.nim --- lib/impure/graphics.nim | 236 +++++++++++++++++++-------------------- lib/wrappers/sdl/sdl.nim | 26 ++--- 2 files changed, 131 insertions(+), 131 deletions(-) diff --git a/lib/impure/graphics.nim b/lib/impure/graphics.nim index dda7626ba..dfadb46ee 100644 --- a/lib/impure/graphics.nim +++ b/lib/impure/graphics.nim @@ -14,7 +14,7 @@ import colors, math from sdl import PSurface # Bug -from sdl_ttf import OpenFont, closeFont +from sdl_ttf import openFont, closeFont type TRect* = tuple[x, y, width, height: int] @@ -25,24 +25,24 @@ type w*, h*: Natural s*: sdl.PSurface - EGraphics* = object of EIO + EGraphics* = object of IOError TFont {.pure, final.} = object f: sdl_ttf.PFont - color: SDL.TColor + color: sdl.TColor PFont* = ref TFont ## represents a font -proc toSdlColor*(c: TColor): Sdl.TColor = - ## Convert colors.TColor to SDL.TColor +proc toSdlColor*(c: Color): sdl.TColor = + ## Convert colors.TColor to sdl.TColor var x = c.extractRGB result.r = x.r and 0xff result.g = x.g and 0xff result.b = x.b and 0xff -proc createSdlColor*(sur: PSurface, c: TColor, alpha: int = 0): int32 = +proc createSdlColor*(sur: PSurface, c: Color, alpha: int = 0): int32 = ## Creates a color using ``sdl.MapRGBA``. var x = c.extractRGB - return sdl.MapRGBA(sur.s.format, x.r and 0xff, x.g and 0xff, + return sdl.mapRGBA(sur.s.format, x.r and 0xff, x.g and 0xff, x.b and 0xff, alpha and 0xff) proc toSdlRect*(r: TRect): sdl.TRect = @@ -53,7 +53,7 @@ proc toSdlRect*(r: TRect): sdl.TRect = result.h = uint16(r.height) proc raiseEGraphics = - raise newException(EGraphics, $SDL.GetError()) + raise newException(EGraphics, $sdl.getError()) proc surfaceFinalizer(s: PSurface) = sdl.freeSurface(s.s) @@ -62,21 +62,21 @@ proc newSurface*(width, height: int): PSurface = new(result, surfaceFinalizer) result.w = width result.h = height - result.s = SDL.CreateRGBSurface(SDL.SWSURFACE, width, height, + result.s = sdl.createRGBSurface(sdl.SWSURFACE, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0) if result.s == nil: raiseEGraphics() - assert(not sdl.MustLock(result.s)) + assert(not sdl.mustLock(result.s)) proc fontFinalizer(f: PFont) = closeFont(f.f) proc newFont*(name = "VeraMono.ttf", size = 9, color = colBlack): PFont = ## Creates a new font object. Raises ``EIO`` if the font cannot be loaded. new(result, fontFinalizer) - result.f = OpenFont(name, size.cint) + result.f = openFont(name, size.cint) if result.f == nil: - raise newException(EIO, "Could not open font file: " & name) + raise newException(IOError, "Could not open font file: " & name) result.color = toSdlColor(color) var @@ -92,7 +92,7 @@ proc newScreenSurface*(width, height: int): PSurface = new(result, surfaceFinalizer) result.w = width result.h = height - result.s = SDL.SetVideoMode(width, height, 0, 0) + result.s = sdl.setVideoMode(width, height, 0, 0) if result.s == nil: raiseEGraphics() @@ -100,7 +100,7 @@ proc writeToBMP*(sur: PSurface, filename: string) = ## Saves the contents of the surface `sur` to the file `filename` as a ## BMP file. if sdl.saveBMP(sur.s, filename) != 0: - raise newException(EIO, "cannot write: " & filename) + raise newException(IOError, "cannot write: " & filename) type TPixels = array[0..1000_000-1, int32] @@ -110,44 +110,44 @@ template setPix(video, pitch, x, y, col: expr): stmt = video[y * pitch + x] = int32(col) template getPix(video, pitch, x, y: expr): expr = - colors.TColor(video[y * pitch + x]) + colors.Color(video[y * pitch + x]) const ColSize = 4 -proc getPixel(sur: PSurface, x, y: Natural): colors.TColor {.inline.} = +proc getPixel(sur: PSurface, x, y: Natural): colors.Color {.inline.} = assert x <% sur.w assert y <% sur.h result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch.int div ColSize, x, y) -proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) {.inline.} = +proc setPixel(sur: PSurface, x, y: Natural, col: colors.Color) {.inline.} = assert x <% sur.w assert y <% sur.h var pixs = cast[PPixels](sur.s.pixels) #pixs[y * (sur.s.pitch div colSize) + x] = int(col) setPix(pixs, sur.s.pitch.int div ColSize, x, y, col) -proc `[]`*(sur: PSurface, p: TPoint): TColor = +proc `[]`*(sur: PSurface, p: TPoint): Color = ## get pixel at position `p`. No range checking is done! result = getPixel(sur, p.x, p.y) -proc `[]`*(sur: PSurface, x, y: int): TColor = +proc `[]`*(sur: PSurface, x, y: int): Color = ## get pixel at position ``(x, y)``. No range checking is done! result = getPixel(sur, x, y) -proc `[]=`*(sur: PSurface, p: TPoint, col: TColor) = +proc `[]=`*(sur: PSurface, p: TPoint, col: Color) = ## set the pixel at position `p`. No range checking is done! setPixel(sur, p.x, p.y, col) -proc `[]=`*(sur: PSurface, x, y: int, col: TColor) = +proc `[]=`*(sur: PSurface, x, y: int, col: Color) = ## set the pixel at position ``(x, y)``. No range checking is done! setPixel(sur, x, y, col) proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcRect: TRect) = ## Copies ``srcSurf`` into ``destSurf`` - var destTRect, srcTRect: SDL.TRect + var destTRect, srcTRect: sdl.TRect destTRect.x = int16(destRect.x) destTRect.y = int16(destRect.y) @@ -159,12 +159,12 @@ proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcTRect.w = uint16(srcRect.width) srcTRect.h = uint16(srcRect.height) - if SDL.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0: + if sdl.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0: raiseEGraphics() proc textBounds*(text: string, font = defaultFont): tuple[width, height: int] = var w, h: cint - if sdl_ttf.SizeUTF8(font.f, text, w, h) < 0: raiseEGraphics() + if sdl_ttf.sizeUTF8(font.f, text, w, h) < 0: raiseEGraphics() result.width = int(w) result.height = int(h) @@ -175,21 +175,21 @@ proc drawText*(sur: PSurface, p: TPoint, text: string, font = defaultFont) = new(textSur, surfaceFinalizer) # Render the text - textSur.s = sdl_ttf.RenderTextBlended(font.f, text, font.color) + textSur.s = sdl_ttf.renderTextBlended(font.f, text, font.color) # Merge the text surface with sur sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h)) proc drawText*(sur: PSurface, p: TPoint, text: string, - bg: TColor, font = defaultFont) = + bg: Color, font = defaultFont) = ## Draws text, at location ``p`` with font ``font``. ``bg`` ## is the background color. var textSur: PSurface # This surface will have the text drawn on it new(textSur, surfaceFinalizer) - textSur.s = sdl_ttf.RenderTextShaded(font.f, text, font.color, toSdlColor(bg)) + textSur.s = sdl_ttf.renderTextShaded(font.f, text, font.color, toSdlColor(bg)) # Merge the text surface with sur sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h)) -proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) = +proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: Color) = ## draws a circle with center `p` and radius `r` with the given color ## onto the surface `sur`. var video = cast[PPixels](sur.s.pixels) @@ -229,7 +229,7 @@ proc `>-<`(val: int, s: PSurface): int {.inline.} = proc `>|<`(val: int, s: PSurface): int {.inline.} = return if val < 0: 0 elif val >= s.h: s.h-1 else: val -proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) = +proc drawLine*(sur: PSurface, p1, p2: TPoint, color: Color) = ## draws a line between the two points `p1` and `p2` with the given color ## onto the surface `sur`. var stepx, stepy: int = 0 @@ -273,7 +273,7 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) = fraction = fraction + dx setPix(video, pitch, x0, y0, color) -proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) = +proc drawHorLine*(sur: PSurface, x, y, w: Natural, color: Color) = ## draws a horizontal line from (x,y) to (x+w-1, y). var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize @@ -282,7 +282,7 @@ proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) = for i in 0 .. min(sur.s.w-x, w)-1: setPix(video, pitch, x + i, y, color) -proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) = +proc drawVerLine*(sur: PSurface, x, y, h: Natural, color: Color) = ## draws a vertical line from (x,y) to (x, y+h-1). var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize @@ -291,7 +291,7 @@ proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) = for i in 0 .. min(sur.s.h-y, h)-1: setPix(video, pitch, x, y + i, color) -proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) = +proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: Color) = ## draws a circle with center `p` and radius `r` with the given color ## onto the surface `sur` and fills it. var a = 1 - r @@ -301,11 +301,11 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) = var y = p.y while px <= py: # Fill up the middle half of the circle - DrawVerLine(s, x + px, y, py + 1, color) - DrawVerLine(s, x + px, y - py, py, color) + drawVerLine(s, x + px, y, py + 1, color) + drawVerLine(s, x + px, y - py, py, color) if px != 0: - DrawVerLine(s, x - px, y, py + 1, color) - DrawVerLine(s, x - px, y - py, py, color) + drawVerLine(s, x - px, y, py + 1, color) + drawVerLine(s, x - px, y - py, py, color) if a < 0: a = a + (2 * px + 3) else: @@ -313,13 +313,13 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) = py = py - 1 # Fill up the left/right half of the circle if py >= px: - DrawVerLine(s, x + py + 1, y, px + 1, color) - DrawVerLine(s, x + py + 1, y - px, px, color) - DrawVerLine(s, x - py - 1, y, px + 1, color) - DrawVerLine(s, x - py - 1, y - px, px, color) + drawVerLine(s, x + py + 1, y, px + 1, color) + drawVerLine(s, x + py + 1, y - px, px, color) + drawVerLine(s, x - py - 1, y, px + 1, color) + drawVerLine(s, x - py - 1, y - px, px, color) px = px + 1 -proc drawRect*(sur: PSurface, r: TRect, color: TColor) = +proc drawRect*(sur: PSurface, r: TRect, color: Color) = ## draws a rectangle. var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize @@ -337,78 +337,78 @@ proc drawRect*(sur: PSurface, r: TRect, color: TColor) = setPix(video, pitch, r.x, r.y + i, color) setPix(video, pitch, r.x + minW - 1, r.y + i, color) # Draw right side -proc fillRect*(sur: PSurface, r: TRect, col: TColor) = +proc fillRect*(sur: PSurface, r: TRect, col: Color) = ## Fills a rectangle using sdl's ``FillRect`` function. var rect = toSdlRect(r) - if sdl.FillRect(sur.s, addr(rect), sur.createSdlColor(col)) == -1: + if sdl.fillRect(sur.s, addr(rect), sur.createSdlColor(col)) == -1: raiseEGraphics() -proc plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) = +proc plot4EllipsePoints(sur: PSurface, cx, cy, x, y: Natural, col: Color) = var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize - if CX+X <= sur.s.w-1: - if CY+Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY+Y, col) - if CY-Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY-Y, col) - if CX-X <= sur.s.w-1: - if CY+Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY+Y, col) - if CY-Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY-Y, col) + if cx+x <= sur.s.w-1: + if cy+y <= sur.s.h-1: setPix(video, pitch, cx+x, cy+y, col) + if cy-y <= sur.s.h-1: setPix(video, pitch, cx+x, cy-y, col) + if cx-x <= sur.s.w-1: + if cy+y <= sur.s.h-1: setPix(video, pitch, cx-x, cy+y, col) + if cy-y <= sur.s.h-1: setPix(video, pitch, cx-x, cy-y, col) -proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural, - col: TColor) = +proc drawEllipse*(sur: PSurface, cx, cy, xRadius, yRadius: Natural, + col: Color) = ## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the ## ellipse, ``XRadius`` and ``YRadius`` specify half the width and height ## of the ellipse. var - X, Y: Natural - XChange, YChange: Int - EllipseError: Natural - TwoASquare, TwoBSquare: Natural - StoppingX, StoppingY: Natural + x, y: Natural + xChange, yChange: int + ellipseError: Natural + twoASquare, twoBSquare: Natural + stoppingX, stoppingY: Natural - TwoASquare = 2 * XRadius * XRadius - TwoBSquare = 2 * YRadius * YRadius - X = XRadius - Y = 0 - XChange = YRadius * YRadius * (1 - 2 * XRadius) - YChange = XRadius * XRadius - EllipseError = 0 - StoppingX = TwoBSquare * XRadius - StoppingY = 0 + twoASquare = 2 * xRadius * xRadius + twoBSquare = 2 * yRadius * yRadius + x = xRadius + y = 0 + xChange = yRadius * yRadius * (1 - 2 * xRadius) + yChange = xRadius * xRadius + ellipseError = 0 + stoppingX = twoBSquare * xRadius + stoppingY = 0 - while StoppingX >= StoppingY: # 1st set of points, y` > - 1 - sur.Plot4EllipsePoints(CX, CY, X, Y, col) - inc(Y) - inc(StoppingY, TwoASquare) - inc(EllipseError, YChange) - inc(YChange, TwoASquare) - if (2 * EllipseError + XChange) > 0 : + while stoppingX >= stoppingY: # 1st set of points, y` > - 1 + sur.plot4EllipsePoints(cx, cy, x, y, col) + inc(y) + inc(stoppingY, twoASquare) + inc(ellipseError, yChange) + inc(yChange, twoASquare) + if (2 * ellipseError + xChange) > 0 : dec(x) - dec(StoppingX, TwoBSquare) - inc(EllipseError, XChange) - inc(XChange, TwoBSquare) + dec(stoppingX, twoBSquare) + inc(ellipseError, xChange) + inc(xChange, twoBSquare) # 1st point set is done; start the 2nd set of points - X = 0 - Y = YRadius - XChange = YRadius * YRadius - YChange = XRadius * XRadius * (1 - 2 * YRadius) - EllipseError = 0 - StoppingX = 0 - StoppingY = TwoASquare * YRadius - while StoppingX <= StoppingY: - sur.Plot4EllipsePoints(CX, CY, X, Y, col) - inc(X) - inc(StoppingX, TwoBSquare) - inc(EllipseError, XChange) - inc(XChange,TwoBSquare) - if (2 * EllipseError + YChange) > 0: - dec(Y) - dec(StoppingY, TwoASquare) - inc(EllipseError, YChange) - inc(YChange,TwoASquare) + x = 0 + y = yRadius + xChange = yRadius * yRadius + yChange = xRadius * xRadius * (1 - 2 * yRadius) + ellipseError = 0 + stoppingX = 0 + stoppingY = twoASquare * yRadius + while stoppingX <= stoppingY: + sur.plot4EllipsePoints(cx, cy, x, y, col) + inc(x) + inc(stoppingX, twoBSquare) + inc(ellipseError, xChange) + inc(xChange,twoBSquare) + if (2 * ellipseError + yChange) > 0: + dec(y) + dec(stoppingY, twoASquare) + inc(ellipseError, yChange) + inc(yChange,twoASquare) -proc plotAA(sur: PSurface, x, y: int, c: float, color: TColor) = +proc plotAA(sur: PSurface, x, y: int, c: float, color: Color) = if (x > 0 and x < sur.s.w) and (y > 0 and y < sur.s.h): var video = cast[PPixels](sur.s.pixels) var pitch = sur.s.pitch.int div ColSize @@ -424,7 +424,7 @@ template cround(x: expr): expr = ipart(x + 0.5) template fpart(x: expr): expr = x - ipart(x) template rfpart(x: expr): expr = 1.0 - fpart(x) -proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) = +proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: Color) = ## Draws a anti-aliased line from ``p1`` to ``p2``, using Xiaolin Wu's ## line algorithm var (x1, x2, y1, y2) = (p1.x.toFloat(), p2.x.toFloat(), @@ -444,11 +444,11 @@ proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) = swap(x2, y2) swap(dx, dy) - template doPlot(x, y: int, c: float, color: TColor): stmt = + template doPlot(x, y: int, c: float, color: Color): stmt = if ax < ay: - sur.PlotAA(y, x, c, color) + sur.plotAA(y, x, c, color) else: - sur.PlotAA(x, y, c, color) + sur.plotAA(x, y, c, color) if x2 < x1: swap(x1, x2) @@ -482,22 +482,22 @@ proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) = intery = intery + gradient inc(x) -proc fillSurface*(sur: PSurface, color: TColor) = +proc fillSurface*(sur: PSurface, color: Color) = ## Fills the entire surface with ``color``. - if sdl.FillRect(sur.s, nil, sur.createSdlColor(color)) == -1: + if sdl.fillRect(sur.s, nil, sur.createSdlColor(color)) == -1: raiseEGraphics() template withEvents*(surf: PSurface, event: expr, actions: stmt): stmt {. immediate.} = ## Simple template which creates an event loop. ``Event`` is the name of the ## variable containing the TEvent object. - while True: - var event: SDL.TEvent - if SDL.WaitEvent(addr(event)) == 1: + while true: + var event: sdl.TEvent + if sdl.waitEvent(addr(event)) == 1: actions -if sdl.Init(sdl.INIT_VIDEO) < 0: raiseEGraphics() -if sdl_ttf.Init() < 0: raiseEGraphics() +if sdl.init(sdl.INIT_VIDEO) < 0: raiseEGraphics() +if sdl_ttf.init() < 0: raiseEGraphics() when isMainModule: var surf = newScreenSurface(800, 600) @@ -539,19 +539,19 @@ when isMainModule: withEvents(surf, event): var eventp = addr(event) case event.kind: - of SDL.QUITEV: + of sdl.QUITEV: break - of SDL.KEYDOWN: - var evk = sdl.EvKeyboard(eventp) - if evk.keysym.sym == SDL.K_LEFT: + of sdl.KEYDOWN: + var evk = sdl.evKeyboard(eventp) + if evk.keysym.sym == sdl.K_LEFT: surf.drawHorLine(395, 300, 50, colBlack) echo("Drawing") - elif evk.keysym.sym == SDL.K_ESCAPE: + elif evk.keysym.sym == sdl.K_ESCAPE: break else: echo(evk.keysym.sym) - of SDL.MOUSEBUTTONDOWN: - var mbd = sdl.EvMouseButton(eventp) + of sdl.MOUSEBUTTONDOWN: + var mbd = sdl.evMouseButton(eventp) if mouseStartX == -1 or mouseStartY == -1: mouseStartX = int(mbd.x) mouseStartY = int(mbd.y) @@ -560,16 +560,16 @@ when isMainModule: mouseStartX = -1 mouseStartY = -1 - of SDL.MouseMotion: - var mm = sdl.EvMouseMotion(eventp) + of sdl.MOUSEMOTION: + var mm = sdl.evMouseMotion(eventp) if mouseStartX != -1 and mouseStartY != -1: surf.drawLineAA((mouseStartX, mouseStartY), (int(mm.x), int(mm.y)), colPurple) #echo(mm.x, " ", mm.y, " ", mm.yrel) else: - #echo(event.kind) + discard "echo(event.kind)" - SDL.UpdateRect(surf.s, 0, 0, 800, 600) + sdl.updateRect(surf.s, 0, 0, 800, 600) surf.writeToBMP("test.bmp") - SDL.Quit() + sdl.quit() diff --git a/lib/wrappers/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim index e09dfd59a..449b651f9 100644 --- a/lib/wrappers/sdl/sdl.nim +++ b/lib/wrappers/sdl/sdl.nim @@ -1287,19 +1287,19 @@ template evconv(procName: expr, ptrName: typedesc, assertions: TEventSeq): stmt assert(contains(assertions, event.kind)) result = cast[ptrName](event) -evconv(EvActive, PActiveEvent, {ACTIVEEVENT}) -evconv(EvKeyboard, PKeyboardEvent, {KEYDOWN, KEYUP}) -evconv(EvMouseMotion, PMouseMotionEvent, {MOUSEMOTION}) -evconv(EvMouseButton, PMouseButtonEvent, {MOUSEBUTTONDOWN, MOUSEBUTTONUP}) -evconv(EvJoyAxis, PJoyAxisEvent,{JOYAXISMOTION}) -evconv(EvJoyBall, PJoyBallEvent, {JOYBALLMOTION}) -evconv(EvJoyHat, PJoyHatEvent, {JOYHATMOTION}) -evconv(EvJoyButton, PJoyButtonEvent, {JOYBUTTONDOWN, JOYBUTTONUP}) -evconv(EvResize, PResizeEvent, {VIDEORESIZE}) -evconv(EvExpose, PExposeEvent, {VIDEOEXPOSE}) -evconv(EvQuit, PQuitEvent, {QUITEV}) -evconv(EvUser, PUserEvent, {USEREVENT}) -evconv(EvSysWM, PSysWMEvent, {SYSWMEVENT}) +evconv(evActive, PActiveEvent, {ACTIVEEVENT}) +evconv(evKeyboard, PKeyboardEvent, {KEYDOWN, KEYUP}) +evconv(evMouseMotion, PMouseMotionEvent, {MOUSEMOTION}) +evconv(evMouseButton, PMouseButtonEvent, {MOUSEBUTTONDOWN, MOUSEBUTTONUP}) +evconv(evJoyAxis, PJoyAxisEvent,{JOYAXISMOTION}) +evconv(evJoyBall, PJoyBallEvent, {JOYBALLMOTION}) +evconv(evJoyHat, PJoyHatEvent, {JOYHATMOTION}) +evconv(evJoyButton, PJoyButtonEvent, {JOYBUTTONDOWN, JOYBUTTONUP}) +evconv(evResize, PResizeEvent, {VIDEORESIZE}) +evconv(evExpose, PExposeEvent, {VIDEOEXPOSE}) +evconv(evQuit, PQuitEvent, {QUITEV}) +evconv(evUser, PUserEvent, {USEREVENT}) +evconv(evSysWM, PSysWMEvent, {SYSWMEVENT}) #------------------------------------------------------------------------------ # initialization From d4bc11b654384ffbccef8b2f549513f2c5a8fdc0 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 19 Sep 2014 00:54:01 +0200 Subject: [PATCH 145/409] cleaned up various modules --- lib/impure/db_postgres.nim | 10 ++++----- lib/impure/osinfo_posix.nim | 31 ++++++++++++++-------------- lib/impure/osinfo_win.nim | 10 ++++----- lib/impure/rdstdin.nim | 8 +++---- lib/impure/zipfiles.nim | 20 +++++++++--------- lib/wrappers/expat.nim | 8 +++---- lib/wrappers/postgres.nim | 14 ++++++------- lib/wrappers/readline/history.nim | 2 +- lib/wrappers/readline/readline.nim | 10 ++++----- lib/wrappers/readline/rltypedefs.nim | 2 +- lib/wrappers/zip/libzip.nim | 12 +++++------ web/nim.ini | 2 +- 12 files changed, 65 insertions(+), 64 deletions(-) diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index 116356489..6ea2bdbee 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -16,14 +16,14 @@ type TDbConn* = PPGconn ## encapsulates a database connection TRow* = seq[string] ## a row of a dataset. NULL database values will be ## transformed always to the empty string. - EDb* = object of EIO ## exception that is raised if a database error occurs + EDb* = object of IOError ## exception that is raised if a database error occurs TSqlQuery* = distinct string ## an SQL query string - FDb* = object of FIO ## effect that denotes a database operation - FReadDb* = object of FDB ## effect that denotes a read operation - FWriteDb* = object of FDB ## effect that denotes a write operation - + FDb* = object of IOEffect ## effect that denotes a database operation + FReadDb* = object of FDb ## effect that denotes a read operation + FWriteDb* = object of FDb ## effect that denotes a write operation + proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} = ## constructs a TSqlQuery from the string `query`. This is supposed to be ## used as a raw-string-literal modifier: diff --git a/lib/impure/osinfo_posix.nim b/lib/impure/osinfo_posix.nim index 4fde82012..1baff8c55 100644 --- a/lib/impure/osinfo_posix.nim +++ b/lib/impure/osinfo_posix.nim @@ -1,20 +1,21 @@ import posix, strutils, os -type - Tstatfs {.importc: "struct statfs64", - header: "", final, pure.} = object - f_type: int - f_bsize: int - f_blocks: int - f_bfree: int - f_bavail: int - f_files: int - f_ffree: int - f_fsid: int - f_namelen: int +when false: + type + Tstatfs {.importc: "struct statfs64", + header: "", final, pure.} = object + f_type: int + f_bsize: int + f_blocks: int + f_bfree: int + f_bavail: int + f_files: int + f_ffree: int + f_fsid: int + f_namelen: int -proc statfs(path: string, buf: var Tstatfs): int {. - importc, header: "".} + proc statfs(path: string, buf: var Tstatfs): int {. + importc, header: "".} proc getSystemVersion*(): string = @@ -23,7 +24,7 @@ proc getSystemVersion*(): string = var unix_info: TUtsname if uname(unix_info) != 0: - os.OSError() + os.raiseOSError(osLastError()) if $unix_info.sysname == "Linux": # Linux diff --git a/lib/impure/osinfo_win.nim b/lib/impure/osinfo_win.nim index 572e50273..f423a34a3 100644 --- a/lib/impure/osinfo_win.nim +++ b/lib/impure/osinfo_win.nim @@ -375,7 +375,7 @@ proc getFileSize*(file: string): BiggestInt = var hFile = findFirstFileA(file, fileData) if hFile == INVALID_HANDLE_VALUE: - raise newException(EIO, $getLastError()) + raise newException(IOError, $getLastError()) return fileData.nFileSizeLow @@ -386,10 +386,10 @@ proc getDiskFreeSpaceEx*(lpDirectoryName: cstring, lpFreeBytesAvailableToCaller, proc getPartitionInfo*(partition: string): TPartitionInfo = ## Retrieves partition info, for example ``partition`` may be ``"C:\"`` - var FreeBytes, TotalBytes, TotalFreeBytes: TFiletime - var res = getDiskFreeSpaceEx(r"C:\", FreeBytes, TotalBytes, - TotalFreeBytes) - return (FreeBytes, TotalBytes) + var freeBytes, totalBytes, totalFreeBytes: TFiletime + discard getDiskFreeSpaceEx(r"C:\", freeBytes, totalBytes, + totalFreeBytes) + return (freeBytes, totalBytes) when isMainModule: var r = getMemoryInfo() diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index 9153d2360..07ef13fd9 100644 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -15,13 +15,13 @@ when defined(Windows): proc readLineFromStdin*(prompt: string): TaintedString {. - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = ## Reads a line from stdin. stdout.write(prompt) result = readLine(stdin) proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {. - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = ## Reads a `line` from stdin. `line` must not be ## ``nil``! May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or @@ -35,7 +35,7 @@ else: import readline, history proc readLineFromStdin*(prompt: string): TaintedString {. - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = var buffer = readline.readLine(prompt) if isNil(buffer): quit(0) result = TaintedString($buffer) @@ -44,7 +44,7 @@ else: readline.free(buffer) proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {. - tags: [FReadIO, FWriteIO].} = + tags: [ReadIOEffect, WriteIOEffect].} = var buffer = readline.readLine(prompt) if isNil(buffer): quit(0) line = TaintedString($buffer) diff --git a/lib/impure/zipfiles.nim b/lib/impure/zipfiles.nim index b7df30d89..fb687e6f1 100644 --- a/lib/impure/zipfiles.nim +++ b/lib/impure/zipfiles.nim @@ -13,18 +13,18 @@ import streams, libzip, times, os type - TZipArchive* = object of TObject ## represents a zip archive - mode: TFileMode + TZipArchive* = object of RootObj ## represents a zip archive + mode: FileMode w: PZip proc zipError(z: var TZipArchive) = - var e: ref EIO + var e: ref IOError new(e) e.msg = $zip_strerror(z.w) raise e -proc open*(z: var TZipArchive, filename: string, mode: TFileMode = fmRead): bool = +proc open*(z: var TZipArchive, filename: string, mode: FileMode = fmRead): bool = ## Opens a zip file for reading, writing or appending. All file modes are ## supported. Returns true iff successful, false otherwise. var err, flags: int32 @@ -72,7 +72,7 @@ proc addFile*(z: var TZipArchive, file: string) = proc mySourceCallback(state, data: pointer, len: int, cmd: TZipSourceCmd): int {.cdecl.} = - var src = cast[PStream](state) + var src = cast[Stream](state) case cmd of ZIP_SOURCE_OPEN: if src.setPositionImpl != nil: setPosition(src, 0) # reset @@ -93,7 +93,7 @@ proc mySourceCallback(state, data: pointer, len: int, of constZIP_SOURCE_FREE: GC_unref(src) else: assert(false) -proc addFile*(z: var TZipArchive, dest: string, src: PStream) = +proc addFile*(z: var TZipArchive, dest: string, src: Stream) = ## Adds a file named with `dest` to the archive `z`. `dest` ## may contain a path. The file's content is read from the `src` stream. assert(z.mode != fmRead) @@ -107,14 +107,14 @@ proc addFile*(z: var TZipArchive, dest: string, src: PStream) = # -------------- zip file stream --------------------------------------------- type - TZipFileStream = object of TStream + TZipFileStream = object of StreamObj f: PZipFile PZipFileStream* = ref TZipFileStream ## a reader stream of a file within a zip archive -proc fsClose(s: PStream) = zip_fclose(PZipFileStream(s).f) -proc fsReadData(s: PStream, buffer: pointer, bufLen: int): int = +proc fsClose(s: Stream) = zip_fclose(PZipFileStream(s).f) +proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int = result = zip_fread(PZipFileStream(s).f, buffer, bufLen) proc newZipFileStream(f: PZipFile): PZipFileStream = @@ -144,7 +144,7 @@ iterator walkFiles*(z: var TZipArchive): string = inc(i) -proc extractFile*(z: var TZipArchive, srcFile: string, dest: PStream) = +proc extractFile*(z: var TZipArchive, srcFile: string, dest: Stream) = ## extracts a file from the zip archive `z` to the destination stream. var strm = getStream(z, srcFile) while true: diff --git a/lib/wrappers/expat.nim b/lib/wrappers/expat.nim index 3400dfdf7..d2dac44c3 100644 --- a/lib/wrappers/expat.nim +++ b/lib/wrappers/expat.nim @@ -176,7 +176,7 @@ proc ParserCreate_MM*(encoding: cstring, memsuite: ptr TMemory_Handling_Suite, # Added in Expat 1.95.3. # -proc ParserReset*(parser: PParser, encoding: cstring): Bool{.cdecl, +proc ParserReset*(parser: PParser, encoding: cstring): bool{.cdecl, importc: "XML_ParserReset", dynlib: expatDll.} # atts is array of name/value pairs, terminated by 0; # names and values are 0 terminated. @@ -601,7 +601,7 @@ proc UseParserAsHandlerArg*(parser: PParser){.cdecl, # XML_ERROR_FEATURE_REQUIRES_XML_DTD. # -proc UseForeignDTD*(parser: PParser, useDTD: Bool): TError{.cdecl, +proc UseForeignDTD*(parser: PParser, useDTD: bool): TError{.cdecl, importc: "XML_UseForeignDTD", dynlib: expatDll.} # Sets the base to be used for resolving relative URIs in system # identifiers in declarations. Resolving relative identifiers is @@ -681,7 +681,7 @@ proc ParseBuffer*(parser: PParser, len: cint, isFinal: cint): TStatus{.cdecl, # When suspended, parsing can be resumed by calling XML_ResumeParser(). # -proc StopParser*(parser: PParser, resumable: Bool): TStatus{.cdecl, +proc StopParser*(parser: PParser, resumable: bool): TStatus{.cdecl, importc: "XML_StopParser", dynlib: expatDll.} # Resumes parsing after it has been suspended with XML_StopParser(). # Must not be called from within a handler call-back. Returns same @@ -703,7 +703,7 @@ type INITIALIZED, PARSING, FINISHED, SUSPENDED TParsingStatus*{.pure, final.} = object parsing*: TParsing - finalBuffer*: Bool + finalBuffer*: bool # Returns status of parser with respect to being initialized, parsing, diff --git a/lib/wrappers/postgres.nim b/lib/wrappers/postgres.nim index b69c34f3a..6c857de40 100644 --- a/lib/wrappers/postgres.nim +++ b/lib/wrappers/postgres.nim @@ -68,9 +68,9 @@ type dbName*: cstring status*: TConnStatusType errorMessage*: array[0..(ERROR_MSG_LENGTH) - 1, char] - Pfin*: TFile - Pfout*: TFile - Pfdebug*: TFile + Pfin*: File + Pfout*: File + Pfdebug*: File sock*: int32 laddr*: TSockAddr raddr*: TSockAddr @@ -199,7 +199,7 @@ when defined(USE_SSL): importc: "PQgetssl".} proc pqsetErrorVerbosity*(conn: PPGconn, verbosity: PGVerbosity): PGVerbosity{. cdecl, dynlib: dllName, importc: "PQsetErrorVerbosity".} -proc pqtrace*(conn: PPGconn, debug_port: TFile){.cdecl, dynlib: dllName, +proc pqtrace*(conn: PPGconn, debug_port: File){.cdecl, dynlib: dllName, importc: "PQtrace".} proc pquntrace*(conn: PPGconn){.cdecl, dynlib: dllName, importc: "PQuntrace".} proc pqsetNoticeReceiver*(conn: PPGconn, theProc: PQnoticeReceiver, arg: pointer): PQnoticeReceiver{. @@ -315,12 +315,12 @@ proc pqescapeBytea*(bintext: cstring, binlen: int, bytealen: var int): cstring{. cdecl, dynlib: dllName, importc: "PQescapeBytea".} proc pqunescapeBytea*(strtext: cstring, retbuflen: var int): cstring{.cdecl, dynlib: dllName, importc: "PQunescapeBytea".} -proc pqprint*(fout: TFile, res: PPGresult, ps: PPQprintOpt){.cdecl, +proc pqprint*(fout: File, res: PPGresult, ps: PPQprintOpt){.cdecl, dynlib: dllName, importc: "PQprint".} -proc pqdisplayTuples*(res: PPGresult, fp: TFile, fillAlign: int32, +proc pqdisplayTuples*(res: PPGresult, fp: File, fillAlign: int32, fieldSep: cstring, printHeader: int32, quiet: int32){. cdecl, dynlib: dllName, importc: "PQdisplayTuples".} -proc pqprintTuples*(res: PPGresult, fout: TFile, printAttName: int32, +proc pqprintTuples*(res: PPGresult, fout: File, printAttName: int32, terseOutput: int32, width: int32){.cdecl, dynlib: dllName, importc: "PQprintTuples".} proc lo_open*(conn: PPGconn, lobjId: Oid, mode: int32): int32{.cdecl, diff --git a/lib/wrappers/readline/history.nim b/lib/wrappers/readline/history.nim index 12dfa2707..caa857ceb 100644 --- a/lib/wrappers/readline/history.nim +++ b/lib/wrappers/readline/history.nim @@ -142,7 +142,7 @@ proc history_get*(a2: cint): ptr THIST_ENTRY{.cdecl, importc: "history_get", # Return the timestamp associated with the HIST_ENTRY * passed as an # argument -proc history_get_time*(a2: ptr THIST_ENTRY): TTime{.cdecl, +proc history_get_time*(a2: ptr THIST_ENTRY): Time{.cdecl, importc: "history_get_time", dynlib: historyDll.} # Return the number of bytes that the primary history entries are using. # This just adds up the lengths of the_history->lines. diff --git a/lib/wrappers/readline/readline.nim b/lib/wrappers/readline/readline.nim index bbe416534..5a319243e 100644 --- a/lib/wrappers/readline/readline.nim +++ b/lib/wrappers/readline/readline.nim @@ -776,7 +776,7 @@ proc execute_next*(a2: cint): cint{.cdecl, importc: "rl_execute_next", proc clear_pending_input*(): cint{.cdecl, importc: "rl_clear_pending_input", dynlib: readlineDll.} proc read_key*(): cint{.cdecl, importc: "rl_read_key", dynlib: readlineDll.} -proc getc*(a2: TFile): cint{.cdecl, importc: "rl_getc", dynlib: readlineDll.} +proc getc*(a2: File): cint{.cdecl, importc: "rl_getc", dynlib: readlineDll.} proc set_keyboard_input_timeout*(a2: cint): cint{.cdecl, importc: "rl_set_keyboard_input_timeout", dynlib: readlineDll.} # `Public' utility functions . @@ -881,8 +881,8 @@ when false: # The name of the terminal to use. var terminal_name*{.importc: "rl_terminal_name", dynlib: readlineDll.}: cstring # The input and output streams. - var instream*{.importc: "rl_instream", dynlib: readlineDll.}: TFile - var outstream*{.importc: "rl_outstream", dynlib: readlineDll.}: TFile + var instream*{.importc: "rl_instream", dynlib: readlineDll.}: File + var outstream*{.importc: "rl_outstream", dynlib: readlineDll.}: File # If non-zero, Readline gives values of LINES and COLUMNS from the environment # greater precedence than values fetched from the kernel when computing the # screen dimensions. @@ -1184,8 +1184,8 @@ type insmode*: cint edmode*: cint kseqlen*: cint - inf*: TFile - outf*: TFile + inf*: File + outf*: File pendingin*: cint theMacro*: cstring # signal state catchsigs*: cint diff --git a/lib/wrappers/readline/rltypedefs.nim b/lib/wrappers/readline/rltypedefs.nim index 202cf925d..847834e80 100644 --- a/lib/wrappers/readline/rltypedefs.nim +++ b/lib/wrappers/readline/rltypedefs.nim @@ -48,7 +48,7 @@ type # Input function type type - Tgetc_func* = proc (a2: TFile): cint{.cdecl.} + Tgetc_func* = proc (a2: File): cint{.cdecl.} # Generic function that takes a character buffer (which could be the readline # line buffer) and an index into it (which could be rl_point) and returns diff --git a/lib/wrappers/zip/libzip.nim b/lib/wrappers/zip/libzip.nim index ebd74c7fd..86670b450 100644 --- a/lib/wrappers/zip/libzip.nim +++ b/lib/wrappers/zip/libzip.nim @@ -64,15 +64,15 @@ type TZipSourceCallback* = proc (state: pointer, data: pointer, length: int, cmd: TZipSourceCmd): int {.cdecl.} PZipStat* = ptr TZipStat - TZipStat* = object ## the 'zip_stat' struct + TZipStat* = object ## the 'zip_stat' struct name*: cstring ## name of the file index*: int32 ## index within archive crc*: int32 ## crc of file data - mtime*: TTime ## modification time + mtime*: Time ## modification time size*: int ## size of file (uncompressed) - compSize*: int ## size of file (compressed) - compMethod*: int16 ## compression method used - encryptionMethod*: int16 ## encryption method used + compSize*: int ## size of file (compressed) + compMethod*: int16 ## compression method used + encryptionMethod*: int16 ## encryption method used TZip = object TZipSource = object @@ -225,7 +225,7 @@ proc zip_source_buffer*(para1: PZip, para2: pointer, para3: int, para4: int32): cdecl, mydll, importc: "zip_source_buffer".} proc zip_source_file*(para1: PZip, para2: cstring, para3: int, para4: int): PZipSource {. cdecl, mydll, importc: "zip_source_file".} -proc zip_source_filep*(para1: PZip, para2: TFile, para3: int, para4: int): PZipSource {. +proc zip_source_filep*(para1: PZip, para2: File, para3: int, para4: int): PZipSource {. cdecl, mydll, importc: "zip_source_filep".} proc zip_source_free*(para1: PZipSource) {.cdecl, mydll, importc: "zip_source_free".} diff --git a/web/nim.ini b/web/nim.ini index a5efbaf2a..1bf75e209 100644 --- a/web/nim.ini +++ b/web/nim.ini @@ -80,7 +80,7 @@ webdoc: "wrappers/expat;wrappers/pcre" webdoc: "wrappers/tre;wrappers/openssl" webdoc: "wrappers/libuv;wrappers/joyent_http_parser" -webdoc: "posix/posix;wrappers/odbcsql;impure/dialogs" +webdoc: "posix/posix;wrappers/odbcsql" webdoc: "wrappers/zip/zlib;wrappers/zip/libzip" webdoc: "wrappers/libsvm.nim" webdoc: "windows" From 137ade4f6e595a7a228943c849ff0a9684d90299 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 19 Sep 2014 00:59:11 +0200 Subject: [PATCH 146/409] cleaned up expat wrapper --- lib/wrappers/expat.nim | 152 ++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/lib/wrappers/expat.nim b/lib/wrappers/expat.nim index d2dac44c3..a3d888201 100644 --- a/lib/wrappers/expat.nim +++ b/lib/wrappers/expat.nim @@ -77,8 +77,8 @@ type type TContent*{.pure, final.} = object - typ*: TContent_Type - quant*: TContent_Quant + typ*: TContentType + quant*: TContentQuant name*: cstring numchildren*: cint children*: ptr TContent @@ -93,7 +93,7 @@ type TElementDeclHandler* = proc (userData: pointer, name: cstring, model: ptr TContent){.cdecl.} -proc SetElementDeclHandler*(parser: PParser, eldecl: TElementDeclHandler){. +proc setElementDeclHandler*(parser: PParser, eldecl: TElementDeclHandler){. cdecl, importc: "XML_SetElementDeclHandler", dynlib: expatDll.} # The Attlist declaration handler is called for *each* attribute. So # a single Attlist declaration with multiple attributes declared will @@ -106,10 +106,10 @@ proc SetElementDeclHandler*(parser: PParser, eldecl: TElementDeclHandler){. type TAttlistDeclHandler* = proc (userData: pointer, elname: cstring, - attname: cstring, att_type: cstring, + attname: cstring, attType: cstring, dflt: cstring, isrequired: cint){.cdecl.} -proc SetAttlistDeclHandler*(parser: PParser, attdecl: TAttlistDeclHandler){. +proc setAttlistDeclHandler*(parser: PParser, attdecl: TAttlistDeclHandler){. cdecl, importc: "XML_SetAttlistDeclHandler", dynlib: expatDll.} # The XML declaration handler is called for *both* XML declarations # and text declarations. The way to distinguish is that the version @@ -124,20 +124,20 @@ type TXmlDeclHandler* = proc (userData: pointer, version: cstring, encoding: cstring, standalone: cint){.cdecl.} -proc SetXmlDeclHandler*(parser: PParser, xmldecl: TXmlDeclHandler){.cdecl, +proc setXmlDeclHandler*(parser: PParser, xmldecl: TXmlDeclHandler){.cdecl, importc: "XML_SetXmlDeclHandler", dynlib: expatDll.} type TMemory_Handling_Suite*{.pure, final.} = object - malloc_fcn*: proc (size: int): pointer{.cdecl.} - realloc_fcn*: proc (p: pointer, size: int): pointer{.cdecl.} - free_fcn*: proc (p: pointer){.cdecl.} + mallocFcn*: proc (size: int): pointer{.cdecl.} + reallocFcn*: proc (p: pointer, size: int): pointer{.cdecl.} + freeFcn*: proc (p: pointer){.cdecl.} # Constructs a new parser; encoding is the encoding specified by the # external protocol or NULL if there is none specified. # -proc ParserCreate*(encoding: cstring): PParser{.cdecl, +proc parserCreate*(encoding: cstring): PParser{.cdecl, importc: "XML_ParserCreate", dynlib: expatDll.} # Constructs a new parser and namespace processor. Element type # names and attribute names that belong to a namespace will be @@ -151,7 +151,7 @@ proc ParserCreate*(encoding: cstring): PParser{.cdecl, # triplets (see XML_SetReturnNSTriplet). # -proc ParserCreateNS*(encoding: cstring, namespaceSeparator: char): PParser{. +proc parserCreateNS*(encoding: cstring, namespaceSeparator: char): PParser{. cdecl, importc: "XML_ParserCreateNS", dynlib: expatDll.} # Constructs a new parser using the memory management suite referred to # by memsuite. If memsuite is NULL, then use the standard library memory @@ -163,7 +163,7 @@ proc ParserCreateNS*(encoding: cstring, namespaceSeparator: char): PParser{. # the given suite. # -proc ParserCreate_MM*(encoding: cstring, memsuite: ptr TMemory_Handling_Suite, +proc parserCreateMM*(encoding: cstring, memsuite: ptr TMemoryHandlingSuite, namespaceSeparator: cstring): PParser{.cdecl, importc: "XML_ParserCreate_MM", dynlib: expatDll.} # Prepare a parser object to be re-used. This is particularly @@ -176,7 +176,7 @@ proc ParserCreate_MM*(encoding: cstring, memsuite: ptr TMemory_Handling_Suite, # Added in Expat 1.95.3. # -proc ParserReset*(parser: PParser, encoding: cstring): bool{.cdecl, +proc parserReset*(parser: PParser, encoding: cstring): bool{.cdecl, importc: "XML_ParserReset", dynlib: expatDll.} # atts is array of name/value pairs, terminated by 0; # names and values are 0 terminated. @@ -230,7 +230,7 @@ type type TStartDoctypeDeclHandler* = proc (userData: pointer, doctypeName: cstring, sysid: cstring, pubid: cstring, - has_internal_subset: cint){.cdecl.} + hasInternalSubset: cint){.cdecl.} # This is called for the start of the DOCTYPE declaration when the # closing > is encountered, but after processing any external @@ -261,12 +261,12 @@ type type TEntityDeclHandler* = proc (userData: pointer, entityName: cstring, - is_parameter_entity: cint, value: cstring, - value_length: cint, base: cstring, + isParameterEntity: cint, value: cstring, + valueLength: cint, base: cstring, systemId: cstring, publicId: cstring, notationName: cstring){.cdecl.} -proc SetEntityDeclHandler*(parser: PParser, handler: TEntityDeclHandler){.cdecl, +proc setEntityDeclHandler*(parser: PParser, handler: TEntityDeclHandler){.cdecl, importc: "XML_SetEntityDeclHandler", dynlib: expatDll.} # OBSOLETE -- OBSOLETE -- OBSOLETE # This handler has been superceded by the EntityDeclHandler above. @@ -372,7 +372,7 @@ type type TSkippedEntityHandler* = proc (userData: pointer, entityName: cstring, - is_parameter_entity: cint){.cdecl.} + isParameterEntity: cint){.cdecl.} # This structure is filled in by the XML_UnknownEncodingHandler to # provide information to the parser about encodings that are unknown @@ -455,27 +455,27 @@ type TUnknownEncodingHandler* = proc (encodingHandlerData: pointer, name: cstring, info: ptr TEncoding): cint{.cdecl.} -proc SetElementHandler*(parser: PParser, start: TStartElementHandler, +proc setElementHandler*(parser: PParser, start: TStartElementHandler, endHandler: TEndElementHandler){.cdecl, importc: "XML_SetElementHandler", dynlib: expatDll.} -proc SetStartElementHandler*(parser: PParser, handler: TStartElementHandler){. +proc setStartElementHandler*(parser: PParser, handler: TStartElementHandler){. cdecl, importc: "XML_SetStartElementHandler", dynlib: expatDll.} -proc SetEndElementHandler*(parser: PParser, handler: TEndElementHandler){.cdecl, +proc setEndElementHandler*(parser: PParser, handler: TEndElementHandler){.cdecl, importc: "XML_SetEndElementHandler", dynlib: expatDll.} -proc SetCharacterDataHandler*(parser: PParser, handler: TCharacterDataHandler){. +proc setCharacterDataHandler*(parser: PParser, handler: TCharacterDataHandler){. cdecl, importc: "XML_SetCharacterDataHandler", dynlib: expatDll.} -proc SetProcessingInstructionHandler*(parser: PParser, +proc setProcessingInstructionHandler*(parser: PParser, handler: TProcessingInstructionHandler){. cdecl, importc: "XML_SetProcessingInstructionHandler", dynlib: expatDll.} -proc SetCommentHandler*(parser: PParser, handler: TCommentHandler){.cdecl, +proc setCommentHandler*(parser: PParser, handler: TCommentHandler){.cdecl, importc: "XML_SetCommentHandler", dynlib: expatDll.} -proc SetCdataSectionHandler*(parser: PParser, start: TStartCdataSectionHandler, +proc setCdataSectionHandler*(parser: PParser, start: TStartCdataSectionHandler, endHandler: TEndCdataSectionHandler){.cdecl, importc: "XML_SetCdataSectionHandler", dynlib: expatDll.} -proc SetStartCdataSectionHandler*(parser: PParser, +proc setStartCdataSectionHandler*(parser: PParser, start: TStartCdataSectionHandler){.cdecl, importc: "XML_SetStartCdataSectionHandler", dynlib: expatDll.} -proc SetEndCdataSectionHandler*(parser: PParser, +proc setEndCdataSectionHandler*(parser: PParser, endHandler: TEndCdataSectionHandler){.cdecl, importc: "XML_SetEndCdataSectionHandler", dynlib: expatDll.} # This sets the default handler and also inhibits expansion of @@ -483,42 +483,42 @@ proc SetEndCdataSectionHandler*(parser: PParser, # default handler, or to the skipped entity handler, if one is set. # -proc SetDefaultHandler*(parser: PParser, handler: TDefaultHandler){.cdecl, +proc setDefaultHandler*(parser: PParser, handler: TDefaultHandler){.cdecl, importc: "XML_SetDefaultHandler", dynlib: expatDll.} # This sets the default handler but does not inhibit expansion of # internal entities. The entity reference will not be passed to the # default handler. # -proc SetDefaultHandlerExpand*(parser: PParser, handler: TDefaultHandler){.cdecl, +proc setDefaultHandlerExpand*(parser: PParser, handler: TDefaultHandler){.cdecl, importc: "XML_SetDefaultHandlerExpand", dynlib: expatDll.} -proc SetDoctypeDeclHandler*(parser: PParser, start: TStartDoctypeDeclHandler, +proc setDoctypeDeclHandler*(parser: PParser, start: TStartDoctypeDeclHandler, endHandler: TEndDoctypeDeclHandler){.cdecl, importc: "XML_SetDoctypeDeclHandler", dynlib: expatDll.} -proc SetStartDoctypeDeclHandler*(parser: PParser, +proc setStartDoctypeDeclHandler*(parser: PParser, start: TStartDoctypeDeclHandler){.cdecl, importc: "XML_SetStartDoctypeDeclHandler", dynlib: expatDll.} -proc SetEndDoctypeDeclHandler*(parser: PParser, +proc setEndDoctypeDeclHandler*(parser: PParser, endHandler: TEndDoctypeDeclHandler){.cdecl, importc: "XML_SetEndDoctypeDeclHandler", dynlib: expatDll.} -proc SetUnparsedEntityDeclHandler*(parser: PParser, +proc setUnparsedEntityDeclHandler*(parser: PParser, handler: TUnparsedEntityDeclHandler){.cdecl, importc: "XML_SetUnparsedEntityDeclHandler", dynlib: expatDll.} -proc SetNotationDeclHandler*(parser: PParser, handler: TNotationDeclHandler){. +proc setNotationDeclHandler*(parser: PParser, handler: TNotationDeclHandler){. cdecl, importc: "XML_SetNotationDeclHandler", dynlib: expatDll.} -proc SetNamespaceDeclHandler*(parser: PParser, +proc setNamespaceDeclHandler*(parser: PParser, start: TStartNamespaceDeclHandler, endHandler: TEndNamespaceDeclHandler){.cdecl, importc: "XML_SetNamespaceDeclHandler", dynlib: expatDll.} -proc SetStartNamespaceDeclHandler*(parser: PParser, +proc setStartNamespaceDeclHandler*(parser: PParser, start: TStartNamespaceDeclHandler){.cdecl, importc: "XML_SetStartNamespaceDeclHandler", dynlib: expatDll.} -proc SetEndNamespaceDeclHandler*(parser: PParser, +proc setEndNamespaceDeclHandler*(parser: PParser, endHandler: TEndNamespaceDeclHandler){.cdecl, importc: "XML_SetEndNamespaceDeclHandler", dynlib: expatDll.} -proc SetNotStandaloneHandler*(parser: PParser, handler: TNotStandaloneHandler){. +proc setNotStandaloneHandler*(parser: PParser, handler: TNotStandaloneHandler){. cdecl, importc: "XML_SetNotStandaloneHandler", dynlib: expatDll.} -proc SetExternalEntityRefHandler*(parser: PParser, +proc setExternalEntityRefHandler*(parser: PParser, handler: TExternalEntityRefHandler){.cdecl, importc: "XML_SetExternalEntityRefHandler", dynlib: expatDll.} # If a non-NULL value for arg is specified here, then it will be @@ -526,11 +526,11 @@ proc SetExternalEntityRefHandler*(parser: PParser, # instead of the parser object. # -proc SetExternalEntityRefHandlerArg*(parser: PParser, arg: pointer){.cdecl, +proc setExternalEntityRefHandlerArg*(parser: PParser, arg: pointer){.cdecl, importc: "XML_SetExternalEntityRefHandlerArg", dynlib: expatDll.} -proc SetSkippedEntityHandler*(parser: PParser, handler: TSkippedEntityHandler){. +proc setSkippedEntityHandler*(parser: PParser, handler: TSkippedEntityHandler){. cdecl, importc: "XML_SetSkippedEntityHandler", dynlib: expatDll.} -proc SetUnknownEncodingHandler*(parser: PParser, +proc setUnknownEncodingHandler*(parser: PParser, handler: TUnknownEncodingHandler, encodingHandlerData: pointer){.cdecl, importc: "XML_SetUnknownEncodingHandler", dynlib: expatDll.} @@ -539,7 +539,7 @@ proc SetUnknownEncodingHandler*(parser: PParser, # corresponding markup to be passed to the default handler. # -proc DefaultCurrent*(parser: PParser){.cdecl, importc: "XML_DefaultCurrent", +proc defaultCurrent*(parser: PParser){.cdecl, importc: "XML_DefaultCurrent", dynlib: expatDll.} # If do_nst is non-zero, and namespace processing is in effect, and # a name has a prefix (i.e. an explicit namespace qualifier) then @@ -555,15 +555,15 @@ proc DefaultCurrent*(parser: PParser){.cdecl, importc: "XML_DefaultCurrent", # XML_ParseBuffer has no effect. # -proc SetReturnNSTriplet*(parser: PParser, do_nst: cint){.cdecl, +proc setReturnNSTriplet*(parser: PParser, doNst: cint){.cdecl, importc: "XML_SetReturnNSTriplet", dynlib: expatDll.} # This value is passed as the userData argument to callbacks. -proc SetUserData*(parser: PParser, userData: pointer){.cdecl, +proc setUserData*(parser: PParser, userData: pointer){.cdecl, importc: "XML_SetUserData", dynlib: expatDll.} # Returns the last value set by XML_SetUserData or NULL. -template GetUserData*(parser: expr): expr = +template getUserData*(parser: expr): expr = (cast[ptr pointer]((parser))[] ) # This is equivalent to supplying an encoding argument to @@ -573,14 +573,14 @@ template GetUserData*(parser: expr): expr = # has no effect and returns XML_STATUS_ERROR. # -proc SetEncoding*(parser: PParser, encoding: cstring): TStatus{.cdecl, +proc setEncoding*(parser: PParser, encoding: cstring): TStatus{.cdecl, importc: "XML_SetEncoding", dynlib: expatDll.} # If this function is called, then the parser will be passed as the # first argument to callbacks instead of userData. The userData will # still be accessible using XML_GetUserData. # -proc UseParserAsHandlerArg*(parser: PParser){.cdecl, +proc useParserAsHandlerArg*(parser: PParser){.cdecl, importc: "XML_UseParserAsHandlerArg", dynlib: expatDll.} # If useDTD == XML_TRUE is passed to this function, then the parser # will assume that there is an external subset, even if none is @@ -601,7 +601,7 @@ proc UseParserAsHandlerArg*(parser: PParser){.cdecl, # XML_ERROR_FEATURE_REQUIRES_XML_DTD. # -proc UseForeignDTD*(parser: PParser, useDTD: bool): TError{.cdecl, +proc useForeignDTD*(parser: PParser, useDTD: bool): TError{.cdecl, importc: "XML_UseForeignDTD", dynlib: expatDll.} # Sets the base to be used for resolving relative URIs in system # identifiers in declarations. Resolving relative identifiers is @@ -612,9 +612,9 @@ proc UseForeignDTD*(parser: PParser, useDTD: bool): TError{.cdecl, # XML_STATUS_OK otherwise. # -proc SetBase*(parser: PParser, base: cstring): TStatus{.cdecl, +proc setBase*(parser: PParser, base: cstring): TStatus{.cdecl, importc: "XML_SetBase", dynlib: expatDll.} -proc GetBase*(parser: PParser): cstring{.cdecl, importc: "XML_GetBase", +proc getBase*(parser: PParser): cstring{.cdecl, importc: "XML_GetBase", dynlib: expatDll.} # Returns the number of the attribute/value pairs passed in last call # to the XML_StartElementHandler that were specified in the start-tag @@ -623,7 +623,7 @@ proc GetBase*(parser: PParser): cstring{.cdecl, importc: "XML_GetBase", # XML_StartElementHandler. # -proc GetSpecifiedAttributeCount*(parser: PParser): cint{.cdecl, +proc getSpecifiedAttributeCount*(parser: PParser): cint{.cdecl, importc: "XML_GetSpecifiedAttributeCount", dynlib: expatDll.} # Returns the index of the ID attribute passed in the last call to # XML_StartElementHandler, or -1 if there is no ID attribute. Each @@ -631,7 +631,7 @@ proc GetSpecifiedAttributeCount*(parser: PParser): cint{.cdecl, # index into the atts array passed to the XML_StartElementHandler. # -proc GetIdAttributeIndex*(parser: PParser): cint{.cdecl, +proc getIdAttributeIndex*(parser: PParser): cint{.cdecl, importc: "XML_GetIdAttributeIndex", dynlib: expatDll.} # Parses some input. Returns XML_STATUS_ERROR if a fatal error is # detected. The last call to XML_Parse must have isFinal true; len @@ -643,11 +643,11 @@ proc GetIdAttributeIndex*(parser: PParser): cint{.cdecl, # values. # -proc Parse*(parser: PParser, s: cstring, len: cint, isFinal: cint): TStatus{. +proc parse*(parser: PParser, s: cstring, len: cint, isFinal: cint): TStatus{. cdecl, importc: "XML_Parse", dynlib: expatDll.} -proc GetBuffer*(parser: PParser, len: cint): pointer{.cdecl, +proc getBuffer*(parser: PParser, len: cint): pointer{.cdecl, importc: "XML_GetBuffer", dynlib: expatDll.} -proc ParseBuffer*(parser: PParser, len: cint, isFinal: cint): TStatus{.cdecl, +proc parseBuffer*(parser: PParser, len: cint, isFinal: cint): TStatus{.cdecl, importc: "XML_ParseBuffer", dynlib: expatDll.} # Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. # Must be called from within a call-back handler, except when aborting @@ -681,7 +681,7 @@ proc ParseBuffer*(parser: PParser, len: cint, isFinal: cint): TStatus{.cdecl, # When suspended, parsing can be resumed by calling XML_ResumeParser(). # -proc StopParser*(parser: PParser, resumable: bool): TStatus{.cdecl, +proc stopParser*(parser: PParser, resumable: bool): TStatus{.cdecl, importc: "XML_StopParser", dynlib: expatDll.} # Resumes parsing after it has been suspended with XML_StopParser(). # Must not be called from within a handler call-back. Returns same @@ -696,7 +696,7 @@ proc StopParser*(parser: PParser, resumable: bool): TStatus{.cdecl, # application to call XML_ResumeParser() on it at the appropriate moment. # -proc ResumeParser*(parser: PParser): TStatus{.cdecl, +proc resumeParser*(parser: PParser): TStatus{.cdecl, importc: "XML_ResumeParser", dynlib: expatDll.} type TParsing* = enum @@ -712,7 +712,7 @@ type # XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED # -proc GetParsingStatus*(parser: PParser, status: ptr TParsingStatus){.cdecl, +proc getParsingStatus*(parser: PParser, status: ptr TParsingStatus){.cdecl, importc: "XML_GetParsingStatus", dynlib: expatDll.} # Creates an XML_Parser object that can parse an external general # entity; context is a '\0'-terminated string specifying the parse @@ -731,7 +731,7 @@ proc GetParsingStatus*(parser: PParser, status: ptr TParsingStatus){.cdecl, # Otherwise returns a new XML_Parser object. # -proc ExternalEntityParserCreate*(parser: PParser, context: cstring, +proc externalEntityParserCreate*(parser: PParser, context: cstring, encoding: cstring): PParser{.cdecl, importc: "XML_ExternalEntityParserCreate", dynlib: expatDll.} type @@ -763,13 +763,13 @@ type # XML_ParseBuffer, then it has no effect and will always return 0. # -proc SetParamEntityParsing*(parser: PParser, parsing: TParamEntityParsing): cint{. +proc setParamEntityParsing*(parser: PParser, parsing: TParamEntityParsing): cint{. cdecl, importc: "XML_SetParamEntityParsing", dynlib: expatDll.} # If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then # XML_GetErrorCode returns information about the error. # -proc GetErrorCode*(parser: PParser): TError{.cdecl, importc: "XML_GetErrorCode", +proc getErrorCode*(parser: PParser): TError{.cdecl, importc: "XML_GetErrorCode", dynlib: expatDll.} # These functions return information about the current parse # location. They may be called from any callback called to report @@ -788,17 +788,17 @@ proc GetErrorCode*(parser: PParser): TError{.cdecl, importc: "XML_GetErrorCode", # parse event, as described above. # -proc GetCurrentLineNumber*(parser: PParser): int{.cdecl, +proc getCurrentLineNumber*(parser: PParser): int{.cdecl, importc: "XML_GetCurrentLineNumber", dynlib: expatDll.} -proc GetCurrentColumnNumber*(parser: PParser): int{.cdecl, +proc getCurrentColumnNumber*(parser: PParser): int{.cdecl, importc: "XML_GetCurrentColumnNumber", dynlib: expatDll.} -proc GetCurrentByteIndex*(parser: PParser): int{.cdecl, +proc getCurrentByteIndex*(parser: PParser): int{.cdecl, importc: "XML_GetCurrentByteIndex", dynlib: expatDll.} # Return the number of bytes in the current event. # Returns 0 if the event is in an internal entity. # -proc GetCurrentByteCount*(parser: PParser): cint{.cdecl, +proc getCurrentByteCount*(parser: PParser): cint{.cdecl, importc: "XML_GetCurrentByteCount", dynlib: expatDll.} # If XML_CONTEXT_BYTES is defined, returns the input buffer, sets # the integer pointed to by offset to the offset within this buffer @@ -811,31 +811,31 @@ proc GetCurrentByteCount*(parser: PParser): cint{.cdecl, # the handler that makes the call. # -proc GetInputContext*(parser: PParser, offset: ptr cint, size: ptr cint): cstring{. +proc getInputContext*(parser: PParser, offset: ptr cint, size: ptr cint): cstring{. cdecl, importc: "XML_GetInputContext", dynlib: expatDll.} # Frees the content model passed to the element declaration handler -proc FreeContentModel*(parser: PParser, model: ptr TContent){.cdecl, +proc freeContentModel*(parser: PParser, model: ptr TContent){.cdecl, importc: "XML_FreeContentModel", dynlib: expatDll.} # Exposing the memory handling functions used in Expat -proc MemMalloc*(parser: PParser, size: int): pointer{.cdecl, +proc memMalloc*(parser: PParser, size: int): pointer{.cdecl, importc: "XML_MemMalloc", dynlib: expatDll.} -proc MemRealloc*(parser: PParser, p: pointer, size: int): pointer{.cdecl, +proc memRealloc*(parser: PParser, p: pointer, size: int): pointer{.cdecl, importc: "XML_MemRealloc", dynlib: expatDll.} -proc MemFree*(parser: PParser, p: pointer){.cdecl, importc: "XML_MemFree", +proc memFree*(parser: PParser, p: pointer){.cdecl, importc: "XML_MemFree", dynlib: expatDll.} # Frees memory used by the parser. -proc ParserFree*(parser: PParser){.cdecl, importc: "XML_ParserFree", +proc parserFree*(parser: PParser){.cdecl, importc: "XML_ParserFree", dynlib: expatDll.} # Returns a string describing the error. -proc ErrorString*(code: TError): cstring{.cdecl, importc: "XML_ErrorString", +proc errorString*(code: TError): cstring{.cdecl, importc: "XML_ErrorString", dynlib: expatDll.} # Return a string containing the version number of this expat -proc ExpatVersion*(): cstring{.cdecl, importc: "XML_ExpatVersion", +proc expatVersion*(): cstring{.cdecl, importc: "XML_ExpatVersion", dynlib: expatDll.} type TExpat_Version*{.pure, final.} = object @@ -848,7 +848,7 @@ type # number information for this version of expat. # -proc ExpatVersionInfo*(): TExpat_Version{.cdecl, +proc expatVersionInfo*(): TExpatVersion{.cdecl, importc: "XML_ExpatVersionInfo", dynlib: expatDll.} # Added in Expat 1.95.5. @@ -863,7 +863,7 @@ type value*: int -proc GetFeatureList*(): ptr TFeature{.cdecl, importc: "XML_GetFeatureList", +proc getFeatureList*(): ptr TFeature{.cdecl, importc: "XML_GetFeatureList", dynlib: expatDll.} # Expat follows the GNU/Linux convention of odd number minor version for # beta/development releases and even number minor version for stable From 4bf0bb7ad745afdf00ea024f0e60489846cca355 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 19 Sep 2014 01:09:23 +0200 Subject: [PATCH 147/409] cleaned up iup.nim --- lib/wrappers/iup.nim | 1016 +++++++++++++++++++++--------------------- 1 file changed, 508 insertions(+), 508 deletions(-) diff --git a/lib/wrappers/iup.nim b/lib/wrappers/iup.nim index dd98b84b8..6695dc5e2 100644 --- a/lib/wrappers/iup.nim +++ b/lib/wrappers/iup.nim @@ -68,7 +68,7 @@ proc alarm*(title, msg, b1, b2, b3: cstring): cint {. proc scanf*(format: cstring): cint {. importc: "IupScanf", dynlib: dllname, cdecl, varargs.} proc listDialog*(theType: cint, title: cstring, size: cint, - list: cstringArray, op, max_col, max_lin: cint, + list: cstringArray, op, maxCol, maxLin: cint, marks: ptr cint): cint {. importc: "IupListDialog", dynlib: dllname, cdecl.} proc getText*(title, text: cstring): cint {. @@ -77,15 +77,15 @@ proc getColor*(x, y: cint, r, g, b: var byte): cint {. importc: "IupGetColor", dynlib: dllname, cdecl.} type - Iparamcb* = proc (dialog: PIhandle, param_index: cint, - user_data: pointer): cint {.cdecl.} + Iparamcb* = proc (dialog: PIhandle, paramIndex: cint, + userData: pointer): cint {.cdecl.} -proc getParam*(title: cstring, action: Iparamcb, user_data: pointer, +proc getParam*(title: cstring, action: Iparamcb, userData: pointer, format: cstring): cint {. importc: "IupGetParam", cdecl, varargs, dynlib: dllname.} -proc getParamv*(title: cstring, action: Iparamcb, user_data: pointer, - format: cstring, param_count, param_extra: cint, - param_data: pointer): cint {. +proc getParamv*(title: cstring, action: Iparamcb, userData: pointer, + format: cstring, paramCount, paramExtra: cint, + paramData: pointer): cint {. importc: "IupGetParamv", cdecl, dynlib: dllname.} @@ -125,7 +125,7 @@ proc destroy*(ih: PIhandle) {.importc: "IupDestroy", cdecl, dynlib: dllname.} proc detach*(child: PIhandle) {.importc: "IupDetach", cdecl, dynlib: dllname.} proc append*(ih, child: PIhandle): PIhandle {. importc: "IupAppend", cdecl, dynlib: dllname, discardable.} -proc insert*(ih, ref_child, child: PIhandle): PIhandle {. +proc insert*(ih, refChild, child: PIhandle): PIhandle {. importc: "IupInsert", cdecl, dynlib: dllname, discardable.} proc getChild*(ih: PIhandle, pos: cint): PIhandle {. importc: "IupGetChild", cdecl, dynlib: dllname.} @@ -143,7 +143,7 @@ proc getDialog*(ih: PIhandle): PIhandle {. importc: "IupGetDialog", cdecl, dynlib: dllname.} proc getDialogChild*(ih: PIhandle, name: cstring): PIhandle {. importc: "IupGetDialogChild", cdecl, dynlib: dllname.} -proc reparent*(ih, new_parent: PIhandle): cint {. +proc reparent*(ih, newParent: PIhandle): cint {. importc: "IupReparent", cdecl, dynlib: dllname.} proc popup*(ih: PIhandle, x, y: cint): cint {. @@ -181,7 +181,7 @@ proc setfAttribute*(ih: PIhandle, name, format: cstring) {. importc: "IupSetfAttribute", cdecl, dynlib: dllname, varargs.} proc getAllAttributes*(ih: PIhandle, names: cstringArray, n: cint): cint {. importc: "IupGetAllAttributes", cdecl, dynlib: dllname.} -proc setAtt*(handle_name: cstring, ih: PIhandle, name: cstring): PIhandle {. +proc setAtt*(handleName: cstring, ih: PIhandle, name: cstring): PIhandle {. importc: "IupSetAtt", cdecl, dynlib: dllname, varargs, discardable.} proc setGlobal*(name, value: cstring) {. @@ -226,7 +226,7 @@ proc getAllDialogs*(names: cstringArray, n: cint): cint {. proc getName*(ih: PIhandle): cstring {. importc: "IupGetName", cdecl, dynlib: dllname.} -proc setAttributeHandle*(ih: PIhandle, name: cstring, ih_named: PIhandle) {. +proc setAttributeHandle*(ih: PIhandle, name: cstring, ihNamed: PIhandle) {. importc: "IupSetAttributeHandle", cdecl, dynlib: dllname.} proc getAttributeHandle*(ih: PIhandle, name: cstring): PIhandle {. importc: "IupGetAttributeHandle", cdecl, dynlib: dllname.} @@ -266,9 +266,9 @@ proc hbox*(child: PIhandle): PIhandle {. proc hboxv*(children: ptr PIhandle): PIhandle {. importc: "IupHboxv", cdecl, dynlib: dllname.} -proc normalizer*(ih_first: PIhandle): PIhandle {. +proc normalizer*(ihFirst: PIhandle): PIhandle {. importc: "IupNormalizer", cdecl, dynlib: dllname, varargs.} -proc normalizerv*(ih_list: ptr PIhandle): PIhandle {. +proc normalizerv*(ihList: ptr PIhandle): PIhandle {. importc: "IupNormalizerv", cdecl, dynlib: dllname.} proc cbox*(child: PIhandle): PIhandle {. @@ -434,516 +434,516 @@ const IUP_MASK_INT* = "[+/-]?/d+" IUP_MASK_UINT* = "/d+" -# from 32 to 126, all character sets are equal, -# the key code i the same as the character code. -const - K_SP* = cint(ord(' ')) - K_exclam* = cint(ord('!')) - K_quotedbl* = cint(ord('\"')) - K_numbersign* = cint(ord('#')) - K_dollar* = cint(ord('$')) - K_percent* = cint(ord('%')) - K_ampersand* = cint(ord('&')) - K_apostrophe* = cint(ord('\'')) - K_parentleft* = cint(ord('(')) - K_parentright* = cint(ord(')')) - K_asterisk* = cint(ord('*')) - K_plus* = cint(ord('+')) - K_comma* = cint(ord(',')) - K_minus* = cint(ord('-')) - K_period* = cint(ord('.')) - K_slash* = cint(ord('/')) - K_0* = cint(ord('0')) - K_1* = cint(ord('1')) - K_2* = cint(ord('2')) - K_3* = cint(ord('3')) - K_4* = cint(ord('4')) - K_5* = cint(ord('5')) - K_6* = cint(ord('6')) - K_7* = cint(ord('7')) - K_8* = cint(ord('8')) - K_9* = cint(ord('9')) - K_colon* = cint(ord(':')) - K_semicolon* = cint(ord(';')) - K_less* = cint(ord('<')) - K_equal* = cint(ord('=')) - K_greater* = cint(ord('>')) - K_question* = cint(ord('?')) - K_at* = cint(ord('@')) - K_upperA* = cint(ord('A')) - K_upperB* = cint(ord('B')) - K_upperC* = cint(ord('C')) - K_upperD* = cint(ord('D')) - K_upperE* = cint(ord('E')) - K_upperF* = cint(ord('F')) - K_upperG* = cint(ord('G')) - K_upperH* = cint(ord('H')) - K_upperI* = cint(ord('I')) - K_upperJ* = cint(ord('J')) - K_upperK* = cint(ord('K')) - K_upperL* = cint(ord('L')) - K_upperM* = cint(ord('M')) - K_upperN* = cint(ord('N')) - K_upperO* = cint(ord('O')) - K_upperP* = cint(ord('P')) - K_upperQ* = cint(ord('Q')) - K_upperR* = cint(ord('R')) - K_upperS* = cint(ord('S')) - K_upperT* = cint(ord('T')) - K_upperU* = cint(ord('U')) - K_upperV* = cint(ord('V')) - K_upperW* = cint(ord('W')) - K_upperX* = cint(ord('X')) - K_upperY* = cint(ord('Y')) - K_upperZ* = cint(ord('Z')) - K_bracketleft* = cint(ord('[')) - K_backslash* = cint(ord('\\')) - K_bracketright* = cint(ord(']')) - K_circum* = cint(ord('^')) - K_underscore* = cint(ord('_')) - K_grave* = cint(ord('`')) - K_lowera* = cint(ord('a')) - K_lowerb* = cint(ord('b')) - K_lowerc* = cint(ord('c')) - K_lowerd* = cint(ord('d')) - K_lowere* = cint(ord('e')) - K_lowerf* = cint(ord('f')) - K_lowerg* = cint(ord('g')) - K_lowerh* = cint(ord('h')) - K_loweri* = cint(ord('i')) - K_lowerj* = cint(ord('j')) - K_lowerk* = cint(ord('k')) - K_lowerl* = cint(ord('l')) - K_lowerm* = cint(ord('m')) - K_lowern* = cint(ord('n')) - K_lowero* = cint(ord('o')) - K_lowerp* = cint(ord('p')) - K_lowerq* = cint(ord('q')) - K_lowerr* = cint(ord('r')) - K_lowers* = cint(ord('s')) - K_lowert* = cint(ord('t')) - K_loweru* = cint(ord('u')) - K_lowerv* = cint(ord('v')) - K_lowerw* = cint(ord('w')) - K_lowerx* = cint(ord('x')) - K_lowery* = cint(ord('y')) - K_lowerz* = cint(ord('z')) - K_braceleft* = cint(ord('{')) - K_bar* = cint(ord('|')) - K_braceright* = cint(ord('}')) - K_tilde* = cint(ord('~')) - -proc isPrint*(c: cint): bool = return c > 31 and c < 127 - -# also define the escape sequences that have keys associated -const - K_BS* = cint(ord('\b')) - K_TAB* = cint(ord('\t')) - K_LF* = cint(10) - K_CR* = cint(13) - -# IUP Extended Key Codes, range start at 128 -# Modifiers use 256 interval -# These key code definitions are specific to IUP - -proc isXkey*(c: cint): bool = return c > 128 -proc isShiftXkey*(c: cint): bool = return c > 256 and c < 512 -proc isCtrlXkey*(c: cint): bool = return c > 512 and c < 768 -proc isAltXkey*(c: cint): bool = return c > 768 and c < 1024 -proc isSysXkey*(c: cint): bool = return c > 1024 and c < 1280 - -proc iUPxCODE*(c: cint): cint = return c + cint(128) # Normal (must be above 128) +# from 32 to 126, all character sets are equal, +# the key code i the same as the character code. +const + K_SP* = cint(ord(' ')) + K_exclam* = cint(ord('!')) + K_quotedbl* = cint(ord('\"')) + K_numbersign* = cint(ord('#')) + K_dollar* = cint(ord('$')) + K_percent* = cint(ord('%')) + K_ampersand* = cint(ord('&')) + K_apostrophe* = cint(ord('\'')) + K_parentleft* = cint(ord('(')) + K_parentright* = cint(ord(')')) + K_asterisk* = cint(ord('*')) + K_plus* = cint(ord('+')) + K_comma* = cint(ord(',')) + K_minus* = cint(ord('-')) + K_period* = cint(ord('.')) + K_slash* = cint(ord('/')) + K_0* = cint(ord('0')) + K_1* = cint(ord('1')) + K_2* = cint(ord('2')) + K_3* = cint(ord('3')) + K_4* = cint(ord('4')) + K_5* = cint(ord('5')) + K_6* = cint(ord('6')) + K_7* = cint(ord('7')) + K_8* = cint(ord('8')) + K_9* = cint(ord('9')) + K_colon* = cint(ord(':')) + K_semicolon* = cint(ord(';')) + K_less* = cint(ord('<')) + K_equal* = cint(ord('=')) + K_greater* = cint(ord('>')) + K_question* = cint(ord('?')) + K_at* = cint(ord('@')) + K_upperA* = cint(ord('A')) + K_upperB* = cint(ord('B')) + K_upperC* = cint(ord('C')) + K_upperD* = cint(ord('D')) + K_upperE* = cint(ord('E')) + K_upperF* = cint(ord('F')) + K_upperG* = cint(ord('G')) + K_upperH* = cint(ord('H')) + K_upperI* = cint(ord('I')) + K_upperJ* = cint(ord('J')) + K_upperK* = cint(ord('K')) + K_upperL* = cint(ord('L')) + K_upperM* = cint(ord('M')) + K_upperN* = cint(ord('N')) + K_upperO* = cint(ord('O')) + K_upperP* = cint(ord('P')) + K_upperQ* = cint(ord('Q')) + K_upperR* = cint(ord('R')) + K_upperS* = cint(ord('S')) + K_upperT* = cint(ord('T')) + K_upperU* = cint(ord('U')) + K_upperV* = cint(ord('V')) + K_upperW* = cint(ord('W')) + K_upperX* = cint(ord('X')) + K_upperY* = cint(ord('Y')) + K_upperZ* = cint(ord('Z')) + K_bracketleft* = cint(ord('[')) + K_backslash* = cint(ord('\\')) + K_bracketright* = cint(ord(']')) + K_circum* = cint(ord('^')) + K_underscore* = cint(ord('_')) + K_grave* = cint(ord('`')) + K_lowera* = cint(ord('a')) + K_lowerb* = cint(ord('b')) + K_lowerc* = cint(ord('c')) + K_lowerd* = cint(ord('d')) + K_lowere* = cint(ord('e')) + K_lowerf* = cint(ord('f')) + K_lowerg* = cint(ord('g')) + K_lowerh* = cint(ord('h')) + K_loweri* = cint(ord('i')) + K_lowerj* = cint(ord('j')) + K_lowerk* = cint(ord('k')) + K_lowerl* = cint(ord('l')) + K_lowerm* = cint(ord('m')) + K_lowern* = cint(ord('n')) + K_lowero* = cint(ord('o')) + K_lowerp* = cint(ord('p')) + K_lowerq* = cint(ord('q')) + K_lowerr* = cint(ord('r')) + K_lowers* = cint(ord('s')) + K_lowert* = cint(ord('t')) + K_loweru* = cint(ord('u')) + K_lowerv* = cint(ord('v')) + K_lowerw* = cint(ord('w')) + K_lowerx* = cint(ord('x')) + K_lowery* = cint(ord('y')) + K_lowerz* = cint(ord('z')) + K_braceleft* = cint(ord('{')) + K_bar* = cint(ord('|')) + K_braceright* = cint(ord('}')) + K_tilde* = cint(ord('~')) + +proc isPrint*(c: cint): bool = return c > 31 and c < 127 + +# also define the escape sequences that have keys associated +const + K_BS* = cint(ord('\b')) + K_TAB* = cint(ord('\t')) + K_LF* = cint(10) + K_CR* = cint(13) + +# IUP Extended Key Codes, range start at 128 +# Modifiers use 256 interval +# These key code definitions are specific to IUP + +proc isXkey*(c: cint): bool = return c > 128 +proc isShiftXkey*(c: cint): bool = return c > 256 and c < 512 +proc isCtrlXkey*(c: cint): bool = return c > 512 and c < 768 +proc isAltXkey*(c: cint): bool = return c > 768 and c < 1024 +proc isSysXkey*(c: cint): bool = return c > 1024 and c < 1280 + +proc iUPxCODE*(c: cint): cint = return c + cint(128) # Normal (must be above 128) proc iUPsxCODE*(c: cint): cint = return c + cint(256) # Shift (must have range to include the standard keys and the normal # extended keys, so must be above 256 -proc iUPcxCODE*(c: cint): cint = return c + cint(512) # Ctrl -proc iUPmxCODE*(c: cint): cint = return c + cint(768) # Alt -proc iUPyxCODE*(c: cint): cint = return c + cint(1024) # Sys (Win or Apple) +proc iUPcxCODE*(c: cint): cint = return c + cint(512) # Ctrl +proc iUPmxCODE*(c: cint): cint = return c + cint(768) # Alt +proc iUPyxCODE*(c: cint): cint = return c + cint(1024) # Sys (Win or Apple) -const - IUP_NUMMAXCODES* = 1280 ## 5*256=1280 Normal+Shift+Ctrl+Alt+Sys - - K_HOME* = iupxCODE(1) - K_UP* = iupxCODE(2) - K_PGUP* = iupxCODE(3) - K_LEFT* = iupxCODE(4) - K_MIDDLE* = iupxCODE(5) - K_RIGHT* = iupxCODE(6) - K_END* = iupxCODE(7) - K_DOWN* = iupxCODE(8) - K_PGDN* = iupxCODE(9) - K_INS* = iupxCODE(10) - K_DEL* = iupxCODE(11) - K_PAUSE* = iupxCODE(12) - K_ESC* = iupxCODE(13) - K_ccedilla* = iupxCODE(14) - K_F1* = iupxCODE(15) - K_F2* = iupxCODE(16) - K_F3* = iupxCODE(17) - K_F4* = iupxCODE(18) - K_F5* = iupxCODE(19) - K_F6* = iupxCODE(20) - K_F7* = iupxCODE(21) - K_F8* = iupxCODE(22) - K_F9* = iupxCODE(23) - K_F10* = iupxCODE(24) - K_F11* = iupxCODE(25) - K_F12* = iupxCODE(26) - K_Print* = iupxCODE(27) - K_Menu* = iupxCODE(28) - - K_acute* = iupxCODE(29) # no Shift/Ctrl/Alt - - K_sHOME* = iUPsxCODE(K_HOME) - K_sUP* = iUPsxCODE(K_UP) - K_sPGUP* = iUPsxCODE(K_PGUP) - K_sLEFT* = iUPsxCODE(K_LEFT) - K_sMIDDLE* = iUPsxCODE(K_MIDDLE) - K_sRIGHT* = iUPsxCODE(K_RIGHT) - K_sEND* = iUPsxCODE(K_END) - K_sDOWN* = iUPsxCODE(K_DOWN) - K_sPGDN* = iUPsxCODE(K_PGDN) - K_sINS* = iUPsxCODE(K_INS) - K_sDEL* = iUPsxCODE(K_DEL) - K_sSP* = iUPsxCODE(K_SP) - K_sTAB* = iUPsxCODE(K_TAB) - K_sCR* = iUPsxCODE(K_CR) - K_sBS* = iUPsxCODE(K_BS) - K_sPAUSE* = iUPsxCODE(K_PAUSE) - K_sESC* = iUPsxCODE(K_ESC) - K_sCcedilla* = iUPsxCODE(K_ccedilla) - K_sF1* = iUPsxCODE(K_F1) - K_sF2* = iUPsxCODE(K_F2) - K_sF3* = iUPsxCODE(K_F3) - K_sF4* = iUPsxCODE(K_F4) - K_sF5* = iUPsxCODE(K_F5) - K_sF6* = iUPsxCODE(K_F6) - K_sF7* = iUPsxCODE(K_F7) - K_sF8* = iUPsxCODE(K_F8) - K_sF9* = iUPsxCODE(K_F9) - K_sF10* = iUPsxCODE(K_F10) - K_sF11* = iUPsxCODE(K_F11) - K_sF12* = iUPsxCODE(K_F12) - K_sPrint* = iUPsxCODE(K_Print) - K_sMenu* = iUPsxCODE(K_Menu) - - K_cHOME* = iUPcxCODE(K_HOME) - K_cUP* = iUPcxCODE(K_UP) - K_cPGUP* = iUPcxCODE(K_PGUP) - K_cLEFT* = iUPcxCODE(K_LEFT) - K_cMIDDLE* = iUPcxCODE(K_MIDDLE) - K_cRIGHT* = iUPcxCODE(K_RIGHT) - K_cEND* = iUPcxCODE(K_END) - K_cDOWN* = iUPcxCODE(K_DOWN) - K_cPGDN* = iUPcxCODE(K_PGDN) - K_cINS* = iUPcxCODE(K_INS) - K_cDEL* = iUPcxCODE(K_DEL) - K_cSP* = iUPcxCODE(K_SP) - K_cTAB* = iUPcxCODE(K_TAB) - K_cCR* = iUPcxCODE(K_CR) - K_cBS* = iUPcxCODE(K_BS) - K_cPAUSE* = iUPcxCODE(K_PAUSE) - K_cESC* = iUPcxCODE(K_ESC) - K_cCcedilla* = iUPcxCODE(K_ccedilla) - K_cF1* = iUPcxCODE(K_F1) - K_cF2* = iUPcxCODE(K_F2) - K_cF3* = iUPcxCODE(K_F3) - K_cF4* = iUPcxCODE(K_F4) - K_cF5* = iUPcxCODE(K_F5) - K_cF6* = iUPcxCODE(K_F6) - K_cF7* = iUPcxCODE(K_F7) - K_cF8* = iUPcxCODE(K_F8) - K_cF9* = iUPcxCODE(K_F9) - K_cF10* = iUPcxCODE(K_F10) - K_cF11* = iUPcxCODE(K_F11) - K_cF12* = iUPcxCODE(K_F12) - K_cPrint* = iUPcxCODE(K_Print) - K_cMenu* = iUPcxCODE(K_Menu) - - K_mHOME* = iUPmxCODE(K_HOME) - K_mUP* = iUPmxCODE(K_UP) - K_mPGUP* = iUPmxCODE(K_PGUP) - K_mLEFT* = iUPmxCODE(K_LEFT) - K_mMIDDLE* = iUPmxCODE(K_MIDDLE) - K_mRIGHT* = iUPmxCODE(K_RIGHT) - K_mEND* = iUPmxCODE(K_END) - K_mDOWN* = iUPmxCODE(K_DOWN) - K_mPGDN* = iUPmxCODE(K_PGDN) - K_mINS* = iUPmxCODE(K_INS) - K_mDEL* = iUPmxCODE(K_DEL) - K_mSP* = iUPmxCODE(K_SP) - K_mTAB* = iUPmxCODE(K_TAB) - K_mCR* = iUPmxCODE(K_CR) - K_mBS* = iUPmxCODE(K_BS) - K_mPAUSE* = iUPmxCODE(K_PAUSE) - K_mESC* = iUPmxCODE(K_ESC) - K_mCcedilla* = iUPmxCODE(K_ccedilla) - K_mF1* = iUPmxCODE(K_F1) - K_mF2* = iUPmxCODE(K_F2) - K_mF3* = iUPmxCODE(K_F3) - K_mF4* = iUPmxCODE(K_F4) - K_mF5* = iUPmxCODE(K_F5) - K_mF6* = iUPmxCODE(K_F6) - K_mF7* = iUPmxCODE(K_F7) - K_mF8* = iUPmxCODE(K_F8) - K_mF9* = iUPmxCODE(K_F9) - K_mF10* = iUPmxCODE(K_F10) - K_mF11* = iUPmxCODE(K_F11) - K_mF12* = iUPmxCODE(K_F12) - K_mPrint* = iUPmxCODE(K_Print) - K_mMenu* = iUPmxCODE(K_Menu) - - K_yHOME* = iUPyxCODE(K_HOME) - K_yUP* = iUPyxCODE(K_UP) - K_yPGUP* = iUPyxCODE(K_PGUP) - K_yLEFT* = iUPyxCODE(K_LEFT) - K_yMIDDLE* = iUPyxCODE(K_MIDDLE) - K_yRIGHT* = iUPyxCODE(K_RIGHT) - K_yEND* = iUPyxCODE(K_END) - K_yDOWN* = iUPyxCODE(K_DOWN) - K_yPGDN* = iUPyxCODE(K_PGDN) - K_yINS* = iUPyxCODE(K_INS) - K_yDEL* = iUPyxCODE(K_DEL) - K_ySP* = iUPyxCODE(K_SP) - K_yTAB* = iUPyxCODE(K_TAB) - K_yCR* = iUPyxCODE(K_CR) - K_yBS* = iUPyxCODE(K_BS) - K_yPAUSE* = iUPyxCODE(K_PAUSE) - K_yESC* = iUPyxCODE(K_ESC) - K_yCcedilla* = iUPyxCODE(K_ccedilla) - K_yF1* = iUPyxCODE(K_F1) - K_yF2* = iUPyxCODE(K_F2) - K_yF3* = iUPyxCODE(K_F3) - K_yF4* = iUPyxCODE(K_F4) - K_yF5* = iUPyxCODE(K_F5) - K_yF6* = iUPyxCODE(K_F6) - K_yF7* = iUPyxCODE(K_F7) - K_yF8* = iUPyxCODE(K_F8) - K_yF9* = iUPyxCODE(K_F9) - K_yF10* = iUPyxCODE(K_F10) - K_yF11* = iUPyxCODE(K_F11) - K_yF12* = iUPyxCODE(K_F12) - K_yPrint* = iUPyxCODE(K_Print) - K_yMenu* = iUPyxCODE(K_Menu) - - K_sPlus* = iUPsxCODE(K_plus) - K_sComma* = iUPsxCODE(K_comma) - K_sMinus* = iUPsxCODE(K_minus) - K_sPeriod* = iUPsxCODE(K_period) - K_sSlash* = iUPsxCODE(K_slash) - K_sAsterisk* = iUPsxCODE(K_asterisk) - - K_cupperA* = iUPcxCODE(K_upperA) - K_cupperB* = iUPcxCODE(K_upperB) - K_cupperC* = iUPcxCODE(K_upperC) - K_cupperD* = iUPcxCODE(K_upperD) - K_cupperE* = iUPcxCODE(K_upperE) - K_cupperF* = iUPcxCODE(K_upperF) - K_cupperG* = iUPcxCODE(K_upperG) - K_cupperH* = iUPcxCODE(K_upperH) - K_cupperI* = iUPcxCODE(K_upperI) - K_cupperJ* = iUPcxCODE(K_upperJ) - K_cupperK* = iUPcxCODE(K_upperK) - K_cupperL* = iUPcxCODE(K_upperL) - K_cupperM* = iUPcxCODE(K_upperM) - K_cupperN* = iUPcxCODE(K_upperN) - K_cupperO* = iUPcxCODE(K_upperO) - K_cupperP* = iUPcxCODE(K_upperP) - K_cupperQ* = iUPcxCODE(K_upperQ) - K_cupperR* = iUPcxCODE(K_upperR) - K_cupperS* = iUPcxCODE(K_upperS) - K_cupperT* = iUPcxCODE(K_upperT) - K_cupperU* = iUPcxCODE(K_upperU) - K_cupperV* = iUPcxCODE(K_upperV) - K_cupperW* = iUPcxCODE(K_upperW) - K_cupperX* = iUPcxCODE(K_upperX) - K_cupperY* = iUPcxCODE(K_upperY) - K_cupperZ* = iUPcxCODE(K_upperZ) - K_c1* = iUPcxCODE(K_1) - K_c2* = iUPcxCODE(K_2) - K_c3* = iUPcxCODE(K_3) - K_c4* = iUPcxCODE(K_4) - K_c5* = iUPcxCODE(K_5) - K_c6* = iUPcxCODE(K_6) - K_c7* = iUPcxCODE(K_7) - K_c8* = iUPcxCODE(K_8) - K_c9* = iUPcxCODE(K_9) - K_c0* = iUPcxCODE(K_0) - K_cPlus* = iUPcxCODE(K_plus) - K_cComma* = iUPcxCODE(K_comma) - K_cMinus* = iUPcxCODE(K_minus) - K_cPeriod* = iUPcxCODE(K_period) - K_cSlash* = iUPcxCODE(K_slash) - K_cSemicolon* = iUPcxCODE(K_semicolon) - K_cEqual* = iUPcxCODE(K_equal) - K_cBracketleft* = iUPcxCODE(K_bracketleft) - K_cBracketright* = iUPcxCODE(K_bracketright) - K_cBackslash* = iUPcxCODE(K_backslash) - K_cAsterisk* = iUPcxCODE(K_asterisk) - - K_mupperA* = iUPmxCODE(K_upperA) - K_mupperB* = iUPmxCODE(K_upperB) - K_mupperC* = iUPmxCODE(K_upperC) - K_mupperD* = iUPmxCODE(K_upperD) - K_mupperE* = iUPmxCODE(K_upperE) - K_mupperF* = iUPmxCODE(K_upperF) - K_mupperG* = iUPmxCODE(K_upperG) - K_mupperH* = iUPmxCODE(K_upperH) - K_mupperI* = iUPmxCODE(K_upperI) - K_mupperJ* = iUPmxCODE(K_upperJ) - K_mupperK* = iUPmxCODE(K_upperK) - K_mupperL* = iUPmxCODE(K_upperL) - K_mupperM* = iUPmxCODE(K_upperM) - K_mupperN* = iUPmxCODE(K_upperN) - K_mupperO* = iUPmxCODE(K_upperO) - K_mupperP* = iUPmxCODE(K_upperP) - K_mupperQ* = iUPmxCODE(K_upperQ) - K_mupperR* = iUPmxCODE(K_upperR) - K_mupperS* = iUPmxCODE(K_upperS) - K_mupperT* = iUPmxCODE(K_upperT) - K_mupperU* = iUPmxCODE(K_upperU) - K_mupperV* = iUPmxCODE(K_upperV) - K_mupperW* = iUPmxCODE(K_upperW) - K_mupperX* = iUPmxCODE(K_upperX) - K_mupperY* = iUPmxCODE(K_upperY) - K_mupperZ* = iUPmxCODE(K_upperZ) - K_m1* = iUPmxCODE(K_1) - K_m2* = iUPmxCODE(K_2) - K_m3* = iUPmxCODE(K_3) - K_m4* = iUPmxCODE(K_4) - K_m5* = iUPmxCODE(K_5) - K_m6* = iUPmxCODE(K_6) - K_m7* = iUPmxCODE(K_7) - K_m8* = iUPmxCODE(K_8) - K_m9* = iUPmxCODE(K_9) - K_m0* = iUPmxCODE(K_0) - K_mPlus* = iUPmxCODE(K_plus) - K_mComma* = iUPmxCODE(K_comma) - K_mMinus* = iUPmxCODE(K_minus) - K_mPeriod* = iUPmxCODE(K_period) - K_mSlash* = iUPmxCODE(K_slash) - K_mSemicolon* = iUPmxCODE(K_semicolon) - K_mEqual* = iUPmxCODE(K_equal) - K_mBracketleft* = iUPmxCODE(K_bracketleft) - K_mBracketright* = iUPmxCODE(K_bracketright) - K_mBackslash* = iUPmxCODE(K_backslash) - K_mAsterisk* = iUPmxCODE(K_asterisk) - - K_yA* = iUPyxCODE(K_upperA) - K_yB* = iUPyxCODE(K_upperB) - K_yC* = iUPyxCODE(K_upperC) - K_yD* = iUPyxCODE(K_upperD) - K_yE* = iUPyxCODE(K_upperE) - K_yF* = iUPyxCODE(K_upperF) - K_yG* = iUPyxCODE(K_upperG) - K_yH* = iUPyxCODE(K_upperH) - K_yI* = iUPyxCODE(K_upperI) - K_yJ* = iUPyxCODE(K_upperJ) - K_yK* = iUPyxCODE(K_upperK) - K_yL* = iUPyxCODE(K_upperL) - K_yM* = iUPyxCODE(K_upperM) - K_yN* = iUPyxCODE(K_upperN) - K_yO* = iUPyxCODE(K_upperO) - K_yP* = iUPyxCODE(K_upperP) - K_yQ* = iUPyxCODE(K_upperQ) - K_yR* = iUPyxCODE(K_upperR) - K_yS* = iUPyxCODE(K_upperS) - K_yT* = iUPyxCODE(K_upperT) - K_yU* = iUPyxCODE(K_upperU) - K_yV* = iUPyxCODE(K_upperV) - K_yW* = iUPyxCODE(K_upperW) - K_yX* = iUPyxCODE(K_upperX) - K_yY* = iUPyxCODE(K_upperY) - K_yZ* = iUPyxCODE(K_upperZ) - K_y1* = iUPyxCODE(K_1) - K_y2* = iUPyxCODE(K_2) - K_y3* = iUPyxCODE(K_3) - K_y4* = iUPyxCODE(K_4) - K_y5* = iUPyxCODE(K_5) - K_y6* = iUPyxCODE(K_6) - K_y7* = iUPyxCODE(K_7) - K_y8* = iUPyxCODE(K_8) - K_y9* = iUPyxCODE(K_9) - K_y0* = iUPyxCODE(K_0) - K_yPlus* = iUPyxCODE(K_plus) - K_yComma* = iUPyxCODE(K_comma) - K_yMinus* = iUPyxCODE(K_minus) - K_yPeriod* = iUPyxCODE(K_period) - K_ySlash* = iUPyxCODE(K_slash) - K_ySemicolon* = iUPyxCODE(K_semicolon) - K_yEqual* = iUPyxCODE(K_equal) - K_yBracketleft* = iUPyxCODE(K_bracketleft) - K_yBracketright* = iUPyxCODE(K_bracketright) - K_yBackslash* = iUPyxCODE(K_backslash) - K_yAsterisk* = iUPyxCODE(K_asterisk) +const + IUP_NUMMAXCODES* = 1280 ## 5*256=1280 Normal+Shift+Ctrl+Alt+Sys -proc controlsOpen*(): cint {.cdecl, importc: "IupControlsOpen", dynlib: dllname.} -proc controlsClose*() {.cdecl, importc: "IupControlsClose", dynlib: dllname.} - -proc oldValOpen*() {.cdecl, importc: "IupOldValOpen", dynlib: dllname.} -proc oldTabsOpen*() {.cdecl, importc: "IupOldTabsOpen", dynlib: dllname.} - -proc colorbar*(): PIhandle {.cdecl, importc: "IupColorbar", dynlib: dllname.} -proc cells*(): PIhandle {.cdecl, importc: "IupCells", dynlib: dllname.} -proc colorBrowser*(): PIhandle {.cdecl, importc: "IupColorBrowser", dynlib: dllname.} -proc gauge*(): PIhandle {.cdecl, importc: "IupGauge", dynlib: dllname.} -proc dial*(theType: cstring): PIhandle {.cdecl, importc: "IupDial", dynlib: dllname.} -proc matrix*(action: cstring): PIhandle {.cdecl, importc: "IupMatrix", dynlib: dllname.} - -# IupMatrix utilities + K_HOME* = iUPxCODE(1) + K_UP* = iUPxCODE(2) + K_PGUP* = iUPxCODE(3) + K_LEFT* = iUPxCODE(4) + K_MIDDLE* = iUPxCODE(5) + K_RIGHT* = iUPxCODE(6) + K_END* = iUPxCODE(7) + K_DOWN* = iUPxCODE(8) + K_PGDN* = iUPxCODE(9) + K_INS* = iUPxCODE(10) + K_DEL* = iUPxCODE(11) + K_PAUSE* = iUPxCODE(12) + K_ESC* = iUPxCODE(13) + K_ccedilla* = iUPxCODE(14) + K_F1* = iUPxCODE(15) + K_F2* = iUPxCODE(16) + K_F3* = iUPxCODE(17) + K_F4* = iUPxCODE(18) + K_F5* = iUPxCODE(19) + K_F6* = iUPxCODE(20) + K_F7* = iUPxCODE(21) + K_F8* = iUPxCODE(22) + K_F9* = iUPxCODE(23) + K_F10* = iUPxCODE(24) + K_F11* = iUPxCODE(25) + K_F12* = iUPxCODE(26) + K_Print* = iUPxCODE(27) + K_Menu* = iUPxCODE(28) + + K_acute* = iUPxCODE(29) # no Shift/Ctrl/Alt + + K_sHOME* = iUPsxCODE(K_HOME) + K_sUP* = iUPsxCODE(K_UP) + K_sPGUP* = iUPsxCODE(K_PGUP) + K_sLEFT* = iUPsxCODE(K_LEFT) + K_sMIDDLE* = iUPsxCODE(K_MIDDLE) + K_sRIGHT* = iUPsxCODE(K_RIGHT) + K_sEND* = iUPsxCODE(K_END) + K_sDOWN* = iUPsxCODE(K_DOWN) + K_sPGDN* = iUPsxCODE(K_PGDN) + K_sINS* = iUPsxCODE(K_INS) + K_sDEL* = iUPsxCODE(K_DEL) + K_sSP* = iUPsxCODE(K_SP) + K_sTAB* = iUPsxCODE(K_TAB) + K_sCR* = iUPsxCODE(K_CR) + K_sBS* = iUPsxCODE(K_BS) + K_sPAUSE* = iUPsxCODE(K_PAUSE) + K_sESC* = iUPsxCODE(K_ESC) + K_sCcedilla* = iUPsxCODE(K_ccedilla) + K_sF1* = iUPsxCODE(K_F1) + K_sF2* = iUPsxCODE(K_F2) + K_sF3* = iUPsxCODE(K_F3) + K_sF4* = iUPsxCODE(K_F4) + K_sF5* = iUPsxCODE(K_F5) + K_sF6* = iUPsxCODE(K_F6) + K_sF7* = iUPsxCODE(K_F7) + K_sF8* = iUPsxCODE(K_F8) + K_sF9* = iUPsxCODE(K_F9) + K_sF10* = iUPsxCODE(K_F10) + K_sF11* = iUPsxCODE(K_F11) + K_sF12* = iUPsxCODE(K_F12) + K_sPrint* = iUPsxCODE(K_Print) + K_sMenu* = iUPsxCODE(K_Menu) + + K_cHOME* = iUPcxCODE(K_HOME) + K_cUP* = iUPcxCODE(K_UP) + K_cPGUP* = iUPcxCODE(K_PGUP) + K_cLEFT* = iUPcxCODE(K_LEFT) + K_cMIDDLE* = iUPcxCODE(K_MIDDLE) + K_cRIGHT* = iUPcxCODE(K_RIGHT) + K_cEND* = iUPcxCODE(K_END) + K_cDOWN* = iUPcxCODE(K_DOWN) + K_cPGDN* = iUPcxCODE(K_PGDN) + K_cINS* = iUPcxCODE(K_INS) + K_cDEL* = iUPcxCODE(K_DEL) + K_cSP* = iUPcxCODE(K_SP) + K_cTAB* = iUPcxCODE(K_TAB) + K_cCR* = iUPcxCODE(K_CR) + K_cBS* = iUPcxCODE(K_BS) + K_cPAUSE* = iUPcxCODE(K_PAUSE) + K_cESC* = iUPcxCODE(K_ESC) + K_cCcedilla* = iUPcxCODE(K_ccedilla) + K_cF1* = iUPcxCODE(K_F1) + K_cF2* = iUPcxCODE(K_F2) + K_cF3* = iUPcxCODE(K_F3) + K_cF4* = iUPcxCODE(K_F4) + K_cF5* = iUPcxCODE(K_F5) + K_cF6* = iUPcxCODE(K_F6) + K_cF7* = iUPcxCODE(K_F7) + K_cF8* = iUPcxCODE(K_F8) + K_cF9* = iUPcxCODE(K_F9) + K_cF10* = iUPcxCODE(K_F10) + K_cF11* = iUPcxCODE(K_F11) + K_cF12* = iUPcxCODE(K_F12) + K_cPrint* = iUPcxCODE(K_Print) + K_cMenu* = iUPcxCODE(K_Menu) + + K_mHOME* = iUPmxCODE(K_HOME) + K_mUP* = iUPmxCODE(K_UP) + K_mPGUP* = iUPmxCODE(K_PGUP) + K_mLEFT* = iUPmxCODE(K_LEFT) + K_mMIDDLE* = iUPmxCODE(K_MIDDLE) + K_mRIGHT* = iUPmxCODE(K_RIGHT) + K_mEND* = iUPmxCODE(K_END) + K_mDOWN* = iUPmxCODE(K_DOWN) + K_mPGDN* = iUPmxCODE(K_PGDN) + K_mINS* = iUPmxCODE(K_INS) + K_mDEL* = iUPmxCODE(K_DEL) + K_mSP* = iUPmxCODE(K_SP) + K_mTAB* = iUPmxCODE(K_TAB) + K_mCR* = iUPmxCODE(K_CR) + K_mBS* = iUPmxCODE(K_BS) + K_mPAUSE* = iUPmxCODE(K_PAUSE) + K_mESC* = iUPmxCODE(K_ESC) + K_mCcedilla* = iUPmxCODE(K_ccedilla) + K_mF1* = iUPmxCODE(K_F1) + K_mF2* = iUPmxCODE(K_F2) + K_mF3* = iUPmxCODE(K_F3) + K_mF4* = iUPmxCODE(K_F4) + K_mF5* = iUPmxCODE(K_F5) + K_mF6* = iUPmxCODE(K_F6) + K_mF7* = iUPmxCODE(K_F7) + K_mF8* = iUPmxCODE(K_F8) + K_mF9* = iUPmxCODE(K_F9) + K_mF10* = iUPmxCODE(K_F10) + K_mF11* = iUPmxCODE(K_F11) + K_mF12* = iUPmxCODE(K_F12) + K_mPrint* = iUPmxCODE(K_Print) + K_mMenu* = iUPmxCODE(K_Menu) + + K_yHOME* = iUPyxCODE(K_HOME) + K_yUP* = iUPyxCODE(K_UP) + K_yPGUP* = iUPyxCODE(K_PGUP) + K_yLEFT* = iUPyxCODE(K_LEFT) + K_yMIDDLE* = iUPyxCODE(K_MIDDLE) + K_yRIGHT* = iUPyxCODE(K_RIGHT) + K_yEND* = iUPyxCODE(K_END) + K_yDOWN* = iUPyxCODE(K_DOWN) + K_yPGDN* = iUPyxCODE(K_PGDN) + K_yINS* = iUPyxCODE(K_INS) + K_yDEL* = iUPyxCODE(K_DEL) + K_ySP* = iUPyxCODE(K_SP) + K_yTAB* = iUPyxCODE(K_TAB) + K_yCR* = iUPyxCODE(K_CR) + K_yBS* = iUPyxCODE(K_BS) + K_yPAUSE* = iUPyxCODE(K_PAUSE) + K_yESC* = iUPyxCODE(K_ESC) + K_yCcedilla* = iUPyxCODE(K_ccedilla) + K_yF1* = iUPyxCODE(K_F1) + K_yF2* = iUPyxCODE(K_F2) + K_yF3* = iUPyxCODE(K_F3) + K_yF4* = iUPyxCODE(K_F4) + K_yF5* = iUPyxCODE(K_F5) + K_yF6* = iUPyxCODE(K_F6) + K_yF7* = iUPyxCODE(K_F7) + K_yF8* = iUPyxCODE(K_F8) + K_yF9* = iUPyxCODE(K_F9) + K_yF10* = iUPyxCODE(K_F10) + K_yF11* = iUPyxCODE(K_F11) + K_yF12* = iUPyxCODE(K_F12) + K_yPrint* = iUPyxCODE(K_Print) + K_yMenu* = iUPyxCODE(K_Menu) + + K_sPlus* = iUPsxCODE(K_plus) + K_sComma* = iUPsxCODE(K_comma) + K_sMinus* = iUPsxCODE(K_minus) + K_sPeriod* = iUPsxCODE(K_period) + K_sSlash* = iUPsxCODE(K_slash) + K_sAsterisk* = iUPsxCODE(K_asterisk) + + K_cupperA* = iUPcxCODE(K_upperA) + K_cupperB* = iUPcxCODE(K_upperB) + K_cupperC* = iUPcxCODE(K_upperC) + K_cupperD* = iUPcxCODE(K_upperD) + K_cupperE* = iUPcxCODE(K_upperE) + K_cupperF* = iUPcxCODE(K_upperF) + K_cupperG* = iUPcxCODE(K_upperG) + K_cupperH* = iUPcxCODE(K_upperH) + K_cupperI* = iUPcxCODE(K_upperI) + K_cupperJ* = iUPcxCODE(K_upperJ) + K_cupperK* = iUPcxCODE(K_upperK) + K_cupperL* = iUPcxCODE(K_upperL) + K_cupperM* = iUPcxCODE(K_upperM) + K_cupperN* = iUPcxCODE(K_upperN) + K_cupperO* = iUPcxCODE(K_upperO) + K_cupperP* = iUPcxCODE(K_upperP) + K_cupperQ* = iUPcxCODE(K_upperQ) + K_cupperR* = iUPcxCODE(K_upperR) + K_cupperS* = iUPcxCODE(K_upperS) + K_cupperT* = iUPcxCODE(K_upperT) + K_cupperU* = iUPcxCODE(K_upperU) + K_cupperV* = iUPcxCODE(K_upperV) + K_cupperW* = iUPcxCODE(K_upperW) + K_cupperX* = iUPcxCODE(K_upperX) + K_cupperY* = iUPcxCODE(K_upperY) + K_cupperZ* = iUPcxCODE(K_upperZ) + K_c1* = iUPcxCODE(K_1) + K_c2* = iUPcxCODE(K_2) + K_c3* = iUPcxCODE(K_3) + K_c4* = iUPcxCODE(K_4) + K_c5* = iUPcxCODE(K_5) + K_c6* = iUPcxCODE(K_6) + K_c7* = iUPcxCODE(K_7) + K_c8* = iUPcxCODE(K_8) + K_c9* = iUPcxCODE(K_9) + K_c0* = iUPcxCODE(K_0) + K_cPlus* = iUPcxCODE(K_plus) + K_cComma* = iUPcxCODE(K_comma) + K_cMinus* = iUPcxCODE(K_minus) + K_cPeriod* = iUPcxCODE(K_period) + K_cSlash* = iUPcxCODE(K_slash) + K_cSemicolon* = iUPcxCODE(K_semicolon) + K_cEqual* = iUPcxCODE(K_equal) + K_cBracketleft* = iUPcxCODE(K_bracketleft) + K_cBracketright* = iUPcxCODE(K_bracketright) + K_cBackslash* = iUPcxCODE(K_backslash) + K_cAsterisk* = iUPcxCODE(K_asterisk) + + K_mupperA* = iUPmxCODE(K_upperA) + K_mupperB* = iUPmxCODE(K_upperB) + K_mupperC* = iUPmxCODE(K_upperC) + K_mupperD* = iUPmxCODE(K_upperD) + K_mupperE* = iUPmxCODE(K_upperE) + K_mupperF* = iUPmxCODE(K_upperF) + K_mupperG* = iUPmxCODE(K_upperG) + K_mupperH* = iUPmxCODE(K_upperH) + K_mupperI* = iUPmxCODE(K_upperI) + K_mupperJ* = iUPmxCODE(K_upperJ) + K_mupperK* = iUPmxCODE(K_upperK) + K_mupperL* = iUPmxCODE(K_upperL) + K_mupperM* = iUPmxCODE(K_upperM) + K_mupperN* = iUPmxCODE(K_upperN) + K_mupperO* = iUPmxCODE(K_upperO) + K_mupperP* = iUPmxCODE(K_upperP) + K_mupperQ* = iUPmxCODE(K_upperQ) + K_mupperR* = iUPmxCODE(K_upperR) + K_mupperS* = iUPmxCODE(K_upperS) + K_mupperT* = iUPmxCODE(K_upperT) + K_mupperU* = iUPmxCODE(K_upperU) + K_mupperV* = iUPmxCODE(K_upperV) + K_mupperW* = iUPmxCODE(K_upperW) + K_mupperX* = iUPmxCODE(K_upperX) + K_mupperY* = iUPmxCODE(K_upperY) + K_mupperZ* = iUPmxCODE(K_upperZ) + K_m1* = iUPmxCODE(K_1) + K_m2* = iUPmxCODE(K_2) + K_m3* = iUPmxCODE(K_3) + K_m4* = iUPmxCODE(K_4) + K_m5* = iUPmxCODE(K_5) + K_m6* = iUPmxCODE(K_6) + K_m7* = iUPmxCODE(K_7) + K_m8* = iUPmxCODE(K_8) + K_m9* = iUPmxCODE(K_9) + K_m0* = iUPmxCODE(K_0) + K_mPlus* = iUPmxCODE(K_plus) + K_mComma* = iUPmxCODE(K_comma) + K_mMinus* = iUPmxCODE(K_minus) + K_mPeriod* = iUPmxCODE(K_period) + K_mSlash* = iUPmxCODE(K_slash) + K_mSemicolon* = iUPmxCODE(K_semicolon) + K_mEqual* = iUPmxCODE(K_equal) + K_mBracketleft* = iUPmxCODE(K_bracketleft) + K_mBracketright* = iUPmxCODE(K_bracketright) + K_mBackslash* = iUPmxCODE(K_backslash) + K_mAsterisk* = iUPmxCODE(K_asterisk) + + K_yA* = iUPyxCODE(K_upperA) + K_yB* = iUPyxCODE(K_upperB) + K_yC* = iUPyxCODE(K_upperC) + K_yD* = iUPyxCODE(K_upperD) + K_yE* = iUPyxCODE(K_upperE) + K_yF* = iUPyxCODE(K_upperF) + K_yG* = iUPyxCODE(K_upperG) + K_yH* = iUPyxCODE(K_upperH) + K_yI* = iUPyxCODE(K_upperI) + K_yJ* = iUPyxCODE(K_upperJ) + K_yK* = iUPyxCODE(K_upperK) + K_yL* = iUPyxCODE(K_upperL) + K_yM* = iUPyxCODE(K_upperM) + K_yN* = iUPyxCODE(K_upperN) + K_yO* = iUPyxCODE(K_upperO) + K_yP* = iUPyxCODE(K_upperP) + K_yQ* = iUPyxCODE(K_upperQ) + K_yR* = iUPyxCODE(K_upperR) + K_yS* = iUPyxCODE(K_upperS) + K_yT* = iUPyxCODE(K_upperT) + K_yU* = iUPyxCODE(K_upperU) + K_yV* = iUPyxCODE(K_upperV) + K_yW* = iUPyxCODE(K_upperW) + K_yX* = iUPyxCODE(K_upperX) + K_yY* = iUPyxCODE(K_upperY) + K_yZ* = iUPyxCODE(K_upperZ) + K_y1* = iUPyxCODE(K_1) + K_y2* = iUPyxCODE(K_2) + K_y3* = iUPyxCODE(K_3) + K_y4* = iUPyxCODE(K_4) + K_y5* = iUPyxCODE(K_5) + K_y6* = iUPyxCODE(K_6) + K_y7* = iUPyxCODE(K_7) + K_y8* = iUPyxCODE(K_8) + K_y9* = iUPyxCODE(K_9) + K_y0* = iUPyxCODE(K_0) + K_yPlus* = iUPyxCODE(K_plus) + K_yComma* = iUPyxCODE(K_comma) + K_yMinus* = iUPyxCODE(K_minus) + K_yPeriod* = iUPyxCODE(K_period) + K_ySlash* = iUPyxCODE(K_slash) + K_ySemicolon* = iUPyxCODE(K_semicolon) + K_yEqual* = iUPyxCODE(K_equal) + K_yBracketleft* = iUPyxCODE(K_bracketleft) + K_yBracketright* = iUPyxCODE(K_bracketright) + K_yBackslash* = iUPyxCODE(K_backslash) + K_yAsterisk* = iUPyxCODE(K_asterisk) + +proc controlsOpen*(): cint {.cdecl, importc: "IupControlsOpen", dynlib: dllname.} +proc controlsClose*() {.cdecl, importc: "IupControlsClose", dynlib: dllname.} + +proc oldValOpen*() {.cdecl, importc: "IupOldValOpen", dynlib: dllname.} +proc oldTabsOpen*() {.cdecl, importc: "IupOldTabsOpen", dynlib: dllname.} + +proc colorbar*(): PIhandle {.cdecl, importc: "IupColorbar", dynlib: dllname.} +proc cells*(): PIhandle {.cdecl, importc: "IupCells", dynlib: dllname.} +proc colorBrowser*(): PIhandle {.cdecl, importc: "IupColorBrowser", dynlib: dllname.} +proc gauge*(): PIhandle {.cdecl, importc: "IupGauge", dynlib: dllname.} +proc dial*(theType: cstring): PIhandle {.cdecl, importc: "IupDial", dynlib: dllname.} +proc matrix*(action: cstring): PIhandle {.cdecl, importc: "IupMatrix", dynlib: dllname.} + +# IupMatrix utilities proc matSetAttribute*(ih: PIhandle, name: cstring, lin, col: cint, value: cstring) {. - cdecl, importc: "IupMatSetAttribute", dynlib: dllname.} + cdecl, importc: "IupMatSetAttribute", dynlib: dllname.} proc matStoreAttribute*(ih: PIhandle, name: cstring, lin, col: cint, value: cstring) {.cdecl, - importc: "IupMatStoreAttribute", dynlib: dllname.} + importc: "IupMatStoreAttribute", dynlib: dllname.} proc matGetAttribute*(ih: PIhandle, name: cstring, lin, col: cint): cstring {. - cdecl, importc: "IupMatGetAttribute", dynlib: dllname.} + cdecl, importc: "IupMatGetAttribute", dynlib: dllname.} proc matGetInt*(ih: PIhandle, name: cstring, lin, col: cint): cint {. - cdecl, importc: "IupMatGetInt", dynlib: dllname.} + cdecl, importc: "IupMatGetInt", dynlib: dllname.} proc matGetFloat*(ih: PIhandle, name: cstring, lin, col: cint): cfloat {. - cdecl, importc: "IupMatGetFloat", dynlib: dllname.} + cdecl, importc: "IupMatGetFloat", dynlib: dllname.} proc matSetfAttribute*(ih: PIhandle, name: cstring, lin, col: cint, format: cstring) {.cdecl, importc: "IupMatSetfAttribute", - dynlib: dllname, varargs.} - -# Used by IupColorbar -const - IUP_PRIMARY* = -1 - IUP_SECONDARY* = -2 - -# Initialize PPlot widget class -proc pPlotOpen*() {.cdecl, importc: "IupPPlotOpen", dynlib: dllname.} - -# Create an PPlot widget instance -proc pPlot*: PIhandle {.cdecl, importc: "IupPPlot", dynlib: dllname.} - -# Add dataset to plot -proc pPlotBegin*(ih: PIhandle, strXdata: cint) {. - cdecl, importc: "IupPPlotBegin", dynlib: dllname.} -proc pPlotAdd*(ih: PIhandle, x, y: cfloat) {. - cdecl, importc: "IupPPlotAdd", dynlib: dllname.} -proc pPlotAddStr*(ih: PIhandle, x: cstring, y: cfloat) {. - cdecl, importc: "IupPPlotAddStr", dynlib: dllname.} -proc pPlotEnd*(ih: PIhandle): cint {. - cdecl, importc: "IupPPlotEnd", dynlib: dllname.} - -proc pPlotInsertStr*(ih: PIhandle, index, sample_index: cint, x: cstring, - y: cfloat) {.cdecl, importc: "IupPPlotInsertStr", - dynlib: dllname.} -proc pPlotInsert*(ih: PIhandle, index, sample_index: cint, - x, y: cfloat) {. - cdecl, importc: "IupPPlotInsert", dynlib: dllname.} - -# convert from plot coordinates to pixels -proc pPlotTransform*(ih: PIhandle, x, y: cfloat, ix, iy: var cint) {. - cdecl, importc: "IupPPlotTransform", dynlib: dllname.} - -# Plot on the given device. Uses a "cdCanvas*". -proc pPlotPaintTo*(ih: PIhandle, cnv: pointer) {. - cdecl, importc: "IupPPlotPaintTo", dynlib: dllname.} - + dynlib: dllname, varargs.} + +# Used by IupColorbar +const + IUP_PRIMARY* = -1 + IUP_SECONDARY* = -2 + +# Initialize PPlot widget class +proc pPlotOpen*() {.cdecl, importc: "IupPPlotOpen", dynlib: dllname.} + +# Create an PPlot widget instance +proc pPlot*: PIhandle {.cdecl, importc: "IupPPlot", dynlib: dllname.} + +# Add dataset to plot +proc pPlotBegin*(ih: PIhandle, strXdata: cint) {. + cdecl, importc: "IupPPlotBegin", dynlib: dllname.} +proc pPlotAdd*(ih: PIhandle, x, y: cfloat) {. + cdecl, importc: "IupPPlotAdd", dynlib: dllname.} +proc pPlotAddStr*(ih: PIhandle, x: cstring, y: cfloat) {. + cdecl, importc: "IupPPlotAddStr", dynlib: dllname.} +proc pPlotEnd*(ih: PIhandle): cint {. + cdecl, importc: "IupPPlotEnd", dynlib: dllname.} + +proc pPlotInsertStr*(ih: PIhandle, index, sampleIndex: cint, x: cstring, + y: cfloat) {.cdecl, importc: "IupPPlotInsertStr", + dynlib: dllname.} +proc pPlotInsert*(ih: PIhandle, index, sampleIndex: cint, + x, y: cfloat) {. + cdecl, importc: "IupPPlotInsert", dynlib: dllname.} + +# convert from plot coordinates to pixels +proc pPlotTransform*(ih: PIhandle, x, y: cfloat, ix, iy: var cint) {. + cdecl, importc: "IupPPlotTransform", dynlib: dllname.} + +# Plot on the given device. Uses a "cdCanvas*". +proc pPlotPaintTo*(ih: PIhandle, cnv: pointer) {. + cdecl, importc: "IupPPlotPaintTo", dynlib: dllname.} + From 59b9af074cc411431efd06762ede7b16ee831c5e Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 19 Sep 2014 01:16:12 +0200 Subject: [PATCH 148/409] updated libcurl.nim --- lib/wrappers/libcurl.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/wrappers/libcurl.nim b/lib/wrappers/libcurl.nim index bd8616759..8c962f6cb 100644 --- a/lib/wrappers/libcurl.nim +++ b/lib/wrappers/libcurl.nim @@ -43,10 +43,10 @@ type Pinfotype* = ptr Tinfotype Plock_access* = ptr Tlock_access Plock_data* = ptr Tlock_data - Pmalloc_callback* = ptr tmalloc_callback + Pmalloc_callback* = ptr Tmalloc_callback PNETRC_OPTION* = ptr TNETRC_OPTION Pproxytype* = ptr Tproxytype - Prealloc_callback* = ptr trealloc_callback + Prealloc_callback* = ptr Trealloc_callback Pslist* = ptr Tslist Psocket* = ptr Tsocket PSSL_VERSION* = ptr TSSL_VERSION @@ -309,7 +309,7 @@ type TMsg*{.pure, final.} = object msg*: TMSGEnum easy_handle*: PCurl - whatever*: Pointer #data : record + whatever*: pointer #data : record # case longint of # 0 : ( whatever : pointer ); # 1 : ( result : CURLcode ); @@ -442,7 +442,7 @@ proc slist_append*(slist: Pslist, p: cstring): Pslist{.cdecl, dynlib: libname, importc: "curl_slist_append".} proc slist_free_all*(para1: Pslist){.cdecl, dynlib: libname, importc: "curl_slist_free_all".} -proc getdate*(p: cstring, unused: ptr TTime): TTime{.cdecl, dynlib: libname, +proc getdate*(p: cstring, unused: ptr Time): Time{.cdecl, dynlib: libname, importc: "curl_getdate".} proc share_init*(): PSH{.cdecl, dynlib: libname, importc: "curl_share_init".} proc share_setopt*(para1: PSH, option: TSHoption): TSHcode{.cdecl, varargs, From 6a8a7678aa0b6b875a27345c73a430d0e3ace366 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 19 Sep 2014 01:30:26 +0200 Subject: [PATCH 149/409] cleaned up openssl.nim a bit --- lib/wrappers/openssl.nim | 83 ++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index a668f3526..abdfcdb52 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -45,7 +45,7 @@ when defined(WINDOWS): const DLLSSLName = "(ssleay32|libssl32).dll" DLLUtilName = "libeay32.dll" - from winlean import TSocketHandle + from winlean import SocketHandle else: const versions = "(|.1.0.0|.0.9.9|.0.9.8|.0.9.7|.0.9.6|.0.9.5|.0.9.4)" @@ -57,7 +57,7 @@ else: const DLLSSLName = "libssl.so" & versions DLLUtilName = "libcrypto.so" & versions - from posix import TSocketHandle + from posix import SocketHandle type SslStruct {.final, pure.} = object @@ -207,58 +207,59 @@ proc SSLv2_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.} proc SSLv3_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.} proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_new*(context: PSSL_CTX): PSSL{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_free*(ssl: PSSL){.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_new*(meth: PSSL_METHOD): PSSL_CTX{.cdecl, +proc SSL_new*(context: SslCtx): SslPtr{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_free*(ssl: SslPtr){.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_CTX_new*(meth: PSSL_METHOD): SslCtx{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_load_verify_locations*(ctx: PSSL_CTX, CAfile: cstring, +proc SSL_CTX_load_verify_locations*(ctx: SslCtx, CAfile: cstring, CApath: cstring): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_free*(arg0: PSSL_CTX){.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_set_verify*(s: PSSL_CTX, mode: int, cb: proc (a: int, b: pointer): int {.cdecl.}){.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_get_verify_result*(ssl: PSSL): int{.cdecl, +proc SSL_CTX_free*(arg0: SslCtx){.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_CTX_set_verify*(s: SslCtx, mode: int, cb: proc (a: int, b: pointer): int {.cdecl.}){.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_get_verify_result*(ssl: SslPtr): int{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_set_cipher_list*(s: PSSLCTX, ciphers: cstring): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_use_certificate_file*(ctx: PSSL_CTX, filename: cstring, typ: cInt): cInt{. +proc SSL_CTX_set_cipher_list*(s: SslCtx, ciphers: cstring): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_CTX_use_certificate_file*(ctx: SslCtx, filename: cstring, typ: cInt): cInt{. stdcall, dynlib: DLLSSLName, importc.} -proc SSL_CTX_use_certificate_chain_file*(ctx: PSSL_CTX, filename: cstring): cInt{. +proc SSL_CTX_use_certificate_chain_file*(ctx: SslCtx, filename: cstring): cInt{. stdcall, dynlib: DLLSSLName, importc.} -proc SSL_CTX_use_PrivateKey_file*(ctx: PSSL_CTX, +proc SSL_CTX_use_PrivateKey_file*(ctx: SslCtx, filename: cstring, typ: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_CTX_check_private_key*(ctx: PSSL_CTX): cInt{.cdecl, dynlib: DLLSSLName, +proc SSL_CTX_check_private_key*(ctx: SslCtx): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_set_fd*(ssl: PSSL, fd: TSocketHandle): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_set_fd*(ssl: SslPtr, fd: SocketHandle): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_shutdown*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_connect*(ssl: PSSL): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_read*(ssl: PSSL, buf: pointer, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_write*(ssl: PSSL, buf: cstring, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_get_error*(s: PSSL, ret_code: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_accept*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc SSL_pending*(ssl: PSSL): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_shutdown*(ssl: SslPtr): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_connect*(ssl: SslPtr): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_read*(ssl: SslPtr, buf: pointer, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_write*(ssl: SslPtr, buf: cstring, num: int): cint{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_get_error*(s: SslPtr, ret_code: cInt): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_accept*(ssl: SslPtr): cInt{.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_pending*(ssl: SslPtr): cInt{.cdecl, dynlib: DLLSSLName, importc.} -proc BIO_new_ssl_connect*(ctx: PSSL_CTX): PBIO{.cdecl, +proc BIO_new_ssl_connect*(ctx: SslCtx): BIO{.cdecl, dynlib: DLLSSLName, importc.} -proc BIO_ctrl*(bio: PBIO, cmd: cint, larg: int, arg: cstring): int{.cdecl, +proc BIO_ctrl*(bio: BIO, cmd: cint, larg: int, arg: cstring): int{.cdecl, dynlib: DLLSSLName, importc.} -proc BIO_get_ssl*(bio: PBIO, ssl: ptr PSSL): int = +proc BIO_get_ssl*(bio: BIO, ssl: ptr SslPtr): int = return BIO_ctrl(bio, BIO_C_GET_SSL, 0, cast[cstring](ssl)) -proc BIO_set_conn_hostname*(bio: PBIO, name: cstring): int = +proc BIO_set_conn_hostname*(bio: BIO, name: cstring): int = return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, name) -proc BIO_do_handshake*(bio: PBIO): int = +proc BIO_do_handshake*(bio: BIO): int = return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, nil) -proc BIO_do_connect*(bio: PBIO): int = +proc BIO_do_connect*(bio: BIO): int = return BIO_do_handshake(bio) -proc BIO_read*(b: PBIO, data: cstring, length: cInt): cInt{.cdecl, - dynlib: DLLUtilName, importc.} -proc BIO_write*(b: PBIO, data: cstring, length: cInt): cInt{.cdecl, - dynlib: DLLUtilName, importc.} +when not defined(nimfix): + proc BIO_read*(b: BIO, data: cstring, length: cInt): cInt{.cdecl, + dynlib: DLLUtilName, importc.} + proc BIO_write*(b: BIO, data: cstring, length: cInt): cInt{.cdecl, + dynlib: DLLUtilName, importc.} -proc BIO_free*(b: PBIO): cInt{.cdecl, dynlib: DLLUtilName, importc.} +proc BIO_free*(b: BIO): cInt{.cdecl, dynlib: DLLUtilName, importc.} -proc ERR_print_errors_fp*(fp: TFile){.cdecl, dynlib: DLLSSLName, importc.} +proc ERR_print_errors_fp*(fp: File){.cdecl, dynlib: DLLSSLName, importc.} proc ERR_error_string*(e: cInt, buf: cstring): cstring{.cdecl, dynlib: DLLUtilName, importc.} @@ -277,19 +278,19 @@ proc CRYPTO_malloc_init*() = when not defined(windows): CRYPTO_set_mem_functions(alloc, realloc, dealloc) -proc SSL_CTX_ctrl*(ctx: PSSL_CTX, cmd: cInt, larg: int, parg: pointer): int{. +proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cInt, larg: int, parg: pointer): int{. cdecl, dynlib: DLLSSLName, importc.} -proc SSLCTXSetMode*(ctx: PSSL_CTX, mode: int): int = +proc SSLCTXSetMode*(ctx: SslCtx, mode: int): int = result = SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, mode, nil) -proc bioNew*(b: PBIO_METHOD): PBIO{.cdecl, dynlib: DLLUtilName, importc: "BIO_new".} -proc bioFreeAll*(b: PBIO){.cdecl, dynlib: DLLUtilName, importc: "BIO_free_all".} +proc bioNew*(b: PBIO_METHOD): BIO{.cdecl, dynlib: DLLUtilName, importc: "BIO_new".} +proc bioFreeAll*(b: BIO){.cdecl, dynlib: DLLUtilName, importc: "BIO_free_all".} proc bioSMem*(): PBIO_METHOD{.cdecl, dynlib: DLLUtilName, importc: "BIO_s_mem".} -proc bioCtrlPending*(b: PBIO): cInt{.cdecl, dynlib: DLLUtilName, importc: "BIO_ctrl_pending".} -proc bioRead*(b: PBIO, Buf: cstring, length: cInt): cInt{.cdecl, +proc bioCtrlPending*(b: BIO): cInt{.cdecl, dynlib: DLLUtilName, importc: "BIO_ctrl_pending".} +proc bioRead*(b: BIO, Buf: cstring, length: cInt): cInt{.cdecl, dynlib: DLLUtilName, importc: "BIO_read".} -proc bioWrite*(b: PBIO, Buf: cstring, length: cInt): cInt{.cdecl, +proc bioWrite*(b: BIO, Buf: cstring, length: cInt): cInt{.cdecl, dynlib: DLLUtilName, importc: "BIO_write".} proc sslSetConnectState*(s: SslPtr) {.cdecl, From bf2e8ee95bf714191f379d4f5f8ebcd990659033 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 19 Sep 2014 01:46:21 +0200 Subject: [PATCH 150/409] updated pdcurses.nim --- lib/wrappers/pdcurses.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/wrappers/pdcurses.nim b/lib/wrappers/pdcurses.nim index a53289bce..bed69648a 100644 --- a/lib/wrappers/pdcurses.nim +++ b/lib/wrappers/pdcurses.nim @@ -741,7 +741,7 @@ proc getbkgd*(a2: ptr TWINDOW): cunsignedlong{.extdecl, importc: "getbkgd", proc getnstr*(a2: cstring; a3: cint): cint{.extdecl, importc: "getnstr", dynlib: pdcursesdll.} proc getstr*(a2: cstring): cint{.extdecl, importc: "getstr", dynlib: pdcursesdll.} -proc getwin*(a2: TFile): ptr TWINDOW{.extdecl, importc: "getwin", +proc getwin*(a2: File): ptr TWINDOW{.extdecl, importc: "getwin", dynlib: pdcursesdll.} proc halfdelay*(a2: cint): cint{.extdecl, importc: "halfdelay", dynlib: pdcursesdll.} @@ -895,7 +895,7 @@ proc mvwvline*(a2: ptr TWINDOW; a3: cint; a4: cint; a5: cunsignedlong; a6: cint) proc napms*(a2: cint): cint{.extdecl, importc: "napms", dynlib: pdcursesdll.} proc newpad*(a2: cint; a3: cint): ptr TWINDOW{.extdecl, importc: "newpad", dynlib: pdcursesdll.} -proc newterm*(a2: cstring; a3: TFile; a4: TFile): ptr TSCREEN{.extdecl, +proc newterm*(a2: cstring; a3: File; a4: File): ptr TSCREEN{.extdecl, importc: "newterm", dynlib: pdcursesdll.} proc newwin*(a2: cint; a3: cint; a4: cint; a5: cint): ptr TWINDOW{.extdecl, importc: "newwin", dynlib: pdcursesdll.} @@ -924,7 +924,7 @@ proc prefresh*(a2: ptr TWINDOW; a3: cint; a4: cint; a5: cint; a6: cint; a7: cint a8: cint): cint{.extdecl, importc: "prefresh", dynlib: pdcursesdll.} proc printw*(a2: cstring): cint{.varargs, extdecl, importc: "printw", dynlib: pdcursesdll.} -proc putwin*(a2: ptr TWINDOW; a3: TFile): cint{.extdecl, importc: "putwin", +proc putwin*(a2: ptr TWINDOW; a3: File): cint{.extdecl, importc: "putwin", dynlib: pdcursesdll.} proc qiflush*(){.extdecl, importc: "qiflush", dynlib: pdcursesdll.} proc raw*(): cint{.extdecl, importc: "raw", dynlib: pdcursesdll.} From 082bcb070f2e313cc6d0edad3f992a666a820785 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 19 Sep 2014 15:17:34 +0100 Subject: [PATCH 151/409] Fix --gc:none with --cs:partial. --- lib/system/mmdisp.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index ab3f91d20..e091c0889 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -308,7 +308,7 @@ elif defined(nogc): dest[] = src var allocator {.rtlThreadVar.}: TMemRegion - InstantiateForRegion(allocator) + instantiateForRegion(allocator) include "system/cellsets" From 80255d88893beb28a930d1ffe0ad25fc1905d6bf Mon Sep 17 00:00:00 2001 From: Reimer Behrends Date: Sun, 21 Sep 2014 18:30:03 +0200 Subject: [PATCH 152/409] Fix the C++ exception struct in nimbase.h. The struct NimException still referred to the old exception type E_Base, which has since been renamed to Exception. This made the C++ backend fail on any code that used exceptions. --- lib/nimbase.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nimbase.h b/lib/nimbase.h index b43094227..f49855076 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -175,9 +175,9 @@ __clang__ # define NIM_NIL 0 struct NimException { - NimException(struct E_Base* exp, const char* msg): exp(exp), msg(msg) {} + NimException(struct Exception* exp, const char* msg): exp(exp), msg(msg) {} - struct E_Base* exp; + struct Exception* exp; const char* msg; }; #else From 7916b1f9aa93fca368afda8b18396230ac7f338c Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 21 Sep 2014 18:39:00 +0200 Subject: [PATCH 153/409] implemented 'guard' annotation --- compiler/ast.nim | 16 +++-- compiler/ccgexprs.nim | 4 +- compiler/ccgstmts.nim | 4 +- compiler/cgen.nim | 8 +-- compiler/guards.nim | 16 +++++ compiler/jsgen.nim | 5 +- compiler/magicsys.nim | 2 +- compiler/msgs.nim | 9 +-- compiler/pragmas.nim | 88 ++++++++++++++---------- compiler/rodread.nim | 7 +- compiler/rodwrite.nim | 3 - compiler/semexprs.nim | 4 ++ compiler/sempass2.nim | 134 +++++++++++++++++++++++-------------- compiler/semstmts.nim | 9 ++- compiler/semtypes.nim | 2 +- compiler/types.nim | 2 +- compiler/vmgen.nim | 2 + compiler/wordrecg.nim | 4 +- tests/parallel/tguard1.nim | 37 ++++++++++ tests/parallel/tguard2.nim | 27 ++++++++ todo.txt | 7 +- 21 files changed, 267 insertions(+), 123 deletions(-) create mode 100644 tests/parallel/tguard1.nim create mode 100644 tests/parallel/tguard2.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index 2ba9cdb2e..e3e8fd49f 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -679,7 +679,7 @@ type heapRoot*: PRope # keeps track of the enclosing heap object that # owns this location (required by GC algorithms # employing heap snapshots or sliding views) - a*: int # location's "address", i.e. slot for temporaries + #a*: int # location's "address", i.e. slot for temporaries # ---------------- end of backend information ------------------------------ @@ -732,8 +732,9 @@ type # check for the owner when touching 'usedGenerics'. usedGenerics*: seq[PInstantiation] tab*: TStrTable # interface table for modules + of skLet, skVar, skField: + guard*: PSym else: nil - magic*: TMagic typ*: PType name*: PIdent @@ -795,7 +796,8 @@ type deepCopy*: PSym # overriden 'deepCopy' operation size*: BiggestInt # the size of the type in bytes # -1 means that the size is unkwown - align*: int # the type's alignment requirements + align*: int16 # the type's alignment requirements + lockLevel*: int16 # lock level as required for deadlock checking loc*: TLoc TPair*{.final.} = object @@ -1173,8 +1175,8 @@ proc newType(kind: TTypeKind, owner: PSym): PType = result.id = getID() when debugIds: registerId(result) - #if result.id < 2000 then - # MessageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id)) + #if result.id < 2000: + # messageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id)) proc mergeLoc(a: var TLoc, b: TLoc) = if a.k == low(a.k): a.k = b.k @@ -1182,7 +1184,7 @@ proc mergeLoc(a: var TLoc, b: TLoc) = a.flags = a.flags + b.flags if a.t == nil: a.t = b.t if a.r == nil: a.r = b.r - if a.a == 0: a.a = b.a + #if a.a == 0: a.a = b.a proc assignType(dest, src: PType) = dest.kind = src.kind @@ -1230,6 +1232,8 @@ proc copySym(s: PSym, keepId: bool = false): PSym = result.position = s.position result.loc = s.loc result.annex = s.annex # BUGFIX + if result.kind in {skVar, skLet, skField}: + result.guard = s.guard proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo): PSym = result = newSym(s.kind, newIdent, s.owner, info) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 8914ad0de..ca34cfa3a 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -409,7 +409,6 @@ proc putDataIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) = d.k = locData d.t = getUniqueType(t) d.r = r - d.a = -1 proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) = var a: TLoc @@ -425,7 +424,6 @@ proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) = d.k = locExpr d.t = getUniqueType(t) d.r = r - d.a = -1 proc binaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc @@ -1508,7 +1506,6 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) = linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n", getTypeDesc(p.module, srct), getTypeDesc(p.module, destt), lbl) tmp.k = locExpr - tmp.a = -1 tmp.t = srct tmp.s = OnStack tmp.flags = {} @@ -2043,6 +2040,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = nkFromStmt, nkTemplateDef, nkMacroDef: discard of nkPragma: genPragma(p, n) + of nkPragmaBlock: expr(p, n.lastSon, d) of nkProcDef, nkMethodDef, nkConverterDef: if (n.sons[genericParamsPos].kind == nkEmpty): var prc = n.sons[namePos].sym diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index efa8b0adc..e30b2c561 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -443,7 +443,7 @@ proc genBlock(p: BProc, t: PNode, d: var TLoc) = assert(t.sons[0].kind == nkSym) var sym = t.sons[0].sym sym.loc.k = locOther - sym.loc.a = p.breakIdx + sym.position = p.breakIdx+1 expr(p, t.sons[1], d) endBlock(p) @@ -482,7 +482,7 @@ proc genBreakStmt(p: BProc, t: PNode) = assert(t.sons[0].kind == nkSym) var sym = t.sons[0].sym assert(sym.loc.k == locOther) - idx = sym.loc.a + idx = sym.position-1 else: # an unnamed 'break' can only break a loop after 'transf' pass: while idx >= 0 and not p.blocks[idx].isLoop: dec idx diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 490aeec4b..743e877a1 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -55,7 +55,7 @@ proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) = result.s = s result.t = getUniqueType(typ) result.r = nil - result.a = - 1 + #result.a = - 1 result.flags = {} proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) = @@ -63,7 +63,7 @@ proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) = if a.k == locNone: a.k = k a.t = getUniqueType(typ) - a.a = - 1 + #a.a = - 1 a.s = s if a.r == nil: a.r = r @@ -407,7 +407,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) = result.r = con("LOC", toRope(p.labels)) linefmt(p, cpsLocals, "$1 $2;$n", getTypeDesc(p.module, t), result.r) result.k = locTemp - result.a = - 1 + #result.a = - 1 result.t = getUniqueType(t) result.s = OnStack result.flags = {} @@ -425,7 +425,7 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) = [getTypeDesc(p.module, toKeepAlive.t), fid]) inc(p.gcFrameId) result.k = locTemp - result.a = -1 + #result.a = -1 result.t = toKeepAlive.t result.s = OnStack result.flags = {} diff --git a/compiler/guards.nim b/compiler/guards.nim index 05128f409..cd0aaf296 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -838,6 +838,22 @@ proc addAsgnFact*(m: var TModel, key, value: PNode) = fact.sons[2] = value m.add fact +proc sameSubexprs*(m: TModel; a, b: PNode): bool = + # This should be used to check whether two *path expressions* refer to the + # same memory location according to 'm'. This is tricky: + # lock a[i].guard: + # ... + # access a[i].guarded + # + # Here a[i] is the same as a[i] iff 'i' and 'a' are not changed via '...'. + # However, nil checking requires exactly the same mechanism! But for now + # we simply use sameTree and live with the unsoundness of the analysis. + var check = newNodeI(nkCall, a.info, 3) + check.sons[0] = newSymNode(opEq) + check.sons[1] = a + check.sons[2] = b + result = m.doesImply(check) == impYes + proc addCaseBranchFacts*(m: var TModel, n: PNode, i: int) = let branch = n.sons[i] if branch.kind == nkOfBranch: diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 652f439a9..4772aecb5 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -724,7 +724,7 @@ proc genBlock(p: PProc, n: PNode, r: var TCompRes) = if (n.sons[0].kind != nkSym): internalError(n.info, "genBlock") var sym = n.sons[0].sym sym.loc.k = locOther - sym.loc.a = idx + sym.position = idx+1 setLen(p.blocks, idx + 1) p.blocks[idx].id = - p.unique # negative because it isn't used yet let labl = p.unique @@ -741,7 +741,7 @@ proc genBreakStmt(p: PProc, n: PNode) = assert(n.sons[0].kind == nkSym) let sym = n.sons[0].sym assert(sym.loc.k == locOther) - idx = sym.loc.a + idx = sym.position-1 else: # an unnamed 'break' can only break a loop after 'transf' pass: idx = len(p.blocks) - 1 @@ -1654,6 +1654,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = r.res = nil of nkGotoState, nkState: internalError(n.info, "first class iterators not implemented") + of nkPragmaBlock: gen(p, n.lastSon, r) else: internalError(n.info, "gen: unknown node type: " & $n.kind) var globals: PGlobals diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index a794253df..6d4c65268 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -35,7 +35,7 @@ proc registerSysType(t: PType) = proc newSysType(kind: TTypeKind, size: int): PType = result = newType(kind, systemModule) result.size = size - result.align = size + result.align = size.int16 proc getSysSym(name: string): PSym = result = strTableGet(systemModule.tab, getIdent(name)) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index da2fe122d..8368fe5fd 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -119,7 +119,7 @@ type warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode, warnEachIdentIsTuple, warnShadowIdent, warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2, - warnUninit, warnGcMem, warnUser, + warnUninit, warnGcMem, warnUnguardedAccess, warnUser, hintSuccess, hintSuccessX, hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded, hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled, @@ -387,9 +387,10 @@ const warnProveField: "cannot prove that field '$1' is accessible [ProveField]", warnProveIndex: "cannot prove index '$1' is valid [ProveIndex]", warnGcUnsafe: "not GC-safe: '$1' [GcUnsafe]", - warnGcUnsafe2: "cannot prove '$1' is GC-safe. This will become a compile time error in the future.", + warnGcUnsafe2: "cannot prove '$1' is GC-safe. Does not compile with --threads:on.", warnUninit: "'$1' might not have been initialized [Uninit]", warnGcMem: "'$1' uses GC'ed memory [GcMem]", + warnUnguardedAccess: "'$1' is accessed without its guard [UnguardedAccess]", warnUser: "$1 [User]", hintSuccess: "operation successful [Success]", hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]", @@ -410,7 +411,7 @@ const hintUser: "$1 [User]"] const - WarningsToStr*: array[0..26, string] = ["CannotOpenFile", "OctalEscape", + WarningsToStr*: array[0..27, string] = ["CannotOpenFile", "OctalEscape", "XIsNeverRead", "XmightNotBeenInit", "Deprecated", "ConfigDeprecated", "SmallLshouldNotBeUsed", "UnknownMagic", @@ -419,7 +420,7 @@ const "AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap", "UnsafeCode", "EachIdentIsTuple", "ShadowIdent", "ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit", - "GcMem", "User"] + "GcMem", "UnguardedAccess", "User"] HintsToStr*: array[0..16, string] = ["Success", "SuccessX", "LineTooLong", "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 24b2f6750..815369066 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -24,7 +24,7 @@ const wCompilerproc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl, - wGensym, wInject, wRaises, wTags, wUses, wOperator, wDelegator, wGcSafe, + wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe, wOverride} converterPragmas* = procPragmas methodPragmas* = procPragmas @@ -36,8 +36,8 @@ const iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect, wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern, wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises, - wTags, wUses, wOperator, wGcSafe} - exprPragmas* = {wLine} + wTags, wLocks, wGcSafe} + exprPragmas* = {wLine, wLocks} stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints, wLinedir, wStacktrace, wLinetrace, wOptimization, wHint, wWarning, wError, @@ -49,23 +49,23 @@ const lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, - wRaises, wUses, wTags, wGcSafe} + wRaises, wLocks, wTags, wGcSafe} typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow, wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef, wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, wBorrow, wGcSafe} fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError} + wImportCpp, wImportObjC, wError, wGuard} varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern, wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, - wGensym, wInject, wCodegenDecl} + wGensym, wInject, wCodegenDecl, wGuard} constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl, wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject} letPragmas* = varPragmas procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect, - wThread, wRaises, wUses, wTags, wGcSafe} + wThread, wRaises, wLocks, wTags, wGcSafe} allRoutinePragmas* = procPragmas + iteratorPragmas + lambdaPragmas proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) @@ -514,26 +514,27 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) = else: invalidPragma(n) -proc pragmaUses(c: PContext, n: PNode) = - proc processExc(c: PContext, x: PNode): PNode = - if x.kind in {nkAccQuoted, nkIdent, nkSym, - nkOpenSymChoice, nkClosedSymChoice}: - if considerQuotedIdent(x).s == "*": - return newSymNode(ast.anyGlobal) - result = c.semExpr(c, x) - if result.kind != nkSym or sfGlobal notin result.sym.flags: - localError(x.info, "'$1' is not a global variable" % result.renderTree) - result = newSymNode(ast.anyGlobal) - - if n.kind == nkExprColonExpr: - let it = n.sons[1] - if it.kind notin {nkCurly, nkBracket}: - n.sons[1] = processExc(c, it) - else: - for i in 0 .. high(int16): + localError(n.info, "integer must be in the valid range of int16") + else: + result = int16(x) proc typeBorrow(sym: PSym, n: PNode) = if n.kind == nkExprColonExpr: @@ -563,11 +564,25 @@ proc deprecatedStmt(c: PContext; pragma: PNode) = else: localError(n.info, "key:value pair expected") +proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym = + if it.kind != nkExprColonExpr: + invalidPragma(it); return + let n = it[1] + if n.kind == nkSym: + result = n.sym + elif kind == skField: + # we return a dummy symbol; later passes over the type will repair it. Note + # that generic instantiation needs to know about this too. But we're lazy + # and perform the lookup on demand instead. + result = newSym(skUnknown, considerQuotedIdent(n), nil, n.info) + else: + result = qualifiedLookUp(c, n) + proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, validPragmas: TSpecialWords): bool = var it = n.sons[i] var key = if it.kind == nkExprColonExpr: it.sons[0] else: it - if key.kind == nkIdent: + if key.kind == nkIdent: var userPragma = strTableGet(c.userPragmas, key.ident) if userPragma != nil: inc c.instCounter @@ -599,11 +614,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wAlign: if sym.typ == nil: invalidPragma(it) var align = expectIntLit(c, it) - if not isPowerOfTwo(align) and align != 0: + if (not isPowerOfTwo(align) and align != 0) or align >% high(int16): localError(it.info, errPowerOfTwoExpected) else: - sym.typ.align = align - of wSize: + sym.typ.align = align.int16 + of wSize: if sym.typ == nil: invalidPragma(it) var size = expectIntLit(c, it) if not isPowerOfTwo(size) or size <= 0 or size > 8: @@ -806,10 +821,15 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, if sym == nil: invalidPragma(it) of wLine: pragmaLine(c, it) of wRaises, wTags: pragmaRaisesOrTags(c, it) - of wUses: pragmaUses(c, it) - of wOperator: - if sym == nil: invalidPragma(it) - else: sym.position = expectIntLit(c, it) + of wLocks: + if sym == nil: pragmaLockStmt(c, it) + elif sym.typ == nil: invalidPragma(it) + else: sym.typ.lockLevel = pragmaLocks(c, it) + of wGuard: + if sym == nil or sym.kind notin {skVar, skLet, skField}: + invalidPragma(it) + else: + sym.guard = pragmaGuard(c, it, sym.kind) of wInjectStmt: if it.kind != nkExprColonExpr: localError(it.info, errExprExpected) diff --git a/compiler/rodread.nim b/compiler/rodread.nim index 3cc37fb98..3b3538e5d 100644 --- a/compiler/rodread.nim +++ b/compiler/rodread.nim @@ -280,11 +280,6 @@ proc decodeLoc(r: PRodReader, loc: var TLoc, info: TLineInfo) = loc.r = toRope(decodeStr(r.s, r.pos)) else: loc.r = nil - if r.s[r.pos] == '?': - inc(r.pos) - loc.a = decodeVInt(r.s, r.pos) - else: - loc.a = 0 if r.s[r.pos] == '>': inc(r.pos) else: internalError(info, "decodeLoc " & r.s[r.pos]) @@ -326,7 +321,7 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType = result.size = - 1 if r.s[r.pos] == '=': inc(r.pos) - result.align = decodeVInt(r.s, r.pos) + result.align = decodeVInt(r.s, r.pos).int16 else: result.align = 2 decodeLoc(r, result.loc, info) diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 7eacb0883..9fed7ac52 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -187,9 +187,6 @@ proc encodeLoc(w: PRodWriter, loc: TLoc, result: var string) = if loc.r != nil: add(result, '!') encodeStr(ropeToStr(loc.r), result) - if loc.a != 0: - add(result, '?') - encodeVInt(loc.a, result) if oldLen + 1 == result.len: # no data was necessary, so remove the '<' again: setLen(result, oldLen) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 11215ae68..64914cb25 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1626,6 +1626,10 @@ proc instantiateCreateFlowVarCall(c: PContext; t: PType; initIdTable(bindings) bindings.idTablePut(sym.ast[genericParamsPos].sons[0].typ, t) result = c.semGenerateInstance(c, sym, bindings, info) + # since it's an instantiation, we unmark it as a compilerproc. Otherwise + # codegen would fail: + result.flags = result.flags - {sfCompilerProc, sfExportC, sfImportC} + result.loc.r = nil proc setMs(n: PNode, s: PSym): PNode = result = n diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index fee70af15..794b7ec80 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -57,9 +57,13 @@ discard """ c() --> we need a stack of scopes for this analysis -""" -const trackGlobals = false ## we don't need it for now + # XXX enhance the algorithm to care about 'dirty' expressions: + lock a[i].L: + inc i # mark 'i' dirty + lock a[j].L: + access a[i], a[j] # --> reject a[i] +""" type TEffects = object @@ -71,12 +75,69 @@ type init: seq[int] # list of initialized variables guards: TModel # nested guards locked: seq[PNode] # locked locations - gcUnsafe, isRecursive: bool + gcUnsafe, isRecursive, isToplevel: bool PEffects = var TEffects proc isLocalVar(a: PEffects, s: PSym): bool = s.kind in {skVar, skResult} and sfGlobal notin s.flags and s.owner == a.owner +proc lockLocations(a: PEffects; pragma: PNode) = + if pragma.kind != nkExprColonExpr: + internalError(pragma.info, "no colon") + return + for x in pragma[1]: + a.locked.add x + +proc guardGlobal(a: PEffects; n: PNode; guard: PSym) = + # check whether the corresponding lock is held: + for L in a.locked: + if L.kind == nkSym and L.sym == guard: return + # we allow accesses nevertheless in top level statements for + # easier initialization: + #if a.isTopLevel: + # message(n.info, warnUnguardedAccess, renderTree(n)) + #else: + if not a.isTopLevel: + localError(n.info, errGenerated, "unguarded access: " & renderTree(n)) + +# 'guard*' are checks which are concerned with 'guard' annotations +# (var x{.guard: y.}: int) +proc guardDotAccess(a: PEffects; n: PNode) = + let ri = n.sons[1] + internalAssert ri.kind == nkSym and ri.sym.kind == skField + var g = ri.sym.guard + if g.isNil or a.isTopLevel: return + # fixup guard: + if g.kind == skUnknown: + var field: PSym = nil + var ty = n.sons[0].typ.skipTypes(abstractPtrs) + if ty.kind == tyTuple: + field = lookupInRecord(ty.n, g.name) + else: + while ty != nil and ty.kind == tyObject: + field = lookupInRecord(ty.n, g.name) + if field != nil: break + ty = ty.sons[0] + if ty == nil: break + ty = ty.skipTypes(abstractPtrs) + if field == nil: + localError(n.info, errGenerated, "invalid guard field: " & g.name.s) + return + g = field + #ri.sym.guard = field + # XXX unfortunately this is not correct for generic instantiations! + if g.kind == skField: + let dot = newNodeI(nkDotExpr, n.info, 2) + dot.sons[0] = n.sons[0] + dot.sons[1] = newSymNode(g) + dot.typ = g.typ + for L in a.locked: + #if a.guards.sameSubexprs(dot, L): return + if guards.sameTree(dot, L): return + localError(n.info, errGenerated, "unguarded access: " & renderTree(n)) + else: + guardGlobal(a, n, g) + proc initVar(a: PEffects, n: PNode) = if n.kind != nkSym: return let s = n.sym @@ -93,13 +154,6 @@ proc initVarViaNew(a: PEffects, n: PNode) = # are initialized: initVar(a, n) -when trackGlobals: - proc addUse(a: PEffects, e: PNode) = - var aa = a.uses - for i in 0 .. Date: Sun, 21 Sep 2014 23:57:54 +0200 Subject: [PATCH 154/409] made some tests green --- compiler/sempass2.nim | 2 +- compiler/semstmts.nim | 2 +- compiler/semtypes.nim | 3 + lib/pure/sockets.nim | 7 +- tests/bind/tnicerrorforsymchoice.nim | 6 +- .../argument_parser/argument_parser.nim | 64 +++++++++---------- tests/manyloc/nake/nakefile.nim | 6 +- .../tri_engine/math/vec.nim | 8 +-- tests/parallel/tflowvar.nim | 1 + tests/types/tforwty2.nim | 2 +- todo.txt | 1 - 11 files changed, 53 insertions(+), 49 deletions(-) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 794b7ec80..43c6f9ccd 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -104,7 +104,7 @@ proc guardGlobal(a: PEffects; n: PNode; guard: PSym) = # (var x{.guard: y.}: int) proc guardDotAccess(a: PEffects; n: PNode) = let ri = n.sons[1] - internalAssert ri.kind == nkSym and ri.sym.kind == skField + if ri.kind != nkSym or ri.sym.kind != skField: return var g = ri.sym.guard if g.isNil or a.isTopLevel: return # fixup guard: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index bd9ca6a0e..524a8fd99 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -448,7 +448,7 @@ proc semConst(c: PContext, n: PNode): PNode = if typ == nil: localError(a.sons[2].info, errConstExprExpected) continue - if not typeAllowed(typ, skConst): + if not typeAllowed(typ, skConst) and def.kind != nkNilLit: localError(a.info, errXisNoType, typeToString(typ)) continue v.typ = typ diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 765ab5be8..b3ff6c82a 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1342,6 +1342,9 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = if def.typ.kind != tyTypeDesc: typ = newTypeWithSons(c, tyStatic, @[def.typ]) else: + # the following line fixes ``TV2*[T:SomeNumber=TR] = array[0..1, T]`` + # from manyloc/named_argument_bug/triengine: + def.typ = def.typ.skipTypes({tyTypeDesc}) if not containsGenericType(def.typ): def = fitNode(c, typ, def) diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 33f4e8144..6975f07c0 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -142,9 +142,10 @@ type TSOBool: SOBool, TRecvLineResult: RecvLineResult, TReadLineResult: ReadLineResult, ETimeout: TimeoutError].} - -let - invalidSocket*: Socket = nil ## invalid socket +when defined(booting): + let invalidSocket*: Socket = nil ## invalid socket +else: + const invalidSocket*: Socket = nil ## invalid socket when defined(windows): let diff --git a/tests/bind/tnicerrorforsymchoice.nim b/tests/bind/tnicerrorforsymchoice.nim index a0e9091c3..e1ff090dd 100644 --- a/tests/bind/tnicerrorforsymchoice.nim +++ b/tests/bind/tnicerrorforsymchoice.nim @@ -5,13 +5,13 @@ discard """ #bug #442 import scgi, sockets, asyncio, strtabs -proc handleSCGIRequest[TScgi: TScgiState | PAsyncScgiState](s: TScgi) = +proc handleSCGIRequest[TScgi: ScgiState | AsyncScgiState](s: TScgi) = discard -proc handleSCGIRequest(client: PAsyncSocket, headers: PStringTable, +proc handleSCGIRequest(client: AsyncSocket, headers: StringTableRef, input: string) = discard -proc test(handle: proc (client: PAsyncSocket, headers: PStringTable, +proc test(handle: proc (client: AsyncSocket, headers: StringTableRef, input: string), b: int) = discard diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim index 29b70a84c..fec00dbf8 100644 --- a/tests/manyloc/argument_parser/argument_parser.nim +++ b/tests/manyloc/argument_parser/argument_parser.nim @@ -76,14 +76,14 @@ type case kind*: Tparam_kind of PK_EMPTY: nil of PK_INT: int_val*: int - of PK_BIGGEST_INT: big_int_val*: biggestInt + of PK_BIGGEST_INT: big_int_val*: BiggestInt of PK_FLOAT: float_val*: float - of PK_BIGGEST_FLOAT: big_float_val*: biggestFloat + of PK_BIGGEST_FLOAT: big_float_val*: BiggestFloat of PK_STRING: str_val*: string of PK_BOOL: bool_val*: bool of PK_HELP: nil - Tcommandline_results* = object of TObject ## \ + Tcommandline_results* = object of RootObj ## \ ## Contains the results of the parsing. ## ## Usually this is the result of the parse() call, but you can inherit from @@ -97,7 +97,7 @@ type ## the first name variant for all options to avoid you repeating the test ## with different keys. positional_parameters*: seq[Tparsed_parameter] - options*: TOrderedTable[string, Tparsed_parameter] + options*: OrderedTable[string, Tparsed_parameter] # - Tparam_kind procs @@ -193,7 +193,7 @@ template new_parsed_parameter*(tkind: Tparam_kind, expr): Tparsed_parameter = proc init*(param: var Tcommandline_results; positional_parameters: seq[Tparsed_parameter] = @[]; - options: TOrderedTable[string, Tparsed_parameter] = + options: OrderedTable[string, Tparsed_parameter] = initOrderedTable[string, Tparsed_parameter](4)) = ## Initialization helper with default parameters. param.positional_parameters = positional_parameters @@ -231,12 +231,12 @@ template run_custom_proc(parsed_parameter: Tparsed_parameter, ## Pass in the string of the parameter triggering the call. If the if not custom_validator.isNil: except: - raise_or_quit(EInvalidValue, ("Couldn't run custom proc for " & + raise_or_quit(ValueError, ("Couldn't run custom proc for " & "parameter $1:\n$2" % [escape(parameter), getCurrentExceptionMsg()])) let message = custom_validator(parameter, parsed_parameter) if not message.isNil and message.len > 0: - raise_or_quit(EInvalidValue, ("Failed to validate value for " & + raise_or_quit(ValueError, ("Failed to validate value for " & "parameter $1:\n$2" % [escape(parameter), message])) @@ -246,50 +246,50 @@ proc parse_parameter(quit_on_failure: bool, param, value: string, ## ## Pass the parameter string which requires a value and the text the user ## passed in for it. It will be parsed according to the param_kind. This proc - ## will raise (EInvalidValue, EOverflow) if something can't be parsed. + ## will raise (ValueError, EOverflow) if something can't be parsed. result.kind = param_kind case param_kind: of PK_INT: try: result.int_val = value.parseInt - except EOverflow: - raise_or_quit(EOverflow, ("parameter $1 requires an " & + except OverflowError: + raise_or_quit(OverflowError, ("parameter $1 requires an " & "integer, but $2 is too large to fit into one") % [param, escape(value)]) - except EInvalidValue: - raise_or_quit(EInvalidValue, ("parameter $1 requires an " & + except ValueError: + raise_or_quit(ValueError, ("parameter $1 requires an " & "integer, but $2 can't be parsed into one") % [param, escape(value)]) of PK_STRING: result.str_val = value of PK_FLOAT: try: result.float_val = value.parseFloat - except EInvalidValue: - raise_or_quit(EInvalidValue, ("parameter $1 requires a " & + except ValueError: + raise_or_quit(ValueError, ("parameter $1 requires a " & "float, but $2 can't be parsed into one") % [param, escape(value)]) of PK_BOOL: try: result.bool_val = value.parseBool - except EInvalidValue: - raise_or_quit(EInvalidValue, ("parameter $1 requires a " & + except ValueError: + raise_or_quit(ValueError, ("parameter $1 requires a " & "boolean, but $2 can't be parsed into one. Valid values are: " & "y, yes, true, 1, on, n, no, false, 0, off") % [param, escape(value)]) of PK_BIGGEST_INT: try: let parsed_len = parseBiggestInt(value, result.big_int_val) if value.len != parsed_len or parsed_len < 1: - raise_or_quit(EInvalidValue, ("parameter $1 requires an " & + raise_or_quit(ValueError, ("parameter $1 requires an " & "integer, but $2 can't be parsed completely into one") % [ param, escape(value)]) - except EInvalidValue: - raise_or_quit(EInvalidValue, ("parameter $1 requires an " & + except ValueError: + raise_or_quit(ValueError, ("parameter $1 requires an " & "integer, but $2 can't be parsed into one") % [param, escape(value)]) of PK_BIGGEST_FLOAT: try: let parsed_len = parseBiggestFloat(value, result.big_float_val) if value.len != parsed_len or parsed_len < 1: - raise_or_quit(EInvalidValue, ("parameter $1 requires a " & + raise_or_quit(ValueError, ("parameter $1 requires a " & "float, but $2 can't be parsed completely into one") % [ param, escape(value)]) - except EInvalidValue: - raise_or_quit(EInvalidValue, ("parameter $1 requires a " & + except ValueError: + raise_or_quit(ValueError, ("parameter $1 requires a " & "float, but $2 can't be parsed into one") % [param, escape(value)]) of PK_EMPTY: discard @@ -298,15 +298,15 @@ proc parse_parameter(quit_on_failure: bool, param, value: string, template build_specification_lookup(): - TOrderedTable[string, ptr Tparameter_specification] = + OrderedTable[string, ptr Tparameter_specification] = ## Returns the table used to keep pointers to all of the specifications. - var result {.gensym.}: TOrderedTable[string, ptr Tparameter_specification] + var result {.gensym.}: OrderedTable[string, ptr Tparameter_specification] result = initOrderedTable[string, ptr Tparameter_specification]( nextPowerOfTwo(expected.len)) for i in 0..expected.len-1: for param_to_detect in expected[i].names: if result.hasKey(param_to_detect): - raise_or_quit(EInvalidKey, + raise_or_quit(KeyError, "Parameter $1 repeated in input specification" % param_to_detect) else: result[param_to_detect] = addr(expected[i]) @@ -344,7 +344,7 @@ proc parse*(expected: seq[Tparameter_specification] = @[], ## ## If there is any kind of error and quit_on_failure is true, the quit proc ## will be called with a user error message. If quit_on_failure is false - ## errors will raise exceptions (usually EInvalidValue or EOverflow) instead + ## errors will raise exceptions (usually ValueError or EOverflow) instead ## for you to catch and handle. assert type_of_positional_parameters != PK_EMPTY and @@ -359,7 +359,7 @@ proc parse*(expected: seq[Tparameter_specification] = @[], # Prepare the input parameter list, maybe get it from the OS if not available. var args = args if args == nil: - let total_params = ParamCount() + let total_params = paramCount() #echo "Got no explicit args, retrieving from OS. Count: ", total_params newSeq(args, total_params) for i in 0..total_params - 1: @@ -387,7 +387,7 @@ proc parse*(expected: seq[Tparameter_specification] = @[], if param.consumes == PK_HELP: echo_help(expected, type_of_positional_parameters, bad_prefixes, end_of_options) - raise_or_quit(EInvalidKey, "") + raise_or_quit(KeyError, "") if param.consumes != PK_EMPTY: if i + 1 < args.len: @@ -396,14 +396,14 @@ proc parse*(expected: seq[Tparameter_specification] = @[], run_custom_proc(parsed, param.custom_validator, arg) i += 1 else: - raise_or_quit(EInvalidValue, ("parameter $1 requires a " & + raise_or_quit(ValueError, ("parameter $1 requires a " & "value, but none was provided") % [arg]) result.options[param.names[0]] = parsed break adding_positional_parameter else: for bad_prefix in bad_prefixes: if arg.startsWith(bad_prefix): - raise_or_quit(EInvalidValue, ("Found ambiguos parameter '$1' " & + raise_or_quit(ValueError, ("Found ambiguos parameter '$1' " & "starting with '$2', put '$3' as the previous parameter " & "if you want to force it as positional parameter.") % [arg, bad_prefix, end_of_options]) @@ -415,7 +415,7 @@ proc parse*(expected: seq[Tparameter_specification] = @[], i += 1 -proc toString(runes: seq[TRune]): string = +proc toString(runes: seq[Rune]): string = result = "" for rune in runes: result.add(rune.toUTF8) @@ -424,7 +424,7 @@ proc ascii_cmp(a, b: string): int = ## Comparison ignoring non ascii characters, for better switch sorting. let a = filterIt(toSeq(runes(a)), it.isAlpha()) # Can't use filterIt twice, github bug #351. - let b = filter(toSeq(runes(b)), proc(x: TRune): bool = x.isAlpha()) + let b = filter(toSeq(runes(b)), proc(x: Rune): bool = x.isAlpha()) return system.cmp(toString(a), toString(b)) diff --git a/tests/manyloc/nake/nakefile.nim b/tests/manyloc/nake/nakefile.nim index be7398fa0..d1d712964 100644 --- a/tests/manyloc/nake/nakefile.nim +++ b/tests/manyloc/nake/nakefile.nim @@ -84,7 +84,7 @@ task "download", "download game assets": skipAssets = false path = expandFilename("data") path.add DirSep - path.add(extractFilename(gameAssets)) + path.add(extractFilename(GameAssets)) if existsFile(path): echo "The file already exists\n", "[R]emove [M]ove [Q]uit [S]kip Source: ", GameAssets @@ -92,7 +92,7 @@ task "download", "download game assets": of "r": removeFile path of "m": - moveFile path, path/../(extractFilename(gameAssets)&"-old") + moveFile path, path/../(extractFilename(GameAssets)&"-old") of "s": skipAssets = true else: @@ -101,7 +101,7 @@ task "download", "download game assets": echo "Downloading from ", GameAssets if not skipAssets: echo "Downloading to ", path - downloadFile gameAssets, path + downloadFile GameAssets, path echo "Download finished" let targetDir = parentDir(parentDir(path)) diff --git a/tests/manyloc/named_argument_bug/tri_engine/math/vec.nim b/tests/manyloc/named_argument_bug/tri_engine/math/vec.nim index a6b7bac63..3b57acb8e 100644 --- a/tests/manyloc/named_argument_bug/tri_engine/math/vec.nim +++ b/tests/manyloc/named_argument_bug/tri_engine/math/vec.nim @@ -3,10 +3,10 @@ import tri_engine/config type - TV2*[T:TNumber=TR] = array[0..1, T] - TV3*[T:TNumber=TR] = array[0..2, T] - TV4*[T:TNumber=TR] = array[0..3, T] - TVT*[T:TNumber=TR] = TV2|TV3|TV4 + TV2*[T:SomeNumber=TR] = array[0..1, T] + TV3*[T:SomeNumber=TR] = array[0..2, T] + TV4*[T:SomeNumber=TR] = array[0..3, T] + TVT*[T:SomeNumber=TR] = TV2|TV3|TV4 #TV2* = array[0..1, TR] #TV3* = array[0..2, TR] #TV4* = array[0..3, TR] diff --git a/tests/parallel/tflowvar.nim b/tests/parallel/tflowvar.nim index 488c65a91..fd3aa326e 100644 --- a/tests/parallel/tflowvar.nim +++ b/tests/parallel/tflowvar.nim @@ -1,6 +1,7 @@ discard """ output: '''foobarfoobar bazbearbazbear + 1''' cmd: "nim $target --threads:on $options $file" """ diff --git a/tests/types/tforwty2.nim b/tests/types/tforwty2.nim index a6d899011..d103314c5 100644 --- a/tests/types/tforwty2.nim +++ b/tests/types/tforwty2.nim @@ -18,5 +18,5 @@ type PSDL_Sem = ptr TSDL_Sem TSDL_Sem = TSDL_Semaphore -proc SDL_CreateSemaphore(initial_value: Int32): PSDL_Sem {. +proc SDL_CreateSemaphore(initial_value: int32): PSDL_Sem {. importc: "SDL_CreateSemaphore".} diff --git a/todo.txt b/todo.txt index 3aa96294c..3e89ab77b 100644 --- a/todo.txt +++ b/todo.txt @@ -8,7 +8,6 @@ version 0.10 version 0.9.6 ============= -- fix tflowvar codegen test - allow simple read accesses to global variables --> difficult to ensure that no data races happen - split idetools into separate tool From 1a3b730bf5a2e5978d2dad3d8fb4c157134535e7 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 22 Sep 2014 01:25:13 +0200 Subject: [PATCH 155/409] made tests green --- examples/curlex.nim | 2 +- examples/htmlrefs.nim | 6 +-- examples/httpserver2.nim | 58 ++++++++++++++--------------- examples/sdlex.nim | 28 +++++++------- lib/pure/concurrency/threadpool.nim | 4 +- tests/effects/teffects1.nim | 2 +- tests/effects/tgcsafe.nim | 3 +- todo.txt | 6 ++- 8 files changed, 56 insertions(+), 53 deletions(-) diff --git a/examples/curlex.nim b/examples/curlex.nim index 1d0f18ddd..9dadd9a90 100644 --- a/examples/curlex.nim +++ b/examples/curlex.nim @@ -3,7 +3,7 @@ import var hCurl = easy_init() if hCurl != nil: - discard easy_setopt(hCurl, OPT_VERBOSE, True) + discard easy_setopt(hCurl, OPT_VERBOSE, true) discard easy_setopt(hCurl, OPT_URL, "http://force7.de/nimrod") discard easy_perform(hCurl) easy_cleanup(hCurl) diff --git a/examples/htmlrefs.nim b/examples/htmlrefs.nim index 6be28d1ca..5364d61b6 100644 --- a/examples/htmlrefs.nim +++ b/examples/htmlrefs.nim @@ -12,7 +12,7 @@ if paramCount() < 1: quit("Usage: htmlrefs filename[.html]") var links = 0 # count the number of links -var filename = addFileExt(ParamStr(1), "html") +var filename = addFileExt(paramStr(1), "html") var s = newFileStream(filename, fmRead) if s == nil: quit("cannot open the file " & filename) var x: XmlParser @@ -43,12 +43,12 @@ block mainLoop: while x.kind == xmlCharData: desc.add(x.charData) x.next() - Echo(desc & ": " & link) + echo(desc & ": " & link) else: x.next() of xmlEof: break # end of file reached of xmlError: - Echo(errorMsg(x)) + echo(errorMsg(x)) x.next() else: x.next() # skip other events diff --git a/examples/httpserver2.nim b/examples/httpserver2.nim index 45350ac89..13fea9e21 100644 --- a/examples/httpserver2.nim +++ b/examples/httpserver2.nim @@ -7,19 +7,19 @@ const type TRequestMethod = enum reqGet, reqPost TServer* = object ## contains the current server state - socket: TSocket + s: Socket job: seq[TJob] TJob* = object - client: TSocket - process: PProcess + client: Socket + process: Process # --------------- output messages -------------------------------------------- -proc sendTextContentType(client: TSocket) = +proc sendTextContentType(client: Socket) = send(client, "Content-type: text/html" & wwwNL) send(client, wwwNL) -proc badRequest(client: TSocket) = +proc badRequest(client: Socket) = # Inform the client that a request it has made has a problem. send(client, "HTTP/1.0 400 BAD REQUEST" & wwwNL) sendTextContentType(client) @@ -27,19 +27,19 @@ proc badRequest(client: TSocket) = "such as a POST without a Content-Length.

" & wwwNL) -proc cannotExec(client: TSocket) = +proc cannotExec(client: Socket) = send(client, "HTTP/1.0 500 Internal Server Error" & wwwNL) sendTextContentType(client) send(client, "

Error prohibited CGI execution.

" & wwwNL) -proc headers(client: TSocket, filename: string) = +proc headers(client: Socket, filename: string) = # XXX could use filename to determine file type send(client, "HTTP/1.0 200 OK" & wwwNL) send(client, ServerSig) sendTextContentType(client) -proc notFound(client: TSocket, path: string) = +proc notFound(client: Socket, path: string) = send(client, "HTTP/1.0 404 NOT FOUND" & wwwNL) send(client, ServerSig) sendTextContentType(client) @@ -50,7 +50,7 @@ proc notFound(client: TSocket, path: string) = send(client, "" & wwwNL) -proc unimplemented(client: TSocket) = +proc unimplemented(client: Socket) = send(client, "HTTP/1.0 501 Method Not Implemented" & wwwNL) send(client, ServerSig) sendTextContentType(client) @@ -62,24 +62,25 @@ proc unimplemented(client: TSocket) = # ----------------- file serving --------------------------------------------- -proc discardHeaders(client: TSocket) = skip(client) +proc discardHeaders(client: Socket) = skip(client) -proc serveFile(client: TSocket, filename: string) = +proc serveFile(client: Socket, filename: string) = discardHeaders(client) - var f: TFile + var f: File if open(f, filename): headers(client, filename) const bufSize = 8000 # != 8K might be good for memory manager var buf = alloc(bufsize) - while True: + while true: var bytesread = readBuffer(f, buf, bufsize) if bytesread > 0: var byteswritten = send(client, buf, bytesread) if bytesread != bytesWritten: + let err = osLastError() dealloc(buf) close(f) - OSError() + raiseOSError(err) if bytesread != bufSize: break dealloc(buf) close(f) @@ -89,7 +90,7 @@ proc serveFile(client: TSocket, filename: string) = # ------------------ CGI execution ------------------------------------------- -proc executeCgi(server: var TServer, client: TSocket, path, query: string, +proc executeCgi(server: var TServer, client: Socket, path, query: string, meth: TRequestMethod) = var env = newStringTable(modeCaseInsensitive) var contentLength = -1 @@ -131,9 +132,10 @@ proc executeCgi(server: var TServer, client: TSocket, path, query: string, if meth == reqPost: # get from client and post to CGI program: var buf = alloc(contentLength) - if recv(client, buf, contentLength) != contentLength: + if recv(client, buf, contentLength) != contentLength: + let err = osLastError() dealloc(buf) - OSError() + raiseOSError(err) var inp = process.inputStream inp.writeData(buf, contentLength) dealloc(buf) @@ -163,7 +165,7 @@ proc animate(server: var TServer) = # --------------- Server Setup ----------------------------------------------- -proc acceptRequest(server: var TServer, client: TSocket) = +proc acceptRequest(server: var TServer, client: Socket) = var cgi = false var query = "" var buf = "" @@ -197,7 +199,7 @@ proc acceptRequest(server: var TServer, client: TSocket) = if path[path.len-1] == '/' or existsDir(path): path = path / "index.html" - if not ExistsFile(path): + if not existsFile(path): discardHeaders(client) notFound(client, path) client.close() @@ -215,26 +217,24 @@ proc acceptRequest(server: var TServer, client: TSocket) = else: executeCgi(server, client, path, query, meth) - - when isMainModule: var port = 80 var server: TServer server.job = @[] - server.socket = socket(AF_INET) - if server.socket == InvalidSocket: OSError() - server.socket.bindAddr(port=TPort(port)) - listen(server.socket) + server.s = socket(AF_INET) + if server.s == invalidSocket: raiseOSError(osLastError()) + server.s.bindAddr(port=Port(port)) + listen(server.s) echo("server up on port " & $port) while true: # check for new new connection & handle it - var list: seq[TSocket] = @[server.socket] + var list: seq[Socket] = @[server.s] if select(list, 10) > 0: - var client: TSocket + var client: Socket new(client) - accept(server.socket, client) + accept(server.s, client) try: acceptRequest(server, client) except: @@ -244,4 +244,4 @@ when isMainModule: animate(server) # some slack for CPU sleep(10) - server.socket.close() + server.s.close() diff --git a/examples/sdlex.nim b/examples/sdlex.nim index 665affff8..3dd474d8e 100644 --- a/examples/sdlex.nim +++ b/examples/sdlex.nim @@ -9,21 +9,21 @@ var event: TEvent bgColor = colChocolate.int32 -if Init(INIT_VIDEO) != 0: +if init(INIT_VIDEO) != 0: quit "SDL failed to initialize!" -screen = SetVideoMode(640, 480, 16, SWSURFACE or ANYFORMAT) +screen = setVideoMode(640, 480, 16, SWSURFACE or ANYFORMAT) if screen.isNil: - quit($sdl.GetError()) + quit($sdl.getError()) -greeting = IMG_load("tux.png") +greeting = imgLoad("tux.png") if greeting.isNil: echo "Failed to load tux.png" else: ## convert the image to alpha and free the old one - var s = greeting.DisplayFormatAlpha() + var s = greeting.displayFormatAlpha() swap(greeting, s) - s.FreeSurface() + s.freeSurface() r.x = 0 r.y = 0 @@ -31,22 +31,22 @@ r.y = 0 block game_loop: while true: - while PollEvent(addr event) > 0: + while pollEvent(addr event) > 0: case event.kind of QUITEV: break game_loop of KEYDOWN: - if EvKeyboard(addr event).keysym.sym == K_ESCAPE: + if evKeyboard(addr event).keysym.sym == K_ESCAPE: break game_loop else: discard - discard FillRect(screen, nil, bgColor) - discard BlitSurface(greeting, nil, screen, addr r) - discard Flip(screen) + discard fillRect(screen, nil, bgColor) + discard blitSurface(greeting, nil, screen, addr r) + discard flip(screen) -greeting.FreeSurface() -screen.FreeSurface() -sdl.Quit() +greeting.freeSurface() +screen.freeSurface() +sdl.quit() ## fowl wuz here 10/2012 \ No newline at end of file diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index fe08e94fc..7b0593b3e 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -94,7 +94,7 @@ type idx: int FlowVarBase* = ref FlowVarBaseObj ## untyped base class for 'FlowVar[T]' - FlowVarBaseObj = object of TObject + FlowVarBaseObj = object of RootObj ready, usesCondVar: bool cv: CondVar #\ # for 'awaitAny' support @@ -164,7 +164,7 @@ proc cleanFlowVars(w: ptr Worker) = let q = addr(w.q) acquire(q.lock) for i in 0 .. difficult to ensure that - no data races happen - split idetools into separate tool - split docgen into separate tool - .benign pragma @@ -63,6 +63,8 @@ version 0.9.x - implicit deref for parameter matching - overloading of '='; general lift mechanism +- allow simple read accesses to global variables --> difficult to ensure that + no data races happen - pragmas need 'bindSym' support - pragmas need re-work: 'push' is dangerous, 'hasPragma' does not work reliably with user-defined pragmas From 8930ba50b99be7cd508a5d3284ef278ccb736767 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 22 Sep 2014 08:34:05 +0200 Subject: [PATCH 156/409] 'let' within 'parallel' now works --- compiler/semparallel.nim | 4 ++-- compiler/sempass2.nim | 2 +- tests/parallel/tlet_spawn.nim | 14 ++++++++++++++ todo.txt | 7 ++++--- 4 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 tests/parallel/tlet_spawn.nim diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim index fe735c9f2..c4546f616 100644 --- a/compiler/semparallel.nim +++ b/compiler/semparallel.nim @@ -335,7 +335,7 @@ proc analyse(c: var AnalysisCtx; n: PNode) = localError(n.info, "invalid control flow for 'parallel'") # 'break' that leaves the 'parallel' section is not valid either # or maybe we should generate a 'try' XXX - of nkVarSection: + of nkVarSection, nkLetSection: for it in n: let value = it.lastSon if value.kind != nkEmpty: @@ -396,7 +396,7 @@ proc transformSpawnSons(owner: PSym; n, barrier: PNode): PNode = proc transformSpawn(owner: PSym; n, barrier: PNode): PNode = case n.kind - of nkVarSection: + of nkVarSection, nkLetSection: result = nil for it in n: let b = it.lastSon diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 43c6f9ccd..a330e0ecd 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -599,7 +599,7 @@ proc track(tracked: PEffects, n: PNode) = addAsgnFact(tracked.guards, n.sons[0], n.sons[1]) notNilCheck(tracked, n.sons[1], n.sons[0].typ) when false: cstringCheck(tracked, n) - of nkVarSection: + of nkVarSection, nkLetSection: for child in n: let last = lastSon(child) if child.kind == nkIdentDefs and last.kind != nkEmpty: diff --git a/tests/parallel/tlet_spawn.nim b/tests/parallel/tlet_spawn.nim new file mode 100644 index 000000000..463ee1a47 --- /dev/null +++ b/tests/parallel/tlet_spawn.nim @@ -0,0 +1,14 @@ + +import threadpool + +proc foo(): int = 999 + +# test that the disjoint checker deals with 'a = spawn f(); g = spawn f()': + +proc main = + parallel: + let f = spawn foo() + let b = spawn foo() + echo "done", f, " ", b + +main() diff --git a/todo.txt b/todo.txt index b62c48d75..70173d50e 100644 --- a/todo.txt +++ b/todo.txt @@ -2,10 +2,12 @@ version 0.10 ============ - Test nimfix on various babel packages -- Pegs do not work at compile-time - deprecate recursive tuples; tuple needs laxer type checking - string case should require an 'else' - # echo type.int +- VM: try does not work at all +- VM: Pegs do not work at compile-time +- VM: ptr/ref T cannot work in general version 0.9.6 ============= @@ -22,7 +24,6 @@ Concurrency generics *when the type is constructed* - test 'deepCopy' -- the disjoint checker needs to deal with 'a = spawn f(); g = spawn f()' - implement 'foo[1..4] = spawn(f[4..7])' - document the new 'spawn' and 'parallel' statements @@ -30,7 +31,7 @@ Low priority: - support for exception propagation? (hard to implement) - the copying of the 'ref Promise' into the thead local storage only happens to work due to the write barrier's implementation -- implement lock levels --> first without the more complex race avoidance +- implement lock levels Misc From dfd73902772a0236e09cae534ba98f1a58c194ad Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 24 Sep 2014 03:01:16 +0200 Subject: [PATCH 157/409] added $* for subexes --- doc/subexes.txt | 2 ++ lib/pure/subexes.nim | 3 +++ 2 files changed, 5 insertions(+) diff --git a/doc/subexes.txt b/doc/subexes.txt index 7cad183b9..decf30eef 100644 --- a/doc/subexes.txt +++ b/doc/subexes.txt @@ -16,10 +16,12 @@ Notation meaning ``$name`` use named argument, you can wrap the named argument in curly braces (eg. ``${name}``) to separate it from the next characters. +``$$`` produces a single ``$`` ``$1`` use first argument ``$-1`` use last argument ``${1..3}`` use arguments 1 to 3 ``${..}`` use all arguments +``$*`` use all arguments (same as ``${..}``) ``${#..}`` use all remaining arguments ``${..-2}`` use all arguments except the last argument ``${$1}`` use argument X where ``X = parseInt(arg[1])`` diff --git a/lib/pure/subexes.nim b/lib/pure/subexes.nim index 452978c09..c87823926 100644 --- a/lib/pure/subexes.nim +++ b/lib/pure/subexes.nim @@ -196,6 +196,9 @@ proc scanDollar(p: var TFormatParser, a: openarray[string], s: var string) = of '$': emitChar p, s, '$' inc i + of '*': + for j in 0..a.high: emitStr p, s, a[j] + inc i of '{': call: let (x, y) = scanSlice(p, a) From 1088814e56811f3bca77f191d8c492405712fcdb Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 26 Sep 2014 09:36:09 +0200 Subject: [PATCH 158/409] deepCopy is instantiated when its corresponding type is instantiated --- compiler/ccgtypes.nim | 2 +- compiler/sem.nim | 2 ++ compiler/semdata.nim | 3 +++ compiler/semstmts.nim | 7 ++++++- compiler/semtypinst.nim | 12 ++++++++++++ compiler/sigmatch.nim | 12 ++++++++++++ doc/manual.txt | 5 +++++ lib/system/deepcopy.nim | 18 +++++++++--------- tests/parallel/tdeepcopy2.nim | 35 +++++++++++++++++++++++++++++++++++ todo.txt | 6 ++---- 10 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 tests/parallel/tdeepcopy2.nim diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 4cb6a9977..1b0b9e103 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -898,7 +898,7 @@ include ccgtrav proc genDeepCopyProc(m: BModule; s: PSym; result: PRope) = genProc(m, s) - appf(m.s[cfsTypeInit3], "$1.deepcopy = (N_NIMCALL_PTR(void*, void*)) $2;$n", + appf(m.s[cfsTypeInit3], "$1.deepcopy =(N_NIMCALL_PTR(void*,)(void*))$2;$n", [result, s.loc.r]) proc genTypeInfo(m: BModule, t: PType): PRope = diff --git a/compiler/sem.nim b/compiler/sem.nim index 1b6e6fe2e..7446384d2 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -371,6 +371,8 @@ proc myOpen(module: PSym): PPassContext = c.semInferredLambda = semInferredLambda c.semGenerateInstance = generateInstance c.semTypeNode = semTypeNode + c.instDeepCopy = sigmatch.instDeepCopy + pushProcCon(c, module) pushOwner(c.module) c.importTable = openScope(c) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 667556222..bc7b8cdc2 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -92,6 +92,9 @@ type lastGenericIdx*: int # used for the generics stack hloLoopDetector*: int # used to prevent endless loops in the HLO inParallelStmt*: int + instDeepCopy*: proc (c: PContext; dc: PSym; t: PType; + info: TLineInfo): PSym {.nimcall.} + proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair = result.genericSym = s diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 524a8fd99..c386785be 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1029,7 +1029,11 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = sameType(s.typ.sons[1], s.typ.sons[0]): # Note: we store the deepCopy in the base of the pointer to mitigate # the problem that pointers are structural types: - let t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst) + var t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst) + while true: + if t.kind == tyGenericBody: t = t.lastSon + elif t.kind == tyGenericInvokation: t = t.sons[0] + else: break if t.kind in {tyObject, tyDistinct, tyEnum}: if t.deepCopy.isNil: t.deepCopy = s else: @@ -1044,6 +1048,7 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = of "=": discard else: localError(n.info, errGenerated, "'destroy' or 'deepCopy' expected for 'override'") + incl(s.flags, sfUsed) type TProcCompilationSteps = enum diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 4563dc8d4..fa4d2cc0b 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -299,6 +299,18 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = if newbody.isGenericAlias: newbody = newbody.skipGenericAlias rawAddSon(result, newbody) checkPartialConstructedType(cl.info, newbody) + let dc = newbody.deepCopy + if dc != nil and sfFromGeneric notin newbody.deepCopy.flags: + # 'deepCopy' needs to be instantiated for + # generics *when the type is constructed*: + newbody.deepCopy = cl.c.instDeepCopy(cl.c, dc, result, cl.info) + when false: + var bindings: TIdTable + initIdTable(bindings) + debug newbody + bindings.idTablePut(dc.ast[genericParamsPos].sons[0].typ, newbody) + newbody.deepCopy = cl.c.semGenerateInstance(cl.c, dc, bindings, cl.info) + assert sfFromGeneric in newbody.deepCopy.flags proc eraseVoidParams*(t: PType) = if t.sons[0] != nil and t.sons[0].kind == tyEmpty: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 51ae4e8f5..59f954ff0 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1482,6 +1482,18 @@ proc argtypeMatches*(c: PContext, f, a: PType): bool = # instantiate generic converters for that result = res != nil +proc instDeepCopy*(c: PContext; dc: PSym; t: PType; info: TLineInfo): PSym {. + procvar.} = + var m: TCandidate + initCandidate(c, m, dc.typ) + var f = dc.typ.sons[1] + if f.kind in {tyRef, tyPtr}: f = f.lastSon + if typeRel(m, f, t) == isNone: + localError(info, errGenerated, "cannot instantiate 'deepCopy'") + else: + result = c.semGenerateInstance(c, dc, m.bindings, info) + assert sfFromGeneric in result.flags + include suggest when not declared(tests): diff --git a/doc/manual.txt b/doc/manual.txt index 3d44110f5..8b0f5a5e6 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -4386,6 +4386,8 @@ like ``let v = expr``, ``var v = expr``, ``parameter = defaultValue`` or for parameter passing no assignment is performed. The ``override`` pragma is optional for overriding ``=``. +**Note**: Overriding of operator ``=`` is not yet implemented. + destructors ----------- @@ -4446,6 +4448,9 @@ Be aware that destructors are not called for objects allocated with ``new``. This may change in future versions of language, but for now the ``finalizer`` parameter to ``new`` has to be used. +**Note**: Destructors are still experimental and the spec might change +significantly in order to incorporate an escape analysis. + deepCopy -------- diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index 902999970..e4356a25d 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -82,17 +82,16 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size), cast[pointer](s +% i*% mt.base.size), mt.base) of tyRef: - if mt.base.deepcopy != nil: - let z = mt.base.deepcopy(cast[PPointer](src)[]) + let s2 = cast[PPointer](src)[] + if s2 == nil: + unsureAsgnRef(cast[PPointer](dest), s2) + elif mt.base.deepcopy != nil: + let z = mt.base.deepcopy(s2) unsureAsgnRef(cast[PPointer](dest), z) else: # we modify the header of the cell temporarily; instead of the type # field we store a forwarding pointer. XXX This is bad when the cloning # fails due to OOM etc. - let s2 = cast[PPointer](src)[] - if s2 == nil: - unsureAsgnRef(cast[PPointer](dest), s2) - return when declared(usrToCell): # unfortunately we only have cycle detection for our native GCs. let x = usrToCell(s2) @@ -116,10 +115,11 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) = genericDeepCopyAux(z, s2, realType.base) of tyPtr: # no cycle check here, but also not really required - if mt.base.deepcopy != nil: - cast[PPointer](dest)[] = mt.base.deepcopy(cast[PPointer](s)[]) + let s2 = cast[PPointer](src)[] + if s2 != nil and mt.base.deepcopy != nil: + cast[PPointer](dest)[] = mt.base.deepcopy(s2) else: - cast[PPointer](dest)[] = cast[PPointer](s)[] + cast[PPointer](dest)[] = s2 else: copyMem(dest, src, mt.size) diff --git a/tests/parallel/tdeepcopy2.nim b/tests/parallel/tdeepcopy2.nim new file mode 100644 index 000000000..748ef4d9b --- /dev/null +++ b/tests/parallel/tdeepcopy2.nim @@ -0,0 +1,35 @@ +discard """ + output: '''called deepCopy for int +called deepCopy for int +done999 999 +""" + +import threadpool + + +type + Bar[T] = object + x: T + +proc deepCopy[T](b: ref Bar[T]): ref Bar[T] {.override.} = + result.new + result.x = b.x + when T is int: + echo "called deepCopy for int" + else: + echo "called deepCopy for something else" + +proc foo(b: ref Bar[int]): int = 999 + +# test that the disjoint checker deals with 'a = spawn f(); g = spawn f()': + +proc main = + var dummy: ref Bar[int] + new(dummy) + dummy.x = 44 + parallel: + let f = spawn foo(dummy) + let b = spawn foo(dummy) + echo "done", f, " ", b + +main() diff --git a/todo.txt b/todo.txt index 70173d50e..7f89678e2 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ version 0.10 ============ +- use the effect system for static deadlock prevention - Test nimfix on various babel packages - deprecate recursive tuples; tuple needs laxer type checking - string case should require an 'else' @@ -20,9 +21,7 @@ version 0.9.6 Concurrency ----------- -- 'deepCopy' needs to be instantiated for - generics *when the type is constructed* -- test 'deepCopy' +- test 'deepCopy' for closures - implement 'foo[1..4] = spawn(f[4..7])' - document the new 'spawn' and 'parallel' statements @@ -117,7 +116,6 @@ Concurrency/Effect system provide a ``syncgc`` pragma to trigger compiler injection --> more general: an ``injectLoop`` pragma - 'writes: []' effect; track reads/writes for shared types -- use the effect system for static deadlock prevention and race detection - ``~`` operator for effects - introduce 'noaddr' pragma to prevent taking the address of a location; this is very handy to prevent aliasing of global data From d576fbb39a771016d869706db169806eb8972c79 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 27 Sep 2014 15:06:06 +0200 Subject: [PATCH 159/409] implemented locking levels; still incomplete --- compiler/ast.nim | 3 +++ compiler/ccgtypes.nim | 2 +- compiler/pragmas.nim | 12 +++++----- compiler/sempass2.nim | 49 ++++++++++++++++++++++++++++++++++++++--- compiler/semtypinst.nim | 7 ------ lib/nimbase.h | 2 ++ todo.txt | 2 -- 7 files changed, 58 insertions(+), 19 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index e3e8fd49f..919a1a3fd 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1165,6 +1165,7 @@ proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode, result.sons = @[name, pattern, genericParams, params, pragmas, exceptions, body] +const UnspecifiedLockLevel* = -1 proc newType(kind: TTypeKind, owner: PSym): PType = new(result) @@ -1173,6 +1174,7 @@ proc newType(kind: TTypeKind, owner: PSym): PType = result.size = - 1 result.align = 2 # default alignment result.id = getID() + result.lockLevel = UnspecifiedLockLevel when debugIds: registerId(result) #if result.id < 2000: @@ -1195,6 +1197,7 @@ proc assignType(dest, src: PType) = dest.align = src.align dest.destructor = src.destructor dest.deepCopy = src.deepCopy + dest.lockLevel = src.lockLevel # this fixes 'type TLock = TSysLock': if src.sym != nil: if dest.sym != nil: diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 1b0b9e103..4b52d3956 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -898,7 +898,7 @@ include ccgtrav proc genDeepCopyProc(m: BModule; s: PSym; result: PRope) = genProc(m, s) - appf(m.s[cfsTypeInit3], "$1.deepcopy =(N_NIMCALL_PTR(void*,)(void*))$2;$n", + appf(m.s[cfsTypeInit3], "$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n", [result, s.loc.r]) proc genTypeInfo(m: BModule, t: PType): PRope = diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 815369066..5f9ee218f 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -529,12 +529,12 @@ proc pragmaLocks(c: PContext, it: PNode): int16 = if it.kind != nkExprColonExpr: invalidPragma(it) else: - let n = it[1] - let x = expectIntLit(c, n) - if x < low(int16) or x > high(int16): - localError(n.info, "integer must be in the valid range of int16") - else: - result = int16(x) + if it[1].kind != nkNilLit: + let x = expectIntLit(c, it) + if x < 0 or x > high(int16): + localError(it[1].info, "integer must be within 0..high(int16)") + else: + result = int16(x) proc typeBorrow(sym: PSym, n: PNode) = if n.kind == nkExprColonExpr: diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index a330e0ecd..981e69900 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -69,24 +69,44 @@ type TEffects = object exc: PNode # stack of exceptions tags: PNode # list of tags - uses: PNode # list of used global variables bottom: int owner: PSym init: seq[int] # list of initialized variables guards: TModel # nested guards locked: seq[PNode] # locked locations gcUnsafe, isRecursive, isToplevel: bool + maxLockLevel, currLockLevel: int16 PEffects = var TEffects proc isLocalVar(a: PEffects, s: PSym): bool = s.kind in {skVar, skResult} and sfGlobal notin s.flags and s.owner == a.owner +proc getLockLevel(t: PType): int16 = + var t = t + # tyGenericInst(TLock {tyGenericBody}, tyStatic, tyObject): + if t.kind == tyGenericInst and t.len == 3: t = t.sons[1] + if t.kind == tyStatic and t.n != nil and t.n.kind in {nkCharLit..nkInt64Lit}: + result = t.n.intVal.int16 + proc lockLocations(a: PEffects; pragma: PNode) = if pragma.kind != nkExprColonExpr: internalError(pragma.info, "no colon") return + var firstLL = -1'i16 for x in pragma[1]: + let thisLL = getLockLevel(x.typ) + if thisLL != 0: + if firstLL < 0: firstLL = thisLL + elif firstLL != thisLL: + localError(x.info, errGenerated, + "multi-lock requires the same static lock level for every operand") + a.maxLockLevel = max(a.maxLockLevel, firstLL) a.locked.add x + if firstLL >= 0 and firstLL != a.currLockLevel: + if a.currLockLevel > 0 and a.currLockLevel < firstLL: + localError(pragma.info, errGenerated, + "invalid nested locking") + a.currLockLevel = firstLL proc guardGlobal(a: PEffects; n: PNode; guard: PSym) = # check whether the corresponding lock is held: @@ -242,7 +262,8 @@ proc mergeTags(a: PEffects, b, comesFrom: PNode) = proc listEffects(a: PEffects) = for e in items(a.exc): message(e.info, hintUser, typeToString(e.typ)) for e in items(a.tags): message(e.info, hintUser, typeToString(e.typ)) - for e in items(a.uses): message(e.info, hintUser, e.sym.name.s) + #if a.maxLockLevel != 0: + # message(e.info, hintUser, "lockLevel: " & a.maxLockLevel) proc catches(tracked: PEffects, e: PType) = let e = skipTypes(e, skipPtrs) @@ -368,7 +389,6 @@ proc documentRaises*(n: PNode) = if n.sons[namePos].kind != nkSym: return documentEffect(n, n.sons[pragmasPos], wRaises, exceptionEffects) documentEffect(n, n.sons[pragmasPos], wTags, tagEffects) - #documentEffect(n, n.sons[pragmasPos], wUses, usesEffects) template notGcSafe(t): expr = {tfGcSafe, tfNoSideEffect} * t.flags == {} @@ -376,6 +396,15 @@ proc importedFromC(n: PNode): bool = # when imported from C, we assume GC-safety. result = n.kind == nkSym and sfImportc in n.sym.flags +proc mergeLockLevels(tracked: PEffects, n: PNode, t: PType) = + if t.lockLevel > tracked.currLockLevel: + # if in lock section: + if tracked.currLockLevel > 0: + localError n.info, errGenerated, + "expected lock level <= " & $tracked.currLockLevel & + " but got lock level " & $t.lockLevel + tracked.maxLockLevel = max(tracked.maxLockLevel, t.lockLevel) + proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = let pragma = s.ast.sons[pragmasPos] let spec = effectSpec(pragma, wRaises) @@ -387,6 +416,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = if notGcSafe(s.typ) and sfImportc notin s.flags: if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n)) tracked.gcUnsafe = true + mergeLockLevels(tracked, n, s.typ) proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = let n = n.skipConv @@ -577,6 +607,7 @@ proc track(tracked: PEffects, n: PNode) = if not (a.kind == nkSym and a.sym == tracked.owner): message(n.info, warnGcUnsafe, renderTree(n)) tracked.gcUnsafe = true + mergeLockLevels(tracked, n, op) for i in 1 .. disp.typ.lockLevel: + localError(branch.info, + "base method has lock level $1, but dispatcher has $2" % + [$branch.typ.lockLevel, $disp.typ.lockLevel]) proc setEffectsForProcType*(t: PType, n: PNode) = var effects = t.n.sons[0] @@ -764,6 +801,12 @@ proc trackProc*(s: PSym, body: PNode) = else: localError(s.info, warnGcUnsafe2, s.name.s) if not t.gcUnsafe: s.typ.flags.incl tfGcSafe + if s.typ.lockLevel == UnspecifiedLockLevel: + s.typ.lockLevel = t.maxLockLevel + elif t.maxLockLevel > s.typ.lockLevel: + localError(s.info, + "declared lock level is $1, but real lock level is $2" % + [$s.typ.lockLevel, $t.maxLockLevel]) proc trackTopLevelStmt*(module: PSym; n: PNode) = if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef, diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index fa4d2cc0b..9c15be635 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -304,13 +304,6 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = # 'deepCopy' needs to be instantiated for # generics *when the type is constructed*: newbody.deepCopy = cl.c.instDeepCopy(cl.c, dc, result, cl.info) - when false: - var bindings: TIdTable - initIdTable(bindings) - debug newbody - bindings.idTablePut(dc.ast[genericParamsPos].sons[0].typ, newbody) - newbody.deepCopy = cl.c.semGenerateInstance(cl.c, dc, bindings, cl.info) - assert sfFromGeneric in newbody.deepCopy.flags proc eraseVoidParams*(t: PType) = if t.sons[0] != nil and t.sons[0].kind == tyEmpty: diff --git a/lib/nimbase.h b/lib/nimbase.h index f49855076..2ca3bd886 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -141,9 +141,11 @@ __clang__ /* these compilers have a fastcall so use it: */ # define N_NIMCALL(rettype, name) rettype __fastcall name # define N_NIMCALL_PTR(rettype, name) rettype (__fastcall *name) +# define N_RAW_NIMCALL __fastcall #else # define N_NIMCALL(rettype, name) rettype name /* no modifier */ # define N_NIMCALL_PTR(rettype, name) rettype (*name) +# define N_RAW_NIMCALL #endif #define N_CLOSURE(rettype, name) N_NIMCALL(rettype, name) diff --git a/todo.txt b/todo.txt index 7f89678e2..c43132cd5 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ version 0.10 ============ -- use the effect system for static deadlock prevention - Test nimfix on various babel packages - deprecate recursive tuples; tuple needs laxer type checking - string case should require an 'else' @@ -30,7 +29,6 @@ Low priority: - support for exception propagation? (hard to implement) - the copying of the 'ref Promise' into the thead local storage only happens to work due to the write barrier's implementation -- implement lock levels Misc From baae9bfea816e370849d39e219d423ef120d8a52 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sat, 27 Sep 2014 17:15:32 +0100 Subject: [PATCH 160/409] s/sock/fd/. Fixes #1487. --- lib/pure/asyncdispatch.nim | 88 +++++++++++++++++++------------------- lib/pure/asyncfile.nim | 4 +- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index fb0023292..073cd3576 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -326,8 +326,8 @@ when defined(windows) or defined(nimdoc): TCompletionKey = Dword TCompletionData* = object - sock*: TAsyncFD # TODO: Rename this. - cb*: proc (sock: TAsyncFD, bytesTransferred: Dword, + fd*: TAsyncFD # TODO: Rename this. + cb*: proc (fd: TAsyncFD, bytesTransferred: Dword, errcode: OSErrorCode) {.closure,gcsafe.} PDispatcher* = ref object of PDispatcherBase @@ -357,18 +357,18 @@ when defined(windows) or defined(nimdoc): if gDisp.isNil: gDisp = newDispatcher() result = gDisp - proc register*(sock: TAsyncFD) = - ## Registers ``sock`` with the dispatcher. + proc register*(fd: TAsyncFD) = + ## Registers ``fd`` with the dispatcher. let p = getGlobalDispatcher() - if createIoCompletionPort(sock.THandle, p.ioPort, - cast[TCompletionKey](sock), 1) == 0: + if createIoCompletionPort(fd.THandle, p.ioPort, + cast[TCompletionKey](fd), 1) == 0: raiseOSError(osLastError()) - p.handles.incl(sock) + p.handles.incl(fd) - proc verifyPresence(sock: TAsyncFD) = - ## Ensures that socket has been registered with the dispatcher. + proc verifyPresence(fd: TAsyncFD) = + ## Ensures that file descriptor has been registered with the dispatcher. let p = getGlobalDispatcher() - if sock notin p.handles: + if fd notin p.handles: raise newException(ValueError, "Operation performed on a socket which has not been registered with" & " the dispatcher yet.") @@ -394,16 +394,16 @@ when defined(windows) or defined(nimdoc): # TODO: http://www.serverframework.com/handling-multiple-pending-socket-read-and-write-operations.html if res: # This is useful for ensuring the reliability of the overlapped struct. - assert customOverlapped.data.sock == lpCompletionKey.TAsyncFD + assert customOverlapped.data.fd == lpCompletionKey.TAsyncFD - customOverlapped.data.cb(customOverlapped.data.sock, + customOverlapped.data.cb(customOverlapped.data.fd, lpNumberOfBytesTransferred, OSErrorCode(-1)) GC_unref(customOverlapped) else: let errCode = osLastError() if customOverlapped != nil: - assert customOverlapped.data.sock == lpCompletionKey.TAsyncFD - customOverlapped.data.cb(customOverlapped.data.sock, + assert customOverlapped.data.fd == lpCompletionKey.TAsyncFD + customOverlapped.data.cb(customOverlapped.data.fd, lpNumberOfBytesTransferred, errCode) GC_unref(customOverlapped) else: @@ -506,8 +506,8 @@ when defined(windows) or defined(nimdoc): # http://blogs.msdn.com/b/oldnewthing/archive/2011/02/02/10123392.aspx var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + ol.data = TCompletionData(fd: socket, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): retFuture.complete() @@ -570,8 +570,8 @@ when defined(windows) or defined(nimdoc): var flagsio = flags.toOSFlags().Dword var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + ol.data = TCompletionData(fd: socket, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): if bytesCount == 0 and dataBuf.buf[0] == '\0': @@ -648,8 +648,8 @@ when defined(windows) or defined(nimdoc): var bytesReceived, lowFlags: Dword var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + ol.data = TCompletionData(fd: socket, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): retFuture.complete() @@ -737,8 +737,8 @@ when defined(windows) or defined(nimdoc): var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: socket, cb: - proc (sock: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + ol.data = TCompletionData(fd: socket, cb: + proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): completeAccept() @@ -806,10 +806,10 @@ else: type TAsyncFD* = distinct cint - TCallback = proc (sock: TAsyncFD): bool {.closure,gcsafe.} + TCallback = proc (fd: TAsyncFD): bool {.closure,gcsafe.} PData* = ref object of PObject - sock: TAsyncFD + fd: TAsyncFD readCBs: seq[TCallback] writeCBs: seq[TCallback] @@ -828,15 +828,15 @@ else: if gDisp.isNil: gDisp = newDispatcher() result = gDisp - proc update(sock: TAsyncFD, events: set[TEvent]) = + proc update(fd: TAsyncFD, events: set[TEvent]) = let p = getGlobalDispatcher() - assert sock.SocketHandle in p.selector - discard p.selector.update(sock.SocketHandle, events) + assert fd.SocketHandle in p.selector + discard p.selector.update(fd.SocketHandle, events) - proc register*(sock: TAsyncFD) = + proc register*(fd: TAsyncFD) = let p = getGlobalDispatcher() - var data = PData(sock: sock, readCBs: @[], writeCBs: @[]) - p.selector.register(sock.SocketHandle, {}, data.PObject) + var data = PData(fd: fd, readCBs: @[], writeCBs: @[]) + p.selector.register(fd.SocketHandle, {}, data.PObject) proc newAsyncRawSocket*(domain: cint, typ: cint, protocol: cint): TAsyncFD = result = newRawSocket(domain, typ, protocol).TAsyncFD @@ -858,26 +858,26 @@ else: proc unregister*(fd: TAsyncFD) = getGlobalDispatcher().selector.unregister(fd.SocketHandle) - proc addRead*(sock: TAsyncFD, cb: TCallback) = + proc addRead*(fd: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() - if sock.SocketHandle notin p.selector: + if fd.SocketHandle notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") - p.selector[sock.SocketHandle].data.PData.readCBs.add(cb) - update(sock, p.selector[sock.SocketHandle].events + {EvRead}) + p.selector[fd.SocketHandle].data.PData.readCBs.add(cb) + update(fd, p.selector[fd.SocketHandle].events + {EvRead}) - proc addWrite*(sock: TAsyncFD, cb: TCallback) = + proc addWrite*(fd: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() - if sock.SocketHandle notin p.selector: + if fd.SocketHandle notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") - p.selector[sock.SocketHandle].data.PData.writeCBs.add(cb) - update(sock, p.selector[sock.SocketHandle].events + {EvWrite}) + p.selector[fd.SocketHandle].data.PData.writeCBs.add(cb) + update(fd, p.selector[fd.SocketHandle].events + {EvWrite}) proc poll*(timeout = 500) = let p = getGlobalDispatcher() for info in p.selector.select(timeout): let data = PData(info.key.data) - assert data.sock == info.key.fd.TAsyncFD - #echo("In poll ", data.sock.cint) + assert data.fd == info.key.fd.TAsyncFD + #echo("In poll ", data.fd.cint) if EvRead in info.events: # Callback may add items to ``data.readCBs`` which causes issues if # we are iterating over ``data.readCBs`` at the same time. We therefore @@ -885,7 +885,7 @@ else: let currentCBs = data.readCBs data.readCBs = @[] for cb in currentCBs: - if not cb(data.sock): + if not cb(data.fd): # Callback wants to be called again. data.readCBs.add(cb) @@ -893,7 +893,7 @@ else: let currentCBs = data.writeCBs data.writeCBs = @[] for cb in currentCBs: - if not cb(data.sock): + if not cb(data.fd): # Callback wants to be called again. data.writeCBs.add(cb) @@ -902,7 +902,7 @@ else: if data.readCBs.len != 0: newEvents = {EvRead} if data.writeCBs.len != 0: newEvents = newEvents + {EvWrite} if newEvents != info.key.events: - update(data.sock, newEvents) + update(data.fd, newEvents) else: # FD no longer a part of the selector. Likely been closed # (e.g. socket disconnected). @@ -914,7 +914,7 @@ else: af = AF_INET): Future[void] = var retFuture = newFuture[void]("connect") - proc cb(sock: TAsyncFD): bool = + proc cb(fd: TAsyncFD): bool = # We have connected. retFuture.complete() return true diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim index e861c6e48..c09cb5a35 100644 --- a/lib/pure/asyncfile.nim +++ b/lib/pure/asyncfile.nim @@ -125,7 +125,7 @@ proc read*(f: AsyncFile, size: int): Future[string] = var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: f.fd, cb: + ol.data = TCompletionData(fd: f.fd, cb: proc (fd: TAsyncFD, bytesCount: Dword, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): @@ -251,7 +251,7 @@ proc write*(f: AsyncFile, data: string): Future[void] = var ol = PCustomOverlapped() GC_ref(ol) - ol.data = TCompletionData(sock: f.fd, cb: + ol.data = TCompletionData(fd: f.fd, cb: proc (fd: TAsyncFD, bytesCount: DWord, errcode: OSErrorCode) = if not retFuture.finished: if errcode == OSErrorCode(-1): From dcaba49c3f5be8670aa5add8f92f42efa363b0c1 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 28 Sep 2014 13:38:26 +0200 Subject: [PATCH 161/409] deprecated '#[' comments for future multi-line comment feature --- compiler/lexer.nim | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 40524564e..cbc87972d 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -662,7 +662,10 @@ proc getOperator(L: var TLexer, tok: var TToken) = proc scanComment(L: var TLexer, tok: var TToken) = var pos = L.bufpos var buf = L.buf - when not defined(nimfix): assert buf[pos+1] == '#' + when not defined(nimfix): + assert buf[pos+1] == '#' + if buf[pos+2] == '[': + lexMessagePos(L, warnDeprecated, pos, "use '## [' instead; '##['") tok.tokType = tkComment # iNumber contains the number of '\n' in the token tok.iNumber = 0 @@ -741,6 +744,8 @@ proc skip(L: var TLexer, tok: var TToken) = else: # do not skip documentation comment: if buf[pos+1] == '#': break + if buf[pos+1] == '[': + lexMessagePos(L, warnDeprecated, pos, "use '# [' instead; '#['") while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}: inc(pos) else: break # EndOfFile also leaves the loop From 2df195c8e27aff3bf77b86e4b8234a20afd58ce8 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Thu, 2 Oct 2014 00:59:07 +0200 Subject: [PATCH 162/409] Fixes line numbering. --- lib/packages/docutils/rstgen.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index e62b627bd..282cfa3b0 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -831,7 +831,7 @@ proc buildLinesHTMLTable(params: CodeBlockParams, code: string): result = ("
", "
") return - var codeLines = code.strip(leading = false).countLines + var codeLines = 1 + code.strip.countLines assert codeLines > 0 result.beginTable = """
"""
   var line = params.startLine

From e9dec2feedc25afd8af8fc3db3131ffbb4b284a7 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 2 Oct 2014 02:33:14 +0200
Subject: [PATCH 163/409] better lock level handling

---
 compiler/ast.nim      | 13 ++++++--
 compiler/pragmas.nim  | 20 ++++++++-----
 compiler/sempass2.nim | 70 +++++++++++++++++++++++++++++--------------
 compiler/types.nim    | 15 +++++-----
 4 files changed, 78 insertions(+), 40 deletions(-)

diff --git a/compiler/ast.nim b/compiler/ast.nim
index 919a1a3fd..1fbbd56d4 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -770,6 +770,7 @@ type
                               # it won't cause problems
   
   TTypeSeq* = seq[PType]
+  TLockLevel* = distinct int16
   TType* {.acyclic.} = object of TIdObj # \
                               # types are identical iff they have the
                               # same id; there may be multiple copies of a type
@@ -797,7 +798,7 @@ type
     size*: BiggestInt         # the size of the type in bytes
                               # -1 means that the size is unkwown
     align*: int16             # the type's alignment requirements
-    lockLevel*: int16         # lock level as required for deadlock checking
+    lockLevel*: TLockLevel    # lock level as required for deadlock checking
     loc*: TLoc
 
   TPair*{.final.} = object 
@@ -1165,7 +1166,15 @@ proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
   result.sons = @[name, pattern, genericParams, params,
                   pragmas, exceptions, body]
 
-const UnspecifiedLockLevel* = -1
+const
+  UnspecifiedLockLevel* = TLockLevel(-1'i16)
+  MaxLockLevel* = 1000'i16
+  UnknownLockLevel* = TLockLevel(1001'i16)
+
+proc `$`*(x: TLockLevel): string =
+  if x.ord == UnspecifiedLockLevel.ord: result = ""
+  elif x.ord == UnknownLockLevel.ord: result = ""
+  else: result = $int16(x)
 
 proc newType(kind: TTypeKind, owner: PSym): PType = 
   new(result)
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 5f9ee218f..510023bb8 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -525,16 +525,16 @@ proc pragmaLockStmt(c: PContext; it: PNode) =
       for i in 0 ..  high(int16):
-        localError(it[1].info, "integer must be within 0..high(int16)")
+      if x < 0 or x > MaxLockLevel:
+        localError(it[1].info, "integer must be within 0.." & $MaxLockLevel)
       else:
-        result = int16(x)
+        result = TLockLevel(x)
 
 proc typeBorrow(sym: PSym, n: PNode) =
   if n.kind == nkExprColonExpr:
@@ -571,10 +571,14 @@ proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym =
   if n.kind == nkSym:
     result = n.sym
   elif kind == skField:
-    # we return a dummy symbol; later passes over the type will repair it. Note
-    # that generic instantiation needs to know about this too. But we're lazy
-    # and perform the lookup on demand instead.
-    result = newSym(skUnknown, considerQuotedIdent(n), nil, n.info)
+    # First check if the guard is a global variable:
+    result = qualifiedLookUp(c, n, {})
+    if result.isNil or result.kind notin {skLet, skVar} or
+        sfGlobal notin result.flags:
+      # We return a dummy symbol; later passes over the type will repair it.
+      # Generic instantiation needs to know about this too. But we're lazy
+      # and perform the lookup on demand instead.
+      result = newSym(skUnknown, considerQuotedIdent(n), nil, n.info)
   else:
     result = qualifiedLookUp(c, n)
 
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 981e69900..94a3b49e3 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -75,35 +75,42 @@ type
     guards: TModel # nested guards
     locked: seq[PNode] # locked locations
     gcUnsafe, isRecursive, isToplevel: bool
-    maxLockLevel, currLockLevel: int16
+    maxLockLevel, currLockLevel: TLockLevel
   PEffects = var TEffects
 
+proc `<`(a, b: TLockLevel): bool {.borrow.}
+proc `<=`(a, b: TLockLevel): bool {.borrow.}
+proc `==`(a, b: TLockLevel): bool {.borrow.}
+proc max(a, b: TLockLevel): TLockLevel {.borrow.}
+
 proc isLocalVar(a: PEffects, s: PSym): bool =
   s.kind in {skVar, skResult} and sfGlobal notin s.flags and s.owner == a.owner
 
-proc getLockLevel(t: PType): int16 =
+proc getLockLevel(t: PType): TLockLevel =
   var t = t
   # tyGenericInst(TLock {tyGenericBody}, tyStatic, tyObject):
   if t.kind == tyGenericInst and t.len == 3: t = t.sons[1]
   if t.kind == tyStatic and t.n != nil and t.n.kind in {nkCharLit..nkInt64Lit}:
-    result = t.n.intVal.int16
+    result = t.n.intVal.TLockLevel
 
 proc lockLocations(a: PEffects; pragma: PNode) =
   if pragma.kind != nkExprColonExpr:
-    internalError(pragma.info, "no colon")
+    localError(pragma.info, errGenerated, "locks pragma without argument")
     return
-  var firstLL = -1'i16
+  var firstLL = TLockLevel(-1'i16)
   for x in pragma[1]:
     let thisLL = getLockLevel(x.typ)
-    if thisLL != 0:
-      if firstLL < 0: firstLL = thisLL
+    if thisLL != 0.TLockLevel:
+      if thisLL < 0.TLockLevel or thisLL > MaxLockLevel.TLockLevel:
+        localError(x.info, "invalid lock level: " & $thisLL)
+      elif firstLL < 0.TLockLevel: firstLL = thisLL
       elif firstLL != thisLL:
         localError(x.info, errGenerated,
           "multi-lock requires the same static lock level for every operand")
       a.maxLockLevel = max(a.maxLockLevel, firstLL)
     a.locked.add x
-  if firstLL >= 0 and firstLL != a.currLockLevel:
-    if a.currLockLevel > 0 and a.currLockLevel < firstLL:
+  if firstLL >= 0.TLockLevel and firstLL != a.currLockLevel:
+    if a.currLockLevel > 0.TLockLevel and a.currLockLevel <= firstLL:
       localError(pragma.info, errGenerated,
         "invalid nested locking")
     a.currLockLevel = firstLL
@@ -396,14 +403,23 @@ proc importedFromC(n: PNode): bool =
   # when imported from C, we assume GC-safety.
   result = n.kind == nkSym and sfImportc in n.sym.flags
 
-proc mergeLockLevels(tracked: PEffects, n: PNode, t: PType) =
-  if t.lockLevel > tracked.currLockLevel:
+proc getLockLevel(s: PSym): TLockLevel =
+  result = s.typ.lockLevel
+  if result == UnspecifiedLockLevel:
+    if {sfImportc, sfNoSideEffect} * s.flags != {} or
+       tfNoSideEffect in s.typ.flags:
+      result = 0.TLockLevel
+    else:
+      result = UnknownLockLevel
+
+proc mergeLockLevels(tracked: PEffects, n: PNode, lockLevel: TLockLevel) =
+  if lockLevel >= tracked.currLockLevel:
     # if in lock section:
-    if tracked.currLockLevel > 0:
+    if tracked.currLockLevel > 0.TLockLevel:
       localError n.info, errGenerated,
-        "expected lock level <= " & $tracked.currLockLevel &
-        " but got lock level " & $t.lockLevel
-    tracked.maxLockLevel = max(tracked.maxLockLevel, t.lockLevel)
+        "expected lock level < " & $tracked.currLockLevel &
+        " but got lock level " & $lockLevel
+    tracked.maxLockLevel = max(tracked.maxLockLevel, lockLevel)
 
 proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
   let pragma = s.ast.sons[pragmasPos]
@@ -416,7 +432,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
   if notGcSafe(s.typ) and sfImportc notin s.flags:
     if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
     tracked.gcUnsafe = true
-  mergeLockLevels(tracked, n, s.typ)
+  mergeLockLevels(tracked, n, s.getLockLevel)
 
 proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
   let n = n.skipConv
@@ -436,6 +452,13 @@ proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
       message(n.info, errGenerated, "'$1' is provably nil" % n.renderTree)
     of impYes: discard
 
+proc assumeTheWorst(tracked: PEffects; n: PNode; op: PType) =
+  addEffect(tracked, createRaise(n))
+  addTag(tracked, createTag(n))
+  let lockLevel = if op.lockLevel == UnspecifiedLockLevel: UnknownLockLevel
+                  else: op.lockLevel
+  mergeLockLevels(tracked, n, lockLevel)
+
 proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
   let op = skipConvAndClosure(n).typ
   if op != nil and op.kind == tyProc and n.kind != nkNilLit:
@@ -451,8 +474,7 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
         propagateEffects(tracked, n, n.sym)
       else:
         # we have no explicit effects so assume the worst:
-        addEffect(tracked, createRaise(n))
-        addTag(tracked, createTag(n))
+        assumeTheWorst(tracked, n, op)
       # assume GcUnsafe unless in its type; 'forward' does not matter:
       if notGcSafe(op):
         if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
@@ -588,8 +610,12 @@ proc track(tracked: PEffects, n: PNode) =
     # are indistinguishable from normal procs (both have tyProc type) and
     # we can detect them only by checking for attached nkEffectList.
     if op != nil and op.kind == tyProc and op.n.sons[0].kind == nkEffectList:
-      if a.kind == nkSym and a.sym == tracked.owner:
-        tracked.isRecursive = true
+      if a.kind == nkSym:
+        if a.sym == tracked.owner: tracked.isRecursive = true
+        # even for recursive calls we need to check the lock levels (!):
+        mergeLockLevels(tracked, n, a.sym.getLockLevel)
+      else:
+        mergeLockLevels(tracked, n, op.lockLevel)
       var effectList = op.n.sons[0]
       if a.kind == nkSym and a.sym.kind == skMethod:
         propagateEffects(tracked, n, a.sym)
@@ -597,8 +623,7 @@ proc track(tracked: PEffects, n: PNode) =
         if isForwardedProc(a):
           propagateEffects(tracked, n, a.sym)
         elif isIndirectCall(a, tracked.owner):
-          addEffect(tracked, createRaise(n))
-          addTag(tracked, createTag(n))
+          assumeTheWorst(tracked, n, op)
       else:
         mergeEffects(tracked, effectList.sons[exceptionEffects], n)
         mergeTags(tracked, effectList.sons[tagEffects], n)
@@ -607,7 +632,6 @@ proc track(tracked: PEffects, n: PNode) =
           if not (a.kind == nkSym and a.sym == tracked.owner):
             message(n.info, warnGcUnsafe, renderTree(n))
             tracked.gcUnsafe = true
-        mergeLockLevels(tracked, n, op)
     for i in 1 ..  0: result = firstOrd(lastSon(t))
@@ -1360,7 +1360,8 @@ proc compatibleEffects*(formal, actual: PType): bool =
       if real.len == 0: return false
       result = compatibleEffectsAux(st, real.sons[tagEffects])
       if not result: return
-  result = true
+  result = formal.lockLevel.ord < 0 or
+      actual.lockLevel.ord <= formal.lockLevel.ord
 
 proc isCompileTimeOnly*(t: PType): bool {.inline.} =
   result = t.kind in {tyTypeDesc, tyStatic}

From 2c1f3f75f5d37db810113cf37e1b38c3b7b09ee7 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 2 Oct 2014 02:33:59 +0200
Subject: [PATCH 164/409] manual split up into multiple files; documented the
 new concurrency system

---
 doc/backends.txt              |    8 +-
 doc/manual.txt                | 5859 +--------------------------------
 doc/manual/about.txt          |   37 +
 doc/manual/compiler_msgs.txt  |    7 +
 doc/manual/definitions.txt    |   49 +
 doc/manual/effects.txt        |  129 +
 doc/manual/exceptions.txt     |  132 +
 doc/manual/ffi.txt            |  209 ++
 doc/manual/generics.txt       |  346 ++
 doc/manual/lexing.txt         |  356 ++
 doc/manual/locking.txt        |  197 ++
 doc/manual/modules.txt        |  185 ++
 doc/manual/pragmas.txt        |  477 +++
 doc/manual/procs.txt          |  554 ++++
 doc/manual/special_ops.txt    |   54 +
 doc/manual/stmts.txt          |  647 ++++
 doc/manual/syntax.txt         |  112 +
 doc/manual/taint.txt          |   20 +
 doc/manual/templates.txt      |  404 +++
 doc/manual/threads.txt        |  209 ++
 doc/manual/trmacros.txt       |  361 ++
 doc/manual/type_bound_ops.txt |  112 +
 doc/manual/type_rel.txt       |  191 ++
 doc/manual/type_sections.txt  |   23 +
 doc/manual/typedesc.txt       |  146 +
 doc/manual/types.txt          | 1153 +++++++
 doc/spawn.txt                 |   62 +-
 doc/tut1.txt                  |   12 +-
 doc/tut2.txt                  |   44 +-
 koch.nim                      |    2 +-
 todo.txt                      |    2 +-
 31 files changed, 6198 insertions(+), 5901 deletions(-)
 create mode 100644 doc/manual/about.txt
 create mode 100644 doc/manual/compiler_msgs.txt
 create mode 100644 doc/manual/definitions.txt
 create mode 100644 doc/manual/effects.txt
 create mode 100644 doc/manual/exceptions.txt
 create mode 100644 doc/manual/ffi.txt
 create mode 100644 doc/manual/generics.txt
 create mode 100644 doc/manual/lexing.txt
 create mode 100644 doc/manual/locking.txt
 create mode 100644 doc/manual/modules.txt
 create mode 100644 doc/manual/pragmas.txt
 create mode 100644 doc/manual/procs.txt
 create mode 100644 doc/manual/special_ops.txt
 create mode 100644 doc/manual/stmts.txt
 create mode 100644 doc/manual/syntax.txt
 create mode 100644 doc/manual/taint.txt
 create mode 100644 doc/manual/templates.txt
 create mode 100644 doc/manual/threads.txt
 create mode 100644 doc/manual/trmacros.txt
 create mode 100644 doc/manual/type_bound_ops.txt
 create mode 100644 doc/manual/type_rel.txt
 create mode 100644 doc/manual/type_sections.txt
 create mode 100644 doc/manual/typedesc.txt
 create mode 100644 doc/manual/types.txt

diff --git a/doc/backends.txt b/doc/backends.txt
index 307f141b2..eb16217cd 100644
--- a/doc/backends.txt
+++ b/doc/backends.txt
@@ -103,7 +103,7 @@ component?).
 
 
 Nim code calling the backend
---------------------------------
+----------------------------
 
 Nim code can interface with the backend through the `Foreign function
 interface `_ mainly through the
@@ -211,7 +211,7 @@ javascript, you should see the value ``10``. In JavaScript the `echo proc
 
 
 Backend code calling Nim
----------------------------
+------------------------
 
 Backend code can interface with Nim code exposed through the `exportc
 pragma `_. The ``exportc`` pragma is the *generic*
@@ -235,7 +235,7 @@ Nim code.
 
 
 Nim invocation example from C
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Create a ``fib.nim`` file with the following content:
 
@@ -291,7 +291,7 @@ use ``-ldl`` too to link in required dlopen functionality.
 
 
 Nim invocation example from JavaScript
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Create a ``mhost.html`` file with the following content:
 
diff --git a/doc/manual.txt b/doc/manual.txt
index 8b0f5a5e6..5c6f64344 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -12,5838 +12,27 @@ Nim Manual
   user to one/some of the other players, but the total amount seems to remain
   pretty much constant for a given task. -- Ran
 
-
-
-About this document
-===================
-
-**Note**: This document is a draft! Several of Nim's features need more
-precise wording. This manual will evolve into a proper specification some
-day.
-
-This document describes the lexis, the syntax, and the semantics of Nim.
-
-The language constructs are explained using an extended BNF, in
-which ``(a)*`` means 0 or more ``a``'s, ``a+`` means 1 or more ``a``'s, and
-``(a)?`` means an optional *a*. Parentheses may be used to group elements.
-
-``&`` is the lookahead operator; ``&a`` means that an ``a`` is expected but
-not consumed. It will be consumed in the following rule.
-
-The ``|``, ``/`` symbols are used to mark alternatives and have the lowest 
-precedence. ``/`` is the ordered choice that requires the parser to try the 
-alternatives in the given order. ``/`` is often used to ensure the grammar
-is not ambiguous. 
-
-Non-terminals start with a lowercase letter, abstract terminal symbols are in
-UPPERCASE. Verbatim terminal symbols (including keywords) are quoted
-with ``'``. An example::
-
-  ifStmt = 'if' expr ':' stmts ('elif' expr ':' stmts)* ('else' stmts)?
-  
-The binary ``^*`` operator is used as a shorthand for 0 or more occurances
-separated by its second argument; likewise ``^+`` means 1 or more 
-occurances: ``a ^+ b`` is short for ``a (b a)*`` 
-and ``a ^* b`` is short for ``(a (b a)*)?``. Example::
-
-  arrayConstructor = '[' expr ^* ',' ']'
-
-Other parts of Nim - like scoping rules or runtime semantics are only
-described in an informal manner for now.
-
-
-Definitions
-===========
-
-A Nim program specifies a computation that acts on a memory consisting of
-components called `locations`:idx:. A variable is basically a name for a
-location. Each variable and location is of a certain `type`:idx:. The
-variable's type is called `static type`:idx:, the location's type is called
-`dynamic type`:idx:. If the static type is not the same as the dynamic type,
-it is a super-type or subtype of the dynamic type.
-
-An `identifier`:idx: is a symbol declared as a name for a variable, type,
-procedure, etc. The region of the program over which a declaration applies is
-called the `scope`:idx: of the declaration. Scopes can be nested. The meaning
-of an identifier is determined by the smallest enclosing scope in which the
-identifier is declared unless overloading resolution rules suggest otherwise.
-
-An expression specifies a computation that produces a value or location.
-Expressions that produce locations are called `l-values`:idx:. An l-value
-can denote either a location or the value the location contains, depending on
-the context. Expressions whose values can be determined statically are called
-`constant expressions`:idx:; they are never l-values.
-
-A `static error`:idx: is an error that the implementation detects before
-program execution. Unless explicitly classified, an error is a static error.
-
-A `checked runtime error`:idx: is an error that the implementation detects
-and reports at runtime. The method for reporting such errors is via *raising
-exceptions* or *dying with a fatal error*. However, the implementation 
-provides a means to disable these runtime checks. See the section pragmas_
-for details. 
-
-Wether a checked runtime error results in an exception or in a fatal error at
-runtime is implementation specific. Thus the following program is always
-invalid:
-
-.. code-block:: nim
-  var a: array[0..1, char]
-  let i = 5
-  try:
-    a[i] = 'N'
-  except EInvalidIndex:
-    echo "invalid index"
-
-An `unchecked runtime error`:idx: is an error that is not guaranteed to be
-detected, and can cause the subsequent behavior of the computation to
-be arbitrary. Unchecked runtime errors cannot occur if only `safe`:idx:
-language features are used.
-
-
-Lexical Analysis
-================
-
-Encoding
---------
-
-All Nim source files are in the UTF-8 encoding (or its ASCII subset). Other
-encodings are not supported. Any of the standard platform line termination
-sequences can be used - the Unix form using ASCII LF (linefeed), the Windows
-form using the ASCII sequence CR LF (return followed by linefeed), or the old
-Macintosh form using the ASCII CR (return) character. All of these forms can be
-used equally, regardless of platform.
-
-
-Indentation
------------
-
-Nim's standard grammar describes an `indentation sensitive`:idx: language.
-This means that all the control structures are recognized by indentation.
-Indentation consists only of spaces; tabulators are not allowed.
-
-The indentation handling is implemented as follows: The lexer annotates the
-following token with the preceding number of spaces; indentation is not
-a separate token. This trick allows parsing of Nim with only 1 token of
-lookahead.
-
-The parser uses a stack of indentation levels: the stack consists of integers
-counting the spaces. The indentation information is queried at strategic 
-places in the parser but ignored otherwise: The pseudo terminal ``IND{>}``
-denotes an indentation that consists of more spaces than the entry at the top
-of the stack; IND{=} an indentation that has the same number of spaces. ``DED``
-is another pseudo terminal that describes the *action* of popping a value
-from the stack, ``IND{>}`` then implies to push onto the stack.
-
-With this notation we can now easily define the core of the grammar: A block of
-statements (simplified example)::
-
-  ifStmt = 'if' expr ':' stmt
-           (IND{=} 'elif' expr ':' stmt)* 
-           (IND{=} 'else' ':' stmt)?
-
-  simpleStmt = ifStmt / ...
-
-  stmt = IND{>} stmt ^+ IND{=} DED  # list of statements
-       / simpleStmt                 # or a simple statement
-
-
-
-Comments
---------
-
-Comments start anywhere outside a string or character literal with the
-hash character ``#``.
-Comments consist of a concatenation of `comment pieces`:idx:. A comment piece
-starts with ``#`` and runs until the end of the line. The end of line characters
-belong to the piece. If the next line only consists of a comment piece with
-no other tokens between it and the preceding one, it does not start a new
-comment:
-
-
-.. code-block:: nim
-  i = 0     # This is a single comment over multiple lines.
-    # The scanner merges these two pieces.
-    # The comment continues here.
-
-
-`Documentation comments`:idx: are comments that start with two ``##``.
-Documentation comments are tokens; they are only allowed at certain places in
-the input file as they belong to the syntax tree!
-
-
-Identifiers & Keywords
-----------------------
-
-Identifiers in Nim can be any string of letters, digits
-and underscores, beginning with a letter. Two immediate following
-underscores ``__`` are not allowed::
-
-  letter ::= 'A'..'Z' | 'a'..'z' | '\x80'..'\xff'
-  digit ::= '0'..'9'
-  IDENTIFIER ::= letter ( ['_'] (letter | digit) )*
-
-Currently any unicode character with an ordinal value > 127 (non ASCII) is
-classified as a ``letter`` and may thus be part of an identifier but later
-versions of the language may assign some Unicode characters to belong to the
-operator characters instead.
-
-The following keywords are reserved and cannot be used as identifiers:
-
-.. code-block:: nim
-   :file: keywords.txt
-
-Some keywords are unused; they are reserved for future developments of the
-language.
-
-Nim is a `style-insensitive`:idx: language. This means that it is not
-case-sensitive and even underscores are ignored:
-**type** is a reserved word, and so is **TYPE** or **T_Y_P_E**. The idea behind
-this is that this allows programmers to use their own preferred spelling style
-and libraries written by different programmers cannot use incompatible
-conventions. A Nim-aware editor or IDE can show the identifiers as
-preferred. Another advantage is that it frees the programmer from remembering
-the exact spelling of an identifier.
-
-
-String literals
----------------
-
-Terminal symbol in the grammar: ``STR_LIT``.
-
-String literals can be delimited by matching double quotes, and can
-contain the following `escape sequences`:idx:\ :
-
-==================         ===================================================
-  Escape sequence          Meaning
-==================         ===================================================
-  ``\n``                   `newline`:idx:
-  ``\r``, ``\c``           `carriage return`:idx:
-  ``\l``                   `line feed`:idx:
-  ``\f``                   `form feed`:idx:
-  ``\t``                   `tabulator`:idx:
-  ``\v``                   `vertical tabulator`:idx:
-  ``\\``                   `backslash`:idx:
-  ``\"``                   `quotation mark`:idx:
-  ``\'``                   `apostrophe`:idx:
-  ``\`` '0'..'9'+          `character with decimal value d`:idx:;
-                           all decimal digits directly
-                           following are used for the character
-  ``\a``                   `alert`:idx:
-  ``\b``                   `backspace`:idx:
-  ``\e``                   `escape`:idx: `[ESC]`:idx:
-  ``\x`` HH                `character with hex value HH`:idx:;
-                           exactly two hex digits are allowed
-==================         ===================================================
-
-
-Strings in Nim may contain any 8-bit value, even embedded zeros. However 
-some operations may interpret the first binary zero as a terminator.
-
-
-Triple quoted string literals
------------------------------
-
-Terminal symbol in the grammar: ``TRIPLESTR_LIT``.
-
-String literals can also be delimited by three double quotes
-``"""`` ... ``"""``.
-Literals in this form may run for several lines, may contain ``"`` and do not
-interpret any escape sequences.
-For convenience, when the opening ``"""`` is followed by a newline (there may
-be whitespace between the opening ``"""`` and the newline),
-the newline (and the preceding whitespace) is not included in the string. The
-ending of the string literal is defined by the pattern ``"""[^"]``, so this:
-
-.. code-block:: nim 
-  """"long string within quotes""""
-
-Produces::
-
-  "long string within quotes"
-
-
-Raw string literals
--------------------
-
-Terminal symbol in the grammar: ``RSTR_LIT``.
-
-There are also raw string literals that are preceded with the 
-letter ``r`` (or ``R``) and are delimited by matching double quotes (just 
-like ordinary string literals) and do not interpret the escape sequences. 
-This is especially convenient for regular expressions or Windows paths:
-
-.. code-block:: nim
-
-  var f = openFile(r"C:\texts\text.txt") # a raw string, so ``\t`` is no tab
-
-To produce a single ``"`` within a raw string literal, it has to be doubled:
-
-.. code-block:: nim
-
-  r"a""b"
-  
-Produces::
-  
-  a"b
-
-``r""""`` is not possible with this notation, because the three leading 
-quotes introduce a triple quoted string literal. ``r"""`` is the same 
-as ``"""`` since triple quoted string literals do not interpret escape 
-sequences either.
-
-
-Generalized raw string literals
--------------------------------
-
-Terminal symbols in the grammar: ``GENERALIZED_STR_LIT``, 
-``GENERALIZED_TRIPLESTR_LIT``.
-
-The construct ``identifier"string literal"`` (without whitespace between the
-identifier and the opening quotation mark) is a
-generalized raw string literal. It is a shortcut for the construct
-``identifier(r"string literal")``, so it denotes a procedure call with a
-raw string literal as its only argument. Generalized raw string literals
-are especially convenient for embedding mini languages directly into Nim
-(for example regular expressions).
-
-The construct ``identifier"""string literal"""`` exists too. It is a shortcut
-for ``identifier("""string literal""")``.
-
-
-Character literals
-------------------
-
-Character literals are enclosed in single quotes ``''`` and can contain the
-same escape sequences as strings - with one exception: `newline`:idx: (``\n``)
-is not allowed as it may be wider than one character (often it is the pair
-CR/LF for example).  Here are the valid `escape sequences`:idx: for character
-literals:
-
-==================         ===================================================
-  Escape sequence          Meaning
-==================         ===================================================
-  ``\r``, ``\c``           `carriage return`:idx:
-  ``\l``                   `line feed`:idx:
-  ``\f``                   `form feed`:idx:
-  ``\t``                   `tabulator`:idx:
-  ``\v``                   `vertical tabulator`:idx:
-  ``\\``                   `backslash`:idx:
-  ``\"``                   `quotation mark`:idx:
-  ``\'``                   `apostrophe`:idx:
-  ``\`` '0'..'9'+          `character with decimal value d`:idx:;
-                           all decimal digits directly
-                           following are used for the character
-  ``\a``                   `alert`:idx:
-  ``\b``                   `backspace`:idx:
-  ``\e``                   `escape`:idx: `[ESC]`:idx:
-  ``\x`` HH                `character with hex value HH`:idx:;
-                           exactly two hex digits are allowed
-==================         ===================================================
-
-A character is not an Unicode character but a single byte. The reason for this
-is efficiency: for the overwhelming majority of use-cases, the resulting
-programs will still handle UTF-8 properly as UTF-8 was specially designed for
-this. Another reason is that Nim can thus support ``array[char, int]`` or
-``set[char]`` efficiently as many algorithms rely on this feature.  The `TRune`
-type is used for Unicode characters, it can represent any Unicode character.
-``TRune`` is declared in the `unicode module `_.
-
-
-Numerical constants
--------------------
-
-Numerical constants are of a single type and have the form::
-
-  hexdigit = digit | 'A'..'F' | 'a'..'f'
-  octdigit = '0'..'7'
-  bindigit = '0'..'1'
-  HEX_LIT = '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )*
-  DEC_LIT = digit ( ['_'] digit )*
-  OCT_LIT = '0o' octdigit ( ['_'] octdigit )*
-  BIN_LIT = '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
-  
-  INT_LIT = HEX_LIT
-          | DEC_LIT
-          | OCT_LIT
-          | BIN_LIT
-
-  INT8_LIT = INT_LIT ['\''] ('i' | 'I') '8'
-  INT16_LIT = INT_LIT ['\''] ('i' | 'I') '16'
-  INT32_LIT = INT_LIT ['\''] ('i' | 'I') '32'
-  INT64_LIT = INT_LIT ['\''] ('i' | 'I') '64'
-
-  UINT8_LIT = INT_LIT ['\''] ('u' | 'U')
-  UINT8_LIT = INT_LIT ['\''] ('u' | 'U') '8'
-  UINT16_LIT = INT_LIT ['\''] ('u' | 'U') '16'
-  UINT32_LIT = INT_LIT ['\''] ('u' | 'U') '32'
-  UINT64_LIT = INT_LIT ['\''] ('u' | 'U') '64'
-
-  exponent = ('e' | 'E' ) ['+' | '-'] digit ( ['_'] digit )*
-  FLOAT_LIT = digit (['_'] digit)* (('.' (['_'] digit)* [exponent]) |exponent)
-  FLOAT32_LIT = HEX_LIT '\'' ('f'|'F') '32'
-              | (FLOAT_LIT | DEC_LIT | OCT_LIT | BIN_LIT) ['\''] ('f'|'F') '32'
-  FLOAT64_LIT = HEX_LIT '\'' ('f'|'F') '64'
-              | (FLOAT_LIT | DEC_LIT | OCT_LIT | BIN_LIT) ['\''] ('f'|'F') '64'
-
-
-As can be seen in the productions, numerical constants can contain underscores
-for readability. Integer and floating point literals may be given in decimal (no
-prefix), binary (prefix ``0b``), octal (prefix ``0o``) and hexadecimal
-(prefix ``0x``) notation.
-
-There exists a literal for each numerical type that is
-defined. The suffix starting with an apostrophe ('\'') is called a
-`type suffix`:idx:. Literals without a type suffix are of the type ``int``,
-unless the literal contains a dot or ``E|e`` in which case it is of
-type ``float``. For notational convenience the apostrophe of a type suffix
-is optional if it is not ambiguous (only hexadecimal floating point literals
-with a type suffix can be ambiguous).
-
-
-The type suffixes are:
-
-=================    =========================
-  Type Suffix        Resulting type of literal
-=================    =========================
-  ``'i8``            int8
-  ``'i16``           int16
-  ``'i32``           int32
-  ``'i64``           int64
-  ``'u``             uint
-  ``'u8``            uint8
-  ``'u16``           uint16
-  ``'u32``           uint32
-  ``'u64``           uint64
-  ``'f32``           float32
-  ``'f64``           float64
-=================    =========================
-
-Floating point literals may also be in binary, octal or hexadecimal
-notation:
-``0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64``
-is approximately 1.72826e35 according to the IEEE floating point standard.
-
-
-Operators
----------
-
-In Nim one can define his own operators. An operator is any
-combination of the following characters::
-
-       =     +     -     *     /     <     >
-       @     $     ~     &     %     |
-       !     ?     ^     .     :     \
-
-These keywords are also operators:
-``and or not xor shl shr div mod in notin is isnot of``.
-
-`=`:tok:, `:`:tok:, `::`:tok: are not available as general operators; they
-are used for other notational purposes. 
-
-``*:`` is as a special case the two tokens `*`:tok: and `:`:tok:
-(to support ``var v*: T``).
-
-
-Other tokens
-------------
-
-The following strings denote other tokens::
-
-    `   (     )     {     }     [     ]     ,  ;   [.    .]  {.   .}  (.  .)
-
-
-The `slice`:idx: operator `..`:tok: takes precedence over other tokens that 
-contain a dot: `{..}`:tok: are the three tokens `{`:tok:, `..`:tok:, `}`:tok: 
-and not the two tokens `{.`:tok:, `.}`:tok:.
-
-
-Syntax
-======
-
-This section lists Nim's standard syntax. How the parser handles
-the indentation is already described in the `Lexical Analysis`_ section.
-
-Nim allows user-definable operators.
-Binary operators have 10 different levels of precedence.
-
-Relevant character
-------------------
-
-An operator symbol's *relevant character* is its first
-character unless the first character is ``\`` and its length is greater than 1
-then it is the second character.
-
-This rule allows to escape operator symbols with ``\`` and keeps the operator's
-precedence and associativity; this is useful for meta programming.
-
-
-Associativity
--------------
-
-Binary operators whose relevant character is ``^`` are right-associative, all
-other binary operators are left-associative.
-
-Precedence
-----------
-
-Unary operators always bind stronger than any binary 
-operator: ``$a + b`` is ``($a) + b`` and not ``$(a + b)``.
-
-If an unary operator's relevant character is ``@`` it is a `sigil-like`:idx: 
-operator which binds stronger than a ``primarySuffix``: ``@x.abc`` is parsed
-as ``(@x).abc`` whereas ``$x.abc`` is parsed as ``$(x.abc)``.
-
-
-For binary operators that are not keywords the precedence is determined by the
-following rules:
-
-If the operator ends with ``=`` and its relevant character is none of 
-``<``, ``>``, ``!``, ``=``, ``~``, ``?``, it is an *assignment operator* which
-has the lowest precedence.
-
-Otherwise precedence is determined by the relevant character.
-
-================  ===============================================  ==================  ===============
-Precedence level    Operators                                      Relevant character  Terminal symbol
-================  ===============================================  ==================  ===============
-  9 (highest)                                                      ``$  ^``            OP9
-  8               ``*    /    div   mod   shl  shr  %``            ``* % \  /``        OP8
-  7               ``+    -``                                       ``+  ~  |``         OP7
-  6               ``&``                                            ``&``               OP6
-  5               ``..``                                           ``.``               OP5
-  4               ``==  <= < >= > !=  in notin is isnot not of``   ``= <  > !``        OP4
-  3               ``and``                                                              OP3
-  2               ``or xor``                                                           OP2
-  1                                                                ``@  : ?``          OP1
-  0 (lowest)      *assignment operator* (like ``+=``, ``*=``)                          OP0
-================  ===============================================  ==================  ===============
-
-
-Strong spaces
--------------
-
-The number of spaces preceeding a non-keyword operator affects precedence
-if the experimental parser directive ``#!strongSpaces`` is used. Indentation
-is not used to determine the number of spaces. If 2 or more operators have the
-same number of preceding spaces the precedence table applies, so ``1 + 3 * 4``
-is still parsed as ``1 + (3 * 4)``, but ``1+3 * 4`` is parsed as ``(1+3) * 4``:
-
-.. code-block:: nim
-  #! strongSpaces
-  if foo+4 * 4 == 8 and b&c | 9  ++
-      bar:
-    echo ""
-  # is parsed as
-  if ((foo+4)*4 == 8) and (((b&c) | 9) ++ bar): echo ""
-
-
-Furthermore whether an operator is used a prefix operator is affected by the
-number of spaces: 
-
-.. code-block:: nim
-  #! strongSpaces
-  echo $foo
-  # is parsed as
-  echo($foo)
-
-This also affects whether ``[]``, ``{}``, ``()`` are parsed as constructors
-or as accessors:
-
-.. code-block:: nim
-  #! strongSpaces
-  echo (1,2)
-  # is parsed as
-  echo((1,2))
-
-Only 0, 1, 2, 4 or 8 spaces are allowed to specify precedence and it is
-enforced that infix operators have the same amount of spaces before and after
-them. This rules does not apply when a newline follows after the operator,
-then only the preceding spaces are considered.
-
-
-Grammar
--------
-
-The grammar's start symbol is ``module``.
-
-.. include:: grammar.txt
-   :literal:
-
-
-
-Types
-=====
-
-All expressions have a type which is known at compile time. Nim
-is statically typed. One can declare new types, which is in essence defining
-an identifier that can be used to denote this custom type.
-
-These are the major type classes:
-
-* ordinal types (consist of integer, bool, character, enumeration
-  (and subranges thereof) types)
-* floating point types
-* string type
-* structured types
-* reference (pointer) type
-* procedural type
-* generic type
-
-
-Ordinal types
--------------
-Ordinal types have the following characteristics:
-
-- Ordinal types are countable and ordered. This property allows
-  the operation of functions as ``inc``, ``ord``, ``dec`` on ordinal types to
-  be defined.
-- Ordinal values have a smallest possible value. Trying to count further
-  down than the smallest value gives a checked runtime or static error.
-- Ordinal values have a largest possible value. Trying to count further
-  than the largest value gives a checked runtime or static error.
-
-Integers, bool, characters and enumeration types (and subranges of these
-types) belong to ordinal types. For reasons of simplicity of implementation
-the types ``uint`` and ``uint64`` are not ordinal types.
-
-
-Pre-defined integer types
--------------------------
-These integer types are pre-defined:
-
-``int``
-  the generic signed integer type; its size is platform dependent and has the
-  same size as a pointer. This type should be used in general. An integer 
-  literal that has no type suffix is of this type.
-
-intXX
-  additional signed integer types of XX bits use this naming scheme
-  (example: int16 is a 16 bit wide integer).
-  The current implementation supports ``int8``, ``int16``, ``int32``, ``int64``.
-  Literals of these types have the suffix 'iXX.
-
-``uint``
-  the generic `unsigned integer`:idx: type; its size is platform dependent and
-  has the same size as a pointer. An integer literal with the type 
-  suffix ``'u`` is of this type.
-
-uintXX
-  additional signed integer types of XX bits use this naming scheme
-  (example: uint16 is a 16 bit wide unsigned integer).
-  The current implementation supports ``uint8``, ``uint16``, ``uint32``,
-  ``uint64``. Literals of these types have the suffix 'uXX.
-  Unsigned operations all wrap around; they cannot lead to over- or 
-  underflow errors.
-
-
-In addition to the usual arithmetic operators for signed and unsigned integers
-(``+ - *`` etc.) there are also operators that formally work on *signed* 
-integers but treat their arguments as *unsigned*: They are mostly provided 
-for backwards compatibility with older versions of the language that lacked 
-unsigned integer types. These unsigned operations for signed integers use 
-the ``%`` suffix as convention:
-
-
-======================   ======================================================
-operation                meaning
-======================   ======================================================
-``a +% b``               unsigned integer addition
-``a -% b``               unsigned integer subtraction
-``a *% b``               unsigned integer multiplication
-``a /% b``               unsigned integer division
-``a %% b``               unsigned integer modulo operation
-``a <% b``               treat ``a`` and ``b`` as unsigned and compare
-``a <=% b``              treat ``a`` and ``b`` as unsigned and compare
-``ze(a)``                extends the bits of ``a`` with zeros until it has the
-                         width of the ``int`` type
-``toU8(a)``              treats ``a`` as unsigned and converts it to an
-                         unsigned integer of 8 bits (but still the
-                         ``int8`` type)
-``toU16(a)``             treats ``a`` as unsigned and converts it to an
-                         unsigned integer of 16 bits (but still the
-                         ``int16`` type)
-``toU32(a)``             treats ``a`` as unsigned and converts it to an
-                         unsigned integer of 32 bits (but still the
-                         ``int32`` type)
-======================   ======================================================
-
-`Automatic type conversion`:idx: is performed in expressions where different
-kinds of integer types are used: the smaller type is converted to the larger.
-
-A `narrowing type conversion`:idx: converts a larger to a smaller type (for
-example ``int32 -> int16``. A `widening type conversion`:idx: converts a 
-smaller type to a larger type (for example ``int16 -> int32``). In Nim only
-widening type conversions are *implicit*:
-
-.. code-block:: nim
-  var myInt16 = 5i16
-  var myInt: int
-  myInt16 + 34     # of type ``int16``
-  myInt16 + myInt  # of type ``int``
-  myInt16 + 2i32   # of type ``int32``
-
-However, ``int`` literals are implicitly convertible to a smaller integer type
-if the literal's value fits this smaller type and such a conversion is less
-expensive than other implicit conversions, so ``myInt16 + 34`` produces 
-an ``int16`` result.
-
-For further details, see `Convertible relation`_.
-
-
-Subrange types
---------------
-A subrange type is a range of values from an ordinal type (the base
-type). To define a subrange type, one must specify it's limiting values: the
-lowest and highest value of the type:
-
-.. code-block:: nim
-  type
-    Subrange = range[0..5]
-
-
-``Subrange`` is a subrange of an integer which can only hold the values 0
-to 5. Assigning any other value to a variable of type ``Subrange`` is a
-checked runtime error (or static error if it can be statically
-determined). Assignments from the base type to one of its subrange types
-(and vice versa) are allowed.
-
-A subrange type has the same size as its base type (``int`` in the example).
-
-Nim requires `interval arithmetic`:idx: for subrange types over a set
-of built-in operators that involve constants: ``x %% 3`` is of 
-type ``range[0..2]``. The following built-in operators for integers are 
-affected by this rule: ``-``, ``+``, ``*``, ``min``, ``max``, ``succ``,
-``pred``, ``mod``, ``div``, ``%%``, ``and`` (bitwise ``and``).
-
-Bitwise ``and`` only produces a ``range`` if one of its operands is a 
-constant *x* so that (x+1) is a number of two.
-(Bitwise ``and`` is then a ``%%`` operation.)
-
-This means that the following code is accepted:
-
-.. code-block:: nim
-  case (x and 3) + 7
-  of 7: echo "A"
-  of 8: echo "B"
-  of 9: echo "C"
-  of 10: echo "D"
-  # note: no ``else`` required as (x and 3) + 7 has the type: range[7..10]
-  
-
-Pre-defined floating point types
---------------------------------
-
-The following floating point types are pre-defined:
-
-``float``
-  the generic floating point type; its size is platform dependent
-  (the compiler chooses the processor's fastest floating point type).
-  This type should be used in general.
-
-floatXX
-  an implementation may define additional floating point types of XX bits using
-  this naming scheme (example: float64 is a 64 bit wide float). The current
-  implementation supports ``float32`` and ``float64``. Literals of these types
-  have the suffix 'fXX.
-
-
-Automatic type conversion in expressions with different kinds
-of floating point types is performed: See `Convertible relation`_ for further
-details. Arithmetic performed on floating point types follows the IEEE
-standard. Integer types are not converted to floating point types automatically
-and vice versa.
-
-The IEEE standard defines five types of floating-point exceptions:
-
-* Invalid: operations with mathematically invalid operands,
-  for example 0.0/0.0, sqrt(-1.0), and log(-37.8).
-* Division by zero: divisor is zero and dividend is a finite nonzero number,
-  for example 1.0/0.0.
-* Overflow: operation produces a result that exceeds the range of the exponent, 
-  for example MAXDOUBLE+0.0000000000001e308.
-* Underflow: operation produces a result that is too small to be represented 
-  as a normal number, for example, MINDOUBLE * MINDOUBLE.
-* Inexact: operation produces a result that cannot be represented with infinite 
-  precision, for example, 2.0 / 3.0, log(1.1) and 0.1 in input.
-
-The IEEE exceptions are either ignored at runtime or mapped to the 
-Nim exceptions: `EFloatInvalidOp`:idx:, `EFloatDivByZero`:idx:,
-`EFloatOverflow`:idx:, `EFloatUnderflow`:idx:, and `EFloatInexact`:idx:. 
-These exceptions inherit from the `EFloatingPoint`:idx: base class.
-
-Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control
-whether the IEEE exceptions are ignored or trap a Nim exception:
-
-.. code-block:: nim
-  {.NanChecks: on, InfChecks: on.}
-  var a = 1.0
-  var b = 0.0
-  echo b / b # raises EFloatInvalidOp
-  echo a / b # raises EFloatOverflow
-
-In the current implementation ``EFloatDivByZero`` and ``EFloatInexact`` are 
-never raised. ``EFloatOverflow`` is raised instead of ``EFloatDivByZero``.
-There is also a `floatChecks`:idx: pragma that is a short-cut for the 
-combination of ``NaNChecks`` and ``InfChecks`` pragmas. ``floatChecks`` are
-turned off as default.
-
-The only operations that are affected by the ``floatChecks`` pragma are
-the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
-
-An implementation should always use the maximum precision available to evaluate
-floating pointer values at compile time; this means expressions like
-``0.09'f32 + 0.01'f32 == 0.09'f64 + 0.01'f64`` are true.
-
-
-Boolean type
-------------
-The boolean type is named `bool`:idx: in Nim and can be one of the two
-pre-defined values ``true`` and ``false``. Conditions in while,
-if, elif, when statements need to be of type bool.
-
-This condition holds::
-
-  ord(false) == 0 and ord(true) == 1
-
-The operators ``not, and, or, xor, <, <=, >, >=, !=, ==`` are defined
-for the bool type. The ``and`` and ``or`` operators perform short-cut
-evaluation. Example:
-
-.. code-block:: nim
-
-  while p != nil and p.name != "xyz":
-    # p.name is not evaluated if p == nil
-    p = p.next
-
-
-The size of the bool type is one byte.
-
-
-Character type
---------------
-The character type is named ``char`` in Nim. Its size is one byte.
-Thus it cannot represent an UTF-8 character, but a part of it.
-The reason for this is efficiency: for the overwhelming majority of use-cases,
-the resulting programs will still handle UTF-8 properly as UTF-8 was specially
-designed for this.
-Another reason is that Nim can support ``array[char, int]`` or
-``set[char]`` efficiently as many algorithms rely on this feature. The
-`TRune` type is used for Unicode characters, it can represent any Unicode
-character. ``TRune`` is declared in the `unicode module `_.
-
-
-
-
-Enumeration types
------------------
-Enumeration types define a new type whose values consist of the ones
-specified. The values are ordered. Example:
-
-.. code-block:: nim
-
-  type
-    TDirection = enum
-      north, east, south, west
-
-
-Now the following holds::
-
-  ord(north) == 0
-  ord(east) == 1
-  ord(south) == 2
-  ord(west) == 3
-
-Thus, north < east < south < west. The comparison operators can be used
-with enumeration types.
-
-For better interfacing to other programming languages, the fields of enum
-types can be assigned an explicit ordinal value. However, the ordinal values
-have to be in ascending order. A field whose ordinal value is not
-explicitly given is assigned the value of the previous field + 1.
-
-An explicit ordered enum can have *holes*:
-
-.. code-block:: nim
-  type
-    TTokenType = enum
-      a = 2, b = 4, c = 89 # holes are valid
-
-However, it is then not an ordinal anymore, so it is not possible to use these
-enums as an index type for arrays. The procedures ``inc``, ``dec``, ``succ``
-and ``pred`` are not available for them either.
-
-
-The compiler supports the built-in stringify operator ``$`` for enumerations.
-The stringify's result can be controlled by explicitly giving the string 
-values to use:
-
-.. code-block:: nim
-
-  type
-    TMyEnum = enum
-      valueA = (0, "my value A"),
-      valueB = "value B",
-      valueC = 2,
-      valueD = (3, "abc")
-
-As can be seen from the example, it is possible to both specify a field's 
-ordinal value and its string value by using a tuple. It is also
-possible to only specify one of them.
-
-An enum can be marked with the ``pure`` pragma so that it's fields are not
-added to the current scope, so they always need to be accessed 
-via ``TMyEnum.value``:
-
-.. code-block:: nim
-
-  type
-    TMyEnum {.pure.} = enum
-      valueA, valueB, valueC, valueD
-  
-  echo valueA # error: Unknown identifier
-  echo TMyEnum.valueA # works
-
-
-String type
------------
-All string literals are of the type ``string``. A string in Nim is very
-similar to a sequence of characters. However, strings in Nim are both
-zero-terminated and have a length field. One can retrieve the length with the
-builtin ``len`` procedure; the length never counts the terminating zero.
-The assignment operator for strings always copies the string.
-The ``&`` operator concatenates strings.
-
-Strings are compared by their lexicographical order. All comparison operators
-are available. Strings can be indexed like arrays (lower bound is 0). Unlike
-arrays, they can be used in case statements:
-
-.. code-block:: nim
-
-  case paramStr(i)
-  of "-v": incl(options, optVerbose)
-  of "-h", "-?": incl(options, optHelp)
-  else: write(stdout, "invalid command line option!\n")
-
-Per convention, all strings are UTF-8 strings, but this is not enforced. For
-example, when reading strings from binary files, they are merely a sequence of
-bytes. The index operation ``s[i]`` means the i-th *char* of ``s``, not the
-i-th *unichar*. The iterator ``runes`` from the `unicode module
-`_ can be used for iteration over all Unicode characters.
-
-
-CString type
-------------
-The ``cstring`` type represents a pointer to a zero-terminated char array
-compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy
-interfacing with C. The index operation ``s[i]`` means the i-th *char* of 
-``s``; however no bounds checking for ``cstring`` is performed making the
-index operation unsafe.
-
-A Nim ``string`` is implicitly convertible 
-to ``cstring`` for convenience. If a Nim string is passed to a C-style
-variadic proc, it is implicitly converted to ``cstring`` too:
-
-.. code-block:: nim
-  proc printf(formatstr: cstring) {.importc: "printf", varargs, 
-                                    header: "".}
-  
-  printf("This works %s", "as expected")
-
-Even though the conversion is implicit, it is not *safe*: The garbage collector
-does not consider a ``cstring`` to be a root and may collect the underlying 
-memory. However in practice this almost never happens as the GC considers
-stack roots conservatively. One can use the builtin procs ``GC_ref`` and
-``GC_unref`` to keep the string data alive for the rare cases where it does
-not work.
-
-A `$` proc is defined for cstrings that returns a string. Thus to get a nim
-string from a cstring:
-
-.. code-block:: nim
-  var str: string = "Hello!"
-  var cstr: cstring = s
-  var newstr: string = $cstr
-
-
-Structured types
-----------------
-A variable of a structured type can hold multiple values at the same
-time. Structured types can be nested to unlimited levels. Arrays, sequences,
-tuples, objects and sets belong to the structured types.
-
-Array and sequence types
-------------------------
-Arrays are a homogeneous type, meaning that each element in the array
-has the same type. Arrays always have a fixed length which is specified at
-compile time (except for open arrays). They can be indexed by any ordinal type.
-A parameter ``A`` may be an *open array*, in which case it is indexed by
-integers from 0 to ``len(A)-1``. An array expression may be constructed by the
-array constructor ``[]``.
-
-Sequences are similar to arrays but of dynamic length which may change
-during runtime (like strings). Sequences are implemented as growable arrays, 
-allocating pieces of memory as items are added. A sequence ``S`` is always
-indexed by integers from 0 to ``len(S)-1`` and its bounds are checked. 
-Sequences can be constructed by the array constructor ``[]`` in conjunction
-with the array to sequence operator ``@``. Another way to allocate space for a
-sequence is to call the built-in ``newSeq`` procedure.
-
-A sequence may be passed to a parameter that is of type *open array*.
-
-Example:
-
-.. code-block:: nim
-
-  type
-    TIntArray = array[0..5, int] # an array that is indexed with 0..5
-    TIntSeq = seq[int] # a sequence of integers
-  var
-    x: TIntArray
-    y: TIntSeq
-  x = [1, 2, 3, 4, 5, 6]  # [] is the array constructor
-  y = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence
-
-The lower bound of an array or sequence may be received by the built-in proc
-``low()``, the higher bound by ``high()``. The length may be
-received by ``len()``. ``low()`` for a sequence or an open array always returns
-0, as this is the first valid index.
-One can append elements to a sequence with the ``add()`` proc or the ``&``
-operator, and remove (and get) the last element of a sequence with the
-``pop()`` proc.
-
-The notation ``x[i]`` can be used to access the i-th element of ``x``.
-
-Arrays are always bounds checked (at compile-time or at runtime). These
-checks can be disabled via pragmas or invoking the compiler with the
-``--boundChecks:off`` command line switch.
-
-
-Open arrays
------------
-
-Often fixed size arrays turn out to be too inflexible; procedures should
-be able to deal with arrays of different sizes. The `openarray`:idx: type
-allows this; it can only be used for parameters. Openarrays are always 
-indexed with an ``int`` starting at position 0. The ``len``, ``low`` 
-and ``high`` operations are available for open arrays too. Any array with 
-a compatible base type can be passed to an openarray parameter, the index 
-type does not matter. In addition to arrays sequences can also be passed 
-to an open array parameter.
-
-The openarray type cannot be nested: multidimensional openarrays are not
-supported because this is seldom needed and cannot be done efficiently.
-
-
-Varargs
--------
-
-A ``varargs`` parameter is an openarray parameter that additionally
-allows to pass a variable number of arguments to a procedure. The compiler 
-converts the list of arguments to an array implicitly:
-
-.. code-block:: nim
-  proc myWriteln(f: TFile, a: varargs[string]) =
-    for s in items(a):
-      write(f, s)
-    write(f, "\n")
-
-  myWriteln(stdout, "abc", "def", "xyz")
-  # is transformed to:
-  myWriteln(stdout, ["abc", "def", "xyz"])
-
-This transformation is only done if the varargs parameter is the
-last parameter in the procedure header. It is also possible to perform
-type conversions in this context:
-
-.. code-block:: nim
-  proc myWriteln(f: TFile, a: varargs[string, `$`]) =
-    for s in items(a):
-      write(f, s)
-    write(f, "\n")
-
-  myWriteln(stdout, 123, "abc", 4.0)
-  # is transformed to:
-  myWriteln(stdout, [$123, $"def", $4.0])
-
-In this example ``$`` is applied to any argument that is passed to the 
-parameter ``a``. (Note that ``$`` applied to strings is a nop.)
-
-
-
-Tuples and object types
------------------------
-A variable of a tuple or object type is a heterogeneous storage
-container.
-A tuple or object defines various named *fields* of a type. A tuple also
-defines an *order* of the fields. Tuples are meant for heterogeneous storage
-types with no overhead and few abstraction possibilities. The constructor ``()``
-can be used to construct tuples. The order of the fields in the constructor
-must match the order of the tuple's definition. Different tuple-types are
-*equivalent* if they specify the same fields of the same type in the same
-order. The *names* of the fields also have to be identical but this might
-change in a future version of the language.
-
-The assignment operator for tuples copies each component.
-The default assignment operator for objects copies each component. Overloading
-of the assignment operator for objects is not possible, but this will change
-in future versions of the compiler.
-
-.. code-block:: nim
-
-  type
-    TPerson = tuple[name: string, age: int] # type representing a person:
-                                            # a person consists of a name
-                                            # and an age
-  var
-    person: TPerson
-  person = (name: "Peter", age: 30)
-  # the same, but less readable:
-  person = ("Peter", 30)
-
-The implementation aligns the fields for best access performance. The alignment
-is compatible with the way the C compiler does it. 
-
-For consistency  with ``object`` declarations, tuples in a ``type`` section
-can also be defined with indentation instead of ``[]``:
-
-.. code-block:: nim
-  type
-    TPerson = tuple   # type representing a person
-      name: string    # a person consists of a name
-      age: natural    # and an age
-
-Objects provide many features that tuples do not. Object provide inheritance
-and information hiding. Objects have access to their type at runtime, so that
-the ``of`` operator can be used to determine the object's type.
-
-.. code-block:: nim
-  type
-    TPerson {.inheritable.} = object
-      name*: string   # the * means that `name` is accessible from other modules
-      age: int        # no * means that the field is hidden
-
-    TStudent = object of TPerson # a student is a person
-      id: int                    # with an id field
-
-  var
-    student: TStudent
-    person: TPerson
-  assert(student of TStudent) # is true
-
-Object fields that should be visible from outside the defining module, have to
-be marked by ``*``. In contrast to tuples, different object types are
-never *equivalent*. Objects that have no ancestor are implicitly ``final``
-and thus have no hidden type field. One can use the ``inheritable`` pragma to
-introduce new object roots apart from ``system.TObject``.
-
-
-Object construction
--------------------
-
-Objects can also be created with an `object construction expression`:idx: that
-has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is 
-an ``object`` type or a ``ref object`` type:
-
-.. code-block:: nim
-  var student = TStudent(name: "Anton", age: 5, id: 3)
-
-For a ``ref object`` type ``system.new`` is invoked implicitly.
-
-
-Object variants
----------------
-Often an object hierarchy is overkill in certain situations where simple
-variant types are needed.
-
-An example:
-
-.. code-block:: nim
-
-  # This is an example how an abstract syntax tree could be modelled in Nim
-  type
-    TNodeKind = enum  # the different node types
-      nkInt,          # a leaf with an integer value
-      nkFloat,        # a leaf with a float value
-      nkString,       # a leaf with a string value
-      nkAdd,          # an addition
-      nkSub,          # a subtraction
-      nkIf            # an if statement
-    PNode = ref TNode
-    TNode = object
-      case kind: TNodeKind  # the ``kind`` field is the discriminator
-      of nkInt: intVal: int
-      of nkFloat: floatVal: float
-      of nkString: strVal: string
-      of nkAdd, nkSub:
-        leftOp, rightOp: PNode
-      of nkIf:
-        condition, thenPart, elsePart: PNode
-
-  # create a new case object:
-  var n = PNode(kind: nkIf, condition: nil)
-  # accessing n.thenPart is valid because the ``nkIf`` branch is active:
-  n.thenPart = PNode(kind: nkFloat, floatVal: 2.0)
-
-  # the following statement raises an `EInvalidField` exception, because
-  # n.kind's value does not fit and the ``nkString`` branch is not active:
-  n.strVal = ""
-  
-  # invalid: would change the active object branch:
-  n.kind = nkInt
-  
-  var x = PNode(kind: nkAdd, leftOp: PNode(kind: nkInt, intVal: 4),
-                             rightOp: PNode(kind: nkInt, intVal: 2))
-  # valid: does not change the active object branch:
-  x.kind = nkSub
-
-As can been seen from the example, an advantage to an object hierarchy is that
-no casting between different object types is needed. Yet, access to invalid
-object fields raises an exception.
-
-The syntax of ``case`` in an object declaration follows closely the syntax of
-the ``case`` statement: The branches in a ``case`` section may be indented too.
-
-In the example the ``kind`` field is called the `discriminator`:idx:\: For
-safety its address cannot be taken and assignments to it are restricted: The
-new value must not lead to a change of the active object branch. For an object
-branch switch ``system.reset`` has to be used.
-
-
-Set type
---------
-
-.. include:: sets_fragment.txt
-
-Reference and pointer types
----------------------------
-References (similar to pointers in other programming languages) are a
-way to introduce many-to-one relationships. This means different references can
-point to and modify the same location in memory (also called `aliasing`:idx:).
-
-Nim distinguishes between `traced`:idx: and `untraced`:idx: references.
-Untraced references are also called *pointers*. Traced references point to
-objects of a garbage collected heap, untraced references point to
-manually allocated objects or to objects somewhere else in memory. Thus
-untraced references are *unsafe*. However for certain low-level operations
-(accessing the hardware) untraced references are unavoidable.
-
-Traced references are declared with the **ref** keyword, untraced references
-are declared with the **ptr** keyword.
-
-An empty subscript ``[]`` notation can be used to derefer a reference, 
-the ``addr`` procedure returns the address of an item. An address is always 
-an untraced reference.
-Thus the usage of ``addr`` is an *unsafe* feature.
-
-The ``.`` (access a tuple/object field operator)
-and ``[]`` (array/string/sequence index operator) operators perform implicit
-dereferencing operations for reference types:
-
-.. code-block:: nim
-
-  type
-    PNode = ref TNode
-    TNode = object
-      le, ri: PNode
-      data: int
-
-  var
-    n: PNode
-  new(n)
-  n.data = 9 
-  # no need to write n[].data; in fact n[].data is highly discouraged!
-
-As a syntactical extension ``object`` types can be anonymous if
-declared in a type section via the ``ref object`` or ``ptr object`` notations.
-This feature is useful if an object should only gain reference semantics:
-
-.. code-block:: nim
-
-  type
-    Node = ref object
-      le, ri: Node
-      data: int
-
-
-To allocate a new traced object, the built-in procedure ``new`` has to be used.
-To deal with untraced memory, the procedures ``alloc``, ``dealloc`` and
-``realloc`` can be used. The documentation of the system module contains
-further information.
-
-If a reference points to *nothing*, it has the value ``nil``.
-
-Special care has to be taken if an untraced object contains traced objects like
-traced references, strings or sequences: in order to free everything properly,
-the built-in procedure ``GCunref`` has to be called before freeing the untraced
-memory manually:
-
-.. code-block:: nim
-  type
-    TData = tuple[x, y: int, s: string]
-
-  # allocate memory for TData on the heap:
-  var d = cast[ptr TData](alloc0(sizeof(TData)))
-
-  # create a new string on the garbage collected heap:
-  d.s = "abc"
-
-  # tell the GC that the string is not needed anymore:
-  GCunref(d.s)
-
-  # free the memory:
-  dealloc(d)
-
-Without the ``GCunref`` call the memory allocated for the ``d.s`` string would
-never be freed. The example also demonstrates two important features for low
-level programming: the ``sizeof`` proc returns the size of a type or value
-in bytes. The ``cast`` operator can circumvent the type system: the compiler
-is forced to treat the result of the ``alloc0`` call (which returns an untyped
-pointer) as if it would have the type ``ptr TData``. Casting should only be
-done if it is unavoidable: it breaks type safety and bugs can lead to
-mysterious crashes.
-
-**Note**: The example only works because the memory is initialized to zero
-(``alloc0`` instead of ``alloc`` does this): ``d.s`` is thus initialized to
-``nil`` which the string assignment can handle. One needs to know low level
-details like this when mixing garbage collected data with unmanaged memory.
-
-.. XXX finalizers for traced objects
-
-
-Not nil annotation
-------------------
-
-All types for that ``nil`` is a valid value can be annotated to 
-exclude ``nil`` as a valid value with the ``not nil`` annotation:
-
-.. code-block:: nim
-  type
-    PObject = ref TObj not nil
-    TProc = (proc (x, y: int)) not nil
-    
-  proc p(x: PObject) =
-    echo "not nil"
-  
-  # compiler catches this:
-  p(nil)
-  
-  # and also this:
-  var x: PObject
-  p(x)
-
-The compiler ensures that every code path initializes variables which contain
-not nilable pointers. The details of this analysis are still to be specified
-here.
-
-
-Memory regions
---------------
-
-The types ``ref`` and ``ptr`` can get an optional ``region`` annotation.
-A region has to be an object type.
-
-Regions are very useful to separate user space and kernel memory in the
-development of OS kernels:
-
-.. code-block:: nim
-  type
-    Kernel = object
-    Userspace = object
-
-  var a: Kernel ptr Stat
-  var b: Userspace ptr Stat
-
-  # the following does not compile as the pointer types are incompatible:
-  a = b
-
-As the example shows ``ptr`` can also be used as a binary
-operator, ``region ptr T`` is a shortcut for ``ptr[region, T]``.
-
-In order to make generic code easier to write ``ptr T`` is a subtype
-of ``ptr[R, T]`` for any ``R``.
-
-Furthermore the subtype relation of the region object types is lifted to
-the pointer types: If ``A <: B`` then ``ptr[A, T] <: ptr[B, T]``. This can be
-used to model subregions of memory. As a special typing rule ``ptr[R, T]`` is
-not compatible to ``pointer`` to prevent the following from compiling:
-
-.. code-block:: nim
-  # from system
-  proc dealloc(p: pointer)
-
-  # wrap some scripting language
-  type
-    PythonsHeap = object
-    PyObjectHeader = object
-      rc: int
-      typ: pointer
-    PyObject = ptr[PythonsHeap, PyObjectHeader]
-
-  proc createPyObject(): PyObject {.importc: "...".}
-  proc destroyPyObject(x: PyObject) {.importc: "...".}
-
-  var foo = createPyObject()
-  # type error here, how convenient:
-  dealloc(foo)
-
-
-Future directions:
-
-* Memory regions might become available for  ``string`` and ``seq`` too.
-* Builtin regions like ``private``, ``global`` and ``local`` will
-  prove very useful for the upcoming OpenCL target.
-* Builtin "regions" can model ``lent`` and ``unique`` pointers.
-
-
-
-Procedural type
----------------
-A procedural type is internally a pointer to a procedure. ``nil`` is
-an allowed value for variables of a procedural type. Nim uses procedural
-types to achieve `functional`:idx: programming techniques.
-
-Examples:
-
-.. code-block:: nim
-
-  proc printItem(x: int) = ...
-
-  proc forEach(c: proc (x: int) {.cdecl.}) =
-    ...
-
-  forEach(printItem)  # this will NOT compile because calling conventions differ
-
-  
-.. code-block:: nim
-
-  type
-    TOnMouseMove = proc (x, y: int) {.closure.}
-  
-  proc onMouseMove(mouseX, mouseY: int) =
-    # has default calling convention
-    echo "x: ", mouseX, " y: ", mouseY
-  
-  proc setOnMouseMove(mouseMoveEvent: TOnMouseMove) = discard
-  
-  # ok, 'onMouseMove' has the default calling convention, which is compatible
-  # to 'closure':
-  setOnMouseMove(onMouseMove)
-  
-
-A subtle issue with procedural types is that the calling convention of the
-procedure influences the type compatibility: procedural types are only
-compatible if they have the same calling convention. As a special extension,
-a procedure of the calling convention ``nimcall`` can be passed to a parameter
-that expects a proc of the calling convention ``closure``.
-
-Nim supports these `calling conventions`:idx:\:
-
-`nimcall`:idx:
-    is the default convention used for a Nim **proc**. It is the
-    same as ``fastcall``, but only for C compilers that support ``fastcall``.
-
-`closure`:idx:
-    is the default calling convention for a **procedural type** that lacks
-    any pragma annotations. It indicates that the procedure has a hidden
-    implicit parameter (an *environment*). Proc vars that have the calling
-    convention ``closure`` take up two machine words: One for the proc pointer
-    and another one for the pointer to implicitly passed environment.
-
-`stdcall`:idx:
-    This the stdcall convention as specified by Microsoft. The generated C
-    procedure is declared with the ``__stdcall`` keyword.
-
-`cdecl`:idx:
-    The cdecl convention means that a procedure shall use the same convention
-    as the C compiler. Under windows the generated C procedure is declared with
-    the ``__cdecl`` keyword.
-
-`safecall`:idx:
-    This is the safecall convention as specified by Microsoft. The generated C
-    procedure is declared with the ``__safecall`` keyword. The word *safe*
-    refers to the fact that all hardware registers shall be pushed to the
-    hardware stack.
-
-`inline`:idx:
-    The inline convention means the the caller should not call the procedure,
-    but inline its code directly. Note that Nim does not inline, but leaves
-    this to the C compiler; it generates ``__inline`` procedures. This is
-    only a hint for the compiler: it may completely ignore it and
-    it may inline procedures that are not marked as ``inline``.
-
-`fastcall`:idx:
-    Fastcall means different things to different C compilers. One gets whatever
-    the C ``__fastcall`` means.
-
-`syscall`:idx:
-    The syscall convention is the same as ``__syscall`` in C. It is used for
-    interrupts.
-
-`noconv`:idx:
-    The generated C code will not have any explicit calling convention and thus
-    use the C compiler's default calling convention. This is needed because
-    Nim's default calling convention for procedures is ``fastcall`` to
-    improve speed.
-
-Most calling conventions exist only for the Windows 32-bit platform.
-
-Assigning/passing a procedure to a procedural variable is only allowed if one
-of the following conditions hold:
-1) The procedure that is accessed resides in the current module.
-2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma`_).
-3) The procedure has a calling convention that differs from ``nimcall``.
-4) The procedure is anonymous.
-
-The rules' purpose is to prevent the case that extending a non-``procvar`` 
-procedure with default parameters breaks client code.
-
-The default calling convention is ``nimcall``, unless it is an inner proc (a
-proc inside of a proc). For an inner proc an analysis is performed whether it
-accesses its environment. If it does so, it has the calling convention
-``closure``, otherwise it has the calling convention ``nimcall``.
-
-
-Distinct type
--------------
-
-A ``distinct`` type is new type derived from a `base type`:idx: that is
-incompatible with its base type. In particular, it is an essential property
-of a distinct type that it **does not** imply a subtype relation between it
-and its base type. Explicit type conversions from a distinct type to its
-base type and vice versa are allowed.
-
-
-Modelling currencies
-~~~~~~~~~~~~~~~~~~~~
-
-A distinct type can be used to model different physical `units`:idx: with a
-numerical base type, for example. The following example models currencies.
-
-Different currencies should not be mixed in monetary calculations. Distinct
-types are a perfect tool to model different currencies:
-
-.. code-block:: nim
-  type
-    TDollar = distinct int
-    TEuro = distinct int
-  
-  var
-    d: TDollar
-    e: TEuro
-
-  echo d + 12
-  # Error: cannot add a number with no unit and a ``TDollar``
-
-Unfortunately, ``d + 12.TDollar`` is not allowed either,
-because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So
-a ``+`` for dollars needs to be defined:
-
-.. code-block::
-  proc `+` (x, y: TDollar): TDollar =
-    result = TDollar(int(x) + int(y))
-
-It does not make sense to multiply a dollar with a dollar, but with a
-number without unit; and the same holds for division:
-
-.. code-block::
-  proc `*` (x: TDollar, y: int): TDollar =
-    result = TDollar(int(x) * y)
-
-  proc `*` (x: int, y: TDollar): TDollar =
-    result = TDollar(x * int(y))
-    
-  proc `div` ...
-
-This quickly gets tedious. The implementations are trivial and the compiler
-should not generate all this code only to optimize it away later - after all
-``+`` for dollars should produce the same binary code as ``+`` for ints.
-The pragma `borrow`:idx: has been designed to solve this problem; in principle
-it generates the above trivial implementations:
-
-.. code-block:: nim
-  proc `*` (x: TDollar, y: int): TDollar {.borrow.}
-  proc `*` (x: int, y: TDollar): TDollar {.borrow.}
-  proc `div` (x: TDollar, y: int): TDollar {.borrow.}
-
-The ``borrow`` pragma makes the compiler use the same implementation as
-the proc that deals with the distinct type's base type, so no code is
-generated.
-
-But it seems all this boilerplate code needs to be repeated for the ``TEuro``
-currency. This can be solved with templates_.
-
-.. code-block:: nim
-  template additive(typ: typedesc): stmt =
-    proc `+` *(x, y: typ): typ {.borrow.}
-    proc `-` *(x, y: typ): typ {.borrow.}
-    
-    # unary operators:
-    proc `+` *(x: typ): typ {.borrow.}
-    proc `-` *(x: typ): typ {.borrow.}
-
-  template multiplicative(typ, base: typedesc): stmt =
-    proc `*` *(x: typ, y: base): typ {.borrow.}
-    proc `*` *(x: base, y: typ): typ {.borrow.}
-    proc `div` *(x: typ, y: base): typ {.borrow.}
-    proc `mod` *(x: typ, y: base): typ {.borrow.}
-
-  template comparable(typ: typedesc): stmt =
-    proc `<` * (x, y: typ): bool {.borrow.}
-    proc `<=` * (x, y: typ): bool {.borrow.}
-    proc `==` * (x, y: typ): bool {.borrow.}
-
-  template defineCurrency(typ, base: expr): stmt =
-    type
-      typ* = distinct base
-    additive(typ)
-    multiplicative(typ, base)
-    comparable(typ)
-    
-  defineCurrency(TDollar, int)
-  defineCurrency(TEuro, int)
-
-
-The borrow pragma can also be used to annotate the distinct type to allow
-certain builtin operations to be lifted:
-
-.. code-block:: nim
-  type
-    Foo = object
-      a, b: int
-      s: string
-
-    Bar {.borrow: `.`.} = distinct Foo
-
-  var bb: ref Bar
-  new bb
-  # field access now valid
-  bb.a = 90
-  bb.s = "abc"
-
-Currently only the dot accessor can be borrowed in this way.
-
-
-Avoiding SQL injection attacks
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-An SQL statement that is passed from Nim to an SQL database might be
-modelled as a string. However, using string templates and filling in the
-values is vulnerable to the famous `SQL injection attack`:idx:\:
-
-.. code-block:: nim
-  import strutils
-
-  proc query(db: TDbHandle, statement: string) = ...
-
-  var
-    username: string
-
-  db.query("SELECT FROM users WHERE name = '$1'" % username)
-  # Horrible security hole, but the compiler does not mind!
-
-This can be avoided by distinguishing strings that contain SQL from strings
-that don't. Distinct types provide a means to introduce a new string type
-``TSQL`` that is incompatible with ``string``:
-
-.. code-block:: nim
-  type
-    TSQL = distinct string
-
-  proc query(db: TDbHandle, statement: TSQL) = ...
-
-  var
-    username: string
-
-  db.query("SELECT FROM users WHERE name = '$1'" % username)
-  # Error at compile time: `query` expects an SQL string!
-
-
-It is an essential property of abstract types that they **do not** imply a
-subtype relation between the abtract type and its base type. Explict type
-conversions from ``string`` to ``TSQL`` are allowed:
-
-.. code-block:: nim
-  import strutils, sequtils
-
-  proc properQuote(s: string): TSQL =
-    # quotes a string properly for an SQL statement
-    return TSQL(s)
-
-  proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
-    # quote each argument:
-    let v = values.mapIt(TSQL, properQuote(it))
-    # we need a temporary type for the type conversion :-(
-    type TStrSeq = seq[string]
-    # call strutils.`%`:
-    result = TSQL(string(frmt) % TStrSeq(v))
-
-  db.query("SELECT FROM users WHERE name = '$1'".TSQL % [username])
-
-Now we have compile-time checking against SQL injection attacks.  Since
-``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed for nice
-looking ``TSQL`` string literals. The hypothetical ``TSQL`` type actually
-exists in the library as the `TSqlQuery type `_ of
-modules like `db_sqlite `_.
-
-
-Void type
----------
-
-The ``void`` type denotes the absense of any type. Parameters of 
-type ``void`` are treated as non-existent, ``void`` as a return type means that
-the procedure does not return a value:
-
-.. code-block:: nim
-  proc nothing(x, y: void): void =
-    echo "ha"
-  
-  nothing() # writes "ha" to stdout
-
-The ``void`` type is particularly useful for generic code:
-
-.. code-block:: nim
-  proc callProc[T](p: proc (x: T), x: T) =
-    when T is void: 
-      p()
-    else:
-      p(x)
-
-  proc intProc(x: int) = discard
-  proc emptyProc() = discard
-
-  callProc[int](intProc, 12)
-  callProc[void](emptyProc)
-  
-However, a ``void`` type cannot be inferred in generic code:
-
-.. code-block:: nim
-  callProc(emptyProc) 
-  # Error: type mismatch: got (proc ())
-  # but expected one of: 
-  # callProc(p: proc (T), x: T)
-
-The ``void`` type is only valid for parameters and return types; other symbols
-cannot have the type ``void``.
-
-
-Type relations
-==============
-
-The following section defines several relations on types that are needed to
-describe the type checking done by the compiler.
-
-
-Type equality
--------------
-Nim uses structural type equivalence for most types. Only for objects,
-enumerations and distinct types name equivalence is used. The following
-algorithm (in pseudo-code) determines type equality:
-
-.. code-block:: nim
-  proc typeEqualsAux(a, b: PType,
-                     s: var set[PType * PType]): bool =
-    if (a,b) in s: return true
-    incl(s, (a,b))
-    if a.kind == b.kind:
-      case a.kind
-      of int, intXX, float, floatXX, char, string, cstring, pointer, 
-          bool, nil, void:
-        # leaf type: kinds identical; nothing more to check
-        result = true
-      of ref, ptr, var, set, seq, openarray:
-        result = typeEqualsAux(a.baseType, b.baseType, s)
-      of range:
-        result = typeEqualsAux(a.baseType, b.baseType, s) and
-          (a.rangeA == b.rangeA) and (a.rangeB == b.rangeB)
-      of array:
-        result = typeEqualsAux(a.baseType, b.baseType, s) and
-                 typeEqualsAux(a.indexType, b.indexType, s)
-      of tuple:
-        if a.tupleLen == b.tupleLen:
-          for i in 0..a.tupleLen-1:
-            if not typeEqualsAux(a[i], b[i], s): return false
-          result = true
-      of object, enum, distinct:
-        result = a == b
-      of proc:
-        result = typeEqualsAux(a.parameterTuple, b.parameterTuple, s) and
-                 typeEqualsAux(a.resultType, b.resultType, s) and
-                 a.callingConvention == b.callingConvention
-
-  proc typeEquals(a, b: PType): bool =
-    var s: set[PType * PType] = {}
-    result = typeEqualsAux(a, b, s)
-
-Since types are graphs which can have cycles, the above algorithm needs an
-auxiliary set ``s`` to detect this case.
-
-
-Type equality modulo type distinction
--------------------------------------
-
-The following algorithm (in pseudo-code) determines whether two types
-are equal with no respect to ``distinct`` types. For brevity the cycle check
-with an auxiliary set ``s`` is omitted:
-
-.. code-block:: nim
-  proc typeEqualsOrDistinct(a, b: PType): bool =
-    if a.kind == b.kind:
-      case a.kind
-      of int, intXX, float, floatXX, char, string, cstring, pointer, 
-          bool, nil, void:
-        # leaf type: kinds identical; nothing more to check
-        result = true
-      of ref, ptr, var, set, seq, openarray:
-        result = typeEqualsOrDistinct(a.baseType, b.baseType)
-      of range:
-        result = typeEqualsOrDistinct(a.baseType, b.baseType) and
-          (a.rangeA == b.rangeA) and (a.rangeB == b.rangeB)
-      of array:
-        result = typeEqualsOrDistinct(a.baseType, b.baseType) and
-                 typeEqualsOrDistinct(a.indexType, b.indexType)
-      of tuple:
-        if a.tupleLen == b.tupleLen:
-          for i in 0..a.tupleLen-1:
-            if not typeEqualsOrDistinct(a[i], b[i]): return false
-          result = true
-      of distinct:
-        result = typeEqualsOrDistinct(a.baseType, b.baseType)
-      of object, enum:
-        result = a == b
-      of proc:
-        result = typeEqualsOrDistinct(a.parameterTuple, b.parameterTuple) and
-                 typeEqualsOrDistinct(a.resultType, b.resultType) and
-                 a.callingConvention == b.callingConvention
-    elif a.kind == distinct:
-      result = typeEqualsOrDistinct(a.baseType, b)
-    elif b.kind == distinct:
-      result = typeEqualsOrDistinct(a, b.baseType)
-      
-
-Subtype relation
-----------------
-If object ``a`` inherits from ``b``, ``a`` is a subtype of ``b``. This subtype
-relation is extended to the types ``var``, ``ref``, ``ptr``:
-
-.. code-block:: nim
-  proc isSubtype(a, b: PType): bool =
-    if a.kind == b.kind:
-      case a.kind
-      of object:
-        var aa = a.baseType
-        while aa != nil and aa != b: aa = aa.baseType
-        result = aa == b
-      of var, ref, ptr:
-        result = isSubtype(a.baseType, b.baseType)
-
-.. XXX nil is a special value!
-
-
-Convertible relation
---------------------
-A type ``a`` is **implicitly** convertible to type ``b`` iff the following
-algorithm returns true:
-
-.. code-block:: nim
-  # XXX range types?
-  proc isImplicitlyConvertible(a, b: PType): bool =
-    case a.kind
-    of int:     result = b in {int8, int16, int32, int64, uint, uint8, uint16,
-                               uint32, uint64, float, float32, float64}
-    of int8:    result = b in {int16, int32, int64, int}
-    of int16:   result = b in {int32, int64, int}
-    of int32:   result = b in {int64, int}
-    of uint:    result = b in {uint32, uint64}
-    of uint8:   result = b in {uint16, uint32, uint64}
-    of uint16:  result = b in {uint32, uint64}
-    of uint32:  result = b in {uint64}
-    of float:   result = b in {float32, float64}
-    of float32: result = b in {float64, float}
-    of float64: result = b in {float32, float}
-    of seq:
-      result = b == openArray and typeEquals(a.baseType, b.baseType)
-    of array:
-      result = b == openArray and typeEquals(a.baseType, b.baseType)
-      if a.baseType == char and a.indexType.rangeA == 0:
-        result = b = cstring
-    of cstring, ptr:
-      result = b == pointer
-    of string:
-      result = b == cstring
-
-A type ``a`` is **explicitly** convertible to type ``b`` iff the following
-algorithm returns true:
- 
-.. code-block:: nim
-  proc isIntegralType(t: PType): bool =
-    result = isOrdinal(t) or t.kind in {float, float32, float64}
-
-  proc isExplicitlyConvertible(a, b: PType): bool =
-    result = false
-    if isImplicitlyConvertible(a, b): return true
-    if typeEqualsOrDistinct(a, b): return true
-    if isIntegralType(a) and isIntegralType(b): return true
-    if isSubtype(a, b) or isSubtype(b, a): return true
-    
-The convertible relation can be relaxed by a user-defined type 
-`converter`:idx:.
-
-.. code-block:: nim
-  converter toInt(x: char): int = result = ord(x)
-
-  var
-    x: int
-    chr: char = 'a'
-
-  # implicit conversion magic happens here
-  x = chr
-  echo x # => 97
-  # you can use the explicit form too
-  x = chr.toInt
-  echo x # => 97
-
-The type conversion ``T(a)`` is an L-value if ``a`` is an L-value and 
-``typeEqualsOrDistinct(T, type(a))`` holds.
-
-
-Assignment compatibility
-------------------------
-
-An expression ``b`` can be assigned to an expression ``a`` iff ``a`` is an
-`l-value` and ``isImplicitlyConvertible(b.typ, a.typ)`` holds.
-
-
-Overloading resolution
-----------------------
-
-To be written.
-
-
-Statements and expressions
-==========================
-
-Nim uses the common statement/expression paradigm: Statements do not
-produce a value in contrast to expressions. However, some expressions are 
-statements.
-
-Statements are separated into `simple statements`:idx: and
-`complex statements`:idx:.
-Simple statements are statements that cannot contain other statements like
-assignments, calls or the ``return`` statement; complex statements can
-contain other statements. To avoid the `dangling else problem`:idx:, complex
-statements always have to be intended. The details can be found in the grammar.
-
-
-Statement list expression
--------------------------
-
-Statements can also occur in an expression context that looks 
-like ``(stmt1; stmt2; ...; ex)``. This is called
-an statement list expression or ``(;)``. The type 
-of ``(stmt1; stmt2; ...; ex)`` is the type of ``ex``. All the other statements
-must be of type ``void``. (One can use ``discard`` to produce a ``void`` type.)
-``(;)`` does not introduce a new scope.
-
-
-Discard statement
------------------
-
-Example:
-
-.. code-block:: nim
-  proc p(x, y: int): int = 
-    result = x + y
-
-  discard p(3, 4) # discard the return value of `p`
-
-The ``discard`` statement evaluates its expression for side-effects and
-throws the expression's resulting value away. 
-
-Ignoring the return value of a procedure without using a discard statement is
-a static error.
-
-The return value can be ignored implicitly if the called proc/iterator has
-been declared with the `discardable`:idx: pragma: 
-
-.. code-block:: nim
-  proc p(x, y: int): int {.discardable.} = 
-    result = x + y
-    
-  p(3, 4) # now valid
-
-An empty ``discard`` statement is often used as a null statement:
-
-.. code-block:: nim
-  proc classify(s: string) =
-    case s[0]
-    of SymChars, '_': echo "an identifier"
-    of '0'..'9': echo "a number"
-    else: discard
-
-
-Var statement
--------------
-
-Var statements declare new local and global variables and
-initialize them. A comma separated list of variables can be used to specify
-variables of the same type:
-
-.. code-block:: nim
-
-  var
-    a: int = 0
-    x, y, z: int
-
-If an initializer is given the type can be omitted: the variable is then of the
-same type as the initializing expression. Variables are always initialized
-with a default value if there is no initializing expression. The default
-value depends on the type and is always a zero in binary.
-
-============================    ==============================================
-Type                            default value
-============================    ==============================================
-any integer type                0
-any float                       0.0
-char                            '\\0'
-bool                            false
-ref or pointer type             nil
-procedural type                 nil
-sequence                        nil (*not* ``@[]``)
-string                          nil (*not* "")
-tuple[x: A, y: B, ...]          (default(A), default(B), ...)
-                                (analogous for objects)
-array[0..., T]                  [default(T), ...]
-range[T]                        default(T); this may be out of the valid range
-T = enum                        cast[T](0); this may be an invalid value
-============================    ==============================================
-
-
-The implicit initialization can be avoided for optimization reasons with the
-`noinit`:idx: pragma: 
-
-.. code-block:: nim
-  var
-    a {.noInit.}: array [0..1023, char] 
-
-If a proc is annotated with the ``noinit`` pragma this refers to its implicit
-``result`` variable:
-
-.. code-block:: nim
-  proc returnUndefinedValue: int {.noinit.} = discard
-
-
-The implicit initialization can be also prevented by the `requiresInit`:idx:
-type pragma. The compiler requires an explicit initialization then. However
-it does a `control flow analysis`:idx: to prove the variable has been 
-initialized and does not rely on syntactic properties:
-
-.. code-block:: nim
-  type
-    TMyObject = object {.requiresInit.}
-    
-  proc p() =
-    # the following is valid:
-    var x: TMyObject
-    if someCondition():
-      x = a()
-    else:
-      x = a()
-    use x
-
-let statement
--------------
-
-A ``let`` statement declares new local and global `single assignment`:idx:
-variables and binds a value to them. The syntax is the of the ``var`` 
-statement, except that the keyword ``var`` is replaced by the keyword ``let``.
-Let variables are not l-values and can thus not be passed to ``var`` parameters
-nor can their address be taken. They cannot be assigned new values.
-
-For let variables the same pragmas are available as for ordinary variables.
-
-
-Const section
--------------
-
-`Constants`:idx: are symbols which are bound to a value. The constant's value
-cannot change. The compiler must be able to evaluate the expression in a
-constant declaration at compile time.
-
-Nim contains a sophisticated compile-time evaluator, so procedures which
-have no side-effect can be used in constant expressions too:
-
-.. code-block:: nim
-  import strutils
-  const
-    constEval = contains("abc", 'b') # computed at compile time!
-
-
-The rules for compile-time computability are: 
-
-1. Literals are compile-time computable.
-2. Type conversions are compile-time computable.
-3. Procedure calls of the form ``p(X)`` are compile-time computable if
-   ``p`` is a proc without side-effects (see the `noSideEffect pragma`_ 
-   for details) and if ``X`` is a (possibly empty) list of compile-time 
-   computable arguments.
-
-
-Constants cannot be of type ``ptr``, ``ref``, ``var`` or ``object``, nor can 
-they contain such a type.
-
-
-Static statement/expression
----------------------------
-
-A static statement/expression can be used to enforce compile 
-time evaluation explicitly. Enforced compile time evaluation can even evaluate
-code that has side effects: 
-
-.. code-block::
-
-  static:
-    echo "echo at compile time"
-
-It's a static error if the compiler cannot perform the evaluation at compile 
-time.
-
-The current implementation poses some restrictions for compile time
-evaluation: Code which contains ``cast`` or makes use of the foreign function
-interface cannot be evaluated at compile time. Later versions of Nim will
-support the FFI at compile time.
-
-
-If statement
-------------
-
-Example:
-
-.. code-block:: nim
-
-  var name = readLine(stdin)
-
-  if name == "Andreas":
-    echo("What a nice name!")
-  elif name == "":
-    echo("Don't you have a name?")
-  else:
-    echo("Boring name...")
-
-The ``if`` statement is a simple way to make a branch in the control flow:
-The expression after the keyword ``if`` is evaluated, if it is true
-the corresponding statements after the ``:`` are executed. Otherwise
-the expression after the ``elif`` is evaluated (if there is an
-``elif`` branch), if it is true the corresponding statements after
-the ``:`` are executed. This goes on until the last ``elif``. If all
-conditions fail, the ``else`` part is executed. If there is no ``else``
-part, execution continues with the statement after the ``if`` statement.
-
-The scoping for an ``if`` statement is slightly subtle to support an important 
-use case. A new scope starts for the ``if``/``elif`` condition and ends after
-the corresponding *then* block:
-
-.. code-block:: nim
-  if {| (let m = input =~ re"(\w+)=\w+"; m.isMatch):
-    echo "key ", m[0], " value ", m[1]  |}
-  elif {| (let m = input =~ re""; m.isMatch):
-    echo "new m in this scope" |}
-  else:
-    # 'm' not declared here
-
-In the example the scopes have been enclosed in ``{|  |}``. 
-
-
-Case statement
---------------
-
-Example:
-
-.. code-block:: nim
-
-  case readline(stdin)
-  of "delete-everything", "restart-computer":
-    echo("permission denied")
-  of "go-for-a-walk":     echo("please yourself")
-  else:                   echo("unknown command")
-  
-  # indentation of the branches is also allowed; and so is an optional colon
-  # after the selecting expression:
-  case readline(stdin):
-    of "delete-everything", "restart-computer":
-      echo("permission denied")
-    of "go-for-a-walk":     echo("please yourself")
-    else:                   echo("unknown command")
-  
-
-The ``case`` statement is similar to the if statement, but it represents
-a multi-branch selection. The expression after the keyword ``case`` is
-evaluated and if its value is in a *slicelist* the corresponding statements
-(after the ``of`` keyword) are executed. If the value is not in any
-given *slicelist* the ``else`` part is executed. If there is no ``else``
-part and not all possible values that ``expr`` can hold occur in a 
-``slicelist``, a static error occurs. This holds only for expressions of 
-ordinal types. "All possible values" of ``expr`` are determined by ``expr``'s
-type. 
-
-If the expression is not of an ordinal type, and no ``else`` part is
-given, control passes after the ``case`` statement.
-
-To suppress the static error in the ordinal case an ``else`` part with an
-empty ``discard`` statement can be used.
-
-As a special semantic extension, an expression in an ``of`` branch of a case
-statement may evaluate to a set or array constructor; the set or array is then
-expanded into a list of its elements:
-
-.. code-block:: nim
-  const
-    SymChars: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'}
-
-  proc classify(s: string) =
-    case s[0]
-    of SymChars, '_': echo "an identifier"
-    of '0'..'9': echo "a number"
-    else: echo "other"
-  
-  # is equivalent to:
-  proc classify(s: string) =
-    case s[0]
-    of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_': echo "an identifier"
-    of '0'..'9': echo "a number"
-    else: echo "other"
-
-
-When statement
---------------
-
-Example:
-
-.. code-block:: nim
-
-  when sizeof(int) == 2:
-    echo("running on a 16 bit system!")
-  elif sizeof(int) == 4:
-    echo("running on a 32 bit system!")
-  elif sizeof(int) == 8:
-    echo("running on a 64 bit system!")
-  else:
-    echo("cannot happen!")
-
-The ``when`` statement is almost identical to the ``if`` statement with some
-exceptions:
-
-* Each condition (``expr``) has to be a constant expression (of type ``bool``).
-* The statements do not open a new scope.
-* The statements that belong to the expression that evaluated to true are
-  translated by the compiler, the other statements are not checked for
-  semantics! However, each condition is checked for semantics.
-
-The ``when`` statement enables conditional compilation techniques. As
-a special syntactic extension, the ``when`` construct is also available
-within ``object`` definitions.
-
-
-Return statement
-----------------
-
-Example:
-
-.. code-block:: nim
-  return 40+2
-
-The ``return`` statement ends the execution of the current procedure.
-It is only allowed in procedures. If there is an ``expr``, this is syntactic
-sugar for:
-
-.. code-block:: nim
-  result = expr
-  return result
-
-
-``return`` without an expression is a short notation for ``return result`` if
-the proc has a return type. The `result`:idx: variable is always the return
-value of the procedure. It is automatically declared by the compiler. As all
-variables, ``result`` is initialized to (binary) zero:
-
-.. code-block:: nim
-  proc returnZero(): int =
-    # implicitly returns 0
-
-
-Yield statement
----------------
-
-Example:
-
-.. code-block:: nim
-  yield (1, 2, 3)
-
-The ``yield`` statement is used instead of the ``return`` statement in
-iterators. It is only valid in iterators. Execution is returned to the body
-of the for loop that called the iterator. Yield does not end the iteration
-process, but execution is passed back to the iterator if the next iteration
-starts. See the section about iterators (`Iterators and the for statement`_)
-for further information.
-
-
-Block statement
----------------
-
-Example:
-
-.. code-block:: nim
-  var found = false
-  block myblock:
-    for i in 0..3:
-      for j in 0..3:
-        if a[j][i] == 7:
-          found = true
-          break myblock # leave the block, in this case both for-loops
-  echo(found)
-
-The block statement is a means to group statements to a (named) ``block``.
-Inside the block, the ``break`` statement is allowed to leave the block
-immediately. A ``break`` statement can contain a name of a surrounding
-block to specify which block is to leave.
-
-
-Break statement
----------------
-
-Example:
-
-.. code-block:: nim
-  break
-
-The ``break`` statement is used to leave a block immediately. If ``symbol``
-is given, it is the name of the enclosing block that is to leave. If it is
-absent, the innermost block is left.
-
-
-While statement
----------------
-
-Example:
-
-.. code-block:: nim
-  echo("Please tell me your password: \n")
-  var pw = readLine(stdin)
-  while pw != "12345":
-    echo("Wrong password! Next try: \n")
-    pw = readLine(stdin)
-
-
-The ``while`` statement is executed until the ``expr`` evaluates to false.
-Endless loops are no error. ``while`` statements open an `implicit block`,
-so that they can be left with a ``break`` statement.
-
-
-Continue statement
-------------------
-
-A ``continue`` statement leads to the immediate next iteration of the
-surrounding loop construct. It is only allowed within a loop. A continue
-statement is syntactic sugar for a nested block:
-
-.. code-block:: nim
-  while expr1:
-    stmt1
-    continue
-    stmt2
-
-Is equivalent to:
-
-.. code-block:: nim
-  while expr1:
-    block myBlockName:
-      stmt1
-      break myBlockName
-      stmt2
-
-
-Assembler statement
--------------------
-
-The direct embedding of assembler code into Nim code is supported
-by the unsafe ``asm`` statement. Identifiers in the assembler code that refer to
-Nim identifiers shall be enclosed in a special character which can be
-specified in the statement's pragmas. The default special character is ``'`'``:
-
-.. code-block:: nim
-  {.push stackTrace:off.}
-  proc addInt(a, b: int): int =
-    # a in eax, and b in edx
-    asm """
-        mov eax, `a`
-        add eax, `b`
-        jno theEnd
-        call `raiseOverflow`
-      theEnd:
-    """
-  {.pop.}
-
-If the GNU assembler is used, quotes and newlines are inserted automatically:
-
-.. code-block:: nim
-  proc addInt(a, b: int): int =
-    asm """
-      addl %%ecx, %%eax
-      jno 1
-      call `raiseOverflow`
-      1:
-      :"=a"(`result`)
-      :"a"(`a`), "c"(`b`)
-    """
-
-Instead of:
-
-.. code-block:: nim
-  proc addInt(a, b: int): int =
-    asm """
-      "addl %%ecx, %%eax\n"
-      "jno 1\n"
-      "call `raiseOverflow`\n"
-      "1: \n"
-      :"=a"(`result`)
-      :"a"(`a`), "c"(`b`)
-    """
-
-Using statement
----------------
-
-**Warning**: The ``using`` statement is highly experimental!
-
-The using statement provides syntactic convenience for procs that
-heavily use a single contextual parameter. When applied to a variable or a
-constant, it will instruct Nim to automatically consider the used symbol as
-a hidden leading parameter for any procedure calls, following the using
-statement in the current scope. Thus, it behaves much like the hidden `this`
-parameter available in some object-oriented programming languages.
-
-.. code-block:: nim
-
-  var s = socket()
-  using s
-
-  connect(host, port)
-  send(data)
-
-  while true:
-    let line = readLine(timeout)
-    ...
-
-
-When applied to a callable symbol, it brings the designated symbol in the
-current scope. Thus, it can be used to disambiguate between imported symbols
-from different modules having the same name.
-
-.. code-block:: nim
-  import windows, sdl
-  using sdl.SetTimer
-
-Note that ``using`` only *adds* to the current context, it doesn't remove or
-replace, **neither** does it create a new scope. What this means is that if one
-applies this to multiple variables the compiler will find conflicts in what
-variable to use:
-
-.. code-block:: nim
-  var a, b = "kill it"
-  using a
-  add(" with fire")
-  using b
-  add(" with water")
-  echo a
-  echo b
-
-When the compiler reaches the second ``add`` call, both ``a`` and ``b`` could
-be used with the proc, so one gets ``Error: expression '(a|b)' has no type (or
-is ambiguous)``. To solve this one would need to nest ``using`` with a
-``block`` statement so as to control the reach of the ``using`` statement.
-
-If expression
--------------
-
-An `if expression` is almost like an if statement, but it is an expression.
-Example:
-
-.. code-block:: nim
-  var y = if x > 8: 9 else: 10
-
-An if expression always results in a value, so the ``else`` part is
-required. ``Elif`` parts are also allowed.
-
-When expression
----------------
-
-Just like an `if expression`, but corresponding to the when statement.
-
-Case expression
----------------
-
-The `case expression` is again very similar to the case statement:
-
-.. code-block:: nim
-  var favoriteFood = case animal
-    of "dog": "bones"
-    of "cat": "mice"
-    elif animal.endsWith"whale": "plankton"
-    else:
-      echo "I'm not sure what to serve, but everybody loves ice cream"
-      "ice cream"
-
-As seen in the above example, the case expression can also introduce side
-effects. When multiple statements are given for a branch, Nim will use
-the last expression as the result value, much like in an `expr` template.
-
-Table constructor
------------------
-
-A table constructor is syntactic sugar for an array constructor:
-
-.. code-block:: nim
-  {"key1": "value1", "key2", "key3": "value2"}
-  
-  # is the same as:
-  [("key1", "value1"), ("key2", "value2"), ("key3", "value2")]
-
-
-The empty table can be written ``{:}`` (in contrast to the empty set 
-which is ``{}``) which is thus another way to write as the empty array
-constructor ``[]``. This slightly unusal way of supporting tables 
-has lots of advantages:
-
-* The order of the (key,value)-pairs is preserved, thus it is easy to
-  support ordered dicts with for example ``{key: val}.newOrderedTable``.
-* A table literal can be put into a ``const`` section and the compiler
-  can easily put it into the executable's data section just like it can
-  for arrays and the generated data section requires a minimal amount
-  of memory.
-* Every table implementation is treated equal syntactically.
-* Apart from the minimal syntactic sugar the language core does not need to
-  know about tables.
-
-
-Type conversions
-----------------
-Syntactically a `type conversion` is like a procedure call, but a
-type name replaces the procedure name. A type conversion is always
-safe in the sense that a failure to convert a type to another
-results in an exception (if it cannot be determined statically).
-
-
-Type casts
-----------
-Example:
-
-.. code-block:: nim
-  cast[int](x)
-
-Type casts are a crude mechanism to interpret the bit pattern of
-an expression as if it would be of another type. Type casts are
-only needed for low-level programming and are inherently unsafe.
-
-
-The addr operator
------------------
-The ``addr`` operator returns the address of an l-value. If the type of the
-location is ``T``, the `addr` operator result is of the type ``ptr T``. An
-address is always an untraced reference. Taking the address of an object that
-resides on the stack is **unsafe**, as the pointer may live longer than the
-object on the stack and can thus reference a non-existing object. One can get
-the address of variables, but one can't use it on variables declared through
-``let`` statements:
-
-.. code-block:: nim
-
-  let t1 = "Hello"
-  var
-    t2 = t1
-    t3 : pointer = addr(t2)
-  echo repr(addr(t2))
-  # --> ref 0x7fff6b71b670 --> 0x10bb81050"Hello"
-  echo cast[ptr string](t3)[]
-  # --> Hello
-  # The following line doesn't compile:
-  echo repr(addr(t1))
-  # Error: expression has no address
-
-
-Procedures
-==========
-
-What most programming languages call `methods`:idx: or `functions`:idx: are
-called `procedures`:idx: in Nim (which is the correct terminology). A
-procedure declaration defines an identifier and associates it with a block
-of code. 
-A procedure may call itself recursively. A parameter may be given a default
-value that is used if the caller does not provide a value for this parameter.
-
-If the proc declaration has no body, it is a `forward`:idx: declaration. If
-the proc returns a value, the procedure body can access an implicitly declared
-variable named `result`:idx: that represents the return value. Procs can be
-overloaded. The overloading resolution algorithm tries to find the proc that is
-the best match for the arguments. Example:
-
-.. code-block:: nim
-
-  proc toLower(c: Char): Char = # toLower for characters
-    if c in {'A'..'Z'}:
-      result = chr(ord(c) + (ord('a') - ord('A')))
-    else:
-      result = c
-
-  proc toLower(s: string): string = # toLower for strings
-    result = newString(len(s))
-    for i in 0..len(s) - 1:
-      result[i] = toLower(s[i]) # calls toLower for characters; no recursion!
-
-Calling a procedure can be done in many different ways:
-
-.. code-block:: nim
-  proc callme(x, y: int, s: string = "", c: char, b: bool = false) = ...
-
-  # call with positional arguments # parameter bindings:
-  callme(0, 1, "abc", '\t', true)  # (x=0, y=1, s="abc", c='\t', b=true)
-  # call with named and positional arguments:
-  callme(y=1, x=0, "abd", '\t')    # (x=0, y=1, s="abd", c='\t', b=false)
-  # call with named arguments (order is not relevant):
-  callme(c='\t', y=1, x=0)         # (x=0, y=1, s="", c='\t', b=false)
-  # call as a command statement: no () needed:
-  callme 0, 1, "abc", '\t'
-
-
-A procedure cannot modify its parameters (unless the parameters have the type
-`var`).
-
-`Operators`:idx: are procedures with a special operator symbol as identifier:
-
-.. code-block:: nim
-  proc `$` (x: int): string =
-    # converts an integer to a string; this is a prefix operator.
-    result = intToStr(x)
-
-Operators with one parameter are prefix operators, operators with two
-parameters are infix operators. (However, the parser distinguishes these from
-the operator's position within an expression.) There is no way to declare
-postfix operators: all postfix operators are built-in and handled by the
-grammar explicitly.
-
-Any operator can be called like an ordinary proc with the '`opr`'
-notation. (Thus an operator can have more than two parameters):
-
-.. code-block:: nim
-  proc `*+` (a, b, c: int): int =
-    # Multiply and add
-    result = a * b + c
-
-  assert `*+`(3, 4, 6) == `*`(a, `+`(b, c))
-
-
-Method call syntax
-------------------
-
-For object oriented programming, the syntax ``obj.method(args)`` can be used 
-instead of ``method(obj, args)``. The parentheses can be omitted if there are no
-remaining arguments: ``obj.len`` (instead of ``len(obj)``).
-
-This method call syntax is not restricted to objects, it can be used
-to supply any type of first argument for procedures:
-
-.. code-block:: nim
-  
-  echo("abc".len) # is the same as echo(len("abc"))
-  echo("abc".toUpper())
-  echo({'a', 'b', 'c'}.card)
-  stdout.writeln("Hallo") # the same as writeln(stdout, "Hallo")
-
-Another way to look at the method call syntax is that it provides the missing
-postfix notation.
-
-
-Properties
-----------
-Nim has no need for *get-properties*: Ordinary get-procedures that are called
-with the *method call syntax* achieve the same. But setting a value is 
-different; for this a special setter syntax is needed:
-
-.. code-block:: nim
-  
-  type
-    TSocket* = object of TObject
-      FHost: int # cannot be accessed from the outside of the module
-                 # the `F` prefix is a convention to avoid clashes since
-                 # the accessors are named `host`
-
-  proc `host=`*(s: var TSocket, value: int) {.inline.} =
-    ## setter of hostAddr
-    s.FHost = value
-  
-  proc host*(s: TSocket): int {.inline.} =
-    ## getter of hostAddr
-    s.FHost
-
-  var
-    s: TSocket
-  s.host = 34  # same as `host=`(s, 34)
-
-
-Command invocation syntax
--------------------------
-
-Routines can be invoked without the ``()`` if the call is syntatically
-a statement. This command invocation syntax also works for
-expressions, but then only a single argument may follow. This restriction
-means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as
-``echo(f(1, f(2)))``. The method call syntax may be used to provide one
-more argument in this case:
-
-.. code-block:: nim
-  proc optarg(x:int, y:int = 0):int = x + y
-  proc singlearg(x:int):int = 20*x
-  
-  echo optarg 1, " ", singlearg 2  # prints "1 40"
-  
-  let fail = optarg 1, optarg 8   # Wrong. Too many arguments for a command call
-  let x = optarg(1, optarg 8)  # traditional procedure call with 2 arguments
-  let y = 1.optarg optarg 8    # same thing as above, w/o the parenthesis
-  assert x == y
-
-The command invocation syntax also can't have complex expressions as arguments. 
-For example: (`anonymous procs`_), ``if``, ``case`` or ``try``. The (`do 
-notation`_) is limited, but usable for a single proc (see the example in the 
-corresponding section). Function calls with no arguments still needs () to 
-distinguish between a call and the function itself as a first class value.
-
-
-Closures
---------
-
-Procedures can appear at the top level in a module as well as inside other
-scopes, in which case they are called nested procs. A nested proc can access
-local variables from its enclosing scope and if it does so it becomes a
-closure. Any captured variables are stored in a hidden additional argument
-to the closure (its environment) and they are accessed by reference by both
-the closure and its enclosing scope (i.e. any modifications made to them are
-visible in both places). The closure environment may be allocated on the heap
-or on the stack if the compiler determines that this would be safe.
-
-
-Anonymous Procs
----------------
-
-Procs can also be treated as expressions, in which case it's allowed to omit
-the proc's name.
-
-.. code-block:: nim
-  var cities = @["Frankfurt", "Tokyo", "New York"]
-
-  cities.sort(proc (x,y: string): int =
-      cmp(x.len, y.len))
-
-
-Procs as expressions can appear both as nested procs and inside top level 
-executable code.
-
-
-Do notation
------------
-
-As a special more convenient notation, proc expressions involved in procedure
-calls can use the ``do`` keyword:
-
-.. code-block:: nim
-  sort(cities) do (x,y: string) -> int:
-    cmp(x.len, y.len)
-  # Less parenthesis using the method plus command syntax:
-  cities = cities.map do (x:string) -> string:  
-    "City of " & x
-
-``do`` is written after the parentheses enclosing the regular proc params. 
-The proc expression represented by the do block is appended to them.
-
-More than one ``do`` block can appear in a single call:
-
-.. code-block:: nim
-  proc performWithUndo(task: proc(), undo: proc()) = ...
-
-  performWithUndo do:
-    # multiple-line block of code
-    # to perform the task
-  do:
-    # code to undo it
-
-For compatibility with ``stmt`` templates and macros, the ``do`` keyword can be
-omitted if the supplied proc doesn't have any parameters and return value. 
-The compatibility works in the other direction too as the ``do`` syntax can be
-used with macros and templates expecting ``stmt`` blocks.
-
-
-Nonoverloadable builtins
-------------------------
-
-The following builtin procs cannot be overloaded for reasons of implementation
-simplicity (they require specialized semantic checking)::
-
-  defined, definedInScope, compiles, low, high, sizeOf, 
-  is, of, echo, shallowCopy, getAst, spawn
-
-Thus they act more like keywords than like ordinary identifiers; unlike a 
-keyword however, a redefinition may `shadow`:idx: the definition in 
-the ``system`` module.
-
-
-Var parameters
---------------
-The type of a parameter may be prefixed with the ``var`` keyword:
-
-.. code-block:: nim
-  proc divmod(a, b: int; res, remainder: var int) =
-    res = a div b
-    remainder = a mod b
-
-  var
-    x, y: int
-
-  divmod(8, 5, x, y) # modifies x and y
-  assert x == 1
-  assert y == 3
-
-In the example, ``res`` and ``remainder`` are `var parameters`.
-Var parameters can be modified by the procedure and the changes are
-visible to the caller. The argument passed to a var parameter has to be
-an l-value. Var parameters are implemented as hidden pointers. The
-above example is equivalent to:
-
-.. code-block:: nim
-  proc divmod(a, b: int; res, remainder: ptr int) =
-    res[] = a div b
-    remainder[] = a mod b
-
-  var
-    x, y: int
-  divmod(8, 5, addr(x), addr(y))
-  assert x == 1
-  assert y == 3
-
-In the examples, var parameters or pointers are used to provide two
-return values. This can be done in a cleaner way by returning a tuple:
-
-.. code-block:: nim
-  proc divmod(a, b: int): tuple[res, remainder: int] =
-    (a div b, a mod b)
-
-  var t = divmod(8, 5)
-
-  assert t.res == 1
-  assert t.remainder == 3
-
-One can use `tuple unpacking`:idx: to access the tuple's fields:
-
-.. code-block:: nim
-  var (x, y) = divmod(8, 5) # tuple unpacking
-  assert x == 1
-  assert y == 3
-
-
-Var return type
----------------
-
-A proc, converter or iterator may return a ``var`` type which means that the
-returned value is an l-value and can be modified by the caller:
-
-.. code-block:: nim
-  var g = 0
-
-  proc WriteAccessToG(): var int =
-    result = g
-  
-  WriteAccessToG() = 6
-  assert g == 6
-
-It is a compile time error if the implicitly introduced pointer could be 
-used to access a location beyond its lifetime:
-
-.. code-block:: nim
-  proc WriteAccessToG(): var int =
-    var g = 0
-    result = g # Error!
-
-For iterators, a component of a tuple return type can have a ``var`` type too: 
-
-.. code-block:: nim
-  iterator mpairs(a: var seq[string]): tuple[key: int, val: var string] =
-    for i in 0..a.high:
-      yield (i, a[i])
-
-In the standard library every name of a routine that returns a ``var`` type
-starts with the prefix ``m`` per convention.
-
-
-Overloading of the subscript operator
--------------------------------------
-
-The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
-
-
-Multi-methods
-=============
-
-Procedures always use static dispatch. Multi-methods use dynamic
-dispatch.
-
-.. code-block:: nim
-  type
-    TExpr = object ## abstract base class for an expression
-    TLiteral = object of TExpr
-      x: int
-    TPlusExpr = object of TExpr
-      a, b: ref TExpr
-      
-  method eval(e: ref TExpr): int =
-    # override this base method
-    quit "to override!"
-  
-  method eval(e: ref TLiteral): int = return e.x
-
-  method eval(e: ref TPlusExpr): int =
-    # watch out: relies on dynamic binding
-    result = eval(e.a) + eval(e.b)
-  
-  proc newLit(x: int): ref TLiteral =
-    new(result)
-    result.x = x
-    
-  proc newPlus(a, b: ref TExpr): ref TPlusExpr =
-    new(result)
-    result.a = a
-    result.b = b
-  
-  echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
-  
-In the example the constructors ``newLit`` and ``newPlus`` are procs
-because they should use static binding, but ``eval`` is a method because it
-requires dynamic binding.
-
-In a multi-method all parameters that have an object type are used for the
-dispatching:
-
-.. code-block:: nim
-  type
-    TThing = object
-    TUnit = object of TThing
-      x: int
-      
-  method collide(a, b: TThing) {.inline.} =
-    quit "to override!"
-    
-  method collide(a: TThing, b: TUnit) {.inline.} =
-    echo "1"
-  
-  method collide(a: TUnit, b: TThing) {.inline.} =
-    echo "2"
-  
-  var
-    a, b: TUnit
-  collide(a, b) # output: 2
-
-
-Invocation of a multi-method cannot be ambiguous: collide 2 is preferred over 
-collide 1 because the resolution works from left to right. 
-In the example ``TUnit, TThing`` is preferred over ``TThing, TUnit``.
-
-**Performance note**: Nim does not produce a virtual method table, but
-generates dispatch trees. This avoids the expensive indirect branch for method
-calls and enables inlining. However, other optimizations like compile time
-evaluation or dead code elimination do not work with methods.
-
-
-Iterators and the for statement
-===============================
-
-The `for`:idx: statement is an abstract mechanism to iterate over the elements
-of a container. It relies on an `iterator`:idx: to do so. Like ``while``
-statements, ``for`` statements open an `implicit block`:idx:, so that they
-can be left with a ``break`` statement. 
-
-The ``for`` loop declares iteration variables - their scope reaches until the
-end of the loop body. The iteration variables' types are inferred by the
-return type of the iterator.
-
-An iterator is similar to a procedure, except that it can be called in the
-context of a ``for`` loop. Iterators provide a way to specify the iteration over
-an abstract type. A key role in the execution of a ``for`` loop plays the
-``yield`` statement in the called iterator. Whenever a ``yield`` statement is
-reached the data is bound to the ``for`` loop variables and control continues
-in the body of the ``for`` loop. The iterator's local variables and execution
-state are automatically saved between calls. Example:
-
-.. code-block:: nim
-  # this definition exists in the system module
-  iterator items*(a: string): char {.inline.} =
-    var i = 0
-    while i < len(a):
-      yield a[i]
-      inc(i)
-
-  for ch in items("hello world"): # `ch` is an iteration variable
-    echo(ch)
-
-The compiler generates code as if the programmer would have written this:
-
-.. code-block:: nim
-  var i = 0
-  while i < len(a):
-    var ch = a[i]
-    echo(ch)
-    inc(i)
-
-If the iterator yields a tuple, there can be as many iteration variables
-as there are components in the tuple. The i'th iteration variable's type is
-the type of the i'th component. In other words, implicit tuple unpacking in a 
-for loop context is supported.
-
-Implict items/pairs invocations
--------------------------------
-
-If the for loop expression ``e`` does not denote an iterator and the for loop
-has exactly 1 variable, the for loop expression is rewritten to ``items(e)``;
-ie. an ``items`` iterator is implicitly invoked:
-
-.. code-block:: nim
-  for x in [1,2,3]: echo x
-  
-If the for loop has exactly 2 variables, a ``pairs`` iterator is implicitly
-invoked.
-
-Symbol lookup of the identifiers ``items``/``pairs`` is performed after 
-the rewriting step, so that all overloadings of ``items``/``pairs`` are taken
-into account.
-
-
-First class iterators
----------------------
-
-There are 2 kinds of iterators in Nim: *inline* and *closure* iterators.
-An `inline iterator`:idx: is an iterator that's always inlined by the compiler 
-leading to zero overhead for the abstraction, but may result in a heavy
-increase in code size. Inline iterators are second class citizens;
-They can be passed as parameters only to other inlining code facilities like
-templates, macros and other inline iterators.
-
-In contrast to that, a `closure iterator`:idx: can be passed around more freely:
-
-.. code-block:: nim
-  iterator count0(): int {.closure.} =
-    yield 0
-   
-  iterator count2(): int {.closure.} =
-    var x = 1
-    yield x
-    inc x
-    yield x
-
-  proc invoke(iter: iterator(): int {.closure.}) =
-    for x in iter(): echo x
-
-  invoke(count0)
-  invoke(count2)
-
-Closure iterators have other restrictions than inline iterators:
-
-1. ``yield`` in a closure iterator can not occur in a ``try`` statement.
-2. For now, a closure iterator cannot be evaluated at compile time.
-3. ``return`` is allowed in a closure iterator (but rarely useful).
-4. Both inline and closure iterators cannot be recursive.
-
-Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly
-default to being inline, but that this may change in future versions of the
-implementation.
-
-The ``iterator`` type is always of the calling convention ``closure`` 
-implicitly; the following example shows how to use iterators to implement
-a `collaborative tasking`:idx: system:
-
-.. code-block:: nim
-  # simple tasking:
-  type
-    TTask = iterator (ticker: int)
-
-  iterator a1(ticker: int) {.closure.} =
-    echo "a1: A"
-    yield
-    echo "a1: B"
-    yield
-    echo "a1: C"
-    yield
-    echo "a1: D"
-
-  iterator a2(ticker: int) {.closure.} =
-    echo "a2: A"
-    yield
-    echo "a2: B"
-    yield
-    echo "a2: C"
-
-  proc runTasks(t: varargs[TTask]) =
-    var ticker = 0
-    while true:
-      let x = t[ticker mod t.len]
-      if finished(x): break
-      x(ticker)
-      inc ticker
-
-  runTasks(a1, a2)
-
-The builtin ``system.finished`` can be used to determine if an iterator has
-finished its operation; no exception is raised on an attempt to invoke an
-iterator that has already finished its work.
-
-Closure iterators are *resumable functions* and so one has to provide the
-arguments to every call. To get around this limitation one can capture
-parameters of an outer factory proc:
-
-.. code-block:: nim
-  proc mycount(a, b: int): iterator (): int =
-    result = iterator (): int =
-      var x = a
-      while x <= b:
-        yield x
-        inc x
-
-  let foo = mycount(1, 4)
-
-  for f in foo():
-    echo f
-
-Implicit return type
---------------------
-
-Since inline interators must always produce values that will be consumed in
-a for loop, the compiler will implicity use the ``auto`` return type if no
-type is given by the user. In contrast, since closure iterators can be used
-as a collaborative tasking system, ``void`` is a valid return type for them.
-
-
-Type sections
-=============
-
-Example:
-
-.. code-block:: nim
-  type # example demonstrating mutually recursive types
-    PNode = ref TNode # a traced pointer to a TNode
-    TNode = object
-      le, ri: PNode   # left and right subtrees
-      sym: ref TSym   # leaves contain a reference to a TSym
-
-    TSym = object     # a symbol
-      name: string    # the symbol's name
-      line: int       # the line the symbol was declared in
-      code: PNode     # the symbol's abstract syntax tree
-
-A type section begins with the ``type`` keyword. It contains multiple
-type definitions. A type definition binds a type to a name. Type definitions
-can be recursive or even mutually recursive. Mutually recursive types are only
-possible within a single ``type`` section. Nominal types like ``objects`` 
-or ``enums`` can only be defined in a ``type`` section.
-
-
-Exception handling
-==================
-
-Try statement
--------------
-
-Example:
-
-.. code-block:: nim
-  # read the first two lines of a text file that should contain numbers
-  # and tries to add them
-  var
-    f: TFile
-  if open(f, "numbers.txt"):
-    try:
-      var a = readLine(f)
-      var b = readLine(f)
-      echo("sum: " & $(parseInt(a) + parseInt(b)))
-    except EOverflow:
-      echo("overflow!")
-    except EInvalidValue:
-      echo("could not convert string to integer")
-    except EIO:
-      echo("IO error!")
-    except:
-      echo("Unknown exception!")
-    finally:
-      close(f)
-
-
-The statements after the ``try`` are executed in sequential order unless
-an exception ``e`` is raised. If the exception type of ``e`` matches any
-listed in an ``except`` clause the corresponding statements are executed.
-The statements following the ``except`` clauses are called
-`exception handlers`:idx:.
-
-The empty `except`:idx: clause is executed if there is an exception that is
-not listed otherwise. It is similar to an ``else`` clause in ``if`` statements.
-
-If there is a `finally`:idx: clause, it is always executed after the
-exception handlers.
-
-The exception is *consumed* in an exception handler. However, an
-exception handler may raise another exception. If the exception is not
-handled, it is propagated through the call stack. This means that often
-the rest of the procedure - that is not within a ``finally`` clause -
-is not executed (if an exception occurs).
-
-
-Except and finally statements
------------------------------
-
-``except`` and ``finally`` can also be used as a stand-alone statements.
-Any statements following them in the current block will be considered to be 
-in an implicit try block:
-
-.. code-block:: nim
-  var f = open("numbers.txt")
-  finally: close(f)
-  ...
-
-The ``except`` statement has a limitation in this form: one can't specify the
-type of the exception, one has to catch everything. Also, if one wants to use
-both ``finally`` and ``except`` one needs to reverse the usual sequence of the
-statements. Example:
-
-.. code-block:: nim
-  proc test() =
-    raise newException(E_base, "Hey ho")
-  
-  proc tester() =
-    finally: echo "3. Finally block"
-    except: echo "2. Except block"
-    echo "1. Pre exception"
-    test()
-    echo "4. Post exception"
-  # --> 1, 2, 3 is printed, 4 is never reached
-
-
-Raise statement
----------------
-
-Example:
-
-.. code-block:: nim
-  raise newEOS("operating system failed")
-
-Apart from built-in operations like array indexing, memory allocation, etc.
-the ``raise`` statement is the only way to raise an exception.
-
-.. XXX document this better!
-
-If no exception name is given, the current exception is `re-raised`:idx:. The
-`ENoExceptionToReraise`:idx: exception is raised if there is no exception to
-re-raise. It follows that the ``raise`` statement *always* raises an
-exception (unless a raise hook has been provided).
-
-
-OnRaise builtin
----------------
-
-`system.onRaise() `_ can be used to override the
-behaviour of ``raise`` for a single ``try`` statement. ``onRaise`` has to be
-called within the ``try`` statement that should be affected.
-
-This allows for a Lisp-like `condition system`:idx:\:
-
-.. code-block:: nim
-  var myFile = open("broken.txt", fmWrite)
-  try:
-    onRaise do (e: ref E_Base)-> bool:
-      if e of EIO:
-        stdout.writeln "ok, writing to stdout instead"
-      else:
-        # do raise other exceptions:
-        result = true
-    myFile.writeln "writing to broken file"
-  finally:
-    myFile.close()
-
-``OnRaise`` can only *filter* raised exceptions, it cannot transform one
-exception into another. (Nor should ``onRaise`` raise an exception though 
-this is currently not enforced.) This restriction keeps the exception tracking
-analysis sound.
-
-
-Effect system
-=============
-
-Exception tracking
-------------------
-
-Nim supports exception tracking. The `raises`:idx: pragma can be used
-to explicitly define which exceptions a proc/iterator/method/converter is 
-allowed to raise. The compiler verifies this:
-
-.. code-block:: nim
-  proc p(what: bool) {.raises: [EIO, EOS].} =
-    if what: raise newException(EIO, "IO")
-    else: raise newException(EOS, "OS")
-
-An empty ``raises`` list (``raises: []``) means that no exception may be raised:
-
-.. code-block:: nim
-  proc p(): bool {.raises: [].} =
-    try:
-      unsafeCall()
-      result = true
-    except:
-      result = false
-
-
-A ``raises`` list can also be attached to a proc type. This affects type 
-compatibility:
-
-.. code-block:: nim
-  type
-    TCallback = proc (s: string) {.raises: [EIO].}
-  var
-    c: TCallback
-
-  proc p(x: string) =
-    raise newException(EOS, "OS")
-  
-  c = p # type error
-
-
-For a routine ``p`` the compiler uses inference rules to determine the set of
-possibly raised exceptions; the algorithm operates on ``p``'s call graph:
-
-1. Every indirect call via some proc type ``T`` is assumed to
-   raise ``system.E_Base`` (the base type of the exception hierarchy) and
-   thus any exception unless ``T`` has an explicit ``raises`` list.
-   However if the call is of the form ``f(...)`` where ``f`` is a parameter
-   of the currently analysed routine it is ignored. The call is optimistically 
-   assumed to have no effect. Rule 2 compensates for this case.
-2. Every expression of some proc type wihtin a call that is not a call 
-   itself (and not nil) is assumed to be called indirectly somehow and thus 
-   its raises list is added to ``p``'s raises list.
-3. Every call to a proc ``q`` which has an unknown body (due to a forward 
-   declaration or an ``importc`` pragma) is assumed to 
-   raise ``system.E_Base`` unless ``q`` has an explicit ``raises`` list.
-4. Every call to a method ``m`` is assumed to 
-   raise ``system.E_Base`` unless ``m`` has an explicit ``raises`` list.
-5. For every other call the analysis can determine an exact ``raises`` list.
-6. For determining a ``raises`` list, the ``raise`` and ``try`` statements 
-   of ``p`` are taken into consideration.
-
-Rules 1-2 ensure the following works: 
-
-.. code-block:: nim
-  proc noRaise(x: proc()) {.raises: [].} =
-    # unknown call that might raise anything, but valid:
-    x()
-    
-  proc doRaise() {.raises: [EIO].} =
-    raise newException(EIO, "IO")
-  
-  proc use() {.raises: [].} =
-    # doesn't compile! Can raise EIO!
-    noRaise(doRaise)
-
-So in many cases a callback does not cause the compiler to be overly
-conservative in its effect analysis.
-
-
-Tag tracking
-------------
-
-The exception tracking is part of Nim's `effect system`:idx:. Raising an
-exception is an *effect*. Other effects can also be defined. A user defined 
-effect is a means to *tag* a routine and to perform checks against this tag:
-
-.. code-block:: nim
-  type IO = object ## input/output effect
-  proc readLine(): string {.tags: [IO].}
-  
-  proc no_IO_please() {.tags: [].} =
-    # the compiler prevents this:
-    let x = readLine()
-
-A tag has to be a type name. A ``tags`` list - like a ``raises`` list - can 
-also be attached to a proc type. This affects type compatibility.
-
-The inference for tag tracking is analogous to the inference for 
-exception tracking.
-
-
-Read/Write tracking
--------------------
-
-**Note**: Read/write tracking is not yet implemented!
-
-The inference for read/write tracking is analogous to the inference for 
-exception tracking.
-
-
-Effects pragma
---------------
-
-The ``effects`` pragma has been designed to assist the programmer with the
-effects analysis. It is a statement that makes the compiler output all inferred
-effects up to the ``effects``'s position:
-
-.. code-block:: nim
-  proc p(what: bool) =
-    if what:
-      raise newException(EIO, "IO")
-      {.effects.}
-    else:
-      raise newException(EOS, "OS")
-
-The compiler produces a hint message that ``EIO`` can be raised. ``EOS`` is not
-listed as it cannot be raised in the branch the ``effects`` pragma appears in.
-
-
-Generics
-========
-
-Example:
-
-.. code-block:: nim
-  type
-    TBinaryTree[T] = object      # TBinaryTree is a generic type with
-                                 # with generic param ``T``
-      le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil
-      data: T                    # the data stored in a node
-    PBinaryTree[T] = ref TBinaryTree[T] # a shorthand for notational convenience
-
-  proc newNode[T](data: T): PBinaryTree[T] = # constructor for a node
-    new(result)
-    result.data = data
-
-  proc add[T](root: var PBinaryTree[T], n: PBinaryTree[T]) =
-    if root == nil:
-      root = n
-    else:
-      var it = root
-      while it != nil:
-        var c = cmp(it.data, n.data) # compare the data items; uses
-                                     # the generic ``cmp`` proc that works for
-                                     # any type that has a ``==`` and ``<``
-                                     # operator
-        if c < 0:
-          if it.le == nil:
-            it.le = n
-            return
-          it = it.le
-        else:
-          if it.ri == nil:
-            it.ri = n
-            return
-          it = it.ri
-
-  iterator inorder[T](root: PBinaryTree[T]): T =
-    # inorder traversal of a binary tree
-    # recursive iterators are not yet implemented, so this does not work in
-    # the current compiler!
-    if root.le != nil: yield inorder(root.le)
-    yield root.data
-    if root.ri != nil: yield inorder(root.ri)
-
-  var
-    root: PBinaryTree[string] # instantiate a PBinaryTree with the type string
-  add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and
-  add(root, newNode("world")) # ``add``
-  for str in inorder(root):
-    writeln(stdout, str)
-
-Generics are Nim's means to parametrize procs, iterators or types with
-`type parameters`:idx:. Depending on context, the brackets are used either to
-introduce type parameters or to instantiate a generic proc, iterator or type.
-
-
-Is operator
------------
-
-The ``is`` operator checks for type equivalence at compile time. It is
-therefore very useful for type specialization within generic code: 
-
-.. code-block:: nim
-  type
-    TTable[TKey, TValue] = object
-      keys: seq[TKey]
-      values: seq[TValue]
-      when not (TKey is string): # nil value for strings used for optimization
-        deletedKeys: seq[bool]
-
-
-Type operator
--------------
-
-The ``type`` (in many other languages called `typeof`:idx:) operator can
-be used to get the type of an expression: 
-
-.. code-block:: nim
-  var x = 0
-  var y: type(x) # y has type int
-
-If ``type`` is used to determine the result type of a proc/iterator/converter
-call ``c(X)`` (where ``X`` stands for a possibly empty list of arguments), the
-interpretation where ``c`` is an iterator is preferred over the
-other interpretations:
-
-.. code-block:: nim
-  import strutils
-  
-  # strutils contains both a ``split`` proc and iterator, but since an
-  # an iterator is the preferred interpretation, `y` has the type ``string``:
-  var y: type("a b c".split)
-
-
-Type Classes
-------------
-
-A type class is a special pseudo-type that can be used to match against
-types in the context of overload resolution or the ``is`` operator. 
-Nim supports the following built-in type classes:
-
-==================   ===================================================
-type class           matches
-==================   ===================================================
-``object``           any object type
-``tuple``            any tuple type
-
-``enum``             any enumeration
-``proc``             any proc type
-``ref``              any ``ref`` type
-``ptr``              any ``ptr`` type
-``var``              any ``var`` type
-``distinct``         any distinct type
-``array``            any array type
-``set``              any set type
-``seq``              any seq type
-``auto``             any type 
-==================   ===================================================
-
-Furthermore, every generic type automatically creates a type class of the same
-name that will match any instantiation of the generic type.
-
-Type classes can be combined using the standard boolean operators to form
-more complex type classes:
-
-.. code-block:: nim
-  # create a type class that will match all tuple and object types
-  type TRecordType = tuple or object
-
-  proc printFields(rec: TRecordType) =
-    for key, value in fieldPairs(rec):
-      echo key, " = ", value
-
-Procedures utilizing type classes in such manner are considered to be
-`implicitly generic`:idx:. They will be instantiated once for each unique 
-combination of param types used within the program.
-
-Nim also allows for type classes and regular types to be specified
-as `type constraints`:idx: of the generic type parameter:
-
-.. code-block:: nim
-  proc onlyIntOrString[T: int|string](x, y: T) = discard
-  
-  onlyIntOrString(450, 616) # valid
-  onlyIntOrString(5.0, 0.0) # type mismatch
-  onlyIntOrString("xy", 50) # invalid as 'T' cannot be both at the same time
-
-By default, during overload resolution each named type class will bind to
-exactly one concrete type. Here is an example taken directly from the system
-module to illustrate this:
-
-.. code-block:: nim
-  proc `==`*(x, y: tuple): bool = 
-    ## requires `x` and `y` to be of the same tuple type
-    ## generic ``==`` operator for tuples that is lifted from the components
-    ## of `x` and `y`.
-    result = true
-    for a, b in fields(x, y):
-      if a != b: result = false
-
-Alternatively, the ``distinct`` type modifier can be applied to the type class 
-to allow each param matching the type class to bind to a different type. 
-
-If a proc param doesn't have a type specified, Nim will use the
-``distinct auto`` type class (also known as ``any``):
-
-.. code-block:: nim
-  # allow any combination of param types
-  proc concat(a, b): string = $a & $b
-
-Procs written with the implicitly generic style will often need to refer to the
-type parameters of the matched generic type. They can be easily accessed using
-the dot syntax:
-
-.. code-block:: nim
-  type TMatrix[T, Rows, Columns] = object
-    ...
-
-  proc `[]`(m: TMatrix, row, col: int): TMatrix.T = 
-    m.data[col * high(TMatrix.Columns) + row]
-
-Alternatively, the `type` operator can be used over the proc params for similar
-effect when anonymous or distinct type classes are used.
-
-When a generic type is instantiated with a type class instead of a concrete
-type, this results in another more specific type class:
-
-.. code-block:: nim
-  seq[ref object]  # Any sequence storing references to any object type
-  
-  type T1 = auto
-  proc foo(s: seq[T1], e: T1)
-    # seq[T1] is the same as just `seq`, but T1 will be allowed to bind
-    # to a single type, while the signature is being matched
-
-  TMatrix[Ordinal] # Any TMatrix instantiation using integer values
-
-As seen in the previous example, in such instantiations, it's not necessary to
-supply all type parameters of the generic type, because any missing ones will
-be inferred to have the equivalent of the `any` type class and thus they will
-match anything without discrimination.
-
-
-User defined type classes
--------------------------
-
-**Note**: User defined type classes are still in development.
-
-The user-defined type classes are available in two flavours - declarative and
-imperative. Both are used to specify an arbitrary set of requirements that the
-matched type must satisfy.
-
-Declarative type classes are written in the following form:
-
-.. code-block:: nim
-  type
-    Comparable = generic x, y
-      (x < y) is bool
-
-    Container[T] = generic c
-      c.len is ordinal
-      items(c) is iterator
-      for value in c:
-        type(value) is T
-
-The type class will be matched if:
-
-a) all of the expressions within the body can be compiled for the tested type
-b) all statically evaluatable boolean expressions in the body must be true
-
-The identifiers following the `generic` keyword represent instances of the
-currently matched type. These instances can act both as variables of the type,
-when used in contexts where a value is expected, and as the type itself when
-used in contexts where a type is expected.
-
-Please note that the ``is`` operator allows one to easily verify the precise
-type signatures of the required operations, but since type inference and
-default parameters are still applied in the provided block, it's also possible
-to encode usage protocols that do not reveal implementation details.
-
-As a special rule providing further convenience when writing type classes, any
-type value appearing in a callable expression will be treated as a variable of
-the designated type for overload resolution purposes, unless the type value was
-passed in its explicit ``typedesc[T]`` form:
-
-.. code-block:: nim
-  type
-    OutputStream = generic S
-      write(var S, string)
-
-Much like generics, the user defined type classes will be instantiated exactly
-once for each tested type and any static code included within them will also be
-executed once.
-
-
-Type inference with type classes
---------------------------------
-
-If a type class is used as the return type of a proc and it won't be bound to
-a concrete type by some of the proc params, Nim will infer the return type
-from the proc body. This is usually used with the ``auto`` type class:
-
-.. code-block:: nim
-  proc makePair(a, b): auto = (first: a, second: b)
-
-The return type will be treated as an additional generic param and can be
-explicitly specified at call sites as any other generic param.
-
-Future versions of Nim may also support overloading based on the return type
-of the overloads. In such settings, the expected result type at call sites may 
-also influence the inferred return type.
-
-..
-  Likewise, if a type class is used in another position where Nim expects a
-  concrete type (e.g. a variable declaration or a type coercion), Nim will try
-  to infer the concrete type by applying the matching algorithm that also used
-  in overload resolution.
-
-
-Symbol lookup in generics
--------------------------
-
-The symbol binding rules in generics are slightly subtle: There are "open" and
-"closed" symbols. A "closed" symbol cannot be re-bound in the instantiation
-context, an "open" symbol can. Per default overloaded symbols are open
-and every other symbol is closed.
-
-Open symbols are looked up in two different contexts: Both the context
-at definition and the context at instantiation are considered:
-
-.. code-block:: nim
-  type
-    TIndex = distinct int
-  
-  proc `==` (a, b: TIndex): bool {.borrow.}
-  
-  var a = (0, 0.TIndex)
-  var b = (0, 0.TIndex)
-  
-  echo a == b # works!
-
-In the example the generic ``==`` for tuples (as defined in the system module)
-uses the ``==`` operators of the tuple's components. However, the ``==`` for
-the ``TIndex`` type is defined *after* the ``==`` for tuples; yet the example
-compiles as the instantiation takes the currently defined symbols into account
-too.
-
-A symbol can be forced to be open by a `mixin`:idx: declaration: 
-
-.. code-block:: nim
-  proc create*[T](): ref T =
-    # there is no overloaded 'init' here, so we need to state that it's an
-    # open symbol explicitly:
-    mixin init
-    new result
-    init result
-
-
-Bind statement
---------------
-
-The ``bind`` statement is the counterpart to the ``mixin`` statement. It 
-can be used to explicitly declare identifiers that should be bound early (i.e.
-the identifiers should be looked up in the scope of the template/generic
-definition):
-
-.. code-block:: nim
-  # Module A
-  var 
-    lastId = 0
-  
-  template genId*: expr =
-    bind lastId
-    inc(lastId)
-    lastId
-
-.. code-block:: nim
-  # Module B
-  import A
-  
-  echo genId()
-
-But a ``bind`` is rarely useful because symbol binding from the definition
-scope is the default.
-
-
-Templates
-=========
-
-A template is a simple form of a macro: It is a simple substitution
-mechanism that operates on Nim's abstract syntax trees. It is processed in
-the semantic pass of the compiler.
-
-The syntax to *invoke* a template is the same as calling a procedure.
-
-Example:
-
-.. code-block:: nim
-  template `!=` (a, b: expr): expr =
-    # this definition exists in the System module
-    not (a == b)
-
-  assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))
-
-The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact 
-templates:
-
-| ``a > b`` is transformed into ``b < a``.
-| ``a in b`` is transformed into ``contains(b, a)``. 
-| ``notin`` and ``isnot`` have the obvious meanings.
-
-The "types" of templates can be the symbols ``expr`` (stands for *expression*), 
-``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type 
-description*). These are "meta types", they can only be used in certain 
-contexts. Real types can be used too; this implies that expressions are 
-expected.
-
-
-Ordinary vs immediate templates
--------------------------------
-
-There are two different kinds of templates: immediate templates and
-ordinary templates. Ordinary templates take part in overloading resolution. As
-such their arguments need to be type checked before the template is invoked.
-So ordinary templates cannot receive undeclared identifiers:
-
-.. code-block:: nim
-
-  template declareInt(x: expr) = 
-    var x: int
-
-  declareInt(x) # error: unknown identifier: 'x'
-
-An ``immediate`` template does not participate in overload resolution and so
-its arguments are not checked for semantics before invocation. So they can
-receive undeclared identifiers:
-
-.. code-block:: nim
-
-  template declareInt(x: expr) {.immediate.} = 
-    var x: int
-
-  declareInt(x) # valid
-
-
-Passing a code block to a template
-----------------------------------
-
-If there is a ``stmt`` parameter it should be the last in the template
-declaration, because statements are passed to a template via a
-special ``:`` syntax:
-
-.. code-block:: nim
-
-  template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} =
-    var f: TFile
-    if open(f, fn, mode):
-      try:
-        actions
-      finally:
-        close(f)
-    else:
-      quit("cannot open: " & fn)
-      
-  withFile(txt, "ttempl3.txt", fmWrite):
-    txt.writeln("line 1")
-    txt.writeln("line 2")
-  
-In the example the two ``writeln`` statements are bound to the ``actions``
-parameter.
-
-
-Symbol binding in templates
----------------------------
-
-A template is a `hygienic`:idx: macro and so opens a new scope. Most symbols are
-bound from the definition scope of the template:
-
-.. code-block:: nim
-  # Module A
-  var 
-    lastId = 0
-  
-  template genId*: expr =
-    inc(lastId)
-    lastId
-
-.. code-block:: nim
-  # Module B
-  import A
-  
-  echo genId() # Works as 'lastId' has been bound in 'genId's defining scope
-
-As in generics symbol binding can be influenced via ``mixin`` or ``bind`` 
-statements.
-
-
-
-Identifier construction
------------------------
-
-In templates identifiers can be constructed with the backticks notation:
-
-.. code-block:: nim
-
-  template typedef(name: expr, typ: typedesc) {.immediate.} = 
-    type
-      `T name`* {.inject.} = typ
-      `P name`* {.inject.} = ref `T name`
-      
-  typedef(myint, int)
-  var x: PMyInt
-
-In the example ``name`` is instantiated with ``myint``, so \`T name\` becomes
-``Tmyint``.
-
-
-Lookup rules for template parameters
-------------------------------------
-
-A parameter ``p`` in a template is even substituted in the expression ``x.p``.
-Thus template arguments can be used as field names and a global symbol can be
-shadowed by the same argument name even when fully qualified:
-
-.. code-block:: nim
-  # module 'm'
-
-  type
-    TLev = enum
-      levA, levB
-
-  var abclev = levB
-
-  template tstLev(abclev: TLev) =
-    echo abclev, " ", m.abclev
-
-  tstLev(levA)
-  # produces: 'levA levA'
-  
-But the global symbol can properly be captured by a ``bind`` statement:
-
-.. code-block:: nim
-  # module 'm'
-
-  type
-    TLev = enum
-      levA, levB
-
-  var abclev = levB
-
-  template tstLev(abclev: TLev) =
-    bind m.abclev
-    echo abclev, " ", m.abclev
-
-  tstLev(levA)
-  # produces: 'levA levB'
-
-
-Hygiene in templates
---------------------
-
-Per default templates are `hygienic`:idx:\: Local identifiers declared in a
-template cannot be accessed in the instantiation context:
-
-.. code-block:: nim
-  
-  template newException*(exceptn: typedesc, message: string): expr =
-    var
-      e: ref exceptn  # e is implicitly gensym'ed here
-    new(e)
-    e.msg = message
-    e
-    
-  # so this works:
-  let e = "message"
-  raise newException(EIO, e)
-
-
-Whether a symbol that is declared in a template is exposed to the instantiation
-scope is controlled by the `inject`:idx: and `gensym`:idx: pragmas: gensym'ed
-symbols are not exposed but inject'ed are.
-
-The default for symbols of entity ``type``, ``var``, ``let`` and ``const``
-is ``gensym`` and for ``proc``, ``iterator``, ``converter``, ``template``,
-``macro`` is ``inject``. However, if the name of the entity is passed as a 
-template parameter, it is an inject'ed symbol:
-
-.. code-block:: nim
-  template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} =
-    block:
-      var f: TFile  # since 'f' is a template param, it's injected implicitly
-      ...
-      
-  withFile(txt, "ttempl3.txt", fmWrite):
-    txt.writeln("line 1")
-    txt.writeln("line 2")
-
-
-The ``inject`` and ``gensym`` pragmas are second class annotations; they have
-no semantics outside of a template definition and cannot be abstracted over:
-
-.. code-block:: nim
-  {.pragma myInject: inject.}
-  
-  template t() =
-    var x {.myInject.}: int # does NOT work
-
-
-To get rid of hygiene in templates, one can use the `dirty`:idx: pragma for
-a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates.
-
-
-
-Macros
-======
-
-A macro is a special kind of low level template. Macros can be used
-to implement `domain specific languages`:idx:. Like templates, macros come in
-the 2 flavors *immediate* and *ordinary*.
-
-While macros enable advanced compile-time code transformations, they
-cannot change Nim's syntax. However, this is no real restriction because
-Nim's syntax is flexible enough anyway.
-
-To write macros, one needs to know how the Nim concrete syntax is converted
-to an abstract syntax tree.
-
-There are two ways to invoke a macro:
-(1) invoking a macro like a procedure call (`expression macros`)
-(2) invoking a macro with the special ``macrostmt`` syntax (`statement macros`)
-
-
-Expression Macros
------------------
-
-The following example implements a powerful ``debug`` command that accepts a
-variable number of arguments:
-
-.. code-block:: nim
-  # to work with Nim syntax trees, we need an API that is defined in the
-  # ``macros`` module:
-  import macros
-
-  macro debug(n: varargs[expr]): stmt =
-    # `n` is a Nim AST that contains the whole macro invocation
-    # this macro returns a list of statements:
-    result = newNimNode(nnkStmtList, n)
-    # iterate over any argument that is passed to this macro:
-    for i in 0..n.len-1:
-      # add a call to the statement list that writes the expression;
-      # `toStrLit` converts an AST to its string representation:
-      add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i])))
-      # add a call to the statement list that writes ": "
-      add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
-      # add a call to the statement list that writes the expressions value:
-      add(result, newCall("writeln", newIdentNode("stdout"), n[i]))
-
-  var
-    a: array [0..10, int]
-    x = "some string"
-  a[0] = 42
-  a[1] = 45
-
-  debug(a[0], a[1], x)
-
-The macro call expands to:
-
-.. code-block:: nim
-  write(stdout, "a[0]")
-  write(stdout, ": ")
-  writeln(stdout, a[0])
-
-  write(stdout, "a[1]")
-  write(stdout, ": ")
-  writeln(stdout, a[1])
-
-  write(stdout, "x")
-  write(stdout, ": ")
-  writeln(stdout, x)
-
-
-Arguments that are passed to a ``varargs`` parameter are wrapped in an array
-constructor expression. This is why ``debug`` iterates over all of ``n``'s
-children.
-
-
-BindSym
--------
-
-The above ``debug`` macro relies on the fact that ``write``, ``writeln`` and
-``stdout`` are declared in the system module and thus visible in the 
-instantiating context. There is a way to use bound identifiers
-(aka `symbols`:idx:) instead of using unbound identifiers. The ``bindSym`` 
-builtin can be used for that:
-
-.. code-block:: nim
-  import macros
-
-  macro debug(n: varargs[expr]): stmt =
-    result = newNimNode(nnkStmtList, n)
-    for i in 0..n.len-1:
-      # we can bind symbols in scope via 'bindSym':
-      add(result, newCall(bindSym"write", bindSym"stdout", toStrLit(n[i])))
-      add(result, newCall(bindSym"write", bindSym"stdout", newStrLitNode(": ")))
-      add(result, newCall(bindSym"writeln", bindSym"stdout", n[i]))
-
-  var
-    a: array [0..10, int]
-    x = "some string"
-  a[0] = 42
-  a[1] = 45
-
-  debug(a[0], a[1], x)
-
-The macro call expands to:
-
-.. code-block:: nim
-  write(stdout, "a[0]")
-  write(stdout, ": ")
-  writeln(stdout, a[0])
-
-  write(stdout, "a[1]")
-  write(stdout, ": ")
-  writeln(stdout, a[1])
-
-  write(stdout, "x")
-  write(stdout, ": ")
-  writeln(stdout, x)
-
-However, the symbols ``write``, ``writeln`` and ``stdout`` are already bound
-and are not looked up again. As the example shows, ``bindSym`` does work with
-overloaded symbols implicitly.
-
-
-Statement Macros
-----------------
-
-Statement macros are defined just as expression macros. However, they are
-invoked by an expression following a colon.
-
-The following example outlines a macro that generates a lexical analyzer from
-regular expressions:
-
-.. code-block:: nim
-  import macros
-
-  macro case_token(n: stmt): stmt =
-    # creates a lexical analyzer from regular expressions
-    # ... (implementation is an exercise for the reader :-)
-    discard
-
-  case_token: # this colon tells the parser it is a macro statement
-  of r"[A-Za-z_]+[A-Za-z_0-9]*":
-    return tkIdentifier
-  of r"0-9+":
-    return tkInteger
-  of r"[\+\-\*\?]+":
-    return tkOperator
-  else:
-    return tkUnknown
-
-
-**Style note**: For code readability, it is the best idea to use the least
-powerful programming construct that still suffices. So the "check list" is:
-
-(1) Use an ordinary proc/iterator, if possible.
-(2) Else: Use a generic proc/iterator, if possible.
-(3) Else: Use a template, if possible.
-(4) Else: Use a macro.
-
-
-Macros as pragmas
------------------
-
-Whole routines (procs, iterators etc.) can also be passed to a template or 
-a macro via the pragma notation: 
-
-.. code-block:: nim
-  template m(s: stmt) = discard
-
-  proc p() {.m.} = discard
-
-This is a simple syntactic transformation into:
-
-.. code-block:: nim
-  template m(s: stmt) = discard
-
-  m:
-    proc p() = discard
-
-
-Special Types
-=============
-
-static[T]
----------
-
-**Note**: static[T] is still in development.
-
-As their name suggests, static params must be known at compile-time:
-
-.. code-block:: nim
-
-  proc precompiledRegex(pattern: static[string]): TRegEx =
-    var res {.global.} = re(pattern)
-    return res
-
-  precompiledRegex("/d+") # Replaces the call with a precompiled
-                          # regex, stored in a global variable
-
-  precompiledRegex(paramStr(1)) # Error, command-line options
-                                # are not known at compile-time
-
-
-For the purposes of code generation, all static params are treated as
-generic params - the proc will be compiled separately for each unique
-supplied value (or combination of values). 
-
-Furthermore, the system module defines a `semistatic[T]` type than can be
-used to declare procs accepting both static and run-time values, which can
-optimize their body according to the supplied param using the `isStatic(p)`
-predicate:
-
-.. code-block:: nim
-
-  # The following proc will be compiled once for each unique static
-  # value and also once for the case handling all run-time values:
-
-  proc re(pattern: semistatic[string]): TRegEx =
-    when isStatic(pattern):
-      result = precompiledRegex(pattern)
-    else:
-      result = compile(pattern)
-
-Static params can also appear in the signatures of generic types:
-
-.. code-block:: nim
-
-  type
-    Matrix[M,N: static[int]; T: Number] = array[0..(M*N - 1), T]
-      # Note how `Number` is just a type constraint here, while
-      # `static[int]` requires us to supply a compile-time int value
-
-    AffineTransform2D[T] = Matrix[3, 3, T]
-    AffineTransform3D[T] = Matrix[4, 4, T]
-
-  var m1: AffineTransform3D[float]  # OK
-  var m2: AffineTransform2D[string] # Error, `string` is not a `Number`
-
-
-typedesc
---------
-
-`typedesc` is a special type allowing one to treat types as compile-time values
-(i.e. if types are compile-time values and all values have a type, then 
-typedesc must be their type).
-
-When used as a regular proc param, typedesc acts as a type class. The proc
-will be instantiated for each unique type parameter and one can refer to the
-instantiation type using the param name:
-
-.. code-block:: nim
-
-  proc new(T: typedesc): ref T =
-    echo "allocating ", T.name
-    new(result)
-
-  var n = TNode.new
-  var tree = new(TBinaryTree[int])
-
-When multiple typedesc params are present, they act like a distinct type class
-(i.e. they will bind freely to different types). To force a bind-once behavior
-one can use a named alias or an explicit `typedesc` generic param:
-
-.. code-block:: nim
-
-  # `type1` and `type2` are aliases for typedesc available from system.nim
-  proc acceptOnlyTypePairs(A, B: type1; C, D: type2)
-  proc acceptOnlyTypePairs[T: typedesc, U: typedesc](A, B: T; C, D: U)
-
-Once bound, typedesc params can appear in the rest of the proc signature:
-
-.. code-block:: nim
-
-  template declareVariableWithType(T: typedesc, value: T) =
-    var x: T = value
-
-  declareVariableWithType int, 42
-
-When used with macros and .compileTime. procs on the other hand, the compiler
-does not need to instantiate the code multiple times, because types then can be
-manipulated using the unified internal symbol representation. In such context
-typedesc acts as any other type. One can create variables, store typedesc
-values inside containers and so on. For example, here is how one can create 
-a type-safe wrapper for the unsafe `printf` function from C:
-
-.. code-block:: nim
-  macro safePrintF(formatString: string{lit}, args: varargs[expr]): expr =
-    var i = 0
-    for c in formatChars(formatString):
-      var expectedType = case c
-        of 'c': char
-        of 'd', 'i', 'x', 'X': int
-        of 'f', 'e', 'E', 'g', 'G': float
-        of 's': string
-        of 'p': pointer
-        else: EOutOfRange
-      
-      var actualType = args[i].getType
-      inc i
-
-      if expectedType == EOutOfRange:
-        error c & " is not a valid format character"
-      elif expectedType != actualType:
-        error "type mismatch for argument ", i, ". expected type: ",
-              expectedType.name, ", actual type: ", actualType.name
-    
-    # keep the original callsite, but use cprintf instead
-    result = callsite()
-    result[0] = newIdentNode(!"cprintf")
-
-
-Overload resolution can be further influenced by constraining the set of
-types that will match the typedesc param:
-
-.. code-block:: nim
-
-  template maxval(T: typedesc[int]): int = high(int)
-  template maxval(T: typedesc[float]): float = Inf
-
-  var i = int.maxval
-  var f = float.maxval
-  var s = string.maxval # error, maxval is not implemented for string
-
-The constraint can be a concrete type or a type class.
-
-
-Special Operators
-=================
-
-dot operators
--------------
-
-Nim offers a special family of dot operators that can be used to
-intercept and rewrite proc call and field access attempts, referring
-to previously undeclared symbol names. They can be used to provide a
-fluent interface to objects lying outside the static confines of the
-type system such as values from dynamic scripting languages
-or dynamic file formats such as JSON or XML.
-
-When Nim encounters an expression that cannot be resolved by the
-standard overload resolution rules, the current scope will be searched
-for a dot operator that can be matched against a re-written form of
-the expression, where the unknown field or proc name is converted to
-an additional static string parameter:
-
-.. code-block:: nim
-  a.b # becomes `.`(a, "b")
-  a.b(c, d) # becomes `.`(a, "b", c, d)
-
-The matched dot operators can be symbols of any callable kind (procs,
-templates and macros), depending on the desired effect:
-
-.. code-block:: nim
-  proc `.` (js: PJsonNode, field: string): JSON = js[field]
-
-  var js = parseJson("{ x: 1, y: 2}")
-  echo js.x # outputs 1
-  echo js.y # outputs 2
-
-The following dot operators are available:
-
-operator `.`
------------- 
-This operator will be matched against both field accesses and method calls.
-
-operator `.()`
----------------
-This operator will be matched exclusively against method calls. It has higher
-precedence than the `.` operator and this allows one to handle expressions like
-`x.y` and `x.y()` differently if one is interfacing with a scripting language
-for example.
-
-operator `.=`
--------------
-This operator will be matched against assignments to missing fields.
-
-.. code-block:: nim
-  a.b = c # becomes `.=`(a, "b", c)
-
-
-Type bound operations
-=====================
-
-There are 3 operations that are bound to a type:
-
-1. Assignment
-2. Destruction
-3. Deep copying for communication between threads
-
-These operations can be *overriden* instead of *overloaded*. This means the
-implementation is automatically lifted to structured types. For instance if type
-``T`` has an overriden assignment operator ``=`` this operator is also used
-for assignments of the type ``seq[T]``. Since these operations are bound to a
-type they have to be bound to a nominal type for reasons of simplicity of
-implementation: This means an overriden ``deepCopy`` for ``ref T`` is really
-bound to ``T`` and not to ``ref T``. This also means that one cannot override
-``deepCopy`` for both ``ptr T`` and ``ref T`` at the same time; instead a
-helper distinct or object type has to be used for one pointer type.
-
-
-operator `=`
-------------
-
-This operator is the assignment operator. Note that in the contexts 
-like ``let v = expr``, ``var v = expr``, ``parameter = defaultValue`` or for
-parameter passing no assignment is performed. The ``override`` pragma is
-optional for overriding ``=``.
-
-**Note**: Overriding of operator ``=`` is not yet implemented.
-
-
-destructors
------------
-
-A destructor must have a single parameter with a concrete type (the name of a
-generic type is allowed too). The name of the destructor has to be ``destroy``
-and it need to be annotated with the ``override`` pragma.
-
-``destroy(v)`` will be automatically invoked for every local stack 
-variable ``v`` that goes out of scope.
-
-If a structured type features a field with destructable type and 
-the user has not provided an explicit implementation, a destructor for the
-structured type will be automatically generated. Calls to any base class 
-destructors in both user-defined and generated destructors will be inserted.
-
-A destructor is attached to the type it destructs; expressions of this type
-can then only be used in *destructible contexts* and as parameters:
-
-.. code-block:: nim
-  type
-    TMyObj = object
-      x, y: int
-      p: pointer
-      
-  proc destroy(o: var TMyObj) {.override.} =
-    if o.p != nil: dealloc o.p
-    
-  proc open: TMyObj =
-    result = TMyObj(x: 1, y: 2, p: alloc(3))
- 
-  proc work(o: TMyObj) =
-    echo o.x
-    # No destructor invoked here for 'o' as 'o' is a parameter.
-
-  proc main() =
-    # destructor automatically invoked at the end of the scope:
-    var x = open()
-    # valid: pass 'x' to some other proc:
-    work(x)
-    
-    # Error: usage of a type with a destructor in a non destructible context
-    echo open()
-
-A destructible context is currently only the following:
-
-1. The ``expr`` in ``var x = expr``.
-2. The ``expr`` in ``let x = expr``.
-3. The ``expr`` in ``return expr``.
-4. The ``expr`` in ``result = expr`` where ``result`` is the special symbol
-   introduced by the compiler.
-
-These rules ensure that the construction is tied to a variable and can easily
-be destructed at its scope exit. Later versions of the language will improve
-the support of destructors.
-
-Be aware that destructors are not called for objects allocated with ``new``.
-This may change in future versions of language, but for now the ``finalizer``
-parameter to ``new`` has to be used.
-
-**Note**: Destructors are still experimental and the spec might change
-significantly in order to incorporate an escape analysis.
-
-
-deepCopy
---------
-
-``deepCopy`` is a builtin that is invoked whenever data is passed to
-a ``spawn``'ed proc to ensure memory safety. The programmer can override its
-behaviour for a specific ``ref`` or ``ptr`` type ``T``. (Later versions of the
-language may weaken this restriction.)
-
-The signature has to be:
-
-.. code-block:: nim
-  proc deepCopy(x: T): T {.override.}
-
-This mechanism is used by most data structures that support shared memory like
-channels to implement thread safe automatic memory management.
-
-The builtin ``deepCopy`` can even clone closures and their environments. See
-the documentation of `spawn`_ for details.
-
-
-Term rewriting macros
-=====================
-
-Term rewriting macros are macros or templates that have not only
-a *name* but also a *pattern* that is searched for after the semantic checking
-phase of the compiler: This means they provide an easy way to enhance the 
-compilation pipeline with user defined optimizations:
-
-.. code-block:: nim
-  template optMul{`*`(a, 2)}(a: int): int = a+a
-  
-  let x = 3
-  echo x * 2
-
-The compiler now rewrites ``x * 2`` as ``x + x``. The code inside the
-curlies is the pattern to match against. The operators ``*``,  ``**``,
-``|``, ``~`` have a special meaning in patterns if they are written in infix 
-notation, so to match verbatim against ``*`` the ordinary function call syntax
-needs to be used.
-
-
-Unfortunately optimizations are hard to get right and even the tiny example
-is **wrong**: 
-
-.. code-block:: nim
-  template optMul{`*`(a, 2)}(a: int): int = a+a
-  
-  proc f(): int =
-    echo "side effect!"
-    result = 55
-  
-  echo f() * 2
-
-We cannot duplicate 'a' if it denotes an expression that has a side effect!
-Fortunately Nim supports side effect analysis:
-
-.. code-block:: nim
-  template optMul{`*`(a, 2)}(a: int{noSideEffect}): int = a+a
-  
-  proc f(): int =
-    echo "side effect!"
-    result = 55
-  
-  echo f() * 2 # not optimized ;-)
-
-So what about ``2 * a``? We should tell the compiler ``*`` is commutative. We
-cannot really do that however as the following code only swaps arguments
-blindly:
-
-.. code-block:: nim
-  template mulIsCommutative{`*`(a, b)}(a, b: int): int = b*a
-  
-What optimizers really need to do is a *canonicalization*:
-
-.. code-block:: nim
-  template canonMul{`*`(a, b)}(a: int{lit}, b: int): int = b*a
-
-The ``int{lit}`` parameter pattern matches against an expression of 
-type ``int``, but only if it's a literal.
-
-
-
-Parameter constraints
----------------------
-
-The `parameter constraint`:idx: expression can use the operators ``|`` (or), 
-``&`` (and) and ``~`` (not) and the following predicates:
-
-===================      =====================================================
-Predicate                Meaning
-===================      =====================================================
-``atom``                 The matching node has no children.
-``lit``                  The matching node is a literal like "abc", 12.
-``sym``                  The matching node must be a symbol (a bound 
-                         identifier).
-``ident``                The matching node must be an identifier (an unbound
-                         identifier).
-``call``                 The matching AST must be a call/apply expression.
-``lvalue``               The matching AST must be an lvalue.
-``sideeffect``           The matching AST must have a side effect.
-``nosideeffect``         The matching AST must have no side effect.
-``param``                A symbol which is a parameter.
-``genericparam``         A symbol which is a generic parameter.
-``module``               A symbol which is a module.
-``type``                 A symbol which is a type.
-``var``                  A symbol which is a variable.
-``let``                  A symbol which is a ``let`` variable.
-``const``                A symbol which is a constant.
-``result``               The special ``result`` variable.
-``proc``                 A symbol which is a proc.
-``method``               A symbol which is a method.
-``iterator``             A symbol which is an iterator.
-``converter``            A symbol which is a converter.
-``macro``                A symbol which is a macro.
-``template``             A symbol which is a template.
-``field``                A symbol which is a field in a tuple or an object.
-``enumfield``            A symbol which is a field in an enumeration.
-``forvar``               A for loop variable.
-``label``                A label (used in ``block`` statements).
-``nk*``                  The matching AST must have the specified kind. 
-                         (Example: ``nkIfStmt`` denotes an ``if`` statement.)
-``alias``                States that the marked parameter needs to alias 
-                         with *some* other parameter.
-``noalias``              States that *every* other parameter must not alias
-                         with the marked parameter.
-===================      =====================================================
-
-The ``alias`` and ``noalias`` predicates refer not only to the matching AST,
-but also to every other bound parameter; syntactially they need to occur after
-the ordinary AST predicates:
-
-.. code-block:: nim
-  template ex{a = b + c}(a: int{noalias}, b, c: int) =
-    # this transformation is only valid if 'b' and 'c' do not alias 'a':
-    a = b
-    inc a, c
-
-
-Pattern operators
------------------
-
-The operators ``*``,  ``**``, ``|``, ``~`` have a special meaning in patterns
-if they are written in infix notation.
-
-
-The ``|`` operator
-~~~~~~~~~~~~~~~~~~
-
-The ``|`` operator if used as infix operator creates an ordered choice:
-
-.. code-block:: nim
-  template t{0|1}(): expr = 3
-  let a = 1
-  # outputs 3:
-  echo a
-
-The matching is performed after the compiler performed some optimizations like
-constant folding, so the following does not work:
-
-.. code-block:: nim
-  template t{0|1}(): expr = 3
-  # outputs 1:
-  echo 1
-
-The reason is that the compiler already transformed the 1 into "1" for
-the ``echo`` statement. However, a term rewriting macro should not change the
-semantics anyway. In fact they can be deactived with the ``--patterns:off``
-command line option or temporarily with the ``patterns`` pragma. 
-
-
-The ``{}`` operator
-~~~~~~~~~~~~~~~~~~~
-
-A pattern expression can be bound to a pattern parameter via the ``expr{param}``
-notation: 
-
-.. code-block:: nim
-  template t{(0|1|2){x}}(x: expr): expr = x+1
-  let a = 1
-  # outputs 2:
-  echo a
-
-
-The ``~`` operator
-~~~~~~~~~~~~~~~~~~
-
-The ``~`` operator is the **not** operator in patterns:
-
-.. code-block:: nim
-  template t{x = (~x){y} and (~x){z}}(x, y, z: bool): stmt =
-    x = y
-    if x: x = z
-  
-  var
-    a = false
-    b = true
-    c = false
-  a = b and c
-  echo a
-
-
-The ``*`` operator
-~~~~~~~~~~~~~~~~~~
-
-The ``*`` operator can *flatten* a nested binary expression like ``a & b & c``
-to ``&(a, b, c)``: 
-
-.. code-block:: nim
-  var
-    calls = 0
-    
-  proc `&&`(s: varargs[string]): string =
-    result = s[0]
-    for i in 1..len(s)-1: result.add s[i]
-    inc calls
-
-  template optConc{ `&&` * a }(a: string): expr = &&a
-
-  let space = " "
-  echo "my" && (space & "awe" && "some " ) && "concat"
-
-  # check that it's been optimized properly:
-  doAssert calls == 1
-
-
-The second operator of `*` must be a parameter; it is used to gather all the
-arguments. The expression ``"my" && (space & "awe" && "some " ) && "concat"``
-is passed to ``optConc`` in ``a`` as a special list (of kind ``nkArgList``) 
-which is flattened into a call expression; thus the invocation of ``optConc`` 
-produces:
-
-.. code-block:: nim
-   `&&`("my", space & "awe", "some ", "concat")
-
-
-The ``**`` operator
-~~~~~~~~~~~~~~~~~~~
-
-The ``**`` is much like the ``*`` operator, except that it gathers not only
-all the arguments, but also the matched operators in reverse polish notation:
-
-.. code-block:: nim
-  import macros
-
-  type
-    TMatrix = object
-      dummy: int
-
-  proc `*`(a, b: TMatrix): TMatrix = discard
-  proc `+`(a, b: TMatrix): TMatrix = discard
-  proc `-`(a, b: TMatrix): TMatrix = discard
-  proc `$`(a: TMatrix): string = result = $a.dummy
-  proc mat21(): TMatrix =
-    result.dummy = 21
-
-  macro optM{ (`+`|`-`|`*`) ** a }(a: TMatrix): expr =
-    echo treeRepr(a)
-    result = newCall(bindSym"mat21")
-
-  var x, y, z: TMatrix
-
-  echo x + y * z - x 
-
-This passes the expression ``x + y * z - x`` to the ``optM`` macro as
-an ``nnkArgList`` node containing::
-
-  Arglist
-    Sym "x"
-    Sym "y"
-    Sym "z"
-    Sym "*"
-    Sym "+"
-    Sym "x"
-    Sym "-"
-
-(Which is the reverse polish notation of ``x + y * z - x``.)
-
-
-Parameters
-----------
-
-Parameters in a pattern are type checked in the matching process. If a 
-parameter is of the type ``varargs`` it is treated specially and it can match
-0 or more arguments in the AST to be matched against:
-
-.. code-block:: nim
-  template optWrite{
-    write(f, x)
-    ((write|writeln){w})(f, y)
-  }(x, y: varargs[expr], f: TFile, w: expr) =
-    w(f, x, y)
-  
-
-
-Example: Partial evaluation
----------------------------
-
-The following example shows how some simple partial evaluation can be
-implemented with term rewriting:
-
-.. code-block:: nim
-  proc p(x, y: int; cond: bool): int =
-    result = if cond: x + y else: x - y
-
-  template optP1{p(x, y, true)}(x, y: expr): expr = x + y
-  template optP2{p(x, y, false)}(x, y: expr): expr = x - y
-
-
-Example: Hoisting
------------------
-
-The following example shows how some form of hoisting can be implemented:
-
-.. code-block:: nim
-  import pegs
-
-  template optPeg{peg(pattern)}(pattern: string{lit}): TPeg =
-    var gl {.global, gensym.} = peg(pattern)
-    gl
-
-  for i in 0 .. 3:
-    echo match("(a b c)", peg"'(' @ ')'")
-    echo match("W_HI_Le", peg"\y 'while'")
-
-The ``optPeg`` template optimizes the case of a peg constructor with a string
-literal, so that the pattern will only be parsed once at program startup and
-stored in a global ``gl`` which is then re-used. This optimization is called 
-hoisting because it is comparable to classical loop hoisting.
-
-
-AST based overloading
-=====================
-
-Parameter constraints can also be used for ordinary routine parameters; these
-constraints affect ordinary overloading resolution then:
-
-.. code-block:: nim
-  proc optLit(a: string{lit|`const`}) =
-    echo "string literal"
-  proc optLit(a: string) =
-    echo "no string literal"
-
-  const
-    constant = "abc"
-
-  var
-    variable = "xyz"
-
-  optLit("literal")
-  optLit(constant)
-  optLit(variable)
-
-However, the constraints ``alias`` and ``noalias`` are not available in
-ordinary routines.
-
-
-Move optimization
------------------
-
-The ``call`` constraint is particularly useful to implement a move 
-optimization for types that have copying semantics:
-
-.. code-block:: nim
-  proc `[]=`*(t: var TTable, key: string, val: string) =
-    ## puts a (key, value)-pair into `t`. The semantics of string require
-    ## a copy here:
-    let idx = findInsertionPosition(key)
-    t[idx] = key
-    t[idx] = val
-
-  proc `[]=`*(t: var TTable, key: string{call}, val: string{call}) =
-    ## puts a (key, value)-pair into `t`. Optimized version that knows that
-    ## the strings are unique and thus don't need to be copied:
-    let idx = findInsertionPosition(key)
-    shallowCopy t[idx], key
-    shallowCopy t[idx], val
-
-  var t: TTable
-  # overloading resolution ensures that the optimized []= is called here:
-  t[f()] = g()
-
-
-
-Modules
-=======
-Nim supports splitting a program into pieces by a module concept.
-Each module needs to be in its own file and has its own `namespace`:idx:.
-Modules enable `information hiding`:idx: and `separate compilation`:idx:.
-A module may gain access to symbols of another module by the `import`:idx:
-statement. `Recursive module dependencies`:idx: are allowed, but slightly
-subtle. Only top-level symbols that are marked with an asterisk (``*``) are
-exported.
-
-The algorithm for compiling modules is:
-
-- compile the whole module as usual, following import statements recursively
-
-- if there is a cycle only import the already parsed symbols (that are
-  exported); if an unknown identifier occurs then abort
-
-This is best illustrated by an example:
-
-.. code-block:: nim
-  # Module A
-  type
-    T1* = int  # Module A exports the type ``T1``
-  import B     # the compiler starts parsing B
-
-  proc main() =
-    var i = p(3) # works because B has been parsed completely here
-
-  main()
-
-
-.. code-block:: nim
-  # Module B
-  import A  # A is not parsed here! Only the already known symbols
-            # of A are imported.
-
-  proc p*(x: A.T1): A.T1 =
-    # this works because the compiler has already
-    # added T1 to A's interface symbol table
-    result = x + 1
-
-
-Import statement
-~~~~~~~~~~~~~~~~
-
-After the ``import`` statement a list of module names can follow or a single
-module name followed by an ``except`` to prevent some symbols to be imported:
-
-.. code-block:: nim
-  import strutils except `%`
-
-  # doesn't work then:
-  echo "$1" % "abc"
-
-
-Module names in imports
-~~~~~~~~~~~~~~~~~~~~~~~
-
-A module alias can be introduced via the ``as`` keyword:
-
-.. code-block:: nim
-  import strutils as su, sequtils as qu
-
-  echo su.format("$1", "lalelu")
-
-The original module name is then not accessible. The 
-notations ``path/to/module`` or ``path.to.module`` or ``"path/to/module"`` 
-can be used to refer to a module in subdirectories:
-
-.. code-block:: nim
-  import lib.pure.strutils, lib/pure/os, "lib/pure/times"
-
-Note that the module name is still ``strutils`` and not ``lib.pure.strutils``
-and so one **cannot** do:
-
-.. code-block:: nim
-  import lib.pure.strutils
-  echo lib.pure.strutils
-
-Likewise the following does not make sense as the name is ``strutils`` already:
-
-.. code-block:: nim
-  import lib.pure.strutils as strutils
-
-
-From import statement
-~~~~~~~~~~~~~~~~~~~~~
-
-After the ``from`` statement a module name follows followed by 
-an ``import`` to list the symbols one likes to use without explict
-full qualification:
-
-.. code-block:: nim
-  from strutils import `%`
-
-  echo "$1" % "abc"
-  # always possible: full qualification:
-  echo strutils.replace("abc", "a", "z")
-
-It's also possible to use ``from module import nil`` if one wants to import 
-the module but wants to enforce fully qualified access to every symbol 
-in ``module``.
-
-
-Export statement
-~~~~~~~~~~~~~~~~
-
-An ``export`` statement can be used for symbol fowarding so that client
-modules don't need to import a module's dependencies:
-
-.. code-block:: nim
-  # module B
-  type TMyObject* = object
-
-.. code-block:: nim
-  # module A
-  import B
-  export B.TMyObject
-  
-  proc `$`*(x: TMyObject): string = "my object"
-
-
-.. code-block:: nim
-  # module C
-  import A
-  
-  # B.TMyObject has been imported implicitly here: 
-  var x: TMyObject
-  echo($x)
-
-
-Scope rules
------------
-Identifiers are valid from the point of their declaration until the end of
-the block in which the declaration occurred. The range where the identifier
-is known is the scope of the identifier. The exact scope of an
-identifier depends on the way it was declared.
-
-Block scope
-~~~~~~~~~~~
-The *scope* of a variable declared in the declaration part of a block
-is valid from the point of declaration until the end of the block. If a
-block contains a second block, in which the identifier is redeclared,
-then inside this block, the second declaration will be valid. Upon
-leaving the inner block, the first declaration is valid again. An
-identifier cannot be redefined in the same block, except if valid for
-procedure or iterator overloading purposes.
-
-
-Tuple or object scope
-~~~~~~~~~~~~~~~~~~~~~
-The field identifiers inside a tuple or object definition are valid in the
-following places:
-
-* To the end of the tuple/object definition.
-* Field designators of a variable of the given tuple/object type.
-* In all descendant types of the object type.
-
-Module scope
-~~~~~~~~~~~~
-All identifiers of a module are valid from the point of declaration until
-the end of the module. Identifiers from indirectly dependent modules are *not* 
-available. The `system`:idx: module is automatically imported in every other 
-module.
-
-If a module imports an identifier by two different modules, each occurrence of
-the identifier has to be qualified, unless it is an overloaded procedure or
-iterator in which case the overloading resolution takes place:
-
-.. code-block:: nim
-  # Module A
-  var x*: string
-
-.. code-block:: nim
-  # Module B
-  var x*: int
-
-.. code-block:: nim
-  # Module C
-  import A, B
-  write(stdout, x) # error: x is ambiguous
-  write(stdout, A.x) # no error: qualifier used
-
-  var x = 4
-  write(stdout, x) # not ambiguous: uses the module C's x
-
-
-Compiler Messages
-=================
-
-The Nim compiler emits different kinds of messages: `hint`:idx:,
-`warning`:idx:, and `error`:idx: messages. An *error* message is emitted if
-the compiler encounters any static error.
-
-
-Pragmas
-=======
-
-Pragmas are Nim's method to give the compiler additional information /
-commands without introducing a massive number of new keywords. Pragmas are
-processed on the fly during semantic checking. Pragmas are enclosed in the
-special ``{.`` and ``.}`` curly brackets. Pragmas are also often used as a
-first implementation to play with a language feature before a nicer syntax
-to access the feature becomes available.
-
-
-noSideEffect pragma
--------------------
-The ``noSideEffect`` pragma is used to mark a proc/iterator to have no side
-effects. This means that the proc/iterator only changes locations that are
-reachable from its parameters and the return value only depends on the
-arguments. If none of its parameters have the type ``var T``
-or ``ref T`` or ``ptr T`` this means no locations are modified. It is a static
-error to mark a proc/iterator to have no side effect if the compiler cannot
-verify this.
-
-As a special semantic rule, the built-in `debugEcho `_
-pretends to be free of side effects, so that it can be used for debugging
-routines marked as ``noSideEffect``.
-
-**Future directions**: ``func`` may become a keyword and syntactic sugar for a
-proc with no side effects:
-
-.. code-block:: nim
-  func `+` (x, y: int): int
-
-
-destructor pragma
------------------
-
-The ``destructor`` pragma is used to mark a proc to act as a type destructor.
-Its usage is deprecated, use the ``override`` pragma instead.
-See `type bound operations`_.
-
-
-override pragma
----------------
-
-See `type bound operations`_ instead.
-
-procvar pragma
---------------
-The ``procvar`` pragma is used to mark a proc that it can be passed to a
-procedural variable.
-
-
-compileTime pragma
-------------------
-The ``compileTime`` pragma is used to mark a proc to be used at compile
-time only. No code will be generated for it. Compile time procs are useful
-as helpers for macros.
-
-
-noReturn pragma
----------------
-The ``noreturn`` pragma is used to mark a proc that never returns. 
-
-
-Acyclic pragma
---------------
-The ``acyclic`` pragma can be used for object types to mark them as acyclic
-even though they seem to be cyclic. This is an **optimization** for the garbage
-collector to not consider objects of this type as part of a cycle:
-
-.. code-block:: nim
-  type
-    PNode = ref TNode
-    TNode {.acyclic, final.} = object
-      left, right: PNode
-      data: string
-
-In the example a tree structure is declared with the ``TNode`` type. Note that
-the type definition is recursive and the GC has to assume that objects of
-this type may form a cyclic graph. The ``acyclic`` pragma passes the
-information that this cannot happen to the GC. If the programmer uses the
-``acyclic`` pragma for data types that are in reality cyclic, the GC may leak
-memory, but nothing worse happens.
-
-**Future directions**: The ``acyclic`` pragma may become a property of a
-``ref`` type:
-
-.. code-block:: nim
-  type
-    PNode = acyclic ref TNode
-    TNode = object
-      left, right: PNode
-      data: string
-
-
-Final pragma
-------------
-The ``final`` pragma can be used for an object type to specify that it
-cannot be inherited from.
-
-
-shallow pragma
---------------
-The ``shallow`` pragma affects the semantics of a type: The compiler is
-allowed to make a shallow copy. This can cause serious semantic issues and
-break memory safety! However, it can speed up assignments considerably, 
-because the semantics of Nim require deep copying of sequences and strings. 
-This can be expensive, especially if sequences are used to build a tree
-structure: 
-
-.. code-block:: nim
-  type
-    TNodeKind = enum nkLeaf, nkInner
-    TNode {.final, shallow.} = object
-      case kind: TNodeKind
-      of nkLeaf: 
-        strVal: string
-      of nkInner: 
-        children: seq[TNode]
-
-
-Pure pragma
------------
-An object type can be marked with the ``pure`` pragma so that its type 
-field which is used for runtime type identification is omitted. This is
-necessary for binary compatibility with other compiled languages.
-
-
-AsmNoStackFrame pragma
-----------------------
-A proc can be marked with the ``AsmNoStackFrame`` pragma to tell the compiler
-it should not generate a stack frame for the proc. There are also no exit
-statements like ``return result;`` generated and the generated C function is
-declared as ``__declspec(naked)`` or ``__attribute__((naked))`` (depending on
-the used C compiler).
-
-**Note**: This pragma should only be used by procs which consist solely of
-assembler statements.
-
-error pragma
-------------
-The ``error`` pragma is used to make the compiler output an error message
-with the given content. Compilation does not necessarily abort after an error
-though. 
-
-The ``error`` pragma can also be used to
-annotate a symbol (like an iterator or proc). The *usage* of the symbol then
-triggers a compile-time error. This is especially useful to rule out that some
-operation is valid due to overloading and type conversions: 
-
-.. code-block:: nim
-  ## check that underlying int values are compared and not the pointers:
-  proc `==`(x, y: ptr int): bool {.error.}
-
-
-fatal pragma
-------------
-The ``fatal`` pragma is used to make the compiler output an error message
-with the given content. In contrast to the ``error`` pragma, compilation
-is guaranteed to be aborted by this pragma. Example:
-
-.. code-block:: nim
-  when not defined(objc):
-    {.fatal: "Compile this program with the objc command!".}
-
-warning pragma
---------------
-The ``warning`` pragma is used to make the compiler output a warning message
-with the given content. Compilation continues after the warning.
-
-hint pragma
------------
-The ``hint`` pragma is used to make the compiler output a hint message with
-the given content. Compilation continues after the hint.
-
-line pragma
------------
-The ``line`` pragma can be used to affect line information of the annotated
-statement as seen in stack backtraces:
-
-.. code-block:: nim
-  
-  template myassert*(cond: expr, msg = "") =
-    if not cond:
-      # change run-time line information of the 'raise' statement:
-      {.line: InstantiationInfo().}:
-        raise newException(EAssertionFailed, msg)
-
-If the ``line`` pragma is used with a parameter, the parameter needs be a
-``tuple[filename: string, line: int]``. If it is used without a parameter,
-``system.InstantiationInfo()`` is used.
-
-
-linearScanEnd pragma
---------------------
-The ``linearScanEnd`` pragma can be used to tell the compiler how to 
-compile a Nim `case`:idx: statement. Syntactically it has to be used as a
-statement:
-
-.. code-block:: nim
-  case myInt
-  of 0: 
-    echo "most common case"
-  of 1: 
-    {.linearScanEnd.}
-    echo "second most common case"
-  of 2: echo "unlikely: use branch table"
-  else: echo "unlikely too: use branch table for ", myInt
-
-In the example, the case branches ``0`` and ``1`` are much more common than 
-the other cases. Therefore the generated assembler code should test for these 
-values first, so that the CPU's branch predictor has a good chance to succeed 
-(avoiding an expensive CPU pipeline stall). The other cases might be put into a
-jump table for O(1) overhead, but at the cost of a (very likely) pipeline
-stall. 
-
-The ``linearScanEnd`` pragma should be put into the last branch that should be
-tested against via linear scanning. If put into the last branch of the
-whole ``case`` statement, the whole ``case`` statement uses linear scanning.
-
-
-computedGoto pragma
--------------------
-The ``computedGoto`` pragma can be used to tell the compiler how to 
-compile a Nim `case`:idx: in a ``while true`` statement. 
-Syntactically it has to be used as a statement inside the loop:
-
-.. code-block:: nim
-
-  type
-    MyEnum = enum
-      enumA, enumB, enumC, enumD, enumE
-
-  proc vm() =
-    var instructions: array [0..100, MyEnum]
-    instructions[2] = enumC
-    instructions[3] = enumD
-    instructions[4] = enumA
-    instructions[5] = enumD
-    instructions[6] = enumC
-    instructions[7] = enumA
-    instructions[8] = enumB
-
-    instructions[12] = enumE
-    var pc = 0
-    while true:
-      {.computedGoto.}
-      let instr = instructions[pc]
-      case instr
-      of enumA:
-        echo "yeah A"
-      of enumC, enumD:
-        echo "yeah CD"
-      of enumB:
-        echo "yeah B"
-      of enumE:
-        break
-      inc(pc)
-    
-  vm()
-
-As the example shows ``computedGoto`` is mostly useful for interpreters. If
-the underlying backend (C compiler) does not support the computed goto 
-extension the pragma is simply ignored.
-
-
-unroll pragma
--------------
-The ``unroll`` pragma can be used to tell the compiler that it should unroll
-a `for`:idx: or `while`:idx: loop for runtime efficiency: 
-
-.. code-block:: nim
-  proc searchChar(s: string, c: char): int = 
-    for i in 0 .. s.high:
-      {.unroll: 4.}
-      if s[i] == c: return i
-    result = -1
-
-In the above example, the search loop is unrolled by a factor 4. The unroll
-factor can be left out too; the compiler then chooses an appropriate unroll
-factor.
-
-**Note**: Currently the compiler recognizes but ignores this pragma.
-
-
-immediate pragma
-----------------
-
-See `Ordinary vs immediate templates`_.
-
-
-compilation option pragmas
---------------------------
-The listed pragmas here can be used to override the code generation options
-for a proc/method/converter.
-
-The implementation currently provides the following possible options (various
-others may be added later).
-
-===============  ===============  ============================================
-pragma           allowed values   description
-===============  ===============  ============================================
-checks           on|off           Turns the code generation for all runtime
-                                  checks on or off.
-boundChecks      on|off           Turns the code generation for array bound
-                                  checks on or off.
-overflowChecks   on|off           Turns the code generation for over- or
-                                  underflow checks on or off.
-nilChecks        on|off           Turns the code generation for nil pointer
-                                  checks on or off.
-assertions       on|off           Turns the code generation for assertions
-                                  on or off.
-warnings         on|off           Turns the warning messages of the compiler
-                                  on or off.
-hints            on|off           Turns the hint messages of the compiler
-                                  on or off.
-optimization     none|speed|size  Optimize the code for speed or size, or
-                                  disable optimization.
-patterns         on|off           Turns the term rewriting templates/macros
-                                  on or off.
-callconv         cdecl|...        Specifies the default calling convention for
-                                  all procedures (and procedure types) that
-                                  follow.
-===============  ===============  ============================================
-
-Example:
-
-.. code-block:: nim
-  {.checks: off, optimization: speed.}
-  # compile without runtime checks and optimize for speed
-
-
-push and pop pragmas
---------------------
-The `push/pop`:idx: pragmas are very similar to the option directive,
-but are used to override the settings temporarily. Example:
-
-.. code-block:: nim
-  {.push checks: off.}
-  # compile this section without runtime checks as it is
-  # speed critical
-  # ... some code ...
-  {.pop.} # restore old settings
-
-
-register pragma
----------------
-The ``register`` pragma is for variables only. It declares the variable as
-``register``, giving the compiler a hint that the variable should be placed
-in a hardware register for faster access. C compilers usually ignore this
-though and for good reasons: Often they do a better job without it anyway.
-
-In highly specific cases (a dispatch loop of an bytecode interpreter for
-example) it may provide benefits, though.
-
-
-global pragma
--------------
-The ``global`` pragma can be applied to a variable within a proc to instruct
-the compiler to store it in a global location and initialize it once at program
-startup.
-
-.. code-block:: nim
-  proc isHexNumber(s: string): bool =
-    var pattern {.global.} = re"[0-9a-fA-F]+"
-    result = s.match(pattern)
-
-When used within a generic proc, a separate unique global variable will be
-created for each instantiation of the proc. The order of initialization of
-the created global variables within a module is not defined, but all of them
-will be initialized after any top-level variables in their originating module
-and before any variable in a module that imports it.
-
-DeadCodeElim pragma
--------------------
-The ``deadCodeElim`` pragma only applies to whole modules: It tells the
-compiler to activate (or deactivate) dead code elimination for the module the
-pragma appears in.
-
-The ``--deadCodeElim:on`` command line switch has the same effect as marking
-every module with ``{.deadCodeElim:on}``. However, for some modules such as
-the GTK wrapper it makes sense to *always* turn on dead code elimination -
-no matter if it is globally active or not.
-
-Example:
-
-.. code-block:: nim
-  {.deadCodeElim: on.}
-
-
-..
-  NoForward pragma
-  ----------------
-  The ``noforward`` pragma can be used to turn on and off a special compilation
-  mode that to large extent eliminates the need for forward declarations. In this
-  mode, the proc definitions may appear out of order and the compiler will postpone
-  their semantic analysis and compilation until it actually needs to generate code
-  using the definitions. In this regard, this mode is similar to the modus operandi
-  of dynamic scripting languages, where the function calls are not resolved until
-  the code is executed. Here is the detailed algorithm taken by the compiler:
-
-  1. When a callable symbol is first encountered, the compiler will only note the
-  symbol callable name and it will add it to the appropriate overload set in the
-  current scope. At this step, it won't try to resolve any of the type expressions
-  used in the signature of the symbol (so they can refer to other not yet defined
-  symbols).
-
-  2. When a top level call is encountered (usually at the very end of the module),
-  the compiler will try to determine the actual types of all of the symbols in the
-  matching overload set. This is a potentially recursive process as the signatures
-  of the symbols may include other call expressions, whoose types will be resolved
-  at this point too.
-
-  3. Finally, after the best overload is picked, the compiler will start compiling
-  the body of the respective symbol. This in turn will lead the compiler to discover
-  more call expresions that need to be resolved and steps 2 and 3 will be repeated
-  as necessary.
-
-  Please note that if a callable symbol is never used in this scenario, its body
-  will never be compiled. This is the default behavior leading to best compilation
-  times, but if exhaustive compilation of all definitions is required, using 
-  ``nim check`` provides this option as well.
-
-  Example:
-
-  .. code-block:: nim
-
-    {.noforward: on.}
-
-    proc foo(x: int) =
-      bar x
-
-    proc bar(x: int) =
-      echo x
-
-    foo(10)
-
-
-Pragma pragma
--------------
-
-The ``pragma`` pragma can be used to declare user defined pragmas. This is 
-useful because Nim's templates and macros do not affect pragmas. User 
-defined pragmas are in a different module-wide scope than all other symbols. 
-They cannot be imported from a module.
-
-Example:
-
-.. code-block:: nim
-  when appType == "lib":
-    {.pragma: rtl, exportc, dynlib, cdecl.}
-  else:
-    {.pragma: rtl, importc, dynlib: "client.dll", cdecl.}
-    
-  proc p*(a, b: int): int {.rtl.} = 
-    result = a+b
-
-In the example a new pragma named ``rtl`` is introduced that either imports
-a symbol from a dynamic library or exports the symbol for dynamic library
-generation.
-
-
-Disabling certain messages
---------------------------
-Nim generates some warnings and hints ("line too long") that may annoy the
-user. A mechanism for disabling certain messages is provided: Each hint
-and warning message contains a symbol in brackets. This is the message's
-identifier that can be used to enable or disable it:
-
-.. code-block:: Nim
-  {.hint[LineTooLong]: off.} # turn off the hint about too long lines
-
-This is often better than disabling all warnings at once.
-
-
-Foreign function interface
-==========================
-
-Nim's `FFI`:idx: (foreign function interface) is extensive and only the
-parts that scale to other future backends (like the LLVM/JavaScript backends)
-are documented here.
-
-
-Importc pragma
---------------
-The ``importc`` pragma provides a means to import a proc or a variable
-from C. The optional argument is a string containing the C identifier. If
-the argument is missing, the C name is the Nim identifier *exactly as
-spelled*:
-
-.. code-block::
-  proc printf(formatstr: cstring) {.header: "", importc: "printf", varargs.}
-
-Note that this pragma is somewhat of a misnomer: Other backends will provide
-the same feature under the same name. Also, if one is interfacing with C++
-the `ImportCpp pragma `_ and
-interfacing with Objective-C the `ImportObjC pragma
-`_ can be used.
-
-
-Exportc pragma
---------------
-The ``exportc`` pragma provides a means to export a type, a variable, or a
-procedure to C. Enums and constants can't be exported. The optional argument
-is a string containing the C identifier.  If the argument is missing, the C
-name is the Nim identifier *exactly as spelled*:
-
-.. code-block:: Nim
-  proc callme(formatstr: cstring) {.exportc: "callMe", varargs.}
-
-Note that this pragma is somewhat of a misnomer: Other backends will provide
-the same feature under the same name.
-
-
-Extern pragma
--------------
-Like ``exportc`` or ``importc``, the ``extern`` pragma affects name
-mangling. The string literal passed to ``extern`` can be a format string:
-
-.. code-block:: Nim
-  proc p(s: string) {.extern: "prefix$1".} =
-    echo s
-
-In the example the external name of ``p`` is set to ``prefixp``.
-
-
-Bycopy pragma
--------------
-
-The ``bycopy`` pragma can be applied to an object or tuple type and
-instructs the compiler to pass the type by value to procs:
-
-.. code-block:: nim
-  type
-    TVector {.bycopy, pure.} = object
-      x, y, z: float
-
-
-Byref pragma
-------------
-
-The ``byref`` pragma can be applied to an object or tuple type and instructs
-the compiler to pass the type by reference (hidden pointer) to procs.
-
-
-Varargs pragma
---------------
-The ``varargs`` pragma can be applied to procedures only (and procedure 
-types). It tells Nim that the proc can take a variable number of parameters 
-after the last specified parameter. Nim string values will be converted to C
-strings automatically:
-
-.. code-block:: Nim
-  proc printf(formatstr: cstring) {.nodecl, varargs.}
-
-  printf("hallo %s", "world") # "world" will be passed as C string
-
-
-Union pragma
-------------
-The ``union`` pragma can be applied to any ``object`` type. It means all
-of the object's fields are overlaid in memory. This produces a ``union``
-instead of a ``struct`` in the generated C/C++ code. The object declaration
-then must not use inheritance or any GC'ed memory but this is currently not
-checked.
-
-**Future directions**: GC'ed memory should be allowed in unions and the GC
-should scan unions conservatively.
-
-Packed pragma
--------------
-The ``packed`` pragma can be applied to any ``object`` type. It ensures 
-that the fields of an object are packed back-to-back in memory. It is useful 
-to store packets or messages from/to network or hardware drivers, and for 
-interoperability with C. Combining packed pragma with inheritance is not 
-defined, and it should not be used with GC'ed memory (ref's).  
-
-**Future directions**: Using GC'ed memory in packed pragma will result in 
-compile-time error. Usage with inheritance should be defined and documented.
-
-Unchecked pragma
-----------------
-The ``unchecked`` pragma can be used to mark a named array as ``unchecked``
-meaning its bounds are not checked. This is often useful when one wishes to
-implement his own flexibly sized arrays. Additionally an unchecked array is
-translated into a C array of undetermined size:
-
-.. code-block:: nim
-  type
-    ArrayPart{.unchecked.} = array[0..0, int]
-    MySeq = object
-      len, cap: int
-      data: ArrayPart
-
-Produces roughly this C code:
-
-.. code-block:: C
-  typedef struct {
-    NI len;
-    NI cap;
-    NI data[];
-  } MySeq;
-
-The bounds checking done at compile time is not disabled for now, so to access
-``s.data[C]`` (where ``C`` is a constant) the array's index needs needs to
-include ``C``.
-
-The base type of the unchecked array may not contain any GC'ed memory but this
-is currently not checked.
-
-**Future directions**: GC'ed memory should be allowed in unchecked arrays and
-there should be an explicit annotation of how the GC is to determine the
-runtime size of the array.
-
-
-Dynlib pragma for import
-------------------------
-With the ``dynlib`` pragma a procedure or a variable can be imported from
-a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). 
-The non-optional argument has to be the name of the dynamic library:
-
-.. code-block:: Nim
-  proc gtk_image_new(): PGtkWidget
-    {.cdecl, dynlib: "libgtk-x11-2.0.so", importc.}
-
-In general, importing a dynamic library does not require any special linker
-options or linking with import libraries. This also implies that no *devel*
-packages need to be installed.
-
-The ``dynlib`` import mechanism supports a versioning scheme: 
-
-.. code-block:: nim 
-  proc Tcl_Eval(interp: pTcl_Interp, script: cstring): int {.cdecl, 
-    importc, dynlib: "libtcl(|8.5|8.4|8.3).so.(1|0)".}
-
-At runtime the dynamic library is searched for (in this order)::
-  
-  libtcl.so.1
-  libtcl.so.0
-  libtcl8.5.so.1  
-  libtcl8.5.so.0
-  libtcl8.4.so.1
-  libtcl8.4.so.0
-  libtcl8.3.so.1
-  libtcl8.3.so.0
-
-The ``dynlib`` pragma supports not only constant strings as argument but also
-string expressions in general:
-
-.. code-block:: nim
-  import os
-
-  proc getDllName: string = 
-    result = "mylib.dll"
-    if existsFile(result): return
-    result = "mylib2.dll"
-    if existsFile(result): return
-    quit("could not load dynamic library")
-  
-  proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
-
-**Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant
-strings, because they are precompiled.
-
-**Note**: Passing variables to the ``dynlib`` pragma will fail at runtime 
-because of order of initialization problems.
-
-**Note**: A ``dynlib`` import can be overriden with 
-the ``--dynlibOverride:name`` command line option. The Compiler User Guide
-contains further information.
-
-
-Dynlib pragma for export
-------------------------
-
-With the ``dynlib`` pragma a procedure can also be exported to
-a dynamic library. The pragma then has no argument and has to be used in
-conjunction with the ``exportc`` pragma:
-
-.. code-block:: Nim
-  proc exportme(): int {.cdecl, exportc, dynlib.}
-
-This is only useful if the program is compiled as a dynamic library via the
-``--app:lib`` command line option.
-
-
-Threads
-=======
-
-To enable thread support the ``--threads:on`` command line switch needs to 
-be used. The ``system`` module then contains several threading primitives. 
-See the `threads `_ and `channels `_ modules 
-for the thread API.
-
-Nim's memory model for threads is quite different than that of other common
-programming languages (C, Pascal, Java): Each thread has its own (garbage 
-collected) heap and sharing of memory is restricted to global variables. This 
-helps to prevent race conditions. GC efficiency is improved quite a lot, 
-because the GC never has to stop other threads and see what they reference.
-Memory allocation requires no lock at all! This design easily scales to massive
-multicore processors that will become the norm in the future.
-
-
-Thread pragma
--------------
-
-A proc that is executed as a new thread of execution should be marked by the
-``thread`` pragma. The compiler checks procedures marked as ``thread`` for
-violations of the `no heap sharing restriction`:idx:\: This restriction implies
-that it is invalid to construct a data structure that consists of memory 
-allocated from different (thread local) heaps. 
-
-A thread proc is passed to ``createThread`` or ``spawn`` and invoked 
-indirectly; so the ``thread`` pragma implies ``procvar``.
-
-
-GC safety
----------
-
-We call a proc ``p`` `GC safe`:idx: when it doesn't access any global variable
-that contains GC'ed memory (``string``, ``seq``, ``ref`` or a closure) either
-directly or indirectly through a call to a GC unsafe proc. 
-
-The `gcsafe`:idx: annotation can be used to mark a proc to be gcsafe
-otherwise this property is inferred by the compiler. Note that ``noSideEfect``
-implies ``gcsafe``. The only way to create a thread is via ``spawn`` or
-``createThead``. ``spawn`` is usually the preferable method. Either way
-the invoked proc must not use ``var`` parameters nor must any of its parameters
-contain a ``ref`` or ``closure`` type. This enforces
-the *no heap sharing restriction*. 
-
-Routines that are imported from C are always assumed to be ``gcsafe``.
-To enable the GC-safety checking the ``--threadAnalysis:on`` command line
-switch must be used. This is a temporary workaround to ease the porting effort
-from old code to the new threading model. In the future the thread analysis
-will always be performed.
-
-
-Future directions:
-
-- For structured fork&join parallelism more efficient parameter passing can
-  be performed and much more can be proven safe.
-- A shared GC'ed heap is planned.
-
-
-Threadvar pragma
-----------------
-
-A global variable can be marked with the ``threadvar`` pragma; it is 
-a `thread-local`:idx: variable then:
-
-.. code-block:: nim
-  var checkpoints* {.threadvar.}: seq[string]
-
-Due to implementation restrictions thread local variables cannot be 
-initialized within the ``var`` section. (Every thread local variable needs to
-be replicated at thread creation.)
-
-
-Threads and exceptions
-----------------------
-
-The interaction between threads and exceptions is simple: A *handled* exception 
-in one thread cannot affect any other thread. However, an *unhandled* 
-exception in one thread terminates the whole *process*!
-
-
-Spawn
------
-
-Nim has a builtin thread pool that can be used for CPU intensive tasks. For
-IO intensive tasks the upcoming ``async`` and ``await`` features should be
-used. `spawn`:idx: is used to pass a task to the thread pool:
-
-.. code-block:: nim
-  proc processLine(line: string) =
-    # do some heavy lifting here:
-    discard
-    
-  for x in lines("myinput.txt"):
-    spawn processLine(x)
-  sync()
-
-Currently the expression that ``spawn`` takes is however quite restricted: 
-
-* It must be a call expression ``f(a, ...)``.
-* ``f`` must be ``gcsafe``.
-* ``f`` must not have the calling convention ``closure``.
-* ``f``'s parameters may not be of type ``var``.
-  This means one has to use raw ``ptr``'s for data passing reminding the
-  programmer to be careful.
-* ``ref`` parameters are deeply copied which is a subtle semantic change and
-  can cause performance problems but ensures memory safety.
-* For *safe* data exchange between ``f`` and the caller a global ``TChannel``
-  needs to be used. Other means will be provided soon.
-
-
-
-Taint mode
-==========
-
-The Nim compiler and most parts of the standard library support 
-a taint mode. Input strings are declared with the `TaintedString`:idx: 
-string type declared in the ``system`` module.
-
-If the taint mode is turned on (via the ``--taintMode:on`` command line 
-option) it is a distinct string type which helps to detect input
-validation errors:
-
-.. code-block:: nim
-  echo "your name: "
-  var name: TaintedString = stdin.readline
-  # it is safe here to output the name without any input validation, so
-  # we simply convert `name` to string to make the compiler happy: 
-  echo "hi, ", name.string
-
-If the taint mode is turned off, ``TaintedString`` is simply an alias for
-``string``.
+.. include:: manual/about.txt
+.. include:: manual/definitions.txt
+.. include:: manual/lexing.txt
+.. include:: manual/syntax.txt
+.. include:: manual/types.txt
+.. include:: manual/type_rel.txt
+.. include:: manual/stmts.txt
+.. include:: manual/procs.txt
+.. include:: manual/type_sections.txt
+.. include:: manual/exceptions.txt
+.. include:: manual/effects.txt
+.. include:: manual/generics.txt
+.. include:: manual/templates.txt
+.. include:: manual/typedesc.txt
+.. include:: manual/special_ops.txt
+.. include:: manual/type_bound_ops.txt
+.. include:: manual/trmacros.txt
+.. include:: manual/modules.txt
+.. include:: manual/compiler_msgs.txt
+.. include:: manual/pragmas.txt
+.. include:: manual/ffi.txt
+.. include:: manual/threads.txt
+.. include:: manual/locking.txt
+.. include:: manual/taint.txt
diff --git a/doc/manual/about.txt b/doc/manual/about.txt
new file mode 100644
index 000000000..13307279b
--- /dev/null
+++ b/doc/manual/about.txt
@@ -0,0 +1,37 @@
+About this document
+===================
+
+**Note**: This document is a draft! Several of Nim's features need more
+precise wording. This manual will evolve into a proper specification some
+day.
+
+This document describes the lexis, the syntax, and the semantics of Nim.
+
+The language constructs are explained using an extended BNF, in
+which ``(a)*`` means 0 or more ``a``'s, ``a+`` means 1 or more ``a``'s, and
+``(a)?`` means an optional *a*. Parentheses may be used to group elements.
+
+``&`` is the lookahead operator; ``&a`` means that an ``a`` is expected but
+not consumed. It will be consumed in the following rule.
+
+The ``|``, ``/`` symbols are used to mark alternatives and have the lowest 
+precedence. ``/`` is the ordered choice that requires the parser to try the 
+alternatives in the given order. ``/`` is often used to ensure the grammar
+is not ambiguous. 
+
+Non-terminals start with a lowercase letter, abstract terminal symbols are in
+UPPERCASE. Verbatim terminal symbols (including keywords) are quoted
+with ``'``. An example::
+
+  ifStmt = 'if' expr ':' stmts ('elif' expr ':' stmts)* ('else' stmts)?
+  
+The binary ``^*`` operator is used as a shorthand for 0 or more occurances
+separated by its second argument; likewise ``^+`` means 1 or more 
+occurances: ``a ^+ b`` is short for ``a (b a)*`` 
+and ``a ^* b`` is short for ``(a (b a)*)?``. Example::
+
+  arrayConstructor = '[' expr ^* ',' ']'
+
+Other parts of Nim - like scoping rules or runtime semantics are only
+described in an informal manner for now.
+
diff --git a/doc/manual/compiler_msgs.txt b/doc/manual/compiler_msgs.txt
new file mode 100644
index 000000000..3cf8417b0
--- /dev/null
+++ b/doc/manual/compiler_msgs.txt
@@ -0,0 +1,7 @@
+Compiler Messages
+=================
+
+The Nim compiler emits different kinds of messages: `hint`:idx:,
+`warning`:idx:, and `error`:idx: messages. An *error* message is emitted if
+the compiler encounters any static error.
+
diff --git a/doc/manual/definitions.txt b/doc/manual/definitions.txt
new file mode 100644
index 000000000..687980dbc
--- /dev/null
+++ b/doc/manual/definitions.txt
@@ -0,0 +1,49 @@
+
+Definitions
+===========
+
+A Nim program specifies a computation that acts on a memory consisting of
+components called `locations`:idx:. A variable is basically a name for a
+location. Each variable and location is of a certain `type`:idx:. The
+variable's type is called `static type`:idx:, the location's type is called
+`dynamic type`:idx:. If the static type is not the same as the dynamic type,
+it is a super-type or subtype of the dynamic type.
+
+An `identifier`:idx: is a symbol declared as a name for a variable, type,
+procedure, etc. The region of the program over which a declaration applies is
+called the `scope`:idx: of the declaration. Scopes can be nested. The meaning
+of an identifier is determined by the smallest enclosing scope in which the
+identifier is declared unless overloading resolution rules suggest otherwise.
+
+An expression specifies a computation that produces a value or location.
+Expressions that produce locations are called `l-values`:idx:. An l-value
+can denote either a location or the value the location contains, depending on
+the context. Expressions whose values can be determined statically are called
+`constant expressions`:idx:; they are never l-values.
+
+A `static error`:idx: is an error that the implementation detects before
+program execution. Unless explicitly classified, an error is a static error.
+
+A `checked runtime error`:idx: is an error that the implementation detects
+and reports at runtime. The method for reporting such errors is via *raising
+exceptions* or *dying with a fatal error*. However, the implementation 
+provides a means to disable these runtime checks. See the section pragmas_
+for details. 
+
+Wether a checked runtime error results in an exception or in a fatal error at
+runtime is implementation specific. Thus the following program is always
+invalid:
+
+.. code-block:: nim
+  var a: array[0..1, char]
+  let i = 5
+  try:
+    a[i] = 'N'
+  except EInvalidIndex:
+    echo "invalid index"
+
+An `unchecked runtime error`:idx: is an error that is not guaranteed to be
+detected, and can cause the subsequent behavior of the computation to
+be arbitrary. Unchecked runtime errors cannot occur if only `safe`:idx:
+language features are used.
+
diff --git a/doc/manual/effects.txt b/doc/manual/effects.txt
new file mode 100644
index 000000000..73934ab34
--- /dev/null
+++ b/doc/manual/effects.txt
@@ -0,0 +1,129 @@
+Effect system
+=============
+
+Exception tracking
+------------------
+
+Nim supports exception tracking. The `raises`:idx: pragma can be used
+to explicitly define which exceptions a proc/iterator/method/converter is 
+allowed to raise. The compiler verifies this:
+
+.. code-block:: nim
+  proc p(what: bool) {.raises: [IOError, OSError].} =
+    if what: raise newException(IOError, "IO")
+    else: raise newException(OSError, "OS")
+
+An empty ``raises`` list (``raises: []``) means that no exception may be raised:
+
+.. code-block:: nim
+  proc p(): bool {.raises: [].} =
+    try:
+      unsafeCall()
+      result = true
+    except:
+      result = false
+
+
+A ``raises`` list can also be attached to a proc type. This affects type 
+compatibility:
+
+.. code-block:: nim
+  type
+    TCallback = proc (s: string) {.raises: [IOError].}
+  var
+    c: TCallback
+
+  proc p(x: string) =
+    raise newException(OSError, "OS")
+  
+  c = p # type error
+
+
+For a routine ``p`` the compiler uses inference rules to determine the set of
+possibly raised exceptions; the algorithm operates on ``p``'s call graph:
+
+1. Every indirect call via some proc type ``T`` is assumed to
+   raise ``system.Exception`` (the base type of the exception hierarchy) and
+   thus any exception unless ``T`` has an explicit ``raises`` list.
+   However if the call is of the form ``f(...)`` where ``f`` is a parameter
+   of the currently analysed routine it is ignored. The call is optimistically 
+   assumed to have no effect. Rule 2 compensates for this case.
+2. Every expression of some proc type wihtin a call that is not a call 
+   itself (and not nil) is assumed to be called indirectly somehow and thus 
+   its raises list is added to ``p``'s raises list.
+3. Every call to a proc ``q`` which has an unknown body (due to a forward 
+   declaration or an ``importc`` pragma) is assumed to 
+   raise ``system.Exception`` unless ``q`` has an explicit ``raises`` list.
+4. Every call to a method ``m`` is assumed to 
+   raise ``system.Exception`` unless ``m`` has an explicit ``raises`` list.
+5. For every other call the analysis can determine an exact ``raises`` list.
+6. For determining a ``raises`` list, the ``raise`` and ``try`` statements 
+   of ``p`` are taken into consideration.
+
+Rules 1-2 ensure the following works: 
+
+.. code-block:: nim
+  proc noRaise(x: proc()) {.raises: [].} =
+    # unknown call that might raise anything, but valid:
+    x()
+    
+  proc doRaise() {.raises: [IOError].} =
+    raise newException(IOError, "IO")
+  
+  proc use() {.raises: [].} =
+    # doesn't compile! Can raise IOError!
+    noRaise(doRaise)
+
+So in many cases a callback does not cause the compiler to be overly
+conservative in its effect analysis.
+
+
+Tag tracking
+------------
+
+The exception tracking is part of Nim's `effect system`:idx:. Raising an
+exception is an *effect*. Other effects can also be defined. A user defined 
+effect is a means to *tag* a routine and to perform checks against this tag:
+
+.. code-block:: nim
+  type IO = object ## input/output effect
+  proc readLine(): string {.tags: [IO].}
+  
+  proc no_IO_please() {.tags: [].} =
+    # the compiler prevents this:
+    let x = readLine()
+
+A tag has to be a type name. A ``tags`` list - like a ``raises`` list - can 
+also be attached to a proc type. This affects type compatibility.
+
+The inference for tag tracking is analogous to the inference for 
+exception tracking.
+
+
+Read/Write tracking
+-------------------
+
+**Note**: Read/write tracking is not yet implemented!
+
+The inference for read/write tracking is analogous to the inference for 
+exception tracking.
+
+
+Effects pragma
+--------------
+
+The ``effects`` pragma has been designed to assist the programmer with the
+effects analysis. It is a statement that makes the compiler output all inferred
+effects up to the ``effects``'s position:
+
+.. code-block:: nim
+  proc p(what: bool) =
+    if what:
+      raise newException(IOError, "IO")
+      {.effects.}
+    else:
+      raise newException(OSError, "OS")
+
+The compiler produces a hint message that ``IOError`` can be raised. ``OSError``
+is not listed as it cannot be raised in the branch the ``effects`` pragma
+appears in.
diff --git a/doc/manual/exceptions.txt b/doc/manual/exceptions.txt
new file mode 100644
index 000000000..ba2ea30a0
--- /dev/null
+++ b/doc/manual/exceptions.txt
@@ -0,0 +1,132 @@
+Exception handling
+==================
+
+Try statement
+-------------
+
+Example:
+
+.. code-block:: nim
+  # read the first two lines of a text file that should contain numbers
+  # and tries to add them
+  var
+    f: File
+  if open(f, "numbers.txt"):
+    try:
+      var a = readLine(f)
+      var b = readLine(f)
+      echo("sum: " & $(parseInt(a) + parseInt(b)))
+    except OverflowError:
+      echo("overflow!")
+    except ValueError:
+      echo("could not convert string to integer")
+    except IOError:
+      echo("IO error!")
+    except:
+      echo("Unknown exception!")
+    finally:
+      close(f)
+
+
+The statements after the ``try`` are executed in sequential order unless
+an exception ``e`` is raised. If the exception type of ``e`` matches any
+listed in an ``except`` clause the corresponding statements are executed.
+The statements following the ``except`` clauses are called
+`exception handlers`:idx:.
+
+The empty `except`:idx: clause is executed if there is an exception that is
+not listed otherwise. It is similar to an ``else`` clause in ``if`` statements.
+
+If there is a `finally`:idx: clause, it is always executed after the
+exception handlers.
+
+The exception is *consumed* in an exception handler. However, an
+exception handler may raise another exception. If the exception is not
+handled, it is propagated through the call stack. This means that often
+the rest of the procedure - that is not within a ``finally`` clause -
+is not executed (if an exception occurs).
+
+
+Except and finally statements
+-----------------------------
+
+``except`` and ``finally`` can also be used as a stand-alone statements.
+Any statements following them in the current block will be considered to be 
+in an implicit try block:
+
+.. code-block:: nim
+  var f = open("numbers.txt")
+  finally: close(f)
+  ...
+
+The ``except`` statement has a limitation in this form: one can't specify the
+type of the exception, one has to catch everything. Also, if one wants to use
+both ``finally`` and ``except`` one needs to reverse the usual sequence of the
+statements. Example:
+
+.. code-block:: nim
+  proc test() =
+    raise newException(Exception, "Hey ho")
+  
+  proc tester() =
+    finally: echo "3. Finally block"
+    except: echo "2. Except block"
+    echo "1. Pre exception"
+    test()
+    echo "4. Post exception"
+  # --> 1, 2, 3 is printed, 4 is never reached
+
+
+Raise statement
+---------------
+
+Example:
+
+.. code-block:: nim
+  raise newEOS("operating system failed")
+
+Apart from built-in operations like array indexing, memory allocation, etc.
+the ``raise`` statement is the only way to raise an exception.
+
+.. XXX document this better!
+
+If no exception name is given, the current exception is `re-raised`:idx:. The
+`ReraiseError`:idx: exception is raised if there is no exception to
+re-raise. It follows that the ``raise`` statement *always* raises an
+exception (unless a raise hook has been provided).
+
+
+onRaise builtin
+---------------
+
+`system.onRaise() `_ can be used to override the
+behaviour of ``raise`` for a single ``try`` statement. ``onRaise`` has to be
+called within the ``try`` statement that should be affected.
+
+This allows for a Lisp-like `condition system`:idx:\:
+
+.. code-block:: nim
+  var myFile = open("broken.txt", fmWrite)
+  try:
+    onRaise do (e: ref Exception)-> bool:
+      if e of IOError:
+        stdout.writeln "ok, writing to stdout instead"
+      else:
+        # do raise other exceptions:
+        result = true
+    myFile.writeln "writing to broken file"
+  finally:
+    myFile.close()
+
+``onRaise`` can only *filter* raised exceptions, it cannot transform one
+exception into another. (Nor should ``onRaise`` raise an exception though 
+this is currently not enforced.) This restriction keeps the exception tracking
+analysis sound.
+
+
+Exception hierarchy
+-------------------
+
+The exception tree is defined in the `system `_ module:
+
+.. include:: exception_hierarchy_fragment.txt
diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt
new file mode 100644
index 000000000..0ad4ebba9
--- /dev/null
+++ b/doc/manual/ffi.txt
@@ -0,0 +1,209 @@
+Foreign function interface
+==========================
+
+Nim's `FFI`:idx: (foreign function interface) is extensive and only the
+parts that scale to other future backends (like the LLVM/JavaScript backends)
+are documented here.
+
+
+Importc pragma
+--------------
+The ``importc`` pragma provides a means to import a proc or a variable
+from C. The optional argument is a string containing the C identifier. If
+the argument is missing, the C name is the Nim identifier *exactly as
+spelled*:
+
+.. code-block::
+  proc printf(formatstr: cstring) {.header: "", importc: "printf", varargs.}
+
+Note that this pragma is somewhat of a misnomer: Other backends will provide
+the same feature under the same name. Also, if one is interfacing with C++
+the `ImportCpp pragma `_ and
+interfacing with Objective-C the `ImportObjC pragma
+`_ can be used.
+
+
+Exportc pragma
+--------------
+The ``exportc`` pragma provides a means to export a type, a variable, or a
+procedure to C. Enums and constants can't be exported. The optional argument
+is a string containing the C identifier.  If the argument is missing, the C
+name is the Nim identifier *exactly as spelled*:
+
+.. code-block:: Nim
+  proc callme(formatstr: cstring) {.exportc: "callMe", varargs.}
+
+Note that this pragma is somewhat of a misnomer: Other backends will provide
+the same feature under the same name.
+
+
+Extern pragma
+-------------
+Like ``exportc`` or ``importc``, the ``extern`` pragma affects name
+mangling. The string literal passed to ``extern`` can be a format string:
+
+.. code-block:: Nim
+  proc p(s: string) {.extern: "prefix$1".} =
+    echo s
+
+In the example the external name of ``p`` is set to ``prefixp``.
+
+
+Bycopy pragma
+-------------
+
+The ``bycopy`` pragma can be applied to an object or tuple type and
+instructs the compiler to pass the type by value to procs:
+
+.. code-block:: nim
+  type
+    TVector {.bycopy, pure.} = object
+      x, y, z: float
+
+
+Byref pragma
+------------
+
+The ``byref`` pragma can be applied to an object or tuple type and instructs
+the compiler to pass the type by reference (hidden pointer) to procs.
+
+
+Varargs pragma
+--------------
+The ``varargs`` pragma can be applied to procedures only (and procedure 
+types). It tells Nim that the proc can take a variable number of parameters 
+after the last specified parameter. Nim string values will be converted to C
+strings automatically:
+
+.. code-block:: Nim
+  proc printf(formatstr: cstring) {.nodecl, varargs.}
+
+  printf("hallo %s", "world") # "world" will be passed as C string
+
+
+Union pragma
+------------
+The ``union`` pragma can be applied to any ``object`` type. It means all
+of the object's fields are overlaid in memory. This produces a ``union``
+instead of a ``struct`` in the generated C/C++ code. The object declaration
+then must not use inheritance or any GC'ed memory but this is currently not
+checked.
+
+**Future directions**: GC'ed memory should be allowed in unions and the GC
+should scan unions conservatively.
+
+Packed pragma
+-------------
+The ``packed`` pragma can be applied to any ``object`` type. It ensures 
+that the fields of an object are packed back-to-back in memory. It is useful 
+to store packets or messages from/to network or hardware drivers, and for 
+interoperability with C. Combining packed pragma with inheritance is not 
+defined, and it should not be used with GC'ed memory (ref's).  
+
+**Future directions**: Using GC'ed memory in packed pragma will result in 
+compile-time error. Usage with inheritance should be defined and documented.
+
+Unchecked pragma
+----------------
+The ``unchecked`` pragma can be used to mark a named array as ``unchecked``
+meaning its bounds are not checked. This is often useful when one wishes to
+implement his own flexibly sized arrays. Additionally an unchecked array is
+translated into a C array of undetermined size:
+
+.. code-block:: nim
+  type
+    ArrayPart{.unchecked.} = array[0..0, int]
+    MySeq = object
+      len, cap: int
+      data: ArrayPart
+
+Produces roughly this C code:
+
+.. code-block:: C
+  typedef struct {
+    NI len;
+    NI cap;
+    NI data[];
+  } MySeq;
+
+The bounds checking done at compile time is not disabled for now, so to access
+``s.data[C]`` (where ``C`` is a constant) the array's index needs needs to
+include ``C``.
+
+The base type of the unchecked array may not contain any GC'ed memory but this
+is currently not checked.
+
+**Future directions**: GC'ed memory should be allowed in unchecked arrays and
+there should be an explicit annotation of how the GC is to determine the
+runtime size of the array.
+
+
+Dynlib pragma for import
+------------------------
+With the ``dynlib`` pragma a procedure or a variable can be imported from
+a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). 
+The non-optional argument has to be the name of the dynamic library:
+
+.. code-block:: Nim
+  proc gtk_image_new(): PGtkWidget
+    {.cdecl, dynlib: "libgtk-x11-2.0.so", importc.}
+
+In general, importing a dynamic library does not require any special linker
+options or linking with import libraries. This also implies that no *devel*
+packages need to be installed.
+
+The ``dynlib`` import mechanism supports a versioning scheme: 
+
+.. code-block:: nim 
+  proc Tcl_Eval(interp: pTcl_Interp, script: cstring): int {.cdecl, 
+    importc, dynlib: "libtcl(|8.5|8.4|8.3).so.(1|0)".}
+
+At runtime the dynamic library is searched for (in this order)::
+  
+  libtcl.so.1
+  libtcl.so.0
+  libtcl8.5.so.1  
+  libtcl8.5.so.0
+  libtcl8.4.so.1
+  libtcl8.4.so.0
+  libtcl8.3.so.1
+  libtcl8.3.so.0
+
+The ``dynlib`` pragma supports not only constant strings as argument but also
+string expressions in general:
+
+.. code-block:: nim
+  import os
+
+  proc getDllName: string = 
+    result = "mylib.dll"
+    if existsFile(result): return
+    result = "mylib2.dll"
+    if existsFile(result): return
+    quit("could not load dynamic library")
+  
+  proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}
+
+**Note**: Patterns like ``libtcl(|8.5|8.4).so`` are only supported in constant
+strings, because they are precompiled.
+
+**Note**: Passing variables to the ``dynlib`` pragma will fail at runtime 
+because of order of initialization problems.
+
+**Note**: A ``dynlib`` import can be overriden with 
+the ``--dynlibOverride:name`` command line option. The Compiler User Guide
+contains further information.
+
+
+Dynlib pragma for export
+------------------------
+
+With the ``dynlib`` pragma a procedure can also be exported to
+a dynamic library. The pragma then has no argument and has to be used in
+conjunction with the ``exportc`` pragma:
+
+.. code-block:: Nim
+  proc exportme(): int {.cdecl, exportc, dynlib.}
+
+This is only useful if the program is compiled as a dynamic library via the
+``--app:lib`` command line option.
diff --git a/doc/manual/generics.txt b/doc/manual/generics.txt
new file mode 100644
index 000000000..6f1b2ee0d
--- /dev/null
+++ b/doc/manual/generics.txt
@@ -0,0 +1,346 @@
+Generics
+========
+
+Generics are Nim's means to parametrize procs, iterators or types with
+`type parameters`:idx:. Depending on context, the brackets are used either to
+introduce type parameters or to instantiate a generic proc, iterator or type.
+
+The following example shows a generic binary tree can be modelled:
+
+.. code-block:: nim
+  type
+    TBinaryTree[T] = object      # TBinaryTree is a generic type with
+                                 # with generic param ``T``
+      le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil
+      data: T                    # the data stored in a node
+    PBinaryTree[T] = ref TBinaryTree[T] # a shorthand for notational convenience
+
+  proc newNode[T](data: T): PBinaryTree[T] = # constructor for a node
+    new(result)
+    result.data = data
+
+  proc add[T](root: var PBinaryTree[T], n: PBinaryTree[T]) =
+    if root == nil:
+      root = n
+    else:
+      var it = root
+      while it != nil:
+        var c = cmp(it.data, n.data) # compare the data items; uses
+                                     # the generic ``cmp`` proc that works for
+                                     # any type that has a ``==`` and ``<``
+                                     # operator
+        if c < 0:
+          if it.le == nil:
+            it.le = n
+            return
+          it = it.le
+        else:
+          if it.ri == nil:
+            it.ri = n
+            return
+          it = it.ri
+
+  iterator inorder[T](root: PBinaryTree[T]): T =
+    # inorder traversal of a binary tree
+    # recursive iterators are not yet implemented, so this does not work in
+    # the current compiler!
+    if root.le != nil: yield inorder(root.le)
+    yield root.data
+    if root.ri != nil: yield inorder(root.ri)
+
+  var
+    root: PBinaryTree[string] # instantiate a PBinaryTree with the type string
+  add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and
+  add(root, newNode("world")) # ``add``
+  for str in inorder(root):
+    writeln(stdout, str)
+
+
+Is operator
+-----------
+
+The ``is`` operator checks for type equivalence at compile time. It is
+therefore very useful for type specialization within generic code: 
+
+.. code-block:: nim
+  type
+    TTable[TKey, TValue] = object
+      keys: seq[TKey]
+      values: seq[TValue]
+      when not (TKey is string): # nil value for strings used for optimization
+        deletedKeys: seq[bool]
+
+
+Type operator
+-------------
+
+The ``type`` (in many other languages called `typeof`:idx:) operator can
+be used to get the type of an expression: 
+
+.. code-block:: nim
+  var x = 0
+  var y: type(x) # y has type int
+
+If ``type`` is used to determine the result type of a proc/iterator/converter
+call ``c(X)`` (where ``X`` stands for a possibly empty list of arguments), the
+interpretation where ``c`` is an iterator is preferred over the
+other interpretations:
+
+.. code-block:: nim
+  import strutils
+  
+  # strutils contains both a ``split`` proc and iterator, but since an
+  # an iterator is the preferred interpretation, `y` has the type ``string``:
+  var y: type("a b c".split)
+
+
+Type Classes
+------------
+
+A type class is a special pseudo-type that can be used to match against
+types in the context of overload resolution or the ``is`` operator. 
+Nim supports the following built-in type classes:
+
+==================   ===================================================
+type class           matches
+==================   ===================================================
+``object``           any object type
+``tuple``            any tuple type
+
+``enum``             any enumeration
+``proc``             any proc type
+``ref``              any ``ref`` type
+``ptr``              any ``ptr`` type
+``var``              any ``var`` type
+``distinct``         any distinct type
+``array``            any array type
+``set``              any set type
+``seq``              any seq type
+``auto``             any type 
+==================   ===================================================
+
+Furthermore, every generic type automatically creates a type class of the same
+name that will match any instantiation of the generic type.
+
+Type classes can be combined using the standard boolean operators to form
+more complex type classes:
+
+.. code-block:: nim
+  # create a type class that will match all tuple and object types
+  type TRecordType = tuple or object
+
+  proc printFields(rec: TRecordType) =
+    for key, value in fieldPairs(rec):
+      echo key, " = ", value
+
+Procedures utilizing type classes in such manner are considered to be
+`implicitly generic`:idx:. They will be instantiated once for each unique 
+combination of param types used within the program.
+
+Nim also allows for type classes and regular types to be specified
+as `type constraints`:idx: of the generic type parameter:
+
+.. code-block:: nim
+  proc onlyIntOrString[T: int|string](x, y: T) = discard
+  
+  onlyIntOrString(450, 616) # valid
+  onlyIntOrString(5.0, 0.0) # type mismatch
+  onlyIntOrString("xy", 50) # invalid as 'T' cannot be both at the same time
+
+By default, during overload resolution each named type class will bind to
+exactly one concrete type. Here is an example taken directly from the system
+module to illustrate this:
+
+.. code-block:: nim
+  proc `==`*(x, y: tuple): bool = 
+    ## requires `x` and `y` to be of the same tuple type
+    ## generic ``==`` operator for tuples that is lifted from the components
+    ## of `x` and `y`.
+    result = true
+    for a, b in fields(x, y):
+      if a != b: result = false
+
+Alternatively, the ``distinct`` type modifier can be applied to the type class 
+to allow each param matching the type class to bind to a different type. 
+
+If a proc param doesn't have a type specified, Nim will use the
+``distinct auto`` type class (also known as ``any``):
+
+.. code-block:: nim
+  # allow any combination of param types
+  proc concat(a, b): string = $a & $b
+
+Procs written with the implicitly generic style will often need to refer to the
+type parameters of the matched generic type. They can be easily accessed using
+the dot syntax:
+
+.. code-block:: nim
+  type TMatrix[T, Rows, Columns] = object
+    ...
+
+  proc `[]`(m: TMatrix, row, col: int): TMatrix.T = 
+    m.data[col * high(TMatrix.Columns) + row]
+
+Alternatively, the `type` operator can be used over the proc params for similar
+effect when anonymous or distinct type classes are used.
+
+When a generic type is instantiated with a type class instead of a concrete
+type, this results in another more specific type class:
+
+.. code-block:: nim
+  seq[ref object]  # Any sequence storing references to any object type
+  
+  type T1 = auto
+  proc foo(s: seq[T1], e: T1)
+    # seq[T1] is the same as just `seq`, but T1 will be allowed to bind
+    # to a single type, while the signature is being matched
+
+  TMatrix[Ordinal] # Any TMatrix instantiation using integer values
+
+As seen in the previous example, in such instantiations, it's not necessary to
+supply all type parameters of the generic type, because any missing ones will
+be inferred to have the equivalent of the `any` type class and thus they will
+match anything without discrimination.
+
+
+User defined type classes
+-------------------------
+
+**Note**: User defined type classes are still in development.
+
+The user-defined type classes are available in two flavours - declarative and
+imperative. Both are used to specify an arbitrary set of requirements that the
+matched type must satisfy.
+
+Declarative type classes are written in the following form:
+
+.. code-block:: nim
+  type
+    Comparable = generic x, y
+      (x < y) is bool
+
+    Container[T] = generic c
+      c.len is ordinal
+      items(c) is iterator
+      for value in c:
+        type(value) is T
+
+The type class will be matched if:
+
+a) all of the expressions within the body can be compiled for the tested type
+b) all statically evaluatable boolean expressions in the body must be true
+
+The identifiers following the `generic` keyword represent instances of the
+currently matched type. These instances can act both as variables of the type,
+when used in contexts where a value is expected, and as the type itself when
+used in contexts where a type is expected.
+
+Please note that the ``is`` operator allows one to easily verify the precise
+type signatures of the required operations, but since type inference and
+default parameters are still applied in the provided block, it's also possible
+to encode usage protocols that do not reveal implementation details.
+
+As a special rule providing further convenience when writing type classes, any
+type value appearing in a callable expression will be treated as a variable of
+the designated type for overload resolution purposes, unless the type value was
+passed in its explicit ``typedesc[T]`` form:
+
+.. code-block:: nim
+  type
+    OutputStream = generic S
+      write(var S, string)
+
+Much like generics, the user defined type classes will be instantiated exactly
+once for each tested type and any static code included within them will also be
+executed once.
+
+
+Type inference with type classes
+--------------------------------
+
+If a type class is used as the return type of a proc and it won't be bound to
+a concrete type by some of the proc params, Nim will infer the return type
+from the proc body. This is usually used with the ``auto`` type class:
+
+.. code-block:: nim
+  proc makePair(a, b): auto = (first: a, second: b)
+
+The return type will be treated as an additional generic param and can be
+explicitly specified at call sites as any other generic param.
+
+Future versions of Nim may also support overloading based on the return type
+of the overloads. In such settings, the expected result type at call sites may 
+also influence the inferred return type.
+
+..
+  Likewise, if a type class is used in another position where Nim expects a
+  concrete type (e.g. a variable declaration or a type coercion), Nim will try
+  to infer the concrete type by applying the matching algorithm that also used
+  in overload resolution.
+
+
+Symbol lookup in generics
+-------------------------
+
+The symbol binding rules in generics are slightly subtle: There are "open" and
+"closed" symbols. A "closed" symbol cannot be re-bound in the instantiation
+context, an "open" symbol can. Per default overloaded symbols are open
+and every other symbol is closed.
+
+Open symbols are looked up in two different contexts: Both the context
+at definition and the context at instantiation are considered:
+
+.. code-block:: nim
+  type
+    TIndex = distinct int
+  
+  proc `==` (a, b: TIndex): bool {.borrow.}
+  
+  var a = (0, 0.TIndex)
+  var b = (0, 0.TIndex)
+  
+  echo a == b # works!
+
+In the example the generic ``==`` for tuples (as defined in the system module)
+uses the ``==`` operators of the tuple's components. However, the ``==`` for
+the ``TIndex`` type is defined *after* the ``==`` for tuples; yet the example
+compiles as the instantiation takes the currently defined symbols into account
+too.
+
+A symbol can be forced to be open by a `mixin`:idx: declaration: 
+
+.. code-block:: nim
+  proc create*[T](): ref T =
+    # there is no overloaded 'init' here, so we need to state that it's an
+    # open symbol explicitly:
+    mixin init
+    new result
+    init result
+
+
+Bind statement
+--------------
+
+The ``bind`` statement is the counterpart to the ``mixin`` statement. It 
+can be used to explicitly declare identifiers that should be bound early (i.e.
+the identifiers should be looked up in the scope of the template/generic
+definition):
+
+.. code-block:: nim
+  # Module A
+  var 
+    lastId = 0
+  
+  template genId*: expr =
+    bind lastId
+    inc(lastId)
+    lastId
+
+.. code-block:: nim
+  # Module B
+  import A
+  
+  echo genId()
+
+But a ``bind`` is rarely useful because symbol binding from the definition
+scope is the default.
diff --git a/doc/manual/lexing.txt b/doc/manual/lexing.txt
new file mode 100644
index 000000000..c3894b13d
--- /dev/null
+++ b/doc/manual/lexing.txt
@@ -0,0 +1,356 @@
+Lexical Analysis
+================
+
+Encoding
+--------
+
+All Nim source files are in the UTF-8 encoding (or its ASCII subset). Other
+encodings are not supported. Any of the standard platform line termination
+sequences can be used - the Unix form using ASCII LF (linefeed), the Windows
+form using the ASCII sequence CR LF (return followed by linefeed), or the old
+Macintosh form using the ASCII CR (return) character. All of these forms can be
+used equally, regardless of platform.
+
+
+Indentation
+-----------
+
+Nim's standard grammar describes an `indentation sensitive`:idx: language.
+This means that all the control structures are recognized by indentation.
+Indentation consists only of spaces; tabulators are not allowed.
+
+The indentation handling is implemented as follows: The lexer annotates the
+following token with the preceding number of spaces; indentation is not
+a separate token. This trick allows parsing of Nim with only 1 token of
+lookahead.
+
+The parser uses a stack of indentation levels: the stack consists of integers
+counting the spaces. The indentation information is queried at strategic 
+places in the parser but ignored otherwise: The pseudo terminal ``IND{>}``
+denotes an indentation that consists of more spaces than the entry at the top
+of the stack; IND{=} an indentation that has the same number of spaces. ``DED``
+is another pseudo terminal that describes the *action* of popping a value
+from the stack, ``IND{>}`` then implies to push onto the stack.
+
+With this notation we can now easily define the core of the grammar: A block of
+statements (simplified example)::
+
+  ifStmt = 'if' expr ':' stmt
+           (IND{=} 'elif' expr ':' stmt)* 
+           (IND{=} 'else' ':' stmt)?
+
+  simpleStmt = ifStmt / ...
+
+  stmt = IND{>} stmt ^+ IND{=} DED  # list of statements
+       / simpleStmt                 # or a simple statement
+
+
+
+Comments
+--------
+
+Comments start anywhere outside a string or character literal with the
+hash character ``#``.
+Comments consist of a concatenation of `comment pieces`:idx:. A comment piece
+starts with ``#`` and runs until the end of the line. The end of line characters
+belong to the piece. If the next line only consists of a comment piece with
+no other tokens between it and the preceding one, it does not start a new
+comment:
+
+
+.. code-block:: nim
+  i = 0     # This is a single comment over multiple lines.
+    # The scanner merges these two pieces.
+    # The comment continues here.
+
+
+`Documentation comments`:idx: are comments that start with two ``##``.
+Documentation comments are tokens; they are only allowed at certain places in
+the input file as they belong to the syntax tree!
+
+
+Identifiers & Keywords
+----------------------
+
+Identifiers in Nim can be any string of letters, digits
+and underscores, beginning with a letter. Two immediate following
+underscores ``__`` are not allowed::
+
+  letter ::= 'A'..'Z' | 'a'..'z' | '\x80'..'\xff'
+  digit ::= '0'..'9'
+  IDENTIFIER ::= letter ( ['_'] (letter | digit) )*
+
+Currently any unicode character with an ordinal value > 127 (non ASCII) is
+classified as a ``letter`` and may thus be part of an identifier but later
+versions of the language may assign some Unicode characters to belong to the
+operator characters instead.
+
+The following keywords are reserved and cannot be used as identifiers:
+
+.. code-block:: nim
+   :file: keywords.txt
+
+Some keywords are unused; they are reserved for future developments of the
+language.
+
+Nim is a `style-insensitive`:idx: language. This means that it is not
+case-sensitive and even underscores are ignored:
+**type** is a reserved word, and so is **TYPE** or **T_Y_P_E**. The idea behind
+this is that this allows programmers to use their own preferred spelling style
+and libraries written by different programmers cannot use incompatible
+conventions. A Nim-aware editor or IDE can show the identifiers as
+preferred. Another advantage is that it frees the programmer from remembering
+the exact spelling of an identifier.
+
+
+String literals
+---------------
+
+Terminal symbol in the grammar: ``STR_LIT``.
+
+String literals can be delimited by matching double quotes, and can
+contain the following `escape sequences`:idx:\ :
+
+==================         ===================================================
+  Escape sequence          Meaning
+==================         ===================================================
+  ``\n``                   `newline`:idx:
+  ``\r``, ``\c``           `carriage return`:idx:
+  ``\l``                   `line feed`:idx:
+  ``\f``                   `form feed`:idx:
+  ``\t``                   `tabulator`:idx:
+  ``\v``                   `vertical tabulator`:idx:
+  ``\\``                   `backslash`:idx:
+  ``\"``                   `quotation mark`:idx:
+  ``\'``                   `apostrophe`:idx:
+  ``\`` '0'..'9'+          `character with decimal value d`:idx:;
+                           all decimal digits directly
+                           following are used for the character
+  ``\a``                   `alert`:idx:
+  ``\b``                   `backspace`:idx:
+  ``\e``                   `escape`:idx: `[ESC]`:idx:
+  ``\x`` HH                `character with hex value HH`:idx:;
+                           exactly two hex digits are allowed
+==================         ===================================================
+
+
+Strings in Nim may contain any 8-bit value, even embedded zeros. However 
+some operations may interpret the first binary zero as a terminator.
+
+
+Triple quoted string literals
+-----------------------------
+
+Terminal symbol in the grammar: ``TRIPLESTR_LIT``.
+
+String literals can also be delimited by three double quotes
+``"""`` ... ``"""``.
+Literals in this form may run for several lines, may contain ``"`` and do not
+interpret any escape sequences.
+For convenience, when the opening ``"""`` is followed by a newline (there may
+be whitespace between the opening ``"""`` and the newline),
+the newline (and the preceding whitespace) is not included in the string. The
+ending of the string literal is defined by the pattern ``"""[^"]``, so this:
+
+.. code-block:: nim 
+  """"long string within quotes""""
+
+Produces::
+
+  "long string within quotes"
+
+
+Raw string literals
+-------------------
+
+Terminal symbol in the grammar: ``RSTR_LIT``.
+
+There are also raw string literals that are preceded with the 
+letter ``r`` (or ``R``) and are delimited by matching double quotes (just 
+like ordinary string literals) and do not interpret the escape sequences. 
+This is especially convenient for regular expressions or Windows paths:
+
+.. code-block:: nim
+
+  var f = openFile(r"C:\texts\text.txt") # a raw string, so ``\t`` is no tab
+
+To produce a single ``"`` within a raw string literal, it has to be doubled:
+
+.. code-block:: nim
+
+  r"a""b"
+  
+Produces::
+  
+  a"b
+
+``r""""`` is not possible with this notation, because the three leading 
+quotes introduce a triple quoted string literal. ``r"""`` is the same 
+as ``"""`` since triple quoted string literals do not interpret escape 
+sequences either.
+
+
+Generalized raw string literals
+-------------------------------
+
+Terminal symbols in the grammar: ``GENERALIZED_STR_LIT``, 
+``GENERALIZED_TRIPLESTR_LIT``.
+
+The construct ``identifier"string literal"`` (without whitespace between the
+identifier and the opening quotation mark) is a
+generalized raw string literal. It is a shortcut for the construct
+``identifier(r"string literal")``, so it denotes a procedure call with a
+raw string literal as its only argument. Generalized raw string literals
+are especially convenient for embedding mini languages directly into Nim
+(for example regular expressions).
+
+The construct ``identifier"""string literal"""`` exists too. It is a shortcut
+for ``identifier("""string literal""")``.
+
+
+Character literals
+------------------
+
+Character literals are enclosed in single quotes ``''`` and can contain the
+same escape sequences as strings - with one exception: `newline`:idx: (``\n``)
+is not allowed as it may be wider than one character (often it is the pair
+CR/LF for example).  Here are the valid `escape sequences`:idx: for character
+literals:
+
+==================         ===================================================
+  Escape sequence          Meaning
+==================         ===================================================
+  ``\r``, ``\c``           `carriage return`:idx:
+  ``\l``                   `line feed`:idx:
+  ``\f``                   `form feed`:idx:
+  ``\t``                   `tabulator`:idx:
+  ``\v``                   `vertical tabulator`:idx:
+  ``\\``                   `backslash`:idx:
+  ``\"``                   `quotation mark`:idx:
+  ``\'``                   `apostrophe`:idx:
+  ``\`` '0'..'9'+          `character with decimal value d`:idx:;
+                           all decimal digits directly
+                           following are used for the character
+  ``\a``                   `alert`:idx:
+  ``\b``                   `backspace`:idx:
+  ``\e``                   `escape`:idx: `[ESC]`:idx:
+  ``\x`` HH                `character with hex value HH`:idx:;
+                           exactly two hex digits are allowed
+==================         ===================================================
+
+A character is not an Unicode character but a single byte. The reason for this
+is efficiency: for the overwhelming majority of use-cases, the resulting
+programs will still handle UTF-8 properly as UTF-8 was specially designed for
+this. Another reason is that Nim can thus support ``array[char, int]`` or
+``set[char]`` efficiently as many algorithms rely on this feature.  The `TRune`
+type is used for Unicode characters, it can represent any Unicode character.
+``TRune`` is declared in the `unicode module `_.
+
+
+Numerical constants
+-------------------
+
+Numerical constants are of a single type and have the form::
+
+  hexdigit = digit | 'A'..'F' | 'a'..'f'
+  octdigit = '0'..'7'
+  bindigit = '0'..'1'
+  HEX_LIT = '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )*
+  DEC_LIT = digit ( ['_'] digit )*
+  OCT_LIT = '0o' octdigit ( ['_'] octdigit )*
+  BIN_LIT = '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
+  
+  INT_LIT = HEX_LIT
+          | DEC_LIT
+          | OCT_LIT
+          | BIN_LIT
+
+  INT8_LIT = INT_LIT ['\''] ('i' | 'I') '8'
+  INT16_LIT = INT_LIT ['\''] ('i' | 'I') '16'
+  INT32_LIT = INT_LIT ['\''] ('i' | 'I') '32'
+  INT64_LIT = INT_LIT ['\''] ('i' | 'I') '64'
+
+  UINT8_LIT = INT_LIT ['\''] ('u' | 'U')
+  UINT8_LIT = INT_LIT ['\''] ('u' | 'U') '8'
+  UINT16_LIT = INT_LIT ['\''] ('u' | 'U') '16'
+  UINT32_LIT = INT_LIT ['\''] ('u' | 'U') '32'
+  UINT64_LIT = INT_LIT ['\''] ('u' | 'U') '64'
+
+  exponent = ('e' | 'E' ) ['+' | '-'] digit ( ['_'] digit )*
+  FLOAT_LIT = digit (['_'] digit)* (('.' (['_'] digit)* [exponent]) |exponent)
+  FLOAT32_LIT = HEX_LIT '\'' ('f'|'F') '32'
+              | (FLOAT_LIT | DEC_LIT | OCT_LIT | BIN_LIT) ['\''] ('f'|'F') '32'
+  FLOAT64_LIT = HEX_LIT '\'' ('f'|'F') '64'
+              | (FLOAT_LIT | DEC_LIT | OCT_LIT | BIN_LIT) ['\''] ('f'|'F') '64'
+
+
+As can be seen in the productions, numerical constants can contain underscores
+for readability. Integer and floating point literals may be given in decimal (no
+prefix), binary (prefix ``0b``), octal (prefix ``0o``) and hexadecimal
+(prefix ``0x``) notation.
+
+There exists a literal for each numerical type that is
+defined. The suffix starting with an apostrophe ('\'') is called a
+`type suffix`:idx:. Literals without a type suffix are of the type ``int``,
+unless the literal contains a dot or ``E|e`` in which case it is of
+type ``float``. For notational convenience the apostrophe of a type suffix
+is optional if it is not ambiguous (only hexadecimal floating point literals
+with a type suffix can be ambiguous).
+
+
+The type suffixes are:
+
+=================    =========================
+  Type Suffix        Resulting type of literal
+=================    =========================
+  ``'i8``            int8
+  ``'i16``           int16
+  ``'i32``           int32
+  ``'i64``           int64
+  ``'u``             uint
+  ``'u8``            uint8
+  ``'u16``           uint16
+  ``'u32``           uint32
+  ``'u64``           uint64
+  ``'f32``           float32
+  ``'f64``           float64
+=================    =========================
+
+Floating point literals may also be in binary, octal or hexadecimal
+notation:
+``0B0_10001110100_0000101001000111101011101111111011000101001101001001'f64``
+is approximately 1.72826e35 according to the IEEE floating point standard.
+
+
+Operators
+---------
+
+In Nim one can define his own operators. An operator is any
+combination of the following characters::
+
+       =     +     -     *     /     <     >
+       @     $     ~     &     %     |
+       !     ?     ^     .     :     \
+
+These keywords are also operators:
+``and or not xor shl shr div mod in notin is isnot of``.
+
+`=`:tok:, `:`:tok:, `::`:tok: are not available as general operators; they
+are used for other notational purposes. 
+
+``*:`` is as a special case the two tokens `*`:tok: and `:`:tok:
+(to support ``var v*: T``).
+
+
+Other tokens
+------------
+
+The following strings denote other tokens::
+
+    `   (     )     {     }     [     ]     ,  ;   [.    .]  {.   .}  (.  .)
+
+
+The `slice`:idx: operator `..`:tok: takes precedence over other tokens that 
+contain a dot: `{..}`:tok: are the three tokens `{`:tok:, `..`:tok:, `}`:tok: 
+and not the two tokens `{.`:tok:, `.}`:tok:.
+
diff --git a/doc/manual/locking.txt b/doc/manual/locking.txt
new file mode 100644
index 000000000..b646f0cee
--- /dev/null
+++ b/doc/manual/locking.txt
@@ -0,0 +1,197 @@
+Guards and locks
+================
+
+Apart from ``spawn`` and ``parallel`` Nim also provides all the common low level
+concurrency mechanisms like locks, atomic intristics or condition variables.
+
+Nim significantly improves on the safety of these features via additional
+pragmas:
+
+1) A `guard`:idx: annotation is introduced to prevent data races.
+2) Every access of a guarded memory location needs to happen in an
+   appropriate `locks`:idx: statement.
+3) Locks and routines can be annotated with `lock levels`:idx: to prevent
+   deadlocks at compile time.
+
+Guards and the locks section
+----------------------------
+
+Protecting global variables
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Global variables and object fields can be annotated via an ``guard`` pragma: 
+
+.. code-block:: nim
+  var glock: TLock
+  var gdata {.guard: glock.}: int
+
+The compiler then ensures that every access of ``gdata`` is within a ``locks``
+section:
+
+.. code-block:: nim
+  proc invalid =
+    # invalid: unguarded access:
+    echo gdata
+
+  proc valid =
+    # valid access:
+    {.locks: [glock].}:
+      echo gdata
+
+Top level accesses to ``gdata`` are always allowed so that it can be initialized
+conveniently. It is *assumed* (but not enforced) that every top level statement
+is executed before any concurrent action happens.
+
+The ``locks`` section deliberately looks ugly because it has no runtime
+semantics and should not be used directly! It should only be used in templates
+that also implement some form of locking at runtime:
+
+.. code-block:: nim
+  template lock(a: TLock; body: stmt) =
+    pthread_mutex_lock(a)
+    {.locks: [a].}:
+      try:
+        body
+      finally:
+        pthread_mutex_unlock(a)
+
+
+The guard does not need to be of any particular type. It is flexible enough to
+model low level lockfree mechanisms:
+
+.. code-block:: nim
+  var dummyLock {.compileTime.}: int
+  var atomicCounter {.guard: dummyLock.}: int
+  
+  template atomicRead(x): expr =
+    {.locks: [dummyLock].}:
+      memoryReadBarrier()
+      x
+
+  echo atomicRead(atomicCounter)
+
+
+The ``locks`` pragma takes a list of lock expressions ``locks: [a, b, ...]``
+in order to support *multi lock* statements. Why these are essential is
+explained in the `lock levels`_ section.
+
+
+Protecting general locations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``guard`` annotation can also be used to protect fields within an object.
+The guard then needs to be another field within the same object or a
+global variable.
+
+Since objects can reside on the heap or on the stack this greatly enhances the
+expressivity of the language:
+
+.. code-block:: nim
+  type
+    ProtectedCounter = object
+      v {.guard: L.}: int
+      L: TLock
+
+  proc incCounters(counters: var openArray[ProtectedCounter]) =
+    for i in 0..counters.high:
+      lock counters[i].L:
+        inc counters[i].v
+
+The access to field ``x.v`` is allowed since its guard ``x.L``  is active.
+After template expansion, this amounts to:
+
+.. code-block:: nim
+  proc incCounters(counters: var openArray[ProtectedCounter]) =
+    for i in 0..counters.high:
+      pthread_mutex_lock(counters[i].L)
+      {.locks: [counters[i].L].}:
+        try:
+          inc counters[i].v
+        finally:
+          pthread_mutex_unlock(counters[i].L)
+
+There is an analysis that checks that ``counters[i].L`` is the lock that
+corresponds to the protected location ``counters[i].v``. This analysis is called
+`path analysis`:idx: because it deals with paths to locations
+like ``obj.field[i].fieldB[j]``.
+
+The path analysis is **currently unsound**, but that doesn't make it useless.
+Two paths are considered equivalent if they are syntactically the same.
+
+This means the following compiles (for now) even though it really should not:
+
+.. code-block:: nim
+  {.locks: [a[i].L].}:
+    inc i
+    access a[i].v
+
+
+
+Lock levels
+-----------
+
+Lock levels are used to enforce a global locking order in order to prevent
+deadlocks at compile-time. A lock level is an constant integer in the range
+0..1_000. Lock level 0 means that no lock is acquired at all.
+
+If a section of code holds a lock of level ``M`` than it can also acquire any 
+lock of level ``N < M``. Another lock of level ``M`` cannot be acquired. Locks
+of the same level can only be acquired *at the same time* within a 
+single ``locks`` section:
+
+.. code-block:: nim
+  var a, b: TLock[2]
+  var x: TLock[1]
+  # invalid locking order: TLock[1] cannot be acquired before TLock[2]:
+  {.locks: [x].}: 
+    {.locks: [a].}:
+      ...
+  # valid locking order: TLock[2] acquired before TLock[1]:
+  {.locks: [a].}: 
+    {.locks: [x].}:
+      ...
+
+  # invalid locking order: TLock[2] acquired before TLock[2]:
+  {.locks: [a].}: 
+    {.locks: [b].}:
+      ...
+
+  # valid locking order, locks of the same level acquired at the same time:
+  {.locks: [a, b].}: 
+    ...
+
+
+So here is how a typical multilock statement can be implemented in Nim:
+
+.. code-block:: nim
+  template multilock(a, b: ptr TLock; body: stmt) =
+    if cast[ByteAddress](a) < cast[ByteAddress](b):
+      pthread_mutex_lock(a)
+      pthread_mutex_lock(b)
+    else:
+      pthread_mutex_lock(b)
+      pthread_mutex_lock(a)
+    {.locks: [a, b].}:
+      try:
+        body
+      finally:
+        pthread_mutex_unlock(a)
+        pthread_mutex_unlock(b)
+
+
+Whole routines can also be annotated with a ``locks`` pragma that takes a lock
+level. This then means that the routine may acquire locks of up to this level.
+This is essential so that procs can be called within a ``locks`` section:
+
+.. code-block:: nim
+  proc p() {.locks: 3.} = discard 
+
+  var a: TLock[4]
+  {.locks: [a].}:
+    # p's locklevel (3) is strictly less than a's (4) so the call is allowed:
+    p()
+
+
+As usual ``locks`` is an inferred effect and there is a subtype 
+relation: ``proc () {.locks: N.}`` is a subtype of ``proc () {.locks: M.}``
+iff (M <= N).
diff --git a/doc/manual/modules.txt b/doc/manual/modules.txt
new file mode 100644
index 000000000..f412587db
--- /dev/null
+++ b/doc/manual/modules.txt
@@ -0,0 +1,185 @@
+Modules
+=======
+Nim supports splitting a program into pieces by a module concept.
+Each module needs to be in its own file and has its own `namespace`:idx:.
+Modules enable `information hiding`:idx: and `separate compilation`:idx:.
+A module may gain access to symbols of another module by the `import`:idx:
+statement. `Recursive module dependencies`:idx: are allowed, but slightly
+subtle. Only top-level symbols that are marked with an asterisk (``*``) are
+exported.
+
+The algorithm for compiling modules is:
+
+- compile the whole module as usual, following import statements recursively
+
+- if there is a cycle only import the already parsed symbols (that are
+  exported); if an unknown identifier occurs then abort
+
+This is best illustrated by an example:
+
+.. code-block:: nim
+  # Module A
+  type
+    T1* = int  # Module A exports the type ``T1``
+  import B     # the compiler starts parsing B
+
+  proc main() =
+    var i = p(3) # works because B has been parsed completely here
+
+  main()
+
+
+.. code-block:: nim
+  # Module B
+  import A  # A is not parsed here! Only the already known symbols
+            # of A are imported.
+
+  proc p*(x: A.T1): A.T1 =
+    # this works because the compiler has already
+    # added T1 to A's interface symbol table
+    result = x + 1
+
+
+Import statement
+~~~~~~~~~~~~~~~~
+
+After the ``import`` statement a list of module names can follow or a single
+module name followed by an ``except`` to prevent some symbols to be imported:
+
+.. code-block:: nim
+  import strutils except `%`
+
+  # doesn't work then:
+  echo "$1" % "abc"
+
+
+Module names in imports
+~~~~~~~~~~~~~~~~~~~~~~~
+
+A module alias can be introduced via the ``as`` keyword:
+
+.. code-block:: nim
+  import strutils as su, sequtils as qu
+
+  echo su.format("$1", "lalelu")
+
+The original module name is then not accessible. The 
+notations ``path/to/module`` or ``path.to.module`` or ``"path/to/module"`` 
+can be used to refer to a module in subdirectories:
+
+.. code-block:: nim
+  import lib.pure.strutils, lib/pure/os, "lib/pure/times"
+
+Note that the module name is still ``strutils`` and not ``lib.pure.strutils``
+and so one **cannot** do:
+
+.. code-block:: nim
+  import lib.pure.strutils
+  echo lib.pure.strutils
+
+Likewise the following does not make sense as the name is ``strutils`` already:
+
+.. code-block:: nim
+  import lib.pure.strutils as strutils
+
+
+From import statement
+~~~~~~~~~~~~~~~~~~~~~
+
+After the ``from`` statement a module name follows followed by 
+an ``import`` to list the symbols one likes to use without explict
+full qualification:
+
+.. code-block:: nim
+  from strutils import `%`
+
+  echo "$1" % "abc"
+  # always possible: full qualification:
+  echo strutils.replace("abc", "a", "z")
+
+It's also possible to use ``from module import nil`` if one wants to import 
+the module but wants to enforce fully qualified access to every symbol 
+in ``module``.
+
+
+Export statement
+~~~~~~~~~~~~~~~~
+
+An ``export`` statement can be used for symbol fowarding so that client
+modules don't need to import a module's dependencies:
+
+.. code-block:: nim
+  # module B
+  type TMyObject* = object
+
+.. code-block:: nim
+  # module A
+  import B
+  export B.TMyObject
+  
+  proc `$`*(x: TMyObject): string = "my object"
+
+
+.. code-block:: nim
+  # module C
+  import A
+  
+  # B.TMyObject has been imported implicitly here: 
+  var x: TMyObject
+  echo($x)
+
+
+Scope rules
+-----------
+Identifiers are valid from the point of their declaration until the end of
+the block in which the declaration occurred. The range where the identifier
+is known is the scope of the identifier. The exact scope of an
+identifier depends on the way it was declared.
+
+Block scope
+~~~~~~~~~~~
+The *scope* of a variable declared in the declaration part of a block
+is valid from the point of declaration until the end of the block. If a
+block contains a second block, in which the identifier is redeclared,
+then inside this block, the second declaration will be valid. Upon
+leaving the inner block, the first declaration is valid again. An
+identifier cannot be redefined in the same block, except if valid for
+procedure or iterator overloading purposes.
+
+
+Tuple or object scope
+~~~~~~~~~~~~~~~~~~~~~
+The field identifiers inside a tuple or object definition are valid in the
+following places:
+
+* To the end of the tuple/object definition.
+* Field designators of a variable of the given tuple/object type.
+* In all descendant types of the object type.
+
+Module scope
+~~~~~~~~~~~~
+All identifiers of a module are valid from the point of declaration until
+the end of the module. Identifiers from indirectly dependent modules are *not* 
+available. The `system`:idx: module is automatically imported in every other 
+module.
+
+If a module imports an identifier by two different modules, each occurrence of
+the identifier has to be qualified, unless it is an overloaded procedure or
+iterator in which case the overloading resolution takes place:
+
+.. code-block:: nim
+  # Module A
+  var x*: string
+
+.. code-block:: nim
+  # Module B
+  var x*: int
+
+.. code-block:: nim
+  # Module C
+  import A, B
+  write(stdout, x) # error: x is ambiguous
+  write(stdout, A.x) # no error: qualifier used
+
+  var x = 4
+  write(stdout, x) # not ambiguous: uses the module C's x
diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt
new file mode 100644
index 000000000..1a19cb129
--- /dev/null
+++ b/doc/manual/pragmas.txt
@@ -0,0 +1,477 @@
+Pragmas
+=======
+
+Pragmas are Nim's method to give the compiler additional information /
+commands without introducing a massive number of new keywords. Pragmas are
+processed on the fly during semantic checking. Pragmas are enclosed in the
+special ``{.`` and ``.}`` curly brackets. Pragmas are also often used as a
+first implementation to play with a language feature before a nicer syntax
+to access the feature becomes available.
+
+
+noSideEffect pragma
+-------------------
+The ``noSideEffect`` pragma is used to mark a proc/iterator to have no side
+effects. This means that the proc/iterator only changes locations that are
+reachable from its parameters and the return value only depends on the
+arguments. If none of its parameters have the type ``var T``
+or ``ref T`` or ``ptr T`` this means no locations are modified. It is a static
+error to mark a proc/iterator to have no side effect if the compiler cannot
+verify this.
+
+As a special semantic rule, the built-in `debugEcho `_
+pretends to be free of side effects, so that it can be used for debugging
+routines marked as ``noSideEffect``.
+
+**Future directions**: ``func`` may become a keyword and syntactic sugar for a
+proc with no side effects:
+
+.. code-block:: nim
+  func `+` (x, y: int): int
+
+
+destructor pragma
+-----------------
+
+The ``destructor`` pragma is used to mark a proc to act as a type destructor.
+Its usage is deprecated, use the ``override`` pragma instead.
+See `type bound operations`_.
+
+
+override pragma
+---------------
+
+See `type bound operations`_ instead.
+
+procvar pragma
+--------------
+The ``procvar`` pragma is used to mark a proc that it can be passed to a
+procedural variable.
+
+
+compileTime pragma
+------------------
+The ``compileTime`` pragma is used to mark a proc to be used at compile
+time only. No code will be generated for it. Compile time procs are useful
+as helpers for macros.
+
+
+noReturn pragma
+---------------
+The ``noreturn`` pragma is used to mark a proc that never returns. 
+
+
+acyclic pragma
+--------------
+The ``acyclic`` pragma can be used for object types to mark them as acyclic
+even though they seem to be cyclic. This is an **optimization** for the garbage
+collector to not consider objects of this type as part of a cycle:
+
+.. code-block:: nim
+  type
+    PNode = ref TNode
+    TNode {.acyclic, final.} = object
+      left, right: PNode
+      data: string
+
+In the example a tree structure is declared with the ``TNode`` type. Note that
+the type definition is recursive and the GC has to assume that objects of
+this type may form a cyclic graph. The ``acyclic`` pragma passes the
+information that this cannot happen to the GC. If the programmer uses the
+``acyclic`` pragma for data types that are in reality cyclic, the GC may leak
+memory, but nothing worse happens.
+
+**Future directions**: The ``acyclic`` pragma may become a property of a
+``ref`` type:
+
+.. code-block:: nim
+  type
+    PNode = acyclic ref TNode
+    TNode = object
+      left, right: PNode
+      data: string
+
+
+final pragma
+------------
+The ``final`` pragma can be used for an object type to specify that it
+cannot be inherited from.
+
+
+shallow pragma
+--------------
+The ``shallow`` pragma affects the semantics of a type: The compiler is
+allowed to make a shallow copy. This can cause serious semantic issues and
+break memory safety! However, it can speed up assignments considerably, 
+because the semantics of Nim require deep copying of sequences and strings. 
+This can be expensive, especially if sequences are used to build a tree
+structure: 
+
+.. code-block:: nim
+  type
+    TNodeKind = enum nkLeaf, nkInner
+    TNode {.final, shallow.} = object
+      case kind: TNodeKind
+      of nkLeaf: 
+        strVal: string
+      of nkInner: 
+        children: seq[TNode]
+
+
+pure pragma
+-----------
+An object type can be marked with the ``pure`` pragma so that its type 
+field which is used for runtime type identification is omitted. This used to be
+necessary for binary compatibility with other compiled languages.
+
+An enum type can be marked as ``pure``. Then access of its fields always
+requires full qualification.
+
+
+asmNoStackFrame pragma
+----------------------
+A proc can be marked with the ``AsmNoStackFrame`` pragma to tell the compiler
+it should not generate a stack frame for the proc. There are also no exit
+statements like ``return result;`` generated and the generated C function is
+declared as ``__declspec(naked)`` or ``__attribute__((naked))`` (depending on
+the used C compiler).
+
+**Note**: This pragma should only be used by procs which consist solely of
+assembler statements.
+
+error pragma
+------------
+The ``error`` pragma is used to make the compiler output an error message
+with the given content. Compilation does not necessarily abort after an error
+though. 
+
+The ``error`` pragma can also be used to
+annotate a symbol (like an iterator or proc). The *usage* of the symbol then
+triggers a compile-time error. This is especially useful to rule out that some
+operation is valid due to overloading and type conversions: 
+
+.. code-block:: nim
+  ## check that underlying int values are compared and not the pointers:
+  proc `==`(x, y: ptr int): bool {.error.}
+
+
+fatal pragma
+------------
+The ``fatal`` pragma is used to make the compiler output an error message
+with the given content. In contrast to the ``error`` pragma, compilation
+is guaranteed to be aborted by this pragma. Example:
+
+.. code-block:: nim
+  when not defined(objc):
+    {.fatal: "Compile this program with the objc command!".}
+
+warning pragma
+--------------
+The ``warning`` pragma is used to make the compiler output a warning message
+with the given content. Compilation continues after the warning.
+
+hint pragma
+-----------
+The ``hint`` pragma is used to make the compiler output a hint message with
+the given content. Compilation continues after the hint.
+
+line pragma
+-----------
+The ``line`` pragma can be used to affect line information of the annotated
+statement as seen in stack backtraces:
+
+.. code-block:: nim
+  
+  template myassert*(cond: expr, msg = "") =
+    if not cond:
+      # change run-time line information of the 'raise' statement:
+      {.line: InstantiationInfo().}:
+        raise newException(EAssertionFailed, msg)
+
+If the ``line`` pragma is used with a parameter, the parameter needs be a
+``tuple[filename: string, line: int]``. If it is used without a parameter,
+``system.InstantiationInfo()`` is used.
+
+
+linearScanEnd pragma
+--------------------
+The ``linearScanEnd`` pragma can be used to tell the compiler how to 
+compile a Nim `case`:idx: statement. Syntactically it has to be used as a
+statement:
+
+.. code-block:: nim
+  case myInt
+  of 0: 
+    echo "most common case"
+  of 1: 
+    {.linearScanEnd.}
+    echo "second most common case"
+  of 2: echo "unlikely: use branch table"
+  else: echo "unlikely too: use branch table for ", myInt
+
+In the example, the case branches ``0`` and ``1`` are much more common than 
+the other cases. Therefore the generated assembler code should test for these 
+values first, so that the CPU's branch predictor has a good chance to succeed 
+(avoiding an expensive CPU pipeline stall). The other cases might be put into a
+jump table for O(1) overhead, but at the cost of a (very likely) pipeline
+stall. 
+
+The ``linearScanEnd`` pragma should be put into the last branch that should be
+tested against via linear scanning. If put into the last branch of the
+whole ``case`` statement, the whole ``case`` statement uses linear scanning.
+
+
+computedGoto pragma
+-------------------
+The ``computedGoto`` pragma can be used to tell the compiler how to 
+compile a Nim `case`:idx: in a ``while true`` statement. 
+Syntactically it has to be used as a statement inside the loop:
+
+.. code-block:: nim
+
+  type
+    MyEnum = enum
+      enumA, enumB, enumC, enumD, enumE
+
+  proc vm() =
+    var instructions: array [0..100, MyEnum]
+    instructions[2] = enumC
+    instructions[3] = enumD
+    instructions[4] = enumA
+    instructions[5] = enumD
+    instructions[6] = enumC
+    instructions[7] = enumA
+    instructions[8] = enumB
+
+    instructions[12] = enumE
+    var pc = 0
+    while true:
+      {.computedGoto.}
+      let instr = instructions[pc]
+      case instr
+      of enumA:
+        echo "yeah A"
+      of enumC, enumD:
+        echo "yeah CD"
+      of enumB:
+        echo "yeah B"
+      of enumE:
+        break
+      inc(pc)
+    
+  vm()
+
+As the example shows ``computedGoto`` is mostly useful for interpreters. If
+the underlying backend (C compiler) does not support the computed goto 
+extension the pragma is simply ignored.
+
+
+unroll pragma
+-------------
+The ``unroll`` pragma can be used to tell the compiler that it should unroll
+a `for`:idx: or `while`:idx: loop for runtime efficiency: 
+
+.. code-block:: nim
+  proc searchChar(s: string, c: char): int = 
+    for i in 0 .. s.high:
+      {.unroll: 4.}
+      if s[i] == c: return i
+    result = -1
+
+In the above example, the search loop is unrolled by a factor 4. The unroll
+factor can be left out too; the compiler then chooses an appropriate unroll
+factor.
+
+**Note**: Currently the compiler recognizes but ignores this pragma.
+
+
+immediate pragma
+----------------
+
+See `Ordinary vs immediate templates`_.
+
+
+compilation option pragmas
+--------------------------
+The listed pragmas here can be used to override the code generation options
+for a proc/method/converter.
+
+The implementation currently provides the following possible options (various
+others may be added later).
+
+===============  ===============  ============================================
+pragma           allowed values   description
+===============  ===============  ============================================
+checks           on|off           Turns the code generation for all runtime
+                                  checks on or off.
+boundChecks      on|off           Turns the code generation for array bound
+                                  checks on or off.
+overflowChecks   on|off           Turns the code generation for over- or
+                                  underflow checks on or off.
+nilChecks        on|off           Turns the code generation for nil pointer
+                                  checks on or off.
+assertions       on|off           Turns the code generation for assertions
+                                  on or off.
+warnings         on|off           Turns the warning messages of the compiler
+                                  on or off.
+hints            on|off           Turns the hint messages of the compiler
+                                  on or off.
+optimization     none|speed|size  Optimize the code for speed or size, or
+                                  disable optimization.
+patterns         on|off           Turns the term rewriting templates/macros
+                                  on or off.
+callconv         cdecl|...        Specifies the default calling convention for
+                                  all procedures (and procedure types) that
+                                  follow.
+===============  ===============  ============================================
+
+Example:
+
+.. code-block:: nim
+  {.checks: off, optimization: speed.}
+  # compile without runtime checks and optimize for speed
+
+
+push and pop pragmas
+--------------------
+The `push/pop`:idx: pragmas are very similar to the option directive,
+but are used to override the settings temporarily. Example:
+
+.. code-block:: nim
+  {.push checks: off.}
+  # compile this section without runtime checks as it is
+  # speed critical
+  # ... some code ...
+  {.pop.} # restore old settings
+
+
+register pragma
+---------------
+The ``register`` pragma is for variables only. It declares the variable as
+``register``, giving the compiler a hint that the variable should be placed
+in a hardware register for faster access. C compilers usually ignore this
+though and for good reasons: Often they do a better job without it anyway.
+
+In highly specific cases (a dispatch loop of an bytecode interpreter for
+example) it may provide benefits, though.
+
+
+global pragma
+-------------
+The ``global`` pragma can be applied to a variable within a proc to instruct
+the compiler to store it in a global location and initialize it once at program
+startup.
+
+.. code-block:: nim
+  proc isHexNumber(s: string): bool =
+    var pattern {.global.} = re"[0-9a-fA-F]+"
+    result = s.match(pattern)
+
+When used within a generic proc, a separate unique global variable will be
+created for each instantiation of the proc. The order of initialization of
+the created global variables within a module is not defined, but all of them
+will be initialized after any top-level variables in their originating module
+and before any variable in a module that imports it.
+
+deadCodeElim pragma
+-------------------
+The ``deadCodeElim`` pragma only applies to whole modules: It tells the
+compiler to activate (or deactivate) dead code elimination for the module the
+pragma appears in.
+
+The ``--deadCodeElim:on`` command line switch has the same effect as marking
+every module with ``{.deadCodeElim:on}``. However, for some modules such as
+the GTK wrapper it makes sense to *always* turn on dead code elimination -
+no matter if it is globally active or not.
+
+Example:
+
+.. code-block:: nim
+  {.deadCodeElim: on.}
+
+
+..
+  NoForward pragma
+  ----------------
+  The ``noforward`` pragma can be used to turn on and off a special compilation
+  mode that to large extent eliminates the need for forward declarations. In this
+  mode, the proc definitions may appear out of order and the compiler will postpone
+  their semantic analysis and compilation until it actually needs to generate code
+  using the definitions. In this regard, this mode is similar to the modus operandi
+  of dynamic scripting languages, where the function calls are not resolved until
+  the code is executed. Here is the detailed algorithm taken by the compiler:
+
+  1. When a callable symbol is first encountered, the compiler will only note the
+  symbol callable name and it will add it to the appropriate overload set in the
+  current scope. At this step, it won't try to resolve any of the type expressions
+  used in the signature of the symbol (so they can refer to other not yet defined
+  symbols).
+
+  2. When a top level call is encountered (usually at the very end of the module),
+  the compiler will try to determine the actual types of all of the symbols in the
+  matching overload set. This is a potentially recursive process as the signatures
+  of the symbols may include other call expressions, whoose types will be resolved
+  at this point too.
+
+  3. Finally, after the best overload is picked, the compiler will start compiling
+  the body of the respective symbol. This in turn will lead the compiler to discover
+  more call expresions that need to be resolved and steps 2 and 3 will be repeated
+  as necessary.
+
+  Please note that if a callable symbol is never used in this scenario, its body
+  will never be compiled. This is the default behavior leading to best compilation
+  times, but if exhaustive compilation of all definitions is required, using 
+  ``nim check`` provides this option as well.
+
+  Example:
+
+  .. code-block:: nim
+
+    {.noforward: on.}
+
+    proc foo(x: int) =
+      bar x
+
+    proc bar(x: int) =
+      echo x
+
+    foo(10)
+
+
+pragma pragma
+-------------
+
+The ``pragma`` pragma can be used to declare user defined pragmas. This is 
+useful because Nim's templates and macros do not affect pragmas. User 
+defined pragmas are in a different module-wide scope than all other symbols. 
+They cannot be imported from a module.
+
+Example:
+
+.. code-block:: nim
+  when appType == "lib":
+    {.pragma: rtl, exportc, dynlib, cdecl.}
+  else:
+    {.pragma: rtl, importc, dynlib: "client.dll", cdecl.}
+    
+  proc p*(a, b: int): int {.rtl.} = 
+    result = a+b
+
+In the example a new pragma named ``rtl`` is introduced that either imports
+a symbol from a dynamic library or exports the symbol for dynamic library
+generation.
+
+
+Disabling certain messages
+--------------------------
+Nim generates some warnings and hints ("line too long") that may annoy the
+user. A mechanism for disabling certain messages is provided: Each hint
+and warning message contains a symbol in brackets. This is the message's
+identifier that can be used to enable or disable it:
+
+.. code-block:: Nim
+  {.hint[LineTooLong]: off.} # turn off the hint about too long lines
+
+This is often better than disabling all warnings at once.
+
+
diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt
new file mode 100644
index 000000000..66f9ad58f
--- /dev/null
+++ b/doc/manual/procs.txt
@@ -0,0 +1,554 @@
+Procedures
+==========
+
+What most programming languages call `methods`:idx: or `functions`:idx: are
+called `procedures`:idx: in Nim (which is the correct terminology). A
+procedure declaration defines an identifier and associates it with a block
+of code. 
+A procedure may call itself recursively. A parameter may be given a default
+value that is used if the caller does not provide a value for this parameter.
+
+If the proc declaration has no body, it is a `forward`:idx: declaration. If
+the proc returns a value, the procedure body can access an implicitly declared
+variable named `result`:idx: that represents the return value. Procs can be
+overloaded. The overloading resolution algorithm tries to find the proc that is
+the best match for the arguments. Example:
+
+.. code-block:: nim
+
+  proc toLower(c: Char): Char = # toLower for characters
+    if c in {'A'..'Z'}:
+      result = chr(ord(c) + (ord('a') - ord('A')))
+    else:
+      result = c
+
+  proc toLower(s: string): string = # toLower for strings
+    result = newString(len(s))
+    for i in 0..len(s) - 1:
+      result[i] = toLower(s[i]) # calls toLower for characters; no recursion!
+
+Calling a procedure can be done in many different ways:
+
+.. code-block:: nim
+  proc callme(x, y: int, s: string = "", c: char, b: bool = false) = ...
+
+  # call with positional arguments # parameter bindings:
+  callme(0, 1, "abc", '\t', true)  # (x=0, y=1, s="abc", c='\t', b=true)
+  # call with named and positional arguments:
+  callme(y=1, x=0, "abd", '\t')    # (x=0, y=1, s="abd", c='\t', b=false)
+  # call with named arguments (order is not relevant):
+  callme(c='\t', y=1, x=0)         # (x=0, y=1, s="", c='\t', b=false)
+  # call as a command statement: no () needed:
+  callme 0, 1, "abc", '\t'
+
+
+A procedure cannot modify its parameters (unless the parameters have the type
+`var`).
+
+`Operators`:idx: are procedures with a special operator symbol as identifier:
+
+.. code-block:: nim
+  proc `$` (x: int): string =
+    # converts an integer to a string; this is a prefix operator.
+    result = intToStr(x)
+
+Operators with one parameter are prefix operators, operators with two
+parameters are infix operators. (However, the parser distinguishes these from
+the operator's position within an expression.) There is no way to declare
+postfix operators: all postfix operators are built-in and handled by the
+grammar explicitly.
+
+Any operator can be called like an ordinary proc with the '`opr`'
+notation. (Thus an operator can have more than two parameters):
+
+.. code-block:: nim
+  proc `*+` (a, b, c: int): int =
+    # Multiply and add
+    result = a * b + c
+
+  assert `*+`(3, 4, 6) == `*`(a, `+`(b, c))
+
+
+Method call syntax
+------------------
+
+For object oriented programming, the syntax ``obj.method(args)`` can be used 
+instead of ``method(obj, args)``. The parentheses can be omitted if there are no
+remaining arguments: ``obj.len`` (instead of ``len(obj)``).
+
+This method call syntax is not restricted to objects, it can be used
+to supply any type of first argument for procedures:
+
+.. code-block:: nim
+  
+  echo("abc".len) # is the same as echo(len("abc"))
+  echo("abc".toUpper())
+  echo({'a', 'b', 'c'}.card)
+  stdout.writeln("Hallo") # the same as writeln(stdout, "Hallo")
+
+Another way to look at the method call syntax is that it provides the missing
+postfix notation.
+
+
+Properties
+----------
+Nim has no need for *get-properties*: Ordinary get-procedures that are called
+with the *method call syntax* achieve the same. But setting a value is 
+different; for this a special setter syntax is needed:
+
+.. code-block:: nim
+  
+  type
+    TSocket* = object of TObject
+      FHost: int # cannot be accessed from the outside of the module
+                 # the `F` prefix is a convention to avoid clashes since
+                 # the accessors are named `host`
+
+  proc `host=`*(s: var TSocket, value: int) {.inline.} =
+    ## setter of hostAddr
+    s.FHost = value
+  
+  proc host*(s: TSocket): int {.inline.} =
+    ## getter of hostAddr
+    s.FHost
+
+  var
+    s: TSocket
+  s.host = 34  # same as `host=`(s, 34)
+
+
+Command invocation syntax
+-------------------------
+
+Routines can be invoked without the ``()`` if the call is syntatically
+a statement. This command invocation syntax also works for
+expressions, but then only a single argument may follow. This restriction
+means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as
+``echo(f(1, f(2)))``. The method call syntax may be used to provide one
+more argument in this case:
+
+.. code-block:: nim
+  proc optarg(x:int, y:int = 0):int = x + y
+  proc singlearg(x:int):int = 20*x
+  
+  echo optarg 1, " ", singlearg 2  # prints "1 40"
+  
+  let fail = optarg 1, optarg 8   # Wrong. Too many arguments for a command call
+  let x = optarg(1, optarg 8)  # traditional procedure call with 2 arguments
+  let y = 1.optarg optarg 8    # same thing as above, w/o the parenthesis
+  assert x == y
+
+The command invocation syntax also can't have complex expressions as arguments. 
+For example: (`anonymous procs`_), ``if``, ``case`` or ``try``. The (`do 
+notation`_) is limited, but usable for a single proc (see the example in the 
+corresponding section). Function calls with no arguments still needs () to 
+distinguish between a call and the function itself as a first class value.
+
+
+Closures
+--------
+
+Procedures can appear at the top level in a module as well as inside other
+scopes, in which case they are called nested procs. A nested proc can access
+local variables from its enclosing scope and if it does so it becomes a
+closure. Any captured variables are stored in a hidden additional argument
+to the closure (its environment) and they are accessed by reference by both
+the closure and its enclosing scope (i.e. any modifications made to them are
+visible in both places). The closure environment may be allocated on the heap
+or on the stack if the compiler determines that this would be safe.
+
+
+Anonymous Procs
+---------------
+
+Procs can also be treated as expressions, in which case it's allowed to omit
+the proc's name.
+
+.. code-block:: nim
+  var cities = @["Frankfurt", "Tokyo", "New York"]
+
+  cities.sort(proc (x,y: string): int =
+      cmp(x.len, y.len))
+
+
+Procs as expressions can appear both as nested procs and inside top level 
+executable code.
+
+
+Do notation
+-----------
+
+As a special more convenient notation, proc expressions involved in procedure
+calls can use the ``do`` keyword:
+
+.. code-block:: nim
+  sort(cities) do (x,y: string) -> int:
+    cmp(x.len, y.len)
+  # Less parenthesis using the method plus command syntax:
+  cities = cities.map do (x:string) -> string:  
+    "City of " & x
+
+``do`` is written after the parentheses enclosing the regular proc params. 
+The proc expression represented by the do block is appended to them.
+
+More than one ``do`` block can appear in a single call:
+
+.. code-block:: nim
+  proc performWithUndo(task: proc(), undo: proc()) = ...
+
+  performWithUndo do:
+    # multiple-line block of code
+    # to perform the task
+  do:
+    # code to undo it
+
+For compatibility with ``stmt`` templates and macros, the ``do`` keyword can be
+omitted if the supplied proc doesn't have any parameters and return value. 
+The compatibility works in the other direction too as the ``do`` syntax can be
+used with macros and templates expecting ``stmt`` blocks.
+
+
+Nonoverloadable builtins
+------------------------
+
+The following builtin procs cannot be overloaded for reasons of implementation
+simplicity (they require specialized semantic checking)::
+
+  defined, definedInScope, compiles, low, high, sizeOf, 
+  is, of, echo, shallowCopy, getAst, spawn
+
+Thus they act more like keywords than like ordinary identifiers; unlike a 
+keyword however, a redefinition may `shadow`:idx: the definition in 
+the ``system`` module.
+
+
+Var parameters
+--------------
+The type of a parameter may be prefixed with the ``var`` keyword:
+
+.. code-block:: nim
+  proc divmod(a, b: int; res, remainder: var int) =
+    res = a div b
+    remainder = a mod b
+
+  var
+    x, y: int
+
+  divmod(8, 5, x, y) # modifies x and y
+  assert x == 1
+  assert y == 3
+
+In the example, ``res`` and ``remainder`` are `var parameters`.
+Var parameters can be modified by the procedure and the changes are
+visible to the caller. The argument passed to a var parameter has to be
+an l-value. Var parameters are implemented as hidden pointers. The
+above example is equivalent to:
+
+.. code-block:: nim
+  proc divmod(a, b: int; res, remainder: ptr int) =
+    res[] = a div b
+    remainder[] = a mod b
+
+  var
+    x, y: int
+  divmod(8, 5, addr(x), addr(y))
+  assert x == 1
+  assert y == 3
+
+In the examples, var parameters or pointers are used to provide two
+return values. This can be done in a cleaner way by returning a tuple:
+
+.. code-block:: nim
+  proc divmod(a, b: int): tuple[res, remainder: int] =
+    (a div b, a mod b)
+
+  var t = divmod(8, 5)
+
+  assert t.res == 1
+  assert t.remainder == 3
+
+One can use `tuple unpacking`:idx: to access the tuple's fields:
+
+.. code-block:: nim
+  var (x, y) = divmod(8, 5) # tuple unpacking
+  assert x == 1
+  assert y == 3
+
+
+Var return type
+---------------
+
+A proc, converter or iterator may return a ``var`` type which means that the
+returned value is an l-value and can be modified by the caller:
+
+.. code-block:: nim
+  var g = 0
+
+  proc WriteAccessToG(): var int =
+    result = g
+  
+  WriteAccessToG() = 6
+  assert g == 6
+
+It is a compile time error if the implicitly introduced pointer could be 
+used to access a location beyond its lifetime:
+
+.. code-block:: nim
+  proc WriteAccessToG(): var int =
+    var g = 0
+    result = g # Error!
+
+For iterators, a component of a tuple return type can have a ``var`` type too: 
+
+.. code-block:: nim
+  iterator mpairs(a: var seq[string]): tuple[key: int, val: var string] =
+    for i in 0..a.high:
+      yield (i, a[i])
+
+In the standard library every name of a routine that returns a ``var`` type
+starts with the prefix ``m`` per convention.
+
+
+Overloading of the subscript operator
+-------------------------------------
+
+The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
+
+
+Multi-methods
+=============
+
+Procedures always use static dispatch. Multi-methods use dynamic
+dispatch.
+
+.. code-block:: nim
+  type
+    TExpr = object ## abstract base class for an expression
+    TLiteral = object of TExpr
+      x: int
+    TPlusExpr = object of TExpr
+      a, b: ref TExpr
+      
+  method eval(e: ref TExpr): int =
+    # override this base method
+    quit "to override!"
+  
+  method eval(e: ref TLiteral): int = return e.x
+
+  method eval(e: ref TPlusExpr): int =
+    # watch out: relies on dynamic binding
+    result = eval(e.a) + eval(e.b)
+  
+  proc newLit(x: int): ref TLiteral =
+    new(result)
+    result.x = x
+    
+  proc newPlus(a, b: ref TExpr): ref TPlusExpr =
+    new(result)
+    result.a = a
+    result.b = b
+  
+  echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
+  
+In the example the constructors ``newLit`` and ``newPlus`` are procs
+because they should use static binding, but ``eval`` is a method because it
+requires dynamic binding.
+
+In a multi-method all parameters that have an object type are used for the
+dispatching:
+
+.. code-block:: nim
+  type
+    TThing = object
+    TUnit = object of TThing
+      x: int
+      
+  method collide(a, b: TThing) {.inline.} =
+    quit "to override!"
+    
+  method collide(a: TThing, b: TUnit) {.inline.} =
+    echo "1"
+  
+  method collide(a: TUnit, b: TThing) {.inline.} =
+    echo "2"
+  
+  var
+    a, b: TUnit
+  collide(a, b) # output: 2
+
+
+Invocation of a multi-method cannot be ambiguous: collide 2 is preferred over 
+collide 1 because the resolution works from left to right. 
+In the example ``TUnit, TThing`` is preferred over ``TThing, TUnit``.
+
+**Performance note**: Nim does not produce a virtual method table, but
+generates dispatch trees. This avoids the expensive indirect branch for method
+calls and enables inlining. However, other optimizations like compile time
+evaluation or dead code elimination do not work with methods.
+
+
+Iterators and the for statement
+===============================
+
+The `for`:idx: statement is an abstract mechanism to iterate over the elements
+of a container. It relies on an `iterator`:idx: to do so. Like ``while``
+statements, ``for`` statements open an `implicit block`:idx:, so that they
+can be left with a ``break`` statement. 
+
+The ``for`` loop declares iteration variables - their scope reaches until the
+end of the loop body. The iteration variables' types are inferred by the
+return type of the iterator.
+
+An iterator is similar to a procedure, except that it can be called in the
+context of a ``for`` loop. Iterators provide a way to specify the iteration over
+an abstract type. A key role in the execution of a ``for`` loop plays the
+``yield`` statement in the called iterator. Whenever a ``yield`` statement is
+reached the data is bound to the ``for`` loop variables and control continues
+in the body of the ``for`` loop. The iterator's local variables and execution
+state are automatically saved between calls. Example:
+
+.. code-block:: nim
+  # this definition exists in the system module
+  iterator items*(a: string): char {.inline.} =
+    var i = 0
+    while i < len(a):
+      yield a[i]
+      inc(i)
+
+  for ch in items("hello world"): # `ch` is an iteration variable
+    echo(ch)
+
+The compiler generates code as if the programmer would have written this:
+
+.. code-block:: nim
+  var i = 0
+  while i < len(a):
+    var ch = a[i]
+    echo(ch)
+    inc(i)
+
+If the iterator yields a tuple, there can be as many iteration variables
+as there are components in the tuple. The i'th iteration variable's type is
+the type of the i'th component. In other words, implicit tuple unpacking in a 
+for loop context is supported.
+
+Implict items/pairs invocations
+-------------------------------
+
+If the for loop expression ``e`` does not denote an iterator and the for loop
+has exactly 1 variable, the for loop expression is rewritten to ``items(e)``;
+ie. an ``items`` iterator is implicitly invoked:
+
+.. code-block:: nim
+  for x in [1,2,3]: echo x
+  
+If the for loop has exactly 2 variables, a ``pairs`` iterator is implicitly
+invoked.
+
+Symbol lookup of the identifiers ``items``/``pairs`` is performed after 
+the rewriting step, so that all overloadings of ``items``/``pairs`` are taken
+into account.
+
+
+First class iterators
+---------------------
+
+There are 2 kinds of iterators in Nim: *inline* and *closure* iterators.
+An `inline iterator`:idx: is an iterator that's always inlined by the compiler 
+leading to zero overhead for the abstraction, but may result in a heavy
+increase in code size. Inline iterators are second class citizens;
+They can be passed as parameters only to other inlining code facilities like
+templates, macros and other inline iterators.
+
+In contrast to that, a `closure iterator`:idx: can be passed around more freely:
+
+.. code-block:: nim
+  iterator count0(): int {.closure.} =
+    yield 0
+   
+  iterator count2(): int {.closure.} =
+    var x = 1
+    yield x
+    inc x
+    yield x
+
+  proc invoke(iter: iterator(): int {.closure.}) =
+    for x in iter(): echo x
+
+  invoke(count0)
+  invoke(count2)
+
+Closure iterators have other restrictions than inline iterators:
+
+1. ``yield`` in a closure iterator can not occur in a ``try`` statement.
+2. For now, a closure iterator cannot be evaluated at compile time.
+3. ``return`` is allowed in a closure iterator (but rarely useful).
+4. Both inline and closure iterators cannot be recursive.
+
+Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly
+default to being inline, but that this may change in future versions of the
+implementation.
+
+The ``iterator`` type is always of the calling convention ``closure`` 
+implicitly; the following example shows how to use iterators to implement
+a `collaborative tasking`:idx: system:
+
+.. code-block:: nim
+  # simple tasking:
+  type
+    TTask = iterator (ticker: int)
+
+  iterator a1(ticker: int) {.closure.} =
+    echo "a1: A"
+    yield
+    echo "a1: B"
+    yield
+    echo "a1: C"
+    yield
+    echo "a1: D"
+
+  iterator a2(ticker: int) {.closure.} =
+    echo "a2: A"
+    yield
+    echo "a2: B"
+    yield
+    echo "a2: C"
+
+  proc runTasks(t: varargs[TTask]) =
+    var ticker = 0
+    while true:
+      let x = t[ticker mod t.len]
+      if finished(x): break
+      x(ticker)
+      inc ticker
+
+  runTasks(a1, a2)
+
+The builtin ``system.finished`` can be used to determine if an iterator has
+finished its operation; no exception is raised on an attempt to invoke an
+iterator that has already finished its work.
+
+Closure iterators are *resumable functions* and so one has to provide the
+arguments to every call. To get around this limitation one can capture
+parameters of an outer factory proc:
+
+.. code-block:: nim
+  proc mycount(a, b: int): iterator (): int =
+    result = iterator (): int =
+      var x = a
+      while x <= b:
+        yield x
+        inc x
+
+  let foo = mycount(1, 4)
+
+  for f in foo():
+    echo f
+
+Implicit return type
+--------------------
+
+Since inline interators must always produce values that will be consumed in
+a for loop, the compiler will implicity use the ``auto`` return type if no
+type is given by the user. In contrast, since closure iterators can be used
+as a collaborative tasking system, ``void`` is a valid return type for them.
diff --git a/doc/manual/special_ops.txt b/doc/manual/special_ops.txt
new file mode 100644
index 000000000..46135f129
--- /dev/null
+++ b/doc/manual/special_ops.txt
@@ -0,0 +1,54 @@
+Special Operators
+=================
+
+dot operators
+-------------
+
+Nim offers a special family of dot operators that can be used to
+intercept and rewrite proc call and field access attempts, referring
+to previously undeclared symbol names. They can be used to provide a
+fluent interface to objects lying outside the static confines of the
+type system such as values from dynamic scripting languages
+or dynamic file formats such as JSON or XML.
+
+When Nim encounters an expression that cannot be resolved by the
+standard overload resolution rules, the current scope will be searched
+for a dot operator that can be matched against a re-written form of
+the expression, where the unknown field or proc name is converted to
+an additional static string parameter:
+
+.. code-block:: nim
+  a.b # becomes `.`(a, "b")
+  a.b(c, d) # becomes `.`(a, "b", c, d)
+
+The matched dot operators can be symbols of any callable kind (procs,
+templates and macros), depending on the desired effect:
+
+.. code-block:: nim
+  proc `.` (js: PJsonNode, field: string): JSON = js[field]
+
+  var js = parseJson("{ x: 1, y: 2}")
+  echo js.x # outputs 1
+  echo js.y # outputs 2
+
+The following dot operators are available:
+
+operator `.`
+------------ 
+This operator will be matched against both field accesses and method calls.
+
+operator `.()`
+---------------
+This operator will be matched exclusively against method calls. It has higher
+precedence than the `.` operator and this allows one to handle expressions like
+`x.y` and `x.y()` differently if one is interfacing with a scripting language
+for example.
+
+operator `.=`
+-------------
+This operator will be matched against assignments to missing fields.
+
+.. code-block:: nim
+  a.b = c # becomes `.=`(a, "b", c)
+
+
diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt
new file mode 100644
index 000000000..b706101e1
--- /dev/null
+++ b/doc/manual/stmts.txt
@@ -0,0 +1,647 @@
+Statements and expressions
+==========================
+
+Nim uses the common statement/expression paradigm: Statements do not
+produce a value in contrast to expressions. However, some expressions are 
+statements.
+
+Statements are separated into `simple statements`:idx: and
+`complex statements`:idx:.
+Simple statements are statements that cannot contain other statements like
+assignments, calls or the ``return`` statement; complex statements can
+contain other statements. To avoid the `dangling else problem`:idx:, complex
+statements always have to be intended. The details can be found in the grammar.
+
+
+Statement list expression
+-------------------------
+
+Statements can also occur in an expression context that looks 
+like ``(stmt1; stmt2; ...; ex)``. This is called
+an statement list expression or ``(;)``. The type 
+of ``(stmt1; stmt2; ...; ex)`` is the type of ``ex``. All the other statements
+must be of type ``void``. (One can use ``discard`` to produce a ``void`` type.)
+``(;)`` does not introduce a new scope.
+
+
+Discard statement
+-----------------
+
+Example:
+
+.. code-block:: nim
+  proc p(x, y: int): int = 
+    result = x + y
+
+  discard p(3, 4) # discard the return value of `p`
+
+The ``discard`` statement evaluates its expression for side-effects and
+throws the expression's resulting value away. 
+
+Ignoring the return value of a procedure without using a discard statement is
+a static error.
+
+The return value can be ignored implicitly if the called proc/iterator has
+been declared with the `discardable`:idx: pragma: 
+
+.. code-block:: nim
+  proc p(x, y: int): int {.discardable.} = 
+    result = x + y
+    
+  p(3, 4) # now valid
+
+An empty ``discard`` statement is often used as a null statement:
+
+.. code-block:: nim
+  proc classify(s: string) =
+    case s[0]
+    of SymChars, '_': echo "an identifier"
+    of '0'..'9': echo "a number"
+    else: discard
+
+
+Var statement
+-------------
+
+Var statements declare new local and global variables and
+initialize them. A comma separated list of variables can be used to specify
+variables of the same type:
+
+.. code-block:: nim
+
+  var
+    a: int = 0
+    x, y, z: int
+
+If an initializer is given the type can be omitted: the variable is then of the
+same type as the initializing expression. Variables are always initialized
+with a default value if there is no initializing expression. The default
+value depends on the type and is always a zero in binary.
+
+============================    ==============================================
+Type                            default value
+============================    ==============================================
+any integer type                0
+any float                       0.0
+char                            '\\0'
+bool                            false
+ref or pointer type             nil
+procedural type                 nil
+sequence                        nil (*not* ``@[]``)
+string                          nil (*not* "")
+tuple[x: A, y: B, ...]          (default(A), default(B), ...)
+                                (analogous for objects)
+array[0..., T]                  [default(T), ...]
+range[T]                        default(T); this may be out of the valid range
+T = enum                        cast[T](0); this may be an invalid value
+============================    ==============================================
+
+
+The implicit initialization can be avoided for optimization reasons with the
+`noinit`:idx: pragma: 
+
+.. code-block:: nim
+  var
+    a {.noInit.}: array [0..1023, char] 
+
+If a proc is annotated with the ``noinit`` pragma this refers to its implicit
+``result`` variable:
+
+.. code-block:: nim
+  proc returnUndefinedValue: int {.noinit.} = discard
+
+
+The implicit initialization can be also prevented by the `requiresInit`:idx:
+type pragma. The compiler requires an explicit initialization then. However
+it does a `control flow analysis`:idx: to prove the variable has been 
+initialized and does not rely on syntactic properties:
+
+.. code-block:: nim
+  type
+    TMyObject = object {.requiresInit.}
+    
+  proc p() =
+    # the following is valid:
+    var x: TMyObject
+    if someCondition():
+      x = a()
+    else:
+      x = a()
+    use x
+
+let statement
+-------------
+
+A ``let`` statement declares new local and global `single assignment`:idx:
+variables and binds a value to them. The syntax is the of the ``var`` 
+statement, except that the keyword ``var`` is replaced by the keyword ``let``.
+Let variables are not l-values and can thus not be passed to ``var`` parameters
+nor can their address be taken. They cannot be assigned new values.
+
+For let variables the same pragmas are available as for ordinary variables.
+
+
+Const section
+-------------
+
+`Constants`:idx: are symbols which are bound to a value. The constant's value
+cannot change. The compiler must be able to evaluate the expression in a
+constant declaration at compile time.
+
+Nim contains a sophisticated compile-time evaluator, so procedures which
+have no side-effect can be used in constant expressions too:
+
+.. code-block:: nim
+  import strutils
+  const
+    constEval = contains("abc", 'b') # computed at compile time!
+
+
+The rules for compile-time computability are: 
+
+1. Literals are compile-time computable.
+2. Type conversions are compile-time computable.
+3. Procedure calls of the form ``p(X)`` are compile-time computable if
+   ``p`` is a proc without side-effects (see the `noSideEffect pragma`_ 
+   for details) and if ``X`` is a (possibly empty) list of compile-time 
+   computable arguments.
+
+
+Constants cannot be of type ``ptr``, ``ref``, ``var`` or ``object``, nor can 
+they contain such a type.
+
+
+Static statement/expression
+---------------------------
+
+A static statement/expression can be used to enforce compile 
+time evaluation explicitly. Enforced compile time evaluation can even evaluate
+code that has side effects: 
+
+.. code-block::
+
+  static:
+    echo "echo at compile time"
+
+It's a static error if the compiler cannot perform the evaluation at compile 
+time.
+
+The current implementation poses some restrictions for compile time
+evaluation: Code which contains ``cast`` or makes use of the foreign function
+interface cannot be evaluated at compile time. Later versions of Nim will
+support the FFI at compile time.
+
+
+If statement
+------------
+
+Example:
+
+.. code-block:: nim
+
+  var name = readLine(stdin)
+
+  if name == "Andreas":
+    echo("What a nice name!")
+  elif name == "":
+    echo("Don't you have a name?")
+  else:
+    echo("Boring name...")
+
+The ``if`` statement is a simple way to make a branch in the control flow:
+The expression after the keyword ``if`` is evaluated, if it is true
+the corresponding statements after the ``:`` are executed. Otherwise
+the expression after the ``elif`` is evaluated (if there is an
+``elif`` branch), if it is true the corresponding statements after
+the ``:`` are executed. This goes on until the last ``elif``. If all
+conditions fail, the ``else`` part is executed. If there is no ``else``
+part, execution continues with the statement after the ``if`` statement.
+
+The scoping for an ``if`` statement is slightly subtle to support an important 
+use case. A new scope starts for the ``if``/``elif`` condition and ends after
+the corresponding *then* block:
+
+.. code-block:: nim
+  if {| (let m = input =~ re"(\w+)=\w+"; m.isMatch):
+    echo "key ", m[0], " value ", m[1]  |}
+  elif {| (let m = input =~ re""; m.isMatch):
+    echo "new m in this scope" |}
+  else:
+    # 'm' not declared here
+
+In the example the scopes have been enclosed in ``{|  |}``. 
+
+
+Case statement
+--------------
+
+Example:
+
+.. code-block:: nim
+
+  case readline(stdin)
+  of "delete-everything", "restart-computer":
+    echo("permission denied")
+  of "go-for-a-walk":     echo("please yourself")
+  else:                   echo("unknown command")
+  
+  # indentation of the branches is also allowed; and so is an optional colon
+  # after the selecting expression:
+  case readline(stdin):
+    of "delete-everything", "restart-computer":
+      echo("permission denied")
+    of "go-for-a-walk":     echo("please yourself")
+    else:                   echo("unknown command")
+  
+
+The ``case`` statement is similar to the if statement, but it represents
+a multi-branch selection. The expression after the keyword ``case`` is
+evaluated and if its value is in a *slicelist* the corresponding statements
+(after the ``of`` keyword) are executed. If the value is not in any
+given *slicelist* the ``else`` part is executed. If there is no ``else``
+part and not all possible values that ``expr`` can hold occur in a 
+``slicelist``, a static error occurs. This holds only for expressions of 
+ordinal types. "All possible values" of ``expr`` are determined by ``expr``'s
+type. 
+
+If the expression is not of an ordinal type, and no ``else`` part is
+given, control passes after the ``case`` statement.
+
+To suppress the static error in the ordinal case an ``else`` part with an
+empty ``discard`` statement can be used.
+
+As a special semantic extension, an expression in an ``of`` branch of a case
+statement may evaluate to a set or array constructor; the set or array is then
+expanded into a list of its elements:
+
+.. code-block:: nim
+  const
+    SymChars: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'}
+
+  proc classify(s: string) =
+    case s[0]
+    of SymChars, '_': echo "an identifier"
+    of '0'..'9': echo "a number"
+    else: echo "other"
+  
+  # is equivalent to:
+  proc classify(s: string) =
+    case s[0]
+    of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_': echo "an identifier"
+    of '0'..'9': echo "a number"
+    else: echo "other"
+
+
+When statement
+--------------
+
+Example:
+
+.. code-block:: nim
+
+  when sizeof(int) == 2:
+    echo("running on a 16 bit system!")
+  elif sizeof(int) == 4:
+    echo("running on a 32 bit system!")
+  elif sizeof(int) == 8:
+    echo("running on a 64 bit system!")
+  else:
+    echo("cannot happen!")
+
+The ``when`` statement is almost identical to the ``if`` statement with some
+exceptions:
+
+* Each condition (``expr``) has to be a constant expression (of type ``bool``).
+* The statements do not open a new scope.
+* The statements that belong to the expression that evaluated to true are
+  translated by the compiler, the other statements are not checked for
+  semantics! However, each condition is checked for semantics.
+
+The ``when`` statement enables conditional compilation techniques. As
+a special syntactic extension, the ``when`` construct is also available
+within ``object`` definitions.
+
+
+Return statement
+----------------
+
+Example:
+
+.. code-block:: nim
+  return 40+2
+
+The ``return`` statement ends the execution of the current procedure.
+It is only allowed in procedures. If there is an ``expr``, this is syntactic
+sugar for:
+
+.. code-block:: nim
+  result = expr
+  return result
+
+
+``return`` without an expression is a short notation for ``return result`` if
+the proc has a return type. The `result`:idx: variable is always the return
+value of the procedure. It is automatically declared by the compiler. As all
+variables, ``result`` is initialized to (binary) zero:
+
+.. code-block:: nim
+  proc returnZero(): int =
+    # implicitly returns 0
+
+
+Yield statement
+---------------
+
+Example:
+
+.. code-block:: nim
+  yield (1, 2, 3)
+
+The ``yield`` statement is used instead of the ``return`` statement in
+iterators. It is only valid in iterators. Execution is returned to the body
+of the for loop that called the iterator. Yield does not end the iteration
+process, but execution is passed back to the iterator if the next iteration
+starts. See the section about iterators (`Iterators and the for statement`_)
+for further information.
+
+
+Block statement
+---------------
+
+Example:
+
+.. code-block:: nim
+  var found = false
+  block myblock:
+    for i in 0..3:
+      for j in 0..3:
+        if a[j][i] == 7:
+          found = true
+          break myblock # leave the block, in this case both for-loops
+  echo(found)
+
+The block statement is a means to group statements to a (named) ``block``.
+Inside the block, the ``break`` statement is allowed to leave the block
+immediately. A ``break`` statement can contain a name of a surrounding
+block to specify which block is to leave.
+
+
+Break statement
+---------------
+
+Example:
+
+.. code-block:: nim
+  break
+
+The ``break`` statement is used to leave a block immediately. If ``symbol``
+is given, it is the name of the enclosing block that is to leave. If it is
+absent, the innermost block is left.
+
+
+While statement
+---------------
+
+Example:
+
+.. code-block:: nim
+  echo("Please tell me your password: \n")
+  var pw = readLine(stdin)
+  while pw != "12345":
+    echo("Wrong password! Next try: \n")
+    pw = readLine(stdin)
+
+
+The ``while`` statement is executed until the ``expr`` evaluates to false.
+Endless loops are no error. ``while`` statements open an `implicit block`,
+so that they can be left with a ``break`` statement.
+
+
+Continue statement
+------------------
+
+A ``continue`` statement leads to the immediate next iteration of the
+surrounding loop construct. It is only allowed within a loop. A continue
+statement is syntactic sugar for a nested block:
+
+.. code-block:: nim
+  while expr1:
+    stmt1
+    continue
+    stmt2
+
+Is equivalent to:
+
+.. code-block:: nim
+  while expr1:
+    block myBlockName:
+      stmt1
+      break myBlockName
+      stmt2
+
+
+Assembler statement
+-------------------
+
+The direct embedding of assembler code into Nim code is supported
+by the unsafe ``asm`` statement. Identifiers in the assembler code that refer to
+Nim identifiers shall be enclosed in a special character which can be
+specified in the statement's pragmas. The default special character is ``'`'``:
+
+.. code-block:: nim
+  {.push stackTrace:off.}
+  proc addInt(a, b: int): int =
+    # a in eax, and b in edx
+    asm """
+        mov eax, `a`
+        add eax, `b`
+        jno theEnd
+        call `raiseOverflow`
+      theEnd:
+    """
+  {.pop.}
+
+If the GNU assembler is used, quotes and newlines are inserted automatically:
+
+.. code-block:: nim
+  proc addInt(a, b: int): int =
+    asm """
+      addl %%ecx, %%eax
+      jno 1
+      call `raiseOverflow`
+      1:
+      :"=a"(`result`)
+      :"a"(`a`), "c"(`b`)
+    """
+
+Instead of:
+
+.. code-block:: nim
+  proc addInt(a, b: int): int =
+    asm """
+      "addl %%ecx, %%eax\n"
+      "jno 1\n"
+      "call `raiseOverflow`\n"
+      "1: \n"
+      :"=a"(`result`)
+      :"a"(`a`), "c"(`b`)
+    """
+
+Using statement
+---------------
+
+**Warning**: The ``using`` statement is highly experimental!
+
+The using statement provides syntactic convenience for procs that
+heavily use a single contextual parameter. When applied to a variable or a
+constant, it will instruct Nim to automatically consider the used symbol as
+a hidden leading parameter for any procedure calls, following the using
+statement in the current scope. Thus, it behaves much like the hidden `this`
+parameter available in some object-oriented programming languages.
+
+.. code-block:: nim
+
+  var s = socket()
+  using s
+
+  connect(host, port)
+  send(data)
+
+  while true:
+    let line = readLine(timeout)
+    ...
+
+
+When applied to a callable symbol, it brings the designated symbol in the
+current scope. Thus, it can be used to disambiguate between imported symbols
+from different modules having the same name.
+
+.. code-block:: nim
+  import windows, sdl
+  using sdl.SetTimer
+
+Note that ``using`` only *adds* to the current context, it doesn't remove or
+replace, **neither** does it create a new scope. What this means is that if one
+applies this to multiple variables the compiler will find conflicts in what
+variable to use:
+
+.. code-block:: nim
+  var a, b = "kill it"
+  using a
+  add(" with fire")
+  using b
+  add(" with water")
+  echo a
+  echo b
+
+When the compiler reaches the second ``add`` call, both ``a`` and ``b`` could
+be used with the proc, so one gets ``Error: expression '(a|b)' has no type (or
+is ambiguous)``. To solve this one would need to nest ``using`` with a
+``block`` statement so as to control the reach of the ``using`` statement.
+
+If expression
+-------------
+
+An `if expression` is almost like an if statement, but it is an expression.
+Example:
+
+.. code-block:: nim
+  var y = if x > 8: 9 else: 10
+
+An if expression always results in a value, so the ``else`` part is
+required. ``Elif`` parts are also allowed.
+
+When expression
+---------------
+
+Just like an `if expression`, but corresponding to the when statement.
+
+Case expression
+---------------
+
+The `case expression` is again very similar to the case statement:
+
+.. code-block:: nim
+  var favoriteFood = case animal
+    of "dog": "bones"
+    of "cat": "mice"
+    elif animal.endsWith"whale": "plankton"
+    else:
+      echo "I'm not sure what to serve, but everybody loves ice cream"
+      "ice cream"
+
+As seen in the above example, the case expression can also introduce side
+effects. When multiple statements are given for a branch, Nim will use
+the last expression as the result value, much like in an `expr` template.
+
+Table constructor
+-----------------
+
+A table constructor is syntactic sugar for an array constructor:
+
+.. code-block:: nim
+  {"key1": "value1", "key2", "key3": "value2"}
+  
+  # is the same as:
+  [("key1", "value1"), ("key2", "value2"), ("key3", "value2")]
+
+
+The empty table can be written ``{:}`` (in contrast to the empty set 
+which is ``{}``) which is thus another way to write as the empty array
+constructor ``[]``. This slightly unusal way of supporting tables 
+has lots of advantages:
+
+* The order of the (key,value)-pairs is preserved, thus it is easy to
+  support ordered dicts with for example ``{key: val}.newOrderedTable``.
+* A table literal can be put into a ``const`` section and the compiler
+  can easily put it into the executable's data section just like it can
+  for arrays and the generated data section requires a minimal amount
+  of memory.
+* Every table implementation is treated equal syntactically.
+* Apart from the minimal syntactic sugar the language core does not need to
+  know about tables.
+
+
+Type conversions
+----------------
+Syntactically a `type conversion` is like a procedure call, but a
+type name replaces the procedure name. A type conversion is always
+safe in the sense that a failure to convert a type to another
+results in an exception (if it cannot be determined statically).
+
+
+Type casts
+----------
+Example:
+
+.. code-block:: nim
+  cast[int](x)
+
+Type casts are a crude mechanism to interpret the bit pattern of
+an expression as if it would be of another type. Type casts are
+only needed for low-level programming and are inherently unsafe.
+
+
+The addr operator
+-----------------
+The ``addr`` operator returns the address of an l-value. If the type of the
+location is ``T``, the `addr` operator result is of the type ``ptr T``. An
+address is always an untraced reference. Taking the address of an object that
+resides on the stack is **unsafe**, as the pointer may live longer than the
+object on the stack and can thus reference a non-existing object. One can get
+the address of variables, but one can't use it on variables declared through
+``let`` statements:
+
+.. code-block:: nim
+
+  let t1 = "Hello"
+  var
+    t2 = t1
+    t3 : pointer = addr(t2)
+  echo repr(addr(t2))
+  # --> ref 0x7fff6b71b670 --> 0x10bb81050"Hello"
+  echo cast[ptr string](t3)[]
+  # --> Hello
+  # The following line doesn't compile:
+  echo repr(addr(t1))
+  # Error: expression has no address
diff --git a/doc/manual/syntax.txt b/doc/manual/syntax.txt
new file mode 100644
index 000000000..0ae353edd
--- /dev/null
+++ b/doc/manual/syntax.txt
@@ -0,0 +1,112 @@
+Syntax
+======
+
+This section lists Nim's standard syntax. How the parser handles
+the indentation is already described in the `Lexical Analysis`_ section.
+
+Nim allows user-definable operators.
+Binary operators have 10 different levels of precedence.
+
+Relevant character
+------------------
+
+An operator symbol's *relevant character* is its first
+character unless the first character is ``\`` and its length is greater than 1
+then it is the second character.
+
+This rule allows to escape operator symbols with ``\`` and keeps the operator's
+precedence and associativity; this is useful for meta programming.
+
+
+Associativity
+-------------
+
+Binary operators whose relevant character is ``^`` are right-associative, all
+other binary operators are left-associative.
+
+Precedence
+----------
+
+Unary operators always bind stronger than any binary 
+operator: ``$a + b`` is ``($a) + b`` and not ``$(a + b)``.
+
+If an unary operator's relevant character is ``@`` it is a `sigil-like`:idx: 
+operator which binds stronger than a ``primarySuffix``: ``@x.abc`` is parsed
+as ``(@x).abc`` whereas ``$x.abc`` is parsed as ``$(x.abc)``.
+
+
+For binary operators that are not keywords the precedence is determined by the
+following rules:
+
+If the operator ends with ``=`` and its relevant character is none of 
+``<``, ``>``, ``!``, ``=``, ``~``, ``?``, it is an *assignment operator* which
+has the lowest precedence.
+
+Otherwise precedence is determined by the relevant character.
+
+================  ===============================================  ==================  ===============
+Precedence level    Operators                                      Relevant character  Terminal symbol
+================  ===============================================  ==================  ===============
+  9 (highest)                                                      ``$  ^``            OP9
+  8               ``*    /    div   mod   shl  shr  %``            ``* % \  /``        OP8
+  7               ``+    -``                                       ``+  ~  |``         OP7
+  6               ``&``                                            ``&``               OP6
+  5               ``..``                                           ``.``               OP5
+  4               ``==  <= < >= > !=  in notin is isnot not of``   ``= <  > !``        OP4
+  3               ``and``                                                              OP3
+  2               ``or xor``                                                           OP2
+  1                                                                ``@  : ?``          OP1
+  0 (lowest)      *assignment operator* (like ``+=``, ``*=``)                          OP0
+================  ===============================================  ==================  ===============
+
+
+Strong spaces
+-------------
+
+The number of spaces preceeding a non-keyword operator affects precedence
+if the experimental parser directive ``#!strongSpaces`` is used. Indentation
+is not used to determine the number of spaces. If 2 or more operators have the
+same number of preceding spaces the precedence table applies, so ``1 + 3 * 4``
+is still parsed as ``1 + (3 * 4)``, but ``1+3 * 4`` is parsed as ``(1+3) * 4``:
+
+.. code-block:: nim
+  #! strongSpaces
+  if foo+4 * 4 == 8 and b&c | 9  ++
+      bar:
+    echo ""
+  # is parsed as
+  if ((foo+4)*4 == 8) and (((b&c) | 9) ++ bar): echo ""
+
+
+Furthermore whether an operator is used a prefix operator is affected by the
+number of spaces: 
+
+.. code-block:: nim
+  #! strongSpaces
+  echo $foo
+  # is parsed as
+  echo($foo)
+
+This also affects whether ``[]``, ``{}``, ``()`` are parsed as constructors
+or as accessors:
+
+.. code-block:: nim
+  #! strongSpaces
+  echo (1,2)
+  # is parsed as
+  echo((1,2))
+
+Only 0, 1, 2, 4 or 8 spaces are allowed to specify precedence and it is
+enforced that infix operators have the same amount of spaces before and after
+them. This rules does not apply when a newline follows after the operator,
+then only the preceding spaces are considered.
+
+
+Grammar
+-------
+
+The grammar's start symbol is ``module``.
+
+.. include:: grammar.txt
+   :literal:
+
diff --git a/doc/manual/taint.txt b/doc/manual/taint.txt
new file mode 100644
index 000000000..84f0c68b1
--- /dev/null
+++ b/doc/manual/taint.txt
@@ -0,0 +1,20 @@
+Taint mode
+==========
+
+The Nim compiler and most parts of the standard library support 
+a taint mode. Input strings are declared with the `TaintedString`:idx: 
+string type declared in the ``system`` module.
+
+If the taint mode is turned on (via the ``--taintMode:on`` command line 
+option) it is a distinct string type which helps to detect input
+validation errors:
+
+.. code-block:: nim
+  echo "your name: "
+  var name: TaintedString = stdin.readline
+  # it is safe here to output the name without any input validation, so
+  # we simply convert `name` to string to make the compiler happy: 
+  echo "hi, ", name.string
+
+If the taint mode is turned off, ``TaintedString`` is simply an alias for
+``string``.
diff --git a/doc/manual/templates.txt b/doc/manual/templates.txt
new file mode 100644
index 000000000..d63f61f54
--- /dev/null
+++ b/doc/manual/templates.txt
@@ -0,0 +1,404 @@
+Templates
+=========
+
+A template is a simple form of a macro: It is a simple substitution
+mechanism that operates on Nim's abstract syntax trees. It is processed in
+the semantic pass of the compiler.
+
+The syntax to *invoke* a template is the same as calling a procedure.
+
+Example:
+
+.. code-block:: nim
+  template `!=` (a, b: expr): expr =
+    # this definition exists in the System module
+    not (a == b)
+
+  assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))
+
+The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact 
+templates:
+
+| ``a > b`` is transformed into ``b < a``.
+| ``a in b`` is transformed into ``contains(b, a)``. 
+| ``notin`` and ``isnot`` have the obvious meanings.
+
+The "types" of templates can be the symbols ``expr`` (stands for *expression*), 
+``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type 
+description*). These are "meta types", they can only be used in certain 
+contexts. Real types can be used too; this implies that expressions are 
+expected.
+
+
+Ordinary vs immediate templates
+-------------------------------
+
+There are two different kinds of templates: immediate templates and
+ordinary templates. Ordinary templates take part in overloading resolution. As
+such their arguments need to be type checked before the template is invoked.
+So ordinary templates cannot receive undeclared identifiers:
+
+.. code-block:: nim
+
+  template declareInt(x: expr) = 
+    var x: int
+
+  declareInt(x) # error: unknown identifier: 'x'
+
+An ``immediate`` template does not participate in overload resolution and so
+its arguments are not checked for semantics before invocation. So they can
+receive undeclared identifiers:
+
+.. code-block:: nim
+
+  template declareInt(x: expr) {.immediate.} = 
+    var x: int
+
+  declareInt(x) # valid
+
+
+Passing a code block to a template
+----------------------------------
+
+If there is a ``stmt`` parameter it should be the last in the template
+declaration, because statements are passed to a template via a
+special ``:`` syntax:
+
+.. code-block:: nim
+
+  template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} =
+    var f: TFile
+    if open(f, fn, mode):
+      try:
+        actions
+      finally:
+        close(f)
+    else:
+      quit("cannot open: " & fn)
+      
+  withFile(txt, "ttempl3.txt", fmWrite):
+    txt.writeln("line 1")
+    txt.writeln("line 2")
+  
+In the example the two ``writeln`` statements are bound to the ``actions``
+parameter.
+
+
+Symbol binding in templates
+---------------------------
+
+A template is a `hygienic`:idx: macro and so opens a new scope. Most symbols are
+bound from the definition scope of the template:
+
+.. code-block:: nim
+  # Module A
+  var 
+    lastId = 0
+  
+  template genId*: expr =
+    inc(lastId)
+    lastId
+
+.. code-block:: nim
+  # Module B
+  import A
+  
+  echo genId() # Works as 'lastId' has been bound in 'genId's defining scope
+
+As in generics symbol binding can be influenced via ``mixin`` or ``bind`` 
+statements.
+
+
+
+Identifier construction
+-----------------------
+
+In templates identifiers can be constructed with the backticks notation:
+
+.. code-block:: nim
+
+  template typedef(name: expr, typ: typedesc) {.immediate.} = 
+    type
+      `T name`* {.inject.} = typ
+      `P name`* {.inject.} = ref `T name`
+      
+  typedef(myint, int)
+  var x: PMyInt
+
+In the example ``name`` is instantiated with ``myint``, so \`T name\` becomes
+``Tmyint``.
+
+
+Lookup rules for template parameters
+------------------------------------
+
+A parameter ``p`` in a template is even substituted in the expression ``x.p``.
+Thus template arguments can be used as field names and a global symbol can be
+shadowed by the same argument name even when fully qualified:
+
+.. code-block:: nim
+  # module 'm'
+
+  type
+    TLev = enum
+      levA, levB
+
+  var abclev = levB
+
+  template tstLev(abclev: TLev) =
+    echo abclev, " ", m.abclev
+
+  tstLev(levA)
+  # produces: 'levA levA'
+  
+But the global symbol can properly be captured by a ``bind`` statement:
+
+.. code-block:: nim
+  # module 'm'
+
+  type
+    TLev = enum
+      levA, levB
+
+  var abclev = levB
+
+  template tstLev(abclev: TLev) =
+    bind m.abclev
+    echo abclev, " ", m.abclev
+
+  tstLev(levA)
+  # produces: 'levA levB'
+
+
+Hygiene in templates
+--------------------
+
+Per default templates are `hygienic`:idx:\: Local identifiers declared in a
+template cannot be accessed in the instantiation context:
+
+.. code-block:: nim
+  
+  template newException*(exceptn: typedesc, message: string): expr =
+    var
+      e: ref exceptn  # e is implicitly gensym'ed here
+    new(e)
+    e.msg = message
+    e
+    
+  # so this works:
+  let e = "message"
+  raise newException(EIO, e)
+
+
+Whether a symbol that is declared in a template is exposed to the instantiation
+scope is controlled by the `inject`:idx: and `gensym`:idx: pragmas: gensym'ed
+symbols are not exposed but inject'ed are.
+
+The default for symbols of entity ``type``, ``var``, ``let`` and ``const``
+is ``gensym`` and for ``proc``, ``iterator``, ``converter``, ``template``,
+``macro`` is ``inject``. However, if the name of the entity is passed as a 
+template parameter, it is an inject'ed symbol:
+
+.. code-block:: nim
+  template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} =
+    block:
+      var f: TFile  # since 'f' is a template param, it's injected implicitly
+      ...
+      
+  withFile(txt, "ttempl3.txt", fmWrite):
+    txt.writeln("line 1")
+    txt.writeln("line 2")
+
+
+The ``inject`` and ``gensym`` pragmas are second class annotations; they have
+no semantics outside of a template definition and cannot be abstracted over:
+
+.. code-block:: nim
+  {.pragma myInject: inject.}
+  
+  template t() =
+    var x {.myInject.}: int # does NOT work
+
+
+To get rid of hygiene in templates, one can use the `dirty`:idx: pragma for
+a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates.
+
+
+
+Macros
+======
+
+A macro is a special kind of low level template. Macros can be used
+to implement `domain specific languages`:idx:. Like templates, macros come in
+the 2 flavors *immediate* and *ordinary*.
+
+While macros enable advanced compile-time code transformations, they
+cannot change Nim's syntax. However, this is no real restriction because
+Nim's syntax is flexible enough anyway.
+
+To write macros, one needs to know how the Nim concrete syntax is converted
+to an abstract syntax tree.
+
+There are two ways to invoke a macro:
+(1) invoking a macro like a procedure call (`expression macros`)
+(2) invoking a macro with the special ``macrostmt`` syntax (`statement macros`)
+
+
+Expression Macros
+-----------------
+
+The following example implements a powerful ``debug`` command that accepts a
+variable number of arguments:
+
+.. code-block:: nim
+  # to work with Nim syntax trees, we need an API that is defined in the
+  # ``macros`` module:
+  import macros
+
+  macro debug(n: varargs[expr]): stmt =
+    # `n` is a Nim AST that contains the whole macro invocation
+    # this macro returns a list of statements:
+    result = newNimNode(nnkStmtList, n)
+    # iterate over any argument that is passed to this macro:
+    for i in 0..n.len-1:
+      # add a call to the statement list that writes the expression;
+      # `toStrLit` converts an AST to its string representation:
+      add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i])))
+      # add a call to the statement list that writes ": "
+      add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
+      # add a call to the statement list that writes the expressions value:
+      add(result, newCall("writeln", newIdentNode("stdout"), n[i]))
+
+  var
+    a: array [0..10, int]
+    x = "some string"
+  a[0] = 42
+  a[1] = 45
+
+  debug(a[0], a[1], x)
+
+The macro call expands to:
+
+.. code-block:: nim
+  write(stdout, "a[0]")
+  write(stdout, ": ")
+  writeln(stdout, a[0])
+
+  write(stdout, "a[1]")
+  write(stdout, ": ")
+  writeln(stdout, a[1])
+
+  write(stdout, "x")
+  write(stdout, ": ")
+  writeln(stdout, x)
+
+
+Arguments that are passed to a ``varargs`` parameter are wrapped in an array
+constructor expression. This is why ``debug`` iterates over all of ``n``'s
+children.
+
+
+BindSym
+-------
+
+The above ``debug`` macro relies on the fact that ``write``, ``writeln`` and
+``stdout`` are declared in the system module and thus visible in the 
+instantiating context. There is a way to use bound identifiers
+(aka `symbols`:idx:) instead of using unbound identifiers. The ``bindSym`` 
+builtin can be used for that:
+
+.. code-block:: nim
+  import macros
+
+  macro debug(n: varargs[expr]): stmt =
+    result = newNimNode(nnkStmtList, n)
+    for i in 0..n.len-1:
+      # we can bind symbols in scope via 'bindSym':
+      add(result, newCall(bindSym"write", bindSym"stdout", toStrLit(n[i])))
+      add(result, newCall(bindSym"write", bindSym"stdout", newStrLitNode(": ")))
+      add(result, newCall(bindSym"writeln", bindSym"stdout", n[i]))
+
+  var
+    a: array [0..10, int]
+    x = "some string"
+  a[0] = 42
+  a[1] = 45
+
+  debug(a[0], a[1], x)
+
+The macro call expands to:
+
+.. code-block:: nim
+  write(stdout, "a[0]")
+  write(stdout, ": ")
+  writeln(stdout, a[0])
+
+  write(stdout, "a[1]")
+  write(stdout, ": ")
+  writeln(stdout, a[1])
+
+  write(stdout, "x")
+  write(stdout, ": ")
+  writeln(stdout, x)
+
+However, the symbols ``write``, ``writeln`` and ``stdout`` are already bound
+and are not looked up again. As the example shows, ``bindSym`` does work with
+overloaded symbols implicitly.
+
+
+Statement Macros
+----------------
+
+Statement macros are defined just as expression macros. However, they are
+invoked by an expression following a colon.
+
+The following example outlines a macro that generates a lexical analyzer from
+regular expressions:
+
+.. code-block:: nim
+  import macros
+
+  macro case_token(n: stmt): stmt =
+    # creates a lexical analyzer from regular expressions
+    # ... (implementation is an exercise for the reader :-)
+    discard
+
+  case_token: # this colon tells the parser it is a macro statement
+  of r"[A-Za-z_]+[A-Za-z_0-9]*":
+    return tkIdentifier
+  of r"0-9+":
+    return tkInteger
+  of r"[\+\-\*\?]+":
+    return tkOperator
+  else:
+    return tkUnknown
+
+
+**Style note**: For code readability, it is the best idea to use the least
+powerful programming construct that still suffices. So the "check list" is:
+
+(1) Use an ordinary proc/iterator, if possible.
+(2) Else: Use a generic proc/iterator, if possible.
+(3) Else: Use a template, if possible.
+(4) Else: Use a macro.
+
+
+Macros as pragmas
+-----------------
+
+Whole routines (procs, iterators etc.) can also be passed to a template or 
+a macro via the pragma notation: 
+
+.. code-block:: nim
+  template m(s: stmt) = discard
+
+  proc p() {.m.} = discard
+
+This is a simple syntactic transformation into:
+
+.. code-block:: nim
+  template m(s: stmt) = discard
+
+  m:
+    proc p() = discard
+
diff --git a/doc/manual/threads.txt b/doc/manual/threads.txt
new file mode 100644
index 000000000..d29cab6ca
--- /dev/null
+++ b/doc/manual/threads.txt
@@ -0,0 +1,209 @@
+Threads
+=======
+
+To enable thread support the ``--threads:on`` command line switch needs to 
+be used. The ``system`` module then contains several threading primitives. 
+See the `threads `_ and `channels `_ modules 
+for the low level thread API. There are also high level parallelism constructs
+available. See `spawn`_ for further details.
+
+Nim's memory model for threads is quite different than that of other common
+programming languages (C, Pascal, Java): Each thread has its own (garbage 
+collected) heap and sharing of memory is restricted to global variables. This 
+helps to prevent race conditions. GC efficiency is improved quite a lot, 
+because the GC never has to stop other threads and see what they reference.
+Memory allocation requires no lock at all! This design easily scales to massive
+multicore processors that are becoming the norm.
+
+
+Thread pragma
+-------------
+
+A proc that is executed as a new thread of execution should be marked by the
+``thread`` pragma for reasons of readability. The compiler checks for
+violations of the `no heap sharing restriction`:idx:\: This restriction implies
+that it is invalid to construct a data structure that consists of memory 
+allocated from different (thread local) heaps.
+
+A thread proc is passed to ``createThread`` or ``spawn`` and invoked 
+indirectly; so the ``thread`` pragma implies ``procvar``.
+
+
+GC safety
+---------
+
+We call a proc ``p`` `GC safe`:idx: when it doesn't access any global variable
+that contains GC'ed memory (``string``, ``seq``, ``ref`` or a closure) either
+directly or indirectly through a call to a GC unsafe proc. 
+
+The `gcsafe`:idx: annotation can be used to mark a proc to be gcsafe,
+otherwise this property is inferred by the compiler. Note that ``noSideEfect``
+implies ``gcsafe``. The only way to create a thread is via ``spawn`` or
+``createThead``. ``spawn`` is usually the preferable method. Either way
+the invoked proc must not use ``var`` parameters nor must any of its parameters
+contain a ``ref`` or ``closure`` type. This enforces
+the *no heap sharing restriction*.
+
+Routines that are imported from C are always assumed to be ``gcsafe``.
+To enable the GC-safety checking the ``--threadAnalysis:on`` command line
+switch must be used. This is a temporary workaround to ease the porting effort
+from old code to the new threading model. In the future the thread analysis
+will always be performed.
+
+
+Future directions:
+
+- A shared GC'ed heap might be provided.
+
+
+Threadvar pragma
+----------------
+
+A global variable can be marked with the ``threadvar`` pragma; it is 
+a `thread-local`:idx: variable then:
+
+.. code-block:: nim
+  var checkpoints* {.threadvar.}: seq[string]
+
+Due to implementation restrictions thread local variables cannot be 
+initialized within the ``var`` section. (Every thread local variable needs to
+be replicated at thread creation.)
+
+
+Threads and exceptions
+----------------------
+
+The interaction between threads and exceptions is simple: A *handled* exception 
+in one thread cannot affect any other thread. However, an *unhandled* 
+exception in one thread terminates the whole *process*!
+
+
+
+Parallel & Spawn
+================
+
+Nim has two flavors of parallelism: 
+1) `Structured`:idx: parallelism via the ``parallel`` statement.
+2) `Unstructured`:idx: parallelism via the standalone ``spawn`` statement.
+
+Nim has a builtin thread pool that can be used for CPU intensive tasks. For
+IO intensive tasks the ``async`` and ``await`` features should be
+used instead. Both parallel and spawn need the `threadpool `_
+module to work.
+
+Somewhat confusingly, ``spawn`` is also used in the ``parallel`` statement
+with slightly different semantics. ``spawn`` always takes a call expression of
+the form ``f(a, ...)``. Let ``T`` be ``f``'s return type. If ``T`` is ``void``
+then ``spawn``'s return type is also ``void``. Within a ``parallel`` section
+``spawn``'s return type is ``T``, otherwise it is ``FlowVar[T]``.
+
+The compiler can ensure the location in ``location = spawn f(...)`` is not
+read prematurely within a ``parallel`` section and so there is no need for
+the overhead of an indirection via ``FlowVar[T]`` to ensure correctness.
+
+**Note**: Currently exceptions are not propagated between ``spawn``ed tasks!
+
+
+Spawn statement
+---------------
+
+`spawn`:idx: can be used to pass a task to the thread pool:
+
+.. code-block:: nim
+  import threadpool
+
+  proc processLine(line: string) =
+    discard "do some heavy lifting here"
+  
+  for x in lines("myinput.txt"):
+    spawn processLine(x)
+  sync()
+
+For reasons of type safety and implementation simplicity the expression
+that ``spawn`` takes is restricted:
+
+* It must be a call expression ``f(a, ...)``.
+* ``f`` must be ``gcsafe``.
+* ``f`` must not have the calling convention ``closure``.
+* ``f``'s parameters may not be of type ``var``.
+  This means one has to use raw ``ptr``'s for data passing reminding the
+  programmer to be careful.
+* ``ref`` parameters are deeply copied which is a subtle semantic change and
+  can cause performance problems but ensures memory safety. This deep copy
+  is performed via ``system.deepCopy`` and so can be overriden.
+* For *safe* data exchange between ``f`` and the caller a global ``TChannel``
+  needs to be used. However, since spawn can return a result, often no further
+  communication is required. 
+
+
+``spawn`` executes the passed expression on the thread pool and returns
+a `data flow variable`:idx: ``FlowVar[T]`` that can be read from. The reading
+with the ``^`` operator is **blocking**. However, one can use ``awaitAny`` to
+wait on multiple flow variables at the same time:
+
+.. code-block:: nim
+  import threadpool, ...
+  
+  # wait until 2 out of 3 servers received the update:
+  proc main =
+    var responses = newSeq[RawFlowVar](3)
+    for i in 0..2:
+      responses[i] = spawn tellServer(Update, "key", "value")
+    var index = awaitAny(responses)
+    assert index >= 0
+    responses.del(index)
+    discard awaitAny(responses)
+
+Data flow variables ensure that no data races
+are possible. Due to technical limitations not every type ``T`` is possible in
+a data flow variable: ``T`` has to be of the type ``ref``, ``string``, ``seq``
+or of a type that doesn't contain a type that is garbage collected. This
+restriction will be removed in the future.
+
+
+
+Parallel statement
+------------------
+
+Example:
+
+.. code-block:: nim
+  # Compute PI in an inefficient way
+  import strutils, math, threadpool
+
+  proc term(k: float): float = 4 * math.pow(-1, k) / (2*k + 1)
+
+  proc pi(n: int): float =
+    var ch = newSeq[float](n+1)
+    parallel:
+      for k in 0..ch.high:
+        ch[k] = spawn term(float(k))
+    for k in 0..ch.high:
+      result += ch[k]
+
+  echo formatFloat(pi(5000))
+
+
+The parallel statement is the preferred mechanism to introduce parallelism
+in a Nim program. A subset of the Nim language is valid within a
+``parallel`` section. This subset is checked to be free of data races at
+compile time. A sophisticated `disjoint checker`:idx: ensures that no data
+races are possible even though shared memory is extensively supported!
+
+The subset is in fact the full language with the following
+restrictions / changes:
+
+* ``spawn`` within a ``parallel`` section has special semantics.
+* Every location of the form ``a[i]`` and ``a[i..j]`` and ``dest`` where
+  ``dest`` is part of the pattern ``dest = spawn f(...)`` has to be
+  provably disjoint. This is called the *disjoint check*.
+* Every other complex location ``loc`` that is used in a spawned
+  proc (``spawn f(loc)``) has to be immutable for the duration of
+  the ``parallel`` section. This is called the *immutability check*. Currently
+  it is not specified what exactly "complex location" means. We need to make
+  this an optimization!
+* Every array access has to be provably within bounds. This is called 
+  the *bounds check*.
+* Slices are optimized so that no copy is performed. This optimization is not
+  yet performed for ordinary slices outside of a ``parallel`` section. Slices
+  are also special in that they currently do not support negative indexes!
diff --git a/doc/manual/trmacros.txt b/doc/manual/trmacros.txt
new file mode 100644
index 000000000..715c9f850
--- /dev/null
+++ b/doc/manual/trmacros.txt
@@ -0,0 +1,361 @@
+Term rewriting macros
+=====================
+
+Term rewriting macros are macros or templates that have not only
+a *name* but also a *pattern* that is searched for after the semantic checking
+phase of the compiler: This means they provide an easy way to enhance the 
+compilation pipeline with user defined optimizations:
+
+.. code-block:: nim
+  template optMul{`*`(a, 2)}(a: int): int = a+a
+  
+  let x = 3
+  echo x * 2
+
+The compiler now rewrites ``x * 2`` as ``x + x``. The code inside the
+curlies is the pattern to match against. The operators ``*``,  ``**``,
+``|``, ``~`` have a special meaning in patterns if they are written in infix 
+notation, so to match verbatim against ``*`` the ordinary function call syntax
+needs to be used.
+
+
+Unfortunately optimizations are hard to get right and even the tiny example
+is **wrong**: 
+
+.. code-block:: nim
+  template optMul{`*`(a, 2)}(a: int): int = a+a
+  
+  proc f(): int =
+    echo "side effect!"
+    result = 55
+  
+  echo f() * 2
+
+We cannot duplicate 'a' if it denotes an expression that has a side effect!
+Fortunately Nim supports side effect analysis:
+
+.. code-block:: nim
+  template optMul{`*`(a, 2)}(a: int{noSideEffect}): int = a+a
+  
+  proc f(): int =
+    echo "side effect!"
+    result = 55
+  
+  echo f() * 2 # not optimized ;-)
+
+So what about ``2 * a``? We should tell the compiler ``*`` is commutative. We
+cannot really do that however as the following code only swaps arguments
+blindly:
+
+.. code-block:: nim
+  template mulIsCommutative{`*`(a, b)}(a, b: int): int = b*a
+  
+What optimizers really need to do is a *canonicalization*:
+
+.. code-block:: nim
+  template canonMul{`*`(a, b)}(a: int{lit}, b: int): int = b*a
+
+The ``int{lit}`` parameter pattern matches against an expression of 
+type ``int``, but only if it's a literal.
+
+
+
+Parameter constraints
+---------------------
+
+The `parameter constraint`:idx: expression can use the operators ``|`` (or), 
+``&`` (and) and ``~`` (not) and the following predicates:
+
+===================      =====================================================
+Predicate                Meaning
+===================      =====================================================
+``atom``                 The matching node has no children.
+``lit``                  The matching node is a literal like "abc", 12.
+``sym``                  The matching node must be a symbol (a bound 
+                         identifier).
+``ident``                The matching node must be an identifier (an unbound
+                         identifier).
+``call``                 The matching AST must be a call/apply expression.
+``lvalue``               The matching AST must be an lvalue.
+``sideeffect``           The matching AST must have a side effect.
+``nosideeffect``         The matching AST must have no side effect.
+``param``                A symbol which is a parameter.
+``genericparam``         A symbol which is a generic parameter.
+``module``               A symbol which is a module.
+``type``                 A symbol which is a type.
+``var``                  A symbol which is a variable.
+``let``                  A symbol which is a ``let`` variable.
+``const``                A symbol which is a constant.
+``result``               The special ``result`` variable.
+``proc``                 A symbol which is a proc.
+``method``               A symbol which is a method.
+``iterator``             A symbol which is an iterator.
+``converter``            A symbol which is a converter.
+``macro``                A symbol which is a macro.
+``template``             A symbol which is a template.
+``field``                A symbol which is a field in a tuple or an object.
+``enumfield``            A symbol which is a field in an enumeration.
+``forvar``               A for loop variable.
+``label``                A label (used in ``block`` statements).
+``nk*``                  The matching AST must have the specified kind. 
+                         (Example: ``nkIfStmt`` denotes an ``if`` statement.)
+``alias``                States that the marked parameter needs to alias 
+                         with *some* other parameter.
+``noalias``              States that *every* other parameter must not alias
+                         with the marked parameter.
+===================      =====================================================
+
+The ``alias`` and ``noalias`` predicates refer not only to the matching AST,
+but also to every other bound parameter; syntactially they need to occur after
+the ordinary AST predicates:
+
+.. code-block:: nim
+  template ex{a = b + c}(a: int{noalias}, b, c: int) =
+    # this transformation is only valid if 'b' and 'c' do not alias 'a':
+    a = b
+    inc a, c
+
+
+Pattern operators
+-----------------
+
+The operators ``*``,  ``**``, ``|``, ``~`` have a special meaning in patterns
+if they are written in infix notation.
+
+
+The ``|`` operator
+~~~~~~~~~~~~~~~~~~
+
+The ``|`` operator if used as infix operator creates an ordered choice:
+
+.. code-block:: nim
+  template t{0|1}(): expr = 3
+  let a = 1
+  # outputs 3:
+  echo a
+
+The matching is performed after the compiler performed some optimizations like
+constant folding, so the following does not work:
+
+.. code-block:: nim
+  template t{0|1}(): expr = 3
+  # outputs 1:
+  echo 1
+
+The reason is that the compiler already transformed the 1 into "1" for
+the ``echo`` statement. However, a term rewriting macro should not change the
+semantics anyway. In fact they can be deactived with the ``--patterns:off``
+command line option or temporarily with the ``patterns`` pragma. 
+
+
+The ``{}`` operator
+~~~~~~~~~~~~~~~~~~~
+
+A pattern expression can be bound to a pattern parameter via the ``expr{param}``
+notation: 
+
+.. code-block:: nim
+  template t{(0|1|2){x}}(x: expr): expr = x+1
+  let a = 1
+  # outputs 2:
+  echo a
+
+
+The ``~`` operator
+~~~~~~~~~~~~~~~~~~
+
+The ``~`` operator is the **not** operator in patterns:
+
+.. code-block:: nim
+  template t{x = (~x){y} and (~x){z}}(x, y, z: bool): stmt =
+    x = y
+    if x: x = z
+  
+  var
+    a = false
+    b = true
+    c = false
+  a = b and c
+  echo a
+
+
+The ``*`` operator
+~~~~~~~~~~~~~~~~~~
+
+The ``*`` operator can *flatten* a nested binary expression like ``a & b & c``
+to ``&(a, b, c)``: 
+
+.. code-block:: nim
+  var
+    calls = 0
+    
+  proc `&&`(s: varargs[string]): string =
+    result = s[0]
+    for i in 1..len(s)-1: result.add s[i]
+    inc calls
+
+  template optConc{ `&&` * a }(a: string): expr = &&a
+
+  let space = " "
+  echo "my" && (space & "awe" && "some " ) && "concat"
+
+  # check that it's been optimized properly:
+  doAssert calls == 1
+
+
+The second operator of `*` must be a parameter; it is used to gather all the
+arguments. The expression ``"my" && (space & "awe" && "some " ) && "concat"``
+is passed to ``optConc`` in ``a`` as a special list (of kind ``nkArgList``) 
+which is flattened into a call expression; thus the invocation of ``optConc`` 
+produces:
+
+.. code-block:: nim
+   `&&`("my", space & "awe", "some ", "concat")
+
+
+The ``**`` operator
+~~~~~~~~~~~~~~~~~~~
+
+The ``**`` is much like the ``*`` operator, except that it gathers not only
+all the arguments, but also the matched operators in reverse polish notation:
+
+.. code-block:: nim
+  import macros
+
+  type
+    TMatrix = object
+      dummy: int
+
+  proc `*`(a, b: TMatrix): TMatrix = discard
+  proc `+`(a, b: TMatrix): TMatrix = discard
+  proc `-`(a, b: TMatrix): TMatrix = discard
+  proc `$`(a: TMatrix): string = result = $a.dummy
+  proc mat21(): TMatrix =
+    result.dummy = 21
+
+  macro optM{ (`+`|`-`|`*`) ** a }(a: TMatrix): expr =
+    echo treeRepr(a)
+    result = newCall(bindSym"mat21")
+
+  var x, y, z: TMatrix
+
+  echo x + y * z - x 
+
+This passes the expression ``x + y * z - x`` to the ``optM`` macro as
+an ``nnkArgList`` node containing::
+
+  Arglist
+    Sym "x"
+    Sym "y"
+    Sym "z"
+    Sym "*"
+    Sym "+"
+    Sym "x"
+    Sym "-"
+
+(Which is the reverse polish notation of ``x + y * z - x``.)
+
+
+Parameters
+----------
+
+Parameters in a pattern are type checked in the matching process. If a 
+parameter is of the type ``varargs`` it is treated specially and it can match
+0 or more arguments in the AST to be matched against:
+
+.. code-block:: nim
+  template optWrite{
+    write(f, x)
+    ((write|writeln){w})(f, y)
+  }(x, y: varargs[expr], f: TFile, w: expr) =
+    w(f, x, y)
+  
+
+
+Example: Partial evaluation
+---------------------------
+
+The following example shows how some simple partial evaluation can be
+implemented with term rewriting:
+
+.. code-block:: nim
+  proc p(x, y: int; cond: bool): int =
+    result = if cond: x + y else: x - y
+
+  template optP1{p(x, y, true)}(x, y: expr): expr = x + y
+  template optP2{p(x, y, false)}(x, y: expr): expr = x - y
+
+
+Example: Hoisting
+-----------------
+
+The following example shows how some form of hoisting can be implemented:
+
+.. code-block:: nim
+  import pegs
+
+  template optPeg{peg(pattern)}(pattern: string{lit}): TPeg =
+    var gl {.global, gensym.} = peg(pattern)
+    gl
+
+  for i in 0 .. 3:
+    echo match("(a b c)", peg"'(' @ ')'")
+    echo match("W_HI_Le", peg"\y 'while'")
+
+The ``optPeg`` template optimizes the case of a peg constructor with a string
+literal, so that the pattern will only be parsed once at program startup and
+stored in a global ``gl`` which is then re-used. This optimization is called 
+hoisting because it is comparable to classical loop hoisting.
+
+
+AST based overloading
+=====================
+
+Parameter constraints can also be used for ordinary routine parameters; these
+constraints affect ordinary overloading resolution then:
+
+.. code-block:: nim
+  proc optLit(a: string{lit|`const`}) =
+    echo "string literal"
+  proc optLit(a: string) =
+    echo "no string literal"
+
+  const
+    constant = "abc"
+
+  var
+    variable = "xyz"
+
+  optLit("literal")
+  optLit(constant)
+  optLit(variable)
+
+However, the constraints ``alias`` and ``noalias`` are not available in
+ordinary routines.
+
+
+Move optimization
+-----------------
+
+The ``call`` constraint is particularly useful to implement a move 
+optimization for types that have copying semantics:
+
+.. code-block:: nim
+  proc `[]=`*(t: var TTable, key: string, val: string) =
+    ## puts a (key, value)-pair into `t`. The semantics of string require
+    ## a copy here:
+    let idx = findInsertionPosition(key)
+    t[idx] = key
+    t[idx] = val
+
+  proc `[]=`*(t: var TTable, key: string{call}, val: string{call}) =
+    ## puts a (key, value)-pair into `t`. Optimized version that knows that
+    ## the strings are unique and thus don't need to be copied:
+    let idx = findInsertionPosition(key)
+    shallowCopy t[idx], key
+    shallowCopy t[idx], val
+
+  var t: TTable
+  # overloading resolution ensures that the optimized []= is called here:
+  t[f()] = g()
+
diff --git a/doc/manual/type_bound_ops.txt b/doc/manual/type_bound_ops.txt
new file mode 100644
index 000000000..64c6c325d
--- /dev/null
+++ b/doc/manual/type_bound_ops.txt
@@ -0,0 +1,112 @@
+Type bound operations
+=====================
+
+There are 3 operations that are bound to a type:
+
+1. Assignment
+2. Destruction
+3. Deep copying for communication between threads
+
+These operations can be *overriden* instead of *overloaded*. This means the
+implementation is automatically lifted to structured types. For instance if type
+``T`` has an overriden assignment operator ``=`` this operator is also used
+for assignments of the type ``seq[T]``. Since these operations are bound to a
+type they have to be bound to a nominal type for reasons of simplicity of
+implementation: This means an overriden ``deepCopy`` for ``ref T`` is really
+bound to ``T`` and not to ``ref T``. This also means that one cannot override
+``deepCopy`` for both ``ptr T`` and ``ref T`` at the same time; instead a
+helper distinct or object type has to be used for one pointer type.
+
+
+operator `=`
+------------
+
+This operator is the assignment operator. Note that in the contexts 
+like ``let v = expr``, ``var v = expr``, ``parameter = defaultValue`` or for
+parameter passing no assignment is performed. The ``override`` pragma is
+optional for overriding ``=``.
+
+**Note**: Overriding of operator ``=`` is not yet implemented.
+
+
+destructors
+-----------
+
+A destructor must have a single parameter with a concrete type (the name of a
+generic type is allowed too). The name of the destructor has to be ``destroy``
+and it need to be annotated with the ``override`` pragma.
+
+``destroy(v)`` will be automatically invoked for every local stack 
+variable ``v`` that goes out of scope.
+
+If a structured type features a field with destructable type and 
+the user has not provided an explicit implementation, a destructor for the
+structured type will be automatically generated. Calls to any base class 
+destructors in both user-defined and generated destructors will be inserted.
+
+A destructor is attached to the type it destructs; expressions of this type
+can then only be used in *destructible contexts* and as parameters:
+
+.. code-block:: nim
+  type
+    TMyObj = object
+      x, y: int
+      p: pointer
+      
+  proc destroy(o: var TMyObj) {.override.} =
+    if o.p != nil: dealloc o.p
+    
+  proc open: TMyObj =
+    result = TMyObj(x: 1, y: 2, p: alloc(3))
+ 
+  proc work(o: TMyObj) =
+    echo o.x
+    # No destructor invoked here for 'o' as 'o' is a parameter.
+
+  proc main() =
+    # destructor automatically invoked at the end of the scope:
+    var x = open()
+    # valid: pass 'x' to some other proc:
+    work(x)
+    
+    # Error: usage of a type with a destructor in a non destructible context
+    echo open()
+
+A destructible context is currently only the following:
+
+1. The ``expr`` in ``var x = expr``.
+2. The ``expr`` in ``let x = expr``.
+3. The ``expr`` in ``return expr``.
+4. The ``expr`` in ``result = expr`` where ``result`` is the special symbol
+   introduced by the compiler.
+
+These rules ensure that the construction is tied to a variable and can easily
+be destructed at its scope exit. Later versions of the language will improve
+the support of destructors.
+
+Be aware that destructors are not called for objects allocated with ``new``.
+This may change in future versions of language, but for now the ``finalizer``
+parameter to ``new`` has to be used.
+
+**Note**: Destructors are still experimental and the spec might change
+significantly in order to incorporate an escape analysis.
+
+
+deepCopy
+--------
+
+``deepCopy`` is a builtin that is invoked whenever data is passed to
+a ``spawn``'ed proc to ensure memory safety. The programmer can override its
+behaviour for a specific ``ref`` or ``ptr`` type ``T``. (Later versions of the
+language may weaken this restriction.)
+
+The signature has to be:
+
+.. code-block:: nim
+  proc deepCopy(x: T): T {.override.}
+
+This mechanism is used by most data structures that support shared memory like
+channels to implement thread safe automatic memory management.
+
+The builtin ``deepCopy`` can even clone closures and their environments. See
+the documentation of `spawn`_ for details.
diff --git a/doc/manual/type_rel.txt b/doc/manual/type_rel.txt
new file mode 100644
index 000000000..74539f907
--- /dev/null
+++ b/doc/manual/type_rel.txt
@@ -0,0 +1,191 @@
+Type relations
+==============
+
+The following section defines several relations on types that are needed to
+describe the type checking done by the compiler.
+
+
+Type equality
+-------------
+Nim uses structural type equivalence for most types. Only for objects,
+enumerations and distinct types name equivalence is used. The following
+algorithm (in pseudo-code) determines type equality:
+
+.. code-block:: nim
+  proc typeEqualsAux(a, b: PType,
+                     s: var set[PType * PType]): bool =
+    if (a,b) in s: return true
+    incl(s, (a,b))
+    if a.kind == b.kind:
+      case a.kind
+      of int, intXX, float, floatXX, char, string, cstring, pointer, 
+          bool, nil, void:
+        # leaf type: kinds identical; nothing more to check
+        result = true
+      of ref, ptr, var, set, seq, openarray:
+        result = typeEqualsAux(a.baseType, b.baseType, s)
+      of range:
+        result = typeEqualsAux(a.baseType, b.baseType, s) and
+          (a.rangeA == b.rangeA) and (a.rangeB == b.rangeB)
+      of array:
+        result = typeEqualsAux(a.baseType, b.baseType, s) and
+                 typeEqualsAux(a.indexType, b.indexType, s)
+      of tuple:
+        if a.tupleLen == b.tupleLen:
+          for i in 0..a.tupleLen-1:
+            if not typeEqualsAux(a[i], b[i], s): return false
+          result = true
+      of object, enum, distinct:
+        result = a == b
+      of proc:
+        result = typeEqualsAux(a.parameterTuple, b.parameterTuple, s) and
+                 typeEqualsAux(a.resultType, b.resultType, s) and
+                 a.callingConvention == b.callingConvention
+
+  proc typeEquals(a, b: PType): bool =
+    var s: set[PType * PType] = {}
+    result = typeEqualsAux(a, b, s)
+
+Since types are graphs which can have cycles, the above algorithm needs an
+auxiliary set ``s`` to detect this case.
+
+
+Type equality modulo type distinction
+-------------------------------------
+
+The following algorithm (in pseudo-code) determines whether two types
+are equal with no respect to ``distinct`` types. For brevity the cycle check
+with an auxiliary set ``s`` is omitted:
+
+.. code-block:: nim
+  proc typeEqualsOrDistinct(a, b: PType): bool =
+    if a.kind == b.kind:
+      case a.kind
+      of int, intXX, float, floatXX, char, string, cstring, pointer, 
+          bool, nil, void:
+        # leaf type: kinds identical; nothing more to check
+        result = true
+      of ref, ptr, var, set, seq, openarray:
+        result = typeEqualsOrDistinct(a.baseType, b.baseType)
+      of range:
+        result = typeEqualsOrDistinct(a.baseType, b.baseType) and
+          (a.rangeA == b.rangeA) and (a.rangeB == b.rangeB)
+      of array:
+        result = typeEqualsOrDistinct(a.baseType, b.baseType) and
+                 typeEqualsOrDistinct(a.indexType, b.indexType)
+      of tuple:
+        if a.tupleLen == b.tupleLen:
+          for i in 0..a.tupleLen-1:
+            if not typeEqualsOrDistinct(a[i], b[i]): return false
+          result = true
+      of distinct:
+        result = typeEqualsOrDistinct(a.baseType, b.baseType)
+      of object, enum:
+        result = a == b
+      of proc:
+        result = typeEqualsOrDistinct(a.parameterTuple, b.parameterTuple) and
+                 typeEqualsOrDistinct(a.resultType, b.resultType) and
+                 a.callingConvention == b.callingConvention
+    elif a.kind == distinct:
+      result = typeEqualsOrDistinct(a.baseType, b)
+    elif b.kind == distinct:
+      result = typeEqualsOrDistinct(a, b.baseType)
+      
+
+Subtype relation
+----------------
+If object ``a`` inherits from ``b``, ``a`` is a subtype of ``b``. This subtype
+relation is extended to the types ``var``, ``ref``, ``ptr``:
+
+.. code-block:: nim
+  proc isSubtype(a, b: PType): bool =
+    if a.kind == b.kind:
+      case a.kind
+      of object:
+        var aa = a.baseType
+        while aa != nil and aa != b: aa = aa.baseType
+        result = aa == b
+      of var, ref, ptr:
+        result = isSubtype(a.baseType, b.baseType)
+
+.. XXX nil is a special value!
+
+
+Convertible relation
+--------------------
+A type ``a`` is **implicitly** convertible to type ``b`` iff the following
+algorithm returns true:
+
+.. code-block:: nim
+  # XXX range types?
+  proc isImplicitlyConvertible(a, b: PType): bool =
+    case a.kind
+    of int:     result = b in {int8, int16, int32, int64, uint, uint8, uint16,
+                               uint32, uint64, float, float32, float64}
+    of int8:    result = b in {int16, int32, int64, int}
+    of int16:   result = b in {int32, int64, int}
+    of int32:   result = b in {int64, int}
+    of uint:    result = b in {uint32, uint64}
+    of uint8:   result = b in {uint16, uint32, uint64}
+    of uint16:  result = b in {uint32, uint64}
+    of uint32:  result = b in {uint64}
+    of float:   result = b in {float32, float64}
+    of float32: result = b in {float64, float}
+    of float64: result = b in {float32, float}
+    of seq:
+      result = b == openArray and typeEquals(a.baseType, b.baseType)
+    of array:
+      result = b == openArray and typeEquals(a.baseType, b.baseType)
+      if a.baseType == char and a.indexType.rangeA == 0:
+        result = b = cstring
+    of cstring, ptr:
+      result = b == pointer
+    of string:
+      result = b == cstring
+
+A type ``a`` is **explicitly** convertible to type ``b`` iff the following
+algorithm returns true:
+ 
+.. code-block:: nim
+  proc isIntegralType(t: PType): bool =
+    result = isOrdinal(t) or t.kind in {float, float32, float64}
+
+  proc isExplicitlyConvertible(a, b: PType): bool =
+    result = false
+    if isImplicitlyConvertible(a, b): return true
+    if typeEqualsOrDistinct(a, b): return true
+    if isIntegralType(a) and isIntegralType(b): return true
+    if isSubtype(a, b) or isSubtype(b, a): return true
+    
+The convertible relation can be relaxed by a user-defined type 
+`converter`:idx:.
+
+.. code-block:: nim
+  converter toInt(x: char): int = result = ord(x)
+
+  var
+    x: int
+    chr: char = 'a'
+
+  # implicit conversion magic happens here
+  x = chr
+  echo x # => 97
+  # you can use the explicit form too
+  x = chr.toInt
+  echo x # => 97
+
+The type conversion ``T(a)`` is an L-value if ``a`` is an L-value and 
+``typeEqualsOrDistinct(T, type(a))`` holds.
+
+
+Assignment compatibility
+------------------------
+
+An expression ``b`` can be assigned to an expression ``a`` iff ``a`` is an
+`l-value` and ``isImplicitlyConvertible(b.typ, a.typ)`` holds.
+
+
+Overloading resolution
+----------------------
+
+To be written.
diff --git a/doc/manual/type_sections.txt b/doc/manual/type_sections.txt
new file mode 100644
index 000000000..5413e896e
--- /dev/null
+++ b/doc/manual/type_sections.txt
@@ -0,0 +1,23 @@
+Type sections
+=============
+
+Example:
+
+.. code-block:: nim
+  type # example demonstrating mutually recursive types
+    PNode = ref TNode # a traced pointer to a TNode
+    TNode = object
+      le, ri: PNode   # left and right subtrees
+      sym: ref TSym   # leaves contain a reference to a TSym
+
+    TSym = object     # a symbol
+      name: string    # the symbol's name
+      line: int       # the line the symbol was declared in
+      code: PNode     # the symbol's abstract syntax tree
+
+A type section begins with the ``type`` keyword. It contains multiple
+type definitions. A type definition binds a type to a name. Type definitions
+can be recursive or even mutually recursive. Mutually recursive types are only
+possible within a single ``type`` section. Nominal types like ``objects`` 
+or ``enums`` can only be defined in a ``type`` section.
+
diff --git a/doc/manual/typedesc.txt b/doc/manual/typedesc.txt
new file mode 100644
index 000000000..d1d8bc87a
--- /dev/null
+++ b/doc/manual/typedesc.txt
@@ -0,0 +1,146 @@
+Special Types
+=============
+
+static[T]
+---------
+
+**Note**: static[T] is still in development.
+
+As their name suggests, static params must be known at compile-time:
+
+.. code-block:: nim
+
+  proc precompiledRegex(pattern: static[string]): TRegEx =
+    var res {.global.} = re(pattern)
+    return res
+
+  precompiledRegex("/d+") # Replaces the call with a precompiled
+                          # regex, stored in a global variable
+
+  precompiledRegex(paramStr(1)) # Error, command-line options
+                                # are not known at compile-time
+
+
+For the purposes of code generation, all static params are treated as
+generic params - the proc will be compiled separately for each unique
+supplied value (or combination of values). 
+
+Furthermore, the system module defines a `semistatic[T]` type than can be
+used to declare procs accepting both static and run-time values, which can
+optimize their body according to the supplied param using the `isStatic(p)`
+predicate:
+
+.. code-block:: nim
+
+  # The following proc will be compiled once for each unique static
+  # value and also once for the case handling all run-time values:
+
+  proc re(pattern: semistatic[string]): TRegEx =
+    when isStatic(pattern):
+      result = precompiledRegex(pattern)
+    else:
+      result = compile(pattern)
+
+Static params can also appear in the signatures of generic types:
+
+.. code-block:: nim
+
+  type
+    Matrix[M,N: static[int]; T: Number] = array[0..(M*N - 1), T]
+      # Note how `Number` is just a type constraint here, while
+      # `static[int]` requires us to supply a compile-time int value
+
+    AffineTransform2D[T] = Matrix[3, 3, T]
+    AffineTransform3D[T] = Matrix[4, 4, T]
+
+  var m1: AffineTransform3D[float]  # OK
+  var m2: AffineTransform2D[string] # Error, `string` is not a `Number`
+
+
+typedesc
+--------
+
+`typedesc` is a special type allowing one to treat types as compile-time values
+(i.e. if types are compile-time values and all values have a type, then 
+typedesc must be their type).
+
+When used as a regular proc param, typedesc acts as a type class. The proc
+will be instantiated for each unique type parameter and one can refer to the
+instantiation type using the param name:
+
+.. code-block:: nim
+
+  proc new(T: typedesc): ref T =
+    echo "allocating ", T.name
+    new(result)
+
+  var n = TNode.new
+  var tree = new(TBinaryTree[int])
+
+When multiple typedesc params are present, they act like a distinct type class
+(i.e. they will bind freely to different types). To force a bind-once behavior
+one can use a named alias or an explicit `typedesc` generic param:
+
+.. code-block:: nim
+
+  # `type1` and `type2` are aliases for typedesc available from system.nim
+  proc acceptOnlyTypePairs(A, B: type1; C, D: type2)
+  proc acceptOnlyTypePairs[T: typedesc, U: typedesc](A, B: T; C, D: U)
+
+Once bound, typedesc params can appear in the rest of the proc signature:
+
+.. code-block:: nim
+
+  template declareVariableWithType(T: typedesc, value: T) =
+    var x: T = value
+
+  declareVariableWithType int, 42
+
+When used with macros and .compileTime. procs on the other hand, the compiler
+does not need to instantiate the code multiple times, because types then can be
+manipulated using the unified internal symbol representation. In such context
+typedesc acts as any other type. One can create variables, store typedesc
+values inside containers and so on. For example, here is how one can create 
+a type-safe wrapper for the unsafe `printf` function from C:
+
+.. code-block:: nim
+  macro safePrintF(formatString: string{lit}, args: varargs[expr]): expr =
+    var i = 0
+    for c in formatChars(formatString):
+      var expectedType = case c
+        of 'c': char
+        of 'd', 'i', 'x', 'X': int
+        of 'f', 'e', 'E', 'g', 'G': float
+        of 's': string
+        of 'p': pointer
+        else: EOutOfRange
+      
+      var actualType = args[i].getType
+      inc i
+
+      if expectedType == EOutOfRange:
+        error c & " is not a valid format character"
+      elif expectedType != actualType:
+        error "type mismatch for argument ", i, ". expected type: ",
+              expectedType.name, ", actual type: ", actualType.name
+    
+    # keep the original callsite, but use cprintf instead
+    result = callsite()
+    result[0] = newIdentNode(!"cprintf")
+
+
+Overload resolution can be further influenced by constraining the set of
+types that will match the typedesc param:
+
+.. code-block:: nim
+
+  template maxval(T: typedesc[int]): int = high(int)
+  template maxval(T: typedesc[float]): float = Inf
+
+  var i = int.maxval
+  var f = float.maxval
+  var s = string.maxval # error, maxval is not implemented for string
+
+The constraint can be a concrete type or a type class.
+
+
diff --git a/doc/manual/types.txt b/doc/manual/types.txt
new file mode 100644
index 000000000..274177cfb
--- /dev/null
+++ b/doc/manual/types.txt
@@ -0,0 +1,1153 @@
+Types
+=====
+
+All expressions have a type which is known at compile time. Nim
+is statically typed. One can declare new types, which is in essence defining
+an identifier that can be used to denote this custom type.
+
+These are the major type classes:
+
+* ordinal types (consist of integer, bool, character, enumeration
+  (and subranges thereof) types)
+* floating point types
+* string type
+* structured types
+* reference (pointer) type
+* procedural type
+* generic type
+
+
+Ordinal types
+-------------
+Ordinal types have the following characteristics:
+
+- Ordinal types are countable and ordered. This property allows
+  the operation of functions as ``inc``, ``ord``, ``dec`` on ordinal types to
+  be defined.
+- Ordinal values have a smallest possible value. Trying to count further
+  down than the smallest value gives a checked runtime or static error.
+- Ordinal values have a largest possible value. Trying to count further
+  than the largest value gives a checked runtime or static error.
+
+Integers, bool, characters and enumeration types (and subranges of these
+types) belong to ordinal types. For reasons of simplicity of implementation
+the types ``uint`` and ``uint64`` are not ordinal types.
+
+
+Pre-defined integer types
+-------------------------
+These integer types are pre-defined:
+
+``int``
+  the generic signed integer type; its size is platform dependent and has the
+  same size as a pointer. This type should be used in general. An integer 
+  literal that has no type suffix is of this type.
+
+intXX
+  additional signed integer types of XX bits use this naming scheme
+  (example: int16 is a 16 bit wide integer).
+  The current implementation supports ``int8``, ``int16``, ``int32``, ``int64``.
+  Literals of these types have the suffix 'iXX.
+
+``uint``
+  the generic `unsigned integer`:idx: type; its size is platform dependent and
+  has the same size as a pointer. An integer literal with the type 
+  suffix ``'u`` is of this type.
+
+uintXX
+  additional signed integer types of XX bits use this naming scheme
+  (example: uint16 is a 16 bit wide unsigned integer).
+  The current implementation supports ``uint8``, ``uint16``, ``uint32``,
+  ``uint64``. Literals of these types have the suffix 'uXX.
+  Unsigned operations all wrap around; they cannot lead to over- or 
+  underflow errors.
+
+
+In addition to the usual arithmetic operators for signed and unsigned integers
+(``+ - *`` etc.) there are also operators that formally work on *signed* 
+integers but treat their arguments as *unsigned*: They are mostly provided 
+for backwards compatibility with older versions of the language that lacked 
+unsigned integer types. These unsigned operations for signed integers use 
+the ``%`` suffix as convention:
+
+
+======================   ======================================================
+operation                meaning
+======================   ======================================================
+``a +% b``               unsigned integer addition
+``a -% b``               unsigned integer subtraction
+``a *% b``               unsigned integer multiplication
+``a /% b``               unsigned integer division
+``a %% b``               unsigned integer modulo operation
+``a <% b``               treat ``a`` and ``b`` as unsigned and compare
+``a <=% b``              treat ``a`` and ``b`` as unsigned and compare
+``ze(a)``                extends the bits of ``a`` with zeros until it has the
+                         width of the ``int`` type
+``toU8(a)``              treats ``a`` as unsigned and converts it to an
+                         unsigned integer of 8 bits (but still the
+                         ``int8`` type)
+``toU16(a)``             treats ``a`` as unsigned and converts it to an
+                         unsigned integer of 16 bits (but still the
+                         ``int16`` type)
+``toU32(a)``             treats ``a`` as unsigned and converts it to an
+                         unsigned integer of 32 bits (but still the
+                         ``int32`` type)
+======================   ======================================================
+
+`Automatic type conversion`:idx: is performed in expressions where different
+kinds of integer types are used: the smaller type is converted to the larger.
+
+A `narrowing type conversion`:idx: converts a larger to a smaller type (for
+example ``int32 -> int16``. A `widening type conversion`:idx: converts a 
+smaller type to a larger type (for example ``int16 -> int32``). In Nim only
+widening type conversions are *implicit*:
+
+.. code-block:: nim
+  var myInt16 = 5i16
+  var myInt: int
+  myInt16 + 34     # of type ``int16``
+  myInt16 + myInt  # of type ``int``
+  myInt16 + 2i32   # of type ``int32``
+
+However, ``int`` literals are implicitly convertible to a smaller integer type
+if the literal's value fits this smaller type and such a conversion is less
+expensive than other implicit conversions, so ``myInt16 + 34`` produces 
+an ``int16`` result.
+
+For further details, see `Convertible relation`_.
+
+
+Subrange types
+--------------
+A subrange type is a range of values from an ordinal type (the base
+type). To define a subrange type, one must specify it's limiting values: the
+lowest and highest value of the type:
+
+.. code-block:: nim
+  type
+    Subrange = range[0..5]
+
+
+``Subrange`` is a subrange of an integer which can only hold the values 0
+to 5. Assigning any other value to a variable of type ``Subrange`` is a
+checked runtime error (or static error if it can be statically
+determined). Assignments from the base type to one of its subrange types
+(and vice versa) are allowed.
+
+A subrange type has the same size as its base type (``int`` in the example).
+
+Nim requires `interval arithmetic`:idx: for subrange types over a set
+of built-in operators that involve constants: ``x %% 3`` is of 
+type ``range[0..2]``. The following built-in operators for integers are 
+affected by this rule: ``-``, ``+``, ``*``, ``min``, ``max``, ``succ``,
+``pred``, ``mod``, ``div``, ``%%``, ``and`` (bitwise ``and``).
+
+Bitwise ``and`` only produces a ``range`` if one of its operands is a 
+constant *x* so that (x+1) is a number of two.
+(Bitwise ``and`` is then a ``%%`` operation.)
+
+This means that the following code is accepted:
+
+.. code-block:: nim
+  case (x and 3) + 7
+  of 7: echo "A"
+  of 8: echo "B"
+  of 9: echo "C"
+  of 10: echo "D"
+  # note: no ``else`` required as (x and 3) + 7 has the type: range[7..10]
+  
+
+Pre-defined floating point types
+--------------------------------
+
+The following floating point types are pre-defined:
+
+``float``
+  the generic floating point type; its size is platform dependent
+  (the compiler chooses the processor's fastest floating point type).
+  This type should be used in general.
+
+floatXX
+  an implementation may define additional floating point types of XX bits using
+  this naming scheme (example: float64 is a 64 bit wide float). The current
+  implementation supports ``float32`` and ``float64``. Literals of these types
+  have the suffix 'fXX.
+
+
+Automatic type conversion in expressions with different kinds
+of floating point types is performed: See `Convertible relation`_ for further
+details. Arithmetic performed on floating point types follows the IEEE
+standard. Integer types are not converted to floating point types automatically
+and vice versa.
+
+The IEEE standard defines five types of floating-point exceptions:
+
+* Invalid: operations with mathematically invalid operands,
+  for example 0.0/0.0, sqrt(-1.0), and log(-37.8).
+* Division by zero: divisor is zero and dividend is a finite nonzero number,
+  for example 1.0/0.0.
+* Overflow: operation produces a result that exceeds the range of the exponent, 
+  for example MAXDOUBLE+0.0000000000001e308.
+* Underflow: operation produces a result that is too small to be represented 
+  as a normal number, for example, MINDOUBLE * MINDOUBLE.
+* Inexact: operation produces a result that cannot be represented with infinite 
+  precision, for example, 2.0 / 3.0, log(1.1) and 0.1 in input.
+
+The IEEE exceptions are either ignored at runtime or mapped to the 
+Nim exceptions: `EFloatInvalidOp`:idx:, `EFloatDivByZero`:idx:,
+`EFloatOverflow`:idx:, `EFloatUnderflow`:idx:, and `EFloatInexact`:idx:. 
+These exceptions inherit from the `EFloatingPoint`:idx: base class.
+
+Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control
+whether the IEEE exceptions are ignored or trap a Nim exception:
+
+.. code-block:: nim
+  {.NanChecks: on, InfChecks: on.}
+  var a = 1.0
+  var b = 0.0
+  echo b / b # raises EFloatInvalidOp
+  echo a / b # raises EFloatOverflow
+
+In the current implementation ``EFloatDivByZero`` and ``EFloatInexact`` are 
+never raised. ``EFloatOverflow`` is raised instead of ``EFloatDivByZero``.
+There is also a `floatChecks`:idx: pragma that is a short-cut for the 
+combination of ``NaNChecks`` and ``InfChecks`` pragmas. ``floatChecks`` are
+turned off as default.
+
+The only operations that are affected by the ``floatChecks`` pragma are
+the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
+
+An implementation should always use the maximum precision available to evaluate
+floating pointer values at compile time; this means expressions like
+``0.09'f32 + 0.01'f32 == 0.09'f64 + 0.01'f64`` are true.
+
+
+Boolean type
+------------
+The boolean type is named `bool`:idx: in Nim and can be one of the two
+pre-defined values ``true`` and ``false``. Conditions in while,
+if, elif, when statements need to be of type bool.
+
+This condition holds::
+
+  ord(false) == 0 and ord(true) == 1
+
+The operators ``not, and, or, xor, <, <=, >, >=, !=, ==`` are defined
+for the bool type. The ``and`` and ``or`` operators perform short-cut
+evaluation. Example:
+
+.. code-block:: nim
+
+  while p != nil and p.name != "xyz":
+    # p.name is not evaluated if p == nil
+    p = p.next
+
+
+The size of the bool type is one byte.
+
+
+Character type
+--------------
+The character type is named ``char`` in Nim. Its size is one byte.
+Thus it cannot represent an UTF-8 character, but a part of it.
+The reason for this is efficiency: for the overwhelming majority of use-cases,
+the resulting programs will still handle UTF-8 properly as UTF-8 was specially
+designed for this.
+Another reason is that Nim can support ``array[char, int]`` or
+``set[char]`` efficiently as many algorithms rely on this feature. The
+`TRune` type is used for Unicode characters, it can represent any Unicode
+character. ``TRune`` is declared in the `unicode module `_.
+
+
+
+
+Enumeration types
+-----------------
+Enumeration types define a new type whose values consist of the ones
+specified. The values are ordered. Example:
+
+.. code-block:: nim
+
+  type
+    TDirection = enum
+      north, east, south, west
+
+
+Now the following holds::
+
+  ord(north) == 0
+  ord(east) == 1
+  ord(south) == 2
+  ord(west) == 3
+
+Thus, north < east < south < west. The comparison operators can be used
+with enumeration types.
+
+For better interfacing to other programming languages, the fields of enum
+types can be assigned an explicit ordinal value. However, the ordinal values
+have to be in ascending order. A field whose ordinal value is not
+explicitly given is assigned the value of the previous field + 1.
+
+An explicit ordered enum can have *holes*:
+
+.. code-block:: nim
+  type
+    TTokenType = enum
+      a = 2, b = 4, c = 89 # holes are valid
+
+However, it is then not an ordinal anymore, so it is not possible to use these
+enums as an index type for arrays. The procedures ``inc``, ``dec``, ``succ``
+and ``pred`` are not available for them either.
+
+
+The compiler supports the built-in stringify operator ``$`` for enumerations.
+The stringify's result can be controlled by explicitly giving the string 
+values to use:
+
+.. code-block:: nim
+
+  type
+    TMyEnum = enum
+      valueA = (0, "my value A"),
+      valueB = "value B",
+      valueC = 2,
+      valueD = (3, "abc")
+
+As can be seen from the example, it is possible to both specify a field's 
+ordinal value and its string value by using a tuple. It is also
+possible to only specify one of them.
+
+An enum can be marked with the ``pure`` pragma so that it's fields are not
+added to the current scope, so they always need to be accessed 
+via ``TMyEnum.value``:
+
+.. code-block:: nim
+
+  type
+    TMyEnum {.pure.} = enum
+      valueA, valueB, valueC, valueD
+  
+  echo valueA # error: Unknown identifier
+  echo TMyEnum.valueA # works
+
+
+String type
+-----------
+All string literals are of the type ``string``. A string in Nim is very
+similar to a sequence of characters. However, strings in Nim are both
+zero-terminated and have a length field. One can retrieve the length with the
+builtin ``len`` procedure; the length never counts the terminating zero.
+The assignment operator for strings always copies the string.
+The ``&`` operator concatenates strings.
+
+Strings are compared by their lexicographical order. All comparison operators
+are available. Strings can be indexed like arrays (lower bound is 0). Unlike
+arrays, they can be used in case statements:
+
+.. code-block:: nim
+
+  case paramStr(i)
+  of "-v": incl(options, optVerbose)
+  of "-h", "-?": incl(options, optHelp)
+  else: write(stdout, "invalid command line option!\n")
+
+Per convention, all strings are UTF-8 strings, but this is not enforced. For
+example, when reading strings from binary files, they are merely a sequence of
+bytes. The index operation ``s[i]`` means the i-th *char* of ``s``, not the
+i-th *unichar*. The iterator ``runes`` from the `unicode module
+`_ can be used for iteration over all Unicode characters.
+
+
+CString type
+------------
+The ``cstring`` type represents a pointer to a zero-terminated char array
+compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy
+interfacing with C. The index operation ``s[i]`` means the i-th *char* of 
+``s``; however no bounds checking for ``cstring`` is performed making the
+index operation unsafe.
+
+A Nim ``string`` is implicitly convertible 
+to ``cstring`` for convenience. If a Nim string is passed to a C-style
+variadic proc, it is implicitly converted to ``cstring`` too:
+
+.. code-block:: nim
+  proc printf(formatstr: cstring) {.importc: "printf", varargs, 
+                                    header: "".}
+  
+  printf("This works %s", "as expected")
+
+Even though the conversion is implicit, it is not *safe*: The garbage collector
+does not consider a ``cstring`` to be a root and may collect the underlying 
+memory. However in practice this almost never happens as the GC considers
+stack roots conservatively. One can use the builtin procs ``GC_ref`` and
+``GC_unref`` to keep the string data alive for the rare cases where it does
+not work.
+
+A `$` proc is defined for cstrings that returns a string. Thus to get a nim
+string from a cstring:
+
+.. code-block:: nim
+  var str: string = "Hello!"
+  var cstr: cstring = s
+  var newstr: string = $cstr
+
+
+Structured types
+----------------
+A variable of a structured type can hold multiple values at the same
+time. Structured types can be nested to unlimited levels. Arrays, sequences,
+tuples, objects and sets belong to the structured types.
+
+Array and sequence types
+------------------------
+Arrays are a homogeneous type, meaning that each element in the array
+has the same type. Arrays always have a fixed length which is specified at
+compile time (except for open arrays). They can be indexed by any ordinal type.
+A parameter ``A`` may be an *open array*, in which case it is indexed by
+integers from 0 to ``len(A)-1``. An array expression may be constructed by the
+array constructor ``[]``.
+
+Sequences are similar to arrays but of dynamic length which may change
+during runtime (like strings). Sequences are implemented as growable arrays, 
+allocating pieces of memory as items are added. A sequence ``S`` is always
+indexed by integers from 0 to ``len(S)-1`` and its bounds are checked. 
+Sequences can be constructed by the array constructor ``[]`` in conjunction
+with the array to sequence operator ``@``. Another way to allocate space for a
+sequence is to call the built-in ``newSeq`` procedure.
+
+A sequence may be passed to a parameter that is of type *open array*.
+
+Example:
+
+.. code-block:: nim
+
+  type
+    TIntArray = array[0..5, int] # an array that is indexed with 0..5
+    TIntSeq = seq[int] # a sequence of integers
+  var
+    x: TIntArray
+    y: TIntSeq
+  x = [1, 2, 3, 4, 5, 6]  # [] is the array constructor
+  y = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence
+
+The lower bound of an array or sequence may be received by the built-in proc
+``low()``, the higher bound by ``high()``. The length may be
+received by ``len()``. ``low()`` for a sequence or an open array always returns
+0, as this is the first valid index.
+One can append elements to a sequence with the ``add()`` proc or the ``&``
+operator, and remove (and get) the last element of a sequence with the
+``pop()`` proc.
+
+The notation ``x[i]`` can be used to access the i-th element of ``x``.
+
+Arrays are always bounds checked (at compile-time or at runtime). These
+checks can be disabled via pragmas or invoking the compiler with the
+``--boundChecks:off`` command line switch.
+
+
+Open arrays
+-----------
+
+Often fixed size arrays turn out to be too inflexible; procedures should
+be able to deal with arrays of different sizes. The `openarray`:idx: type
+allows this; it can only be used for parameters. Openarrays are always 
+indexed with an ``int`` starting at position 0. The ``len``, ``low`` 
+and ``high`` operations are available for open arrays too. Any array with 
+a compatible base type can be passed to an openarray parameter, the index 
+type does not matter. In addition to arrays sequences can also be passed 
+to an open array parameter.
+
+The openarray type cannot be nested: multidimensional openarrays are not
+supported because this is seldom needed and cannot be done efficiently.
+
+
+Varargs
+-------
+
+A ``varargs`` parameter is an openarray parameter that additionally
+allows to pass a variable number of arguments to a procedure. The compiler 
+converts the list of arguments to an array implicitly:
+
+.. code-block:: nim
+  proc myWriteln(f: TFile, a: varargs[string]) =
+    for s in items(a):
+      write(f, s)
+    write(f, "\n")
+
+  myWriteln(stdout, "abc", "def", "xyz")
+  # is transformed to:
+  myWriteln(stdout, ["abc", "def", "xyz"])
+
+This transformation is only done if the varargs parameter is the
+last parameter in the procedure header. It is also possible to perform
+type conversions in this context:
+
+.. code-block:: nim
+  proc myWriteln(f: TFile, a: varargs[string, `$`]) =
+    for s in items(a):
+      write(f, s)
+    write(f, "\n")
+
+  myWriteln(stdout, 123, "abc", 4.0)
+  # is transformed to:
+  myWriteln(stdout, [$123, $"def", $4.0])
+
+In this example ``$`` is applied to any argument that is passed to the 
+parameter ``a``. (Note that ``$`` applied to strings is a nop.)
+
+
+
+Tuples and object types
+-----------------------
+A variable of a tuple or object type is a heterogeneous storage
+container.
+A tuple or object defines various named *fields* of a type. A tuple also
+defines an *order* of the fields. Tuples are meant for heterogeneous storage
+types with no overhead and few abstraction possibilities. The constructor ``()``
+can be used to construct tuples. The order of the fields in the constructor
+must match the order of the tuple's definition. Different tuple-types are
+*equivalent* if they specify the same fields of the same type in the same
+order. The *names* of the fields also have to be identical but this might
+change in a future version of the language.
+
+The assignment operator for tuples copies each component.
+The default assignment operator for objects copies each component. Overloading
+of the assignment operator for objects is not possible, but this will change
+in future versions of the compiler.
+
+.. code-block:: nim
+
+  type
+    TPerson = tuple[name: string, age: int] # type representing a person:
+                                            # a person consists of a name
+                                            # and an age
+  var
+    person: TPerson
+  person = (name: "Peter", age: 30)
+  # the same, but less readable:
+  person = ("Peter", 30)
+
+The implementation aligns the fields for best access performance. The alignment
+is compatible with the way the C compiler does it. 
+
+For consistency  with ``object`` declarations, tuples in a ``type`` section
+can also be defined with indentation instead of ``[]``:
+
+.. code-block:: nim
+  type
+    TPerson = tuple   # type representing a person
+      name: string    # a person consists of a name
+      age: natural    # and an age
+
+Objects provide many features that tuples do not. Object provide inheritance
+and information hiding. Objects have access to their type at runtime, so that
+the ``of`` operator can be used to determine the object's type.
+
+.. code-block:: nim
+  type
+    TPerson {.inheritable.} = object
+      name*: string   # the * means that `name` is accessible from other modules
+      age: int        # no * means that the field is hidden
+
+    TStudent = object of TPerson # a student is a person
+      id: int                    # with an id field
+
+  var
+    student: TStudent
+    person: TPerson
+  assert(student of TStudent) # is true
+
+Object fields that should be visible from outside the defining module, have to
+be marked by ``*``. In contrast to tuples, different object types are
+never *equivalent*. Objects that have no ancestor are implicitly ``final``
+and thus have no hidden type field. One can use the ``inheritable`` pragma to
+introduce new object roots apart from ``system.TObject``.
+
+
+Object construction
+-------------------
+
+Objects can also be created with an `object construction expression`:idx: that
+has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is 
+an ``object`` type or a ``ref object`` type:
+
+.. code-block:: nim
+  var student = TStudent(name: "Anton", age: 5, id: 3)
+
+For a ``ref object`` type ``system.new`` is invoked implicitly.
+
+
+Object variants
+---------------
+Often an object hierarchy is overkill in certain situations where simple
+variant types are needed.
+
+An example:
+
+.. code-block:: nim
+
+  # This is an example how an abstract syntax tree could be modelled in Nim
+  type
+    TNodeKind = enum  # the different node types
+      nkInt,          # a leaf with an integer value
+      nkFloat,        # a leaf with a float value
+      nkString,       # a leaf with a string value
+      nkAdd,          # an addition
+      nkSub,          # a subtraction
+      nkIf            # an if statement
+    PNode = ref TNode
+    TNode = object
+      case kind: TNodeKind  # the ``kind`` field is the discriminator
+      of nkInt: intVal: int
+      of nkFloat: floatVal: float
+      of nkString: strVal: string
+      of nkAdd, nkSub:
+        leftOp, rightOp: PNode
+      of nkIf:
+        condition, thenPart, elsePart: PNode
+
+  # create a new case object:
+  var n = PNode(kind: nkIf, condition: nil)
+  # accessing n.thenPart is valid because the ``nkIf`` branch is active:
+  n.thenPart = PNode(kind: nkFloat, floatVal: 2.0)
+
+  # the following statement raises an `EInvalidField` exception, because
+  # n.kind's value does not fit and the ``nkString`` branch is not active:
+  n.strVal = ""
+  
+  # invalid: would change the active object branch:
+  n.kind = nkInt
+  
+  var x = PNode(kind: nkAdd, leftOp: PNode(kind: nkInt, intVal: 4),
+                             rightOp: PNode(kind: nkInt, intVal: 2))
+  # valid: does not change the active object branch:
+  x.kind = nkSub
+
+As can been seen from the example, an advantage to an object hierarchy is that
+no casting between different object types is needed. Yet, access to invalid
+object fields raises an exception.
+
+The syntax of ``case`` in an object declaration follows closely the syntax of
+the ``case`` statement: The branches in a ``case`` section may be indented too.
+
+In the example the ``kind`` field is called the `discriminator`:idx:\: For
+safety its address cannot be taken and assignments to it are restricted: The
+new value must not lead to a change of the active object branch. For an object
+branch switch ``system.reset`` has to be used.
+
+
+Set type
+--------
+
+.. include:: sets_fragment.txt
+
+Reference and pointer types
+---------------------------
+References (similar to pointers in other programming languages) are a
+way to introduce many-to-one relationships. This means different references can
+point to and modify the same location in memory (also called `aliasing`:idx:).
+
+Nim distinguishes between `traced`:idx: and `untraced`:idx: references.
+Untraced references are also called *pointers*. Traced references point to
+objects of a garbage collected heap, untraced references point to
+manually allocated objects or to objects somewhere else in memory. Thus
+untraced references are *unsafe*. However for certain low-level operations
+(accessing the hardware) untraced references are unavoidable.
+
+Traced references are declared with the **ref** keyword, untraced references
+are declared with the **ptr** keyword.
+
+An empty subscript ``[]`` notation can be used to derefer a reference, 
+the ``addr`` procedure returns the address of an item. An address is always 
+an untraced reference.
+Thus the usage of ``addr`` is an *unsafe* feature.
+
+The ``.`` (access a tuple/object field operator)
+and ``[]`` (array/string/sequence index operator) operators perform implicit
+dereferencing operations for reference types:
+
+.. code-block:: nim
+
+  type
+    PNode = ref TNode
+    TNode = object
+      le, ri: PNode
+      data: int
+
+  var
+    n: PNode
+  new(n)
+  n.data = 9 
+  # no need to write n[].data; in fact n[].data is highly discouraged!
+
+As a syntactical extension ``object`` types can be anonymous if
+declared in a type section via the ``ref object`` or ``ptr object`` notations.
+This feature is useful if an object should only gain reference semantics:
+
+.. code-block:: nim
+
+  type
+    Node = ref object
+      le, ri: Node
+      data: int
+
+
+To allocate a new traced object, the built-in procedure ``new`` has to be used.
+To deal with untraced memory, the procedures ``alloc``, ``dealloc`` and
+``realloc`` can be used. The documentation of the system module contains
+further information.
+
+If a reference points to *nothing*, it has the value ``nil``.
+
+Special care has to be taken if an untraced object contains traced objects like
+traced references, strings or sequences: in order to free everything properly,
+the built-in procedure ``GCunref`` has to be called before freeing the untraced
+memory manually:
+
+.. code-block:: nim
+  type
+    TData = tuple[x, y: int, s: string]
+
+  # allocate memory for TData on the heap:
+  var d = cast[ptr TData](alloc0(sizeof(TData)))
+
+  # create a new string on the garbage collected heap:
+  d.s = "abc"
+
+  # tell the GC that the string is not needed anymore:
+  GCunref(d.s)
+
+  # free the memory:
+  dealloc(d)
+
+Without the ``GCunref`` call the memory allocated for the ``d.s`` string would
+never be freed. The example also demonstrates two important features for low
+level programming: the ``sizeof`` proc returns the size of a type or value
+in bytes. The ``cast`` operator can circumvent the type system: the compiler
+is forced to treat the result of the ``alloc0`` call (which returns an untyped
+pointer) as if it would have the type ``ptr TData``. Casting should only be
+done if it is unavoidable: it breaks type safety and bugs can lead to
+mysterious crashes.
+
+**Note**: The example only works because the memory is initialized to zero
+(``alloc0`` instead of ``alloc`` does this): ``d.s`` is thus initialized to
+``nil`` which the string assignment can handle. One needs to know low level
+details like this when mixing garbage collected data with unmanaged memory.
+
+.. XXX finalizers for traced objects
+
+
+Not nil annotation
+------------------
+
+All types for that ``nil`` is a valid value can be annotated to 
+exclude ``nil`` as a valid value with the ``not nil`` annotation:
+
+.. code-block:: nim
+  type
+    PObject = ref TObj not nil
+    TProc = (proc (x, y: int)) not nil
+    
+  proc p(x: PObject) =
+    echo "not nil"
+  
+  # compiler catches this:
+  p(nil)
+  
+  # and also this:
+  var x: PObject
+  p(x)
+
+The compiler ensures that every code path initializes variables which contain
+not nilable pointers. The details of this analysis are still to be specified
+here.
+
+
+Memory regions
+--------------
+
+The types ``ref`` and ``ptr`` can get an optional ``region`` annotation.
+A region has to be an object type.
+
+Regions are very useful to separate user space and kernel memory in the
+development of OS kernels:
+
+.. code-block:: nim
+  type
+    Kernel = object
+    Userspace = object
+
+  var a: Kernel ptr Stat
+  var b: Userspace ptr Stat
+
+  # the following does not compile as the pointer types are incompatible:
+  a = b
+
+As the example shows ``ptr`` can also be used as a binary
+operator, ``region ptr T`` is a shortcut for ``ptr[region, T]``.
+
+In order to make generic code easier to write ``ptr T`` is a subtype
+of ``ptr[R, T]`` for any ``R``.
+
+Furthermore the subtype relation of the region object types is lifted to
+the pointer types: If ``A <: B`` then ``ptr[A, T] <: ptr[B, T]``. This can be
+used to model subregions of memory. As a special typing rule ``ptr[R, T]`` is
+not compatible to ``pointer`` to prevent the following from compiling:
+
+.. code-block:: nim
+  # from system
+  proc dealloc(p: pointer)
+
+  # wrap some scripting language
+  type
+    PythonsHeap = object
+    PyObjectHeader = object
+      rc: int
+      typ: pointer
+    PyObject = ptr[PythonsHeap, PyObjectHeader]
+
+  proc createPyObject(): PyObject {.importc: "...".}
+  proc destroyPyObject(x: PyObject) {.importc: "...".}
+
+  var foo = createPyObject()
+  # type error here, how convenient:
+  dealloc(foo)
+
+
+Future directions:
+
+* Memory regions might become available for  ``string`` and ``seq`` too.
+* Builtin regions like ``private``, ``global`` and ``local`` will
+  prove very useful for the upcoming OpenCL target.
+* Builtin "regions" can model ``lent`` and ``unique`` pointers.
+
+
+
+Procedural type
+---------------
+A procedural type is internally a pointer to a procedure. ``nil`` is
+an allowed value for variables of a procedural type. Nim uses procedural
+types to achieve `functional`:idx: programming techniques.
+
+Examples:
+
+.. code-block:: nim
+
+  proc printItem(x: int) = ...
+
+  proc forEach(c: proc (x: int) {.cdecl.}) =
+    ...
+
+  forEach(printItem)  # this will NOT compile because calling conventions differ
+
+  
+.. code-block:: nim
+
+  type
+    TOnMouseMove = proc (x, y: int) {.closure.}
+  
+  proc onMouseMove(mouseX, mouseY: int) =
+    # has default calling convention
+    echo "x: ", mouseX, " y: ", mouseY
+  
+  proc setOnMouseMove(mouseMoveEvent: TOnMouseMove) = discard
+  
+  # ok, 'onMouseMove' has the default calling convention, which is compatible
+  # to 'closure':
+  setOnMouseMove(onMouseMove)
+  
+
+A subtle issue with procedural types is that the calling convention of the
+procedure influences the type compatibility: procedural types are only
+compatible if they have the same calling convention. As a special extension,
+a procedure of the calling convention ``nimcall`` can be passed to a parameter
+that expects a proc of the calling convention ``closure``.
+
+Nim supports these `calling conventions`:idx:\:
+
+`nimcall`:idx:
+    is the default convention used for a Nim **proc**. It is the
+    same as ``fastcall``, but only for C compilers that support ``fastcall``.
+
+`closure`:idx:
+    is the default calling convention for a **procedural type** that lacks
+    any pragma annotations. It indicates that the procedure has a hidden
+    implicit parameter (an *environment*). Proc vars that have the calling
+    convention ``closure`` take up two machine words: One for the proc pointer
+    and another one for the pointer to implicitly passed environment.
+
+`stdcall`:idx:
+    This the stdcall convention as specified by Microsoft. The generated C
+    procedure is declared with the ``__stdcall`` keyword.
+
+`cdecl`:idx:
+    The cdecl convention means that a procedure shall use the same convention
+    as the C compiler. Under windows the generated C procedure is declared with
+    the ``__cdecl`` keyword.
+
+`safecall`:idx:
+    This is the safecall convention as specified by Microsoft. The generated C
+    procedure is declared with the ``__safecall`` keyword. The word *safe*
+    refers to the fact that all hardware registers shall be pushed to the
+    hardware stack.
+
+`inline`:idx:
+    The inline convention means the the caller should not call the procedure,
+    but inline its code directly. Note that Nim does not inline, but leaves
+    this to the C compiler; it generates ``__inline`` procedures. This is
+    only a hint for the compiler: it may completely ignore it and
+    it may inline procedures that are not marked as ``inline``.
+
+`fastcall`:idx:
+    Fastcall means different things to different C compilers. One gets whatever
+    the C ``__fastcall`` means.
+
+`syscall`:idx:
+    The syscall convention is the same as ``__syscall`` in C. It is used for
+    interrupts.
+
+`noconv`:idx:
+    The generated C code will not have any explicit calling convention and thus
+    use the C compiler's default calling convention. This is needed because
+    Nim's default calling convention for procedures is ``fastcall`` to
+    improve speed.
+
+Most calling conventions exist only for the Windows 32-bit platform.
+
+Assigning/passing a procedure to a procedural variable is only allowed if one
+of the following conditions hold:
+1) The procedure that is accessed resides in the current module.
+2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma`_).
+3) The procedure has a calling convention that differs from ``nimcall``.
+4) The procedure is anonymous.
+
+The rules' purpose is to prevent the case that extending a non-``procvar`` 
+procedure with default parameters breaks client code.
+
+The default calling convention is ``nimcall``, unless it is an inner proc (a
+proc inside of a proc). For an inner proc an analysis is performed whether it
+accesses its environment. If it does so, it has the calling convention
+``closure``, otherwise it has the calling convention ``nimcall``.
+
+
+Distinct type
+-------------
+
+A ``distinct`` type is new type derived from a `base type`:idx: that is
+incompatible with its base type. In particular, it is an essential property
+of a distinct type that it **does not** imply a subtype relation between it
+and its base type. Explicit type conversions from a distinct type to its
+base type and vice versa are allowed.
+
+
+Modelling currencies
+~~~~~~~~~~~~~~~~~~~~
+
+A distinct type can be used to model different physical `units`:idx: with a
+numerical base type, for example. The following example models currencies.
+
+Different currencies should not be mixed in monetary calculations. Distinct
+types are a perfect tool to model different currencies:
+
+.. code-block:: nim
+  type
+    TDollar = distinct int
+    TEuro = distinct int
+  
+  var
+    d: TDollar
+    e: TEuro
+
+  echo d + 12
+  # Error: cannot add a number with no unit and a ``TDollar``
+
+Unfortunately, ``d + 12.TDollar`` is not allowed either,
+because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So
+a ``+`` for dollars needs to be defined:
+
+.. code-block::
+  proc `+` (x, y: TDollar): TDollar =
+    result = TDollar(int(x) + int(y))
+
+It does not make sense to multiply a dollar with a dollar, but with a
+number without unit; and the same holds for division:
+
+.. code-block::
+  proc `*` (x: TDollar, y: int): TDollar =
+    result = TDollar(int(x) * y)
+
+  proc `*` (x: int, y: TDollar): TDollar =
+    result = TDollar(x * int(y))
+    
+  proc `div` ...
+
+This quickly gets tedious. The implementations are trivial and the compiler
+should not generate all this code only to optimize it away later - after all
+``+`` for dollars should produce the same binary code as ``+`` for ints.
+The pragma `borrow`:idx: has been designed to solve this problem; in principle
+it generates the above trivial implementations:
+
+.. code-block:: nim
+  proc `*` (x: TDollar, y: int): TDollar {.borrow.}
+  proc `*` (x: int, y: TDollar): TDollar {.borrow.}
+  proc `div` (x: TDollar, y: int): TDollar {.borrow.}
+
+The ``borrow`` pragma makes the compiler use the same implementation as
+the proc that deals with the distinct type's base type, so no code is
+generated.
+
+But it seems all this boilerplate code needs to be repeated for the ``TEuro``
+currency. This can be solved with templates_.
+
+.. code-block:: nim
+  template additive(typ: typedesc): stmt =
+    proc `+` *(x, y: typ): typ {.borrow.}
+    proc `-` *(x, y: typ): typ {.borrow.}
+    
+    # unary operators:
+    proc `+` *(x: typ): typ {.borrow.}
+    proc `-` *(x: typ): typ {.borrow.}
+
+  template multiplicative(typ, base: typedesc): stmt =
+    proc `*` *(x: typ, y: base): typ {.borrow.}
+    proc `*` *(x: base, y: typ): typ {.borrow.}
+    proc `div` *(x: typ, y: base): typ {.borrow.}
+    proc `mod` *(x: typ, y: base): typ {.borrow.}
+
+  template comparable(typ: typedesc): stmt =
+    proc `<` * (x, y: typ): bool {.borrow.}
+    proc `<=` * (x, y: typ): bool {.borrow.}
+    proc `==` * (x, y: typ): bool {.borrow.}
+
+  template defineCurrency(typ, base: expr): stmt =
+    type
+      typ* = distinct base
+    additive(typ)
+    multiplicative(typ, base)
+    comparable(typ)
+    
+  defineCurrency(TDollar, int)
+  defineCurrency(TEuro, int)
+
+
+The borrow pragma can also be used to annotate the distinct type to allow
+certain builtin operations to be lifted:
+
+.. code-block:: nim
+  type
+    Foo = object
+      a, b: int
+      s: string
+
+    Bar {.borrow: `.`.} = distinct Foo
+
+  var bb: ref Bar
+  new bb
+  # field access now valid
+  bb.a = 90
+  bb.s = "abc"
+
+Currently only the dot accessor can be borrowed in this way.
+
+
+Avoiding SQL injection attacks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An SQL statement that is passed from Nim to an SQL database might be
+modelled as a string. However, using string templates and filling in the
+values is vulnerable to the famous `SQL injection attack`:idx:\:
+
+.. code-block:: nim
+  import strutils
+
+  proc query(db: TDbHandle, statement: string) = ...
+
+  var
+    username: string
+
+  db.query("SELECT FROM users WHERE name = '$1'" % username)
+  # Horrible security hole, but the compiler does not mind!
+
+This can be avoided by distinguishing strings that contain SQL from strings
+that don't. Distinct types provide a means to introduce a new string type
+``TSQL`` that is incompatible with ``string``:
+
+.. code-block:: nim
+  type
+    TSQL = distinct string
+
+  proc query(db: TDbHandle, statement: TSQL) = ...
+
+  var
+    username: string
+
+  db.query("SELECT FROM users WHERE name = '$1'" % username)
+  # Error at compile time: `query` expects an SQL string!
+
+
+It is an essential property of abstract types that they **do not** imply a
+subtype relation between the abtract type and its base type. Explict type
+conversions from ``string`` to ``TSQL`` are allowed:
+
+.. code-block:: nim
+  import strutils, sequtils
+
+  proc properQuote(s: string): TSQL =
+    # quotes a string properly for an SQL statement
+    return TSQL(s)
+
+  proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
+    # quote each argument:
+    let v = values.mapIt(TSQL, properQuote(it))
+    # we need a temporary type for the type conversion :-(
+    type TStrSeq = seq[string]
+    # call strutils.`%`:
+    result = TSQL(string(frmt) % TStrSeq(v))
+
+  db.query("SELECT FROM users WHERE name = '$1'".TSQL % [username])
+
+Now we have compile-time checking against SQL injection attacks.  Since
+``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed for nice
+looking ``TSQL`` string literals. The hypothetical ``TSQL`` type actually
+exists in the library as the `TSqlQuery type `_ of
+modules like `db_sqlite `_.
+
+
+Void type
+---------
+
+The ``void`` type denotes the absense of any type. Parameters of 
+type ``void`` are treated as non-existent, ``void`` as a return type means that
+the procedure does not return a value:
+
+.. code-block:: nim
+  proc nothing(x, y: void): void =
+    echo "ha"
+  
+  nothing() # writes "ha" to stdout
+
+The ``void`` type is particularly useful for generic code:
+
+.. code-block:: nim
+  proc callProc[T](p: proc (x: T), x: T) =
+    when T is void: 
+      p()
+    else:
+      p(x)
+
+  proc intProc(x: int) = discard
+  proc emptyProc() = discard
+
+  callProc[int](intProc, 12)
+  callProc[void](emptyProc)
+  
+However, a ``void`` type cannot be inferred in generic code:
+
+.. code-block:: nim
+  callProc(emptyProc) 
+  # Error: type mismatch: got (proc ())
+  # but expected one of: 
+  # callProc(p: proc (T), x: T)
+
+The ``void`` type is only valid for parameters and return types; other symbols
+cannot have the type ``void``.
diff --git a/doc/spawn.txt b/doc/spawn.txt
index b2496285f..fb2f851c7 100644
--- a/doc/spawn.txt
+++ b/doc/spawn.txt
@@ -19,6 +19,36 @@ read prematurely within a ``parallel`` section and so there is no need for
 the overhead of an indirection via ``FlowVar[T]`` to ensure correctness.
 
 
+Spawn statement
+===============
+
+A standalone ``spawn`` statement is a simple construct. It executes
+the passed expression on the thread pool and returns a `data flow variable`:idx:
+``FlowVar[T]`` that can be read from. The reading with the ``^`` operator is
+**blocking**. However, one can use ``awaitAny`` to wait on multiple flow
+variables at the same time:
+
+.. code-block:: nim
+  import threadpool, ...
+  
+  # wait until 2 out of 3 servers received the update:
+  proc main =
+    var responses = newSeq[RawFlowVar](3)
+    for i in 0..2:
+      responses[i] = spawn tellServer(Update, "key", "value")
+    var index = awaitAny(responses)
+    assert index >= 0
+    responses.del(index)
+    discard awaitAny(responses)
+
+Data flow variables ensure that no data races
+are possible. Due to technical limitations not every type ``T`` is possible in
+a data flow variable: ``T`` has to be of the type ``ref``, ``string``, ``seq``
+or of a type that doesn't contain a type that is garbage collected. This
+restriction will be removed in the future.
+
+
+
 Parallel statement
 ==================
 
@@ -64,35 +94,3 @@ restrictions / changes:
 * Slices are optimized so that no copy is performed. This optimization is not
   yet performed for ordinary slices outside of a ``parallel`` section. Slices
   are also special in that they currently do not support negative indexes!
-
-
-
-
-Spawn statement
-===============
-
-A standalone ``spawn`` statement is a simple construct. It executes
-the passed expression on the thread pool and returns a `data flow variable`:idx:
-``FlowVar[T]`` that can be read from. The reading with the ``^`` operator is
-**blocking**. However, one can use ``awaitAny`` to wait on multiple flow
-variables at the same time:
-
-.. code-block:: nim
-  import threadpool, ...
-  
-  # wait until 2 out of 3 servers received the update:
-  proc main =
-    var responses = newSeq[RawFlowVar](3)
-    for i in 0..2:
-      responses[i] = spawn tellServer(Update, "key", "value")
-    var index = awaitAny(responses)
-    assert index >= 0
-    responses.del(index)
-    discard awaitAny(responses)
-
-Like the ``parallel`` statement data flow variables ensure that no data races
-are possible. Due to technical limitations not every type ``T`` is possible in
-a data flow variable: ``T`` has to be of the type ``ref``, ``string``, ``seq``
-or of a type that doesn't contain a type that is garbage collected. This
-restriction will be removed in the future.
-
diff --git a/doc/tut1.txt b/doc/tut1.txt
index b90736bd0..2a836190c 100644
--- a/doc/tut1.txt
+++ b/doc/tut1.txt
@@ -65,8 +65,8 @@ done with spaces only, tabulators are not allowed.
 
 String literals are enclosed in double quotes. The ``var`` statement declares
 a new variable named ``name`` of type ``string`` with the value that is
-returned by the `readLine `_ procedure. Since the
-compiler knows that `readLine `_ returns a string,
+returned by the `readLine `_ procedure. Since the
+compiler knows that `readLine `_ returns a string,
 you can leave out the type in the declaration (this is called `local type
 inference`:idx:). So this will work too:
 
@@ -77,7 +77,7 @@ Note that this is basically the only form of type inference that exists in
 Nim: it is a good compromise between brevity and readability.
 
 The "hello world" program contains several identifiers that are already known
-to the compiler: ``echo``, `readLine `_, etc.
+to the compiler: ``echo``, `readLine `_, etc.
 These built-ins are declared in the system_ module which is implicitly
 imported by any other module.
 
@@ -526,7 +526,7 @@ Procedures
 ==========
 
 To define new commands like `echo `_ and `readLine
-`_ in the examples, the concept of a `procedure`
+`_ in the examples, the concept of a `procedure`
 is needed. (Some languages call them *methods* or *functions*.) In Nim new
 procedures are defined with the ``proc`` keyword:
 
@@ -1269,7 +1269,7 @@ arguments to a procedure. The compiler converts the list of arguments
 to an array automatically:
 
 .. code-block:: nim
-  proc myWriteln(f: TFile, a: varargs[string]) =
+  proc myWriteln(f: File, a: varargs[string]) =
     for s in items(a):
       write(f, s)
     write(f, "\n")
@@ -1283,7 +1283,7 @@ last parameter in the procedure header. It is also possible to perform
 type conversions in this context:
 
 .. code-block:: nim
-  proc myWriteln(f: TFile, a: varargs[string, `$`]) =
+  proc myWriteln(f: File, a: varargs[string, `$`]) =
     for s in items(a):
       write(f, s)
     write(f, "\n")
diff --git a/doc/tut2.txt b/doc/tut2.txt
index 0c54fa9a1..651c38838 100644
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -130,7 +130,7 @@ The syntax for type conversions is ``destination_type(expression_to_convert)``
   proc getID(x: TPerson): int =
     TStudent(x).id
 
-The ``EInvalidObjectConversion`` exception is raised if ``x`` is not a
+The ``InvalidObjectConversionError`` exception is raised if ``x`` is not a
 ``TStudent``.
 
 
@@ -164,7 +164,7 @@ An example:
         condition, thenPart, elsePart: PNode
 
   var n = PNode(kind: nkFloat, floatVal: 1.0)
-  # the following statement raises an `EInvalidField` exception, because
+  # the following statement raises an `FieldError` exception, because
   # n.kind's value does not fit:
   n.strVal = ""
 
@@ -346,9 +346,9 @@ Exceptions
 ==========
 
 In Nim exceptions are objects. By convention, exception types are
-prefixed with an 'E', not 'T'. The `system `_ module defines an
+suffixed with 'Error'. The `system `_ module defines an
 exception hierarchy that you might want to stick to. Exceptions derive from
-E_Base, which provides the common interface.
+``system.Exception``, which provides the common interface.
 
 Exceptions have to be allocated on the heap because their lifetime is unknown.
 The compiler will prevent you from raising an exception created on the stack.
@@ -366,7 +366,7 @@ Raising an exception is done with the ``raise`` statement:
 
 .. code-block:: nim
   var
-    e: ref EOS
+    e: ref OSError
   new(e)
   e.msg = "the request to the OS failed"
   raise e
@@ -376,7 +376,7 @@ is *re-raised*. For the purpose of avoiding repeating this common code pattern,
 the template ``newException`` in the ``system`` module can be used:
 
 .. code-block:: nim
-  raise newException(EOS, "the request to the OS failed")
+  raise newException(OSError, "the request to the OS failed")
 
 
 Try statement
@@ -388,17 +388,17 @@ The ``try`` statement handles exceptions:
   # read the first two lines of a text file that should contain numbers
   # and tries to add them
   var
-    f: TFile
+    f: File
   if open(f, "numbers.txt"):
     try:
       let a = readLine(f)
       let b = readLine(f)
       echo "sum: ", parseInt(a) + parseInt(b)
-    except EOverflow:
+    except OverflowError:
       echo "overflow!"
-    except EInvalidValue:
+    except ValueError:
       echo "could not convert string to integer"
-    except EIO:
+    except IOError:
       echo "IO error!"
     except:
       echo "Unknown exception!"
@@ -426,7 +426,7 @@ If you need to *access* the actual exception object or message inside an
 ``except`` branch you can use the `getCurrentException()
 `_ and `getCurrentExceptionMsg()
 `_ procs from the `system `_
-module.  Example:
+module. Example:
 
 .. code-block:: nim
   try:
@@ -441,9 +441,9 @@ module.  Example:
 Exception hierarchy
 -------------------
 
-If you want to create your own exceptions you can inherit from E_Base, but you
-can also inherit from one of the existing exceptions if they fit your purpose.
-The exception tree is:
+If you want to create your own exceptions you can inherit from ``system.Exception``,
+but you can also inherit from one of the existing exceptions if they fit your
+purpose. The exception tree is:
 
 .. include:: exception_hierarchy_fragment.txt
 
@@ -456,12 +456,12 @@ Annotating procs with raised exceptions
 Through the use of the optional ``{.raises.}`` pragma you can specify that a
 proc is meant to raise a specific set of exceptions, or none at all. If the
 ``{.raises.}`` pragma is used, the compiler will verify that this is true. For
-instance, if you specify that a proc raises ``EIO``, and at some point it (or
-one of the procs it calls) starts raising a new exception the compiler will
+instance, if you specify that a proc raises ``IOError``, and at some point it
+(or one of the procs it calls) starts raising a new exception the compiler will
 prevent that proc from compiling. Usage example:
 
 .. code-block:: nim
-  proc complexProc() {.raises: [EIO, EArithmetic].} =
+  proc complexProc() {.raises: [IOError, ArithmeticError].} =
     ...
 
   proc simpleProc() {.raises: [].} =
@@ -624,10 +624,10 @@ via a special ``:`` syntax:
 
 .. code-block:: nim
 
-  template withFile(f: expr, filename: string, mode: TFileMode,
+  template withFile(f: expr, filename: string, mode: FileMode,
                     body: stmt): stmt {.immediate.} =
     let fn = filename
-    var f: TFile
+    var f: File
     if open(f, fn, mode):
       try:
         body
@@ -767,7 +767,7 @@ use the following snippet of code as the starting point:
 
   import strutils, tables
 
-  proc readCfgAtRuntime(cfgFilename: string): TTable[string, string] =
+  proc readCfgAtRuntime(cfgFilename: string): Table[string, string] =
     let
       inputString = readFile(cfgFilename)
     var
@@ -801,7 +801,7 @@ to be included along the program containing the license information::
   licenseKey,M1Tl3PjBWO2CC48m
 
 The ``readCfgAtRuntime`` proc will open the given filename and return a
-``TTable`` from the `tables module `_. The parsing of the file is
+``Table`` from the `tables module `_. The parsing of the file is
 done (without much care for handling invalid data or corner cases) using the
 ``splitLines`` proc from the `strutils module `_. There are many
 things which can fail; mind the purpose is explaining how to make this run at
@@ -871,7 +871,7 @@ this limitation by using the ``slurp`` proc from the `system module
 `_, which was precisely made for compilation time (just like
 ``gorge`` which executes an external program and captures its output).
 
-The interesting thing is that our macro does not return a runtime ``TTable``
+The interesting thing is that our macro does not return a runtime ``Table``
 object. Instead, it builds up Nim source code into the ``source`` variable.
 For each line of the configuration file a ``const`` variable will be generated.
 To avoid conflicts we prefix these variables with ``cfg``. In essence, what the
diff --git a/koch.nim b/koch.nim
index b7a32a1b4..a43701194 100644
--- a/koch.nim
+++ b/koch.nim
@@ -38,7 +38,7 @@ Options:
   --help, -h               shows this help and quits
 Possible Commands:
   boot [options]           bootstraps with given command line options
-  install [dir]            installs to given directory
+  install [bindir]         installs to given directory
   clean                    cleans Nimrod project; removes generated files
   web [options]            generates the website
   csource [options]        builds the C sources for installation
diff --git a/todo.txt b/todo.txt
index c43132cd5..b5d832fe0 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,7 @@
 version 0.10
 ============
 
+- document the new concurrency system
 - Test nimfix on various babel packages
 - deprecate recursive tuples; tuple needs laxer type checking
 - string case should require an 'else'
@@ -14,7 +15,6 @@ version 0.9.6
 
 - split idetools into separate tool
 - split docgen into separate tool
-- .benign pragma
 - scopes are still broken for generic instantiation!
 
 Concurrency

From c99ec1654452eede8b374eb85cb05b2e759be23f Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 2 Oct 2014 10:08:41 +0200
Subject: [PATCH 165/409] deprecated string case statements without 'else'

---
 compiler/semstmts.nim |  6 +++++-
 doc/manual/stmts.txt  | 10 ++++------
 doc/tut1.txt          |  2 +-
 web/news.txt          |  5 +++++
 4 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index c386785be..063df30fd 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -199,11 +199,12 @@ proc semCase(c: PContext, n: PNode): PNode =
   var covered: BiggestInt = 0
   var typ = commonTypeBegin
   var hasElse = false
+  var notOrdinal = false
   case skipTypes(n.sons[0].typ, abstractVarRange-{tyTypeDesc}).kind
   of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool:
     chckCovered = true
   of tyFloat..tyFloat128, tyString, tyError:
-    discard
+    notOrdinal = true
   else:
     localError(n.info, errSelectorMustBeOfCertainTypes)
     return
@@ -233,6 +234,9 @@ proc semCase(c: PContext, n: PNode): PNode =
       hasElse = true
     else:
       illFormedAst(x)
+  if notOrdinal and not hasElse:
+    message(n.info, warnDeprecated,
+            "use 'else: discard'; non-ordinal case without 'else'")
   if chckCovered:
     if covered == toCover(n.sons[0].typ):
       hasElse = true
diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt
index b706101e1..1307ff917 100644
--- a/doc/manual/stmts.txt
+++ b/doc/manual/stmts.txt
@@ -262,13 +262,11 @@ given *slicelist* the ``else`` part is executed. If there is no ``else``
 part and not all possible values that ``expr`` can hold occur in a 
 ``slicelist``, a static error occurs. This holds only for expressions of 
 ordinal types. "All possible values" of ``expr`` are determined by ``expr``'s
-type. 
+type. To suppress the static error an ``else`` part with an
+empty ``discard`` statement should be used.
 
-If the expression is not of an ordinal type, and no ``else`` part is
-given, control passes after the ``case`` statement.
-
-To suppress the static error in the ordinal case an ``else`` part with an
-empty ``discard`` statement can be used.
+For non ordinal types it is not possible to list every possible value and so
+these always require an ``else`` part.
 
 As a special semantic extension, an expression in an ``of`` branch of a case
 statement may evaluate to a set or array constructor; the set or array is then
diff --git a/doc/tut1.txt b/doc/tut1.txt
index 2a836190c..950f758f1 100644
--- a/doc/tut1.txt
+++ b/doc/tut1.txt
@@ -312,7 +312,7 @@ the compiler that for every other value nothing should be done:
 The empty `discard statement`_ is a *do nothing* statement. The compiler knows
 that a case statement with an else part cannot fail and thus the error 
 disappears. Note that it is impossible to cover all possible string values: 
-that is why there is no such check for string cases.
+that is why string cases always need an ``else`` branch.
 
 In general the case statement is used for subrange types or enumerations where
 it is of great help that the compiler checks that you covered any possible
diff --git a/web/news.txt b/web/news.txt
index 93cb71f94..233a8e2c7 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -47,11 +47,16 @@ News
     found under the `nim-code `_ organisation.
   - Removed the deprecated ``web`` module, the ``httpclient`` module should
     be used instead.
+  - String case (or any non-ordinal case) statements 
+    without 'else' are deprecated.
+
 
   Language Additions
   ------------------
 
   - There is a new ``parallel`` statement for safe fork&join parallel computing.
+  - ``guard`` and ``lock`` pragmas have been implemented to support safer
+    concurrent programming.
   
 
   Library Additions

From 4298553de48ba1a3bd9b98b4c1716674294cf4da Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 2 Oct 2014 10:52:32 +0200
Subject: [PATCH 166/409] system.writeFile works at compile-time

---
 compiler/vmops.nim | 9 +++++++++
 todo.txt           | 2 --
 web/news.txt       | 2 +-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/compiler/vmops.nim b/compiler/vmops.nim
index 8e75cc23a..aa25d208a 100644
--- a/compiler/vmops.nim
+++ b/compiler/vmops.nim
@@ -21,6 +21,9 @@ template mathop(op) {.immediate, dirty.} =
 template osop(op) {.immediate, dirty.} =
   registerCallback(c, "stdlib.os." & astToStr(op), `op Wrapper`)
 
+template systemop(op) {.immediate, dirty.} =
+  registerCallback(c, "stdlib.system." & astToStr(op), `op Wrapper`)
+
 template wrap1f(op) {.immediate, dirty.} =
   proc `op Wrapper`(a: VmArgs) {.nimcall.} =
     setResult(a, op(getFloat(a, 0)))
@@ -36,6 +39,11 @@ template wrap1s(op) {.immediate, dirty.} =
     setResult(a, op(getString(a, 0)))
   osop op
 
+template wrap2svoid(op) {.immediate, dirty.} =
+  proc `op Wrapper`(a: VmArgs) {.nimcall.} =
+    op(getString(a, 0), getString(a, 1))
+  systemop op
+
 proc registerAdditionalOps*(c: PCtx) =
   wrap1f(sqrt)
   wrap1f(ln)
@@ -64,3 +72,4 @@ proc registerAdditionalOps*(c: PCtx) =
   wrap1s(existsEnv)
   wrap1s(dirExists)
   wrap1s(fileExists)
+  wrap2svoid(writeFile)
diff --git a/todo.txt b/todo.txt
index b5d832fe0..ed09a21d1 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,10 +1,8 @@
 version 0.10
 ============
 
-- document the new concurrency system
 - Test nimfix on various babel packages
 - deprecate recursive tuples; tuple needs laxer type checking
-- string case should require an 'else'
 - # echo type.int
 - VM: try does not work at all
 - VM: Pegs do not work at compile-time
diff --git a/web/news.txt b/web/news.txt
index 233a8e2c7..7edd7c9df 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -57,7 +57,7 @@ News
   - There is a new ``parallel`` statement for safe fork&join parallel computing.
   - ``guard`` and ``lock`` pragmas have been implemented to support safer
     concurrent programming.
-  
+  - ``system.writeFile`` can be used at compile-time.
 
   Library Additions
   -----------------

From 2475794a75cb0455ba9cdf7af427047fb9cde61e Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 2 Oct 2014 11:10:43 +0200
Subject: [PATCH 167/409] fixes a minor bug when 'type' is used in a wrong way

---
 compiler/renderer.nim | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 29f581573..a4469acda 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -1009,9 +1009,9 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
     put(g, tkElse, " else")
     putWithSpace(g, tkColon, ":")
     gsub(g, n.sons[0])
-  of nkTypeOfExpr: 
+  of nkTypeOfExpr:
     putWithSpace(g, tkType, "type")
-    gsub(g, n.sons[0])
+    if n.len > 0: gsub(g, n.sons[0])
   of nkRefTy: 
     if sonsLen(n) > 0:
       putWithSpace(g, tkRef, "ref")

From 62ccf135294672995e08584723c35162f7facc22 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 2 Oct 2014 15:55:48 +0200
Subject: [PATCH 168/409] 'try' works at compile-time

---
 compiler/vm.nim | 13 ++++++-
 todo.txt        | 95 ++-----------------------------------------------
 2 files changed, 15 insertions(+), 93 deletions(-)

diff --git a/compiler/vm.nim b/compiler/vm.nim
index f74f2e0d7..e5b357a11 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -258,8 +258,16 @@ proc cleanUpOnException(c: PCtx; tos: PStackFrame):
         c.currentExceptionB = c.currentExceptionA
         c.currentExceptionA = nil
         # execute the corresponding handler:
+        while c.code[pc2].opcode == opcExcept: inc pc2
         return (pc2, f)
       inc pc2
+      if c.code[pc2].opcode != opcExcept and nextExceptOrFinally >= 0:
+        # we're at the end of the *except list*, but maybe there is another
+        # *except branch*?
+        pc2 = nextExceptOrFinally+1
+        if c.code[pc2].opcode == opcExcept:
+          nextExceptOrFinally = pc2 + c.code[pc2].regBx - wordExcess
+
     if nextExceptOrFinally >= 0:
       pc2 = nextExceptOrFinally
     if c.code[pc2].opcode == opcFinally:
@@ -891,10 +899,13 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
     of opcTry:
       let rbx = instr.regBx - wordExcess
       tos.pushSafePoint(pc + rbx)
+      assert c.code[pc+rbx].opcode in {opcExcept, opcFinally}
     of opcExcept:
       # just skip it; it's followed by a jump;
       # we'll execute in the 'raise' handler
-      discard
+      let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
+      inc pc, rbx
+      assert c.code[pc+1].opcode in {opcExcept, opcFinally}
     of opcFinally:
       # just skip it; it's followed by the code we need to execute anyway
       tos.popSafePoint()
diff --git a/todo.txt b/todo.txt
index ed09a21d1..2a6a74dae 100644
--- a/todo.txt
+++ b/todo.txt
@@ -3,8 +3,6 @@ version 0.10
 
 - Test nimfix on various babel packages
 - deprecate recursive tuples; tuple needs laxer type checking
-- # echo type.int
-- VM: try does not work at all
 - VM: Pegs do not work at compile-time
 - VM: ptr/ref T cannot work in general
 
@@ -13,7 +11,6 @@ version 0.9.6
 
 - split idetools into separate tool
 - split docgen into separate tool
-- scopes are still broken for generic instantiation!
 
 Concurrency
 -----------
@@ -46,6 +43,7 @@ Misc
 Bugs
 ====
 
+- scopes are still broken for generic instantiation!
 - bug: 'type T = ref T' not recognized as illegal recursion
 - bug: type conversions concerning proc types are weird
 - compilation of niminst takes way too long. looks like a regression
@@ -58,7 +56,7 @@ version 0.9.x
 
 
 - implicit deref for parameter matching
-- overloading of '='; general lift mechanism
+- overloading of '='
 - allow simple read accesses to global variables --> difficult to ensure that
   no data races happen
 - pragmas need 'bindSym' support
@@ -70,81 +68,22 @@ version 0.9.x
 - provide --nilChecks:on|off
 - ensure (ref T)(a, b) works as a type conversion and type constructor
 - optimize 'genericReset'; 'newException' leads to code bloat
-- stack-less GC
 
 
 version 0.9.X
 =============
 
 - macros as type pragmas
+- implement type API for macros
 - lazy overloading resolution:
   * special case ``tyStmt``
-- FFI:
-  * test: times.format with the FFI
 - document NimMain and check whether it works for threading
-- 'quote' without 'do' doesn't work: parser/grammar issue; could be supported
-
-
-version 0.9.X
-=============
-
-- implement the missing features wrt inheritance
-- better support for macros that rewrite procs
-- macros need access to types and symbols (partially implemented)
-- enforce 'simpleExpr' more often --> doesn't work; tkProc is
-  part of primary!
-- the typeDesc/expr unification is weird and only necessary because of
-  the ambiguous a[T] construct: It would be easy to support a[expr] for
-  generics but require a[.typeDesc] if that's required; this would also
-  allow [.ref T.](x) for a more general type conversion construct; for
-  templates that would work too: T([.ref int])
-
-
-Concurrency/Effect system
-=========================
-
-- shared memory heap: ``shared ref`` etc. The only hard part in the GC is to
-  "stop the world". However, it may be worthwhile to generate explicit 
-  (or implicit) syncGC() calls in loops. Automatic loop injection seems
-  troublesome, but maybe we can come up with a simple heuristic. (All procs
-  that `new` shared memory are syncGC() candidates... But then 'new' itself
-  calls syncGC() so that's pointless.) Hm instead of an heuristic simply
-  provide a ``syncgc`` pragma to trigger compiler injection --> more general:
-  an ``injectLoop`` pragma
-- 'writes: []' effect; track reads/writes for shared types
-- ``~`` operator for effects
-- introduce 'noaddr' pragma to prevent taking the address of a location; this
-  is very handy to prevent aliasing of global data
-
-
-version 0.9.XX
-==============
-
-- make 'clamp' a magic for the range stuff
-- better type syntax for functions and tuples: tuple(int, int); (int,int)->int
-
-
-Memory safety
-=============
-
-- object branch transitions from low(selector) are unsafe! ---> Needs a 
-  deprecation path
-- object branch transitions can't work with the current 'reset'; add a 'reset'
-  with an additional parameter --> simple:
-  provide a 'reset(x, TObj(k: nkValue))' instead? why bother? '=' does the
-  same.
-- returning 'var T' is unsafe and needs some static analysis
-
 
 GC
 ==
 
-- precise stack marking; embrace C++ code generation for that
-- marker procs for Boehm GC
 - hybrid GC
-- acyclic vs prunable; introduce GC hints
 - use big blocks in the allocator
-- object pooling support for *hard* realtime systems
 - provide tool/API to track leaks/object counts
 - resizing of strings/sequences could take into account the memory that
   is allocated
@@ -155,31 +94,3 @@ CGEN
 - codegen should use "NIM_CAST" macro and respect aliasing rules for GCC
 - ``restrict`` pragma + backend support
 - 'const' objects including case objects
-
-
-Not essential for 1.0.0
-=======================
-
-- allow implicit forward declarations of procs via a pragma (so that the
-  wrappers can deactivate it): better solution: introduce the notion of a 
-  'proc section' that is similar to a type section.
-- implement the "snoopResult" pragma; no, make a strutils with string append
-  semantics instead ...
-- implement "closure tuple consists of a single 'ref'" optimization
-- new feature: ``distinct T with operations``
-- arglist as a type (iterator chaining); variable length type lists for generics
-- object constructors: static check for fields if discriminator is known at 
-  compile time
-- prove array accesses
-
-
-Optimizations
-=============
-
-- optimize 'if' with a constant condition --> necessary in frontend for better
-  dead code elimination; also necessary to prevent  ``if c > 0: 1 div c``
-- escape analysis for string/seq seems to be easy to do too;
-  even further write barrier specialization
-- inlining of first class functions
-- proc specialization in the code gen for write barrier specialization
-- VM/optimizer: implement on the fly CSE

From 279e897eab4806ee66b0a03d9e7ecf7940a57c6e Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 2 Oct 2014 16:15:16 +0200
Subject: [PATCH 169/409] bugfix: 'T = ref T' is an illegal recursive type

---
 compiler/semexprs.nim | 1 +
 compiler/semfold.nim  | 1 +
 compiler/types.nim    | 5 +++--
 todo.txt              | 4 +++-
 web/news.txt          | 1 +
 5 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 64914cb25..d3650f984 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -367,6 +367,7 @@ proc isOpImpl(c: PContext, n: PNode): PNode =
       result = newIntNode(nkIntLit, ord(t.kind == tyProc and
                                         t.callConv == ccClosure and 
                                         tfIterator notin t.flags))
+    else: discard
   else:
     var t2 = n[2].typ.skipTypes({tyTypeDesc})
     maybeLiftType(t2, c, n.info)
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 6972e3f1c..76ac23e0d 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -255,6 +255,7 @@ proc evalIs(n, a: PNode): PNode =
       result = newIntNode(nkIntLit, ord(t.kind == tyProc and
                                         t.callConv == ccClosure and 
                                         tfIterator in t.flags))
+    else: discard
   else:
     # XXX semexprs.isOpImpl is slightly different and requires a context. yay.
     let t2 = n[2].typ
diff --git a/compiler/types.nim b/compiler/types.nim
index 5ef2d627b..55ec971d9 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1208,8 +1208,9 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
     else: result = ptrSize
     a = ptrSize
   of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray,
-     tyBigNum: 
-    result = ptrSize
+     tyBigNum:
+    if typ.lastSon == typ: result = szIllegalRecursion
+    else: result = ptrSize
     a = result
   of tyArray, tyArrayConstr:
     let elemSize = computeSizeAux(typ.sons[1], a)
diff --git a/todo.txt b/todo.txt
index 2a6a74dae..e06b3d030 100644
--- a/todo.txt
+++ b/todo.txt
@@ -2,7 +2,10 @@ version 0.10
 ============
 
 - Test nimfix on various babel packages
+
+- bug: 'type T = ref T' not recognized as illegal recursion
 - deprecate recursive tuples; tuple needs laxer type checking
+
 - VM: Pegs do not work at compile-time
 - VM: ptr/ref T cannot work in general
 
@@ -44,7 +47,6 @@ Bugs
 ====
 
 - scopes are still broken for generic instantiation!
-- bug: 'type T = ref T' not recognized as illegal recursion
 - bug: type conversions concerning proc types are weird
 - compilation of niminst takes way too long. looks like a regression
 - docgen: sometimes effects are listed twice
diff --git a/web/news.txt b/web/news.txt
index 7edd7c9df..cf24139f7 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -49,6 +49,7 @@ News
     be used instead.
   - String case (or any non-ordinal case) statements 
     without 'else' are deprecated.
+  - Recursive tuple types are deprecated. Use ``object`` instead.
 
 
   Language Additions

From 595cc93762397ad6948a3b14298fe23a00b89667 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 2 Oct 2014 16:54:05 +0200
Subject: [PATCH 170/409] recursive tuple types are now invalid (breaking
 change)

---
 compiler/types.nim                |  4 +-
 doc/manual/types.txt              | 80 +++++++++++++++++--------------
 lib/pure/collections/sequtils.nim |  2 +
 todo.txt                          |  5 --
 web/news.txt                      |  2 +-
 5 files changed, 51 insertions(+), 42 deletions(-)

diff --git a/compiler/types.nim b/compiler/types.nim
index 55ec971d9..07a0cf941 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1209,7 +1209,9 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
     a = ptrSize
   of tyNil, tyCString, tyString, tySequence, tyPtr, tyRef, tyVar, tyOpenArray,
      tyBigNum:
-    if typ.lastSon == typ: result = szIllegalRecursion
+    let base = typ.lastSon
+    if base == typ or (base.kind == tyTuple and base.size==szIllegalRecursion):
+      result = szIllegalRecursion
     else: result = ptrSize
     a = result
   of tyArray, tyArrayConstr:
diff --git a/doc/manual/types.txt b/doc/manual/types.txt
index 274177cfb..b8cde8c37 100644
--- a/doc/manual/types.txt
+++ b/doc/manual/types.txt
@@ -194,9 +194,10 @@ The IEEE standard defines five types of floating-point exceptions:
   precision, for example, 2.0 / 3.0, log(1.1) and 0.1 in input.
 
 The IEEE exceptions are either ignored at runtime or mapped to the 
-Nim exceptions: `EFloatInvalidOp`:idx:, `EFloatDivByZero`:idx:,
-`EFloatOverflow`:idx:, `EFloatUnderflow`:idx:, and `EFloatInexact`:idx:. 
-These exceptions inherit from the `EFloatingPoint`:idx: base class.
+Nim exceptions: `FloatInvalidOpError`:idx:, `FloatDivByZeroError`:idx:,
+`FloatOverflowError`:idx:, `FloatUnderflowError`:idx:,
+and `FloatInexactError`:idx:. 
+These exceptions inherit from the `FloatingPointError`:idx: base class.
 
 Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control
 whether the IEEE exceptions are ignored or trap a Nim exception:
@@ -205,11 +206,12 @@ whether the IEEE exceptions are ignored or trap a Nim exception:
   {.NanChecks: on, InfChecks: on.}
   var a = 1.0
   var b = 0.0
-  echo b / b # raises EFloatInvalidOp
-  echo a / b # raises EFloatOverflow
+  echo b / b # raises FloatInvalidOpError
+  echo a / b # raises FloatOverflowError
 
-In the current implementation ``EFloatDivByZero`` and ``EFloatInexact`` are 
-never raised. ``EFloatOverflow`` is raised instead of ``EFloatDivByZero``.
+In the current implementation ``FloatDivByZeroError`` and ``FloatInexactError``
+are never raised. ``FloatOverflowError`` is raised instead of
+``FloatDivByZeroError``.
 There is also a `floatChecks`:idx: pragma that is a short-cut for the 
 combination of ``NaNChecks`` and ``InfChecks`` pragmas. ``floatChecks`` are
 turned off as default.
@@ -269,7 +271,7 @@ specified. The values are ordered. Example:
 .. code-block:: nim
 
   type
-    TDirection = enum
+    Direction = enum
       north, east, south, west
 
 
@@ -292,7 +294,7 @@ An explicit ordered enum can have *holes*:
 
 .. code-block:: nim
   type
-    TTokenType = enum
+    TokenType = enum
       a = 2, b = 4, c = 89 # holes are valid
 
 However, it is then not an ordinal anymore, so it is not possible to use these
@@ -307,7 +309,7 @@ values to use:
 .. code-block:: nim
 
   type
-    TMyEnum = enum
+    MyEnum = enum
       valueA = (0, "my value A"),
       valueB = "value B",
       valueC = 2,
@@ -319,16 +321,16 @@ possible to only specify one of them.
 
 An enum can be marked with the ``pure`` pragma so that it's fields are not
 added to the current scope, so they always need to be accessed 
-via ``TMyEnum.value``:
+via ``MyEnum.value``:
 
 .. code-block:: nim
 
   type
-    TMyEnum {.pure.} = enum
+    MyEnum {.pure.} = enum
       valueA, valueB, valueC, valueD
   
   echo valueA # error: Unknown identifier
-  echo TMyEnum.valueA # works
+  echo MyEnum.valueA # works
 
 
 String type
@@ -358,7 +360,7 @@ i-th *unichar*. The iterator ``runes`` from the `unicode module
 `_ can be used for iteration over all Unicode characters.
 
 
-CString type
+cstring type
 ------------
 The ``cstring`` type represents a pointer to a zero-terminated char array
 compatible to the type ``char*`` in Ansi C. Its primary purpose lies in easy
@@ -422,11 +424,11 @@ Example:
 .. code-block:: nim
 
   type
-    TIntArray = array[0..5, int] # an array that is indexed with 0..5
-    TIntSeq = seq[int] # a sequence of integers
+    IntArray = array[0..5, int] # an array that is indexed with 0..5
+    IntSeq = seq[int] # a sequence of integers
   var
-    x: TIntArray
-    y: TIntSeq
+    x: IntArray
+    y: IntSeq
   x = [1, 2, 3, 4, 5, 6]  # [] is the array constructor
   y = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence
 
@@ -469,7 +471,7 @@ allows to pass a variable number of arguments to a procedure. The compiler
 converts the list of arguments to an array implicitly:
 
 .. code-block:: nim
-  proc myWriteln(f: TFile, a: varargs[string]) =
+  proc myWriteln(f: File, a: varargs[string]) =
     for s in items(a):
       write(f, s)
     write(f, "\n")
@@ -483,7 +485,7 @@ last parameter in the procedure header. It is also possible to perform
 type conversions in this context:
 
 .. code-block:: nim
-  proc myWriteln(f: TFile, a: varargs[string, `$`]) =
+  proc myWriteln(f: File, a: varargs[string, `$`]) =
     for s in items(a):
       write(f, s)
     write(f, "\n")
@@ -518,11 +520,11 @@ in future versions of the compiler.
 .. code-block:: nim
 
   type
-    TPerson = tuple[name: string, age: int] # type representing a person:
-                                            # a person consists of a name
-                                            # and an age
+    Person = tuple[name: string, age: int] # type representing a person:
+                                           # a person consists of a name
+                                           # and an age
   var
-    person: TPerson
+    person: Person
   person = (name: "Peter", age: 30)
   # the same, but less readable:
   person = ("Peter", 30)
@@ -535,9 +537,9 @@ can also be defined with indentation instead of ``[]``:
 
 .. code-block:: nim
   type
-    TPerson = tuple   # type representing a person
-      name: string    # a person consists of a name
-      age: natural    # and an age
+    Person = tuple   # type representing a person
+      name: string   # a person consists of a name
+      age: natural   # and an age
 
 Objects provide many features that tuples do not. Object provide inheritance
 and information hiding. Objects have access to their type at runtime, so that
@@ -545,23 +547,23 @@ the ``of`` operator can be used to determine the object's type.
 
 .. code-block:: nim
   type
-    TPerson {.inheritable.} = object
+    Person {.inheritable.} = object
       name*: string   # the * means that `name` is accessible from other modules
       age: int        # no * means that the field is hidden
 
-    TStudent = object of TPerson # a student is a person
-      id: int                    # with an id field
+    Student = object of Person # a student is a person
+      id: int                  # with an id field
 
   var
-    student: TStudent
-    person: TPerson
-  assert(student of TStudent) # is true
+    student: Student
+    person: Person
+  assert(student of Student) # is true
 
 Object fields that should be visible from outside the defining module, have to
 be marked by ``*``. In contrast to tuples, different object types are
 never *equivalent*. Objects that have no ancestor are implicitly ``final``
 and thus have no hidden type field. One can use the ``inheritable`` pragma to
-introduce new object roots apart from ``system.TObject``.
+introduce new object roots apart from ``system.RootObj``.
 
 
 Object construction
@@ -572,7 +574,7 @@ has the syntax ``T(fieldA: valueA, fieldB: valueB, ...)`` where ``T`` is
 an ``object`` type or a ``ref object`` type:
 
 .. code-block:: nim
-  var student = TStudent(name: "Anton", age: 5, id: 3)
+  var student = Student(name: "Anton", age: 5, id: 3)
 
 For a ``ref object`` type ``system.new`` is invoked implicitly.
 
@@ -680,6 +682,14 @@ dereferencing operations for reference types:
   n.data = 9 
   # no need to write n[].data; in fact n[].data is highly discouraged!
 
+In order to simplify structural type checking, recursive tuples are not valid:
+
+.. code-block:: nim
+  # invalid recursion
+  type MyTuple = tuple[a: ref MyTuple]
+
+Likewise ``T = ref T`` is an invalid type.
+
 As a syntactical extension ``object`` types can be anonymous if
 declared in a type section via the ``ref object`` or ``ptr object`` notations.
 This feature is useful if an object should only gain reference semantics:
diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim
index 9d22f0c3c..b824210a5 100644
--- a/lib/pure/collections/sequtils.nim
+++ b/lib/pure/collections/sequtils.nim
@@ -61,6 +61,8 @@ proc deduplicate*[T](seq1: seq[T]): seq[T] =
   result = @[]
   for itm in items(seq1):
     if not result.contains(itm): result.add(itm)
+
+{.deprecated: [distnct: deduplicate].}
     
 proc zip*[S, T](seq1: seq[S], seq2: seq[T]): seq[tuple[a: S, b: T]] =
   ## Returns a new sequence with a combination of the two input sequences.
diff --git a/todo.txt b/todo.txt
index e06b3d030..d4fb1a7b9 100644
--- a/todo.txt
+++ b/todo.txt
@@ -3,9 +3,6 @@ version 0.10
 
 - Test nimfix on various babel packages
 
-- bug: 'type T = ref T' not recognized as illegal recursion
-- deprecate recursive tuples; tuple needs laxer type checking
-
 - VM: Pegs do not work at compile-time
 - VM: ptr/ref T cannot work in general
 
@@ -37,8 +34,6 @@ Misc
 - make tuple unpacking work in a non-var/let context
 - special rule for ``[]=``, items, pairs
 - built-in 'getImpl'
-- type API for macros; make 'spawn' a macro
-- markAndSweepGC should expose an API for fibers
 - prevent 'alloc(TypeWithGCedMemory)'
 - some table related tests are wrong (memory usage checks)
 
diff --git a/web/news.txt b/web/news.txt
index cf24139f7..527b29898 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -49,7 +49,7 @@ News
     be used instead.
   - String case (or any non-ordinal case) statements 
     without 'else' are deprecated.
-  - Recursive tuple types are deprecated. Use ``object`` instead.
+  - Recursive tuple types are not allowed anymore. Use ``object`` instead.
 
 
   Language Additions

From e65c296bcca4bf0f690e026374c900e33e885a93 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Fri, 3 Oct 2014 01:21:35 +0200
Subject: [PATCH 171/409] implemented mixed mode codegen

---
 compiler/ast.nim      |  2 ++
 compiler/ccgcalls.nim |  4 +--
 compiler/ccgexprs.nim | 38 ++++++++++++-------------
 compiler/ccgmerge.nim |  2 +-
 compiler/ccgstmts.nim | 11 ++++----
 compiler/ccgtrav.nim  |  8 +++---
 compiler/ccgtypes.nim | 14 ++++-----
 compiler/ccgutils.nim |  2 +-
 compiler/cgen.nim     | 66 ++++++++++++++++++++++++++-----------------
 compiler/extccomp.nim | 41 +++++++++++++--------------
 compiler/main.nim     |  2 --
 compiler/pragmas.nim  |  5 ++++
 lib/nimbase.h         | 10 +++++--
 todo.txt              |  4 +--
 web/news.txt          | 19 ++++++++++++-
 15 files changed, 133 insertions(+), 95 deletions(-)

diff --git a/compiler/ast.nim b/compiler/ast.nim
index 1fbbd56d4..762e09a95 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -291,6 +291,8 @@ const
 
   sfNoRoot* = sfBorrow # a local variable is provably no root so it doesn't
                        # require RC ops
+  sfCompileToCpp* = sfInfixCall       # compile the module as C++ code
+  sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
 
 const
   # getting ready for the future expr/stmt merge
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim
index 753d375af..b01a81c5e 100644
--- a/compiler/ccgcalls.nim
+++ b/compiler/ccgcalls.nim
@@ -103,9 +103,9 @@ proc openArrayLoc(p: BProc, n: PNode): PRope =
       result = ropef("$1, $1Len0", [rdLoc(a)])
     of tyString, tySequence:
       if skipTypes(n.typ, abstractInst).kind == tyVar:
-        result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField()])
+        result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField(p)])
       else:
-        result = ropef("$1->data, $1->$2", [a.rdLoc, lenField()])
+        result = ropef("$1->data, $1->$2", [a.rdLoc, lenField(p)])
     of tyArray, tyArrayConstr:
       result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
     else: internalError("openArrayLoc: " & typeToString(a.t))
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index ca34cfa3a..75f0f3a42 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -721,7 +721,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
         internalError(e.info, "genRecordField")
       field = lookupInRecord(ty.n, f.name)
       if field != nil: break
-      if gCmd != cmdCompileToCpp: app(r, ".Sup")
+      if not p.module.compileToCpp: app(r, ".Sup")
       ty = getUniqueType(ty.sons[0])
     if field == nil: internalError(e.info, "genRecordField 2 ")
     if field.loc.r == nil: internalError(e.info, "genRecordField 3")
@@ -773,7 +773,7 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
       assert(ty.kind in {tyTuple, tyObject})
       field = lookupInRecord(ty.n, f.name)
       if field != nil: break
-      if gCmd != cmdCompileToCpp: app(r, ".Sup")
+      if not p.module.compileToCpp: app(r, ".Sup")
       ty = getUniqueType(ty.sons[0])
     if field == nil: internalError(e.info, "genCheckedRecordField")
     if field.loc.r == nil:
@@ -840,11 +840,11 @@ proc genSeqElem(p: BProc, e: PNode, d: var TLoc) =
     if ty.kind == tyString:
       linefmt(p, cpsStmts,
            "if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
-           rdLoc(b), rdLoc(a), lenField())
+           rdLoc(b), rdLoc(a), lenField(p))
     else:
       linefmt(p, cpsStmts,
            "if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n",
-           rdLoc(b), rdLoc(a), lenField())
+           rdLoc(b), rdLoc(a), lenField(p))
   if d.k == locNone: d.s = OnHeap
   d.heapRoot = a.r
   if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
@@ -937,7 +937,7 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
       if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
         inc(L, len(e.sons[i + 1].strVal))
       else:
-        appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
+        appf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
       app(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
   linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, toRope(L))
   app(p.s(cpsStmts), appends)
@@ -977,7 +977,7 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
       if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
         inc(L, len(e.sons[i + 2].strVal))
       else:
-        appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
+        appf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
       app(appends, rfmt(p.module, "#appendString($1, $2);$n",
                         rdLoc(dest), rdLoc(a)))
   linefmt(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
@@ -990,7 +990,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
   # seq &= x  -->
   #    seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
   #    seq->data[seq->len-1] = x;
-  let seqAppendPattern = if gCmd != cmdCompileToCpp:
+  let seqAppendPattern = if not p.module.compileToCpp:
                            "$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n"
                          else:
                            "$1 = ($2) #incrSeq($1, sizeof($3));$n"
@@ -1003,7 +1003,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
       getTypeDesc(p.module, skipTypes(e.sons[2].typ, abstractVar))])
   keepAlive(p, a)
   initLoc(dest, locExpr, b.t, OnHeap)
-  dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField())
+  dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField(p))
   genAssignment(p, dest, b, {needToCopy, afDestIsNil})
   gcUsage(e)
 
@@ -1097,7 +1097,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
     while ty != nil:
       field = lookupInRecord(ty.n, it.sons[0].sym.name)
       if field != nil: break
-      if gCmd != cmdCompileToCpp: app(tmp2.r, ".Sup")
+      if not p.module.compileToCpp: app(tmp2.r, ".Sup")
       ty = getUniqueType(ty.sons[0])
     if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr")
     if it.len == 3 and optFieldCheck in p.options:
@@ -1198,8 +1198,8 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
     if t.kind != tyVar: nilCheck = r
     r = rfmt(nil, "(*$1)", r)
     t = skipTypes(t.lastSon, typedescInst)
-  if gCmd != cmdCompileToCpp:
-    while (t.kind == tyObject) and (t.sons[0] != nil):
+  if not p.module.compileToCpp:
+    while t.kind == tyObject and t.sons[0] != nil:
       app(r, ~".Sup")
       t = skipTypes(t.sons[0], typedescInst)
   if isObjLackingTypeField(t):
@@ -1244,7 +1244,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
       putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
     of tyString, tySequence:
       putIntoDest(p, b, e.typ, 
-                  ropef("$1->data, $1->$2", [rdLoc(a), lenField()]))
+                  ropef("$1->data, $1->$2", [rdLoc(a), lenField(p)]))
     of tyArray, tyArrayConstr:
       putIntoDest(p, b, e.typ,
                   ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
@@ -1287,7 +1287,7 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)")
     else: unaryExpr(p, e, d, "strlen($1)")
   of tyString, tySequence:
-    if gCmd != cmdCompileToCpp:
+    if not p.module.compileToCpp:
       if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)")
       else: unaryExpr(p, e, d, "$1->Sup.len")
     else:
@@ -1305,7 +1305,7 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
   initLocExpr(p, e.sons[1], a)
   initLocExpr(p, e.sons[2], b)
   var t = skipTypes(e.sons[1].typ, abstractVar)
-  let setLenPattern = if gCmd != cmdCompileToCpp:
+  let setLenPattern = if not p.module.compileToCpp:
       "$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n"
     else:
       "$1 = ($3) #setLengthSeq($1, sizeof($4), $2);$n"
@@ -1561,11 +1561,11 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
   elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""):
     initLocExpr(p, e.sons[2], x)
     putIntoDest(p, d, e.typ,
-      rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
+      rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField(p)))
   elif (b.kind in {nkStrLit..nkTripleStrLit}) and (b.strVal == ""):
     initLocExpr(p, e.sons[1], x)
     putIntoDest(p, d, e.typ,
-      rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
+      rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField(p)))
   else:
     binaryExpr(p, e, d, "#eqStrings($1, $2)")
 
@@ -1824,7 +1824,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
       if t.kind != tyVar: nilCheck = r
       r = ropef("(*$1)", [r])
       t = skipTypes(t.lastSon, abstractInst)
-    if gCmd != cmdCompileToCpp:
+    if not p.module.compileToCpp:
       while t.kind == tyObject and t.sons[0] != nil:
         app(r, ".Sup")
         t = skipTypes(t.sons[0], abstractInst)
@@ -1842,7 +1842,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
                                    [getTypeDesc(p.module, dest), addrLoc(a)]))
 
 proc downConv(p: BProc, n: PNode, d: var TLoc) =
-  if gCmd == cmdCompileToCpp:
+  if p.module.compileToCpp:
     expr(p, n.sons[0], d)     # downcast does C++ for us
   else:
     var dest = skipTypes(n.typ, abstractPtrs)
@@ -2028,7 +2028,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
       initLocExpr(p, n.sons[0], a)
   of nkAsmStmt: genAsmStmt(p, n)
   of nkTryStmt:
-    if gCmd == cmdCompileToCpp: genTryCpp(p, n, d)
+    if p.module.compileToCpp: genTryCpp(p, n, d)
     else: genTry(p, n, d)
   of nkRaiseStmt: genRaiseStmt(p, n)
   of nkTypeSection:
diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim
index 9aca4b0f7..36da68d23 100644
--- a/compiler/ccgmerge.nim
+++ b/compiler/ccgmerge.nim
@@ -249,7 +249,7 @@ proc readMergeInfo*(cfilename: string, m: BModule) =
       break
 
 type
-  TMergeSections = object {.pure.}
+  TMergeSections = object
     f: TCFileSections
     p: TCProcSections
 
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index e30b2c561..92af9b18e 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -289,8 +289,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
   
   var alreadyPoppedCnt = p.inExceptBlock
   for i in countup(1, howManyTrys):
-
-    if gCmd != cmdCompileToCpp:
+    if not p.module.compileToCpp:
       # Pop safe points generated by try
       if alreadyPoppedCnt > 0:
         dec alreadyPoppedCnt
@@ -312,7 +311,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
   for i in countdown(howManyTrys-1, 0): 
     p.nestedTryStmts.add(stack[i])
 
-  if gCmd != cmdCompileToCpp:
+  if not p.module.compileToCpp:
     # Pop exceptions that was handled by the
     # except-blocks we are in
     for i in countdown(howManyExcepts-1, 0):
@@ -496,7 +495,7 @@ proc genBreakStmt(p: BProc, t: PNode) =
   lineF(p, cpsStmts, "goto $1;$n", [label])
 
 proc getRaiseFrmt(p: BProc): string = 
-  if gCmd == cmdCompileToCpp: 
+  if p.module.compileToCpp:
     result = "throw NimException($1, $2);$n"
   elif getCompilerProc("Exception") != nil:
     result = "#raiseException((#Exception*)$1, $2);$n"
@@ -517,10 +516,10 @@ proc genRaiseStmt(p: BProc, t: PNode) =
     var typ = skipTypes(t.sons[0].typ, abstractPtrs)
     genLineDir(p, t)
     lineCg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
-  else: 
+  else:
     genLineDir(p, t)
     # reraise the last exception:
-    if gCmd == cmdCompileToCpp:
+    if p.module.compileToCpp:
       line(p, cpsStmts, ~"throw;$n")
     else:
       linefmt(p, cpsStmts, "#reraiseException();$n")
diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim
index 16ec564e8..8bb820283 100644
--- a/compiler/ccgtrav.nim
+++ b/compiler/ccgtrav.nim
@@ -49,8 +49,8 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) =
     genTraverseProc(c, ropef("$1.$2", accessor, field.loc.r), field.loc.t)
   else: internalError(n.info, "genTraverseProc()")
 
-proc parentObj(accessor: PRope): PRope {.inline.} =
-  if gCmd != cmdCompileToCpp:
+proc parentObj(accessor: PRope; m: BModule): PRope {.inline.} =
+  if not m.compileToCpp:
     result = ropef("$1.Sup", accessor)
   else:
     result = accessor
@@ -71,7 +71,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
     lineF(p, cpsStmts, "}$n")
   of tyObject:
     for i in countup(0, sonsLen(typ) - 1):
-      genTraverseProc(c, accessor.parentObj, typ.sons[i])
+      genTraverseProc(c, accessor.parentObj(c.p.module), typ.sons[i])
     if typ.n != nil: genTraverseProc(c, accessor, typ.n)
   of tyTuple:
     let typ = getUniqueType(typ)
@@ -91,7 +91,7 @@ proc genTraverseProcSeq(c: var TTraversalClosure, accessor: PRope, typ: PType) =
   var i: TLoc
   getTemp(p, getSysType(tyInt), i)
   lineF(p, cpsStmts, "for ($1 = 0; $1 < $2->$3; $1++) {$n",
-      i.r, accessor, toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len"))
+      i.r, accessor, toRope(if c.p.module.compileToCpp: "len" else: "Sup.len"))
   genTraverseProc(c, ropef("$1->data[$2]", accessor, i.r), typ.sons[0])
   lineF(p, cpsStmts, "}$n")
   
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 4b52d3956..fbdea7e66 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -342,8 +342,8 @@ proc getTypePre(m: BModule, typ: PType): PRope =
 proc structOrUnion(t: PType): PRope =
   (if tfUnion in t.flags: toRope("union") else: toRope("struct"))
 
-proc getForwardStructFormat(): string = 
-  if gCmd == cmdCompileToCpp: result = "$1 $2;$n"
+proc getForwardStructFormat(m: BModule): string = 
+  if m.compileToCpp: result = "$1 $2;$n"
   else: result = "typedef $1 $2 $2;$n"
   
 proc getTypeForward(m: BModule, typ: PType): PRope = 
@@ -355,7 +355,7 @@ proc getTypeForward(m: BModule, typ: PType): PRope =
   of tySequence, tyTuple, tyObject: 
     result = getTypeName(typ)
     if not isImportedType(typ): 
-      appf(m.s[cfsForwardTypes], getForwardStructFormat(),
+      appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
           [structOrUnion(typ), result])
     idTablePut(m.forwTypeCache, typ, result)
   else: internalError("getTypeForward(" & $typ.kind & ')')
@@ -442,7 +442,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope,
       else: 
         appcg(m, result, " {$n#TNimType* m_type;$n", [name, attribute])
         hasField = true
-    elif gCmd == cmdCompileToCpp: 
+    elif m.compileToCpp:
       appcg(m, result, " : public $1 {$n", 
                       [getTypeDescAux(m, typ.sons[0], check)])
       hasField = true
@@ -538,7 +538,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
     if result == nil: 
       result = getTypeName(t)
       if not isImportedType(t): 
-        appf(m.s[cfsForwardTypes], getForwardStructFormat(),
+        appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
             [structOrUnion(t), result])
       idTablePut(m.forwTypeCache, t, result)
     assert(cacheGetType(m.typeCache, t) == nil)
@@ -550,7 +550,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
           cSeq = "struct $2 {$n" &
                  "  #TGenericSeq Sup;$n"
         appcg(m, m.s[cfsSeqTypes],
-            (if gCmd == cmdCompileToCpp: cppSeq else: cSeq) &
+            (if m.compileToCpp: cppSeq else: cSeq) &
             "  $1 data[SEQ_DECL_SIZE];$n" & 
             "};$n", [getTypeDescAux(m, t.sons[0], check), result])
       else: 
@@ -570,7 +570,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
     if result == nil: 
       result = getTypeName(t)
       if not isImportedType(t): 
-        appf(m.s[cfsForwardTypes], getForwardStructFormat(),
+        appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
            [structOrUnion(t), result])
       idTablePut(m.forwTypeCache, t, result)
     idTablePut(m.typeCache, t, result) # always call for sideeffects:
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim
index 54af3c705..7396c0bf8 100644
--- a/compiler/ccgutils.nim
+++ b/compiler/ccgutils.nim
@@ -171,7 +171,7 @@ proc mangle*(name: string): string =
   ## Lowercases the given name and manges any non-alphanumeric characters
   ## so they are represented as `HEX____`. If the name starts with a number,
   ## `N` is prepended
-  result = ""
+  result = newStringOfCap(name.len)
   case name[0]
   of Letters:
     result.add(name[0].toLower)
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 743e877a1..44d4d18e1 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -297,6 +297,9 @@ proc accessThreadLocalVar(p: BProc, s: PSym)
 proc emulatedThreadVars(): bool {.inline.}
 proc genProc(m: BModule, prc: PSym)
 
+template compileToCpp(m: BModule): expr =
+  gCmd == cmdCompileToCpp or sfCompileToCpp in m.module.flags
+
 include "ccgtypes.nim"
 
 # ------------------------------ Manager of temporaries ------------------
@@ -326,7 +329,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
     var r = rdLoc(a)
     if not takeAddr: r = ropef("(*$1)", [r])
     var s = skipTypes(t, abstractInst)
-    if gCmd != cmdCompileToCpp:
+    if not p.module.compileToCpp:
       while (s.kind == tyObject) and (s.sons[0] != nil):
         app(r, ".Sup")
         s = skipTypes(s.sons[0], abstractInst)
@@ -506,7 +509,7 @@ proc assignLocalVar(p: BProc, s: PSym) =
     #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
     #  app(decl, " GC_GUARD")
     if sfVolatile in s.flags or (p.nestedTryStmts.len > 0 and
-                                 gCmd != cmdCompileToCpp):
+                                 not p.module.compileToCpp):
       app(decl, " volatile")
     appf(decl, " $1;$n", [s.loc.r])
   else:
@@ -587,8 +590,8 @@ proc initLocExpr(p: BProc, e: PNode, result: var TLoc) =
   initLoc(result, locNone, e.typ, OnUnknown)
   expr(p, e, result)
 
-proc lenField: PRope {.inline.} =
-  result = toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len")
+proc lenField(p: BProc): PRope =
+  result = toRope(if p.module.compileToCpp: "len" else: "Sup.len")
 
 include ccgcalls, "ccgstmts.nim", "ccgexprs.nim"
 
@@ -812,7 +815,12 @@ proc genProcAux(m: BModule, prc: PSym) =
     app(generatedProc, returnStmt)
     app(generatedProc, ~"}$N")
   app(m.s[cfsProcs], generatedProc)
-  
+
+proc crossesCppBoundary(m: BModule; sym: PSym): bool {.inline.} =
+  result = sfCompileToCpp in m.module.flags and
+           sfCompileToCpp notin sym.getModule().flags and
+           gCmd != cmdCompileToCpp
+
 proc genProcPrototype(m: BModule, sym: PSym) = 
   useHeader(m, sym)
   if lfNoDecl in sym.loc.flags: return 
@@ -824,6 +832,8 @@ proc genProcPrototype(m: BModule, sym: PSym) =
       if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
   elif not containsOrIncl(m.declaredProtos, sym.id):
     var header = genProcHeader(m, sym)
+    if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
+      header = con("extern \"C\" ", header)
     if sfPure in sym.flags and hasNakedAttribute in CC[cCompiler].props:
       header.app(" __attribute__((naked))")
     app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
@@ -915,7 +925,7 @@ proc addIntTypes(result: var PRope) {.inline.} =
   appf(result, "#define NIM_INTBITS $1", [
     platform.CPU[targetCPU].intSize.toRope])
 
-proc getCopyright(cfilenoext: string): PRope =
+proc getCopyright(cfile: string): PRope =
   if optCompileOnly in gGlobalOptions:
     result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
         "/*   (c) 2014 Andreas Rumpf */$N" &
@@ -935,10 +945,10 @@ proc getCopyright(cfilenoext: string): PRope =
         toRope(platform.OS[targetOS].name),
         toRope(platform.CPU[targetCPU].name),
         toRope(extccomp.CC[extccomp.cCompiler].name),
-        toRope(getCompileCFileCmd(cfilenoext))])
+        toRope(getCompileCFileCmd(cfile))])
 
-proc getFileHeader(cfilenoext: string): PRope =
-  result = getCopyright(cfilenoext)
+proc getFileHeader(cfile: string): PRope =
+  result = getCopyright(cfile)
   addIntTypes(result)
 
 proc genFilenames(m: BModule): PRope =
@@ -1078,9 +1088,9 @@ proc registerModuleToMain(m: PSym) =
   var
     init = m.getInitName
     datInit = m.getDatInitName
-  appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
+  appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
                       "declare void $1() noinline$N", [init])
-  appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
+  appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
                       "declare void $1() noinline$N", [datInit])
   if sfSystemModule notin m.flags:
     appff(mainDatInit, "\t$1();$N", "call void ()* $1$n", [datInit])
@@ -1092,7 +1102,7 @@ proc registerModuleToMain(m: PSym) =
     
 proc genInitCode(m: BModule) = 
   var initname = getInitName(m.module)
-  var prc = ropeff("N_NOINLINE(void, $1)(void) {$N", 
+  var prc = ropeff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N", 
                    "define void $1() noinline {$n", [initname])
   if m.typeNodes > 0: 
     appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n", 
@@ -1135,7 +1145,7 @@ proc genInitCode(m: BModule) =
   app(prc, deinitGCFrame(m.initProc))
   appf(prc, "}$N$N")
 
-  prc.appff("N_NOINLINE(void, $1)(void) {$N",
+  prc.appff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
             "define void $1() noinline {$n", [getDatInitName(m.module)])
 
   for i in cfsTypeInit1..cfsDynLibInit:
@@ -1155,8 +1165,8 @@ proc genInitCode(m: BModule) =
         (i.ord - '0'.ord).toRope, el)
       app(m.s[cfsInitProc], ex)
 
-proc genModule(m: BModule, cfilenoext: string): PRope = 
-  result = getFileHeader(cfilenoext)
+proc genModule(m: BModule, cfile: string): PRope = 
+  result = getFileHeader(cfile)
   result.app(genMergeInfo(m))
   
   generateHeaders(m)
@@ -1297,7 +1307,11 @@ proc writeHeader(m: BModule) =
   writeRope(result, m.filename)
 
 proc getCFile(m: BModule): string =
-  result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), cExt)
+  let ext =
+      if m.compileToCpp: ".cpp"
+      elif gCmd == cmdCompileToOC or sfCompileToObjC in m.module.flags: ".m"
+      else: ".c"
+  result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), ext)
 
 proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
   assert optSymbolFiles in gGlobalOptions
@@ -1326,10 +1340,10 @@ proc finishModule(m: BModule) =
   dec(gForwardedProcsCounter, i)
   setLen(m.forwardedProcs, 0)
 
-proc shouldRecompile(code: PRope, cfile, cfilenoext: string): bool = 
+proc shouldRecompile(code: PRope, cfile: string): bool = 
   result = true
   if optForceFullMake notin gGlobalOptions:
-    var objFile = toObjFile(cfilenoext)
+    var objFile = toObjFile(cfile)
     if writeRopeIfNotEqual(code, cfile): return 
     if existsFile(objFile) and os.fileNewer(objFile, cfile): result = false
   else: 
@@ -1354,26 +1368,26 @@ proc writeModule(m: BModule, pending: bool) =
       app(m.s[cfsProcHeaders], mainModProcs)
       generateThreadVarsSize(m)
     
-    var code = genModule(m, cfilenoext)
+    var code = genModule(m, cfile)
     when hasTinyCBackend:
       if gCmd == cmdRun:
         tccgen.compileCCode(ropeToStr(code))
         return
 
-    if shouldRecompile(code, cfile, cfilenoext):
-      addFileToCompile(cfilenoext)
+    if shouldRecompile(code, cfile):
+      addFileToCompile(cfile)
   elif pending and mergeRequired(m) and sfMainModule notin m.module.flags:
     mergeFiles(cfile, m)
     genInitCode(m)
     finishTypeDescriptions(m)
-    var code = genModule(m, cfilenoext)
+    var code = genModule(m, cfile)
     writeRope(code, cfile)
-    addFileToCompile(cfilenoext)
+    addFileToCompile(cfile)
   elif not existsFile(toObjFile(cfilenoext)):
     # Consider: first compilation compiles ``system.nim`` and produces
     # ``system.c`` but then compilation fails due to an error. This means
     # that ``system.o`` is missing, so we need to call the C compiler for it:
-    addFileToCompile(cfilenoext)
+    addFileToCompile(cfile)
   
   addFileToLink(cfilenoext)
 
@@ -1385,9 +1399,9 @@ proc updateCachedModule(m: BModule) =
     mergeFiles(cfile, m)
     genInitCode(m)
     finishTypeDescriptions(m)
-    var code = genModule(m, cfilenoext)
+    var code = genModule(m, cfile)
     writeRope(code, cfile)
-    addFileToCompile(cfilenoext)
+    addFileToCompile(cfile)
 
   addFileToLink(cfilenoext)
 
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 7a213aea4..7d9744bc5 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -323,10 +323,7 @@ const
 
 var
   cCompiler* = ccGcc # the used compiler
-
-  cExt* = ".c" # extension of generated C/C++ files
-               # (can be changed to .cpp later)
-  
+  gMixedMode*: bool  # true if some module triggered C++ codegen
   cIncludes*: seq[string] = @[]   # directories to search for included files
   cLibs*: seq[string] = @[]       # directories to search for lib files
   cLinkedLibs*: seq[string] = @[] # libraries to link
@@ -387,8 +384,6 @@ proc initVars*() =
   # we need to define the symbol here, because ``CC`` may have never been set!
   for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name)
   defineSymbol(CC[cCompiler].name)
-  if gCmd == cmdCompileToCpp: cExt = ".cpp"
-  elif gCmd == cmdCompileToOC: cExt = ".m"
   addCompileOption(getConfigVar(cCompiler, ".options.always"))
   addLinkOption(getConfigVar(cCompiler, ".options.linker"))
   if len(ccompilerpath) == 0:
@@ -397,9 +392,9 @@ proc initVars*() =
 proc completeCFilePath*(cfile: string, createSubDir: bool = true): string = 
   result = completeGeneratedFilePath(cfile, createSubDir)
 
-proc toObjFile*(filenameWithoutExt: string): string = 
+proc toObjFile*(filename: string): string = 
   # Object file for compilation
-  result = changeFileExt(filenameWithoutExt, CC[cCompiler].objExt)
+  result = changeFileExt(filename, CC[cCompiler].objExt)
 
 proc addFileToCompile*(filename: string) =
   appendStr(toCompile, filename)
@@ -497,6 +492,7 @@ proc getCompilerExe(compiler: TSystemCC): string =
 
 proc getLinkerExe(compiler: TSystemCC): string =
   result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
+           elif gMixedMode and gCmd != cmdCompileToCpp: CC[compiler].cppCompiler
            else: compiler.getCompilerExe
 
 proc getCompileCFileCmd*(cfilename: string, isExternal = false): string = 
@@ -507,11 +503,11 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
   
   if needsExeExt(): exe = addFileExt(exe, "exe")
   if optGenDynLib in gGlobalOptions and
-      ospNeedsPIC in platform.OS[targetOS].props: 
+      ospNeedsPIC in platform.OS[targetOS].props:
     add(options, ' ' & CC[c].pic)
   
   var includeCmd, compilePattern: string
-  if not noAbsolutePaths(): 
+  if not noAbsolutePaths():
     # compute include paths:
     includeCmd = CC[c].includeCmd & quoteShell(libpath)
 
@@ -519,26 +515,27 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
       includeCmd.add([CC[c].includeCmd, includeDir.quoteShell])
 
     compilePattern = joinPath(ccompilerpath, exe)
-  else: 
+  else:
     includeCmd = ""
     compilePattern = c.getCompilerExe
   
-  var cfile = if noAbsolutePaths(): extractFilename(cfilename) 
+  var cfile = if noAbsolutePaths(): extractFilename(cfilename)
               else: cfilename
-  var objfile = if not isExternal or noAbsolutePaths(): 
-                  toObjFile(cfile) 
-                else: 
+  var objfile = if not isExternal or noAbsolutePaths():
+                  toObjFile(cfile)
+                else:
                   completeCFilePath(toObjFile(cfile))
-  cfile = quoteShell(addFileExt(cfile, cExt))
   objfile = quoteShell(objfile)
   result = quoteShell(compilePattern % [
-    "file", cfile, "objfile", objfile, "options", options, 
-    "include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath])
+    "file", cfile, "objfile", objfile, "options", options,
+    "include", includeCmd, "nimrod", getPrefixDir(),
+    "nim", getPrefixDir(), "lib", libpath])
   add(result, ' ')
   addf(result, CC[c].compileTmpl, [
-    "file", cfile, "objfile", objfile, 
-    "options", options, "include", includeCmd, 
-    "nimrod", quoteShell(getPrefixDir()), 
+    "file", cfile, "objfile", objfile,
+    "options", options, "include", includeCmd,
+    "nimrod", quoteShell(getPrefixDir()),
+    "nim", quoteShell(getPrefixDir()),
     "lib", quoteShell(libpath)])
 
 proc footprint(filename: string): TCrc32 =
@@ -668,7 +665,7 @@ proc callCCompiler*(projectfile: string) =
 proc genMappingFiles(list: TLinkedList): PRope = 
   var it = PStrEntry(list.head)
   while it != nil: 
-    appf(result, "--file:r\"$1\"$N", [toRope(addFileExt(it.data, cExt))])
+    appf(result, "--file:r\"$1\"$N", [toRope(it.data)])
     it = PStrEntry(it.next)
 
 proc writeMapping*(gSymbolMapping: PRope) = 
diff --git a/compiler/main.nim b/compiler/main.nim
index c80c9a873..82e55058c 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -272,13 +272,11 @@ proc mainCommand* =
     gCmd = cmdCompileToC
     commandCompileToC()
   of "cpp", "compiletocpp":
-    extccomp.cExt = ".cpp"
     gCmd = cmdCompileToCpp
     if cCompiler == ccGcc: setCC("gcc")
     defineSymbol("cpp")
     commandCompileToC()
   of "objc", "compiletooc":
-    extccomp.cExt = ".m"
     gCmd = cmdCompileToOC
     defineSymbol("objc")
     commandCompileToC()
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 510023bb8..4d6d311c9 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -128,12 +128,17 @@ proc processImportCpp(s: PSym, extname: string) =
   incl(s.flags, sfImportc)
   incl(s.flags, sfInfixCall)
   excl(s.flags, sfForward)
+  let m = s.getModule()
+  incl(m.flags, sfCompileToCpp)
+  extccomp.gMixedMode = true
 
 proc processImportObjC(s: PSym, extname: string) =
   setExternName(s, extname)
   incl(s.flags, sfImportc)
   incl(s.flags, sfNamedParamCall)
   excl(s.flags, sfForward)
+  let m = s.getModule()
+  incl(m.flags, sfCompileToObjC)
 
 proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
   result = newNodeIT(nkStrLit, n.info, getSysType(tyString))
diff --git a/lib/nimbase.h b/lib/nimbase.h
index 2ca3bd886..ac90081d8 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -1,7 +1,7 @@
 /*
 
-            Nimrod's Runtime Library
-        (c) Copyright 2013 Andreas Rumpf
+            Nim's Runtime Library
+        (c) Copyright 2014 Andreas Rumpf
 
     See the file "copying.txt", included in this
     distribution, for details about the copyright.
@@ -384,3 +384,9 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
    "error: 'assert_numbits' declared as an array with a negative size" */
 typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
 #endif
+
+#ifdef  __cplusplus
+#  define NIM_EXTERNC extern "C"
+#else
+#  define NIM_EXTERNC
+#endif
diff --git a/todo.txt b/todo.txt
index d4fb1a7b9..7790a9c8a 100644
--- a/todo.txt
+++ b/todo.txt
@@ -3,8 +3,6 @@ version 0.10
 
 - Test nimfix on various babel packages
 
-- VM: Pegs do not work at compile-time
-- VM: ptr/ref T cannot work in general
 
 version 0.9.6
 =============
@@ -41,6 +39,8 @@ Misc
 Bugs
 ====
 
+- VM: Pegs do not work at compile-time
+- VM: ptr/ref T cannot work in general
 - scopes are still broken for generic instantiation!
 - bug: type conversions concerning proc types are weird
 - compilation of niminst takes way too long. looks like a regression
diff --git a/web/news.txt b/web/news.txt
index 527b29898..ceb23a6dd 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -52,13 +52,30 @@ News
   - Recursive tuple types are not allowed anymore. Use ``object`` instead.
 
 
+  Compiler Additions
+  ------------------
+
+  - The compiler now supports *mixed* Objective C / C++ / C code generation:
+    The modules that use ``importCpp`` or ``importObjc`` are compiled to C++
+    or Objective C code, any other module is compiled to C code. This
+    improves interoperability.
+
+
   Language Additions
   ------------------
 
   - There is a new ``parallel`` statement for safe fork&join parallel computing.
   - ``guard`` and ``lock`` pragmas have been implemented to support safer
     concurrent programming.
-  - ``system.writeFile`` can be used at compile-time.
+  - The following procs are now available at compile-time::
+
+      math.sqrt, math.ln, math.log10, math.log2, math.exp, math.round,
+      math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos, math.cosh,
+      math.hypot, math.sinh, math.sin, math.tan, math.tanh, math.pow,
+      math.trunc, math.floor, math.ceil, math.fmod,
+      os.getEnv, os.existsEnv, os.dirExists, os.fileExists,
+      system.writeFile
+
 
   Library Additions
   -----------------

From 4616a1e006f0b909d204d8e8f1ad3cd43d8db556 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sat, 4 Oct 2014 14:23:17 +0200
Subject: [PATCH 172/409] updated some tests

---
 compiler/semstmts.nim        | 2 +-
 doc/manual/locking.txt       | 6 ++++--
 tests/typerel/trectuple.nim  | 4 ++++
 tests/typerel/trectuples.nim | 4 ++++
 todo.txt                     | 3 +--
 5 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 063df30fd..255507548 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -268,7 +268,7 @@ proc semTry(c: PContext, n: PNode): PNode =
     checkMinSonsLen(a, 1)
     var length = sonsLen(a)
     if a.kind == nkExceptBranch:
-      # XXX what does this do? so that ``except [a, b, c]`` is supported?
+      # so that ``except [a, b, c]`` is supported:
       if length == 2 and a.sons[0].kind == nkBracket:
         a.sons[0..0] = a.sons[0].sons
         length = a.sonsLen
diff --git a/doc/manual/locking.txt b/doc/manual/locking.txt
index b646f0cee..1a6d2783c 100644
--- a/doc/manual/locking.txt
+++ b/doc/manual/locking.txt
@@ -19,7 +19,7 @@ Guards and the locks section
 Protecting global variables
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Global variables and object fields can be annotated via an ``guard`` pragma: 
+Object fields and global variables can be annotated via a ``guard`` pragma:
 
 .. code-block:: nim
   var glock: TLock
@@ -161,7 +161,9 @@ single ``locks`` section:
     ...
 
 
-So here is how a typical multilock statement can be implemented in Nim:
+Here is how a typical multilock statement can be implemented in Nim. Note how
+the runtime check is required to ensure a global ordering for two locks ``a``
+and ``b`` of the same lock level:
 
 .. code-block:: nim
   template multilock(a, b: ptr TLock; body: stmt) =
diff --git a/tests/typerel/trectuple.nim b/tests/typerel/trectuple.nim
index 7c43ec5ba..ebaaa2ea7 100644
--- a/tests/typerel/trectuple.nim
+++ b/tests/typerel/trectuple.nim
@@ -1,3 +1,7 @@
+discard """
+  errormsg: "illegal recursion in type 'TNode'"
+  line: 8
+"""
 
 type
     PNode = ref TNode
diff --git a/tests/typerel/trectuples.nim b/tests/typerel/trectuples.nim
index c59cfe880..a74e4859c 100644
--- a/tests/typerel/trectuples.nim
+++ b/tests/typerel/trectuples.nim
@@ -1,3 +1,7 @@
+discard """
+  errormsg: "illegal recursion in type 'Node'"
+  line: 6
+"""
 
 type Node = tuple[left: ref Node]
 
diff --git a/todo.txt b/todo.txt
index 7790a9c8a..1e01793de 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,7 @@
 version 0.10
 ============
 
+- fix the bug that keeps 'defer' template from working
 - Test nimfix on various babel packages
 
 
@@ -27,7 +28,6 @@ Low priority:
 Misc
 ----
 
-- fix the bug that keeps 'defer' template from working
 - make '--implicitStatic:on' the default
 - make tuple unpacking work in a non-var/let context
 - special rule for ``[]=``, items, pairs
@@ -62,7 +62,6 @@ version 0.9.x
 - memory manager: add a measure of fragmentation
 - implement 'bits' pragmas
 - we need a magic thisModule symbol
-- provide --nilChecks:on|off
 - ensure (ref T)(a, b) works as a type conversion and type constructor
 - optimize 'genericReset'; 'newException' leads to code bloat
 

From a9a5766c665c1d88f61669d562483fc8794d3960 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sun, 5 Oct 2014 03:06:19 +0200
Subject: [PATCH 173/409] docgen should work again

---
 compiler/condsyms.nim      |  2 ++
 compiler/msgs.nim          |  6 ++--
 compiler/nim.ini           |  4 +--
 compiler/sempass2.nim      | 13 +++++++--
 doc/manual/threads.txt     |  2 +-
 lib/impure/db_postgres.nim | 12 ++++----
 lib/js/dom.nim             | 36 +++++++++++------------
 lib/pure/ftpclient.nim     | 15 +++++-----
 lib/pure/json.nim          | 58 ++++++++++++++++++------------------
 lib/pure/logging.nim       |  5 +++-
 lib/system/jssys.nim       |  5 ++--
 lib/wrappers/libuv.nim     | 60 +++++++++++++++++++-------------------
 tools/nimweb.nim           |  2 +-
 web/babelpkglist.nim       |  4 +--
 web/nim.ini                |  2 +-
 15 files changed, 120 insertions(+), 106 deletions(-)

diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 137ec409f..8652844f3 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -69,6 +69,8 @@ const
     reportMissedDeadlines avoidTimeMachine useClone ignoreAllocationSize
     debugExecProcesses pcreDll useLipzipSrc
     preventDeadlocks UNICODE winUnicode trackGcHeaders posixRealtime
+
+    nimStdSetjmp nimRawSetjmp nimSigSetjmp
   """.split
 
 proc initDefines*() = 
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 8368fe5fd..51d2836f8 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -119,7 +119,7 @@ type
     warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode,
     warnEachIdentIsTuple, warnShadowIdent, 
     warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
-    warnUninit, warnGcMem, warnUnguardedAccess, warnUser,
+    warnUninit, warnGcMem, warnLockLevel, warnUser,
     hintSuccess, hintSuccessX,
     hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
     hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
@@ -390,7 +390,7 @@ const
     warnGcUnsafe2: "cannot prove '$1' is GC-safe. Does not compile with --threads:on.",
     warnUninit: "'$1' might not have been initialized [Uninit]",
     warnGcMem: "'$1' uses GC'ed memory [GcMem]",
-    warnUnguardedAccess: "'$1' is accessed without its guard [UnguardedAccess]",
+    warnLockLevel: "$1 [LockLevel]",
     warnUser: "$1 [User]", 
     hintSuccess: "operation successful [Success]", 
     hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]", 
@@ -420,7 +420,7 @@ const
     "AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap",
     "UnsafeCode", "EachIdentIsTuple", "ShadowIdent", 
     "ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
-    "GcMem", "UnguardedAccess", "User"]
+    "GcMem", "LockLevel", "User"]
 
   HintsToStr*: array[0..16, string] = ["Success", "SuccessX", "LineTooLong", 
     "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", 
diff --git a/compiler/nim.ini b/compiler/nim.ini
index 3833a77cd..6f3f663d9 100644
--- a/compiler/nim.ini
+++ b/compiler/nim.ini
@@ -29,7 +29,7 @@ App: Console
 License: "copying.txt"
 
 [Config]
-Files: "config/nimrod.cfg"
+Files: "config/nim.cfg"
 Files: "config/nimdoc.cfg"
 Files: "config/nimdoc.tex.cfg"
 
@@ -59,7 +59,7 @@ Files: "icons/koch_icon.o"
 
 Files: "compiler/readme.txt"
 Files: "compiler/nim.ini"
-Files: "compiler/nimrod.cfg"
+Files: "compiler/nim.nimrod.cfg"
 Files: "compiler/*.nim"
 Files: "compiler/c2nim/*.nim"
 Files: "compiler/c2nim/*.cfg"
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 94a3b49e3..f9c577977 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -411,6 +411,7 @@ proc getLockLevel(s: PSym): TLockLevel =
       result = 0.TLockLevel
     else:
       result = UnknownLockLevel
+      #message(s.info, warnUser, "FOR THIS " & s.name.s)
 
 proc mergeLockLevels(tracked: PEffects, n: PNode, lockLevel: TLockLevel) =
   if lockLevel >= tracked.currLockLevel:
@@ -757,9 +758,15 @@ proc checkMethodEffects*(disp, branch: PSym) =
     localError(branch.info, "base method is GC-safe, but '$1' is not" % 
                                 branch.name.s)
   if branch.typ.lockLevel > disp.typ.lockLevel:
-    localError(branch.info,
-      "base method has lock level $1, but dispatcher has $2" %
-        [$branch.typ.lockLevel, $disp.typ.lockLevel])
+    when true:
+      message(branch.info, warnLockLevel,
+        "base method has lock level $1, but dispatcher has $2" %
+          [$branch.typ.lockLevel, $disp.typ.lockLevel])
+    else:
+      # XXX make this an error after bigbreak has been released:
+      localError(branch.info,
+        "base method has lock level $1, but dispatcher has $2" %
+          [$branch.typ.lockLevel, $disp.typ.lockLevel])
 
 proc setEffectsForProcType*(t: PType, n: PNode) =
   var effects = t.n.sons[0]
diff --git a/doc/manual/threads.txt b/doc/manual/threads.txt
index d29cab6ca..a96abf060 100644
--- a/doc/manual/threads.txt
+++ b/doc/manual/threads.txt
@@ -101,7 +101,7 @@ The compiler can ensure the location in ``location = spawn f(...)`` is not
 read prematurely within a ``parallel`` section and so there is no need for
 the overhead of an indirection via ``FlowVar[T]`` to ensure correctness.
 
-**Note**: Currently exceptions are not propagated between ``spawn``ed tasks!
+**Note**: Currently exceptions are not propagated between ``spawn``'ed tasks!
 
 
 Spawn statement
diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim
index 4080cd61f..6ba539377 100644
--- a/lib/impure/db_postgres.nim
+++ b/lib/impure/db_postgres.nim
@@ -143,12 +143,12 @@ iterator fastRows*(db: TDbConn, stmtName: TSqlPrepared,
                    args: varargs[string, `$`]): TRow {.tags: [FReadDB].} =
   ## executes the prepared query and iterates over the result dataset.
   var res = setupQuery(db, stmtName, args)
-  var L = PQnfields(res)
+  var L = pqNfields(res)
   var result = newRow(L)
-  for i in 0..PQntuples(res)-1:
+  for i in 0..pqNtuples(res)-1:
     setRow(res, result, i, L)
     yield result
-  PQclear(res)
+  pqClear(res)
 
 proc getRow*(db: TDbConn, query: TSqlQuery,
              args: varargs[string, `$`]): TRow {.tags: [FReadDB].} =
@@ -163,10 +163,10 @@ proc getRow*(db: TDbConn, query: TSqlQuery,
 proc getRow*(db: TDbConn, stmtName: TSqlPrepared,
              args: varargs[string, `$`]): TRow {.tags: [FReadDB].} =
   var res = setupQuery(db, stmtName, args)
-  var L = PQnfields(res)
+  var L = pqNfields(res)
   result = newRow(L)
   setRow(res, result, 0, L)
-  PQclear(res)
+  pqClear(res)
 
 proc getAllRows*(db: TDbConn, query: TSqlQuery,
                  args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} =
@@ -179,7 +179,7 @@ proc getAllRows*(db: TDbConn, stmtName: TSqlPrepared,
                  args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} =
   ## executes the prepared query and returns the whole result dataset.
   result = @[]
-  for r in FastRows(db, stmtName, args):
+  for r in fastRows(db, stmtName, args):
     result.add(r)
 
 iterator rows*(db: TDbConn, query: TSqlQuery,
diff --git a/lib/js/dom.nim b/lib/js/dom.nim
index b07666dd1..91b260a64 100644
--- a/lib/js/dom.nim
+++ b/lib/js/dom.nim
@@ -14,7 +14,7 @@ when not defined(js) and not defined(Nimdoc):
   {.error: "This module only works on the JavaScript platform".}
 
 type
-  TEventHandlers* {.importc.} = object of TObject
+  TEventHandlers* {.importc.} = object of RootObj
     onabort*: proc (event: ref TEvent) {.nimcall.}
     onblur*: proc (event: ref TEvent) {.nimcall.}
     onchange*: proc (event: ref TEvent) {.nimcall.}
@@ -124,14 +124,14 @@ type
     embeds*: seq[ref TEmbed]
     links*: seq[ref TLink]
 
-  TLink* {.importc.} = object of TObject
+  TLink* {.importc.} = object of RootObj
     name*: cstring
     target*: cstring
     text*: cstring
     x*: int
     y*: int
 
-  TEmbed* {.importc.} = object of TObject
+  TEmbed* {.importc.} = object of RootObj
     height*: int
     hspace*: int
     name*: cstring
@@ -142,12 +142,12 @@ type
     play*: proc () {.nimcall.}
     stop*: proc () {.nimcall.}
 
-  TAnchor* {.importc.} = object of TObject
+  TAnchor* {.importc.} = object of RootObj
     name*: cstring
     text*: cstring
     x*, y*: int
 
-  TApplet* {.importc.} = object of TObject
+  TApplet* {.importc.} = object of RootObj
 
   TElement* {.importc.} = object of TEventHandlers
     checked*: bool
@@ -166,7 +166,7 @@ type
     select*: proc () {.nimcall.}
     options*: seq[ref TOption]
 
-  TOption* {.importc.} = object of TObject
+  TOption* {.importc.} = object of RootObj
     defaultSelected*: bool
     selected*: bool
     selectedIndex*: int
@@ -209,7 +209,7 @@ type
     DocumentTypeNode,
     DocumentFragmentNode,
     NotationNode
-  TNode* {.importc.} = object of TObject
+  TNode* {.importc.} = object of RootObj
     attributes*: seq[ref TNode]
     childNodes*: seq[ref TNode]
     data*: cstring
@@ -241,7 +241,7 @@ type
     setAttributeNode*: proc (attr: ref TNode) {.nimcall.}
     style*: ref TStyle
 
-  TStyle* {.importc.} = object of TObject
+  TStyle* {.importc.} = object of RootObj
     background*: cstring
     backgroundAttachment*: cstring
     backgroundColor*: cstring
@@ -335,7 +335,7 @@ type
     removeAttribute*: proc (attr: cstring, caseSensitive=false) {.nimcall.}
     setAttribute*: proc (attr, value: cstring, caseSensitive=false) {.nimcall.}
 
-  TEvent* {.importc.} = object of TObject
+  TEvent* {.importc.} = object of RootObj
     altKey*, ctrlKey*, shiftKey*: bool
     button*: int
     clientX*, clientY*: int
@@ -373,7 +373,7 @@ type
     SUBMIT*: int
     UNLOAD*: int
 
-  TLocation* {.importc.} = object of TObject
+  TLocation* {.importc.} = object of RootObj
     hash*: cstring
     host*: cstring
     hostname*: cstring
@@ -385,13 +385,13 @@ type
     reload*: proc () {.nimcall.}
     replace*: proc (s: cstring) {.nimcall.}
 
-  THistory* {.importc.} = object of TObject
+  THistory* {.importc.} = object of RootObj
     length*: int
     back*: proc () {.nimcall.}
     forward*: proc () {.nimcall.}
     go*: proc (pagesToJump: int) {.nimcall.}
 
-  TNavigator* {.importc.} = object of TObject
+  TNavigator* {.importc.} = object of RootObj
     appCodeName*: cstring
     appName*: cstring
     appVersion*: cstring
@@ -402,18 +402,18 @@ type
     javaEnabled*: proc (): bool {.nimcall.}
     mimeTypes*: seq[ref TMimeType]
 
-  TPlugin* {.importc.} = object of TObject
+  TPlugin* {.importc.} = object of RootObj
     description*: cstring
     filename*: cstring
     name*: cstring
 
-  TMimeType* {.importc.} = object of TObject
+  TMimeType* {.importc.} = object of RootObj
     description*: cstring
     enabledPlugin*: ref TPlugin
     suffixes*: seq[cstring]
     `type`*: cstring
 
-  TLocationBar* {.importc.} = object of TObject
+  TLocationBar* {.importc.} = object of RootObj
     visible*: bool
   TMenuBar* = TLocationBar
   TPersonalBar* = TLocationBar
@@ -421,7 +421,7 @@ type
   TToolBar* = TLocationBar
   TStatusBar* = TLocationBar
 
-  TScreen* {.importc.} = object of TObject
+  TScreen* {.importc.} = object of RootObj
     availHeight*: int
     availWidth*: int
     colorDepth*: int
@@ -429,8 +429,8 @@ type
     pixelDepth*: int
     width*: int
 
-  TTimeOut* {.importc.} = object of TObject
-  TInterval* {.importc.} = object of TObject
+  TTimeOut* {.importc.} = object of RootObj
+  TInterval* {.importc.} = object of RootObj
 
 var
   window* {.importc, nodecl.}: ref TWindow
diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim
index 37b25871d..975eae7e2 100644
--- a/lib/pure/ftpclient.nim
+++ b/lib/pure/ftpclient.nim
@@ -446,13 +446,14 @@ proc getFile[T](ftp: FtpBase[T], async = false): bool =
       ftp.job.file.write(r2)
     elif returned and r2 == "":
       ftp.dsockConnected = false
-  
-  if not async:
-    var readSocks: seq[TSocket] = @[ftp.csock]
-    blockingOperation(ftp.csock):
-      if readSocks.select(1) != 0 and ftp.csock in readSocks:
-        assertReply ftp.expectReply(), "226"
-        return true
+
+  when T is TSocket:
+    if not async:
+      var readSocks: seq[TSocket] = @[ftp.csock]
+      blockingOperation(ftp.csock):
+        if readSocks.select(1) != 0 and ftp.csock in readSocks:
+          assertReply ftp.expectReply(), "226"
+          return true
 
 proc retrFile*[T](ftp: FtpBase[T], file, dest: string, async = false) =
   ## Downloads ``file`` and saves it to ``dest``. Usage of this function
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 8bd05ad55..385787d6c 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -542,7 +542,7 @@ proc raiseParseErr*(p: JsonParser, msg: string) {.noinline, noreturn.} =
   raise newException(JsonParsingError, errorMsgExpected(p, msg))
 
 proc newJString*(s: string): JsonNode =
-  ## Creates a new `JString PJsonNode`.
+  ## Creates a new `JString JsonNode`.
   new(result)
   result.kind = JString
   result.str = s
@@ -553,73 +553,73 @@ proc newJStringMove(s: string): JsonNode =
   shallowCopy(result.str, s)
 
 proc newJInt*(n: BiggestInt): JsonNode =
-  ## Creates a new `JInt PJsonNode`.
+  ## Creates a new `JInt JsonNode`.
   new(result)
   result.kind = JInt
   result.num  = n
 
 proc newJFloat*(n: float): JsonNode =
-  ## Creates a new `JFloat PJsonNode`.
+  ## Creates a new `JFloat JsonNode`.
   new(result)
   result.kind = JFloat
   result.fnum  = n
 
 proc newJBool*(b: bool): JsonNode =
-  ## Creates a new `JBool PJsonNode`.
+  ## Creates a new `JBool JsonNode`.
   new(result)
   result.kind = JBool
   result.bval = b
 
 proc newJNull*(): JsonNode =
-  ## Creates a new `JNull PJsonNode`.
+  ## Creates a new `JNull JsonNode`.
   new(result)
 
 proc newJObject*(): JsonNode =
-  ## Creates a new `JObject PJsonNode`
+  ## Creates a new `JObject JsonNode`
   new(result)
   result.kind = JObject
   result.fields = @[]
 
 proc newJArray*(): JsonNode =
-  ## Creates a new `JArray PJsonNode`
+  ## Creates a new `JArray JsonNode`
   new(result)
   result.kind = JArray
   result.elems = @[]
 
 
 proc `%`*(s: string): JsonNode =
-  ## Generic constructor for JSON data. Creates a new `JString PJsonNode`.
+  ## Generic constructor for JSON data. Creates a new `JString JsonNode`.
   new(result)
   result.kind = JString
   result.str = s
 
 proc `%`*(n: BiggestInt): JsonNode =
-  ## Generic constructor for JSON data. Creates a new `JInt PJsonNode`.
+  ## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
   new(result)
   result.kind = JInt
   result.num  = n
 
 proc `%`*(n: float): JsonNode =
-  ## Generic constructor for JSON data. Creates a new `JFloat PJsonNode`.
+  ## Generic constructor for JSON data. Creates a new `JFloat JsonNode`.
   new(result)
   result.kind = JFloat
   result.fnum  = n
 
 proc `%`*(b: bool): JsonNode =
-  ## Generic constructor for JSON data. Creates a new `JBool PJsonNode`.
+  ## Generic constructor for JSON data. Creates a new `JBool JsonNode`.
   new(result)
   result.kind = JBool
   result.bval = b
 
 proc `%`*(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode =
-  ## Generic constructor for JSON data. Creates a new `JObject PJsonNode`
+  ## Generic constructor for JSON data. Creates a new `JObject JsonNode`
   new(result)
   result.kind = JObject
   newSeq(result.fields, keyVals.len)
   for i, p in pairs(keyVals): result.fields[i] = p
 
 proc `%`*(elements: openArray[JsonNode]): JsonNode =
-  ## Generic constructor for JSON data. Creates a new `JArray PJsonNode`
+  ## Generic constructor for JSON data. Creates a new `JArray JsonNode`
   new(result)
   result.kind = JArray
   newSeq(result.elems, elements.len)
@@ -932,7 +932,7 @@ proc parseJson(p: var JsonParser): JsonNode =
 
 when not defined(js):
   proc parseJson*(s: Stream, filename: string): JsonNode =
-    ## Parses from a stream `s` into a `PJsonNode`. `filename` is only needed
+    ## Parses from a stream `s` into a `JsonNode`. `filename` is only needed
     ## for nice error messages.
     var p: JsonParser
     p.open(s, filename)
@@ -945,7 +945,7 @@ when not defined(js):
     result = parseJson(newStringStream(buffer), "input")
 
   proc parseFile*(filename: string): JsonNode =
-    ## Parses `file` into a `PJsonNode`.
+    ## Parses `file` into a `JsonNode`.
     var stream = newFileStream(filename, fmRead)
     if stream == nil:
       raise newException(IOError, "cannot read from file: " & filename)
@@ -956,7 +956,7 @@ else:
     TJSObject = object
   proc parseNativeJson(x: cstring): TJSObject {.importc: "JSON.parse".}
 
-  proc getVarType(x): TJsonNodeKind =
+  proc getVarType(x): JsonNodeKind =
     result = JNull
     proc getProtoName(y): cstring
       {.importc: "Object.prototype.toString.call".}
@@ -991,7 +991,7 @@ else:
       return `x`[`y`];
     """
 
-  proc convertObject(x: TJSObject): PJsonNode =
+  proc convertObject(x: TJSObject): JsonNode =
     case getVarType(x)
     of JArray:
       result = newJArray()
@@ -1018,15 +1018,15 @@ else:
     of JNull:
       result = newJNull()
 
-  proc parseJson*(buffer: string): PJsonNode =
+  proc parseJson*(buffer: string): JsonNode =
     return parseNativeJson(buffer).convertObject()
 
 when false:
   import os
-  var s = newFileStream(ParamStr(1), fmRead)
-  if s == nil: quit("cannot open the file" & ParamStr(1))
-  var x: TJsonParser
-  open(x, s, ParamStr(1))
+  var s = newFileStream(paramStr(1), fmRead)
+  if s == nil: quit("cannot open the file" & paramStr(1))
+  var x: JsonParser
+  open(x, s, paramStr(1))
   while true:
     next(x)
     case x.kind
@@ -1035,13 +1035,13 @@ when false:
       break
     of jsonEof: break
     of jsonString, jsonInt, jsonFloat: echo(x.str)
-    of jsonTrue: Echo("!TRUE")
-    of jsonFalse: Echo("!FALSE")
-    of jsonNull: Echo("!NULL")
-    of jsonObjectStart: Echo("{")
-    of jsonObjectEnd: Echo("}")
-    of jsonArrayStart: Echo("[")
-    of jsonArrayEnd: Echo("]")
+    of jsonTrue: echo("!TRUE")
+    of jsonFalse: echo("!FALSE")
+    of jsonNull: echo("!NULL")
+    of jsonObjectStart: echo("{")
+    of jsonObjectEnd: echo("}")
+    of jsonArrayStart: echo("[")
+    of jsonArrayEnd: echo("]")
     
   close(x)
 
diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim
index bd5e1bf42..9247f69c5 100644
--- a/lib/pure/logging.nim
+++ b/lib/pure/logging.nim
@@ -107,9 +107,12 @@ proc substituteLog(frmt: string): string =
       of "app":  result.add(app)
       of "appdir": result.add(app.splitFile.dir)
       of "appname": result.add(app.splitFile.name)
+      else: discard
 
 method log*(logger: Logger, level: Level,
-            frmt: string, args: varargs[string, `$`]) {.raises: [Exception], tags: [FTime, FWriteIO, FReadIO].} =
+            frmt: string, args: varargs[string, `$`]) {.
+            raises: [Exception], 
+            tags: [TimeEffect, WriteIOEffect, ReadIOEffect].} =
   ## Override this method in custom loggers. Default implementation does
   ## nothing.
   discard
diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim
index f76c0e515..9b4a7d556 100644
--- a/lib/system/jssys.nim
+++ b/lib/system/jssys.nim
@@ -345,11 +345,12 @@ else:
       node.appendChild(document.createTextNode(x))
       node.appendChild(document.createElement("br"))
     else: 
-      raise newException(EInvalidValue, " element does not exist yet!")
+      raise newException(ValueError, " element does not exist yet!")
 
   proc rawEcho {.compilerproc.} =
     var node = document.getElementsByTagName("body")[0]
-    if node == nil: raise newException(EIO, " element does not exist yet!")
+    if node == nil:
+      raise newException(IOError, " element does not exist yet!")
     asm """
       for (var i = 0; i < arguments.length; ++i) {
         var x = `toJSStr`(arguments[i]);
diff --git a/lib/wrappers/libuv.nim b/lib/wrappers/libuv.nim
index 1b6416982..3189ec408 100644
--- a/lib/wrappers/libuv.nim
+++ b/lib/wrappers/libuv.nim
@@ -35,7 +35,7 @@ type
   GetAddrInfoProc* = proc (handle: PGetAddrInfo, status: cint, res: ptr TAddrInfo)
 
   ExitProc* = proc (a2: PProcess, exit_status: cint, term_signal: cint)
-  FsProc* = proc (req: pFS)
+  FsProc* = proc (req: PFS)
   WorkProc* = proc (req: PWork)
   AfterWorkProc* = proc (req: PWork)
 
@@ -338,7 +338,7 @@ type
     FS_CHMOD, FS_FCHMOD, FS_FSYNC, FS_FDATASYNC, FS_UNLINK, FS_RMDIR, FS_MKDIR,
     FS_RENAME, FS_READDIR, FS_LINK, FS_SYMLINK, FS_READLINK, FS_CHOWN, FS_FCHOWN
 
-  tFS* {.pure, final, importc: "uv_fs_t", header: "uv.h".} = object
+  TFS* {.pure, final, importc: "uv_fs_t", header: "uv.h".} = object
     typ* {.importc: "type".}: TReqType
     data* {.importc: "data".}: pointer
     loop* {.importc: "loop".}: PLoop
@@ -349,7 +349,7 @@ type
     path* {.importc: "path".}: cstring
     errorno* {.importc: "errorno".}: cint
 
-  pFS* = ptr tFS
+  PFS* = ptr TFS
 
   TReq* {.pure, final, importc: "uv_req_t", header: "uv.h".} = object
     typ* {.importc: "type".}: TReqType
@@ -591,85 +591,85 @@ proc process_kill*(a2: PProcess, signum: cint): cint{.
 proc queue_work*(loop: PLoop, req: PWork, work_cb: WorkProc, after_work_cb: AfterWorkProc): cint{.
     importc: "uv_queue_work", header: "uv.h".}
 
-proc req_cleanup*(req: pFS){.
+proc req_cleanup*(req: PFS){.
     importc: "uv_fs_req_cleanup", header: "uv.h".}
 
-proc close*(loop: PLoop, req: pFS, file: TFile, cb: FsProc): cint{.
+proc close*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{.
     importc: "uv_fs_close", header: "uv.h".}
 
-proc open*(loop: PLoop, req: pFS, path: cstring, flags: cint, mode: cint, cb: FsProc): cint{.
+proc open*(loop: PLoop, req: PFS, path: cstring, flags: cint, mode: cint, cb: FsProc): cint{.
     importc: "uv_fs_open", header: "uv.h".}
 
-proc read*(loop: PLoop, req: pFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{.
+proc read*(loop: PLoop, req: PFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{.
     importc: "uv_fs_read", header: "uv.h".}
 
-proc unlink*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{.
+proc unlink*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_unlink", header: "uv.h".}
 
-proc write*(loop: PLoop, req: pFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{.
+proc write*(loop: PLoop, req: PFS, file: TFile, buf: pointer, length: csize, offset: coff, cb: FsProc): cint{.
     importc: "uv_fs_write", header: "uv.h".}
 
-proc mkdir*(loop: PLoop, req: pFS, path: cstring, mode: cint, cb: FsProc): cint{.
+proc mkdir*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{.
     importc: "uv_fs_mkdir", header: "uv.h".}
 
-proc rmdir*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{.
+proc rmdir*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_rmdir", header: "uv.h".}
 
-proc readdir*(loop: PLoop, req: pFS, path: cstring, flags: cint, cb: FsProc): cint{.
+proc readdir*(loop: PLoop, req: PFS, path: cstring, flags: cint, cb: FsProc): cint{.
     importc: "uv_fs_readdir", header: "uv.h".}
 
-proc stat*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{.
+proc stat*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_stat", header: "uv.h".}
 
-proc fstat*(loop: PLoop, req: pFS, file: TFile, cb: FsProc): cint{.
+proc fstat*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{.
     importc: "uv_fs_fstat", header: "uv.h".}
 
-proc rename*(loop: PLoop, req: pFS, path: cstring, new_path: cstring, cb: FsProc): cint{.
+proc rename*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_rename", header: "uv.h".}
 
-proc fsync*(loop: PLoop, req: pFS, file: TFile, cb: FsProc): cint{.
+proc fsync*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{.
     importc: "uv_fs_fsync", header: "uv.h".}
 
-proc fdatasync*(loop: PLoop, req: pFS, file: TFile, cb: FsProc): cint{.
+proc fdatasync*(loop: PLoop, req: PFS, file: TFile, cb: FsProc): cint{.
     importc: "uv_fs_fdatasync", header: "uv.h".}
 
-proc ftruncate*(loop: PLoop, req: pFS, file: TFile, offset: coff, cb: FsProc): cint{.
+proc ftruncate*(loop: PLoop, req: PFS, file: TFile, offset: coff, cb: FsProc): cint{.
     importc: "uv_fs_ftruncate", header: "uv.h".}
 
-proc sendfile*(loop: PLoop, req: pFS, out_fd: TFile, in_fd: TFile, in_offset: coff, length: csize, cb: FsProc): cint{.
+proc sendfile*(loop: PLoop, req: PFS, out_fd: TFile, in_fd: TFile, in_offset: coff, length: csize, cb: FsProc): cint{.
     importc: "uv_fs_sendfile", header: "uv.h".}
 
-proc chmod*(loop: PLoop, req: pFS, path: cstring, mode: cint, cb: FsProc): cint{.
+proc chmod*(loop: PLoop, req: PFS, path: cstring, mode: cint, cb: FsProc): cint{.
     importc: "uv_fs_chmod", header: "uv.h".}
 
-proc utime*(loop: PLoop, req: pFS, path: cstring, atime: cdouble, mtime: cdouble, cb: FsProc): cint{.
+proc utime*(loop: PLoop, req: PFS, path: cstring, atime: cdouble, mtime: cdouble, cb: FsProc): cint{.
     importc: "uv_fs_utime", header: "uv.h".}
 
-proc futime*(loop: PLoop, req: pFS, file: TFile, atime: cdouble, mtime: cdouble, cb: FsProc): cint{.
+proc futime*(loop: PLoop, req: PFS, file: TFile, atime: cdouble, mtime: cdouble, cb: FsProc): cint{.
     importc: "uv_fs_futime", header: "uv.h".}
 
-proc lstat*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{.
+proc lstat*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_lstat", header: "uv.h".}
 
-proc link*(loop: PLoop, req: pFS, path: cstring, new_path: cstring, cb: FsProc): cint{.
+proc link*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_link", header: "uv.h".}
 
-proc symlink*(loop: PLoop, req: pFS, path: cstring, new_path: cstring, flags: cint, cb: FsProc): cint{.
+proc symlink*(loop: PLoop, req: PFS, path: cstring, new_path: cstring, flags: cint, cb: FsProc): cint{.
     importc: "uv_fs_symlink", header: "uv.h".}
 
-proc readlink*(loop: PLoop, req: pFS, path: cstring, cb: FsProc): cint{.
+proc readlink*(loop: PLoop, req: PFS, path: cstring, cb: FsProc): cint{.
     importc: "uv_fs_readlink", header: "uv.h".}
 
-proc fchmod*(loop: PLoop, req: pFS, file: TFile, mode: cint, cb: FsProc): cint{.
+proc fchmod*(loop: PLoop, req: PFS, file: TFile, mode: cint, cb: FsProc): cint{.
     importc: "uv_fs_fchmod", header: "uv.h".}
 
-proc chown*(loop: PLoop, req: pFS, path: cstring, uid: cint, gid: cint, cb: FsProc): cint{.
+proc chown*(loop: PLoop, req: PFS, path: cstring, uid: cint, gid: cint, cb: FsProc): cint{.
     importc: "uv_fs_chown", header: "uv.h".}
 
-proc fchown*(loop: PLoop, req: pFS, file: TFile, uid: cint, gid: cint, cb: FsProc): cint{.
+proc fchown*(loop: PLoop, req: PFS, file: TFile, uid: cint, gid: cint, cb: FsProc): cint{.
     importc: "uv_fs_fchown", header: "uv.h".}
 
-proc event_init*(loop: PLoop, handle: PFsEvent, filename: cstring, cb: FsEventProc): cint{.
+proc event_init*(loop: PLoop, handle: PFSEvent, filename: cstring, cb: FsEventProc): cint{.
     importc: "uv_fs_event_init", header: "uv.h".}
 
 proc ip4_addr*(ip: cstring, port: cint): TSockAddrIn{.
diff --git a/tools/nimweb.nim b/tools/nimweb.nim
index a98a27a13..24ade58fc 100644
--- a/tools/nimweb.nim
+++ b/tools/nimweb.nim
@@ -35,7 +35,7 @@ proc initConfigData(c: var TConfigData) =
   c.pdf = @[]
   c.infile = ""
   c.outdir = ""
-  c.nimArgs = "--hint[Conf]:off "
+  c.nimArgs = "--hint[Conf]:off --hint[Path]:off --hint[Processing]:off "
   c.authors = ""
   c.projectTitle = ""
   c.projectName = ""
diff --git a/web/babelpkglist.nim b/web/babelpkglist.nim
index 5da7d60a9..aeea57a0d 100644
--- a/web/babelpkglist.nim
+++ b/web/babelpkglist.nim
@@ -10,7 +10,7 @@ proc decodeContent(content: string): string =
     if line != "":
       result.add decode(line)
 
-proc contains(x: seq[PJSonNode], s: string): bool =
+proc contains(x: seq[JSonNode], s: string): bool =
   for i in x:
     assert i.kind == JString
     if i.str == s: return true
@@ -20,7 +20,7 @@ proc processContent(content: string) =
   assert jsonDoc.kind == JArray
   var jsonArr = jsonDoc.elems
 
-  jsonArr.sort do (x, y: PJsonNode) -> int:
+  jsonArr.sort do (x, y: JsonNode) -> int:
     strutils.cmpIgnoreCase(x["name"].str, y["name"].str)
 
   var
diff --git a/web/nim.ini b/web/nim.ini
index 1bf75e209..d0867ca4e 100644
--- a/web/nim.ini
+++ b/web/nim.ini
@@ -36,7 +36,7 @@ UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson."""
 
 
 [Documentation]
-doc: "endb;intern;apis;lib;manual;tut1;tut2;nimc;overview;filters"
+doc: "endb;intern;apis;lib;manual.txt;tut1;tut2;nimc;overview;filters"
 doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt"
 pdf: "manual;lib;tut1;tut2;nimc;niminst;gc"
 srcdoc2: "system.nim"

From 40601ada5f001bed7d9ce5f1e61f296540ae8869 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sun, 5 Oct 2014 03:24:39 +0200
Subject: [PATCH 174/409] fixes #1551

---
 compiler/semexprs.nim | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index d3650f984..34e8c6fcd 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1629,8 +1629,9 @@ proc instantiateCreateFlowVarCall(c: PContext; t: PType;
   result = c.semGenerateInstance(c, sym, bindings, info)
   # since it's an instantiation, we unmark it as a compilerproc. Otherwise
   # codegen would fail:
-  result.flags = result.flags - {sfCompilerProc, sfExportC, sfImportC}
-  result.loc.r = nil
+  if sfCompilerProc in result.flags:
+    result.flags = result.flags - {sfCompilerProc, sfExportC, sfImportC}
+    result.loc.r = nil
 
 proc setMs(n: PNode, s: PSym): PNode = 
   result = n

From 3354f7e0982d1db512cd2aad9cd78a52d3379d02 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sun, 5 Oct 2014 11:43:48 +0200
Subject: [PATCH 175/409] fixes a race condition that caused '^' to hang

---
 lib/pure/concurrency/threadpool.nim | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim
index 7b0593b3e..fbd344e4e 100644
--- a/lib/pure/concurrency/threadpool.nim
+++ b/lib/pure/concurrency/threadpool.nim
@@ -95,7 +95,7 @@ type
 
   FlowVarBase* = ref FlowVarBaseObj ## untyped base class for 'FlowVar[T]'
   FlowVarBaseObj = object of RootObj
-    ready, usesCondVar: bool
+    ready, usesCondVar, awaited: bool
     cv: CondVar #\
     # for 'awaitAny' support
     ai: ptr AwaitInfo
@@ -129,8 +129,8 @@ type
 proc await*(fv: FlowVarBase) =
   ## waits until the value for the flowVar arrives. Usually it is not necessary
   ## to call this explicitly.
-  if fv.usesCondVar:
-    fv.usesCondVar = false
+  if fv.usesCondVar and not fv.awaited:
+    fv.awaited = true
     await(fv.cv)
     destroyCondVar(fv.cv)
 
@@ -185,7 +185,8 @@ proc nimFlowVarSignal(fv: FlowVarBase) {.compilerProc.} =
     inc fv.ai.cv.counter
     release(fv.ai.cv.L)
     signal(fv.ai.cv.c)
-  if fv.usesCondVar: signal(fv.cv)
+  if fv.usesCondVar: 
+    signal(fv.cv)
 
 proc awaitAndThen*[T](fv: FlowVar[T]; action: proc (x: T) {.closure.}) =
   ## blocks until the ``fv`` is available and then passes its value

From 16e0cda136d598527cfb35e9baeae5318e4d4f8c Mon Sep 17 00:00:00 2001
From: Dominik Picheta 
Date: Sun, 5 Oct 2014 20:22:07 +0100
Subject: [PATCH 176/409] CS fixes for dialogs on Windows.

---
 lib/impure/dialogs.nim  | 4 ++--
 lib/windows/windows.nim | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/impure/dialogs.nim b/lib/impure/dialogs.nim
index bbed99239..4ea66a6e6 100644
--- a/lib/impure/dialogs.nim
+++ b/lib/impure/dialogs.nim
@@ -200,14 +200,14 @@ proc chooseDir*(window: PWindow, root: string = ""): string =
       BrowseInfo: TBrowseInfo
       DisplayName: array [0..MAX_PATH, char]
       TempPath: array [0..MAX_PATH, char]
-    Result = ""
+    result = ""
     #BrowseInfo.hwndOwner = Application.Handle
     BrowseInfo.pszDisplayName = DisplayName
     BrowseInfo.ulFlags = 1 #BIF_RETURNONLYFSDIRS
     lpItemID = SHBrowseForFolder(cast[LPBrowseInfo](addr(BrowseInfo)))
     if lpItemId != nil:
       discard SHGetPathFromIDList(lpItemID, TempPath)
-      Result = $TempPath
+      result = $TempPath
       discard GlobalFreePtr(lpItemID)
   else:
     var chooser = file_chooser_dialog_new("Select Directory", window,
diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim
index f5b69402a..9008d63e3 100644
--- a/lib/windows/windows.nim
+++ b/lib/windows/windows.nim
@@ -10725,7 +10725,7 @@ type
     nMaxFileTitle*: DWORD
     lpstrInitialDir*: LPCTSTR
     lpstrTitle*: LPCTSTR
-    Flags*: DWORD
+    flags*: DWORD
     nFileOffset*: int16
     nFileExtension*: int16
     lpstrDefExt*: LPCTSTR

From da0fab70467a138081f5e0240fa66c7cae460b9e Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sun, 5 Oct 2014 23:36:47 +0200
Subject: [PATCH 177/409] nimfix now in its own directory; single file mode now
 the default

---
 compiler/commands.nim                | 4 +++-
 compiler/lookups.nim                 | 2 +-
 compiler/{ => nimfix}/nimfix.nim     | 5 +++--
 compiler/{ => nimfix}/nimfix.nim.cfg | 3 ++-
 compiler/{ => nimfix}/pretty.nim     | 0
 compiler/{ => nimfix}/prettybase.nim | 0
 compiler/sem.nim                     | 4 ++--
 compiler/sigmatch.nim                | 2 +-
 8 files changed, 12 insertions(+), 8 deletions(-)
 rename compiler/{ => nimfix}/nimfix.nim (95%)
 rename compiler/{ => nimfix}/nimfix.nim.cfg (83%)
 rename compiler/{ => nimfix}/pretty.nim (100%)
 rename compiler/{ => nimfix}/prettybase.nim (100%)

diff --git a/compiler/commands.nim b/compiler/commands.nim
index f8f6a9a33..616e50507 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -234,7 +234,9 @@ proc processPath(path: string, notRelativeToProj = false): string =
             path 
           else:
             options.gProjectPath / path
-  result = unixToNativePath(p % ["nimrod", getPrefixDir(), "lib", libpath,
+  result = unixToNativePath(p % ["nimrod", getPrefixDir(),
+    "nim", getPrefixDir(),
+    "lib", libpath,
     "home", removeTrailingDirSep(os.getHomeDir()),
     "projectname", options.gProjectName,
     "projectpath", options.gProjectPath])
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index 07ac43f38..fa1837296 100644
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -11,7 +11,7 @@
 
 import 
   intsets, ast, astalgo, idents, semdata, types, msgs, options, rodread, 
-  renderer, wordrecg, idgen, prettybase
+  renderer, wordrecg, idgen, nimfix.prettybase
 
 proc ensureNoMissingOrUnusedSymbols(scope: PScope)
 
diff --git a/compiler/nimfix.nim b/compiler/nimfix/nimfix.nim
similarity index 95%
rename from compiler/nimfix.nim
rename to compiler/nimfix/nimfix.nim
index 15174fd48..e561b6d4d 100644
--- a/compiler/nimfix.nim
+++ b/compiler/nimfix/nimfix.nim
@@ -21,7 +21,7 @@ Usage:
 Options:
   --overwriteFiles:on|off          overwrite the original nim files.
                                    DEFAULT is ON!
-  --onlyMainfile                   overwrite only the main file.
+  --wholeProject                   overwrite every processed file.
   --checkExtern:on|off             style check also extern names
   --styleCheck:on|off|auto         performs style checking for identifiers
                                    and suggests an alternative spelling; 
@@ -46,6 +46,7 @@ proc mainCommand =
 proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
   var p = parseopt.initOptParser(cmd)
   var argsCount = 0
+  gOnlyMainfile = true
   while true: 
     parseopt.next(p)
     case p.kind
@@ -68,7 +69,7 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
         of "on": gStyleCheck = StyleCheck.Warn
         of "auto": gStyleCheck = StyleCheck.Auto
         else: localError(gCmdLineInfo, errOnOrOffExpected)
-      of "onlymainfile": gOnlyMainfile = true
+      of "wholeproject": gOnlyMainfile = false
       else:
         processSwitch(pass, p)
     of cmdArgument:
diff --git a/compiler/nimfix.nim.cfg b/compiler/nimfix/nimfix.nim.cfg
similarity index 83%
rename from compiler/nimfix.nim.cfg
rename to compiler/nimfix/nimfix.nim.cfg
index 61df6742e..31a41e080 100644
--- a/compiler/nimfix.nim.cfg
+++ b/compiler/nimfix/nimfix.nim.cfg
@@ -2,9 +2,10 @@
 # gc:markAndSweep
 
 hint[XDeclaredButNotUsed]:off
-path:"$projectPath/.."
+path:"$projectPath/../.."
 
 path:"$lib/packages/docutils"
+path:"$nim/compiler"
 
 define:useStdoutAsStdmsg
 symbol:nimfix
diff --git a/compiler/pretty.nim b/compiler/nimfix/pretty.nim
similarity index 100%
rename from compiler/pretty.nim
rename to compiler/nimfix/pretty.nim
diff --git a/compiler/prettybase.nim b/compiler/nimfix/prettybase.nim
similarity index 100%
rename from compiler/prettybase.nim
rename to compiler/nimfix/prettybase.nim
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 7446384d2..63475a566 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -15,11 +15,11 @@ import
   magicsys, parser, nversion, nimsets, semfold, importer,
   procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
   intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
-  evaltempl, patterns, parampatterns, sempass2, pretty, semmacrosanity,
+  evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity,
   semparallel, lowerings
 
 when defined(nimfix):
-  import prettybase
+  import nimfix.prettybase
 
 # implementation
 
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 59f954ff0..b5e01811e 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -13,7 +13,7 @@
 import 
   intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
   magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
-  pretty
+  nimfix.pretty
 
 when not defined(noDocgen):
   import docgen

From b781e25ec63b340a6c215721e07a25e4bda42994 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Mon, 6 Oct 2014 01:01:23 +0200
Subject: [PATCH 178/409] should compile with csources again

---
 compiler/ast.nim | 1 -
 todo.txt         | 2 --
 2 files changed, 3 deletions(-)

diff --git a/compiler/ast.nim b/compiler/ast.nim
index 762e09a95..db6003b87 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -681,7 +681,6 @@ type
     heapRoot*: PRope          # keeps track of the enclosing heap object that
                               # owns this location (required by GC algorithms
                               # employing heap snapshots or sliding views)
-    #a*: int                   # location's "address", i.e. slot for temporaries
 
   # ---------------- end of backend information ------------------------------
 
diff --git a/todo.txt b/todo.txt
index 1e01793de..e24175e8b 100644
--- a/todo.txt
+++ b/todo.txt
@@ -15,9 +15,7 @@ Concurrency
 -----------
 
 - test 'deepCopy' for closures
-
 - implement 'foo[1..4] = spawn(f[4..7])'
-- document the new 'spawn' and 'parallel' statements
 
 Low priority:
 - support for exception propagation? (hard to implement)

From a585caebcd70dd40c2b37f064818039362417d32 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Wed, 8 Oct 2014 09:10:57 +0200
Subject: [PATCH 179/409] bugfix: c++ support for 'NimThreadVarsSize'

---
 compiler/ccgthreadvars.nim | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/compiler/ccgthreadvars.nim b/compiler/ccgthreadvars.nim
index 60bc0fc4b..c24dd5c41 100644
--- a/compiler/ccgthreadvars.nim
+++ b/compiler/ccgthreadvars.nim
@@ -57,6 +57,9 @@ proc generateThreadLocalStorage(m: BModule) =
 
 proc generateThreadVarsSize(m: BModule) =
   if nimtv != nil:
-    app(m.s[cfsProcs], 
-      "NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}" & tnl)
-
+    let externc = if gCmd != cmdCompileToCpp and
+                       sfCompileToCpp in m.module.flags: "extern \"C\""
+                  else: ""
+    appf(m.s[cfsProcs],
+      "$#NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}$n",
+      [externc.toRope])

From 1d8ee0f876029b2a0501689d793353c878b2085c Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 9 Oct 2014 09:28:36 +0200
Subject: [PATCH 180/409] improved trimcc tool

---
 tools/trimcc.nim | 140 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 119 insertions(+), 21 deletions(-)

diff --git a/tools/trimcc.nim b/tools/trimcc.nim
index 4d9686195..b6bf282b6 100644
--- a/tools/trimcc.nim
+++ b/tools/trimcc.nim
@@ -1,29 +1,127 @@
 # Trim C compiler installation to a minimum
 
-import strutils, os
-
-proc newName(f: string): string =
-  var (dir, name, ext) = splitFile(f)
-  return dir / "trim_" & name & ext
-
-proc walker(dir: string) = 
+import strutils, os, pegs, strtabs, math, threadpool, times
+
+proc fakeCppDep(x: ptr float) {.importcpp: "fakeCppDep", header: "".}
+
+const
+  Essential = """gcc.exe g++.exe gdb.exe ld.exe as.exe c++.exe cpp.exe cc1.exe
+crtbegin.o crtend.o crt2.o dllcrt2.o
+libexpat-1.dll libwinpthread-1.dll
+
+aio.h
+dlfcn.h
+fcntl.h fenv.h fmtmsg.h fnmatch.h ftw.h
+errno.h
+glob.h gtmath.h
+if.h in.h ipc.h
+langinfo.h locale.h
+math.h mman.h
+netdb.h nl_types.h
+poll.h pthread.h pwd.h
+sched.h select.h semaphore.h signal.h
+socket.h spawn.h stat.h statvfs.h stdio.h stdlib.h string.h strings.h
+tcp.h time.h types.h
+ucontext.h uio.h utsname.h unistd.h
+wait.h
+varargs.h
+windows.h
+zlib.h
+""".split
+  BucketSize = 40
+
+proc includes(headerpath, headerfile: string, whitelist: StringTableRef) =
+  whitelist[headerfile] = "processed"
+  for line in lines(headerpath):
+    if line =~ peg"""s <- ws '#include' ws ('"' / '<') {[^">]+} ('"' / '>') ws
+                     comment <- '/*' @ '*/' / '//' .*
+                     ws <- (comment / \s+)* """:
+      let m = matches[0].extractFilename
+      if whitelist[m] != "processed":
+        whitelist[m] = "found"
+
+proc processIncludes(dir: string, whitelist: StringTableRef) =
   for kind, path in walkDir(dir):
     case kind
-    of pcFile:
-      moveFile(dest=newName(path), source=path)
-      # test if installation still works:
-      if execShellCmd(r"nimrod c --force_build koch") == 0:
-        echo "Optional: ", path
-        removeFile(newName(path))
-      else:
-        echo "Required: ", path
-        # copy back:
-        moveFile(dest=path, source=newName(path))
-    of pcDir:
-      walker(path)
+    of pcFile:
+      let name = extractFilename(path)
+      if ('.' notin name and "include" in path) or ("c++" in path):
+        let n = whitelist[name]
+        if n != "processed": whitelist[name] = "found"
+      if name.endswith(".h"):
+        let n = whitelist[name]
+        if n == "found": includes(path, name, whitelist)
+    of pcDir: processIncludes(path, whitelist)
+    else: discard
+
+proc gatherFiles(dir: string, whitelist: StringTableRef, result: var seq[string]) =
+  for kind, path in walkDir(dir):
+    case kind
+    of pcFile:
+      let name = extractFilename(path)
+      if not whitelist.hasKey(name):
+        result.add(path)
+    of pcDir: gatherFiles(path, whitelist, result)
     else: discard
 
-if paramCount() == 1:
-  walker(paramStr(1))
+proc newName(f: string): string =
+  let (dir, name, ext) = splitFile(f)
+  return dir / "trim_" & name & ext
+
+proc ccStillWorks(): bool =
+  const
+    c1 = r"nim c --force_build koch"
+    c2 = r"nim c --force_build --threads:on --out:temp.exe tools/trimcc"
+  result = execShellCmd(c1) == 0 and execShellCmd(c2) == 0
+
+proc trialDeletion(files: seq[string], a, b: int) =
+  for i in a .. min(b, files.high):
+    let path = files[i]
+    moveFile(dest=newName(path), source=path)
+  if ccStillWorks():
+    for i in a .. min(b, files.high):
+      let path = files[i]
+      echo "Optional: ", path
+      removeFile(newName(path))
+  else:
    for i in a .. min(b, files.high):
+      let path = files[i]
+      echo "Required: ", path
+      # copy back:
+      moveFile(dest=path, source=newName(path))
+
+proc main(dir: string) =
+  var whitelist = newStringTable(modeCaseInsensitive)
+  for e in Essential:
+    whitelist[e] = "found"
+  while true:
+    let oldLen = whitelist.len
+    processIncludes(dir, whitelist)
+    if oldLen == whitelist.len: break
+  var allFiles: seq[string] = @[]
+  gatherFiles(dir, whitelist, allFiles)
+  when true:
+    var i = 0
+    while i < allFiles.len:
+      trialDeletion(allFiles, i, i+BucketSize-1)
+      inc i, BucketSize
+  else:
+    for x in allFiles: echo x
+
+proc fakeTimeDep() = echo(times.getDateStr())
+
+proc fakedeps() =
+  var x = 0.4
+  {.emit: "#if 0\n".}
+  fakeCppDep(addr x)
+  {.emit: "#endif\n".}
+
+  # this is not true:
+  if math.sin(x) > 0.6:
+    spawn(fakeTimeDep())
+
+if paramCount() == 1:
+  doAssert ccStillWorks()
+  fakedeps()
+  main(paramStr(1))
 else:
   quit "Usage: trimcc c_compiler_directory"

From 8b93e4132cd9f41182dc9fa46d5c79a71a2c09ef Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sat, 11 Oct 2014 01:11:37 +0200
Subject: [PATCH 181/409] added untested winrelease target

---
 koch.nim | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/koch.nim b/koch.nim
index a43701194..2cbfe01c5 100644
--- a/koch.nim
+++ b/koch.nim
@@ -48,6 +48,7 @@ Possible Commands:
   update                   updates nim to the latest version from github
                            (compile koch with -d:withUpdate to enable)
   temp options             creates a temporary compiler for testing
+  winrelease               creates a release (for coredevs only)
 Boot options:
   -d:release               produce a release version of the compiler
   -d:tinyc                 include the Tiny C backend (not supported on Windows)
@@ -278,6 +279,33 @@ when defined(withUpdate):
     boot(args)
     echo("Update complete!")
 
+# -------------- builds a release ---------------------------------------------
+
+proc run7z(platform: string, patterns: varargs[string]) =
+  const tmpDir = "nim-" & NimVersion
+  createDir tmpDir
+  try:
+    for pattern in patterns:
+      for f in walkFiles(pattern):
+        if "nimcache" notin f:
+          copyFile(f, tmpDir / f)
+    exec("7z a -tzip $1-$2.zip $1" % [tmpDir, platform])
+  finally:
+    removeDir tmpDir
+
+proc winRelease() =
+  boot(" -d:release")
+  #buildTool("tools/niminst/niminst", " -d:release")
+  buildTool("tools/nimgrep", " -d:release")
+  buildTool("compiler/nimfix/nimfix", " -d:release")
+
+  run7z("win32", "bin/nim.exe", "bin/c2nim.exe", "bin/nimgrep.exe",
+        "bin/nimfix.exe",
+        "bin/babel.exe", "bin/*.dll",
+        "config", "dist/*.dll", "examples", "lib",
+        "readme.txt", "contributors.txt", "copying.txt")
+  # second step: XXX build 64 bit version
+
 # -------------- tests --------------------------------------------------------
 
 template `|`(a, b): expr = (if a.len > 0: a else: b)
@@ -321,5 +349,6 @@ of cmdArgument:
     else:
       quit "this Koch has not been compiled with -d:withUpdate"
   of "temp": temp(op.cmdLineRest)
+  of "winrelease": winRelease()
   else: showHelp()
 of cmdEnd: showHelp()

From 5272213da4b0701890d8a42fb292962704f0b99d Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sat, 11 Oct 2014 01:30:17 +0200
Subject: [PATCH 182/409] documentation updates

---
 compiler/nversion.nim |  4 ++--
 doc/manual/lexing.txt | 33 +++++++++++++++++++++------
 todo.txt              |  2 +-
 tools/restorecc.nim   | 16 +++++++++++++
 web/index.txt         | 52 +++++++++++++++++++++----------------------
 web/news.txt          |  8 +++++--
 web/question.txt      | 43 ++++++++++++++++++-----------------
 7 files changed, 99 insertions(+), 59 deletions(-)
 create mode 100644 tools/restorecc.nim

diff --git a/compiler/nversion.nim b/compiler/nversion.nim
index 968feb081..c29880fe2 100644
--- a/compiler/nversion.nim
+++ b/compiler/nversion.nim
@@ -13,8 +13,8 @@
 const 
   MaxSetElements* = 1 shl 16  # (2^16) to support unicode character sets?
   VersionMajor* = 0
-  VersionMinor* = 9
-  VersionPatch* = 6
+  VersionMinor* = 10
+  VersionPatch* = 0
   VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
 
   RodFileVersion* = "1215"       # modify this if the rod-format changes!
diff --git a/doc/manual/lexing.txt b/doc/manual/lexing.txt
index c3894b13d..4de7936a3 100644
--- a/doc/manual/lexing.txt
+++ b/doc/manual/lexing.txt
@@ -93,14 +93,33 @@ The following keywords are reserved and cannot be used as identifiers:
 Some keywords are unused; they are reserved for future developments of the
 language.
 
-Nim is a `style-insensitive`:idx: language. This means that it is not
-case-sensitive and even underscores are ignored:
-**type** is a reserved word, and so is **TYPE** or **T_Y_P_E**. The idea behind
-this is that this allows programmers to use their own preferred spelling style
-and libraries written by different programmers cannot use incompatible
-conventions. A Nim-aware editor or IDE can show the identifiers as
+
+Identifier equality
+-------------------
+
+Two identifiers are considered equal if the following algorithm returns true:
+
+.. code-block:: nim
+  proc sameIdentifier(a, b: string): bool =
+    a[0] == b[0] and a.replace("_", "").toLower == b.replace("_", "").toLower
+
+That means only the first letters are compared in a case sensitive manner. Other
+letters are compared case insensitively and underscores are ignored.
+
+This rather strange way to do identifier comparisons is called
+`partial case insensitivity`:idx: and has some advantages over the conventional
+case sensitivity:
+
+It allows programmers to mostly use their own preferred
+spelling style and libraries written by different programmers cannot use
+incompatible conventions. A Nim-aware editor or IDE can show the identifiers as
 preferred. Another advantage is that it frees the programmer from remembering
-the exact spelling of an identifier.
+the exact spelling of an identifier. The exception with respect to the first
+letter allows common code like ``var foo: Foo`` to be parsed unambiguously.
+
+Historically, Nim was a `style-insensitive`:idx: language. This means that it
+was not case-sensitive and underscores were ignored and there was no distinction
+between ``foo`` and ``Foo``.
 
 
 String literals
diff --git a/todo.txt b/todo.txt
index e24175e8b..3e511dc49 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,7 +1,6 @@
 version 0.10
 ============
 
-- fix the bug that keeps 'defer' template from working
 - Test nimfix on various babel packages
 
 
@@ -37,6 +36,7 @@ Misc
 Bugs
 ====
 
+- fix the bug that keeps 'defer' template from working
 - VM: Pegs do not work at compile-time
 - VM: ptr/ref T cannot work in general
 - scopes are still broken for generic instantiation!
diff --git a/tools/restorecc.nim b/tools/restorecc.nim
new file mode 100644
index 000000000..f5d8f0bb3
--- /dev/null
+++ b/tools/restorecc.nim
@@ -0,0 +1,16 @@
+
+import os, strutils
+
+proc main(dir: string, wanted: string) =
+  for kind, path in walkDir(dir):
+    case kind
+    of pcFile:
+      let name = extractFilename(path)
+      if name == wanted:
+        let newLoc = path.replace("mingw_backup", "mingw")
+        echo "creating ", newLoc
+        copyFile(path, newLoc)
+    of pcDir: main(path, wanted)
+    else: discard
+
+main("dist/mingw_backup", paramStr(1))
diff --git a/web/index.txt b/web/index.txt
index 947ebb706..04c953628 100644
--- a/web/index.txt
+++ b/web/index.txt
@@ -2,13 +2,13 @@
 Home
 ====
 
-Welcome to Nimrod
------------------
+Welcome to Nim
+--------------
 
-**Nimrod** is a statically typed, imperative programming language that tries to
-give the programmer ultimate power without compromises on runtime efficiency. 
-This means it focuses on compile-time mechanisms in all their
-various forms.
+**Nim** (formerly known as "Nimrod") is a statically typed, imperative 
+programming language that tries to give the programmer ultimate power without 
+compromises on runtime efficiency. This means it focuses on compile-time
+mechanisms in all their various forms.
 
 Beneath a nice infix/indentation based syntax with a 
 powerful (AST based, hygienic) macro system lies a semantic model that supports 
@@ -18,10 +18,10 @@ shared memory heap is also provided for the increased efficiency that results
 from that model.
 
 
-Nimrod looks like this:
-=======================
+Nim looks like this:
+====================
 
-.. code-block:: nimrod
+.. code-block:: nim
   # compute average line length
   var count = 0
   var sum = 0
@@ -34,11 +34,11 @@ Nimrod looks like this:
     if count > 0: sum / count else: 0
 
 
-Nimrod is efficient
-===================
+Nim is efficient
+================
 
 * Native code generation (currently via compilation to C), not dependent on a
-  virtual machine: **Nimrod produces small executables without dependencies
+  virtual machine: **Nim produces small executables without dependencies
   for easy redistribution.**
 * A fast **non-tracing** garbage collector that supports soft 
   real-time systems (like games).
@@ -55,11 +55,11 @@ Nimrod is efficient
   the stack.
 
 
-Nimrod is expressive
-====================
+Nim is expressive
+=================
 
-* **The Nimrod compiler and all of the standard library are implemented in 
-  Nimrod.**
+* **The Nim compiler and all of the standard library are implemented in 
+  Nim.**
 * Built-in high level datatypes: strings, sets, sequences, etc.
 * Modern type system with local type inference, tuples, variants, 
   generics, etc.
@@ -69,31 +69,31 @@ Nimrod is expressive
 * Macros can modify the abstract syntax tree at compile time.
 
 
-Nimrod is elegant
-=================
+Nim is elegant
+==============
 
-* Macros can use the imperative paradigm to construct parse trees. Nimrod
+* Macros can use the imperative paradigm to construct parse trees. Nim
   does not require a different coding style for meta programming.
-* Macros cannot change Nimrod's syntax because there is no need for it. 
-  Nimrod's syntax is flexible enough.
+* Macros cannot change Nim's syntax because there is no need for it. 
+  Nim's syntax is flexible enough.
 * Statements are grouped by indentation but can span multiple lines.
   Indentation must not contain tabulators so the compiler always sees
   the code the same way as you do.
 
 
-Nimrod plays nice with others
-=============================
+Nim plays nice with others
+==========================
 
-* The Nimrod Compiler runs on Windows, Linux, BSD and Mac OS X.
+* The Nim Compiler runs on Windows, Linux, BSD and Mac OS X.
   Porting to other platforms is easy.
-* **The Nimrod Compiler can also generate C++ or Objective C for easier
+* **The Nim Compiler can also generate C++ or Objective C for easier
   interfacing.**
 * There are lots of bindings: for example, bindings to GTK2, the Windows API, 
   the POSIX API, OpenGL, SDL, Cairo, Python, Lua, TCL, X11, libzip, PCRE, 
   libcurl, mySQL and SQLite are included in the standard distribution or
   can easily be obtained via the
   `Babel package manager `_.
-* A C to Nimrod conversion utility: New bindings to C libraries are easily 
+* A C to Nim conversion utility: New bindings to C libraries are easily 
   generated by ``c2nim``.
 
 
diff --git a/web/news.txt b/web/news.txt
index ceb23a6dd..8a28292e6 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -3,8 +3,8 @@ News
 ====
 
 ..
-  2014-06-29 Version 0.9.6 released
-  =================================
+  2014-10-11 Version 0.10.0 released
+  ==================================
 
   Changes affecting backwards compatibility
   -----------------------------------------
@@ -47,6 +47,10 @@ News
     found under the `nim-code `_ organisation.
   - Removed the deprecated ``web`` module, the ``httpclient`` module should
     be used instead.
+  - Large parts of the stdlib got rid of the T/P type prefixes. Instead most
+    types now simply start with an uppercased letter. The
+    so called "partial case sensitivity" is now active allowing code 
+    like ``var foo: Foo``.
   - String case (or any non-ordinal case) statements 
     without 'else' are deprecated.
   - Recursive tuple types are not allowed anymore. Use ``object`` instead.
diff --git a/web/question.txt b/web/question.txt
index e6f4d40a5..52809ff90 100644
--- a/web/question.txt
+++ b/web/question.txt
@@ -6,11 +6,12 @@
 General
 =======
 
-What is Nimrod?
----------------
+What is Nim?
+------------
 
-Nimrod is a statically typed, imperative programming language that tries to
-give the programmer ultimate power without compromises on runtime efficiency. 
+Nim (formerly known as "Nimrod") is a statically typed, imperative programming
+language that tries to give the programmer ultimate power without compromises
+on runtime efficiency.
 This means it focuses on compile-time mechanisms in all their
 various forms. Beneath a nice infix/indentation based syntax with a 
 powerful (AST based, hygienic) macro system lies a semantic model that supports 
@@ -23,7 +24,7 @@ from that model.
 Why yet another programming language?
 -------------------------------------
 
-Nimrod is one of the very few *programmable* statically typed languages, and 
+Nim is one of the very few *programmable* statically typed languages, and 
 one of the even fewer that produces native binaries that require no 
 runtime or interpreter.
 
@@ -36,29 +37,29 @@ C++, Python, Lisp, Oberon.
 
 
 
-What is Nimrod's take on concurrency?
--------------------------------------
+What is Nim's take on concurrency?
+----------------------------------
 
-Nimrod primarily focusses on thread local (and garbage collected) heaps and 
-asynchronous message passing between threads. Each thread has its own GC, so no 
+Nim primarily focusses on thread local (and garbage collected) heaps and 
+message passing between threads. Each thread has its own GC, so no 
 "stop the world" mechanism is necessary. An unsafe shared memory heap is also
-provided. 
+provided.
 
 Future versions will additionally include a GC "per thread group" 
-and Nimrod's type system will be enhanced to accurately model this shared
+and Nim's type system will be enhanced to accurately model this shared
 memory heap.
 
 
-How is Nimrod licensed?
------------------------
+How is Nim licensed?
+--------------------
 
-The Nimrod compiler and the library are MIT licensed.
+The Nim compiler and the library are MIT licensed.
 This means that you can use any license for your own programs developed with
-Nimrod.
+Nim.
 
 
-How stable is Nimrod?
----------------------
+How stable is Nim?
+------------------
 
 The compiler is in development and some important features are still missing.
 However, the compiler is quite stable already: It is able to compile itself 
@@ -66,11 +67,11 @@ and a substantial body of other code. Until version 1.0.0 is released,
 minor incompatibilities with older versions of the compiler will be introduced.
 
 
-How fast is Nimrod?
--------------------
+How fast is Nim?
+----------------
 Benchmarks show it to be comparable to C. Some language features (methods, 
 closures, message passing) are not yet as optimized as they could and will be.
-The only overhead Nimrod has over C is the GC which has been tuned 
+The only overhead Nim has over C is the GC which has been tuned 
 for years but still needs some work.
 
 
@@ -84,7 +85,7 @@ but would require much work.
 What about editor support?
 --------------------------
 
-- Nimrod IDE: https://github.com/nimrod-code/Aporia
+- Nim IDE: https://github.com/nimrod-code/Aporia
 - Emacs: https://github.com/Tass/nimrod-mode
 - Vim: https://github.com/zah/nimrod.vim/
 - Scite: Included

From aac8de6b4c9e57bac9367b585d22da8afc7849f1 Mon Sep 17 00:00:00 2001
From: Erik O'Leary 
Date: Fri, 10 Oct 2014 22:36:15 -0500
Subject: [PATCH 183/409] Fixed FD_SET casing

---
 csources                |  1 +
 lib/posix/posix.nim     |  2 +-
 lib/pure/asyncio.nim    | 10 +++++-----
 lib/pure/rawsockets.nim |  2 +-
 lib/pure/sockets.nim    |  2 +-
 lib/windows/winlean.nim |  2 +-
 6 files changed, 10 insertions(+), 9 deletions(-)
 create mode 160000 csources

diff --git a/csources b/csources
new file mode 160000
index 000000000..b0bcf88e2
--- /dev/null
+++ b/csources
@@ -0,0 +1 @@
+Subproject commit b0bcf88e26730b23d22e2663adf1babb05bd5a71
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index c3085f0fb..8c1c258db 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -2382,7 +2382,7 @@ proc hstrerror*(herrnum: cint): cstring {.importc, header: "".}
 proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "".}
 proc FD_ISSET*(a1: cint | SocketHandle, a2: var TFdSet): cint {.
   importc, header: "".}
-proc fdSet*(a1: cint | SocketHandle, a2: var TFdSet) {.
+proc FD_SET*(a1: cint | SocketHandle, a2: var TFdSet) {.
   importc: "FD_SET", header: "".}
 proc FD_ZERO*(a1: var TFdSet) {.importc, header: "".}
 
diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim
index bb0d29fc4..0dbc0a3d5 100644
--- a/lib/pure/asyncio.nim
+++ b/lib/pure/asyncio.nim
@@ -91,11 +91,11 @@ import sockets, os
 ##      getSocket(s).accept(client)
 
 when defined(windows):
-  from winlean import TimeVal, SocketHandle, fdSet, FD_ZERO, TFdSet,
-    fdSet, FD_ISSET, select
+  from winlean import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet,
+    FD_ISSET, select
 else:
-  from posix import TimeVal, SocketHandle, fdSet, FD_ZERO, TFdSet,
-    fdSet, FD_ISSET, select
+  from posix import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet,
+    FD_ISSET, select
 
 type
   DelegateObj* = object
@@ -556,7 +556,7 @@ proc createFdSet(fd: var TFdSet, s: seq[Delegate], m: var int) =
   FD_ZERO(fd)
   for i in items(s): 
     m = max(m, int(i.fd))
-    fdSet(i.fd, fd)
+    FD_SET(i.fd, fd)
    
 proc pruneSocketSet(s: var seq[Delegate], fd: var TFdSet) =
   var i = 0
diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim
index 5756ca23d..62a011999 100644
--- a/lib/pure/rawsockets.nim
+++ b/lib/pure/rawsockets.nim
@@ -372,7 +372,7 @@ proc createFdSet(fd: var TFdSet, s: seq[SocketHandle], m: var int) =
   FD_ZERO(fd)
   for i in items(s): 
     m = max(m, int(i))
-    fdSet(i, fd)
+    FD_SET(i, fd)
    
 proc pruneSocketSet(s: var seq[SocketHandle], fd: var TFdSet) = 
   var i = 0
diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim
index 6975f07c0..36389edcc 100644
--- a/lib/pure/sockets.nim
+++ b/lib/pure/sockets.nim
@@ -936,7 +936,7 @@ proc createFdSet(fd: var TFdSet, s: seq[Socket], m: var int) =
   FD_ZERO(fd)
   for i in items(s): 
     m = max(m, int(i.fd))
-    fdSet(i.fd, fd)
+    FD_SET(i.fd, fd)
    
 proc pruneSocketSet(s: var seq[Socket], fd: var TFdSet) =
   var i = 0
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index cc633d90b..76d17bc4a 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -536,7 +536,7 @@ proc WSAFDIsSet(s: SocketHandle, set: var TFdSet): bool {.
 proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint = 
   result = if WSAFDIsSet(socket, set): 1'i32 else: 0'i32
 
-proc fdSet*(socket: SocketHandle, s: var TFdSet) = 
+proc FD_SET*(socket: SocketHandle, s: var TFdSet) = 
   if s.fd_count < FD_SETSIZE:
     s.fd_array[int(s.fd_count)] = socket
     inc(s.fd_count)

From 09f177e0ccdea872fb560e834efa897030cb06de Mon Sep 17 00:00:00 2001
From: Erik O'Leary 
Date: Fri, 10 Oct 2014 22:49:44 -0500
Subject: [PATCH 184/409] patched fdset call in osproc

---
 lib/pure/osproc.nim | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index f47df73ca..0557b26f7 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -887,7 +887,7 @@ elif not defined(useNimRtl):
     FD_ZERO(fd)
     for i in items(s):
       m = max(m, int(i.outHandle))
-      fdSet(cint(i.outHandle), fd)
+      FD_SET(cint(i.outHandle), fd)
 
   proc pruneProcessSet(s: var seq[Process], fd: var TFdSet) =
     var i = 0

From 679aefd89c6b0ba74270c5651f26d362935d31da Mon Sep 17 00:00:00 2001
From: Erwan Ameil 
Date: Sun, 12 Oct 2014 23:30:32 +0200
Subject: [PATCH 185/409] Prettify compiler output for verbosity=1 Long lines
 displaying the invocation of the c compiler are replaced with short, readable
 lines.

---
 compiler/extccomp.nim | 36 ++++++++++++++++++++++++------------
 lib/pure/osproc.nim   | 22 +++++++++++++++++++---
 2 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 7d9744bc5..b5519216e 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -412,8 +412,12 @@ proc addFileToLink*(filename: string) =
   prependStr(toLink, filename)
   # BUGFIX: was ``appendStr``
 
-proc execExternalProgram*(cmd: string) = 
-  if optListCmd in gGlobalOptions or gVerbosity > 0: msgWriteln(cmd)
+proc execExternalProgram*(cmd: string, prettyCmd = "") =
+  if optListCmd in gGlobalOptions or gVerbosity > 0:
+    if prettyCmd != "":
+      msgWriteln(prettyCmd)
+    else:
+      msgWriteln(cmd)
   if execCmd(cmd) != 0: rawMessage(errExecutionOfProgramFailed, "")
 
 proc generateScript(projectFile: string, script: PRope) = 
@@ -566,14 +570,16 @@ proc addExternalFileToCompile*(filename: string) =
   if optForceFullMake in gGlobalOptions or externalFileChanged(filename):
     appendStr(externalToCompile, filename)
 
-proc compileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq, 
-                  isExternal: bool) = 
+proc compileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq,
+                  prettyCmds: var TStringSeq, isExternal: bool) =
   var it = PStrEntry(list.head)
   while it != nil: 
     inc(fileCounter)          # call the C compiler for the .c file:
     var compileCmd = getCompileCFileCmd(it.data, isExternal)
     if optCompileOnly notin gGlobalOptions: 
       add(cmds, compileCmd)
+      let (dir, name, ext) = splitFile(it.data)
+      add(prettyCmds, "CC: " & name)
     if optGenScript in gGlobalOptions: 
       app(script, compileCmd)
       app(script, tnl)
@@ -589,19 +595,22 @@ proc callCCompiler*(projectfile: string) =
   var c = cCompiler
   var script: PRope = nil
   var cmds: TStringSeq = @[]
-  compileCFile(toCompile, script, cmds, false)
-  compileCFile(externalToCompile, script, cmds, true)
+  var prettyCmds: TStringSeq = @[]
+  compileCFile(toCompile, script, cmds, prettyCmds, false)
+  compileCFile(externalToCompile, script, cmds, prettyCmds, true)
+  if gVerbosity != 1:
+      prettyCmds = @[]
   if optCompileOnly notin gGlobalOptions: 
     if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors()
     var res = 0
     if gNumberOfProcessors <= 1: 
       for i in countup(0, high(cmds)): res = max(execCmd(cmds[i]), res)
     elif optListCmd in gGlobalOptions or gVerbosity > 0: 
-      res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams}, 
-                          gNumberOfProcessors)
+      res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
+                          gNumberOfProcessors, prettyCmds)
     else: 
-      res = execProcesses(cmds, {poUseShell, poParentStreams}, 
-                          gNumberOfProcessors)
+      res = execProcesses(cmds, {poUseShell, poParentStreams},
+                          gNumberOfProcessors, prettyCmds)
     if res != 0:
       if gNumberOfProcessors <= 1:
         rawMessage(errExecutionOfProgramFailed, [])
@@ -622,7 +631,6 @@ proc callCCompiler*(projectfile: string) =
     if optGenStaticLib in gGlobalOptions:
       linkCmd = CC[c].buildLib % ["libfile", (libNameTmpl() % gProjectName),
                                   "objfiles", objfiles]
-      if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
     else:
       var linkerExe = getConfigVar(c, ".linkerexe")
       if len(linkerExe) == 0: linkerExe = c.getLinkerExe
@@ -654,7 +662,11 @@ proc callCCompiler*(projectfile: string) =
           "objfiles", objfiles, "exefile", exefile,
           "nimrod", quoteShell(getPrefixDir()),
           "lib", quoteShell(libpath)])
-      if optCompileOnly notin gGlobalOptions: execExternalProgram(linkCmd)
+    if optCompileOnly notin gGlobalOptions:
+      if gVerbosity == 1:
+        execExternalProgram(linkCmd, "[Linking]")
+      else:
+        execExternalProgram(linkCmd)
   else:
     linkCmd = ""
   if optGenScript in gGlobalOptions:
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index f47df73ca..56b758ad8 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -235,22 +235,32 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} =
 
 proc execProcesses*(cmds: openArray[string],
                     options = {poStdErrToStdOut, poParentStreams},
-                    n = countProcessors()): int {.rtl, extern: "nosp$1",
+                    n = countProcessors(),
+                    prettyCmds: openArray[string] = @[]): int
+                    {.rtl, extern: "nosp$1",
                     tags: [ExecIOEffect, TimeEffect, ReadEnvEffect]} =
   ## executes the commands `cmds` in parallel. Creates `n` processes
   ## that execute in parallel. The highest return value of all processes
-  ## is returned.
+  ## is returned. If `prettyCmds` are provided, prints them on the console
+  ## instead of the real commands (for prettier output).
+  var options = options
   when defined(posix):
     # poParentStreams causes problems on Posix, so we simply disable it:
-    var options = options - {poParentStreams}
+    options = options - {poParentStreams}
 
   assert n > 0
+  var usePrettyPrintouts = false
+  if prettyCmds.len == cmds.len:
+    options = options - {poEchoCmd}
+    usePrettyPrintouts = true
   if n > 1:
     var q: seq[Process]
     newSeq(q, n)
     var m = min(n, cmds.len)
     for i in 0..m-1:
       q[i] = startCmd(cmds[i], options=options)
+      if usePrettyPrintouts:
+        echo prettyCmds[i]
     when defined(noBusyWaiting):
       var r = 0
       for i in m..high(cmds):
@@ -264,6 +274,8 @@ proc execProcesses*(cmds: openArray[string],
         result = max(waitForExit(q[r]), result)
         if q[r] != nil: close(q[r])
         q[r] = startCmd(cmds[i], options=options)
+        if usePrettyPrintouts:
+          echo prettyCmds[i]
         r = (r + 1) mod n
     else:
       var i = m
@@ -275,6 +287,8 @@ proc execProcesses*(cmds: openArray[string],
             result = max(waitForExit(q[r]), result)
             if q[r] != nil: close(q[r])
             q[r] = startCmd(cmds[i], options=options)
+            if usePrettyPrintouts:
+              echo prettyCmds[i]
             inc(i)
             if i > high(cmds): break
     for j in 0..m-1:
@@ -283,6 +297,8 @@ proc execProcesses*(cmds: openArray[string],
   else:
     for i in 0..high(cmds):
       var p = startCmd(cmds[i], options=options)
+      if usePrettyPrintouts:
+        echo prettyCmds[i]
       result = max(waitForExit(p), result)
       close(p)
 

From 06c32aab29b0e33653aa9c144bfe4994e706a84e Mon Sep 17 00:00:00 2001
From: Erwan Ameil 
Date: Mon, 13 Oct 2014 01:54:44 +0200
Subject: [PATCH 186/409] Tidy up the prettification of the default verbosity c
 compilation output

---
 compiler/extccomp.nim | 15 +++++++++------
 lib/pure/osproc.nim   | 38 +++++++++++++++++++-------------------
 2 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index b5519216e..f19b3e7ce 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -596,21 +596,24 @@ proc callCCompiler*(projectfile: string) =
   var script: PRope = nil
   var cmds: TStringSeq = @[]
   var prettyCmds: TStringSeq = @[]
+  let prettyCb = proc (idx: int) =
+    echo prettyCmds[idx]
   compileCFile(toCompile, script, cmds, prettyCmds, false)
   compileCFile(externalToCompile, script, cmds, prettyCmds, true)
-  if gVerbosity != 1:
-      prettyCmds = @[]
   if optCompileOnly notin gGlobalOptions: 
     if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors()
     var res = 0
     if gNumberOfProcessors <= 1: 
       for i in countup(0, high(cmds)): res = max(execCmd(cmds[i]), res)
-    elif optListCmd in gGlobalOptions or gVerbosity > 0: 
+    elif optListCmd in gGlobalOptions or gVerbosity > 1:
       res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
-                          gNumberOfProcessors, prettyCmds)
-    else: 
+                          gNumberOfProcessors)
+    elif gVerbosity == 1:
       res = execProcesses(cmds, {poUseShell, poParentStreams},
-                          gNumberOfProcessors, prettyCmds)
+                          gNumberOfProcessors, prettyCb)
+    else:
+      res = execProcesses(cmds, {poUseShell, poParentStreams},
+                          gNumberOfProcessors)
     if res != 0:
       if gNumberOfProcessors <= 1:
         rawMessage(errExecutionOfProgramFailed, [])
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 56b758ad8..35183c37c 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -236,31 +236,23 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} =
 proc execProcesses*(cmds: openArray[string],
                     options = {poStdErrToStdOut, poParentStreams},
                     n = countProcessors(),
-                    prettyCmds: openArray[string] = @[]): int
-                    {.rtl, extern: "nosp$1",
-                    tags: [ExecIOEffect, TimeEffect, ReadEnvEffect]} =
+                    beforeRunEvent: proc(idx: int){.closure.}): int
+                    {.rtl, tags: [ExecIOEffect, TimeEffect, ReadEnvEffect]} =
   ## executes the commands `cmds` in parallel. Creates `n` processes
   ## that execute in parallel. The highest return value of all processes
-  ## is returned. If `prettyCmds` are provided, prints them on the console
-  ## instead of the real commands (for prettier output).
-  var options = options
+  ## is returned. Runs `beforeRunEvent` before running each command.
   when defined(posix):
     # poParentStreams causes problems on Posix, so we simply disable it:
-    options = options - {poParentStreams}
+    var options = options - {poParentStreams}
 
   assert n > 0
-  var usePrettyPrintouts = false
-  if prettyCmds.len == cmds.len:
-    options = options - {poEchoCmd}
-    usePrettyPrintouts = true
   if n > 1:
     var q: seq[Process]
     newSeq(q, n)
     var m = min(n, cmds.len)
     for i in 0..m-1:
+      beforeRunEvent(i)
       q[i] = startCmd(cmds[i], options=options)
-      if usePrettyPrintouts:
-        echo prettyCmds[i]
     when defined(noBusyWaiting):
       var r = 0
       for i in m..high(cmds):
@@ -273,9 +265,8 @@ proc execProcesses*(cmds: openArray[string],
           echo(err)
         result = max(waitForExit(q[r]), result)
         if q[r] != nil: close(q[r])
+        beforeRunEvent(i)
         q[r] = startCmd(cmds[i], options=options)
-        if usePrettyPrintouts:
-          echo prettyCmds[i]
         r = (r + 1) mod n
     else:
       var i = m
@@ -286,9 +277,8 @@ proc execProcesses*(cmds: openArray[string],
             #echo(outputStream(q[r]).readLine())
             result = max(waitForExit(q[r]), result)
             if q[r] != nil: close(q[r])
+            beforeRunEvent(i)
             q[r] = startCmd(cmds[i], options=options)
-            if usePrettyPrintouts:
-              echo prettyCmds[i]
             inc(i)
             if i > high(cmds): break
     for j in 0..m-1:
@@ -296,12 +286,22 @@ proc execProcesses*(cmds: openArray[string],
       if q[j] != nil: close(q[j])
   else:
     for i in 0..high(cmds):
+      beforeRunEvent(i)
       var p = startCmd(cmds[i], options=options)
-      if usePrettyPrintouts:
-        echo prettyCmds[i]
       result = max(waitForExit(p), result)
       close(p)
 
+let emptyCb = proc(idx: int) {.closure.} = discard
+proc execProcesses*(cmds: openArray[string],
+                    options = {poStdErrToStdOut, poParentStreams},
+                    n = countProcessors()): int
+                    {.rtl, extern: "nosp$1",
+                    tags: [ExecIOEffect, TimeEffect, ReadEnvEffect]} =
+  ## executes the commands `cmds` in parallel. Creates `n` processes
+  ## that execute in parallel. The highest return value of all processes
+  ## is returned.
+  return execProcesses(cmds, options, n, emptyCb)
+
 proc select*(readfds: var seq[Process], timeout = 500): int
   ## `select` with a sensible Nim interface. `timeout` is in miliseconds.
   ## Specify -1 for no timeout. Returns the number of processes that are

From 753733e9e2d2a48d9272fce09c47487429c9bd87 Mon Sep 17 00:00:00 2001
From: Clay Sweetser 
Date: Tue, 14 Oct 2014 21:13:19 -0400
Subject: [PATCH 187/409] Improve the trimcc tool's batching algorithm.

---
 tools/fakedeps.nim |  18 ++++
 tools/trimcc.nim   | 207 +++++++++++++++++++++++++++------------------
 2 files changed, 145 insertions(+), 80 deletions(-)
 create mode 100644 tools/fakedeps.nim

diff --git a/tools/fakedeps.nim b/tools/fakedeps.nim
new file mode 100644
index 000000000..80623fafb
--- /dev/null
+++ b/tools/fakedeps.nim
@@ -0,0 +1,18 @@
+import strutils, os, pegs, strtabs, math, threadpool, times
+
+proc fakeCppDep(x: ptr float) {.importcpp: "fakeCppDep", header: "".}
+proc fakeTimeDep() = echo(times.getDateStr())
+proc fakedeps() =
+  var x = 0.4
+  {.emit: "#if 0\n".}
+  fakeCppDep(addr x)
+  {.emit: "#endif\n".}
+
+  # this is not true:
+  if math.sin(x) > 0.6:
+    spawn(fakeTimeDep())
+
+proc main =
+  fakedeps()
+when isMainModule:
+  main()
\ No newline at end of file
diff --git a/tools/trimcc.nim b/tools/trimcc.nim
index b6bf282b6..276ea1dbe 100644
--- a/tools/trimcc.nim
+++ b/tools/trimcc.nim
@@ -1,34 +1,17 @@
-# Trim C compiler installation to a minimum
-
-import strutils, os, pegs, strtabs, math, threadpool, times
+# Trim C compiler installation to a minimum
 
-proc fakeCppDep(x: ptr float) {.importcpp: "fakeCppDep", header: "".}
+import strutils, os, pegs, strtabs, math, threadpool, times
 
 const
   Essential = """gcc.exe g++.exe gdb.exe ld.exe as.exe c++.exe cpp.exe cc1.exe
-crtbegin.o crtend.o crt2.o dllcrt2.o
-libexpat-1.dll libwinpthread-1.dll
-
-aio.h
-dlfcn.h
-fcntl.h fenv.h fmtmsg.h fnmatch.h ftw.h
-errno.h
-glob.h gtmath.h
-if.h in.h ipc.h
-langinfo.h locale.h
-math.h mman.h
-netdb.h nl_types.h
-poll.h pthread.h pwd.h
-sched.h select.h semaphore.h signal.h
-socket.h spawn.h stat.h statvfs.h stdio.h stdlib.h string.h strings.h
-tcp.h time.h types.h
-ucontext.h uio.h utsname.h unistd.h
-wait.h
-varargs.h
-windows.h
-zlib.h
+crtbegin.o crtend.o crt2.o dllcrt2.o libgcc_s_dw2-1.dll libgcc_s_sjlj-1.dll
+libgcc_s_seh-1.dll libexpat-1.dll libwinpthread-1.dll aio.h dlfcn.h fcntl.h
+fenv.h fmtmsg.h fnmatch.h ftw.h errno.h glob.h gtmath.h if.h in.h ipc.h
+langinfo.h locale.h math.h mman.h netdb.h nl_types.h poll.h pthread.h pwd.h
+sched.h select.h semaphore.h signal.h socket.h spawn.h stat.h statvfs.h stdio.h
+stdlib.h string.h strings.h tcp.h time.h types.h ucontext.h uio.h utsname.h
+unistd.h wait.h varargs.h windows.h zlib.h
 """.split
-  BucketSize = 40
 
 proc includes(headerpath, headerfile: string, whitelist: StringTableRef) =
   whitelist[headerfile] = "processed"
@@ -40,88 +23,152 @@ proc includes(headerpath, headerfile: string, whitelist: StringTableRef) =
       if whitelist[m] != "processed":
         whitelist[m] = "found"
 
-proc processIncludes(dir: string, whitelist: StringTableRef) =
-  for kind, path in walkDir(dir):
-    case kind
+proc processIncludes(dir: string, whitelist: StringTableRef) =
+  for kind, path in walkDir(dir):
+    case kind
     of pcFile:
       let name = extractFilename(path)
       if ('.' notin name and "include" in path) or ("c++" in path):
         let n = whitelist[name]
-        if n != "processed": whitelist[name] = "found"
+        if n != "processed": whitelist[name] = "found"
       if name.endswith(".h"):
         let n = whitelist[name]
         if n == "found": includes(path, name, whitelist)
-    of pcDir: processIncludes(path, whitelist)
+    of pcDir: processIncludes(path, whitelist)
     else: discard
 
-proc gatherFiles(dir: string, whitelist: StringTableRef, result: var seq[string]) =
-  for kind, path in walkDir(dir):
-    case kind
+proc gatherFiles(dir: string, whitelist: StringTableRef, result: var seq[string]) =
+  for kind, path in walkDir(dir):
+    case kind
     of pcFile:
-      let name = extractFilename(path)
+      let name = extractFilename(path)
       if not whitelist.hasKey(name):
         result.add(path)
-    of pcDir: gatherFiles(path, whitelist, result)
-    else: discard
-
-proc newName(f: string): string =
-  let (dir, name, ext) = splitFile(f)
-  return dir / "trim_" & name & ext
+    of pcDir:
+      gatherFiles(path, whitelist, result)
+    else:
+      discard
+
+proc gatherEmptyFolders(dir: string, whitelist: StringTableRef, result: var seq[string]) =
+  var empty = true
+  for kind, path in walkDir(dir):
+    case kind
+    of pcFile:
+      empty = false
+    of pcDir:
+      let (none, name) = splitPath(path)
+      if not whitelist.hasKey(name):
+        gatherEmptyFolders(path, whitelist, result)
+      empty = false
+    else:
+      discard
+  if empty:
+    result.add(dir)
+
+proc newName(f: string): string =
+  let (dir, name, ext) = splitFile(f)
+  return dir / "trim_" & name & ext
 
 proc ccStillWorks(): bool =
   const
-    c1 = r"nim c --force_build koch"
-    c2 = r"nim c --force_build --threads:on --out:temp.exe tools/trimcc"
-  result = execShellCmd(c1) == 0 and execShellCmd(c2) == 0
-
-proc trialDeletion(files: seq[string], a, b: int) =
-  for i in a .. min(b, files.high):
-    let path = files[i]
-    moveFile(dest=newName(path), source=path)
+    c1 = r"nim c --verbosity:0 --force_build koch"
+    c2 = r"nim c --verbosity:0 --force_build --threads:on --out:tempOne.exe trimcc"
+    c3 = r"nim c --verbosity:0 --force_build --threads:on --out:tempTwo.exe fakeDeps"
+    c4 = r".\koch.exe"
+    c5 = r".\tempOne.exe"
+    c6 = r".\tempTwo.exe"
+  result = execShellCmd(c1) == 0 and execShellCmd(c2) == 0 and
+           execShellCmd(c3) == 0 and execShellCmd(c4) == 0 and
+           execShellCmd(c5) == 0 and execShellCmd(c6) == 0
+
+proc trialDeletion(files: seq[string], a, b: int, whitelist: StringTableRef): bool =
+  result = true
+  var single = (a == min(b, files.high))
+  for path in files[a .. min(b, files.high)]:
+    try:
+      moveFile(dest=newName(path), source=path)
+    except OSError:
+      return false
+
+  # Test if compilation still works, even with the moved files.
   if ccStillWorks():
-    for i in a .. min(b, files.high):
-      let path = files[i]
-      echo "Optional: ", path
-      removeFile(newName(path))
-  else:
    for i in a .. min(b, files.high):
-      let path = files[i]
-      echo "Required: ", path
-      # copy back:
-      moveFile(dest=path, source=newName(path))
+    for path in files[a .. min(b, files.high)]:
+      try:
+        removeFile(newName(path))
+        echo "Optional: ", path
+      except OSError:
+        echo "Warning, couldn't move ", path
+        moveFile(dest=path, source=newName(path))
+        return false
+  else:
+    for path in files[a .. min(b, files.high)]:
+      echo "Required: ", path
+      moveFile(dest=path, source=newName(path))
+      if single:
+        whitelist[path] = "found"
+      result = false
 
 proc main(dir: string) =
+  # Construct a whitelist of files to not remove
   var whitelist = newStringTable(modeCaseInsensitive)
   for e in Essential:
     whitelist[e] = "found"
   while true:
     let oldLen = whitelist.len
     processIncludes(dir, whitelist)
-    if oldLen == whitelist.len: break
-  var allFiles: seq[string] = @[]
-  gatherFiles(dir, whitelist, allFiles)
-  when true:
+    if oldLen == whitelist.len:
+      break
+
+  # Remove batches of files
+  var nearlyDone = false
+  while true:
+    # Gather files to test
+    var allFiles = newSeq[string]()
+    gatherFiles(dir, whitelist, allFiles)
+
+    # Determine the initial size of groups to check
+    var
+      maxBucketSize = len(allFiles)
+      bucketSize = 1
+
+    # Loop through the list of files, deleting batches
     var i = 0
     while i < allFiles.len:
-      trialDeletion(allFiles, i, i+BucketSize-1)
-      inc i, BucketSize
-  else:
-    for x in allFiles: echo x
+      var success = trialDeletion(allFiles, i, i+bucketSize-1, whitelist)
+      inc i, bucketSize
 
-proc fakeTimeDep() = echo(times.getDateStr())
+      # If we aren't on the last pass, adjust the batch size based on success
+      if not nearlyDone:
+        if success:
+          bucketSize = min(bucketSize * 2, maxBucketSize)
+        else:
+          bucketSize = max(bucketSize div 2, 1)
+      echo "Bucket size is now ", bucketSize
 
-proc fakedeps() =
-  var x = 0.4
-  {.emit: "#if 0\n".}
-  fakeCppDep(addr x)
-  {.emit: "#endif\n".}
+    # After looping through all the files, check if we need to break.
+    if nearlyDone:
+      break
+    if bucketSize == 1:
+      nearlyDone = true
+
+  while true:
+    var
+      emptyFolders = newSeq[string]()
+      changed = false
+
+    gatherEmptyFolders(dir, whitelist, emptyFolders)
+    for path in emptyFolders:
+      removeDir(path)
+      if not ccStillWorks():
+        createDir(path)
+        whitelist[path] = "found"
+      else:
+        changed = true
+    if not changed:
+      break
 
-  # this is not true:
-  if math.sin(x) > 0.6:
-    spawn(fakeTimeDep())
-
 if paramCount() == 1:
   doAssert ccStillWorks()
-  fakedeps()
-  main(paramStr(1))
-else:
-  quit "Usage: trimcc c_compiler_directory"
+  main(paramStr(1))
+else:
+  quit "Usage: trimcc c_compiler_directory", QuitSuccess

From 99b36cb71ec2b4b4468e8d1a170809445923d3c1 Mon Sep 17 00:00:00 2001
From: Clay Sweetser 
Date: Tue, 14 Oct 2014 21:16:18 -0400
Subject: [PATCH 188/409] Allow koch.nim to be run without a failure if given
 no arguments.

---
 koch.nim | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/koch.nim b/koch.nim
index 3ea3475b9..bd3c9552b 100644
--- a/koch.nim
+++ b/koch.nim
@@ -329,7 +329,7 @@ proc temp(args: string) =
 
 proc showHelp() = 
   quit(HelpText % [NimVersion & repeatChar(44-len(NimVersion)), 
-                   CompileDate, CompileTime])
+                   CompileDate, CompileTime], QuitSuccess)
 
 var op = initOptParser()
 op.next()

From 50d9db03c64f6641254c098ba359dfc11e352936 Mon Sep 17 00:00:00 2001
From: Billingsly Wetherfordshire 
Date: Mon, 20 Oct 2014 19:12:10 -0500
Subject: [PATCH 189/409] fix issue #1581

---
 compiler/vmgen.nim | 1 +
 1 file changed, 1 insertion(+)

diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index fac3cf1bf..e0e34306c 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1126,6 +1126,7 @@ proc checkCanEval(c: PCtx; n: PNode) =
   # we need to ensure that we don't evaluate 'x' here:
   # proc foo() = var x ...
   let s = n.sym
+  if {sfCompileTime, sfGlobal} <= s.flags: return
   if s.kind in {skVar, skTemp, skLet, skParam, skResult} and 
       not s.isOwnedBy(c.prc.sym) and s.owner != c.module:
     cannotEval(n)

From c95e0df29d67ae1e3c6905a7b3e9e8cc01bde791 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Tue, 21 Oct 2014 19:51:46 +0200
Subject: [PATCH 190/409] 'echo' doesn't lock

---
 lib/system.nim | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/system.nim b/lib/system.nim
index da49386ed..f8edca760 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -2125,7 +2125,8 @@ elif hostOS != "standalone":
       inc(i)
   {.pop.}
 
-proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], gcsafe.}
+proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], gcsafe,
+                                    locks: 0.}
   ## Writes and flushes the parameters to the standard output.
   ##
   ## Special built-in that takes a variable number of arguments. Each argument
@@ -2141,7 +2142,7 @@ proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], gcsafe
   ## instead.
 
 proc debugEcho*[T](x: varargs[T, `$`]) {.magic: "Echo", noSideEffect, 
-                                         tags: [], raises: [].}
+                                         tags: [], raises: [], locks: 0.}
   ## Same as `echo <#echo>`_, but as a special semantic rule, ``debugEcho``
   ## pretends to be free of side effects, so that it can be used for debugging
   ## routines marked as `noSideEffect `_.

From 9025e89fb91353a1ded538b587b2e26848122460 Mon Sep 17 00:00:00 2001
From: Nick Greenfield 
Date: Thu, 23 Oct 2014 18:01:39 -0700
Subject: [PATCH 191/409] Add nimblepath so Nim can find Nimble-installed
 packages out-of-the-box

---
 config/nim.cfg | 1 +
 1 file changed, 1 insertion(+)

diff --git a/config/nim.cfg b/config/nim.cfg
index b0a1ff81b..6ec32cb7b 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -40,6 +40,7 @@ path="$lib/pure/unidecode"
 
 @if nimbabel:
   babelpath="$home/.babel/pkgs/"
+  nimblepath="$home/.nimble/pkgs/"
 @end
 
 @if release or quick:

From 8a53732910af0afd22d1bacd3538e94c05cf3d69 Mon Sep 17 00:00:00 2001
From: Clay Sweetser 
Date: Fri, 24 Oct 2014 02:03:35 -0400
Subject: [PATCH 192/409] Fixes #1583

---
 koch.nim | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/koch.nim b/koch.nim
index a94920429..cbc22b2a3 100644
--- a/koch.nim
+++ b/koch.nim
@@ -18,6 +18,8 @@ when defined(gcc) and defined(windows):
 import
   os, strutils, parseopt, osproc, streams
 
+import "compiler/nversion.nim"
+
 when defined(withUpdate):
   import httpclient
 when defined(haveZipLib):
@@ -91,13 +93,13 @@ const
 
 proc csource(args: string) = 
   exec("$4 cc $1 -r $3 --var:version=$2 csource compiler/nim.ini $1" %
-       [args, NimVersion, compileNimInst, findNim()])
+       [args, VersionAsString, compileNimInst, findNim()])
 
 proc zip(args: string) =
   exec("$3 cc -r $2 --var:version=$1 --var:mingw=mingw32 scripts compiler/nim.ini" %
-       [NimVersion, compileNimInst, findNim()])
+       [VersionAsString, compileNimInst, findNim()])
   exec("$# --var:version=$# --var:mingw=mingw32 zip compiler/nim.ini" %
-       ["tools/niminst/niminst".exe, NimVersion])
+       ["tools/niminst/niminst".exe, VersionAsString])
   
 proc buildTool(toolname, args: string) = 
   exec("$# cc $# $#" % [findNim(), args, toolname])
@@ -111,16 +113,16 @@ proc nsis(args: string) =
   exec "nim c compiler" / "nim.nim"
   copyExe("compiler/nim".exe, "bin/nim_debug".exe)
   exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw32" &
-        " nsis compiler/nim") % NimVersion)
+        " nsis compiler/nim") % VersionAsString)
 
 proc install(args: string) = 
   exec("$# cc -r $# --var:version=$# --var:mingw=mingw32 scripts compiler/nim.ini" %
-       [findNim(), compileNimInst, NimVersion])
+       [findNim(), compileNimInst, VersionAsString])
   exec("sh ./install.sh $#" % args)
 
 proc web(args: string) =
   exec("$# cc -r tools/nimweb.nim $# web/nim --putenv:nimversion=$#" %
-       [findNim(), args, NimVersion])
+       [findNim(), args, VersionAsString])
 
 # -------------- boot ---------------------------------------------------------
 
@@ -287,7 +289,7 @@ when defined(withUpdate):
 # -------------- builds a release ---------------------------------------------
 
 proc run7z(platform: string, patterns: varargs[string]) =
-  const tmpDir = "nim-" & NimVersion
+  const tmpDir = "nim-" & VersionAsString
   createDir tmpDir
   try:
     for pattern in patterns:
@@ -331,7 +333,7 @@ proc temp(args: string) =
   if args.len > 0: exec(finalDest & " " & args)
 
 proc showHelp() = 
-  quit(HelpText % [NimVersion & repeatChar(44-len(NimVersion)), 
+  quit(HelpText % [VersionAsString & repeatChar(44-len(VersionAsString)), 
                    CompileDate, CompileTime], QuitSuccess)
 
 var op = initOptParser()

From a639824e5e3ec2a6eca97f31f55623254144ca81 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sat, 25 Oct 2014 22:01:23 +0200
Subject: [PATCH 193/409] introduced 'benign' pragma

---
 compiler/condsyms.nim   |   3 +-
 compiler/sempass2.nim   |   2 +
 lib/system.nim          | 136 ++++++++++++++++++++--------------------
 lib/system/alloc.nim    |   2 +-
 lib/system/assign.nim   |  12 ++--
 lib/system/avltree.nim  |   4 +-
 lib/system/cgprocs.nim  |   4 +-
 lib/system/channels.nim |  18 +++---
 lib/system/deepcopy.nim |   4 +-
 lib/system/excpt.nim    |  12 ++--
 lib/system/gc.nim       |  20 +++---
 lib/system/gc_ms.nim    |  16 ++---
 lib/system/hti.nim      |   4 +-
 lib/system/inclrtl.nim  |   5 ++
 14 files changed, 125 insertions(+), 117 deletions(-)

diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 8652844f3..9c07972cf 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -41,7 +41,7 @@ proc countDefinedSymbols*(): int =
   for key, val in pairs(gSymbols):
     if val == "true": inc(result)
 
-# For ease of bootstrapping, we keep there here and not in the global config
+# For ease of bootstrapping, we keep them here and not in the global config
 # file for now:
 const
   additionalSymbols = """
@@ -88,6 +88,7 @@ proc initDefines*() =
   defineSymbol("nimrequiresnimframe")
   defineSymbol("nimparsebiggestfloatmagic")
   defineSymbol("nimalias")
+  defineSymbol("nimlocks")
   
   # add platform specific symbols:
   for c in low(CPU)..high(CPU):
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index f9c577977..cbabc755b 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -458,6 +458,8 @@ proc assumeTheWorst(tracked: PEffects; n: PNode; op: PType) =
   addTag(tracked, createTag(n))
   let lockLevel = if op.lockLevel == UnspecifiedLockLevel: UnknownLockLevel
                   else: op.lockLevel
+  #if lockLevel == UnknownLockLevel:
+  #  message(n.info, warnUser, "had to assume the worst here")
   mergeLockLevels(tracked, n, lockLevel)
 
 proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
diff --git a/lib/system.nim b/lib/system.nim
index da49386ed..795203e4e 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1318,20 +1318,20 @@ proc substr*(s: string, first, last: int): string {.
   ## or `limit`:idx: a string's length.
 
 when not defined(nimrodVM):
-  proc zeroMem*(p: pointer, size: int) {.importc, noDecl, gcsafe.}
+  proc zeroMem*(p: pointer, size: int) {.importc, noDecl, benign.}
     ## overwrites the contents of the memory at ``p`` with the value 0.
     ## Exactly ``size`` bytes will be overwritten. Like any procedure
     ## dealing with raw memory this is *unsafe*.
 
   proc copyMem*(dest, source: pointer, size: int) {.
-    importc: "memcpy", header: "", gcsafe.}
+    importc: "memcpy", header: "", benign.}
     ## copies the contents from the memory at ``source`` to the memory
     ## at ``dest``. Exactly ``size`` bytes will be copied. The memory
     ## regions may not overlap. Like any procedure dealing with raw
     ## memory this is *unsafe*.
 
   proc moveMem*(dest, source: pointer, size: int) {.
-    importc: "memmove", header: "", gcsafe.}
+    importc: "memmove", header: "", benign.}
     ## copies the contents from the memory at ``source`` to the memory
     ## at ``dest``. Exactly ``size`` bytes will be copied. The memory
     ## regions may overlap, ``moveMem`` handles this case appropriately
@@ -1346,14 +1346,14 @@ when not defined(nimrodVM):
     ## *unsafe*.
 
   when hostOS != "standalone":
-    proc alloc*(size: int): pointer {.noconv, rtl, tags: [], gcsafe.}
+    proc alloc*(size: int): pointer {.noconv, rtl, tags: [], benign.}
       ## allocates a new memory block with at least ``size`` bytes. The
       ## block has to be freed with ``realloc(block, 0)`` or
       ## ``dealloc(block)``. The block is not initialized, so reading
       ## from it before writing to it is undefined behaviour!
       ## The allocated memory belongs to its allocating thread!
       ## Use `allocShared` to allocate from a shared heap.
-    proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline, gcsafe.} =
+    proc createU*(T: typedesc, size = 1.Positive): ptr T {.inline, benign.} =
       ## allocates a new memory block with at least ``T.sizeof * size``
       ## bytes. The block has to be freed with ``resize(block, 0)`` or
       ## ``free(block)``. The block is not initialized, so reading
@@ -1361,14 +1361,14 @@ when not defined(nimrodVM):
       ## The allocated memory belongs to its allocating thread!
       ## Use `createSharedU` to allocate from a shared heap.
       cast[ptr T](alloc(T.sizeof * size))
-    proc alloc0*(size: int): pointer {.noconv, rtl, tags: [], gcsafe.}
+    proc alloc0*(size: int): pointer {.noconv, rtl, tags: [], benign.}
       ## allocates a new memory block with at least ``size`` bytes. The
       ## block has to be freed with ``realloc(block, 0)`` or
       ## ``dealloc(block)``. The block is initialized with all bytes
       ## containing zero, so it is somewhat safer than ``alloc``.
       ## The allocated memory belongs to its allocating thread!
       ## Use `allocShared0` to allocate from a shared heap.
-    proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, gcsafe.} =
+    proc create*(T: typedesc, size = 1.Positive): ptr T {.inline, benign.} =
       ## allocates a new memory block with at least ``T.sizeof * size``
       ## bytes. The block has to be freed with ``resize(block, 0)`` or
       ## ``free(block)``. The block is initialized with all bytes
@@ -1377,7 +1377,7 @@ when not defined(nimrodVM):
       ## Use `createShared` to allocate from a shared heap.
       cast[ptr T](alloc0(T.sizeof * size))
     proc realloc*(p: pointer, newSize: int): pointer {.noconv, rtl, tags: [], 
-                                                       gcsafe.}
+                                                       benign.}
       ## grows or shrinks a given memory block. If p is **nil** then a new
       ## memory block is returned. In either way the block has at least
       ## ``newSize`` bytes. If ``newSize == 0`` and p is not **nil**
@@ -1385,7 +1385,7 @@ when not defined(nimrodVM):
       ## be freed with ``dealloc``.
       ## The allocated memory belongs to its allocating thread!
       ## Use `reallocShared` to reallocate from a shared heap.
-    proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline, gcsafe.} =
+    proc resize*[T](p: ptr T, newSize: Natural): ptr T {.inline, benign.} =
       ## grows or shrinks a given memory block. If p is **nil** then a new
       ## memory block is returned. In either way the block has at least
       ## ``T.sizeof * newSize`` bytes. If ``newSize == 0`` and p is not
@@ -1394,7 +1394,7 @@ when not defined(nimrodVM):
       ## its allocating thread!
       ## Use `resizeShared` to reallocate from a shared heap.
       cast[ptr T](realloc(p, T.sizeof * newSize))
-    proc dealloc*(p: pointer) {.noconv, rtl, tags: [], gcsafe.}
+    proc dealloc*(p: pointer) {.noconv, rtl, tags: [], benign.}
       ## frees the memory allocated with ``alloc``, ``alloc0`` or
       ## ``realloc``. This procedure is dangerous! If one forgets to
       ## free the memory a leak occurs; if one tries to access freed
@@ -1402,23 +1402,23 @@ when not defined(nimrodVM):
       ## or other memory may be corrupted. 
       ## The freed memory must belong to its allocating thread!
       ## Use `deallocShared` to deallocate from a shared heap.
-    proc free*[T](p: ptr T) {.inline, gcsafe.} =
+    proc free*[T](p: ptr T) {.inline, benign.} =
       dealloc(p)
-    proc allocShared*(size: int): pointer {.noconv, rtl, gcsafe.}
+    proc allocShared*(size: int): pointer {.noconv, rtl, benign.}
       ## allocates a new memory block on the shared heap with at
       ## least ``size`` bytes. The block has to be freed with
       ## ``reallocShared(block, 0)`` or ``deallocShared(block)``. The block
       ## is not initialized, so reading from it before writing to it is 
       ## undefined behaviour!
     proc createSharedU*(T: typedesc, size = 1.Positive): ptr T {.inline, 
-                                                                 gcsafe.} =
+                                                                 benign.} =
       ## allocates a new memory block on the shared heap with at
       ## least ``T.sizeof * size`` bytes. The block has to be freed with
       ## ``resizeShared(block, 0)`` or ``freeShared(block)``. The block
       ## is not initialized, so reading from it before writing to it is 
       ## undefined behaviour!
       cast[ptr T](allocShared(T.sizeof * size))
-    proc allocShared0*(size: int): pointer {.noconv, rtl, gcsafe.}
+    proc allocShared0*(size: int): pointer {.noconv, rtl, benign.}
       ## allocates a new memory block on the shared heap with at 
       ## least ``size`` bytes. The block has to be freed with
       ## ``reallocShared(block, 0)`` or ``deallocShared(block)``.
@@ -1432,7 +1432,7 @@ when not defined(nimrodVM):
       ## containing zero, so it is somewhat safer than ``createSharedU``.
       cast[ptr T](allocShared0(T.sizeof * size))
     proc reallocShared*(p: pointer, newSize: int): pointer {.noconv, rtl, 
-                                                             gcsafe.}
+                                                             benign.}
       ## grows or shrinks a given memory block on the heap. If p is **nil**
       ## then a new memory block is returned. In either way the block has at
       ## least ``newSize`` bytes. If ``newSize == 0`` and p is not **nil**
@@ -1445,13 +1445,13 @@ when not defined(nimrodVM):
       ## not **nil** ``resizeShared`` calls ``freeShared(p)``. In other
       ## cases the block has to be freed with ``freeShared``.
       cast[ptr T](reallocShared(p, T.sizeof * newSize))
-    proc deallocShared*(p: pointer) {.noconv, rtl, gcsafe.}
+    proc deallocShared*(p: pointer) {.noconv, rtl, benign.}
       ## frees the memory allocated with ``allocShared``, ``allocShared0`` or
       ## ``reallocShared``. This procedure is dangerous! If one forgets to
       ## free the memory a leak occurs; if one tries to access freed
       ## memory (or just freeing it twice!) a core dump may happen
       ## or other memory may be corrupted.
-    proc freeShared*[T](p: ptr T) {.inline, gcsafe.} =
+    proc freeShared*[T](p: ptr T) {.inline, benign.} =
       ## frees the memory allocated with ``createShared``, ``createSharedU`` or
       ## ``resizeShared``. This procedure is dangerous! If one forgets to
       ## free the memory a leak occurs; if one tries to access freed
@@ -1993,15 +1993,15 @@ when false:
 # ----------------- GC interface ---------------------------------------------
 
 when not defined(nimrodVM) and hostOS != "standalone":
-  proc GC_disable*() {.rtl, inl.}
+  proc GC_disable*() {.rtl, inl, benign.}
     ## disables the GC. If called n-times, n calls to `GC_enable` are needed to
     ## reactivate the GC. Note that in most circumstances one should only disable
     ## the mark and sweep phase with `GC_disableMarkAndSweep`.
 
-  proc GC_enable*() {.rtl, inl.}
+  proc GC_enable*() {.rtl, inl, benign.}
     ## enables the GC again.
 
-  proc GC_fullCollect*() {.rtl.}
+  proc GC_fullCollect*() {.rtl, benign.}
     ## forces a full garbage collection pass.
     ## Ordinary code does not need to call this (and should not).
 
@@ -2014,32 +2014,32 @@ when not defined(nimrodVM) and hostOS != "standalone":
 
   {.deprecated: [TGC_Strategy: GC_Strategy].}
 
-  proc GC_setStrategy*(strategy: GC_Strategy) {.rtl, deprecated.}
+  proc GC_setStrategy*(strategy: GC_Strategy) {.rtl, deprecated, benign.}
     ## tells the GC the desired strategy for the application.
     ## **Deprecated** since version 0.8.14. This has always been a nop.
 
-  proc GC_enableMarkAndSweep*() {.rtl.}
-  proc GC_disableMarkAndSweep*() {.rtl.}
+  proc GC_enableMarkAndSweep*() {.rtl, benign.}
+  proc GC_disableMarkAndSweep*() {.rtl, benign.}
     ## the current implementation uses a reference counting garbage collector
     ## with a seldomly run mark and sweep phase to free cycles. The mark and
     ## sweep phase may take a long time and is not needed if the application
     ## does not create cycles. Thus the mark and sweep phase can be deactivated
     ## and activated separately from the rest of the GC.
 
-  proc GC_getStatistics*(): string {.rtl.}
+  proc GC_getStatistics*(): string {.rtl, benign.}
     ## returns an informative string about the GC's activity. This may be useful
     ## for tweaking.
     
-  proc GC_ref*[T](x: ref T) {.magic: "GCref", gcsafe.}
-  proc GC_ref*[T](x: seq[T]) {.magic: "GCref", gcsafe.}
-  proc GC_ref*(x: string) {.magic: "GCref", gcsafe.}
+  proc GC_ref*[T](x: ref T) {.magic: "GCref", benign.}
+  proc GC_ref*[T](x: seq[T]) {.magic: "GCref", benign.}
+  proc GC_ref*(x: string) {.magic: "GCref", benign.}
     ## marks the object `x` as referenced, so that it will not be freed until
     ## it is unmarked via `GC_unref`. If called n-times for the same object `x`,
     ## n calls to `GC_unref` are needed to unmark `x`. 
     
-  proc GC_unref*[T](x: ref T) {.magic: "GCunref", gcsafe.}
-  proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", gcsafe.}
-  proc GC_unref*(x: string) {.magic: "GCunref", gcsafe.}
+  proc GC_unref*[T](x: ref T) {.magic: "GCunref", benign.}
+  proc GC_unref*[T](x: seq[T]) {.magic: "GCunref", benign.}
+  proc GC_unref*(x: string) {.magic: "GCunref", benign.}
     ## see the documentation of `GC_ref`.
 
 template accumulateResult*(iter: expr) =
@@ -2057,7 +2057,7 @@ const NimStackTrace = compileOption("stacktrace")
 # of the code
 
 var
-  globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, gcsafe.}
+  globalRaiseHook*: proc (e: ref Exception): bool {.nimcall, benign.}
     ## with this hook you can influence exception handling on a global level.
     ## If not nil, every 'raise' statement ends up calling this hook. Ordinary
     ## application code should never set this hook! You better know what you
@@ -2065,7 +2065,7 @@ var
     ## exception is caught and does not propagate further through the call
     ## stack.
 
-  localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, gcsafe.}
+  localRaiseHook* {.threadvar.}: proc (e: ref Exception): bool {.nimcall, benign.}
     ## with this hook you can influence exception handling on a
     ## thread local level.
     ## If not nil, every 'raise' statement ends up calling this hook. Ordinary
@@ -2073,7 +2073,7 @@ var
     ## do when setting this. If ``localRaiseHook`` returns false, the exception
     ## is caught and does not propagate further through the call stack.
     
-  outOfMemHook*: proc () {.nimcall, tags: [], gcsafe.}
+  outOfMemHook*: proc () {.nimcall, tags: [], benign.}
     ## set this variable to provide a procedure that should be called 
     ## in case of an `out of memory`:idx: event. The standard handler
     ## writes an error message and terminates the program. `outOfMemHook` can
@@ -2125,7 +2125,7 @@ elif hostOS != "standalone":
       inc(i)
   {.pop.}
 
-proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], gcsafe.}
+proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.}
   ## Writes and flushes the parameters to the standard output.
   ##
   ## Special built-in that takes a variable number of arguments. Each argument
@@ -2178,7 +2178,7 @@ when not declared(sysFatal):
       e.msg = message & arg
       raise e
 
-proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", gcsafe.}
+proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo", benign.}
   ## get type information for `x`. Ordinary code should not use this, but
   ## the `typeinfo` module instead.
 
@@ -2294,14 +2294,14 @@ when not defined(JS): #and not defined(NimrodVM):
 
     proc open*(f: var File, filename: string,
                mode: FileMode = fmRead, bufSize: int = -1): bool {.tags: [],
-               gcsafe.}
+               benign.}
       ## Opens a file named `filename` with given `mode`.
       ##
       ## Default mode is readonly. Returns true iff the file could be opened.
       ## This throws no exception if the file could not be opened.
 
     proc open*(f: var File, filehandle: FileHandle,
-               mode: FileMode = fmRead): bool {.tags: [], gcsafe.}
+               mode: FileMode = fmRead): bool {.tags: [], benign.}
       ## Creates a ``TFile`` from a `filehandle` with given `mode`.
       ##
       ## Default mode is readonly. Returns true iff the file could be opened.
@@ -2316,7 +2316,7 @@ when not defined(JS): #and not defined(NimrodVM):
         sysFatal(IOError, "cannot open: ", filename)
 
     proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {.
-      tags: [], gcsafe.}
+      tags: [], benign.}
       ## reopens the file `f` with given `filename` and `mode`. This 
       ## is often used to redirect the `stdin`, `stdout` or `stderr`
       ## file variables.
@@ -2326,7 +2326,7 @@ when not defined(JS): #and not defined(NimrodVM):
     proc close*(f: File) {.importc: "fclose", header: "", tags: [].}
       ## Closes the file.
 
-    proc endOfFile*(f: File): bool {.tags: [], gcsafe.}
+    proc endOfFile*(f: File): bool {.tags: [], benign.}
       ## Returns true iff `f` is at the end.
       
     proc readChar*(f: File): char {.
@@ -2336,40 +2336,40 @@ when not defined(JS): #and not defined(NimrodVM):
       importc: "fflush", header: "", tags: [WriteIOEffect].}
       ## Flushes `f`'s buffer.
 
-    proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], gcsafe.}
+    proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], benign.}
       ## Reads all data from the stream `file`.
       ##
       ## Raises an IO exception in case of an error. It is an error if the
       ## current file position is not at the beginning of the file.
     
-    proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], gcsafe.}
+    proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], benign.}
       ## Opens a file named `filename` for reading. Then calls `readAll`
       ## and closes the file afterwards. Returns the string. 
       ## Raises an IO exception in case of an error.
 
-    proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], gcsafe.}
+    proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], benign.}
       ## Opens a file named `filename` for writing. Then writes the
       ## `content` completely to the file and closes the file afterwards.
       ## Raises an IO exception in case of an error.
 
-    proc write*(f: File, r: float32) {.tags: [WriteIOEffect], gcsafe.}
-    proc write*(f: File, i: int) {.tags: [WriteIOEffect], gcsafe.}
-    proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], gcsafe.}
-    proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], gcsafe.}
-    proc write*(f: File, s: string) {.tags: [WriteIOEffect], gcsafe.}
-    proc write*(f: File, b: bool) {.tags: [WriteIOEffect], gcsafe.}
-    proc write*(f: File, c: char) {.tags: [WriteIOEffect], gcsafe.}
-    proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], gcsafe.}
-    proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], gcsafe.}
+    proc write*(f: File, r: float32) {.tags: [WriteIOEffect], benign.}
+    proc write*(f: File, i: int) {.tags: [WriteIOEffect], benign.}
+    proc write*(f: File, i: BiggestInt) {.tags: [WriteIOEffect], benign.}
+    proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], benign.}
+    proc write*(f: File, s: string) {.tags: [WriteIOEffect], benign.}
+    proc write*(f: File, b: bool) {.tags: [WriteIOEffect], benign.}
+    proc write*(f: File, c: char) {.tags: [WriteIOEffect], benign.}
+    proc write*(f: File, c: cstring) {.tags: [WriteIOEffect], benign.}
+    proc write*(f: File, a: varargs[string, `$`]) {.tags: [WriteIOEffect], benign.}
       ## Writes a value to the file `f`. May throw an IO exception.
 
-    proc readLine*(f: File): TaintedString  {.tags: [ReadIOEffect], gcsafe.}
+    proc readLine*(f: File): TaintedString  {.tags: [ReadIOEffect], benign.}
       ## reads a line of text from the file `f`. May throw an IO exception.
       ## A line of text may be delimited by ``CR``, ``LF`` or
       ## ``CRLF``. The newline character(s) are not part of the returned string.
     
     proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect], 
-                  gcsafe.}
+                  benign.}
       ## reads a line of text from the file `f` into `line`. `line` must not be
       ## ``nil``! May throw an IO exception.
       ## A line of text may be delimited by ``CR``, ``LF`` or
@@ -2379,57 +2379,57 @@ when not defined(JS): #and not defined(NimrodVM):
 
     when not defined(booting):
       proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, 
-                               tags: [WriteIOEffect], gcsafe.}
+                               tags: [WriteIOEffect], benign.}
         ## writes the values `x` to `f` and then writes "\n".
         ## May throw an IO exception.
     else:
       proc writeln*[Ty](f: File, x: varargs[Ty, `$`]) {.inline, 
                                tags: [WriteIOEffect].}
 
-    proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], gcsafe.}
+    proc getFileSize*(f: File): int64 {.tags: [ReadIOEffect], benign.}
       ## retrieves the file size (in bytes) of `f`.
 
     proc readBytes*(f: File, a: var openArray[int8], start, len: int): int {.
-      tags: [ReadIOEffect], gcsafe.}
+      tags: [ReadIOEffect], benign.}
       ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
       ## the actual number of bytes that have been read which may be less than
       ## `len` (if not as many bytes are remaining), but not greater.
 
     proc readChars*(f: File, a: var openArray[char], start, len: int): int {.
-      tags: [ReadIOEffect], gcsafe.}
+      tags: [ReadIOEffect], benign.}
       ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
       ## the actual number of bytes that have been read which may be less than
       ## `len` (if not as many bytes are remaining), but not greater.
 
     proc readBuffer*(f: File, buffer: pointer, len: int): int {.
-      tags: [ReadIOEffect], gcsafe.}
+      tags: [ReadIOEffect], benign.}
       ## reads `len` bytes into the buffer pointed to by `buffer`. Returns
       ## the actual number of bytes that have been read which may be less than
       ## `len` (if not as many bytes are remaining), but not greater.
 
     proc writeBytes*(f: File, a: openArray[int8], start, len: int): int {.
-      tags: [WriteIOEffect], gcsafe.}
+      tags: [WriteIOEffect], benign.}
       ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
       ## the number of actual written bytes, which may be less than `len` in case
       ## of an error.
 
     proc writeChars*(f: File, a: openArray[char], start, len: int): int {.
-      tags: [WriteIOEffect], gcsafe.}
+      tags: [WriteIOEffect], benign.}
       ## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
       ## the number of actual written bytes, which may be less than `len` in case
       ## of an error.
 
     proc writeBuffer*(f: File, buffer: pointer, len: int): int {.
-      tags: [WriteIOEffect], gcsafe.}
+      tags: [WriteIOEffect], benign.}
       ## writes the bytes of buffer pointed to by the parameter `buffer` to the
       ## file `f`. Returns the number of actual written bytes, which may be less
       ## than `len` in case of an error.
 
-    proc setFilePos*(f: File, pos: int64) {.gcsafe.}
+    proc setFilePos*(f: File, pos: int64) {.benign.}
       ## sets the position of the file pointer that is used for read/write
       ## operations. The file's first byte has the index zero.
 
-    proc getFilePos*(f: File): int64 {.gcsafe.}
+    proc getFilePos*(f: File): int64 {.benign.}
       ## retrieves the current position of the file pointer that is used to
       ## read from the file `f`. The file's first byte has the index zero.
 
@@ -2476,11 +2476,11 @@ when not defined(JS): #and not defined(NimrodVM):
 
   when not defined(NimrodVM):
     proc atomicInc*(memLoc: var int, x: int = 1): int {.inline, 
-      discardable, gcsafe.}
+      discardable, benign.}
       ## atomic increment of `memLoc`. Returns the value after the operation.
     
     proc atomicDec*(memLoc: var int, x: int = 1): int {.inline, 
-      discardable, gcsafe.}
+      discardable, benign.}
       ## atomic decrement of `memLoc`. Returns the value after the operation.
 
     include "system/atomics"
@@ -2611,11 +2611,11 @@ when not defined(JS): #and not defined(NimrodVM):
     include "system/assign"
     include "system/repr"
 
-    proc getCurrentException*(): ref Exception {.compilerRtl, inl, gcsafe.} =
+    proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} =
       ## retrieves the current exception; if there is none, nil is returned.
       result = currException
 
-    proc getCurrentExceptionMsg*(): string {.inline, gcsafe.} =
+    proc getCurrentExceptionMsg*(): string {.inline, benign.} =
       ## retrieves the error message that was attached to the current
       ## exception; if there is none, "" is returned.
       var e = getCurrentException()
@@ -2631,7 +2631,7 @@ when not defined(JS): #and not defined(NimrodVM):
         excHandler.hasRaiseAction = true
         excHandler.raiseAction = action
 
-    proc setCurrentException*(exc: ref Exception) {.inline, gcsafe.} =
+    proc setCurrentException*(exc: ref Exception) {.inline, benign.} =
       ## sets the current exception.
       ##
       ## **Warning**: Only use this if you know what you are doing.
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 9f227f0c5..fd3ced832 100644
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -514,7 +514,7 @@ proc getSmallChunk(a: var TMemRegion): PSmallChunk =
   result = cast[PSmallChunk](res)
 
 # -----------------------------------------------------------------------------
-proc isAllocatedPtr(a: TMemRegion, p: pointer): bool
+proc isAllocatedPtr(a: TMemRegion, p: pointer): bool {.benign.}
 
 proc allocInv(a: TMemRegion): bool =
   ## checks some (not all yet) invariants of the allocator's data structures.
diff --git a/lib/system/assign.nim b/lib/system/assign.nim
index 6c58c24c2..8d53e127c 100644
--- a/lib/system/assign.nim
+++ b/lib/system/assign.nim
@@ -7,11 +7,11 @@
 #    distribution, for details about the copyright.
 #
 
-proc genericResetAux(dest: pointer, n: ptr TNimNode) {.gcsafe.}
+proc genericResetAux(dest: pointer, n: ptr TNimNode) {.benign.}
 
-proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.gcsafe.}
+proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) {.benign.}
 proc genericAssignAux(dest, src: pointer, n: ptr TNimNode,
-                      shallow: bool) {.gcsafe.} =
+                      shallow: bool) {.benign.} =
   var
     d = cast[ByteAddress](dest)
     s = cast[ByteAddress](src)
@@ -136,8 +136,8 @@ proc genericAssignOpenArray(dest, src: pointer, len: int,
     genericAssign(cast[pointer](d +% i*% mt.base.size),
                   cast[pointer](s +% i*% mt.base.size), mt.base)
 
-proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, gcsafe.}
-proc objectInitAux(dest: pointer, n: ptr TNimNode) {.gcsafe.} =
+proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, benign.}
+proc objectInitAux(dest: pointer, n: ptr TNimNode) {.benign.} =
   var d = cast[ByteAddress](dest)
   case n.kind
   of nkNone: sysAssert(false, "objectInitAux")
@@ -182,7 +182,7 @@ else:
     mixin destroy
     for i in countup(0, r.len - 1): destroy(r[i])
 
-proc genericReset(dest: pointer, mt: PNimType) {.compilerProc, gcsafe.}
+proc genericReset(dest: pointer, mt: PNimType) {.compilerProc, benign.}
 proc genericResetAux(dest: pointer, n: ptr TNimNode) =
   var d = cast[ByteAddress](dest)
   case n.kind
diff --git a/lib/system/avltree.nim b/lib/system/avltree.nim
index 157799b28..292097062 100644
--- a/lib/system/avltree.nim
+++ b/lib/system/avltree.nim
@@ -51,7 +51,7 @@ proc split(t: var PAvlNode) =
     t.link[0] = temp
     inc t.level
 
-proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.gcsafe.} =
+proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.benign.} =
   if t == bottom:
     t = allocAvlNode(a, key, upperBound)
   else:
@@ -64,7 +64,7 @@ proc add(a: var TMemRegion, t: var PAvlNode, key, upperBound: int) {.gcsafe.} =
     skew(t)
     split(t)
 
-proc del(a: var TMemRegion, t: var PAvlNode, x: int) {.gcsafe.} =
+proc del(a: var TMemRegion, t: var PAvlNode, x: int) {.benign.} =
   if t == bottom: return
   a.last = t
   if x <% t.key:
diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim
index d46e715f1..089846578 100644
--- a/lib/system/cgprocs.nim
+++ b/lib/system/cgprocs.nim
@@ -9,7 +9,7 @@
 
 # Headers for procs that the code generator depends on ("compilerprocs")
 
-proc addChar(s: NimString, c: char): NimString {.compilerProc, gcsafe.}
+proc addChar(s: NimString, c: char): NimString {.compilerProc, benign.}
 
 type
   TLibHandle = pointer       # private type
@@ -21,5 +21,5 @@ proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.}
 
 proc nimLoadLibraryError(path: string) {.compilerproc, noinline.}
 
-proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline, gcsafe.}
+proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline, benign.}
 
diff --git a/lib/system/channels.nim b/lib/system/channels.nim
index 4796ebb82..3e5ca0795 100644
--- a/lib/system/channels.nim
+++ b/lib/system/channels.nim
@@ -49,9 +49,9 @@ proc deinitRawChannel(p: pointer) =
   deinitSysCond(c.cond)
 
 proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, 
-              mode: TLoadStoreMode) {.gcsafe.}
+              mode: TLoadStoreMode) {.benign.}
 proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
-              mode: TLoadStoreMode) {.gcsafe.} =
+              mode: TLoadStoreMode) {.benign.} =
   var
     d = cast[ByteAddress](dest)
     s = cast[ByteAddress](src)
@@ -225,15 +225,15 @@ proc recv*[TMsg](c: var TChannel[TMsg]): TMsg =
   acquireSys(q.lock)
   llRecv(q, addr(result), cast[PNimType](getTypeInfo(result)))
   releaseSys(q.lock)
-
-proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool,
-                                                  msg: TMsg] =
-  ## try to receives a message from the channel `c` if available. Otherwise
-  ## it returns ``(false, default(msg))``.
+
+proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool,
+                                                  msg: TMsg] =
+  ## try to receives a message from the channel `c` if available. Otherwise
+  ## it returns ``(false, default(msg))``.
   var q = cast[PRawChannel](addr(c))
-  if q.mask != ChannelDeadMask:
+  if q.mask != ChannelDeadMask:
     if tryAcquireSys(q.lock):
-      llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg)))
+      llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg)))
       result.dataAvailable = true
       releaseSys(q.lock)
 
diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim
index e4356a25d..fbebb17a8 100644
--- a/lib/system/deepcopy.nim
+++ b/lib/system/deepcopy.nim
@@ -7,8 +7,8 @@
 #    distribution, for details about the copyright.
 #
 
-proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.gcsafe.}
-proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.gcsafe.} =
+proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) {.benign.}
+proc genericDeepCopyAux(dest, src: pointer, n: ptr TNimNode) {.benign.} =
   var
     d = cast[ByteAddress](dest)
     s = cast[ByteAddress](src)
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index c0e99a5e2..e21eeca6a 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -11,7 +11,7 @@
 # use the heap (and nor exceptions) do not include the GC or memory allocator.
 
 var
-  errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], gcsafe.})
+  errorMessageWriter*: (proc(msg: string) {.tags: [WriteIOEffect], benign.})
     ## Function that will be called
     ## instead of stdmsg.write when printing stacktrace.
     ## Unstable API.
@@ -32,10 +32,10 @@ proc showErrorMessage(data: cstring) =
   else:
     writeToStdErr(data)
 
-proc chckIndx(i, a, b: int): int {.inline, compilerproc, gcsafe.}
-proc chckRange(i, a, b: int): int {.inline, compilerproc, gcsafe.}
-proc chckRangeF(x, a, b: float): float {.inline, compilerproc, gcsafe.}
-proc chckNil(p: pointer) {.noinline, compilerproc, gcsafe.}
+proc chckIndx(i, a, b: int): int {.inline, compilerproc, benign.}
+proc chckRange(i, a, b: int): int {.inline, compilerproc, benign.}
+proc chckRangeF(x, a, b: float): float {.inline, compilerproc, benign.}
+proc chckNil(p: pointer) {.noinline, compilerproc, benign.}
 
 var
   framePtr {.threadvar.}: PFrame
@@ -343,5 +343,5 @@ when not defined(noSignalHandler):
 
 proc setControlCHook(hook: proc () {.noconv.}) =
   # ugly cast, but should work on all architectures:
-  type TSignalHandler = proc (sig: cint) {.noconv, gcsafe.}
+  type TSignalHandler = proc (sig: cint) {.noconv, benign.}
   c_signal(SIGINT, cast[TSignalHandler](hook))
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index c4b3a4928..fe4b40903 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -51,7 +51,7 @@ type
     waZctDecRef, waPush, waCycleDecRef, waMarkGray, waScan, waScanBlack, 
     waCollectWhite,
 
-  TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe.}
+  TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.}
     # A ref type can have a finalizer that is called before the object's
     # storage is freed.
 
@@ -152,11 +152,11 @@ template gcTrace(cell, state: expr): stmt {.immediate.} =
   when traceGC: traceCell(cell, state)
 
 # forward declarations:
-proc collectCT(gch: var TGcHeap) {.gcsafe.}
-proc isOnStack*(p: pointer): bool {.noinline, gcsafe.}
-proc forAllChildren(cell: PCell, op: TWalkOp) {.gcsafe.}
-proc doOperation(p: pointer, op: TWalkOp) {.gcsafe.}
-proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.gcsafe.}
+proc collectCT(gch: var TGcHeap) {.benign.}
+proc isOnStack*(p: pointer): bool {.noinline, benign.}
+proc forAllChildren(cell: PCell, op: TWalkOp) {.benign.}
+proc doOperation(p: pointer, op: TWalkOp) {.benign.}
+proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.benign.}
 # we need the prototype here for debugging purposes
 
 when hasThreadSupport and hasSharedHeap:
@@ -294,7 +294,7 @@ proc initGC() =
 
 when useMarkForDebug or useBackupGc:
   type
-    TGlobalMarkerProc = proc () {.nimcall, gcsafe.}
+    TGlobalMarkerProc = proc () {.nimcall, benign.}
   var
     globalMarkersLen: int
     globalMarkers: array[0.. 7_000, TGlobalMarkerProc]
@@ -311,7 +311,7 @@ proc cellsetReset(s: var TCellSet) =
   deinit(s)
   init(s)
 
-proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
+proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.benign.} =
   var d = cast[ByteAddress](dest)
   case n.kind
   of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
@@ -680,11 +680,11 @@ proc doOperation(p: pointer, op: TWalkOp) =
 proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} =
   doOperation(d, TWalkOp(op))
 
-proc collectZCT(gch: var TGcHeap): bool {.gcsafe.}
+proc collectZCT(gch: var TGcHeap): bool {.benign.}
 
 when useMarkForDebug or useBackupGc:
   proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl,
-                                                         gcsafe.}
+                                                         benign.}
 
 proc collectRoots(gch: var TGcHeap) =
   for s in elements(gch.cycleRoots):
diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim
index f90000a1c..242ca1608 100644
--- a/lib/system/gc_ms.nim
+++ b/lib/system/gc_ms.nim
@@ -32,11 +32,11 @@ type
                    # local 
     waMarkPrecise  # fast precise marking
 
-  TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, gcsafe.}
+  TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.}
     # A ref type can have a finalizer that is called before the object's
     # storage is freed.
   
-  TGlobalMarkerProc = proc () {.nimcall, gcsafe.}
+  TGlobalMarkerProc = proc () {.nimcall, benign.}
 
   TGcStat = object
     collections: int         # number of performed full collections
@@ -116,11 +116,11 @@ when BitsPerPage mod (sizeof(int)*8) != 0:
   {.error: "(BitsPerPage mod BitsPerUnit) should be zero!".}
 
 # forward declarations:
-proc collectCT(gch: var TGcHeap) {.gcsafe.}
-proc isOnStack*(p: pointer): bool {.noinline, gcsafe.}
-proc forAllChildren(cell: PCell, op: TWalkOp) {.gcsafe.}
-proc doOperation(p: pointer, op: TWalkOp) {.gcsafe.}
-proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.gcsafe.}
+proc collectCT(gch: var TGcHeap) {.benign.}
+proc isOnStack*(p: pointer): bool {.noinline, benign.}
+proc forAllChildren(cell: PCell, op: TWalkOp) {.benign.}
+proc doOperation(p: pointer, op: TWalkOp) {.benign.}
+proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) {.benign.}
 # we need the prototype here for debugging purposes
 
 proc prepareDealloc(cell: PCell) =
@@ -168,7 +168,7 @@ proc initGC() =
       Init(gch.allocated)
       init(gch.marked)
 
-proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
+proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.benign.} =
   var d = cast[ByteAddress](dest)
   case n.kind
   of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
diff --git a/lib/system/hti.nim b/lib/system/hti.nim
index 4a8ab2485..e599668a7 100644
--- a/lib/system/hti.nim
+++ b/lib/system/hti.nim
@@ -85,8 +85,8 @@ type
     base: ptr TNimType
     node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
     finalizer: pointer # the finalizer for the type
-    marker: proc (p: pointer, op: int) {.nimcall, gcsafe.} # marker proc for GC
-    deepcopy: proc (p: pointer): pointer {.nimcall, gcsafe.}
+    marker: proc (p: pointer, op: int) {.nimcall, benign.} # marker proc for GC
+    deepcopy: proc (p: pointer): pointer {.nimcall, benign.}
   PNimType = ptr TNimType
   
 # node.len may be the ``first`` element of a set
diff --git a/lib/system/inclrtl.nim b/lib/system/inclrtl.nim
index a975bb7c2..aac802229 100644
--- a/lib/system/inclrtl.nim
+++ b/lib/system/inclrtl.nim
@@ -46,3 +46,8 @@ else:
 
 when not defined(nimsuperops):
   {.pragma: operator.}
+
+when defined(nimlocks):
+  {.pragma: benign, gcsafe, locks: 0.}
+else:
+  {.pragma: benign, gcsafe.}

From fdf996925b6b23e3127ce699c976e9e07bdfe13f Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sun, 26 Oct 2014 13:36:42 +0100
Subject: [PATCH 194/409] implements #1588

---
 compiler/pragmas.nim | 3 +++
 doc/nimc.txt         | 5 ++++-
 web/news.txt         | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 4d6d311c9..52eb46bf4 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -448,6 +448,9 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
           addSon(result, newSymNode(e))
         else: 
           addSon(result, newStrNode(nkStrLit, sub))
+      else:
+        # an empty '``' produces a single '`'
+        addSon(result, newStrNode(nkStrLit, $marker))
       if c < 0: break 
       a = c + 1
   else: illFormedAst(n)
diff --git a/doc/nimc.txt b/doc/nimc.txt
index 8af045e2e..3b7390d78 100644
--- a/doc/nimc.txt
+++ b/doc/nimc.txt
@@ -382,7 +382,10 @@ Example:
   {.pop.}
 
   embedsC()
-
+
+As can be seen from the example, to Nim symbols can be referred via backticks.
+Use two backticks to produce a single verbatim backtick.
+
 
 ImportCpp pragma
 ----------------
diff --git a/web/news.txt b/web/news.txt
index 7038e8234..c9374558a 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -49,6 +49,9 @@ News
       os.getEnv, os.existsEnv, os.dirExists, os.fileExists,
       system.writeFile
 
+  - Two backticks now produce a single backtick within an ``emit`` or ``asm``
+    statement.
+    
 
 2014-10-19 Nimrod version 0.9.6 released
 ========================================

From 7a48942719f4a557abafefd6d5cbd8b25a283e3a Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sun, 26 Oct 2014 19:54:43 +0100
Subject: [PATCH 195/409] nicer error messages (untested)

---
 compiler/sem.nim        |  3 +--
 compiler/semcall.nim    | 43 ++++++++++++++++++++++++++++++-----------
 compiler/semdata.nim    |  3 +--
 compiler/semexprs.nim   |  5 ++---
 compiler/sigmatch.nim   | 20 ++++++++++---------
 compiler/types.nim      | 29 +++++++++++++++------------
 lib/core/typeinfo.nim   |  1 +
 lib/impure/zipfiles.nim |  2 +-
 lib/system.nim          | 26 +++++++++++++++----------
 9 files changed, 82 insertions(+), 50 deletions(-)

diff --git a/compiler/sem.nim b/compiler/sem.nim
index 63475a566..81846e1b4 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -40,8 +40,7 @@ proc semParamList(c: PContext, n, genericParams: PNode, s: PSym)
 proc addParams(c: PContext, n: PNode, kind: TSymKind)
 proc maybeAddResult(c: PContext, s: PSym, n: PNode)
 proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
-proc tryExpr(c: PContext, n: PNode,
-             flags: TExprFlags = {}, bufferErrors = false): PNode
+proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
 proc fixImmediateParams(n: PNode): PNode
 proc activate(c: PContext, n: PNode)
 proc semQuoteAst(c: PContext, n: PNode): PNode
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 6f92a75a6..a4490b782 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -39,7 +39,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
                        initialBinding: PNode,
                        filter: TSymKinds,
                        best, alt: var TCandidate,
-                       errors: var seq[string]) =
+                       errors: var CandidateErrors) =
   var o: TOverloadIter
   var sym = initOverloadIter(o, c, headSymbol)
   var symScope = o.lastOverloadScope
@@ -58,10 +58,10 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
       z.calleeSym = sym
       matches(c, n, orig, z)
       if errors != nil:
-        errors.safeAdd(getProcHeader(sym))
+        errors.safeAdd(sym)
         if z.errors != nil:
           for err in z.errors:
-            errors[errors.len - 1].add("\n  " & err)
+            errors.add(err)
       if z.state == csMatch:
         # little hack so that iterators are preferred over everything else:
         if sym.kind in skIterators: inc(z.exactMatches, 200)
@@ -74,7 +74,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
           else: discard
     sym = nextOverloadIter(o, c, headSymbol)
 
-proc notFoundError*(c: PContext, n: PNode, errors: seq[string]) =
+proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
   # Gives a detailed error message; this is separated from semOverloadedCall,
   # as semOverlodedCall is already pretty slow (and we need this information
   # only in case of an error).
@@ -83,18 +83,39 @@ proc notFoundError*(c: PContext, n: PNode, errors: seq[string]) =
     globalError(n.info, errTypeMismatch, "")
   if errors.len == 0:
     localError(n.info, errExprXCannotBeCalled, n[0].renderTree)
-  var result = msgKindToString(errTypeMismatch)
-  add(result, describeArgs(c, n, 1))
-  add(result, ')')
+
+  # to avoid confusing errors like: 
+  #   got (SslPtr, SocketHandle)
+  #   but expected one of: 
+  #   openssl.SSL_set_fd(ssl: SslPtr, fd: SocketHandle): cint
+  # we do a pre-analysis. If all types produce the same string, we will add
+  # module information.
+  let proto = describeArgs(c, n, 1, preferName)
   
+  var prefer = preferName
+  for err in errors:
+    var errProto = "("
+    let n = err.typ.n
+    for i in countup(1, n.len - 1): 
+      var p = n.sons[i]
+      if p.kind == nkSym:
+        add(errProto, typeToString(p.sym.typ, prefer))
+        if i != n.len-1: add(errProto, ", ")
+      # else: ignore internal error as we're already in error handling mode
+    add(errProto, ')')
+    if errProto == proto:
+      prefer = preferModuleInfo
+      break
+  # now use the information stored in 'prefer' to produce a nice error message:
+  var result = msgKindToString(errTypeMismatch)
+  add(result, describeArgs(c, n, 1, prefer))
+  add(result, ')')
   var candidates = ""
   for err in errors:
-    add(candidates, err)
+    add(candidates, err.getProcHeader(prefer))
     add(candidates, "\n")
-
   if candidates != "":
     add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates)
-
   localError(n.info, errGenerated, result)
 
 proc gatherUsedSyms(c: PContext, usedSyms: var seq[PNode]) =
@@ -114,7 +135,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
   else:
     initialBinding = nil
 
-  var errors: seq[string]
+  var errors: CandidateErrors
   var usedSyms: seq[PNode]
 
   template pickBest(headSymbol: expr) =
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index bc7b8cdc2..921e87d30 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -72,8 +72,7 @@ type
     libs*: TLinkedList         # all libs used by this module
     semConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # for the pragmas
     semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
-    semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {},
-                       bufferErrors = false): PNode {.nimcall.}
+    semTryExpr*: proc (c: PContext, n: PNode,flags: TExprFlags = {}): PNode {.nimcall.}
     semTryConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.}
     semOperand*: proc (c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.nimcall.}
     semConstBoolExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # XXX bite the bullet
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index f2d0c0b82..f156470fe 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1551,8 +1551,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
     newNode(nkCall, n.info, quotes)])
   result = semExpandToAst(c, result)
 
-proc tryExpr(c: PContext, n: PNode,
-             flags: TExprFlags = {}, bufferErrors = false): PNode =
+proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
   # watch out, hacks ahead:
   let oldErrorCount = msgs.gErrorCounter
   let oldErrorMax = msgs.gErrorMax
@@ -1566,7 +1565,7 @@ proc tryExpr(c: PContext, n: PNode,
   let oldOwnerLen = len(gOwners)
   let oldGenerics = c.generics
   let oldErrorOutputs = errorOutputs
-  errorOutputs = if bufferErrors: {eInMemory} else: {}
+  #errorOutputs = if bufferErrors: {eInMemory} else: {}
   let oldContextLen = msgs.getInfoContextLen()
   
   let oldInGenericContext = c.inGenericContext
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index b5e01811e..4a3773ed8 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -22,6 +22,7 @@ type
   TCandidateState* = enum 
     csEmpty, csMatch, csNoMatch
 
+  CandidateErrors* = seq[PSym]
   TCandidate* {.final.} = object
     c*: PContext
     exactMatches*: int       # also misused to prefer iters over procs
@@ -45,7 +46,7 @@ type
                              # a distrinct type
     typedescMatched: bool
     inheritancePenalty: int  # to prefer closest father object type
-    errors*: seq[string]     # additional clarifications to be displayed to the
+    errors*: CandidateErrors # additional clarifications to be displayed to the
                              # user if overload resolution fails
 
   TTypeRelation* = enum      # order is important!
@@ -202,16 +203,17 @@ proc writeMatches*(c: TCandidate) =
   writeln(stdout, "intconv matches: " & $c.intConvMatches)
   writeln(stdout, "generic matches: " & $c.genericMatches)
 
-proc argTypeToString(arg: PNode): string =
+proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string =
   if arg.kind in nkSymChoices:
-    result = typeToString(arg[0].typ)
+    result = typeToString(arg[0].typ, prefer)
     for i in 1 .. 
Date: Sun, 26 Oct 2014 22:48:54 +0100
Subject: [PATCH 196/409] implements #78

---
 compiler/semcall.nim  |  3 +--
 compiler/types.nim    |  4 ++--
 csources              |  1 -
 tests/clearmsg/mb.nim |  2 ++
 tests/clearmsg/mc.nim |  3 +++
 tests/clearmsg/ta.nim | 12 ++++++++++++
 6 files changed, 20 insertions(+), 5 deletions(-)
 delete mode 160000 csources
 create mode 100644 tests/clearmsg/mb.nim
 create mode 100644 tests/clearmsg/mc.nim
 create mode 100644 tests/clearmsg/ta.nim

diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index a4490b782..d3720b0ab 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -94,7 +94,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
   
   var prefer = preferName
   for err in errors:
-    var errProto = "("
+    var errProto = ""
     let n = err.typ.n
     for i in countup(1, n.len - 1): 
       var p = n.sons[i]
@@ -102,7 +102,6 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
         add(errProto, typeToString(p.sym.typ, prefer))
         if i != n.len-1: add(errProto, ", ")
       # else: ignore internal error as we're already in error handling mode
-    add(errProto, ')')
     if errProto == proto:
       prefer = preferModuleInfo
       break
diff --git a/compiler/types.nim b/compiler/types.nim
index e03762155..87f2e1a59 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -419,10 +419,10 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
        sfAnon notin t.sym.flags:
     if t.kind == tyInt and isIntLit(t):
       return t.sym.name.s & " literal(" & $t.n.intVal & ")"
-    if prefer == preferName:
+    if prefer == preferName or t.sym.owner.isNil:
       return t.sym.name.s
     else:
-      return t.sym.skipGenericOwner.name.s & '.' & t.sym.name.s
+      return t.sym.owner.name.s & '.' & t.sym.name.s
   case t.kind
   of tyInt:
     if not isIntLit(t) or prefer == preferExported:
diff --git a/csources b/csources
deleted file mode 160000
index b0bcf88e2..000000000
--- a/csources
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit b0bcf88e26730b23d22e2663adf1babb05bd5a71
diff --git a/tests/clearmsg/mb.nim b/tests/clearmsg/mb.nim
new file mode 100644
index 000000000..2d21e2396
--- /dev/null
+++ b/tests/clearmsg/mb.nim
@@ -0,0 +1,2 @@
+type
+  typ* = distinct string
diff --git a/tests/clearmsg/mc.nim b/tests/clearmsg/mc.nim
new file mode 100644
index 000000000..79d7431df
--- /dev/null
+++ b/tests/clearmsg/mc.nim
@@ -0,0 +1,3 @@
+
+type
+  typ* = distinct int
diff --git a/tests/clearmsg/ta.nim b/tests/clearmsg/ta.nim
new file mode 100644
index 000000000..b21522d12
--- /dev/null
+++ b/tests/clearmsg/ta.nim
@@ -0,0 +1,12 @@
+discard """
+  errormsg: 'type mismatch: got (mc.typ)'
+  line: 12
+"""
+
+import mb, mc
+
+proc test(testing: mb.typ) =
+  discard
+
+var s: mc.typ
+test(s)

From 73ff0432dc374057d817c95be074737b82c3024c Mon Sep 17 00:00:00 2001
From: Araq 
Date: Mon, 27 Oct 2014 00:12:36 +0100
Subject: [PATCH 197/409] docgen works on linux

---
 lib/pure/net.nim         | 4 ++--
 lib/wrappers/openssl.nim | 8 +++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 60298ec88..f63f5fff8 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -232,10 +232,10 @@ when defined(ssl):
 
 proc socketError*(socket: Socket, err: int = -1, async = false,
                   lastError = (-1).OSErrorCode) =
-  ## Raises an EOS error based on the error code returned by ``SSLGetError``
+  ## Raises an OSError based on the error code returned by ``SSLGetError``
   ## (for SSL sockets) and ``osLastError`` otherwise.
   ##
-  ## If ``async`` is ``True`` no error will be thrown in the case when the
+  ## If ``async`` is ``true`` no error will be thrown in the case when the
   ## error was caused by no data being available to be read.
   ##
   ## If ``err`` is not lower than 0 no exception will be raised.
diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim
index abdfcdb52..6e85fb9dd 100644
--- a/lib/wrappers/openssl.nim
+++ b/lib/wrappers/openssl.nim
@@ -41,7 +41,9 @@
 
 {.deadCodeElim: on.}
 
-when defined(WINDOWS): 
+const useWinVersion = defined(Windows) or defined(nimdoc)
+
+when useWinVersion: 
   const 
     DLLSSLName = "(ssleay32|libssl32).dll"
     DLLUtilName = "libeay32.dll"
@@ -270,12 +272,12 @@ proc OpenSSL_add_all_algorithms*(){.cdecl, dynlib: DLLUtilName, importc: "OPENSS
 
 proc OPENSSL_config*(configName: cstring){.cdecl, dynlib: DLLSSLName, importc.}
 
-when not defined(windows):
+when not useWinVersion:
   proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, 
     dynlib: DLLUtilName, importc.}
 
 proc CRYPTO_malloc_init*() =
-  when not defined(windows):
+  when not useWinVersion:
     CRYPTO_set_mem_functions(alloc, realloc, dealloc)
 
 proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cInt, larg: int, parg: pointer): int{.

From 3939e674d028b63492aaadd9b892c82095acfaf0 Mon Sep 17 00:00:00 2001
From: Clay Sweetser 
Date: Wed, 29 Oct 2014 14:29:09 -0400
Subject: [PATCH 198/409] Fix #1599

Compiler-specific options are now read with the '{compiler}.cpp' prefix in C++ mode.
 GCC C++ mode is fixed.
---
 compiler/extccomp.nim | 38 ++++++++++++++++++++++++++++----------
 config/nim.cfg        | 14 +++++++-------
 2 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index 7d9744bc5..1e585fbcc 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -7,8 +7,10 @@
 #    distribution, for details about the copyright.
 #
 
-# module for calling the different external C compilers
-# some things are read in from the configuration file
+# Module providing functions for calling the different external C compilers
+# Uses some hard-wired facts about each C/C++ compiler, plus options read
+# from a configuration file, to provide generalized procedures to compile
+# nim files.
 
 import
   lists, ropes, os, strutils, osproc, platform, condsyms, options, msgs, crc
@@ -59,6 +61,7 @@ type
 template compiler(name: expr, settings: stmt): stmt {.immediate.} =
   proc name: TInfoCC {.compileTime.} = settings
 
+# GNU C and C++ Compiler
 compiler gcc:
   result = (
     name: "gcc",
@@ -84,21 +87,24 @@ compiler gcc:
     props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
             hasNakedAttribute})
 
+# LLVM Frontend for GCC/G++
 compiler llvmGcc:
-  result = gcc()
-  
+  result = gcc() # Uses settings from GCC
+
   result.name = "llvm_gcc"
   result.compilerExe = "llvm-gcc"
   result.cppCompiler = "llvm-g++"
   result.buildLib = "llvm-ar rcs $libfile $objfiles"
 
+# Clang (LLVM) C/C++ Compiler
 compiler clang:
-  result = llvmGcc()
+  result = llvmGcc() # Uses settings from llvmGcc
 
   result.name = "clang"
   result.compilerExe = "clang"
   result.cppCompiler = "clang++"
 
+# Microsoft Visual C/C++ Compiler
 compiler vcc:
   result = (
     name: "vcc",
@@ -123,6 +129,7 @@ compiler vcc:
     packedPragma: "#pragma pack(1)",
     props: {hasCpp, hasAssume, hasNakedDeclspec})
 
+# Intel C/C++ Compiler
 compiler icl:
   # Intel compilers try to imitate the native ones (gcc and msvc)
   when defined(windows):
@@ -134,6 +141,7 @@ compiler icl:
   result.compilerExe = "icl"
   result.linkerExe = "icl"
 
+# Local C Compiler
 compiler lcc:
   result = (
     name: "lcc",
@@ -158,6 +166,7 @@ compiler lcc:
     packedPragma: "", # XXX: not supported yet
     props: {})
 
+# Borland C Compiler
 compiler bcc:
   result = (
     name: "bcc",
@@ -182,6 +191,7 @@ compiler bcc:
     packedPragma: "", # XXX: not supported yet
     props: {hasCpp})
 
+# Digital Mars C Compiler
 compiler dmc:
   result = (
     name: "dmc",
@@ -206,6 +216,7 @@ compiler dmc:
     packedPragma: "#pragma pack(1)",
     props: {hasCpp})
 
+# Watcom C Compiler
 compiler wcc:
   result = (
     name: "wcc",
@@ -230,6 +241,7 @@ compiler wcc:
     packedPragma: "", # XXX: not supported yet
     props: {hasCpp})
 
+# Tiny C Compiler
 compiler tcc:
   result = (
     name: "tcc",
@@ -254,6 +266,7 @@ compiler tcc:
     packedPragma: "", # XXX: not supported yet
     props: {hasSwitchRange, hasComputedGoto})
 
+# Pelles C Compiler
 compiler pcc:
   # Pelles C
   result = (
@@ -279,6 +292,7 @@ compiler pcc:
     packedPragma: "", # XXX: not supported yet
     props: {})
 
+# Your C Compiler
 compiler ucc:
   result = (
     name: "ucc",
@@ -339,7 +353,9 @@ var
   compileOptions: string = ""
   ccompilerpath: string = ""
 
-proc nameToCC*(name: string): TSystemCC = 
+proc nameToCC*(name: string): TSystemCC =
+  ## Returns the kind of compiler referred to by `name`, or ccNone
+  ## if the name doesn't refer to any known compiler.
   for i in countup(succ(ccNone), high(TSystemCC)): 
     if cmpIgnoreStyle(name, CC[i].name) == 0: 
       return i
@@ -348,17 +364,18 @@ proc nameToCC*(name: string): TSystemCC =
 proc getConfigVar(c: TSystemCC, suffix: string): string =
   # use ``cpu.os.cc`` for cross compilation, unless ``--compileOnly`` is given
   # for niminst support
+  let fullSuffix = (if gCmd == cmdCompileToCpp: ".cpp" & suffix else: suffix)
   if (platform.hostOS != targetOS or platform.hostCPU != targetCPU) and
       optCompileOnly notin gGlobalOptions:
     let fullCCname = platform.CPU[targetCPU].name & '.' & 
                      platform.OS[targetOS].name & '.' & 
-                     CC[c].name & suffix
+                     CC[c].name & fullSuffix
     result = getConfigVar(fullCCname)
     if result.len == 0:
       # not overriden for this cross compilation setting?
-      result = getConfigVar(CC[c].name & suffix)
+      result = getConfigVar(CC[c].name & fullSuffix)
   else:
-    result = getConfigVar(CC[c].name & suffix)
+    result = getConfigVar(CC[c].name & fullSuffix)
 
 proc setCC*(ccname: string) = 
   cCompiler = nameToCC(ccname)
@@ -482,7 +499,7 @@ proc getLinkOptions: string =
 
 proc needsExeExt(): bool {.inline.} =
   result = (optGenScript in gGlobalOptions and targetOS == osWindows) or
-                                       (platform.hostOS == osWindows)
+           (platform.hostOS == osWindows)
 
 proc getCompilerExe(compiler: TSystemCC): string =
   result = if gCmd == cmdCompileToCpp: CC[compiler].cppCompiler
@@ -539,6 +556,7 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
     "lib", quoteShell(libpath)])
 
 proc footprint(filename: string): TCrc32 =
+  # note, '><' further modifies a crc value with a string.
   result = crcFromFile(filename) ><
       platform.OS[targetOS].name ><
       platform.CPU[targetCPU].name ><
diff --git a/config/nim.cfg b/config/nim.cfg
index 6ec32cb7b..62fe3307e 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -71,7 +71,7 @@ hint[LineTooLong]=off
   @if not bsd:
     # -fopenmp
     gcc.options.linker = "-ldl"
-    gpp.options.linker = "-ldl"
+    gcc.cpp.options.linker = "-ldl"
     clang.options.linker = "-ldl"
     tcc.options.linker = "-ldl"
   @end
@@ -101,19 +101,19 @@ hint[LineTooLong]=off
   cc = clang
   tlsEmulation:on
   gcc.options.always = "-w -fasm-blocks"
-  gpp.options.always = "-w -fasm-blocks -fpermissive"
+  gcc.cpp.options.always = "-w -fasm-blocks -fpermissive"
 @else:
-  gcc.options.always = "-w"
-  gpp.options.always = "-w -fpermissive"
+  gcc.options.always = "-w" 
+  gcc.cpp.options.always = "-w -fpermissive"
 @end
 
 gcc.options.speed = "-O3 -fno-strict-aliasing"
 gcc.options.size = "-Os"
 gcc.options.debug = "-g3 -O0"
 
-gpp.options.speed = "-O3 -fno-strict-aliasing"
-gpp.options.size = "-Os"
-gpp.options.debug = "-g3 -O0"
+gcc.cpp.options.speed = "-O3 -fno-strict-aliasing"
+gcc.cpp.options.size = "-Os"
+gcc.cpp.options.debug = "-g3 -O0"
 #passl = "-pg"
 
 # Configuration for the LLVM GCC compiler:

From bc3464ede77bba781928b7b0f425373a520077a4 Mon Sep 17 00:00:00 2001
From: Flaviu Tamas 
Date: Tue, 21 Oct 2014 16:49:29 -0400
Subject: [PATCH 199/409] Modify pegs.nim such that no match will return nil

An empty match will return ""
A zero-length match will return nil

Add test cases

Add news information
---
 lib/pure/pegs.nim | 18 +++++++++++++++++-
 web/news.txt      |  2 ++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim
index b2d8a2a4f..6eb7dee78 100644
--- a/lib/pure/pegs.nim
+++ b/lib/pure/pegs.nim
@@ -737,7 +737,12 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
 
 template fillMatches(s, caps, c: expr) =
   for k in 0..c.ml-1:
-    caps[k] = substr(s, c.matches[k][0], c.matches[k][1])
+    let startIdx = c.matches[k][0]
+    let endIdx = c.matches[k][1]
+    if startIdx != -1:
+      caps[k] = substr(s, startIdx, endIdx)
+    else:
+      caps[k] = nil
 
 proc match*(s: string, pattern: Peg, matches: var openArray[string],
             start = 0): bool {.nosideEffect, rtl, extern: "npegs$1Capture".} =
@@ -1767,3 +1772,14 @@ when isMainModule:
 
   assert match("prefix/start", peg"^start$", 7)
 
+  if "foo" =~ peg"{'a'}?.*":
+    assert matches[0] == nil
+  else: assert false
+
+  if "foo" =~ peg"{''}.*":
+    assert matches[0] == ""
+  else: assert false
+
+  if "foo" =~ peg"{'foo'}":
+    assert matches[0] == "foo"
+  else: assert false
diff --git a/web/news.txt b/web/news.txt
index c9374558a..c79eb55cc 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -20,6 +20,8 @@ News
   - String case (or any non-ordinal case) statements
     without 'else' are deprecated.
   - Recursive tuple types are not allowed anymore. Use ``object`` instead.
+  - The PEGS module returns ``nil`` instead of ``""`` when an optional capture
+    fails to match
 
   Language Additions
   ------------------

From 218cb7587a351c9a29a7de5961f168a5cdbb5a70 Mon Sep 17 00:00:00 2001
From: Flaviu Tamas 
Date: Sun, 26 Oct 2014 09:31:21 -0400
Subject: [PATCH 200/409] re module returns nil on failed captures

- tests included
- news.txt updated
---
 lib/impure/re.nim | 16 +++++++++++++---
 web/news.txt      |  2 ++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/lib/impure/re.nim b/lib/impure/re.nim
index fc9ed3ce0..6e3a69c62 100644
--- a/lib/impure/re.nim
+++ b/lib/impure/re.nim
@@ -92,7 +92,7 @@ proc matchOrFind(s: string, pattern: Regex, matches: var openArray[string],
     var a = rawMatches[i * 2]
     var b = rawMatches[i * 2 + 1]
     if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1)
-    else: matches[i-1] = ""
+    else: matches[i-1] = nil
   return rawMatches[1] - rawMatches[0]
   
 proc findBounds*(s: string, pattern: Regex, matches: var openArray[string],
@@ -110,7 +110,7 @@ proc findBounds*(s: string, pattern: Regex, matches: var openArray[string],
     var a = rawMatches[i * 2]
     var b = rawMatches[i * 2 + 1]
     if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1)
-    else: matches[i-1] = ""
+    else: matches[i-1] = nil
   return (rawMatches[0].int, rawMatches[1].int - 1)
   
 proc findBounds*(s: string, pattern: Regex, 
@@ -190,7 +190,7 @@ proc find*(s: string, pattern: Regex, matches: var openArray[string],
     var a = rawMatches[i * 2]
     var b = rawMatches[i * 2 + 1]
     if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1)
-    else: matches[i-1] = ""
+    else: matches[i-1] = nil
   return rawMatches[0]
 
 proc find*(s: string, pattern: Regex, start = 0): int =
@@ -310,6 +310,8 @@ proc replacef*(s: string, sub: Regex, by: string): string =
   while true:
     var match = findBounds(s, sub, caps, prev)
     if match.first < 0: break
+    assert result != nil
+    assert s != nil
     add(result, substr(s, prev, match.first-1))
     addf(result, by, caps)
     prev = match.last + 1
@@ -450,6 +452,14 @@ when isMainModule:
     assert matches[1] == "abc"
   else:
     assert false
+  
+  if "abc" =~ re"(cba)?.*":
+    assert matches[0] == nil
+  else: assert false
+
+  if "abc" =~ re"().*":
+    assert matches[0] == ""
+  else: assert false
     
   assert "var1=key; var2=key2".endsWith(re"\w+=\w+")
   assert("var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2") ==
diff --git a/web/news.txt b/web/news.txt
index c79eb55cc..b4316c989 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -22,6 +22,8 @@ News
   - Recursive tuple types are not allowed anymore. Use ``object`` instead.
   - The PEGS module returns ``nil`` instead of ``""`` when an optional capture
     fails to match
+  - The re module returns ``nil`` instead of ``""`` when an optional capture
+    fails to match
 
   Language Additions
   ------------------

From 4b61592602fdcf4d3870421bbc126b281fce3af5 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 30 Oct 2014 22:36:23 +0100
Subject: [PATCH 201/409] minor bugfix for notFoundError

---
 compiler/semcall.nim | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index d3720b0ab..3971b8ff5 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -99,7 +99,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
     for i in countup(1, n.len - 1): 
       var p = n.sons[i]
       if p.kind == nkSym:
-        add(errProto, typeToString(p.sym.typ, prefer))
+        add(errProto, typeToString(p.sym.typ, preferName))
         if i != n.len-1: add(errProto, ", ")
       # else: ignore internal error as we're already in error handling mode
     if errProto == proto:
@@ -327,7 +327,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
     result = explicitGenericSym(c, n, s)
   elif a.kind in {nkClosedSymChoice, nkOpenSymChoice}:
     # choose the generic proc with the proper number of type parameters.
-    # XXX I think this could be improved by reusing sigmatch.ParamTypesMatch.
+    # XXX I think this could be improved by reusing sigmatch.paramTypesMatch.
     # It's good enough for now.
     result = newNodeI(a.kind, n.info)
     for i in countup(0, len(a)-1): 

From 860a28802e1ee86c5b512d4ad0aacf419c17ed4f Mon Sep 17 00:00:00 2001
From: Araq 
Date: Fri, 31 Oct 2014 21:11:36 +0100
Subject: [PATCH 202/409] fixes #1595

---
 compiler/semexprs.nim | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index f156470fe..287a11b33 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1945,11 +1945,22 @@ proc semExport(c: PContext, n: PNode): PNode =
     if s == nil:
       localError(a.info, errGenerated, "invalid expr for 'export': " &
           renderTree(a))
-    while s != nil:
-      if s.kind in ExportableSymKinds+{skModule}:
-        x.add(newSymNode(s, a.info))
-        strTableAdd(c.module.tab, s)
-      s = nextOverloadIter(o, c, a)
+    elif s.kind == skModule:
+      # forward everything from that module:
+      strTableAdd(c.module.tab, s)
+      x.add(newSymNode(s, a.info))
+      var ti: TTabIter
+      var it = initTabIter(ti, s.tab)
+      while it != nil:
+        if it.kind in ExportableSymKinds+{skModule}:
+          strTableAdd(c.module.tab, it)
+        it = nextIter(ti, s.tab)
+    else:
+      while s != nil:
+        if s.kind in ExportableSymKinds+{skModule}:
+          x.add(newSymNode(s, a.info))
+          strTableAdd(c.module.tab, s)
+        s = nextOverloadIter(o, c, a)
   when false:
     if c.module.ast.isNil:
       c.module.ast = newNodeI(nkStmtList, n.info)

From 590461d88a5cff9679b2dcb421990b9a32a94529 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Fri, 31 Oct 2014 21:13:02 +0100
Subject: [PATCH 203/409] updated the test

---
 tests/modules/mexport2a.nim |  5 +++++
 tests/modules/mexport2b.nim |  1 +
 tests/modules/texport2.nim  | 10 ++++++++++
 3 files changed, 16 insertions(+)
 create mode 100644 tests/modules/mexport2a.nim
 create mode 100644 tests/modules/mexport2b.nim
 create mode 100644 tests/modules/texport2.nim

diff --git a/tests/modules/mexport2a.nim b/tests/modules/mexport2a.nim
new file mode 100644
index 000000000..deaef8fa4
--- /dev/null
+++ b/tests/modules/mexport2a.nim
@@ -0,0 +1,5 @@
+
+import mexport2b
+export mexport2b
+proc printAbc*() = echo "abc"
+
diff --git a/tests/modules/mexport2b.nim b/tests/modules/mexport2b.nim
new file mode 100644
index 000000000..8ea6085de
--- /dev/null
+++ b/tests/modules/mexport2b.nim
@@ -0,0 +1 @@
+proc printXyz*() = echo "xyz"
diff --git a/tests/modules/texport2.nim b/tests/modules/texport2.nim
new file mode 100644
index 000000000..0826eec9d
--- /dev/null
+++ b/tests/modules/texport2.nim
@@ -0,0 +1,10 @@
+# bug #1595
+
+import mexport2a
+
+proc main() =
+  echo "Import Test, two lines should follow. One with abc and one with xyz."
+  printAbc()
+  printXyz()
+
+main()

From 2e26734ea72253f219064e6d9a6e0fd89b5f049e Mon Sep 17 00:00:00 2001
From: Araq 
Date: Fri, 31 Oct 2014 23:09:19 +0100
Subject: [PATCH 204/409] Nimrod -> Nim

---
 tools/nimweb.nim | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/nimweb.nim b/tools/nimweb.nim
index 6312dace4..46c1d0d85 100644
--- a/tools/nimweb.nim
+++ b/tools/nimweb.nim
@@ -68,12 +68,12 @@ Options:
   -h, --help          shows this help
   -v, --version       shows the version
 Compile_options:
-  will be passed to the Nimrod compiler
+  will be passed to the Nim compiler
 """
 
   rYearMonthDayTitle = r"(\d{4})-(\d{2})-(\d{2})\s+(.*)"
-  rssUrl = "http://nimrod-code.org/news.xml"
-  rssNewsUrl = "http://nimrod-code.org/news.html"
+  rssUrl = "http://nim-lang.org/news.xml"
+  rssNewsUrl = "http://nim-lang.org/news.html"
   validAnchorCharacters = Letters + Digits
 
 
@@ -355,7 +355,7 @@ proc generateRss(outputFilename: string, news: seq[TRssItem]) =
   output.write("""
 
 """)
-  output.write(title("Nimrod website news"))
+  output.write(title("Nim website news"))
   output.write(link(href = rssUrl, rel = "self"))
   output.write(link(href = rssNewsUrl))
   output.write(id(rssNewsUrl))
@@ -371,7 +371,7 @@ proc generateRss(outputFilename: string, news: seq[TRssItem]) =
         link(`type` = "text/html", rel = "alternate",
           href = genNewsLink(joinedTitle)),
         updatedDate(rss.year, rss.month, rss.day),
-        "Nimrod",
+        "Nim",
         content(joinedTitle, `type` = "text"),
       ))
 

From dac43e0fdd393c3267040e91e95592ba184a4527 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sat, 1 Nov 2014 01:14:51 +0100
Subject: [PATCH 205/409] minor changes to the threading docs

---
 doc/manual/threads.txt | 13 +++++++------
 todo.txt               |  9 +++++----
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/doc/manual/threads.txt b/doc/manual/threads.txt
index a96abf060..245545f6f 100644
--- a/doc/manual/threads.txt
+++ b/doc/manual/threads.txt
@@ -74,8 +74,8 @@ Threads and exceptions
 ----------------------
 
 The interaction between threads and exceptions is simple: A *handled* exception 
-in one thread cannot affect any other thread. However, an *unhandled* 
-exception in one thread terminates the whole *process*!
+in one thread cannot affect any other thread. However, an *unhandled* exception
+in one thread terminates the whole *process*!
 
 
 
@@ -94,9 +94,10 @@ module to work.
 Somewhat confusingly, ``spawn`` is also used in the ``parallel`` statement
 with slightly different semantics. ``spawn`` always takes a call expression of
 the form ``f(a, ...)``. Let ``T`` be ``f``'s return type. If ``T`` is ``void``
-then ``spawn``'s return type is also ``void``. Within a ``parallel`` section
-``spawn``'s return type is ``T``, otherwise it is ``FlowVar[T]``.
+then ``spawn``'s return type is also ``void`` otherwise it is ``FlowVar[T]``.
 
+Within a ``parallel`` section sometimes the ``FlowVar[T]`` is eliminated
+to ``T``. This happens when ``T`` does not contain any GC'ed memory.
 The compiler can ensure the location in ``location = spawn f(...)`` is not
 read prematurely within a ``parallel`` section and so there is no need for
 the overhead of an indirection via ``FlowVar[T]`` to ensure correctness.
@@ -133,7 +134,7 @@ that ``spawn`` takes is restricted:
   is performed via ``system.deepCopy`` and so can be overriden.
 * For *safe* data exchange between ``f`` and the caller a global ``TChannel``
   needs to be used. However, since spawn can return a result, often no further
-  communication is required. 
+  communication is required.
 
 
 ``spawn`` executes the passed expression on the thread pool and returns
@@ -158,7 +159,7 @@ Data flow variables ensure that no data races
 are possible. Due to technical limitations not every type ``T`` is possible in
 a data flow variable: ``T`` has to be of the type ``ref``, ``string``, ``seq``
 or of a type that doesn't contain a type that is garbage collected. This
-restriction will be removed in the future.
+restriction is not hard to work-around in practice.
 
 
 
diff --git a/todo.txt b/todo.txt
index 3e511dc49..417c2ef04 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,8 +1,9 @@
 version 0.10
 ============
 
-- Test nimfix on various babel packages
-
+- Declare nimfix as beta-quality.
+- make nimble part of the distribution
+- fix babelpackagelist bug
 
 version 0.9.6
 =============
@@ -49,8 +50,8 @@ Bugs
 version 0.9.x
 =============
 
-
-- implicit deref for parameter matching
+- implicit deref for parameter matching; but only for  x.f(a, b) --> looks like
+  a nice compromise
 - overloading of '='
 - allow simple read accesses to global variables --> difficult to ensure that
   no data races happen

From a77dc8e46c48ee6d999e3dc249d3d8f42dc1d286 Mon Sep 17 00:00:00 2001
From: Flaviu Tamas 
Date: Sat, 1 Nov 2014 17:12:45 -0400
Subject: [PATCH 206/409] Remove extra trailing zero

---
 lib/pure/oids.nim | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim
index 7c58a2dda..06e049d46 100644
--- a/lib/pure/oids.nim
+++ b/lib/pure/oids.nim
@@ -52,10 +52,9 @@ proc oidToString*(oid: Oid, str: cstring) =
     str[2 * i] = hex[(b and 0xF0) shr 4]
     str[2 * i + 1] = hex[b and 0xF]
     inc(i)
-  str[24] = '\0'
 
 proc `$`*(oid: Oid): string =
-  result = newString(25)
+  result = newString(24)
   oidToString(oid, result)
 
 var

From cbe733afa25c262cc77781d87cda11efbcbb9fa8 Mon Sep 17 00:00:00 2001
From: Varriount 
Date: Sat, 1 Nov 2014 17:52:00 -0400
Subject: [PATCH 207/409] Revert "Remove extra trailing zero"

---
 lib/pure/oids.nim | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim
index 06e049d46..7c58a2dda 100644
--- a/lib/pure/oids.nim
+++ b/lib/pure/oids.nim
@@ -52,9 +52,10 @@ proc oidToString*(oid: Oid, str: cstring) =
     str[2 * i] = hex[(b and 0xF0) shr 4]
     str[2 * i + 1] = hex[b and 0xF]
     inc(i)
+  str[24] = '\0'
 
 proc `$`*(oid: Oid): string =
-  result = newString(24)
+  result = newString(25)
   oidToString(oid, result)
 
 var

From c4d05ca130e944cb10ba1ec40ffafe0a7f83b58a Mon Sep 17 00:00:00 2001
From: Araq 
Date: Sun, 2 Nov 2014 14:35:13 +0100
Subject: [PATCH 208/409] better effect inference

---
 compiler/sempass2.nim       | 25 +++++++++++++++++--------
 tests/effects/teffects1.nim |  2 +-
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index cbabc755b..0d8c7c479 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -181,6 +181,10 @@ proc initVarViaNew(a: PEffects, n: PNode) =
     # are initialized:
     initVar(a, n)
 
+proc warnAboutGcUnsafe(n: PNode) =
+  #assert false
+  message(n.info, warnGcUnsafe, renderTree(n))
+
 proc useVar(a: PEffects, n: PNode) =
   let s = n.sym
   if isLocalVar(a, s):
@@ -195,7 +199,7 @@ proc useVar(a: PEffects, n: PNode) =
     if s.guard != nil: guardGlobal(a, n, s.guard)
     if (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem) and 
         tfGcSafe notin s.typ.flags:
-      if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
+      if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
       a.gcUnsafe = true
 
 type
@@ -431,7 +435,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
   mergeTags(tracked, tagSpec, n)
 
   if notGcSafe(s.typ) and sfImportc notin s.flags:
-    if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
+    if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
     tracked.gcUnsafe = true
   mergeLockLevels(tracked, n, s.getLockLevel)
 
@@ -462,8 +466,13 @@ proc assumeTheWorst(tracked: PEffects; n: PNode; op: PType) =
   #  message(n.info, warnUser, "had to assume the worst here")
   mergeLockLevels(tracked, n, lockLevel)
 
+proc isOwnedProcVar(n: PNode; owner: PSym): bool =
+  # XXX prove the soundness of this effect system rule
+  result = n.kind == nkSym and n.sym.kind == skParam and owner == n.sym.owner
+
 proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
-  let op = skipConvAndClosure(n).typ
+  let a = skipConvAndClosure(n)
+  let op = a.typ
   if op != nil and op.kind == tyProc and n.kind != nkNilLit:
     internalAssert op.n.sons[0].kind == nkEffectList
     var effectList = op.n.sons[0]
@@ -475,18 +484,18 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
         # we have no explicit effects but it's a forward declaration and so it's
         # stated there are no additional effects, so simply propagate them:
         propagateEffects(tracked, n, n.sym)
-      else:
+      elif not isOwnedProcVar(a, tracked.owner):
         # we have no explicit effects so assume the worst:
         assumeTheWorst(tracked, n, op)
       # assume GcUnsafe unless in its type; 'forward' does not matter:
-      if notGcSafe(op):
-        if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
+      if notGcSafe(op) and not isOwnedProcVar(a, tracked.owner):
+        if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
         tracked.gcUnsafe = true
     else:
       mergeEffects(tracked, effectList.sons[exceptionEffects], n)
       mergeTags(tracked, effectList.sons[tagEffects], n)
       if notGcSafe(op):
-        if warnGcUnsafe in gNotes: message(n.info, warnGcUnsafe, renderTree(n))
+        if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n)
         tracked.gcUnsafe = true
   notNilCheck(tracked, n, paramType)
 
@@ -633,7 +642,7 @@ proc track(tracked: PEffects, n: PNode) =
         if notGcSafe(op) and not importedFromC(a):
           # and it's not a recursive call:
           if not (a.kind == nkSym and a.sym == tracked.owner):
-            message(n.info, warnGcUnsafe, renderTree(n))
+            warnAboutGcUnsafe(n)
             tracked.gcUnsafe = true
     for i in 1 .. 
Date: Sun, 2 Nov 2014 15:55:33 +0100
Subject: [PATCH 209/409] Change empty callback into nil

---
 lib/pure/osproc.nim | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 35183c37c..d51a2b224 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -236,8 +236,8 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} =
 proc execProcesses*(cmds: openArray[string],
                     options = {poStdErrToStdOut, poParentStreams},
                     n = countProcessors(),
-                    beforeRunEvent: proc(idx: int){.closure.}): int
-                    {.rtl, tags: [ExecIOEffect, TimeEffect, ReadEnvEffect]} =
+                    beforeRunEvent: proc(idx: int)): int
+                    {.rtl, tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
   ## executes the commands `cmds` in parallel. Creates `n` processes
   ## that execute in parallel. The highest return value of all processes
   ## is returned. Runs `beforeRunEvent` before running each command.
@@ -251,7 +251,8 @@ proc execProcesses*(cmds: openArray[string],
     newSeq(q, n)
     var m = min(n, cmds.len)
     for i in 0..m-1:
-      beforeRunEvent(i)
+      if beforeRunEvent != nil:
+        beforeRunEvent(i)
       q[i] = startCmd(cmds[i], options=options)
     when defined(noBusyWaiting):
       var r = 0
@@ -265,7 +266,8 @@ proc execProcesses*(cmds: openArray[string],
           echo(err)
         result = max(waitForExit(q[r]), result)
         if q[r] != nil: close(q[r])
-        beforeRunEvent(i)
+        if beforeRunEvent != nil:
+          beforeRunEvent(i)
         q[r] = startCmd(cmds[i], options=options)
         r = (r + 1) mod n
     else:
@@ -277,7 +279,8 @@ proc execProcesses*(cmds: openArray[string],
             #echo(outputStream(q[r]).readLine())
             result = max(waitForExit(q[r]), result)
             if q[r] != nil: close(q[r])
-            beforeRunEvent(i)
+            if beforeRunEvent != nil:
+              beforeRunEvent(i)
             q[r] = startCmd(cmds[i], options=options)
             inc(i)
             if i > high(cmds): break
@@ -286,21 +289,21 @@ proc execProcesses*(cmds: openArray[string],
       if q[j] != nil: close(q[j])
   else:
     for i in 0..high(cmds):
-      beforeRunEvent(i)
+      if beforeRunEvent != nil:
+        beforeRunEvent(i)
       var p = startCmd(cmds[i], options=options)
       result = max(waitForExit(p), result)
       close(p)
 
-let emptyCb = proc(idx: int) {.closure.} = discard
 proc execProcesses*(cmds: openArray[string],
                     options = {poStdErrToStdOut, poParentStreams},
                     n = countProcessors()): int
                     {.rtl, extern: "nosp$1",
-                    tags: [ExecIOEffect, TimeEffect, ReadEnvEffect]} =
+                    tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
   ## executes the commands `cmds` in parallel. Creates `n` processes
   ## that execute in parallel. The highest return value of all processes
   ## is returned.
-  return execProcesses(cmds, options, n, emptyCb)
+  return execProcesses(cmds, options, n, nil)
 
 proc select*(readfds: var seq[Process], timeout = 500): int
   ## `select` with a sensible Nim interface. `timeout` is in miliseconds.

From 49e93326615e0201ab2ba031e9aa3a1392818aa9 Mon Sep 17 00:00:00 2001
From: Erwan Ameil 
Date: Sun, 2 Nov 2014 16:06:01 +0100
Subject: [PATCH 210/409] Use defaut nil callback for execProcesses

---
 lib/pure/osproc.nim | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index d51a2b224..71ca51764 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -236,7 +236,7 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} =
 proc execProcesses*(cmds: openArray[string],
                     options = {poStdErrToStdOut, poParentStreams},
                     n = countProcessors(),
-                    beforeRunEvent: proc(idx: int)): int
+                    beforeRunEvent: proc(idx: int) = nil): int
                     {.rtl, tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
   ## executes the commands `cmds` in parallel. Creates `n` processes
   ## that execute in parallel. The highest return value of all processes
@@ -295,16 +295,6 @@ proc execProcesses*(cmds: openArray[string],
       result = max(waitForExit(p), result)
       close(p)
 
-proc execProcesses*(cmds: openArray[string],
-                    options = {poStdErrToStdOut, poParentStreams},
-                    n = countProcessors()): int
-                    {.rtl, extern: "nosp$1",
-                    tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
-  ## executes the commands `cmds` in parallel. Creates `n` processes
-  ## that execute in parallel. The highest return value of all processes
-  ## is returned.
-  return execProcesses(cmds, options, n, nil)
-
 proc select*(readfds: var seq[Process], timeout = 500): int
   ## `select` with a sensible Nim interface. `timeout` is in miliseconds.
   ## Specify -1 for no timeout. Returns the number of processes that are

From c3a4cc87ca8aac8138da2aa083ac3a68dda98b14 Mon Sep 17 00:00:00 2001
From: Erwan Ameil 
Date: Sun, 2 Nov 2014 16:11:17 +0100
Subject: [PATCH 211/409] Forgot to keep extern pragma for execProcesses

---
 lib/pure/osproc.nim | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 71ca51764..59eecf88d 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -237,7 +237,8 @@ proc execProcesses*(cmds: openArray[string],
                     options = {poStdErrToStdOut, poParentStreams},
                     n = countProcessors(),
                     beforeRunEvent: proc(idx: int) = nil): int
-                    {.rtl, tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
+                    {.rtl, extern: "nosp$1",
+                    tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} =
   ## executes the commands `cmds` in parallel. Creates `n` processes
   ## that execute in parallel. The highest return value of all processes
   ## is returned. Runs `beforeRunEvent` before running each command.

From 771e3db869f14fe49a6b41f02623867fe931d5d8 Mon Sep 17 00:00:00 2001
From: Flaviu Tamas 
Date: Sun, 2 Nov 2014 17:05:23 -0500
Subject: [PATCH 212/409] Remove extra trailing zero from oid

`$` would return a string of length 25, including the trailing null
String length changed to 24, avoiding an extra null byte in the output
---
 lib/pure/oids.nim | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim
index 7c58a2dda..0dc8e3c15 100644
--- a/lib/pure/oids.nim
+++ b/lib/pure/oids.nim
@@ -55,7 +55,7 @@ proc oidToString*(oid: Oid, str: cstring) =
   str[24] = '\0'
 
 proc `$`*(oid: Oid): string =
-  result = newString(25)
+  result = newString(24)
   oidToString(oid, result)
 
 var

From 1b4dd6f61e311e774b218173b9b4f47c9a78ac8d Mon Sep 17 00:00:00 2001
From: Varriount 
Date: Mon, 3 Nov 2014 01:51:54 -0500
Subject: [PATCH 213/409] Update buildbat.tmpl

Batch scripts generated by `koch csources` now return proper error codes, and stop when there is an error.
---
 tools/niminst/buildbat.tmpl | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/tools/niminst/buildbat.tmpl b/tools/niminst/buildbat.tmpl
index 9a19fc70b..415574273 100644
--- a/tools/niminst/buildbat.tmpl
+++ b/tools/niminst/buildbat.tmpl
@@ -20,6 +20,7 @@ REM call the compiler:
 ECHO %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
 %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
 #      linkCmd.add(" " & changeFileExt(f, "o"))
+IF ERRORLEVEL 1 (GOTO:END)
 #    end for
 
 ECHO %LINKER% -o ?{"%BIN_DIR%"\toLower(c.name)}.exe ?linkCmd %LINK_FLAGS%
@@ -27,4 +28,14 @@ ECHO %LINKER% -o ?{"%BIN_DIR%"\toLower(c.name)}.exe ?linkCmd %LINK_FLAGS%
 
 #  end block
 
-ECHO SUCCESS
+:END
+IF ERRORLEVEL 1 (
+    ECHO FAILURE
+    ECHO.
+    ECHO CSource compilation failed. Please check that the gcc compiler is in
+    ECHO the PATH environment variable, and that you are calling the batch script
+    ECHO that matches the target architecture of the compiler.
+) ELSE (
+    ECHO SUCCESS
+)
+exit /b %ERRORLEVEL%

From 26b4761f14bbd81101dff9e1258c081b99da1a67 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Mon, 3 Nov 2014 10:44:30 +0100
Subject: [PATCH 214/409] actors module is deprecated

---
 doc/lib.txt | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/doc/lib.txt b/doc/lib.txt
index a29e32429..6de4cfbda 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -60,9 +60,11 @@ Core
 * `typetraits `_
   This module defines compile-time reflection procs for working with types.
 
-* `actors `_
-  Actor support for Nim; implemented as a layer on top of the threads and
-  channels modules.
+* `threadpool `_
+  Implements Nim's `spawn `_.
+
+* `cpuinfo `_
+  This module implements procs to determine the number of CPUs / cores.
 
 
 Collections and algorithms

From 59c0a2db8427852d919f8a65cd0158d52ade2ab7 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Mon, 3 Nov 2014 10:47:14 +0100
Subject: [PATCH 215/409] added threadpool and cpuinfo to the docgen

---
 todo.txt    | 1 +
 web/nim.ini | 1 +
 2 files changed, 2 insertions(+)

diff --git a/todo.txt b/todo.txt
index 417c2ef04..ca35efbae 100644
--- a/todo.txt
+++ b/todo.txt
@@ -2,6 +2,7 @@ version 0.10
 ============
 
 - Declare nimfix as beta-quality.
+- implement 'static_call'
 - make nimble part of the distribution
 - fix babelpackagelist bug
 
diff --git a/web/nim.ini b/web/nim.ini
index e982d6ec3..dd29eb330 100644
--- a/web/nim.ini
+++ b/web/nim.ini
@@ -43,6 +43,7 @@ pdf: "manual;lib;tut1;tut2;nimc;niminst;gc"
 srcdoc2: "system.nim"
 srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned"
 srcdoc2: "impure/re;pure/sockets;pure/typetraits"
+srcdoc2: "pure/concurrency/threadpool.nim;pure/concurrency/cpuinfo.nim"
 srcdoc: "system/threads.nim;system/channels.nim;js/dom"
 srcdoc2: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm"
 srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib"

From 8f0b248825e177254155fde47c1d855dfdc5a777 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Tue, 4 Nov 2014 07:33:09 +0100
Subject: [PATCH 216/409] proper development version number

---
 compiler/nversion.nim | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/nversion.nim b/compiler/nversion.nim
index c29880fe2..910ebfb59 100644
--- a/compiler/nversion.nim
+++ b/compiler/nversion.nim
@@ -14,7 +14,7 @@ const
   MaxSetElements* = 1 shl 16  # (2^16) to support unicode character sets?
   VersionMajor* = 0
   VersionMinor* = 10
-  VersionPatch* = 0
+  VersionPatch* = 1
   VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
 
   RodFileVersion* = "1215"       # modify this if the rod-format changes!

From 0a2296b12313b8ce84e8190b6200885fdb06bf96 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Tue, 4 Nov 2014 07:47:31 +0100
Subject: [PATCH 217/409] added module fenv's docs

---
 doc/lib.txt                   | 4 ++++
 lib/{impure => pure}/fenv.nim | 0
 web/news.txt                  | 7 +++++++
 web/nim.ini                   | 1 +
 4 files changed, 12 insertions(+)
 rename lib/{impure => pure}/fenv.nim (100%)

diff --git a/doc/lib.txt b/doc/lib.txt
index 6de4cfbda..aba05c2ba 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -175,6 +175,7 @@ Generic Operating System Services
   This module implements the ability to monitor a directory/file for changes
   using Posix's inotify API.
 
+
 Math libraries
 --------------
 
@@ -184,6 +185,9 @@ Math libraries
 * `complex `_
   This module implements complex numbers and their mathematical operations.
 
+* `fenv `_
+  Floating-point environment. Handling of floating-point rounding and
+  exceptions (overflow, zero-devide, etc.).
 
 
 Internet Protocols and Support
diff --git a/lib/impure/fenv.nim b/lib/pure/fenv.nim
similarity index 100%
rename from lib/impure/fenv.nim
rename to lib/pure/fenv.nim
diff --git a/web/news.txt b/web/news.txt
index b4316c989..9e6ca73b9 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -57,6 +57,13 @@ News
     statement.
     
 
+  Library Additions
+  -----------------
+
+  - Added module ``fenv`` to control the handling of floating-point rounding and
+    exceptions (overflow, zero-devide, etc.).
+
+
 2014-10-19 Nimrod version 0.9.6 released
 ========================================
 
diff --git a/web/nim.ini b/web/nim.ini
index dd29eb330..98eadf3ce 100644
--- a/web/nim.ini
+++ b/web/nim.ini
@@ -75,6 +75,7 @@ srcdoc2: "wrappers/tre;wrappers/openssl;wrappers/pcre"
 srcdoc2: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc"
 srcdoc2: "wrappers/readline/readline;wrappers/readline/rltypedefs"
 srcdoc2: "wrappers/joyent_http_parser"
+srcdoc2: "pure/fenv"
 
 webdoc: "pure/md5;wrappers/mysql;wrappers/iup"
 webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc"

From 1f63d1c76e733812e5e61d81e83429f853511fe7 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Tue, 4 Nov 2014 08:38:56 +0100
Subject: [PATCH 218/409] documented nimfix

---
 compiler/nimfix/nimfix.nim |  2 +-
 doc/nimfix.txt             | 56 ++++++++++++++++++++++++++++++++++++++
 doc/tools.txt              |  4 +++
 install.txt                | 18 ++++++------
 todo.txt                   |  5 ++--
 web/news.txt               |  8 ++++--
 web/nim.ini                |  1 +
 7 files changed, 79 insertions(+), 15 deletions(-)
 create mode 100644 doc/nimfix.txt

diff --git a/compiler/nimfix/nimfix.nim b/compiler/nimfix/nimfix.nim
index e561b6d4d..7b42537c4 100644
--- a/compiler/nimfix/nimfix.nim
+++ b/compiler/nimfix/nimfix.nim
@@ -16,7 +16,7 @@ import options, commands, modules, sem, passes, passaux, pretty, msgs, nimconf,
 const Usage = """
 Nimfix - Tool to patch Nim code
 Usage:
-  nimfix [options] projectflie.nim
+  nimfix [options] projectfile.nim
 
 Options:
   --overwriteFiles:on|off          overwrite the original nim files.
diff --git a/doc/nimfix.txt b/doc/nimfix.txt
new file mode 100644
index 000000000..6d78f3e3f
--- /dev/null
+++ b/doc/nimfix.txt
@@ -0,0 +1,56 @@
+=====================
+  Nimfix User Guide
+=====================
+
+:Author: Andreas Rumpf
+:Version: |nimversion|
+
+**WARNING**: Nimfix is currently beta-quality.
+
+Nimfix is a tool to help you upgrade from Nimrod (<= version 0.9.6) to
+Nim (=> version 0.10.0).
+
+It performs 3 different actions:
+
+1. It makes your code case consistent.
+2. It renames every symbol that has a deprecation rule. So if a module has a
+   rule ``{.deprecated: [TFoo: Foo].}`` then ``TFoo`` is replaced by ``Foo``.
+3. It can also check that your identifiers adhere to the official style guide
+   and optionally modify them to do so (via ``--styleCheck:auto``).
+
+Note that ``nimfix`` defaults to **overwrite** your code unless you
+use ``--overwriteFiles:off``! But hey, if you do not use a version control
+system by this day and age, your project is already in big trouble.
+
+
+Installation
+------------
+
+Nimfix is part of the compiler distribution. Compile via::
+
+  nim c compiler/nimfix/nimfix.nim
+  mv compiler/nimfix/nimfix bin
+
+Or on windows::
+
+  nim c compiler\nimfix\nimfix.nim
+  move compiler\nimfix\nimfix.exe bin
+
+Usage
+-----
+
+Usage:
+  nimfix [options] projectfile.nim
+
+Options:
+
+  --overwriteFiles:on|off       overwrite the original nim files. DEFAULT is ON!
+  --wholeProject                overwrite every processed file.
+  --checkExtern:on|off          style check also extern names
+  --styleCheck:on|off|auto      performs style checking for identifiers
+                                and suggests an alternative spelling; 
+                                'auto' corrects the spelling.
+
+In addition, all command line options of Nim are supported.
+
+
diff --git a/doc/tools.txt b/doc/tools.txt
index 0b39762c6..7f2830879 100644
--- a/doc/tools.txt
+++ b/doc/tools.txt
@@ -18,3 +18,7 @@ The standard distribution ships with the following tools:
 
 - | `estp `_
   | Nim's slow platform independent embedded stack trace profiler.
+
+- | `nimfix `_
+  | Nimfix is a tool to help you upgrade from Nimrod (<= version 0.9.6) to
+    Nim (=> version 0.10.0).
diff --git a/install.txt b/install.txt
index 4543e4ece..deca55599 100644
--- a/install.txt
+++ b/install.txt
@@ -9,25 +9,25 @@ should be in your ``$PATH`` (most likely the case). Note that some few Linux
 distributions do not ship with a GCC compiler preinstalled - then you have to
 install it.
 
-Install Nimrod by downloading the appropriate ``.zip`` file and extracting it 
-to a directory of your choice. The Nimrod Compiler will stay in this
+Install Nim by downloading the appropriate ``.zip`` file and extracting it 
+to a directory of your choice. The Nim Compiler will stay in this
 directory (unless you copy it somewhere else). The compiler does not need 
-write access to its directory, so copying the nimrod folder to ``/opt`` 
+write access to its directory, so copying the nim folder to ``/opt`` 
 works.
 
 Then run the following command::
 
   sh build.sh
 
-Unlike other software, Nimrod does not distribute its files over the whole file
+Unlike other software, Nim does not distribute its files over the whole file
 hierarchy. This has the advantage that you can deinstall it by just deleting
 its folder. The disadvantage is that you have to add it to your ``PATH``
 manually. An alternative is to create a symbolic link in ``/usr/bin``::
 
-  [sudo] ln -s $your_install_dir/bin/nimrod  /usr/bin/nimrod
+  [sudo] ln -s $your_install_dir/bin/nim  /usr/bin/nim
 
 There are also ``install.sh`` and ``deinstall.sh`` scripts for distributing 
-the files over the UNIX hierarchy. However, updating your Nimrod installation
+the files over the UNIX hierarchy. However, updating your Nim installation
 is more cumbersome then.
 
 
@@ -43,9 +43,9 @@ You need to install Apple's developer's tools for the GNU Compiler Collection.
 Installation on Windows
 -----------------------
 
-Install Nimrod by downloading and running the ``nimrod_$version.exe`` file.
+Install Nim by downloading and running the ``nim_$version.exe`` file.
 As default, the ``GCC`` compiler is used that is bundled with this installer.
-You can change the configuration file ``config/nimrod.cfg`` to use
+You can change the configuration file ``config/nim.cfg`` to use
 another C compiler or change the path to GCC.
 
 Currently, the following C compilers are supported under Windows:
@@ -64,5 +64,5 @@ However, most testing is done with GCC.
 Bootstrapping from Github
 -------------------------
 
-Take a look at the readme file on github `here `_
+Take a look at the readme file on github `here `_
 for instructions.
diff --git a/todo.txt b/todo.txt
index ca35efbae..3fddf20c2 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,10 +1,11 @@
 version 0.10
 ============
 
-- Declare nimfix as beta-quality.
+- fix deepCopy bug in parallel section
+- fix missing GC_ref bug for flow variables
 - implement 'static_call'
 - make nimble part of the distribution
-- fix babelpackagelist bug
+
 
 version 0.9.6
 =============
diff --git a/web/news.txt b/web/news.txt
index 9e6ca73b9..2f2290b5b 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -21,9 +21,9 @@ News
     without 'else' are deprecated.
   - Recursive tuple types are not allowed anymore. Use ``object`` instead.
   - The PEGS module returns ``nil`` instead of ``""`` when an optional capture
-    fails to match
+    fails to match.
   - The re module returns ``nil`` instead of ``""`` when an optional capture
-    fails to match
+    fails to match.
 
   Language Additions
   ------------------
@@ -55,7 +55,9 @@ News
 
   - Two backticks now produce a single backtick within an ``emit`` or ``asm``
     statement.
-    
+  - There is a new tool, `nimfix `_ to help you in updating your
+    code from Nimrod to Nim.
+  
 
   Library Additions
   -----------------
diff --git a/web/nim.ini b/web/nim.ini
index 98eadf3ce..6624910d1 100644
--- a/web/nim.ini
+++ b/web/nim.ini
@@ -39,6 +39,7 @@ UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson."""
 [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"
 pdf: "manual;lib;tut1;tut2;nimc;niminst;gc"
 srcdoc2: "system.nim"
 srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned"

From 0c3299383aa61099d52e88786161d68628a508ec Mon Sep 17 00:00:00 2001
From: Araq 
Date: Tue, 4 Nov 2014 09:50:00 +0100
Subject: [PATCH 219/409] todo.txt updates

---
 todo.txt | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/todo.txt b/todo.txt
index 3fddf20c2..a45a4f50a 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,18 +1,14 @@
 version 0.10
 ============
 
-- fix deepCopy bug in parallel section
 - fix missing GC_ref bug for flow variables
+- fix deepCopy bug in parallel section
 - implement 'static_call'
 - make nimble part of the distribution
-
-
-version 0.9.6
-=============
-
 - split idetools into separate tool
 - split docgen into separate tool
 
+
 Concurrency
 -----------
 

From b13c51cc2aa1f47bc95c4c45d02c04bc3cff783e Mon Sep 17 00:00:00 2001
From: Araq 
Date: Wed, 5 Nov 2014 01:55:33 +0100
Subject: [PATCH 220/409] compiler bootstraps again

---
 compiler/msgs.nim | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index d40d94a71..944446624 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -413,7 +413,7 @@ const
     hintUser: "$1 [User]"]
 
 const
-  WarningsToStr*: array[0..27, string] = ["CannotOpenFile", "OctalEscape", 
+  WarningsToStr*: array[0..28, string] = ["CannotOpenFile", "OctalEscape", 
     "XIsNeverRead", "XmightNotBeenInit",
     "Deprecated", "ConfigDeprecated",
     "SmallLshouldNotBeUsed", "UnknownMagic", 

From ee9c70e0348b0586d69faa06d2ed1655bb216a6a Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 6 Nov 2014 00:21:39 +0100
Subject: [PATCH 221/409] user defined pragmas work for generics instantiated
 in different modules

---
 compiler/pragmas.nim  | 14 +++++++++++---
 compiler/semstmts.nim |  2 +-
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 52eb46bf4..b548837fe 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -71,7 +71,7 @@ const
 proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
 # implementation
 
-proc invalidPragma(n: PNode) = 
+proc invalidPragma(n: PNode) =
   localError(n.info, errInvalidPragmaX, renderTree(n, {renderNoComments}))
 
 proc pragmaAsm*(c: PContext, n: PNode): char = 
@@ -601,6 +601,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
       if c.instCounter > 100: 
         globalError(it.info, errRecursiveDependencyX, userPragma.name.s)
       pragma(c, sym, userPragma.ast, validPragmas)
+      # ensure the pragma is also remember for generic instantiations in other
+      # modules:
+      n.sons[i] = userPragma.ast
       dec c.instCounter
     else:
       var k = whichKeyword(key.ident)
@@ -883,8 +886,13 @@ proc hasPragma*(n: PNode, pragma: TSpecialWord): bool =
   
   return false
 
-proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
+proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
   if n == nil: return
   for i in countup(0, sonsLen(n) - 1):
-    if singlePragma(c, sym, n, i, validPragmas): break
+    if n.sons[i].kind == nkPragma: pragmaRec(c, sym, n.sons[i], validPragmas)
+    elif singlePragma(c, sym, n, i, validPragmas): break
+
+proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
+  if n == nil: return
+  pragmaRec(c, sym, n, validPragmas)
   implicitPragmas(c, sym, n, validPragmas)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 255507548..c6906d98e 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1145,7 +1145,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
       pragma(c, s, n.sons[pragmasPos], validPragmas)
     else:
       implicitPragmas(c, s, n, validPragmas)
-  else: 
+  else:
     if n.sons[pragmasPos].kind != nkEmpty: 
       localError(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc)
     if sfForward notin proto.flags: 

From 9500dfcc2e7b56a626744eff3000612b13c79575 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Thu, 6 Nov 2014 01:53:57 +0100
Subject: [PATCH 222/409] fixes #1612

---
 compiler/semexprs.nim       | 3 +--
 tests/modules/mexport2a.nim | 2 ++
 tests/modules/mexport2b.nim | 2 ++
 tests/modules/texport2.nim  | 3 ++-
 4 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 287a11b33..1ceec7fbe 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1943,8 +1943,7 @@ proc semExport(c: PContext, n: PNode): PNode =
     var o: TOverloadIter
     var s = initOverloadIter(o, c, a)
     if s == nil:
-      localError(a.info, errGenerated, "invalid expr for 'export': " &
-          renderTree(a))
+      localError(a.info, errGenerated, "cannot export: " & renderTree(a))
     elif s.kind == skModule:
       # forward everything from that module:
       strTableAdd(c.module.tab, s)
diff --git a/tests/modules/mexport2a.nim b/tests/modules/mexport2a.nim
index deaef8fa4..3cf84337e 100644
--- a/tests/modules/mexport2a.nim
+++ b/tests/modules/mexport2a.nim
@@ -3,3 +3,5 @@ import mexport2b
 export mexport2b
 proc printAbc*() = echo "abc"
 
+proc foo*() = echo "A.foo"
+
diff --git a/tests/modules/mexport2b.nim b/tests/modules/mexport2b.nim
index 8ea6085de..1af034133 100644
--- a/tests/modules/mexport2b.nim
+++ b/tests/modules/mexport2b.nim
@@ -1 +1,3 @@
 proc printXyz*() = echo "xyz"
+
+proc foo*(x: int) = echo "B.foo"
diff --git a/tests/modules/texport2.nim b/tests/modules/texport2.nim
index 0826eec9d..6e55873c5 100644
--- a/tests/modules/texport2.nim
+++ b/tests/modules/texport2.nim
@@ -1,4 +1,4 @@
-# bug #1595
+# bug #1595, #1612
 
 import mexport2a
 
@@ -8,3 +8,4 @@ proc main() =
   printXyz()
 
 main()
+foo(3)

From ead00d2328507b3ee70f3d49a74d94d946729e14 Mon Sep 17 00:00:00 2001
From: Reimer Behrends 
Date: Thu, 6 Nov 2014 02:09:51 +0100
Subject: [PATCH 223/409] Properly initialize the stack with emulated thread
 variables.

---
 compiler/cgen.nim | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index afeac8c88..8e20ba654 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -1061,8 +1061,7 @@ proc genMainProc(m: BModule) =
     gBreakpoints.app(m.genFilenames)
   
   let initStackBottomCall =
-    if emulatedThreadVars() or
-      platform.targetOS == osStandalone: "".toRope
+    if platform.targetOS == osStandalone: "".toRope
     else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N")
   inc(m.labels)
   appcg(m, m.s[cfsProcs], PreMainBody, [

From c43e7c4ff6929c4da5feba68f905d58daceb5e84 Mon Sep 17 00:00:00 2001
From: Reimer Behrends 
Date: Thu, 6 Nov 2014 02:23:40 +0100
Subject: [PATCH 224/409] Remove references to pthread_mutex_timedlock().

The pthread_mutex_timedlock() function is not supported on a number
of architectures and is not actually used by the library or compiler,
but prevents C++ compilation on systems that do not support it when
threads are enabled.
---
 lib/system/threads.nim | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/lib/system/threads.nim b/lib/system/threads.nim
index 7dac9d9aa..287c6db95 100644
--- a/lib/system/threads.nim
+++ b/lib/system/threads.nim
@@ -116,16 +116,6 @@ else:
   proc pthread_cancel(a1: TSysThread): cint {.
     importc: "pthread_cancel", header: "".}
 
-  proc acquireSysTimeoutAux(L: var TSysLock, timeout: var Ttimespec): cint {.
-    importc: "pthread_mutex_timedlock", header: "".}
-
-  proc acquireSysTimeout(L: var TSysLock, msTimeout: int) {.inline.} =
-    var a: Ttimespec
-    a.tv_sec = msTimeout div 1000
-    a.tv_nsec = (msTimeout mod 1000) * 1000
-    var res = acquireSysTimeoutAux(L, a)
-    if res != 0'i32: raise newException(EResourceExhausted, $strerror(res))
-
   type
     TThreadVarSlot {.importc: "pthread_key_t", pure, final,
                    header: "".} = object

From b5586264a0e0515f88f7ad4944bb987930fbd7b9 Mon Sep 17 00:00:00 2001
From: Araq 
Date: Fri, 7 Nov 2014 00:27:31 +0100
Subject: [PATCH 225/409] broken attempt to fix queue exhaustion

---
 lib/pure/concurrency/threadpool.nim | 50 +++++++++++++----------
 tests/parallel/tconvexhull.nim      | 62 +++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 21 deletions(-)
 create mode 100644 tests/parallel/tconvexhull.nim

diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim
index fbd344e4e..727bbffa2 100644
--- a/lib/pure/concurrency/threadpool.nim
+++ b/lib/pure/concurrency/threadpool.nim
@@ -100,7 +100,7 @@ type
     # for 'awaitAny' support
     ai: ptr AwaitInfo
     idx: int
-    data: pointer  # we incRef and unref it to keep it alive
+    data: RootRef  # we incRef and unref it to keep it alive
     owner: pointer # ptr Worker
 
   FlowVarObj[T] = object of FlowVarBaseObj
@@ -112,7 +112,7 @@ type
     len: int
     lock: TLock
     empty: TCond
-    data: array[512, pointer]
+    data: array[2, pointer]
 
   WorkerProc = proc (thread, args: pointer) {.nimcall, gcsafe.}
   Worker = object
@@ -134,6 +134,22 @@ proc await*(fv: FlowVarBase) =
     await(fv.cv)
     destroyCondVar(fv.cv)
 
+proc selectWorker(w: ptr Worker; fn: WorkerProc; data: pointer): bool =
+  if cas(addr w.ready, true, false):
+    w.data = data
+    w.f = fn
+    signal(w.taskArrived)
+    await(w.taskStarted)
+    result = true
+
+proc wakeupWorkerToProcessQueue(w: ptr Worker) =
+  # Note that if this fails somebody else already woke up the thread so it's
+  # perfectly fine to do nothing:
+  if cas(addr w.ready, true, false):
+    w.data = nil
+    w.f = proc (t, a: pointer) {.nimcall.} = discard
+    signal(w.taskArrived)
+
 proc finished(fv: FlowVarBase) =
   doAssert fv.ai.isNil, "flowVar is still attached to an 'awaitAny'"
   # we have to protect against the rare cases where the owner of the flowVar
@@ -144,18 +160,17 @@ proc finished(fv: FlowVarBase) =
   let owner = cast[ptr Worker](fv.owner)
   let q = addr(owner.q)
   var waited = false
-  while true:
+  acquire(q.lock)
+  while not (q.len < q.data.len):
+    echo "EXHAUSTED!"
+    release(q.lock)
+    wakeupWorkerToProcessQueue(owner)
     acquire(q.lock)
-    if q.len < q.data.len:
-      q.data[q.len] = fv.data
-      inc q.len
-      release(q.lock)
-      break
-    else:
-      # the queue is exhausted! We block until it has been cleaned:
-      release(q.lock)
-      wait(q.empty, q.lock)
-      waited = true
+    wait(q.empty, q.lock)
+    waited = true
+  q.data[q.len] = cast[pointer](fv.data)
+  inc q.len
+  release(q.lock)
   fv.data = nil
   # wakeup other potentially waiting threads:
   if waited: signal(q.empty)
@@ -165,6 +180,7 @@ proc cleanFlowVars(w: ptr Worker) =
   acquire(q.lock)
   for i in 0 ..  0 and cross(result[lr1 - 1], result[lr1], p[i]) <= 0:
+    discard result.pop
+    lr1 -= 1
+  result.add(p[i])
+  lr1 += 1
+
+proc half[T](p: seq[T]; upper: bool): seq[T] =
+  var i, lr1: int
+  result = @[]
+  lr1 = -1
+  if upper:
+    i = 0
+    while i <= high(p):
+      pro()
+      i += 1
+  else:
+    i = high(p)
+    while i >= low(p):
+      pro()
+      i -= 1
+  discard result.pop
+
+proc convex_hull[T](points: var seq[T], cmp: proc(x, y: T): int {.closure.}) : seq[T] =
+  if len(points) < 2: return points
+  points.sort(cmp)
+  var ul: array[2, FlowVar[seq[T]]]
+  parallel:
+    for k in 0..ul.high:
+      ul[k] = spawn half[T](points, k == 0)
+  result = concat(^ul[0], ^ul[1])
+
+var s = map(toSeq(0..999999), proc(x: int): Point = (float(x div 1000), float(x mod 1000)))
+setMaxPoolSize 2
+
+#echo convex_hull[Point](s, cmpPoint)
+for i in 0..5:
+  echo convex_hull[Point](s, cmpPoint) ==
+      @[(0.0, 0.0), (999.0, 0.0), (999.0, 999.0), (0.0, 999.0)]

From f31c62315fae230d1146a140838be8806eaa0950 Mon Sep 17 00:00:00 2001
From: Erik O'Leary 
Date: Thu, 6 Nov 2014 18:41:21 -0600
Subject: [PATCH 226/409] Made 'headers' public

---
 lib/pure/httpclient.nim | 88 ++++++++++++++++++++---------------------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index 892ddac40..81314e967 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -17,27 +17,27 @@
 ##
 ## Retrieving a website
 ## ====================
-## 
+##
 ## This example uses HTTP GET to retrieve
 ## ``http://google.com``
-## 
+##
 ## .. code-block:: Nim
 ##   echo(getContent("http://google.com"))
-## 
+##
 ## Using HTTP POST
 ## ===============
-## 
-## This example demonstrates the usage of the W3 HTML Validator, it 
+##
+## This example demonstrates the usage of the W3 HTML Validator, it
 ## uses ``multipart/form-data`` as the ``Content-Type`` to send the HTML to
-## the server. 
-## 
+## the server.
+##
 ## .. code-block:: Nim
 ##   var headers: string = "Content-Type: multipart/form-data; boundary=xyz\c\L"
 ##   var body: string = "--xyz\c\L"
 ##   # soap 1.2 output
 ##   body.add("Content-Disposition: form-data; name=\"output\"\c\L")
 ##   body.add("\c\Lsoap12\c\L")
-##    
+##
 ##   # html
 ##   body.add("--xyz\c\L")
 ##   body.add("Content-Disposition: form-data; name=\"uploaded_file\";" &
@@ -45,7 +45,7 @@
 ##   body.add("Content-Type: text/html\c\L")
 ##   body.add("\c\L

test

\c\L") ## body.add("--xyz--") -## +## ## echo(postContent("http://validator.w3.org/check", headers, body)) ## ## Asynchronous HTTP requests @@ -95,8 +95,8 @@ from net import nil type Response* = tuple[ - version: string, - status: string, + version: string, + status: string, headers: StringTableRef, body: string] @@ -108,7 +108,7 @@ type ## does not conform to the implemented ## protocol - HttpRequestError* = object of IOError ## Thrown in the ``getContent`` proc + HttpRequestError* = object of IOError ## Thrown in the ``getContent`` proc ## and ``postContent`` proc, ## when the server returns an error @@ -123,7 +123,7 @@ proc httpError(msg: string) = new(e) e.msg = msg raise e - + proc fileError(msg: string) = var e: ref IOError new(e) @@ -167,7 +167,7 @@ proc parseChunks(s: TSocket, timeout: int): string = s.skip(2, timeout) # Skip \c\L # Trailer headers will only be sent if the request specifies that we want # them: http://tools.ietf.org/html/rfc2616#section-3.6.1 - + proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = result = "" if headers["Transfer-Encoding"] == "chunked": @@ -191,7 +191,7 @@ proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = " got: " & $received) else: # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO - + # -REGION- Connection: Close # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.5 if headers["Connection"] == "close": @@ -241,7 +241,7 @@ proc parseResponse(s: TSocket, getBody: bool, timeout: int): TResponse = inc(linei, le) if line[linei] != ':': httpError("invalid headers") inc(linei) # Skip : - + result.headers[name] = line[linei.. -1].strip() if not fullyRead: httpError("Connection was closed before full request has been made") @@ -256,17 +256,17 @@ type ## correspond to a GET request, but without the response ## body. httpGET, ## Retrieves the specified resource. - httpPOST, ## Submits data to be processed to the identified - ## resource. The data is included in the body of the + httpPOST, ## Submits data to be processed to the identified + ## resource. The data is included in the body of the ## request. httpPUT, ## Uploads a representation of the specified resource. httpDELETE, ## Deletes the specified resource. - httpTRACE, ## Echoes back the received request, so that a client + httpTRACE, ## Echoes back the received request, so that a client ## can see what intermediate servers are adding or ## changing in the request. - httpOPTIONS, ## Returns the HTTP methods that the server supports + httpOPTIONS, ## Returns the HTTP methods that the server supports ## for specified address. - httpCONNECT ## Converts the request connection to a transparent + httpCONNECT ## Converts the request connection to a transparent ## TCP/IP tunnel, usually used for proxies. {.deprecated: [THttpMethod: HttpMethod].} @@ -281,7 +281,7 @@ proc newProxy*(url: string, auth = ""): PProxy = ## Constructs a new ``TProxy`` object. result = PProxy(url: parseUrl(url), auth: auth) -proc request*(url: string, httpMethod = httpGET, extraHeaders = "", +proc request*(url: string, httpMethod = httpGET, extraHeaders = "", body = "", sslContext: PSSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, @@ -298,7 +298,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", headers.add(" " & url) headers.add(" HTTP/1.1\c\L") - + add(headers, "Host: " & r.hostname & "\c\L") if userAgent != "": add(headers, "User-Agent: " & userAgent & "\c\L") @@ -307,7 +307,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", add(headers, "Proxy-Authorization: basic " & auth & "\c\L") add(headers, extraHeaders) add(headers, "\c\L") - + var s = socket() if s == invalidSocket: raiseOSError(osLastError()) var port = sockets.TPort(80) @@ -320,7 +320,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", "SSL support is not available. Cannot connect over SSL.") if r.port != "": port = sockets.TPort(r.port.parseInt) - + if timeout == -1: s.connect(r.hostname, port) else: @@ -328,10 +328,10 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", s.send(headers) if body != "": s.send(body) - + result = parseResponse(s, httpMethod != httpHEAD, timeout) s.close() - + proc redirection(status: string): bool = const redirectionNRs = ["301", "302", "303", "307"] for i in items(redirectionNRs): @@ -346,7 +346,7 @@ proc getNewLocation(lastUrl: string, headers: PStringTable): string = if r.hostname == "" and r.path != "": let origParsed = parseURL(lastUrl) result = origParsed.hostname & "/" & r.path - + proc get*(url: string, extraHeaders = "", maxRedirects = 5, sslContext: PSSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, @@ -365,7 +365,7 @@ proc get*(url: string, extraHeaders = "", maxRedirects = 5, result = request(redirectTo, httpGET, extraHeaders, "", sslContext, timeout, userAgent, proxy) lastUrl = redirectTo - + proc getContent*(url: string, extraHeaders = "", maxRedirects = 5, sslContext: PSSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, @@ -381,7 +381,7 @@ proc getContent*(url: string, extraHeaders = "", maxRedirects = 5, raise newException(EHTTPRequestErr, r.status) else: return r.body - + proc post*(url: string, extraHeaders = "", body = "", maxRedirects = 5, sslContext: PSSLContext = defaultSSLContext, @@ -404,7 +404,7 @@ proc post*(url: string, extraHeaders = "", body = "", result = request(redirectTo, meth, xh, body, sslContext, timeout, userAgent, proxy) lastUrl = redirectTo - + proc postContent*(url: string, extraHeaders = "", body = "", maxRedirects = 5, sslContext: PSSLContext = defaultSSLContext, @@ -421,7 +421,7 @@ proc postContent*(url: string, extraHeaders = "", body = "", raise newException(EHTTPRequestErr, r.status) else: return r.body - + proc downloadFile*(url: string, outputFilename: string, sslContext: PSSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, @@ -456,7 +456,7 @@ type socket: AsyncSocket connected: bool currentURL: TURL ## Where we are currently connected. - headers: StringTableRef + headers*: StringTableRef maxRedirects: int userAgent: string when defined(ssl): @@ -528,7 +528,7 @@ proc parseChunks(client: PAsyncHttpClient): Future[string] {.async.} = discard await recvFull(client.socket, 2) # Skip \c\L # Trailer headers will only be sent if the request specifies that we want # them: http://tools.ietf.org/html/rfc2616#section-3.6.1 - + proc parseBody(client: PAsyncHttpClient, headers: PStringTable): Future[string] {.async.} = result = "" @@ -549,7 +549,7 @@ proc parseBody(client: PAsyncHttpClient, $length & " got " & $result.len) else: # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO - + # -REGION- Connection: Close # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.5 if headers["Connection"] == "close": @@ -598,7 +598,7 @@ proc parseResponse(client: PAsyncHttpClient, inc(linei, le) if line[linei] != ':': httpError("invalid headers") inc(linei) # Skip : - + result.headers[name] = line[linei.. -1].strip() if not fullyRead: httpError("Connection was closed before full request has been made") @@ -621,14 +621,14 @@ proc newConnection(client: PAsyncHttpClient, url: TURL) {.async.} = else: rawsockets.TPort(80) else: rawsockets.TPort(url.port.parseInt) - + if url.scheme.toLower() == "https": when defined(ssl): client.sslContext.wrapSocket(client.socket) else: raise newException(EHttpRequestErr, "SSL support is not available. Cannot connect over SSL.") - + await client.socket.connect(url.hostname, port) client.currentURL = url client.connected = true @@ -648,13 +648,13 @@ proc request*(client: PAsyncHttpClient, url: string, httpMethod = httpGET, if not client.headers.hasKey("user-agent") and client.userAgent != "": client.headers["User-Agent"] = client.userAgent - + var headers = generateHeaders(r, httpMethod, client.headers) - + await client.socket.send(headers) if body != "": await client.socket.send(body) - + result = await parseResponse(client, httpMethod != httpHEAD) proc get*(client: PAsyncHttpClient, url: string): Future[TResponse] {.async.} = @@ -676,7 +676,7 @@ when isMainModule: proc main() {.async.} = var client = newAsyncHttpClient() var resp = await client.request("http://picheta.me") - + echo("Got response: ", resp.status) echo("Body:\n") echo(resp.body) @@ -703,13 +703,13 @@ when isMainModule: #var r = get("http://validator.w3.org/check?uri=http%3A%2F%2Fgoogle.com& # charset=%28detect+automatically%29&doctype=Inline&group=0") - + var headers: string = "Content-Type: multipart/form-data; boundary=xyz\c\L" var body: string = "--xyz\c\L" # soap 1.2 output body.add("Content-Disposition: form-data; name=\"output\"\c\L") body.add("\c\Lsoap12\c\L") - + # html body.add("--xyz\c\L") body.add("Content-Disposition: form-data; name=\"uploaded_file\";" & From 06e9932e8ae6860b1c96c57138d2d56e51f7036d Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 7 Nov 2014 01:54:47 +0100 Subject: [PATCH 227/409] fixes exhaustion bug and missing GC_ref code generation --- compiler/lowerings.nim | 6 ++++++ lib/pure/concurrency/threadpool.nim | 9 ++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 8e5ffd48a..ae19f5366 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -286,6 +286,12 @@ proc createWrapperProc(f: PNode; threadParam, argsParam: PSym; typeToString(fv.typ.sons[1])) body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode, if fk == fvGC: "data" else: "blob", fv.info), call) + if fk == fvGC: + let incRefCall = newNodeI(nkCall, fv.info, 2) + incRefCall.sons[0] = newSymNode(createMagic("GCref", mGCref)) + incRefCall.sons[1] = indirectAccess(threadLocalProm.newSymNode, + "data", fv.info) + body.add incRefCall if barrier == nil: # by now 'fv' is shared and thus might have beeen overwritten! we need # to use the thread-local view instead: diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 727bbffa2..7959a6c92 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -100,7 +100,8 @@ type # for 'awaitAny' support ai: ptr AwaitInfo idx: int - data: RootRef # we incRef and unref it to keep it alive + data: pointer # we incRef and unref it to keep it alive; note this MUST NOT + # be RootRef here otherwise the wrong GC keeps track of it! owner: pointer # ptr Worker FlowVarObj[T] = object of FlowVarBaseObj @@ -162,10 +163,8 @@ proc finished(fv: FlowVarBase) = var waited = false acquire(q.lock) while not (q.len < q.data.len): - echo "EXHAUSTED!" - release(q.lock) + #echo "EXHAUSTED!" wakeupWorkerToProcessQueue(owner) - acquire(q.lock) wait(q.empty, q.lock) waited = true q.data[q.len] = cast[pointer](fv.data) @@ -180,7 +179,7 @@ proc cleanFlowVars(w: ptr Worker) = acquire(q.lock) for i in 0 .. Date: Fri, 7 Nov 2014 14:48:11 +0000 Subject: [PATCH 228/409] Implement SO_REUSEADDR for asyncnet and asynchttpserver. --- lib/pure/asynchttpserver.nim | 6 +++++- lib/pure/asyncnet.nim | 13 +++++++++++++ lib/pure/net.nim | 3 ++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 257fbaeb5..f40090c64 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -37,6 +37,7 @@ type AsyncHttpServer* = ref object socket: PAsyncSocket + reuseAddr: bool HttpCode* = enum Http200 = "200 OK", @@ -64,9 +65,10 @@ proc `==`*(protocol: tuple[orig: string, major, minor: int], of HttpVer10: 0 result = protocol.major == major and protocol.minor == minor -proc newAsyncHttpServer*(): PAsyncHttpServer = +proc newAsyncHttpServer*(reuseAddr = true): PAsyncHttpServer = ## Creates a new ``AsyncHttpServer`` instance. new result + result.reuseAddr = reuseAddr proc addHeaders(msg: var string, headers: PStringTable) = for k, v in headers: @@ -210,6 +212,8 @@ proc serve*(server: PAsyncHttpServer, port: Port, ## ## When a request is made by a client the specified callback will be called. server.socket = newAsyncSocket() + if server.reuseAddr: + server.socket.setSockOpt(OptReuseAddr, true) server.socket.bindAddr(port, address) server.socket.listen() diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 72fe51a7e..7028a358d 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -60,6 +60,8 @@ import rawsockets import net import os +export SOBool + when defined(ssl): import openssl @@ -425,6 +427,17 @@ when defined(ssl): socket.bioOut = bioNew(bio_s_mem()) sslSetBio(socket.sslHandle, socket.bioIn, socket.bioOut) +proc getSockOpt*(socket: AsyncSocket, opt: SOBool, level = SOL_SOCKET): bool {. + tags: [ReadIOEffect].} = + ## Retrieves option ``opt`` as a boolean value. + var res = getSockOptInt(socket.fd, cint(level), toCInt(opt)) + result = res != 0 + +proc setSockOpt*(socket: AsyncSocket, opt: SOBool, value: bool, + level = SOL_SOCKET) {.tags: [WriteIOEffect].} = + ## Sets option ``opt`` to a boolean value specified by ``value``. + var valuei = cint(if value: 1 else: 0) + setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei) when isMainModule: type diff --git a/lib/pure/net.nim b/lib/pure/net.nim index f63f5fff8..2b2c8cfda 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -428,7 +428,8 @@ proc close*(socket: Socket) = elif res != 1: socketError(socket) -proc toCInt(opt: SOBool): cint = +proc toCInt*(opt: SOBool): cint = + ## Converts a ``SOBool`` into its Socket Option cint representation. case opt of OptAcceptConn: SO_ACCEPTCONN of OptBroadcast: SO_BROADCAST From 943d4ee71448f7efd2a7feb1126a401f68573979 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 8 Nov 2014 11:18:25 +0100 Subject: [PATCH 229/409] fixed the deadlock that happens when stress testing ToFreeQueue --- lib/pure/concurrency/threadpool.nim | 55 ++++++++++++++++------------- tests/parallel/tdeepcopy2.nim | 2 +- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 7959a6c92..1e1f0c26d 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -112,8 +112,8 @@ type ToFreeQueue = object len: int lock: TLock - empty: TCond - data: array[2, pointer] + empty: CondVar + data: array[128, pointer] WorkerProc = proc (thread, args: pointer) {.nimcall, gcsafe.} Worker = object @@ -143,13 +143,27 @@ proc selectWorker(w: ptr Worker; fn: WorkerProc; data: pointer): bool = await(w.taskStarted) result = true +proc cleanFlowVars(w: ptr Worker) = + let q = addr(w.q) + acquire(q.lock) + for i in 0 .. Date: Sat, 8 Nov 2014 11:19:15 +0100 Subject: [PATCH 230/409] TAtomType includes 'bool' --- lib/system/atomics.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 5e5c72fae..f816c8201 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -37,7 +37,7 @@ when someGcc and hasThreadSupport: ## and release stores in all threads. type - TAtomType* = TNumber|pointer|ptr|char + TAtomType* = SomeNumber|pointer|ptr|char|bool ## Type Class representing valid types for use with atomic procs proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {. @@ -204,16 +204,16 @@ else: when (defined(x86) or defined(amd64)) and someGcc: - proc cpuRelax {.inline.} = + proc cpuRelax* {.inline.} = {.emit: """asm volatile("pause" ::: "memory");""".} elif (defined(x86) or defined(amd64)) and defined(vcc): - proc cpuRelax {.importc: "YieldProcessor", header: "".} + proc cpuRelax* {.importc: "YieldProcessor", header: "".} elif defined(icl): - proc cpuRelax {.importc: "_mm_pause", header: "xmmintrin.h".} + proc cpuRelax* {.importc: "_mm_pause", header: "xmmintrin.h".} elif false: from os import sleep - proc cpuRelax {.inline.} = os.sleep(1) + proc cpuRelax* {.inline.} = os.sleep(1) when not declared(fence) and hasThreadSupport: # XXX fixme From 830e0c0009d25d84a26fc997722eee4ecd015fd9 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 8 Nov 2014 15:47:00 +0100 Subject: [PATCH 231/409] the codegen doesn't emit deepCopy for parallel statements --- compiler/lowerings.nim | 27 ++++++++++------- compiler/nimconf.nim | 8 +++-- readme.md | 6 ++-- tests/parallel/tconvexhull.nim | 2 ++ tests/parallel/tdeepcopy2.nim | 8 ++--- todo.txt | 5 ++-- web/community.txt | 54 +++++++++++++++++----------------- web/index.txt | 4 +-- web/news.txt | 2 ++ 9 files changed, 64 insertions(+), 52 deletions(-) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index ae19f5366..661472a05 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -204,7 +204,7 @@ proc flowVarKind(t: PType): TFlowVarKind = else: fvBlob proc addLocalVar(varSection, varInit: PNode; owner: PSym; typ: PType; - v: PNode): PSym = + v: PNode; useShallowCopy=false): PSym = result = newSym(skTemp, getIdent(genPrefix), owner, varSection.info) result.typ = typ incl(result.flags, sfFromGeneric) @@ -215,11 +215,14 @@ proc addLocalVar(varSection, varInit: PNode; owner: PSym; typ: PType; vpart.sons[2] = if varInit.isNil: v else: ast.emptyNode varSection.add vpart if varInit != nil: - let deepCopyCall = newNodeI(nkCall, varInit.info, 3) - deepCopyCall.sons[0] = newSymNode(createMagic("deepCopy", mDeepCopy)) - deepCopyCall.sons[1] = newSymNode(result) - deepCopyCall.sons[2] = v - varInit.add deepCopyCall + if useShallowCopy: + varInit.add newFastAsgnStmt(newSymNode(result), v) + else: + let deepCopyCall = newNodeI(nkCall, varInit.info, 3) + deepCopyCall.sons[0] = newSymNode(createMagic("deepCopy", mDeepCopy)) + deepCopyCall.sons[1] = newSymNode(result) + deepCopyCall.sons[2] = v + varInit.add deepCopyCall discard """ We generate roughly this: @@ -420,7 +423,8 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym; result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), n[3]) let threadLocal = addLocalVar(varSection,nil, objType.owner, fieldA.typ, - indirectAccess(castExpr, fieldA, n.info)) + indirectAccess(castExpr, fieldA, n.info), + useShallowCopy=true) slice.sons[2] = threadLocal.newSymNode else: let a = genAddrOf(n) @@ -434,7 +438,8 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym; slice.sons[1] = genDeref(indirectAccess(castExpr, field, n.info)) let threadLocal = addLocalVar(varSection,nil, objType.owner, fieldB.typ, - indirectAccess(castExpr, fieldB, n.info)) + indirectAccess(castExpr, fieldB, n.info), + useShallowCopy=true) slice.sons[3] = threadLocal.newSymNode call.add slice elif (let size = computeSize(argType); size < 0 or size > 16) and @@ -445,7 +450,8 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym; objType.addField(field) result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a) let threadLocal = addLocalVar(varSection,nil, objType.owner, field.typ, - indirectAccess(castExpr, field, n.info)) + indirectAccess(castExpr, field, n.info), + useShallowCopy=true) call.add(genDeref(threadLocal.newSymNode)) else: # boring case @@ -454,7 +460,8 @@ proc setupArgsForParallelism(n: PNode; objType: PType; scratchObj: PSym; result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n) let threadLocal = addLocalVar(varSection, varInit, objType.owner, field.typ, - indirectAccess(castExpr, field, n.info)) + indirectAccess(castExpr, field, n.info), + useShallowCopy=true) call.add(threadLocal.newSymNode) proc wrapProcForSpawn*(owner: PSym; spawnExpr: PNode; retType: PType; diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index 98fe831d3..bcf9b5359 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -113,7 +113,7 @@ proc parseDirective(L: var TLexer, tok: var TToken) = case whichKeyword(tok.ident) of wIf: setLen(condStack, len(condStack) + 1) - var res = evalppIf(L, tok) + let res = evalppIf(L, tok) condStack[high(condStack)] = res if not res: jumpToDirective(L, tok, jdElseEndif) of wElif: doElif(L, tok) @@ -224,8 +224,10 @@ proc loadConfigs*(cfg: string) = if libpath == "": # choose default libpath: var prefix = getPrefixDir() - if prefix == "/usr": libpath = "/usr/lib/nim" - elif prefix == "/usr/local": libpath = "/usr/local/lib/nim" + when defined(posix): + if prefix == "/usr": libpath = "/usr/lib/nim" + elif prefix == "/usr/local": libpath = "/usr/local/lib/nim" + else: libpath = joinPath(prefix, "lib") else: libpath = joinPath(prefix, "lib") if optSkipConfigFile notin gGlobalOptions: diff --git a/readme.md b/readme.md index a2f83b4b0..3cc007e3b 100644 --- a/readme.md +++ b/readme.md @@ -30,9 +30,9 @@ To build from source you will need: If you are on a fairly modern *nix system, the following steps should work: ``` -$ git clone git://github.com/Araq/Nimrod.git -$ cd Nimrod -$ git clone --depth 1 git://github.com/nimrod-code/csources +$ git clone git://github.com/Araq/Nim.git +$ cd Nim +$ git clone --depth 1 git://github.com/nim-code/csources $ cd csources && sh build.sh $ cd .. $ bin/nim c koch diff --git a/tests/parallel/tconvexhull.nim b/tests/parallel/tconvexhull.nim index c97fed39b..d7e4f7716 100644 --- a/tests/parallel/tconvexhull.nim +++ b/tests/parallel/tconvexhull.nim @@ -5,6 +5,8 @@ true true true true''' + +ccodeCheck: "!'deepcopy('" """ # parallel convex hull for Nim bigbreak diff --git a/tests/parallel/tdeepcopy2.nim b/tests/parallel/tdeepcopy2.nim index eca19f639..8ffdcc5f2 100644 --- a/tests/parallel/tdeepcopy2.nim +++ b/tests/parallel/tdeepcopy2.nim @@ -27,9 +27,9 @@ proc main = var dummy: ref Bar[int] new(dummy) dummy.x = 44 - parallel: - let f = spawn foo(dummy) - let b = spawn foo(dummy) - echo "done", f, " ", b + #parallel: + let f = spawn foo(dummy) + let b = spawn foo(dummy) + echo "done", ^f, " ", ^b main() diff --git a/todo.txt b/todo.txt index a45a4f50a..52b26f006 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,8 @@ version 0.10 ============ -- fix missing GC_ref bug for flow variables -- fix deepCopy bug in parallel section -- implement 'static_call' +- find out why global installations end up using the wrong stdlib +- implement 'procCall' - make nimble part of the distribution - split idetools into separate tool - split docgen into separate tool diff --git a/web/community.txt b/web/community.txt index d45e7df61..958f7aea1 100644 --- a/web/community.txt +++ b/web/community.txt @@ -1,74 +1,74 @@ Forum ===== -The `Nimrod forum `_ is the place where most +The `Nim forum `_ is the place where most discussions related to the language happen. It not only includes discussions -relating to the design of Nimrod but also allows for beginners to ask questions -relating to Nimrod. +relating to the design of Nim but also allows for beginners to ask questions +relating to Nim. IRC ==== -Many Nimrod developers are a part of the -`#nimrod IRC channel `_ on -Freenode. That is the place where the rest of the discussion relating to Nimrod -occurs. Be sure to join us there if you wish to discuss Nimrod in real-time. -IRC is the perfect place for people just starting to learn Nimrod and we +Many Nim developers are a part of the +`#nim IRC channel `_ on +Freenode. That is the place where the rest of the discussion relating to Nim +occurs. Be sure to join us there if you wish to discuss Nim in real-time. +IRC is the perfect place for people just starting to learn Nim and we welcome any questions that you may have! You may also be interested in reading the -`IRC logs `_ which are an archive of all +`IRC logs `_ which are an archive of all of the previous discussions that took place in the IRC channel. Github ====== -Nimrod's `source code `_ is hosted on Github. -Together with the `wiki `_ and -`issue tracker `_. +Nim's `source code `_ is hosted on Github. +Together with the `wiki `_ and +`issue tracker `_. -Github also hosts other projects relating to Nimrod. These projects are a part -of the `nimrod-code organisation `_. -This includes the `Babel package manager `_ -and its `package repository `_. +Github also hosts other projects relating to Nim. These projects are a part +of the `nim-code organisation `_. +This includes the `Babel package manager `_ +and its `package repository `_. Twitter ======= -Follow us `@nimrodlang `_ for latest news about -Nimrod. +Follow us `@nimlang `_ for latest news about +Nim. Reddit ====== -Subscribe to `/r/nimrod `_ for latest news about -Nimrod. +Subscribe to `/r/nim `_ for latest news about +Nim. StackOverflow ============= -When asking a question relating to Nimrod, be sure to use the -`Nimrod `_ tag in your +When asking a question relating to Nim, be sure to use the +`Nim `_ tag in your question. How to help =========== There are always many things to be done in the main -`Nimrod repository `_, check out the -`issues `_ for +`Nim repository `_, check out the +`issues `_ for things to do; pull requests are always welcome. You can also contribute to the many other projects hosted by the -`nimrod-code `_ organisation on github. If you +`nim-code `_ organisation on github. If you can't find anything you fancy doing, you can always ask for inspiration on IRC -(irc.freenode.net #nimrod) or on the `Nimrod forums `_. +(irc.freenode.net #nim) or on the `Nim forums `_. Donations --------- If you love what we do and are feeling generous then you can always donate. Contributions of any quantity are greatly appreciated and will contribute to -making Nimrod even better! +making Nim even better! Gittip `````` diff --git a/web/index.txt b/web/index.txt index 04c953628..e48c54f17 100644 --- a/web/index.txt +++ b/web/index.txt @@ -92,7 +92,7 @@ Nim plays nice with others the POSIX API, OpenGL, SDL, Cairo, Python, Lua, TCL, X11, libzip, PCRE, libcurl, mySQL and SQLite are included in the standard distribution or can easily be obtained via the - `Babel package manager `_. + `Nimble package manager `_. * A C to Nim conversion utility: New bindings to C libraries are easily generated by ``c2nim``. @@ -101,5 +101,5 @@ Roadmap to 1.0 ============== Please have a look at -this `wiki page `_ for +this `wiki page `_ for an up-to-date overview. diff --git a/web/news.txt b/web/news.txt index 2f2290b5b..2a9c24231 100644 --- a/web/news.txt +++ b/web/news.txt @@ -9,6 +9,8 @@ News Changes affecting backwards compatibility ----------------------------------------- + - **The language has been renamed from Nimrod to Nim.** The name of the + compiler changed from ``nimrod`` to ``nim`` too. - ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to prevent name conflicts with the new type ``FileHandle``. - Comments are now not part of the AST, as such you cannot use them in place From ea57f340f2870f1c08d00ff1c2ef18e94c40f9b0 Mon Sep 17 00:00:00 2001 From: def Date: Sat, 8 Nov 2014 15:54:48 +0100 Subject: [PATCH 232/409] Fix compile because of case sensitivity --- lib/core/locks.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/locks.nim b/lib/core/locks.nim index 42a3aec7b..817d84858 100644 --- a/lib/core/locks.nim +++ b/lib/core/locks.nim @@ -45,7 +45,7 @@ var when noDeadlocks: var locksLen {.threadvar.}: int - locks {.threadvar.}: array [0..MaxLocksPerThread-1, pointer] + locks {.threadvar.}: array [0..maxLocksPerThread-1, pointer] proc orderedLocks(): bool = for i in 0 .. locksLen-2: From b6e006fbbe0db7c786e4fb4a3039d544991e380c Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 10 Nov 2014 01:33:25 +0100 Subject: [PATCH 233/409] fixes #1646 --- readme.md | 4 ++-- tests/parallel/t5000.nim | 22 ++++++++++++++++++++++ todo.txt | 3 +-- tools/niminst/niminst.nim | 2 +- web/community.txt | 12 ++++++------ 5 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 tests/parallel/t5000.nim diff --git a/readme.md b/readme.md index 3cc007e3b..8a4cd93b3 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,7 @@ documentation. Compiling the Nim compiler is quite straightforward. Because the Nim compiler itself is written in the Nim programming language the C source of an older version of the compiler are needed to bootstrap the -latest version. The C sources are available in a separate repo [here](http://github.com/nim-code/csources). +latest version. The C sources are available in a separate repo [here](http://github.com/nim-lang/csources). Pre-compiled snapshots of the compiler are also available on [Nimbuild](http://build.nim-lang.org/). Your platform however may not @@ -32,7 +32,7 @@ If you are on a fairly modern *nix system, the following steps should work: ``` $ git clone git://github.com/Araq/Nim.git $ cd Nim -$ git clone --depth 1 git://github.com/nim-code/csources +$ git clone --depth 1 git://github.com/nim-lang/csources $ cd csources && sh build.sh $ cd .. $ bin/nim c koch diff --git a/tests/parallel/t5000.nim b/tests/parallel/t5000.nim new file mode 100644 index 000000000..025c327fa --- /dev/null +++ b/tests/parallel/t5000.nim @@ -0,0 +1,22 @@ +discard """ + output: '''50005000''' +""" + +import threadpool, strutils + +proc foo(x: int): string = $x + +proc main() = + var a = newSeq[int]() + for i in 1..10000: + add(a, i) + + var s = 0 + for i in a: + s += parseInt(^spawn(foo(i))) + echo s + +setMaxPoolSize 2 + +parallel: + spawn main() diff --git a/todo.txt b/todo.txt index 52b26f006..a6ea31560 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,8 @@ version 0.10 ============ -- find out why global installations end up using the wrong stdlib -- implement 'procCall' - make nimble part of the distribution +- implement 'procCall' - split idetools into separate tool - split docgen into separate tool diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 022b14209..9ee3eb9b9 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -148,7 +148,7 @@ Options: -h, --help shows this help -v, --version shows the version Compile_options: - will be passed to the Nimrod compiler + will be passed to the Nim compiler """ proc parseCmdLine(c: var TConfigData) = diff --git a/web/community.txt b/web/community.txt index 958f7aea1..bac5e0ada 100644 --- a/web/community.txt +++ b/web/community.txt @@ -17,7 +17,7 @@ IRC is the perfect place for people just starting to learn Nim and we welcome any questions that you may have! You may also be interested in reading the -`IRC logs `_ which are an archive of all +`IRC logs `_ which are an archive of all of the previous discussions that took place in the IRC channel. Github @@ -28,9 +28,9 @@ Together with the `wiki `_ and `issue tracker `_. Github also hosts other projects relating to Nim. These projects are a part -of the `nim-code organisation `_. -This includes the `Babel package manager `_ -and its `package repository `_. +of the `nim-lang organisation `_. +This includes the `Babel package manager `_ +and its `package repository `_. Twitter ======= @@ -59,9 +59,9 @@ There are always many things to be done in the main `issues `_ for things to do; pull requests are always welcome. You can also contribute to the many other projects hosted by the -`nim-code `_ organisation on github. If you +`nim-lang `_ organisation on github. If you can't find anything you fancy doing, you can always ask for inspiration on IRC -(irc.freenode.net #nim) or on the `Nim forums `_. +(irc.freenode.net #nim) or on the `Nim forums `_. Donations --------- From 81353b2dbc6d5b0c0d6624820c77900f3754ea50 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 10 Nov 2014 07:57:19 +0100 Subject: [PATCH 234/409] renamed CondVar to Semaphore --- compiler/lowerings.nim | 2 +- lib/pure/concurrency/threadpool.nim | 52 ++++++++++++++--------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 661472a05..f9f7d6432 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -556,7 +556,7 @@ proc wrapProcForSpawn*(owner: PSym; spawnExpr: PNode; retType: PType; # create flowVar: result.add newFastAsgnStmt(fvField, callProc(spawnExpr[2])) if barrier == nil: - result.add callCodegenProc("nimFlowVarCreateCondVar", fvField) + result.add callCodegenProc("nimFlowVarCreateSemaphore", fvField) elif spawnKind == srByVar: var field = newSym(skField, getIdent"fv", owner, n.info) diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 1e1f0c26d..28ef25d95 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -17,27 +17,27 @@ import cpuinfo, cpuload, locks {.push stackTrace:off.} type - CondVar = object + Semaphore = object c: TCond L: TLock counter: int -proc createCondVar(): CondVar = +proc createSemaphore(): Semaphore = initCond(result.c) initLock(result.L) -proc destroyCondVar(cv: var CondVar) {.inline.} = +proc destroySemaphore(cv: var Semaphore) {.inline.} = deinitCond(cv.c) deinitLock(cv.L) -proc await(cv: var CondVar) = +proc await(cv: var Semaphore) = acquire(cv.L) while cv.counter <= 0: wait(cv.c, cv.L) dec cv.counter release(cv.L) -proc signal(cv: var CondVar) = +proc signal(cv: var Semaphore) = acquire(cv.L) inc cv.counter release(cv.L) @@ -48,7 +48,7 @@ const CacheLineSize = 32 # true for most archs type Barrier {.compilerProc.} = object entered: int - cv: CondVar # condvar takes 3 words at least + cv: Semaphore # Semaphore takes 3 words at least when sizeof(int) < 8: cacheAlign: array[CacheLineSize-4*sizeof(int), byte] left: int @@ -75,12 +75,12 @@ proc openBarrier(b: ptr Barrier) {.compilerProc, inline.} = proc closeBarrier(b: ptr Barrier) {.compilerProc.} = fence() if b.left != b.entered: - b.cv = createCondVar() + b.cv = createSemaphore() fence() b.interest = true fence() while b.left != b.entered: await(b.cv) - destroyCondVar(b.cv) + destroySemaphore(b.cv) {.pop.} @@ -90,13 +90,13 @@ type foreign* = object ## a region that indicates the pointer comes from a ## foreign thread heap. AwaitInfo = object - cv: CondVar + cv: Semaphore idx: int FlowVarBase* = ref FlowVarBaseObj ## untyped base class for 'FlowVar[T]' FlowVarBaseObj = object of RootObj - ready, usesCondVar, awaited: bool - cv: CondVar #\ + ready, usesSemaphore, awaited: bool + cv: Semaphore #\ # for 'awaitAny' support ai: ptr AwaitInfo idx: int @@ -112,13 +112,13 @@ type ToFreeQueue = object len: int lock: TLock - empty: CondVar + empty: Semaphore data: array[128, pointer] WorkerProc = proc (thread, args: pointer) {.nimcall, gcsafe.} Worker = object - taskArrived: CondVar - taskStarted: CondVar #\ + taskArrived: Semaphore + taskStarted: Semaphore #\ # task data: f: WorkerProc data: pointer @@ -130,10 +130,10 @@ type proc await*(fv: FlowVarBase) = ## waits until the value for the flowVar arrives. Usually it is not necessary ## to call this explicitly. - if fv.usesCondVar and not fv.awaited: + if fv.usesSemaphore and not fv.awaited: fv.awaited = true await(fv.cv) - destroyCondVar(fv.cv) + destroySemaphore(fv.cv) proc selectWorker(w: ptr Worker; fn: WorkerProc; data: pointer): bool = if cas(addr w.ready, true, false): @@ -191,9 +191,9 @@ proc fvFinalizer[T](fv: FlowVar[T]) = finished(fv) proc nimCreateFlowVar[T](): FlowVar[T] {.compilerProc.} = new(result, fvFinalizer) -proc nimFlowVarCreateCondVar(fv: FlowVarBase) {.compilerProc.} = - fv.cv = createCondVar() - fv.usesCondVar = true +proc nimFlowVarCreateSemaphore(fv: FlowVarBase) {.compilerProc.} = + fv.cv = createSemaphore() + fv.usesSemaphore = true proc nimFlowVarSignal(fv: FlowVarBase) {.compilerProc.} = if fv.ai != nil: @@ -202,7 +202,7 @@ proc nimFlowVarSignal(fv: FlowVarBase) {.compilerProc.} = inc fv.ai.cv.counter release(fv.ai.cv.L) signal(fv.ai.cv.c) - if fv.usesCondVar: + if fv.usesSemaphore: signal(fv.cv) proc awaitAndThen*[T](fv: FlowVar[T]; action: proc (x: T) {.closure.}) = @@ -242,7 +242,7 @@ proc awaitAny*(flowVars: openArray[FlowVarBase]): int = ## **Note**: This results in non-deterministic behaviour and so should be ## avoided. var ai: AwaitInfo - ai.cv = createCondVar() + ai.cv = createSemaphore() var conflicts = 0 for i in 0 .. flowVars.high: if cas(addr flowVars[i].ai, nil, addr ai): @@ -256,7 +256,7 @@ proc awaitAny*(flowVars: openArray[FlowVarBase]): int = discard cas(addr flowVars[i].ai, addr ai, nil) else: result = -1 - destroyCondVar(ai.cv) + destroySemaphore(ai.cv) proc nimArgsPassingDone(p: pointer) {.compilerProc.} = let w = cast[ptr Worker](p) @@ -270,7 +270,7 @@ var currentPoolSize: int maxPoolSize = MaxThreadPoolSize minPoolSize = 4 - gSomeReady = createCondVar() + gSomeReady = createSemaphore() readyWorker: ptr Worker proc slave(w: ptr Worker) {.thread.} = @@ -307,10 +307,10 @@ proc setMaxPoolSize*(size: range[1..MaxThreadPoolSize]) = w.shutdown = true proc activateThread(i: int) {.noinline.} = - workersData[i].taskArrived = createCondVar() - workersData[i].taskStarted = createCondVar() + workersData[i].taskArrived = createSemaphore() + workersData[i].taskStarted = createSemaphore() workersData[i].initialized = true - workersData[i].q.empty = createCondVar() + workersData[i].q.empty = createSemaphore() initLock(workersData[i].q.lock) createThread(workers[i], slave, addr(workersData[i])) From 78b3f739b13b93e42016e32e0f923436ce9b207e Mon Sep 17 00:00:00 2001 From: def Date: Tue, 11 Nov 2014 00:47:32 +0100 Subject: [PATCH 235/409] Remove runtime deadlock prevention as deadlock detection at compile-time is available Conflicts: lib/core/locks.nim --- lib/core/locks.nim | 108 +-------------------------------------------- 1 file changed, 2 insertions(+), 106 deletions(-) diff --git a/lib/core/locks.nim b/lib/core/locks.nim index 817d84858..4e85474fb 100644 --- a/lib/core/locks.nim +++ b/lib/core/locks.nim @@ -8,19 +8,12 @@ # ## This module contains Nim's support for locks and condition vars. -## If the symbol ``preventDeadlocks`` is defined -## (compiled with ``-d:preventDeadlocks``) special logic is added to -## every ``acquire``, ``tryAcquire`` and ``release`` action that ensures at -## runtime that no deadlock can occur. This is achieved by forcing a thread -## to release its locks should it be part of a deadlock. This thread then -## re-acquires its locks and proceeds. include "system/syslocks" type TLock* = TSysLock ## Nim lock; whether this is re-entrant - ## or not is unspecified! However, compilation - ## in preventDeadlocks-mode guarantees re-entrancy. + ## or not is unspecified! TCond* = TSysCond ## Nim condition variable LockEffect* = object of RootEffect ## effect that denotes that some lock operation @@ -31,26 +24,6 @@ type ## released {.deprecated: [FLock: LockEffect, FAquireLock: AquireEffect, FReleaseLock: ReleaseEffect].} - -const - noDeadlocks = defined(preventDeadlocks) - maxLocksPerThread* = 10 ## max number of locks a thread can hold - ## at the same time; this limit is only relevant - ## when compiled with ``-d:preventDeadlocks``. - -var - deadlocksPrevented*: int ## counts the number of times a - ## deadlock has been prevented - -when noDeadlocks: - var - locksLen {.threadvar.}: int - locks {.threadvar.}: array [0..maxLocksPerThread-1, pointer] - - proc orderedLocks(): bool = - for i in 0 .. locksLen-2: - if locks[i] >= locks[i+1]: return false - result = true proc initLock*(lock: var TLock) {.inline.} = ## Initializes the given lock. @@ -63,90 +36,13 @@ proc deinitLock*(lock: var TLock) {.inline.} = proc tryAcquire*(lock: var TLock): bool {.tags: [AquireEffect].} = ## Tries to acquire the given lock. Returns `true` on success. result = tryAcquireSys(lock) - when noDeadlocks: - if not result: return - # we have to add it to the ordered list. Oh, and we might fail if - # there is no space in the array left ... - if locksLen >= len(locks): - releaseSys(lock) - raise newException(EResourceExhausted, "cannot acquire additional lock") - # find the position to add: - var p = addr(lock) - var L = locksLen-1 - var i = 0 - while i <= L: - assert locks[i] != nil - if locks[i] < p: inc(i) # in correct order - elif locks[i] == p: return # thread already holds lock - else: - # do the crazy stuff here: - while L >= i: - locks[L+1] = locks[L] - dec L - locks[i] = p - inc(locksLen) - assert orderedLocks() - return - # simply add to the end: - locks[locksLen] = p - inc(locksLen) - assert orderedLocks() proc acquire*(lock: var TLock) {.tags: [AquireEffect].} = ## Acquires the given lock. - when nodeadlocks: - var p = addr(lock) - var L = locksLen-1 - var i = 0 - while i <= L: - assert locks[i] != nil - if locks[i] < p: inc(i) # in correct order - elif locks[i] == p: return # thread already holds lock - else: - # do the crazy stuff here: - if locksLen >= len(locks): - raise newException(EResourceExhausted, - "cannot acquire additional lock") - while L >= i: - releaseSys(cast[ptr TSysLock](locks[L])[]) - locks[L+1] = locks[L] - dec L - # acquire the current lock: - acquireSys(lock) - locks[i] = p - inc(locksLen) - # acquire old locks in proper order again: - L = locksLen-1 - inc i - while i <= L: - acquireSys(cast[ptr TSysLock](locks[i])[]) - inc(i) - # DANGER: We can only modify this global var if we gained every lock! - # NO! We need an atomic increment. Crap. - discard system.atomicInc(deadlocksPrevented, 1) - assert orderedLocks() - return - - # simply add to the end: - if locksLen >= len(locks): - raise newException(EResourceExhausted, "cannot acquire additional lock") - acquireSys(lock) - locks[locksLen] = p - inc(locksLen) - assert orderedLocks() - else: - acquireSys(lock) + acquireSys(lock) proc release*(lock: var TLock) {.tags: [ReleaseEffect].} = ## Releases the given lock. - when nodeadlocks: - var p = addr(lock) - var L = locksLen - for i in countdown(L-1, 0): - if locks[i] == p: - for j in i..L-2: locks[j] = locks[j+1] - dec locksLen - break releaseSys(lock) From af84f754b08ea53178042112ed0f2b64d11c0733 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 11 Nov 2014 09:55:31 +0100 Subject: [PATCH 236/409] proper fix for stack initialization and threadvar emulation --- compiler/cgen.nim | 9 +++++++-- lib/system/threads.nim | 38 +++++++++++++++++++++++++++----------- todo.txt | 1 + 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 8e20ba654..9e353f0ea 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -973,7 +973,7 @@ proc genMainProc(m: BModule) = "\tvoid (*volatile inner)();$N" & "\tsystemDatInit();$N" & "\tinner = PreMainInner;$N" & - "$4" & + "$4$5" & "\t(*inner)();$N" & "}$N$N" @@ -1065,7 +1065,12 @@ proc genMainProc(m: BModule) = else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N") inc(m.labels) appcg(m, m.s[cfsProcs], PreMainBody, [ - mainDatInit, gBreakpoints, otherModsInit, initStackBottomCall]) + mainDatInit, gBreakpoints, otherModsInit, + if emulatedThreadVars() and platform.targetOS != osStandalone: + ropecg(m, "\t#initThreadVarsEmulation();$N") + else: + "".toRope, + initStackBottomCall]) appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, toRope(m.labels)]) if optNoMain notin gGlobalOptions: diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 287c6db95..496c31af1 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -79,12 +79,20 @@ when defined(windows): type TThreadVarSlot = distinct int32 - proc threadVarAlloc(): TThreadVarSlot {. - importc: "TlsAlloc", stdcall, dynlib: "kernel32".} - proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. - importc: "TlsSetValue", stdcall, dynlib: "kernel32".} - proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. - importc: "TlsGetValue", stdcall, dynlib: "kernel32".} + when true: + proc threadVarAlloc(): TThreadVarSlot {. + importc: "TlsAlloc", stdcall, header: "".} + proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. + importc: "TlsSetValue", stdcall, header: "".} + proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. + importc: "TlsGetValue", stdcall, header: "".} + else: + proc threadVarAlloc(): TThreadVarSlot {. + importc: "TlsAlloc", stdcall, dynlib: "kernel32".} + proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. + importc: "TlsSetValue", stdcall, dynlib: "kernel32".} + proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. + importc: "TlsGetValue", stdcall, dynlib: "kernel32".} else: {.passL: "-pthread".} @@ -174,7 +182,18 @@ type # XXX it'd be more efficient to not use a global variable for the # thread storage slot, but to rely on the implementation to assign slot X # for us... ;-) -var globalsSlot = threadVarAlloc() +var globalsSlot: TThreadVarSlot + +when not defined(useNimRtl): + when not useStackMaskHack: + var mainThread: TGcThread + +proc initThreadVarsEmulation() {.compilerProc, inline.} = + when not defined(useNimRtl): + globalsSlot = threadVarAlloc() + when declared(mainThread): + threadVarSetValue(globalsSlot, addr(mainThread)) + #const globalsSlot = TThreadVarSlot(0) #sysAssert checkSlot.int == globalsSlot.int @@ -192,11 +211,8 @@ when useStackMaskHack: # create for the main thread. Note: do not insert this data into the list # of all threads; it's not to be stopped etc. when not defined(useNimRtl): - when not useStackMaskHack: - var mainThread: TGcThread - threadVarSetValue(globalsSlot, addr(mainThread)) - when not defined(createNimRtl): initStackBottom() + #when not defined(createNimRtl): initStackBottom() initGC() when emulatedThreadVars: diff --git a/todo.txt b/todo.txt index a6ea31560..e0d6313b3 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ version 0.10 ============ +showstopper: Nim does not boot with --threads:on! - make nimble part of the distribution - implement 'procCall' - split idetools into separate tool From aae180e26b7392da5050048a7528d7ef3b25986f Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 11 Nov 2014 21:32:22 +0100 Subject: [PATCH 237/409] fixes #1560 --- tests/iter/titer2.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/iter/titer2.nim b/tests/iter/titer2.nim index 5c407ebe4..4a7f76883 100644 --- a/tests/iter/titer2.nim +++ b/tests/iter/titer2.nim @@ -1,5 +1,8 @@ discard """ - output: '''true''' + output: '''true +3 +4 +5''' cmd: "nim $target --gc:none --hints:on --warnings:off $options $file" """ @@ -49,3 +52,6 @@ block Test1: echo "true" +# bug #1560 +for i in @[3, 4, 5]: + echo($i) From 2d43fcafe0cedd4f78611dddccc31e1bef432aab Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 12 Nov 2014 00:04:04 +0100 Subject: [PATCH 238/409] fixes #1593 --- compiler/ccgexprs.nim | 14 ++++++++++++-- tests/ccgbugs/tcvarargs.nim | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 tests/ccgbugs/tcvarargs.nim diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 75f0f3a42..b6feb78b2 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -11,6 +11,14 @@ # -------------------------- constant expressions ------------------------ +proc int64Literal(i: BiggestInt): PRope = + if i > low(int64): + result = rfmt(nil, "IL64($1)", toRope(i)) + else: + result = ~"(IL64(-9223372036854775807) - IL64(1))" + +proc uint64Literal(i: uint64): PRope = toRope($i & "ULL") + proc intLiteral(i: BiggestInt): PRope = if (i > low(int32)) and (i <= high(int32)): result = toRope(i) @@ -46,16 +54,18 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope = case n.kind of nkCharLit..nkUInt64Lit: case skipTypes(ty, abstractVarRange).kind - of tyChar, tyInt64, tyNil: + of tyChar, tyNil: result = intLiteral(n.intVal) of tyInt: - if (n.intVal >= low(int32)) and (n.intVal <= high(int32)): + if n.intVal >= low(int32) and n.intVal <= high(int32): result = int32Literal(int32(n.intVal)) else: result = intLiteral(n.intVal) of tyBool: if n.intVal != 0: result = ~"NIM_TRUE" else: result = ~"NIM_FALSE" + of tyInt64: result = int64Literal(n.intVal) + of tyUInt64: result = uint64Literal(uint64(n.intVal)) else: result = ropef("(($1) $2)", [getTypeDesc(p.module, skipTypes(ty, abstractVarRange)), intLiteral(n.intVal)]) diff --git a/tests/ccgbugs/tcvarargs.nim b/tests/ccgbugs/tcvarargs.nim new file mode 100644 index 000000000..ebaf83a4a --- /dev/null +++ b/tests/ccgbugs/tcvarargs.nim @@ -0,0 +1,34 @@ +discard """ + output: '''17 +17 +17 +17 +17 +17 +''' +""" + +# bug #1593 + +{.emit: """ +#include + +void foo(int n, ...) { + NI64 k; + int i; + va_list argp; + va_start(argp, n); + for (i = 1; i <= n; i++) { + k = va_arg(argp, NI64); + printf("%lld\n", (long long)k); + } + va_end(argp); +} +""".} + +proc foo(x: cint) {.importc, varargs, nodecl.} + +proc main() = + const k = 17'i64 + foo(6, k, k, k, k, k, k) +main() From b2f577df23d5daae873df18ff345965f8dc7e47b Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 12 Nov 2014 02:36:59 +0100 Subject: [PATCH 239/409] fixes #1473 --- compiler/lexer.nim | 19 +++++++++++++------ compiler/msgs.nim | 10 +++++++++- compiler/parser.nim | 9 +++++---- compiler/vm.nim | 30 +++++++++++++++++++++++------- compiler/vmdef.nim | 5 ++++- compiler/vmgen.nim | 9 +++++++-- compiler/vmops.nim | 5 +++++ lib/core/macros.nim | 26 +++++++++++++++++++++----- tests/macros/ttryparseexpr.nim | 17 +++++++++++++++++ 9 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 tests/macros/ttryparseexpr.nim diff --git a/compiler/lexer.nim b/compiler/lexer.nim index cbc87972d..dbeec8acf 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -116,7 +116,8 @@ type literal*: string # the parsed (string) literal; and # documentation comments are here too line*, col*: int - + + TErrorHandler* = proc (info: TLineInfo; msg: TMsgKind; arg: string) TLexer* = object of TBaseLexer fileIdx*: int32 indentAhead*: int # if > 0 an indendation has already been read @@ -124,7 +125,7 @@ type # needs so much look-ahead currLineIndent*: int strongSpaces*: bool - + errorHandler*: TErrorHandler var gLinesCompiled*: int # all lines that have been compiled @@ -222,12 +223,18 @@ proc getColumn(L: TLexer): int = proc getLineInfo(L: TLexer): TLineInfo = result = newLineInfo(L.fileIdx, L.lineNumber, getColNumber(L, L.bufpos)) -proc lexMessage(L: TLexer, msg: TMsgKind, arg = "") = - msgs.message(getLineInfo(L), msg, arg) +proc dispMessage(L: TLexer; info: TLineInfo; msg: TMsgKind; arg: string) = + if L.errorHandler.isNil: + msgs.message(info, msg, arg) + else: + L.errorHandler(info, msg, arg) -proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = +proc lexMessage(L: TLexer, msg: TMsgKind, arg = "") = + L.dispMessage(getLineInfo(L), msg, arg) + +proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.fileIdx, L.lineNumber, pos - L.lineStart) - msgs.message(info, msg, arg) + L.dispMessage(info, msg, arg) proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: set[char]) = var pos = L.bufpos # use registers for pos, buf diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 944446624..7f4f81dd0 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -450,7 +450,7 @@ type projPath*: string # This is relative to the project's root shortName*: string # short name of the module quotedName*: PRope # cached quoted short name for codegen - # purpoes + # purposes lines*: seq[PRope] # the source code of the module # used for better error messages and @@ -789,6 +789,14 @@ proc writeSurroundingSrc(info: TLineInfo) = msgWriteln(indent & info.sourceLine.ropeToStr) msgWriteln(indent & repeatChar(info.col, ' ') & '^') +proc formatMsg*(info: TLineInfo, msg: TMsgKind, arg: string): string = + let frmt = case msg + of warnMin..warnMax: PosWarningFormat + of hintMin..hintMax: PosHintFormat + else: PosErrorFormat + result = frmt % [toMsgFilename(info), coordToStr(info.line), + coordToStr(info.col), getMessageStr(msg, arg)] + proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, eh: TErrorHandling) = var frmt: string diff --git a/compiler/parser.nim b/compiler/parser.nim index 20c037c00..e4de75a07 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -41,8 +41,7 @@ type proc parseAll*(p: var TParser): PNode proc closeParser*(p: var TParser) proc parseTopLevelStmt*(p: var TParser): PNode -proc parseString*(s: string, filename: string = "", line: int = 0): PNode - + # helpers for the other parsers proc isOperator*(tok: TToken): bool proc getTok*(p: var TParser) @@ -96,7 +95,7 @@ proc parMessage(p: TParser, msg: TMsgKind, arg = "") = proc parMessage(p: TParser, msg: TMsgKind, tok: TToken) = ## Produce and emit a parser message to output about the token `tok` - lexMessage(p.lex, msg, prettyTok(tok)) + parMessage(p, msg, prettyTok(tok)) template withInd(p: expr, body: stmt) {.immediate.} = let oldInd = p.currInd @@ -1995,7 +1994,8 @@ proc parseTopLevelStmt(p: var TParser): PNode = if result.kind == nkEmpty: parMessage(p, errExprExpected, p.tok) break -proc parseString(s: string, filename: string = "", line: int = 0): PNode = +proc parseString*(s: string; filename: string = ""; line: int = 0; + errorHandler: TErrorHandler = nil): PNode = ## Parses a string into an AST, returning the top node. ## `filename` and `line`, although optional, provide info so that the ## compiler can generate correct error messages referring to the original @@ -2007,6 +2007,7 @@ proc parseString(s: string, filename: string = "", line: int = 0): PNode = # XXX for now the builtin 'parseStmt/Expr' functions do not know about strong # spaces... openParser(parser, filename, stream, false) + parser.lex.errorHandler = errorHandler result = parser.parseAll closeParser(parser) diff --git a/compiler/vm.nim b/compiler/vm.nim index e5b357a11..a15807b24 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -814,7 +814,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = if prc.offset < -1: # it's a callback: c.callbacks[-prc.offset-2].value( - VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs))) + VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs), + currentException: c.currentExceptionB)) elif sfImportc in prc.flags: if allowFFI notin c.features: globalError(c.debug[pc], errGenerated, "VM not allowed to do FFI") @@ -1146,16 +1147,31 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcParseExprToAst: decodeB(rkNode) # c.debug[pc].line.int - countLines(regs[rb].strVal) ? + var error: string let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, - c.debug[pc].line.int) - if sonsLen(ast) != 1: - globalError(c.debug[pc], errExprExpected, "multiple statements") - regs[ra].node = ast.sons[0] + c.debug[pc].line.int, + proc (info: TLineInfo; msg: TMsgKind; arg: string) = + if error.isNil: error = formatMsg(info, msg, arg)) + if not error.isNil: + c.errorFlag = error + elif sonsLen(ast) != 1: + c.errorFlag = formatMsg(c.debug[pc], errExprExpected, "multiple statements") + else: + regs[ra].node = ast.sons[0] of opcParseStmtToAst: decodeB(rkNode) + var error: string let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, - c.debug[pc].line.int) - regs[ra].node = ast + c.debug[pc].line.int, + proc (info: TLineInfo; msg: TMsgKind; arg: string) = + if error.isNil: error = formatMsg(info, msg, arg)) + if not error.isNil: + c.errorFlag = error + else: + regs[ra].node = ast + of opcQueryErrorFlag: + createStr regs[ra] + regs[ra].node.strVal = c.errorFlag of opcCallSite: ensureKind(rkNode) if c.callsite != nil: regs[ra].node = c.callsite diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index d7cdafb69..c06606318 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -92,6 +92,7 @@ type opcGorge, opcParseExprToAst, opcParseStmtToAst, + opcQueryErrorFlag, opcNError, opcNWarning, opcNHint, @@ -174,6 +175,7 @@ type VmArgs* = object ra*, rb*, rc*: Natural slots*: pointer + currentException*: PNode VmCallback* = proc (args: VmArgs) {.closure.} PCtx* = ref TCtx @@ -195,6 +197,7 @@ type loopIterations*: int comesFromHeuristic*: TLineInfo # Heuristic for better macro stack traces callbacks*: seq[tuple[key: string, value: VmCallback]] + errorFlag*: string TPosition* = distinct int @@ -204,7 +207,7 @@ proc newCtx*(module: PSym): PCtx = PCtx(code: @[], debug: @[], globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[], prc: PProc(blocks: @[]), module: module, loopIterations: MaxLoopIterations, - comesFromHeuristic: unknownLineInfo(), callbacks: @[]) + comesFromHeuristic: unknownLineInfo(), callbacks: @[], errorFlag: "") proc refresh*(c: PCtx, module: PSym) = c.module = module diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index e0e34306c..da31eab3d 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -987,8 +987,13 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = unused(n, dest) genUnaryStmt(c, n, opcNWarning) of mNError: - unused(n, dest) - genUnaryStmt(c, n, opcNError) + if n.len <= 1: + # query error condition: + c.gABC(n, opcQueryErrorFlag, dest) + else: + # setter + unused(n, dest) + genUnaryStmt(c, n, opcNError) of mNCallSite: if dest < 0: dest = c.getTemp(n.typ) c.gABC(n, opcCallSite, dest) diff --git a/compiler/vmops.nim b/compiler/vmops.nim index aa25d208a..ef2bfabb2 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -44,6 +44,10 @@ template wrap2svoid(op) {.immediate, dirty.} = op(getString(a, 0), getString(a, 1)) systemop op +proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} = + setResult(a, if a.currentException.isNil: "" + else: a.currentException.sons[2].strVal) + proc registerAdditionalOps*(c: PCtx) = wrap1f(sqrt) wrap1f(ln) @@ -73,3 +77,4 @@ proc registerAdditionalOps*(c: PCtx) = wrap1s(dirExists) wrap1s(fileExists) wrap2svoid(writeFile) + systemop getCurrentExceptionMsg diff --git a/lib/core/macros.nim b/lib/core/macros.nim index db2bfa9a6..b61fe1d17 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -249,13 +249,29 @@ proc lineinfo*(n: PNimrodNode): string {.magic: "NLineInfo", noSideEffect.} ## returns the position the node appears in the original source file ## in the form filename(line, col) -proc parseExpr*(s: string): PNimrodNode {.magic: "ParseExprToAst", noSideEffect.} - ## Compiles the passed string to its AST representation. - ## Expects a single expression. +proc internalParseExpr(s: string): PNimrodNode {. + magic: "ParseExprToAst", noSideEffect.} -proc parseStmt*(s: string): PNimrodNode {.magic: "ParseStmtToAst", noSideEffect.} +proc internalParseStmt(s: string): PNimrodNode {. + magic: "ParseStmtToAst", noSideEffect.} + +proc internalErrorFlag*(): string {.magic: "NError", noSideEffect.} + ## Some builtins set an error flag. This is then turned into a proper + ## exception. **Note**: Ordinary application code should not call this. + +proc parseExpr*(s: string): PNimrodNode {.noSideEffect, compileTime.} = ## Compiles the passed string to its AST representation. - ## Expects one or more statements. + ## Expects a single expression. Raises ``ValueError`` for parsing errors. + result = internalParseExpr(s) + let x = internalErrorFlag() + if x.len > 0: raise newException(ValueError, x) + +proc parseStmt*(s: string): PNimrodNode {.noSideEffect, compileTime.} = + ## Compiles the passed string to its AST representation. + ## Expects one or more statements. Raises ``ValueError`` for parsing errors. + result = internalParseStmt(s) + let x = internalErrorFlag() + if x.len > 0: raise newException(ValueError, x) proc getAst*(macroOrTemplate: expr): PNimrodNode {.magic: "ExpandToAst", noSideEffect.} ## Obtains the AST nodes returned from a macro or template invocation. diff --git a/tests/macros/ttryparseexpr.nim b/tests/macros/ttryparseexpr.nim new file mode 100644 index 000000000..2a6f4437d --- /dev/null +++ b/tests/macros/ttryparseexpr.nim @@ -0,0 +1,17 @@ +discard """ + outputsub: '''Error: invalid indentation''' +""" + +# feature request #1473 +import macros + +macro test(text: string): expr = + try: + result = parseExpr(text.strVal) + except ValueError: + result = newLit getCurrentExceptionMsg() + +const + a = test("foo&&") + +echo a From 29b1709fc45aec2a6224a03dc0d1363a21958a42 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 12 Nov 2014 02:45:54 +0100 Subject: [PATCH 240/409] fixes a regression that made 'system.compiles' output the produced error messages --- compiler/semexprs.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 1ceec7fbe..bf2344f11 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1565,7 +1565,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = let oldOwnerLen = len(gOwners) let oldGenerics = c.generics let oldErrorOutputs = errorOutputs - #errorOutputs = if bufferErrors: {eInMemory} else: {} + errorOutputs = {} let oldContextLen = msgs.getInfoContextLen() let oldInGenericContext = c.inGenericContext From 77353b8084922c4a79b63109382185cbe182ca54 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 12 Nov 2014 02:56:02 +0100 Subject: [PATCH 241/409] fixes #1127 --- compiler/ccgtypes.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index fbdea7e66..c3905f3e6 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -330,7 +330,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope = of tyNil: result = typeNameOrLiteral(typ, "0") of tyInt..tyUInt64: result = typeNameOrLiteral(typ, NumericalTypeToStr[typ.kind]) - of tyRange: result = getSimpleTypeDesc(m, typ.sons[0]) + of tyDistinct, tyRange: result = getSimpleTypeDesc(m, typ.sons[0]) else: result = nil proc getTypePre(m: BModule, typ: PType): PRope = From bc5879b9b7e9574638c1336d3f2b44024b6e0401 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 13 Nov 2014 09:12:27 +0100 Subject: [PATCH 242/409] fixes error propagation for macros.parseExpr --- compiler/vm.nim | 1 + tests/macros/ttryparseexpr.nim | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index a15807b24..f75db56b8 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1172,6 +1172,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcQueryErrorFlag: createStr regs[ra] regs[ra].node.strVal = c.errorFlag + c.errorFlag.setLen 0 of opcCallSite: ensureKind(rkNode) if c.callsite != nil: regs[ra].node = c.callsite diff --git a/tests/macros/ttryparseexpr.nim b/tests/macros/ttryparseexpr.nim index 2a6f4437d..af932eb7d 100644 --- a/tests/macros/ttryparseexpr.nim +++ b/tests/macros/ttryparseexpr.nim @@ -1,5 +1,5 @@ discard """ - outputsub: '''Error: invalid indentation''' + outputsub: '''Error: invalid indentation 45''' """ # feature request #1473 @@ -12,6 +12,8 @@ macro test(text: string): expr = result = newLit getCurrentExceptionMsg() const + valid = 45 a = test("foo&&") + b = test("valid") -echo a +echo a, " ", b From 37cc9b2226fc422561700dd1197450106db2b7c5 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 13 Nov 2014 19:07:27 +0100 Subject: [PATCH 243/409] fixes #1181 --- compiler/ccgexprs.nim | 60 ++++++++++++---------- compiler/ccgstmts.nim | 11 ++++ compiler/cgen.nim | 2 - lib/pure/osproc.nim | 6 +-- tests/{ccg => ccgbugs}/tmissingbracket.nim | 0 5 files changed, 46 insertions(+), 33 deletions(-) rename tests/{ccg => ccgbugs}/tmissingbracket.nim (100%) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index b6feb78b2..b91c54e8b 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -655,13 +655,15 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = ropef(unArithTab[op], [rdLoc(a), toRope(getSize(t) * 8), getSimpleTypeDesc(p.module, e.typ)])) -proc genDeref(p: BProc, e: PNode, d: var TLoc) = - var a: TLoc - if mapType(e.sons[0].typ) in {ctArray, ctPtrToArray}: +proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) = + if mapType(e.sons[0].typ) in {ctArray, ctPtrToArray} and not enforceDeref: # XXX the amount of hacks for C's arrays is incredible, maybe we should # simply wrap them in a struct? --> Losing auto vectorization then? + #if e[0].kind != nkBracketExpr: + # message(e.info, warnUser, "CAME HERE " & renderTree(e)) expr(p, e.sons[0], d) else: + var a: TLoc initLocExpr(p, e.sons[0], a) case skipTypes(a.t, abstractInst).kind of tyRef: @@ -794,15 +796,15 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = else: genRecordField(p, e.sons[0], d) -proc genArrayElem(p: BProc, e: PNode, d: var TLoc) = +proc genArrayElem(p: BProc, x, y: PNode, d: var TLoc) = var a, b: TLoc - initLocExpr(p, e.sons[0], a) - initLocExpr(p, e.sons[1], b) + initLocExpr(p, x, a) + initLocExpr(p, y, b) var ty = skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs) var first = intLiteral(firstOrd(ty)) # emit range check: if optBoundsCheck in p.options and tfUncheckedArray notin ty.flags: - if not isConstExpr(e.sons[1]): + if not isConstExpr(y): # semantic pass has already checked for const index expressions if firstOrd(ty) == 0: if (firstOrd(b.t) < firstOrd(ty)) or (lastOrd(b.t) > lastOrd(ty)): @@ -812,26 +814,26 @@ proc genArrayElem(p: BProc, e: PNode, d: var TLoc) = linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n", rdCharLoc(b), first, intLiteral(lastOrd(ty))) else: - let idx = getOrdValue(e.sons[1]) + let idx = getOrdValue(y) if idx < firstOrd(ty) or idx > lastOrd(ty): - localError(e.info, errIndexOutOfBounds) + localError(x.info, errIndexOutOfBounds) d.inheritLocation(a) putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)), rfmt(nil, "$1[($2)- $3]", rdLoc(a), rdCharLoc(b), first)) -proc genCStringElem(p: BProc, e: PNode, d: var TLoc) = +proc genCStringElem(p: BProc, x, y: PNode, d: var TLoc) = var a, b: TLoc - initLocExpr(p, e.sons[0], a) - initLocExpr(p, e.sons[1], b) + initLocExpr(p, x, a) + initLocExpr(p, y, b) var ty = skipTypes(a.t, abstractVarRange) if d.k == locNone: d.s = a.s putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)), rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b))) -proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) = +proc genOpenArrayElem(p: BProc, x, y: PNode, d: var TLoc) = var a, b: TLoc - initLocExpr(p, e.sons[0], a) - initLocExpr(p, e.sons[1], b) # emit range check: + initLocExpr(p, x, a) + initLocExpr(p, y, b) # emit range check: if optBoundsCheck in p.options: linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len0)) #raiseIndexError();$n", rdLoc(b), rdLoc(a)) # BUGFIX: ``>=`` and not ``>``! @@ -839,10 +841,10 @@ proc genOpenArrayElem(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), rfmt(nil, "$1[$2]", rdLoc(a), rdCharLoc(b))) -proc genSeqElem(p: BProc, e: PNode, d: var TLoc) = +proc genSeqElem(p: BProc, x, y: PNode, d: var TLoc) = var a, b: TLoc - initLocExpr(p, e.sons[0], a) - initLocExpr(p, e.sons[1], b) + initLocExpr(p, x, a) + initLocExpr(p, y, b) var ty = skipTypes(a.t, abstractVarRange) if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check: @@ -862,6 +864,17 @@ proc genSeqElem(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), rfmt(nil, "$1->data[$2]", rdLoc(a), rdCharLoc(b))) +proc genBracketExpr(p: BProc; n: PNode; d: var TLoc) = + var ty = skipTypes(n.sons[0].typ, abstractVarRange) + if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange) + case ty.kind + of tyArray, tyArrayConstr: genArrayElem(p, n.sons[0], n.sons[1], d) + of tyOpenArray, tyVarargs: genOpenArrayElem(p, n.sons[0], n.sons[1], d) + of tySequence, tyString: genSeqElem(p, n.sons[0], n.sons[1], d) + of tyCString: genCStringElem(p, n.sons[0], n.sons[1], d) + of tyTuple: genTupleElem(p, n, d) + else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')') + proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) = # how to generate code? # 'expr1 and expr2' becomes: @@ -1985,16 +1998,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of nkCast: genCast(p, n, d) of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, d) of nkHiddenAddr, nkAddr: genAddr(p, n, d) - of nkBracketExpr: - var ty = skipTypes(n.sons[0].typ, abstractVarRange) - if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange) - case ty.kind - of tyArray, tyArrayConstr: genArrayElem(p, n, d) - of tyOpenArray, tyVarargs: genOpenArrayElem(p, n, d) - of tySequence, tyString: genSeqElem(p, n, d) - of tyCString: genCStringElem(p, n, d) - of tyTuple: genTupleElem(p, n, d) - else: internalError(n.info, "expr(nkBracketExpr, " & $ty.kind & ')') + of nkBracketExpr: genBracketExpr(p, n, d) of nkDerefExpr, nkHiddenDeref: genDeref(p, n, d) of nkDotExpr: genRecordField(p, n, d) of nkCheckedFieldExpr: genCheckedRecordField(p, n, d) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 0898f0b03..e5848f558 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -68,10 +68,21 @@ proc genVarTuple(p: BProc, n: PNode) = [rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)]) putLocIntoDest(p, v.loc, field) +proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) + proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} = if ri.kind in nkCallKinds and (ri.sons[0].kind != nkSym or ri.sons[0].sym.magic == mNone): genAsgnCall(p, le, ri, a) + elif ri.kind in {nkDerefExpr, nkHiddenDeref}: + # this is a hacky way to fix #1181 (tmissingderef):: + # + # var arr1 = cast[ptr array[4, int8]](addr foo)[] + # + # However, fixing this properly really requires modelling 'array' as + # a 'struct' in C to preserve dereferencing semantics completely. Not + # worth the effort until version 1.0 is out. + genDeref(p, ri, a, enforceDeref=true) else: expr(p, ri, a) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 9e353f0ea..112203ef1 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -55,7 +55,6 @@ proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) = result.s = s result.t = getUniqueType(typ) result.r = nil - #result.a = - 1 result.flags = {} proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) = @@ -63,7 +62,6 @@ proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) = if a.k == locNone: a.k = k a.t = getUniqueType(typ) - #a.a = - 1 a.s = s if a.r == nil: a.r = r diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 3963497fd..2983712c8 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -495,10 +495,10 @@ when defined(Windows) and not defined(useNimRtl): if running(p): discard terminateProcess(p.fProcessHandle, 0) - proc kill(p: PProcess) = + proc kill(p: Process) = terminate(p) - - proc waitForExit(p: PProcess, timeout: int = -1): int = + + proc waitForExit(p: Process, timeout: int = -1): int = discard waitForSingleObject(p.fProcessHandle, timeout.int32) var res: int32 diff --git a/tests/ccg/tmissingbracket.nim b/tests/ccgbugs/tmissingbracket.nim similarity index 100% rename from tests/ccg/tmissingbracket.nim rename to tests/ccgbugs/tmissingbracket.nim From f52fd8785f3c3247ef5b018738f2920b79b7f8f6 Mon Sep 17 00:00:00 2001 From: def Date: Thu, 13 Nov 2014 21:34:46 +0100 Subject: [PATCH 244/409] Fix some deprecation warnings caused by renames --- lib/posix/epoll.nim | 4 +- lib/pure/asyncdispatch.nim | 44 +++++++------- lib/pure/asyncio.nim | 46 +++++++-------- lib/pure/asyncnet.nim | 80 +++++++++++++------------- lib/pure/collections/queues.nim | 14 ++--- lib/pure/concurrency/cpuload.nim | 2 +- lib/pure/httpclient.nim | 98 ++++++++++++++++---------------- lib/pure/httpserver.nim | 76 ++++++++++++------------- lib/pure/math.nim | 3 +- lib/pure/net.nim | 28 ++++----- lib/pure/smtp.nim | 40 ++++++------- lib/pure/sockets.nim | 38 ++++++------- 12 files changed, 237 insertions(+), 236 deletions(-) diff --git a/lib/posix/epoll.nim b/lib/posix/epoll.nim index 5565a5ae8..bc84611a6 100644 --- a/lib/posix/epoll.nim +++ b/lib/posix/epoll.nim @@ -9,7 +9,7 @@ {.deadCodeElim:on.} -from posix import TSocketHandle +from posix import SocketHandle const EPOLLIN* = 0x00000001 @@ -58,7 +58,7 @@ proc epoll_create1*(flags: cint): cint {.importc: "epoll_create1", ## Same as epoll_create but with an FLAGS parameter. The unused SIZE ## parameter has been dropped. -proc epoll_ctl*(epfd: cint; op: cint; fd: cint | TSocketHandle; event: ptr epoll_event): cint {. +proc epoll_ctl*(epfd: cint; op: cint; fd: cint | SocketHandle; event: ptr epoll_event): cint {. importc: "epoll_ctl", header: "".} ## Manipulate an epoll instance "epfd". Returns 0 in case of success, ## -1 in case of error ( the "errno" variable will contain the diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 073cd3576..41b20cb35 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -242,7 +242,7 @@ proc echoOriginalStackTrace[T](future: Future[T]) = proc read*[T](future: Future[T]): T = ## Retrieves the value of ``future``. Future must be finished otherwise - ## this function will fail with a ``EInvalidValue`` exception. + ## this function will fail with a ``ValueError`` exception. ## ## If the result of the future is an error then that error will be raised. if future.finished: @@ -808,13 +808,13 @@ else: TAsyncFD* = distinct cint TCallback = proc (fd: TAsyncFD): bool {.closure,gcsafe.} - PData* = ref object of PObject + PData* = ref object of RootRef fd: TAsyncFD readCBs: seq[TCallback] writeCBs: seq[TCallback] PDispatcher* = ref object of PDispatcherBase - selector: PSelector + selector: Selector proc `==`*(x, y: TAsyncFD): bool {.borrow.} @@ -828,7 +828,7 @@ else: if gDisp.isNil: gDisp = newDispatcher() result = gDisp - proc update(fd: TAsyncFD, events: set[TEvent]) = + proc update(fd: TAsyncFD, events: set[Event]) = let p = getGlobalDispatcher() assert fd.SocketHandle in p.selector discard p.selector.update(fd.SocketHandle, events) @@ -836,16 +836,16 @@ else: proc register*(fd: TAsyncFD) = let p = getGlobalDispatcher() var data = PData(fd: fd, readCBs: @[], writeCBs: @[]) - p.selector.register(fd.SocketHandle, {}, data.PObject) + p.selector.register(fd.SocketHandle, {}, data.RootRef) proc newAsyncRawSocket*(domain: cint, typ: cint, protocol: cint): TAsyncFD = result = newRawSocket(domain, typ, protocol).TAsyncFD result.SocketHandle.setBlocking(false) register(result) - proc newAsyncRawSocket*(domain: TDomain = AF_INET, - typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP): TAsyncFD = + proc newAsyncRawSocket*(domain: Domain = AF_INET, + typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP): TAsyncFD = result = newRawSocket(domain, typ, protocol).TAsyncFD result.SocketHandle.setBlocking(false) register(result) @@ -861,14 +861,14 @@ else: proc addRead*(fd: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() if fd.SocketHandle notin p.selector: - raise newException(EInvalidValue, "File descriptor not registered.") + raise newException(ValueError, "File descriptor not registered.") p.selector[fd.SocketHandle].data.PData.readCBs.add(cb) update(fd, p.selector[fd.SocketHandle].events + {EvRead}) proc addWrite*(fd: TAsyncFD, cb: TCallback) = let p = getGlobalDispatcher() if fd.SocketHandle notin p.selector: - raise newException(EInvalidValue, "File descriptor not registered.") + raise newException(ValueError, "File descriptor not registered.") p.selector[fd.SocketHandle].data.PData.writeCBs.add(cb) update(fd, p.selector[fd.SocketHandle].events + {EvWrite}) @@ -898,7 +898,7 @@ else: data.writeCBs.add(cb) if info.key in p.selector: - var newEvents: set[TEvent] + var newEvents: set[Event] if data.readCBs.len != 0: newEvents = {EvRead} if data.writeCBs.len != 0: newEvents = newEvents + {EvWrite} if newEvents != info.key.events: @@ -910,7 +910,7 @@ else: processTimers(p) - proc connect*(socket: TAsyncFD, address: string, port: TPort, + proc connect*(socket: TAsyncFD, address: string, port: Port, af = AF_INET): Future[void] = var retFuture = newFuture[void]("connect") @@ -921,7 +921,7 @@ else: var aiList = getAddrInfo(address, port, af) var success = false - var lastError: TOSErrorCode + var lastError: OSErrorCode var it = aiList while it != nil: var ret = connect(socket.SocketHandle, it.ai_addr, it.ai_addrlen.Socklen) @@ -942,11 +942,11 @@ else: dealloc(aiList) if not success: - retFuture.fail(newException(EOS, osErrorMsg(lastError))) + retFuture.fail(newException(OSError, osErrorMsg(lastError))) return retFuture proc recv*(socket: TAsyncFD, size: int, - flags = {TSocketFlags.SafeDisconn}): Future[string] = + flags = {SocketFlag.SafeDisconn}): Future[string] = var retFuture = newFuture[string]("recv") var readBuffer = newString(size) @@ -962,7 +962,7 @@ else: if flags.isDisconnectionError(lastError): retFuture.complete("") else: - retFuture.fail(newException(EOS, osErrorMsg(lastError))) + retFuture.fail(newException(OSError, osErrorMsg(lastError))) else: result = false # We still want this callback to be called. elif res == 0: @@ -977,7 +977,7 @@ else: return retFuture proc send*(socket: TAsyncFD, data: string, - flags = {TSocketFlags.SafeDisconn}): Future[void] = + flags = {SocketFlag.SafeDisconn}): Future[void] = var retFuture = newFuture[void]("send") var written = 0 @@ -994,7 +994,7 @@ else: if flags.isDisconnectionError(lastError): retFuture.complete() else: - retFuture.fail(newException(EOS, osErrorMsg(lastError))) + retFuture.fail(newException(OSError, osErrorMsg(lastError))) else: result = false # We still want this callback to be called. else: @@ -1008,7 +1008,7 @@ else: addWrite(socket, cb) return retFuture - proc acceptAddr*(socket: TAsyncFD, flags = {TSocketFlags.SafeDisconn}): + proc acceptAddr*(socket: TAsyncFD, flags = {SocketFlag.SafeDisconn}): Future[tuple[address: string, client: TAsyncFD]] = var retFuture = newFuture[tuple[address: string, client: TAsyncFD]]("acceptAddr") @@ -1027,7 +1027,7 @@ else: if flags.isDisconnectionError(lastError): return false else: - retFuture.fail(newException(EOS, osErrorMsg(lastError))) + retFuture.fail(newException(OSError, osErrorMsg(lastError))) else: register(client.TAsyncFD) retFuture.complete(($inet_ntoa(sockAddress.sin_addr), client.TAsyncFD)) @@ -1302,7 +1302,7 @@ macro async*(prc: stmt): stmt {.immediate.} = outerProcBody.add(closureIterator) # -> createCb(retFuture) - var cbName = newIdentNode("cb") + #var cbName = newIdentNode("cb") var procCb = newCall(bindSym"createCb", retFutureSym, iteratorNameSym, newStrLitNode(prc[0].getName)) outerProcBody.add procCb @@ -1372,7 +1372,7 @@ proc runForever*() = while true: poll() -proc waitFor*[T](fut: PFuture[T]): T = +proc waitFor*[T](fut: Future[T]): T = ## **Blocks** the current thread until the specified future completes. while not fut.finished: poll() diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 0dbc0a3d5..4c25952a8 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -180,10 +180,10 @@ proc asyncSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, if result.socket == invalidSocket: raiseOSError(osLastError()) result.socket.setBlocking(false) -proc toAsyncSocket*(sock: Socket, state: SocketStatus = SockConnected): PAsyncSocket = - ## Wraps an already initialized ``TSocket`` into a PAsyncSocket. +proc toAsyncSocket*(sock: Socket, state: SocketStatus = SockConnected): AsyncSocket = + ## Wraps an already initialized ``TSocket`` into a AsyncSocket. ## This is useful if you want to use an already connected TSocket as an - ## asynchronous PAsyncSocket in asyncio's event loop. + ## asynchronous AsyncSocket in asyncio's event loop. ## ## ``state`` may be overriden, i.e. if ``sock`` is not connected it should be ## adjusted properly. By default it will be assumed that the socket is @@ -201,7 +201,7 @@ proc toAsyncSocket*(sock: Socket, state: SocketStatus = SockConnected): PAsyncSo ## SockUDPBound Socket is a UDP socket which is listening for data. ## ================ ================================================================ ## - ## **Warning**: If ``state`` is set incorrectly the resulting ``PAsyncSocket`` + ## **Warning**: If ``state`` is set incorrectly the resulting ``AsyncSocket`` ## object may not work properly. ## ## **Note**: This will set ``sock`` to be non-blocking. @@ -213,8 +213,8 @@ proc toAsyncSocket*(sock: Socket, state: SocketStatus = SockConnected): PAsyncSo proc asyncSockHandleRead(h: RootRef) = when defined(ssl): - if PAsyncSocket(h).socket.isSSL and not - PAsyncSocket(h).socket.gotHandshake: + if AsyncSocket(h).socket.isSSL and not + AsyncSocket(h).socket.gotHandshake: return if AsyncSocket(h).info != SockListening: @@ -226,8 +226,8 @@ proc asyncSockHandleRead(h: RootRef) = proc close*(sock: AsyncSocket) {.gcsafe.} proc asyncSockHandleWrite(h: RootRef) = when defined(ssl): - if PAsyncSocket(h).socket.isSSL and not - PAsyncSocket(h).socket.gotHandshake: + if AsyncSocket(h).socket.isSSL and not + AsyncSocket(h).socket.gotHandshake: return if AsyncSocket(h).info == SockConnecting: @@ -266,17 +266,17 @@ proc asyncSockHandleWrite(h: RootRef) = when defined(ssl): proc asyncSockDoHandshake(h: PObject) {.gcsafe.} = - if PAsyncSocket(h).socket.isSSL and not - PAsyncSocket(h).socket.gotHandshake: - if PAsyncSocket(h).sslNeedAccept: + if AsyncSocket(h).socket.isSSL and not + AsyncSocket(h).socket.gotHandshake: + if AsyncSocket(h).sslNeedAccept: var d = "" - let ret = PAsyncSocket(h).socket.acceptAddrSSL(PAsyncSocket(h).socket, d) + let ret = AsyncSocket(h).socket.acceptAddrSSL(AsyncSocket(h).socket, d) assert ret != AcceptNoClient if ret == AcceptSuccess: - PAsyncSocket(h).info = SockConnected + AsyncSocket(h).info = SockConnected else: # handshake will set socket's ``sslNoHandshake`` field. - discard PAsyncSocket(h).socket.handshake() + discard AsyncSocket(h).socket.handshake() proc asyncSockTask(h: RootRef) = @@ -453,7 +453,7 @@ proc setHandleWrite*(s: AsyncSocket, ## ## To remove this event you should use the ``delHandleWrite`` function. ## It is advised to use that function instead of just setting the event to - ## ``proc (s: PAsyncSocket) = nil`` as that would mean that that function + ## ``proc (s: AsyncSocket) = nil`` as that would mean that that function ## would be called constantly. s.deleg.mode = fmReadWrite s.handleWrite = handleWrite @@ -655,10 +655,10 @@ proc len*(disp: Dispatcher): int = when isMainModule: - proc testConnect(s: PAsyncSocket, no: int) = + proc testConnect(s: AsyncSocket, no: int) = echo("Connected! " & $no) - proc testRead(s: PAsyncSocket, no: int) = + proc testRead(s: AsyncSocket, no: int) = echo("Reading! " & $no) var data = "" if not s.readLine(data): return @@ -668,15 +668,15 @@ when isMainModule: echo(data) echo("Finished reading! " & $no) - proc testAccept(s: PAsyncSocket, disp: PDispatcher, no: int) = + proc testAccept(s: AsyncSocket, disp: PDispatcher, no: int) = echo("Accepting client! " & $no) - var client: PAsyncSocket + var client: AsyncSocket new(client) var address = "" s.acceptAddr(client, address) echo("Accepted ", address) client.handleRead = - proc (s: PAsyncSocket) = + proc (s: AsyncSocket) = testRead(s, 2) disp.register(client) @@ -686,16 +686,16 @@ when isMainModule: var s = asyncSocket() s.connect("amber.tenthbit.net", TPort(6667)) s.handleConnect = - proc (s: PAsyncSocket) = + proc (s: AsyncSocket) = testConnect(s, 1) s.handleRead = - proc (s: PAsyncSocket) = + proc (s: AsyncSocket) = testRead(s, 1) d.register(s) var server = asyncSocket() server.handleAccept = - proc (s: PAsyncSocket) = + proc (s: AsyncSocket) = testAccept(s, d, 78) server.bindAddr(TPort(5555)) server.listen() diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 7028a358d..fd29e0a22 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -67,7 +67,7 @@ when defined(ssl): type # TODO: I would prefer to just do: - # PAsyncSocket* {.borrow: `.`.} = distinct PSocket. But that doesn't work. + # AsyncSocket* {.borrow: `.`.} = distinct Socket. But that doesn't work. AsyncSocketDesc = object fd*: SocketHandle closed*: bool ## determines whether this socket has been closed @@ -91,7 +91,7 @@ type # TODO: Save AF, domain etc info and reuse it in procs which need it like connect. -proc newSocket(fd: TAsyncFD, isBuff: bool): PAsyncSocket = +proc newSocket(fd: TAsyncFD, isBuff: bool): AsyncSocket = assert fd != osInvalidSocket.TAsyncFD new(result) result.fd = fd.SocketHandle @@ -99,12 +99,12 @@ proc newSocket(fd: TAsyncFD, isBuff: bool): PAsyncSocket = if isBuff: result.currPos = 0 -proc newAsyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, - protocol: TProtocol = IPPROTO_TCP, buffered = true): PAsyncSocket = +proc newAsyncSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP, buffered = true): AsyncSocket = ## Creates a new asynchronous socket. result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) -proc newAsyncSocket*(domain, typ, protocol: cint, buffered = true): PAsyncSocket = +proc newAsyncSocket*(domain, typ, protocol: cint, buffered = true): AsyncSocket = ## Creates a new asynchronous socket. result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) @@ -126,7 +126,7 @@ when defined(ssl): else: raiseSSLError("Unknown Error") proc sendPendingSslData(socket: AsyncSocket, - flags: set[TSocketFlags]) {.async.} = + flags: set[SocketFlag]) {.async.} = let len = bioCtrlPending(socket.bioOut) if len > 0: var data = newStringOfCap(len) @@ -137,7 +137,7 @@ when defined(ssl): data.setLen(read) await socket.fd.TAsyncFd.send(data, flags) - proc appeaseSsl(socket: AsyncSocket, flags: set[TSocketFlags], + proc appeaseSsl(socket: AsyncSocket, flags: set[SocketFlag], sslError: cint) {.async.} = case sslError of SSL_ERROR_WANT_WRITE: @@ -150,7 +150,7 @@ when defined(ssl): else: raiseSSLError("Cannot appease SSL.") - template sslLoop(socket: AsyncSocket, flags: set[TSocketFlags], + template sslLoop(socket: AsyncSocket, flags: set[SocketFlag], op: expr) = var opResult {.inject.} = -1.cint while opResult < 0: @@ -162,21 +162,21 @@ when defined(ssl): let err = getSslError(socket.sslHandle, opResult.cint) yield appeaseSsl(socket, flags, err.cint) -proc connect*(socket: PAsyncSocket, address: string, port: TPort, +proc connect*(socket: AsyncSocket, address: string, port: Port, af = AF_INET) {.async.} = ## Connects ``socket`` to server at ``address:port``. ## ## Returns a ``Future`` which will complete when the connection succeeds ## or an error occurs. await connect(socket.fd.TAsyncFD, address, port, af) - let flags = {TSocketFlags.SafeDisconn} if socket.isSsl: when defined(ssl): + let flags = {SocketFlag.SafeDisconn} sslSetConnectState(socket.sslHandle) sslLoop(socket, flags, sslDoHandshake(socket.sslHandle)) -proc readInto(buf: cstring, size: int, socket: PAsyncSocket, - flags: set[TSocketFlags]): Future[int] {.async.} = +proc readInto(buf: cstring, size: int, socket: AsyncSocket, + flags: set[SocketFlag]): Future[int] {.async.} = if socket.isSsl: when defined(ssl): # SSL mode. @@ -190,14 +190,14 @@ proc readInto(buf: cstring, size: int, socket: PAsyncSocket, # Not in SSL mode. result = data.len -proc readIntoBuf(socket: PAsyncSocket, - flags: set[TSocketFlags]): Future[int] {.async.} = +proc readIntoBuf(socket: AsyncSocket, + flags: set[SocketFlag]): Future[int] {.async.} = result = await readInto(addr socket.buffer[0], BufferSize, socket, flags) socket.currPos = 0 socket.bufLen = result -proc recv*(socket: PAsyncSocket, size: int, - flags = {TSocketFlags.SafeDisconn}): Future[string] {.async.} = +proc recv*(socket: AsyncSocket, size: int, + flags = {SocketFlag.SafeDisconn}): Future[string] {.async.} = ## Reads **up to** ``size`` bytes from ``socket``. ## ## For buffered sockets this function will attempt to read all the requested @@ -218,7 +218,7 @@ proc recv*(socket: PAsyncSocket, size: int, let originalBufPos = socket.currPos if socket.bufLen == 0: - let res = await socket.readIntoBuf(flags - {TSocketFlags.Peek}) + let res = await socket.readIntoBuf(flags - {SocketFlag.Peek}) if res == 0: result.setLen(0) return @@ -226,10 +226,10 @@ proc recv*(socket: PAsyncSocket, size: int, var read = 0 while read < size: if socket.currPos >= socket.bufLen: - if TSocketFlags.Peek in flags: + if SocketFlag.Peek in flags: # We don't want to get another buffer if we're peeking. break - let res = await socket.readIntoBuf(flags - {TSocketFlags.Peek}) + let res = await socket.readIntoBuf(flags - {SocketFlag.Peek}) if res == 0: break @@ -238,7 +238,7 @@ proc recv*(socket: PAsyncSocket, size: int, read.inc(chunk) socket.currPos.inc(chunk) - if TSocketFlags.Peek in flags: + if SocketFlag.Peek in flags: # Restore old buffer cursor position. socket.currPos = originalBufPos result.setLen(read) @@ -247,8 +247,8 @@ proc recv*(socket: PAsyncSocket, size: int, let read = await readInto(addr result[0], size, socket, flags) result.setLen(read) -proc send*(socket: PAsyncSocket, data: string, - flags = {TSocketFlags.SafeDisconn}) {.async.} = +proc send*(socket: AsyncSocket, data: string, + flags = {SocketFlag.SafeDisconn}) {.async.} = ## Sends ``data`` to ``socket``. The returned future will complete once all ## data has been sent. assert socket != nil @@ -261,12 +261,12 @@ proc send*(socket: PAsyncSocket, data: string, else: await send(socket.fd.TAsyncFD, data, flags) -proc acceptAddr*(socket: PAsyncSocket, flags = {TSocketFlags.SafeDisconn}): - Future[tuple[address: string, client: PAsyncSocket]] = +proc acceptAddr*(socket: AsyncSocket, flags = {SocketFlag.SafeDisconn}): + Future[tuple[address: string, client: AsyncSocket]] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection and the remote address of the client. ## The future will complete when the connection is successfully accepted. - var retFuture = newFuture[tuple[address: string, client: PAsyncSocket]]("asyncnet.acceptAddr") + var retFuture = newFuture[tuple[address: string, client: AsyncSocket]]("asyncnet.acceptAddr") var fut = acceptAddr(socket.fd.TAsyncFD, flags) fut.callback = proc (future: Future[tuple[address: string, client: TAsyncFD]]) = @@ -279,15 +279,15 @@ proc acceptAddr*(socket: PAsyncSocket, flags = {TSocketFlags.SafeDisconn}): retFuture.complete(resultTup) return retFuture -proc accept*(socket: PAsyncSocket, - flags = {TSocketFlags.SafeDisconn}): Future[PAsyncSocket] = +proc accept*(socket: AsyncSocket, + flags = {SocketFlag.SafeDisconn}): Future[AsyncSocket] = ## Accepts a new connection. Returns a future containing the client socket ## corresponding to that connection. ## The future will complete when the connection is successfully accepted. - var retFut = newFuture[PAsyncSocket]("asyncnet.accept") + var retFut = newFuture[AsyncSocket]("asyncnet.accept") var fut = acceptAddr(socket, flags) fut.callback = - proc (future: Future[tuple[address: string, client: PAsyncSocket]]) = + proc (future: Future[tuple[address: string, client: AsyncSocket]]) = assert future.finished if future.failed: retFut.fail(future.readError) @@ -295,8 +295,8 @@ proc accept*(socket: PAsyncSocket, retFut.complete(future.read.client) return retFut -proc recvLine*(socket: PAsyncSocket, - flags = {TSocketFlags.SafeDisconn}): Future[string] {.async.} = +proc recvLine*(socket: AsyncSocket, + flags = {SocketFlag.SafeDisconn}): Future[string] {.async.} = ## Reads a line of data from ``socket``. Returned future will complete once ## a full line is read or an error occurs. ## @@ -317,7 +317,7 @@ proc recvLine*(socket: PAsyncSocket, template addNLIfEmpty(): stmt = if result.len == 0: result.add("\c\L") - assert TSocketFlags.Peek notin flags ## TODO: + assert SocketFlag.Peek notin flags ## TODO: if socket.isBuffered: result = "" if socket.bufLen == 0: @@ -365,7 +365,7 @@ proc recvLine*(socket: PAsyncSocket, return add(result.string, c) -proc listen*(socket: PAsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = +proc listen*(socket: AsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} = ## Marks ``socket`` as accepting connections. ## ``Backlog`` specifies the maximum length of the ## queue of pending connections. @@ -373,7 +373,7 @@ proc listen*(socket: PAsyncSocket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} ## Raises an EOS error upon failure. if listen(socket.fd, backlog) < 0'i32: raiseOSError(osLastError()) -proc bindAddr*(socket: PAsyncSocket, port = Port(0), address = "") {. +proc bindAddr*(socket: AsyncSocket, port = Port(0), address = "") {. tags: [ReadIOEffect].} = ## Binds ``address``:``port`` to the socket. ## @@ -397,7 +397,7 @@ proc bindAddr*(socket: PAsyncSocket, port = Port(0), address = "") {. raiseOSError(osLastError()) dealloc(aiList) -proc close*(socket: PAsyncSocket) = +proc close*(socket: AsyncSocket) = ## Closes the socket. socket.fd.TAsyncFD.closeSocket() when defined(ssl): @@ -419,7 +419,7 @@ when defined(ssl): ## prone to security vulnerabilities. socket.isSsl = true socket.sslContext = ctx - socket.sslHandle = SSLNew(PSSLCTX(socket.sslContext)) + socket.sslHandle = SSLNew(SSLCTX(socket.sslContext)) if socket.sslHandle == nil: raiseSslError() @@ -449,7 +449,7 @@ when isMainModule: when test == HighClient: proc main() {.async.} = var sock = newAsyncSocket() - await sock.connect("irc.freenode.net", TPort(6667)) + await sock.connect("irc.freenode.net", Port(6667)) while true: let line = await sock.recvLine() if line == "": @@ -460,7 +460,7 @@ when isMainModule: asyncCheck main() elif test == LowClient: var sock = newAsyncSocket() - var f = connect(sock, "irc.freenode.net", TPort(6667)) + var f = connect(sock, "irc.freenode.net", Port(6667)) f.callback = proc (future: Future[void]) = echo("Connected in future!") @@ -471,9 +471,9 @@ when isMainModule: echo("Read ", future.read.len, ": ", future.read.repr) elif test == LowServer: var sock = newAsyncSocket() - sock.bindAddr(TPort(6667)) + sock.bindAddr(Port(6667)) sock.listen() - proc onAccept(future: Future[PAsyncSocket]) = + proc onAccept(future: Future[AsyncSocket]) = let client = future.read echo "Accepted ", client.fd.cint var t = send(client, "test\c\L") diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim index d1c94868a..38e0b4212 100644 --- a/lib/pure/collections/queues.nim +++ b/lib/pure/collections/queues.nim @@ -18,17 +18,17 @@ type {.deprecated: [TQueue: Queue].} -proc initQueue*[T](initialSize=4): TQueue[T] = +proc initQueue*[T](initialSize=4): Queue[T] = ## creates a new queue. `initialSize` needs to be a power of 2. assert isPowerOfTwo(initialSize) result.mask = initialSize-1 newSeq(result.data, initialSize) -proc len*[T](q: TQueue[T]): int = +proc len*[T](q: Queue[T]): int = ## returns the number of elements of `q`. result = q.count -iterator items*[T](q: TQueue[T]): T = +iterator items*[T](q: Queue[T]): T = ## yields every element of `q`. var i = q.rd var c = q.count @@ -37,7 +37,7 @@ iterator items*[T](q: TQueue[T]): T = yield q.data[i] i = (i + 1) and q.mask -proc add*[T](q: var TQueue[T], item: T) = +proc add*[T](q: var Queue[T], item: T) = ## adds an `item` to the end of the queue `q`. var cap = q.mask+1 if q.count >= cap: @@ -55,18 +55,18 @@ proc add*[T](q: var TQueue[T], item: T) = q.data[q.wr] = item q.wr = (q.wr + 1) and q.mask -proc enqueue*[T](q: var TQueue[T], item: T) = +proc enqueue*[T](q: var Queue[T], item: T) = ## alias for the ``add`` operation. add(q, item) -proc dequeue*[T](q: var TQueue[T]): T = +proc dequeue*[T](q: var Queue[T]): T = ## removes and returns the first element of the queue `q`. assert q.count > 0 dec q.count result = q.data[q.rd] q.rd = (q.rd + 1) and q.mask -proc `$`*[T](q: TQueue[T]): string = +proc `$`*[T](q: Queue[T]): string = ## turns a queue into its string representation. result = "[" for x in items(q): diff --git a/lib/pure/concurrency/cpuload.nim b/lib/pure/concurrency/cpuload.nim index 74a639be1..88fb4a064 100644 --- a/lib/pure/concurrency/cpuload.nim +++ b/lib/pure/concurrency/cpuload.nim @@ -57,7 +57,7 @@ proc advice*(s: var ThreadPoolState): ThreadPoolAdvice = s.prevProcKernel = procKernel s.prevProcUser = procUser elif defined(linux): - proc fscanf(c: TFile, frmt: cstring) {.varargs, importc, + proc fscanf(c: File, frmt: cstring) {.varargs, importc, header: "".} var f = open("/proc/loadavg") diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 81314e967..2b161778c 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -101,7 +101,7 @@ type body: string] Proxy* = ref object - url*: TUrl + url*: Url auth*: string ProtocolError* = object of IOError ## exception that is raised when server @@ -130,7 +130,7 @@ proc fileError(msg: string) = e.msg = msg raise e -proc parseChunks(s: TSocket, timeout: int): string = +proc parseChunks(s: Socket, timeout: int): string = result = "" var ri = 0 while true: @@ -168,7 +168,7 @@ proc parseChunks(s: TSocket, timeout: int): string = # Trailer headers will only be sent if the request specifies that we want # them: http://tools.ietf.org/html/rfc2616#section-3.6.1 -proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = +proc parseBody(s: Socket, headers: StringTableRef, timeout: int): string = result = "" if headers["Transfer-Encoding"] == "chunked": result = parseChunks(s, timeout) @@ -203,7 +203,7 @@ proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = buf.setLen(r) result.add(buf) -proc parseResponse(s: TSocket, getBody: bool, timeout: int): TResponse = +proc parseResponse(s: Socket, getBody: bool, timeout: int): Response = var parsedStatus = false var linei = 0 var fullyRead = false @@ -272,20 +272,20 @@ type {.deprecated: [THttpMethod: HttpMethod].} when not defined(ssl): - type PSSLContext = ref object - let defaultSSLContext: PSSLContext = nil + type SSLContext = ref object + let defaultSSLContext: SSLContext = nil else: let defaultSSLContext = newContext(verifyMode = CVerifyNone) -proc newProxy*(url: string, auth = ""): PProxy = +proc newProxy*(url: string, auth = ""): Proxy = ## Constructs a new ``TProxy`` object. - result = PProxy(url: parseUrl(url), auth: auth) + result = Proxy(url: parseUrl(url), auth: auth) proc request*(url: string, httpMethod = httpGET, extraHeaders = "", body = "", - sslContext: PSSLContext = defaultSSLContext, + sslContext: SSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, - proxy: PProxy = nil): TResponse = + proxy: Proxy = nil): Response = ## | Requests ``url`` with the specified ``httpMethod``. ## | Extra headers can be specified and must be seperated by ``\c\L`` ## | An optional timeout can be specified in miliseconds, if reading from the @@ -310,16 +310,16 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", var s = socket() if s == invalidSocket: raiseOSError(osLastError()) - var port = sockets.TPort(80) + var port = sockets.Port(80) if r.scheme == "https": when defined(ssl): sslContext.wrapSocket(s) - port = sockets.TPort(443) + port = sockets.Port(443) else: - raise newException(EHttpRequestErr, + raise newException(HttpRequestError, "SSL support is not available. Cannot connect over SSL.") if r.port != "": - port = sockets.TPort(r.port.parseInt) + port = sockets.Port(r.port.parseInt) if timeout == -1: s.connect(r.hostname, port) @@ -338,7 +338,7 @@ proc redirection(status: string): bool = if status.startsWith(i): return true -proc getNewLocation(lastUrl: string, headers: PStringTable): string = +proc getNewLocation(lastUrl: string, headers: StringTableRef): string = result = headers["Location"] if result == "": httpError("location header expected") # Relative URLs. (Not part of the spec, but soon will be.) @@ -348,10 +348,10 @@ proc getNewLocation(lastUrl: string, headers: PStringTable): string = result = origParsed.hostname & "/" & r.path proc get*(url: string, extraHeaders = "", maxRedirects = 5, - sslContext: PSSLContext = defaultSSLContext, + sslContext: SSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, - proxy: PProxy = nil): TResponse = - ## | GETs the ``url`` and returns a ``TResponse`` object + proxy: Proxy = nil): Response = + ## | GETs the ``url`` and returns a ``Response`` object ## | This proc also handles redirection ## | Extra headers can be specified and must be separated by ``\c\L``. ## | An optional timeout can be specified in miliseconds, if reading from the @@ -367,9 +367,9 @@ proc get*(url: string, extraHeaders = "", maxRedirects = 5, lastUrl = redirectTo proc getContent*(url: string, extraHeaders = "", maxRedirects = 5, - sslContext: PSSLContext = defaultSSLContext, + sslContext: SSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, - proxy: PProxy = nil): string = + proxy: Proxy = nil): string = ## | GETs the body and returns it as a string. ## | Raises exceptions for the status codes ``4xx`` and ``5xx`` ## | Extra headers can be specified and must be separated by ``\c\L``. @@ -378,16 +378,16 @@ proc getContent*(url: string, extraHeaders = "", maxRedirects = 5, var r = get(url, extraHeaders, maxRedirects, sslContext, timeout, userAgent, proxy) if r.status[0] in {'4','5'}: - raise newException(EHTTPRequestErr, r.status) + raise newException(HttpRequestError, r.status) else: return r.body proc post*(url: string, extraHeaders = "", body = "", maxRedirects = 5, - sslContext: PSSLContext = defaultSSLContext, + sslContext: SSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, - proxy: PProxy = nil): TResponse = - ## | POSTs ``body`` to the ``url`` and returns a ``TResponse`` object. + proxy: Proxy = nil): Response = + ## | POSTs ``body`` to the ``url`` and returns a ``Response`` object. ## | This proc adds the necessary Content-Length header. ## | This proc also handles redirection. ## | Extra headers can be specified and must be separated by ``\c\L``. @@ -407,9 +407,9 @@ proc post*(url: string, extraHeaders = "", body = "", proc postContent*(url: string, extraHeaders = "", body = "", maxRedirects = 5, - sslContext: PSSLContext = defaultSSLContext, + sslContext: SSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, - proxy: PProxy = nil): string = + proxy: Proxy = nil): string = ## | POSTs ``body`` to ``url`` and returns the response's body as a string ## | Raises exceptions for the status codes ``4xx`` and ``5xx`` ## | Extra headers can be specified and must be separated by ``\c\L``. @@ -418,18 +418,18 @@ proc postContent*(url: string, extraHeaders = "", body = "", var r = post(url, extraHeaders, body, maxRedirects, sslContext, timeout, userAgent, proxy) if r.status[0] in {'4','5'}: - raise newException(EHTTPRequestErr, r.status) + raise newException(HttpRequestError, r.status) else: return r.body proc downloadFile*(url: string, outputFilename: string, - sslContext: PSSLContext = defaultSSLContext, + sslContext: SSLContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, - proxy: PProxy = nil) = + proxy: Proxy = nil) = ## | Downloads ``url`` and saves it to ``outputFilename`` ## | An optional timeout can be specified in miliseconds, if reading from the ## server takes longer than specified an ETimeout exception will be raised. - var f: TFile + var f: File if open(f, outputFilename, fmWrite): f.write(getContent(url, sslContext = sslContext, timeout = timeout, userAgent = userAgent, proxy = proxy)) @@ -437,8 +437,8 @@ proc downloadFile*(url: string, outputFilename: string, else: fileError("Unable to open file") -proc generateHeaders(r: TURL, httpMethod: THttpMethod, - headers: PStringTable): string = +proc generateHeaders(r: Url, httpMethod: HttpMethod, + headers: StringTableRef): string = result = substr($httpMethod, len("http")) # TODO: Proxies result.add(" /" & r.path & r.query) @@ -455,7 +455,7 @@ type AsyncHttpClient* = ref object socket: AsyncSocket connected: bool - currentURL: TURL ## Where we are currently connected. + currentURL: Url ## Where we are currently connected. headers*: StringTableRef maxRedirects: int userAgent: string @@ -466,7 +466,7 @@ type proc newAsyncHttpClient*(userAgent = defUserAgent, maxRedirects = 5, sslContext = defaultSslContext): AsyncHttpClient = - ## Creates a new PAsyncHttpClient instance. + ## Creates a new AsyncHttpClient instance. ## ## ``userAgent`` specifies the user agent that will be used when making ## requests. @@ -488,7 +488,7 @@ proc close*(client: AsyncHttpClient) = client.socket.close() client.connected = false -proc recvFull(socket: PAsyncSocket, size: int): Future[string] {.async.} = +proc recvFull(socket: AsyncSocket, size: int): Future[string] {.async.} = ## Ensures that all the data requested is read and returned. result = "" while true: @@ -497,7 +497,7 @@ proc recvFull(socket: PAsyncSocket, size: int): Future[string] {.async.} = if data == "": break # We've been disconnected. result.add data -proc parseChunks(client: PAsyncHttpClient): Future[string] {.async.} = +proc parseChunks(client: AsyncHttpClient): Future[string] {.async.} = result = "" var ri = 0 while true: @@ -529,8 +529,8 @@ proc parseChunks(client: PAsyncHttpClient): Future[string] {.async.} = # Trailer headers will only be sent if the request specifies that we want # them: http://tools.ietf.org/html/rfc2616#section-3.6.1 -proc parseBody(client: PAsyncHttpClient, - headers: PStringTable): Future[string] {.async.} = +proc parseBody(client: AsyncHttpClient, + headers: StringTableRef): Future[string] {.async.} = result = "" if headers["Transfer-Encoding"] == "chunked": result = await parseChunks(client) @@ -559,8 +559,8 @@ proc parseBody(client: PAsyncHttpClient, if buf == "": break result.add(buf) -proc parseResponse(client: PAsyncHttpClient, - getBody: bool): Future[TResponse] {.async.} = +proc parseResponse(client: AsyncHttpClient, + getBody: bool): Future[Response] {.async.} = var parsedStatus = false var linei = 0 var fullyRead = false @@ -607,34 +607,34 @@ proc parseResponse(client: PAsyncHttpClient, else: result.body = "" -proc newConnection(client: PAsyncHttpClient, url: TURL) {.async.} = +proc newConnection(client: AsyncHttpClient, url: Url) {.async.} = if client.currentURL.hostname != url.hostname or client.currentURL.scheme != url.scheme: if client.connected: client.close() client.socket = newAsyncSocket() - # TODO: I should be able to write 'net.TPort' here... + # TODO: I should be able to write 'net.Port' here... let port = if url.port == "": if url.scheme.toLower() == "https": - rawsockets.TPort(443) + rawsockets.Port(443) else: - rawsockets.TPort(80) - else: rawsockets.TPort(url.port.parseInt) + rawsockets.Port(80) + else: rawsockets.Port(url.port.parseInt) if url.scheme.toLower() == "https": when defined(ssl): client.sslContext.wrapSocket(client.socket) else: - raise newException(EHttpRequestErr, + raise newException(HttpRequestError, "SSL support is not available. Cannot connect over SSL.") await client.socket.connect(url.hostname, port) client.currentURL = url client.connected = true -proc request*(client: PAsyncHttpClient, url: string, httpMethod = httpGET, - body = ""): Future[TResponse] {.async.} = +proc request*(client: AsyncHttpClient, url: string, httpMethod = httpGET, + body = ""): Future[Response] {.async.} = ## Connects to the hostname specified by the URL and performs a request ## using the method specified. ## @@ -657,7 +657,7 @@ proc request*(client: PAsyncHttpClient, url: string, httpMethod = httpGET, result = await parseResponse(client, httpMethod != httpHEAD) -proc get*(client: PAsyncHttpClient, url: string): Future[TResponse] {.async.} = +proc get*(client: AsyncHttpClient, url: string): Future[Response] {.async.} = ## Connects to the hostname specified by the URL and performs a GET request. ## ## This procedure will follow redirects up to a maximum number of redirects diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim index dc6db4738..38a068ea1 100644 --- a/lib/pure/httpserver.nim +++ b/lib/pure/httpserver.nim @@ -15,12 +15,12 @@ ## import strutils, sockets, httpserver ## ## var counter = 0 -## proc handleRequest(client: TSocket, path, query: string): bool {.procvar.} = +## proc handleRequest(client: Socket, path, query: string): bool {.procvar.} = ## inc(counter) ## client.send("Hello for the $#th time." % $counter & wwwNL) ## return false # do not stop processing ## -## run(handleRequest, TPort(80)) +## run(handleRequest, Port(80)) ## import parseutils, strutils, os, osproc, strtabs, streams, sockets, asyncio @@ -31,14 +31,14 @@ const # --------------- output messages -------------------------------------------- -proc sendTextContentType(client: TSocket) = +proc sendTextContentType(client: Socket) = send(client, "Content-type: text/html" & wwwNL) send(client, wwwNL) -proc sendStatus(client: TSocket, status: string) = +proc sendStatus(client: Socket, status: string) = send(client, "HTTP/1.1 " & status & wwwNL) -proc badRequest(client: TSocket) = +proc badRequest(client: Socket) = # Inform the client that a request it has made has a problem. send(client, "HTTP/1.1 400 Bad Request" & wwwNL) sendTextContentType(client) @@ -46,18 +46,18 @@ proc badRequest(client: TSocket) = "such as a POST without a Content-Length.

" & wwwNL) when false: - proc cannotExec(client: TSocket) = + proc cannotExec(client: Socket) = send(client, "HTTP/1.1 500 Internal Server Error" & wwwNL) sendTextContentType(client) send(client, "

Error prohibited CGI execution." & wwwNL) -proc headers(client: TSocket, filename: string) = +proc headers(client: Socket, filename: string) = # XXX could use filename to determine file type send(client, "HTTP/1.1 200 OK" & wwwNL) send(client, ServerSig) sendTextContentType(client) -proc notFound(client: TSocket) = +proc notFound(client: Socket) = send(client, "HTTP/1.1 404 NOT FOUND" & wwwNL) send(client, ServerSig) sendTextContentType(client) @@ -67,7 +67,7 @@ proc notFound(client: TSocket) = send(client, "is unavailable or nonexistent.

" & wwwNL) send(client, "" & wwwNL) -proc unimplemented(client: TSocket) = +proc unimplemented(client: Socket) = send(client, "HTTP/1.1 501 Method Not Implemented" & wwwNL) send(client, ServerSig) sendTextContentType(client) @@ -79,11 +79,11 @@ proc unimplemented(client: TSocket) = # ----------------- file serving --------------------------------------------- when false: - proc discardHeaders(client: TSocket) = skip(client) + proc discardHeaders(client: Socket) = skip(client) -proc serveFile*(client: TSocket, filename: string) = +proc serveFile*(client: Socket, filename: string) = ## serves a file to the client. - var f: TFile + var f: File if open(f, filename): headers(client, filename) const bufSize = 8000 # != 8K might be good for memory manager @@ -108,7 +108,7 @@ when false: type TRequestMethod = enum reqGet, reqPost - proc executeCgi(client: TSocket, path, query: string, meth: TRequestMethod) = + proc executeCgi(client: Socket, path, query: string, meth: TRequestMethod) = var env = newStringTable(modeCaseInsensitive) var contentLength = -1 case meth @@ -158,7 +158,7 @@ when false: # --------------- Server Setup ----------------------------------------------- - proc acceptRequest(client: TSocket) = + proc acceptRequest(client: Socket) = var cgi = false var query = "" var buf = TaintedString"" @@ -208,21 +208,21 @@ when false: executeCgi(client, path, query, meth) type - TServer* = object of TObject ## contains the current server state - socket: TSocket - port: TPort - client*: TSocket ## the socket to write the file data to - reqMethod*: string ## Request method. GET or POST. - path*, query*: string ## path and query the client requested - headers*: PStringTable ## headers with which the client made the request - body*: string ## only set with POST requests - ip*: string ## ip address of the requesting client + TServer* = object of RootObj ## contains the current server state + socket: Socket + port: Port + client*: Socket ## the socket to write the file data to + reqMethod*: string ## Request method. GET or POST. + path*, query*: string ## path and query the client requested + headers*: StringTableRef ## headers with which the client made the request + body*: string ## only set with POST requests + ip*: string ## ip address of the requesting client PAsyncHTTPServer* = ref TAsyncHTTPServer TAsyncHTTPServer = object of TServer - asyncSocket: PAsyncSocket + asyncSocket: AsyncSocket -proc open*(s: var TServer, port = TPort(80), reuseAddr = false) = +proc open*(s: var TServer, port = Port(80), reuseAddr = false) = ## creates a new server at port `port`. If ``port == 0`` a free port is ## acquired that can be accessed later by the ``port`` proc. s.socket = socket(AF_INET) @@ -232,7 +232,7 @@ proc open*(s: var TServer, port = TPort(80), reuseAddr = false) = bindAddr(s.socket, port) listen(s.socket) - if port == TPort(0): + if port == Port(0): s.port = getSockName(s.socket) else: s.port = port @@ -243,13 +243,13 @@ proc open*(s: var TServer, port = TPort(80), reuseAddr = false) = s.query = "" s.headers = {:}.newStringTable() -proc port*(s: var TServer): TPort = +proc port*(s: var TServer): Port = ## get the port number the server has acquired. result = s.port proc next*(s: var TServer) = ## proceed to the first/next request. - var client: TSocket + var client: Socket new(client) var ip: string acceptAddr(s.socket, client, ip) @@ -358,9 +358,9 @@ proc close*(s: TServer) = ## closes the server (and the socket the server uses). close(s.socket) -proc run*(handleRequest: proc (client: TSocket, +proc run*(handleRequest: proc (client: Socket, path, query: string): bool {.closure.}, - port = TPort(80)) = + port = Port(80)) = ## encapsulates the server object and main loop var s: TServer open(s, port) @@ -375,7 +375,7 @@ proc run*(handleRequest: proc (client: TSocket, proc nextAsync(s: PAsyncHTTPServer) = ## proceed to the first/next request. - var client: TSocket + var client: Socket new(client) var ip: string acceptAddr(getSocket(s.asyncSocket), client, ip) @@ -474,16 +474,16 @@ proc nextAsync(s: PAsyncHTTPServer) = s.query = "" s.path = data.substr(i, last-1) -proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSocket, +proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: Socket, path, query: string): bool {.closure, gcsafe.}, - port = TPort(80), address = "", + port = Port(80), address = "", reuseAddr = false): PAsyncHTTPServer = ## Creates an Asynchronous HTTP server at ``port``. var capturedRet: PAsyncHTTPServer new(capturedRet) capturedRet.asyncSocket = asyncSocket() capturedRet.asyncSocket.handleAccept = - proc (s: PAsyncSocket) = + proc (s: AsyncSocket) = nextAsync(capturedRet) let quit = handleRequest(capturedRet, capturedRet.client, capturedRet.path, capturedRet.query) @@ -493,7 +493,7 @@ proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSo capturedRet.asyncSocket.bindAddr(port, address) capturedRet.asyncSocket.listen() - if port == TPort(0): + if port == Port(0): capturedRet.port = getSockName(capturedRet.asyncSocket) else: capturedRet.port = port @@ -506,8 +506,8 @@ proc asyncHTTPServer*(handleRequest: proc (server: PAsyncHTTPServer, client: TSo capturedRet.headers = {:}.newStringTable() result = capturedRet -proc register*(d: PDispatcher, s: PAsyncHTTPServer) = - ## Registers a ``PAsyncHTTPServer`` with a ``PDispatcher``. +proc register*(d: Dispatcher, s: PAsyncHTTPServer) = + ## Registers a ``PAsyncHTTPServer`` with a ``Dispatcher``. d.register(s.asyncSocket) proc close*(h: PAsyncHTTPServer) = @@ -518,7 +518,7 @@ when isMainModule: var counter = 0 var s: TServer - open(s, TPort(0)) + open(s, Port(0)) echo("httpserver running on port ", s.port) while true: next(s) diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 1b6572d53..987c35d1c 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -196,7 +196,6 @@ when not defined(JS): ## computes x to power raised of y. # C procs: - proc gettime(dummy: ptr cint): cint {.importc: "time", header: "".} proc srand(seed: cint) {.importc: "srand", header: "".} proc rand(): cint {.importc: "rand", header: "".} @@ -331,6 +330,8 @@ proc standardDeviation*(s: RunningStat): float = {.pop.} when isMainModule and not defined(JS): + proc gettime(dummy: ptr cint): cint {.importc: "time", header: "".} + # Verifies random seed initialization. let seed = gettime(nil) randomize(seed) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 2b2c8cfda..8afc6c5c5 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -54,8 +54,8 @@ type when defined(ssl): case isSsl*: bool of true: - sslHandle*: PSSL - sslContext*: PSSLContext + sslHandle*: SSLPtr + sslContext*: SSLContext sslNoHandshake*: bool # True if needs handshake. sslHasPeekChar*: bool sslPeekChar*: char @@ -147,11 +147,11 @@ when defined(ssl): raise newException(SSLError, $errStr) # http://simplestcodings.blogspot.co.uk/2010/08/secure-server-client-using-openssl-in-c.html - proc loadCertificates(ctx: PSSL_CTX, certFile, keyFile: string) = + proc loadCertificates(ctx: SSL_CTX, certFile, keyFile: string) = if certFile != "" and not existsFile(certFile): - raise newException(system.EIO, "Certificate file could not be found: " & certFile) + raise newException(system.IOError, "Certificate file could not be found: " & certFile) if keyFile != "" and not existsFile(keyFile): - raise newException(system.EIO, "Key file could not be found: " & keyFile) + raise newException(system.IOError, "Key file could not be found: " & keyFile) if certFile != "": var ret = SSLCTXUseCertificateChainFile(ctx, certFile) @@ -168,7 +168,7 @@ when defined(ssl): raiseSSLError("Verification of private key file failed.") proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer, - certFile = "", keyFile = ""): PSSLContext = + certFile = "", keyFile = ""): SSLContext = ## Creates an SSL context. ## ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 @@ -184,7 +184,7 @@ when defined(ssl): ## path, a server socket will most likely not work without these. ## Certificates can be generated using the following command: ## ``openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem``. - var newCTX: PSSL_CTX + var newCTX: SSL_CTX case protVersion of protSSLv23: newCTX = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support. @@ -210,9 +210,9 @@ when defined(ssl): discard newCTX.SSLCTXSetMode(SSL_MODE_AUTO_RETRY) newCTX.loadCertificates(certFile, keyFile) - return PSSLContext(newCTX) + return SSLContext(newCTX) - proc wrapSocket*(ctx: PSSLContext, socket: PSocket) = + proc wrapSocket*(ctx: SSLContext, socket: Socket) = ## Wraps a socket in an SSL context. This function effectively turns ## ``socket`` into an SSL socket. ## @@ -221,7 +221,7 @@ when defined(ssl): socket.isSSL = true socket.sslContext = ctx - socket.sslHandle = SSLNew(PSSLCTX(socket.sslContext)) + socket.sslHandle = SSLNew(SSLCTX(socket.sslContext)) socket.sslNoHandshake = false socket.sslHasPeekChar = false if socket.sslHandle == nil: @@ -350,9 +350,9 @@ proc acceptAddr*(server: Socket, client: var Socket, address: var string, address = $inet_ntoa(sockAddress.sin_addr) when false: #defined(ssl): - proc acceptAddrSSL*(server: PSocket, client: var PSocket, + proc acceptAddrSSL*(server: Socket, client: var Socket, address: var string): TSSLAcceptResult {. - tags: [FReadIO].} = + tags: [ReadIOEffect].} = ## This procedure should only be used for non-blocking **SSL** sockets. ## It will immediately return with one of the following values: ## @@ -480,7 +480,7 @@ proc connect*(socket: Socket, address: string, port = Port(0), socketError(socket, ret) when defined(ssl): - proc handshake*(socket: PSocket): bool {.tags: [FReadIO, FWriteIO].} = + proc handshake*(socket: Socket): bool {.tags: [ReadIOEffect, WriteIOEffect].} = ## This proc needs to be called on a socket after it connects. This is ## only applicable when using ``connectAsync``. ## This proc performs the SSL handshake. @@ -510,7 +510,7 @@ when defined(ssl): else: raiseSSLError("Socket is not an SSL socket.") - proc gotHandshake*(socket: PSocket): bool = + proc gotHandshake*(socket: Socket): bool = ## Determines whether a handshake has occurred between a client (``socket``) ## and the server that ``socket`` is connected to. ## diff --git a/lib/pure/smtp.nim b/lib/pure/smtp.nim index e088e0bd9..26f0c9591 100644 --- a/lib/pure/smtp.nim +++ b/lib/pure/smtp.nim @@ -54,12 +54,12 @@ type {.deprecated: [EInvalidReply: ReplyError, TMessage: Message, TSMTP: Smtp].} -proc debugSend(smtp: TSMTP, cmd: string) = +proc debugSend(smtp: Smtp, cmd: string) = if smtp.debug: echo("C:" & cmd) smtp.sock.send(cmd) -proc debugRecv(smtp: var TSMTP): TaintedString = +proc debugRecv(smtp: var Smtp): TaintedString = var line = TaintedString"" smtp.sock.readLine(line) @@ -67,11 +67,11 @@ proc debugRecv(smtp: var TSMTP): TaintedString = echo("S:" & line.string) return line -proc quitExcpt(smtp: TSMTP, msg: string) = +proc quitExcpt(smtp: Smtp, msg: string) = smtp.debugSend("QUIT") - raise newException(EInvalidReply, msg) + raise newException(ReplyError, msg) -proc checkReply(smtp: var TSMTP, reply: string) = +proc checkReply(smtp: var Smtp, reply: string) = var line = smtp.debugRecv() if not line.string.startswith(reply): quitExcpt(smtp, "Expected " & reply & " reply, got: " & line.string) @@ -86,9 +86,9 @@ else: proc connect*(address: string, port = Port(25), ssl = false, debug = false, - sslContext = defaultSSLContext): TSMTP = + sslContext = defaultSSLContext): Smtp = ## Establishes a connection with a SMTP server. - ## May fail with EInvalidReply or with a socket error. + ## May fail with ReplyError or with a socket error. result.sock = newSocket() if ssl: when compiledWithSsl: @@ -103,10 +103,10 @@ proc connect*(address: string, port = Port(25), result.debugSend("HELO " & address & "\c\L") result.checkReply("250") -proc auth*(smtp: var TSMTP, username, password: string) = +proc auth*(smtp: var Smtp, username, password: string) = ## Sends an AUTH command to the server to login as the `username` ## using `password`. - ## May fail with EInvalidReply. + ## May fail with ReplyError. smtp.debugSend("AUTH LOGIN\c\L") smtp.checkReply("334") # TODO: Check whether it's asking for the "Username:" @@ -117,11 +117,11 @@ proc auth*(smtp: var TSMTP, username, password: string) = smtp.debugSend(encode(password) & "\c\L") smtp.checkReply("235") # Check whether the authentification was successful. -proc sendmail*(smtp: var TSMTP, fromaddr: string, +proc sendmail*(smtp: var Smtp, fromaddr: string, toaddrs: seq[string], msg: string) = ## Sends `msg` from `fromaddr` to `toaddr`. ## Messages may be formed using ``createMessage`` by converting the - ## TMessage into a string. + ## Message into a string. smtp.debugSend("MAIL FROM:<" & fromaddr & ">\c\L") smtp.checkReply("250") @@ -136,13 +136,13 @@ proc sendmail*(smtp: var TSMTP, fromaddr: string, smtp.debugSend(".\c\L") smtp.checkReply("250") -proc close*(smtp: TSMTP) = +proc close*(smtp: Smtp) = ## Disconnects from the SMTP server and closes the socket. smtp.debugSend("QUIT\c\L") smtp.sock.close() proc createMessage*(mSubject, mBody: string, mTo, mCc: seq[string], - otherHeaders: openarray[tuple[name, value: string]]): TMessage = + otherHeaders: openarray[tuple[name, value: string]]): Message = ## Creates a new MIME compliant message. result.msgTo = mTo result.msgCc = mCc @@ -153,7 +153,7 @@ proc createMessage*(mSubject, mBody: string, mTo, mCc: seq[string], result.msgOtherHeaders[n] = v proc createMessage*(mSubject, mBody: string, mTo, - mCc: seq[string] = @[]): TMessage = + mCc: seq[string] = @[]): Message = ## Alternate version of the above. result.msgTo = mTo result.msgCc = mCc @@ -161,8 +161,8 @@ proc createMessage*(mSubject, mBody: string, mTo, result.msgBody = mBody result.msgOtherHeaders = newStringTable() -proc `$`*(msg: TMessage): string = - ## stringify for ``TMessage``. +proc `$`*(msg: Message): string = + ## stringify for ``Message``. result = "" if msg.msgTo.len() > 0: result = "TO: " & msg.msgTo.join(", ") & "\c\L" @@ -192,7 +192,7 @@ proc newAsyncSmtp*(address: string, port: Port, useSsl = false, raise newException(ESystem, "SMTP module compiled without SSL support") -proc quitExcpt(smtp: AsyncSmtp, msg: string): PFuture[void] = +proc quitExcpt(smtp: AsyncSmtp, msg: string): Future[void] = var retFuture = newFuture[void]() var sendFut = smtp.sock.send("QUIT") sendFut.callback = @@ -208,7 +208,7 @@ proc checkReply(smtp: AsyncSmtp, reply: string) {.async.} = proc connect*(smtp: AsyncSmtp) {.async.} = ## Establishes a connection with a SMTP server. - ## May fail with EInvalidReply or with a socket error. + ## May fail with ReplyError or with a socket error. await smtp.sock.connect(smtp.address, smtp.port) await smtp.checkReply("220") @@ -218,7 +218,7 @@ proc connect*(smtp: AsyncSmtp) {.async.} = proc auth*(smtp: AsyncSmtp, username, password: string) {.async.} = ## Sends an AUTH command to the server to login as the `username` ## using `password`. - ## May fail with EInvalidReply. + ## May fail with ReplyError. await smtp.sock.send("AUTH LOGIN\c\L") await smtp.checkReply("334") # TODO: Check whether it's asking for the "Username:" @@ -233,7 +233,7 @@ proc sendMail*(smtp: AsyncSmtp, fromAddr: string, toAddrs: seq[string], msg: string) {.async.} = ## Sends ``msg`` from ``fromAddr`` to the addresses specified in ``toAddrs``. ## Messages may be formed using ``createMessage`` by converting the - ## TMessage into a string. + ## Message into a string. await smtp.sock.send("MAIL FROM:<" & fromAddr & ">\c\L") await smtp.checkReply("250") diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 36389edcc..99cdc002c 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -55,7 +55,7 @@ when defined(ssl): SSLProtVersion* = enum protSSLv2, protSSLv3, protTLSv1, protSSLv23 - SSLContext* = distinct PSSLCTX + SSLContext* = distinct SSLCTX SSLAcceptResult* = enum AcceptNoClient = 0, AcceptNoHandshake, AcceptSuccess @@ -79,7 +79,7 @@ type when defined(ssl): case isSsl: bool of true: - sslHandle: PSSL + sslHandle: SSLPtr sslContext: SSLContext sslNoHandshake: bool # True if needs handshake. sslHasPeekChar: bool @@ -254,21 +254,21 @@ when defined(ssl): proc raiseSSLError(s = "") = if s != "": - raise newException(ESSL, s) + raise newException(SSLError, s) let err = ErrPeekLastError() if err == 0: - raise newException(ESSL, "No error reported.") + raise newException(SSLError, "No error reported.") if err == -1: raiseOSError(osLastError()) var errStr = ErrErrorString(err, nil) - raise newException(ESSL, $errStr) + raise newException(SSLError, $errStr) # http://simplestcodings.blogspot.co.uk/2010/08/secure-server-client-using-openssl-in-c.html - proc loadCertificates(ctx: PSSL_CTX, certFile, keyFile: string) = + proc loadCertificates(ctx: SSL_CTX, certFile, keyFile: string) = if certFile != "" and not existsFile(certFile): - raise newException(system.EIO, "Certificate file could not be found: " & certFile) + raise newException(system.IOError, "Certificate file could not be found: " & certFile) if keyFile != "" and not existsFile(keyFile): - raise newException(system.EIO, "Key file could not be found: " & keyFile) + raise newException(system.IOError, "Key file could not be found: " & keyFile) if certFile != "": var ret = SSLCTXUseCertificateChainFile(ctx, certFile) @@ -285,7 +285,7 @@ when defined(ssl): raiseSslError("Verification of private key file failed.") proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer, - certFile = "", keyFile = ""): PSSLContext = + certFile = "", keyFile = ""): SSLContext = ## Creates an SSL context. ## ## Protocol version specifies the protocol to use. SSLv2, SSLv3, TLSv1 are @@ -301,7 +301,7 @@ when defined(ssl): ## path, a server socket will most likely not work without these. ## Certificates can be generated using the following command: ## ``openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem``. - var newCTX: PSSL_CTX + var newCTX: SSL_CTX case protVersion of protSSLv23: newCTX = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support. @@ -327,9 +327,9 @@ when defined(ssl): discard newCTX.SSLCTXSetMode(SSL_MODE_AUTO_RETRY) newCTX.loadCertificates(certFile, keyFile) - return PSSLContext(newCTX) + return SSLContext(newCTX) - proc wrapSocket*(ctx: PSSLContext, socket: TSocket) = + proc wrapSocket*(ctx: SSLContext, socket: Socket) = ## Wraps a socket in an SSL context. This function effectively turns ## ``socket`` into an SSL socket. ## @@ -338,7 +338,7 @@ when defined(ssl): socket.isSSL = true socket.sslContext = ctx - socket.sslHandle = SSLNew(PSSLCTX(socket.sslContext)) + socket.sslHandle = SSLNew(SSLCTX(socket.sslContext)) socket.sslNoHandshake = false socket.sslHasPeekChar = false if socket.sslHandle == nil: @@ -561,9 +561,9 @@ proc setBlocking*(s: Socket, blocking: bool) {.tags: [], gcsafe.} ## Sets blocking mode on socket when defined(ssl): - proc acceptAddrSSL*(server: TSocket, client: var TSocket, - address: var string): TSSLAcceptResult {. - tags: [FReadIO].} = + proc acceptAddrSSL*(server: Socket, client: var Socket, + address: var string): SSLAcceptResult {. + tags: [ReadIOEffect].} = ## This procedure should only be used for non-blocking **SSL** sockets. ## It will immediately return with one of the following values: ## @@ -886,7 +886,7 @@ proc connectAsync*(socket: Socket, name: string, port = Port(0), socket.sslNoHandshake = true when defined(ssl): - proc handshake*(socket: TSocket): bool {.tags: [FReadIO, FWriteIO].} = + proc handshake*(socket: Socket): bool {.tags: [ReadIOEffect, WriteIOEffect].} = ## This proc needs to be called on a socket after it connects. This is ## only applicable when using ``connectAsync``. ## This proc performs the SSL handshake. @@ -916,7 +916,7 @@ when defined(ssl): else: raiseSslError("Socket is not an SSL socket.") - proc gotHandshake*(socket: TSocket): bool = + proc gotHandshake*(socket: Socket): bool = ## Determines whether a handshake has occurred between a client (``socket``) ## and the server that ``socket`` is connected to. ## @@ -1689,7 +1689,7 @@ proc setBlocking(s: Socket, blocking: bool) = raiseOSError(osLastError()) s.nonblocking = not blocking -discard """ proc setReuseAddr*(s: TSocket) = +discard """ proc setReuseAddr*(s: Socket) = var blah: int = 1 var mode = SO_REUSEADDR if setsockopt(s.fd, SOL_SOCKET, mode, addr blah, TSOcklen(sizeof(int))) == -1: From ad71fb41a3367ef2661b0aacb86f792e0b7192b5 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 01:38:17 +0100 Subject: [PATCH 245/409] fixes #1258 --- doc/manual/templates.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/manual/templates.txt b/doc/manual/templates.txt index d63f61f54..4793d68a7 100644 --- a/doc/manual/templates.txt +++ b/doc/manual/templates.txt @@ -225,6 +225,23 @@ a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates. +Limitations of the method invokation syntax +------------------------------------------- + +The expression ``x`` in ``x.f`` needs to be semantically checked (that means +symbol lookup and type checking) before it can be decided that it needs to be +rewritten to ``f(x)``. Therefore the dot syntax has some limiations when it +is used to invoke templates/macros: + +.. code-block:: nim + template declareVar(name: expr): stmt = + const name {.inject.} = 45 + + # Doesn't compile: + unknownIdentifier.declareVar + + + Macros ====== From b5d741928ea7a37eeee0a45077bdd136729b1ec4 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 01:38:39 +0100 Subject: [PATCH 246/409] fixes #1106 --- doc/manual/procs.txt | 59 ++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index 66f9ad58f..8baf01dbb 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -214,12 +214,16 @@ Nonoverloadable builtins The following builtin procs cannot be overloaded for reasons of implementation simplicity (they require specialized semantic checking):: - defined, definedInScope, compiles, low, high, sizeOf, - is, of, echo, shallowCopy, getAst, spawn + declared, defined, definedInScope, compiles, low, high, sizeOf, + is, of, echo, shallowCopy, getAst, astToStr, spawn Thus they act more like keywords than like ordinary identifiers; unlike a keyword however, a redefinition may `shadow`:idx: the definition in -the ``system`` module. +the ``system`` module. From this list the following should be written in dot +notation ``x.f`` since ``x`` cannot be type checked before it gets passed +to ``f``:: + + declared, defined, definedInScope, compiles, getAst, astToStr Var parameters @@ -323,27 +327,27 @@ dispatch. .. code-block:: nim type - TExpr = object ## abstract base class for an expression - TLiteral = object of TExpr + Expression = object ## abstract base class for an expression + Literal = object of Expression x: int - TPlusExpr = object of TExpr - a, b: ref TExpr + PlusExpr = object of Expression + a, b: ref Expression - method eval(e: ref TExpr): int = + method eval(e: ref Expression): int = # override this base method quit "to override!" - method eval(e: ref TLiteral): int = return e.x + method eval(e: ref Literal): int = return e.x - method eval(e: ref TPlusExpr): int = + method eval(e: ref PlusExpr): int = # watch out: relies on dynamic binding result = eval(e.a) + eval(e.b) - proc newLit(x: int): ref TLiteral = + proc newLit(x: int): ref Literal = new(result) result.x = x - proc newPlus(a, b: ref TExpr): ref TPlusExpr = + proc newPlus(a, b: ref Expression): ref PlusExpr = new(result) result.a = a result.b = b @@ -359,27 +363,27 @@ dispatching: .. code-block:: nim type - TThing = object - TUnit = object of TThing + Thing = object + Unit = object of Thing x: int - method collide(a, b: TThing) {.inline.} = + method collide(a, b: Thing) {.inline.} = quit "to override!" - method collide(a: TThing, b: TUnit) {.inline.} = + method collide(a: Thing, b: Unit) {.inline.} = echo "1" - method collide(a: TUnit, b: TThing) {.inline.} = + method collide(a: Unit, b: Thing) {.inline.} = echo "2" var - a, b: TUnit + a, b: Unit collide(a, b) # output: 2 Invocation of a multi-method cannot be ambiguous: collide 2 is preferred over collide 1 because the resolution works from left to right. -In the example ``TUnit, TThing`` is preferred over ``TThing, TUnit``. +In the example ``Unit, Thing`` is preferred over ``Thing, Unit``. **Performance note**: Nim does not produce a virtual method table, but generates dispatch trees. This avoids the expensive indirect branch for method @@ -496,7 +500,7 @@ a `collaborative tasking`:idx: system: .. code-block:: nim # simple tasking: type - TTask = iterator (ticker: int) + Task = iterator (ticker: int) iterator a1(ticker: int) {.closure.} = echo "a1: A" @@ -514,7 +518,7 @@ a `collaborative tasking`:idx: system: yield echo "a2: C" - proc runTasks(t: varargs[TTask]) = + proc runTasks(t: varargs[Task]) = var ticker = 0 while true: let x = t[ticker mod t.len] @@ -545,10 +549,11 @@ parameters of an outer factory proc: for f in foo(): echo f -Implicit return type --------------------- +.. + Implicit return type + -------------------- -Since inline interators must always produce values that will be consumed in -a for loop, the compiler will implicity use the ``auto`` return type if no -type is given by the user. In contrast, since closure iterators can be used -as a collaborative tasking system, ``void`` is a valid return type for them. + Since inline interators must always produce values that will be consumed in + a for loop, the compiler will implicity use the ``auto`` return type if no + type is given by the user. In contrast, since closure iterators can be used + as a collaborative tasking system, ``void`` is a valid return type for them. From 78346c25878bd1555697ee0a4ccdb9c9d5f8238f Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 01:39:53 +0100 Subject: [PATCH 247/409] astToStr is a special magic --- compiler/ast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index db6003b87..4f0b47b85 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -610,7 +610,7 @@ const # thus cannot be overloaded (also documented in the spec!): SpecialSemMagics* = { mDefined, mDefinedInScope, mCompiles, mLow, mHigh, mSizeOf, mIs, mOf, - mEcho, mShallowCopy, mExpandToAst, mParallel, mSpawn} + mEcho, mShallowCopy, mExpandToAst, mParallel, mSpawn, mAstToStr} type PNode* = ref TNode From a848c2d02b16bf55ff4e435ea40a465d42dda871 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 01:49:26 +0100 Subject: [PATCH 248/409] fixes #1634 --- doc/manual/modules.txt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/manual/modules.txt b/doc/manual/modules.txt index f412587db..95a13a560 100644 --- a/doc/manual/modules.txt +++ b/doc/manual/modules.txt @@ -6,7 +6,8 @@ Modules enable `information hiding`:idx: and `separate compilation`:idx:. A module may gain access to symbols of another module by the `import`:idx: statement. `Recursive module dependencies`:idx: are allowed, but slightly subtle. Only top-level symbols that are marked with an asterisk (``*``) are -exported. +exported. A valid module name can only be a valid Nim identifier (and thus its +filename is ``identifier.nim``). The algorithm for compiling modules is: @@ -53,6 +54,17 @@ module name followed by an ``except`` to prevent some symbols to be imported: echo "$1" % "abc" +Include statement +~~~~~~~~~~~~~~~~~ +The ``include`` statement does something fundamentally different than +importing a module: it merely includes the contents of a file. The ``include`` +statement is useful to split up a large module into several files: + +.. code-block:: nim + include fileA, fileB, fileC + + + Module names in imports ~~~~~~~~~~~~~~~~~~~~~~~ From 03b152ac66e2e40d840f0ab64cc1edba6593b2c9 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 02:03:51 +0100 Subject: [PATCH 249/409] fixes #1633 --- doc/manual/stmts.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt index 1307ff917..8d958733d 100644 --- a/doc/manual/stmts.txt +++ b/doc/manual/stmts.txt @@ -607,6 +607,10 @@ type name replaces the procedure name. A type conversion is always safe in the sense that a failure to convert a type to another results in an exception (if it cannot be determined statically). +Ordinary procs are often preferred over type conversions in Nim: For instance, +``$`` is the ``toString`` operator by convention and ``toFloat`` and ``toInt`` +can be used to convert from floating point to integer or vice versa. + Type casts ---------- From 2b9b09e0521802a92105d0e351ccc6176cadd541 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 02:11:39 +0100 Subject: [PATCH 250/409] fixes #1470 --- doc/manual/procs.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index 8baf01dbb..5fda7bb0f 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -69,6 +69,24 @@ notation. (Thus an operator can have more than two parameters): assert `*+`(3, 4, 6) == `*`(a, `+`(b, c)) +Export marker +------------- + +If a declared symbol is marked with an `asterisk`:idx: it is exported from the +current module: + +.. code-block:: nim + + proc exportedEcho*(s: string) = echo s + proc `*`*(a: string; b: int): string = + result = newStringOfCap(a.len * b) + for i in 1..b: result.add a + + var exportedVar*: int + const exportedConst* = 78 + type ExportedType* = distinct int + + Method call syntax ------------------ From 61c1fd6944c074b4a554a365bd9ce678942dd69e Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 02:18:00 +0100 Subject: [PATCH 251/409] fixes #930 --- doc/manual/exceptions.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/manual/exceptions.txt b/doc/manual/exceptions.txt index ba2ea30a0..b3727b7cf 100644 --- a/doc/manual/exceptions.txt +++ b/doc/manual/exceptions.txt @@ -47,8 +47,8 @@ the rest of the procedure - that is not within a ``finally`` clause - is not executed (if an exception occurs). -Except and finally statements ------------------------------ +Standalone except and finally statements +---------------------------------------- ``except`` and ``finally`` can also be used as a stand-alone statements. Any statements following them in the current block will be considered to be @@ -76,6 +76,9 @@ statements. Example: echo "4. Post exception" # --> 1, 2, 3 is printed, 4 is never reached +Top level standalone ``finally`` or ``except`` statements are not supported +since it's unclear what such a statement should refer to. + Raise statement --------------- From 65ca05730dd91f8a9c2408379415bca19f0c74ba Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 02:20:26 +0100 Subject: [PATCH 252/409] onRaise doesn't work as documented as is dubious --- doc/manual/exceptions.txt | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/doc/manual/exceptions.txt b/doc/manual/exceptions.txt index b3727b7cf..7cad1c2b4 100644 --- a/doc/manual/exceptions.txt +++ b/doc/manual/exceptions.txt @@ -99,34 +99,6 @@ re-raise. It follows that the ``raise`` statement *always* raises an exception (unless a raise hook has been provided). -onRaise builtin ---------------- - -`system.onRaise() `_ can be used to override the -behaviour of ``raise`` for a single ``try`` statement. ``onRaise`` has to be -called within the ``try`` statement that should be affected. - -This allows for a Lisp-like `condition system`:idx:\: - -.. code-block:: nim - var myFile = open("broken.txt", fmWrite) - try: - onRaise do (e: ref Exception)-> bool: - if e of IOError: - stdout.writeln "ok, writing to stdout instead" - else: - # do raise other exceptions: - result = true - myFile.writeln "writing to broken file" - finally: - myFile.close() - -``onRaise`` can only *filter* raised exceptions, it cannot transform one -exception into another. (Nor should ``onRaise`` raise an exception though -this is currently not enforced.) This restriction keeps the exception tracking -analysis sound. - - Exception hierarchy ------------------- From a7538a9727e8ab9cf23aff4b1a848e40e690131f Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 02:25:16 +0100 Subject: [PATCH 253/409] fixes #1324 --- doc/manual/procs.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index 5fda7bb0f..e03845d76 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -297,6 +297,11 @@ One can use `tuple unpacking`:idx: to access the tuple's fields: assert y == 3 +**Note**: ``var`` parameters are never necessary for efficient parameter +passing. Since non-var parameters cannot be modified the compiler is always +free to pass arguments by reference if it considers it can speed up execution. + + Var return type --------------- From 981b24f9167885fd878a53a2b057783d7964bbf5 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 02:25:46 +0100 Subject: [PATCH 254/409] removed outdated note --- doc/tut1.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/tut1.txt b/doc/tut1.txt index 950f758f1..1a6530e6c 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -1644,9 +1644,6 @@ statement is useful to split up a large module into several files: .. code-block:: nim include fileA, fileB, fileC -**Note**: The documentation generator currently does not follow ``include`` -statements, so exported symbols in an include file will not show up in the -generated documentation. Part 2 From 9e00d3aec2da69c23cdb5dba0e3f654e99ded379 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 14 Nov 2014 02:40:55 +0100 Subject: [PATCH 255/409] fixes #693 --- doc/sets_fragment.txt | 1 - lib/system.nim | 3 --- web/news.txt | 4 +++- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/doc/sets_fragment.txt b/doc/sets_fragment.txt index 32dbac1c2..59d434807 100644 --- a/doc/sets_fragment.txt +++ b/doc/sets_fragment.txt @@ -29,7 +29,6 @@ operation meaning ``e in A`` set membership (A contains element e) ``e notin A`` A does not contain element e ``contains(A, e)`` A contains element e -``A -+- B`` symmetric set difference (= (A - B) + (B - A)) ``card(A)`` the cardinality of A (number of elements in A) ``incl(A, elem)`` same as ``A = A + {elem}`` ``excl(A, elem)`` same as ``A = A - {elem}`` diff --git a/lib/system.nim b/lib/system.nim index 7b78d1cf1..59a10f7e8 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -842,9 +842,6 @@ proc `+` *[T](x, y: set[T]): set[T] {.magic: "PlusSet", noSideEffect.} ## This operator computes the union of two sets. proc `-` *[T](x, y: set[T]): set[T] {.magic: "MinusSet", noSideEffect.} ## This operator computes the difference of two sets. -proc `-+-` *[T](x, y: set[T]): set[T] {.magic: "SymDiffSet", noSideEffect.} - ## computes the symmetric set difference. This is the same as - ## ``(A - B) + (B - A)``, but more efficient. proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} ## One should overload this proc if one wants to overload the ``in`` operator. diff --git a/web/news.txt b/web/news.txt index 2a9c24231..7f2e3c1a8 100644 --- a/web/news.txt +++ b/web/news.txt @@ -3,7 +3,7 @@ News ==== .. - 2014-10-21 Version 0.10.0 released + 2014-10-21 Version 0.10.2 released ================================== Changes affecting backwards compatibility @@ -26,6 +26,8 @@ News fails to match. - The re module returns ``nil`` instead of ``""`` when an optional capture fails to match. + - The "symmetric set difference" operator (``-+-``) never worked and has been + removed. Language Additions ------------------ From f7dca91344392a200392bdbd5d2d7c5167298e93 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 15 Nov 2014 11:10:13 +0100 Subject: [PATCH 256/409] fixes #619 --- doc/manual/procs.txt | 6 +++++- doc/manual/templates.txt | 19 +++++++++++++++++-- lib/pure/collections/sequtils.nim | 4 ++++ lib/pure/fenv.nim | 2 +- lib/system.nim | 5 ++--- todo.txt | 1 - web/download.txt | 2 +- web/news.txt | 2 +- 8 files changed, 31 insertions(+), 10 deletions(-) diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index e03845d76..9ddae6230 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -84,7 +84,9 @@ current module: var exportedVar*: int const exportedConst* = 78 - type ExportedType* = distinct int + type + ExportedType* = object + exportedField*: int Method call syntax @@ -107,6 +109,8 @@ to supply any type of first argument for procedures: Another way to look at the method call syntax is that it provides the missing postfix notation. +See also: `Limitations of the method call syntax`_. + Properties ---------- diff --git a/doc/manual/templates.txt b/doc/manual/templates.txt index 4793d68a7..d90c2203e 100644 --- a/doc/manual/templates.txt +++ b/doc/manual/templates.txt @@ -225,8 +225,8 @@ a template. ``inject`` and ``gensym`` have no effect in ``dirty`` templates. -Limitations of the method invokation syntax -------------------------------------------- +Limitations of the method call syntax +------------------------------------- The expression ``x`` in ``x.f`` needs to be semantically checked (that means symbol lookup and type checking) before it can be decided that it needs to be @@ -241,6 +241,21 @@ is used to invoke templates/macros: unknownIdentifier.declareVar +Another common example is this: + +.. code-block:: nim + from sequtils import toSeq + + iterator something: string = + yield "Hello" + yield "World" + + var info = something().toSeq() + +The problem here is that the compiler already decided that ``something()`` as +an iterator is not callable in this context before ``toSeq`` gets its +chance to convert it into a sequence. + Macros ====== diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index b824210a5..befc9bacb 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -302,6 +302,10 @@ template toSeq*(iter: expr): expr {.immediate.} = ## result = true) ## assert odd_numbers == @[1, 3, 5, 7, 9] ## + ## **Note**: Since this is an immediate macro, you cannot always invoke this + ## as ``x.toSeq``, depending on the ``x``. + ## See `this `_ + ## for an explanation. var result {.gensym.}: seq[type(iter)] = @[] for x in iter: add(result, x) result diff --git a/lib/pure/fenv.nim b/lib/pure/fenv.nim index 1859f7be7..415ef455e 100644 --- a/lib/pure/fenv.nim +++ b/lib/pure/fenv.nim @@ -8,7 +8,7 @@ # ## Floating-point environment. Handling of floating-point rounding and -## exceptions (overflow, zero-devide, etc.). +## exceptions (overflow, division by zero, etc.). {.deadCodeElim:on.} diff --git a/lib/system.nim b/lib/system.nim index 59a10f7e8..f268889d6 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -904,9 +904,8 @@ proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.} ## Checks if `x` has a type of `y` ## ## .. code-block:: Nim - ## assert(EFloatingPoint of EBase) - ## assert(EIO of ESystem) - ## assert(EDivByZero of EBase) + ## assert(FloatingPointError of Exception) + ## assert(DivByZeroError of Exception) proc cmp*[T](x, y: T): int {.procvar.} = ## Generic compare proc. Returns a value < 0 iff x < y, a value > 0 iff x > y diff --git a/todo.txt b/todo.txt index e0d6313b3..a6ea31560 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ version 0.10 ============ -showstopper: Nim does not boot with --threads:on! - make nimble part of the distribution - implement 'procCall' - split idetools into separate tool diff --git a/web/download.txt b/web/download.txt index 2d3abe3db..59ecdc3f5 100644 --- a/web/download.txt +++ b/web/download.txt @@ -40,7 +40,7 @@ Change the branch to suit your needs:: git clone -b master git://github.com/Araq/Nimrod.git cd Nimrod - git clone --depth 1 git://github.com/nimrod-code/csources + git clone -b master --depth 1 git://github.com/nimrod-code/csources cd csources && sh build.sh cd .. bin/nimrod c koch diff --git a/web/news.txt b/web/news.txt index 7f2e3c1a8..0c3cedf35 100644 --- a/web/news.txt +++ b/web/news.txt @@ -67,7 +67,7 @@ News ----------------- - Added module ``fenv`` to control the handling of floating-point rounding and - exceptions (overflow, zero-devide, etc.). + exceptions (overflow, division by zero, etc.). 2014-10-19 Nimrod version 0.9.6 released From 90b606b3da125af0b4645e20b2efb1f10e1c59c8 Mon Sep 17 00:00:00 2001 From: Simon Krauter Date: Sat, 15 Nov 2014 18:05:49 +0100 Subject: [PATCH 257/409] Fix issue #1660 https://github.com/Araq/Nimrod/issues/1660 --- compiler/jsgen.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 4772aecb5..37eaa9fb7 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1669,7 +1669,8 @@ proc genHeader(): PRope = "/* (c) 2014 Andreas Rumpf */$n$n" & "$nvar Globals = this;$n" & "var framePtr = null;$n" & - "var excHandler = null;$n", + "var excHandler = null;$n" & + "var lastJSError = null;$n", [toRope(VersionAsString)]) proc genModule(p: PProc, n: PNode) = From 03d76c6d5e00d6a4f2b99ab51df7a8c4109dc1db Mon Sep 17 00:00:00 2001 From: Elie Zedeck Date: Sun, 16 Nov 2014 12:52:24 +0300 Subject: [PATCH 258/409] Added generic OpenWrt compilers for --cpu:mips --- config/nim.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/nim.cfg b/config/nim.cfg index 62fe3307e..ef416323a 100644 --- a/config/nim.cfg +++ b/config/nim.cfg @@ -13,6 +13,9 @@ cc = gcc arm.linux.gcc.exe = "arm-linux-gcc" arm.linux.gcc.linkerexe = "arm-linux-gcc" +mips.linux.gcc.exe = "mips-openwrt-linux-gcc" +mips.linux.gcc.linkerexe = "mips-openwrt-linux-gcc" + @if not nimfix: cs:partial @end From 04069bbe9d9cef3e0f5a8cc6eb80c5a900ec0b86 Mon Sep 17 00:00:00 2001 From: Elie Zedeck Date: Sun, 16 Nov 2014 12:53:43 +0300 Subject: [PATCH 259/409] Uses execve() in osproc on OpenWrt and uClibc-based platforms. --- lib/pure/osproc.nim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 2983712c8..bfdb0efed 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -822,7 +822,11 @@ elif not defined(useNimRtl): environ = data.sysEnv discard execvp(data.sysCommand, data.sysArgs) else: - discard execvpe(data.sysCommand, data.sysArgs, data.sysEnv) + when defined(uClibc): + # uClibc environment (OpenWrt included) doesn't have the full execvpe + discard execve(data.sysCommand, data.sysArgs, data.sysEnv) + else: + discard execvpe(data.sysCommand, data.sysArgs, data.sysEnv) else: discard execve(data.sysCommand, data.sysArgs, data.sysEnv) From 8349cee613e971525b7c21aeee16eac41decd139 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 16 Nov 2014 20:32:05 +0100 Subject: [PATCH 260/409] fixes #1055 --- compiler/ast.nim | 2 +- compiler/seminst.nim | 9 ++++--- doc/intern.txt | 40 ++++++++++++++++++++++++++------ lib/packages/docutils/rstgen.nim | 8 +++---- tests/compiles/tevilcompiles.nim | 12 ++++++++++ 5 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 tests/compiles/tevilcompiles.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index 4f0b47b85..ec309ba1a 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1055,7 +1055,7 @@ proc discardSons(father: PNode) = father.sons = nil when defined(useNodeIds): - const nodeIdToDebug* = 310841 # 612794 + const nodeIdToDebug* = -1 # 884953 # 612794 #612840 # 612905 # 614635 # 614637 # 614641 # 423408 #429107 # 430443 # 441048 # 441090 # 441153 diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 8ac3849b4..2decb5d0b 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -157,8 +157,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable, # # The solution would be to move this logic into semtypinst, but # at this point semtypinst have to become part of sem, because it - # will need to use openScope, addDecl, etc - # + # will need to use openScope, addDecl, etc. addDecl(c, prc) pushInfoContext(info) @@ -223,7 +222,11 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, n.sons[genericParamsPos] = ast.emptyNode var oldPrc = genericCacheGet(fn, entry[]) if oldPrc == nil: - fn.procInstCache.safeAdd(entry) + # we MUST not add potentially wrong instantiations to the caching mechanism. + # This means recursive instantiations behave differently when in + # a ``compiles`` context but this is the lesser evil. See + # bug #1055 (tevilcompiles). + if c.inCompilesContext == 0: fn.procInstCache.safeAdd(entry) c.generics.add(makeInstPair(fn, entry)) if n.sons[pragmasPos].kind != nkEmpty: pragma(c, result, n.sons[pragmasPos], allRoutinePragmas) diff --git a/doc/intern.txt b/doc/intern.txt index 6cd1987aa..26dd49444 100644 --- a/doc/intern.txt +++ b/doc/intern.txt @@ -118,6 +118,34 @@ Thus we need to serialize this graph as RTTI for C code generation. Look at the file ``lib/system/hti.nim`` for more information. +Debugging the compiler +====================== + +You can of course use GDB or Visual Studio to debug the +compiler (via ``--debuginfo --lineDir:on``). However, there +are also lots of procs that aid in debugging: + + +.. code-block:: nim + # pretty prints the Nim AST + echo renderTree(someNode) + # outputs some JSON representation + debug(someNode) + # pretty prints some type + echo typeToString(someType) + debug(someType) + echo symbol.name.s + debug(symbol) + # pretty prints the nimrod ast, but annotates symbol IDs: + echo renderTree(someNode, {renderIds}) + if n.info ?? "temp.nim": + # only output when it comes from "temp.nim" + echo renderTree(n) + if n.info ?? "temp.nim": + # why does it process temp.nim here? + writeStackTrace() + + The compiler's architecture =========================== @@ -255,16 +283,14 @@ turned on". Debugging Nim's memory management -==================================== +================================= The following paragraphs are mostly a reminder for myself. Things to keep in mind: -* Segmentation faults can have multiple reasons: One that is frequently - forgotten is that *stack overflow* can trigger one! * If an assertion in Nim's memory manager or GC fails, the stack trace keeps allocating memory! Thus a stack overflow may happen, hiding the - real issue. + real issue. * What seem to be C code generation problems is often a bug resulting from not producing prototypes, so that some types default to ``cint``. Testing without the ``-w`` option helps! @@ -304,8 +330,8 @@ modifying a ``TCellSet`` during traversation leads to undefined behaviour. type TCellSet # hidden - proc CellSetInit(s: var TCellSet) # initialize a new set - proc CellSetDeinit(s: var TCellSet) # empty the set and free its memory + proc cellSetInit(s: var TCellSet) # initialize a new set + proc cellSetDeinit(s: var TCellSet) # empty the set and free its memory proc incl(s: var TCellSet, elem: PCell) # include an element proc excl(s: var TCellSet, elem: PCell) # exclude an element @@ -493,7 +519,7 @@ Accumulator ----------- .. code-block:: nim - proc GetAccumulator(start: int): proc (): int {.closure} = + proc getAccumulator(start: int): proc (): int {.closure} = var i = start return lambda: int = inc i diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index cfbc4a708..50246f2e0 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -728,9 +728,9 @@ proc renderTocEntry(d: PDoc, e: TTocEntry, result: var string) = "\\item\\label{$1_toc} $2\\ref{$1}\n", [e.refname, e.header]) proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, - result: var string) = + result: var string) = var tmp = "" - while j <= high(d.tocPart): + while j <= high(d.tocPart): var a = abs(d.tocPart[j].n.level) if a == lvl: renderTocEntry(d, d.tocPart[j], tmp) @@ -740,11 +740,11 @@ proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, else: break if lvl > 1: - dispA(d.target, result, "
    $1
", + dispA(d.target, result, "
    $1
", "\\begin{enumerate}$1\\end{enumerate}", [tmp]) else: result.add(tmp) - + proc renderImage(d: PDoc, n: PRstNode, result: var string) = var options = "" var s = getFieldValue(n, "scale") diff --git a/tests/compiles/tevilcompiles.nim b/tests/compiles/tevilcompiles.nim new file mode 100644 index 000000000..0930507d1 --- /dev/null +++ b/tests/compiles/tevilcompiles.nim @@ -0,0 +1,12 @@ +# bug #1055 +import unittest +type TMatrix*[N,M: static[int], T] = object + data*: array[0..N*M-1, T] +proc `==`*(a: distinct TMatrix; b: distinct TMatrix): bool = + result = a.data == b.data + +test "c": + var a = TMatrix[2,2,int](data: [1,2,3,4]) + var b = TMatrix[2,2,int](data: [1,2,3,4]) + check(a == b) + From 4c7c612efeb9c0ad323068fb9b1624c849602e86 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 16 Nov 2014 20:39:47 +0100 Subject: [PATCH 261/409] document uClibc switch --- doc/nimc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/nimc.txt b/doc/nimc.txt index 3b7390d78..64ed6ce06 100644 --- a/doc/nimc.txt +++ b/doc/nimc.txt @@ -251,6 +251,7 @@ Define Effect ``nodejs`` The JS target is actually ``node.js``. ``ssl`` Enables OpenSSL support for the sockets module. ``memProfiler`` Enables memory profiling for the native GC. +``uClibc`` Use uClibc instead of libc. (Relevant for Unix-like OSes) ================== ========================================================= From fd532b6dab930db7f456700f791065f22c155f9c Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 16 Nov 2014 21:59:21 +0100 Subject: [PATCH 262/409] fixes #206 --- compiler/patterns.nim | 2 +- tests/trmacros/tnoalias2.nim | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/trmacros/tnoalias2.nim diff --git a/compiler/patterns.nim b/compiler/patterns.nim index 3d71aa4d1..9ac0988c5 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -260,7 +260,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = # couldn't bind parameter: if isNil(x): return nil result.add(x) - if requiresAA: addToArgList(args, n) + if requiresAA: addToArgList(args, x) # perform alias analysis here: if requiresAA: for i in 1 .. < params.len: diff --git a/tests/trmacros/tnoalias2.nim b/tests/trmacros/tnoalias2.nim new file mode 100644 index 000000000..5a816acb9 --- /dev/null +++ b/tests/trmacros/tnoalias2.nim @@ -0,0 +1,19 @@ +discard """ + output: '''0''' +""" + +# bug #206 +template optimizeOut{testFunc(a, b)}(a: int, b: int{alias}) : expr = 0 + +proc testFunc(a, b: int): int = result = a + b +var testVar = 1 +echo testFunc(testVar, testVar) + + +template ex{a = b + c}(a : int{noalias}, b, c : int) = + a = b + inc a, b + echo "came here" + +var x = 5 +x = x + x From 729e048a324a6908b6a2d19a7d0186c05880151c Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 17 Nov 2014 08:28:24 +0100 Subject: [PATCH 263/409] fixes #940 --- compiler/renderer.nim | 11 +++++++++-- compiler/semgnrc.nim | 2 +- compiler/semtempl.nim | 3 ++- compiler/sigmatch.nim | 2 +- doc/manual/locking.txt | 1 + tests/template/twrongopensymchoice.nim | 24 ++++++++++++++++++++++++ 6 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 tests/template/twrongopensymchoice.nim diff --git a/compiler/renderer.nim b/compiler/renderer.nim index a4469acda..b0d328f9e 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -894,8 +894,15 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkParLe, "(") for i in countup(0, sonsLen(n) - 1): if i > 0: put(g, tkOpr, "|") - gsub(g, n.sons[i], c) - put(g, tkParRi, ")") + if n.sons[i].kind == nkSym: + let s = n[i].sym + if s.owner != nil: + put g, tkSymbol, n[i].sym.owner.name.s + put g, tkOpr, "." + put g, tkSymbol, n[i].sym.name.s + else: + gsub(g, n.sons[i], c) + put(g, tkParRi, if n.kind == nkOpenSymChoice: "|...)" else: ")") of nkPar, nkClosure: put(g, tkParLe, "(") gcomma(g, n, c) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 6c218fa0c..07e7a5136 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -166,7 +166,7 @@ proc semGenericStmt(c: PContext, n: PNode, var first = 0 var isDefinedMagic = false - if s != nil: + if s != nil: incl(s.flags, sfUsed) isDefinedMagic = s.magic in {mDefined, mDefinedInScope, mCompiles} let scOption = if s.name.id in ctx: scForceOpen else: scOpen diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 0a647a65d..38b0536db 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -63,7 +63,8 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule): PNode = else: # semantic checking requires a type; ``fitNode`` deals with it # appropriately - let kind = if r == scClosed: nkClosedSymChoice else: nkOpenSymChoice + let kind = if r == scClosed or n.kind == nkDotExpr: nkClosedSymChoice + else: nkOpenSymChoice result = newNodeIT(kind, n.info, newTypeS(tyNone, c)) a = initOverloadIter(o, c, n) while a != nil: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 4a3773ed8..e44cd7049 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -23,7 +23,7 @@ type csEmpty, csMatch, csNoMatch CandidateErrors* = seq[PSym] - TCandidate* {.final.} = object + TCandidate* = object c*: PContext exactMatches*: int # also misused to prefer iters over procs genericMatches: int # also misused to prefer constraints diff --git a/doc/manual/locking.txt b/doc/manual/locking.txt index 1a6d2783c..864eeccb5 100644 --- a/doc/manual/locking.txt +++ b/doc/manual/locking.txt @@ -13,6 +13,7 @@ pragmas: 3) Locks and routines can be annotated with `lock levels`:idx: to prevent deadlocks at compile time. + Guards and the locks section ---------------------------- diff --git a/tests/template/twrongopensymchoice.nim b/tests/template/twrongopensymchoice.nim new file mode 100644 index 000000000..5a02a813c --- /dev/null +++ b/tests/template/twrongopensymchoice.nim @@ -0,0 +1,24 @@ +discard """ + output: '''10''' +""" + +# bug #940 + +type + Foo* = ref object + b*: int + +proc new*(this: var Foo) = + assert this != nil + this.b = 10 + +proc new*(T: typedesc[Foo]): Foo = + system.new(result) + twrongopensymchoice.new(result) + +proc main = + var f = Foo.new() + echo f.b + +when isMainModule: + main() From c5cc20d33797f094a742c0a7f39a59e867a380f7 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 17 Nov 2014 08:54:31 +0100 Subject: [PATCH 264/409] fixes #1548 --- compiler/ccgexprs.nim | 7 ++++--- compiler/jsgen.nim | 12 ++++++++++-- compiler/semexprs.nim | 39 +++++---------------------------------- compiler/vmgen.nim | 12 +++++++----- doc/manual/procs.txt | 2 +- 5 files changed, 27 insertions(+), 45 deletions(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index b91c54e8b..7d704c15b 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -916,14 +916,15 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) = proc genEcho(p: BProc, n: PNode) = # this unusal way of implementing it ensures that e.g. ``echo("hallo", 45)`` # is threadsafe. + internalAssert n.kind == nkBracket discard lists.includeStr(p.module.headerFiles, "") var args: PRope = nil var a: TLoc - for i in countup(1, n.len-1): + for i in countup(0, n.len-1): initLocExpr(p, n.sons[i], a) appf(args, ", ($1)->data", [rdLoc(a)]) linefmt(p, cpsStmts, "printf($1$2);$n", - makeCString(repeatStr(n.len-1, "%s") & tnl), args) + makeCString(repeatStr(n.len, "%s") & tnl), args) proc gcUsage(n: PNode) = if gSelectedGC == gcNone: message(n.info, warnGcMem, n.renderTree) @@ -1693,7 +1694,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = discard cgsym(p.module, opr.loc.r.ropeToStr) genCall(p, e, d) of mReset: genReset(p, e) - of mEcho: genEcho(p, e) + of mEcho: genEcho(p, e[1].skipConv) of mArrToSeq: genArrToSeq(p, e, d) of mNLen..mNError: localError(e.info, errCannotGenerateCodeForX, e.sons[0].sym.name.s) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 37eaa9fb7..8fc2ec1d2 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1078,8 +1078,16 @@ proc genInfixCall(p: PProc, n: PNode, r: var TCompRes) = proc genEcho(p: PProc, n: PNode, r: var TCompRes) = useMagic(p, "rawEcho") - app(r.res, "rawEcho") - genArgs(p, n, r) + app(r.res, "rawEcho(") + let n = n[1].skipConv + internalAssert n.kind == nkBracket + for i in countup(0, sonsLen(n) - 1): + let it = n.sons[i] + if it.typ.isCompileTimeOnly: continue + if i > 0: app(r.res, ", ") + genArg(p, it, r) + app(r.res, ")") + r.kind = resExpr proc putToSeq(s: string, indirect: bool): PRope = result = toRope(s) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index bf2344f11..73c778530 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -840,45 +840,17 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = if result != nil: result = afterCallActions(c, result, nOrig, flags) else: result = errorNode(c, n) -proc buildStringify(c: PContext, arg: PNode): PNode = - if arg.typ != nil and - skipTypes(arg.typ, abstractInst-{tyTypeDesc}).kind == tyString: - result = arg - else: - result = newNodeI(nkCall, arg.info) - addSon(result, newIdentNode(getIdent"$", arg.info)) - addSon(result, arg) - -proc semEcho(c: PContext, n: PNode): PNode = - # this really is a macro - checkMinSonsLen(n, 1) - for i in countup(1, sonsLen(n) - 1): - var arg = semExprWithType(c, n.sons[i]) - arg = semExprWithType(c, buildStringify(c, arg)) - n.sons[i] = arg - let t = arg.typ - if (t == nil or t.skipTypes(abstractInst).kind != tyString) and - arg.kind != nkEmpty: - localError(n.info, errGenerated, - "implicitly invoked '$' does not return string") - let t = n.sons[0].typ - if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) - result = n - proc buildEchoStmt(c: PContext, n: PNode): PNode = - # we MUST not check 'n' for semantics again here! + # we MUST not check 'n' for semantics again here! But for now we give up: result = newNodeI(nkCall, n.info) var e = strTableGet(magicsys.systemModule.tab, getIdent"echo") if e != nil: - addSon(result, newSymNode(e)) + add(result, newSymNode(e)) else: localError(n.info, errSystemNeeds, "echo") - addSon(result, errorNode(c, n)) - var arg = buildStringify(c, n) - # problem is: implicit '$' is not checked for semantics yet. So we give up - # and check 'arg' for semantics again: - arg = semExpr(c, arg) - if arg != nil: addSon(result, arg) + add(result, errorNode(c, n)) + add(result, n) + result = semExpr(c, result) proc semExprNoType(c: PContext, n: PNode): PNode = result = semExpr(c, n, {efWantStmt}) @@ -1650,7 +1622,6 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mSizeOf: result = semSizeof(c, setMs(n, s)) of mIs: result = semIs(c, setMs(n, s)) of mOf: result = semOf(c, setMs(n, s)) - of mEcho: result = semEcho(c, setMs(n, s)) of mShallowCopy: result = semShallowCopy(c, n, flags) of mExpandToAst: result = semExpandToAst(c, n, s, flags) of mQuoteAst: result = semQuoteAst(c, n) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index da31eab3d..8b7dc293c 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -899,12 +899,14 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = c.freeTemp(tmp) of mEcho: unused(n, dest) - let x = c.getTempRange(n.len-1, slotTempUnknown) - for i in 1.. Date: Mon, 17 Nov 2014 19:53:44 +0000 Subject: [PATCH 265/409] Ensure Request.body is initialised. --- lib/pure/asynchttpserver.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index f40090c64..e0f3b6fc2 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -94,6 +94,8 @@ proc respond*(req: TRequest, code: THttpCode, proc newRequest(): TRequest = result.headers = newStringTable(modeCaseInsensitive) + result.hostname = "" + result.body = "" proc parseHeader(line: string): tuple[key, value: string] = var i = 0 From 17736a1eb45b209c9957214ebb7455ade54fdcc4 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 18 Nov 2014 01:46:52 +0100 Subject: [PATCH 266/409] fixes #1274 --- compiler/ccgexprs.nim | 2 +- tests/objects/tobjconstr2.nim | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 7d704c15b..bced6d50f 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1125,7 +1125,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = ty = getUniqueType(ty.sons[0]) if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr") if it.len == 3 and optFieldCheck in p.options: - genFieldCheck(p, it.sons[2], r, field) + genFieldCheck(p, it.sons[2], tmp2.r, field) app(tmp2.r, ".") app(tmp2.r, field.loc.r) tmp2.k = locTemp diff --git a/tests/objects/tobjconstr2.nim b/tests/objects/tobjconstr2.nim index 8ef7004e4..39683ddc5 100644 --- a/tests/objects/tobjconstr2.nim +++ b/tests/objects/tobjconstr2.nim @@ -32,3 +32,19 @@ type size: tuple[w, h: float] var d = Graphic(kind: 1, size: (12.9, 6.9)) + +# bug #1274 +type + K = enum Koo, Kar + Graphic2 = object of RootObj + case kind: K + of Koo: + radius: float + of Kar: + size: tuple[w, h: float] + +type NamedGraphic = object of Graphic2 + name: string + +var ngr = NamedGraphic(kind: Koo, radius: 6.9, name: "Foo") +echo ngr.name From 168d0fe942e364db8f377e757eb8c00c58bed2fd Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Tue, 18 Nov 2014 21:04:48 -0500 Subject: [PATCH 267/409] Add fancy build status buttons! everyone else is doing it... :P --- readme.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/readme.md b/readme.md index 8a4cd93b3..d5968982b 100644 --- a/readme.md +++ b/readme.md @@ -64,3 +64,10 @@ Read copying.txt for more details. Copyright (c) 2006-2014 Andreas Rumpf. All rights reserved. + +# Build Status +| |Linux|Windows|Mac| +|---|---|---|---| +| x86 | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-x32-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=windows-x32-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=mac-x32-builder) +| x86_64 | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-x64-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=windows-x64-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=mac-x64-builder) +| arm | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-arm5-builder) | From 32ec5af60a5d89fca314c3b432d225f1e248953f Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 19 Nov 2014 23:38:35 +0100 Subject: [PATCH 268/409] fixes #1053, fixes #924 --- compiler/ccgexprs.nim | 16 +++++---- lib/system/assign.nim | 12 ++++--- tests/objects/tinherentedvalues.nim | 55 +++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 tests/objects/tinherentedvalues.nim diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index bced6d50f..0bf2359c5 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -20,7 +20,7 @@ proc int64Literal(i: BiggestInt): PRope = proc uint64Literal(i: uint64): PRope = toRope($i & "ULL") proc intLiteral(i: BiggestInt): PRope = - if (i > low(int32)) and (i <= high(int32)): + if i > low(int32) and i <= high(int32): result = toRope(i) elif i == low(int32): # Nim has the same bug for the same reasons :-) @@ -39,7 +39,7 @@ proc int32Literal(i: int): PRope = proc genHexLiteral(v: PNode): PRope = # hex literals are unsigned in C # so we don't generate hex literals any longer. - if not (v.kind in {nkIntLit..nkUInt64Lit}): + if v.kind notin {nkIntLit..nkUInt64Lit}: internalError(v.info, "genHexLiteral") result = intLiteral(v.intVal) @@ -224,9 +224,9 @@ proc optAsgnLoc(a: TLoc, t: PType, field: PRope): TLoc = proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = let newflags = if src.k == locData: - flags + { needToCopy } + flags + {needToCopy} elif tfShallow in dest.t.flags: - flags - { needToCopy } + flags - {needToCopy} else: flags for i in 0 .. Date: Wed, 19 Nov 2014 23:40:26 +0100 Subject: [PATCH 269/409] fixes #836 --- compiler/sigmatch.nim | 3 +++ .../tcannot_pass_empty_seq_to_generic.nim | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/generics/tcannot_pass_empty_seq_to_generic.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index e44cd7049..266236bf4 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -242,6 +242,9 @@ proc concreteType(c: TCandidate, t: PType): PType = addSonSkipIntLit(result, t.sons[1]) # XXX: semantic checking for the type? of tyNil: result = nil # what should it be? + of tySequence, tySet: + if t.sons[0].kind == tyEmpty: result = nil + else: result = t of tyGenericParam, tyAnything: result = t while true: diff --git a/tests/generics/tcannot_pass_empty_seq_to_generic.nim b/tests/generics/tcannot_pass_empty_seq_to_generic.nim new file mode 100644 index 000000000..5f0363af8 --- /dev/null +++ b/tests/generics/tcannot_pass_empty_seq_to_generic.nim @@ -0,0 +1,17 @@ +discard """ + errormsg: "type mismatch: got (seq[empty])" + line: 16 +""" + +# bug #836 + +type + TOption*[T] = object + case FIsSome: bool + of false: nil + of true: FData: T + +proc some*[T](value: T): TOption[T] = TOption[T](FIsSome: true, FData: value) + +echo some(@[]).FIsSome + From 3215666e33846db87e3b3ac1b6ab51a14f7b6912 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 20 Nov 2014 00:27:35 +0100 Subject: [PATCH 270/409] fixes #1666 --- lib/system.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index f268889d6..62f11bc9a 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2125,7 +2125,7 @@ elif hostOS != "standalone": inc(i) {.pop.} -proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.} +proc echo*(x: varargs[string, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.} ## Writes and flushes the parameters to the standard output. ## ## Special built-in that takes a variable number of arguments. Each argument @@ -2140,8 +2140,8 @@ proc echo*[T](x: varargs[T, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign ## `_ you can use `debugEcho <#debugEcho>`_ ## instead. -proc debugEcho*[T](x: varargs[T, `$`]) {.magic: "Echo", noSideEffect, - tags: [], raises: [].} +proc debugEcho*(x: varargs[string, `$`]) {.magic: "Echo", noSideEffect, + tags: [], raises: [].} ## Same as `echo <#echo>`_, but as a special semantic rule, ``debugEcho`` ## pretends to be free of side effects, so that it can be used for debugging ## routines marked as `noSideEffect `_. From bb532a697edad1bac60a87a7ff43956c9635973d Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 20 Nov 2014 21:02:51 +0100 Subject: [PATCH 271/409] fixes #1562, fixes #1543 --- compiler/astalgo.nim | 14 +++++++++++--- compiler/sem.nim | 2 +- compiler/semtypinst.nim | 2 ++ lib/system.nim | 6 +++++- tests/template/twrongmapit.nim | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 tests/template/twrongmapit.nim diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 110b0c26e..e66158e8d 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -638,14 +638,22 @@ proc strTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} = # This way the newest redefinition is picked by the semantic analyses! assert n.name != nil var h: THash = n.name.h and high(t.data) + var replaceSlot = -1 while true: var it = t.data[h] if it == nil: break + # Semantic checking can happen multiple times thanks to templates + # and overloading: (var x=@[]; x).mapIt(it). + # So it is possible the very same sym is added multiple + # times to the symbol table which we allow here with the 'it == n' check. if it.name.id == n.name.id and reallySameIdent(it.name.s, n.name.s): - t.data[h] = n # overwrite it with newer definition! - return true # found it + if it == n: return false + replaceSlot = h h = nextTry(h, high(t.data)) - if mustRehash(len(t.data), t.counter): + if replaceSlot >= 0: + t.data[replaceSlot] = n # overwrite it with newer definition! + return true # found it + elif mustRehash(len(t.data), t.counter): strTableEnlarge(t) strTableRawInsert(t.data, n) else: diff --git a/compiler/sem.nim b/compiler/sem.nim index 81846e1b4..5b31129a5 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -142,8 +142,8 @@ proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym = # like newSymS, but considers gensym'ed symbols if n.kind == nkSym: + # and sfGenSym in n.sym.flags: result = n.sym - internalAssert sfGenSym in result.flags internalAssert result.kind == kind # when there is a nested proc inside a template, semtmpl # will assign a wrong owner during the first pass over the diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 9c15be635..064bbf823 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -306,6 +306,8 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = newbody.deepCopy = cl.c.instDeepCopy(cl.c, dc, result, cl.info) proc eraseVoidParams*(t: PType) = + # transform '(): void' into '()' because old parts of the compiler really + # doesn't deal with '(): void': if t.sons[0] != nil and t.sons[0].kind == tyEmpty: t.sons[0] = nil diff --git a/lib/system.nim b/lib/system.nim index 62f11bc9a..7731c34cb 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2905,7 +2905,11 @@ proc `*=`*[T: float|float32|float64] (x: var T, y: T) {.inline, noSideEffect.} = ## Multiplies in place a floating point number x = x * y -proc `/=`*[T: float|float32|float64] (x: var T, y: T) {.inline, noSideEffect.} = +proc `/=`*(x: var float64, y: float64) {.inline, noSideEffect.} = + ## Divides in place a floating point number + x = x / y + +proc `/=`*[T: float|float32](x: var T, y: T) {.inline, noSideEffect.} = ## Divides in place a floating point number x = x / y diff --git a/tests/template/twrongmapit.nim b/tests/template/twrongmapit.nim new file mode 100644 index 000000000..4b3e1553f --- /dev/null +++ b/tests/template/twrongmapit.nim @@ -0,0 +1,32 @@ +discard """ + errormsg: "'" + file: "sequtils.nim" + line: 416 +""" +# unfortunately our tester doesn't support multiple lines of compiler +# error messages yet... + +# bug #1562 +type Foo* {.pure, final.} = object + elt: float + +template defineOpAssign(T: expr, op: expr) {.immediate.} = + proc op*(v: var T, w: T) {.inline.} = + for i in 0..1: + op(v.elt, w.elt) + +const ATTEMPT = 0 + +when ATTEMPT == 0: + # FAILS: defining `/=` with template calling template + # ERROR about sem.nim line 144 + template defineOpAssigns(T: expr) {.immediate.} = + mixin `/=` + defineOpAssign(T, `/=`) + + defineOpAssigns(Foo) + +# bug #1543 +import sequtils + +(var i= @[""];i).mapIt(it) From 57689037c54056dec22bab9084a9a501d4521440 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 20 Nov 2014 21:39:08 +0100 Subject: [PATCH 272/409] fixes #916 --- compiler/semfold.nim | 2 +- compiler/vm.nim | 4 ++-- tests/misc/tints.nim | 13 +++++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 76ac23e0d..ba7f3cabd 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -502,7 +502,7 @@ proc foldConv*(n, a: PNode; check = false): PNode = of tyInt..tyInt64: case skipTypes(a.typ, abstractRange).kind of tyFloat..tyFloat64: - result = newIntNodeT(system.toInt(getFloat(a)), n) + result = newIntNodeT(int(getFloat(a)), n) of tyChar: result = newIntNodeT(getOrdValue(a), n) else: result = a diff --git a/compiler/vm.nim b/compiler/vm.nim index f75db56b8..3d2ddfc82 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -328,7 +328,7 @@ proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool = myreset(dest); dest.kind = rkInt case skipTypes(srctyp, abstractRange).kind of tyFloat..tyFloat64: - dest.intVal = system.toInt(src.floatVal) + dest.intVal = int(src.floatVal) else: dest.intVal = src.intVal if dest.intVal < firstOrd(desttyp) or dest.intVal > lastOrd(desttyp): @@ -338,7 +338,7 @@ proc opConv*(dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): bool = myreset(dest); dest.kind = rkInt case skipTypes(srctyp, abstractRange).kind of tyFloat..tyFloat64: - dest.intVal = system.toInt(src.floatVal) + dest.intVal = int(src.floatVal) else: dest.intVal = src.intVal and ((1 shl (desttyp.size*8))-1) of tyFloat..tyFloat64: diff --git a/tests/misc/tints.nim b/tests/misc/tints.nim index 3e413026a..ded24fb5c 100644 --- a/tests/misc/tints.nim +++ b/tests/misc/tints.nim @@ -1,6 +1,8 @@ discard """ - file: "tints.nim" - output: "Success" + output: ''' +0 0 +0 0 +Success''' """ # Test the different integer operations @@ -41,5 +43,12 @@ test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8) test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64) test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32) +# bug #916 +proc unc(a: float): float = + return a + +echo int(unc(0.5)), " ", int(unc(-0.5)) +echo int(0.5), " ", int(-0.5) + echo("Success") #OUT Success From 5ab3542c1801ba042fbe964245be004c0683abb2 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 20 Nov 2014 22:06:35 +0100 Subject: [PATCH 273/409] fixes #939 --- compiler/semfold.nim | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index ba7f3cabd..1e92fb832 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -319,8 +319,14 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = of tyInt64, tyInt, tyUInt..tyUInt64: result = newIntNodeT(`shr`(getInt(a), getInt(b)), n) else: internalError(n.info, "constant folding for shr") - of mDivI, mDivI64: result = newIntNodeT(getInt(a) div getInt(b), n) - of mModI, mModI64: result = newIntNodeT(getInt(a) mod getInt(b), n) + of mDivI, mDivI64: + let y = getInt(b) + if y != 0: + result = newIntNodeT(getInt(a) div y, n) + of mModI, mModI64: + let y = getInt(b) + if y != 0: + result = newIntNodeT(getInt(a) mod y, n) of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n) of mSubF64: result = newFloatNodeT(getFloat(a) - getFloat(b), n) of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n) @@ -359,8 +365,14 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = of mAddU: result = newIntNodeT(`+%`(getInt(a), getInt(b)), n) of mSubU: result = newIntNodeT(`-%`(getInt(a), getInt(b)), n) of mMulU: result = newIntNodeT(`*%`(getInt(a), getInt(b)), n) - of mModU: result = newIntNodeT(`%%`(getInt(a), getInt(b)), n) - of mDivU: result = newIntNodeT(`/%`(getInt(a), getInt(b)), n) + of mModU: + let y = getInt(b) + if y != 0: + result = newIntNodeT(`%%`(getInt(a), y), n) + of mDivU: + let y = getInt(b) + if y != 0: + result = newIntNodeT(`/%`(getInt(a), y), n) of mLeSet: result = newIntNodeT(ord(containsSets(a, b)), n) of mEqSet: result = newIntNodeT(ord(equalSets(a, b)), n) of mLtSet: From 326bdae8ca14a981f5ab8c553fbba45e28a36082 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 21 Nov 2014 02:26:49 +0100 Subject: [PATCH 274/409] fixes #837 --- compiler/ccgexprs.nim | 32 ++++++++++++++++++++++-------- compiler/cgen.nim | 2 +- tests/ccgbugs/tcgbug.nim | 1 + tests/ccgbugs/tmissingbracket.nim | 2 +- tests/objects/tobject3.nim | 33 ++++++++++++++++++++++++++++++- tests/objects/toop1.nim | 7 ++----- 6 files changed, 61 insertions(+), 16 deletions(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 0bf2359c5..e05828f8f 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1872,18 +1872,34 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) = expr(p, n.sons[0], d) # downcast does C++ for us else: var dest = skipTypes(n.typ, abstractPtrs) - var src = skipTypes(n.sons[0].typ, abstractPtrs) + + var arg = n.sons[0] + while arg.kind == nkObjDownConv: arg = arg.sons[0] + + var src = skipTypes(arg.typ, abstractPtrs) var a: TLoc - initLocExpr(p, n.sons[0], a) + initLocExpr(p, arg, a) var r = rdLoc(a) - if skipTypes(n.sons[0].typ, abstractInst).kind in {tyRef, tyPtr, tyVar} and - n.sons[0].kind notin {nkHiddenAddr, nkAddr, nkObjDownConv}: + let isRef = skipTypes(arg.typ, abstractInst).kind in {tyRef, tyPtr, tyVar} + if isRef: app(r, "->Sup") - for i in countup(2, abs(inheritanceDiff(dest, src))): app(r, ".Sup") - r = con("&", r) else: - for i in countup(1, abs(inheritanceDiff(dest, src))): app(r, ".Sup") - putIntoDest(p, d, n.typ, r) + app(r, ".Sup") + for i in countup(2, abs(inheritanceDiff(dest, src))): app(r, ".Sup") + if isRef: + # it can happen that we end up generating '&&x->Sup' here, so we pack + # the '&x->Sup' into a temporary and then those address is taken + # (see bug #837). However sometimes using a temporary is not correct: + # init(TFigure(my)) # where it is passed to a 'var TFigure'. We test + # this by ensuring the destination is also a pointer: + if d.k == locNone and skipTypes(n.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}: + getTemp(p, n.typ, d) + linefmt(p, cpsStmts, "$1 = &$2;$n", rdLoc(d), r) + else: + r = con("&", r) + putIntoDest(p, d, n.typ, r) + else: + putIntoDest(p, d, n.typ, r) proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) = var t = getUniqueType(n.typ) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 112203ef1..b00c0b0a7 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -310,7 +310,7 @@ proc rdLoc(a: TLoc): PRope = proc addrLoc(a: TLoc): PRope = result = a.r if lfIndirect notin a.flags and mapType(a.t) != ctArray: - result = con("&", result) + result = con("(&", result).con(")") proc rdCharLoc(a: TLoc): PRope = # read a location that may need a char-cast: diff --git a/tests/ccgbugs/tcgbug.nim b/tests/ccgbugs/tcgbug.nim index 3e4755f2f..92e7b3a66 100644 --- a/tests/ccgbugs/tcgbug.nim +++ b/tests/ccgbugs/tcgbug.nim @@ -35,3 +35,4 @@ type cb: proc (future: PFuture[T]) {.closure.} var k = PFuture[void]() + diff --git a/tests/ccgbugs/tmissingbracket.nim b/tests/ccgbugs/tmissingbracket.nim index ba681ebda..886884d0c 100644 --- a/tests/ccgbugs/tmissingbracket.nim +++ b/tests/ccgbugs/tmissingbracket.nim @@ -34,7 +34,7 @@ proc newInstance(T: typedesc): T = var o = TObj.newInstance() type - TestObj* = object of TObject + TestObj* = object of RootObj t:int SubObject* = object of TestObj diff --git a/tests/objects/tobject3.nim b/tests/objects/tobject3.nim index 935e6ca8c..85cf1cfe3 100644 --- a/tests/objects/tobject3.nim +++ b/tests/objects/tobject3.nim @@ -1,5 +1,9 @@ + +# It turned out that it's hard to generate correct for these two test cases at +# the same time. + type - TFoo = ref object of TObject + TFoo = ref object of RootObj Data: int TBar = ref object of TFoo nil @@ -26,3 +30,30 @@ var b: TBar2 new(b) Foo(b) + +# bug #837 +type + PView* = ref TView + TView* {.inheritable.} = object + data: int + + PWindow* = ref TWindow + TWindow* = object of TView + data3: int + + PDesktop* = ref TDesktop + TDesktop* = object of TView + data2: int + +proc makeDesktop(): PDesktop = new(TDesktop) + +proc makeWindow(): PWindow = new(TWindow) + +proc thisCausesError(a: var PView, b: PView) = + discard + +var dd = makeDesktop() +var aa = makeWindow() + +thisCausesError(dd, aa) + diff --git a/tests/objects/toop1.nim b/tests/objects/toop1.nim index 350799f51..0d8ba124b 100644 --- a/tests/objects/toop1.nim +++ b/tests/objects/toop1.nim @@ -6,7 +6,7 @@ discard """ import macros type - TFigure = object of TObject # abstract base class: + TFigure = object of RootObj # abstract base class: draw: proc (my: var TFigure) {.nimcall.} # concrete classes implement this proc init(f: var TFigure) = @@ -56,7 +56,7 @@ macro `!` (n: expr): stmt {.immediate.} = result.add(n[1]) # obj type - TSocket* = object of TObject + TSocket* = object of RootObj FHost: int # cannot be accessed from the outside of the module # the `F` prefix is a convention to avoid clashes since # the accessors are named `host` @@ -84,6 +84,3 @@ r!draw c!draw() #OUT 34[]o 5 - - - From 2a1acbd1a6042454f99455c721a3fc4c574eb1f8 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 22 Nov 2014 23:09:08 +0100 Subject: [PATCH 275/409] fixes #1669 --- compiler/semtypes.nim | 5 +++-- tests/array/tarray.nim | 9 ++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index b3ff6c82a..d71ad6fe6 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -170,9 +170,10 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = range[1] = semExprWithType(c, n[2], {efDetermineType}) var rangeT: array[2, PType] - for i in 0..1: rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit + for i in 0..1: + rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit - if not sameType(rangeT[0], rangeT[1]): + if not sameType(rangeT[0].skipTypes({tyRange}), rangeT[1].skipTypes({tyRange})): localError(n.info, errPureTypeMismatch) elif not rangeT[0].isOrdinalType: localError(n.info, errOrdinalTypeExpected) diff --git a/tests/array/tarray.nim b/tests/array/tarray.nim index 16ef558d1..01fbdf422 100644 --- a/tests/array/tarray.nim +++ b/tests/array/tarray.nim @@ -1,6 +1,6 @@ discard """ file: "tarray.nim" - output: "10012" + output: "100124" """ # simple check for one dimensional arrays @@ -30,4 +30,11 @@ write(stdout, sum([])) write(stdout, getPos( (x: 5, y: 7) )) #OUT 10012 +# bug #1669 +let filesToCreate = ["tempdir/fl1.a", "tempdir/fl2.b", + "tempdir/tempdir2/fl3.e", "tempdir/tempdir2/tempdir3/fl4.f"] + +var found: array[0..filesToCreate.high, bool] + +echo found.len From 83c655266dd1f9ba3ddbdf9389edbce4d30740a3 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 22 Nov 2014 23:09:50 +0100 Subject: [PATCH 276/409] more robust against unknown line info --- compiler/cgen.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index b00c0b0a7..51c426d79 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -284,7 +284,7 @@ proc genLineDir(p: BProc, t: PNode) = line.toRope, makeCString(toFilename(t.info))) elif ({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and - (p.prc == nil or sfPure notin p.prc.flags): + (p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex >= 0: linefmt(p, cpsStmts, "nimln($1, $2);$n", line.toRope, t.info.quotedFilename) From e1630dcc73f13023205d45cab7bcabc415766b66 Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 23 Nov 2014 01:45:53 +0100 Subject: [PATCH 277/409] fixes #1337 --- compiler/semgnrc.nim | 35 +++++++++------ tests/concurrency/tnodeadlocks.nim | 70 ------------------------------ tests/template/tit.nim | 11 +++++ 3 files changed, 33 insertions(+), 83 deletions(-) delete mode 100644 tests/concurrency/tnodeadlocks.nim create mode 100644 tests/template/tit.nim diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 07e7a5136..0fa16497c 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -13,7 +13,7 @@ # A problem is that it cannot be detected if the symbol is introduced # as in ``var x = ...`` or used because macros/templates can hide this! # So we have to eval templates/macros right here so that symbol -# lookup can be accurate. XXX But this can only be done for immediate macros! +# lookup can be accurate. # included from sem.nim @@ -99,7 +99,7 @@ proc newDot(n, b: PNode): PNode = result.add(b) proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, - ctx: var IntSet): PNode = + ctx: var IntSet; isMacro: var bool): PNode = assert n.kind == nkDotExpr let luf = if withinMixin notin flags: {checkUndeclared} else: {} @@ -113,6 +113,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags, let ident = considerQuotedIdent(n) var s = searchInScopes(c, ident).skipAlias(n) if s != nil and s.kind in routineKinds: + isMacro = s.kind in {skTemplate, skMacro} if withinBind in flags: result = newDot(result, symChoice(c, n, s, scClosed)) elif s.name.id in ctx: @@ -141,7 +142,8 @@ proc semGenericStmt(c: PContext, n: PNode, #var s = qualifiedLookUp(c, n, luf) #if s != nil: result = semGenericStmtSymbol(c, n, s) # XXX for example: ``result.add`` -- ``add`` needs to be looked up here... - result = fuzzyLookup(c, n, flags, ctx) + var dummy: bool + result = fuzzyLookup(c, n, flags, ctx, dummy) of nkEmpty, nkSym..nkNilLit: # see tests/compile/tgensymgeneric.nim: # We need to open the gensym'ed symbol again so that the instantiation @@ -165,10 +167,10 @@ proc semGenericStmt(c: PContext, n: PNode, localError(n.info, errUndeclaredIdentifier, fn.renderTree) var first = 0 - var isDefinedMagic = false + var mixinContext = false if s != nil: incl(s.flags, sfUsed) - isDefinedMagic = s.magic in {mDefined, mDefinedInScope, mCompiles} + mixinContext = s.magic in {mDefined, mDefinedInScope, mCompiles} let scOption = if s.name.id in ctx: scForceOpen else: scOpen case s.kind of skMacro: @@ -177,8 +179,9 @@ proc semGenericStmt(c: PContext, n: PNode, result = semMacroExpr(c, n, n, s, {efNoSemCheck}) result = semGenericStmt(c, result, {}, ctx) else: - n.sons[0] = symChoice(c, n.sons[0], s, scOption) + n.sons[0] = symChoice(c, fn, s, scOption) result = n + mixinContext = true of skTemplate: if macroToExpand(s): styleCheckUse(fn.info, s) @@ -186,34 +189,40 @@ proc semGenericStmt(c: PContext, n: PNode, result = semTemplateExpr(c, n, s, {efNoSemCheck}) result = semGenericStmt(c, result, {}, ctx) else: - n.sons[0] = symChoice(c, n.sons[0], s, scOption) + n.sons[0] = symChoice(c, fn, s, scOption) result = n # BUGFIX: we must not return here, we need to do first phase of - # symbol lookup ... + # symbol lookup. Also since templates and macros can do scope injections + # we need to put the ``c`` in ``t(c)`` in a mixin context to prevent + # the famous "undeclared identifier: it" bug: + mixinContext = true of skUnknown, skParam: # Leave it as an identifier. discard of skProc, skMethod, skIterators, skConverter: - result.sons[0] = symChoice(c, n.sons[0], s, scOption) + result.sons[0] = symChoice(c, fn, s, scOption) first = 1 of skGenericParam: - result.sons[0] = newSymNodeTypeDesc(s, n.sons[0].info) + result.sons[0] = newSymNodeTypeDesc(s, fn.info) styleCheckUse(fn.info, s) first = 1 of skType: # bad hack for generics: if (s.typ != nil) and (s.typ.kind != tyGenericParam): - result.sons[0] = newSymNodeTypeDesc(s, n.sons[0].info) + result.sons[0] = newSymNodeTypeDesc(s, fn.info) styleCheckUse(fn.info, s) first = 1 else: - result.sons[0] = newSymNode(s, n.sons[0].info) + result.sons[0] = newSymNode(s, fn.info) styleCheckUse(fn.info, s) first = 1 + elif fn.kind == nkDotExpr: + result.sons[0] = fuzzyLookup(c, fn, flags, ctx, mixinContext) + first = 1 # Consider 'when defined(globalsSlot): ThreadVarSetValue(globalsSlot, ...)' # in threads.nim: the subtle preprocessing here binds 'globalsSlot' which # is not exported and yet the generic 'threadProcWrapper' works correctly. - let flags = if isDefinedMagic: flags+{withinMixin} else: flags + let flags = if mixinContext: flags+{withinMixin} else: flags for i in countup(first, sonsLen(result) - 1): result.sons[i] = semGenericStmt(c, result.sons[i], flags, ctx) of nkIfStmt: diff --git a/tests/concurrency/tnodeadlocks.nim b/tests/concurrency/tnodeadlocks.nim deleted file mode 100644 index 7a3eedbc2..000000000 --- a/tests/concurrency/tnodeadlocks.nim +++ /dev/null @@ -1,70 +0,0 @@ -discard """ - outputsub: "101" - cmd: "nim $target --hints:on --threads:on $options $file" -""" - -import os, locks - -const - noDeadlocks = defined(preventDeadlocks) - -var - thr: array [0..5, TThread[tuple[a, b: int]]] - L, M, N: TLock - -proc doNothing() = discard - -proc threadFunc(interval: tuple[a, b: int]) {.thread.} = - doNothing() - for i in interval.a..interval.b: - when nodeadlocks: - case i mod 6 - of 0: - acquire(L) # lock stdout - acquire(M) - acquire(N) - of 1: - acquire(L) - acquire(N) # lock stdout - acquire(M) - of 2: - acquire(M) - acquire(L) - acquire(N) - of 3: - acquire(M) - acquire(N) - acquire(L) - of 4: - acquire(N) - acquire(M) - acquire(L) - of 5: - acquire(N) - acquire(L) - acquire(M) - else: assert false - else: - acquire(L) # lock stdout - acquire(M) - - echo i - os.sleep(10) - when nodeadlocks: - echo "deadlocks prevented: ", deadlocksPrevented - when nodeadlocks: - release(N) - release(M) - release(L) - -initLock(L) -initLock(M) -initLock(N) - -proc main = - for i in 0..high(thr): - createThread(thr[i], threadFunc, (i*100, i*100+50)) - joinThreads(thr) - -main() - diff --git a/tests/template/tit.nim b/tests/template/tit.nim new file mode 100644 index 000000000..9866711de --- /dev/null +++ b/tests/template/tit.nim @@ -0,0 +1,11 @@ + +# bug #1337 + +template someIt(a, pred: expr): expr = + var it {.inject.} = 0 + pred + +proc aProc(n) = + n.someIt(echo(it)) + +aProc(89) From 81f013dabbf487a223471bd0eebfb87d23bf9dad Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 23 Nov 2014 16:07:25 +0100 Subject: [PATCH 278/409] fixes #642 --- lib/pure/os.nim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 3a6930654..b5eead91d 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -474,7 +474,11 @@ proc getCreationTime*(file: string): Time {.rtl, extern: "nos$1".} = proc fileNewer*(a, b: string): bool {.rtl, extern: "nos$1".} = ## Returns true if the file `a` is newer than file `b`, i.e. if `a`'s ## modification time is later than `b`'s. - result = getLastModificationTime(a) - getLastModificationTime(b) > 0 + when defined(posix): + result = getLastModificationTime(a) - getLastModificationTime(b) >= 0 + # Posix's resolution sucks so, we use '>=' for posix. + else: + result = getLastModificationTime(a) - getLastModificationTime(b) > 0 proc getCurrentDir*(): string {.rtl, extern: "nos$1", tags: [].} = ## Returns the `current working directory`:idx:. From c1930f1b6e8dd8e542e9982a3791ead864875fff Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 25 Nov 2014 23:10:22 +0100 Subject: [PATCH 279/409] fixes #1672 --- lib/system.nim | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 7731c34cb..460762efc 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2965,16 +2965,13 @@ when true: THide(raiseAssert)(msg) template assert*(cond: bool, msg = "") = - ## Raises ``EAssertionFailure`` with `msg` if `cond` is false. - ## - ## Provides a means to implement `programming by contracts`:idx: in Nim. - ## ``assert`` evaluates expression ``cond`` and if ``cond`` is false, it - ## raises an ``EAssertionFailure`` exception. However, the compiler may not - ## generate any code at all for ``assert`` if it is advised to do so through - ## the ``-d:release`` or ``--assertions:off`` `command line switches - ## `_. - ## - ## Use ``assert`` for debugging purposes only. + ## Raises ``AssertionError`` with `msg` if `cond` is false. Note + ## that ``AssertionError`` is hidden from the effect system, so it doesn't + ## produce ``{.raises: [AssertionError].}``. This exception is only supposed + ## to be caught by unit testing frameworks. + ## The compiler may not generate any code at all for ``assert`` if it is + ## advised to do so through the ``-d:release`` or ``--assertions:off`` + ## `command line switches `_. bind instantiationInfo mixin failedAssertImpl when compileOption("assertions"): From 7edf6fc1d2f8feb8d126065f5429afa71e4aa06e Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 27 Nov 2014 08:36:58 +0100 Subject: [PATCH 280/409] fixes #1547 --- compiler/ccgexprs.nim | 2 +- compiler/trees.nim | 4 +++- tests/ccgbugs/tconstobj.nim | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/ccgbugs/tconstobj.nim diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index e05828f8f..547d0d376 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1718,7 +1718,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc genConstExpr(p: BProc, n: PNode): PRope proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool = - if (nfAllConst in n.flags) and (d.k == locNone) and (sonsLen(n) > 0): + if nfAllConst in n.flags and d.k == locNone and n.len > 0 and n.isDeepConstExpr: var t = getUniqueType(n.typ) discard getTypeDesc(p.module, t) # so that any fields are initialized var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId) diff --git a/compiler/trees.nim b/compiler/trees.nim index b1edd21f3..86a1139a0 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -117,7 +117,9 @@ proc isDeepConstExpr*(n: PNode): bool = of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure: for i in 0 .. Date: Thu, 27 Nov 2014 09:28:48 +0100 Subject: [PATCH 281/409] fixes #1657 --- compiler/semexprs.nim | 8 ++++++-- tests/overload/tsystemcmp.nim | 9 +++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tests/overload/tsystemcmp.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 73c778530..544d59491 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -960,9 +960,13 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) if s != nil: - markUsed(n.sons[1].info, s) + if s.kind in OverloadableSyms: + result = symChoice(c, n, s, scClosed) + else: + markUsed(n.sons[1].info, s) + result = semSym(c, n, s, flags) styleCheckUse(n.sons[1].info, s) - return semSym(c, n, s, flags) + return n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType}) #restoreOldStyleType(n.sons[0]) diff --git a/tests/overload/tsystemcmp.nim b/tests/overload/tsystemcmp.nim new file mode 100644 index 000000000..54dff0c46 --- /dev/null +++ b/tests/overload/tsystemcmp.nim @@ -0,0 +1,9 @@ +discard """ + cmd: r"nim c --hints:on $options --threads:on $file" +""" + +import algorithm + +# bug #1657 +var modules = @["hi", "ho", "ha", "huu"] +sort(modules, system.cmp) From eb69b81859864d8a47272c397971609e56a6d399 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 27 Nov 2014 09:31:40 +0100 Subject: [PATCH 282/409] doc improvements --- doc/manual/definitions.txt | 2 +- lib/pure/marshal.nim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/manual/definitions.txt b/doc/manual/definitions.txt index 687980dbc..9eb20f70f 100644 --- a/doc/manual/definitions.txt +++ b/doc/manual/definitions.txt @@ -39,7 +39,7 @@ invalid: let i = 5 try: a[i] = 'N' - except EInvalidIndex: + except IndexError: echo "invalid index" An `unchecked runtime error`:idx: is an error that is not guaranteed to be diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim index fc63605a9..02abda722 100644 --- a/lib/pure/marshal.nim +++ b/lib/pure/marshal.nim @@ -7,8 +7,8 @@ # distribution, for details about the copyright. # -## This module contains procs for serialization and deseralization of -## arbitrary Nim data structures. The serialization format uses JSON. +## This module contains procs for `serialization`:idx: and `deseralization`:idx: +## of arbitrary Nim data structures. The serialization format uses `JSON`:idx:. ## ## **Restriction**: For objects their type is **not** serialized. This means ## essentially that it does not work if the object has some other runtime From c2b223688d032947dbf9dd28760d9fe89745fe76 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 27 Nov 2014 09:41:36 +0100 Subject: [PATCH 283/409] fixes #1539 --- compiler/cgen.nim | 4 +- compiler/sempass2.nim | 23 ++++-- doc/rst.txt | 110 ----------------------------- tests/ccgbugs/tmissingvolatile.nim | 20 ++++++ 4 files changed, 38 insertions(+), 119 deletions(-) delete mode 100644 doc/rst.txt create mode 100644 tests/ccgbugs/tmissingvolatile.nim diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 51c426d79..c645b81aa 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -506,9 +506,7 @@ proc assignLocalVar(p: BProc, s: PSym) = if sfRegister in s.flags: app(decl, " register") #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds: # app(decl, " GC_GUARD") - if sfVolatile in s.flags or (p.nestedTryStmts.len > 0 and - not p.module.compileToCpp): - app(decl, " volatile") + if sfVolatile in s.flags: app(decl, " volatile") appf(decl, " $1;$n", [s.loc.r]) else: decl = ropef(s.cgDeclFrmt & ";$n", decl, s.loc.r) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 0d8c7c479..f41e169e3 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -69,7 +69,7 @@ type TEffects = object exc: PNode # stack of exceptions tags: PNode # list of tags - bottom: int + bottom, inTryStmt: int owner: PSym init: seq[int] # list of initialized variables guards: TModel # nested guards @@ -165,10 +165,17 @@ proc guardDotAccess(a: PEffects; n: PNode) = else: guardGlobal(a, n, g) -proc initVar(a: PEffects, n: PNode) = +proc makeVolatile(a: PEffects; s: PSym) {.inline.} = + template compileToCpp(a): expr = + gCmd == cmdCompileToCpp or sfCompileToCpp in getModule(a.owner).flags + if a.inTryStmt > 0 and not compileToCpp(a): + incl(s.flags, sfVolatile) + +proc initVar(a: PEffects, n: PNode; volatileCheck: bool) = if n.kind != nkSym: return let s = n.sym if isLocalVar(a, s): + if volatileCheck: makeVolatile(a, s) for x in a.init: if x == s.id: return a.init.add s.id @@ -179,7 +186,9 @@ proc initVarViaNew(a: PEffects, n: PNode) = if {tfNeedsInit, tfNotNil} * s.typ.flags <= {tfNotNil}: # 'x' is not nil, but that doesn't mean its "not nil" children # are initialized: - initVar(a, n) + initVar(a, n, volatileCheck=true) + elif isLocalVar(a, s): + makeVolatile(a, s) proc warnAboutGcUnsafe(n: PNode) = #assert false @@ -304,7 +313,9 @@ proc trackTryStmt(tracked: PEffects, n: PNode) = let oldState = tracked.init.len var inter: TIntersection = @[] - track(tracked, n.sons[0]) + inc tracked.inTryStmt + track(tracked, n.sons[0]) + dec tracked.inTryStmt for i in oldState.. Date: Fri, 28 Nov 2014 02:43:41 +0100 Subject: [PATCH 284/409] implemented procCall builtin --- compiler/ast.nim | 4 ++-- compiler/nversion.nim | 6 +---- compiler/semexprs.nim | 4 ++++ compiler/semfold.nim | 4 ---- compiler/semmagic.nim | 3 +++ compiler/transf.nim | 14 ++++++++---- doc/manual/procs.txt | 8 +++---- lib/system.nim | 48 +++++++++++++++++++++------------------ tests/method/tmultim2.nim | 21 +++++++++-------- todo.txt | 1 - web/news.txt | 2 ++ 11 files changed, 63 insertions(+), 52 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index ec309ba1a..62f2d105f 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -566,8 +566,8 @@ type mBool, mChar, mString, mCstring, mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn, mDeepCopy, - mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, - mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType, + mIsMainModule, mCompileDate, mCompileTime, mProcCall, + mCpuEndian, mHostOS, mHostCPU, mAppType, mNaN, mInf, mNegInf, mCompileOption, mCompileOptionArg, mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, mNKind, diff --git a/compiler/nversion.nim b/compiler/nversion.nim index 910ebfb59..8dc4b90b2 100644 --- a/compiler/nversion.nim +++ b/compiler/nversion.nim @@ -12,10 +12,6 @@ const MaxSetElements* = 1 shl 16 # (2^16) to support unicode character sets? - VersionMajor* = 0 - VersionMinor* = 10 - VersionPatch* = 1 - VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch - + VersionAsString* = system.NimVersion RodFileVersion* = "1215" # modify this if the rod-format changes! diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 544d59491..3ca80a9b1 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1649,6 +1649,10 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = else: result.typ = result[1].typ result.add instantiateCreateFlowVarCall(c, result[1].typ, n.info).newSymNode + of mProcCall: + result = setMs(n, s) + result.sons[1] = semExpr(c, n.sons[1]) + result.typ = n[1].typ else: result = semDirectOp(c, n, flags) proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 1e92fb832..c7ae42548 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -613,10 +613,6 @@ proc getConstExpr(m: PSym, n: PNode): PNode = of mIsMainModule: result = newIntNodeT(ord(sfMainModule in m.flags), n) of mCompileDate: result = newStrNodeT(times.getDateStr(), n) of mCompileTime: result = newStrNodeT(times.getClockStr(), n) - of mNimrodVersion: result = newStrNodeT(VersionAsString, n) - of mNimrodMajor: result = newIntNodeT(VersionMajor, n) - of mNimrodMinor: result = newIntNodeT(VersionMinor, n) - of mNimrodPatch: result = newIntNodeT(VersionPatch, n) of mCpuEndian: result = newIntNodeT(ord(CPU[targetCPU].endian), n) of mHostOS: result = newStrNodeT(toLower(platform.OS[targetOS].name), n) of mHostCPU: result = newStrNodeT(platform.CPU[targetCPU].name.toLower, n) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index a72a6ab7d..d6c420955 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -130,4 +130,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, of mShallowCopy: result = semShallowCopy(c, n, flags) of mNBindSym: result = semBindSym(c, n) of mLocals: result = semLocals(c, n) + of mProcCall: + result = n + result.typ = n[1].typ else: result = n diff --git a/compiler/transf.nim b/compiler/transf.nim index 6196512ba..3409acb74 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -582,7 +582,7 @@ proc getMergeOp(n: PNode): PSym = else: discard proc flattenTreeAux(d, a: PNode, op: PSym) = - var op2 = getMergeOp(a) + let op2 = getMergeOp(a) if op2 != nil and (op2.id == op.id or op.magic != mNone and op2.magic == op.magic): for i in countup(1, sonsLen(a)-1): flattenTreeAux(d, a.sons[i], op) @@ -590,7 +590,7 @@ proc flattenTreeAux(d, a: PNode, op: PSym) = addSon(d, copyTree(a)) proc flattenTree(root: PNode): PNode = - var op = getMergeOp(root) + let op = getMergeOp(root) if op != nil: result = copyNode(root) addSon(result, copyTree(root.sons[0])) @@ -600,8 +600,9 @@ proc flattenTree(root: PNode): PNode = proc transformCall(c: PTransf, n: PNode): PTransNode = var n = flattenTree(n) - var op = getMergeOp(n) - if (op != nil) and (op.magic != mNone) and (sonsLen(n) >= 3): + let op = getMergeOp(n) + let magic = getMagic(n) + if op != nil and op.magic != mNone and n.len >= 3: result = newTransNode(nkCall, n, 0) add(result, transform(c, n.sons[0])) var j = 1 @@ -616,9 +617,12 @@ proc transformCall(c: PTransf, n: PNode): PTransNode = inc(j) add(result, a.PTransNode) if len(result) == 2: result = result[1] - elif getMagic(n) == mNBindSym: + elif magic == mNBindSym: # for bindSym(myconst) we MUST NOT perform constant folding: result = n.PTransNode + elif magic == mProcCall: + # but do not change to its dispatcher: + result = transformSons(c, n[1]) else: let s = transformSons(c, n).PNode # bugfix: check after 'transformSons' if it's still a method call: diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index f48203c3b..d048615eb 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -16,7 +16,7 @@ the best match for the arguments. Example: .. code-block:: nim - proc toLower(c: Char): Char = # toLower for characters + proc toLower(c: char): char = # toLower for characters if c in {'A'..'Z'}: result = chr(ord(c) + (ord('a') - ord('A'))) else: @@ -150,8 +150,8 @@ means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as more argument in this case: .. code-block:: nim - proc optarg(x:int, y:int = 0):int = x + y - proc singlearg(x:int):int = 20*x + proc optarg(x: int, y: int = 0): int = x + y + proc singlearg(x: int): int = 20*x echo optarg 1, " ", singlearg 2 # prints "1 40" @@ -237,7 +237,7 @@ The following builtin procs cannot be overloaded for reasons of implementation simplicity (they require specialized semantic checking):: declared, defined, definedInScope, compiles, low, high, sizeOf, - is, of, shallowCopy, getAst, astToStr, spawn + is, of, shallowCopy, getAst, astToStr, spawn, procCall Thus they act more like keywords than like ordinary identifiers; unlike a keyword however, a redefinition may `shadow`:idx: the definition in diff --git a/lib/system.nim b/lib/system.nim index 460762efc..269dbb1e0 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1016,22 +1016,6 @@ const ## is the time of compilation as a string of the form ## ``HH:MM:SS``. This works thanks to compiler magic. - NimVersion* {.magic: "NimrodVersion"}: string = "0.0.0" - ## is the version of Nim as a string. - ## This works thanks to compiler magic. - - NimMajor* {.magic: "NimrodMajor"}: int = 0 - ## is the major number of Nim's version. - ## This works thanks to compiler magic. - - NimMinor* {.magic: "NimrodMinor"}: int = 0 - ## is the minor number of Nim's version. - ## This works thanks to compiler magic. - - NimPatch* {.magic: "NimrodPatch"}: int = 0 - ## is the patch number of Nim's version. - ## This works thanks to compiler magic. - cpuEndian* {.magic: "CpuEndian"}: Endianness = littleEndian ## is the endianness of the target CPU. This is a valuable piece of ## information for low-level code only. This works thanks to compiler @@ -1048,9 +1032,6 @@ const seqShallowFlag = low(int) -{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion, - NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].} - proc compileOption*(option: string): bool {. magic: "CompileOption", noSideEffect.} ## can be used to determine an on|off compile-time option. Example: @@ -1470,11 +1451,11 @@ template `>%` *(x, y: expr): expr {.immediate.} = y <% x ## treats `x` and `y` as unsigned and compares them. ## Returns true iff ``unsigned(x) > unsigned(y)``. -proc `$` *(x: int): string {.magic: "IntToStr", noSideEffect.} +proc `$`*(x: int): string {.magic: "IntToStr", noSideEffect.} ## The stringify operator for an integer argument. Returns `x` ## converted to a decimal string. -proc `$` *(x: int64): string {.magic: "Int64ToStr", noSideEffect.} +proc `$`*(x: int64): string {.magic: "Int64ToStr", noSideEffect.} ## The stringify operator for an integer argument. Returns `x` ## converted to a decimal string. @@ -1529,6 +1510,20 @@ const ## that you cannot compare a floating point value to this value ## and expect a reasonable result - use the `classify` procedure ## in the module ``math`` for checking for NaN. + NimMajor*: int = 0 + ## is the major number of Nim's version. + + NimMinor*: int = 10 + ## is the minor number of Nim's version. + + NimPatch*: int = 1 + ## is the patch number of Nim's version. + + NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch + ## is the version of Nim as a string. + +{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion, + NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].} # GC interface: @@ -3104,7 +3099,7 @@ proc locals*(): RootObj {.magic: "Locals", noSideEffect.} = ## generates a tuple constructor expression listing all the local variables ## in the current scope. This is quite fast as it does not rely ## on any debug or runtime information. Note that in constrast to what - ## the official signature says, the return type is not ``TObject`` but a + ## the official signature says, the return type is not ``RootObj`` but a ## tuple of a structure that depends on the current scope. Example: ## ## .. code-block:: nim @@ -3132,4 +3127,13 @@ when hostOS != "standalone" and not defined(NimrodVM) and not defined(JS): include "system/deepcopy" +proc procCall*(x: expr) {.magic: "ProcCall".} = + ## special magic to prohibit dynamic binding for `method`:idx: calls. + ## This is similar to `super`:idx: in ordinary OO languages. + ## + ## .. code-block:: nim + ## # 'someMethod' will be resolved fully statically: + ## procCall someMethod(a, b) + discard + {.pop.} #{.push warning[GcMem]: off.} diff --git a/tests/method/tmultim2.nim b/tests/method/tmultim2.nim index 75f652137..c5fb568a0 100644 --- a/tests/method/tmultim2.nim +++ b/tests/method/tmultim2.nim @@ -1,6 +1,9 @@ discard """ file: "tmultim2.nim" - output: "collide: unit, thing collide: unit, thing collide: thing, unit" + output: '''collide: unit, thing +collide: unit, thing +collide: thing, unit +collide: thing, thing''' """ # Test multi methods @@ -12,25 +15,25 @@ type a, b: int method collide(a, b: TThing) {.inline.} = - quit "to override!" + echo "collide: thing, thing" method collide(a: TThing, b: TUnit) {.inline.} = - write stdout, "collide: thing, unit " + echo "collide: thing, unit" method collide(a: TUnit, b: TThing) {.inline.} = - write stdout, "collide: unit, thing " + echo "collide: unit, thing" proc test(a, b: TThing) {.inline.} = collide(a, b) +proc staticCollide(a, b: TThing) {.inline.} = + procCall collide(a, b) + + var a: TThing b, c: TUnit collide(b, c) # ambiguous (unit, thing) or (thing, unit)? -> prefer unit, thing! test(b, c) collide(a, b) -#OUT collide: unit, thing collide: unit, thing collide: thing, unit - - - - +staticCollide(a, b) diff --git a/todo.txt b/todo.txt index a6ea31560..41db0b72f 100644 --- a/todo.txt +++ b/todo.txt @@ -2,7 +2,6 @@ version 0.10 ============ - make nimble part of the distribution -- implement 'procCall' - split idetools into separate tool - split docgen into separate tool diff --git a/web/news.txt b/web/news.txt index 0c3cedf35..fd9ac77c2 100644 --- a/web/news.txt +++ b/web/news.txt @@ -36,6 +36,8 @@ News lock levels and object field ``guards``. - The ``parallel`` statement has been implemented. - ``deepCopy`` has been added to the language. + - The builtin ``procCall`` can be used to get ``super``-like functionality + for multi methods. Compiler Additions From c45e89b486dda811ba94f4a55509d6820596be1b Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 28 Nov 2014 09:32:37 +0100 Subject: [PATCH 285/409] fixes #1039 --- compiler/semgnrc.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 0fa16497c..723789a31 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -350,7 +350,7 @@ proc semGenericStmt(c: PContext, n: PNode, of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, nkIteratorDef, nkLambdaKinds: checkSonsLen(n, bodyPos + 1) - if n.kind notin nkLambdaKinds: + if n.sons[namePos].kind != nkEmpty: addTempDecl(c, getIdentNode(n.sons[0]), skProc) openScope(c) n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos], From 4def86f077fe659ffd98bd6c1bbc43ad68af6ebb Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 28 Nov 2014 09:39:23 +0100 Subject: [PATCH 286/409] pegs module compiles again --- lib/pure/pegs.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 6eb7dee78..1ecb9d19e 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -1467,7 +1467,7 @@ proc builtin(p: var PegParser): Peg = of "W": result = charSet({'\1'..'\xff'} - {'a'..'z','A'..'Z','_','0'..'9'}) of "a": result = charSet({'a'..'z', 'A'..'Z'}) of "A": result = charSet({'\1'..'\xff'} - {'a'..'z', 'A'..'Z'}) - of "ident": result = pegs.ident + of "ident": result = pegs.ident() of "letter": result = unicodeLetter() of "upper": result = unicodeUpper() of "lower": result = unicodeLower() From 51dd4b7601e24ed5997cf5a60d8e7f6f382b5eb1 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 28 Nov 2014 18:15:06 +0100 Subject: [PATCH 287/409] fixes #1489, fixes #1490 --- compiler/jsgen.nim | 23 ++++++++++------------- tests/js/tbyvar.nim | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 tests/js/tbyvar.nim diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 8fc2ec1d2..108c0fe10 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -113,7 +113,7 @@ proc rdLoc(a: TCompRes): PRope {.inline.} = result = ropef("$1[$2]", a.address, a.res) proc newProc(globals: PGlobals, module: BModule, procDef: PNode, - options: TOptions): PProc = + options: TOptions): PProc = result = PProc( blocks: @[], options: options, @@ -942,17 +942,14 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) = case s.kind of skVar, skLet, skResult: r.kind = resExpr - if mapType(n.typ) == etyObject: + if mapType(n.sons[0].typ) == etyObject: # make addr() a no-op: r.typ = etyNone r.res = s.loc.r r.address = nil - elif sfGlobal in s.flags: - # globals are always indirect accessible - r.typ = etyBaseIndex - r.address = toRope("Globals") - r.res = makeJSString(ropeToStr(s.loc.r)) - elif sfAddrTaken in s.flags: + elif {sfGlobal, sfAddrTaken} * s.flags != {}: + # for ease of code generation, we do not distinguish between + # sfAddrTaken and sfGlobal. r.typ = etyBaseIndex r.address = s.loc.r r.res = toRope("0") @@ -981,7 +978,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) = of skVar, skLet, skParam, skTemp, skResult: if s.loc.r == nil: internalError(n.info, "symbol has no generated name: " & s.name.s) - var k = mapType(s.typ) + let k = mapType(s.typ) if k == etyBaseIndex: r.typ = etyBaseIndex if {sfAddrTaken, sfGlobal} * s.flags != {}: @@ -990,7 +987,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) = else: r.address = s.loc.r r.res = con(s.loc.r, "_Idx") - elif k != etyObject and sfAddrTaken in s.flags: + elif k != etyObject and {sfAddrTaken, sfGlobal} * s.flags != {}: r.res = ropef("$1[0]", [s.loc.r]) else: r.res = s.loc.r @@ -1170,8 +1167,9 @@ proc createVar(p: PProc, typ: PType, indirect: bool): PRope = internalError("createVar: " & $t.kind) result = nil -proc isIndirect(v: PSym): bool = - result = (sfAddrTaken in v.flags) and (mapType(v.typ) != etyObject) and +proc isIndirect(v: PSym): bool = + result = {sfAddrTaken, sfGlobal} * v.flags != {} and + (mapType(v.typ) != etyObject) and v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator} proc genVarInit(p: PProc, v: PSym, n: PNode) = @@ -1675,7 +1673,6 @@ proc newModule(module: PSym): BModule = proc genHeader(): PRope = result = ropef("/* Generated by the Nim Compiler v$1 */$n" & "/* (c) 2014 Andreas Rumpf */$n$n" & - "$nvar Globals = this;$n" & "var framePtr = null;$n" & "var excHandler = null;$n" & "var lastJSError = null;$n", diff --git a/tests/js/tbyvar.nim b/tests/js/tbyvar.nim new file mode 100644 index 000000000..5ed2de1da --- /dev/null +++ b/tests/js/tbyvar.nim @@ -0,0 +1,32 @@ +discard """ + output: '''foo 12 +bar 12 +2 +foo 12 +bar 12 +2''' +""" + +# bug #1489 +proc foo(x: int) = echo "foo: ", x +proc bar(y: var int) = echo "bar: ", y + +var x = 12 +foo(x) +bar(x) + +# bug #1490 +var y = 1 +y *= 2 +echo y + +proc main = + var x = 12 + foo(x) + bar(x) + + var y = 1 + y *= 2 + echo y + +main() From 80b83611875383760da40d626a516e794e1245e7 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 29 Nov 2014 13:55:30 +0100 Subject: [PATCH 288/409] smileys configurable; safer image attribute handling --- lib/packages/docutils/rst.nim | 6 ++--- lib/packages/docutils/rstgen.nim | 42 ++++++++++++++++++-------------- todo.txt | 1 + 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim index 07014c754..95d49bad7 100644 --- a/lib/packages/docutils/rst.nim +++ b/lib/packages/docutils/rst.nim @@ -254,11 +254,11 @@ proc getTokens(buffer: string, skipPounds: bool, tokens: var TTokenSeq): int = type TLevelMap = array[char, int] - TSubstitution{.final.} = object + TSubstitution = object key*: string value*: PRstNode - TSharedState {.final.} = object + TSharedState = object options: TRstParseOptions # parsing options uLevel, oLevel: int # counters for the section levels subs: seq[TSubstitution] # substitutions @@ -273,7 +273,7 @@ type # This is for over-underline adornments. msgHandler: TMsgHandler # How to handle errors. findFile: TFindFileHandler # How to find files. - + PSharedState = ref TSharedState TRstParser = object of RootObj idx*: int diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 50246f2e0..514292039 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -60,6 +60,7 @@ type seenIndexTerms: Table[string, int] ## \ ## Keeps count of same text index terms to generate different identifiers ## for hyperlinks. See renderIndexTerm proc for details. + smileyFrmt: string ## How to massage the smiley filename. PDoc = var TRstGenerator ## Alias to type less. @@ -79,8 +80,9 @@ proc init(p: var CodeBlockParams) = proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, config: StringTableRef, filename: string, options: TRstParseOptions, - findFile: TFindFileHandler, - msgHandler: TMsgHandler) = + findFile: TFindFileHandler=nil, + msgHandler: TMsgHandler=nil, + smileyFrmt = "/images/smilies/$1.gif") = ## Initializes a ``TRstGenerator``. ## ## You need to call this before using a ``TRstGenerator`` with any other @@ -121,10 +123,7 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, ## import packages/docutils/rstgen ## ## var gen: TRstGenerator - ## - ## gen.initRstGenerator(outHtml, defaultConfig(), - ## "filename", {}, nil, nil) - + ## gen.initRstGenerator(outHtml, defaultConfig(), "filename", {}) g.config = config g.target = target g.tocPart = @[] @@ -143,6 +142,7 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, let s = config["split.item.toc"] if s != "": g.splitAfter = parseInt(s) for i in low(g.meta)..high(g.meta): g.meta[i] = "" + g.smileyFrmt = smileyFrmt proc writeIndexFile*(g: var TRstGenerator, outfile: string) = ## Writes the current index buffer to the specified output file. @@ -745,34 +745,40 @@ proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, else: result.add(tmp) -proc renderImage(d: PDoc, n: PRstNode, result: var string) = +proc renderImage(d: PDoc, n: PRstNode, result: var string) = + template valid(s): expr = + s.len > 0 and allCharsInSet(s, {'/',':','%','_','\\','\128'..'\xFF'} + + Digits + Letters + WhiteSpace) + var options = "" var s = getFieldValue(n, "scale") - if s != "": dispA(d.target, options, " scale=\"$1\"", " scale=$1", [strip(s)]) + if s.valid: dispA(d.target, options, " scale=\"$1\"", " scale=$1", [strip(s)]) s = getFieldValue(n, "height") - if s != "": dispA(d.target, options, " height=\"$1\"", " height=$1", [strip(s)]) + if s.valid: dispA(d.target, options, " height=\"$1\"", " height=$1", [strip(s)]) s = getFieldValue(n, "width") - if s != "": dispA(d.target, options, " width=\"$1\"", " width=$1", [strip(s)]) + if s.valid: dispA(d.target, options, " width=\"$1\"", " width=$1", [strip(s)]) s = getFieldValue(n, "alt") - if s != "": dispA(d.target, options, " alt=\"$1\"", "", [strip(s)]) + if s.valid: dispA(d.target, options, " alt=\"$1\"", "", [strip(s)]) s = getFieldValue(n, "align") - if s != "": dispA(d.target, options, " align=\"$1\"", "", [strip(s)]) + if s.valid: dispA(d.target, options, " align=\"$1\"", "", [strip(s)]) if options.len > 0: options = dispF(d.target, "$1", "[$1]", [options]) - - dispA(d.target, result, "", "\\includegraphics$2{$1}", - [getArgument(n), options]) + + let arg = getArgument(n) + if arg.valid: + dispA(d.target, result, "", "\\includegraphics$2{$1}", + [arg, options]) if len(n) >= 3: renderRstToOut(d, n.sons[2], result) proc renderSmiley(d: PDoc, n: PRstNode, result: var string) = dispA(d.target, result, - """""", - "\\includegraphics{$1}", [n.text]) + """""", + "\\includegraphics{$1}", [d.smileyFrmt % n.text]) proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) = ## Parses useful fields which can appear before a code block. diff --git a/todo.txt b/todo.txt index 41db0b72f..077f5c9cb 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ version 0.10 ============ +- introduce ``--experimental`` switch - make nimble part of the distribution - split idetools into separate tool - split docgen into separate tool From c2e04abcfa6c4953820a1d24be8d9655c2c685c7 Mon Sep 17 00:00:00 2001 From: Araq Date: Sat, 29 Nov 2014 14:08:42 +0100 Subject: [PATCH 289/409] fixes regression that caused pegs to not compile --- compiler/semexprs.nim | 1 + lib/pure/pegs.nim | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 3ca80a9b1..108e21369 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -962,6 +962,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = if s != nil: if s.kind in OverloadableSyms: result = symChoice(c, n, s, scClosed) + if result.kind == nkSym: result = semSym(c, n, s, flags) else: markUsed(n.sons[1].info, s) result = semSym(c, n, s, flags) diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 1ecb9d19e..6eb7dee78 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -1467,7 +1467,7 @@ proc builtin(p: var PegParser): Peg = of "W": result = charSet({'\1'..'\xff'} - {'a'..'z','A'..'Z','_','0'..'9'}) of "a": result = charSet({'a'..'z', 'A'..'Z'}) of "A": result = charSet({'\1'..'\xff'} - {'a'..'z', 'A'..'Z'}) - of "ident": result = pegs.ident() + of "ident": result = pegs.ident of "letter": result = unicodeLetter() of "upper": result = unicodeUpper() of "lower": result = unicodeLower() From a1c217a2db6e3b263d4bc847d3f888f9ee63dc3c Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 30 Nov 2014 02:56:26 +0100 Subject: [PATCH 290/409] fixes #1684 --- compiler/sigmatch.nim | 4 ++++ tests/generics/tsubtypeconstraint.nim | 13 +++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/generics/tsubtypeconstraint.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 266236bf4..123d1df2e 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -936,6 +936,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = else: if f.sonsLen > 0 and f.sons[0].kind != tyNone: result = typeRel(c, f.lastSon, a) + if doBind and result notin {isNone, isGeneric}: + let concrete = concreteType(c, a) + if concrete == nil: return isNone + put(c.bindings, f, concrete) else: result = isGeneric diff --git a/tests/generics/tsubtypeconstraint.nim b/tests/generics/tsubtypeconstraint.nim new file mode 100644 index 000000000..2f0954522 --- /dev/null +++ b/tests/generics/tsubtypeconstraint.nim @@ -0,0 +1,13 @@ + +# bug #1684 +type + BaseType {.inheritable pure.} = object + idx: int + + DerivedType* {.final pure.} = object of BaseType + +proc index*[Toohoo: BaseType](h: Toohoo): int {.inline.} = h.idx +proc newDerived(idx: int): DerivedType {.inline.} = DerivedType(idx: idx) + +let d = newDerived(2) +assert(d.index == 2) From 866ce10b056edc19e77c8a1b35ca5cb0645be4dd Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 30 Nov 2014 23:11:32 +0100 Subject: [PATCH 291/409] fixes #1687 --- compiler/semtypinst.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 064bbf823..c53464f80 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -291,7 +291,7 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType = var newbody = replaceTypeVarsT(cl, lastSon(body)) newbody.flags = newbody.flags + (t.flags + body.flags - tfInstClearedFlags) - result.flags = result.flags + newbody.flags + result.flags = result.flags + newbody.flags - tfInstClearedFlags newbody.callConv = body.callConv # This type may be a generic alias and we want to resolve it here. # One step is enough, because the recursive nature of From 85d83fd8cb43a1d49a18a6f6329662da47059646 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 1 Dec 2014 22:53:50 +0100 Subject: [PATCH 292/409] fixes regression due to object assignment fixes --- compiler/ccgtypes.nim | 16 +++++++++------- tests/typerel/tnoargopenarray.nim | 2 +- tests/typerel/typalias.nim | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index c3905f3e6..460cb9297 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -166,6 +166,10 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope proc needsComplexAssignment(typ: PType): bool = result = containsGarbageCollectedRef(typ) +proc isObjLackingTypeField(typ: PType): bool {.inline.} = + result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and + (typ.sons[0] == nil) or isPureObject(typ)) + proc isInvalidReturnType(rettype: PType): bool = # Arrays and sets cannot be returned by a C procedure, because C is # such a poor programming language. @@ -177,10 +181,12 @@ proc isInvalidReturnType(rettype: PType): bool = of ctArray: result = not (skipTypes(rettype, typedescInst).kind in {tyVar, tyRef, tyPtr}) - of ctStruct: - result = needsComplexAssignment(skipTypes(rettype, typedescInst)) + of ctStruct: + let t = skipTypes(rettype, typedescInst) + result = needsComplexAssignment(t) or + (t.kind == tyObject and not isObjLackingTypeField(t)) else: result = false - + const CallingConvToStr: array[TCallingConvention, string] = ["N_NIMCALL", "N_STDCALL", "N_CDECL", "N_SAFECALL", @@ -678,10 +684,6 @@ when false: var tmp = getNimType(m) appf(m.s[cfsTypeInit2], "$2 = &$1;$n", [tmp, name]) -proc isObjLackingTypeField(typ: PType): bool {.inline.} = - result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and - (typ.sons[0] == nil) or isPureObject(typ)) - proc genTypeInfoAuxBase(m: BModule, typ: PType, name, base: PRope) = var nimtypeKind: int #allocMemTI(m, typ, name) diff --git a/tests/typerel/tnoargopenarray.nim b/tests/typerel/tnoargopenarray.nim index 20ebe5ecc..3e65194ff 100644 --- a/tests/typerel/tnoargopenarray.nim +++ b/tests/typerel/tnoargopenarray.nim @@ -1,7 +1,7 @@ import db_sqlite -var db: DbConn +var db: TDbConn exec(db, sql"create table blabla()") diff --git a/tests/typerel/typalias.nim b/tests/typerel/typalias.nim index 40ff06765..55dcb9fa6 100644 --- a/tests/typerel/typalias.nim +++ b/tests/typerel/typalias.nim @@ -1,7 +1,7 @@ type TMyObj = TYourObj - TYourObj = object of TObject + TYourObj = object of RootObj x, y: int proc init: TYourObj = From c2b36a0343ed8af0f817743a7b662900cc7c1d92 Mon Sep 17 00:00:00 2001 From: Dustin Lacewell Date: Wed, 3 Dec 2014 13:26:37 -0800 Subject: [PATCH 293/409] Adds some flexibility to the lib name of SDL_ttf to allow for newer distributions --- lib/wrappers/sdl/sdl_ttf.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wrappers/sdl/sdl_ttf.nim b/lib/wrappers/sdl/sdl_ttf.nim index e0410c798..cbea7c078 100644 --- a/lib/wrappers/sdl/sdl_ttf.nim +++ b/lib/wrappers/sdl/sdl_ttf.nim @@ -163,7 +163,7 @@ elif defined(macosx): ttfLibName = "libSDL_ttf-2.0.0.dylib" else: const - ttfLibName = "libSDL_ttf.so(|.1|.0)" + ttfLibName = "libSDL_ttf(-2.0|).so(|.1|.0)" const MAJOR_VERSION* = 2 MINOR_VERSION* = 0 From 51d2096cd340ec9ef0cb1e598d5c389a95b9c456 Mon Sep 17 00:00:00 2001 From: Dustin Lacewell Date: Wed, 3 Dec 2014 15:15:58 -0800 Subject: [PATCH 294/409] Update the pattern to prefer the old version --- lib/pure/sockets.nim | 3 ++- lib/wrappers/sdl/sdl_ttf.nim | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 99cdc002c..e3c32e806 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -45,7 +45,8 @@ else: # Note: The enumerations are mapped to Window's constants. -when defined(ssl): +when defined(ssl): + type SSLError* = object of Exception diff --git a/lib/wrappers/sdl/sdl_ttf.nim b/lib/wrappers/sdl/sdl_ttf.nim index cbea7c078..9ebe70b9d 100644 --- a/lib/wrappers/sdl/sdl_ttf.nim +++ b/lib/wrappers/sdl/sdl_ttf.nim @@ -163,7 +163,7 @@ elif defined(macosx): ttfLibName = "libSDL_ttf-2.0.0.dylib" else: const - ttfLibName = "libSDL_ttf(-2.0|).so(|.1|.0)" + ttfLibName = "libSDL_ttf(|-2.0).so(|.1|.0)" const MAJOR_VERSION* = 2 MINOR_VERSION* = 0 From e27ab367318ceb01a023b367ac908c137e3223c7 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 4 Dec 2014 10:12:32 +0100 Subject: [PATCH 295/409] implements 'defer' --- compiler/ast.nim | 3 ++- compiler/lexer.nim | 6 ++++-- compiler/parser.nim | 10 ++++++---- compiler/semstmts.nim | 21 +++++++++++++++++---- compiler/wordrecg.nim | 4 ++-- doc/gc.txt | 3 ++- doc/grammar.txt | 3 ++- doc/keywords.txt | 2 +- lib/core/macros.nim | 2 +- lib/packages/docutils/highlite.nim | 5 +++-- todo.txt | 5 ++++- web/news.txt | 1 + 12 files changed, 45 insertions(+), 20 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 62f2d105f..1d2b63181 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -160,6 +160,7 @@ type nkConstDef, # a const definition nkTypeDef, # a type definition nkYieldStmt, # the yield statement as a tree + nkDefer, # the 'defer' statement nkTryStmt, # a try statement nkFinally, # a finally section nkRaiseStmt, # a raise statement @@ -566,7 +567,7 @@ type mBool, mChar, mString, mCstring, mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn, mDeepCopy, - mIsMainModule, mCompileDate, mCompileTime, mProcCall, + mIsMainModule, mCompileDate, mCompileTime, mProcCall, mCpuEndian, mHostOS, mHostCPU, mAppType, mNaN, mInf, mNegInf, mCompileOption, mCompileOptionArg, diff --git a/compiler/lexer.nim b/compiler/lexer.nim index dbeec8acf..fb74f27d6 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -35,7 +35,8 @@ type tkSymbol, # keywords: tkAddr, tkAnd, tkAs, tkAsm, tkAtomic, tkBind, tkBlock, tkBreak, tkCase, tkCast, - tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkDo, + tkConst, tkContinue, tkConverter, + tkDefer, tkDiscard, tkDistinct, tkDiv, tkDo, tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkExport, tkFinally, tkFor, tkFrom, tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, @@ -71,7 +72,8 @@ const "tkSymbol", "addr", "and", "as", "asm", "atomic", "bind", "block", "break", "case", "cast", - "const", "continue", "converter", "discard", "distinct", "div", "do", + "const", "continue", "converter", + "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", "finally", "for", "from", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", diff --git a/compiler/parser.nim b/compiler/parser.nim index e4de75a07..b5a9559d9 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -1423,9 +1423,10 @@ proc parseBlock(p: var TParser): PNode = colcom(p, result) addSon(result, parseStmt(p)) -proc parseStatic(p: var TParser): PNode = +proc parseStaticOrDefer(p: var TParser; k: TNodeKind): PNode = #| staticStmt = 'static' colcom stmt - result = newNodeP(nkStaticStmt, p) + #| deferStmt = 'defer' colcom stmt + result = newNodeP(k, p) getTokNoInd(p) colcom(p, result) addSon(result, parseStmt(p)) @@ -1863,7 +1864,7 @@ proc simpleStmt(p: var TParser): PNode = proc complexOrSimpleStmt(p: var TParser): PNode = #| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt #| | tryStmt | finallyStmt | exceptStmt | forStmt - #| | blockStmt | staticStmt | asmStmt + #| | blockStmt | staticStmt | deferStmt | asmStmt #| | 'proc' routine #| | 'method' routine #| | 'iterator' routine @@ -1884,7 +1885,8 @@ proc complexOrSimpleStmt(p: var TParser): PNode = of tkExcept: result = parseExceptBlock(p, nkExceptBranch) of tkFor: result = parseFor(p) of tkBlock: result = parseBlock(p) - of tkStatic: result = parseStatic(p) + of tkStatic: result = parseStaticOrDefer(p, nkStaticStmt) + of tkDefer: result = parseStaticOrDefer(p, nkDefer) of tkAsm: result = parseAsm(p) of tkProc: result = parseRoutine(p, nkProcDef) of tkMethod: result = parseRoutine(p, nkMethodDef) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index c6906d98e..933ac7daf 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1362,8 +1362,9 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = # nkNilLit, nkEmpty}: # dec last for i in countup(0, length - 1): - case n.sons[i].kind - of nkFinally, nkExceptBranch: + let k = n.sons[i].kind + case k + of nkFinally, nkExceptBranch, nkDefer: # stand-alone finally and except blocks are # transformed into regular try blocks: # @@ -1372,12 +1373,24 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = # ... | ... # | finally: # | fclose(f) + var deferPart: PNode + if k == nkDefer: + deferPart = newNodeI(nkFinally, n.sons[i].info) + deferPart.add n.sons[i].sons[0] + elif k == nkFinally: + message(n.info, warnDeprecated, + "use 'defer'; standalone 'finally'") + deferPart = n.sons[i] + else: + message(n.info, warnDeprecated, + "use an explicit 'try'; standalone 'except'") + deferPart = n.sons[i] var tryStmt = newNodeI(nkTryStmt, n.sons[i].info) var body = newNodeI(nkStmtList, n.sons[i].info) if i < n.sonsLen - 1: body.sons = n.sons[(i+1)..(-1)] tryStmt.addSon(body) - tryStmt.addSon(n.sons[i]) + tryStmt.addSon(deferPart) n.sons[i] = semTry(c, tryStmt) n.sons.setLen(i+1) return @@ -1424,7 +1437,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = # a statement list (s; e) has the type 'e': if result.kind == nkStmtList and result.len > 0: var lastStmt = lastSon(result) - if lastStmt.kind != nkNilLit and not ImplicitlyDiscardable(lastStmt): + if lastStmt.kind != nkNilLit and not implicitlyDiscardable(lastStmt): result.typ = lastStmt.typ #localError(lastStmt.info, errGenerated, # "Last expression must be explicitly returned if it " & diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 068f59c71..45206e7e7 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -24,7 +24,7 @@ type wAddr, wAnd, wAs, wAsm, wAtomic, wBind, wBlock, wBreak, wCase, wCast, wConst, - wContinue, wConverter, wDiscard, wDistinct, wDiv, wDo, + wContinue, wConverter, wDefer, wDiscard, wDistinct, wDiv, wDo, wElif, wElse, wEnd, wEnum, wExcept, wExport, wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn, wInclude, wInterface, wIs, wIsnot, wIterator, wLet, @@ -103,7 +103,7 @@ const "addr", "and", "as", "asm", "atomic", "bind", "block", "break", "case", "cast", "const", "continue", "converter", - "discard", "distinct", "div", "do", + "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", "finally", "for", "from", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", diff --git a/doc/gc.txt b/doc/gc.txt index fdb1d1b6c..9398262d9 100644 --- a/doc/gc.txt +++ b/doc/gc.txt @@ -47,7 +47,8 @@ Realtime support ================ To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be -defined. With this switch the GC supports the following operations: +defined via ``--define:useRealtimeGC`` (you can put this into your config +file as well). With this switch the GC supports the following operations: .. code-block:: nim proc GC_setMaxPause*(MaxPauseInUs: int) diff --git a/doc/grammar.txt b/doc/grammar.txt index a54428678..bce3769d0 100644 --- a/doc/grammar.txt +++ b/doc/grammar.txt @@ -142,6 +142,7 @@ exceptBlock = 'except' colcom stmt forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt blockStmt = 'block' symbol? colcom stmt staticStmt = 'static' colcom stmt +deferStmt = 'defer' colcom stmt asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLE_STR_LIT) genericParam = symbol (comma symbol)* (colon expr)? ('=' optInd expr)? genericParamList = '[' optInd @@ -182,7 +183,7 @@ simpleStmt = ((returnStmt | raiseStmt | yieldStmt | discardStmt | breakStmt | includeStmt | commentStmt) / exprStmt) COMMENT? complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt | tryStmt | finallyStmt | exceptStmt | forStmt - | blockStmt | staticStmt | asmStmt + | blockStmt | staticStmt | deferStmt | asmStmt | 'proc' routine | 'method' routine | 'iterator' routine diff --git a/doc/keywords.txt b/doc/keywords.txt index a43b35475..67ff0ab7f 100644 --- a/doc/keywords.txt +++ b/doc/keywords.txt @@ -1,7 +1,7 @@ addr and as asm atomic bind block break case cast const continue converter -discard distinct div do +defer discard distinct div do elif else end enum except export finally for from generic diff --git a/lib/core/macros.nim b/lib/core/macros.nim index b61fe1d17..ed5d3c50c 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -46,7 +46,7 @@ type nnkForStmt, nnkParForStmt, nnkWhileStmt, nnkCaseStmt, nnkTypeSection, nnkVarSection, nnkLetSection, nnkConstSection, nnkConstDef, nnkTypeDef, - nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt, + nnkYieldStmt, nnkDefer, nnkTryStmt, nnkFinally, nnkRaiseStmt, nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt, nnkDiscardStmt, nnkStmtList, nnkImportStmt, diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index d4bd94e5e..9c482575a 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -47,8 +47,9 @@ const # The following list comes from doc/keywords.txt, make sure it is # synchronized with this array by running the module itself as a test case. nimKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block", - "break", "case", "cast", "const", "continue", "converter", "discard", - "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", + "break", "case", "cast", "const", "continue", "converter", + "defer", "discard", "distinct", "div", "do", + "elif", "else", "end", "enum", "except", "export", "finally", "for", "from", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", "let", "macro", "method", "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", diff --git a/todo.txt b/todo.txt index 077f5c9cb..6068c049b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,12 +1,16 @@ version 0.10 ============ + Repetition renders the ridiculous reasonable. + - introduce ``--experimental`` switch +- c2nim depends on the compiler - make nimble part of the distribution - split idetools into separate tool - split docgen into separate tool + Concurrency ----------- @@ -33,7 +37,6 @@ Misc Bugs ==== -- fix the bug that keeps 'defer' template from working - VM: Pegs do not work at compile-time - VM: ptr/ref T cannot work in general - scopes are still broken for generic instantiation! diff --git a/web/news.txt b/web/news.txt index fd9ac77c2..65f245ae6 100644 --- a/web/news.txt +++ b/web/news.txt @@ -28,6 +28,7 @@ News fails to match. - The "symmetric set difference" operator (``-+-``) never worked and has been removed. + - ``defer`` is a keyword now. Language Additions ------------------ From 898501d9d1973a0ac1571a9e34c33f47e36d6c8a Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Thu, 4 Dec 2014 18:47:01 +0000 Subject: [PATCH 296/409] Moved smiliey format to config hash table. --- lib/packages/docutils/rstgen.nim | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 514292039..fc60b3672 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -60,7 +60,6 @@ type seenIndexTerms: Table[string, int] ## \ ## Keeps count of same text index terms to generate different identifiers ## for hyperlinks. See renderIndexTerm proc for details. - smileyFrmt: string ## How to massage the smiley filename. PDoc = var TRstGenerator ## Alias to type less. @@ -81,8 +80,7 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, config: StringTableRef, filename: string, options: TRstParseOptions, findFile: TFindFileHandler=nil, - msgHandler: TMsgHandler=nil, - smileyFrmt = "/images/smilies/$1.gif") = + msgHandler: TMsgHandler=nil) = ## Initializes a ``TRstGenerator``. ## ## You need to call this before using a ``TRstGenerator`` with any other @@ -142,7 +140,6 @@ proc initRstGenerator*(g: var TRstGenerator, target: TOutputTarget, let s = config["split.item.toc"] if s != "": g.splitAfter = parseInt(s) for i in low(g.meta)..high(g.meta): g.meta[i] = "" - g.smileyFrmt = smileyFrmt proc writeIndexFile*(g: var TRstGenerator, outfile: string) = ## Writes the current index buffer to the specified output file. @@ -778,7 +775,7 @@ proc renderSmiley(d: PDoc, n: PRstNode, result: var string) = dispA(d.target, result, """""", - "\\includegraphics{$1}", [d.smileyFrmt % n.text]) + "\\includegraphics{$1}", [d.config["doc.smiley_format"] % n.text]) proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) = ## Parses useful fields which can appear before a code block. @@ -1204,6 +1201,7 @@ $content """) setConfigVar("doc.body_no_toc", "$moduledesc $content") setConfigVar("doc.file", "$content") + setConfigVar("doc.smiley_format", "/images/smilies/$1.gif") # ---------- forum --------------------------------------------------------- From 4b7de4dc5e628bf08ad6673652f1aa2df019525c Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 5 Dec 2014 10:09:29 +0100 Subject: [PATCH 297/409] implemented 'experimental' switch --- compiler/ast.nim | 1 + compiler/commands.nim | 4 ++++ compiler/options.nim | 1 + compiler/pragmas.nim | 8 +++++++- compiler/sem.nim | 3 --- compiler/semdata.nim | 5 +++++ compiler/semexprs.nim | 2 ++ compiler/wordrecg.nim | 5 +++-- doc/advopt.txt | 1 + doc/manual/pragmas.txt | 18 ++++++++++++++++++ doc/manual/stmts.txt | 3 ++- web/news.txt | 5 +++++ 12 files changed, 49 insertions(+), 7 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 1d2b63181..8ebe5afa6 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -294,6 +294,7 @@ const # require RC ops sfCompileToCpp* = sfInfixCall # compile the module as C++ code sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code + sfExperimental* = sfOverriden # module uses the .experimental switch const # getting ready for the future expr/stmt merge diff --git a/compiler/commands.nim b/compiler/commands.nim index f26d1d6c7..a5b0b40d7 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -226,6 +226,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool = of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation) of "implicitstatic": result = contains(gOptions, optImplicitStatic) of "patterns": result = contains(gOptions, optPatterns) + of "experimental": result = gExperimentalMode else: invalidCmdLineOption(passCmd1, switch, info) proc processPath(path: string, notRelativeToProj = false): string = @@ -568,6 +569,9 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = of "none": idents.firstCharIsCS = false else: localError(info, errGenerated, "'partial' or 'none' expected, but found " & arg) + of "experimental": + expectNoArg(switch, arg, pass, info) + gExperimentalMode = true else: if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg) else: invalidCmdLineOption(pass, switch, info) diff --git a/compiler/options.nim b/compiler/options.nim index 838f99f8e..415ac8430 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -115,6 +115,7 @@ var # the tracked source X, saved by the CAAS client. gDirtyOriginalIdx* = 0'i32 # the original source file of the dirtified buffer. gNoNimblePath* = false + gExperimentalMode*: bool proc importantComments*(): bool {.inline.} = gCmd in {cmdDoc, cmdIdeTools} proc usesNativeGC*(): bool {.inline.} = gSelectedGC >= gcRefc diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index b548837fe..879950e79 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -45,7 +45,7 @@ const wBreakpoint, wWatchPoint, wPassl, wPassc, wDeadCodeElim, wDeprecated, wFloatchecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto, - wInjectStmt, wDeprecated} + wInjectStmt, wDeprecated, wExperimental} lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wNosideeffect, wSideeffect, wNoreturn, wDynlib, wHeader, wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, @@ -850,6 +850,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, localError(it.info, errExprExpected) else: it.sons[1] = c.semExpr(c, it.sons[1]) + of wExperimental: + noVal(it) + if isTopLevel(c): + c.module.flags.incl sfExperimental + else: + localError(it.info, "'experimental' pragma only valid as toplevel statement") else: invalidPragma(it) else: invalidPragma(it) else: processNote(c, it) diff --git a/compiler/sem.nim b/compiler/sem.nim index 5b31129a5..5160af20a 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -133,9 +133,6 @@ proc commonType*(x, y: PType): PType = result = newType(k, r.owner) result.addSonSkipIntLit(r) -proc isTopLevel(c: PContext): bool {.inline.} = - result = c.currentScope.depthLevel <= 2 - proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym = result = newSym(kind, considerQuotedIdent(n), getCurrOwner(), n.info) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 921e87d30..f876770c0 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -312,3 +312,8 @@ proc checkSonsLen*(n: PNode, length: int) = proc checkMinSonsLen*(n: PNode, length: int) = if sonsLen(n) < length: illFormedAst(n) +proc isTopLevel*(c: PContext): bool {.inline.} = + result = c.currentScope.depthLevel <= 2 + +proc experimentalMode*(c: PContext): bool {.inline.} = + result = gExperimentalMode or sfExperimental in c.module.flags diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 108e21369..ac82e9fed 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1433,6 +1433,8 @@ proc newAnonSym(kind: TSymKind, info: TLineInfo, proc semUsing(c: PContext, n: PNode): PNode = result = newNodeI(nkEmpty, n.info) + if not experimentalMode(c): + localError(n.info, "use the {.experimental.} pragma to enable 'using'") for e in n.sons: let usedSym = semExpr(c, e) if usedSym.kind == nkSym: diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 45206e7e7..f08ab0ad9 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -61,7 +61,8 @@ type wPassc, wPassl, wBorrow, wDiscardable, wFieldChecks, wWatchPoint, wSubsChar, - wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt, + wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, + wInjectStmt, wExperimental, wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, wAsmNoStackFrame, wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks, @@ -144,7 +145,7 @@ const "passc", "passl", "borrow", "discardable", "fieldchecks", "watchpoint", "subschar", "acyclic", "shallow", "unroll", "linearscanend", - "computedgoto", "injectstmt", + "computedgoto", "injectstmt", "experimental", "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit", "asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked", "guard", "locks", diff --git a/doc/advopt.txt b/doc/advopt.txt index 2ddba12e8..78c3d571a 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -91,4 +91,5 @@ Advanced options: --verbosity:0|1|2|3 set Nim's verbosity level (1 is default) --cs:none|partial set case sensitivity level (default: none); do not use! this setting affects the whole language + --experimental enable experimental language features -v, --version show detailed version information diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt index 6181b3e1b..6bb1314cd 100644 --- a/doc/manual/pragmas.txt +++ b/doc/manual/pragmas.txt @@ -495,3 +495,21 @@ identifier that can be used to enable or disable it: This is often better than disabling all warnings at once. +experimental pragma +------------------- + +The ``experimental`` pragma enables experimental language features. Depending +on the concrete feature this means that the feature is either considered +too unstable for an otherwise stable release or that the future of the feature +is uncertain (it may be removed any time). + +Example: + +.. code-block:: nim + {.experimental.} + + proc useUsing(dest: var string) = + using dest + add "foo" + add "bar" + diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt index 8d958733d..e31be7121 100644 --- a/doc/manual/stmts.txt +++ b/doc/manual/stmts.txt @@ -488,7 +488,8 @@ Instead of: Using statement --------------- -**Warning**: The ``using`` statement is highly experimental! +**Warning**: The ``using`` statement is highly experimental and has to be +explicitly enabled with the `experimental`:idx: pragma or command line option! The using statement provides syntactic convenience for procs that heavily use a single contextual parameter. When applied to a variable or a diff --git a/web/news.txt b/web/news.txt index 65f245ae6..76541560c 100644 --- a/web/news.txt +++ b/web/news.txt @@ -29,6 +29,8 @@ News - The "symmetric set difference" operator (``-+-``) never worked and has been removed. - ``defer`` is a keyword now. + - The ``using`` language feature now needs to be activated via the new + ``{.experimental.}`` pragma that enables experimental language features. Language Additions ------------------ @@ -39,6 +41,9 @@ News - ``deepCopy`` has been added to the language. - The builtin ``procCall`` can be used to get ``super``-like functionality for multi methods. + - There is a new pragma ``{.experimental.}`` that enables experimental + language features per module, or you can enable this features on a global + level with the ``--experimental`` command line option. Compiler Additions From 0011bdfb950e0993931c5b440353f642f60bf4a1 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 5 Dec 2014 17:19:00 +0100 Subject: [PATCH 298/409] bugfix: do not use unknown conditional symbols --- lib/windows/windows.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim index 9008d63e3..f0895217b 100644 --- a/lib/windows/windows.nim +++ b/lib/windows/windows.nim @@ -6743,13 +6743,13 @@ const EXCEPTION_READ_FAULT* = 0 # Access violation was caused by a read EXCEPTION_WRITE_FAULT* = 1 # Access violation was caused by a write -when defined(cpuia64): +when hostCPU == "ia64": const EXCEPTION_EXECUTE_FAULT* = 2 # Access violation was caused by an instruction fetch else: const EXCEPTION_EXECUTE_FAULT* = 8 -when defined(cpupowerpc32): +when hostCPU == "powerpc": # ppc const CONTEXT_CONTROL* = 1 @@ -6758,7 +6758,7 @@ when defined(cpupowerpc32): CONTEXT_DEBUG_REGISTERS* = 8 CONTEXT_FULL* = CONTEXT_CONTROL or CONTEXT_FLOATING_POINT or CONTEXT_INTEGER CONTEXT_DEBUGGER* = CONTEXT_FULL -when defined(cpui386): +when hostCPU == "i386": # x86 # The doc refered me to winnt.h, so I had to look... const @@ -6776,7 +6776,7 @@ when defined(cpui386): CONTEXT_DEBUG_REGISTERS or CONTEXT_EXTENDED_REGISTERS # our own invention FLAG_TRACE_BIT* = 0x00000100 CONTEXT_DEBUGGER* = CONTEXT_FULL or CONTEXT_FLOATING_POINT -when defined(cpux86_64): +when hostCPU == "amd64": const INITIAL_MXCSR* = 0x00001F80 # initial MXCSR value INITIAL_FPCSR* = 0x0000027F # initial FPCSR value @@ -7778,7 +7778,7 @@ elif defined(x86_64): LastExceptionToRip*: DWORD64 LastExceptionFromRip*: DWORD64 -elif defined(powerpc32): +elif hostCPU == "powerpc": # ppc # Floating point registers returned when CONTEXT_FLOATING_POINT is set # Integer registers returned when CONTEXT_INTEGER is set. From cd0f17202ee167c0ec0db2bb497d1c4554655abd Mon Sep 17 00:00:00 2001 From: juxiliary Date: Sat, 6 Dec 2014 21:57:20 +1000 Subject: [PATCH 299/409] Fixing extraneous semicolon in jsgen output jsgen was producing javascript objects like this ``` {, name:"foo"} ``` causing syntax errors in javascript interpretors. --- compiler/jsgen.nim | 2 +- tests/js/testobjs.nim | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/js/testobjs.nim diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 108c0fe10..2ae85d5cf 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1431,7 +1431,7 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) = r.res = toRope("{") r.kind = resExpr for i in countup(1, sonsLen(n) - 1): - if i > 0: app(r.res, ", ") + if i > 1: app(r.res, ", ") var it = n.sons[i] internalAssert it.kind == nkExprColonExpr gen(p, it.sons[1], a) diff --git a/tests/js/testobjs.nim b/tests/js/testobjs.nim new file mode 100644 index 000000000..4fb9a83dc --- /dev/null +++ b/tests/js/testobjs.nim @@ -0,0 +1,34 @@ +## Tests javascript object generation + +type + Kg = distinct float + Price = int + Item = object of RootObj + weight: Kg + price: Price + desc: cstring + Person = object of RootObj + name: cstring + age: int + item: Item + Test = object + name: cstring + Recurse[T] = object + data: T + next: ref Recurse[T] + +var + test = Test(name: "Jorden") + sword = Item(desc: "pointy", weight: Kg(10.0), + price: Price(50)) + knight = Person(name: "robert", age: 19, item: sword) + recurse4 = (ref Recurse[int])(data: 4, next: nil) + recurse3 = (ref Recurse[int])(data: 3, next: recurse4) + recurse2 = (ref Recurse[int])(data: 2, next: recurse3) + recurse1 = Recurse[int](data: 1, next: recurse2) + + +assert(test.name == "Jorden") +assert(knight.age == 19) +assert(knight.item.price == 50) +assert(recurse1.next.next.data == 3) From fde869f1b1b9f5f8a7a9fab0420bead31861aace Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 7 Dec 2014 22:07:48 +0100 Subject: [PATCH 300/409] fixes #1712 --- lib/system/sysstr.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index ba973e9b5..440d040a5 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -251,7 +251,7 @@ proc nimIntToStr(x: int): string {.compilerRtl.} = swap(result[j], result[i-j-1]) proc nimFloatToStr(f: float): string {.compilerproc.} = - var buf: array [0..64, char] + var buf: array[0..64, char] var n: int = c_sprintf(buf, "%.16g", f) var hasDot = false for i in 0..n-1: @@ -292,7 +292,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat, var i = start sign = 1.0 - t: array[128, char] + t: array[500, char] # flaviu says: 325 is the longest reasonable literal ti = 0 hasdigits = false From c7664e7025cb63adb29f44bda8a8d41d4f65a967 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Dec 2014 01:09:31 +0100 Subject: [PATCH 301/409] final version before removal --- lib/system/platforms.nim | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 lib/system/platforms.nim diff --git a/lib/system/platforms.nim b/lib/system/platforms.nim new file mode 100644 index 000000000..3ec6a270e --- /dev/null +++ b/lib/system/platforms.nim @@ -0,0 +1,74 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Platform detection for Nim. This module is included by the system module! +## Do not import it directly! + +type + CpuPlatform* {.pure.} = enum ## the CPU this program will run on. + none, ## unknown CPU + i386, ## 32 bit x86 compatible CPU + m68k, ## M68k based processor + alpha, ## Alpha processor + powerpc, ## 32 bit PowerPC + powerpc64, ## 64 bit PowerPC + sparc, ## Sparc based processor + ia64, ## Intel Itanium + amd64, ## x86_64 (AMD64); 64 bit x86 compatible CPU + mips, ## Mips based processor + arm, ## ARM based processor + vm, ## Some Virtual machine: Nim's VM or JavaScript + avr ## AVR based processor + + OsPlatform* {.pure.} = enum ## the OS this program will run on. + none, dos, windows, os2, linux, morphos, skyos, solaris, + irix, netbsd, freebsd, openbsd, aix, palmos, qnx, amiga, + atari, netware, macos, macosx, haiku, js, nimVM, standalone + +const + targetOS* = when defined(windows): OsPlatform.windows + elif defined(dos): OsPlatform.dos + elif defined(os2): OsPlatform.os2 + elif defined(linux): OsPlatform.linux + elif defined(morphos): OsPlatform.morphos + elif defined(skyos): OsPlatform.skyos + elif defined(solaris): OsPlatform.solaris + elif defined(irix): OsPlatform.irix + elif defined(netbsd): OsPlatform.netbsd + elif defined(freebsd): OsPlatform.freebsd + elif defined(openbsd): OsPlatform.openbsd + elif defined(aix): OsPlatform.aix + elif defined(palmos): OsPlatform.palmos + elif defined(qnx): OsPlatform.qnx + elif defined(amiga): OsPlatform.amiga + elif defined(atari): OsPlatform.atari + elif defined(netware): OsPlatform.netware + elif defined(macosx): OsPlatform.macosx + elif defined(macos): OsPlatform.macos + elif defined(haiku): OsPlatform.haiku + elif defined(js): OsPlatform.js + elif defined(nimrodVM): OsPlatform.nimVM + elif defined(standalone): OsPlatform.standalone + else: OsPlatform.none + ## the OS this program will run on. + + targetCPU* = when defined(i386): CpuPlatform.i386 + elif defined(m68k): CpuPlatform.m68k + elif defined(alpha): CpuPlatform.alpha + elif defined(powerpc): CpuPlatform.powerpc + elif defined(powerpc64): CpuPlatform.powerpc64 + elif defined(sparc): CpuPlatform.sparc + elif defined(ia64): CpuPlatform.ia64 + elif defined(amd64): CpuPlatform.amd64 + elif defined(mips): CpuPlatform.mips + elif defined(arm): CpuPlatform.arm + elif defined(vm): CpuPlatform.vm + elif defined(avr): CpuPlatform.avr + else: CpuPlatform.none + ## the CPU this program will run on. From 08fcc87986c85ea86a0e3183b5b9027c8a117097 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Dec 2014 08:42:18 +0100 Subject: [PATCH 302/409] deprecated old locking effects --- lib/core/locks.nim | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/core/locks.nim b/lib/core/locks.nim index 4e85474fb..766b7b536 100644 --- a/lib/core/locks.nim +++ b/lib/core/locks.nim @@ -16,12 +16,15 @@ type ## or not is unspecified! TCond* = TSysCond ## Nim condition variable - LockEffect* = object of RootEffect ## effect that denotes that some lock operation - ## is performed - AquireEffect* = object of LockEffect ## effect that denotes that some lock is - ## aquired - ReleaseEffect* = object of LockEffect ## effect that denotes that some lock is - ## released + LockEffect* {.deprecated.} = object of RootEffect ## \ + ## effect that denotes that some lock operation + ## is performed. Deprecated, do not use anymore! + AquireEffect* {.deprecated.} = object of LockEffect ## \ + ## effect that denotes that some lock is + ## aquired. Deprecated, do not use anymore! + ReleaseEffect* {.deprecated.} = object of LockEffect ## \ + ## effect that denotes that some lock is + ## released. Deprecated, do not use anymore! {.deprecated: [FLock: LockEffect, FAquireLock: AquireEffect, FReleaseLock: ReleaseEffect].} @@ -33,15 +36,15 @@ proc deinitLock*(lock: var TLock) {.inline.} = ## Frees the resources associated with the lock. deinitSys(lock) -proc tryAcquire*(lock: var TLock): bool {.tags: [AquireEffect].} = +proc tryAcquire*(lock: var TLock): bool = ## Tries to acquire the given lock. Returns `true` on success. result = tryAcquireSys(lock) -proc acquire*(lock: var TLock) {.tags: [AquireEffect].} = +proc acquire*(lock: var TLock) = ## Acquires the given lock. acquireSys(lock) -proc release*(lock: var TLock) {.tags: [ReleaseEffect].} = +proc release*(lock: var TLock) = ## Releases the given lock. releaseSys(lock) From 02f085b4790ecba311003b67caf83ab6f4875c9f Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Dec 2014 08:42:59 +0100 Subject: [PATCH 303/409] minor documentation improvements --- lib/core/typeinfo.nim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim index 84281485f..f3f00f9f5 100644 --- a/lib/core/typeinfo.nim +++ b/lib/core/typeinfo.nim @@ -7,9 +7,12 @@ # distribution, for details about the copyright. # -## This module implements an interface to Nimrod's runtime type information. +## This module implements an interface to Nim's runtime type information. ## Note that even though ``TAny`` and its operations hide the nasty low level ## details from its clients, it remains inherently unsafe! +## +## See the `marshal `_ module for what this module allows you +## to do. {.push hints: off.} @@ -51,7 +54,7 @@ type akUInt32 = 43, ## any represents an unsigned int32 akUInt64 = 44, ## any represents an unsigned int64 - TAny* = object {.pure.} ## can represent any nim value; NOTE: the wrapped + TAny* = object ## can represent any nim value; NOTE: the wrapped ## value can be modified with its wrapper! This means ## that ``TAny`` keeps a non-traced pointer to its ## wrapped value and **must not** live longer than @@ -62,7 +65,7 @@ type ppointer = ptr pointer pbyteArray = ptr array[0.. 0xffff, int8] - TGenSeq {.pure.} = object + TGenSeq = object len, space: int PGenSeq = ptr TGenSeq From 7b480ea2baa55c419ca233ff37f94e1369856817 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Dec 2014 08:43:56 +0100 Subject: [PATCH 304/409] got rid of old code that used to be required for bootstrapping --- lib/pure/parseutils.nim | 95 +++-------------------------------------- 1 file changed, 5 insertions(+), 90 deletions(-) diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index 8f8ca6ab3..1efb141fc 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -231,96 +231,11 @@ proc parseInt*(s: string, number: var int, start = 0): int {. else: number = int(res) -when defined(nimParseBiggestFloatMagic): - proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {. - magic: "ParseBiggestFloat", importc: "nimParseBiggestFloat", noSideEffect.} - ## parses a float starting at `start` and stores the value into `number`. - ## Result is the number of processed chars or 0 if a parsing error - ## occurred. -else: - proc tenToThePowerOf(b: int): BiggestFloat = - var b = b - var a = 10.0 - result = 1.0 - while true: - if (b and 1) == 1: - result *= a - b = b shr 1 - if b == 0: break - a *= a - - proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {. - rtl, extern: "npuParseBiggestFloat", noSideEffect.} = - ## parses a float starting at `start` and stores the value into `number`. - ## Result is the number of processed chars or 0 if there occured a parsing - ## error. - var - esign = 1.0 - sign = 1.0 - i = start - exponent: int - flags: int - number = 0.0 - if s[i] == '+': inc(i) - elif s[i] == '-': - sign = -1.0 - inc(i) - if s[i] == 'N' or s[i] == 'n': - if s[i+1] == 'A' or s[i+1] == 'a': - if s[i+2] == 'N' or s[i+2] == 'n': - if s[i+3] notin IdentChars: - number = NaN - return i+3 - start - return 0 - if s[i] == 'I' or s[i] == 'i': - if s[i+1] == 'N' or s[i+1] == 'n': - if s[i+2] == 'F' or s[i+2] == 'f': - if s[i+3] notin IdentChars: - number = Inf*sign - return i+3 - start - return 0 - while s[i] in {'0'..'9'}: - # Read integer part - flags = flags or 1 - number = number * 10.0 + toFloat(ord(s[i]) - ord('0')) - inc(i) - while s[i] == '_': inc(i) - # Decimal? - if s[i] == '.': - var hd = 1.0 - inc(i) - while s[i] in {'0'..'9'}: - # Read fractional part - flags = flags or 2 - number = number * 10.0 + toFloat(ord(s[i]) - ord('0')) - hd = hd * 10.0 - inc(i) - while s[i] == '_': inc(i) - number = number / hd # this complicated way preserves precision - # Again, read integer and fractional part - if flags == 0: return 0 - # Exponent? - if s[i] in {'e', 'E'}: - inc(i) - if s[i] == '+': - inc(i) - elif s[i] == '-': - esign = -1.0 - inc(i) - if s[i] notin {'0'..'9'}: - return 0 - while s[i] in {'0'..'9'}: - exponent = exponent * 10 + ord(s[i]) - ord('0') - inc(i) - while s[i] == '_': inc(i) - # Calculate Exponent - let hd = tenToThePowerOf(exponent) - if esign > 0.0: number = number * hd - else: number = number / hd - # evaluate sign - number = number * sign - result = i - start - +proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {. + magic: "ParseBiggestFloat", importc: "nimParseBiggestFloat", noSideEffect.} + ## parses a float starting at `start` and stores the value into `number`. + ## Result is the number of processed chars or 0 if a parsing error + ## occurred. proc parseFloat*(s: string, number: var float, start = 0): int {. rtl, extern: "npuParseFloat", noSideEffect.} = From 2804c0373ceabda0253806410871503999cdb8f7 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Dec 2014 08:56:04 +0100 Subject: [PATCH 305/409] compiler\parser.nim implemented arrow like operators --- doc/grammar.txt | 23 ++++++++++---------- doc/manual/syntax.txt | 50 +++++++++++++++++++++---------------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/doc/grammar.txt b/doc/grammar.txt index bce3769d0..e751c2d8d 100644 --- a/doc/grammar.txt +++ b/doc/grammar.txt @@ -4,7 +4,7 @@ semicolon = ';' COMMENT? colon = ':' COMMENT? colcom = ':' COMMENT? -operator = OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9 +operator = OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9 | OP10 | 'or' | 'xor' | 'and' | 'is' | 'isnot' | 'in' | 'notin' | 'of' | 'div' | 'mod' | 'shl' | 'shr' | 'not' | 'addr' | 'static' | '..' @@ -14,16 +14,17 @@ prefixOperator = operator optInd = COMMENT? optPar = (IND{>} | IND{=})? -simpleExpr = assignExpr (OP0 optInd assignExpr)* -assignExpr = orExpr (OP1 optInd orExpr)* -orExpr = andExpr (OP2 optInd andExpr)* -andExpr = cmpExpr (OP3 optInd cmpExpr)* -cmpExpr = sliceExpr (OP4 optInd sliceExpr)* -sliceExpr = ampExpr (OP5 optInd ampExpr)* -ampExpr = plusExpr (OP6 optInd plusExpr)* -plusExpr = mulExpr (OP7 optInd mulExpr)* -mulExpr = dollarExpr (OP8 optInd dollarExpr)* -dollarExpr = primary (OP9 optInd primary)* +simpleExpr = arrowExpr (OP0 optInd arrowExpr)* +arrowExpr = assignExpr (OP1 optInd assignExpr)* +assignExpr = orExpr (OP2 optInd orExpr)* +orExpr = andExpr (OP3 optInd andExpr)* +andExpr = cmpExpr (OP4 optInd cmpExpr)* +cmpExpr = sliceExpr (OP5 optInd sliceExpr)* +sliceExpr = ampExpr (OP6 optInd ampExpr)* +ampExpr = plusExpr (OP7 optInd plusExpr)* +plusExpr = mulExpr (OP8 optInd mulExpr)* +mulExpr = dollarExpr (OP9 optInd dollarExpr)* +dollarExpr = primary (OP10 optInd primary)* symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`' | IDENT indexExpr = expr diff --git a/doc/manual/syntax.txt b/doc/manual/syntax.txt index 0ae353edd..c975e7f48 100644 --- a/doc/manual/syntax.txt +++ b/doc/manual/syntax.txt @@ -5,24 +5,21 @@ This section lists Nim's standard syntax. How the parser handles the indentation is already described in the `Lexical Analysis`_ section. Nim allows user-definable operators. -Binary operators have 10 different levels of precedence. +Binary operators have 11 different levels of precedence. -Relevant character ------------------- - -An operator symbol's *relevant character* is its first -character unless the first character is ``\`` and its length is greater than 1 -then it is the second character. - -This rule allows to escape operator symbols with ``\`` and keeps the operator's -precedence and associativity; this is useful for meta programming. Associativity ------------- -Binary operators whose relevant character is ``^`` are right-associative, all -other binary operators are left-associative. +Binary operators whose first character is ``^`` or its last character +is ``>`` are right-associative, all other binary operators are left-associative. + +Exception: The single "greater than" ``>`` operator is left-associative too. + +Operators ending in ``>`` but longer than a single character are +called `arrow like`:idx:. + Precedence ---------- @@ -30,7 +27,7 @@ Precedence Unary operators always bind stronger than any binary operator: ``$a + b`` is ``($a) + b`` and not ``$(a + b)``. -If an unary operator's relevant character is ``@`` it is a `sigil-like`:idx: +If an unary operator's first character is ``@`` it is a `sigil-like`:idx: operator which binds stronger than a ``primarySuffix``: ``@x.abc`` is parsed as ``(@x).abc`` whereas ``$x.abc`` is parsed as ``$(x.abc)``. @@ -38,25 +35,26 @@ as ``(@x).abc`` whereas ``$x.abc`` is parsed as ``$(x.abc)``. For binary operators that are not keywords the precedence is determined by the following rules: -If the operator ends with ``=`` and its relevant character is none of +If the operator ends with ``=`` and its first character is none of ``<``, ``>``, ``!``, ``=``, ``~``, ``?``, it is an *assignment operator* which has the lowest precedence. -Otherwise precedence is determined by the relevant character. +Otherwise precedence is determined by the first character. ================ =============================================== ================== =============== -Precedence level Operators Relevant character Terminal symbol +Precedence level Operators First character Terminal symbol ================ =============================================== ================== =============== - 9 (highest) ``$ ^`` OP9 - 8 ``* / div mod shl shr %`` ``* % \ /`` OP8 - 7 ``+ -`` ``+ ~ |`` OP7 - 6 ``&`` ``&`` OP6 - 5 ``..`` ``.`` OP5 - 4 ``== <= < >= > != in notin is isnot not of`` ``= < > !`` OP4 - 3 ``and`` OP3 - 2 ``or xor`` OP2 - 1 ``@ : ?`` OP1 - 0 (lowest) *assignment operator* (like ``+=``, ``*=``) OP0 + 10 (highest) ``$ ^`` OP10 + 9 ``* / div mod shl shr %`` ``* % \ /`` OP9 + 8 ``+ -`` ``+ ~ |`` OP8 + 7 ``&`` ``&`` OP7 + 6 ``..`` ``.`` OP6 + 5 ``== <= < >= > != in notin is isnot not of`` ``= < > !`` OP5 + 4 ``and`` OP4 + 3 ``or xor`` OP3 + 2 ``@ : ?`` OP2 + 1 *assignment operator* (like ``+=``, ``*=``) OP1 + 0 (lowest) *arrow like operator* (like ``->``, ``=>``) OP0 ================ =============================================== ================== =============== From cd03f594329bc9906da868c28bdf1f49ceee146f Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Dec 2014 08:56:44 +0100 Subject: [PATCH 306/409] implemented arrow like operators --- compiler/parser.nim | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/compiler/parser.nim b/compiler/parser.nim index b5a9559d9..a91760e15 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -188,18 +188,13 @@ proc parseTypeDesc(p: var TParser): PNode proc parseDoBlocks(p: var TParser, call: PNode) proc parseParamList(p: var TParser, retColon = true): PNode -proc relevantOprChar(ident: PIdent): char {.inline.} = - result = ident.s[0] - var L = ident.s.len - if result == '\\' and L > 1: - result = ident.s[1] - proc isSigilLike(tok: TToken): bool {.inline.} = - result = tok.tokType == tkOpr and relevantOprChar(tok.ident) == '@' + result = tok.tokType == tkOpr and tok.ident.s[0] == '@' -proc isLeftAssociative(tok: TToken): bool {.inline.} = - ## Determines whether the token is left assocative. - result = tok.tokType != tkOpr or relevantOprChar(tok.ident) != '^' +proc isRightAssociative(tok: TToken): bool {.inline.} = + ## Determines whether the token is right assocative. + result = tok.tokType == tkOpr and (tok.ident.s[0] == '^' or + (let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>')) proc getPrecedence(tok: TToken, strongSpaces: bool): int = ## Calculates the precedence of the given token. @@ -209,7 +204,10 @@ proc getPrecedence(tok: TToken, strongSpaces: bool): int = case tok.tokType of tkOpr: let L = tok.ident.s.len - let relevantChar = relevantOprChar(tok.ident) + let relevantChar = tok.ident.s[0] + + # arrow like? + if L > 1 and tok.ident.s[L-1] == '>': return considerStrongSpaces(1) template considerAsgn(value: expr) = result = if tok.ident.s[L-1] == '=': 1 else: considerStrongSpaces(value) @@ -269,17 +267,18 @@ proc checkBinary(p: TParser) {.inline.} = #| #| optInd = COMMENT? #| optPar = (IND{>} | IND{=})? -#| -#| simpleExpr = assignExpr (OP0 optInd assignExpr)* -#| assignExpr = orExpr (OP1 optInd orExpr)* -#| orExpr = andExpr (OP2 optInd andExpr)* -#| andExpr = cmpExpr (OP3 optInd cmpExpr)* -#| cmpExpr = sliceExpr (OP4 optInd sliceExpr)* -#| sliceExpr = ampExpr (OP5 optInd ampExpr)* -#| ampExpr = plusExpr (OP6 optInd plusExpr)* -#| plusExpr = mulExpr (OP7 optInd mulExpr)* -#| mulExpr = dollarExpr (OP8 optInd dollarExpr)* -#| dollarExpr = primary (OP9 optInd primary)* +#| +#| simpleExpr = arrowExpr (OP0 optInd arrowExpr)* +#| arrowExpr = assignExpr (OP1 optInd assignExpr)* +#| assignExpr = orExpr (OP2 optInd orExpr)* +#| orExpr = andExpr (OP3 optInd andExpr)* +#| andExpr = cmpExpr (OP4 optInd cmpExpr)* +#| cmpExpr = sliceExpr (OP5 optInd sliceExpr)* +#| sliceExpr = ampExpr (OP6 optInd ampExpr)* +#| ampExpr = plusExpr (OP7 optInd plusExpr)* +#| plusExpr = mulExpr (OP8 optInd mulExpr)* +#| mulExpr = dollarExpr (OP9 optInd dollarExpr)* +#| dollarExpr = primary (OP10 optInd primary)* proc colcom(p: var TParser, n: PNode) = eat(p, tkColon) @@ -734,7 +733,7 @@ proc parseOperators(p: var TParser, headNode: PNode, # the operator itself must not start on a new line: while opPrec >= limit and p.tok.indent < 0 and not isUnary(p): checkBinary(p) - var leftAssoc = ord(isLeftAssociative(p.tok)) + var leftAssoc = 1-ord(isRightAssociative(p.tok)) var a = newNodeP(nkInfix, p) var opNode = newIdentNodeP(p.tok.ident, p) # skip operator: getTok(p) From 994f7c1f0bebe468e5a9d44a52cadf806348f876 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Dec 2014 19:49:20 +0100 Subject: [PATCH 307/409] changed formating --- lib/impure/db_mysql.nim | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 37bea45b4..968a2923a 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -220,13 +220,12 @@ proc open*(connection, user, password, database: string): TDbConn {. if result == nil: dbError("could not open database connection") let colonPos = connection.find(':') - host = if colonPos < 0: connection - else: substr(connection, 0, colonPos-1) + host = if colonPos < 0: connection + else: substr(connection, 0, colonPos-1) port: int32 = if colonPos < 0: 0'i32 - else: substr(connection, colonPos+1).parseInt.int32 + else: substr(connection, colonPos+1).parseInt.int32 if mysql.realConnect(result, host, user, password, database, port, nil, 0) == nil: var errmsg = $mysql.error(result) db_mysql.close(result) dbError(errmsg) - From 0151d1171636f84999d0ac6cde314e4d7084b3a3 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 8 Dec 2014 22:25:17 +0100 Subject: [PATCH 308/409] fixes #1699 --- lib/system.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 269dbb1e0..0cd4b84e2 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1020,16 +1020,16 @@ const ## is the endianness of the target CPU. This is a valuable piece of ## information for low-level code only. This works thanks to compiler ## magic. - - hostOS* {.magic: "HostOS"}: string = "" + + hostOS* {.magic: "HostOS".}: string = "" ## a string that describes the host operating system. Possible values: ## "windows", "macosx", "linux", "netbsd", "freebsd", "openbsd", "solaris", ## "aix", "standalone". - - hostCPU* {.magic: "HostCPU"}: string = "" + + hostCPU* {.magic: "HostCPU".}: string = "" ## a string that describes the host CPU. Possible values: - ## "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm". - + ## "i386", "alpha", "powerpc", "powerpc64", "sparc", "amd64", "mips", "arm". + seqShallowFlag = low(int) proc compileOption*(option: string): bool {. @@ -2120,7 +2120,7 @@ elif hostOS != "standalone": inc(i) {.pop.} -proc echo*(x: varargs[string, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.} +proc echo*(x: varargs[expr, `$`]) {.magic: "Echo", tags: [WriteIOEffect], benign.} ## Writes and flushes the parameters to the standard output. ## ## Special built-in that takes a variable number of arguments. Each argument @@ -2135,7 +2135,7 @@ proc echo*(x: varargs[string, `$`]) {.magic: "Echo", tags: [WriteIOEffect], beni ## `_ you can use `debugEcho <#debugEcho>`_ ## instead. -proc debugEcho*(x: varargs[string, `$`]) {.magic: "Echo", noSideEffect, +proc debugEcho*(x: varargs[expr, `$`]) {.magic: "Echo", noSideEffect, tags: [], raises: [].} ## Same as `echo <#echo>`_, but as a special semantic rule, ``debugEcho`` ## pretends to be free of side effects, so that it can be used for debugging From 795a7762ccf387140a6fa6d2a8964cb0654a3732 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 9 Dec 2014 01:03:56 +0100 Subject: [PATCH 309/409] minor improvement to the barrier implementation --- compiler/platform.nim | 2 +- lib/pure/concurrency/threadpool.nim | 4 +++- todo.txt | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/platform.nim b/compiler/platform.nim index 2e78d4fc5..c6cb3d244 100644 --- a/compiler/platform.nim +++ b/compiler/platform.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 28ef25d95..0bd97043a 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -65,7 +65,9 @@ proc barrierEnter(b: ptr Barrier) {.compilerProc, inline.} = proc barrierLeave(b: ptr Barrier) {.compilerProc, inline.} = atomicInc b.left when not defined(x86): fence() - if b.interest and b.left == b.entered: signal(b.cv) + # We may not have seen the final value of b.entered yet, + # so we need to check for >= instead of ==. + if b.interest and b.left >= b.entered: signal(b.cv) proc openBarrier(b: ptr Barrier) {.compilerProc, inline.} = b.entered = 0 diff --git a/todo.txt b/todo.txt index 6068c049b..5b0d00e16 100644 --- a/todo.txt +++ b/todo.txt @@ -3,7 +3,10 @@ version 0.10 Repetition renders the ridiculous reasonable. -- introduce ``--experimental`` switch +- document 'converter' +- document the tables module better + + - c2nim depends on the compiler - make nimble part of the distribution - split idetools into separate tool From 74fdd5c2eaa5507b636c70db80df7f9c3f332d2b Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Dec 2014 00:40:48 +0100 Subject: [PATCH 310/409] new website --- todo.txt | 2 - tools/nimweb.nim | 14 +- tools/website.tmpl | 213 ++++-- web/assets/images/bg.jpg | Bin 0 -> 94894 bytes web/assets/images/foot.png | Bin 0 -> 784 bytes web/assets/images/glow-arrow.png | Bin 0 -> 8657 bytes web/assets/images/glow-line.png | Bin 0 -> 2261 bytes web/assets/images/head-link.png | Bin 0 -> 203 bytes web/assets/images/head-link_hover.png | Bin 0 -> 799 bytes web/assets/images/head.png | Bin 0 -> 171 bytes web/assets/images/logo.png | Bin 101053 -> 116562 bytes web/assets/images/mascot.png | Bin 0 -> 18022 bytes web/assets/images/more-links_editors.png | Bin 0 -> 852 bytes web/assets/images/more-links_forum.png | Bin 0 -> 858 bytes web/assets/images/more-links_github.png | Bin 0 -> 713 bytes web/assets/images/more-links_nimbuild.png | Bin 0 -> 724 bytes web/assets/images/quotes.png | Bin 0 -> 979 bytes web/assets/images/sidebar.png | Bin 971 -> 109579 bytes web/assets/images/slideshow-nav.png | Bin 0 -> 416 bytes web/assets/images/slideshow-nav_active.png | Bin 0 -> 673 bytes web/assets/images/tabEnd.png | Bin 0 -> 194 bytes web/assets/style.css | 768 +++++++++++++++------ web/community.txt | 161 +++-- web/documentation.txt | 52 +- web/index.txt | 16 - web/learn.txt | 44 ++ web/news.txt | 16 +- web/nim.ini | 6 +- web/question.txt | 206 +++--- web/ticker.txt | 51 +- 30 files changed, 1055 insertions(+), 494 deletions(-) create mode 100644 web/assets/images/bg.jpg create mode 100644 web/assets/images/foot.png create mode 100644 web/assets/images/glow-arrow.png create mode 100644 web/assets/images/glow-line.png create mode 100644 web/assets/images/head-link.png create mode 100644 web/assets/images/head-link_hover.png create mode 100644 web/assets/images/head.png create mode 100644 web/assets/images/mascot.png create mode 100644 web/assets/images/more-links_editors.png create mode 100644 web/assets/images/more-links_forum.png create mode 100644 web/assets/images/more-links_github.png create mode 100644 web/assets/images/more-links_nimbuild.png create mode 100644 web/assets/images/quotes.png create mode 100644 web/assets/images/slideshow-nav.png create mode 100644 web/assets/images/slideshow-nav_active.png create mode 100644 web/assets/images/tabEnd.png create mode 100644 web/learn.txt diff --git a/todo.txt b/todo.txt index 5b0d00e16..d301acdc3 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,6 @@ version 0.10 ============ - Repetition renders the ridiculous reasonable. - - document 'converter' - document the tables module better diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 46c1d0d85..6fc946552 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -418,14 +418,14 @@ proc main(c: var TConfigData) = quit("[Error] cannot write file: " & outfile) removeFile(temp) copyDir("web/assets", "web/upload/assets") - buildJS("web/upload") + #buildJS("web/upload") buildNewsRss(c, "web/upload") - buildAddDoc(c, "web/upload") - buildDocSamples(c, "web/upload") - buildDoc(c, "web/upload") - buildDocSamples(c, "doc") - buildDoc(c, "doc") - buildPdfDoc(c, "doc") + #buildAddDoc(c, "web/upload") + #buildDocSamples(c, "web/upload") + #buildDoc(c, "web/upload") + #buildDocSamples(c, "doc") + #buildDoc(c, "doc") + #buildPdfDoc(c, "doc") var c: TConfigData initConfigData(c) diff --git a/tools/website.tmpl b/tools/website.tmpl index f3cacdb64..b4dd2631c 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -1,27 +1,24 @@ #! stdtmpl | standard #proc generateHTMLPage(c: var TConfigData, currentTab, content, rss: string): string = # result = "" - + + + + $c.projectTitle + - - $c.projectTitle - - + #if len(rss) > 0: - - #end fi - - - -
- - - - -
+ + #end if + + +
+ - -
+# if currentTab == "index": +
+# else: +
+# end +
+
- - - -
- #if c.quotations.hasKey(currentTab): -
-

- ${c.quotations[currentTab].quote} -
- -- ${c.quotations[currentTab].author} -

-
- #end if - - $content -
-
- - -
+

Latest News

+ + +
+ + +
+
+
+
+
+ $content +
+
+
+ + + + diff --git a/web/assets/images/bg.jpg b/web/assets/images/bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4e33a79ce15aadf50fc685d7b0f6e827821d2925 GIT binary patch literal 94894 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 IKlbGR0F%nD#{d8T literal 0 HcmV?d00001 diff --git a/web/assets/images/foot.png b/web/assets/images/foot.png new file mode 100644 index 0000000000000000000000000000000000000000..dc2561cf35c79f04e1b22ca98a9db897b42d4c36 GIT binary patch literal 784 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 a)U0iX&8^H=;tz)}0E%)dvenYCkpBZy4QF%! literal 0 HcmV?d00001 diff --git a/web/assets/images/glow-line.png b/web/assets/images/glow-line.png new file mode 100644 index 0000000000000000000000000000000000000000..6607bdee90e9b89858ca7cd0c243c7830c71a4e1 GIT binary patch literal 2261 zcmV;`2rBo9P)OxV zSEvt@yMEgdTR&fmL*{|j_OwjT1QR%fus<>fJ^lEl7DitZ4n}qExaEA6PBmpdTZ>3J zKNT~>y@rxN&O{gM0T@bXLdy$^(Goc&d4YppvK9pDIy0L#?UM&xv+ zx#N?Gevk4pJlJ{5foXe=SzWDsvCpd4Ze;y)V9&3YYL-1uh*9s z@35-p@B+fYM_cT_A?)_HPdD*TiK9<8>W1O#HTnqr z4%58)x)e?k~Pd#aPWFGF|qxh8+S7xL>vxO0c} z^V3l7j+7^-;Q%P(o61LLDveZjUWR%px=T7ejE?6TO{LsSG(H)MTeoWQ>70I}L7L_$HNs+;NL5-Weu+bxKKP;WngQxPG8=W{L!ri&op z87)FA1!BZqp3&6X2F)%M0hg}Y?f;Im*MeM9uN$D0`tIJLc}Dh4e#Q@xHh1&)suKG7 ztl8(1ibM5C5Txbx*ad{}e5t~gOBbrLsvki@AiK(Uh}qI?tRg}K?jz%#DOb7WK5T@{ z%)U$MZK?O0US9p83)q@(ge@8wEp1JiF95{`>bj6+W1+CvKZVMlc~h(vTg&{J)tu`z zv4xU=KnT5@!7RT3
- - - - - + When asking a question relating to Nim, be sure to use the + `Nim `_ tag in your + question. -Bitcoin -``````` +.. container:: standout - Bitcoin address: 1BXfuKM2uvoD6mbx4g5xM3eQhLzkCK77tJ + How to help + ----------- + + There are always many things to be done in the main + `Nim repository `_, check out the + `issues `_ for + things to do; pull requests are always welcome. You can + also contribute to the many other projects hosted by the + `nim-lang `_ organisation on github. If you + can't find anything you fancy doing, you can always ask for inspiration on IRC + (irc.freenode.net #nim) or on the `Nim forums `_. + + +.. container:: standout + + Donations + --------- + + If you love what we do and are feeling generous then you can always donate. + Contributions of any quantity are greatly appreciated and will contribute to + making Nim even better! + + Gittip + .. raw:: html + + + + Paypal + .. raw:: html + +
+ + + + +
+ + Bitcoin + Bitcoin address: 1BXfuKM2uvoD6mbx4g5xM3eQhLzkCK77tJ diff --git a/web/documentation.txt b/web/documentation.txt index da0313c32..0bb2b8a0f 100644 --- a/web/documentation.txt +++ b/web/documentation.txt @@ -1 +1,51 @@ -.. include:: ../doc/docs.txt +Nim's Documentation +=================== + +.. container:: standout + + Standards & Guides + ------------------ + + + - | `Standard Library `_ + | This document describes Nim's standard library. + + - | `Language Manual `_ + | The Nim manual is a draft that will evolve into a proper specification. + + - | `Compiler user guide `_ + | The user guide lists command line arguments, special features of the + compiler, etc. + + +.. container:: standout + + Tools & Features + ---------------- + + - | `Source code filters `_ + | The Nim compiler supports source code filters as a simple yet powerful + builtin templating system. + + - | `Tools documentation `_ + | Description of some tools that come with the standard distribution. + + +.. container:: standout + + Internal Details + ---------------- + + - | `Garbage Collector `_ + | Additional documentation about Nim's GC and how to operate it in a + | realtime setting. + + - | `Internal documentation `_ + | The internal documentation describes how the compiler is implemented. Read + this if you want to hack the compiler. + + +Search Options +-------------- + +`Documentation Index `_ - The generated index. **Index + (Ctrl+F) == Joy** diff --git a/web/index.txt b/web/index.txt index e48c54f17..3317ba940 100644 --- a/web/index.txt +++ b/web/index.txt @@ -18,22 +18,6 @@ shared memory heap is also provided for the increased efficiency that results from that model. -Nim looks like this: -==================== - -.. code-block:: nim - # compute average line length - var count = 0 - var sum = 0 - - for line in stdin.lines: - count += 1 - sum += line.len - - echo "Average line length: ", - if count > 0: sum / count else: 0 - - Nim is efficient ================ diff --git a/web/learn.txt b/web/learn.txt new file mode 100644 index 000000000..1b0984cda --- /dev/null +++ b/web/learn.txt @@ -0,0 +1,44 @@ +Nim's Learning Resources +======================== + +.. container:: standout + + Tutorials + --------- + + - | `Tutorial (part I) `_ + | Learn the basics of Nim's types, variables, procedures, control flow, etc... + + - | `Tutorial (part II) `_ + | Learn Nim's more advanced features such as OOP, generics, macros, etc... + + +.. container:: standout + + Examples + -------- + + - | `Nim by Example `_ + | Nim by Example is an excellent starting place for beginners. + + - | `Nim on Rosetta Code `_ + | Many different Nim code examples comparible to other langues for reference. + + - | `Nim for C/C++ Programmers `_ + | A useful cheat-sheet for those most familiar with C/C++ languages. + + +.. container:: standout + + Articles + -------- + + - `Dr Dobbs Nimrod Publication `_ + - `Bootstrapping Nim `_ + + +Documentation +------------- + +More examples of Nim code can be found in the `Nim Language Documenation `_. + diff --git a/web/news.txt b/web/news.txt index 76541560c..d345526c4 100644 --- a/web/news.txt +++ b/web/news.txt @@ -78,8 +78,20 @@ News exceptions (overflow, division by zero, etc.). -2014-10-19 Nimrod version 0.9.6 released -======================================== +2014-12-09 New website design! +============================== + +A brand new website including an improved forum is now live. +All thanks go to Philip Witte and +Dominik Picheta, Philip Witte for the design of the website (together with +the logo) as well as the HTML and CSS code for his template, and Dominik Picheta +for integrating Philip's design with Nim's forum. We're sure you will +agree that Philip's design is beautiful. + + + +2014-10-19 Version 0.9.6 released +================================= **Note: 0.9.6 is the last release of Nimrod. The language is being renamed to Nim. Nim slightly breaks compatibility.** diff --git a/web/nim.ini b/web/nim.ini index 6624910d1..83705e8ce 100644 --- a/web/nim.ini +++ b/web/nim.ini @@ -9,13 +9,15 @@ Authors: "Andreas Rumpf and contributors" # Everything after ; is the ID User_Forum: "http://forum.nim-lang.org;link_forum" Aporia_IDE: "https://github.com/nimrod-code/Aporia;link_aporia" -Nimbuild: "http://build.nim-lang.org;link_nimbuild" +Github_Repo: "http://github.com/Araq/Nimrod;link_github" + [Tabs] # Menu entry: filename home: index news: news docs: documentation +learn: learn download: download community: community FAQ: question @@ -34,7 +36,7 @@ documentation: """Incorrect documentation is often worse than no documentation. - Bertrand Meyer""" download: """There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson.""" - +learn: """Repetition renders the ridiculous reasonable. - Norman Wildberger""" [Documentation] doc: "endb;intern;apis;lib;manual.txt;tut1;tut2;nimc;overview;filters" diff --git a/web/question.txt b/web/question.txt index 52809ff90..23d3b9b67 100644 --- a/web/question.txt +++ b/web/question.txt @@ -6,136 +6,160 @@ General ======= -What is Nim? ------------- +.. container:: standout -Nim (formerly known as "Nimrod") is a statically typed, imperative programming -language that tries to give the programmer ultimate power without compromises -on runtime efficiency. -This means it focuses on compile-time mechanisms in all their -various forms. Beneath a nice infix/indentation based syntax with a -powerful (AST based, hygienic) macro system lies a semantic model that supports -a soft realtime GC on thread local heaps. Asynchronous message passing is used -between threads, so no "stop the world" mechanism is necessary. An unsafe -shared memory heap is also provided for the increased efficiency that results -from that model. + What is Nim? + ------------ + + Nim (formerly known as "Nimrod") is a statically typed, imperative programming + language that tries to give the programmer ultimate power without compromises + on runtime efficiency. + This means it focuses on compile-time mechanisms in all their + various forms. Beneath a nice infix/indentation based syntax with a + powerful (AST based, hygienic) macro system lies a semantic model that supports + a soft realtime GC on thread local heaps. Asynchronous message passing is used + between threads, so no "stop the world" mechanism is necessary. An unsafe + shared memory heap is also provided for the increased efficiency that results + from that model. -Why yet another programming language? -------------------------------------- +.. container:: standout -Nim is one of the very few *programmable* statically typed languages, and -one of the even fewer that produces native binaries that require no -runtime or interpreter. + Why yet another programming language? + ------------------------------------- + + Nim is one of the very few *programmable* statically typed languages, and + one of the even fewer that produces native binaries that require no + runtime or interpreter. -What have been the major influences in the language's design? -------------------------------------------------------------- +.. container:: standout -The language borrows heavily from (in order of impact): Modula 3, Delphi, Ada, -C++, Python, Lisp, Oberon. + What have been the major influences in the language's design? + ------------------------------------------------------------- + + The language borrows heavily from (in order of impact): Modula 3, Delphi, Ada, + C++, Python, Lisp, Oberon. +.. container:: standout -What is Nim's take on concurrency? ----------------------------------- + What is Nim's take on concurrency? + ---------------------------------- -Nim primarily focusses on thread local (and garbage collected) heaps and -message passing between threads. Each thread has its own GC, so no -"stop the world" mechanism is necessary. An unsafe shared memory heap is also -provided. + Nim primarily focusses on thread local (and garbage collected) heaps and + message passing between threads. Each thread has its own GC, so no + "stop the world" mechanism is necessary. An unsafe shared memory heap is also + provided. -Future versions will additionally include a GC "per thread group" -and Nim's type system will be enhanced to accurately model this shared -memory heap. + Future versions will additionally include a GC "per thread group" + and Nim's type system will be enhanced to accurately model this shared + memory heap. -How is Nim licensed? --------------------- +.. container:: standout -The Nim compiler and the library are MIT licensed. -This means that you can use any license for your own programs developed with -Nim. + How is Nim licensed? + -------------------- + + The Nim compiler and the library are MIT licensed. + This means that you can use any license for your own programs developed with + Nim. -How stable is Nim? ------------------- +.. container:: standout -The compiler is in development and some important features are still missing. -However, the compiler is quite stable already: It is able to compile itself -and a substantial body of other code. Until version 1.0.0 is released, -minor incompatibilities with older versions of the compiler will be introduced. + How stable is Nim? + ------------------ + + The compiler is in development and some important features are still missing. + However, the compiler is quite stable already: It is able to compile itself + and a substantial body of other code. Until version 1.0.0 is released, + minor incompatibilities with older versions of the compiler will be introduced. -How fast is Nim? ----------------- -Benchmarks show it to be comparable to C. Some language features (methods, -closures, message passing) are not yet as optimized as they could and will be. -The only overhead Nim has over C is the GC which has been tuned -for years but still needs some work. +.. container:: standout + + How fast is Nim? + ---------------- + Benchmarks show it to be comparable to C. Some language features (methods, + closures, message passing) are not yet as optimized as they could and will be. + The only overhead Nim has over C is the GC which has been tuned + for years but still needs some work. -What about JVM/CLR backends? ----------------------------- +.. container:: standout -A JVM backend is almost impossible. The JVM is not expressive enough. It has -never been designed as a general purpose VM anyway. A CLR backend is possible -but would require much work. + What about JVM/CLR backends? + ---------------------------- -What about editor support? --------------------------- - -- Nim IDE: https://github.com/nimrod-code/Aporia -- Emacs: https://github.com/Tass/nimrod-mode -- Vim: https://github.com/zah/nimrod.vim/ -- Scite: Included -- Gedit: The `Aporia .lang file `_ -- jEdit: https://github.com/exhu/nimrod-misc/tree/master/jedit + A JVM backend is almost impossible. The JVM is not expressive enough. It has + never been designed as a general purpose VM anyway. A CLR backend is possible + but would require much work. -Why is it named ``proc``? -------------------------- +.. container:: standout -*Procedure* used to be the common term as opposed to a *function* which is a -mathematical entity that has no side effects. It was planned to have ``func`` -as syntactic sugar for ``proc {.noSideEffect.}`` but with the more fine-grained -effect system it is not yet clear what ``func`` should be a shortcut for. + What about editor support? + -------------------------- + + - Nim IDE: https://github.com/nimrod-code/Aporia + - Emacs: https://github.com/Tass/nimrod-mode + - Vim: https://github.com/zah/nimrod.vim/ + - Scite: Included + - Gedit: The `Aporia .lang file `_ + - jEdit: https://github.com/exhu/nimrod-misc/tree/master/jedit + + +.. container:: standout + + Why is it named ``proc``? + ------------------------- + + *Procedure* used to be the common term as opposed to a *function* which is a + mathematical entity that has no side effects. It was planned to have ``func`` + as syntactic sugar for ``proc {.noSideEffect.}`` but with the more fine-grained + effect system it is not yet clear what ``func`` should be a shortcut for. Compilation =========== -Which option to use for the fastest executable? ------------------------------------------------ +.. container:: standout -For the standard configuration file, ``-d:release`` does the trick. + Which option to use for the fastest executable? + ----------------------------------------------- + For the standard configuration file, ``-d:release`` does the trick. -Which option to use for the smallest executable? ------------------------------------------------- +.. container:: standout -For the standard configuration file, ``-d:quick --opt:size`` does the trick. + Which option to use for the smallest executable? + ------------------------------------------------ + For the standard configuration file, ``-d:quick --opt:size`` does the trick. -How do I use a different C compiler than the default one? ---------------------------------------------------------- +.. container:: standout -Edit the ``config/nimrod.cfg`` file. -Change the value of the ``cc`` variable to one of the following: + How do I use a different C compiler than the default one? + --------------------------------------------------------- -============== ============================================ -Abbreviation C/C++ Compiler -============== ============================================ -``vcc`` Microsoft's Visual C++ -``gcc`` Gnu C -``llvm_gcc`` LLVM-GCC compiler -``icc`` Intel C++ compiler -``clang`` Clang compiler -``ucc`` Generic UNIX C compiler -============== ============================================ + Edit the ``config/nimrod.cfg`` file. + Change the value of the ``cc`` variable to one of the following: -Other C compilers are not officially supported, but might work too. + ============== ============================================ + Abbreviation C/C++ Compiler + ============== ============================================ + ``vcc`` Microsoft's Visual C++ + ``gcc`` Gnu C + ``llvm_gcc`` LLVM-GCC compiler + ``icc`` Intel C++ compiler + ``clang`` Clang compiler + ``ucc`` Generic UNIX C compiler + ============== ============================================ -If your C compiler is not in the above list, try using the -*generic UNIX C compiler* (``ucc``). If the C compiler needs -different command line arguments try the ``--passc`` and ``--passl`` switches. + Other C compilers are not officially supported, but might work too. + + If your C compiler is not in the above list, try using the + *generic UNIX C compiler* (``ucc``). If the C compiler needs + different command line arguments try the ``--passc`` and ``--passl`` switches. diff --git a/web/ticker.txt b/web/ticker.txt index 98ad25905..a0d2f0a78 100644 --- a/web/ticker.txt +++ b/web/ticker.txt @@ -1,54 +1,21 @@ +
+

Dec 9, 2014

+

The new website design and forum are now online!

+
+ -

Oct 19, 2014

+

Oct 19, 2014

Nimrod version 0.9.6 has been released!

- -

Apr 21, 2014

-

Nimrod version 0.9.4 has been released!

-
- -

Feb 11, 2014

+

Feb 11, 2014

Nimrod featured in Dr. Dobb's Journal

-

Jan 15, 2014

+

Jan 15, 2014

Andreas Rumpf's talk on Nimrod at Strange Loop 2013 is now online.

- -

May 20, 2013

-

New website design!

-
- - -

May 20, 2013

-

Nimrod version 0.9.2 has been released!

-
- - -

Sep 23, 2012

-

Nimrod version 0.9.0 has been released!

-
- - -

Feb 9, 2012

-

Nimrod version 0.8.14 has been released!

-
- - -

Jul 10, 2011

-

Nimrod version 0.8.12 has been released!

-
- - -

Oct 20, 2010

-

Nimrod version 0.8.10 has been released!

-
- - -

Mar 14, 2010

-

Nimrod version 0.8.8 has been released!

-
+See All News... From 85cc5a6a1f0247f0d70f68831a19ec9cab1f5dd3 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Dec 2014 01:57:08 +0100 Subject: [PATCH 311/409] destuctors are experimental; 'func' is now a keyword --- compiler/lexer.nim | 6 +++--- compiler/semstmts.nim | 5 ++++- compiler/wordrecg.nim | 4 ++-- doc/keywords.txt | 2 +- lib/packages/docutils/highlite.nim | 3 ++- tests/destructor/tdestructor.nim | 2 ++ tests/destructor/tdestructor2.nim | 2 ++ tools/nimweb.nim | 2 +- web/news.txt | 3 +++ 9 files changed, 20 insertions(+), 9 deletions(-) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index fb74f27d6..a6b85d7f3 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -38,7 +38,7 @@ type tkConst, tkContinue, tkConverter, tkDefer, tkDiscard, tkDistinct, tkDiv, tkDo, tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkExport, - tkFinally, tkFor, tkFrom, + tkFinally, tkFor, tkFrom, tkFunc, tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, tkIs, tkIsnot, tkIterator, tkLet, @@ -75,9 +75,9 @@ const "const", "continue", "converter", "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", - "finally", "for", "from", "generic", "if", + "finally", "for", "from", "func", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", - "let", + "let", "macro", "method", "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "ptr", "raise", "ref", "return", diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 933ac7daf..c67fdb0f9 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1026,7 +1026,10 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) = proc semOverride(c: PContext, s: PSym, n: PNode) = case s.name.s.normalize - of "destroy": doDestructorStuff(c, s, n) + of "destroy": + doDestructorStuff(c, s, n) + if not experimentalMode(c): + localError n.info, "use the {.experimental.} pragma to enable destructors" of "deepcopy": if s.typ.len == 2 and s.typ.sons[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index f08ab0ad9..1148bdeaf 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -26,7 +26,7 @@ type wBind, wBlock, wBreak, wCase, wCast, wConst, wContinue, wConverter, wDefer, wDiscard, wDistinct, wDiv, wDo, wElif, wElse, wEnd, wEnum, wExcept, wExport, - wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn, + wFinally, wFor, wFrom, wFunc, wGeneric, wIf, wImport, wIn, wInclude, wInterface, wIs, wIsnot, wIterator, wLet, wMacro, wMethod, wMixin, wMod, wNil, wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, @@ -106,7 +106,7 @@ const "const", "continue", "converter", "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", - "finally", "for", "from", "generic", "if", + "finally", "for", "from", "func", "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", "let", "macro", "method", "mixin", "mod", "nil", "not", "notin", diff --git a/doc/keywords.txt b/doc/keywords.txt index 67ff0ab7f..7a4f8c696 100644 --- a/doc/keywords.txt +++ b/doc/keywords.txt @@ -3,7 +3,7 @@ bind block break case cast const continue converter defer discard distinct div do elif else end enum except export -finally for from +finally for from func generic if import in include interface is isnot iterator let diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index 9c482575a..7fc2e1aa3 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -50,7 +50,8 @@ const "break", "case", "cast", "const", "continue", "converter", "defer", "discard", "distinct", "div", "do", "elif", "else", "end", "enum", "except", "export", - "finally", "for", "from", "generic", "if", "import", "in", "include", + "finally", "for", "from", "func", + "generic", "if", "import", "in", "include", "interface", "is", "isnot", "iterator", "let", "macro", "method", "mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "static", diff --git a/tests/destructor/tdestructor.nim b/tests/destructor/tdestructor.nim index f0ea3c5c6..cbaba3154 100644 --- a/tests/destructor/tdestructor.nim +++ b/tests/destructor/tdestructor.nim @@ -22,6 +22,8 @@ myobj destroyed ''' """ +{.experimental.} + type TMyObj = object x, y: int diff --git a/tests/destructor/tdestructor2.nim b/tests/destructor/tdestructor2.nim index a5b62860c..1bdf4993b 100644 --- a/tests/destructor/tdestructor2.nim +++ b/tests/destructor/tdestructor2.nim @@ -3,6 +3,8 @@ discard """ errormsg: " usage of a type with a destructor in a non destructible context" """ +{.experimental.} + type TMyObj = object x, y: int diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 6fc946552..ddbba1e3f 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -418,7 +418,7 @@ proc main(c: var TConfigData) = quit("[Error] cannot write file: " & outfile) removeFile(temp) copyDir("web/assets", "web/upload/assets") - #buildJS("web/upload") + buildJS("web/upload") buildNewsRss(c, "web/upload") #buildAddDoc(c, "web/upload") #buildDocSamples(c, "web/upload") diff --git a/web/news.txt b/web/news.txt index d345526c4..a8dee9c15 100644 --- a/web/news.txt +++ b/web/news.txt @@ -29,8 +29,11 @@ News - The "symmetric set difference" operator (``-+-``) never worked and has been removed. - ``defer`` is a keyword now. + - ``func`` is a keyword now. - The ``using`` language feature now needs to be activated via the new ``{.experimental.}`` pragma that enables experimental language features. + - Destructors are now officially *experimental*. + Language Additions ------------------ From 0cb3d31617f2480ca4d38cbf0a340dbb151796f1 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Dec 2014 02:29:31 +0100 Subject: [PATCH 312/409] further website improvements --- compiler/jsgen.nim | 4 +++- tools/nimweb.nim | 1 + tools/website.tmpl | 8 +++++++- web/nim.ini | 8 +++++--- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 2ae85d5cf..c9daba4d1 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -954,7 +954,9 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) = r.address = s.loc.r r.res = toRope("0") else: - internalError(n.info, "genAddr: 4") + # 'var openArray' for instance produces an 'addr' but this is harmless: + gen(p, n.sons[0], r) + #internalError(n.info, "genAddr: 4 " & renderTree(n)) else: internalError(n.info, "genAddr: 2") of nkCheckedFieldExpr: genCheckedFieldAddr(p, n, r) diff --git a/tools/nimweb.nim b/tools/nimweb.nim index ddbba1e3f..6cd840ab6 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -400,6 +400,7 @@ proc main(c: var TConfigData) = for i in 0..c.tabs.len-1: var file = c.tabs[i].val let rss = if file in ["news", "index"]: extractFilename(rssUrl) else: "" + if '.' in file: continue exec(cmd % [c.nimArgs, file]) var temp = "web" / changeFileExt(file, "temp") var content: string diff --git a/tools/website.tmpl b/tools/website.tmpl index b4dd2631c..88a4dee67 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -24,10 +24,16 @@ # var t = c.tabs[i].val #if currentTab == t: $name + #if t.contains('.'): + href="${t}" title = "$c.projectName - $name">$name + #else: + href="${t}.html" title = "$c.projectName - $name">$name + #end if #end for diff --git a/web/nim.ini b/web/nim.ini index 83705e8ce..8145317b9 100644 --- a/web/nim.ini +++ b/web/nim.ini @@ -7,7 +7,7 @@ Authors: "Andreas Rumpf and contributors" [Links] # Underscores are replaced with a space. # Everything after ; is the ID -User_Forum: "http://forum.nim-lang.org;link_forum" +Community: "community.html;link_forum" Aporia_IDE: "https://github.com/nimrod-code/Aporia;link_aporia" Github_Repo: "http://github.com/Araq/Nimrod;link_github" @@ -15,12 +15,14 @@ Github_Repo: "http://github.com/Araq/Nimrod;link_github" [Tabs] # Menu entry: filename home: index -news: news docs: documentation learn: learn download: download -community: community +forum: "http://forum.nim-lang.org" FAQ: question +# these two are not in the list of "tabs", but do exist: +community: community +news: news [Ticker] file: ticker.txt From 89703f2196a68eaf1719a07c7303528b829c5140 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Dec 2014 19:06:20 +0100 Subject: [PATCH 313/409] fixed typos --- web/learn.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/learn.txt b/web/learn.txt index 1b0984cda..f0e5e57fa 100644 --- a/web/learn.txt +++ b/web/learn.txt @@ -1,5 +1,5 @@ -Nim's Learning Resources -======================== +Learning Nim +============ .. container:: standout @@ -22,7 +22,7 @@ Nim's Learning Resources | Nim by Example is an excellent starting place for beginners. - | `Nim on Rosetta Code `_ - | Many different Nim code examples comparible to other langues for reference. + | Many different Nim code examples comparable to other languages for reference. - | `Nim for C/C++ Programmers `_ | A useful cheat-sheet for those most familiar with C/C++ languages. @@ -40,5 +40,5 @@ Nim's Learning Resources Documentation ------------- -More examples of Nim code can be found in the `Nim Language Documenation `_. +More examples of Nim code can be found in the `Nim Language Documentation `_. From 6fa4809bd9ecbee634fbe9b0ae514c06f86caf7b Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Dec 2014 19:58:52 +0100 Subject: [PATCH 314/409] nimweb builds full docs again --- tools/nimweb.nim | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 6cd840ab6..0242e498e 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -389,7 +389,7 @@ proc buildJS(destPath: string) = exec("nim js -d:release --out:$1 web/babelpkglist.nim" % [destPath / "babelpkglist.js"]) -proc main(c: var TConfigData) = +proc buildWebsite(c: var TConfigData) = const cmd = "nim rst2html --compileonly $1 -o:web/$2.temp web/$2.txt" if c.ticker.len > 0: @@ -419,13 +419,16 @@ proc main(c: var TConfigData) = quit("[Error] cannot write file: " & outfile) removeFile(temp) copyDir("web/assets", "web/upload/assets") - buildJS("web/upload") buildNewsRss(c, "web/upload") - #buildAddDoc(c, "web/upload") - #buildDocSamples(c, "web/upload") - #buildDoc(c, "web/upload") - #buildDocSamples(c, "doc") - #buildDoc(c, "doc") + +proc main(c: var TConfigData) = + buildWebsite(c) + buildJS("web/upload") + buildAddDoc(c, "web/upload") + buildDocSamples(c, "web/upload") + buildDoc(c, "web/upload") + buildDocSamples(c, "doc") + buildDoc(c, "doc") #buildPdfDoc(c, "doc") var c: TConfigData @@ -434,5 +437,6 @@ parseCmdLine(c) parseIniFile(c) when false: buildPdfDoc(c, "doc") + buildWebsite(c) else: main(c) From d3cf767c3acb8a3c202eab7c4133a81273b61a36 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Dec 2014 19:59:14 +0100 Subject: [PATCH 315/409] fixes #1692 --- compiler/vm.nim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index 3d2ddfc82..fe67f4d4c 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -## This file implements the new evaluation engine for Nimrod code. +## This file implements the new evaluation engine for Nim code. ## An instruction is 1-3 int32s in memory, it is a register based VM. const debugEchoCode = false @@ -1151,7 +1151,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, c.debug[pc].line.int, proc (info: TLineInfo; msg: TMsgKind; arg: string) = - if error.isNil: error = formatMsg(info, msg, arg)) + if error.isNil and msg <= msgs.errMax: + error = formatMsg(info, msg, arg)) if not error.isNil: c.errorFlag = error elif sonsLen(ast) != 1: @@ -1164,7 +1165,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath, c.debug[pc].line.int, proc (info: TLineInfo; msg: TMsgKind; arg: string) = - if error.isNil: error = formatMsg(info, msg, arg)) + if error.isNil and msg <= msgs.errMax: + error = formatMsg(info, msg, arg)) if not error.isNil: c.errorFlag = error else: From c00a3fdc5b23d71c440e9046886319376b56efef Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Dec 2014 20:17:36 +0100 Subject: [PATCH 316/409] fixes #1718 --- compiler/vmgen.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 8b7dc293c..fe909b887 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1610,6 +1610,8 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) = gen(c, n.sons[0]) of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(c, n, n.sons[1], dest) + of nkObjDownConv: + genConv(c, n, n.sons[0], dest) of nkVarSection, nkLetSection: unused(n, dest) genVarSection(c, n) From b7c806381695b8f8ceb0676905461b9a145c0350 Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 10 Dec 2014 21:00:02 +0100 Subject: [PATCH 317/409] fixes #1689 --- compiler/vm.nim | 7 +++++++ lib/pure/asyncdispatch.nim | 18 +++++++++--------- todo.txt | 5 +++++ web/news.txt | 7 +++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/compiler/vm.nim b/compiler/vm.nim index fe67f4d4c..2da242771 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1426,6 +1426,12 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = inc(evalMacroCounter) if evalMacroCounter > 100: globalError(n.info, errTemplateInstantiationTooNested) + + # immediate macros can bypass any type and arity checking so we check the + # arity here too: + if sym.typ.len > n.safeLen and sym.typ.len > 1: + globalError(n.info, "got $#, but expected $# argument(s)" % [$ = L + # return value: tos.slots[0].kind = rkNode tos.slots[0].node = newNodeIT(nkEmpty, n.info, sym.typ.sons[0]) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 41b20cb35..a9a0b0fbe 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -419,12 +419,12 @@ when defined(windows) or defined(nimdoc): var acceptExPtr: pointer = nil var getAcceptExSockAddrsPtr: pointer = nil - proc initPointer(s: SocketHandle, func: var pointer, guid: var TGUID): bool = + proc initPointer(s: SocketHandle, fun: var pointer, guid: var TGUID): bool = # Ref: https://github.com/powdahound/twisted/blob/master/twisted/internet/iocpreactor/iocpsupport/winsock_pointers.c var bytesRet: Dword - func = nil + fun = nil result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, addr guid, - sizeof(TGUID).Dword, addr func, sizeof(pointer).Dword, + sizeof(TGUID).Dword, addr fun, sizeof(pointer).Dword, addr bytesRet, nil, nil) == 0 proc initAll() = @@ -440,12 +440,12 @@ when defined(windows) or defined(nimdoc): lpSendBuffer: pointer, dwSendDataLength: Dword, lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool = if connectExPtr.isNil: raise newException(ValueError, "Need to initialise ConnectEx().") - let func = + let fun = cast[proc (s: SocketHandle, name: ptr TSockAddr, namelen: cint, lpSendBuffer: pointer, dwSendDataLength: Dword, lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](connectExPtr) - result = func(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, + result = fun(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped) proc acceptEx(listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, @@ -453,12 +453,12 @@ when defined(windows) or defined(nimdoc): dwRemoteAddressLength: Dword, lpdwBytesReceived: PDword, lpOverlapped: POVERLAPPED): bool = if acceptExPtr.isNil: raise newException(ValueError, "Need to initialise AcceptEx().") - let func = + let fun = cast[proc (listenSock, acceptSock: SocketHandle, lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: Dword, lpdwBytesReceived: PDword, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](acceptExPtr) - result = func(listenSock, acceptSock, lpOutputBuffer, dwReceiveDataLength, + result = fun(listenSock, acceptSock, lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived, lpOverlapped) @@ -469,14 +469,14 @@ when defined(windows) or defined(nimdoc): if getAcceptExSockAddrsPtr.isNil: raise newException(ValueError, "Need to initialise getAcceptExSockAddrs().") - let func = + let fun = cast[proc (lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: Dword, LocalSockaddr: ptr ptr TSockAddr, LocalSockaddrLength: LPInt, RemoteSockaddr: ptr ptr TSockAddr, RemoteSockaddrLength: LPInt) {.stdcall,gcsafe.}](getAcceptExSockAddrsPtr) - func(lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, + fun(lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, LocalSockaddr, LocalSockaddrLength, RemoteSockaddr, RemoteSockaddrLength) diff --git a/todo.txt b/todo.txt index d301acdc3..b0181b241 100644 --- a/todo.txt +++ b/todo.txt @@ -4,6 +4,11 @@ version 0.10 - document 'converter' - document the tables module better +- The bitwise 'not' operator will be renamed to 'bnot' to + prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs! +- A named tuple will be compatible to a tuple with different names. +- The 'do' notation might be trimmed so that its only purpose is to pass + multiple multi line constructs to a macro. - c2nim depends on the compiler - make nimble part of the distribution diff --git a/web/news.txt b/web/news.txt index a8dee9c15..2c1700489 100644 --- a/web/news.txt +++ b/web/news.txt @@ -33,6 +33,13 @@ News - The ``using`` language feature now needs to be activated via the new ``{.experimental.}`` pragma that enables experimental language features. - Destructors are now officially *experimental*. + - Standalone ``except`` and ``finally`` statements are deprecated now. + The standalone ``finally`` can be replaced with ``defer``, + standalone ``except`` requires an explicit ``try``. + - Operators ending in ``>`` are considered as "arrow like" and have their + own priority level and are right associative. This means that + the ``=>`` and ``->`` operators from the `future `_ module + work better. Language Additions From 393be493136d8323d0335bf8c45b0f90a5e9742c Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 11 Dec 2014 01:02:53 +0100 Subject: [PATCH 318/409] fixes #1597 --- compiler/semparallel.nim | 32 ++++++++++++++++++++++-------- tests/parallel/treadafterwrite.nim | 31 +++++++++++++++++++++++++++++ tests/parallel/tuseafterdef.nim | 31 +++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 8 deletions(-) create mode 100644 tests/parallel/treadafterwrite.nim create mode 100644 tests/parallel/tuseafterdef.nim diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim index c4546f616..bd3152b54 100644 --- a/compiler/semparallel.nim +++ b/compiler/semparallel.nim @@ -258,14 +258,18 @@ proc min(a, b: PNode): PNode = proc fromSystem(op: PSym): bool = sfSystemModule in getModule(op).flags +template pushSpawnId(c: expr, body: stmt) {.immediate, dirty.} = + inc c.spawns + let oldSpawnId = c.currentSpawnId + c.currentSpawnId = c.spawns + body + c.currentSpawnId = oldSpawnId + proc analyseCall(c: var AnalysisCtx; n: PNode; op: PSym) = if op.magic == mSpawn: - inc c.spawns - let oldSpawnId = c.currentSpawnId - c.currentSpawnId = c.spawns - gatherArgs(c, n[1]) - analyseSons(c, n) - c.currentSpawnId = oldSpawnId + pushSpawnId(c): + gatherArgs(c, n[1]) + analyseSons(c, n) elif op.magic == mInc or (op.name.s == "+=" and op.fromSystem): if n[1].isLocal: let incr = n[2].skipConv @@ -322,7 +326,14 @@ proc analyse(c: var AnalysisCtx; n: PNode) = let slot = c.getSlot(n[0].sym) slot.blacklisted = true invalidateFacts(c.guards, n[0]) - analyseSons(c, n) + let value = n[1] + if getMagic(value) == mSpawn: + pushSpawnId(c): + gatherArgs(c, value[1]) + analyseSons(c, value[1]) + analyse(c, n[0]) + else: + analyseSons(c, n) addAsgnFact(c.guards, n[0], n[1]) of nkCallKinds: # direct call: @@ -338,13 +349,18 @@ proc analyse(c: var AnalysisCtx; n: PNode) = of nkVarSection, nkLetSection: for it in n: let value = it.lastSon + let isSpawned = getMagic(value) == mSpawn + if isSpawned: + pushSpawnId(c): + gatherArgs(c, value[1]) + analyseSons(c, value[1]) if value.kind != nkEmpty: for j in 0 .. it.len-3: if it[j].isLocal: let slot = c.getSlot(it[j].sym) if slot.lower.isNil: slot.lower = value else: internalError(it.info, "slot already has a lower bound") - analyse(c, value) + if not isSpawned: analyse(c, value) of nkCaseStmt: analyseCase(c, n) of nkIfStmt, nkIfExpr: analyseIf(c, n) of nkWhileStmt: diff --git a/tests/parallel/treadafterwrite.nim b/tests/parallel/treadafterwrite.nim new file mode 100644 index 000000000..f59ad5ae0 --- /dev/null +++ b/tests/parallel/treadafterwrite.nim @@ -0,0 +1,31 @@ +discard """ + errormsg: "'foo' not disjoint from 'foo'" + line: 23 + disabled: "true" +""" + +# bug #1597 + +import strutils, math, threadpool + +type + BoxedFloat = object + value: float + +proc term(k: float): ptr BoxedFloat = + var temp = 4 * math.pow(-1, k) / (2*k + 1) + result = cast[ptr BoxedFloat](allocShared(sizeof(BoxedFloat))) + result.value = temp + +proc pi(n: int): float = + var ch = newSeq[ptr BoxedFloat](n+1) + parallel: + for k in 0..ch.high: + let foo = (spawn term(float(k))) + assert foo != nil + for k in 0..ch.high: + var temp = ch[k][].value + result += temp + deallocShared(ch[k]) + +echo formatFloat(pi(5000)) diff --git a/tests/parallel/tuseafterdef.nim b/tests/parallel/tuseafterdef.nim new file mode 100644 index 000000000..95123e886 --- /dev/null +++ b/tests/parallel/tuseafterdef.nim @@ -0,0 +1,31 @@ +discard """ + errormsg: "(k)..(k) not disjoint from (k)..(k)" + line: 23 +""" + +# bug #1597 + +import strutils, math, threadpool + +type + BoxedFloat = object + value: float + +proc term(k: float): ptr BoxedFloat = + var temp = 4 * math.pow(-1, k) / (2*k + 1) + result = cast[ptr BoxedFloat](allocShared(sizeof(BoxedFloat))) + result.value = temp + +proc pi(n: int): float = + var ch = newSeq[ptr BoxedFloat](n+1) + parallel: + for k in 0..ch.high: + ch[k] = (spawn term(float(k))) + assert ch[k] != nil + for k in 0..ch.high: + var temp = ch[k][].value + result += temp + deallocShared(ch[k]) + + +echo formatFloat(pi(5000)) From 911001991f50bcc77f910747bfbe1c1ff193b594 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 11 Dec 2014 20:50:08 +0100 Subject: [PATCH 319/409] more index terms --- lib/core/typeinfo.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim index f3f00f9f5..1b9b95c24 100644 --- a/lib/core/typeinfo.nim +++ b/lib/core/typeinfo.nim @@ -7,10 +7,11 @@ # distribution, for details about the copyright. # -## This module implements an interface to Nim's runtime type information. +## This module implements an interface to Nim's `runtime type information`:idx: +## (`RTTI`:idx:). ## Note that even though ``TAny`` and its operations hide the nasty low level ## details from its clients, it remains inherently unsafe! -## +## ## See the `marshal `_ module for what this module allows you ## to do. From f731c5aac05f182b2a3861677cbe5445237eccd7 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 11 Dec 2014 20:50:32 +0100 Subject: [PATCH 320/409] disable t5000 test for the autobuilder --- tests/parallel/t5000.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/parallel/t5000.nim b/tests/parallel/t5000.nim index 025c327fa..1dd47a61c 100644 --- a/tests/parallel/t5000.nim +++ b/tests/parallel/t5000.nim @@ -1,7 +1,10 @@ discard """ output: '''50005000''' + disabled: "true" """ +# XXX this seems to deadlock certain Linux machines + import threadpool, strutils proc foo(x: int): string = $x From 50e156db6ecfdd23b6c7d3a5fb3d93974dca2cd8 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 11 Dec 2014 20:51:07 +0100 Subject: [PATCH 321/409] website slightly improved --- todo.txt | 1 - tools/nimweb.nim | 2 +- tools/website.tmpl | 8 ++++---- web/news.txt | 2 -- web/nim.ini | 2 +- web/question.txt | 6 +++--- 6 files changed, 9 insertions(+), 12 deletions(-) diff --git a/todo.txt b/todo.txt index b0181b241..302178b96 100644 --- a/todo.txt +++ b/todo.txt @@ -46,7 +46,6 @@ Bugs - VM: Pegs do not work at compile-time - VM: ptr/ref T cannot work in general - scopes are still broken for generic instantiation! -- bug: type conversions concerning proc types are weird - compilation of niminst takes way too long. looks like a regression - docgen: sometimes effects are listed twice - blocks can "export" an identifier but the CCG generates {} for them ... diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 0242e498e..23d1ef4d9 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -436,7 +436,7 @@ initConfigData(c) parseCmdLine(c) parseIniFile(c) when false: - buildPdfDoc(c, "doc") + #buildPdfDoc(c, "doc") buildWebsite(c) else: main(c) diff --git a/tools/website.tmpl b/tools/website.tmpl index 88a4dee67..9f655a04c 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -136,7 +136,7 @@ p.greet() # or greet(p)

Documentation

Stable Documentation - Github Issues & Requests + Issues & Requests

Community

@@ -146,9 +146,9 @@ p.greet() # or greet(p)
diff --git a/web/news.txt b/web/news.txt index 2c1700489..9971ed724 100644 --- a/web/news.txt +++ b/web/news.txt @@ -373,8 +373,6 @@ We are pleased to announce that version 0.9.2 of the Nimrod compiler has been released. This release has attracted by far the most contributions in comparison to any other release. -This release can be downloaded from `here `_. - This release brings with it many new features and bug fixes, a list of which can be seen later. One of the major new features is the effect system together with exception tracking which allows for checked exceptions and more, diff --git a/web/nim.ini b/web/nim.ini index 8145317b9..6face49bc 100644 --- a/web/nim.ini +++ b/web/nim.ini @@ -19,7 +19,7 @@ docs: documentation learn: learn download: download forum: "http://forum.nim-lang.org" -FAQ: question +faq: question # these two are not in the list of "tabs", but do exist: community: community news: news diff --git a/web/question.txt b/web/question.txt index 23d3b9b67..8f48c1640 100644 --- a/web/question.txt +++ b/web/question.txt @@ -117,9 +117,9 @@ General ------------------------- *Procedure* used to be the common term as opposed to a *function* which is a - mathematical entity that has no side effects. It was planned to have ``func`` - as syntactic sugar for ``proc {.noSideEffect.}`` but with the more fine-grained - effect system it is not yet clear what ``func`` should be a shortcut for. + mathematical entity that has no side effects. It is planned to have ``func`` + as syntactic sugar for ``proc {.noSideEffect.}`` and ``func`` is already a + keyword. Compilation From 5a52e941b5a5e6fa92b76608dc8ed599821cd6c8 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 11 Dec 2014 23:29:26 +0100 Subject: [PATCH 322/409] added 'setupGcForForeignThread' for better C interop --- lib/system/gc.nim | 14 ++++++++++++++ lib/system/gc_ms.nim | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index fe4b40903..e0db3fba4 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -292,6 +292,20 @@ proc initGC() = when useMarkForDebug or useBackupGc: init(gch.marked) +var + localGcInitialized {.rtlThreadVar.}: bool + +proc setupForeignThreadGc*() = + ## call this if you registered a callback that will be run from a thread not + ## under your control. This has a cheap thread-local guard, so the GC for + ## this thread will only be initialized once per thread, no matter how often + ## it is called. + if not localGcInitialized: + localGcInitialized = true + var stackTop {.volatile.}: pointer + setStackBottom(addr(stackTop)) + initGC() + when useMarkForDebug or useBackupGc: type TGlobalMarkerProc = proc () {.nimcall, benign.} diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index 242ca1608..0eafd3255 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -168,6 +168,20 @@ proc initGC() = Init(gch.allocated) init(gch.marked) +var + localGcInitialized {.rtlThreadVar.}: bool + +proc setupForeignThreadGc*() = + ## call this if you registered a callback that will be run from a thread not + ## under your control. This has a cheap thread-local guard, so the GC for + ## this thread will only be initialized once per thread, no matter how often + ## it is called. + if not localGcInitialized: + localGcInitialized = true + var stackTop {.volatile.}: pointer + setStackBottom(addr(stackTop)) + initGC() + proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.benign.} = var d = cast[ByteAddress](dest) case n.kind From 6b088938f70220f7e2702e4ec8829a10646a0db4 Mon Sep 17 00:00:00 2001 From: Philip Wernersbach Date: Thu, 11 Dec 2014 23:19:47 -0500 Subject: [PATCH 323/409] Add build scripts. --- build.sh | 19 +++++++++++++++++++ install.sh.template | 9 +++++++++ 2 files changed, 28 insertions(+) create mode 100755 build.sh create mode 100644 install.sh.template diff --git a/build.sh b/build.sh new file mode 100755 index 000000000..139c28359 --- /dev/null +++ b/build.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -e +set -x + +if [ ! -d "csources" ]; then + git clone --depth 1 https://github.com/nim-lang/csources.git +fi + +cd "csources" +sh build.sh +cd ".." + +./bin/nim c koch +./koch boot -d:release + +cp -f install.sh.template install.sh +chmod +x install.sh + +exit 0 diff --git a/install.sh.template b/install.sh.template new file mode 100644 index 000000000..1292abdab --- /dev/null +++ b/install.sh.template @@ -0,0 +1,9 @@ +#!/bin/sh +set -e +set -x + +if [ "$1" != "" ]; then + exec ./koch install "$1" +else + exec ./koch install +fi From 752e920b58d537b8e871e8711551a1267a7bbb5f Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 12 Dec 2014 14:52:06 +0100 Subject: [PATCH 324/409] documented converters --- doc/manual/procs.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index d048615eb..a4e0e0bda 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -584,3 +584,23 @@ parameters of an outer factory proc: a for loop, the compiler will implicity use the ``auto`` return type if no type is given by the user. In contrast, since closure iterators can be used as a collaborative tasking system, ``void`` is a valid return type for them. + + +Converters +========== + +A converter is like an ordinary proc except that it enhances +the "implicitly convertible" type relation (see `Convertible relation`_): + +.. code-block:: nim + # bad style ahead: Nim is not C. + converter toBool(x: int): bool = x != 0 + + if 4: + echo "compiles" + + +A converter can also be explicitly invoked for improved readability. Note that +implicit converter chaining is not supported: If there is a converter from +type A to type B and from type B to type C the implicit conversion from A to C +is not provided. From 6e6c3d2f1e9efae9fdb05dbdaadccd6dcc8efe41 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 12 Dec 2014 18:25:52 +0100 Subject: [PATCH 325/409] extracted the fields iterator magic to its own file --- compiler/semfields.nim | 159 +++++++++++++++++++++++++++++++++++++++++ compiler/semstmts.nim | 148 +------------------------------------- 2 files changed, 160 insertions(+), 147 deletions(-) create mode 100644 compiler/semfields.nim diff --git a/compiler/semfields.nim b/compiler/semfields.nim new file mode 100644 index 000000000..70dead8ab --- /dev/null +++ b/compiler/semfields.nim @@ -0,0 +1,159 @@ +# +# +# The Nim Compiler +# (c) Copyright 2014 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module does the semantic transformation of the fields* iterators. +# included from semstmts.nim + +type + TFieldInstCtx = object # either 'tup[i]' or 'field' is valid + tupleType: PType # if != nil we're traversing a tuple + tupleIndex: int + field: PSym + replaceByFieldName: bool + +proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode = + case n.kind + of nkEmpty..pred(nkIdent), succ(nkIdent)..nkNilLit: result = n + of nkIdent: + result = n + var L = sonsLen(forLoop) + if c.replaceByFieldName: + if n.ident.id == forLoop[0].ident.id: + let fieldName = if c.tupleType.isNil: c.field.name.s + elif c.tupleType.n.isNil: "Field" & $c.tupleIndex + else: c.tupleType.n.sons[c.tupleIndex].sym.name.s + result = newStrNode(nkStrLit, fieldName) + return + # other fields: + for i in ord(c.replaceByFieldName)..L-3: + if n.ident.id == forLoop[i].ident.id: + var call = forLoop.sons[L-2] + var tupl = call.sons[i+1-ord(c.replaceByFieldName)] + if c.field.isNil: + result = newNodeI(nkBracketExpr, n.info) + result.add(tupl) + result.add(newIntNode(nkIntLit, c.tupleIndex)) + else: + result = newNodeI(nkDotExpr, n.info) + result.add(tupl) + result.add(newSymNode(c.field, n.info)) + break + else: + if n.kind == nkContinueStmt: + localError(n.info, errGenerated, + "'continue' not supported in a 'fields' loop") + result = copyNode(n) + newSons(result, sonsLen(n)) + for i in countup(0, sonsLen(n)-1): + result.sons[i] = instFieldLoopBody(c, n.sons[i], forLoop) + +type + TFieldsCtx = object + c: PContext + m: TMagic + +proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) = + case typ.kind + of nkSym: + var fc: TFieldInstCtx # either 'tup[i]' or 'field' is valid + fc.field = typ.sym + fc.replaceByFieldName = c.m == mFieldPairs + openScope(c.c) + inc c.c.inUnrolledContext + let body = instFieldLoopBody(fc, lastSon(forLoop), forLoop) + father.add(semStmt(c.c, body)) + dec c.c.inUnrolledContext + closeScope(c.c) + of nkNilLit: discard + of nkRecCase: + let L = forLoop.len + let call = forLoop.sons[L-2] + if call.len > 2: + localError(forLoop.info, errGenerated, + "parallel 'fields' iterator does not work for 'case' objects") + return + # iterate over the selector: + semForObjectFields(c, typ[0], forLoop, father) + # we need to generate a case statement: + var caseStmt = newNodeI(nkCaseStmt, forLoop.info) + # generate selector: + var access = newNodeI(nkDotExpr, forLoop.info, 2) + access.sons[0] = call.sons[1] + access.sons[1] = newSymNode(typ.sons[0].sym, forLoop.info) + caseStmt.add(semExprWithType(c.c, access)) + # copy the branches over, but replace the fields with the for loop body: + for i in 1 .. 2: - localError(forLoop.info, errGenerated, - "parallel 'fields' iterator does not work for 'case' objects") - return - # iterate over the selector: - semForObjectFields(c, typ[0], forLoop, father) - # we need to generate a case statement: - var caseStmt = newNodeI(nkCaseStmt, forLoop.info) - # generate selector: - var access = newNodeI(nkDotExpr, forLoop.info, 2) - access.sons[0] = call.sons[1] - access.sons[1] = newSymNode(typ.sons[0].sym, forLoop.info) - caseStmt.add(semExprWithType(c.c, access)) - # copy the branches over, but replace the fields with the for loop body: - for i in 1 .. Date: Fri, 12 Dec 2014 18:26:35 +0100 Subject: [PATCH 326/409] website improvements --- todo.txt | 1 - tools/website.tmpl | 34 +++++++++++++++++++++------------- web/assets/images/favicon.ico | Bin 0 -> 1150 bytes web/assets/style.css | 20 +++++++++++++++++--- web/community.txt | 2 +- web/index.txt | 2 +- web/news.txt | 3 +++ web/question.txt | 1 + 8 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 web/assets/images/favicon.ico diff --git a/todo.txt b/todo.txt index 302178b96..5e2f91b01 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,6 @@ version 0.10 ============ -- document 'converter' - document the tables module better - The bitwise 'not' operator will be renamed to 'bnot' to diff --git a/tools/website.tmpl b/tools/website.tmpl index 9f655a04c..b16373c4f 100644 --- a/tools/website.tmpl +++ b/tools/website.tmpl @@ -8,7 +8,7 @@ $c.projectTitle - + #if len(rss) > 0: #end if @@ -17,7 +17,7 @@

? z*e+3|g3CBm87%p+P{iXBU7>(BQOa>1VW3uS&9}xA>;xsatvfO#<}*c6hTv= z+}{pR=v>c~3heHioN84`7BQRH*QL;ioQPe6Rg)I=8&diP7GjOLrx21*z-r6{6&r^j zJcg#NITIq33`UAI|Lx#euTZf_fD^>VS;gd<^MoiO#9Vt@y=Uar-o~uI^}TK0hgNzU zAF8*_gsjW(!L6LiOKBk!!sxz`yA0ZyseEeU+gYHuIXsOFi|n50i~N`GO;* z_P8##p1sFejVu=&*E~k1kDEec!n{@XwK}8F*N@uAy%N8S)y8>`%^{fFXU}X>h1GS4 zxqoWHydMx)*q-)I_m9BYAd>-iJ`Gp$b`cc@`T}Yz;6eRa&a4s==<$rSt8QpLX-gKy$TA?vzYBe?X8t$9vDN1dTK|>cN6Eq$`i$lC=&DQ$r6~lwE zW7_f2z*gRM=yn}Od*=B+2$PQ-k{w5T4#U?z0piXLhZjd~KKsHP9ujZf@y;8}vuE7N z<1)PWg`eD~)NiauFnVYnV9ox+B+c9F8Y(|Wetx>Jwd7Vg z9c?afw;=yoKOom?$@u0*oqY7G=IG(_=>II|XWEF$Ra8Gz!0m0Q{`(|gW!U_%O?XxI14-? zi-9_Tvb@(Boit`w00r4gJbhi+?{V;Ot6TrPJ6#PZ6yfRO7~*mK?G#I{0|q=S>CJQh z@4wFRM6EF)Xveg2FHX_L+&zZs3r#1?WXfA0{=r+JK~eMildr)6u770n>gU{;n9pjy u=j|zX$DcRep7`-3Qe*= zK;!}PAc~$MK%O7~0X>6WKi zO%f}ZVJx@C0OJ4yc=hL{v1Pb?`D)2zh`2_aA`B!R3EPUifdR&Em+83qWvWt{awqv0 zvyaZxrvSwGZsSGpy^a8UA&nNHbeH4Fv!nV=N#=wAB$fi0q$TmezkTL>K9sXP zJ@K%8Q@yX0c5;qZa&wIBAukkocGKLjiGsUujauW;eaZ9cs!xrX3Itr>?-@2*rSB;h zhf0fYBd4D%^p%?>#a87V3EUKta-er6oh$QtUUqa}U1u)3fs~D39z;e9}3asB#fQhN4_&I0)!>j6jhp)$1*JrhJ3X{oOUlfgkh|;9*!FG6@ z0{V2I*!;j&3s^RIFxq7Mkrd^kXcUvlTj%r?{}0{T>lxpMZ2vzvXRy0_9F2NW<6fEZ zJJ^i1NB*FuvH7u9_7Ap2Oi4N?d)25H_3rL*aCU|v85g93;jrB*y%XrjWG~I_2hcZ& zgqhn~HEcE{FtZTKf_EmJ2fTLdW>($Y4G+3gPRPYWQsZ!NFt4f)R{{VX7t;>@GlPLfI002ovPDHLkV1ijrcCi2e literal 0 HcmV?d00001 diff --git a/web/assets/images/head.png b/web/assets/images/head.png new file mode 100644 index 0000000000000000000000000000000000000000..009f86728e96fb18c580c73b5b8cfed1462ac8d1 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^96+4H!3HFETNbVYQfx`y?k)`fL2$v|<&%LToCO|{ z#Xud`L734=V|E2lkiEpy*OmPqha8W*vHUTuI-rn+r;B5V$MLrp6!{nwcvud$etB4{ z(X>3_!rFryXU~x?W%lS&^JQvuP!Ql?Iq!I9YC?I!&m|5Ylr6TrV&=1ZAfW{`gTd3) K&t;ucLK6VpDKi8B literal 0 HcmV?d00001 diff --git a/web/assets/images/logo.png b/web/assets/images/logo.png index 31ee0a6e11c438d5fad9ec4adce5f34b4b01633f..85d3d2e5169217dbff6c9e0b5407b1bd3507a055 100644 GIT binary patch literal 116562 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ȇ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 HB{Ts5&D)Jn diff --git a/web/assets/images/mascot.png b/web/assets/images/mascot.png new file mode 100644 index 0000000000000000000000000000000000000000..9beb62c017afc19c1d45b73633903df8685b3446 GIT binary patch literal 18022 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 literal 0 HcmV?d00001 diff --git a/web/assets/images/more-links_editors.png b/web/assets/images/more-links_editors.png new file mode 100644 index 0000000000000000000000000000000000000000..f5970ff1f6b4e36687b3155923162c055352e3af GIT binary patch literal 852 zcmV-a1FQUrP)WFU8GbZ8()Nlj2>E@cM*00Ov4L_t(o!^M})YZWmR z#ebR3*w$KYEmZ^&T=_SMLS6cY`k%NIT)ELj(Ul@v?1%lDkGMIJ%k^g76XY2PZ<3iL zC+D1dlb3SNtgs~2sdO}~w%h_Xf%bm@*Z?}M*%c7&iWYBxOHtn$Ier6ps+U>6<#}|^ z_I*_CcNsVbE=2te;0N$i>o!0t0A6Td;<<$|F$NNBBz(JH(V;G2B6eUXSA}jHMtxk$-S9WeXKF9lZQD82H;sB!L?kz zD=>#zU_**8oZ9SGzW=KBO_L8IV=~7;su&I6{fq~`XzY%md<=}qG5{hE zq$RFjU7&Z>c#9;6Ks*XACC4T!PA1Nm-u*HXP`MvY=H&FdUV8CGQ4odWqHFr}H;V(L e75_c|qx=FAQu`p58%ah00000WFU8GbZ8()Nlj2>E@cM*00O>AL_t(o!^M|LZxk^U zguk982_az%OV|#G0|E&lgo4DGU%+qWCvf4w32`GQ4v7XNwuDKBY1>@N=;>j1dKi|L ztm&R{+x5y-Wlxh*;(uPF9(_&$E5JEm9hd+!;0TC+8^C?w39tzafVtWM@D6wh94`Z) z=~#ki0x$yt(7G1%+j9Z>t!q&Ee#cB6fux4HkH8Rk+H)y;1K0u{15;HQ-KV820&Bp7 zKdFHW5?yfB26G<`GZ8osjHQpI0bDW_TgpRa@+ha&01QpvUI5N&AWwBPOaupHtcmQk z4cr78iS`KC2R@$!;1h7eJf{lv7DRRm0&`bOIWxtKfa_vwze|K4I&2pT3`F3Y`ZU08 zX=3gil>2T-=v4rjrW`tbfJ}hz67P0JE12ia%zg>L6nL#_f|;~+%w$)51$OoBy594X zrvek>t|;EsK#!aqlN)>ryf77>u87oTNgii-(q8ZuI8-VQ3zbZOSI#X5j{ewDK-(3? zNU?YH(!3zd4d9-$-&BGuf$+MR)i$HCs@`(Zn_RQMy^(tWu1Sa`!RGc+V1HSHA@ESu z`E52;sEo2+w(y=Nxmf7eDrcs(Algw-%q2oUIZoMj@LRIt7Xew3D{P;s60w+sSM=Pv z$-5ZvAg;=mSv#$B#hRA(Ff%+d)L%A}FABh(56%GZ6~#WVvTjy2=JCidvF56`K%xnl zu4PEdf<0|&p|FVslLLbcVAXW)Vt^jYkZpM^o5zYRg9l*u@y}n*l#X>j!DIlz0B9;Kln$jO5cUugI&=`N3t|C)y-$XX40Mb|Uw+Ps+@Bjb+07*qoM6N<$g07xo#sB~S literal 0 HcmV?d00001 diff --git a/web/assets/images/more-links_github.png b/web/assets/images/more-links_github.png new file mode 100644 index 0000000000000000000000000000000000000000..4a6a844f421c556e5e77987372423e0c32ed818a GIT binary patch literal 713 zcmV;)0yh1LP)WFU8GbZ8()Nlj2>E@cM*00J#ZL_t(o!@ZYZYt%p# z#ed1Bf3!+%)pmWdqJD?stKYi#4a670S5c8li&|TY+io&5zMO%}u*uHu&UPRq49VPc z&$<6ng%Bvb9sq~H7Vr-^115bhSA_vQ0$u}N*A!?4;&Rppbz$#c0V5gv1YBwVVV|wi z0PgF|uk!vUPyvnZYX@*G>YpnHo@n0zVc8g{fo(nC>af1GFBzPGv?d1r%=)02WBf62 ztjKo21@NKoFyJ?EE+EnCF!27M1Y5vcU@QidfpR| zp%r?b7m{FCG@b!Jw090XQ(6rfw-?I-I2D~^;K;Dz1cVF_D=}~Ze3r*=WVi*s4+Yf> z2Ewv2;DC=}A*NFYd{c^1LWU-zxWshw8HQ8iew7%AhsDB^3t%A-ivn;NksXZ|mmruD zo8!IDVXe+&z$pMdu%nhcj{#qT0dFLTOdP4!pQ=cO0SWx7F>oc%NelDc5! z3ad&0@ZR)!XX3!A>AV158fiv}@j(f4XTp(sLmV_(10vGgX%qA$D#`kL8s>>>BTX>3_h+*^ay~4!{~Y z(0!t;2!;VnLtERA$);w=*gdCWC}zX$tc)l*mQUrmH<=UbLfe;)4Q1EFoSS9{cL5-l v>^ezH?h-&}YJ{5ypjyN4c}&kLXMp(+iP#2UmHFg~00000NkvXXu0mjf9lI_? literal 0 HcmV?d00001 diff --git a/web/assets/images/more-links_nimbuild.png b/web/assets/images/more-links_nimbuild.png new file mode 100644 index 0000000000000000000000000000000000000000..473fbe4cdd61275ce171a9affc5482c32b487b5c GIT binary patch literal 724 zcmV;_0xSKAP)WFU8GbZ8()Nlj2>E@cM*00KBkL_t(o!{wJduM{y1 zg}>d4gg_wi*aCq-;vrfP6i`v~d-)$oG*ncGh6}n#ROm8sOyjJw9y>E!iY2HdiHS#Y%mAB@%x02JVv zZ4}^<%_ra{aM$Kj688&vr2&|_MNcqs3r`UP1Z(Pa&Q_J8{Y#TfFI7PIyivTfyfAp%Ziy0O~4H! zQw=;4rRgjL1$foHYzopxlA~D?ZOFnhI}2(@MxTClq3a-fYO*&2aF*!6=;fLyW*vBI zrie`mH~&yoX_vkiF3DadDi}$r1f-LsWQ&TM5P&!#ia=y+UKTA}cJ7(o!PVM>^1xseix=PgWDi0A$))7CcUBHXWSjbw%3A zQg-wn*bHjBjD&UJCq~z%VHs4eYrPPq=VIIZ_dlmc2k-|>Wnf9MrABuE0000raZEUT;9HO5#0X)(53|&QJ0l1wM%4~)65xWq3t+5kX)^9pP zo5<49VbDt|K|rD8 zAO#PS2a0vi-7T933T45Wl7~E)yL(ZFdFcsYCO6K5Jqm|W&K=p&-GWo)|KaTX5R3)O zgF<(9mOpgli_5U9hXu*|W9fjKv}gT=uR_LG(^w7z^w@LpKR7pe*0 z2;BnfK4I0(En5bIxlUw3NoAy1ubk|b-3AL?p+sXehDUi8vRAb12q+8Pf=FBjc^0!* zkH!VY(g@hQB32$`7ca{g1&;J3NT|a2t_bC^Jl(*q3iW~;UT}3?YhWoazhF7D90U-* z<|@0ZjH`5!O1&7~f^d<14+;lk5j$E>aODbHgAm=bppLd2YIAAN9PHNUS>IZ~-so?0 z`va@#(}8u3Ty?9Yf>-83?PR~nO}nx&4WJ8D{Zi*c+L!sYovR^R z*^R%QE*7$CFZ;Au96#Q(uSzc`2yP;cowE!1^IPiMC<0=Anp}F<$J%fyuJ5LxhiCYH zX#@y6A$TQ`5qpxKn^A+0x+VR$z%V!Kyu{{c?rAm;J#`*{EW002ovPDHLkV1jgC B$tM5+ literal 0 HcmV?d00001 diff --git a/web/assets/images/sidebar.png b/web/assets/images/sidebar.png index 77624480eca6c9d8e12570b9b913749a23e11b63..142db93cf81d981c57f5717a732e9cf2146b85a9 100644 GIT binary patch literal 109579 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 diff --git a/web/assets/images/slideshow-nav.png b/web/assets/images/slideshow-nav.png new file mode 100644 index 0000000000000000000000000000000000000000..fbfff3e5dff79b3d0fe32c50b1afe63e731bef71 GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^;vmey1|%P7U0DF6*pj^6T^Rm@;DWu&Cj&(|3p^r= zfjX{(Fr$;k>Unfx)>bHL)Z$ zMWH;iBtya7(>EYRFO{8vfsw`2#WBR=_}i-1+i$yRftriJMQ){Ea;^)a@Ox94Mn zyHA}~R*1x{BX+wgx~{skh0b|gCHKRsZ_(k?FMfRfZ9B!{XI9ty2fQ+m`I@_QtvhmG zEtlFQJ(ox5&khHESFIZE@XoaT?!vP*KZxB*j9caQV#xvHJy&cloevD>)PFqV>cyxl zp@;5&kYZhV%D~6;i`Z>br6tm)o*(LBzWOoMuzxR9pY$Mk&N1FMp)SsSn=3ah?LA!4 zr^Jm%=dbMG`#d8{Vs(s)=>PiS{pWFU8GbZ8()Nlj2>E@cM*00IR`L_t(Y$CZ`MPZLoT z#eeTH!_X=Uv5mw;W5R|N3l}69LRhdh^4IdQ(WMJF#;tK>j1U^2w6;R0^Vpm*m&Xk4 z+~lUyym{xIxgY1c5CSvI%{Z?GNM?XK18$##@!BBCBTT(Kk*E3}fC9*Y2{4sE2$0mU z^#W@FZT)7zf&g;hA20?+z>NYGHb51)2bO@RzzXnOz6vZ0WB^%0T31BbvTQ-_jy zh?$qHJHS4$tC#Cq@Ck4LoSXdLs=&@0;6%Az1~!z6g4vb=AAmL8&B`zJQCc!}$Cd)k zYj1(q>Z(*-<-F&yW5d5X?I}2v5FokJi4!DRV!GcfK zN@L)34#A4Sf2va^WdLuY6&m9a@LhrCwLicw-7WPdc$2eIF9yIj;7di?s;mHxG_gY? z0r$o~2)wU0Jd~zvKGHc8;4|=5IUfi-0Ku7M;na>TX-F4%1#AO5n%YIZJ5*gxl)^Kh zCn5VUUM|{1UICUQ1FK@+)$^JP-jjIsq>5K!ePdNI26xf4wxl2J8a*FLYR6T2?kaYu z-9&Z^B?f#duv|Wkf$PAlcBqS{FPPO<)a_8$aQnLopjv=Cyt=Rp%l|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfJx&=WZJ9}@G#&zlWHUn|N}Tg^b5rw5fLsO!=c3fa zlGGH1^30M91$R&1fE2w{cA&VLr;B3<$MxibxWao)jX==Z*r+IQ>_Rz^KLN;gYz6YA Y7?QTJJl div { position:relative } + + #head-logo { + position:absolute; + left:-390px; + top:0; + width:917px; + height:268px; + pointer-events:none; + background:url("images/logo.png") no-repeat; } + #head.docs #head-logo { left:-381px; position:fixed; } + #head.forum #head-logo { left:-370px; } + + #head-logo-link { + position:absolute; + display:block; + top:10px; + left:10px; + width:236px; + height:85px; } + #head.docs #head-logo-link { left:-260px; } + #head.forum #head-logo-link { left:30px; } + + #head-links { position:absolute; right:0; bottom:13px; } + #head.docs #head-links, + #head.forum #head-links { right:20px; } + #head-links > a { + display:block; + float:left; + padding:10px 25px 25px 25px; + color:rgba(255,255,255,.5); + font-size:14pt; + text-decoration:none; + letter-spacing:1px; + background:url("images/head-link.png") no-repeat center bottom; + transition: + color 0.3s ease-in-out, + text-shadow 0.4s ease-in-out; } + #head-links > a:hover, + #head-links > a.active { + color:#1cb3ec; + text-shadow:0 0 4px rgba(28,179,236,.8); + background-image:url("images/head-link_hover.png"); } + + #head-banner { width:200px; height:100px; background:#000; } + +#neck { z-index:0; height:40px; } +#neck.home { height:370px; } +#neck > div { position:relative } + + #glow-arrow { + position:absolute; + top:-9px; + left:0; + right:-16px; + height:48px; + background:url("images/glow-arrow.png") no-repeat right; } + glow-arrow.docs { left:280px; } + + #glow-line-vert { + position:fixed; + top:100px; + left:280px; + width:3px; + height:844px; + background:url("images/glow-line-vert.png") no-repeat; } + + #slideshow { position:absolute; top:10px; left:10px; width:700px; } + #slideshow > div { visibility:hidden; opacity:0; position:absolute; transition:visibility 0s linear 1s, opacity 1s ease-in-out; } + #slideshow > div.active { visibility:visible; opacity:1; transition-delay:0s; } + #slideshow > div.init { transition-delay:0s; } + #slideshow-nav { z-index:3; position:absolute; top:110px;; right:-12px; } + #slideshow-nav > div { margin:5px 0; width:23px; height:23px; background:url("images/slideshow-nav.png") no-repeat; } + #slideshow-nav > div:hover { background-image:url("images/slideshow-nav_active.png"); opacity:0.5; } + #slideshow-nav > div.active { background-image:url("images/slideshow-nav_active.png"); opacity:1; } + + #slide0 { margin:30px 0 0 10px; } + #slide0 > div { float:left; width:320px; font:10pt monospace; } + #slide0 > div:first-child { margin:0 40px 0 0; } + #slide0 > div > h2 { margin:0 0 5px 0; color:rgba(162,198,223,.78); } + #slide0 > div > pre { + margin:0; + padding:15px 10px; + line-height:14pt; + background:rgba(0,0,0,.4); + border-left:8px solid rgba(0,0,0,.3); + box-shadow:1px 2px 16px rgba(28,180,236,.4); } + + #slide1 { margin-top:50px; } + #slide1 > p { + padding:40px 20px 0 20px; + font-style:italic; + color:rgba(162,198,223,.78); + letter-spacing:1px; + line-height:25pt; + background:url("images/quotes.png") top left no-repeat; } + #slide1 > div { + float:right; + margin-right:40px; + font-style:italic; + font-weight:bold; + color:rgba(93,155,199,.44); } + + #sidebar { + z-index:2; + position:absolute; + top:5px; right:0; + width:275px; + height:726px; + padding:210px 0 0 0; + background:url("images/sidebar.png") no-repeat; } + #sidebar > h3 { margin:0 30px 0 30px; color:rgba(255,255,255,.5); } + #sidebar > h3.blue { color:rgba(28,180,236,.5); } + #sidebar-links, + #sidebar-news { + margin:10px 30px 50px 30px; + padding:10px 0; + background:rgba(0,0,0,.6); } + #sidebar-links { box-shadow:1px 2px 12px rgba(255,255,255,.4); } + #sidebar-news { box-shadow:1px 2px 12px rgba(28,180,236,.6); } + #sidebar-links > a { + display:block; + margin-left:15px; + padding:12px 20px 12px 45px; + font-weight:bold; + text-decoration:none; + letter-spacing:1px; + color:rgba(255,255,255,.4); + transition: + color 0.1s ease-in-out, + text-shadow 0.2s ease-in-out; } + #sidebar-news > a { transition: color 0.3s ease-in-out; } + #sidebar-news > a > h4 { transition: color 0.1s ease-in-out, text-shadow 0.2s ease-in-out; } + #sidebar-links > a:hover { color:#fff; text-shadow:0 0 6px #fff; } + #sidebar-news > a { display:block; padding:15px; color:rgba(255,255,255,.4); text-decoration:none; } + #sidebar-news > a > h4 { margin:0 0 5px 0; color:rgba(28,180,236,.5); } + #sidebar-news > a:hover > h4 { margin:0 0 5px 0; color:rgba(28,180,236,.8); text-shadow:0 0 6px rgba(28,180,236,.6); } + #sidebar-news > a:hover { color:rgba(255,255,255,1); } + #sidebar-news > a.blue { color:rgba(28,180,236,.5); font-weight:bold; } + #sidebar-news > a.blue:hover { color:#fff; } + + #link_forum { background:url("images/more-links_forum.png") no-repeat left center; } + #link_github { background:url("images/more-links_github.png") no-repeat left center; } + #link_editors { background:url("images/more-links_editors.png") no-repeat left center; } + #link_aporia { background:url("images/more-links_editors.png") no-repeat left center; } + #link_nimbuild { background:url("images/more-links_nimbuild.png") no-repeat left center; } + + #overview-bg { + position:fixed; + top:0; + bottom:0; + left:0; + width:280px; + background:rgba(0,0,0,0.25); } + #overview { + z-index:3; + position:fixed; + overflow:auto; + top:115px; + bottom:20px; + left:20px; + width:245px; } + #overview::-webkit-scrollbar { width:5px; } + #overview::-webkit-scrollbar-track { border-radius:2px; background:rgba(255,255,255,.03); } + #overview::-webkit-scrollbar-thumb { border-radius:2px; background:rgba(28,179,236,.5); } + #overview > div { overflow:auto; margin-bottom:40px; } + #overview a { + display:block; + padding:0 10px; + margin:2px 5px 2px 0; + color:rgba(255,255,255,.6); + background:rgba(255,255,255,0.03); + border-radius:2px; + letter-spacing:1px; + text-decoration:none; } + #overview a:hover { color:#fff; background:rgba(255,255,255,0.05); } + #overview > .types a { border-left:2px solid rgba(28,179,236,.4); } + #overview > .procs a { border-left:2px solid rgba(255,223,53,.4); } + #overview > .iters a { border-left:2px solid rgba(255,134,53,.4); } + #overview > div > h4 { + margin:0 5px 10px 0; + padding:5px 10px; + letter-spacing:1px; + color:#fff; + border-left:2px solid #fff; + border-radius:2px; + background:rgba(255,255,255,0.1); } + #overview > .types h4 { color:#1cb3ec; border-color:#1cb3ec; } + #overview > .procs h4 { color:#ffdf35; border-color:#ffdf35; } + #overview > .iters h4 { color:#ff8635; border-color:#ff8635; } + #overview h5 { + color:rgba(28,179,236,.6); + margin:10px 0 5px 0; + padding:5px 5px; + letter-spacing:1px; } + +#body { z-index:1; position:relative; background:rgba(220,231,248,.6); } +#body.docs { margin:0 40px 20px 320px; } +#body.forum { margin:0 40px 20px 40px; } + + #body-border { + position:absolute; + top:-25px; + left:0; + right:0; + height:35px; + background:rgba(0,0,0,.25); } + + #body-border-left { + position:absolute; + left:-25px; + top:-25px; + bottom:-25px; + width:35px; + background:rgba(0,0,0,.25); } + + #body-border-right { + position:absolute; + right:-25px; + top:-25px; + bottom:-25px; + width:35px; + background:rgba(0,0,0,.25); } + + #body-border-bottom { + position:absolute; + left:10px; + right:10px; + bottom:-25px; + height:35px; + background:rgba(0,0,0,.25); } + + #body.docs #body-border, + #body.forum #body-border { left:10px; right:10px; } + + #glow-line { + position:absolute; + top:-27px; + left:100px; + right:-25px; + height:3px; + background:url("images/glow-line.png") no-repeat left; } + #glow-line-bottom { + position:absolute; + bottom:-27px; + left:-25px; + right:100px; + height:3px; + background:url("images/glow-line2.png") no-repeat right; } + + #content { padding:40px 0; line-height:150%; } + #content.page { width:680px; min-height:800px; padding-left:20px; } + #content h1 { font-size:20pt; letter-spacing:1px; color:rgba(0,0,0,.75); } + #content h2 { font-size:16pt; letter-spacing:1px; color:rgba(0,0,0,.7); margin-top:40px; } + #content p { text-align:justify; color:rgba(0,0,0,.8); } + #content a { color:#CEDAE9; text-decoration:none; } + #content a:hover { color:#fff; } + #content ul { padding-left:20px; } + #content li { margin-bottom:10px; text-align:justify; } + + #body.docs #content > div { margin-top:40px; padding-top:40px; border-top:1px dashed rgba(0,0,0,.25); } + #body.docs #content > div:first-child { margin-top:0; padding-top:0; border:none; } + #body.docs #content > div > h3 { + color:#fff; + margin:0 0 10px 0; + padding:10px 20px; + letter-spacing:1px; + border-left:8px solid #fff; + border-radius:3px; + background:rgba(0,0,0,.7); + box-shadow:1px 3px 12px rgba(0,0,0,.4); } + #body.docs #content > #types-wrap > h3 { color:#1cb3ec; border-color:#1cb3ec; } + #body.docs #content > #procs-wrap > h3 { color:#ffdf35; border-color:#ffdf35; } + #body.docs #content > #iters-wrap > h3 { color:#ff8635; border-color:#ff8635; } + #body.docs #content > div > div > div { + overflow:auto; + margin:10px 0; + border-left:8px solid #fff; + border-radius:3px; + background:rgba(0,0,0,.1); } + #body.docs #content > #types-wrap > div > div { border-color:rgba(28,179,236,.5); } + #body.docs #content > #procs-wrap > div > div { border-color:rgba(255,223,53,.5); } + #body.docs #content > #iters-wrap > div > div { border-color:rgba(255,134,53,.5); } + #body.docs #content > #procs-wrap > div > div.overload-head { margin-bottom:0; } + #body.docs #content > #procs-wrap > div > div.overload-tail { margin-top:0; border-top:1px dashed rgba(255,223,53,.5); } + #body.docs #content > #procs-wrap > div > div.overload { margin-top:0; margin-bottom:0; border-top:1px dashed rgba(255,223,53,.5); } + #body.docs #content > #iters-wrap > div > div.overload-head { margin-bottom:0; } + #body.docs #content > #iters-wrap > div > div.overload-tail { margin-top:0; border-top:1px dashed rgba(255,134,53,.5); } + #body.docs #content > #iters-wrap > div > div.overload { margin-top:0; margin-bottom:0; border-top:1px dashed rgba(255,134,53,.5); } + #body.docs #content > div > div > p { margin:20px 10px 10px 10px; } + + #body.docs #content > div > div > div > div { float:left; } + #body.docs #content > div > div > div > div.head { width:60%; } + #body.docs #content > div > div > div > div.data { width:40%; } + + #body.docs #content > h1 > .symbol { + padding:0 8px; + border-radius:5px; + background:rgba(206,218,233,.4); } + + #body.docs #content > div > div > div > div.head > .sign { + margin:0 10px 5px 10px; + padding:10px 10px 0 10px; + font-weight:bold; + border-bottom:1px dashed rgba(0,0,0,.25); } + #body.docs #content > div > div > div > div.head > .desc { + padding:0 20px 10px 20px; + color:rgba(0,0,0,.75); } + #body.docs #content > div > #types > div > div.head > .sign > .symbol { + padding:0 5px; + border-radius:3px; + background:rgba(28,179,236,.4); } + #body.docs #content > div > #procs > div > div.head > .sign > .symbol { + padding:0 5px; + border-radius:3px; + background:rgba(255,223,53,.3); } + #body.docs #content > div > #iters > div > div.head > .sign > .symbol { + padding:0 5px; + border-radius:3px; + background:rgba(255,134,53,.3); } + + #body.docs #content > div > div > div > div.data > div { + margin:0 20px 5px 10px; + padding:10px 0 0 10px; + font-style:italic; + color:rgba(0,0,0,.6); + border-bottom:1px dashed rgba(0,0,0,.25); } + #body.docs #content > div > div > div > div.data > ul { margin:0; padding:0 10px; } + #body.docs #content > div > div > div > div.data > ul:last-child { margin-bottom:5px; padding-bottom:10px; } + #body.docs #content > div > div > div > div.data > ul .symbol { padding:0 5px; border-radius:3px; background:rgba(23,192,23,.25); } + #body.docs #content > div > div > div > div.data > ul.pragmas .symbol { background:rgba(106,50,145,.25); } + #body.docs #content > div > div > div > div.data > ul > li { margin:0; padding:0 10px; list-style:none; } + + #body.docs #content pre { + overflow:auto; + margin:10px 0; + padding:15px 10px; + font-size:10pt; + font-style:normal; + line-height:14pt; + background:rgba(0,0,0,.75); + border-left:8px solid rgba(0,0,0,.3); } + + #docs-sort { float:right; font-size:75%; } + #docs-sort > a { + cursor:default; + margin:0 0 0 10px; + padding:2px 10px; + border-radius:5px; + color:rgba(0,0,0,.25); + background:rgba(0,0,0,.1); + box-shadow:inset 0 1px 8px rgba(0,0,0,.4); } + #docs-sort > a:hover, + #docs-sort > a.active { color:#000; background:rgba(0,0,0,.2); } + + #talk-heads { overflow:auto; margin:0 8px 0 8px; } + #talk-heads > div { float:left; font-size:120%; font-weight:bold; } + #talk-heads > .topic { width:55%; } + #talk-heads > .detail { width:15%; } + #talk-heads > .author { width:15%; } + #talk-heads > .reply { width:15%; } + #talk-heads > div > div { margin:0 10px 10px 10px; padding:0 10px 10px 10px; border-bottom:1px dashed rgba(0,0,0,0.4); } + #talk-heads > .topic > div { margin-left:0; } + #talk-heads > .author > div { margin-right:0; } + + #talk-thread > div, + #talk-threads > div { + position:relative; + margin:5px 0; + overflow:auto; + border-radius:3px; + border:8px solid rgba(0,0,0,.8); + border-top:none; + border-bottom:none; + background:rgba(0,0,0,0.1); } + #talk-thread > div:nth-child(odd) { background:rgba(255,255,255,0.1); } + #talk-threads > div:nth-child(odd) { background:rgba(0,0,0,0.2); } + #talk-thread > div > div, + #talk-threads > div > div { float:left; } + #talk-thread > div > div > div, + #talk-threads > div > div > div { margin:10px 20px; } + #talk-threads > div > .topic { width:55%; } + #talk-threads > div > .reply { width:15%; overflow:hidden; } + #talk-threads > div > .detail { width:15%; overflow:hidden; } + #talk-thread > div > .author, + #talk-threads > div > .author { + position:absolute; + right:0; + top:0; + bottom:0; + width:15%; + overflow:hidden; + background:rgba(0,0,0,0.8); } + #talk-thread > div > .author a, + #talk-threads > div > .author a { color:#1cb3ec !important; } + #talk-thread > div > .author a:hover, + #talk-threads > div > .author a:hover { color:#fff !important; } + #talk-threads > div > .topic .pages { float:right; } + #talk-threads > div > .topic > div > a { font-weight:bold; } + #talk-threads > div > .detail > div { float:left; margin:0; } + #talk-threads > div > .detail > div > div { margin-left:20px; padding:10px 10px 10px 22px; } + #talk-threads > div > .detail > div { width:50%; } + #talk-threads > div > .detail > div:first-child > div { background:url("images/forum-views.png") no-repeat left; } + #talk-threads > div > .detail > div:last-child > div { background:url("images/forum-posts.png") no-repeat left; } + + #talk-thread > div { margin:20px 0; min-height:150px; box-shadow:1px 3px 12px rgba(0,0,0,.4) } + #talk-thread > div > .author > div > .avatar { margin-top:20px; } + #talk-thread > div > .author > div > .avatar > img { box-shadow:0 0 12px #1cb3ec; } + #talk-thread > div > .author > div > .name { } + #talk-thread > div > .topic { width:85%; padding-bottom:10px; } + #talk-thread > div > .topic pre { + overflow:auto; + margin:0; + padding:15px 10px; + font-size:10pt; + font-style:normal; + line-height:14pt; + background:rgba(0,0,0,.75); + border-left:8px solid rgba(0,0,0,.3); } + + #talk-head, + #talk-info { + overflow:auto; + border-radius:3px; + border:8px solid rgba(0,0,0,.2); + border-top:none; + border-bottom:none; + background:rgba(0,0,0,0.1); } + #talk-head { margin-bottom:20px; } + #talk-info { margin-top:20px; } + #talk-head > div, + #talk-info > div { float:left; } + #talk-head > .info, + #talk-info > .info { width:85%; } + #talk-head > .user, + #talk-info > .user { width:15%; background:rgba(0,0,0,.2); } + #talk-info > .user > div > .reply { font-weight:bold; padding-left:22px; background:url("images/forum-reply.png") no-repeat left; } + #talk-head > div > div, + #talk-info > div > div { padding:5px 20px; } + #talk-head > .detail > div { float:left; margin:0; } + #talk-head > .detail > div > div { padding-left:22px; } + #talk-head > .detail > div:first-child > div { background:url("images/forum-views.png") no-repeat left; } + #talk-head > .detail > div:last-child > div { background:url("images/forum-posts.png") no-repeat left; } + + #talk-nav { margin:20px 8px 0 8px; padding-top:10px; border-top:1px dashed rgba(0,0,0,0.4); text-align:center; } + #talk-nav > a.active { text-decoration:underline !important; } + + .standout { + padding:5px 30px; + margin-bottom:20px; + border:8px solid rgba(0,0,0,.8); + border-right-width:16px; + border-top-width:0; + border-bottom-width:0; + border-radius:3px; + background:rgba(0,0,0,0.1); + box-shadow:1px 3px 12px rgba(0,0,0,.4); } + .standout h2 { margin-bottom:10px; padding-bottom:10px; border-bottom:1px dashed rgba(0,0,0,.8); } + .standout li { margin:0 !important; padding-top:10px; border-top:1px dashed rgba(0,0,0,.2); } + .standout ul { padding-bottom:5px; } + .standout ul.tools { list-style:url("images/docs-tools.png"); } + .standout ul.library { list-style:url("images/docs-library.png"); } + .standout ul.internal { list-style:url("images/docs-internal.png"); } + .standout ul.tutorial { list-style:url("images/docs-tutorial.png"); } + .standout ul.example { list-style:url("images/docs-example.png"); } + .standout li:first-child { padding-top:0; border-top:none; } + .standout li p { margin:0 0 10px 0 !important; line-height:130%; } + .standout li > a { font-weight:bold; } + + .forum-user-info, + .forum-user-info * { cursor:help } + +#foot { height:150px; position:relative; top:-10px; letter-spacing:1px; } +#foot.home { background:url("images/foot.png") repeat-x top; height:200px; } +#foot.docs { margin-left:320px; margin-right:40px; } +#foot.forum { margin-left:40px; margin-right:40px; } +#foot > div { position:relative; } +#foot.home > div { width:960px; } +#foot h4 { font-size:11pt; color:rgba(255,255,255,.4); margin:40px 0 6px 0; } +#foot a:hover { color:#fff; } + + #foot-links { float:left; } + #foot-links > div { float:left; padding:0 40px 0 0; line-height:120%; } + #foot-links a { display:block; font-size:10pt; color:rgba(255,255,255,.3); text-decoration:none; } + #foot-legal { float:right; font-size:10pt; color:rgba(255,255,255,.3); line-height:150%; text-align:right; } + #foot-legal a { color:inherit; text-decoration:none; } + #foot-legal > h4 > a { color:inherit; } + + #mascot { + z-index:2; + position:absolute; + top:-340px; + right:25px; + width:202px; + height:319px; + background:url("images/mascot.png") no-repeat; } + + +#body pre { + padding:20px; + border-left:10px solid #8f9698; + background:#f3f6f8; + font-size:15px; + font-family:courier, monospace; + letter-spacing:0; + line-height:17px; + color: #343739; } -#site { z-index:0; position:relative; margin:0 auto; width:960px; } -#site > dive { position:relative; } +#body span.pre { + background-color: #8396A4; /* #E6EDF2; */ + padding: 1pt 3pt; + border-radius: 2pt; + -moz-border-radius: 2pt; + -webkit-border-radius: 2pt; +} - /* site_head */ - #site_head { z-index:0; height:200px; } - - #logo { - z-index:-1; - position:absolute; - top:-35px; - left:-330px; - width:868px; - height:334px; - background:url("images/logo.png") no-repeat; - } - - /* site_neck */ - #site_neck { z-index:1; float:left; width:100%; height:40px; background:url("images/site_neck.png") bottom no-repeat; } - - #site_neck > a { - display:block; - float:left; - margin-top:3px; - margin-right:10px; - padding:4px 20px 0 20px; - height:28px; - color:#959a9b; - background:#394649; - font-size:18px; - } - - #site_neck > a:hover { - margin-top:0; - border-top:3px solid #1cb4ec; - } - - #site_neck > a.active { - margin-top:0; - padding-top:7px; - color:#fff; - background:#1cb4ec; - text-shadow:0 0 4px rgba(255,255,255,0.75); - } - - #site_neck > a.active:hover { - border-top:none; - } - - /* site_body */ - #site_body { z-index:2; float:left; clear:both; width:100%; background:#d1dbe3; } - - #page { position:relative; float:left; padding:20px 30px 50px 50px; width:620px; color:#343739; } - - #page h1 { margin-top:40px; line-height: 28px; } - #page h2 { margin-top:40px; } - - #page p { text-align:justify; } - - #page .quote-image { - z-index:0; - position:absolute; - top:15px; - left:20px; - width:59px; - height:42px; - background:url("images/quote.png") no-repeat; - } - - #page p.quote { - position:relative; - color:#6187a2; - font-style:italic; - letter-spacing:2px; - word-spacing:1px; - } - - #page pre { - padding:20px; - border-left:10px solid #8f9698; - background:#f3f6f8; - font-size:15px; - font-family:courier, monospace; - letter-spacing:0; - line-height:17px; - } - - #page span.pre { - background-color: #E6EDF2; - padding: 1pt 3pt; - border-radius: 2pt; - -moz-border-radius: 2pt; - -webkit-border-radius: 2pt; - } - - #page pre > .Comment { color:#858686; font-style:italic; } - #page pre > .Keyword { color:#1cb4ec; font-weight:bold; } - #page pre > .Operator { color:#777; } - #page pre > .StringLit, #page pre > .DecNumber { color:#ff7302; } - - #page li { margin-top:10px; } - - #page a:hover { text-decoration: underline; } - - #page table.docutils { - background: none repeat scroll 0 0 #F3F6F8; - border-collapse: collapse; - font-size: 8pt; - text-align: left; - width: 480px; - border-spacing: 0; - } - - #page .docutils th { - border-bottom: 2px solid #1a1a1a; - font-size: 14px; - font-weight: normal; - padding: 8px 8px; - } - - #page .docutils td { - padding: 3px 8px; - color: #4d4d4d; - } - - #sidebar_wrap { float:right; width:260px; } - #sidebar { - z-index:0; - position:relative; - left:20px; - padding:0 10px 60px 10px; - width:200px; - background:#394649 url("images/sidebar.png") bottom no-repeat; - } - - #sidebar_head { - z-index:-1; - position:absolute; - top:-220px; - left:-30px; - width:282px; - height:400px; - background:url("images/sidebar_head.png") top no-repeat; - } - - #sidebar > h2 { - position:relative; - left:-40px; - margin:20px 0 0 0; - padding:19px 0 0 48px; - width:204px; - height:47px; - color:#fff; - background:url("images/sidebar_h2.png") no-repeat; - text-shadow:0 0 4px rgba(255,255,255,0.75); - letter-spacing:2px; - } - - #sidebar > .news { display:block; margin-bottom:20px; padding:0 10px; } - #sidebar > .news > h3 { margin:0; color:#cdd1d1; font-size:18px; letter-spacing:2px; } - #sidebar > .news > p { margin:0; color:#99a0a1; } - #sidebar > .news:hover > h3 { color:#fff; text-shadow:0 0 4px rgba(255,255,255,0.75); } - #sidebar > .news:hover > p { color:#eee; text-shadow:0 0 4px rgba(255,255,255,0.5); } - - #sidebar > .link { - display:block; - margin:0; - padding:15px 20px 0 20px; - height:41px; - color:#cdd1d1; - font-size:18px; - font-weight:bold; - } - - #sidebar > .link:hover { - color:#fff; - text-shadow:0 0 4px rgba(255,255,255,0.75); - } - - #link_forum { background:url("images/link_forum.png") top right no-repeat; } - #link_aporia { background:url("images/link_aporia.png") top right no-repeat; } - #link_nimbuild { background:url("images/link_nimbuild.png") top right no-repeat; } - - /* site_foot */ - #site_foot { z-index:3; clear:both; padding-top:40px; height:150px; background:url("images/site_foot.png") top no-repeat; } - - #legal { - float:right; - margin-top:10px; - color:#88888f; - font-size:12px; - letter-spacing:1px; - } - - #legal > a { color:#88888f; } - #legal > a:visited { color:#88888f; } - #legal > a:hover { color:#fff; } +#body pre > .Comment { color:#858686; font-style:italic; } +#body pre > .Keyword { color:#1cb4ec; font-weight:bold; } +#body pre > .Operator { color:#777; } +#body pre > .StringLit, #page pre > .DecNumber { color:#ff7302; } + +#body .docutils th { + border-bottom: 2px solid #1A1A1A; + font-weight: normal; + padding: 8px; +} +#body table.docutils { + border-collapse: collapse; + text-align: left; + border-spacing: 0px; +} diff --git a/web/community.txt b/web/community.txt index bac5e0ada..c5b025067 100644 --- a/web/community.txt +++ b/web/community.txt @@ -1,97 +1,114 @@ -Forum -===== +Nim's Community +=============== -The `Nim forum `_ is the place where most -discussions related to the language happen. It not only includes discussions -relating to the design of Nim but also allows for beginners to ask questions -relating to Nim. +.. container:: standout -IRC -==== + Forum + ----- -Many Nim developers are a part of the -`#nim IRC channel `_ on -Freenode. That is the place where the rest of the discussion relating to Nim -occurs. Be sure to join us there if you wish to discuss Nim in real-time. -IRC is the perfect place for people just starting to learn Nim and we -welcome any questions that you may have! + The `Nim forum `_ is the place where most + discussions related to the language happen. It not only includes discussions + relating to the design of Nim but also allows for beginners to ask questions + relating to Nim. -You may also be interested in reading the -`IRC logs `_ which are an archive of all -of the previous discussions that took place in the IRC channel. -Github -====== +.. container:: standout -Nim's `source code `_ is hosted on Github. -Together with the `wiki `_ and -`issue tracker `_. + IRC + ---- -Github also hosts other projects relating to Nim. These projects are a part -of the `nim-lang organisation `_. -This includes the `Babel package manager `_ -and its `package repository `_. + Many Nim developers are a part of the + `#nim IRC channel `_ on + Freenode. That is the place where the rest of the discussion relating to Nim + occurs. Be sure to join us there if you wish to discuss Nim in real-time. + IRC is the perfect place for people just starting to learn Nim and we + welcome any questions that you may have! -Twitter -======= + You may also be interested in reading the + `IRC logs `_ which are an archive of all + of the previous discussions that took place in the IRC channel. -Follow us `@nimlang `_ for latest news about -Nim. -Reddit -====== +.. container:: standout -Subscribe to `/r/nim `_ for latest news about -Nim. + Github + ------ -StackOverflow -============= + Nim's `source code `_ is hosted on Github. + Together with the `wiki `_ and + `issue tracker `_. -When asking a question relating to Nim, be sure to use the -`Nim `_ tag in your -question. + Github also hosts other projects relating to Nim. These projects are a part + of the `nim-lang organisation `_. + This includes the `Babel package manager `_ + and its `package repository `_. -How to help -=========== -There are always many things to be done in the main -`Nim repository `_, check out the -`issues `_ for -things to do; pull requests are always welcome. You can -also contribute to the many other projects hosted by the -`nim-lang `_ organisation on github. If you -can't find anything you fancy doing, you can always ask for inspiration on IRC -(irc.freenode.net #nim) or on the `Nim forums `_. +.. container:: standout -Donations ---------- + Twitter + ------- -If you love what we do and are feeling generous then you can always donate. -Contributions of any quantity are greatly appreciated and will contribute to -making Nim even better! + Follow us `@nimlang `_ for latest news about + Nim. -Gittip -`````` +.. container:: standout - .. raw:: html + Reddit + ------ - + Subscribe to `/r/nim `_ for latest news about + Nim. -Paypal -`````` +.. container:: standout - .. raw:: html + StackOverflow + ------------- -