This file is indexed.

/usr/share/mozart/doc/compiler/node4.html is in mozart-doc 1.4.0-8ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

1
2
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>4 Application Programmer's Interface</TITLE><LINK href="ozdoc.css" rel="stylesheet" type="text/css"></HEAD><BODY><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="node3.html#chapter.applications">&lt;&lt; Prev</A></TD><TD><A href="index.html">- Up -</A></TD><TD><A href="node5.html#appendix.switches">Next &gt;&gt;</A></TD></TR></TABLE><DIV id="chapter.api"><H1><A name="chapter.api">4 Application Programmer's Interface</A></H1><P> The compiler is available to Mozart applications through the module <CODE>Compiler</CODE>. This chapter describes the functionality provided by that module and its classes. </P><P> First, a number of additional secondary type names used in this description is introduced in <A href="node4.html#section.api.types">Section&nbsp;4.1</A>, then the <CODE>Compiler</CODE> module is described in <A href="node4.html#section.api.module">Section&nbsp;4.2</A>. The material in that section should prove sufficient for most cases. The remainder of the chapter is intended for advanced uses. </P><P> An arbitrary number of compilers may be instantiated, each with its own internal state, and used concurrently. We distinguish between <EM>compiler engines</EM>, described in <A href="node4.html#section.api.engines">Section&nbsp;4.3</A>, which store the state of a compiler and perform the compilation proper, and <EM>compiler interfaces</EM>, described in <A href="node4.html#section.api.interfaces">Section&nbsp;4.4</A>, which allow to observe the activities of compiler engines and to react to them. Both of these use the narrator/listener mechanism described in <A href="node6.html#appendix.narrator">Appendix&nbsp;B</A>; familiarity with this is assumed. </P><P> Finally, examples are presented in <A href="node4.html#section.api.examples">Section&nbsp;4.5</A>; in particular, the provided abstractions are explained in terms of compiler engines and interfaces. </P><DIV id="section.api.types"><H2><A name="section.api.types">4.1 Additional Secondary Types</A></H2><P> This section describes additional secondary types used in the descriptions in this chapter. The conventions defined in <A href="../base/node2.html#section.typestruct.format">Section&nbsp;2.3 of ``The Oz Base Environment''</A> will be respected. </P><DL><DT><CODE><I>Coord</I></CODE> </DT><DD><P>stands for information about source coordinates. This is either <CODE><SPAN class="keyword">unit</SPAN></CODE> if no information is known or a tuple <CODE>pos(</CODE><CODE><I>FileName</I></CODE><CODE>&nbsp;</CODE><CODE><I>Line</I></CODE><CODE>&nbsp;</CODE><CODE><I>Column</I></CODE><CODE>)</CODE>, where <CODE><I>FileName</I></CODE> is represented as an atom (<CODE><SPAN class="string">''</SPAN></CODE> meaning <SPAN class="quasi">`unknown'</SPAN>) and <CODE><I>Line</I></CODE> and <CODE><I>Column</I></CODE> are integers. Line numbering begins at&nbsp;<CODE>1</CODE> and column numbering at&nbsp;<CODE>0</CODE>; a column number of <CODE><SPAN class="keyword">~</SPAN>1</CODE> means <SPAN class="quasi">`unknown'</SPAN>. </P></DD><DT><CODE><I>SwitchName</I></CODE> </DT><DD><P>is an atom which must be a valid switch name (see <A href="node5.html#appendix.switches">Appendix&nbsp;A</A>). </P></DD><DT><CODE><I>PrintName</I></CODE> </DT><DD><P>is an atom which must be a valid variable print name. </P></DD><DT><CODE><I>Env</I></CODE> </DT><DD><P>represents an environment, represented as a record whose features are valid print names. </P></DD></DL><P> </P></DIV><DIV id="section.api.module"><H2><A name="section.api.module">4.2 The <CODE>Compiler</CODE> Module</A></H2><P> </P><DL><DT><CODE>evalExpression</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{Compiler<SPAN class="keyword">.</SPAN>evalExpression&nbsp;</CODE><CODE>+<I>V</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>Env</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>KillP</I></CODE><CODE>&nbsp;</CODE><CODE><I>X</I></CODE><CODE>}</CODE> </P></BLOCKQUOTE></DD><DD><P>evaluates an expression, given as a virtual string&nbsp;<CODE><I>V</I></CODE>, in a base environment enriched by the bindings given by <CODE><I>Env</I></CODE>, either returning the result&nbsp;<CODE><I>X</I></CODE> of the evaluation or raising an exception. Furthermore, the variable <CODE><I>KillP</I></CODE> is bound to a nullary procedure which, when applied, interrupts compilation. </P></DD><DT><CODE>virtualStringToValue</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{Compiler<SPAN class="keyword">.</SPAN>virtualStringToValue&nbsp;</CODE><CODE>+<I>V</I></CODE><CODE>&nbsp;</CODE><CODE><I>X</I></CODE><CODE>}</CODE> </P></BLOCKQUOTE></DD><DD><P>is a replacement for <CODE>System<SPAN class="keyword">.</SPAN>virtualStringToValue</CODE>, which was available in Mozart's predecessor DFKI Oz. </P><P> Note that you are discouraged from using this for large data structures: Because it is much more powerful than <CODE>System<SPAN class="keyword">.</SPAN>virtualStringToValue</CODE>, it can also be much less efficient. Rather, you should use pickling and unpickling of data structures (see <A href="../system/node57.html#chapter.pickle">Chapter&nbsp;22 of ``System Modules''</A>). </P></DD><DT><CODE>engine</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>Compiler<SPAN class="keyword">.</SPAN>engine</CODE> </P></BLOCKQUOTE></DD><DD><P>is the final class from which compiler engines can be instantiated. This is described in detail in <A href="node4.html#section.api.engines">Section&nbsp;4.3</A>. </P></DD><DT><CODE>interface</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>Compiler<SPAN class="keyword">.</SPAN>interface</CODE> </P></BLOCKQUOTE></DD><DD><P>is a class providing a simple mechanism to create compiler interfaces. It is described in detail in <A href="node4.html#section.api.interfaces">Section&nbsp;4.4</A>. </P></DD><DT><CODE>parseOzFile</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{Compiler<SPAN class="keyword">.</SPAN>parseOzFile&nbsp;</CODE><CODE>+<I>V</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>O</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>P</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>Dictionary</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>T</I></CODE><CODE>}</CODE> </P></BLOCKQUOTE></DD><DD><P>parses the Oz source file named <CODE><I>V</I></CODE>, returning an abstract syntax tree as defined in <A href="node7.html#appendix.syntax">Appendix&nbsp;C</A> in <CODE><I>T</I></CODE>. <CODE><I>O</I></CODE> is an instance of the <CODE>PrivateNarrator</CODE> class described in <A href="node6.html#appendix.narrator">Appendix&nbsp;B</A>; its methods are invoked for example to report compilation errors. <CODE><I>P</I></CODE> is a unary procedure expecting a switch name as described in <A href="node5.html#appendix.switches">Appendix&nbsp;A</A> and returning a boolean value indicating the switch's state; in the current implementation, only the settings of <CODE>gump</CODE>, <CODE>allowdeprecated</CODE> and <CODE>showinsert</CODE> are requested. Finally, <CODE><I>Dictionary</I></CODE> is the set of macro names: The keys are defined macro names; its items should always be <CODE><SPAN class="keyword">true</SPAN></CODE>. As a side-effect, <CODE><I>Dictionary</I></CODE> is modified according to <CODE><SPAN class="reference">\define</SPAN></CODE> and <CODE><SPAN class="reference">\undef</SPAN></CODE> macro directives. </P></DD><DT><CODE>parseOzVirtualString</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{Compiler<SPAN class="keyword">.</SPAN>parseOzVirtualString&nbsp;</CODE><CODE>+<I>V</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>O</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>P</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>Dictionary</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>T</I></CODE><CODE>}</CODE> </P></BLOCKQUOTE></DD><DD><P>is similar to <CODE>parseOzFile</CODE>, except that <CODE><I>V</I></CODE> denotes the source text itself instead of a source file name. </P></DD><DT><CODE>assemble</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>{Compiler<SPAN class="keyword">.</SPAN>assemble&nbsp;</CODE><CODE>+<I>Ts</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>Xs</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>SwitchR</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>P</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>V</I></CODE><CODE>}</CODE> </P></BLOCKQUOTE></DD><DD><P>takes a list of bytecode instructions <CODE><I>Ts</I></CODE> for the Mozart virtual machine (see <A href="node8.html#appendix.bytecode">Appendix&nbsp;D</A>), assembles them and returns the result in <CODE><I>P</I></CODE>, a nullary procedure which causes the code to be executed when applied. <CODE><I>Xs</I></CODE> is a list of global variables (the closure of <CODE><I>P</I></CODE>), the first element corresponding to register <CODE>g(0)</CODE>. <CODE><I>SwitchR</I></CODE> is a record whose features are switch names and whose values are booleans. In the current implementation, the switches <CODE>profile</CODE>, <CODE>controlflowinfo</CODE>, <CODE>verify</CODE>, and <CODE>peephole</CODE> are used. All features of <CODE><I>SwitchR</I></CODE> are optional (default values are substituted). <CODE><I>V</I></CODE> is a lazily computed virtual string containing an external representation of the assembled code after peephole optimization. </P></DD></DL><P> </P></DIV><DIV id="section.api.engines"><H2><A name="section.api.engines">4.3 Compiler Engines</A></H2><P> Instances of the <CODE>Compiler<SPAN class="keyword">.</SPAN>engine</CODE> class are active objects called <EM>compiler engines</EM>. Each object's thread processes all <EM>queries</EM> inside its <EM>query queue</EM> sequentially. </P><P> The final class <CODE>Compiler<SPAN class="keyword">.</SPAN>engine</CODE> inherits from <CODE>Narrator<SPAN class="keyword">.</SPAN><SPAN class="string">'class'</SPAN></CODE>, described in <A href="node6.html#appendix.narrator">Appendix&nbsp;B</A>. </P><H3><A name="label15">4.3.1 Methods of the <CODE>Compiler<SPAN class="keyword">.</SPAN>engine</CODE> Class</A></H3><P> </P><DL><DT><CODE>enqueue</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>enqueue(</CODE><CODE>+<I>T</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>I</I></CODE><CODE>&nbsp;<SPAN class="keyword">&lt;=</SPAN>&nbsp;_)</CODE> </P></BLOCKQUOTE></DD><DD><BLOCKQUOTE class="synopsis"><P><CODE>enqueue(</CODE><CODE>+<I>Ts</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>Is</I></CODE><CODE>&nbsp;<SPAN class="keyword">&lt;=</SPAN>&nbsp;_)</CODE> </P></BLOCKQUOTE></DD><DD><P>appends a new query&nbsp;<CODE><I>T</I></CODE> to the query queue. If <CODE><I>T</I></CODE> is an unknown query, an exception is raised immediately. All of the query's input arguments (the subtrees of&nbsp;<CODE><I>T</I></CODE>) are type-checked before it is enqueued. </P><P> Internally, each enqueued query is assigned a unique identification number&nbsp;<CODE><I>I</I></CODE>. This may be used later to remove the query from the queue (unless its execution has already begun or terminated). </P><P> The argument to enqueue may also be a <EM>list</EM> of queries: These are guaranteed to be executed in sequence without other queries interleaving. The second argument then returns a list of identification numbers. </P></DD><DT><CODE>dequeue</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>dequeue(</CODE><CODE>+<I>I</I></CODE><CODE>)</CODE> </P></BLOCKQUOTE></DD><DD><P>dequeues the query with identification number&nbsp;<CODE><I>I</I></CODE>, if that query is still waiting in the query queue for execution, else does nothing. </P></DD><DT><CODE>interrupt</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>interrupt()</CODE> </P></BLOCKQUOTE></DD><DD><P>interrupts execution of the current query. Does not affect the remaining queue. </P></DD><DT><CODE>clearQueue</CODE> </DT><DD><BLOCKQUOTE class="synopsis"><P><CODE>clearQueue()</CODE> </P></BLOCKQUOTE></DD><DD><P>flushes the whole remaining queue. Does not affect the currently processed query (if any). </P></DD></DL><P> </P><H3><A name="label16">4.3.2 Queries</A></H3><P> This chapter documents the queries understood by the Mozart Compiler. </P><P> Some queries request state information from the compiler engine. The following description annotates the corresponding output variables with a question mark, although they only become bound when the query is actually executed. If binding an output variable raises an exception, an error is reported through the registered listeners (see <A href="node6.html#appendix.narrator">Appendix&nbsp;B</A>). </P><DIV class="apropos"><P class="margin">Macro Definitions</P><P> </P><DL><DT><CODE>macroDefine(</CODE><CODE>+<I>V</I></CODE><CODE>)</CODE> </DT><DD><P>Add <CODE><I>V</I></CODE> to the set of defined macro names. </P></DD><DT><CODE>macroUndef(</CODE><CODE>+<I>V</I></CODE><CODE>)</CODE> </DT><DD><P>Remove <CODE><I>V</I></CODE> from the set of defined macro names. </P></DD><DT><CODE>getDefines(</CODE><CODE>?<I>PrintNames</I></CODE><CODE>)</CODE> </DT><DD><P>Return all currently defined macro names as a list, in no particular order. </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">Compiler Switches</P><P> </P><DL><DT><CODE>setSwitch(</CODE><CODE>+<I>SwitchName</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>B</I></CODE><CODE>)</CODE> </DT><DD><P>Set the state of the given switch to either <SPAN class="quasi">`on'</SPAN>, if <CODE><I>B</I></CODE><CODE>&nbsp;<SPAN class="keyword">==</SPAN>&nbsp;<SPAN class="keyword">true</SPAN></CODE>, or to <SPAN class="quasi">`off'</SPAN>, if <CODE><I>B</I></CODE><CODE>&nbsp;<SPAN class="keyword">==</SPAN>&nbsp;<SPAN class="keyword">false</SPAN></CODE>. </P></DD><DT><CODE>getSwitch(</CODE><CODE>+<I>SwitchName</I></CODE><CODE>&nbsp;</CODE><CODE>?<I>B</I></CODE><CODE>)</CODE> </DT><DD><P>Return the state of the given switch. </P></DD><DT><CODE>pushSwitches()</CODE> </DT><DD><P>Save the current settings of all switches onto the internal switch state stack. </P></DD><DT><CODE>popSwitches()</CODE> </DT><DD><P>Restore all switch settings from the topmost element of the internal switch state stack, provided it is not empty, else do nothing. </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">Compiler Options</P><P> </P><DL><DT><CODE>setMaxNumberOfErrors(</CODE><CODE>+<I>I</I></CODE><CODE>)</CODE> </DT><DD><P>Set the maximal number of errors to report for any one compilation before aborting it to&nbsp;<CODE><I>I</I></CODE>. A negative value means never to abort. </P></DD><DT><CODE>getMaxNumberOfErrors(</CODE><CODE>?<I>I</I></CODE><CODE>)</CODE> </DT><DD><P>Return the maximal number of errors to report for any one compilation before aborting it. </P></DD><DT><CODE>setBaseURL(</CODE><CODE>+<I>VU</I></CODE><CODE>)</CODE> </DT><DD><P>Set the base URL relative to which the <CODE><SPAN class="keyword">require</SPAN></CODE> clause of computed functors is resolved. A value of <CODE><SPAN class="keyword">unit</SPAN></CODE> means to resolve the imports relative to the location of the file in which the <CODE><SPAN class="keyword">functor</SPAN></CODE> keyword appeared. </P></DD><DT><CODE>getBaseURL(</CODE><CODE>?<I>AU</I></CODE><CODE>)</CODE> </DT><DD><P>Return the base URL relative to which the <CODE><SPAN class="keyword">require</SPAN></CODE> clause of computed functors is resolved. </P></DD><DT><CODE>setGumpDirectory(</CODE><CODE>+<I>VU</I></CODE><CODE>)</CODE> </DT><DD><P>Set the directory in which Gump output files are created. Can be relative. <CODE><SPAN class="keyword">unit</SPAN></CODE> means the current working directory. </P></DD><DT><CODE>getGumpDirectory(</CODE><CODE>?<I>VU</I></CODE><CODE>)</CODE> </DT><DD><P>Return the directory in which Gump output files are created. </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">The Environment</P><P> </P><DL><DT><CODE>addToEnv(</CODE><CODE>+<I>PrintName</I></CODE><CODE>&nbsp;</CODE><CODE><I>X</I></CODE><CODE>)</CODE> </DT><DD><P>Add a binding for a variable with the given print name, and bound to&nbsp;<CODE><I>X</I></CODE>, to the environment. </P></DD><DT><CODE>lookupInEnv(</CODE><CODE>+<I>PrintName</I></CODE><CODE>&nbsp;</CODE><CODE><I>X</I></CODE><CODE>)</CODE> </DT><DD><P>Look up the binding for the variable with the given print name in the environment and bind <CODE><I>X</I></CODE> to its value. If it does not exist, report an error. </P></DD><DT><CODE>removeFromEnv(</CODE><CODE>+<I>PrintName</I></CODE><CODE>)</CODE> </DT><DD><P>Remove the binding for the variable with the given print name from the environment if it exists. </P></DD><DT><CODE>putEnv(</CODE><CODE>+<I>Env</I></CODE><CODE>)</CODE> </DT><DD><P>Replace the current environment by the one given by <CODE><I>Env</I></CODE>. </P></DD><DT><CODE>mergeEnv(</CODE><CODE>+<I>Env</I></CODE><CODE>)</CODE> </DT><DD><P>Adjoin <CODE><I>Env</I></CODE> to the current environment, overwriting already existing bindings. </P></DD><DT><CODE>getEnv(</CODE><CODE>?<I>Env</I></CODE><CODE>)</CODE> </DT><DD><P>Return the current environment. </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">Feeding Source Text</P><P> </P><DL><DT><CODE>feedVirtualString(</CODE><CODE>+<I>V</I></CODE><CODE>)</CODE> </DT><DD><P>Evaluate the Oz source code given by the virtual string&nbsp;<CODE><I>V</I></CODE>. </P></DD><DT><CODE>feedVirtualString(</CODE><CODE>+<I>V</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>R</I></CODE><CODE>)</CODE> </DT><DD><P>Evaluate the Oz source code given by the virtual string&nbsp;<CODE><I>V</I></CODE>, returning the resulting value in <CODE><I>R</I></CODE><CODE><SPAN class="keyword">.</SPAN>result</CODE> (if the <SPAN class="ignore"><CODE><SPAN class="reference">\switch&nbsp;+</SPAN></CODE></SPAN><CODE><SPAN class="reference">expression</SPAN></CODE> switch is set and <CODE><I>R</I></CODE> has the feature <CODE>result</CODE>). </P></DD><DT><CODE>feedFile(</CODE><CODE>+<I>V</I></CODE><CODE>)</CODE> </DT><DD><P>Evaluate the Oz source code contained in the file with name&nbsp;<CODE><I>V</I></CODE>. </P></DD><DT><CODE>feedFile(</CODE><CODE>+<I>V</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>R</I></CODE><CODE>)</CODE> </DT><DD><P>Evaluate the Oz source code contained in the file with name&nbsp;<CODE><I>V</I></CODE>, returning the resulting value in <CODE><I>R</I></CODE><CODE><SPAN class="keyword">.</SPAN>result</CODE> (if the <SPAN class="ignore"><CODE><SPAN class="reference">\switch&nbsp;+</SPAN></CODE></SPAN><CODE><SPAN class="reference">expression</SPAN></CODE> switch is set and <CODE><I>R</I></CODE> has the feature <CODE>result</CODE>). </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">Synchronization</P><P> </P><DL><DT><CODE>ping(</CODE><CODE>?<I>U</I></CODE><CODE>)</CODE> </DT><DD><P>Bind the variable <CODE><I>U</I></CODE> to <CODE><SPAN class="keyword">unit</SPAN></CODE> on execution of this query. This allows to synchronize on the work of the compiler, e.&nbsp;g., to be informed when a compilation is finished. </P></DD><DT><CODE>ping(</CODE><CODE>?<I>U</I></CODE><CODE>&nbsp;</CODE><CODE><I>X</I></CODE><CODE>)</CODE> </DT><DD><P>Works like the <CODE>ping(_)</CODE> query, except gives a value which will reappear in the response notification sent to interfaces. This allows to identify the <CODE>ping</CODE> query with its <CODE>pong</CODE> notification. </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">Custom Front-Ends</P><P> </P><DL><DT><CODE>setFrontEnd(</CODE><CODE>+<I>ParseFileP</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>ParseVirtualStringP</I></CODE><CODE>)</CODE> </DT><DD><P>Replace the front-end used by the compiler by a custom front-end implemented by procedures <CODE><I>ParseFileP</I></CODE> and <CODE><I>ParseVirtualStringP</I></CODE>. These procedures have the same signature as <CODE>Compiler<SPAN class="keyword">.</SPAN>parseOzFile</CODE> and <CODE>Compiler<SPAN class="keyword">.</SPAN>parseOzVirtualString</CODE>, documented above. Indeed, these procedures implement the default Oz front-end. </P></DD></DL><P></P></DIV></DIV><DIV id="section.api.interfaces"><H2><A name="section.api.interfaces">4.4 Compiler Interfaces</A></H2><P> As said above, compiler engines are narrators. The term ``compiler interface'' simply denotes a standard listener attached to a compiler engine. This section presents what is required to implement a compiler interface. </P><P> First the notifications sent by compiler engines are documented. These include normal compiler output and information about compiler state changes. Then a specific compiler interface is described that makes many compilation tasks easy to control. </P><H3><A name="label17">4.4.1 Sent Notifications</A></H3><DIV class="apropos"><P class="margin">Query Queue</P><P> </P><DL><DT><CODE>newQuery(</CODE><CODE><I>I</I></CODE><CODE>&nbsp;</CODE><CODE><I>T</I></CODE><CODE>)</CODE> </DT><DD><P>A new query&nbsp;<CODE><I>T</I></CODE> with identification&nbsp;<CODE><I>I</I></CODE> has been enqueued. </P></DD><DT><CODE>runQuery(</CODE><CODE><I>I</I></CODE><CODE>&nbsp;</CODE><CODE><I>T</I></CODE><CODE>)</CODE> </DT><DD><P>The query&nbsp;<CODE><I>T</I></CODE> with identification&nbsp;<CODE><I>I</I></CODE> is now being executed. </P></DD><DT><CODE>removeQuery(</CODE><CODE><I>I</I></CODE><CODE>)</CODE> </DT><DD><P>The query with identification&nbsp;<CODE><I>I</I></CODE> has been removed from the query queue, either because it finished executing or because it was dequeued by a user program. </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">Compiler Activity</P><P> </P><DL><DT><CODE>busy()</CODE> </DT><DD><P>The compiler is currently busy (i.&nbsp;e., executing a query). </P></DD><DT><CODE>idle()</CODE> </DT><DD><P>The compiler is currently idle (i.&nbsp;e., waiting for a query to be enqueued). </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">State Change</P><P> </P><DL><DT><CODE>switch(</CODE><CODE><I>SwitchName</I></CODE><CODE>&nbsp;</CODE><CODE><I>B</I></CODE><CODE>)</CODE> </DT><DD><P>The given switch has been set to&nbsp;<CODE><I>B</I></CODE>. </P></DD><DT><CODE>switches(</CODE><CODE><I>R</I></CODE><CODE>)</CODE> </DT><DD><P>The settings of all switches is transmitted as a record mapping each switch name to its setting. </P></DD><DT><CODE>maxNumberOfErrors(</CODE><CODE><I>I</I></CODE><CODE>)</CODE> </DT><DD><P>The maximum number of errors after which to abort compilation has been set to&nbsp;<CODE><I>I</I></CODE>. </P></DD><DT><CODE>baseURL(</CODE><CODE><I>AU</I></CODE><CODE>)</CODE> </DT><DD><P>The base URL relative to which the <CODE><SPAN class="keyword">require</SPAN></CODE> clause of computed functors is resolved has been set to <CODE><I>AU</I></CODE>. </P></DD><DT><CODE>env(</CODE><CODE><I>Env</I></CODE><CODE>)</CODE> </DT><DD><P>The environment has been set to <CODE><I>Env</I></CODE>. </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">Output</P><P> </P><DL><DT><CODE>info(</CODE><CODE><I>V</I></CODE><CODE>)</CODE> </DT><DD><P>An information message&nbsp;<CODE><I>V</I></CODE> is to be printed out. </P></DD><DT><CODE>info(</CODE><CODE><I>V</I></CODE><CODE>&nbsp;</CODE><CODE><I>Coord</I></CODE><CODE>)</CODE> </DT><DD><P>An information message&nbsp;<CODE><I>V</I></CODE>, related to the source coordinates <CODE><I>Coord</I></CODE>, is to be printed out. </P></DD><DT><CODE>message(</CODE><CODE><I>R</I></CODE><CODE>&nbsp;</CODE><CODE><I>Coord</I></CODE><CODE>)</CODE> </DT><DD><P>An error or warning message&nbsp;<CODE><I>R</I></CODE>, related to the source coordinates <CODE><I>Coord</I></CODE>, is to be printed out. <CODE><I>R</I></CODE>&nbsp;has the standard error message format, described in <A href="../system/node77.html#chapter.error">Chapter&nbsp;24 of ``System Modules''</A>. </P></DD><DT><CODE>insert(</CODE><CODE><I>V</I></CODE><CODE>&nbsp;</CODE><CODE><I>Coord</I></CODE><CODE>)</CODE> </DT><DD><P>During parsing, the file named&nbsp;<CODE><I>V</I></CODE> has been read. The corresponding <CODE><SPAN class="reference">\insert</SPAN></CODE> directive (if any) was at source coordinates <CODE><I>Coord</I></CODE>. </P></DD><DT><CODE>displaySource(</CODE><CODE><I>TitleV</I></CODE><CODE>&nbsp;</CODE><CODE><I>ExtV</I></CODE><CODE>&nbsp;</CODE><CODE><I>V</I></CODE><CODE>)</CODE> </DT><DD><P>A source text&nbsp;<CODE><I>V</I></CODE> with title&nbsp;<CODE><I>TitleV</I></CODE> is to be displayed; its format is the one for which the file extension <CODE><I>ExtV</I></CODE> is typically used (such as <CODE>oz</CODE> or <CODE>ozm</CODE>). </P></DD><DT><CODE>attention()</CODE> </DT><DD><P>The error output buffer should be raised with the cursor at the current output coordinates (an error message should follow). </P></DD></DL><P> </P></DIV><DIV class="apropos"><P class="margin">Synchronization</P><P> </P><DL><DT><CODE>pong(</CODE><CODE><I>X</I></CODE><CODE>)</CODE> </DT><DD><P>This is sent in response to a <CODE>ping(_)</CODE> or <CODE>ping(_&nbsp;</CODE><CODE><I>X</I></CODE><CODE>)</CODE> query (see <A href="node4.html#section.api.engines">Section&nbsp;4.3</A>). In the first case, <CODE><SPAN class="keyword">unit</SPAN></CODE> is returned in&nbsp;<CODE><I>X</I></CODE>. </P></DD></DL><P> </P></DIV><H3><A name="label18">4.4.2 The <CODE>Compiler<SPAN class="keyword">.</SPAN>interface</CODE> Class</A></H3><P> The <CODE>Compiler<SPAN class="keyword">.</SPAN>interface</CODE> class is a subclass of the error listener class described in <A href="node6.html#appendix.narrator">Appendix&nbsp;B</A>. Its purpose is to provide a standard listener powerful enough to server many purposes, to spare the user of defining an own listener. </P><DIV class="apropos"><P class="margin">Methods</P><P> In addition to the standard error listener interface, it supports the following methods. </P><DL><DT><CODE>init(</CODE><CODE>+<I>EngineO</I></CODE><CODE>&nbsp;</CODE><CODE>+<I>VerboseL</I></CODE><CODE>&nbsp;<SPAN class="keyword">&lt;=</SPAN>&nbsp;<SPAN class="keyword">false</SPAN>)</CODE> </DT><DD><P>initializes a new compiler interface, attaching it to the compiler engine <CODE><I>EngineO</I></CODE>. <CODE><I>VerboseL</I></CODE> can be one of <CODE><SPAN class="keyword">true</SPAN></CODE>, <CODE><SPAN class="keyword">false</SPAN></CODE>, or <CODE>auto</CODE>: If <CODE><SPAN class="keyword">true</SPAN></CODE>, all messages, including the compiler's banner, will be output. If <CODE><SPAN class="keyword">false</SPAN></CODE>, no messages will be output. If <CODE>auto</CODE>, the interface will remain silent unless an error of warning message arrives, in which case it will become verbose. </P></DD><DT><CODE>sync()</CODE> </DT><DD><P>waits until the compiler engine becomes idle. </P></DD><DT><CODE>getInsertedFiles(</CODE><CODE>?<I>Vs</I></CODE><CODE>)</CODE> </DT><DD><P>returns a list of the file names that compilation has caused the inclusion of so far, in order of appearance. </P></DD><DT><CODE>getSource(</CODE><CODE>?<I>V</I></CODE><CODE>)</CODE> </DT><DD><P>returns the source that has last been displayed by the compiler (typically some intermediate representation), or the empty string if none. </P></DD><DT><CODE>reset()</CODE> </DT><DD><P>clears the internal lists of inserted files and the displayed source. </P></DD><DT><CODE>clear()</CODE> </DT><DD><P>is the same as <CODE>reset</CODE>. </P></DD></DL><P></P></DIV></DIV><DIV id="section.api.examples"><H2><A name="section.api.examples">4.5 Examples</A></H2><H3><A name="label19">4.5.1 Inspecting the Parse Tree</A></H3><P> As a first example, here is an application that expects as single argument the name of an Oz source file. It parses the file, accepting Gump syntax, and displays the parse tree in the Inspector (or <CODE>parseError</CODE> if parsing failed). If there was a parse error, it extracts an error messages and prints that to standard output. </P><BLOCKQUOTE><PRE><SPAN class="keyword">functor</SPAN>&nbsp;<BR><SPAN class="keyword">import</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;Narrator(<SPAN class="string">'class'</SPAN>)<BR>&nbsp;&nbsp;&nbsp;ErrorListener(<SPAN class="string">'class'</SPAN>)<BR>&nbsp;&nbsp;&nbsp;Application(getArgs)<BR>&nbsp;&nbsp;&nbsp;Compiler(parseOzFile)<BR>&nbsp;&nbsp;&nbsp;Inspector(inspect)<BR>&nbsp;&nbsp;&nbsp;System(printInfo)<BR><SPAN class="keyword">define</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;PrivateNarratorO<BR>&nbsp;&nbsp;&nbsp;NarratorO&nbsp;=&nbsp;{New&nbsp;Narrator<SPAN class="keyword">.</SPAN><SPAN class="string">'class'</SPAN>&nbsp;init(?PrivateNarratorO)}<BR>&nbsp;&nbsp;&nbsp;ListenerO&nbsp;=&nbsp;{New&nbsp;ErrorListener<SPAN class="keyword">.</SPAN><SPAN class="string">'class'</SPAN>&nbsp;init(NarratorO)}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">case</SPAN>&nbsp;{Application<SPAN class="keyword">.</SPAN>getArgs&nbsp;plain}&nbsp;<SPAN class="keyword">of</SPAN>&nbsp;[FileName]&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{Inspector<SPAN class="keyword">.</SPAN>inspect<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{Compiler<SPAN class="keyword">.</SPAN>parseOzFile&nbsp;FileName&nbsp;PrivateNarratorO<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">fun</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">$</SPAN>&nbsp;Switch}&nbsp;Switch&nbsp;<SPAN class="keyword">==</SPAN>&nbsp;gump&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;{NewDictionary}}}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">if</SPAN>&nbsp;{ListenerO&nbsp;hasErrors($)}&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{System<SPAN class="keyword">.</SPAN>printInfo&nbsp;{ListenerO&nbsp;getVS($)}}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ListenerO&nbsp;reset()}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR><SPAN class="keyword">end</SPAN>&nbsp;<BR></PRE></BLOCKQUOTE><P> </P><H3><A name="label20">4.5.2 A Look into the Provided Abstractions</A></H3><P> The implementation of the <CODE>Compiler<SPAN class="keyword">.</SPAN>evalExpression</CODE> procedure is a good example of how to use compiler engines and interfaces. <CODE>evalExpression</CODE> causes compilation of an expression within a specified environment. It is synchronous, i.&nbsp;e., only returns after the compilation has finished. Compiler error messages are raised as exceptions, and the compilation may be interrupted using the nullary procedure returned in <CODE>Kill</CODE>. </P><DIV class="apropos"><P class="margin">Startup</P><P> Since we both want to control a compilation (done by a new compiler engine) and to observe the compilation process (to synchronize and to determine whether it produced errors), we first instantiate both an engine and an interface which we register with the engine. A number of queries are enqueued to the engine: We need to set the environment and appropriate compiler switches for compilation of an expression and to cause synchronous execution of the compiled program. When we're done configuring the compiler, we can start compilation of the source proper, expecting a result to be returned in variable <CODE>Result</CODE>. </P></DIV><DIV class="apropos"><P class="margin">Killing</P><P> We then define the <CODE>Kill</CODE> procedure. The rest of the observation is performed in a new thread, because we want to kill the observation as well when <CODE>Kill</CODE> is invoked. <CODE>Kill</CODE> will clear any non-processed queries from the queue and interrupt the current one, then kill the observation thread (unless it had been already dead). </P></DIV><DIV class="apropos"><P class="margin">Observing</P><P> Next we'll observe the running compiler, and for this we need to make use of the interface we created earlier. When the compiler becomes idle, we check whether it has output any error messages, in which case we record the faulty condition, else we report success. The main thread waits until the condition becomes known and reacts upon it. </P><BLOCKQUOTE><PRE><SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">Compiler.evalExpression</SPAN>&nbsp;VS&nbsp;Env&nbsp;?Kill&nbsp;?Result}&nbsp;E&nbsp;I&nbsp;S&nbsp;<SPAN class="keyword">in</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;E&nbsp;=&nbsp;{New&nbsp;Compiler<SPAN class="keyword">.</SPAN>engine&nbsp;init()}<BR>&nbsp;&nbsp;&nbsp;I&nbsp;=&nbsp;{New&nbsp;Compiler<SPAN class="keyword">.</SPAN>interface&nbsp;init(E)}<BR>&nbsp;&nbsp;&nbsp;{E&nbsp;enqueue(mergeEnv(Env))}<BR>&nbsp;&nbsp;&nbsp;{E&nbsp;enqueue(setSwitch(expression&nbsp;<SPAN class="keyword">true</SPAN>))}<BR>&nbsp;&nbsp;&nbsp;{E&nbsp;enqueue(setSwitch(threadedqueries&nbsp;<SPAN class="keyword">false</SPAN>))}<BR>&nbsp;&nbsp;&nbsp;{E&nbsp;enqueue(feedVirtualString(VS&nbsp;return(result:&nbsp;?Result)))}<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">thread</SPAN>&nbsp;T&nbsp;<SPAN class="keyword">in</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;=&nbsp;{Thread<SPAN class="keyword">.</SPAN>this}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">proc</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">Kill</SPAN>}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{E&nbsp;clearQueue()}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{E&nbsp;interrupt()}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">try</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{Thread<SPAN class="keyword">.</SPAN>terminate&nbsp;T}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S&nbsp;=&nbsp;killed<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">catch</SPAN>&nbsp;_&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<SPAN class="keyword">skip</SPAN>&nbsp;&nbsp;&nbsp;%&nbsp;<SPAN class="comment">already&nbsp;dead<BR></SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{I&nbsp;sync()}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">if</SPAN>&nbsp;{I&nbsp;hasErrors($)}&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;Ms&nbsp;<SPAN class="keyword">in</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{I&nbsp;getMessages(?Ms)}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S&nbsp;=&nbsp;error(compiler(evalExpression&nbsp;VS&nbsp;Ms))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">else</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S&nbsp;=&nbsp;success<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">case</SPAN>&nbsp;S&nbsp;<SPAN class="keyword">of</SPAN>&nbsp;error(M)&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{Exception<SPAN class="keyword">.</SPAN>raiseError&nbsp;M}<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">[]</SPAN>&nbsp;success&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<SPAN class="keyword">skip</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">[]</SPAN>&nbsp;killed&nbsp;<SPAN class="keyword">then</SPAN>&nbsp;<SPAN class="keyword">skip</SPAN>&nbsp;<BR>&nbsp;&nbsp;&nbsp;<SPAN class="keyword">end</SPAN>&nbsp;<BR><SPAN class="keyword">end</SPAN>&nbsp;<BR></PRE></BLOCKQUOTE><P> </P></DIV><DIV class="apropos"><P class="margin">virtualStringToValue</P><P> The <CODE>Compiler<SPAN class="keyword">.</SPAN>virtualStringToValue</CODE> is trivial to implement on top of the functionality provided by <CODE>evalExpression</CODE>. </P><BLOCKQUOTE><PRE><SPAN class="keyword">fun</SPAN><SPAN class="variablename">&nbsp;</SPAN>{<SPAN class="functionname">Compiler.virtualStringToValue</SPAN>&nbsp;VS}<BR>&nbsp;&nbsp;&nbsp;{Compiler<SPAN class="keyword">.</SPAN>evalExpression&nbsp;VS&nbsp;env()&nbsp;_}<BR><SPAN class="keyword">end</SPAN>&nbsp;<BR></PRE></BLOCKQUOTE><P></P></DIV></DIV></DIV><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="node3.html#chapter.applications">&lt;&lt; Prev</A></TD><TD><A href="index.html">- Up -</A></TD><TD><A href="node5.html#appendix.switches">Next &gt;&gt;</A></TD></TR></TABLE><HR><ADDRESS><A href="http://www.ps.uni-sb.de/~kornstae/">Leif&nbsp;Kornstaedt</A><BR><SPAN class="version">Version 1.4.0 (20110908185330)</SPAN></ADDRESS></BODY></HTML>