Table of Contents Previous Chapter 39 The CSDL Code Generator

39 The CSDL Code Generator

The CSDL Code Generator translates your SDL system into a CSDL program that you can use as input to the CSDL tool. This chapter deals with the code generation facilities, mainly how to run the code generator and how to design the SDL system to be appropriate for translation to CSDL. It discusses in detail how SDL is translated to CSDL and what directives are available to give additional information to the code generator.

Overview of the CSDL Code Generator

This chapter describes the CSDL Code Generator, which should be used together with the CSDL tool developed by Italtel. Please see the reference list last in this chapter for other appropriate documents.

The CSDL Code Generator is designed to make it possible to generate applications using the CSDL tool, but at the same time to use the C Code Generator in SDT to simulate the SDL system at the SDL level.

-------------------------------------------------------------------
Note:                                                                
The CSDL Code Generator always generate complete files that can      
be used as input to the CSDL tool, and then compiled and linked by   
the C compiler. The user should never change anything in the         
generated files. Instead an appropriate change should be made at     
the SDL level and the files should be regenerated.                   
-------------------------------------------------------------------
Note also that the CSDL Code Generator only accepts the SDL-88 subset of SDL-92 as input. Any usage of the new SDL-92 concept, like the OO concepts or RPC, will be reported as "Feature not implemented" and no code will be generated.

Creating a CSDL program

To obtain an executable program that behaves according to an SDL description, you start the SDT Analyzer and the CSDL Code Generator from the SDT Organizer, by selecting CSDL in the Make dialog (see "Make" on page 1107) and pressing the button Full Make. If the SDL description is syntactically and semantically correct a number of CSDL files and some .c and .h files are generated. You then continue in the same way as if these files where hand written. To help you in this process the CSDL Code Generator can generate a make file and some files describing the file structure and the dependencies between the files.

Directives

The CSDL Code Generator recognizes a number of directives. A directive is an SDL comment that contains additional information for the code generator. The directives that are available for a user of the CSDL Code Generator are discussed in "Implementation of User-Defined Operators" on page 2433 and in "Directives to the CSDL Code Generator" on page 2449.

Contents of this Chapter

You can find more details in the following sections:

Generating a CSDL Program

Creating a CSDL Program

There are four steps that you must take to obtain an executable program:

  1. Start the SDT Analyzer and its built-in CSDL Code Generator from the SDT Organizer's Make dialog (see "Make" on page 1107) for creating a program expressed in CSDL source code. There will also be some generated files directly expressed in the C language.
  2. Run the generated CSDL files through the CSDL tool.
  3. Compile the generated C files (the ones generated by the CSDL Code Generator and the CSDL tool).
  4. Link the necessary files in the same way as for any other CSDL application.
Note that except for the first step, the process of obtaining an executable program is exactly the same as if the application were developed directly in CSDL. To help the user during step 2 and 3, the CSDL Code Generator can generate a make file with the name systemname.mk, where systemname is replaced by the name of the current system. The SDT Analyzer can also execute the make file for the user. The CSDL Code Generator can generate .str and .d files, showing the dependencies between the generated file. These files can be useful during step 4 in the list above. The syntax of these files are described in "Contents of .d and .str Files" on page 2466.

A CSDL program can only be generated for a complete SDL system. It is, however, possible to regenerate only a selected part of the SDL system. If, for example, a local change is made in an SDL block it is possible to regenerate only the code for that block.

--------------------------------------------------------------------
Note:                                                                 
In SDT 3.01 the possibility to regenerate only a subsystem is not im  
plemented. ALWAYS select Full Make in the SDT Organizer's             
Make dialog.                                                          
--------------------------------------------------------------------

File Names

The files that are created during the generation phase will have the file names specified in Edit Separation dialog in the Generate menu in the Organizer. By default this is the name of the SDL unit. Note that the CSDL Code Generator has a fixed separate generation scheme. This is not effected by any options in the Organizer, except for the file names as discussed above.

----------------------------------
File type           File name       
----------------------------------
signal library:     unitname_s.csm  
csp files:          unitname.csp    
generated c files:  unitname_c.c    
generated h files:  unitname_d.h    
make file:          systemname.mk   
dependency files:   systemname.str  
                    systemname.d    
----------------------------------
----------------------------------------------------------------------
Caution!                                                                
There is a potential risk that generated files may overwrite each       
other. As, for example, file names for csp files are unitname.csp,      
overwriting will occur if there are more than one unit (in this case    
process, procedure, or state) with the same name. The user has to       
take the responsibility to avoid such situations by having a strategy   
for naming the units of interest (system, block, substructure, pro      
cess, procedure, state).                                                
----------------------------------------------------------------------
The CSDL Code Generator will assist the user and will find and report situation when files become overwritten. This test can only be performed among the files that are generated in this particular execution. If you for example regenerate code for a process, the code generator cannot report that a state in this process has the same name as a state in another process, and thus that a file will be overwritten. When you regenerate the complete system, the code generator has full control, and can report any file name problems.

If the CSDL Code Generator detects a file name problem according to the discussion above, it will refuse to generate any code at all.

Generated Make File

The generated make file will include a "makeoptions" file where a number of symbols should be defined. To find the correct make option file it is required that the environment variable sctdir refers to the directory containing the makeoptions file. This can be obtained either by performing the UNIX command:

setenv  sctdir  some_appropriate_path
or by adding the definition of sctdir to the make command:

make -f systemname.mk sctdir=some_appropriate_path
The following symbols should be defined in the makeoptions file:

-------------------------------------------------
Symbol         Description                         
-------------------------------------------------
csdlCSDL       Name of the CSDL tool               
csdlCSDLFLAGS  Flags passed to the CSDL tool.      
csdlCC         Name of the C compiler              
csdlCPPFLAGS   Flags passed to the C preprocessor  
csdlCCFLAGS    Flags passed to the C compiler      
csdlIFDEF      Compilation switches                
-------------------------------------------------
Example 199   
csdlCSDL      = csdl
csdlCSDLFLAGS = -r
csdlCC        = cc
csdlCPPFLAGS  = -I. -I/proj/example/test
csdlCCFLAGS   = -O
csdlIFDEF     = -DCOMP_SWITCH_EXAMPLE
  
By using different makeoptions files, different versions of the executable program can be obtained, for example with or without debugging information (usually -g option in C compiler).

Errors During Code Generation

Errors that may occur during code generation are internal errors, that is, errors due to not yet implemented features of SDL, and errors related to problems with open or close operations of files.

