Merge pull request #1967 from def-/more-renames

More renames
This commit is contained in:
Varriount 2015-01-16 21:27:07 -05:00
commit b828bae80d
25 changed files with 237 additions and 237 deletions

View file

@ -31,13 +31,13 @@ documentation with only their well-documented code.
Example: Example:
.. code-block:: nim .. code-block:: nim
type TPerson* = object type Person* = object
## This type contains a description of a person ## This type contains a description of a person
name: string name: string
age: int age: int
Outputs:: Outputs::
TPerson* = object Person* = object
name: string name: string
age: int age: int
@ -268,8 +268,8 @@ The relationship of type to suffix is made by the proc ``complexName`` in the
``compiler/docgen.nim`` file. Here are some examples of complex names for ``compiler/docgen.nim`` file. Here are some examples of complex names for
symbols in the `system module <system.html>`_. symbols in the `system module <system.html>`_.
* ``type TSignedInt = int | int8 | int16 | int32 | int64`` **=>** * ``type SignedInt = int | int8 | int16 | int32 | int64`` **=>**
`#TSignedInt <system.html#TSignedInt>`_ `#SignedInt <system.html#SignedInt>`_
* ``var globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}`` **=>** * ``var globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}`` **=>**
`#globalRaiseHook <system.html#globalRaiseHook>`_ `#globalRaiseHook <system.html#globalRaiseHook>`_
* ``const NimVersion = "0.0.0"`` **=>** * ``const NimVersion = "0.0.0"`` **=>**
@ -307,7 +307,7 @@ columns is:
Nim's rules (eg. \`^\` like in `the actors module Nim's rules (eg. \`^\` like in `the actors module
<actors.html#^,ptr.TChannel[T]>`_). <actors.html#^,ptr.TChannel[T]>`_).
2. Base filename plus anchor hyper link (eg. 2. Base filename plus anchor hyper link (eg.
``algorithm.html#*,int,TSortOrder``). ``algorithm.html#*,int,SortOrder``).
3. Optional human readable string to display as hyper link. If the value is not 3. Optional human readable string to display as hyper link. If the value is not
present or is the empty string, the hyper link will be rendered present or is the empty string, the hyper link will be rendered
using the term. Prefix whitespace indicates that this entry is using the term. Prefix whitespace indicates that this entry is

View file

@ -173,7 +173,7 @@ The template engine is quite flexible. It is easy to produce a procedure that
writes the template code directly to a file:: writes the template code directly to a file::
#! stdtmpl(emit="f.write") | standard #! stdtmpl(emit="f.write") | standard
#proc writeHTMLPage(f: TFile, title, currentTab, content: string, #proc writeHTMLPage(f: File, title, currentTab, content: string,
# tabs: openArray[string]) = # tabs: openArray[string]) =
<head><title>$title</title></head> <head><title>$title</title></head>
<body> <body>

View file

@ -213,7 +213,7 @@ tab characters (``\t``). The values of each column are:
``proj.symbolName``. ``proj.symbolName``.
4. Type/signature. For variables and enums this will contain the 4. Type/signature. For variables and enums this will contain the
type of the symbol, for procs, methods and templates this will type of the symbol, for procs, methods and templates this will
contain the full unique signature (e.g. ``proc (TFile)``). contain the full unique signature (e.g. ``proc (File)``).
5. Full path to the file containing the symbol. 5. Full path to the file containing the symbol.
6. Line where the symbol is located in the file. Lines start to 6. Line where the symbol is located in the file. Lines start to
count at **1**. count at **1**.
@ -258,8 +258,8 @@ skEnumField
.. code-block:: nim .. code-block:: nim
Open(filename, fmWrite) Open(filename, fmWrite)
--> col 2: system.TFileMode.fmWrite --> col 2: system.FileMode.fmWrite
col 3: TFileMode col 3: FileMode
col 7: "" col 7: ""
@ -296,7 +296,7 @@ posterior instances of the iterator.
text = "some text" text = "some text"
letters = toSeq(runes(text)) letters = toSeq(runes(text))
--> col 2: unicode.runes --> col 2: unicode.runes
col 3: iterator (string): TRune col 3: iterator (string): Rune
col 7: "iterates over any unicode character of the string `s`." col 7: "iterates over any unicode character of the string `s`."
@ -423,7 +423,7 @@ returned by idetools returns also the pragmas for the proc.
.. code-block:: nim .. code-block:: nim
Open(filename, fmWrite) Open(filename, fmWrite)
--> col 2: system.Open --> col 2: system.Open
col 3: proc (var TFile, string, TFileMode, int): bool col 3: proc (var File, string, FileMode, int): bool
col 7: col 7:
"Opens a file named `filename` with given `mode`. "Opens a file named `filename` with given `mode`.
@ -487,9 +487,9 @@ skType
.. code-block:: nim .. code-block:: nim
proc writeTempFile() = proc writeTempFile() =
var output: TFile var output: File
--> col 2: system.TFile --> col 2: system.File
col 3: TFile col 3: File
col 7: "" col 7: ""
@ -502,11 +502,11 @@ skVar
.. code-block:: nim .. code-block:: nim
proc writeTempFile() = proc writeTempFile() =
var output: TFile var output: File
output.open("/tmp/somefile", fmWrite) output.open("/tmp/somefile", fmWrite)
output.write("test") output.write("test")
--> col 2: $MODULE.writeTempFile.output --> col 2: $MODULE.writeTempFile.output
col 3: TFile col 3: File
col 7: "" col 7: ""

View file

@ -29,9 +29,9 @@ compatibility:
.. code-block:: nim .. code-block:: nim
type type
TCallback = proc (s: string) {.raises: [IOError].} Callback = proc (s: string) {.raises: [IOError].}
var var
c: TCallback c: Callback
proc p(x: string) = proc p(x: string) =
raise newException(OSError, "OS") raise newException(OSError, "OS")

View file

@ -57,7 +57,7 @@ instructs the compiler to pass the type by value to procs:
.. code-block:: nim .. code-block:: nim
type type
TVector {.bycopy, pure.} = object Vector {.bycopy, pure.} = object
x, y, z: float x, y, z: float

View file

@ -9,17 +9,17 @@ The following example shows a generic binary tree can be modelled:
.. code-block:: nim .. code-block:: nim
type type
TBinaryTree[T] = object # TBinaryTree is a generic type with BinaryTreeObj[T] = object # BinaryTreeObj is a generic type with
# with generic param ``T`` # with generic param ``T``
le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil le, ri: BinaryTree[T] # left and right subtrees; may be nil
data: T # the data stored in a node data: T # the data stored in a node
PBinaryTree[T] = ref TBinaryTree[T] # a shorthand for notational convenience BinaryTree[T] = ref BinaryTreeObj[T] # a shorthand for notational convenience
proc newNode[T](data: T): PBinaryTree[T] = # constructor for a node proc newNode[T](data: T): BinaryTree[T] = # constructor for a node
new(result) new(result)
result.data = data result.data = data
proc add[T](root: var PBinaryTree[T], n: PBinaryTree[T]) = proc add[T](root: var BinaryTree[T], n: BinaryTree[T]) =
if root == nil: if root == nil:
root = n root = n
else: else:
@ -40,7 +40,7 @@ The following example shows a generic binary tree can be modelled:
return return
it = it.ri it = it.ri
iterator inorder[T](root: PBinaryTree[T]): T = iterator inorder[T](root: BinaryTree[T]): T =
# inorder traversal of a binary tree # inorder traversal of a binary tree
# recursive iterators are not yet implemented, so this does not work in # recursive iterators are not yet implemented, so this does not work in
# the current compiler! # the current compiler!
@ -49,7 +49,7 @@ The following example shows a generic binary tree can be modelled:
if root.ri != nil: yield inorder(root.ri) if root.ri != nil: yield inorder(root.ri)
var var
root: PBinaryTree[string] # instantiate a PBinaryTree with the type string root: BinaryTree[string] # instantiate a BinaryTree with the type string
add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and
add(root, newNode("world")) # ``add`` add(root, newNode("world")) # ``add``
for str in inorder(root): for str in inorder(root):
@ -64,10 +64,10 @@ therefore very useful for type specialization within generic code:
.. code-block:: nim .. code-block:: nim
type type
TTable[TKey, TValue] = object Table[Key, Value] = object
keys: seq[TKey] keys: seq[Key]
values: seq[TValue] values: seq[Value]
when not (TKey is string): # nil value for strings used for optimization when not (Key is string): # nil value for strings used for optimization
deletedKeys: seq[bool] deletedKeys: seq[bool]
@ -127,9 +127,9 @@ more complex type classes:
.. code-block:: nim .. code-block:: nim
# create a type class that will match all tuple and object types # create a type class that will match all tuple and object types
type TRecordType = tuple or object type RecordType = tuple or object
proc printFields(rec: TRecordType) = proc printFields(rec: RecordType) =
for key, value in fieldPairs(rec): for key, value in fieldPairs(rec):
echo key, " = ", value echo key, " = ", value
@ -175,11 +175,11 @@ type parameters of the matched generic type. They can be easily accessed using
the dot syntax: the dot syntax:
.. code-block:: nim .. code-block:: nim
type TMatrix[T, Rows, Columns] = object type Matrix[T, Rows, Columns] = object
... ...
proc `[]`(m: TMatrix, row, col: int): TMatrix.T = proc `[]`(m: Matrix, row, col: int): Matrix.T =
m.data[col * high(TMatrix.Columns) + row] m.data[col * high(Matrix.Columns) + row]
Alternatively, the `type` operator can be used over the proc params for similar Alternatively, the `type` operator can be used over the proc params for similar
effect when anonymous or distinct type classes are used. effect when anonymous or distinct type classes are used.
@ -195,7 +195,7 @@ type, this results in another more specific type class:
# seq[T1] is the same as just `seq`, but T1 will be allowed to bind # 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 # to a single type, while the signature is being matched
TMatrix[Ordinal] # Any TMatrix instantiation using integer values Matrix[Ordinal] # Any Matrix instantiation using integer values
As seen in the previous example, in such instantiations, it's not necessary to 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 supply all type parameters of the generic type, because any missing ones will
@ -292,18 +292,18 @@ at definition and the context at instantiation are considered:
.. code-block:: nim .. code-block:: nim
type type
TIndex = distinct int Index = distinct int
proc `==` (a, b: TIndex): bool {.borrow.} proc `==` (a, b: Index): bool {.borrow.}
var a = (0, 0.TIndex) var a = (0, 0.Index)
var b = (0, 0.TIndex) var b = (0, 0.Index)
echo a == b # works! echo a == b # works!
In the example the generic ``==`` for tuples (as defined in the system module) In the example the generic ``==`` for tuples (as defined in the system module)
uses the ``==`` operators of the tuple's components. However, the ``==`` for uses the ``==`` operators of the tuple's components. However, the ``==`` for
the ``TIndex`` type is defined *after* the ``==`` for tuples; yet the example the ``Index`` type is defined *after* the ``==`` for tuples; yet the example
compiles as the instantiation takes the currently defined symbols into account compiles as the instantiation takes the currently defined symbols into account
too. too.

View file

@ -261,9 +261,9 @@ 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 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 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 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` ``set[char]`` efficiently as many algorithms rely on this feature. The `Rune`
type is used for Unicode characters, it can represent any Unicode character. type is used for Unicode characters, it can represent any Unicode character.
``TRune`` is declared in the `unicode module <unicode.html>`_. ``Rune`` is declared in the `unicode module <unicode.html>`_.
Numerical constants Numerical constants

View file

@ -128,22 +128,22 @@ modules don't need to import a module's dependencies:
.. code-block:: nim .. code-block:: nim
# module B # module B
type TMyObject* = object type MyObject* = object
.. code-block:: nim .. code-block:: nim
# module A # module A
import B import B
export B.TMyObject export B.MyObject
proc `$`*(x: TMyObject): string = "my object" proc `$`*(x: MyObject): string = "my object"
.. code-block:: nim .. code-block:: nim
# module C # module C
import A import A
# B.TMyObject has been imported implicitly here: # B.MyObject has been imported implicitly here:
var x: TMyObject var x: MyObject
echo($x) echo($x)

View file

@ -89,12 +89,12 @@ collector to not consider objects of this type as part of a cycle:
.. code-block:: nim .. code-block:: nim
type type
PNode = ref TNode Node = ref NodeObj
TNode {.acyclic, final.} = object NodeObj {.acyclic, final.} = object
left, right: PNode left, right: Node
data: string data: string
In the example a tree structure is declared with the ``TNode`` type. Note that In the example a tree structure is declared with the ``Node`` type. Note that
the type definition is recursive and the GC has to assume that objects of 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 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 information that this cannot happen to the GC. If the programmer uses the
@ -106,9 +106,9 @@ memory, but nothing worse happens.
.. code-block:: nim .. code-block:: nim
type type
PNode = acyclic ref TNode Node = acyclic ref NodeObj
TNode = object NodeObj = object
left, right: PNode left, right: Node
data: string data: string
@ -129,13 +129,13 @@ structure:
.. code-block:: nim .. code-block:: nim
type type
TNodeKind = enum nkLeaf, nkInner NodeKind = enum nkLeaf, nkInner
TNode {.final, shallow.} = object Node {.final, shallow.} = object
case kind: TNodeKind case kind: NodeKind
of nkLeaf: of nkLeaf:
strVal: string strVal: string
of nkInner: of nkInner:
children: seq[TNode] children: seq[Node]
pure pragma pure pragma

View file

@ -121,21 +121,21 @@ different; for this a special setter syntax is needed:
.. code-block:: nim .. code-block:: nim
type type
TSocket* = object of TObject Socket* = object of RootObj
FHost: int # cannot be accessed from the outside of the module FHost: int # cannot be accessed from the outside of the module
# the `F` prefix is a convention to avoid clashes since # the `F` prefix is a convention to avoid clashes since
# the accessors are named `host` # the accessors are named `host`
proc `host=`*(s: var TSocket, value: int) {.inline.} = proc `host=`*(s: var Socket, value: int) {.inline.} =
## setter of hostAddr ## setter of hostAddr
s.FHost = value s.FHost = value
proc host*(s: TSocket): int {.inline.} = proc host*(s: Socket): int {.inline.} =
## getter of hostAddr ## getter of hostAddr
s.FHost s.FHost
var var
s: TSocket s: Socket
s.host = 34 # same as `host=`(s, 34) s.host = 34 # same as `host=`(s, 34)

View file

@ -118,11 +118,11 @@ initialized and does not rely on syntactic properties:
.. code-block:: nim .. code-block:: nim
type type
TMyObject = object {.requiresInit.} MyObject = object {.requiresInit.}
proc p() = proc p() =
# the following is valid: # the following is valid:
var x: TMyObject var x: MyObject
if someCondition(): if someCondition():
x = a() x = a()
else: else:

View file

@ -67,7 +67,7 @@ special ``:`` syntax:
.. code-block:: nim .. code-block:: nim
template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} = template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} =
var f: TFile var f: File
if open(f, fn, mode): if open(f, fn, mode):
try: try:
actions actions
@ -140,12 +140,12 @@ shadowed by the same argument name even when fully qualified:
# module 'm' # module 'm'
type type
TLev = enum Lev = enum
levA, levB levA, levB
var abclev = levB var abclev = levB
template tstLev(abclev: TLev) = template tstLev(abclev: Lev) =
echo abclev, " ", m.abclev echo abclev, " ", m.abclev
tstLev(levA) tstLev(levA)
@ -157,12 +157,12 @@ But the global symbol can properly be captured by a ``bind`` statement:
# module 'm' # module 'm'
type type
TLev = enum Lev = enum
levA, levB levA, levB
var abclev = levB var abclev = levB
template tstLev(abclev: TLev) = template tstLev(abclev: Lev) =
bind m.abclev bind m.abclev
echo abclev, " ", m.abclev echo abclev, " ", m.abclev
@ -202,7 +202,7 @@ template parameter, it is an inject'ed symbol:
.. code-block:: nim .. code-block:: nim
template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} = template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} =
block: block:
var f: TFile # since 'f' is a template param, it's injected implicitly var f: File # since 'f' is a template param, it's injected implicitly
... ...
withFile(txt, "ttempl3.txt", fmWrite): withFile(txt, "ttempl3.txt", fmWrite):

View file

@ -223,21 +223,21 @@ all the arguments, but also the matched operators in reverse polish notation:
import macros import macros
type type
TMatrix = object Matrix = object
dummy: int dummy: int
proc `*`(a, b: TMatrix): TMatrix = discard proc `*`(a, b: Matrix): Matrix = discard
proc `+`(a, b: TMatrix): TMatrix = discard proc `+`(a, b: Matrix): Matrix = discard
proc `-`(a, b: TMatrix): TMatrix = discard proc `-`(a, b: Matrix): Matrix = discard
proc `$`(a: TMatrix): string = result = $a.dummy proc `$`(a: Matrix): string = result = $a.dummy
proc mat21(): TMatrix = proc mat21(): Matrix =
result.dummy = 21 result.dummy = 21
macro optM{ (`+`|`-`|`*`) ** a }(a: TMatrix): expr = macro optM{ (`+`|`-`|`*`) ** a }(a: Matrix): expr =
echo treeRepr(a) echo treeRepr(a)
result = newCall(bindSym"mat21") result = newCall(bindSym"mat21")
var x, y, z: TMatrix var x, y, z: Matrix
echo x + y * z - x echo x + y * z - x
@ -267,7 +267,7 @@ parameter is of the type ``varargs`` it is treated specially and it can match
template optWrite{ template optWrite{
write(f, x) write(f, x)
((write|writeln){w})(f, y) ((write|writeln){w})(f, y)
}(x, y: varargs[expr], f: TFile, w: expr) = }(x, y: varargs[expr], f: File, w: expr) =
w(f, x, y) w(f, x, y)
@ -294,7 +294,7 @@ The following example shows how some form of hoisting can be implemented:
.. code-block:: nim .. code-block:: nim
import pegs import pegs
template optPeg{peg(pattern)}(pattern: string{lit}): TPeg = template optPeg{peg(pattern)}(pattern: string{lit}): Peg =
var gl {.global, gensym.} = peg(pattern) var gl {.global, gensym.} = peg(pattern)
gl gl
@ -341,21 +341,21 @@ The ``call`` constraint is particularly useful to implement a move
optimization for types that have copying semantics: optimization for types that have copying semantics:
.. code-block:: nim .. code-block:: nim
proc `[]=`*(t: var TTable, key: string, val: string) = proc `[]=`*(t: var Table, key: string, val: string) =
## puts a (key, value)-pair into `t`. The semantics of string require ## puts a (key, value)-pair into `t`. The semantics of string require
## a copy here: ## a copy here:
let idx = findInsertionPosition(key) let idx = findInsertionPosition(key)
t[idx] = key t[idx] = key
t[idx] = val t[idx] = val
proc `[]=`*(t: var TTable, key: string{call}, val: string{call}) = proc `[]=`*(t: var Table, key: string{call}, val: string{call}) =
## puts a (key, value)-pair into `t`. Optimized version that knows that ## puts a (key, value)-pair into `t`. Optimized version that knows that
## the strings are unique and thus don't need to be copied: ## the strings are unique and thus don't need to be copied:
let idx = findInsertionPosition(key) let idx = findInsertionPosition(key)
shallowCopy t[idx], key shallowCopy t[idx], key
shallowCopy t[idx], val shallowCopy t[idx], val
var t: TTable var t: Table
# overloading resolution ensures that the optimized []= is called here: # overloading resolution ensures that the optimized []= is called here:
t[f()] = g() t[f()] = g()

View file

@ -49,17 +49,17 @@ can then only be used in *destructible contexts* and as parameters:
.. code-block:: nim .. code-block:: nim
type type
TMyObj = object MyObj = object
x, y: int x, y: int
p: pointer p: pointer
proc destroy(o: var TMyObj) {.override.} = proc destroy(o: var MyObj) {.override.} =
if o.p != nil: dealloc o.p if o.p != nil: dealloc o.p
proc open: TMyObj = proc open: MyObj =
result = TMyObj(x: 1, y: 2, p: alloc(3)) result = MyObj(x: 1, y: 2, p: alloc(3))
proc work(o: TMyObj) = proc work(o: MyObj) =
echo o.x echo o.x
# No destructor invoked here for 'o' as 'o' is a parameter. # No destructor invoked here for 'o' as 'o' is a parameter.

View file

@ -5,15 +5,15 @@ Example:
.. code-block:: nim .. code-block:: nim
type # example demonstrating mutually recursive types type # example demonstrating mutually recursive types
PNode = ref TNode # a traced pointer to a TNode Node = ref NodeObj # a traced pointer to a NodeObj
TNode = object NodeObj = object
le, ri: PNode # left and right subtrees le, ri: Node # left and right subtrees
sym: ref TSym # leaves contain a reference to a TSym sym: ref Sym # leaves contain a reference to a Sym
TSym = object # a symbol Sym = object # a symbol
name: string # the symbol's name name: string # the symbol's name
line: int # the line the symbol was declared in line: int # the line the symbol was declared in
code: PNode # the symbol's abstract syntax tree code: Node # the symbol's abstract syntax tree
A type section begins with the ``type`` keyword. It contains multiple A type section begins with the ``type`` keyword. It contains multiple
type definitions. A type definition binds a type to a name. Type definitions type definitions. A type definition binds a type to a name. Type definitions

View file

@ -10,7 +10,7 @@ As their name suggests, static params must be known at compile-time:
.. code-block:: nim .. code-block:: nim
proc precompiledRegex(pattern: static[string]): TRegEx = proc precompiledRegex(pattern: static[string]): RegEx =
var res {.global.} = re(pattern) var res {.global.} = re(pattern)
return res return res
@ -35,7 +35,7 @@ predicate:
# The following proc will be compiled once for each unique static # The following proc will be compiled once for each unique static
# value and also once for the case handling all run-time values: # value and also once for the case handling all run-time values:
proc re(pattern: semistatic[string]): TRegEx = proc re(pattern: semistatic[string]): RegEx =
when isStatic(pattern): when isStatic(pattern):
result = precompiledRegex(pattern) result = precompiledRegex(pattern)
else: else:
@ -74,8 +74,8 @@ instantiation type using the param name:
echo "allocating ", T.name echo "allocating ", T.name
new(result) new(result)
var n = TNode.new var n = Node.new
var tree = new(TBinaryTree[int]) var tree = new(BinaryTree[int])
When multiple typedesc params are present, they act like a distinct type class 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 (i.e. they will bind freely to different types). To force a bind-once behavior

View file

@ -257,8 +257,8 @@ the resulting programs will still handle UTF-8 properly as UTF-8 was specially
designed for this. designed for this.
Another reason is that Nim 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 ``set[char]`` efficiently as many algorithms rely on this feature. The
`TRune` type is used for Unicode characters, it can represent any Unicode `Rune` type is used for Unicode characters, it can represent any Unicode
character. ``TRune`` is declared in the `unicode module <unicode.html>`_. character. ``Rune`` is declared in the `unicode module <unicode.html>`_.
@ -591,38 +591,38 @@ An example:
# This is an example how an abstract syntax tree could be modelled in Nim # This is an example how an abstract syntax tree could be modelled in Nim
type type
TNodeKind = enum # the different node types NodeKind = enum # the different node types
nkInt, # a leaf with an integer value nkInt, # a leaf with an integer value
nkFloat, # a leaf with a float value nkFloat, # a leaf with a float value
nkString, # a leaf with a string value nkString, # a leaf with a string value
nkAdd, # an addition nkAdd, # an addition
nkSub, # a subtraction nkSub, # a subtraction
nkIf # an if statement nkIf # an if statement
PNode = ref TNode Node = ref NodeObj
TNode = object NodeObj = object
case kind: TNodeKind # the ``kind`` field is the discriminator case kind: NodeKind # the ``kind`` field is the discriminator
of nkInt: intVal: int of nkInt: intVal: int
of nkFloat: floatVal: float of nkFloat: floatVal: float
of nkString: strVal: string of nkString: strVal: string
of nkAdd, nkSub: of nkAdd, nkSub:
leftOp, rightOp: PNode leftOp, rightOp: Node
of nkIf: of nkIf:
condition, thenPart, elsePart: PNode condition, thenPart, elsePart: Node
# create a new case object: # create a new case object:
var n = PNode(kind: nkIf, condition: nil) var n = Node(kind: nkIf, condition: nil)
# accessing n.thenPart is valid because the ``nkIf`` branch is active: # accessing n.thenPart is valid because the ``nkIf`` branch is active:
n.thenPart = PNode(kind: nkFloat, floatVal: 2.0) n.thenPart = Node(kind: nkFloat, floatVal: 2.0)
# the following statement raises an `EInvalidField` exception, because # the following statement raises an `FieldError` exception, because
# n.kind's value does not fit and the ``nkString`` branch is not active: # n.kind's value does not fit and the ``nkString`` branch is not active:
n.strVal = "" n.strVal = ""
# invalid: would change the active object branch: # invalid: would change the active object branch:
n.kind = nkInt n.kind = nkInt
var x = PNode(kind: nkAdd, leftOp: PNode(kind: nkInt, intVal: 4), var x = Node(kind: nkAdd, leftOp: Node(kind: nkInt, intVal: 4),
rightOp: PNode(kind: nkInt, intVal: 2)) rightOp: Node(kind: nkInt, intVal: 2))
# valid: does not change the active object branch: # valid: does not change the active object branch:
x.kind = nkSub x.kind = nkSub
@ -672,13 +672,13 @@ dereferencing operations for reference types:
.. code-block:: nim .. code-block:: nim
type type
PNode = ref TNode Node = ref NodeObj
TNode = object NodeObj = object
le, ri: PNode le, ri: Node
data: int data: int
var var
n: PNode n: Node
new(n) new(n)
n.data = 9 n.data = 9
# no need to write n[].data; in fact n[].data is highly discouraged! # no need to write n[].data; in fact n[].data is highly discouraged!
@ -717,10 +717,10 @@ memory manually:
.. code-block:: nim .. code-block:: nim
type type
TData = tuple[x, y: int, s: string] Data = tuple[x, y: int, s: string]
# allocate memory for TData on the heap: # allocate memory for Data on the heap:
var d = cast[ptr TData](alloc0(sizeof(TData))) var d = cast[ptr Data](alloc0(sizeof(Data)))
# create a new string on the garbage collected heap: # create a new string on the garbage collected heap:
d.s = "abc" d.s = "abc"
@ -736,7 +736,7 @@ 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 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 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 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 pointer) as if it would have the type ``ptr Data``. Casting should only be
done if it is unavoidable: it breaks type safety and bugs can lead to done if it is unavoidable: it breaks type safety and bugs can lead to
mysterious crashes. mysterious crashes.
@ -855,13 +855,13 @@ Examples:
.. code-block:: nim .. code-block:: nim
type type
TOnMouseMove = proc (x, y: int) {.closure.} OnMouseMove = proc (x, y: int) {.closure.}
proc onMouseMove(mouseX, mouseY: int) = proc onMouseMove(mouseX, mouseY: int) =
# has default calling convention # has default calling convention
echo "x: ", mouseX, " y: ", mouseY echo "x: ", mouseX, " y: ", mouseY
proc setOnMouseMove(mouseMoveEvent: TOnMouseMove) = discard proc setOnMouseMove(mouseMoveEvent: OnMouseMove) = discard
# ok, 'onMouseMove' has the default calling convention, which is compatible # ok, 'onMouseMove' has the default calling convention, which is compatible
# to 'closure': # to 'closure':
@ -962,33 +962,33 @@ types are a perfect tool to model different currencies:
.. code-block:: nim .. code-block:: nim
type type
TDollar = distinct int Dollar = distinct int
TEuro = distinct int Euro = distinct int
var var
d: TDollar d: Dollar
e: TEuro e: Euro
echo d + 12 echo d + 12
# Error: cannot add a number with no unit and a ``TDollar`` # Error: cannot add a number with no unit and a ``Dollar``
Unfortunately, ``d + 12.TDollar`` is not allowed either, Unfortunately, ``d + 12.Dollar`` is not allowed either,
because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So because ``+`` is defined for ``int`` (among others), not for ``Dollar``. So
a ``+`` for dollars needs to be defined: a ``+`` for dollars needs to be defined:
.. code-block:: .. code-block::
proc `+` (x, y: TDollar): TDollar = proc `+` (x, y: Dollar): Dollar =
result = TDollar(int(x) + int(y)) result = Dollar(int(x) + int(y))
It does not make sense to multiply a dollar with a dollar, but with a It does not make sense to multiply a dollar with a dollar, but with a
number without unit; and the same holds for division: number without unit; and the same holds for division:
.. code-block:: .. code-block::
proc `*` (x: TDollar, y: int): TDollar = proc `*` (x: Dollar, y: int): Dollar =
result = TDollar(int(x) * y) result = Dollar(int(x) * y)
proc `*` (x: int, y: TDollar): TDollar = proc `*` (x: int, y: Dollar): Dollar =
result = TDollar(x * int(y)) result = Dollar(x * int(y))
proc `div` ... proc `div` ...
@ -999,15 +999,15 @@ The pragma `borrow`:idx: has been designed to solve this problem; in principle
it generates the above trivial implementations: it generates the above trivial implementations:
.. code-block:: nim .. code-block:: nim
proc `*` (x: TDollar, y: int): TDollar {.borrow.} proc `*` (x: Dollar, y: int): Dollar {.borrow.}
proc `*` (x: int, y: TDollar): TDollar {.borrow.} proc `*` (x: int, y: Dollar): Dollar {.borrow.}
proc `div` (x: TDollar, y: int): TDollar {.borrow.} proc `div` (x: Dollar, y: int): Dollar {.borrow.}
The ``borrow`` pragma makes the compiler use the same implementation as 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 the proc that deals with the distinct type's base type, so no code is
generated. generated.
But it seems all this boilerplate code needs to be repeated for the ``TEuro`` But it seems all this boilerplate code needs to be repeated for the ``Euro``
currency. This can be solved with templates_. currency. This can be solved with templates_.
.. code-block:: nim .. code-block:: nim
@ -1037,8 +1037,8 @@ currency. This can be solved with templates_.
multiplicative(typ, base) multiplicative(typ, base)
comparable(typ) comparable(typ)
defineCurrency(TDollar, int) defineCurrency(Dollar, int)
defineCurrency(TEuro, int) defineCurrency(Euro, int)
The borrow pragma can also be used to annotate the distinct type to allow The borrow pragma can also be used to annotate the distinct type to allow
@ -1071,7 +1071,7 @@ values is vulnerable to the famous `SQL injection attack`:idx:\:
.. code-block:: nim .. code-block:: nim
import strutils import strutils
proc query(db: TDbHandle, statement: string) = ... proc query(db: DbHandle, statement: string) = ...
var var
username: string username: string
@ -1081,13 +1081,13 @@ values is vulnerable to the famous `SQL injection attack`:idx:\:
This can be avoided by distinguishing strings that contain SQL from strings 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 that don't. Distinct types provide a means to introduce a new string type
``TSQL`` that is incompatible with ``string``: ``SQL`` that is incompatible with ``string``:
.. code-block:: nim .. code-block:: nim
type type
TSQL = distinct string SQL = distinct string
proc query(db: TDbHandle, statement: TSQL) = ... proc query(db: DbHandle, statement: SQL) = ...
var var
username: string username: string
@ -1098,28 +1098,28 @@ that don't. Distinct types provide a means to introduce a new string type
It is an essential property of abstract types that they **do not** imply a 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 subtype relation between the abtract type and its base type. Explict type
conversions from ``string`` to ``TSQL`` are allowed: conversions from ``string`` to ``SQL`` are allowed:
.. code-block:: nim .. code-block:: nim
import strutils, sequtils import strutils, sequtils
proc properQuote(s: string): TSQL = proc properQuote(s: string): SQL =
# quotes a string properly for an SQL statement # quotes a string properly for an SQL statement
return TSQL(s) return SQL(s)
proc `%` (frmt: TSQL, values: openarray[string]): TSQL = proc `%` (frmt: SQL, values: openarray[string]): SQL =
# quote each argument: # quote each argument:
let v = values.mapIt(TSQL, properQuote(it)) let v = values.mapIt(SQL, properQuote(it))
# we need a temporary type for the type conversion :-( # we need a temporary type for the type conversion :-(
type TStrSeq = seq[string] type StrSeq = seq[string]
# call strutils.`%`: # call strutils.`%`:
result = TSQL(string(frmt) % TStrSeq(v)) result = SQL(string(frmt) % StrSeq(v))
db.query("SELECT FROM users WHERE name = '$1'".TSQL % [username]) db.query("SELECT FROM users WHERE name = '$1'".SQL % [username])
Now we have compile-time checking against SQL injection attacks. Since Now we have compile-time checking against SQL injection attacks. Since
``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed for nice ``"".SQL`` is transformed to ``SQL("")`` no new syntax is needed for nice
looking ``TSQL`` string literals. The hypothetical ``TSQL`` type actually looking ``SQL`` string literals. The hypothetical ``SQL`` type actually
exists in the library as the `TSqlQuery type <db_sqlite.html#TSqlQuery>`_ of exists in the library as the `TSqlQuery type <db_sqlite.html#TSqlQuery>`_ of
modules like `db_sqlite <db_sqlite.html>`_. modules like `db_sqlite <db_sqlite.html>`_.

View file

@ -311,8 +311,8 @@ underlying C ``struct`` in a ``sizeof`` expression:
.. code-block:: Nim .. code-block:: Nim
type type
TDIR* {.importc: "DIR", header: "<dirent.h>", DIR* {.importc: "DIR", header: "<dirent.h>",
final, pure, incompleteStruct.} = object final, pure, incompleteStruct.} = object
Compile pragma Compile pragma
@ -418,8 +418,8 @@ interfacing with libraries written in C++:
irr = "<irrlicht/irrlicht.h>" irr = "<irrlicht/irrlicht.h>"
type type
TIrrlichtDevice {.final, header: irr, importc: "IrrlichtDevice".} = object IrrlichtDeviceObj {.final, header: irr, importc: "IrrlichtDevice".} = object
PIrrlichtDevice = ptr TIrrlichtDevice IrrlichtDevice = ptr IrrlichtDeviceObj
proc createDevice(): PIrrlichtDevice {. proc createDevice(): PIrrlichtDevice {.
header: irr, importc: "createDevice".} header: irr, importc: "createDevice".}
@ -465,11 +465,11 @@ allows *sloppy* interfacing with libraries written in Objective C:
""".} """.}
type type
TId {.importc: "id", header: "<objc/Object.h>", final.} = distinct int Id {.importc: "id", header: "<objc/Object.h>", final.} = distinct int
proc newGreeter: TId {.importobjc: "Greeter new", nodecl.} proc newGreeter: Id {.importobjc: "Greeter new", nodecl.}
proc greet(self: TId, x, y: int) {.importobjc: "greet", nodecl.} proc greet(self: Id, x, y: int) {.importobjc: "greet", nodecl.}
proc free(self: TId) {.importobjc: "free", nodecl.} proc free(self: Id) {.importobjc: "free", nodecl.}
var g = newGreeter() var g = newGreeter()
g.greet(12, 34) g.greet(12, 34)

View file

@ -213,7 +213,7 @@ example ``*`` should not be greedy, so ``\[.*?\]`` should be used instead.
PEG construction PEG construction
---------------- ----------------
There are two ways to construct a PEG in Nim 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 (1) Parsing a string into an AST which consists of `Peg` nodes with the
`peg` proc. `peg` proc.
(2) Constructing the AST directly with proc calls. This method does not (2) Constructing the AST directly with proc calls. This method does not
support constructing rules, only simple expressions and is not as support constructing rules, only simple expressions and is not as

View file

@ -8,9 +8,9 @@ can also be used to include elements (and ranges of elements):
.. code-block:: nim .. code-block:: nim
type type
TCharSet = set[char] CharSet = set[char]
var var
x: TCharSet x: CharSet
x = {'a'..'z', '0'..'9'} # This constructs a set that contains the x = {'a'..'z', '0'..'9'} # This constructs a set that contains the
# letters from 'a' to 'z' and the digits # letters from 'a' to 'z' and the digits
# from '0' to '9' # from '0' to '9'

View file

@ -1350,11 +1350,11 @@ integer.
.. code-block:: nim .. code-block:: nim
type type
TPerson = tuple[name: string, age: int] # type representing a person: Person = tuple[name: string, age: int] # type representing a person:
# a person consists of a name # a person consists of a name
# and an age # and an age
var var
person: TPerson person: Person
person = (name: "Peter", age: 30) person = (name: "Peter", age: 30)
# the same, but less readable: # the same, but less readable:
person = ("Peter", 30) person = ("Peter", 30)
@ -1373,7 +1373,7 @@ integer.
# The following line does not compile, they are different tuples! # The following line does not compile, they are different tuples!
#person = building #person = building
# --> Error: type mismatch: got (tuple[street: string, number: int]) # --> Error: type mismatch: got (tuple[street: string, number: int])
# but expected 'TPerson' # but expected 'Person'
# The following works because the field names and types are the same. # The following works because the field names and types are the same.
var teacher: tuple[name: string, age: int] = ("Mark", 42) var teacher: tuple[name: string, age: int] = ("Mark", 42)

View file

@ -56,19 +56,19 @@ Objects have access to their type at runtime. There is an
.. code-block:: nim .. code-block:: nim
type type
TPerson = object of RootObj Person = object of RootObj
name*: string # the * means that `name` is accessible from other modules name*: string # the * means that `name` is accessible from other modules
age: int # no * means that the field is hidden from other modules age: int # no * means that the field is hidden from other modules
TStudent = object of TPerson # TStudent inherits from TPerson Student = object of Person # Student inherits from Person
id: int # with an id field id: int # with an id field
var var
student: TStudent student: Student
person: TPerson person: Person
assert(student of TStudent) # is true assert(student of Student) # is true
# object construction: # object construction:
student = TStudent(name: "Anton", age: 5, id: 2) student = Student(name: "Anton", age: 5, id: 2)
Object fields that should be visible from outside the defining module have to Object fields that should be visible from outside the defining module have to
be marked by ``*``. In contrast to tuples, different object types are be marked by ``*``. In contrast to tuples, different object types are
@ -100,15 +100,15 @@ Example:
.. code-block:: nim .. code-block:: nim
type type
PNode = ref TNode # a traced reference to a TNode Node = ref NodeObj # a traced reference to a NodeObj
TNode = object NodeObj = object
le, ri: PNode # left and right subtrees le, ri: Node # left and right subtrees
sym: ref TSym # leaves contain a reference to a TSym sym: ref Sym # leaves contain a reference to a Sym
TSym = object # a symbol Sym = object # a symbol
name: string # the symbol's name name: string # the symbol's name
line: int # the line the symbol was declared in line: int # the line the symbol was declared in
code: PNode # the symbol's abstract syntax tree code: PNode # the symbol's abstract syntax tree
Type conversions Type conversions
@ -126,11 +126,11 @@ The syntax for type conversions is ``destination_type(expression_to_convert)``
(like an ordinary call): (like an ordinary call):
.. code-block:: nim .. code-block:: nim
proc getID(x: TPerson): int = proc getID(x: Person): int =
TStudent(x).id Student(x).id
The ``InvalidObjectConversionError`` exception is raised if ``x`` is not a The ``InvalidObjectConversionError`` exception is raised if ``x`` is not a
``TStudent``. ``Student``.
Object variants Object variants
@ -144,16 +144,16 @@ An example:
# This is an example how an abstract syntax tree could be modeled in Nim # This is an example how an abstract syntax tree could be modeled in Nim
type type
TNodeKind = enum # the different node types NodeKind = enum # the different node types
nkInt, # a leaf with an integer value nkInt, # a leaf with an integer value
nkFloat, # a leaf with a float value nkFloat, # a leaf with a float value
nkString, # a leaf with a string value nkString, # a leaf with a string value
nkAdd, # an addition nkAdd, # an addition
nkSub, # a subtraction nkSub, # a subtraction
nkIf # an if statement nkIf # an if statement
PNode = ref TNode Node = ref NodeObj
TNode = object NodeObj = object
case kind: TNodeKind # the ``kind`` field is the discriminator case kind: NodeKind # the ``kind`` field is the discriminator
of nkInt: intVal: int of nkInt: intVal: int
of nkFloat: floatVal: float of nkFloat: floatVal: float
of nkString: strVal: string of nkString: strVal: string
@ -228,21 +228,21 @@ is needed:
.. code-block:: nim .. code-block:: nim
type type
TSocket* = object of RootObj Socket* = object of RootObj
FHost: int # cannot be accessed from the outside of the module FHost: int # cannot be accessed from the outside of the module
# the `F` prefix is a convention to avoid clashes since # the `F` prefix is a convention to avoid clashes since
# the accessors are named `host` # the accessors are named `host`
proc `host=`*(s: var TSocket, value: int) {.inline.} = proc `host=`*(s: var Socket, value: int) {.inline.} =
## setter of hostAddr ## setter of hostAddr
s.FHost = value s.FHost = value
proc host*(s: TSocket): int {.inline.} = proc host*(s: Socket): int {.inline.} =
## getter of hostAddr ## getter of hostAddr
s.FHost s.FHost
var var
s: TSocket s: Socket
s.host = 34 # same as `host=`(s, 34) s.host = 34 # same as `host=`(s, 34)
(The example also shows ``inline`` procedures.) (The example also shows ``inline`` procedures.)
@ -253,10 +253,10 @@ The ``[]`` array access operator can be overloaded to provide
.. code-block:: nim .. code-block:: nim
type type
TVector* = object Vector* = object
x, y, z: float x, y, z: float
proc `[]=`* (v: var TVector, i: int, value: float) = proc `[]=`* (v: var Vector, i: int, value: float) =
# setter # setter
case i case i
of 0: v.x = value of 0: v.x = value
@ -264,7 +264,7 @@ The ``[]`` array access operator can be overloaded to provide
of 2: v.z = value of 2: v.z = value
else: assert(false) else: assert(false)
proc `[]`* (v: TVector, i: int): float = proc `[]`* (v: Vector, i: int): float =
# getter # getter
case i case i
of 0: result = v.x of 0: result = v.x
@ -313,27 +313,27 @@ dispatching:
.. code-block:: nim .. code-block:: nim
type type
TThing = object of RootObj Thing = object of RootObj
TUnit = object of TThing Unit = object of Thing
x: int x: int
method collide(a, b: TThing) {.inline.} = method collide(a, b: Thing) {.inline.} =
quit "to override!" quit "to override!"
method collide(a: TThing, b: TUnit) {.inline.} = method collide(a: Thing, b: Unit) {.inline.} =
echo "1" echo "1"
method collide(a: TUnit, b: TThing) {.inline.} = method collide(a: Unit, b: Thing) {.inline.} =
echo "2" echo "2"
var var
a, b: TUnit a, b: Unit
collide(a, b) # output: 2 collide(a, b) # output: 2
As the example demonstrates, invocation of a multi-method cannot be ambiguous: 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 Collide 2 is preferred over collide 1 because the resolution works from left to
right. Thus ``TUnit, TThing`` is preferred over ``TThing, TUnit``. right. Thus ``Unit, Thing`` is preferred over ``Thing, Unit``.
**Perfomance note**: Nim 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 generates dispatch trees. This avoids the expensive indirect branch for method
@ -479,18 +479,18 @@ containers:
.. code-block:: nim .. code-block:: nim
type type
TBinaryTree[T] = object # TBinaryTree is a generic type with BinaryTreeObj[T] = object # BinaryTree is a generic type with
# with generic param ``T`` # with generic param ``T``
le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil le, ri: BinaryTree[T] # left and right subtrees; may be nil
data: T # the data stored in a node data: T # the data stored in a node
PBinaryTree*[T] = ref TBinaryTree[T] # type that is exported BinaryTree*[T] = ref BinaryTreeObj[T] # type that is exported
proc newNode*[T](data: T): PBinaryTree[T] = proc newNode*[T](data: T): BinaryTree[T] =
# constructor for a node # constructor for a node
new(result) new(result)
result.data = data result.data = data
proc add*[T](root: var PBinaryTree[T], n: PBinaryTree[T]) = proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
# insert a node into the tree # insert a node into the tree
if root == nil: if root == nil:
root = n root = n
@ -511,15 +511,15 @@ containers:
return return
it = it.ri it = it.ri
proc add*[T](root: var PBinaryTree[T], data: T) = proc add*[T](root: var BinaryTree[T], data: T) =
# convenience proc: # convenience proc:
add(root, newNode(data)) add(root, newNode(data))
iterator preorder*[T](root: PBinaryTree[T]): T = iterator preorder*[T](root: BinaryTree[T]): T =
# Preorder traversal of a binary tree. # Preorder traversal of a binary tree.
# Since recursive iterators are not yet implemented, # Since recursive iterators are not yet implemented,
# this uses an explicit stack (which is more efficient anyway): # this uses an explicit stack (which is more efficient anyway):
var stack: seq[PBinaryTree[T]] = @[root] var stack: seq[BinaryTree[T]] = @[root]
while stack.len > 0: while stack.len > 0:
var n = stack.pop() var n = stack.pop()
while n != nil: while n != nil:
@ -528,7 +528,7 @@ containers:
n = n.le # and follow the left pointer n = n.le # and follow the left pointer
var var
root: PBinaryTree[string] # instantiate a PBinaryTree with ``string`` root: BinaryTree[string] # instantiate a BinaryTree with ``string``
add(root, newNode("hello")) # instantiates ``newNode`` and ``add`` add(root, newNode("hello")) # instantiates ``newNode`` and ``add``
add(root, "world") # instantiates the second ``add`` proc add(root, "world") # instantiates the second ``add`` proc
for str in preorder(root): for str in preorder(root):
@ -863,7 +863,7 @@ precisely made for compilation time (just like `gorge <system.html#gorge>`_
which executes an external program and captures its output). which executes an external program and captures its output).
The interesting thing is that our macro does not return a runtime `Table The interesting thing is that our macro does not return a runtime `Table
<tables.html#TTable>`_ object. Instead, it builds up Nim source code into <tables.html#Table>`_ object. Instead, it builds up Nim source code into
the ``source`` variable. For each line of the configuration file a ``const`` the ``source`` variable. For each line of the configuration file a ``const``
variable will be generated (line 15). To avoid conflicts we prefix these variable will be generated (line 15). To avoid conflicts we prefix these
variables with ``cfg``. In essence, what the compiler is doing is replacing variables with ``cfg``. In essence, what the compiler is doing is replacing

View file

@ -513,7 +513,7 @@ proc bounds*(c: Captures,
when not useUnicode: when not useUnicode:
type type
TRune = char Rune = char
template fastRuneAt(s, i, ch: expr) = template fastRuneAt(s, i, ch: expr) =
ch = s[i] ch = s[i]
inc(i) inc(i)

View file

@ -514,7 +514,7 @@ proc bounds*(c: Captures,
when not useUnicode: when not useUnicode:
type type
TRune = char Rune = char
template fastRuneAt(s, i, ch: expr) = template fastRuneAt(s, i, ch: expr) =
ch = s[i] ch = s[i]
inc(i) inc(i)

View file

@ -533,7 +533,7 @@ proc bounds*(c: TCaptures,
when not useUnicode: when not useUnicode:
type type
TRune = char Rune = char
template fastRuneAt(s, i, ch: expr) = template fastRuneAt(s, i, ch: expr) =
ch = s[i] ch = s[i]
inc(i) inc(i)
@ -563,7 +563,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
result = -1 result = -1
of pkLetter: of pkLetter:
if s[start] != '\0': if s[start] != '\0':
var a: TRune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
if isAlpha(a): dec(result, start) if isAlpha(a): dec(result, start)
@ -572,7 +572,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
result = -1 result = -1
of pkLower: of pkLower:
if s[start] != '\0': if s[start] != '\0':
var a: TRune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
if isLower(a): dec(result, start) if isLower(a): dec(result, start)
@ -581,7 +581,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
result = -1 result = -1
of pkUpper: of pkUpper:
if s[start] != '\0': if s[start] != '\0':
var a: TRune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
if isUpper(a): dec(result, start) if isUpper(a): dec(result, start)
@ -590,7 +590,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
result = -1 result = -1
of pkTitle: of pkTitle:
if s[start] != '\0': if s[start] != '\0':
var a: TRune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
if isTitle(a): dec(result, start) if isTitle(a): dec(result, start)
@ -599,7 +599,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
result = -1 result = -1
of pkWhitespace: of pkWhitespace:
if s[start] != '\0': if s[start] != '\0':
var a: TRune var a: Rune
result = start result = start
fastRuneAt(s, result, a) fastRuneAt(s, result, a)
if isWhitespace(a): dec(result, start) if isWhitespace(a): dec(result, start)
@ -623,7 +623,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
of pkTerminalIgnoreCase: of pkTerminalIgnoreCase:
var var
i = 0 i = 0
a, b: TRune a, b: Rune
result = start result = start
while i < len(p.term): while i < len(p.term):
fastRuneAt(p.term, i, a) fastRuneAt(p.term, i, a)
@ -635,15 +635,15 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
of pkTerminalIgnoreStyle: of pkTerminalIgnoreStyle:
var var
i = 0 i = 0
a, b: TRune a, b: Rune
result = start result = start
while i < len(p.term): while i < len(p.term):
while true: while true:
fastRuneAt(p.term, i, a) fastRuneAt(p.term, i, a)
if a != TRune('_'): break if a != Rune('_'): break
while true: while true:
fastRuneAt(s, result, b) fastRuneAt(s, result, b)
if b != TRune('_'): break if b != Rune('_'): break
if toLower(a) != toLower(b): if toLower(a) != toLower(b):
result = -1 result = -1
break break
@ -865,7 +865,7 @@ template `=~`*(s: string, pattern: TPeg): expr =
## else: ## else:
## echo("syntax error") ## echo("syntax error")
## ##
when not definedInScope(matches): when not declaredInScope(matches):
var matches {.inject.}: array[0..MaxSubpatterns-1, string] var matches {.inject.}: array[0..MaxSubpatterns-1, string]
match(s, pattern, matches) match(s, pattern, matches)
@ -964,7 +964,7 @@ proc transformFile*(infile, outfile: string,
## error occurs. This is supposed to be used for quick scripting. ## error occurs. This is supposed to be used for quick scripting.
var x = readFile(infile) var x = readFile(infile)
if not isNil(x): if not isNil(x):
var f: TFile var f: File
if open(f, outfile, fmWrite): if open(f, outfile, fmWrite):
write(f, x.parallelReplace(subs)) write(f, x.parallelReplace(subs))
close(f) close(f)
@ -1404,8 +1404,8 @@ proc arrowIsNextTok(c: TPegLexer): bool =
# ----------------------------- parser ---------------------------------------- # ----------------------------- parser ----------------------------------------
type type
EInvalidPeg* = object of EInvalidValue ## raised if an invalid EInvalidPeg* = object of ValueError ## raised if an invalid
## PEG has been detected ## PEG has been detected
TPegParser = object of TPegLexer ## the PEG parser object TPegParser = object of TPegLexer ## the PEG parser object
tok: TToken tok: TToken
nonterms: seq[PNonTerminal] nonterms: seq[PNonTerminal]