| # Annex C: Collected Abstract Syntax |

This annex incorporates all of the vdm-sl value and type definitions together with an explanation of their function in the language model.

### C.1 Values

The value of tokens in a vdm-sl model expresses some concept which the functions and operations of an explicit version of the model - encapsulating the run-time semantics ('m-' meaning functions) - must define. The descriptive notes attached to each token value and group form a natural language description of the meta-semantics involved.

values

1. The first group of tokens is used to model the uses (see the Accesses type) to which some entity may be put.
   Read : token = mk_token("Read") ;
   Write : token = mk_token("Write") ;
   Use : token = mk_token("Use") ;
   Once : token = mk_token("Once") ;
   - Read This access value is needed to use a reader routine for an entity.
   - Write This access value is needed to use a writer routine for some entity.
   - Use This access value is needed to invoke a method forming part of some entity, not being a reader or writer routine. For a reader/writer routine this signifies shared usage!
   - Once This access value limits the number of reader operations to one. This is strongly connected to the iterator 'once' argument.
2. The four tokens below are used to differentiate the various kinds of class which form part of the abstract syntax (see the Class_Kind type).
   External : token = mk_token("External") ;
   Abstract : token = mk_token("Abstract") ;
   Immutable : token = mk_token("Immutable") ;
   Reference : token = mk_token("Reference") ;
   - External This value for the class kind implies that the associated definition should be translated in accordance with the semantics attached to external classes.
   - Abstract The class definition associated with this token value should be translated in accordance with the semantic rules for an abstract class - ie that there are no associated value or implementation components.
   - Immutable Immutable classes are to be translated in such a way that their features all provide value semantics (ie any operation producing a value of the class does so without altering arguments to the method involved and without alteration to any internal state.
   - Reference A reference class, as its name implies refers to the state of the object which is held in computer storage. Aliassing may occur. The class may have immutable or mutable semantics.
3. The kinds of method (ie those which have different semantics) are modelled by the two following tokens.
   One_Shot : token = mk_token("Routine") ;
   Multiple : token = mk_token("Iter") ;
   - One-ShotThis method kind permits a single invocation at any one point in the source text of a Sather program. That invocation has local state during execution.
   - MultipleThis method kind corresponds to iterators which may be invoked multiple times (as they must be in some loop construct). Internal state is retained between successive invocations in different passes through the loop.
4. Sather defines two kinds of literal value which are represented by the two following tokens.
   Numeric : token = mk_token("Numbers") ;
   Text : token = mk_token("Text") ;
   - Numeric A Numeric value token may be in any form permitted by the language. The textual representation of such a form is irrelevant in the sense that the value represented may appear in any numeric context and be stored in any numeric class object for which that value has meaning.
   - Text A literal of class text is encoded in the repertoire and encoding in which the program is implemented. This may not necessarily be the same as when the program is executed.
5. The following single token has an implementation-defined name or translation-time defined name not defined by the Sather language but which an implementer is required to specify, either as a fixed name or as being determinable by the implementation when a program is actually implemented.
   Distinguished_Method : token = mk_token("implementation-defined") ;
6. The next single token is the model value of void - ie no value at all.
   Void : token = mk_token("void") ;
   - Void This value is required by the model to enable a program to test for the existence of an object and for a programmer to specify that some object does not exist.
7. The next pair of tokens give the model values of the Bit type.
   Set_Bit : token = mk_token("setbit") ;
   Clear_Bit : token = mk_token("clearbit") ;
   - Set_Bit The exact representation of a set bit in a computer is implementation defined and is neither specified nor required to be specifid by an implementation.
   - Clear_Bit The representation of a clear bit is also not defined nor required to be defined providing only that its representation is distinguishable from a set bit.
8. The following pair of tokens provide model values for the Boolean type.
   True : token = mk_token("True") ;
   False : token = mk_token("False") ;
   - True This model of the truth value true has no requirement for any equivalent fixed implementation bit-pattern representing it. An implementation may, in fact, use different representations at different places within an implemented program.
   - False This model of the truth value false must always be represented in such a way that it is distinguishable from the value true.
9. The following single token models the name of the assign feature. While this is merely a method in the conventional sense, it has a fixed semantic model of its operation - fixed by the Sather language to mean providing a value to some object - which that object retains until some other value may be assigned to it. It uses conventional store semantics.
   Assign : token = mk_token("Assign") ;
10. The following group of tokens identifies those which name routines or iterators built-in to the Sather language, not returning a value. See the Built_in_Name type for details.
    Assert : token = mk_token("assert") ;
    At : token = mk_token("@") ;
    Attach : token = mk_token("attach") ;
    Break_Iter : token = mk_token("break!") ;
    Pre_Condition : token = mk_token("pre") ;
    Post_Condition : token = mk_token("post") ;
    Quit : token = mk_token("quit") ;
    Raise : token = mk_token("raise") ;
    Return : token = mk_token("return") ;
    Synchronise : token = mk_token("sync") ;
    Unlock : token = mk_token("unlock") ;
    Until_Iter : token = mk_token("until!") ;
    While_Iter : token = mk_token("while!") ;
    Yield : token = mk_token("yield") ;
    - Assert The assert routine corresponds to the assert statement in the language. Given a logical argument the routine generates run-time code which checks that the value is true (if so doing nothing) or false (if so raising an assertion exception on the object concerned in respect of the routine or iter concerned!).
    - At This routine corresponds to the at statment of the language, taking two arguments and generating code to ensure that the action identified as one parameter will execute on a particular node of a distributed system
    - Attach This routine generates run-time code to create a new thread for executing a sequence of statements attached to the synchronisation object which is one of the two parameters.
    - Break_Iter This routine generates code to quit the currently most local executing loop.
    - Pre_Condition This routine is the same as the assert routine except that it generates a prefix code sequence to a method body.
    - Post_Condition This routine is the same as the assert routine except that it generates a suffix code sequence to a method body.
    - Quit This routine generates code to quit the currently most local executing loop in which the current invocation of the iter in which the statement appears has been invoked.
    - Raise This routine generates code to raise an exception for the object which is its argument for the routine in which the raise appears.
    - Return If there is an argument then this routine generates code so that its value is provided to the environment from which the currently executing routine was invoked, any post-condition is evaluated as is possible thread termination before resuming the code following the routine invocation containing the 'return statement'.
    - Synchronise This routine generates code so that the thread in which the routine is executing blocks until all threads attached to the same synchronisation object are either also blocking or have already terminated.
    - Unlock This routine generates code to explicitly unlock a lock held by the executing thread.
    - Until_Iter This routine generates code which evaluates the argument passed to it, if true then code is generated to quit the currently most local executing loop otherwise nothing is done.
    - While_Iter This routine generates code which evaluates the argument passed to it, if false then code is generated to quit the currently most local executing loop otherwise nothing is done.
    - Yield If there is an argument then this routine generates code so that its value is provided to the environment from which the currently executing iter was invoked, any post-condition is evaluated before saving the iter state before resuming the code following the iter invocation containing the 'yield statement'.
11. The following group of tokens identifies those which name routines built-in to the Sather language which return a value. See the Built_in_Exp_Name type for details.
    Exception : token = mk_token("exception") ;
    Initial : token = mk_token("initial") ;
    Is_void : token = mk_token("is_void") ;
    New : token = mk_token("new") ;
    Result : token = mk_token("result") ;
    Self : token = mk_token("self") ;
    - Exception This routine generates code for the function which provides the object which is the subject of the exception being handled.
    - Initial This routine generates code to save an initial value of some object which is then available for use in the post-condition of the invoking method.
    - Is_void This routine generates a test that the run-time argument is or is not void and for providing the corresponding logical value to the invoker.
    - New This routine generates code to acquire storage for an object. If the call has a run-time parameter then code to acquire storage for an array of this number of objects is generated instead.
    - Result This routine generates code to provide the value of the object returned by some routine, solely for use in a post-condition of the invoker.
    - Self This routine generates coded to provide the value of self to the invoker.

### C.2 Vdm-sl Object & Type related Types

The types in the vdm-sl model of the Sather language enable the abstract structure of an arbitrary well-formed program to be represented as the abstract syntax. This is a graph/tree structure with no circularities.

#### Accesses

Accesses is a token type, restricted by the invariant to have one of four possible access values only. It models a kind of use to which a component having this value may be put.

types
Accesses = token
inv acc ==
(acc = Read)
or (acc = Write)
or (acc = Use)
or (acc = Once) ;

#### Visibility

This type models the set of uses which may be made of an individual feature or argument. If a type feature is marked as private then a set will be empty!

Visibility = set of Accesses ;

#### Class_Kind

Class_Kind is another token type used to model the kind of semantics to be attached to a particular class definition.

Class_Kind = token
inv class ==
(kind = External)
or (kind = Abstract)
or (kind = Immutable)
or (kind = Reference) ;

#### Method_Kind

Method_Kind, another token type, models the kind of semantics to be attached to a class method - whether it is a routine or an iterator.

Method_Kind = token
inv times ==
(times = One_Shot)
or (times = Multiple) ;

#### A Complete Program

A complete program consists of the definition of the distinguished class which contains the method to be invoked by the external environment when executing the program, together with all of those classes on which it (recursively) depends.

Program ::
program_class : Class_Def
dependent_classes : set of Class_Def
inv mk_Program(dist,_) ==
dist.kind in set {Immutable, Reference}
and program_class not in set dependent_classes
and let names : set of token = {forall feat in dist.features & feat.name} in
Distinguished_Method in set names ;

#### Class_Def

This type is at the 'head' of a section of the abstract syntax. One of these is necessary for each class in a program being translated. The class kind component indicates which of the possible kinds of class is defined. In turn this may lead to different invariants and well-formedness functions as described in the body of this specification.

Class_Def ::
kind : Class_Kind
features : set of Feature
typenode : [ Type_Graph ]

#### Type_Graph

A Type graph is the structure which is used to determine type correctness for a complete compiled program. Either of the sets may, of course, be empty. It is expected that the checking of the type graph should only be done once, filling in as needed from the collection of individual class definitions.

Type_Graph ::
subtypes : set of Type_Specifier
supertypes : set of Type_Specifier ;

#### Type_Specifier

A Type_Specifier type defines the structure of individual components of a type graph - as well as the properties of an individual object instantiation.

Type_Specifier ::
id : Type_Name
args : [ set of Type_Specifier]
type_def : Class_Def ;

#### Type_Name

All types in a program require a 'name' whether explicitly specified by the programmer or library writer or generated by the implementation.

Type_Name = token ;

#### Feature

This is the principle type to be found in this abstract syntax model since each component of a class is a feature of one kind or another. It encapsulates all of the descriptors necessary to define each component and argument of the abstract type definition which is the class concept.

Feature ::
name : token
args : [ set of Feature ]
kind : [ Type_Specifier ]
value : [ Expression ]
impl : [ seq of Statement ]
vis : [ Visibility ]
ext_vis : Visibility
uses : [ Method_Kind ] ;

### C.3 Pre-defined Identity Types

The Sather language defines a number of statements and expressions which have pre-defined semantics.

#### Assign_Name

Because of its special nature in being able to change state, this type has been included - even though it only has one possible value.

Assign_Name = token
inv aname ==
aname = Assign ;

#### Built-in_Name

Those routines which correspond to Sather statement kinds or iters which are implementation routines which do not generate code to return some object to the environment from which the method invoked the statement routines are modelled in this class. Note that this is done by merely identifying them as token names. The related semantics of the routine are defined in the body of this specification.

Built_in_Name = token
inv bname ==
(bname = Assert)
or (bname = At)
or (bname = Attach)
or (bname = Break_Iter)
or (bname = Pre_Condition)
or (bname = Post_Condition)
or (bname = Quit)
or (bname = Raise)
or (bname = Return)
or (bname = Synchronise)
or (bname = Unlock)
or (bname = Until_Iter)
or (bname = While_Iter)
or (bname = Yield) ;

#### Built-in_Exp_Name

Those routines which correspond to Sather statement kinds or iters which are implementation routines which generate code to return some object to the environment from which the method invoked the statement routines, are modelled in this class. Note that this is done by merely identifying them as token names. The related semantics of the routine are defined in the body of this specification.

Built_in_Exp_Name = token
inv bien ==
(bien = Exception)
or (bien = Initial)
or (bien = Is_void)
or (bien = New)
or (bien = Result)
or (bien = Self) ;

#### Defined_Feature_Name

This type defines the names of all of those routines which have been written by the programmer, a list which must be disjoint from those corresponding to values, statement or expression routines.

Defined_Feature_Name = token
inv dfn ==
(dfn not in set {ex | ex : Built_In_Name})
and (dfn not in set {ex | ex : Built_In_Exp_Name})
and (dfn not in set {ex1 | ex1 : Built_in_Value})
and dfn <> Assign_Name ;

### C.4 Statement Types

The statements which form the implementation of a feature or feature application are modelled in the structures shown below which is deliberately intended to 'merge' concurrency features into the main syntax tree structures.

#### Statement

The Statement type has three principal variant types provided by the language. Note in particular that all actions are carried out by a call statement of some kind.

Statement =
Guarded_Statement
| Bounded_Statement
| Call_Statement ;

#### Guarded_Statement

The Guarded statement comprises all variants of statement for which execution of some actions is conditional upon the result of evaluating some logical expression. Note that the 'lock' statement alternatives specified in Sather 1.1 have intentionally been separated into a Select statement and a Lock statement although their meaning has not changed.

Guarded_Statement =
Case_Statement
| Typecase_Statement
| Select_Statement
| Protect_Statement
| Lock_Statement
| Conditional_Statement ;

#### Bounded_Statement

Bounded statement variants all have the common property that a possible sequence of statements is delimited by markers which dictate how and where the statements are to be executed.

Bounded_Statement =
Loop_Statement
| Parallel_Statement
| Fork_Statement
| Location_Statement ;

#### Call_Statement

The Call statement comprises all of the statement variants which carry out the actions of a program.

Call_Statement =
Assign_Call
| Predefined_Application
| Feature_Application ;

### C.4.1 Guarded Statements

All of this group are variants of the case statement with, for some, additional protection clauses.

Case_Statement ::
when : [seq of Guard_Clause]
default : [seq of Statement] ;
Guard_Clause ::
val : Expression
body : [seq of Statement] ;
Typecase_Statement =
Case_Statement ;
Protect_Statement ::
body : [seq of Statement]
prot : Case_Statement ;
Select_Statement =
Case_Statement ;
Lock_Statement =
Case_Statement ;
Conditional_Statement =
Case_Statement ;

### C.4.2 Bounded Statements

Apart from the location statement all of these forms of statement are just a sequence of statements.

Loop_Statement ::
impl : [seq of Statement] ;
Parallel_Statement ::
impl : [seq of Statement] ;
Fork_Statement ::
impl : [seq of Statement] ;
Location_Statement ::
objs : set of Feature
impl : [seq of Statement] ;

### C.5 Method Calls

The call statement comprises all of the statement variants which carry out the actions of a program.

Call_Statement =
Assign_Call
| Application_Statement

in which the assignment call is treated specially. There are two variants of application statement - one pre-defined by the language and the other user written.

Application_Statement =
| Predefined_Call
| Feature_Application ;

The expression evaluation calls are analogous to the Application_Statement above, thus -

Eval_Expression =
Predefined_Call
| Feature_Application ;

#### Predefined Calls

The similarity between prredefined call statements and predefined call expressions extends to them having the same abstract syntax - with different invariants, thus for the statement variant -

Predefined_Call ::
id : token
args : Feature
impl : Feature
rval : [Value_Expression] ;
inv mk_Predefined_Call(expid,_,_,val) ==
expid in set dom Built_In_Name
and val = nil

and for the expression variant -

Predefined_Call ::
id : token
args : Feature
impl : Feature
rval : [ Value_Expression] ;
inv mk_Predefined_Call(expid,_,_,val) ==
expid in set dom Built_In_Exp_Name
and val <> nil

#### Feature_Application

Feature application is again common to both expression and statement, the only restriction occurring in the well-formedness function in relation to returned value (or not).

Feature_Application ::
id : Defined_Feature_Name
body : Feature ;

### C.6 Expression Types

This last section of the abstract syntax contains types which define the various result yielding operations of the language.

#### Expression

An expression may either yield a value (which may be further used in obtaining another value) or a location (ie a reference to a storage location).

Expression =
Store_Expression
| Value_Expression ;

#### Store_Expression

An expression which returns a handle to some storage location may provide this in one of three ways :-

1. A reference to some entity in the environment in which the program is executing. This is provided by that environment and is merely a token as far as the executing program is concerned.
2. Some local memory or port address to which the program may (or may not, of course!) have some form of access. This address forms part of the computer in which the program is executing.
3. Some non-local memory or port address to which the program has some access by virtue of being a distributed program.

Store_Expression =
Reference_Value
| Eval_Near
| Eval_Far ;

#### Reference_Value

This type models an uninterpretable token provided to a program from its external environment.

Reference_Value = token ;

#### Eval_Near

This type models a location which is on the computer system which created the location.

Eval_Near = Address ;

#### Eval_Far

This type models a location which is not on the computer system which created the location.

Eval_Far = Address ;

#### Address

An Address models a computer location which may be derived by an implementation as the result of using programming expressions. It refers to a location which is defined by the Sather language. The actual location (or indeed address token) indicated during any program execution is implementation dependent.

Address = token ;

#### Value_Expression

A value expression yields a value of some program type the semantics of which are defined by the defining class. The way in which such values may be manipulated is not defined by the Sather language.

Value_Expression =
Bit_Pattern
| Literal_Value
| Built_in_Value
| Eval_Expression ;

#### Bit_Pattern

The bit pattern is the fundamental way of expressing values of any kind. Any semantics attributed to it are defined by the appropriate class definition. The length of the sequence for any given class is implementation defined.

Bit_Pattern = seq of Bit ;

#### Value_Domain

The Sather language definition requires that numeric and textual values may be expressed when writing programs. The form in which such values appear is necessarily implementation defined.

NOTE | It is important to note that the language specifies no operations on such values unless they are converted into a required library (or other) numeric or text class which defines those pre-defined operations such as add, minus, times, etc.

Value_Domain = token
inv vdom ==
(vdom = Numeric)
or (vdom = Text) ;

#### Literal_Value

Sather defines two general forms of user-specifiable literal values - numbers and text (including individual characters). This type models both the token value and the kind of literal it represents.

Literal_Value ::
code : Bit_Pattern
kind : Value_Domain ;

#### Language defined literal values

Sather defines a small number of literal values which are modelled by the following small group of types.

Built_in_Value =
Bit
| Boolean
| Void ;
Bit = token
inv bitval ==
(bitval = Set_Bit)
or (bitval = Clear_Bit) ;
Boolean = token
inv bval ==
(bval = True)
or (bval = False) ;

| Specification Index |  | Language Index

Comments or enquiries should be made to Keith Hopper. Page last modified: Wednesday, 17 May 2000. |