123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">
- <html>
- <!-- Created on December 10, 2012 by texi2html 1.82
- texi2html was written by:
- Lionel Cons <[email protected]> (original author)
- Karl Berry <[email protected]>
- Olaf Bachmann <[email protected]>
- and many others.
- Maintained by: Many creative people.
- Send bugs and suggestions to <[email protected]>
- -->
- <head>
- <title>avram - a virtual machine code interpreter: 3.1.1 Simple Operations</title>
- <meta name="description" content="avram - a virtual machine code interpreter: 3.1.1 Simple Operations">
- <meta name="keywords" content="avram - a virtual machine code interpreter: 3.1.1 Simple Operations">
- <meta name="resource-type" content="document">
- <meta name="distribution" content="global">
- <meta name="Generator" content="texi2html 1.82">
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <style type="text/css">
- <!--
- a.summary-letter {text-decoration: none}
- blockquote.smallquotation {font-size: smaller}
- pre.display {font-family: serif}
- pre.format {font-family: serif}
- pre.menu-comment {font-family: serif}
- pre.menu-preformatted {font-family: serif}
- pre.smalldisplay {font-family: serif; font-size: smaller}
- pre.smallexample {font-size: smaller}
- pre.smallformat {font-family: serif; font-size: smaller}
- pre.smalllisp {font-size: smaller}
- span.roman {font-family:serif; font-weight:normal;}
- span.sansserif {font-family:sans-serif; font-weight:normal;}
- ul.toc {list-style: none}
- -->
- </style>
- </head>
- <body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
- <a name="Simple-Operations"></a>
- <table cellpadding="1" cellspacing="1" border="0">
- <tr><td valign="middle" align="left">[<a href="Lists.html#Lists" title="Previous section in reading order"> < </a>]</td>
- <td valign="middle" align="left">[<a href="Recoverable-Operations.html#Recoverable-Operations" title="Next section in reading order"> > </a>]</td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left">[<a href="Library-Reference.html#Library-Reference" title="Beginning of this chapter or previous chapter"> << </a>]</td>
- <td valign="middle" align="left">[<a href="Lists.html#Lists" title="Up section"> Up </a>]</td>
- <td valign="middle" align="left">[<a href="Character-Table.html#Character-Table" title="Next chapter"> >> </a>]</td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left">[<a href="avram.html#Top" title="Cover (top) of document">Top</a>]</td>
- <td valign="middle" align="left">[<a href="avram_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td>
- <td valign="middle" align="left">[<a href="Function-Index.html#Function-Index" title="Index">Index</a>]</td>
- <td valign="middle" align="left">[<a href="avram_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
- </tr></table>
- <hr size="1">
- <a name="Simple-Operations-1"></a>
- <h3 class="subsection">3.1.1 Simple Operations</h3>
- <p>These functions are declared in the header file <code>lists.h</code>, which
- should be included in any C source file that uses them with a directive
- such as <code>#include <avm/lists.h></code>. All of these functions except
- the first three have the potential cause a memory overflow. In that
- <a name="index-overflow-2"></a>
- event, a brief message is written to standard error and the process is
- killed rather than returning to the caller. It is possible for client
- programs requiring more robust behavior to do their own error handling
- by using the alternative versions of these operations described in the
- next section.
- </p>
- <dl>
- <dt><a name="index-avm_005finitialize_005flists"></a><u>Function:</u> void <b>avm_initialize_lists</b><i> ()</i></dt>
- <dd><p>The function <code>avm_initialize_lists</code> should be called before any of
- the other ones in this section is called, because it sets up some
- internal data structures. Otherwise, the behavior of the other functions
- is undefined.
- </p></dd></dl>
- <dl>
- <dt><a name="index-avm_005fdispose"></a><u>Function:</u> void <b>avm_dispose</b><i> (list <var>front</var>)</i></dt>
- <dd><p>This function deallocates the memory associated with a given list,
- either by consigning it to a cache maintained internally by the library,
- or by the standard <code>free</code> function if the cache is full. Shared
- lists are taken into account and handled properly according to a
- reference counting scheme. Lists should be freed only by this function,
- not by using <code>free</code> directly.
- </p></dd></dl>
- <dl>
- <dt><a name="index-avm_005fcount_005flists"></a><u>Function:</u> void <b>avm_count_lists</b><i> ()</i></dt>
- <dd><p>If a client program aims to do its own storage reclamation, this
- function can be called optionally at the end of a run when it is
- believed that all lists have been freed. If any allocated lists remain
- at large, a warning will be printed to standard error. This function
- therefore provides a useful check for memory leaks. Overhead is small
- enough that it is not infeasible to leave this check in the production
- code.
- </p></dd></dl>
- <dl>
- <dt><a name="index-avm_005fcopied"></a><u>Function:</u> list <b>avm_copied</b><i> (list <var>operand</var>)</i></dt>
- <dd><p>A copy of the argument list is returned by this function. The copy
- remains intact after the original is reclaimed. A typical use might be
- for retaining part of a list after the rest of it is no longer
- needed. In this example, a list <code>x</code> is traversed by a hypothetical
- <code>visit</code> function to each item, which is then immediately reclaimed.
- </p>
- <table><tr><td> </td><td><pre class="example">while(x){
- visit(x->head);
- old_x = x;
- x = avm_copied(x->tail); /* the right way */
- avm_dispose(old_x);
- }
- </pre></td></tr></table>
- <p>This example allows each item in the list to be visited even as
- previously visited items are reclaimed, because <code>x</code> is copied at
- each iteration. This example contrasts with the next one, which will
- probably cause a segmentation fault.
- <a name="index-segmentation-fault"></a>
- </p>
- <table><tr><td> </td><td><pre class="example">while(x){
- visit(x->head);
- old_x = x;
- x = x->tail; /* the wrong way */
- avm_dispose(old_x);
- }
- </pre></td></tr></table>
- <p>In the second example, a reference is made to a part of a list which no
- longer exists because it has been deallocated.
- </p>
- <p>In fact, the <code>avm_copied</code> function does nothing but increment a
- reference count, so it is a fast, constant time operation that requires
- <a name="index-reference-count-1"></a>
- no additional memory allocation. Semantically this action is equivalent
- to creating a fresh copy of the list, because all list operations in the
- library deal with reference counts properly.
- </p></dd></dl>
- <dl>
- <dt><a name="index-avm_005fjoin"></a><u>Function:</u> list <b>avm_join</b><i> (list <var>left</var>, list <var>right</var>)</i></dt>
- <dd><p>This function takes a pair of lists to a list in which the left is the
- head and the right is the tail. It may need to use <code>malloc</code> to
- allocate additional memory. If there is insufficient memory, an error
- message is written to standard error and the program exits.
- When the list returned by <code>avm_join</code> is eventually deallocated, the
- lists from which it was built are taken with it and must not be
- referenced again. For example, the following code is an error.
- </p>
- <table><tr><td> </td><td><pre class="example">z = avm_join(x,y);
- …
- avm_dispose(z);
- avm_print_list(x); /* error here */
- </pre></td></tr></table>
- <p>To accomplish something similar to this without an error, a copy of
- <code>x</code> should be made, as in the next example.
- </p>
- <table><tr><td> </td><td><pre class="example">z = avm_join(avm_copied(x),y);
- …
- avm_dispose(z);
- avm_print_list(x); /* original x still intact */
- </pre></td></tr></table>
- </dd></dl>
- <dl>
- <dt><a name="index-avm_005fenqueue"></a><u>Function:</u> void <b>avm_enqueue</b><i> (list *<var>front</var>, list *<var>back</var>, list <var>operand</var>)</i></dt>
- <dd><a name="index-queues-1"></a>
- <p>A fast simple way of building a list head first is provided by the
- <code>enqueue</code> function. The <code>front</code> is a pointer to the beginning
- of the list being built, and the <code>back</code> is a pointer to the last
- item. The recommended way to use it would be something like this.
- </p>
- <table><tr><td> </td><td><pre class="example">front = back = NULL;
- avm_enqueue(&front,&back,item);
- avm_enqueue(&front,&back,next_item);
- avm_enqueue(&front,&back,another_item);
- …
- </pre></td></tr></table>
- <p>It might be more typical for the calls to <code>avm_enqueue</code> to appear
- within a loop. In any case, after the above code is executed, the
- following postconditions will hold.
- </p>
- <table><tr><td> </td><td><pre class="example">front->head == item
- front->tail->head == next_item
- front->tail->tail->head == another_item
- back->head == another_item
- back->tail == NULL
- </pre></td></tr></table>
- <p>The <code>avm_enqueue</code> function must never be used on a shared list, because
- it modifies its arguments in place. The only practical way to guarantee
- that a list is not shared is to initialize the <code>front</code> and <code>back</code> to
- <code>NULL</code> as shown before the first call to <code>avm_enqueue</code>, and to
- make no copies of <code>front</code> or <code>back</code> until after the last call
- to <code>avm_enqueue</code>.
- </p>
- <p>Because a list built with <code>avm_enqueue</code> is not shared, it is one of the
- few instances of a list that can have something harmlessly appended to
- it in place. For example, if the next line of code were
- </p>
- <table><tr><td> </td><td><pre class="example">back->tail = rest_of_list;
- </pre></td></tr></table>
- <p>that would be acceptable assuming <code>rest_of_list</code> is not shared and
- does not conceal a dangling or cyclic reference, and if nothing further
- were enqueued.
- </p>
- <p>The items that are enqueued into a list are not copied and will be
- deallocated when the list is deallocated, so they must not be referenced
- thereafter. A non-obvious violation of this convention is implicit in
- the following code.
- </p>
- <table><tr><td> </td><td><pre class="example">…
- avm_enqueue(&front,&back,x->head);
- …
- avm_dispose(front);
- avm_print_list(x); /* error here */
- </pre></td></tr></table>
- <p>This code might cause a segmentation fault because of the reference to
- <a name="index-segmentation-fault-1"></a>
- <code>x</code> after its head has been deallocated. The following code is
- subject to the same problem,
- </p>
- <table><tr><td> </td><td><pre class="example">…
- avm_enqueue(&front,&back,x->head);
- …
- avm_dispose(x);
- avm_print_list(front); /* error here */
- </pre></td></tr></table>
- <p>as is the following.
- </p>
- <table><tr><td> </td><td><pre class="example">…
- avm_enqueue(&front,&back,x->head);
- …
- avm_dispose(x); /* front is now impossible to reclaim */
- avm_dispose(front);
- </pre></td></tr></table>
- <p>The problem with the last example is that it is not valid even to
- dispose of the same list more than once, albeit indirectly.
- </p>
- <p>If part of a list is intended to be enqueued temporarily or
- independently of its parent, the list should be copied explicitly, as
- the following code demonstrates.
- </p>
- <table><tr><td> </td><td><pre class="example">…
- avm_enqueue(&front,&back,avm_copied(x->head)); /* correct */
- …
- avm_dispose(front);
- avm_print_list(x);
- </pre></td></tr></table>
- </dd></dl>
- <dl>
- <dt><a name="index-avm_005flength"></a><u>Function:</u> counter <b>avm_length</b><i> (list <var>operand</var>)</i></dt>
- <dd><p>A <code>counter</code> is meant to be the longest unsigned integer available
- <a name="index-counter"></a>
- on the host machine, and is defined in <code>common.h</code>, which is
- automatically included whenever <code>lists.h</code> is included. The
- <code>avm_length</code> function returns the number of items in a list. If a
- list is <code>NULL</code>, a value of zero is returned. There is a possibility
- of a counter overflow error from this function (<a href="Overflow-Errors.html#Overflow-Errors">Overflow Errors</a>),
- but only on a platform where the <code>counter</code> type is shorter than the
- address length.
- </p></dd></dl>
- <dl>
- <dt><a name="index-avm_005farea"></a><u>Function:</u> counter <b>avm_area</b><i> (list <var>operand</var>)</i></dt>
- <dd><p>This function is similar to <code>avm_length</code>, but it treats its
- argument as a list of lists and returns the summation of their lengths.
- </p></dd></dl>
- <dl>
- <dt><a name="index-avm_005fnatural"></a><u>Function:</u> list <b>avm_natural</b><i> (counter <var>number</var>)</i></dt>
- <dd><a name="index-naturals-2"></a>
- <p>This function takes a <code>counter</code> to its representation as a list, as
- described in <a href="Representation-of-Numeric-and-Textual-Data.html#Representation-of-Numeric-and-Textual-Data">Representation of Numeric and Textual Data</a>. That is,
- the number is represented as a list of bits, least significant bit
- first, with each zero bit represented by <code>NULL</code> and each one bit
- represented by a list whose <code>head</code> and <code>tail</code> are <code>NULL</code>.
- </p></dd></dl>
- <dl>
- <dt><a name="index-avm_005fprint_005flist"></a><u>Function:</u> void <b>avm_print_list</b><i> (list <var>operand</var>)</i></dt>
- <dd><p>The <code>avm_print_list</code> function is not used in any production code
- but retained in the library for debugging purposes. It prints a list to
- <a name="index-standard-output-3"></a>
- standard output using an expression involving only commas and parentheses,
- as per the <code>silly</code> syntax (<a href="A-Simple-Lisp-Like-Language.html#A-Simple-Lisp-Like-Language">A Simple Lisp Like Language</a>). The
- results quickly become unintelligible for lists of any significant size.
- The function is recursively defined and will crash in the event of a
- stack overflow, which will occur in the case of very large or cyclic
- lists.
- </p></dd></dl>
- <dl>
- <dt><a name="index-avm_005fposition"></a><u>Function:</u> list <b>avm_position</b><i> (list <var>key</var>, list <var>table</var>, int *<var>fault</var>)</i></dt>
- <dd><p>This function searches for a <var>key</var> in a short <var>table</var> where
- each item is a possible key.
- </p>
- <p>If it’s not found, a <code>NULL</code> value is returned. If it’s
- found, a list representing a character encoding according to
- <a href="Character-Table.html#Character-Table">Character Table</a> is returned.
- </p>
- <p>The ascii code of the character corresponding to the returned list is
- the position of the <var>key</var> in the <var>table</var>, assuming position
- numbers start with 1.
- </p>
- <p>The table should have a length of 255 or less. If it’s longer and the
- <var>key</var> is found beyond that range, the higher order bits of the
- position number are ignored.
- </p>
- <p>The integer referenced by <var>fault</var> is set to a non-zero value in
- the event of a memory overflow, which could happen in the course of
- the list comparisons necessary for the search.
- </p></dd></dl>
- <hr size="1">
- <table cellpadding="1" cellspacing="1" border="0">
- <tr><td valign="middle" align="left">[<a href="Lists.html#Lists" title="Previous section in reading order"> < </a>]</td>
- <td valign="middle" align="left">[<a href="Recoverable-Operations.html#Recoverable-Operations" title="Next section in reading order"> > </a>]</td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left">[<a href="Library-Reference.html#Library-Reference" title="Beginning of this chapter or previous chapter"> << </a>]</td>
- <td valign="middle" align="left">[<a href="Lists.html#Lists" title="Up section"> Up </a>]</td>
- <td valign="middle" align="left">[<a href="Character-Table.html#Character-Table" title="Next chapter"> >> </a>]</td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left"> </td>
- <td valign="middle" align="left">[<a href="avram.html#Top" title="Cover (top) of document">Top</a>]</td>
- <td valign="middle" align="left">[<a href="avram_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td>
- <td valign="middle" align="left">[<a href="Function-Index.html#Function-Index" title="Index">Index</a>]</td>
- <td valign="middle" align="left">[<a href="avram_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
- </tr></table>
- <p>
- <font size="-1">
- This document was generated on <i>December 10, 2012</i> using <a href="http://www.nongnu.org/texi2html/"><i>texi2html 1.82</i></a>.
- </font>
- <br>
- </p>
- </body>
- </html>
|