All the error messages are listed below, together with a short explanation. Some messages contain a `#' followed by a number which is used to indicate where information, specific of the error situation, can be found.

Feature of SDL not implemented: #1
The translator cannot handle this SDL feature. See the list of restrictions in "Restrictions" on page 2463.

Cannot open outfile
A file that should be generated cannot be opened.

WARNING! Unique name generation failed.
This warning can be ignored in the CSDL Code Generator.

Node = nil in #1
Incorrect node type in #1. Nodetype: #2
Internal error in the PathStructure
Line exceeded MaxLineLength
These four last errors are internal errors in the CSDL Code Generator, which we would be pleased if you reported to us. The telephone and facsimile numbers to Telelogic Customer Support can be found at the beginning of this manual.

Implementation Seen From CSDL

This section contains information about the how the CSDL Code Generator translates SDL-88 to CSDL. The document is structured according to the contents of the generated CSDL files. For more information about CSDL and the translation rules please see reference 1 and 2 in "References" on page 2465.

Common Data Files

For the system and for each block the following files are generated if they have any contents.

Header Files

For the system and for the blocks, header files with the names systemname_d.h and blockname_d.h are generated, if they have any contents. These files contain:

  1. Synonyms
    C macros that are translations of the SDL synonyms.
    External synonyms in SDL causes no code to be generated. Their values are assumed to be included in an other way (defined in an included .h file containing macro definitions for example). For more information about synonyms see "Synonyms" on page 2417.
  2. Newtype, Syntype
    The type definitions in SDL are translated to typedef in C.
    The #TYPE and #HEADING sections in #ADT directives are copied to the file. For more information about abstract data types and #ADT directives please see "Abstract Data Types" on page 2419.
  3. #CODE directive among declarations (#TYPE and #HEADING)
    The contents of the #TYPE and #HEADING sections in #CODE directives are copied to the file.

Files Containing C Functions

For the system, for each block and for each process a C file is generated if it has any contents. The name of the files will be unitname_c.c. Such a file will contain:

  1. If system or block:
    #include the .h files for the enclosing units (system, blocks) followed by #include own .h file.
    If process:
#include "processname_d.h"
  1. The #BODY section in #CODE directives and #ADT directives are copied to the file.

Signal Library Files

For each system, block, and process where signals (or timers) are defined a file with the name unitname_s.csm is generated. For each signal defined in the unit a signal definition according to the example below is generated:

SIGNAL name1 CODE NAME1_CODE { };
SIGNAL name2 CODE NAME2_CODE
    {
    parameters in C
    };
where name1 is a signal with no parameters and name2 is a signal with parameters. The signal parameters given in the SDL declaration of the signal, are named Param1, Param2, and so on. A user can specify his own name for a signal parameter using the directive #SIGFIELD.

Example 200   
SIGNAL
  Sig2(Type1, Type2 /*#SIGFIELD 'MyName'*/, Type3);
This will be translated to

SIGNAL Sig2 CODE SIG2_CODE
    {
    Type1  Param1;
    Type2  MyName;
    Type3  Param3;
    };
  
A timer definition (without parameters) is translated to:

SIGNAL timername CODE TIMERNAME_CODE
    {
    SYHEADER  sy;
    }

Include File for Process Type

State codes

For each state in the process the following definition is generated:

#define STATENAME number
where number is 0, 1, 2, ...

Categories

The following definition is generated:

#define PROCESSNAME_CAT  0
which is used as default CATEGORY within the process.

Inclusions

The common data files (header files) for the system and the enclosing blocks are included here (those that exist).

C statements

For synonyms, newtypes, syntypes, and #CODE directives defined in the process, the same information that is generated in common data files (systemname_d.h or blockname_d.h files) is generated here. See "Header Files" on page 2393.

Private Variables

The CSDL Code Generator recognizes three types of variables.

  1. OWN variables, which are used in one single .csp file (start unit, state unit).
  2. GLOBAL variables, which can be used by any start, state and procedure unit within a process. Such variable will be shared between all instances of the process.
  3. PRIVATE variables, which are local to a process instance and visible throughout the process.
The variables defined in a SDL process (using DCL) are mapped to these three variable types using directives. In the generated file there will a struct with one component for each private variable. There will also be one macro for each such variable.

Example 201   
DCL
  i1, i2  Integer,
  J       Boolean,    /*#GLOBAL*/
  k       Character,  /*#OWN 'state1'*/
  L       Integer;    /*#OWN 'start'*/
The first two variables, i1 and i2, are private variables, the third variable, J, is a GLOBAL variable, while k and L are OWN variables; k to the state unit for state state1 and L for the start up unit. Given the DCL above in a process called P1, the generated declarations will look like:

typedef struct {
  SDL_Integer  i1;
  SDL_Integer  i2;
} P1_DCL;
#define P1_DCL_PTR  ((P1_DCL *)SDLprivate_data_ptr)
#define _I1  P1_DCL_PTR->i1
#define _I2  P1_DCL_PTR->i2
  
There will also be one component in the struct and one macro for each timer defined in the process. The struct component will look like:

SYSIGNAL_TYPE  * timername_to_key;
while the macro will be:

#define TIMERNAME_TO_KEY \
 P1_DCL_PTR->timername_to_key

Startup File (processname.csp)

A startup file contains:

START_UNIT processname;
  seized objects
  own objects
  startup actions

Seized Objects

First in the startup file there are the seized objects:

SEIZE
contents 
ENDSEIZE;
where the contents is described below.

  1. Inclusions. The .h file for the process is included:
#include "processname_d.h"
  1. C statements. Those variables (DCL) that has a GLOBAL directive (see also "Private Variables" on page 2395) are generated as GLOBAL declarations:
GLOBAL type1 varname1;
GLOBAL type2 varname2;
If the variable has a default value, either in the DCL clause or as default value given in the sort definition, this value is assigned in the GLOBAL declaration.
  1. Output Signals. For each signal that the process can send:
OUTSIGNAL
  FROM file1.csm : sig1, sig2, sig3
    ITSELF EXTERN;
  FROM file2.csm : sig4, sig5
    ITSELF EXTERN;
  1. Reference to Procedures. For each procedure that is called in the process the following is generated:
PROCEDURE FROM procedurename.csp USING {void} 
procedurename;
  1. Reference to State. For each state in the process:
STATEUNIT STATENAME FROM statename.csp

Own Objects

Next there is the OWN objects.

OWN
own variables
ENDOWN;
where the OWN variables are described below.

For each own variable (see also "Private Variables" on page 2395) for the start up file, that is variable with directive

/*#OWN 'start'*/
a C variable declaration is generated. If the variable has an initial value in SDL, either by an assignment in the declaration or as a default value for all variables of a given type, this initial value is assigned in the C declaration.

Example 202   
Assume the following declarations in SDL:

SYNTYPE NewInteger = Integer
  DEFAULT 10;
ENDSYNTYPE;
DCL
  I1      Integer = 1,      /*#OWN 'start'*/
  I2, I3  Integer,          /*#OWN 'start'*/
  I4      NewInteger = 20,  /*#OWN 'start'*/
  I5      NewInteger;       /*#OWN 'start'*/
The DCL is then translated to:

OWN
STATIC SDL_Integer  I1 = 1;
STATIC SDL_Integer  I2;
STATIC SDL_Integer  I3;
STATIC NewInteger  I4 = 20;
STATIC NewInteger  I5 = 10;
ENDOWN;
  

Startup Actions

The startup actions, which corresponds to the start transition in an SDL process, has the following structure:

PROCESS processname;
STARTUP;
  initialization of private and global variables
  initialization of timers
  start up transition
ENDSTARTUP;
ENDPROCESS processname;
  1. Initialization of Private and Global Variables
    If the process contains private variables the following task is generated:
TASK 'initialisation of private data';
{
  RES_PRIV_DATA(processname_DCL);
}
This is followed by a TASK where each private variable that should have a start value is assigned this value. Initial values can either be specified in the DCL of as default value in the type declaration.
  1. Initialization of Timers
    Each timer defined in the process will have its variable among the private data initialized in a TASK:
TASK 'initialisation of timers';
{
  TIMER_EX_TO_KEY = NULL;
}
  1. Start up transition
    The start up transition is a translated version of then start transition in the SDL process. The symbols in transitions are translated according to the description that can be found in "CSDL Statements and Terminators" on page 2406.

Single State File (statename.csp)

For each state in the process a file containing the following is generated:

STATE_UNIT statename;
  seized objects
  own objects
  state actions

Seized Objects

The seize objects section contains:

SEIZE
contents
ENDSEIZE;
where the contents is described below.

  1. Inclusions. The .h file for the process is included:
#include "processname_d.h"
  1. C statements. Those variables (DCL) that has a #GLOBAL directive (see also "Seized Objects" on page 2397) are generated as IMPORT declarations:
IMPORT type1 varname1;
IMPORT type2 varname2;
  1. Input Signals. For each signal that can be received in the state (i.e. mention in an INPUT or SAVE statement) the following is generated:
INSIGNAL
  PROCESSNAME_CAT FROM file1.csm : sig1, sig2;
  PROCESSNAME_CAT FROM file2.csm : sig3;
If the same transition should be executed for several state-signal combination, only one of them can be found in the generated code, while for the other combinations it is described in the INSIGNAL section how to find the appropriate transition.
Example 203   
sig4(State1, Sig3)
If the state contains an INPUT *, then the following is generated last in the INSIGNAL section:
PROCESSNAME_CAT FROM "SYLOCK_CSM" : SYlOCK;
If the #CATEGORY directive is used in input or save statements, then each combination of category name - file name will only occur once, containing the list of all the signals for this combination. The #define for all category names except PROCESSNAME_CAT have to be supplied by the user, for example in a #CODE directive. For more information about the #CATEGORY directive please see "#CATEGORY Directive" on page 2462.
  
  1. Output Signals. Each signal that the process can send will be mentioned in a OUTSIGNAL clause according to the example below:
OUTSIGNAL
  FROM file1.csm : sig1, sig2, sig3
    ITSELF EXTERN;
  FROM file2.csm : sig4, sig5
    ITSELF EXTERN;
  1. Reference to Procedures. For each procedure that is called in the process the following is generated:
PROCEDURE FROM procedurename.csp USING {void} 
procedurename;

Own Objects

The OWN section is generated as:

OWN
contents
ENDOWN;
where the contents is described in "Own Objects" on page 2398, except that the #OWN directive should contain the state name, instead of `start'.

Example 204   
/*#OWN 'state1'*/
  

State Actions

The state actions are generated according to the following example.

Example 205   
STATE statename;
contents
ENDSTATE statename;
  
The contents in the state description contains a number of INPUT sections. Details can be found below.

For each input symbols in SDL there will be an INPUT statement containing the same signal, except for signal that in the INSIGNAL section (see page 2400) refers to another state-signal combination.

Example 206   
INPUT signalname;
  
The corresponding transition is then generated, possibly starting with a TASK where the signal parameters are copied to process variables. The translation of action within transitions are discussed in "CSDL Statements and Terminators" on page 2406, while the signal parameter assignment is treated later in this section.

The SDL input INPUT *; is generated as:

INPUT SYlOCK;
This is placed last among the INPUT statements in the file. Please note that INPUT * in SDL and INPUT SYlOCK in CSDL do not have exactly the same meaning. INPUT SYlOCK means "all other signals", while INPUT * means "all other signals in the signalset of the process".

A save of a signal will be translated to:

INPUT signalname;
  TASK 'save signalname';
  {
    SDL_SAVE;
  }
  NEXTSTATE *;
that is, a transition that just saves the signal. In each state file there will only be one such transition, using mappings in the INSIGNAL section to this state-input combination.

In SDL the signal parameters are copied to the process variables mentioned in the input.

Example 207   
INPUT Sig1(Var1, Var2);
  
means that the first signal parameter is at the input of the signal, assigned to the variable Var1, while the second signal parameter is assigned to Var2. After the input the signal parameters are not available in SDL any longer.

It is in SDL also allowed to have an empty position in the variable list, indicating that the corresponding signal parameter should not be copied.

Example 208   
INPUT Sig1(, Var2)
INPUT Sig1(Var1, )
  
This means that the value of the corresponding signal parameter is lost (in SDL).

In the CSDL Code Generator an input is followed by a TASK where the signal parameter are copied to the variables specified in the input. If no parameters should be copied, no task is generated.

Example 209   
The following SDL input:

INPUT Sig2(Var1, , Var3, );
will be translated to:

INPUT Sig2;
TASK 'copy signal parameters'
{
  Var1 = Sig1->Param1;
  Var3 = Sig1->Param3;
}
  
The user has now two possible strategies that he can choose between for each signal parameter reception. The first is to follow SDL and copy the signal parameter to an SDL variable. The second is to leave the corresponding position in the list of variables empty. It is then of course possible to refer to the signal parameter in included CSDL (C) code in #CODE directives in TASK.

Note that the second approach makes the code faster, but also that the SDL system cannot directly be simulated using the SDT C Code Generator. It is however possible to refer to signal parameters in TASKs in a similar way in the generated C code (C Code Generator) as it is in the generated CSDL code. This information will be provided by Telelogic at request.

Procedure File

Note the following differences between SDL and CSDL:

Restrictions in the CSDL Code Generator:

  1. Procedures defined in procedures (nested procedures) are not allowed.
  2. Procedures with states are not allowed.
For each procedure in the process a file, named
procedurename.csp, is generated containing the following:

PROCEDURE_UNIT procedurenameproc;
  seized objects
  own objects
  SDLPROC section

Seized Objects

This section consists of:

SEIZE
contents
ENDSEIZE;
where the contents is described below.

  1. Inclusions
    The .h file for the enclosing process is included:
#include "processname_d.h"
  1. C statements
    Those variables (DCL) in the enclosing process that has a #GLOBAL directive (see also "Seized Objects" on page 2397) and are used within the procedure, are generated as IMPORT declarations:
IMPORT type1 varname1;
IMPORT type2 varname2;
  1. Output Signals
For each signal that the enclosing process can send:

OUTSIGNAL
  FROM file1.csm : sig1, sig2, sig3
    ITSELF EXTERN;
  FROM file2.csm : sig4, sig5
    ITSELF EXTERN;
  1. Reference to Procedure
    For each procedure that is called in the procedure the following is generated:
PROCEDURE FROM procedurename.csp USING {void} 
procedurename;

SDLPROC section

This section contain the procedure name, its parameters, its local variables, and the statements performed by the procedure.

SDLPROC {void} procedurename (parameter1, parameter2)
{
  typename1  parameter1;
  typename2 *parameter2;
};
  local procedure variables
  transition
ENDSDLPROC procedurename;
An SDL IN parameter is passed as a value, while an SDL IN/OUT parameter is passed as the address to the variable. In the example above the first parameter is IN and the second is IN/OUT.

Each variable defined in the SDL procedure (DCL) will generate a variable in CSDL.

Example 210   
Assuming the following SDL DCL in a procedure:

DCL
  i1, i2 : Integer;
  k      : mytype;
the code generator will generate

SDL_Integer  i1;
SDL_Integer  i2;
mytype  k;
  
Any start value will be assigned in a task immediately after the variables.

