The CHILL code generated from an SDL system, may be viewed as a CHILL module interfaced to via signals. This makes it easy to plug in an SDL system as an application program part anywhere in your CHILL software structure. Consistent interfacing of the SDL system will be ensured by the separate compilation scheme of CHIPSY.
The application area for sdl2chill is development and maintenance of real-time application systems. By using sdl2chill, the CHILL program generated for your system will be efficient, reliable, easily readable and open for interfacing and interoperability with other software.
The CHILL program generated from your SDL specified system by using sdl2chill, will be efficient, reliable, easily readable and open for interfacing and interoperability with other software.
In this part of the manual, the usage of sdl2chill for generating application systems is described. When it comes to detailed information on the functionality and usage of the CHIPSY tools and the SDT tools to be used together with sdl2chill, this is described in the CHIPSY Reference Manual and the SDT 3.01 Reference Manual, respectively.
Concurrent real-time execution, communication and timing as implemented by sdl2chill, are directly based on services provided by CRS, the CHIPSY Real-time Operating System. Other features of CRS such as interrupt handling, Input/Output, distributed processing and program execution control, provide additional services you need in order to implement the operational environment to which the SDL system must be interfaced in order to realize its intended purpose.
Testing and debugging are facilitated by means of conventional debuggers or by using the CHIPSY's Pilot. The Pilot is an advanced real-time test and debugging tool that is part of CHIPSY.
CHIPSY is now available on a variety of host and target platforms including Sun SPARC, 386/486 PC with SCO UNIX, and VAX/VMS.
As indicated above, sdl2chill contains two components:
Figure 561 : The Production of an CHILL Executable Program. ----- (fig) -----
-------------------------------------------------------------------- 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 Extensions UNIX ------------------------------------------------------------------ .chill Compilation unit in CHILL source text form .cdbf Compilation unit in CHIPSY Data Base Format .o Object file .exe Executable program .m Makefile ------------------------------------------------------------------The .chill, .cdbf and .o files are created for the system, and are also created for blocks and processes, depending on the separate generation scheme decided by the user. The .m and the .exe files are only created for the system. The file names will be the name of the units (system, block, or process) with the appropriate extension. For more information on generated files and file names see the section "Selecting File Structure for Generated Code - Directive #SEPARATE" on page 2349.
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: #1The translator cannot yet handle this SDL feature. See the list of restrictions and implementation dependencies in the section "Implementation Dependencies" on page 2377.
Cannot open outfileA .chill, or .m file cannot be opened.
WARNING! Unique name generation failed.The scope structure is too deep.
#1 must be a unique name.#1 is replaced by the name of an SDL unit. During code generation sdl2chill prefixes SDL name strings to make them unique. The prefixing algorithm and the limit for the length of the prefix, might make it impossible to generate a prefix, in which case this warning is issued. It is still possible to execute the generated program if the name, without prefix, is unique.
Node = nil in #1 Incorrect node type in #1. Nodetype: #2 Internal error in the PathStructure Line exceeded MaxLineLengthThese four last errors are internal errors in sdl2chill. We would be pleased if you will report such errors to us.
The translation from SDL to CHILL is based on a direct mapping scheme. The basic concepts of SDL such as system structure, communication, behavior, actions and data are directly mapped to matching CHILL constructs of program structuring, concurrent processing, communication, actions and data.
In the first parts of this section we describe the SDL to CHILL mapping as implemented by sdl2chill. The implementation is explained in terms of CHILL and CHIPSY and a good knowledge of both is required in order to understand the mapping details. As rationale and discussion of mapping alternatives are not needed in order to use sdl2chill, this is described in a separate technical document. CHILL source code is easy to read, and as a supplement to reading this section you are recommended to study the generated code for your own system(s).
The last part of this section describes how sdl2chill implements operators and literals in abstract data types. In the general case it is not considered feasible to derive the implementation of operators (and literals) from the axioms. sdl2chill therefore provides support for implementing the operators by user-written CHILL procedures. sdl2chill also offers a simple escape mechanism for types by means of which is it possible for the sdl2chill user to utilize CHILL modes and properties of modes otherwise not accessible from SDL.
Numerous examples are used in this section to illustrate the run-time model and the SDL to CHILL mapping implemented by sdl2chill. In the examples, the prefixes, which can be added to names when they are translated to CHILL, are normally not shown. The prefixes are used to make sure that no name conflicts occur in the generated program. For more information about prefixes see "Names and Prefixes in Generated Code" on page 2357.
The CHILL code generated for a system may be partitioned to several compilation units. How this is facilitated is described in "Selecting File Structure for Generated Code - Directive #SEPARATE" on page 2349.
For the CHILL code to be CHIPSY compilable, sdl2chill also generates a context directive including the SDL Services of CRS.
Example 152 SYSTEM My_System;maps to:
...
ENDSYSTEM;
<> ENVIRONMENT
('(CRS)/_SDL/SDL_support'...)
);
...
My_System:
MODULE
GRANT ALL;
SEIZE ALL;
...
END
My_System;
Example 153 BLOCK My_Block:maps to:
...
ENDBLOCK;
...
Creating the initial number of SDL process instances, if any, maps to a sequence of CHILL start actions executed by the CHILL imaginary outer process. The default value for initial number of processes is 1.
SELF maps to THIS. PARENT maps to an additional (implicit) formal parameter of PId sort for each process definition. OFFSPRING and SENDER map to process local CHILL locations to which values are assigned by in-line CHILL assignment actions.
------------------------------------------------------------------- Note: sdl2chill does not support formal parameters for initially created processes and it is not checked that the number of simultaneous in stances of an SDL process is within the allowed maximum number, if specified. -------------------------------------------------------------------
Example 154 PROCESS my_process (2, );maps to:
...
ENDPROCESS;
my_process: PROCESS(parent INSTANCE);
...
DCL
offspring INSTANCE := NULL
,sender INSTANCE := NULL
;
...
END my_process;
...
DO FOR i := 1 TO 2;
START my_process(NULL);
OD;
Parameter passing for SDL in-parameters map on CHILL "pass by value" IN parameters, while SDL in/out-parameters are implemented by means of bound reference mode formal parameters and in-line CHILL code for referencing (at point of call) and de-referencing (for each applied occurrence of the formal parameter).
-------------------------------------------------------------------- Note: sdl2chill does not support calling an SDL procedure with an empty ac tual parameter. --------------------------------------------------------------------
Example 155 PROCEDURE My_Procedure;maps to:
FPAR IN line_p PID, IN/OUT no Integer;
...
ENDPROCEDURE My_Procedure;
...
My_Procedure:
PROC(line_p INSTANCE, no REF INT);
...
END My_Procedure;
Example 156 SIGNALmaps to:
My_signal_1(INTEGER, PID)
,My_signal_2;
SIGNALThis mapping enables the CHILL inherent process communication and concurrency to be fully exploited by sdl2chill. The interface between the SDL system and its environment is mapped to a set of CHILL signals and connecting the generated program to other CHILL thus code becomes very easy.
My_Signal_1 = (INT, INSTANCE)
,My_Signal_2;
Example 157 DCLmaps to:
Line_Number INTEGER := 99
,Line_P PID;
DCL
Line_Number INT := 99
,Line_P INSTANCE := NULL;
Example 158 START;maps to:
task my_i := 0;
NEXTSTATE s2;
STATE s1;
...
STATE s2;
...
NEXTSTATE s1;
...
...
NEWMODE
states = SET(start_state, s1, s2);
DCL
state states := start_state;
DO WHILE TRUE;
CASE state OF
(start_state):
my_i := 0;
state := s2;
GOTO SDL_next_state;
(s1):
...
(s2):
...
state := s1;
ESAC;
SDL_next_state: ;
...
OD;
The values transported by CHILL signals are received in locations defined by the CHILL signal receive alternative. Copying the received values from the implicit signal reception locations required by CHILL to the variables associated with the input maps on assignment.
The location to which the SDL expression SENDER is mapped, is directly updated by the receive case action.
Example 159 SIGNALmaps to:
My_Signal_1(INTEGER)
,My_Signal_2;
...
DCL sum INTEGER;
...
STATE s1;
INPUT My_Signal_1(sum);
...
INPUT My_Signal_2;
...
NEXTSTATE s2;
...
. ..
SIGNAL
My_Signal_1 = (INT)
,My_Signal_2;
...
DCL sum INT;
...
CASE state OF
(s1):
RECEIVE CASE SET sender;
(My_Signal_1 IN My_signal_1_p1):
sum := My_signal_1_p1;
...
(My_Signal_2):
...
state := s2;
ESAC;
...
ESAC;
In the simplest case, sdl2chill maps the implicit transitions of a state to one empty signal receive alternative receiving the anonymous CHILL signal, else(5). If "save", however, is specified for any signal in a state the CHILL "else signal "cannot be used and explicit empty signal receive alternatives for the signals to be consumed must be generated instead. As shown in the following example, this is fully catered for by sdl2chill.
Example 160 process P1 (1, 1);maps to:
signalset s1, s2, s3, s4;
start;
nextstate n1;
state n1;
input s1;
nextstate n2;
save s2;
state n2;
input s1;
stop;
input s2;
stop;
save*;
state n3;
input s4;
nextstate n1;
endprocess;
P: PROCESS(parent INSTANCE);
NEWMODE
states = SET(start_state, n1, n2, n3);
DCL
offspring INSTANCE := NULL
,sender INSTANCE := NULL
,state states := start_state
;
DO WHILE TRUE;
CASE state OF
(start_state):
state := n1;
GOTO SDL_next_state;
(n1):
RECEIVE CASE SET sender;
(s1):
state := n2;
GOTO SDL_next_state;
(s3):
GOTO SDL_next_state;
/* Implicit transition */
(s4):
GOTO SDL_next_state;
/* Implicit transition */
ESAC;
(n2):
RECEIVE CASE SET sender;
(s1):
STOP;
(s2):
STOP;
ESAC;
(n3):
RECEIVE CASE SET sender;
(s4):
state := n1;
GOTO SDL_next_state;
(else):
GOTO SDL_next_state;
ESAC;
ESAC;
SDL_next_state: ;
OD;
END P
--------------------------------------------------------------------- Note: sdl2chill requires that the actual parameters fully match all formal parameters, i.e. undefined parameters are not supported. Dynamic check to verify that the number of process instances creat ed is within the allowed maximum number, if specified, is not sup ported by sdl2chill. (If, however, all available memory has been used and no more processes can be created then this will of course be detected and reported by CRS.) ---------------------------------------------------------------------If the process definitions of the creating process and the process to be created are mapped to different (separate) CHILL compilation units then an auxiliary proc location is introduced by sdl2chill (if necessary). This is done in order to avoid cycles in the compilation graph. The details are shown in the example below.
Example 161 -- no modularization of the generated CHILLmaps to:
PROCESS My_Process_2 (0, );
FPAR line_p PID, subscriber_no INTEGER;
...
ENDPROCESS My_Process_2;
...
CREATE My_Process_2(P, I);
maps to:
...
offspring := START My_Process_2(P, I, THIS); Example 162 -- full modularization of the generated CHILL
PROCESS My_Process_2 (0, ); /*#PRIO 1024,* */
FPAR line_p PID, subscriber_no INTEGER;
...
ENDPROCESS My_Process_2;
...
CREATE My_Process_2(P, I);
/* Compilation unit of the enclosing block */
NEWMODE par_My_Process_2 =
PROC(INSTANCE, INT, INSTANCE) (INSTANCE);
DCL var_My_Process_2 par_My_Process_2;
/* Compilation unit of process definition */
proc_My_Process_2:
PROC(line_p INSTANCE
,subscriber_no INT
,parent INSTANCE
)(INSTANCE)
RETURN START My_Process_2
(line_p
,subscriber_no
,parent
,1024
,*
);
END;
var_My_Process_2 = proc_My_Process_2;
/* Compilation unit issuing create */
offspring := CALL var_My_Process_2(P,I,THIS);
In the generated CHILL procedure call the actual parameters that matches SDL in/out-parameters are preceded by the referencing operator ->.
------------------------------------------------------------------------- Note: Output without to or output with undefined actual parameters are not supported by sdl2chill. To denote the PId value of initially created processes, the translation directive #PIDLIT has been defined. By means of this directive, any specification relying on output without to may easily be adjusted to output with to, see "Identifying Initially Created Process Instances - Directive #PIDLIT" on page 2364. If, in spite of this, you decide to use output without to, you will find that it maps to CHILL open send signal. As shown in the example below no error message is given, but the comment /* TO ? */ is gen erated in the code to inform you that the CHILL open signal send, in the general case, may not properly implement the semantics of SDL output without to. In this case the generated program therefore may, or may not execute correctly. -------------------------------------------------------------------------
Example 163 SIGNALmaps to:
My_Signal_1(INTEGER,PID)
,My_Signal_2;
...
OUTPUT My_Signal_1(0,OFFSPRING) TO line_p;
OUTPUT My_Signal_2 TO some_p;
OUTPUT My_Signal_2;
SIGNAL
My_Signal_1 = (INT,INSTANCE)
,My_Signal_2;
...
SEND My_Signal_1(0,offspring) TO line_p;
SEND My_Signal_2 TO some_p;
SEND My_Signal_2 /* TO ? */;
Example 164 DECISION My_Integer - 1;maps to:
(2): ...
(4): ...
(6): ...
ENDDECISION;
DCL yDcn_INT INT;
...
yDcn_INT := My_Integer - 1;
IF yDcn_INT = 2
THEN
...
ELSIF yDcn_INT = 4
THEN
...
ELSIF yDcn_INT = 6
THEN
...
ELSE
CAUSE SDL_decision_error;
FI;
The mapping details are shown by Example 165 below.
--------------------------------------------------------------------- Note: sdl2chill restricts the timer definitions and the set and reset state ments to timers for which no (sort) parameters are specified. sdl2chill measures the SDL system time by means of the CRS stop watch, the unit of which is execution platform and system clock de pendent(a). The precision used when computing if the system time associated with a timer has been reached, is a configurable, execution platform dependent parameter of CRS.(b) See also the CHIPSY Reference Manual for more information on implementation details and the CRS tuning options. ---------------------------------------------------------------------
Example 165 TIMER T1, T2;maps to:
...
SET (expiration_time, T1);
SET (NOW + 5, T2);
RESET T1;
TASK b := NOT ACTIVE(T2);
SIGNAL T1, T2;
...
SDL_Set_Timer(expiration_time, ->T1);
SDL_Set_Timer
(SDL_Time_Add
(SDL_NOW()
,SDL_Duration_Lit(5,0)
)
,->T2
);
SDL_Reset_Timer(->T1);
b := NOT SDL_Active(->T2);
A synonym that maps to a location cannot be used in a range condition of a syntype because SDL range conditions are mapped to CHILL range modes and boundary values of CHILL range modes cannot be locations.
To give value to an external SDL synonym by means of CHILL written definitions, perform the following steps:
Example 166 MY_FILE:If you use this structure you can change the value of an external synonym merely by changing the corresponding CHILL data statements and recompiling the system.
MODULE
SYN synonym1 INT = 255;
DCL synonym2 BOOL := FALSE;
GRANT synonym1, synonym2;
END
MY_FILE; Example 167 System S; /*#ENVIRONMENT 'MY_FILE' 'file1' 'file2'*/
We then discuss how user-defined abstract data types are translated, see "Translation of Sorts" on page 2333.
Next the possibility to include CHILL written procedures as implementation of the operators in abstract data types is presented, see "User Defined Operators" on page 2339.
Last, in "More about Abstract Data Types" on page 2344, we discuss more details about operators and the possibilities to include a CHILL written mode definition to represent an SDL sort.
-------------------------------------------------------------- SDL name/operator CHILL name/expression/operator -------------------------------------------------------------- Boolean BOOL False, True FALSE, TRUE not NOT =, /= =, /= and AND or OR xor XOR => <= Character CHAR NUL SDL_NUL SOH SDL_SOH ... ... (for all unprintable characters) 'a' 'a' 'b' 'b' ... ... (for all printable characters except ') '''' '''' =, /= =, /= <, <=, >, >= <, <=, >, >= Charstring SDL_Charstring 'aa' [2,'aa'//(SDL_Charstring_max_le ngth-2)' '] = = /= /= MkString SDL_Charstring_MkString Length SDL_Charstring_Length First SDL_Charstring_First Last SDL_Charstring_Last // SDL_Charstring_Concat SubString SDL_Charstring_SubString Extract! SDL_Charstring_Extract Modify! SDL_Charstring_Modify Integer INT 0, 1, 2,... same as in SDL +, - +, - * * / / =, /= =, /= <, <=, >, >= <, <=, >, >= Float SDL_Float Fix SDL_Fix Natural SDL_Natural Real SDL_Real 0.0,... SDL_Real_Lit(0, 0) - (monadic) SDL_Real_Neg + SDL_Real_Add - (dyadic) SDL_Real_Sub * SDL_Real_Mul / SDL_Real_Div =, /= =, /= < SDL_Real_Lss <= SDL_Real_Leq > SDL_Real_Gtr >= SDL_Real_Gte PId INSTANCE NULL NULL =, /= =, /= Duration SDL_Duration 23.45 SDL_Duration_Lit(23, 450000000) + SDL_Duration_Add - (monadic) SDL_Duration_Neg - (dyadic) SDL_Duration_Sub * SDL_Duration_Mul / SDL_Duration_Div =, /= =, /= > SDL_Duration_Gtr Time SDL_Time 23.45 SDL_Time_Lit(23, 450000000) + SDL_Time_Add - (result: Time) SDL_Time_Sub - (result: Duration) SDL_Time_Diff =, /= =, /= < SDL_Time_Lss <= SDL_Time_Leq > SDL_Time_Gtr >= SDL_Time_Gte --------------------------------------------------------------
We will here briefly describe the modes, synonyms and procedures of the SDL Services used by sdl2chill to implement the SDL predefined types and the associated operators.
The listing below is extracted from source code of the library.
/* CHIPSY Copyright (c) 1992 Kvatro A/S
! -------------------------------------------
! IDENTIFICATION
! CRS:SDL Support:sdl_support.chill
!
! ABSTRACT
! This module implements the SDL Services ! of CRS. ...
! -------------------------------------------
*/
<>ENVIRONMENT
...
SDL_support:
MODULE
...
-- (Z.100 chapter 2.8, 5.5.4.1 and 5.6.4.5) SYNMODE
SDL_Timer_Id = PTR
;
SDL_Set_Timer:
PROC(time SDL_Time
,timer SDL_Timer_Id
)
GENERAL;
-- Implements SDL timer Set (by means -- of the Signal Timing Services
-- provided by CRS).
--
-- If the specified time value is 0 or
-- negative the timer signal will
-- be sent immediately.If active in
-- this case is applied to the timer
-- in the same transition as the timer
-- is set, the result of active is
-- undefined.
SDL_Reset_Timer:
PROC(timer SDL_Timer_Id
)
GENERAL;
-- Implements SDL timer Reset.
SDL_Now:
PROC() RETURNS(SDL_Time)
GENERAL;
-- Implements the SDL imperative
-- operator NOW by means of the CRS
-- system stopwatch.
--
-- At program start-up the system time,
-- SDL NOW, is equal to zero.
SDL_Active_Timer:
PROC(timer SDL_Timer_Id
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL Active timer
-- expression.
-- (Z.100 chapter 5.6.2) SYN
SDL_NUL CHAR = C'00'
,SDL_SOH CHAR = C'01'
,SDL_STX CHAR = C'02'
,SDL_ETX CHAR = C'03'
,SDL_EOT CHAR = C'04'
,SDL_ENQ CHAR = C'05'
,SDL_ACK CHAR = C'06'
,SDL_BEL CHAR = C'07'
,SDL_BS CHAR = C'08'
,SDL_HT CHAR = C'09'
,SDL_LF CHAR = C'0A'
,SDL_VT CHAR = C'0B'
,SDL_FF CHAR = C'0C'
,SDL_CR CHAR = C'0D'
,SDL_SO CHAR = C'0E'
,SDL_SI CHAR = C'0F'
,SDL_DLE CHAR = C'10'
,SDL_DC1 CHAR = C'11'
,SDL_DC2 CHAR = C'12'
,SDL_DC3 CHAR = C'13'
,SDL_DC4 CHAR = C'14'
,SDL_NAK CHAR = C'15'
,SDL_SYN CHAR = C'16'
,SDL_ETB CHAR = C'17'
,SDL_CAN CHAR = C'18'
,SDL_EM CHAR = C'19'
,SDL_SUB CHAR = C'1A'
,SDL_ESC CHAR = C'1B'
,SDL_IS4 CHAR = C'1C'
,SDL_IS3 CHAR = C'1D'
,SDL_IS2 CHAR = C'1E'
,SDL_IS1 CHAR = C'1F'
,SDL_DEL CHAR = C'7F'
;
-- (Z.100 chapter 5.6.4) SYN
SDL_Charstring_max_length INT = 100
;
NEWMODE
SDL_Charstring = STRUCT
(length INT(0:SDL_Charstring_max_length)
,string CHAR(SDL_Charstring_max_length)
)
;
SDL_Charstring_MkString:
PROC(c CHAR
) RETURNS(SDL_Charstring)
GENERAL;
-- Implements the SDL operator:
-- MkString: Char -> Charstring;
SDL_Charstring_Length:
PROC(cs SDL_Charstring
) RETURNS(INT)
GENERAL;
-- Implements the SDL operator:
-- Length: Charstring -> Integer;
SDL_Charstring_First:
PROC(cs SDL_Charstring
) RETURNS(CHAR)
GENERAL;
-- Implements the SDL operator:
-- First: Charstring -> Char;
SDL_Charstring_Last:
PROC(cs SDL_Charstring
) RETURNS(CHAR)
GENERAL;
-- Implements the SDL operator:
-- Last: Charstring -> Char;
SDL_Charstring_Concat:
PROC(cs1 SDL_Charstring
,cs2 SDL_Charstring)
) RETURNS(SDL_Charstring)
GENERAL;
-- Implements the SDL operator:
-- //: Charstring, Charstring
-- -> Charstring;
SDL_Charstring_Extract:
PROC(cs SDL_Charstring
,index INT
) RETURNS(CHAR)
GENERAL;
-- Implements the SDL operator:
-- Extract!: Charstring, Integer
-- -> Char;
SDL_Charstring_Modify:
PROC(cs SDL_Charstring
,index INT
,c CHAR
) RETURNS(SDL_Charstring)
GENERAL;
-- Implements the SDL operator:
-- Modify!: Charstring, Integer, Char
-- -> Charstring;
SDL_Charstring_SubString:
PROC(cs SDL_Charstring
,index INT
,length INT
) RETURNS(SDL_Charstring)
GENERAL;
-- Implements the SDL operator:
-- SubString: Charstring, Integer,
-- Integer -> Charstring;
-- (Z.100 chapter 5.6.6) SYN
SDL_max_int INT = 32_767
;
SYNMODE
SDL_Natural = INT(0 : SDL_max_int)
;
-- (Z.100 chapter 5.6.7) SYNMODE
SDL_Real = STRUCT
(ld LONGDURATION
)
;
SDL_Float:
PROC(i INT
) RETURNS(SDL_Real)
GENERAL;
-- Implements the SDL operator:
-- Float: Integer -> Real;
SDL_Fix:
PROC(r SDL_Real
) RETURNS(INT)
GENERAL;
-- Implements the SDL operator:
-- Fix: Real -> Integer;
SDL_Real_Lit:
PROC(i LONGINT
,f LONGINT
) RETURNS(SDL_Real)
GENERAL;
-- Maps Real literal to SDL_Real mode
-- 'i' denotes the integer part.
-- 'f' denotes the fractional part
-- multiplied by 10**9.
SDL_Real_Neg:
PROC(r SDL_Real
) RETURNS(SDL_Real)
GENERAL;
-- Implements the SDL operator:
-- -: Real -> Real;
SDL_Real_Add:
PROC(l SDL_Real
,r SDL_Real
) RETURNS(SDL_Real)
GENERAL;
-- Implements the SDL operator:
-- +: Real, Real -> Real;
SDL_Real_Sub:
PROC(l SDL_Real
,r SDL_Real
) RETURNS(SDL_Real)
GENERAL;
-- Implements the SDL operator:
-- -: Real, Real -> Real;
SDL_Real_Mul:
PROC(l SDL_Real
,r SDL_Real
) RETURNS(SDL_Real)
GENERAL;
-- Implements the SDL operator:
-- *: Real, Real -> Real;
SDL_Real_Div:
PROC(l SDL_Real
,r SDL_Real
) RETURNS(SDL_Real)
GENERAL;
-- Implements the SDL operator:
-- /: Real, Real -> Real;
SDL_Real_Lss:
PROC(l SDL_Real
,r SDL_Real
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- <: Real, Real -> Boolean;
SDL_Real_Leq:
PROC(l SDL_Real
,r SDL_Real
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- <=: Real, Real -> Boolean;
SDL_Real_Gtr:
PROC(l SDL_Real
,r SDL_Real
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- >: Real, Real -> Boolean;
SDL_Real_Gte:
PROC(l SDL_Real
,r SDL_Real
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- >=: Real, Real -> Boolean;
-- (Z.100 chapter 5.6.11) NEWMODE
SDL_Duration = STRUCT
(ld LONGDURATION
-- LONGDURATION is CRS defined.
-- The unit for representation is
-- 100 nanoseconds.
)
;
SDL_Duration_Lit:
PROC(i LONGINT
,f LONGINT
) RETURNS(SDL_Duration)
GENERAL;
-- Maps Duration literal to
-- SDL_Duration mode.
-- 'i' denotes seconds.
-- 'f' denotes nanoseconds
SDL_Duration_Add:
PROC(l SDL_Duration
,r SDL_Duration
) RETURNS(SDL_Duration)
GENERAL;
-- Implements the SDL operator:
-- +: Duration, Duration -> Duration;
SDL_Duration_Sub:
PROC(l SDL_Duration
,r SDL_Duration
) RETURNS(SDL_Duration)
GENERAL;
-- Implements the SDL operator:
-- -: Duration, Duration -> Duration;
SDL_Duration_Neg:
PROC(r SDL_Duration
) RETURNS(SDL_Duration)
GENERAL;
-- Implements the SDL operator:
-- -: Duration -> Duration;
SDL_Duration_Gtr:
PROC(l SDL_Duration
,r SDL_Duration
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- >: Duration, Duration -> BOOL;
SDL_Duration_Mul:
PROC(l SDL_Duration
,r SDL_Real
) RETURNS(SDL_Duration)
GENERAL;
-- Implements the SDL operator:
-- *: Duration, Real -> Duration;
SDL_Duration_Div:
PROC(l SDL_Duration
,r SDL_Real
) RETURNS(SDL_Duration)
GENERAL;
-- Implements the SDL operator:
-- /: Duration, Real -> Duration;
-- (Z.100 chapter 5.6.12) NEWMODE
SDL_Time = STRUCT
(ld LONGDURATION
-- LONGDURATION is CRS defined.
-- The unit for representation is
-- 100 nanoseconds.
)
;
SDL_Time_Lit:
PROC(i LONGINT
,f LONGINT
) RETURNS(SDL_Time)
GENERAL;
-- Maps Time literal to SDL_Time mode
-- 'i' denotes seconds
-- 'f' denotes nanoseconds
SDL_Time_Lss:
PROC(l SDL_Time
,r SDL_Time
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- <: Time, Time -> Boolean;
SDL_Time_Leq:
PROC(l SDL_Time
,r SDL_Time
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- <=: Time, Time -> Boolean;
SDL_Time_Gtr:
PROC(l SDL_Time
,r SDL_Time
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- >: Time, Time -> Boolean;
SDL_Time_Gte:
PROC(l SDL_Time
,r SDL_Time
) RETURNS(BOOL)
GENERAL;
-- Implements the SDL operator:
-- >=: Time, Time -> Boolean;
SDL_Time_Add:
PROC(l SDL_Time
,r SDL_Duration
) RETURNS(SDL_Time)
GENERAL;
-- Implements the SDL operator:
-- +: Time, Duration -> Time;
SDL_Time_Sub:
PROC(l SDL_Time
,r SDL_Duration
) RETURNS(SDL_Time)
GENERAL;
-- Implements the SDL operator:
-- -: Time, Duration -> Time;
SDL_Time_Diff:
PROC(l SDL_Time
,r SDL_Time
) RETURNS(SDL_Duration)
GENERAL;
-- Implements the SDL operator:
-- -: Time, Time -> Duration;
...
END
SDL_support;
---------------------------------------------------------------------- Note: Due to the implementation of SDL Integer using 16-bit integers in CHILL, there is a restriction in range for integer values. Integers must be in the range -215..215-1.(a) There are in the same way restric tions both in range and precision for Real, Time, and Duration, as they are implemented using the CRS defined mode LONGDURATION. In the interface to SDL Services the literals of Real, Time, and Duration are represented by two 32-bit integers. The first integer of Time, and Duration represents the number of seconds and the second integer represents the number of nanosec onds. The length of charstrings cannot exceed the implementation defined limit of 100. (b) ----------------------------------------------------------------------
The name of these types in the generated CHILL code will be INT, SDL_Natural, BOOL, CHAR, SDL_Charstring, SDL_Real, SDL_Time, SDL_Duration and INSTANCE respectively.
The translation rules for these types and their operators are described in more detail in the "SDL Predefined Types" on page 2321.
Example 168 NEWTYPE EnumType LITERALS Lit1, Lit2, Lit3; ENDNEWTYPE;is translated to:
SYNMODE EnumType = SET(Lit1, Lit2, Lit3);Unfortunately this translation strategy is not always correct. Consider as an example the following sort definition.
Example 169 NEWTYPE Enum2 LITERALS Lit1, Lit2; OPERATORS Op : Enum2 -> Enum2; AXIOMS Op(Lit1) == Lit2; Op(Op(Lit2)) == Lit1; ENDNEWTYPE;When evaluating this definition it is fairly easy to see that the value set of this sort contains three values, the value denoted by Lit1, the value denoted by Lit2, and the value obtained by applying Op to Lit2, that is, Op(Lit2). The latter value does not have any explicit literal denoting its value, which means that an implementation of this sort as an enumeration type in CHILL would be incorrect. In general, the set of literals of a sort and the set of values of a sort are two quite different things. Still the translation rule is included in sdl2chill, since it is valid in most situations.
Example 170 NEWTYPE Str STRUCT a Integer; b Boolean; c Character; ENDNEWTYPE;is translated to:
SYNMODE Str = STRUCT (a INT ,b BOOL ,c CHAR );All the properties of a struct in SDL are preserved in the CHILL 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 CHILL. The predefined operator Make!, which is a constructor of a struct value, is implemented by means of tuples in CHILL. This means that the expression (. 12, true, `a' .) in SDL is translated to the CHILL constant tuple: [ 12, TRUE, `a' ].
The components of a struct may be of any sort that sdl2chill can handle. A component may, however, not directly or indirectly refer to the struct sort itself.
Example 171The sort Str above may not have a component of sort Str. In such a case the translation to a CHILL struct would not any longer be valid.
Example 172 SYNTYPE Idx = Integer CONSTANTS 0:10 ENDSYNTYPE; NEWTYPE Arr ARRAY(Idx, Real) ENDNEWTYPE;is translated to:
SYNMODE Idx = INT(0:10) ,Arr = ARRAY(Idx)SDL_Real ;All the properties of an array in SDL are preserved in the CHILL code. The predefined operators Extract! and Modify! are implemented as indexing of the array in CHILL in the same way as in component selection is done in SDL, so if My_Var is a variable of type Arr, and My_Index is a valid index expression, then My_Var(My_Index) in SDL maps to My_Var(My_Index) in CHILL.
The predefined operator Make!, which is a constructor of an array value, is implemented by means of CHILL tuples. This means that the expression "(. 0.22 .)" in SDL is translated to the CHILL tuple: [ (*): SDL_Real_Lit(0, 220000000) ].
The syntype is translated to a type equal to the parent type using SYNMODE definition. The check that a variable of a syntype with range condition is only assigned legal values, is catered for by CHILL semantic conditions. An attempt to assign an illegal value to such a variable will be reported as a CHILL RANGEFAIL exception at run-time. Similarly, if syntype is specified as index sort in an array, the CHILL semantic conditions will ensure that the index values used in array component selections are within the range conditions specified for the index sort.
Example 173 SYNTYPE Syn1 = integer CONSTANTS 0:10 ENDSYNTYPE; SYNTYPE Syn2 = integer CONSTANTS 0:255 ENDSYNTYPE; SYNTYPE Arr1 = Arr DEFAULT (. 2.0 .); ENDSYNTYPE; /* Arr is defined in the previous example*/is translated to:
SYNMODE
Syn1 = INT(0:10)
,Syn2 = INT(0:255)
,Arr1 = Arr
;
-------------------------------------------------------------------- Note: Note: The SDL system is in error if a variable containing an undefined val ue is accessed. This should have been reported when executing the generated program, but it will not be detected because undefined values are (for performance reasons) generally not catered for in CHILL. As a general rule you should define appropriate default values in sort definitions and use initial value assignment in variable defini tions whenever this is needed. --------------------------------------------------------------------
An sdl2chill directive is an SDL comment with the first character 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:
Example 174 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;The #OP directive can be used to specify how the applied occurrences of the associated literal or operator should be implemented. In the #ADT directive the actual implementation can be defined e.g. in the form of CHILL procedure definitions.
An OP or ADT directive specifying the implementation details of operators and literals should have the following structure:
/*#OP (B) */ /*#ADT (B) */The letter between the parentheses should be B (body)(9). If B has been specified for an operator or literal, then CHILL code for implementing its intended function must be supplied by the user. This CHILL code should be placed in the ADT directive, according to the following example:
Example 175 /*#ADT (B)The CHILL code must start on a new line.
-- CHILL code in the form of procedure
-- definitions implementing operators
-- and literals.
*/
------------------------------------------------------------------- Note: sdl2chill does not check the consistency between the specification of implementation techniques and the actual CHILL code. This check is, together with checking the CHILL code for syntactic and static semantic errors, left to the CHILL compiler. CHILL comments within the code that is included in a #ADT direc tive should be in the form of end-of-line comments. SDL and CHILL use the same symbols for bracketed comments and if such a comment is included, the SDT Analyzer will consider its closing bracket as the end of the SDL comment. -------------------------------------------------------------------In Example 174 the struct Str is defined and there are two literals (Lit1 and Lit2) and two operators (Op1: Str, integer --> Str; and Op2: Str, Boolean --> Str;). The procedures, which should be supplied by the sdl2chill user if B is specified in the OP or ADT directive, are ordinary CHILL procedures.
Example 176 Lit1:Before it is possible to give a complete example of an abstract data type with implementation of its operators supplied as CHILL procedures it is necessary to look at the problem of names and name strings. When a name string of an entity in SDL is translated to CHILL, a suitable sequence of characters, a prefix, is added to the SDL name string, to make the name unique in the CHILL program, see also "Names and Prefixes in Generated Code" on page 2357. This strategy is selected in sdl2chill to avoid name conflicts in the generated code, but it makes it also impossible to predict the actual name string of, for example a mode or a procedure, in the generated program. To handle this problem the user can tell sdl2chill to translate a name string in the user written CHILL code in the same way as SDL name strings are otherwise translated. This is specified by enclosing the SDL name string between "#(" and ")" in the CHILL code. The two procedures in the previous example then become:
PROC() RETURNS(Str);
RETURN [ 2, FALSE, SDL_Real_Lit(2,0) ];
END;
Op1:
PROC(p1 Str, p2 INT)RETURNS(Str);
p1.a +:= p2;
RETURN p1;
END;
Example 177 #(Lit1):The facilities enabling the use of SDL defined names in CHILL code is described in more detail in the section"Applying SDL Names in CHILL Code - Directive #SDL" on page 2351. A few observations concerning the example above might be appropriate:
PROC() RETURNS(#(Str));
RETURN [ 2, FALSE, SDL_Real_Lit(2,0) ];
END;
#(Op1):
PROC(p1 #(Str), p2 INT)RETURNS(#(Str));
p1.a +:= p2;
RETURN p1;
END;
Example 178 NEWTYPE Str STRUCT a Integer; b Boolean; c Real; ADDING LITERALS Lit1; OPERATORS Op1 : Str, Integer -> Str; Op2 : Str, Boolean -> Str; /*#ADT (B)Note that no procedure definition is supplied for the operator Sum. When compiling a generated program where the operator Sum is used, the CHILL compiler will therefore give an error message saying that definition of the name Sum is missing.
#(Lit1):
PROC() RETURNS(#(Str));
RETURN [ 2, FALSE, SDL_Real_Lit(2,0) ];
END;
#(Op1):
PROC(p1 #(Str), p2 INT)RETURNS(#(Str));
p1.a +:= p2;
RETURN p1;
END;
#(Op2):
PROC(p1 #(Str), p2 BOOL)RETURNS(#(Str));
IF p2
THEN
RETURN p1;
ELSE
RETURN #(Lit1)();
FI;
END;
*/ ENDNEWTYPE; Example 179 SYNTYPE Index = Integer
CONSTANTS 1:10 ENDSYNTYPE; NEWTYPE A Array(Index, integer) ADDING LITERALS Zero /*#OP (B) */; OPERATORS Add : A, A -> A; /*#OP (B) */ Sum : A -> Integer; /*#ADT (B)
#(Zero):
PROC() RETURNS(#(A));
RETURN [ (*): 0 ];
END;
#(Add):
PROC(p1 #(A), p2 #(A)) RETURNS(#(A));
DCL Result #(A);
DO FOR i IN #(Index);
Result(i) := p1(i) + p2(i);
OD;
RETURN Result;
END;
*/
ENDNEWTYPE;
For more information about CHILL synonyms, modes and procedures (supplied by the SDL Services and used in generated code) that can be useful when implementing operators in CHILL, see "SDL Predefined Types" on page 2321, and last in "More about Abstract Data Types" below.
For an operator in an abstract data type not only B (body) may be specified. The following choices are available:
----------------------------------------------------------------- Note: As CHILL does not include the possibility to have user defined op erators, I (infix) is only adequate together with S (standard). -----------------------------------------------------------------
Example 180Example of usage of S (standard)
REM : Integer,Integer->Integer; /*#ADT (SI) */ SIZE : Real -> Integer; /*#ADT (SP) */An SDL expression using these operators:
SIZE(a) will be translated to: SIZE(zh723_a)
These examples show how built-in procedures and standard operators of CHILL can be directly utilized in abstract data types.
When generating applications it is sometimes needed, in parts of a system, to use additional CHILL modes such as pointers, other integer modes than INT and the more implementation oriented capabilities of CHILL such as variant structure modes and packing. This is facilitated by means of the #ADT directive.
By this directive it is possible to suppress the generation of mode definitions for an abstract data type and include a CHILL written mode definition instead. Suppressing the generation of the mode definition, however, does not affect the translation of the actions related to the data type.
The #ADT directive to specify that no mode definition shall
be generated from the SDL sort has the following structure(10):
/*#ADT (T)The example below shows how the #ADT directive may be used in order to use the CHIPSY defined integer mode LONGINT from SDL.
CHILL code (that replaces the mode definition
otherwise generated by sdl2chill).
*/
Example 181 SYNTYPE long /*#NAME 'LONGINT' */ = IntegerBelow is another example showing how the #ADT directive may be used to facilitate packing of the components of a structure and to build a linked list of data objects by means of a CHILL defined pointer.
/*#ADT (T)
*/
ENDSYNTYPE;
...
DCL l1 long
,l2 long := 65536;
...
TASK l1 := l2 + l1;
Maps into the following CHILL code:
...
DCL l1 LONGINT i.e. undefined initial value
,l2 LONGINT := 65536;
...
l1 := l2 + l1;
Example 182 SYNTYPE nibble = Integer
CONSTANTS 0:15
ENDSYNTYPE;
NEWTYPE package STRUCT
i nibble;
j nibble;
ADDING
LITERALS
NIL
OPERATORS
SUM: package -> Integer; /*# OP (B) */
DEFAULT NIL;
/*#ADT (T)
SYNMODE
nibble = #(nibble)
,package = #(package)
;
NEWMODE #(package) =
STRUCT
(i nibble PACK
,j nibble PACK
,NEXT REF package
);
#(SUM): PROC (p1 package) (INT);
DCL p REF package := ->p1
,sum INT := 0;
DO WHILE p /= NULL;
sum +:= p->.i + p->.j;
p := p->.NEXT;
OD;
RETURN sum;
END;
#(NIL): PROC() (package);
RETURN [ 0, 0, NULL];
END;
*/
ENDNEWTYPE;
A directive has the general structure:
Example 183Take 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.(11) After this part spaces and carriage returns may be inserted freely.
You may prefix a directive name by "CHILL" or "C" to condition the recognition of the directive to sdl2chill or to the C Code Generator re spectively.
Example 184 system S; /*#SEPARATE 'filename' */ block B; /*#SEPARATE */ process P1; /*#SEPARATE */ process P2 (1, ); /*#SEPARATE */As can be seen a file name should be enclosed between quotes. sdl2chill will append appropriate extensions to this name when it generates code.
If no file name is given in the directive, the name of the system, block, or process will be used to obtain a file name. In such a case the file name will be the same as the name of the unit with the appropriate extension ( .chill .cdbf .o .exe .m ) depending on contents. Characters that are not letters, digits or underlines are stripped from the file name.
Example 185 system S; /*#SEPARATE 'Sfile' */ block B1; /*#SEPARATE */ process P11; /*#SEPARATE 'P11file' */ process P12; block B2; process P21; process P22; /*#SEPARATE */
------------- Sfile.chill B1.chill P11file.chill P12.chill B2.chill P21.chill P22.chill Sfile.m -------------The .chill files contain the CHILL code generated for the corresponding SDL unit and the .m file is the makefile for compiling and linking the application program.
A.cdbf file for each compilation unit will be created when compiling the generated CHILL code. Interfaces between compilation units are contained in the .cdbf files derived for the system unit and for the block units. The compilation order thereby imposed is, of course, catered for by the generated compilation script.
------------------------------------------------- Sfile.chill Contains code for units S, B2, P21 B1.chill Contains code for units B1, P12 P11file.chill Contains code for unit P11 P22.chill Contains code for unit P22 Sfile.m -------------------------------------------------The user defined separate generation option thus makes it possible for a user to completely decide the file structure for the generated code. The comments on files and extensions given above are of course also valid in this case.
----------------------------------------- Sfile.chill Contains code for all units Sfile.m -----------------------------------------The comments on files and extensions earlier are valid even here.
To be able to write CHILL code and use the name string of SDL objects in that code, sdl2chill provides the directive #SDL which is used in CHILL code to translate an SDL name string to the corresponding CHILL name string.
The syntax of the #SDL directive is as follows:
#SDL (SDL name)or
#SDL (SDL name, entity class name)There is also a short form for the directive. No characters are allowed between the # character and the (in this form.
#(SDL name)or
#(SDL name, entity class name)Replace SDL name with the name string of an object in the SDL definition and entity class name by any of the following identifiers (upper and lower case letters are considered to be equal):
------------------------------------------- block newtype signal blockinst operator signallist blocksubst package signalroute blocktype predef sort (= newtype) channel procedure state channelsubst process synonym connect processinst syntype formalpar processtype system gate remoteprd systemtype generator remotevar timer imported service variable label serviceinst view literal servicetype -------------------------------------------This list contains all entity classes, which means that not all of the entries are relevant for practical use. When a #SDL directive is found in included CHILL code, sdl2chill first identifies which SDL object is referred and then replaces the directive by the CHILL name string for that object. The search for the SDL object starts in the current scope (the scope where the CHILL code is included), and follows the scope hierarchy outward to the system definition, until an appropriate SDL object is found. An appropriate SDL name is considered to be found if it has the specified name string and is in the specified entity class. If no entity class name is given the search is performed for all entity classes.
The table in the subsection "SDL Predefined Types" gives the direct translation between an SDL name and the corresponding CHILL name or expression (see page page 2321). For these names the #SDL directive should not be used.
/*#CODE CHILL code that should be included in the generated code. */Type the directive name on the first line and the CHILL code on the following lines up to the end of comment symbol.
A #CODE directive can be placed:
-------------------------------------------------------------------- Note: sdl2chill handles the CHILL code in directives as text and performs no check that the code is valid CHILL code. --------------------------------------------------------------------The code directive is included as a facility in sdl2chill to provide experienced users an escape possibility to the target language CHILL. This increases the application range of sdl2chill.
An example of a possible use of the code directive is: An algorithm for some computation, which in the SDL description is only indicated as task with an informal text, could be implemented in CHILL. In this case the directive #SDL described in the previous subsection probably will become useful to access variables and formal parameters defined in SDL.
Some general hints on how to write CHILL code that can be included into an application program can be found in the last part of the section "User Defined Operators" on page 2339.
SDL and CHILL use the same symbols for start and end of comments. To have CHILL comments within the code that is included in any directive, the CHILL end-of-line comment must be used.
/*#CODE CHILL code containing for example:Code directives to include CHILL 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:
- mode definitions - location declarations - procedure definitions */
Example 186 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 data statements within the directive are thus placed among the other CHILL statements generated 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.
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 definitions and declarations made in code directives are of course available in code directives in tasks in the corresponding unit or in its subunits.
The general hints on how to write CHILL code that fits into a generated CHILL program given in the section "User Defined Operators" on page 2339 and in the section "Applying SDL Names in CHILL Code - Directive #SDL" on page 2351 are also applicable here.
#CODE : Charstring -> S;where S denotes the actual sort name. This operator or rather these operators make it possible to access e.g. locations, procedures and built-in procedures defined in CHILL using the #CODE directive in SDL expressions without violating the syntactic and static semantic rules of SDL.
During SDL to CHILL translation, sdl2chill will just copy the actual Charstring parameter into the generated CHILL code at the place where the #CODE operator is applied.
Example 187Suppose that x and y are SDL variables, which are translated to z72_x and z73_y, that a and b are CHILL locations, and p is a CHILL procedure defined in #CODE directives.
---------------------------------------------- SDL expression CHILL expression ---------------------------------------------- x + #CODE('a') z72_x + a x + #CODE('a * b') z72_x + a * b x * #CODE('(a+b)') * y z72_x * (a + b)* z73_y #CODE('p(a, #SDL(x))') p(a, z72_x) ----------------------------------------------
Within the Charstring parameter of a #CODE operator the #SDL directive is available in the same way as in other included CHILL code. This is shown in the expression in the last line of the example above.
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 188 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');
A generated CHILL name string for an SDL object contains four parts in the following order:
The sequence of characters that make the name string unique is determined by the position of the actual declaration in structure of declarations in the system:
If, for example, a sort is defined as the 5th declaration in a block that in turn is the 12th declaration in the system, then the total sequence will be b4 (if not more than 36 declaration are present on any of the two levels).
Example 189Examples of generated name strings:
------------------------------------------------------------------ SDL
Position of the Declaration Generated name string name string ------------------------------------------------------------------ S1 10th declaration in the system z9_S1 Var2 3rd declaration in the process, ze42_Var2 which is the 5th declaration in the block, which is the 15th declaration is system ------------------------------------------------------------------
This strategy for naming objects in the generated code should be used in all normal situations, as it guarantees that no name conflicts occur. sdl2chill offers, however, possibilities to change this strategy. In the user interface of the Analyzer and sdl2chill it is possible to select one of the following strategies: full prefix, entity class prefix, no prefix, or special prefix. Full prefix is default and is the strategy described above. If entity class prefix is selected, then the prefix that is concatenated with the SDL name string will be in accordance with the table below and depends only on the entity class of the object.
------------------------------------------------------------- Entity class Prefix Entity class Prefix ------------------------------------------------------------- Block, block type, blo Process, Process type, prs block instance Process instance Block substructure bls Remote procedure rpc Channel cha Remote variable imp Channel substructure chs Service, Service type, ser Service instance Connection con Signal sig Formal parameter for Signal list sil Gate gat Signal route sir Generator gen Sort sor Import imp State sta Label lab Syntype syt Literal lit Synonym syo Operator ope System, System type sys Package pac Timer tim Predef pre Variable var Procedure prd View vie -------------------------------------------------------------Using entity class prefix means that the user must guarantee that no name conflict occurs. It also means, however, that the generated name strings are predictable and thus simplifies writing CHILL code where the SDL names are used. You only have to look for name conflicts within entity classes, for example not having two sorts with the same name string. The entity class prefixes handle the case when two objects of different entity class have the same name string. Note that the table above contains all entity classes. Not all of the items are actually used by sdl2chill.
The third alternative, no prefix, means of course that no prefixes are added to the SDL name string. The name string in the CHILL program will then be the SDL name string with the characters that are not allowed in CHILL name strings (everything except letters, digits, and underline) stripped off. In this case, you must guarantee that no name conflict occurs and that the stripped name string is allowed as a CHILL name string, that is, that it begins with a letter.
In the fourth alternative, special prefix, full prefixes are used for all entity classes except variable, formal parameter, sort, and syntype. For these entity classes no prefix is used.
As was said in the beginning of this subsection, you should have a good reason for selecting anything but the full prefix, as it could be very difficult to spot name conflicts. The compiler will in some cases find a conflict, but may in other cases consider the program as legal and generate an executable program with a possibly unwanted behavior.
Example 190 NEWTYPE S /*#NAME 'S' */ STRUCT a Integer; b Boolean; ADDING OPERATORS Op /*#NAME 'OtherName' */ : S, S -> Boolean; ENDNEWTYPE;The name string 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.
Example 191 Process P1; /*#PRIO 2048,3,* */ Process P2(1,1); /*#PRIO *,2 */ ... Create P1; Create P2;
Example 192 Signal S /*#PRIO 6 */; ... Output S; ... Output S /*#PRIO 1*/;
Example 193 System S; /*#MAIN CHILL code for initialization */The #MAIN directive has exactly the same structure as the #CODE directive for including code in tasks. The included code will, however, be placed in the reach of the outermost CHILL module of the generated program, and it will be executed after the initialization of the internal structure, but before any transitions.
Example 194 System S; /*#WITH 'file1' 'file2' */Within the #WITH directive the name of the object files that are to be included in the link operation should be given between quotes, as in the example above. These file names will then be included in the definition of the link operation in the generated .m or .link file.
The makefile will, however, not include any definition of how to compile the corresponding source files, as it is impossible for sdl2chill to know the compilation options or even what compiler the user wants.
-------------------------------------------------------------------- Note: The #WITH directive will only affect the generated make file. There will be no change in the generated CHILL code when a #WITH di rective is introduced. --------------------------------------------------------------------
Example 195 System S; /*#WITH 'file1' 'file2' */ /*#ENVIRONMENT 'file1' 'file2' */Within the #ENVIRONMENT directive the names of the actual CDB_entries should be given between quotes, as in the example above. These file names will then be included in the CHIPSY context directive of the generated compilation unit(s). As shown by the example, the #ENVIRONMENT directive and the #WITH directive may both be used for a system.
A user that knows how to interface to routines in other languages in a CHILL program, can with this knowledge and the #ENVIRONMENT directive and the #WITH directive link modules written in another language together with the generated program.
--------------------------------------------------------------- Note: The #ENVIRONMENT directive will only affect the generated CHILL code. There will be no change in the generated make file when a #ENVIRONMENT directive is introduced. ---------------------------------------------------------------
Example 196 Synonym Pa_lit /*#NAME 'Pa_lit'*/ PId = NULL; ... Process Pa(1,1);/*#PIDLIT 'Pa_lit' */ ... Output my_signal to Pa_lit;In case you create more than one initial instance of a process, the identifying synonym must be an array of which the item sort is PId and the number of items is equal to the number of initially created instances. See also Example 196.
Example 197 Syntype index = integer Constants 1:10 Endsyntype; Newtype PId_array Array(index, PId) Endnewtype; Synonym Pb_lits /*#NAME 'Pb_lits' */
PId_array = (. NULL .); ... Process Pb(1,10);/*#PIDLIT 'Pb_lits' */ ... Output my_signal to Pb_lits(10);
The SDL system may be viewed as a CHILL module interfaced to via signals. This makes it easy to plug in a system as an application program part anywhere in your CHILL software structure and as the interface definition is also generated by sdl2chill, consistency check is fully catered for by CHILL.
The environment of the SDL system consists of CRS, other application program parts, the hardware, a network of computers and so on. In this world other actions than just signal sending and receiving are required. Examples of some actions that an application may want to perform are:
The system interface module is the place where the two worlds, the SDL system and the environment, meet. Here signals sent from the SDL system to the environment can induce all kinds of events in the environment, and events in the environment might cause signals to be sent into the SDL system. The system interfacing code may be collected in a separate interface module or, if more convenient, embedded in the application program part(s) which the SDL system is connected to. Definitions of the signals connecting the SDL system to its environment is provided by sdl2chill, but the actual functionality of the system interface module, of course, you must provide yourself because sdl2chill has no knowledge of this. How to write the system interface module is described in the next section.
When it comes to system architecture, utilization of the application (parts) generated by sdl2chill is very flexible. In a distributed system an application might consist of several communicating SDL systems. Each SDL system will become one executable program. It might execute either as an operating system process (e.g. UNIX process), or it might execute in a processor of its own, communicating over a network with other processors. There can of course also be combinations of these. Distribution is facilitated by means of the CHIPSY Distributed Processing Services as described in the CHIPSY Reference Manual.
Example 198SDL/PR specification
system DemonGame; signal Newgame, Probe, Result, Endgame, ... endsystem DemonGame;Generated CHILL
<> ENVIRONMENT ... DemonGame: MODULE GRANT ALL; ... END DemonGame;System interface module
<> ENVIRONMENT('DemonGame'); ApplyDemonGame: MODULE SEIZE Newgame ,Probe ,Result ,Endgame ... END ApplyDemonGame;
system DemonGame;
signal Newgame, Probe, Result, Endgame, Win, Lose, Score(integer), Game_Ack(pid), Bump, Game_Id(pid); synonym Main_P pid = NULL; synonym Demon_P pid = NULL; channel C3 from DemonBlock to GameBlock with Bump; from GameBlock to DemonBlock with Game_Id; endchannel C3; channel C2 from GameBlock to env with Win, Lose, Score, Game_Ack; endchannel C2; channel C1 from env to GameBlock with Newgame, Probe, Result, Endgame; endchannel C1; block DemonBlock referenced; block GameBlock referenced; endsystem DemonGame; block DemonBlock; connect C3 and R1, R2; signalroute R1 from Demon to env with Bump; signalroute R2 from env to Demon with Game_Id; process Demon (1, 1) referenced; endblock DemonBlock; block GameBlock; signal GameOver; connect C1 and R1, R2; connect C2 and R3, R7; connect C3 and R4, R6; signalroute R2 from env to Game
with Probe, Result; signalroute R4 from env to Game
with Bump; signalroute R5 from Main to Game
with GameOver; signalroute R3 from Game to env
with Win, Lose, Score; signalroute R6 from Game to env
with Game_Id; signalroute R7 from Main to env
with Game_Ack; signalroute R1 from env to Main
with Newgame, Endgame; process Game (0, 1) referenced; process Main (1, 1) referenced; endblock GameBlock; process Demon; /*#PIDLIT 'Demon_P' */ timer T; dcl game_p pid := NULL; start; set( now + 5, T); nextstate generate; state generate; input T; decision game_p = NULL; ( false) : output Bump to game_p; set( now + 0.5, T); nextstate -; ( true) : set( now + 10, T); nextstate -; enddecision; input Game_Id( game_p); nextstate -; endprocess Demon; process Game; dcl Count integer; start; task Count := 0; output Game_Id( self) to Demon_P; nextstate Losing; state Losing; input Probe; output Lose; task Count := Count - 1; nextstate -; input Bump; nextstate Winning; state Winning; input Bump; nextstate Losing; input Probe; output Win; task Count := Count + 1; nextstate -; state * ; input Result; output Score( Count); nextstate -; input GameOver; output Game_Id( NULL) to Demon_P; stop; endprocess Game; process Main; /*#PIDLIT 'Main_P' */ dcl GameP pid; start; nextstate Game_Off; state Game_Off; input Newgame; create Game; task GameP := offspring; output Game_Ack( offspring); nextstate Game_On; state Game_On; input Endgame; output GameOver to GameP; task GameP := NULL; nextstate Game_Off; endprocess Main;
<> ENVIRONMENT ('DemonGame' ,'BasicIo' ,'(CRS)pgh_terminate_program' ); ApplyDemonGame: MODULE SEIZE -- from DemonGame Newgame ,Probe ,Result ,Endgame ,Win ,Lose ,Score ,Game_Ack ,Main_P -- from pgh_terminate_program ,TS_Normal ,Terminate_Program ; NEWMODE Commands = SET (Do_Quit ,S_Newgame ,S_Probe ,S_Result ,S_Endgame ); DCL Menu ARRAY (1:5) CHAR(10):= ['Newgame: 1' ,'Probe : 2' ,'Result : 3' ,'Endgame: 4' ,'Quit : 0'] ,Win_txt CHAR(3) := 'Win' ,Lose_txt CHAR(4) := 'Lose' ,Score_txt CHAR(10):= 'Score is: ' ; Read_Command: PROC() (Commands); DCL choice_no INT := 0 ; new_line(); DO FOR menu_line IN Menu; out_text(-> menu_line); OD; choice_no := in_int(); IF choice_no < 0 OR choice_no > 4 THEN RETURN Read_Command(); ELSE RETURN Commands(choice_no); FI; END Read_Command; Report_Win: PROC(); out_text(-> Win_txt); END Report_Win; Report_Lose: PROC(); out_text(-> Lose_txt); END Report_Lose; Report_Score: PROC(Score INT); out_string(-> Score_txt); out_int(Score); new_line(); END Report_Score; DemonGameInterface: PROCESS(); DCL Game_P INSTANCE := NULL; ; DO FOR EVER; CASE Read_Command() OF (S_Newgame): SEND Newgame TO Main_P; RECEIVE CASE; (Game_Ack IN pid_parm): Game_P := pid_parm; ESAC; (S_Probe): IF Game_P /= NULL THEN SEND Probe TO Game_P; RECEIVE CASE; (Win): Report_Win(); (Lose): Report_Lose(); ESAC; FI; (S_Result): IF Game_P /= NULL THEN SEND Result TO Game_P; RECEIVE CASE; (Score IN int_parm): Report_Score(int_parm); ESAC; FI; (S_Endgame): SEND Endgame TO Main_P; Game_P := NULL; (Do_Quit): Terminate_Program(TS_Normal); ESAC; OD; END DemonGameInterface; START DemonGameInterface();
END ApplyDemonGame;
<> ENVIRONMENT ('(ROOT_CD)/crs/_sdl/sdl_support' ,'(CRS)/sih_else_signal' ); DemonGame: MODULE GRANT ALL; SEIZE ALL; DCL Main_P INSTANCE STATIC := NULL; DCL Demon_P INSTANCE STATIC := NULL; SIGNAL Newgame ,Probe ,Result ,Endgame ,Win ,Lose ,Score = (INT) ,Game_Ack = (INSTANCE) ,Bump ,Game_Id = (INSTANCE) ,T ,GameOver ; Demon: PROCESS(parent INSTANCE); NEWMODE states = SET(start_state, generate) ; DCL offspring INSTANCE := NULL ,sender INSTANCE := NULL ,state states := start_state ,game_p INSTANCE := NULL ; DCL yDcn_BOOL BOOL ; DO WHILE TRUE; CASE state OF (start_state): SDL_Set_Timer (SDL_Time_Add (SDL_Now() ,SDL_Duration_Lit(5, 0) ) , -> T ); state := generate; GOTO SDL_next_state; (generate): RECEIVE CASE SET sender; (Game_Id IN yP1): game_p := yP1; GOTO SDL_next_state; (T): IF game_p=NULL THEN SDL_Set_Timer (SDL_Time_Add (SDL_Now() ,SDL_Duration_Lit(10, 0) ) ,-> T ); GOTO SDL_next_state; ELSE SEND Bump TO game_p; SDL_Set_Timer (SDL_Time_Add(SDL_Now() ,SDL_Duration_Lit(0, 500000000)) ,-> T ); GOTO SDL_next_state; FI; ESAC; ESAC; SDL_next_state: ; OD; END Demon; Demon_P := START Demon(NULL); Game: PROCESS(parent INSTANCE); NEWMODE states = SET(start_state, Losing, Winning) ; DCL offspring INSTANCE := NULL ,sender INSTANCE := NULL ,state states := start_state ,Count INT ; DO WHILE TRUE; CASE state OF (start_state): Count := 0; SEND Game_Id(THIS) TO Demon_P; state := Losing; GOTO SDL_next_state; (Losing): RECEIVE CASE SET sender; (Probe): SEND Lose /* TO ? */; Count := Count-1; GOTO SDL_next_state; (Result): GOTO L_xxLabel1; (Bump): state := Winning; GOTO SDL_next_state; (GameOver): GOTO L_xxLabel2; ESAC; (Winning): RECEIVE CASE SET sender; (Probe): SEND Win /* TO ? */; Count := Count+1; GOTO SDL_next_state; (Result): GOTO L_xxLabel1; (Bump): state := Losing; GOTO SDL_next_state; (GameOver): GOTO L_xxLabel2; ESAC; ESAC; L_xxLabel1: ; SEND Score(Count) /* TO ? */; GOTO SDL_next_state; L_xxLabel2: ; SEND Game_Id(NULL) TO Demon_P; STOP; SDL_next_state: ; OD; END Game; Main: PROCESS(parent INSTANCE); NEWMODE states =
SET(start_state, Game_Off, Game_On) ; DCL offspring INSTANCE := NULL ,sender INSTANCE := NULL ,state states := start_state ,GameP INSTANCE := NULL ; DO WHILE TRUE; CASE state OF (start_state): state := Game_Off; GOTO SDL_next_state; (Game_Off): RECEIVE CASE SET sender; (Newgame): offspring := START Game(THIS); GameP := offspring; SEND Game_Ack(offspring) /* TO ? */; state := Game_On; GOTO SDL_next_state; (else): GOTO SDL_next_state; ESAC; (Game_On): RECEIVE CASE SET sender; (Endgame): SEND GameOver TO GameP; GameP := NULL; state := Game_Off; GOTO SDL_next_state; (else): GOTO SDL_next_state; ESAC; ESAC; SDL_next_state: ; OD; END Main; Main_P := START Main(NULL); END DemonGame;
The restrictions in the SDT Analyzer, which of course also affect sdl2chill, are summarized below. For more information see the chapter The Analyzer.
This page intentionally left blank
Table of Contents Next Chapter