|
|
| ||||||
10.2 Activating the C++ translator |
rsltc -c++ <file>
where <file>
takes the form X or X.rsl and contains
the RSL scheme or object named X. It generates files
X.h and X.cc.
The translator may also be invoked with the command
rsltc -cpp <file>
which produces output more likely to satisfy Microsoft's Visual C++ compiler. In this case the second output file is X.cpp.
X.h contains the include directive
#include "RSL_typs.h"
and X.cc or X.cpp contains the include directive
#include "RSL_typs.cc"
RSL_typs.h and RSL_typs.cc, together with the other files they include or need, namely
RSL_comp.h RSL_list.cc RSL_list.h RSL_map.cc RSL_map.h RSL_prod.h RSL_set.cc RSL_set.h RSL_text.h cpp_RSL.cc cpp_RSL.h cpp_io.cc cpp_io.h cpp_list.cc cpp_list.h cpp_map.h cpp_set.cc cpp_set.h
must be available. These files are all supplied with rsltc. We refer to them below as the RSL library files.
A simple script called "rslcomp" is supplied for compiling. In its Unix/Linux version it takes the form
#!/bin/sh CPP_DIR=... g++ -o $1 -DRSL_io -DRSL_pre -I$CPP_DIR $1.cc
where ... is the directory where the RSL library files are placed. The command
rslcomp X
will compile and link the files X.h and X.cc to make
an executable X. This should only be used when X.rsl
includes a test_case declaration: otherwise there will be no
main function. Otherwise X.cc may be compiled with
hand-written C++ files that #include "X.cc"
.
You should include -DRSL_boolalpha if your compiler accepts the "boolalpha" conversion (e.g. Visual C++ version 6, and perhaps earlier, GNU g++ version 3). See section 10.13.1.
The compilation flag RSL_io enables input and output using the streams library of C++: see section 10.13. It is needed when X.rsl includes a main function, or there will be compilation errors.
The compilation flag RSL_pre is optional. Its inclusion results in run-time checks being included:
Arguments of f(args) not in subtypes
Precondition of f(args) not satisfied
Result r of f(args) not in subtype
Recursion of a function through a subtype condition or precondition is also checked during translation and generates a warning about circularity: execution with RSL_pre defined would cause an infinite loop.
Value x of constant c not in subtype
Initial value x of variable v not in subtype
Assigned value x of variable v not in subtype
Destructor f applied to wrong variant
Reconstructor f applied to wrong variant
The messages are prefixed by the standard file:line:column showing where in an RSL file the error occurred.
RSL_pre is intended for use in testing. It should be used with RSL_io, when any error messages (C++ strings) will be generated on standard output, and (except for the destructor/reconstructor errors) the program continues running. If RSL_io is not present, an error will simply cause the program to abort. This behaviour is defined by the function RSL_warn in the library file cpp_RSL.h, so users can easily change this behaviour if they wish by editing this file. In the case of the destructor/reconstructor errors, the message is also generated on standard output if RSL_io is defined, but the program then always aborts. This behaviour is defined by RSL_fail, also in the library file cpp_RSL.h.
Two kinds of messages may be produced during translation. Both start with the standard file:line:column showing from where in the RSL specification the message was generated.
During execution, run-time error messages may be produced (apart from those listed above when RSL_pre is defined). There are as follows, where x and y indicate values that are part of the generated message.
Head of empty set
Choose from empty set
Head of empty list
Tail of empty list
Choose from empty list
List x applied to non-index y
Head of empty map
Choose from empty map
Map x applied to y: outside domain
Head of empty text
Tail of empty text
Choose from empty text
Case exhausted
Let pattern does not match
These messages are produced by the function RSL_fail, which outputs the message (a C++ string) on standard output (provided RSL_io is defined) and aborts. RSL_fail is defined in the library file cpp_RSL.h, so users can easily change this behaviour if they wish by editing this file.
The following simple scheme SUM:
scheme SUM = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
variable s : Nat := 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
inc : Nat -~-> write s Unit | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
inc(x) ≡ s := s + x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pre x > 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val : Unit → read s Nat | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val() ≡ s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
test_case | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[t1] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
inc(2) ; inc(3) ; val() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
end |
translates to a header file SUM.h:
// Translation produced by rsltc <date> #ifndef SUM_RSL #define SUM_RSL #include "RSL_typs.h" extern void inc(const int x_2C7); extern int val(); extern int s; #ifdef RSL_io extern int RSL_test_case_t1(); #endif //RSL_io #endif //SUM_RSL
and a body file SUM.cc:
// Translation produced by rsltc <date> #include "SUM.h" #include "RSL_typs.cc" void inc(const int x_2C7){ #ifdef RSL_pre if (!(RSL_is_Nat(x_2C7))) RSL_warn("SUM.rsl:6:7: Arguments of inc not in subtypes"); if (!(x_2C7 > 0)) RSL_warn("SUM.rsl:6:7: Precondition of inc not satisfied"); #endif //RSL_pre s = s + x_2C7; } int val(){ return s; } int s = 0; #ifdef RSL_io int RSL_test_case_t1(){ inc(2); inc(3); return val(); } int main(){ cout << "[t1] " << RSL_int_to_string(RSL_test_case_t1()) << "\n"; } #endif //RSL_io
There are several points to note:
SUM_TEST = extend SUM with class test_case ... end
SUM_TEST can then be translated and executed to test SUM.
10.2 Activating the C++ translator | ||||||||
|
|
|