The actions contained in the transition will be translated according to "CSDL Statements and Terminators", next.

CSDL Statements and Terminators

Task

An SDL task is translated to a CSDL TASK. Each assignment in SDL is translated to an assignment in CSDL (or rather in C). The C code in #CODE directives in the task will be copied at the place where they are found.

Procedure Call

An SDL procedure call is translated to a CSDL procedure call.

Example 211   
CALL Proc1(var+1, var2);
is, assuming that the first parameter is IN and the second is IN/OUT and assuming that var and var2 are private variables, translated to:

PROCEDURE Proc1(_VAR+1, &_VAR2);
  

Output

An SDL output is translated to an CSDL OUTPUT. The signal parameters are assigned in a DOING clause in CSDL and the TO expression in CSDL is a translation of the TO expression in the SDL output.

Restriction: It is not allowed to use SDL outputs without TO clause. See also the discussion on the DEST operator below.

Example 212   
OUTPUT Sig1 TO DEST(Sender,1,1,1);
OUTPUT Sig2(Var1, Var2+7) TO DEST(Sender,I,J,K);
is translated to:

OUTPUT Sig1 TO DEST(1,1,1);
OUTPUT Sig2 TO DEST(I,J,K)
  DOING {
    Sig2->Param1 = Var1;
    Sig2->Param2 = Var2+7;
  };
  
By having the directive #TRANSFER (see also "#TRANSFER Directive" on page 2460) immediately before or after the semi-colon ending the output statement in SDL, the keyword TRANSFER is included in CSDL.

Example 213   
OUTPUT Sig1 TO DEST(Sender,1,1,1) /*#TRANSFER*/;
is translated to:

OUTPUT Sig1 TO DEST(1,1,1) TRANSFER;
  
To address signals, PId values are used in SDL. In CSDL, however, a macro with a number of parameters are used (parameters like RTFG_ID, RTFE_TYPE, and so on).

The CSDL Code Generator assumes that the TO expression, which is mandatory, consists of an operator call to the SDL operator DEST. This operator has to be included in an abstract data type preferably at the system level, to be available in SDL.

To be able to use both the CSDL and C Code Generator for the same SDL system, the DEST operator is assumed to have one first parameter which should be used for simulation (C Code Generator) and a number of other parameters used for CSDL.

The CSDL Code Generator will therefore remove the first parameter of any operator that it find in a TO expression. That is, if the CSDL Code Generator finds:

DEST(a,b,c,d,e)
it will generate

DEST(b,c,d,e)
in CSDL. Note, this translation rule is only used in TO clauses and is valid for any operator, not only for DEST.

The DEST operator should in SDL be defined as

DEST : PId, x, y, z, v -> PId;
where x, y, z, v should be some appropriate types. When the system is simulated the DEST operator should just return the first parameter, while when the CSDL Code Generator is used a suitable macro definition of the DEST operator should be included in the definition of the operator.

The name DEST and the number of parameters of the operator are not fixed, but can be tailored to suit users.

Create

An SDL create is translated to a create in CSDL, which is a TASK calling a create function.

Example 214   
The SDL create statements

create P2; /*#PROCPAR (x, y, z)*/
create P2  /*#PROCPAR (a, b, c)*/;
is translated to

TASK 'Create of process P2';
{
  SDL_CREATE (x, y, z);
}
TASK 'Create of process P2';
{
  SDL_CREATE (a, b, c);
}
  
Note that the #PROCPAR directive is mandatory. It will be described in "#PROCPAR Directive" on page 2457.

Stop

A stop action in SDL is translated to a TASK where a stop function is called in CSDL.

Example 215   
stop /*#PROCPAR (x, y, z)*/;
is translated to

TASK 'Stop';
{
  SDL_KILL (x, y, z);
}
  
Note that the #PROCPAR directive is mandatory. It will be described in "#PROCPAR Directive" on page 2457.

Decision (Boolean)

An SDL decision containing a Boolean expression is translated into a BOOLEAN DECISION in CSDL, if it is not identified as a LOOP, see "Loop, Exit_Loop" on page 2411.

Example 216   
The SDL decision:

decision (I=10 or I=20);
(true)  : statement_list1;
(false) : statement_list2;
enddecision;
is translated to:

DECISION ' ' IS (I==10 || I==20);
WHEN (YES) :
  statement_list1;
WHEN (NO) :
  statement_list2;
ENDDECISION;
  

Decision (Case)

The SDL decisions that:

are translated to CASE DECISIONS in CSDL.

Example 217   
The following SDL decision

decision (C);
('a') : task C := 'A';
('b') : task C := 'B';
('c') : task C := 'C';
enddecision;
is translated to

DECISION ' ' IS (C);
WHEN (' ' IS ('a')) :
  TASK 'C := ...';
  {
    C = 'A';
  }
WHEN (' ' IS ('b')) :
  TASK 'C := ...';
  {
    C = 'B';
  }
WHEN (' ' IS ('c')) :
  TASK 'C := ...';
  {
    C = 'C';
  }
ENDDECISION;
  

Decision (Select)

All SDL decisions not translated to BOOLEAN DECISIONS or CASE DECISIONS are translated to CSDL SELECT DECISION, according to the following example.

Example 218   
SDL decision, where I is an integer variable:

decision (I);
(<1) : statement_list1;
(=1) : statement_list2;
(>1) : statement_list3;
enddecision;
This is translated to:

DECISION ' ';
WHEN (' ' IS (I<1)) :
  statement_list1;
WHEN (' ' IS (I=1)) :
  statement_list2;
WHEN (' ' IS (I>1)) :
  statement_list3;
ENDDECISION;
  
An ELSE path in an SDL decision is translated to an OTHERWISE: in CSDL.

Loop, Exit_Loop

An SDL Boolean decision is in some circumstances identified as a CSDL LOOP (WHILE LOOP). The decision should:

Example 219   
Example of SDL decision identified as a LOOP:

L1 :
DECISION (I>5);
(true)  :
  statement_list1;
  JOIN L1;
(false) :
  statement_list2;
ENDDECISION;
This is translated to:

L1 :
LOOP L_L1 WHILE (I>5);
  statement_list1;
ENDLOOP L_L1;
statement_list2;
Note that the LOOP name will be L_ followed by the SDL label name.

  
A decision within a LOOP might under some circumstances be identified as an EXIT_LOOP.

The decision should:

Example 220   
The following SDL statements:

la:
decision (I>10);
(true) :
  task I:=I-1;
  decision (I>100);
  (true) : join E_la;
  (false) :
  enddecision;
  output Sig1(I,1,I)
     to DEST(Sender, 1, 1);
  join la;
(false) :
enddecision;
E_la:
will be translated to:

la :
  LOOP L_la WHILE (I>10);
    TASK 'I := ...';
    {
      I = I-1;
    }
    EXIT_LOOP L_la ON (I>100);
    OUTPUT Sig1 TO DEST(1, 1)
      DOING {
        Sig1->Param1 = I;
        Sig1->f2 = 1;
        Sig1->Param3 = I;
      };
  ENDLOOP L_la;
E_la :
  

Start_Timer

A set operation on a timer is translated to a START_TIMER in CSDL.

Restrictions:

  1. The set statement should have the format defined below, otherwise it is indicated as an error.
  2. Timers with parameters are not handled.
An SDL set of the form:

set(now + mybase*myunits, timername);
where mybase should be a variable, synonym, or value of type duration, and myunits should be of type real (in SDL), is translated to:

START_TIMER SDLTIMER UNITS myunits BASE mybase
  SIGNAL timername KEY TIMERNAME_TO_KEY;
For information about TIMERNAME_TO_KEY please see "Private Variables" on page 2395.

Using the directive #TIMERTYPE it is possible to replace SDLTIMER in the START_TIMER. Please see "#TIMERTYPE Directive" on page 2459 for more information.

Stop_Timer

A reset operation on a timer is translated to a STOP_TIMER in CSDL. An SDL reset of the form:

reset(timername);
is translated to:

STOP_TIMER KEY TIMERNAME_TO_KEY;
Note the semantic difference between reset and STOP_TIMER: A reset action will remove the timer signal from the signal queue if the timer signal has been sent but have not yet caused a transition. This is not true for STOP_TIMER.

Nextstate

An SDL nextstate is translated to a CSDL NEXTSTATE. The state name will be in upper case. Dash nextstate, that is nextstate -, in SDL is translated to NEXTSTATE * in CSDL.

Return

An SDL return is translated to a CSDL RETURN. Note that SDL procedures cannot return any value.

Join and Label

An SDL join (outconnector) is translated to a CSDL JOIN.

An SDL label is translated to a CSDL label:

labelname :
It is the responsibility of the user only to introduce join - label combinations that will become local in one .csp file, that is local within one transition. Note the joining two flow-lines in GR is the same as introducing join - label.

Implementation Seen From SDL

In this section we will discuss most of the SDL concepts and how they are translated into CSDL. In many case references to the previous section Implementation Seen From CSDL is made, not to unnecessarily repeat information.

System, Block, Substructure

These concepts are used to express the hierarchical structure of a system. None of these are translated into CSDL. Files with the names

Unitname_c.c
Unitname_d.h
Unitname_s.csm
may however be generated (Unitname should be replaced with the name of the SDL unit). The .c file contains C code included in #ADT and #CODE directives, while the .h file contains translations of synonyms and data types, as well as C code for #ADT and #CODE directives. The .csm file contains the signal library for the SDL signals defined in the current unit.

Channel and Signal Route

Channels and signal routes in an SDL system are not translated to CSDL.

Process and Procedure

An SDL process will be translated to a CSDL process and an SDL procedure is translated to a CSDL procedure. Each CSDL procedure will be generated on a file of its own.

Files generated from processes and procedures:

Processname.csm
Processname_d.h
Processname_c.c
Processname.csp
Statename.csp
Procedurename.csp
The Processname.csm will contain the signal library for signals and timers defined within the process.

The Processname_d.h contains macros representing synonyms, typedefs from abstract data types, #TYPE and #HEADING sections from #ADT and #CODE directives, and state codes for all the states in the process. The file also contains a struct representing all the private variables in the process. For more information about variables see "Process Variables" on page 2416.

The file Processname_c.c contains #BODY sections of #ADT and #CODE directives found in the process.

The files Processname.csp and Procedurename.csp contain the start transition of the process or procedure.

The files of type Statename.csp contain the implementation of the transitions starting from the state.

Restrictions:

Signal and Timer

A signal definition in SDL is translated to a signal declaration in a CSDL signal library. There will be a signal library file for each system, block, substructure, and process that contains any signal definitions (or timer definitions). For details and examples please see "Signal Library Files" on page 2394.

A timer definition in a process will in the same way introduce a signal declaration in the signal library for the process. For each timer there will also be a variable among the private variables of the process. For more information please see "Private Variables" on page 2395.

Restriction:

