S3 (programming language): Difference between revisions

Content deleted Content added
Link suggestions feature: 3 links added.
 
(12 intermediate revisions by 11 users not shown)
Line 1:
{{Use dmy dates|date=April 2022}}
{{Infobox programming language
| name = S3
Line 27 ⟶ 28:
|title=Kermit Software Source Code Archive
|date=22 Aug 2011
|accessdateaccess-date=1 March 2013
}}</ref> The examples below are selected highlights of the main module (kmt_main_module).
 
The program starts with a module identification, and comments which we quote by way of acknowledgment to the authors:
 
MODULE KMT_MAIN_MODULE; @ Version 1.01 @
<source lang="algol68">
MODULE KMT_MAIN_MODULE; @ Version 1.01 @
@------------------------------------------------------------------------------@
@ @
@ @
@ ----- S W U R C C V M E K E R M I T ----- @
@ @
@ @
@ ---------------------------------------------------------------- @
@ @
@ @
@ Version 1.00 (February 1986) @
@ @
@ Written by : Richard Andrews and David Lord, @
@ South West Universities Regional Computer Centre, @
@ Claverton Down, Bath BA2 7AY, U.K. @
@ @
@ @
@ ---------------------------------------------------------------- @
@ @
@ @
@ Version 1.01 (October 1986) @
@ @
@ Fixes by : Dave Allum and David Lord, SWURCC. @
@ ---------------------------------------------------------------- @
</source>
 
Next follow a number of "mode declarations". Mode is the Algol 68 term for a type.
<pre>
 
MODE KMT_BUFFER IS (96)BYTE;
<source lang="algol68">
MODE KMT_BUFFERKMT_STRING IS REF(96)BYTE;
MODE KMT_STRINGKMT_WORD IS REF()BYTE;
MODE KMT_WORD IS REF()BYTE;
MODE KMT_MTM_VALUES IS ANY
(LONG WORD LW_VALUE,
MODE KMT_MTM_VALUES IS ANY
( LONG WORDINT LW_VALUELI_VALUE,
LONG INTREF WORD LI_VALUE RW_VALUE,
REF WORDINT RW_VALUERI_VALUE,
REF INT LONG WORD RI_VALUERLW_VALUE,
REF LONG WORDINT RLW_VALUERLI_VALUE,
REF()BYTE LONG INT RLI_VALUERVB_VALUE,
REF()REF()BYTE RVB_VALUE,RVRVB_VALUE);
REF()REF()BYTE RVRVB_VALUE);
MODE KMT_PP_PACKET_STATISTICS_S IS STRUCT
(INT INPUT_TOTAL,
MODE KMT_PP_PACKET_STATISTICS_S IS STRUCT
OUTPUT_TOTAL);
(INT INPUT_TOTAL,
</pre>
OUTPUT_TOTAL);
</source>
 
The first type is an array of 96 bytes; the next two are references (pointers) to arrays of bytes. KMT_MTM_VALUES is a union type allowing a variety of different types to appear. Note that WORD is a 32-bit unsigned integer, INT is a 32-bit signed integer; LONG makes it 64 bits. The last option in the union is marked REF()REF()BYTE, which means it is a pointer to an array whose members are pointers to arrays of bytes.
 
Line 87 ⟶ 84:
 
The program continues by declaring external procedures on which the module depends. RESPONSE indicates a return value containing error information:
<pre>
 
EXT PROC (RESPONSE) KMT_UI;
<source lang="algol68">
EXT PROC (RESPONSE) KMT_UI;
EXT PROC (REF INT,INT,RESPONSE) KMT_PH;
EXT PROC (REF INT,INT,RESPONSE) KMT_PH;
EXT PROC (REF INT,REF INT,RESPONSE) KMT_PP_GET_PACKET,
EXT PROC (REF INT,REF INT,BOOL,RESPONSE) KMT_PP_GET_PACKET KMT_PP_SEND_PACKET,
PROC (INT,INT,BOOLREF()BYTE,RESPONSE) KMT_PP_SEND_PACKET,KMT_PP_BUILD_STRING_PACKET_DATA;
</pre>
PROC (REF()BYTE,RESPONSE) KMT_PP_BUILD_STRING_PACKET_DATA;
</source>
 
