10.1 Introduction10.1 Introduction
10 C++ translator 10 C++ translator
10.3 Declarations 10.3 Declarations
10.2 Activating the C++ translator

10.2 Activating the C++ translator

The translator is activated from a shell with the command

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:

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.

  1. Error messages indicate something that could not be translated. The cause of the error must be corrected and the translator run again.

  2. Warning messages have a text starting Warning:. They indicate RSL that could not be translated completely (and the C++ output will not in general compile) but where it may be possible (and perhaps intended) to correct or complete the C++ code by hand. Examples are value definitions without bodies and implicit function or value definitions.

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.

10.2.1 Example

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 : Unitread 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:


Chris George, April 17, 2008

10.2 Activating the C++ translator
10.1 Introduction10.1 Introduction
10 C++ translator 10 C++ translator
10.3 Declarations 10.3 Declarations