Process Variables

Variables defined in DCL will be translated to CSDL according to the description that can be found in the "Private Variables" on page 2395.

State, Input, and Save

This is discussed in detail in "State Actions" on page 2401.

SDL restrictions:

Actions Within Transitions

Please see the "CSDL Statements and Terminators" on page 2406.

Restrictions:

Synonyms

An SDL synonym is generated as a C macro (#define). If the synonym is of a predefined SDL sorts (Integer, Real, Character, and so on) and it is possible to calculate at analysis time, the calculated value will be generated as value in the macro. Otherwise the synonym expression will be translated and used as macro value. A synonym can be calculated if it only contains literals and operators defined in the predefined SDL sorts and other synonyms which are possible to calculate at analysis time.

Example 221   
SYNONYM S1 Integer = 7;
SYNONYM S2 Integer = S1+3;
SYNONYM S3 Integer = UserFunc(1, 5);
will be generated as:

#define S1  7
#define S2  10
#define S3  UserFunc(1, 5)
  
External synonyms can be used to parameterize an SDL system and thereby also a generated program. No code will be generated in CSDL for the external synonyms. The values that should be used for the external synonyms should be included as macro definitions into the generated code. To use a macro definition in C to specify the value of an external synonym, perform the following steps:

  1. First write the macro definitions on a file.
Example 222   
#define synonym1 value1
#define synonym2 value2
  
  1. Then introduce the following #CODE directive at the system level among the SDL definitions of, for example, synonyms, sorts, and signals, but before any use of the synonyms.
Example 223   
/*#CODE
#TYPE
#include "filename"
*/
  
If you use this structure you can change the value of an external synonym merely by changing the corresponding macro definition and recompiling the system.

Abstract Data Types

In this section we first look at the implementation of the predefined data types in SDL, see "SDL Predefined Types" below. We then discuss how user-defined abstract data types are translated, see "Translation of Sorts" on page 2428.

Next the possibility to include hand-coded C functions as implementation of the operators in abstract data types is presented, see "Implementation of User-Defined Operators" on page 2433.

Last, in "More about Abstract Data Types" on page 2440, we discuss more details about operators and the possibilities to include a hand-coded type definition in C to represent the SDL sort.

SDL Predefined Types

Mapping table

Below is a table which summarizes the mapping rules between SDL and C, concerning the predefined types in SDL and their operators.

----------------------------------------------------------------------
SDL name/operator         C name/expression/operator                    
----------------------------------------------------------------------
Boolean                   SDL_Boolean                                   
False, True               SDL_False, SDL_True                           
not                       !                                             
=, /=                     ==, !=                                        
and                       &&                                    
or                        ||                                            
xor                       !=                                            
=>                     <=                                         
Character                 SDL_Character                                 
NUL                       SDL_NUL                                       
SOH                       SDL_SOH                                       
...                       ... (for all unprintable characters)          
'a'                       'a'                                           
'b'                       'b'                                           
...                       ... (for all printable characters except ' )  
''''                      '\''                                          
=, /=                     ==, !=                                        
<, <=, >, >=  <, <=, >, >=                      
Charstring                SDL_Charstring                                
'aa'                      "Laa"                                         
=                         xEq_SDL_Charstring                            
/=                        ! xEq_SDL_Charstring                          
MkString                  xMkString_SDL_Charstring                      
Length                    xLength_SDL_Charstring                        
First                     xFirst_SDL_Charstring                         
Last                      xLast_SDL_Charstring                          
//                        xConcat_SDL_Charstring                        
SubString                 xSubString_SDL_Charstring                     
Extract!                  xExtr_SDL_Charstring                          
Modify!                   xMod_SDL_Charstring                           
Integer                   SDL_Integer                                   
0, 1, 2,...               same as in SDL                                
+, -                      +, -                                          
*                         *                                             
/                         xDiv_SDL_Integer                              
=, /=                     ==, !=                                        
<, <=, >, >=  <, <=, >, >=                      
Float                     xFloat_SDL_Integer                            
Fix                       xFix_SDL_Integer                              
Natural                   SDL_Natural                                   
Real                      SDL_Real                                      
0.0,...                   same as in SDL                                
+, -                      +, -                                          
*                         *                                             
/                         xDiv_SDL_Real                                 
=, /=                     ==, !=                                        
<, <=, >, >=  <, <=, >, >=                      
PId                       SDL_PId                                       
NULL                      SDL_NULL                                      
=, /=                     xEq_SDL_PId, !xEq_SDL_PId                     
Duration                  SDL_Duration                                  
23.45                     SDL_Duration_Lit(23, 450000000)               
+                         xPlus_SDL_Duration                            
- (monadic)               xMonMinus_SDL_Duration                        
- (dyadic)                xMinus_SDL_Duration                           
*                         xMult_SDL_Duration                            
/                         xDiv_SDL_Duration                             
=, /=                     xEq_SDL_Duration,                             
                          ! xEq_SDL_Duration                            
>                      xGT_SDL_Duration                              
Time                      SDL_Time                                      
23.45                     SDL_Time_Lit(23, 450000000)                   
+                         xPlus_SDL_Time                                
- (result: Time)          xMinusT_SDL_Time                              
- (result: Duration)      xMinusD_SDL_Time                              
=, /=                     xEq_SDL_Time,                                 
                          ! xEq_SDL_Time                                
<                      xLT_SDL_Time                                  
<=                     xLE_SDL_Time                                  
>                      xGT_SDL_Time                                  
>=                     xGE_SDL_Time                                  
----------------------------------------------------------------------

C definitions

To be able to use the predefined data types in SDL system the following entities have to be defined in C. This can be seen as part of an SDL run-time library that is included in the CSDL application. The definitions below should be seen as examples. The important information is what symbols that should be defined, depending on which SDL predefined data types that are to be used in the application.

typedef int SDL_Boolean;
#define SDL_False 0
#define SDL_True 1
typedef int SDL_Integer;
typedef int SDL_Natural;
typedef float SDL_Real;
typedef struct {
    xint32  s, ns;
  }  SDL_Time;
typedef SDL_Time  SDL_Duration;
typedef char *SDL_Charstring;
typedef char SDL_Character;
#define SDL_NUL '\000'
#define SDL_SOH '\001'
#define SDL_STX '\002'
#define SDL_ETX '\003'
#define SDL_EOT '\004'
#define SDL_ENQ '\005'
#define SDL_ACK '\006'
#define SDL_BEL '\007'
#define SDL_BS '\010'
#define SDL_HT '\011'
#define SDL_LF '\012'
#define SDL_VT '\013'
#define SDL_FF '\014'
#define SDL_CR '\015'
#define SDL_SO '\016'
#define SDL_SI '\017'
#define SDL_DLE '\020'
#define SDL_DC1 '\021'
#define SDL_DC2 '\022'
#define SDL_DC3 '\023'
#define SDL_DC4 '\024'
#define SDL_NAK '\025'
#define SDL_SYN '\026'
#define SDL_ETB '\027'
#define SDL_CAN '\030'
#define SDL_EM '\031'
#define SDL_SUB '\032'
#define SDL_ESC '\033'
#define SDL_IS4 '\034'
#define SDL_IS3 '\035'
#define SDL_IS2 '\036'
#define SDL_IS1 '\037'
#define SDL_DEL '\177'
#define SDL_PId   ???
#define SDL_NULL  ???
#define xDef_SDL_PId(V) *(V) = SDL_NULL

Functions and Macros

Below is a description of the functions and macros that are used to implement the operators in the predefined data types in SDL.

xFix_SDL_Integer and xFloat_SDL_Integer

extern SDL_Integer xFix_SDL_Integer (SDL_Real Re);
#define xFloat_SDL_Integer(I) ((SDL_Real)I)
These two functions convert between integer and real values and are used to represent the SDL operators Fix and Float. The function xFix_SDL_Integer checks if the value of the real parameter is too large to be converted to an integer (if it would cause integer overflow). In that case an SDL dynamic error is reported and the function returns the value 0. Fix can be a macro if no error check should be performed.

xDiv_SDL_Integer

extern SDL_Integer xDiv_SDL_Integer 
  (SDL_Integer i,
   SDL_Integer k);
This function performs integer division, i.e. returns the value of the expression i / k. The function, however, first checks if k is 0, in which case an SDL dynamic error is reported and the function returns the value 0. If no check is necessary this function is best implemented as a macro.

xDiv_SDL_Real

extern SDL_Real xDiv_SDL_Real 
  (SDL_Real i,
   SDL_Real k);
This function performs real division, that is, it returns the value of the expression i / k. The function first checks if k is 0.0, in which case an SDL dynamic error is reported and the function returns the value 0.0. If no check is necessary this function is best implemented as a macro.

xMkString_SDL_Charstring

extern SDL_Charstring xMkString_SDL_Charstring 
  (SDL_Character C);
The function returns a charstring of length 1 with the component value equal to the character parameter value. This function is used to represent the operator MkString in sort charstring.

xConcat_SDL_Charstring

extern SDL_Charstring xConcat_SDL_Charstring 
  (SDL_Charstring C1, 
   SDL_Charstring C2);
The function concatenates two charstring values to one charstring and is used to represent the operator "//" in sort charstring.

xFirst_SDL_Charstring

extern SDL_Character xFirst_SDL_Charstring 
  (SDL_Charstring C);
The function returns the first character in the charstring parameter and is used to represent the operator First in sort charstring.

xLast_SDL_Charstring

extern SDL_Character xLast_SDL_Charstring 
  (SDL_Charstring C);
The function returns the last character in the charstring parameter and is used to represent the operator Last in sort charstring.

xLength_SDL_Charstring

extern SDL_Integer xLength_SDL_Charstring
  (SDL_Charstring C);
The function returns the number of characters in the charstring parameter and is used to represent the operator Length in sort charstring.

xSubString_SDL_Charstring

extern SDL_Charstring xSubString_SDL_Charstring 
  (SDL_Charstring C,
   SDL_Integer Start,
   SDL_Integer SubLength);
The function returns a charstring which is a substring of C, starting at index Start and with length SubLength. This function is used to represent the operator Substring in sort charstring.

xAss_SDL_Charstring

extern void xAss_SDL_Charstring
  (SDL_Charstring *CVar,
   SDL_Charstring CExpr);
This function is used to assign the charstring value CExpr to the charstring variable that corresponds to the formal parameter CVar. This routine should be used instead of the ordinary C assignment.

xEq_SDL_Charstring

extern SDL_Boolean xEq_SDL_Charstring
  (SDL_Charstring C1,
   SDL_Charstring C2);
The function returns true if two charstrings are equal, otherwise false. This function is used to represent the operator "=" in sort charstring and should be used instead of the ordinary C == operator.

xMod_SDL_Charstring

extern SDL_Charstring xMod_SDL_Charstring
  (SDL_Charstring C,
   SDL_Integer Index,
   SDL_Character Value);
The function returns a charstring which is equal to C, but where the character value at index Index is changed to Value. This function is used to represent the operator Modify! in sort charstring.

xExtr_SDL_Charstring

extern SDL_Character xExtr_SDL_Charstring
  (SDL_Charstring C,
   SDL_Integer Index);
The function returns the character value at the given index and is used to represent the operator Extract! in sort charstring.

xEq_SDL_PId

extern SDL_Boolean xEq_SDL_PId 
  (SDL_PId A,
   SDL_PId B);
This function is used to check if two PId values are equal.

Functions and Macros on Duration Sort

The following functions and macros implement the operators defined in the Duration sort.

xPlus_SDL_Duration (+)

extern SDL_Duration xPlus_SDL_Duration
  (SDL_Duration D1,
   SDL_Duration D2);

xMinus_SDL_Duration (dyadic -)

#define xMinus_SDL_Duration(P1, P2) \
  xPlus_SDL_Duration \
    (P1,xMonMinus_SDL_Duration(P2))

xMonMinus_SDL_Duration (monadic -)

extern SDL_Duration xMonMinus_SDL_Duration
  (SDL_Duration D);

xMult_SDL_Duration (*)

extern SDL_Duration xMult_SDL_Duration
  (SDL_Duration D,
   SDL_Real R);

xDiv_SDL_Duration (/)

extern SDL_Duration xDiv_SDL_Duration
  (SDL_Duration D,
   SDL_Real R);

xGT_SDL_Duration (>)

#define xGT_SDL_Duration(P1, P2)  \
   xLT_SDL_Time (P2, P1)

xEq_SDL_Duration (=)

extern SDL_Boolean xEq_SDL_Duration
  (SDL_Duration D1,
   SDL_Duration D2);

SDL_Duration_Lit

extern SDL_Duration SDL_Duration_Lit
  (xint32 s, xint32 ns);

Functions and Macros on Time Sort

The following functions and macros implement the operators defined in the Time sort.

xPlus_SDL_Time (+)

#define xPlus_SDL_Time(P1, P2) \
  xPlus_SDL_Duration(P1, P2)

xMinusD_SDL_Time (Time-Time->Duration)

#define xMinusD_SDL_Time(P1, P2) \
  xPlus_SDL_Duration(P1, xMonMinus_SDL_Duration(P2))

xMinusT_SDL_Time (Time-Duration->Time)

#define xMinusT_SDL_Time(P1, P2) \
  xPlus_SDL_Duration \
    (P1, xMonMinus_SDL_Duration(P2))

xEq_SDL_Time (=)

#define xEq_SDL_Time(P1, P2) \
  xEq_SDL_Duration(P1, P2)

xLT_SDL_Time (<)

extern SDL_Boolean xLT_SDL_Time
  (SDL_Time T1, SDL_Time T2);

xLE_SDL_Time (<=)

extern SDL_Boolean xLE_SDL_Time
  (SDL_Time T1, SDL_Time T2);

xGT_SDL_Time (>)

#define xGT_SDL_Time(P1, P2) \
   xLT_SDL_Time(P2, P1)

xGE_SDL_Time (>=)

#define xGE_SDL_Time(P1, P2) \
   xLE_SDL_Time(P2, P1)

SDL_Time_Lit

#define SDL_Time_Lit(P1, P2) \
   SDL_Duration_Lit(P1, P2)

Translation of Sorts

The following data types can be handled by the C Code Generator.

Predefined Types

All the predefined data types, Integer, Natural, Boolean, Character, Charstring, Real, Time, Duration, and PId are completely handled by the CSDL Code Generator. The name of these types in the generated C code will be SDL_Integer, SDL_Natural, SDL_Boolean, and so on. The translation rules for these types and their operators are discussed in more detail in "SDL Predefined Types" on page 2419. To be possible to use the predefined data types, the typedefs, macros and function indicated in "SDL Predefined Types" must of course be available.

Enumeration Type

A sort which is not a struct and does not contain any inheritance or generator instantiation, but which contains a literal list, is translated to an enumeration type in C, as can be seen in the example below.

Example 224   
NEWTYPE EnumType  
  LITERALS Lit1, Lit2, Lit3;
ENDNEWTYPE;
is translated to:

typedef enum {Lit1, Lit2, Lit3} EnumType;
  

Struct

An SDL struct is translated to a struct in C, as can be seen in the example below.

Example 225   
NEWTYPE Str STRUCT
  a integer;
  b Boolean;
  c real;
ENDNEWTYPE;
is translated to:

typedef struct {
 SDL_Integer a;
 SDL_Boolean b;
 SDL_Real c;
} Str;
  
All the properties of a struct in SDL are preserved in the CSDL and C code. The predefined operators Extract! and Modify! are implemented as component selection in the struct in the same way as in SDL, that is, if S is a variable of type Str, then S!a in SDL is translated to S.a in C. The predefined operator Make!, which is a constructor of a struct value, is implemented by generating a Make function in C. This means that the expression (. 12, true, 0.22 .) in SDL is translated to the C function call Make(12, true, 0.22). The Make function will of course be given a name that makes it unique.

The components of a struct may be of any sort that the CSDL Code Generator can handle. A component may, however, not directly or indirectly refer to the struct sort itself.

Example 226   
The sort Str above may not have a component of sort Str. In such a case the translation to a C struct would not any longer be valid.

  

Array

Instantiations of the predefined generator array can be handled by the CSDL Code Generator with the following restrictions. The component sort may be any sort that the CSDL Code Generator can handle, but may not directly or indirectly refer to the array type itself (see also the previous paragraph on struct). The index sort should be a discrete sort, with one closed interval of values. This means that the following index sorts may be used:

Another way of defining the allowed index sorts is that the CSDL Code Generator can handle array instantiations with an index sort that can directly be matched to the array concept in C.

An instantiation of the generator array, if it does not violate the restrictions above, is translated to a struct containing an element A which is an array in C. The reason for this translation strategy is that an array may not be result type of a C function (only the address of an array may be result type), which is necessary as SDL operators may have arrays as result. By embedding the C array in a C struct this problem is avoided.

Example 227   
SYNTYPE Syn = integer
  CONSTANTS 0:10
ENDSYNTYPE;
NEWTYPE Arr ARRAY(Syn, real)
ENDNEWTYPE;
is translated to:

typedef SDL_Integer Syn;
typedef struct {
 SDL_Real A[11];
} Arr;
  
All the properties of an array in SDL are preserved in the CSDL and C code. The predefined operators Extract! and Modify! are implemented as component selection of the array in C in the same way as in SDL, so if AVar is a variable of type Arr, and Index is a valid index expression, then AVar(Index) in SDL is translated to AVar.A[Index] in C.

The predefined operator Make!, which is a constructor of an array value, is implemented by generating a Make function in C. This means that the expression "(. 0.22 .)" in SDL is translated to the C function call Make(0.22). The Make function will of course be given a name that makes it unique.

Syntypes

Syntypes may be defined for any sort that the CSDL Code Generator can handle, giving a new name for the sort and possibly a new default value for variables of the sort. Range conditions that restricts the allowed range of values are also allowed. The range conditions are check when the SDL system is simulated using the C Code Generator. No code to perform such checks are generated in CSDL.

The syntype is translated to a type equal to the parent type using typedef.

Example 228   
SYNTYPE Syn = integer
  CONSTANTS 0:10
ENDSYNTYPE;
SYNTYPE Syn2 = integer
  CONSTANTS <0, =2, >=10
ENDSYNTYPE;
SYNTYPE Arr1 = Arr
  DEFAULT (. 2.0 .);
ENDSYNTYPE;
/* Arr defined above */
is translated to:

typedef SDL_Integer Syn;
typedef SDL_Integer Syn2;
typedef Arr Arr1;
  

Default Values

Default values are supported for all sorts that the CSDL Code Generator can handle, both if a default value is given in a sort definition and if an initial value is given in a variable definition (DCL). There is one exception and that is the OWN variables. For a OWN variable the initialization will be part of the variable declaration:

STATIC typename variablename = expression;
which means that this form of initialization must be valid in C for the current type.

Variables with no default value will not be initialized automatically as it will be using the SDT simulation facility.

Operators and Literals

The CSDL Code Generator cannot generate code for operators only based on the information given in SDL. The user have to supply implementations of the operators directly expressed in C. This possibility will be discussed in detail in the subsequent section.

In sorts that are translated to enumeration types in C, literals are obviously handled by the CSDL Code Generator. In sorts that are not translated to enumeration types in C, literals are treated as operators without parameters and are handled exactly in the same way as user defined operators. Note that the CSDL Code Generator does not permit naming of literals using name class literals or character strings.

Axioms and Literal Mappings

Axioms and literal mapping are allowed by the CSDL Code Generator in sorts, but are completely ignored.

Implementation of User-Defined Operators

Including Implementations of Operators

The CSDL Code Generator offers a possibility to include implementations written in C of the operator and literal functions.

Note that the C functions are divided into a function heading (extern or static declaration) and a function body. An example of a function heading (extern declaration) is:

Example 229   
extern SDL_Integer Max 
  (SDL_Integer Para1,
   SDL_Integer Para2);
while the corresponding function body is:

SDL_Integer Max 
  (SDL_Integer Para1,
   SDL_Integer Para2)
{
 if (Para1 > Para2)
   return Para1;
 return Para2;
}
  
---------------------------------------------------------------------
Note:                                                                  
In all examples of this manual, prototypes as defined in ANSI-C, are   
used. If the actual compiler in use does not support prototypes, you   
have to transform the examples to the old C-style for functions.       
---------------------------------------------------------------------
The main reason for this division of functions into heading and body is the separate compilation scheme used in C. If, for example, an abstract data type is defined in a system and used in a process in the system, then there has to be a module interface file (a .h file) for the system containing the external interface (types, extern declarations of functions and so on). The interface file should then be included in the file generated for the process.

Even if separate compilation is not used, the division of functions into heading and body is useful. By having static declarations of the functions, the order in which functions must be defined is relaxed. If static declarations were not used, a function could only call the functions that are defined textually before the actual function.

To select the way the CSDL Code Generator should generate code for operators and literals, CSDL Code Generator directives are used. A CSDL Code Generator directive is an SDL comment with the first characters equal to #, followed by a sequence of letters identifying the directive. In this case the letters are ADT (for Abstract Data Type) and OP (for operator). An ADT directive and an OP directive should thus look like:

/*#ADT */ /*#OP */
The text is not case sensitive.

OP directives are recognized at two different positions in an abstract data type:

ADT directives are recognized immediately before the reserved word ENDNEWTYPE (or ENDSYNTYPE).

Example 230   
NEWTYPE Str STRUCT 
  a integer; 
  b Boolean;
  c real;
ADDING 
LITERALS 
  Lit1 /*#OP */,
  Lit2 /*#OP */;
OPERATORS
  Op1 :Str,integer -> Str; /*#OP */
  Op2 :Str,Boolean -> Str; /*#OP */
/*#ADT */
ENDNEWTYPE;
  
At each of the positions after a literal name or operator definition, you can specify how this literal or operator should be implemented. In the directive immediately before ENDNEWTYPE the default implementation technique can be given. When the CSDL Code Generator determines how to generate code for a literal or an operator, it first looks for an OP directive after the literal name or operator definition. If no such directive is found it looks for a directive immediately before ENDNEWTYPE. If no ADT directive is found here, the generation technique B (for body) is assumed. The B should be interpreted as:

B: The CSDL Code Generator will generate extern definitions (headings) in C for the SDL operator, while the user is supposed to include the C function bodies.
An OP or ADT directive specifying a generation technique should have the following structure:

/*#OP (B) */ /*#ADT (B) */
The code for the functions implementing the SDL operators should be placed in the #BODY section in the ADT directive, according to the following example.

Example 231   
/*#ADT (B)
#BODY
C code, representing bodies of functions
*/
  
The section name, i.e. #BODY, must be given on a line of its own and must have the # character in the first position of the line. Uppercase and lower case letters are as usual considered to be equal. If the section is empty, the section name can also be removed.

---------------------------------------------------------------------
Note:                                                                  
The CSDL Code Generator will not check the consistency between         
the specification of implementation techniques and the actual code     
included in the body section. This check is, together with checking    
the C code for syntactic and semantic errors, left to the C compiler.  
---------------------------------------------------------------------
Unfortunately it is not possible to have C comments within the code that is included in a #ADT directive, as SDL and C use the same symbols for start and end of comments. If a C comment is included, the SDT Analyzer will consider the end of the C comment as the end of the SDL comment. Instead a C macro called COMMENT can be used according to the examples below.

Example 232   
By introducing the macro:

#define COMMENT(p)
it is possible to use comments in the following form:

COMMENT(This is a comment)
COMMENT(These comments may not contain \
        commas and should have a backslash at\ 
       each line break)
COMMENT((By having double parenthesis, any 
         text can be entered into the comments))
  
The function headings representing literals and operators are to a large extent determined by their corresponding definition in SDL. The only thing that is not specified in SDL is the names of the formal parameters. The number of parameters, there types, the result type of the function and function name are all defined in SDL.

Example 233   
In Example 230 on page 2435, where the struct Str is defined, there are two literals (Lit1 and Lit2) and two operators (Op1: Str, integer -> Str; and Op2: Str, Boolean -> Str;). The function heading of the corresponding C functions should be:

extern Str Lit1 (void);
extern Str Lit2 (void);
extern Str Op1 
  (Str yParam1, SDL_Integer yParam2);
extern Str Op2 
  (Str yParam1, SDL_Boolean yParam2);
  
The CSDL Code Generator will, as can be seen in the example above, name the formal parameters yParam1, yParam2 and so on, when it generates a function heading for an operator.

The function bodies, which should be supplied by the user if B is specified in the OP or ADT directive, are ordinary C functions.

Example 234   
Str Lit1 (void)
{
 Str Temp;
 Temp.a = 2;
 Temp.b = false;
 Temp.c = 10.0;
 return Temp;
}
Str Op1 (Str yParam1, SDL_Integer yParam2)
{
 yParam1.a = yParam1.a + yParam2;
 return yParam1;
}
  

Two Examples of ADTs

We now give two complete examples of abstract data types.

Example 235   
NEWTYPE Str STRUCT
  a integer;
  b Boolean;
  c real;
  ADDING
    LITERALS
      Lit;
    OPERATORS
      Op1 : Str, integer -> Str;
      Op2 : Str, Boolean -> Str;
/*#ADT (B)
#BODY
Str Lit1 (void)
{
  return yMake_Str (2,false,10.0);
}
Str Op1 (Str yParam1, SDL_Integer yParam2)
{
  yParam1.a = yParam1.a + yParam2;
  return yParam1;
}
Str Op2  (Str yParam1, SDL_Boolean yParam2)
{
  if (yParam2)
    return yParam1;
  return Lit1();
}
*/
ENDNEWTYPE;
  
The only thing in this example which has not been discussed earlier is the use of the make function in the function for literal Lit1. Each struct in SDL has an implicit operator Make!, which is a constructor for struct values from the struct components. The CSDL Code Generator generates a function that corresponds to this operator with the name yMake_ followed by the sort name. The function has one parameter for each struct component and returns a value of the struct sort. The returned value is the struct value that is obtained when each component is assigned the value of the corresponding parameter. This make function is often very useful when literal functions in struct sorts are to be implemented.

Example 236   
SYNTYPE Index CONSTANTS 1:10
ENDSYNTYPE,
NEWTYPE A Array(Index, integer)
  ADDING
  LITERALS
    Zero /*#OP (B) */;
  OPERATORS
    Add : A, A -> A; /*#OP (B) */
/*#ADT()
#BODY
A Zero (void)
{
 return yMake_A (0);
}
A Add (A yParam1, A yParam2)
{
 Index I;
 A     Result;
 for (I = 1; I<=10; I++)
   Result.A[I] = yParam1.A[I] + yParam2.A[I];
 return Result;
}
*/
ENDNEWTYPE;
  

More about Abstract Data Types

More about Operators

Previously in "Implementation of User-Defined Operators" on page 2433, the possibility to include implementations of operators in abstract data types was described. Here we will first discuss some additional features concerning operators and then describe how to replace the generated type definition for an abstract data type with a user defined type definition.

For an operator in an abstract data type not only B (body) may be specified. The following choices are available:

For each operator one of the letters B, H, S and one of the letters P, I should be supplied, either in a #OP directive, or in a #ADT directive, or as the defaults B and P. For literals P and I have no meaning.

The purpose of S is straight forward and easy to understand, but H might require some explanation. H means that the CSDL Code Generator will not generate any code for the operator, which leaves you with a number of possibilities:

Example 237   
Example of usage of S (standard)

"+" : integer, real -> real; /*#OP (SI) */
sin : real -> real; /*#OP (SP) */
An SDL expression using these operators:

sin(a + 7.0) will be translated to: 
sin(a + 7.0)
  
These examples show how standard functions in the target language can be directly utilized in abstract data types.

Including Type Definitions

In the remaining part of this subsection the possibility to include a type definition in the target language for an abstract data type will be described. When you use this facility, you also have to specify how to perform assignment, test for equal, assign default values, and so on, as this is not possible to generate when the type definition is not known (not generated). All this information is given in the #ADT directive, which has the following structure:

/*#ADT 
(T(x) A(x) E(x) D(x) K(x) X(x) xy 'file name')
#TYPE
C code
#HEADING
C code
#BODY
C code
*/
where each x on the first line should be replaced by one of the characters B, H, S, or G. Replace y by P or I. The interpretation of these characters is similar to the their interpretation for operators.

-----------
B  Body      
H  Heading   
S  Standard  
G  Generate  
P  Prefix    
I  Infix     
-----------
The reason why G (generate) is not allowed for operators or literals is of course that it would mean to generate the implementation of the operators from the axioms, which is, at least in the general case, an impossible task.

The specifications, given in ADT directives, of how to generate code for type definition, assignment, test for equal, and default values should be interpreted according to the table below. More details about the functions can be found in "Help Functions" on page 2446.

Type Definition

First the actual type definition. The entry - should be interpreted as if no specification is given for T.

--------------------------------------------
Type  Interpretation                          
--------------------------------------------
T(G)  Generate type definition from SDL sort  
T(B)  Do not generate type definition         
T     Same as T(B)                            
-     Same As T(G)                            
--------------------------------------------

Assignment

How assignments will be performed for values of the type.

------------------------------------------------------------
Type  Interpretation                                          
------------------------------------------------------------
A(B)  Use the assign function yAss_SortName                   
      Generate heading but not body                           
A(H)  Use the assign function yAss_SortName
Generate no code for function A(G) · If the type definition is generated:
  • Use = if possible and generate no assign function.
  • Else generate heading and body of the assign function yAss_SortName · If type definition is not generated:
  • Use = and generate no assign function A(S) Use = and generate no assign function A Same as A(B) - Same as A(G) ------------------------------------------------------------
  • Equal test

    The method of testing for equality between two values of the type.

    ------------------------------------------------------------
    Type  Method                                                  
    ------------------------------------------------------------
    E(B)  Use the equal function yEq_SortName.                    
          Generate heading but not body.                          
    E(H)  Use the equal function yEq_SortName.                    
          Generate no code for function.                          
    E(G)  ·  If the type definition is generated:                 
          
  • Use == if possible and generate no equal function.
  • Else generate heading and body of the equal func tion yEq_SortName. · If the type definition is not generated
  • Use == and generate no equal function. E(S) Use == and generate no equal function. E Same as E(B) - Same as E(G) ------------------------------------------------------------
  • Initialization

    The default value that variables of the given type will be initialized to. This should be generated and used only if the SDL sort has a default value.

    -----------------------------------------------------------------
    Type  Interpretation                                               
    -----------------------------------------------------------------
    D(B)  Generate heading, but no body of default function            
          yDef_SortName.                                               
    D(H)  Generate neither heading nor body of default function.       
    D(G)  Generate both heading and body of default function, or use   
          macro if adequate.                                           
    D(S)  Same as D(G)                                                 
    D     Same as D(B)                                                 
    -     Same as D(G)                                                 
    -----------------------------------------------------------------
    

    Make!

    In the case of array or struct sorts there will be a make function to implement the constructor Make! defined in SDL.

    -------------------------------------------------------------
    Type  Interpretation                                           
    -------------------------------------------------------------
    K(B)  Generate heading, but no body of the make function       
          yMake_SortName.                                          
    K(H)  Generate neither heading nor body of the make function.  
    K(G)  Generate the make function                               
    K     Same as K(B)                                             
    -     Same as K(G)                                             
    -------------------------------------------------------------
    

    Extract! and Modify!

    This entry specifies how component selection (struct components and array components) should be performed. This feature is, for example, used when an SDL struct is implemented as a pointer to a struct in C.

    ----------------------------------------------------------------------
    Type              Interpretation                                        
    ----------------------------------------------------------------------
    X(B)              Use `->' instead of `.' as struct component selec  
                      tor.                                                  
    X (B, 'string')   Use parameter string as struct component selec        
                      tor. If array type, then insert string between vari   
                      able name and [.                                      
    X(G)              Use component selection according to SDL data         
                      type.                                                 
    X                 Same as X(B)                                          
    -                 Same as X(G)                                          
    ----------------------------------------------------------------------
    
    When generate is specified for a function, the C Code Generator might decide not to generate the heading of the function, as in some cases it is not needed. It might also decide to use a macro implementation instead of a function.

    All code that is not generated, is of course assumed to be included by the user in the #TYPE, #HEADING, and #BODY sections in the #ADT directive.

    You can use another name for an assign function, an equal function and so on, by including the desired name within quotes together with the generation options in the #ADT directive.

    If for example the name of a certain assign function should be AssX, this can be obtained by specifying: A(B `AssX') for the assign function. This name will then be used throughout the generated code, both in generated declaration and at the places where the function is called. Note that the name should be last in the specification for the function.

    You can have an include statement generated together with or replacing the type definition by giving a file name within quotes last in the specification part of the #ADT directive, immediately before the first section with code.

    Example 238   
    
    If the directive

    /*#ADT (T(B) A(S) E(S) 'file name') */ 
    
    is used, the following include statement will be generated:

    #include "file name"
      
    
    --------------------------------------------------------------------
    Note:                                                                 
    You have to turn off the generation of the objects contained in the   
    include file yourself.                                                
    --------------------------------------------------------------------
    
    This facility is introduced to facilitate separately defined and precompiled implementations of abstract data types. By using this include facility to include a .h file containing the type definition and the extern declarations of the appropriate functions and by using the #NAME directive to decide the name that should be used in the generated code, you can achieve this. You just have to link with the appropriate module.

    Help Functions

    An assign function has the following heading:

    void yAss_SortName (SortName *yVar, SortName yExpr)
    
    It should assign the value passed as second parameter to the variable passed as first parameter. The SDL predefined sorts Charstring, Time and Duration use assign functions xAss_SDL_Charstring, xAss_SDL_Time and xAss_SDL_Duration, while all the other predefined types use =. Sorts translated as enum types can always use =, while array and struct sorts can use = if all components can use =. A syntype in SDL uses = if its father type can use =, otherwise it uses the assign function of the father type.

    An equal function has the following heading:

    SDL_Boolean yEq_SortName 
      (SortName yExpr1, SortName yExpr2);
    
    It should return true or false depending on if the two values passed as parameters are equal or not. The SDL predefined sorts Charstring, Time, Duration and PId have equal functions:

    xEq_SDL_Charstring
    xEq_SDL_Time
    xEq_SDL_Duration
    xEq_SDL_PId
    
    while all the other predefined types can use ==. Sorts translated as enum types can always use ==, while array and struct sorts always have equal functions. A syntype in SDL uses == if its father type can use ==, otherwise it uses the equal function of the father type.

    All sorts defined in an SDL system that contains a default value, will have a default function which is used to initialize variables of the actual sort. A default function has the following heading:

    void yDef_SortName (SortName *yVar)
    
    It should assign the default value to the variable passed as parameter. The default function will in many cases be implemented using a macro.

    For each array and struct sort (not Syntypes) there will be a generated make function, which is used as constructor of array or struct values out of there respective components, according to the rules for the Make! operator in SDL.

    ArraySortName  yMake_ArraySortName
      ( ComponentSortName  yExpr )
    StructSortName yMake_StructSortName
      ( ComponentSortName1  yComponentName1;
        ComponentSortName2  yComponentName2 )
    
    The number of parameters in a struct make function is the same as the number of components in the struct.

    Directives to the CSDL Code Generator

    Syntax of Directives

    The CSDL Code Generator recognizes a number of directives given mainly in SDL comments. The #ADT and #OP used in abstract data types are examples of such directives. These directives were described in "Implementation of User-Defined Operators" on page 2433 in connection with abstract data types and are not further discussed here.

    A directive has the general structure:

    1. The start of comment characters: /*
    2. A # character.
    3. The directive name.
    4. Possible directive parameters given in free syntax, that is, spaces and carriage returns are allowed here.
    5. The end of comment characters */.
    Upper and lower case letters are considered to be equal in directive names.

    Example 239   
    
    Take as an example the directive:

     /*#OP (B) */
    
    This comment will be recognized as a directive only if no other character is inserted in the sequence /*#OP. After this part spaces and carriage returns may be inserted freely.

      
    
    There are two versions of all directives, one with the name presented in this manual and the other with the letters CSDL first in the directive name. It is possible, for example, to use either #ADT or #CSDLADT as name for the ADT directive. When just one translator, the CSDL Code Generator, is used it does not matter which version of the name that is used. However, if the same SDL system is used as input both to the CSDL Code Generator for generating an application, and to the C Code Generator for simulation, the #ADT directive will be seen by both code generators. As the C Code Generator also recognizes two versions of the directives, the directive name and the directive name preceded by C, it is possible to have two different ADT directives, using #CADT and #CSDLADT, and having each code generator to only see its own directive.

    Translation of SDL Names to CSDL

    A name in the SDL will be translated to the SDL name stripped from characters that are not allowed in C identifiers (everything except letters, digits, and underscore). It is completely up to the user to guarantee that no name conflict occurs and that the stripped name is allowed as a C identifier, that is, that it begins with a letter and is not a C or CSDL keyword.

    ----------------------------------------------------------------------
    Caution!                                                                
    Note especially that objects forming files, processes, procedures,      
    and states, must have distinct names. Otherwise one file will over      
    write another file! This means, for example, that all states names in   
    all processes have to be different. See also "File Names" on page       
    2389.                                                                   
    ----------------------------------------------------------------------
    
    To include code in the generated code from the C Code Generator, the directive #SDL sometimes have to be used (see "Accessing SDL Names in C Code - Directive #SDL" on page 2027 in chapter 34, The C Code Generator). To simplify the usage of the same code for C and for CSDL, in a common #ADTs for example, the CSDL Code Generator can also handle the #SDL directive. As this directive is only of interest when the CSDL Code Generator is used together with the C Code Generator, it is not further described here.

    Case Sensitivity

    Another aspect concerning identifiers is that SDL is case insensitive, while C is case sensitive. This might introduce problems. The following strategy for upper and lower case letters is used by the Analyzer and CSDL Code Generator. During lexical analysis each unique SDL name is stored in a name table. Only one occurrence of a name, according to the rules of SDL, will be stored in the table. This means that the first found occurrence of a name will govern how that SDL name will be seen, when it comes to upper and lower case letters. The CSDL Code Generator will use the names in the name table to generate CSDL and C names.

    This strategy normally works very well, as each occurrence of a CSDL or C name is generated in the same way. If you, however, are about to use the SDL name in included C code, in for example a #CODE directive, then you need to know how upper and lower case letters are used in the C name. This might be a problem if you have multiple occurrences of the name using different combinations of upper and lower case letters.

    As a solution for this and for other potential problems concerning upper and lower case letters in CSDL and C names, the CSDL Code Generator, as well as the C Code Generator, has an option to translate all SDL names to lower case. This option can be set in the Make dialog in the Organizer (see "Make" on page 1107).

    Another way of removing this problem is to specify the name for an SDL object that should be used in generated code. This is described in the next section.

    Specifying Names in Generated Code -
    Directive #NAME

    If you wish to decide the name of an object in generated code yourself you can use the #NAME directive. Place the directive directly after the name in the declaration of the object. It should contain the desired name to be used in the generated code within quotes.

    Example 240   
    NEWTYPE S /*#NAME 'S' */ STRUCT
      a integer;
      b Boolean;
      ADDING OPERATORS
        Op /*#NAME 'OtherName' */ :
          S, S -> Boolean;
    ENDNEWTYPE;
      
    
    The name defined in a #NAME directive will be used everywhere that the SDL name is used in the generated code, with one exception: The name of the files for generated code are not affected by the usage of #NAME directives.

    Including C Code in TASK -
    Directive #CODE

    You can include your own CSDL (or rather C) code in TASKs by using the #CODE directive. This directive has the following syntax:

    /*#CODE
    C code that should
    be included in
    generated code */
    
    Type the directive name on the first line and the C code on the following lines up to the end of comment symbol.

    A #CODE directive can be placed:

    The C code in the directives is textually included in the generated code at the position of the directive. If, for example, a code directive is placed between two assignment statements, the code in the directive is inserted between the translated version of the assignment statements.

    -----------------------------------------------------------------
    Note:                                                              
    The CSDL Code Generator handles the C code in directives as text   
    and performs no check that the code is valid C code.               
    -----------------------------------------------------------------
    
    The code directive is included as a facility in the CSDL Code Generator to provide experienced users an escape possibility to the target language C. This increases the application range of the CSDL Code Generator.

    Unfortunately it is not possible to have C comments within the code that is included in any directive, as SDL and C use the same symbols for start and end of comments. See also Example 232 on page 2436 which illustrates the possibility to use a C macro COMMENT.

    Including C Declarations -
    Directive #CODE

    The #CODE directive can also be used to include C declarations, for example types, variables, functions, #define, and #include in the declaration parts of the C program. This version of the code directive has the following structure:

    /*#CODE
    #TYPE
    C code containing:
    Types and variables
    #HEADING
    C code containing:
    Extern or static declarations of functions
    #BODY
    C code containing:
    Bodies of functions
    */
    
    The separation of functions into HEADING and BODY sections serves the same purpose as in the #ADT directive, see "Implementation of User-Defined Operators" on page 2433.

    Code directives to include C declarations may, generally speaking, be placed immediately after a semicolon that ends a declaration in SDL. More precisely it is allowed to place a #CODE directive after the semicolon that ends:

    In the following small PR example the allowed positions are marked with an * followed by a number.

    Example 241   
    system s; *1
      signal s1, s2(integer); *2
      channel c1 from env to b1 
        with s1, s2; *3
      newtype n
        ...
      endnewtype n; *4
      block b1; *5
        signalroute sr1 from env to p1 
          with s1, s2; *6
        connect c1 with sr1; *7
        process p1 (1,1); *8
          signalset s1, s2; *9
          dcl a n; *10
          start;
            ...
          state ...;
            ...
        endprocess p1; *11
      endblock b1; *12
    endsystem s1;
      
    
    A code directive is considered to belong to the unit where it is defined and the declarations within the directive are thus placed unitname_d.h or unitname_c.c for that unit. In the example above directives at positions 1, 2, 3, 4, 12 belong to system s, directives at positions 5,6,7,11 belong to block b1, while directives at positions 8, 9, 10 belong to process p1. Only one code directive may be placed at each available position.

    In the generated code the type sections are included in the order of appearance in SDL. However, the type sections are also sensitive for their relative position comparing with SDL sort definitions. This means that the order of the type definitions in the system in the example above will be as follows:

    1. Type sections in 1, 2, 3
    2. Type generated for newtype n
    3. Type sections in 4, 12.
    The heading sections are placed in the order of their appearance in SDL. This applies to the body sections as well. All body sections will be placed after the sequence of heading sections and the heading section will be placed after all the type definitions. The SDL declarations made in the corresponding unit are available in the code directives and can as usual be reached using the #SDL directive. All declarations made in code directives are of course available in code directives in tasks in the corresponding unit or in its subunits.

    Including C Code in SDL Expressions -
    Operator #CODE

    For each sort defined in an SDL system, both predefined and user defined, the CSDL Code Generator includes an operator #CODE with the following signature:

    #CODE : Charstring -> S;
    
    where S is replaced by the actual sort name. This operator or rather these operators make it possible to access variables and functions defined in C using the #CODE directive in SDL expressions and still have syntactically and semantically correct SDL expressions.

    During code generation, the C Code Generator will just copy the Charstring parameter at the place of the #CODE operator.

    Example 242   
    
    Suppose that x and y are SDL variables, that a and b are C variables, and f is a C function defined in #CODE directives.

    --------------------------------
    SDL expression      C expression  
    --------------------------------
    x + #CODE('a')      z72_x + a     
    x + #CODE('a*b')    z72_x + a*b   
    x*#CODE('(a+b)')*y  x*(a+b)*y     
    #CODE('f(a, x)')    f(a, x)       
    --------------------------------
    
      
    
    As there is one #CODE operator for each sort in the system, it is sometimes necessary to qualify the operator with a sort name to make it possible for the SDL Analyzer to resolve which operator that has been used. If, for example, the question and all answers in a decisions are given as applications of #CODE operators, then it is not possible to determine the type for the decision. One of the #CODE operators should then be qualified with a sort name to resolve the conflict.

    Example 243   
    DECISION #CODE('a');
        (#CODE('1')) : TASK ...;
        (#CODE('2')) : TASK ...;
    ENDDECISION; 
    
    In this case the sort of the decision cannot be resolved. To overcome this problem the question could be written as

    DECISION TYPE integer #CODE('a');
      
    

    Directives Specific to CSDL

    The following directives are discussed in this section:

    #OWN
    #GLOBAL
    #PROCPAR
    #TIMERTYPE
    #TRANSFER
    #SIGFIELD
    #CATEGORY
    

    #OWN and #GLOBAL Directives

    The #OWN and #GLOBAL directives are used to indicate the translation rule that should be used for process variables. Please see also "Private Variables" on page 2395.

    The variables defined in an SDL process (using DCL) are mapped to the three variable types own variables, global variables, and private variables using directives according to the example below.

    Example 244   
    DCL
      i1, i2  Integer,
      J       Boolean,    /*#GLOBAL*/
      k       Character,  /*#OWN 'state1'*/
      L       Integer;    /*#OWN 'start'*/
    
    The first two variables, i1 and i2, are private variables, the third variable, J, is a GLOBAL variable, while k and L are OWN variables; k to the state unit for state state1 and L for the start up unit.

      
    
    Note that the #OWN variable takes a parameter which either should be start or the name of a state. If a user wants to indicate private variables by a directive

     /*#PRIVATE */
    
    that is OK, as this will be seen just as a comment by the CSDL Code Generator.

    #PROCPAR Directive

    This directive is used to give the appropriate parameters to the CSDL functions used to implement Create and Stop. These extra parameters are specific to CSDL and has no counterpart in SDL. That is why the information is placed in a directive.

    The example below shows the structure of the directive and how to place it in SDL. The directive should be last in the create or stop action, just before or after the semi-colon. In SDL-GR the directives are best placed in a text-extension box attached to the create or stop symbol. It can also be placed last in a create symbol.

    Example 245   
    
    The following actions in SDL

    create P2; /*#PROCPAR (x,y,z)*/
    create P2  /*#PROCPAR (a,b,c)*/;
    stop  /*#PROCPAR (1,1,1)*/;
    
    are translated to:

    TASK 'Create of process P2';
    {
      SDL_CREATE (x,y,z);
    }
    TASK 'Create of process P2';
    {
      SDL_CREATE (a,b,c);
    }
    TASK 'Stop';
    {
      SDL_KILL (1,1,1);
    }
    
    Note that the parameters in the #PROCPAR directive have just been copied to the generated CSDL code.

      
    

    #TIMERTYPE Directive

    This directive can be used to indicate that the timer should be of another kind than the default SDLTIMER. The directive should be placed last in the Set statement, just before or just following the semi-colon. In GR this means last in the symbol or in an attached text-extension.

    Example 246   
    
    The following Set statements

    set (now+Sec*Ival, Timer_ex);
    set (now+Sec*Ival, Timer_ex);
        /*#TIMERTYPE 'SDLTIMER_REP'*/
    set (now+Sec*Ival, Timer_ex)
        /*#TIMERTYPE 'SDLTIMER_REP_UNEVEN'
          'REP'*/;
    
    are translated to the following CSDL code:

    START_TIMER SDLTIMER UNITS Ival BASE Sec
      SIGNAL Timer_ex KEY TIMER_EX_TO_KEY;
    START_TIMER SDLTIMER_REP UNITS Ival BASE Sec
      SIGNAL Timer_ex KEY TIMER_EX_TO_KEY;
    START_TIMER SDLTIMER_REP_UNEVEN UNITS Ival BASE Sec
      SIGNAL Timer_ex DATA REP KEY TIMER_EX_TO_KEY;
      
    
    The directive parameters are introduced into the START_TIMER statement as timer type and DATA component.

    Note that it is possible to simulate, using the SDT simulation facility, only the SDLTIMER timer type.

    #TRANSFER Directive

    The #TRANSFER directive is used in output statements to indicate that the CSDL keyword TRANSFER should be part of the CSDL OUTPUT statement. The directive should be placed last in the output statement in SDL, just before or after the ending semicolon. In GR that means last in the output symbol or in an attached text extension symbol.

    Example 247   
    
    The following output statements:

    output Sig2 to DEST(Sender, 1, 1);
    output Sig to DEST(Sender, 1, 1)
       /*#TRANSFER*/;
    output Sig to DEST(Sender, 1, 1);
       /*#TRANSFER*/
    
    will be translated to:

    OUTPUT Sig TO DEST(1, 1);
    OUTPUT Sig TO DEST(1, 1) TRANSFER;
    OUTPUT Sig TO DEST(1, 1) TRANSFER;
      
    
    If the signal contains parameters it is possible to specify in SDL that the parameters should not be copied to process variables by not having any variables in the INPUT statement. An example of an input statement of a signal with four parameters, where no parameter should be received is given below.

    INPUT Sig( , , , );
    
    This is useful in connection with TRANSFER, not to unnecessarily copy the signal parameters.

    #SIGFIELD Directive

    The #SIGFIELD directive is used to specify names for signal parameters. In SDL only the types are specified, so the CSDL Code Generator will invent names for the parameters. The names will be Param1, Param2, and so on. By using the #SIGFIELD directive the user can override this default naming.

    Example 248   
    
    The SDL signal definition below:

    signal
      Sig1(integer,
           integer /*#SIGFIELD 'f2'*/,
           integer),
    
    will be translated to the following declaration in the signal library:

    SIGNAL Sig1 CODE SIG1_CODE
        {
        SDL_Integer  Param1;
        SDL_Integer  f2;
        SDL_Integer  Param3;
        };
      
    

    #CATEGORY Directive

    The #CATEGORY directive is used in INPUT and SAVE statements to specify the CATEGORY that should be used in CSDL.

    The directive in inserted directly after the signal name in the input or save statement (or after the comma or semi-colon), see the example below. The CSDL Code Generator will use the directive parameters as CATEGORY in the generated INSIGNAL clause. The code generator will not check if the CATEGORY name are valid but will just copy them to the generated file.

    Example 249   
    
    The SDL code below

    state State1;
      input Sig2 /*#CATEGORY 'CAT_1'*/,
            Sig3 /*#CATEGORY 'CAT_2'*/;
        nextstate State1;
      input Sig5,
            Sig6; /*#CATEGORY 'CAT_2'*/
        nextstate State1;
      save Sig4 /*#CATEGORY 'CAT_1'*/;
    
    might generate the following CSDL code in the INSIGNAL clause, depending on where signals are defined.

    INSIGNAL
      Process1_CAT FROM Block1_s.csm : Sig5;
      CAT_2 FROM Block1_s.csm : Sig6 (State1, Sig5);
      CAT_1 FROM System1_s.csm : Sig2, Sig4;
      CAT_2 FROM System1_s.csm : Sig3 (State1, Sig2);
      
    

    Restrictions

    The CSDL Code Generator handles the majority of concepts according to the definition of CSDL. There are a number of restrictions in the SDL concepts that can be used. These restrictions are discussed in this section.

    The restrictions in the SDT Analyzer, which of course also affect the CSDL Code Generator, are summarized below. For more information see chapter 31, The Analyzer.

    The CSDL Code Generator introduces more severe restrictions on the allowed set of SDL concepts than the Analyzer.

    Only the SDL-88 subset of SDL-92 are supported with the following general restrictions:

    Restrictions concerning abstract data type:

    References

    [3]
    CSDL - Language Reference Manual for OLC by Italtel
    [4]
    SDL/PR-88 to CSDL Specification Table Version 1.0
    by L. De Domenico, Italtel

    Contents of .d and .str Files

    Example 250   
    
    Assume that we have an SDL system with the following structure:

    system sys
      block B1
        process P1
          procedure Proc1
          procedure Proc2
          state State1
        process P2
          state State2
          state State3
          state State4
    
    that is, a system called sys with one block (B1) that contains two processes (P1 and P2). P1 contains two procedures (Proc1 and Proc2) and one state (State1), while P2 contains three states (State2, State3, and State4).

    For this example the following .d file might be generated:

    C1=sys_c.c
    C2=P1_c.c
    CSP1=P1.csp,State1.csp,Proc1.csp,Proc2.csp
    CSP2=P2.csp,State2.csp,State3.csp,State4.csp
      
    
    The .d file will contain all the generated .c and .csp files for the system. Each line in the file will begin with either CX or CSPX, where X is an unique number within each group (C - CSP).

    The number is followed by a = sign and a list of files separated by commas. No spaces or carriage returns are present within the file list. A list will never contain more than 20 file names. In such case a new list is started, with a new unique number.

    Each line will contain the list of all files (.c or .csp) generated for one SDL unit (system, block, substructure, or process). C files might be generated for any SDL unit, while CSP files are only generated for processes (process, procedure, and state).

    The .str file for the system above might look like:

    SYSTEM:sys: sys_d.h, sys_c.c, sys_s.csm
    BLOCK:B1: B1_d.h, B1_s.csm
    PROCESS:P1: P1_d.h, P1.csp, State1.csp, P1_c.c, 
    P1_s.csm
    PROCEDURE:P1: Proc1.csp, Proc2.csp
    PROCESS:P2: P2_d.h, P2.csp, State2.csp, State3.csp, 
    State4.csp
    
    The file will contain references to all generated files, and will be structured in such a way that the files generated for a certain SDL unit are listed after the name of the unit. Note that all procedures for a process are listed on the same line and that it is the process name that is given after the word PROCEDURE.

    This page intentionally left blank

     
    Table of Contents Next Chapter