<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.1" xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:trans="http://docbook.org/ns/transclusion"
         xmlns:svg="http://www.w3.org/2000/svg"
         xmlns:m="http://www.w3.org/1998/Math/MathML"
         xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns:db="http://docbook.org/ns/docbook">
  <title>AST API</title>

  <para>In order to reason about program, code model is translated into form
  suited for processing by Transcend. Translation details are described
  below.</para>

  <section>
    <title>Expression Annotations: 'bind'</title>

    <synopsis>SYNTAX:
**bind**(//symbol-ref//, //annotation//)</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>symbol-ref</emphasis> reference to the expression or
        identifier</para>
      </listitem>

      <listitem>
        <para><emphasis>annotation</emphasis> expression's annotation</para>
      </listitem>
    </itemizedlist>

    <para>Declares expression's annotations.</para>

    <para>Example:</para>

    <programlisting xml:id="ExprAnn_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int 
{
  x = 5::         int; expected(even_number).

  x
}</programlisting>

    <para>gets translated into:</para>

    <programlisting xml:id="Output_ExprAnn_1">bind(s(1,-2,0),expected(even_number)) </programlisting>
  </section>

  <section>
    <title>Code Block: 'scope'</title>

    <synopsis>SYNTAX: 
**scope**(//scope-ref//)</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>scope-ref</emphasis> reference to the code
        block</para>
      </listitem>
    </itemizedlist>

    <para>Declares code block under its unique reference identifier.</para>

    <para>Example:</para>

    <programlisting xml:id="CodeBlock_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: float
{
  x = 3::       float.
  y = 8::       float. 

  x + y 
}</programlisting>

    <para>Translation result: <code
    xml:id="Output_CodeBlock_1">scope(0)</code></para>
  </section>

  <section>
    <title>Code Block Annotations: 'bind_scope'</title>

    <warning>
      <para>Pending syntax changes</para>
    </warning>

    <synopsis>SYNTAX:
**bind_scope**(//scope-ref//, //annotation//, strong)    (1)
**bind_scope**(//scope-ref//, //annotation//, weak(..))  (2)
</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>scope-ref</emphasis> child block's reference</para>
      </listitem>

      <listitem>
        <para><emphasis>annotation</emphasis> code block's annotation</para>
      </listitem>
    </itemizedlist>

    <para>Declares code block's annotations called
    <emphasis>context</emphasis>. There are two forms for different context'
    type:</para>

    <itemizedlist>
      <listitem>
        <para><emphasis>strong</emphasis> context known at compile time</para>
      </listitem>

      <listitem>
        <para><emphasis>weak</emphasis> possible context, can't be decided for
        sure at compile time</para>
      </listitem>
    </itemizedlist>

    <para>Example:</para>

    <programlisting xml:id="CodeBlockAnns_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: float
{
  context::       arithmetic(fast).

  x = 3::         float.
  y = 8::         float. 

  x + y 
}</programlisting>

    <para>Translation's result:</para>

    <programlisting xml:id="Output_CodeBlockAnns_1">bind_scope(0,arithmetic(fast),strong)</programlisting>
  </section>

  <section>
    <title>Code Block Bindings: 'ast_scope_binding'</title>

    <synopsis>SYNTAX:
**ast_scope_binding**(//scope-ref//, //binding-id//, //binding-alias//)</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>scope-ref</emphasis> code block's reference</para>
      </listitem>

      <listitem>
        <para><emphasis>binding-id</emphasis> number of code block's
        binding</para>
      </listitem>

      <listitem>
        <para><emphasis>binding-alias</emphasis> name of a binding</para>
      </listitem>
    </itemizedlist>

    <para>Code blocks have zero or more <emphasis>bindings</emphasis>, i.e.
    Identifiers that have special meaning within the block. Predicate declares
    such code block's bindings. Bindings organized into ordered list. Order is
    conveyed by specifying <emphasis>binding-id</emphasis> for each
    <emphasis>binding-alias.</emphasis></para>

    <para>Example:</para>

    <programlisting xml:id="CodeBlockBinds_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function::     int
{
  loop ( 0 -&gt; acc ):: int 
  {
    if(acc &gt; 10):: int {acc:: int; final} else {acc + 1}
  }
}</programlisting>

    <para>Translation result: <code
    xml:id="Output_CodeBlockBinds_1">ast_scope_binding(1,0,"acc")</code></para>
  </section>

  <section>
    <title>Code Block Parents: 'cfa_parent'</title>

    <synopsis>SYNTAX:
**cfa_parent**(//scope-ref//, **scope**(//scope-parent-ref//))</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>scope-ref</emphasis> child block's reference</para>
      </listitem>

      <listitem>
        <para><emphasis>scope-parent-ref</emphasis> parent block's
        reference</para>
      </listitem>
    </itemizedlist>

    <para>Represents nested code blocks structure in terms of
    <emphasis>child-parent</emphasis> relation.</para>

    <para>Example:</para>

    <programlisting xml:id="CodeBlockParents_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int
{
  x = 19::        int.

  if (x&gt;5):: int {x + 1} else {x - 1}
}</programlisting>

    <para>Translation's result:</para>

    <programlisting xml:id="Output_CodeBlockParents_1">cfa_parent(1, scope(0)).
cfa_parent(2, scope(0)).</programlisting>
  </section>

  <section>
    <title>Function: 'function'</title>

    <synopsis>SYNTAX:
**function**(//fn-name//)</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>fn-name</emphasis> function name</para>
      </listitem>
    </itemizedlist>

    <para>Declares function identified by its name.</para>

    <para>Example:</para>

    <programlisting xml:id="Fn_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int {0}</programlisting>

    <para>Translation's result: <code
    xml:id="Output_Fn_1">function(test)</code></para>
  </section>

  <section>
    <title>Function's Annotations: 'bind_func'</title>

    <synopsis>SYNTAX:
**bind_func**(//fn-name//, //annotation//)</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>fn-name</emphasis> function's name</para>
      </listitem>
    </itemizedlist>

    <para>Declares function's annotations.</para>

    <para>Example:</para>

    <programlisting xml:id="FnAnns_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int; status(obsolete) {0}</programlisting>

    <para>Translation's result: <code
    xml:id="Output_FnAnns_1">bind_func(test,status(obsolete))</code></para>
  </section>

  <section>
    <title>Function's Specialization: 'cfa_function_specializations'</title>

    <synopsis>SYNTAX:
**cfa_function_specializations**(//fn-name//, //guard//)</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>fn-name</emphasis> name of function</para>
      </listitem>

      <listitem>
        <para><emphasis>guard</emphasis> specialization guard</para>
      </listitem>
    </itemizedlist>

    <para>There is a possibility to have several functions with the same name
    called specializations. Each specialization is uniquely determined by
    annotation of special kind called <emphasis>guard</emphasis>.</para>

    <para>Example:</para>

    <programlisting xml:id="FnSpecs_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
guard::             arch(amd64) 
{
  test = function:: i64 {0}
}</programlisting>

    <para>Translation's result: <code
    xml:id="Output_FnSpecs_1">cfa_function_specializations(test,arch(amd64))</code><note>
        <para>See also <link
        xlink:href="/w/syntax#function-specializations">specializations
        syntax</link></para>
      </note></para>
  </section>

  <section>
    <title>Function's Entry: 'cfa_parent'</title>

    <synopsis>SYNTAX:
**cfa_parent**(//scope-entry-ref//, functon(//fn-name//))</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>scope-entry-ref</emphasis> function's entry code block
        reference</para>
      </listitem>

      <listitem>
        <para><emphasis>fn-name</emphasis> function's name</para>
      </listitem>
    </itemizedlist>

    <para>Each function has a single <emphasis>entry</emphasis> code block and
    is declared in terms of <emphasis>child-parent</emphasis> relation between
    entry block(which is top-level in blocks hierarchy of the given function)
    and the function itself.</para>

    <para>Example:</para>

    <programlisting xml:id="FnEntry_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int {0}</programlisting>

    <para>Translation's result: <code
    xml:id="Output_FnEntry_1">cfa_parent(0,function(test))</code></para>
  </section>

  <section>
    <title>Function's Result: 'dfa_fnret'</title>

    <synopsis>SYNTAX:
**dfa_fnret**(//fn-name//, //symbol-ret-ref//)</synopsis>

    <itemizedlist>
      <listitem>
        <para>symbol-ret-ref reference to a function's return
        expression</para>
      </listitem>
    </itemizedlist>

    <para>Specifies which expression is used to compute function's return
    value.</para>

    <para>Example:</para>

    <programlisting xml:id="FnResult_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int {0}</programlisting>

    <para>Translation's result: <code
    xml:id="Output_FnResult_1">dfa_fnret(test,s(0,-2,0))</code></para>
  </section>

  <section>
    <title>Operations. Invocation: 'cfa_call', 'dfa_callfn',
    'dfa_callargs'</title>

    <synopsis>SYNTAX:
**cfa_call**(//scope-caller-ref//, //fn-callee-name//)                          (1)
**dfa_callfn**(//symbol-ref//, //fn-callee-name//)                              (2)
**dfa_callargs**(//symbol-ref//, //arg-formal-name//, //arg-actual-ref//)       (3)
**weak**(**dfa_callargs**(//symbol-ref//, //arg-formal-name//, //arg-actual-ref//)) (4)
</synopsis>

    <itemizedlist>
      <listitem>
        <para><emphasis>scope-caller-ref</emphasis> caller's code block's
        reference</para>
      </listitem>

      <listitem>
        <para><emphasis>fn-callee-name</emphasis> callee function name</para>
      </listitem>

      <listitem>
        <para><emphasis>symbol-ref</emphasis> invocation operation
        reference</para>
      </listitem>

      <listitem>
        <para><emphasis>arg-formal-name</emphasis> function's formal
        argument</para>
      </listitem>

      <listitem>
        <para><emphasis>arg-actual-ref</emphasis> actual argument
        reference</para>
      </listitem>
    </itemizedlist>

    <para>Each function invocation is transformed into several transcend facts
    as explained below:</para>

    <informaltable>
      <tgroup cols="2">
        <colspec colwidth="225*"/>

        <colspec colwidth="775*"/>

        <tbody>
          <row>
            <entry>(1) <code>cfa_call</code></entry>

            <entry>Specifies caller's code block and callee function
            name</entry>
          </row>

          <row>
            <entry>(2) <code>dfa_callfn</code></entry>

            <entry>Declares unique reference to a particular invocation
            site.The reference used by other facts to supply additional
            information</entry>
          </row>

          <row>
            <entry>(3) <code>dfa_callargs</code></entry>

            <entry>Declares assignment relations between actual arguments and
            formal arguments</entry>
          </row>

          <row>
            <entry>(4) <code>weak(dfa_callargs)</code></entry>

            <entry>The same as form (3). <emphasis>Weak</emphasis> relation
            used in cases when there is no enough information at compile time.
            One such case is when several function specializations exist and
            it's impossible to say which exactly specialization is
            called</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>

    <para>Example:</para>

    <programlisting xml:id="OpInvoc_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
inc  = function (x::int)::  int 
{
  x + 1
}

main = function::           int 
{
  arg = 10::                int.
  inc(arg)
}</programlisting>

    <para>After translation following transcend facts are present:</para>

    <programlisting xml:id="Output_OpInvoc_1">cfa_call(1,inc)
dfa_callfn(s(0,-2,1),inc)
weak(dfa_callargs(s(0,-2,1),s(1,-2,0),s(1,-2,1)))
dfa_callargs(s(0,-2,1),s(1,-2,0),s(1,-2,1))</programlisting>
  </section>

  <section>
    <title>Operations. Loops</title>

    <synopsis>**ast_op_map**(//symbol-result-ref//, //symbol-source-ref//, //loop-body-ref//)
**ast_op_fold**(//symbol-result-ref//, //symbol-source-ref//, //symbol-acc-ref//, //loop-body-ref//)</synopsis>

    <itemizedlist>
      <listitem>
        <para>symbol-source-ref input list reference</para>
      </listitem>

      <listitem>
        <para>symbol-acc-ref accumulator reference</para>
      </listitem>

      <listitem>
        <para>symbol-result-ref result list reference</para>
      </listitem>

      <listitem>
        <para>loop-body-ref refers to a loop body expression</para>
      </listitem>
    </itemizedlist>

    <para>Facts declare loop operations.</para>

    <para>Example:</para>

    <programlisting xml:id="OpLoops_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function::       int; entry 
{
  singles = {1, 2, 3}:: [int].
  doubles = loop map(singles-&gt;element:: int)::[int] {2 * element}.
  doubles[0]
}</programlisting>

    <para>produces fact: <code
    xml:id="Output_OpLoops_1">ast_op_map(s(2,-2,0),s(1,-2,0),s(0,-2,1))</code></para>
  </section>
</chapter>
