Files can be read one expression at a time : read(p:port) reads the next CLAIRE expression
on the port p or, in a single step, load(s:string) reads the file associated to the
string s and evaluates it. It returns true when no problem occurred while loading the
file and false otherwise. A variant of this method is the method sload(s:string) which
does the same thing but prints the expression read and the result of their evaluation.
Another variant is the method oload(s:string) which does the same thing but substitute
an optimized form to each method's body. This may hinder the inspection of the code at the
toplevel, but it will increase the efficiency of the interpreter.
Files may contain comments. A comment is anything that follows a // until the end of
the line. When reading, the CLAIRE reader will ignore comments (they will not be read
and hence not evaluated). For instance :
x :+ 1, // increments x by 1 |
To insure compatibility with earlier versions, CLAIRE also recognizes lines that begin with ';'
as comments. Conversely, CLAIRE also support the C syntax for block comments: anything between
/* and */ will be taken as a comment. Comments in CLAIRE may become active comments that behave
like trace statements if they begin with [<level>] (see appendix B). The global variable
NeedComment may be turned to true (it is false by default) to tell the reader to place any comment
found before the definition of a class or a method in the comment slot of the associated CLAIRE
object. The second type of special instructions are immediate conditionals. An immediate conditional
is defined with the same syntax as a regular conditional but with a #if instead of an if :
#if <test> <expression> < else <expression> >opt |
When the reader finds such an expression, it evaluates the test. If the value is true, then
the reader behaves as if it had read the first expression, otherwise it behaves as if it had
read the second expression (or nothing if there is no else). This is useful for implementing
variants (such as debugging versions). For instance :
#if debug printf("the value of x is ~S", x) |
Note that the expression can be a block (within parentheses) which is necessary to place a
definition (like a rule definition) inside a #if. Last, there exists another pre-processing
directive for loading a file within a file: #include(s) loads the file as if it was included
in the file in which the #include is read. There are a few differences between CLAIRE and C++ or Java parsing that need to be underlined :
- Spaces are important since they act as a delimiter. In particular, a space cannot be inserted
between a selector and its arguments in a call. Here is a simple example :
foo (1,2,3) // this is not correct, one must write foo(1,2,3) |
- = is for equality and := for assignment. This is standard in pseudo-code notations because
it is less ambiguous
- characters such as +, *, -, etc. do not have a special status. This allows the user to
use them in a variable name (such as x+y). However, this is not advisable since it is
ambiguous for many readers. A consequence is that spaces are needed around operations within
arithmetic examples such as :
x + (y * z) // instead of x+y*z which is taken as (one) variable name |
- The character '/' plays a special role for namespace (module) membership