Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 159

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../../doc/otp_doc.css" type="text/css">
<title>Erlang -- The Abstract Format</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/erts-5.9.3.1.pdf">PDF</a><br><a href="../../../doc/index.html">Top</a></small><p><strong>Erlang Run-Time System Application (ERTS)</strong><br><strong>User's Guide</strong><br><small>Version 5.9.3.1</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../../../doc/js/flipmenu">
<li id="no" title="Match specifications in Erlang" expanded="false">Match specifications in Erlang<ul>
<li><a href="match_spec.html">
              Top of chapter
            </a></li>
<li title="Grammar"><a href="match_spec.html#id67432">Grammar</a></li>
<li title="Function descriptions"><a href="match_spec.html#id65382">Function descriptions</a></li>
<li title="Variables and literals"><a href="match_spec.html#id73136">Variables and literals</a></li>
<li title="Execution of the match"><a href="match_spec.html#id73066">Execution of the match</a></li>
<li title="Differences between match specifications in ETS and tracing"><a href="match_spec.html#id69369">Differences between match specifications in ETS and tracing</a></li>
<li title="Examples"><a href="match_spec.html#id69408">Examples</a></li>
</ul>
</li>
<li id="no" title="How to interpret the Erlang crash dumps" expanded="false">How to interpret the Erlang crash dumps<ul>
<li><a href="crash_dump.html">
              Top of chapter
            </a></li>
<li title="General information"><a href="crash_dump.html#id71973">General information</a></li>
<li title="Memory information"><a href="crash_dump.html#id69719">Memory information</a></li>
<li title="Internal table information"><a href="crash_dump.html#id69746">Internal table information</a></li>
<li title="Allocated areas"><a href="crash_dump.html#id71628">Allocated areas</a></li>
<li title="Allocator"><a href="crash_dump.html#id71654">Allocator</a></li>
<li title="Process information"><a href="crash_dump.html#id71693">Process information</a></li>
<li title="Port information"><a href="crash_dump.html#id70337">Port information</a></li>
<li title="ETS tables"><a href="crash_dump.html#id70354">ETS tables</a></li>
<li title="Timers"><a href="crash_dump.html#id70452">Timers</a></li>
<li title="Distribution information"><a href="crash_dump.html#id77672">Distribution information</a></li>
<li title="Loaded module information"><a href="crash_dump.html#id77796">Loaded module information</a></li>
<li title="Fun information"><a href="crash_dump.html#id77887">Fun information</a></li>
<li title="Process Data"><a href="crash_dump.html#id77959">Process Data</a></li>
<li title="Atoms"><a href="crash_dump.html#id78034">Atoms</a></li>
<li title="Disclaimer"><a href="crash_dump.html#id78051">Disclaimer</a></li>
</ul>
</li>
<li id="no" title="How to implement an alternative carrier for  the Erlang distribution" expanded="false">How to implement an alternative carrier for  the Erlang distribution<ul>
<li><a href="alt_dist.html">
              Top of chapter
            </a></li>
<li title="Introduction"><a href="alt_dist.html#id78171">Introduction</a></li>
<li title="The driver"><a href="alt_dist.html#id78261">The driver</a></li>
<li title="Putting it all together"><a href="alt_dist.html#id79511">Putting it all together</a></li>
</ul>
</li>
<li id="loadscrollpos" title="The Abstract Format" expanded="true">The Abstract Format<ul>
<li><a href="absform.html">
              Top of chapter
            </a></li>
<li title="Module declarations and forms"><a href="absform.html#id79791">Module declarations and forms</a></li>
<li title="Atomic literals"><a href="absform.html#id79999">Atomic literals</a></li>
<li title="Patterns"><a href="absform.html#id80061">Patterns</a></li>
<li title="Expressions"><a href="absform.html#id80275">Expressions</a></li>
<li title="Clauses"><a href="absform.html#id80983">Clauses</a></li>
<li title="Guards"><a href="absform.html#id81203">Guards</a></li>
<li title="The abstract format after preprocessing"><a href="absform.html#id81478">The abstract format after preprocessing</a></li>
</ul>
</li>
<li id="no" title="tty - A command line interface" expanded="false">tty - A command line interface<ul>
<li><a href="tty.html">
              Top of chapter
            </a></li>
<li title="Normal Mode"><a href="tty.html#id81651">Normal Mode</a></li>
<li title="Shell Break Mode"><a href="tty.html#id82034">Shell Break Mode</a></li>
</ul>
</li>
<li id="no" title="How to implement a driver" expanded="false">How to implement a driver<ul>
<li><a href="driver.html">
              Top of chapter
            </a></li>
