Documentation: directly use ref object + fields (#6598)

This commit is contained in:
Mamy Ratsimbazafy 2017-11-15 22:01:28 +01:00 • committed by Andreas Rumpf
commit e7c09512d2
5 changed files with 48 additions and 37 deletions

View file

@ -9,26 +9,26 @@ The following example shows a generic binary tree can be modelled:
.. code-block:: nim .. code-block:: nim
type type
BinaryTreeObj[T] = object # BinaryTreeObj is a generic type with BinaryTree*[T] = ref object # BinaryTree is a generic type with
# with generic param ``T`` # generic param ``T``
le, ri: BinaryTree[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
BinaryTree[T] = ref BinaryTreeObj[T] # a shorthand for notational convenience
proc newNode[T](data: T): BinaryTree[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 BinaryTree[T], n: BinaryTree[T]) = proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
# insert a node into the tree
if root == nil: if root == nil:
root = n root = n
else: else:
var it = root var it = root
while it != nil: while it != nil:
var c = cmp(it.data, n.data) # compare the data items; uses # compare the data items; uses the generic ``cmp`` proc
# the generic ``cmp`` proc that works for # that works for any type that has a ``==`` and ``<`` operator
# any type that has a ``==`` and ``<`` var c = cmp(it.data, n.data)
# operator
if c < 0: if c < 0:
if it.le == nil: if it.le == nil:
it.le = n it.le = n
@ -40,20 +40,28 @@ The following example shows a generic binary tree can be modelled:
return return
it = it.ri it = it.ri
iterator inorder[T](root: BinaryTree[T]): T = proc add*[T](root: var BinaryTree[T], data: T) =
# inorder traversal of a binary tree # convenience proc:
# recursive iterators are not yet implemented, so this does not work in add(root, newNode(data))
# the current compiler!
if root.le != nil: yield inorder(root.le) iterator preorder*[T](root: BinaryTree[T]): T =
yield root.data # Preorder traversal of a binary tree.
if root.ri != nil: yield inorder(root.ri) # Since recursive iterators are not yet implemented,
# this uses an explicit stack (which is more efficient anyway):
var stack: seq[BinaryTree[T]] = @[root]
while stack.len > 0:
var n = stack.pop()
while n != nil:
yield n.data
add(stack, n.ri) # push right subtree onto the stack
n = n.le # and follow the left pointer
var var
root: BinaryTree[string] # instantiate a BinaryTree with the type string root: BinaryTree[string] # instantiate a BinaryTree with ``string``
add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and add(root, newNode("hello")) # instantiates ``newNode`` and ``add``
add(root, newNode("world")) # ``add`` add(root, "world") # instantiates the second ``add`` proc
for str in inorder(root): for str in preorder(root):
writeLine(stdout, str) stdout.writeLine(str)
Is operator Is operator

View file

@ -102,6 +102,14 @@ collector to not consider objects of this type as part of a cycle:
left, right: Node left, right: Node
data: string data: string
Or if we directly use a ref object:
.. code-block:: nim
type
Node = ref object {.acyclic, final.}
left, right: Node
data: string
In the example a tree structure is declared with the ``Node`` 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

View file

@ -5,8 +5,7 @@ Example:
.. code-block:: nim .. code-block:: nim
type # example demonstrating mutually recursive types type # example demonstrating mutually recursive types
Node = ref NodeObj # a traced pointer to a NodeObj Node = ref object # an object managed by the garbage collector (ref)
NodeObj = object
le, ri: Node # left and right subtrees le, ri: Node # left and right subtrees
sym: ref Sym # leaves contain a reference to a Sym sym: ref Sym # leaves contain a reference to a Sym

View file

@ -1511,8 +1511,7 @@ operators perform implicit dereferencing operations for reference types:
.. code-block:: nim .. code-block:: nim
type type
Node = ref NodeObj Node = ref object
NodeObj = object
le, ri: Node le, ri: Node
data: int data: int
var var

View file

@ -104,15 +104,14 @@ Example:
.. code-block:: nim .. code-block:: nim
type type
Node = ref NodeObj # a traced reference to a NodeObj Node = ref object # a reference to an object with the following field:
NodeObj = object
le, ri: Node # left and right subtrees le, ri: Node # left and right subtrees
sym: ref Sym # leaves contain a reference to a Sym sym: ref Sym # leaves contain a reference to a Sym
Sym = 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: Node # the symbol's abstract syntax tree code: Node # the symbol's abstract syntax tree
Type conversions Type conversions
@ -155,8 +154,7 @@ An example:
nkAdd, # an addition nkAdd, # an addition
nkSub, # a subtraction nkSub, # a subtraction
nkIf # an if statement nkIf # an if statement
Node = ref NodeObj Node = ref object
NodeObj = object
case kind: NodeKind # 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
@ -482,11 +480,10 @@ containers:
.. code-block:: nim .. code-block:: nim
type type
BinaryTreeObj[T] = object # BinaryTree is a generic type with BinaryTree*[T] = ref object # BinaryTree is a generic type with
# with generic param ``T`` # generic param ``T``
le, ri: BinaryTree[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
BinaryTree*[T] = ref BinaryTreeObj[T] # type that is exported
proc newNode*[T](data: T): BinaryTree[T] = proc newNode*[T](data: T): BinaryTree[T] =
# constructor for a node # constructor for a node