<< Prev | - Up - | Next >> |
The compiler is available to Mozart applications through the module Compiler
. This chapter describes the functionality provided by that module and its classes.
First, a number of additional secondary type names used in this description is introduced in Section 5.1, then the Compiler
module is described in Section 5.2. The material in that section should prove sufficient for most cases. The remainder of the chapter is intended for advanced uses.
An arbitrary number of compilers may be instantiated, each with its own internal state, and used concurrently. We distinguish between compiler engines, described in Section 5.3, which store the state of a compiler and perform the compilation proper, and compiler interfaces, described in Section 5.4, which allow to observe the activities of compiler engines and to react to them. Both of these use the narrator/listener mechanism described in Appendix B; familiarity with this is assumed.
Finally, serving the purpose of examples, the provided abstractions are explained in terms of compiler engines and interfaces in Section 5.5.
This section describes additional secondary types used in the descriptions in this chapter. The conventions defined in Section 2.3 of ``The Oz Base Environment'' will be respected.
Coord
stands for information about source coordinates. This is either unit
if no information is known or a tuple pos(
FileName
Line
Column
)
, where FileName
is represented as an atom (''
meaning `unknown') and Line
and Column
are integers. Line numbering begins at 1
and column numbering at 0
; a column number of ~1
means `unknown'.
SwitchName
is an atom which must be a valid switch name (see Appendix A).
PrintName
is an atom which must be a valid variable print name.
Env
represents an environment, represented as a record whose features are valid print names.
Compiler
Module
evalExpression
{Compiler.evalExpression
+V
+Env
?KillP
X
}
evaluates an expression, given as a virtual string V
, in a base environment enriched by the bindings given by Env
, either returning the result X
of the evaluation or raising an exception. Furthermore, the variable KillP
is bound to a nullary procedure which, when applied, interrupts compilation.
virtualStringToValue
{Compiler.virtualStringToValue
+V
X
}
is a replacement for System.virtualStringToValue
, which was available in Mozart's predecessor DFKI Oz.
Note that you are discouraged from using this for large data structures: Because it is much more powerful than System.virtualStringToValue
, it can also be much less efficient. Rather, you should use pickling and unpickling of data structures ``System Modules''.
engine
Compiler.engine
is the final class from which compiler engines can be instantiated. This is described in detail in Section 5.3.
interface
Compiler.interface
is a class providing a simple mechanism to create compiler interfaces. It is described in detail in Section 5.4.
parseOzFile
{Compiler.parseOzFile
+V
+O
+P
+Dictionary
?T
}
parseOzVirtualString
{Compiler.parseOzVirtualString
+V
+O
+P
+Dictionary
?T
}
assemble
{Compiler.assemble
+Ts
+Xs
+SwitchR
?P
}
Instances of the Compiler.engine
class are active objects called compiler engines. Each object's thread processes all queries inside its query queue sequentially.
The final class Compiler.engine
inherits from Narrator.'class'
, described in Appendix B.
Compiler.engine
Class
enqueue
enqueue(
+T
?I
<= _)
enqueue(
+Ts
?Is
<= _)
appends a new query T
to the query queue. If T
is an unknown query, an exception is raised immediately. All of the query's input arguments (the subtrees of T
) are type-checked before it is enqueued.
Internally, each enqueued query is assigned a unique identification number I
. This may be used later to remove the query from the queue (unless its execution has already begun or terminated).
The argument to enqueue may also be a list of queries: These are guaranteed to be executed in sequence without other queries interleaving. The second argument then returns a list of identification numbers.
dequeue
dequeue(
+I
)
dequeues the query with identification number I
, if that query is still waiting in the query queue for execution, else does nothing.
interrupt
interrupt()
interrupts execution of the current query. Does not affect the remaining queue.
clearQueue
clearQueue()
flushes the whole remaining queue. Does not affect the currently processed query (if any).
This chapter documents the queries understood by the Mozart Compiler.
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 Appendix B).
Macro Definitions
macroDefine(
+V
)
Add V
to the set of defined macro names.
macroUndef(
+V
)
Remove V
from the set of defined macro names.
getDefines(
?PrintNames
)
Return all currently defined macro names as a list, in no particular order.
Compiler Switches
setSwitch(
+SwitchName
+B
)
Set the state of the given switch to either `on', if B
== true
, or to `off', if B
== false
.
getSwitch(
+SwitchName
?B
)
Return the state of the given switch.
pushSwitches()
Save the current settings of all switches onto the internal switch state stack.
popSwitches()
Restore all switch settings from the topmost element of the internal switch state stack, provided it is not empty, else do nothing.
Compiler Options
setMaxNumberOfErrors(
+I
)
Set the maximal number of errors to report for any one compilation before aborting it to I
. A negative value means never to abort.
getMaxNumberOfErrors(
?I
)
Return the maximal number of errors to report for any one compilation before aborting it.
setBaseURL(
+VU
)
Set the base URL relative to which the require
clause of computed functors is resolved. A value of unit
means to resolve the imports relative to the location of the file in which the functor
keyword appeared.
getBaseURL(
?AU
)
Return the base URL relative to which the require
clause of computed functors is resolved.
The Environment
addToEnv(
+PrintName
X
)
Add a binding for a variable with the given print name, and bound to X
, to the environment.
lookupInEnv(
+PrintName
X
)
Look up the binding for the variable with the given print name in the environment and bind X
to its value. If it does not exist, report an error.
removeFromEnv(
+PrintName
)
Remove the binding for the variable with the given print name from the environment if it exists.
putEnv(
+Env
)
Replace the current environment by the one given by Env
.
mergeEnv(
+Env
)
Adjoin Env
to the current environment, overwriting already existing bindings.
getEnv(
?Env
)
Return the current environment.
Feeding Source Text
feedVirtualString(
+V
)
Evaluate the Oz source code given by the virtual string V
.
feedVirtualString(
+V
+R
)
Evaluate the Oz source code given by the virtual string V
, returning the resulting value in R
.result
(if the \switch +
expression
switch is set and R
has the feature result
).
feedFile(
+V
)
Evaluate the Oz source code contained in the file with name V
.
feedFile(
+V
+R
)
Evaluate the Oz source code contained in the file with name V
, returning the resulting value in R
.result
(if the \switch +
expression
switch is set and R
has the feature result
).
Synchronization
ping(
?U
)
Bind the variable U
to unit
on execution of this query. This allows to synchronize on the work of the compiler, e. g., to be informed when a compilation is finished.
ping(
?U
X
)
Works like the ping(_)
query, except gives a value which will reappear in the response notification sent to interfaces. This allows to identify the ping
query with its pong
notification.
Custom Front-Ends
setFrontEnd(
+P1
+P2
)
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.
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.
Query Queue
newQuery(
I
T
)
A new query T
with identification I
has been enqueued.
runQuery(
I
T
)
The query T
with identification I
is now being executed.
removeQuery(
I
)
The query with identification I
has been removed from the query queue, either because it finished executing or because it was dequeued by a user program.
Compiler Activity
busy()
The compiler is currently busy (i. e., executing a query).
idle()
The compiler is currently idle (i. e., waiting for a query to be enqueued).
State Change
switch(
SwitchName
B
)
The given switch has been set to B
.
switches(
R
)
The settings of all switches is transmitted as a record mapping each switch name to its setting.
maxNumberOfErrors(
I
)
The maximum number of errors after which to abort compilation has been set to I
.
baseURL(
AU
)
The base URL relative to which the require
clause of computed functors is resolved has been set to AU
.
env(
Env
)
The environment has been set to Env
.
Output
info(
V
)
An information message V
is to be printed out.
info(
V
Coord
)
An information message V
, related to the source coordinates Coord
, is to be printed out.
message(
R
Coord
)
An error or warning message R
, related to the source coordinates Coord
, is to be printed out. R
has the standard error message format, described in mozart/share/lib/sp/Error.oz
.
insert(
V
Coord
)
During parsing, the file named V
has been read. The corresponding \insert
directive (if any) was at source coordinates Coord
.
displaySource(
TitleV
ExtV
V
)
A source text V
with title TitleV
is to be displayed; its format is the one for which the file extension ExtV
is typically used (such as oz
or ozm
).
attention()
The error output buffer should be raised with the cursor at the current output coordinates (an error message should follow).
Synchronization
pong(
X
)
This is sent in response to a ping(_)
or ping(_
X
)
query (see Section 5.3). In the first case, unit
is returned in X
.
Compiler.interface
Class
init(
+EngineO
+L
<= false)
reset()
sync()
getInsertedFiles(
?Vs
)
getSource(
?V
)
proc {Compiler.evalExpression VS Env ?Kill ?Result} E I S in
E = {New Compiler.engine init()}
I = {New Compiler.interface init(E)}
{E enqueue(mergeEnv(Env))}
{E enqueue(setSwitch(expression true))}
{E enqueue(setSwitch(threadedqueries false))}
{E enqueue(feedVirtualString(VS return(result: ?Result)))}
thread T in
T = {Thread.this}
proc {Kill}
{E clearQueue()}
{E interrupt()}
try
{Thread.terminate T}
S = killed
catch _ then skip % already dead
end
end
{I sync()}
if {I hasErrors($)} then Ms in
{I getMessages(?Ms)}
S = error(compiler(evalExpression VS Ms))
else
S = success
end
end
case S of error(M) then
{Exception.raiseError M}
[] success then skip
[] killed then skip
end
end
fun {Compiler.virtualStringToValue VS}
{Compiler.evalExpression VS env() _}
end
<< Prev | - Up - | Next >> |