<li title="Introduction"><a href="driver.html#id82159">Introduction</a></li>
<li title="Sample driver"><a href="driver.html#id82191">Sample driver</a></li>
<li title="Compiling and linking the sample driver"><a href="driver.html#id82593">Compiling and linking the sample driver</a></li>
<li title="Calling a driver as a port in Erlang"><a href="driver.html#id82629">Calling a driver as a port in Erlang</a></li>
<li title="Sample asynchronous driver"><a href="driver.html#id82736">Sample asynchronous driver</a></li>
<li title="An asynchronous driver using driver_async"><a href="driver.html#id83010">An asynchronous driver using driver_async</a></li>
</ul>
</li>
<li id="no" title="Inet configuration" expanded="false">Inet configuration<ul>
<li><a href="inet_cfg.html">
              Top of chapter
            </a></li>
<li title="Introduction"><a href="inet_cfg.html#id83274">Introduction</a></li>
<li title="Configuration Data"><a href="inet_cfg.html#id83378">Configuration Data</a></li>
<li title="User Configuration Example"><a href="inet_cfg.html#id84255">User Configuration Example</a></li>
</ul>
</li>
<li id="no" title="External Term Format" expanded="false">External Term Format<ul>
<li><a href="erl_ext_dist.html">
              Top of chapter
            </a></li>
<li title="Introduction"><a href="erl_ext_dist.html#id84356">Introduction</a></li>
<li title="Distribution header"><a href="erl_ext_dist.html#id84636">Distribution header</a></li>
<li title="ATOM_CACHE_REF"><a href="erl_ext_dist.html#id85209">ATOM_CACHE_REF</a></li>
<li title="SMALL_INTEGER_EXT"><a href="erl_ext_dist.html#id85285">SMALL_INTEGER_EXT</a></li>
<li title="INTEGER_EXT"><a href="erl_ext_dist.html#id85348">INTEGER_EXT</a></li>
<li title="FLOAT_EXT"><a href="erl_ext_dist.html#id85412">FLOAT_EXT</a></li>
<li title="ATOM_EXT"><a href="erl_ext_dist.html#id85488">ATOM_EXT</a></li>
<li title="REFERENCE_EXT"><a href="erl_ext_dist.html#id85583">REFERENCE_EXT</a></li>
<li title="PORT_EXT"><a href="erl_ext_dist.html#id85741">PORT_EXT</a></li>
<li title="PID_EXT"><a href="erl_ext_dist.html#id85860">PID_EXT</a></li>
<li title="SMALL_TUPLE_EXT"><a href="erl_ext_dist.html#id86004">SMALL_TUPLE_EXT</a></li>
<li title="LARGE_TUPLE_EXT"><a href="erl_ext_dist.html#id86096">LARGE_TUPLE_EXT</a></li>
<li title="NIL_EXT"><a href="erl_ext_dist.html#id86186">NIL_EXT</a></li>
<li title="STRING_EXT"><a href="erl_ext_dist.html#id86237">STRING_EXT</a></li>
<li title="LIST_EXT"><a href="erl_ext_dist.html#id86329">LIST_EXT</a></li>
<li title="BINARY_EXT"><a href="erl_ext_dist.html#id86448">BINARY_EXT</a></li>
<li title="SMALL_BIG_EXT"><a href="erl_ext_dist.html#id86545">SMALL_BIG_EXT</a></li>
<li title="LARGE_BIG_EXT"><a href="erl_ext_dist.html#id86652">LARGE_BIG_EXT</a></li>
<li title="NEW_REFERENCE_EXT"><a href="erl_ext_dist.html#id86755">NEW_REFERENCE_EXT</a></li>
<li title="SMALL_ATOM_EXT"><a href="erl_ext_dist.html#id86928">SMALL_ATOM_EXT</a></li>
<li title="FUN_EXT"><a href="erl_ext_dist.html#id87034">FUN_EXT</a></li>
<li title="NEW_FUN_EXT"><a href="erl_ext_dist.html#id87281">NEW_FUN_EXT</a></li>
<li title="EXPORT_EXT"><a href="erl_ext_dist.html#id87658">EXPORT_EXT</a></li>
<li title="BIT_BINARY_EXT"><a href="erl_ext_dist.html#id87802">BIT_BINARY_EXT</a></li>
<li title="NEW_FLOAT_EXT"><a href="erl_ext_dist.html#id87908">NEW_FLOAT_EXT</a></li>
</ul>
</li>
<li id="no" title="Distribution Protocol" expanded="false">Distribution Protocol<ul>
<li><a href="erl_dist_protocol.html">
              Top of chapter
            </a></li>
