Indirection.html 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <html lang="en">
  2. <head>
  3. <title>Indirection - avram - a virtual machine code interpreter</title>
  4. <meta http-equiv="Content-Type" content="text/html">
  5. <meta name="description" content="avram - a virtual machine code interpreter">
  6. <meta name="generator" content="makeinfo 4.13">
  7. <link title="Top" rel="start" href="index.html#Top">
  8. <link rel="up" href="Lists.html#Lists" title="Lists">
  9. <link rel="prev" href="Deconstruction-Functions.html#Deconstruction-Functions" title="Deconstruction Functions">
  10. <link rel="next" href="The-Universal-Function.html#The-Universal-Function" title="The Universal Function">
  11. <link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
  12. <meta http-equiv="Content-Style-Type" content="text/css">
  13. <style type="text/css"><!--
  14. pre.display { font-family:inherit }
  15. pre.format { font-family:inherit }
  16. pre.smalldisplay { font-family:inherit; font-size:smaller }
  17. pre.smallformat { font-family:inherit; font-size:smaller }
  18. pre.smallexample { font-size:smaller }
  19. pre.smalllisp { font-size:smaller }
  20. span.sc { font-variant:small-caps }
  21. span.roman { font-family:serif; font-weight:normal; }
  22. span.sansserif { font-family:sans-serif; font-weight:normal; }
  23. --></style>
  24. </head>
  25. <body>
  26. <div class="node">
  27. <a name="Indirection"></a>
  28. <p>
  29. Next:&nbsp;<a rel="next" accesskey="n" href="The-Universal-Function.html#The-Universal-Function">The Universal Function</a>,
  30. Previous:&nbsp;<a rel="previous" accesskey="p" href="Deconstruction-Functions.html#Deconstruction-Functions">Deconstruction Functions</a>,
  31. Up:&nbsp;<a rel="up" accesskey="u" href="Lists.html#Lists">Lists</a>
  32. <hr>
  33. </div>
  34. <h4 class="subsection">3.1.7 Indirection</h4>
  35. <p>In some cases it is necessary to build a tree from the top down rather
  36. <a name="index-pointers-489"></a>than from the bottom up, when it is not known in advance what's on the
  37. bottom. Although the <code>list</code> type is a pointer itself, these
  38. situations call for a type of pointers to lists, which are declared as
  39. the <code>branch</code> type in <samp><span class="file">branches.h</span></samp>. For example, if <code>b</code> is
  40. declared as a <code>branch</code> and <code>l</code> is declared as a <code>list</code>,
  41. it would be possible to write <code>b = &amp;l</code>.
  42. <p>Facilities are also provided for maintaining queues of branches, which
  43. <a name="index-queues-490"></a>are declared as the <code>branch_queue</code> type. This type is a pointer to
  44. a structure with two fields, <code>above</code> and <code>following</code>, where
  45. <code>above</code> is a <code>branch</code> and <code>following</code> is a
  46. <code>branch_queue</code>.
  47. <p>These functions are used internally elsewhere in the library and might
  48. not be necessary for most client programs to use directly.
  49. <div class="defun">
  50. &mdash; Function: void <b>avm_initialize_branches</b> ()<var><a name="index-avm_005finitialize_005fbranches-491"></a></var><br>
  51. <blockquote><p>This must be done once before any of the other branch related functions is
  52. used, and creates some internal data structures. Results of the other
  53. functions are undefined if this one isn't called first.
  54. </p></blockquote></div>
  55. <div class="defun">
  56. &mdash; Function: void <b>avm_count_branches</b> ()<var><a name="index-avm_005fcount_005fbranches-492"></a></var><br>
  57. <blockquote><p>This function can be used at the end of a run to detect unreclaimed
  58. storage used for branches or branch queues. If any storage remains
  59. unreclaimed, a message about unreclaimed branches is written to standard
  60. error.
  61. </p></blockquote></div>
  62. <div class="defun">
  63. &mdash; Function: void <b>avm_anticipate</b> (<var>branch_queue *front, branch_queue *back, branch operand</var>)<var><a name="index-avm_005fanticipate-493"></a></var><br>
  64. <blockquote><p>This function provides a simple queueing facility for
  65. branches. Similarly to the case with <code>avm_enqueue</code>, <code>front</code>
  66. and <code>back</code> should be initialized to <code>NULL</code> before the first
  67. call. Each call to this function will enqueue one item to the back,
  68. assuming enough memory is available, as the following example shows.
  69. <pre class="example"> front = NULL;
  70. back = NULL;
  71. l = avm_join(NULL,NULL);
  72. anticipate(&amp;front,&amp;back,&amp;(l-&gt;head));
  73. anticipate(&amp;front,&amp;back,&amp;(l-&gt;tail));
  74. </pre>
  75. <p>After the above code is executed, these postconditions will hold.
  76. <pre class="example"> front-&gt;above == &amp;(l-&gt;head)
  77. front-&gt;following-&gt;above == &amp;(l-&gt;tail)
  78. front-&gt;following == back
  79. back-&gt;following == NULL
  80. </pre>
  81. <p>The name &ldquo;anticipate&rdquo; is used because ordinarily the queue contains
  82. positions in a tree to be filled in later. As usual, only unshared trees should be
  83. modified in place.
  84. </p></blockquote></div>
  85. <div class="defun">
  86. &mdash; Function: void <b>avm_recoverable_anticipate</b> (<var>branch_queue *front, branch_queue *back, branch operand, int *fault</var>)<var><a name="index-avm_005frecoverable_005fanticipate-494"></a></var><br>
  87. <blockquote><p>This function is similar to <code>avm_anticipate</code>, except that it will
  88. not exit with an error message in the event of an overflow error, but
  89. will simply set <code>*</code><var>fault</var> to a non-zero value and return to the
  90. caller. If an overflow occurs, nothing about the queue is changed.
  91. </p></blockquote></div>
  92. <div class="defun">
  93. &mdash; Function: void <b>avm_enqueue_branch</b> (<var>branch_queue *front, branch_queue *back, int received_bit</var>)<var><a name="index-avm_005fenqueue_005fbranch-495"></a></var><br>
  94. <blockquote><p>A slightly higher level interface to the <code>avm_anticipate</code> function
  95. is provided by this function, which is useful for building a tree from
  96. <a name="index-trees-496"></a>a string of input bits in a format similar to the one described in
  97. <a href="Concrete-Syntax.html#Concrete-Syntax">Concrete Syntax</a>.
  98. <p>This function should be called the first time with <code>front</code> and
  99. <code>back</code> having been initialized to represent a queue containing a
  100. <a name="index-queues-497"></a>single branch pointing to a list known to the caller. The list itself
  101. need not be allocated or initialized. An easy way of doing so would be
  102. the following.
  103. <pre class="example"> front = NULL;
  104. back = NULL;
  105. avm_anticipate(&amp;front,&amp;back,&amp;my_list);
  106. </pre>
  107. <p>On each call to <code>avm_enqueue_branch</code>, the <var>received_bit</var>
  108. parameter is examined. If it is zero, nothing will be added to the
  109. queue, the list referenced by the front branch will be assigned
  110. <code>NULL</code>, and the front branch will be removed from the queue. If
  111. <var>received_bit</var> is a non-zero value, the list referenced by
  112. the front branch will be assigned to point to a newly created unshared
  113. list node, and two more branches will be appended to the queue. The
  114. first branch to be appended will point to the head of the newly created
  115. list node, and the second branch to be appended will point to the tail.
  116. <p>If the sequence of bits conforms to the required concrete syntax, this
  117. function can be called for each of them in turn, and at the end of the
  118. sequence, the queue will be empty and the list referenced by the initial
  119. branch (i.e., <code>my_list</code>) will be the one specified by the bit
  120. string. If the sequence of bits does not conform to the required
  121. concrete syntax, the error can be detected insofar as the emptying of
  122. the queue will not coincide exactly with the last bit.
  123. <p>The caller should check for the queue becoming prematurely empty due to
  124. syntax errors, because no message is reported by
  125. <code>avm_enqueue_branch</code> in that event, and subsequent attempts to
  126. enqueue anything are ignored. However, in the event of a memory overflow,
  127. an error message is reported and the process is terminated.
  128. </p></blockquote></div>
  129. <div class="defun">
  130. &mdash; Function: void <b>avm_recoverable_enqueue_branch</b> (<var>branch_queue *front, branch_queue *back, int received_bit, int *fault</var>)<var><a name="index-avm_005frecoverable_005fenqueue_005fbranch-498"></a></var><br>
  131. <blockquote><p>This function is similar to <code>avm_enqueue_branch</code> but will leave
  132. error handling to the caller in the event of insufficient memory to
  133. enqueue another branch. Instead of printing an error message and
  134. exiting, it will dispose of the queue, set the <var>fault</var> flag
  135. to a non-zero value, and return. Although the queue will be reclaimed,
  136. the lists referenced by the branches in it will persist. The list nodes
  137. themselves can be reclaimed by disposing of the list whose address was
  138. stored originally in the front branch.
  139. </p></blockquote></div>
  140. <div class="defun">
  141. &mdash; Function: void <b>avm_dispose_branch_queue</b> (<var>branch_queue front</var>)<var><a name="index-avm_005fdispose_005fbranch_005fqueue-499"></a></var><br>
  142. <blockquote><p>This function deallocates a branch queue by chasing the <code>following</code>
  143. fields in each one. It does nothing to the lists referenced by the
  144. branches in the queue.
  145. <p>Rather than using <code>free</code> directly, client programs should use this
  146. function for deallocating branch queues, because it allows better
  147. performance by interacting with a local internal cache of free memory,
  148. and because it performs necessary bookkeeping for
  149. <code>avm_count_branches</code>.
  150. </p></blockquote></div>
  151. <div class="defun">
  152. &mdash; Function: void <b>avm_dispose_branch</b> (<var>branch_queue old</var>)<var><a name="index-avm_005fdispose_005fbranch-500"></a></var><br>
  153. <blockquote><p>This disposes of a single branch queue node rather than a whole queue.
  154. Otherwise, the same comments as those above apply.
  155. </p></blockquote></div>
  156. </body></html>