and also some external variables:
<pre>
 
EXT REF () BYTE KMT_VERSION;
<source lang="algol68">
EXT REF () BYTE KMT_VERSION;
EXT REF BOOL ASG_ROUTE;
EXT REF BOOL ASG_ROUTE;
EXT REF()KMT_MTM_VALUES KMT_MTM_AREA;
EXT REF()KMT_MTM_VALUESBYTE KMT_MTM_AREAMTM_TEXT;
EXT REF()BYTE MTM_TEXTINT MTM_TEXT_LEN;
EXT REF INT()REF ()BYTE MTM_TEXT_LENMTM_RECALL_DATA;
</pre>
EXT REF ()REF ()BYTE MTM_RECALL_DATA;
</source>
 
The rest of the program consists of a number of procedure definitions. One of these, which actually defines the entry point to the program, is reproduced here:
<pre>
 
GLOBAL STATIC (<STATUS 5;PSPACE 10001; TEMPLATE>) PROC KERMIT_THE_FROG IS
<source lang="algol68">
((<LIT "COMMAND">) REF()BYTE OPTION,
GLOBAL STATIC (<STATUS 5;PSPACE 10001; TEMPLATE>) PROC KERMIT_THE_FROG IS
( (<LIT "COMMAND" >) REF()BYTE OPTIONVME_FILE,
(<LIT "" >) REF()BYTE VME_FILEREM_FILE,
(<KEY RESPONSE;DEF N'RESULT>) RESPONSE RESULT):
(<LIT "" >) REF()BYTE REM_FILE,
(<KEY RESPONSE;DEF N'RESULT>) RESPONSE RESULT):
BEGIN
BEGIN
()BYTE JSV_NAME := "ASG"; @ obtain value for ASG_ROUTE bool @
CTM_JS_READ(JSV_NAME,NIL,NIL,ASG_ROUTE,RC_IGNORED);
()BYTE JSV_NAME := "ASG"; @ obtain value for ASG_ROUTE bool @
IF RC_IGNORED NE 0 THEN ASG_ROUTE := FALSE FI;
CTM_JS_READ(JSV_NAME,NIL,NIL,ASG_ROUTE,RC_IGNORED);
IF RC_IGNORED NE 0 THEN ASG_ROUTE := FALSE FI;
@ verify parameter references (parameter values validated later): @
@ OPTION must be of mode REF () BYTE, may not be ZLR or NIL @
@ verify parameter references (parameter values validated later): @
@ OPTION VME_FILE must be of mode REF () BYTE, may not be ZLR, or NIL must not be NIL @
@ VME_FILEREM_FILE must be of mode REF () BYTE, may be ZLR, must not be NIL @
@ REM_FILE must be of mode REF () BYTE, may be ZLR, must not be NIL @
UNLESS (VERIFY OPTION AND VALIDR OPTION)
UNLESS AND (VERIFY OPTIONVME_FILE AND (VALIDR OPTIONVME_FILE OR NOT(VME_FILE IS NIL)))
AND (VERIFY VME_FILEREM_FILE AND (VALIDR VME_FILEREM_FILE OR NOT(VME_FILEREM_FILE IS NIL)))
THEN @ invalid parameter reference @
AND (VERIFY REM_FILE AND (VALIDR REM_FILE OR NOT(REM_FILE IS NIL)))
RESULT := 10002 @ ARCH_INACCESSIBLE_PARAMETER @
THEN @ invalid parameter reference @
RESULT := 10002 @ ARCH_INACCESSIBLE_PARAMETER @
ELSF @ create resource block @
CTM_JS_BEGIN(RESULT);
ELSF @ create resource block @
CTM_JS_BEGIN( RESULT); <= 0
THEN @ resource block created @
RESULT <= 0
LONG LONG WORD KERMIT_RESULT;
THEN @ resource block created @
LONG ANY((3)LONG WORD KERMIT_RESULTAS_LW,(6) WORD AS_W) PARAMS;
PARAMS.AS_LW := (BDESC OPTION,BDESC VME_FILE,BDESC REM_FILE);
ANY((3)LONG WORD AS_LW,(6) WORD AS_W) PARAMS;
PARAMS.AS_LW := (BDESC OPTION,BDESC VME_FILE,BDESC REM_FILE);
@ set up program error handler @
IF KMT_EH_INFORM_PE_CONTINGENCY(RESULT);
@ set up program error handler @
IF KMT_EH_INFORM_PE_CONTINGENCY( RESULT); > 0
THEN @ failed to set error handler @
RESULT > 0
SKIP
THEN @ failed to set error handler @
ELSF CTM_JS_CALL(NIL,PDESC KERMIT_SUPPORT,PARAMS.AS_W,KERMIT_RESULT,
SKIP
RESULT); @ create firewall @
ELSF CTM_JS_CALL(NIL,PDESC KERMIT_SUPPORT,PARAMS.AS_W,KERMIT_RESULT,
RESULT); @ create firewall<= @0
THEN @ either exited normally or via CTM_STOP @
RESULT <= 0
RESULT := IF (S'S'KERMIT_RESULT) <= 0
THEN @ either exited normally or via CTM_STOP @
THEN 0 @ ignore warnings @
RESULT := IF (S'S'KERMIT_RESULT) <= 0
THEN 0ELSE 52000 @ error return common @ ignore warningsresultcode @
ELSE 52000 @ error return common resultcode @FI
FI;
FI;
CTM_JS_END(RC_IGNORED) @ end resource block @
FI
CTM_JS_END(RC_IGNORED) @ end resource block @

FIEND
</pre>
END
</source>
 
Features to note here include:
 
* The declaration of the procedure is decorated with annotations that define a command line syntax allowing the program to be called from SCL, or used from an interactive shell with prompting for default parameter values.
* Procedure calls prefixed CTM are calls to the "Compiler Target Machine", an [[API]] offered by the VME operating system.
 
* "JSV" means "job space variable", VME's term for an [[environment variable]], and the call on CTM_JS_READ reads the value of the variable.
* Procedure calls prefixed CTM are calls to the "Common Target Machine", an [[API]] offered by the VME operating system.
 
* "JSV" means "job space variable", VME's term for an environment variable, and the call on CTM_JS_READ reads the value of the variable.
 
* UNLESS means "if not"; ELSF means "else if".
 
* LONG LONG WORD declares a 128-bit integer, which is a native type supported by the 2900 architecture
* The bulk of the processing is delegated to another procedure, KERMIT_SUPPORT, which can be found in the same module. This is called indirectly via the operating system CTM_JS_CALL, similar to an exec() call on Unix systems; this ensures clean failure handling and tidying up of any resources in the event of a fatal error. The PDESC keyword constructs a "procedure descriptor": essentially it treats KERMIT_SUPPORT as a [[first-class function]] which can be passed as an argument to another function, making CTM_JS_CALL a [[higher-order function]] that calls its supplied argument with appropriate error handling.
 
* The bulk of the processing is delegated to another procedure, KERMIT_SUPPORT, which can be found in the same module. This is called indirectly via the operating system CTM_JS_CALL, similar to an exec() call on Unix systems; this ensures clean failure handling and tidying up of any resources in the event of a fatal error. The PDESC keyword constructs a "procedure descriptor": essentially it treats KERMIT_SUPPORT as a first-class function which can be passed as an argument to another function, making CTM_JS_CALL a higher-order function that calls its supplied argument with appropriate error handling.
 
==References==