<li title="EPMD Protocol"><a href="erl_dist_protocol.html#id88085">EPMD Protocol</a></li>
<li title="Handshake"><a href="erl_dist_protocol.html#id89383">Handshake</a></li>
<li title="Protocol between connected nodes"><a href="erl_dist_protocol.html#id89399">Protocol between connected nodes</a></li>
<li title="New Ctrlmessages for distrvsn = 1 (OTP R4)"><a href="erl_dist_protocol.html#id89841">New Ctrlmessages for distrvsn = 1 (OTP R4)</a></li>
<li title="New Ctrlmessages for distrvsn = 2"><a href="erl_dist_protocol.html#id89939">New Ctrlmessages for distrvsn = 2</a></li>
<li title="New Ctrlmessages for distrvsn = 3 (OTP R5C)"><a href="erl_dist_protocol.html#id89951">New Ctrlmessages for distrvsn = 3 (OTP R5C)</a></li>
<li title="New Ctrlmessages for distrvsn = 4 (OTP R6)"><a href="erl_dist_protocol.html#id89963">New Ctrlmessages for distrvsn = 4 (OTP R6)</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>4 The Abstract Format</h1>
  
  <p></p>
  <p>This document describes the standard representation of parse trees for Erlang
    programs as Erlang terms. This representation is known as the <strong>abstract format</strong>.
    Functions dealing with such parse trees are <span class="code">compile:forms/[1,2]</span>
    and functions in the modules
    <span class="code">epp</span>,
    <span class="code">erl_eval</span>,
    <span class="code">erl_lint</span>,
    <span class="code">erl_pp</span>,
    <span class="code">erl_parse</span>,
    and
    <span class="code">io</span>.
    They are also used as input and output for parse transforms (see the module
    <span class="code">compile</span>).</p>
  <p>We use the function <span class="code">Rep</span> to denote the mapping from an Erlang source
    construct <span class="code">C</span> to its abstract format representation <span class="code">R</span>, and write
    <span class="code">R = Rep(C)</span>.
    </p>
  <p>The word <span class="code">LINE</span> below represents an integer, and denotes the
    number of the line in the source file where the construction occurred.
    Several instances of <span class="code">LINE</span> in the same construction may denote
    different lines.</p>
  <p>Since operators are not terms in their own right, when operators are
    mentioned below, the representation of an operator should be taken to
    be the atom with a printname consisting of the same characters as the
    operator.
    </p>

  <h3><a name="id79791">4.1 
        Module declarations and forms</a></h3>
    
    <p>A module declaration consists of a sequence of forms that are either
      function declarations or attributes.</p>
    <ul>
      <li>If D is a module declaration consisting of the forms
      <span class="code">F_1</span>, ..., <span class="code">F_k</span>, then
       Rep(D) = <span class="code">[Rep(F_1), ..., Rep(F_k)]</span>.</li>
      <li>If F is an attribute <span class="code">-module(Mod)</span>, then
       Rep(F) = <span class="code">{attribute,LINE,module,Mod}</span>.</li>
      <li>If F is an attribute <span class="code">-export([Fun_1/A_1, ..., Fun_k/A_k])</span>, then
       Rep(F) = <span class="code">{attribute,LINE,export,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}</span>.</li>
      <li>If F is an attribute <span class="code">-import(Mod,[Fun_1/A_1, ..., Fun_k/A_k])</span>, then
       Rep(F) = <span class="code">{attribute,LINE,import,{Mod,[{Fun_1,A_1}, ..., {Fun_k,A_k}]}}</span>.</li>
      <li>If F is an attribute <span class="code">-compile(Options)</span>, then
       Rep(F) = <span class="code">{attribute,LINE,compile,Options}</span>.</li>
      <li>If F is an attribute <span class="code">-file(File,Line)</span>, then
       Rep(F) = <span class="code">{attribute,LINE,file,{File,Line}}</span>.</li>
      <li>If F is a record declaration <span class="code">-record(Name,{V_1, ..., V_k})</span>, then
       Rep(F) =
      <span class="code">{attribute,LINE,record,{Name,[Rep(V_1), ..., Rep(V_k)]}}</span>. For Rep(V), see below.</li>
      <li>If F is a wild attribute <span class="code">-A(T)</span>, then
       Rep(F) = <span class="code">{attribute,LINE,A,T}</span>.
      <br>
</li>
      <li>If F is a function declaration <span class="code">Name Fc_1 ; ... ; Name Fc_k</span>, 
       where each <span class="code">Fc_i</span> is a function clause with a
       pattern sequence of the same length <span class="code">Arity</span>, then
       Rep(F) = <span class="code">{function,LINE,Name,Arity,[Rep(Fc_1), ...,Rep(Fc_k)]}</span>.</li>
    </ul>

    <h4>Record fields</h4>
      
      <p>Each field in a record declaration may have an optional
        explicit default initializer expression</p>
      <ul>
        <li>If V is <span class="code">A</span>, then
         Rep(V) = <span class="code">{record_field,LINE,Rep(A)}</span>.</li>
        <li>If V is <span class="code">A = E</span>, then
         Rep(V) = <span class="code">{record_field,LINE,Rep(A),Rep(E)}</span>.</li>
      </ul>
    

    <h4>Representation of parse errors and end of file</h4>
      
      <p>In addition to the representations of forms, the list that represents
        a module declaration (as returned by functions in <span class="code">erl_parse</span> and
        <span class="code">epp</span>) may contain tuples <span class="code">{error,E}</span> and <span class="code">{warning,W}</span>, denoting
        syntactically incorrect forms and warnings, and <span class="code">{eof,LINE}</span>, denoting an end
        of stream encountered before a complete form had been parsed.</p>
    
  

  <h3><a name="id79999">4.2 
        Atomic literals</a></h3>
    
    <p>There are five kinds of atomic literals, which are represented in the
      same way in patterns, expressions and guards:</p>
    <ul>
      <li>If L is an integer or character literal, then
       Rep(L) = <span class="code">{integer,LINE,L}</span>.</li>
      <li>If L is a float literal, then
       Rep(L) = <span class="code">{float,LINE,L}</span>.</li>
      <li>If L is a string literal consisting of the characters
      <span class="code">C_1</span>, ..., <span class="code">C_k</span>, then
       Rep(L) = <span class="code">{string,LINE,[C_1, ..., C_k]}</span>.</li>
      <li>If L is an atom literal, then
       Rep(L) = <span class="code">{atom,LINE,L}</span>.</li>
    </ul>
    <p>Note that negative integer and float literals do not occur as such; they are
      parsed as an application of the unary negation operator.</p>
  

  <h3><a name="id80061">4.3 
        Patterns</a></h3>
    
    <p>If <span class="code">Ps</span> is a sequence of patterns <span class="code">P_1, ..., P_k</span>, then
      Rep(Ps) = <span class="code">[Rep(P_1), ..., Rep(P_k)]</span>. Such sequences occur as the
      list of arguments to a function or fun.</p>
    <p>Individual patterns are represented as follows:</p>
    <ul>
      <li>If P is an atomic literal L, then Rep(P) = Rep(L).</li>
      <li>If P is a compound pattern <span class="code">P_1 = P_2</span>, then
       Rep(P) = <span class="code">{match,LINE,Rep(P_1),Rep(P_2)}</span>.</li>
      <li>If P is a variable pattern <span class="code">V</span>, then
       Rep(P) = <span class="code">{var,LINE,A}</span>,
       where A is an atom with a printname consisting of the same characters as
      <span class="code">V</span>.</li>
      <li>If P is a universal pattern <span class="code">_</span>, then
       Rep(P) = <span class="code">{var,LINE,'_'}</span>.</li>
      <li>If P is a tuple pattern <span class="code">{P_1, ..., P_k}</span>, then
       Rep(P) = <span class="code">{tuple,LINE,[Rep(P_1), ..., Rep(P_k)]}</span>.</li>
      <li>If P is a nil pattern <span class="code">[]</span>, then
       Rep(P) = <span class="code">{nil,LINE}</span>.</li>
      <li>If P is a cons pattern <span class="code">[P_h | P_t]</span>, then
       Rep(P) = <span class="code">{cons,LINE,Rep(P_h),Rep(P_t)}</span>.</li>
      <li>If E is a binary pattern <span class="code">&lt;&lt;P_1:Size_1/TSL_1, ..., P_k:Size_k/TSL_k&gt;&gt;</span>, then
       Rep(E) = <span class="code">{bin,LINE,[{bin_element,LINE,Rep(P_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(P_k),Rep(Size_k),Rep(TSL_k)}]}</span>.
       For Rep(TSL), see below.
       An omitted <span class="code">Size</span> is represented by <span class="code">default</span>. An omitted <span class="code">TSL</span>
       (type specifier list) is represented by <span class="code">default</span>.</li>
      <li>If P is <span class="code">P_1 Op P_2</span>, where <span class="code">Op</span> is a binary operator (this
       is either an occurrence of <span class="code">++</span> applied to a literal string or character
       list, or an occurrence of an expression that can be evaluated to a number
       at compile time),
       then Rep(P) = <span class="code">{op,LINE,Op,Rep(P_1),Rep(P_2)}</span>.</li>
      <li>If P is <span class="code">Op P_0</span>, where <span class="code">Op</span> is a unary operator (this is an
       occurrence of an expression that can be evaluated to a number at compile
       time), then Rep(P) = <span class="code">{op,LINE,Op,Rep(P_0)}</span>.</li>
      <li>If P is a record pattern <span class="code">#Name{Field_1=P_1, ..., Field_k=P_k}</span>,
       then Rep(P) =
      <span class="code">{record,LINE,Name, [{record_field,LINE,Rep(Field_1),Rep(P_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(P_k)}]}</span>.</li>
      <li>If P is <span class="code">#Name.Field</span>, then
       Rep(P) = <span class="code">{record_index,LINE,Name,Rep(Field)}</span>.</li>
      <li>If P is <span class="code">( P_0 )</span>, then
       Rep(P) = <span class="code">Rep(P_0)</span>,
       i.e., patterns cannot be distinguished from their bodies.</li>
    </ul>
    <p>Note that every pattern has the same source form as some expression, and is
      represented the same way as the corresponding expression.</p>
  

  <h3><a name="id80275">4.4 
        Expressions</a></h3>
    
    <p>A body B is a sequence of expressions <span class="code">E_1, ..., E_k</span>, and
      Rep(B) = <span class="code">[Rep(E_1), ..., Rep(E_k)]</span>.</p>
    <p>An expression E is one of the following alternatives:</p>
    <ul>
      <li>If P is an atomic literal <span class="code">L</span>, then
       Rep(P) = Rep(L).</li>
      <li>If E is <span class="code">P = E_0</span>, then
       Rep(E) = <span class="code">{match,LINE,Rep(P),Rep(E_0)}</span>.</li>
      <li>If E is a variable <span class="code">V</span>, then
       Rep(E) = <span class="code">{var,LINE,A}</span>,
       where <span class="code">A</span> is an atom with a printname consisting of the same
       characters as <span class="code">V</span>.</li>
      <li>If E is a tuple skeleton <span class="code">{E_1, ..., E_k}</span>, then
       Rep(E) = <span class="code">{tuple,LINE,[Rep(E_1), ..., Rep(E_k)]}</span>.</li>
      <li>If E is <span class="code">[]</span>, then
       Rep(E) = <span class="code">{nil,LINE}</span>.</li>
      <li>If E is a cons skeleton <span class="code">[E_h | E_t]</span>, then
       Rep(E) = <span class="code">{cons,LINE,Rep(E_h),Rep(E_t)}</span>.</li>
      <li>If E is a binary constructor <span class="code">&lt;&lt;V_1:Size_1/TSL_1, ..., V_k:Size_k/TSL_k&gt;&gt;</span>, then
       Rep(E) = <span class="code">{bin,LINE,[{bin_element,LINE,Rep(V_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(V_k),Rep(Size_k),Rep(TSL_k)}]}</span>.
       For Rep(TSL), see below.
       An omitted <span class="code">Size</span> is represented by <span class="code">default</span>. An omitted <span class="code">TSL</span>
       (type specifier list) is represented by <span class="code">default</span>.</li>
      <li>If E is <span class="code">E_1 Op E_2</span>, where <span class="code">Op</span> is a binary operator,
       then Rep(E) = <span class="code">{op,LINE,Op,Rep(E_1),Rep(E_2)}</span>.</li>
      <li>If E is <span class="code">Op E_0</span>, where <span class="code">Op</span> is a unary operator, then
       Rep(E) = <span class="code">{op,LINE,Op,Rep(E_0)}</span>.</li>
      <li>If E is <span class="code">#Name{Field_1=E_1, ..., Field_k=E_k}</span>, then
       Rep(E) =
      <span class="code">{record,LINE,Name,  [{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}</span>.</li>
      <li>If E is <span class="code">E_0#Name{Field_1=E_1, ..., Field_k=E_k}</span>, then
       Rep(E) =
      <span class="code">{record,LINE,Rep(E_0),Name,  [{record_field,LINE,Rep(Field_1),Rep(E_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(E_k)}]}</span>.</li>
      <li>If E is <span class="code">#Name.Field</span>, then
       Rep(E) = <span class="code">{record_index,LINE,Name,Rep(Field)}</span>.</li>
      <li>If E is <span class="code">E_0#Name.Field</span>, then
       Rep(E) = <span class="code">{record_field,LINE,Rep(E_0),Name,Rep(Field)}</span>.</li>
      <li>If E is <span class="code">catch E_0</span>, then
       Rep(E) = <span class="code">{'catch',LINE,Rep(E_0)}</span>.</li>
      <li>If E is <span class="code">E_0(E_1, ..., E_k)</span>, then
       Rep(E) = <span class="code">{call,LINE,Rep(E_0),[Rep(E_1), ..., Rep(E_k)]}</span>.</li>
      <li>If E is <span class="code">E_m:E_0(E_1, ..., E_k)</span>, then
       Rep(E) =
      <span class="code">{call,LINE,{remote,LINE,Rep(E_m),Rep(E_0)},[Rep(E_1), ...,  Rep(E_k)]}</span>.</li>
      <li>If E is a list comprehension <span class="code">[E_0 || W_1, ..., W_k]</span>,
       where each <span class="code">W_i</span> is a generator or a filter, then
       Rep(E) = <span class="code">{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</span>. For Rep(W), see
       below.</li>
      <li>If E is a binary comprehension <span class="code">&lt;&lt;E_0 || W_1, ..., W_k&gt;&gt;</span>,
       where each <span class="code">W_i</span> is a generator or a filter, then
       Rep(E) = <span class="code">{bc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}</span>. For Rep(W), see
       below.</li>
      <li>If E is <span class="code">begin B end</span>, where <span class="code">B</span> is a body, then
       Rep(E) = <span class="code">{block,LINE,Rep(B)}</span>.</li>
      <li>If E is <span class="code">if Ic_1 ; ... ; Ic_k  end</span>,
       where each <span class="code">Ic_i</span> is an if clause then
       Rep(E) =
      <span class="code">{'if',LINE,[Rep(Ic_1), ..., Rep(Ic_k)]}</span>.</li>
      <li>If E is <span class="code">case E_0 of Cc_1 ; ... ; Cc_k end</span>,
       where <span class="code">E_0</span> is an expression and each <span class="code">Cc_i</span> is a
       case clause then
       Rep(E) =
      <span class="code">{'case',LINE,Rep(E_0),[Rep(Cc_1), ..., Rep(Cc_k)]}</span>.</li>
      <li>If E is <span class="code">try B catch Tc_1 ; ... ; Tc_k end</span>,
       where <span class="code">B</span> is a body and each <span class="code">Tc_i</span> is a catch clause then 
       Rep(E) =
      <span class="code">{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],[]}</span>.</li>
      <li>If E is <span class="code">try B of Cc_1 ; ... ; Cc_k catch Tc_1 ; ... ; Tc_n end</span>,
       where <span class="code">B</span> is a body, 
       each <span class="code">Cc_i</span> is a case clause and 
       each <span class="code">Tc_j</span> is a catch clause then 
       Rep(E) =
      <span class="code">{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1), ..., Rep(Tc_n)],[]}</span>.</li>
      <li>If E is <span class="code">try B after A end</span>,
       where <span class="code">B</span> and <span class="code">A</span> are bodies then
       Rep(E) =
      <span class="code">{'try',LINE,Rep(B),[],[],Rep(A)}</span>.</li>
      <li>If E is <span class="code">try B of Cc_1 ; ... ; Cc_k after A end</span>,
       where <span class="code">B</span> and <span class="code">A</span> are a bodies and
       each <span class="code">Cc_i</span> is a case clause then 
       Rep(E) =
      <span class="code">{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[],Rep(A)}</span>.</li>
      <li>If E is <span class="code">try B catch Tc_1 ; ... ; Tc_k after A end</span>,
       where <span class="code">B</span> and <span class="code">A</span> are bodies and
       each <span class="code">Tc_i</span> is a catch clause then 
       Rep(E) =
      <span class="code">{'try',LINE,Rep(B),[],[Rep(Tc_1), ..., Rep(Tc_k)],Rep(A)}</span>.</li>
      <li>If E is <span class="code">try B of Cc_1 ; ... ; Cc_k  catch Tc_1 ; ... ; Tc_n after A end</span>,
       where <span class="code">B</span> and <span class="code">A</span> are a bodies, 
       each <span class="code">Cc_i</span> is a case clause and
       each <span class="code">Tc_j</span> is a catch clause then 
       Rep(E) =
      <span class="code">{'try',LINE,Rep(B),[Rep(Cc_1), ..., Rep(Cc_k)],[Rep(Tc_1),  ..., Rep(Tc_n)],Rep(A)}</span>.</li>
      <li>If E is <span class="code">receive Cc_1 ; ... ; Cc_k end</span>,
       where each <span class="code">Cc_i</span> is a case clause then
       Rep(E) =
      <span class="code">{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)]}</span>.</li>
      <li>If E is <span class="code">receive Cc_1 ; ... ; Cc_k after E_0 -&gt; B_t end</span>,
       where each <span class="code">Cc_i</span> is a case clause, 
      <span class="code">E_0</span> is an expression and <span class="code">B_t</span> is a body, then
       Rep(E) =
      <span class="code">{'receive',LINE,[Rep(Cc_1), ..., Rep(Cc_k)],Rep(E_0),Rep(B_t)}</span>.</li>
      <li>If E is <span class="code">fun Name / Arity</span>, then
       Rep(E) = <span class="code">{'fun',LINE,{function,Name,Arity}}</span>.</li>
      <li>If E is <span class="code">fun Module:Name/Arity</span>, then
       Rep(E) = <span class="code">{'fun',LINE,{function,Rep(Module),Rep(Name),Rep(Arity)}}</span>.
      (Before the R15 release: Rep(E) = <span class="code">{'fun',LINE,{function,Module,Name,Arity}}</span>.)</li>
      <li>If E is <span class="code">fun Fc_1 ; ... ; Fc_k end</span> 
       where each <span class="code">Fc_i</span> is a function clause then Rep(E) =
      <span class="code">{'fun',LINE,{clauses,[Rep(Fc_1), ..., Rep(Fc_k)]}}</span>.</li>
      <li>If E is <span class="code">query [E_0 || W_1, ..., W_k] end</span>,
       where each <span class="code">W_i</span> is a generator or a filter, then
       Rep(E) = <span class="code">{'query',LINE,{lc,LINE,Rep(E_0),[Rep(W_1), ..., Rep(W_k)]}}</span>.
       For Rep(W), see below.</li>
      <li>If E is <span class="code">E_0.Field</span>, a Mnesia record access
       inside a query, then
       Rep(E) = <span class="code">{record_field,LINE,Rep(E_0),Rep(Field)}</span>.</li>
      <li>If E is <span class="code">( E_0 )</span>, then
       Rep(E) = <span class="code">Rep(E_0)</span>,
       i.e., parenthesized expressions cannot be distinguished from their bodies.</li>
    </ul>

    <h4>Generators and filters</h4>
      
      <p>When W is a generator or a filter (in the body of a list or binary comprehension), then:</p>
      <ul>
        <li>If W is a generator <span class="code">P &lt;- E</span>, where <span class="code">P</span> is a pattern and <span class="code">E</span>
         is an expression, then
         Rep(W) = <span class="code">{generate,LINE,Rep(P),Rep(E)}</span>.</li>
        <li>If W is a generator <span class="code">P &lt;= E</span>, where <span class="code">P</span> is a pattern and <span class="code">E</span>
         is an expression, then
         Rep(W) = <span class="code">{b_generate,LINE,Rep(P),Rep(E)}</span>.</li>
        <li>If W is a filter <span class="code">E</span>, which is an expression, then
         Rep(W) = <span class="code">Rep(E)</span>.</li>
      </ul>
    

    <h4>Binary element type specifiers</h4>
      
      <p>A type specifier list TSL for a binary element is a sequence of type
        specifiers <span class="code">TS_1 - ... - TS_k</span>.
        Rep(TSL) = <span class="code">[Rep(TS_1), ..., Rep(TS_k)]</span>.</p>
      <p>When TS is a type specifier for a binary element, then:</p>
      <ul>
        <li>If TS is an atom <span class="code">A</span>, Rep(TS) = <span class="code">A</span>.</li>
        <li>If TS is a couple <span class="code">A:Value</span> where <span class="code">A</span> is an atom and <span class="code">Value</span>
         is an integer, Rep(TS) = <span class="code">{A, Value}</span>.</li>
      </ul>
    
  

  <h3><a name="id80983">4.5 
        Clauses</a></h3>
    
    <p>There are function clauses, if clauses, case clauses 
      and catch clauses.</p>
    <p>A clause <span class="code">C</span> is one of the following alternatives:</p>
    <ul>
      <li>If C is a function clause <span class="code">( Ps ) -&gt; B</span> 
       where <span class="code">Ps</span> is a pattern sequence and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,Rep(Ps),[],Rep(B)}</span>.</li>
      <li>If C is a function clause <span class="code">( Ps ) when Gs -&gt; B</span> 
       where <span class="code">Ps</span> is a pattern sequence, 
      <span class="code">Gs</span> is a guard sequence and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,Rep(Ps),Rep(Gs),Rep(B)}</span>.</li>
      <li>If C is an if clause <span class="code">Gs -&gt; B</span> 
       where <span class="code">Gs</span> is a guard sequence and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,[],Rep(Gs),Rep(B)}</span>.</li>
      <li>If C is a case clause <span class="code">P -&gt; B</span> 
       where <span class="code">P</span> is a pattern and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,[Rep(P)],[],Rep(B)}</span>.</li>
      <li>If C is a case clause <span class="code">P when Gs -&gt; B</span> 
       where <span class="code">P</span> is a pattern, 
      <span class="code">Gs</span> is a guard sequence and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,[Rep(P)],Rep(Gs),Rep(B)}</span>.</li>
      <li>If C is a catch clause <span class="code">P -&gt; B</span> 
       where <span class="code">P</span> is a pattern and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,[Rep({throw,P,_})],[],Rep(B)}</span>.</li>
      <li>If C is a catch clause <span class="code">X : P -&gt; B</span> 
       where <span class="code">X</span> is an atomic literal or a variable pattern, 
      <span class="code">P</span> is a pattern and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,[Rep({X,P,_})],[],Rep(B)}</span>.</li>
      <li>If C is a catch clause <span class="code">P when Gs -&gt; B</span> 
       where <span class="code">P</span> is a pattern, <span class="code">Gs</span> is a guard sequence 
       and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,[Rep({throw,P,_})],Rep(Gs),Rep(B)}</span>.</li>
      <li>If C is a catch clause <span class="code">X : P when Gs -&gt; B</span> 
       where <span class="code">X</span> is an atomic literal or a variable pattern, 
      <span class="code">P</span> is a pattern, <span class="code">Gs</span> is a guard sequence 
       and <span class="code">B</span> is a body, then 
       Rep(C) = <span class="code">{clause,LINE,[Rep({X,P,_})],Rep(Gs),Rep(B)}</span>.</li>
    </ul>
  

  <h3><a name="id81203">4.6 
        Guards</a></h3>
    
    <p>A guard sequence Gs is a sequence of guards <span class="code">G_1; ...; G_k</span>, and
      Rep(Gs) = <span class="code">[Rep(G_1), ..., Rep(G_k)]</span>. If the guard sequence is
      empty, Rep(Gs) = <span class="code">[]</span>.</p>
    <p>A guard G is a nonempty sequence of guard tests <span class="code">Gt_1, ..., Gt_k</span>, and
      Rep(G) = <span class="code">[Rep(Gt_1), ..., Rep(Gt_k)]</span>.</p>
    <p>A guard test <span class="code">Gt</span> is one of the following alternatives:</p>
    <ul>
      <li>If Gt is an atomic literal L, then Rep(Gt) = Rep(L).</li>
      <li>If Gt is a variable pattern <span class="code">V</span>, then
       Rep(Gt) = <span class="code">{var,LINE,A}</span>,
       where A is an atom with a printname consisting of the same characters as
      <span class="code">V</span>.</li>
      <li>If Gt is a tuple skeleton <span class="code">{Gt_1, ..., Gt_k}</span>, then
       Rep(Gt) = <span class="code">{tuple,LINE,[Rep(Gt_1), ..., Rep(Gt_k)]}</span>.</li>
      <li>If Gt is <span class="code">[]</span>, then
       Rep(Gt) = <span class="code">{nil,LINE}</span>.</li>
      <li>If Gt is a cons skeleton <span class="code">[Gt_h | Gt_t]</span>, then
       Rep(Gt) = <span class="code">{cons,LINE,Rep(Gt_h),Rep(Gt_t)}</span>.</li>
      <li>If Gt is a binary constructor <span class="code">&lt;&lt;Gt_1:Size_1/TSL_1, ..., Gt_k:Size_k/TSL_k&gt;&gt;</span>, then
       Rep(Gt) = <span class="code">{bin,LINE,[{bin_element,LINE,Rep(Gt_1),Rep(Size_1),Rep(TSL_1)}, ..., {bin_element,LINE,Rep(Gt_k),Rep(Size_k),Rep(TSL_k)}]}</span>.
       For Rep(TSL), see above.
       An omitted <span class="code">Size</span> is represented by <span class="code">default</span>. An omitted <span class="code">TSL</span>
       (type specifier list) is represented by <span class="code">default</span>.</li>
      <li>If Gt is <span class="code">Gt_1 Op Gt_2</span>, where <span class="code">Op</span>
       is a binary operator, then Rep(Gt) = <span class="code">{op,LINE,Op,Rep(Gt_1),Rep(Gt_2)}</span>.</li>
      <li>If Gt is <span class="code">Op Gt_0</span>, where <span class="code">Op</span> is a unary operator, then
       Rep(Gt) = <span class="code">{op,LINE,Op,Rep(Gt_0)}</span>.</li>
      <li>If Gt is <span class="code">#Name{Field_1=Gt_1, ..., Field_k=Gt_k}</span>, then
       Rep(E) =
      <span class="code">{record,LINE,Name,  [{record_field,LINE,Rep(Field_1),Rep(Gt_1)}, ..., {record_field,LINE,Rep(Field_k),Rep(Gt_k)}]}</span>.</li>
      <li>If Gt is <span class="code">#Name.Field</span>, then
       Rep(Gt) = <span class="code">{record_index,LINE,Name,Rep(Field)}</span>.</li>
      <li>If Gt is <span class="code">Gt_0#Name.Field</span>, then
       Rep(Gt) = <span class="code">{record_field,LINE,Rep(Gt_0),Name,Rep(Field)}</span>.</li>
      <li>If Gt is <span class="code">A(Gt_1, ..., Gt_k)</span>, where <span class="code">A</span> is an atom, then
       Rep(Gt) = <span class="code">{call,LINE,Rep(A),[Rep(Gt_1), ..., Rep(Gt_k)]}</span>.</li>
      <li>If Gt is <span class="code">A_m:A(Gt_1, ..., Gt_k)</span>, where <span class="code">A_m</span> is 
       the atom <span class="code">erlang</span> and <span class="code">A</span> is an atom or an operator, then
       Rep(Gt) = <span class="code">{call,LINE,{remote,LINE,Rep(A_m),Rep(A)},[Rep(Gt_1), ..., Rep(Gt_k)]}</span>.</li>
      <li>If Gt is <span class="code">{A_m,A}(Gt_1, ..., Gt_k)</span>, where <span class="code">A_m</span> is 
       the atom <span class="code">erlang</span> and <span class="code">A</span> is an atom or an operator, then
       Rep(Gt) = <span class="code">{call,LINE,Rep({A_m,A}),[Rep(Gt_1), ..., Rep(Gt_k)]}</span>.</li>
      <li>If Gt is <span class="code">( Gt_0 )</span>, then
       Rep(Gt) = <span class="code">Rep(Gt_0)</span>,
       i.e., parenthesized guard tests cannot be distinguished from their bodies.</li>
    </ul>
    <p>Note that every guard test has the same source form as some expression,
      and is represented the same way as the corresponding expression.</p>
  

  <h3><a name="id81478">4.7 
        The abstract format after preprocessing</a></h3>
    
    <p>The compilation option <span class="code">debug_info</span> can be given to the
      compiler to have the abstract code stored in 
      the <span class="code">abstract_code</span> chunk in the BEAM file
      (for debugging purposes).</p>
    <p>In OTP R9C and later, the <span class="code">abstract_code</span> chunk will
      contain</p>
    <p><span class="code">{raw_abstract_v1,AbstractCode}</span></p>
    <p>where <span class="code">AbstractCode</span> is the abstract code as described
      in this document.</p>
    <p>In releases of OTP prior to R9C, the abstract code after some more
      processing was stored in the BEAM file. The first element of the
      tuple would be either <span class="code">abstract_v1</span> (R7B) or <span class="code">abstract_v2</span>
      (R8B).</p>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>