.sh 1 "System Components (Compilation Units)"
.(b
system_component  ::=  global_component   #   resource_component
.)b
.lp
A program is constructed from global and resource components.
Global components declare objects shared by resource components.
Resource components declare patterns for resources.
Resources have two parts:  a specification (spec) and a body.
These parts can be compiled together or separately,
as discussed in Sec. 2.2.
The actual way in which components are compiled, linked,
and loaded is implementation dependent;
see the manual pages in Appendix 4 for details
on the current implementation.
.pp
Globals and resources are stored in source files that have an `.sr' suffix.
They are compiled by invoking the compiler with a set
of source file names.
All compilation takes place in the context of a special directory
named `Interfaces'.
This directory is either in the current working directory (the default)
or in a directory named on the command line.
The `Interfaces' directory
contains files that collectively
provide symbol table information for all
system components that have been compiled.
Recompiling a component causes the old information
associated with that component to disappear.
.pp
A component must be compiled after any component it imports
or extends.
Obviously a resource body must be compiled after its spec.
.pp
System components all have user-declared identifiers.
This same identifier may appear after
the end of the component.
.sh 2 "Globals"
.(b
global_component  ::=  |1@global@  global_identifier
		       /1    global_declaration{{*}}
                       /1@end@  global_identifier{{o}}
.)b
.(b
global_declaration  ::=  constant_declaration   #   type_declaration   #   optype_declaration
.)b
.lp
A global component contains declarations global to some or all resources.
These declarations define symbolic constants,
user-defined data types,
or user-defined communication channels (operation types).
The role of global components is analogous to `.h' files
in C programs; they differ in that they are separately compiled
and imported rather than being textually included.
.PS L
%Examples:
.sp .5
	global Characters
	  const TAB := char(9)     	# Horizontal Tab
	  const CR := char(13)     	# Carriage Return
	end

	global Node
	  type node = rec(value : int; link : ptr node)
	  type head = ptr node
	  type tail = ptr node
	end
.PE
.sh 2 "Resources"
.(b
resource_component  ::=  separate_spec   #   spec_and_body   #   separate_body
.)b
.(b
separate_spec  ::=  abstract_spec  #  concrete_spec  @separate@
.)b
.(b
spec_and_body  ::=  concrete_spec  resource_body
.)b
.(b
separate_body  ::=  @body@  resource_identifier  resource_body
.)b
.lp
Resources are the main building block in SR programs.
They are the primary compilation unit, the unit of abstraction and
encapsulation, and the unit for program linking.
.pp
A \fIconcrete resource\fR has a specification and a body.
Instances of concrete resources are created dynamically.
An \fIabstract resource\fR has only a specification.
It is used to define an interface that is subsequently
extended and implemented by one or more other resources.
.pp
Resource specs and bodies can be compiled separately.
The spec and body of a concrete resource can also
be combined.
Two examples of complete resources are shown below;
more complex examples are presented in Sec. 9.
.PS L
%Examples:
.sp .5
	resource simple()
	  initial
	    write("Hello world.")
	  end
	end

	resource factorial()
	  op fact(k : int) returns f : int
	  process main
	    var n : int
	    writes("How many factorials?  "); read(n); write()
	    fa i := 1 to n -> write(i, "factorial is", fact(i)) af
	  end
	  proc fact(k) returns f
	    if k<0 -> f := -1
	    [] k=0 or k=1 -> f := 1
	    [] k>1 -> f := k*fact(k-1)
	    fi
	  end
	end factorial
.PE
.sh 3 "Resource Specifications"
.(b
abstract_spec  ::=  |1@resource@  resource_identifier
                    /1    spec_component{{*}}
                    /1@end@  resource_identifier{{o}}

concrete_spec  ::=  |1@resource@  resource_identifier  (  parameter_spec{{*}}  )   #
                    /1@resource@  resource_identifier
                    /1    spec_component{{*}}
                    /1@body@  resource_identifier  (  parameter_spec{{*}}  )
.)b
.(b
spec_component  ::=  |1import_clause   #   extend_clause   #   operation_declaration   #
                     /1constant_declaration   #   type_declaration   #   optype_declaration
.)b
.(b
import_clause  ::=  @import@  global_or_resource_identifier  ,{{+}}
.)b
.(b
extend_clause  ::=  @extend@ global_or_resource_identifier  ,{{+}}
.)b
.lp
A resource specification describes the interface between a
resource and other components.
All objects declared in a resource spec are automatically
exported.
An import clause is used to acquire access to objects exported
by other components.
The spec for a concrete resource also gives the
parameterization for instances of that resource.
Resource parameters must be passed by value.
.pp
A resource can also extend another resource or global component.
The effect is to bring in all declarations from the
extended component, including import and extend clauses,
just as if they were being declared in the
resource containing @extend@.
This is similar to simply repeating the declarations
of the inherited objects, except the declaration
context might be different since the inherited
objects are declared in the context of their original declarations,
not in the context of the @extend@.
Extending a component also implicitly imports
the extended component.\**
.(f
\**Care should be taken when using @extend@ together with @import@
since it is illegal to import a component more than once,
whether explicitly or implicitly.
.)f
.pp
If more than one component is extended, the extended
components are inherited in the order they are named in the extend clause(s).
Unlike @import@, the effect of @extend@ is recursive:
a resource inherits the objects declared in resources
it extends, as well as in resources they extend, and so on.
.pp
If a resource neither imports nor exports any objects,
it has no spec components.
In this case, the keyword @body@ and the second
instance of the resource identifier may be omitted,
as shown in the @factorial@ resource.
However, such a resource still has a spec, which consists
simply of the resource identifier and parameters.
Thus, instances of the resource can be created by other
resources that import it.
.PS L
%Examples:
.sp .5
	resource Stack             # spec of a concrete resource
	  type result = enum(OK, OVERFLOW, UNDERFLOW)
	  op push(item : int) returns r : result
	  op pop(res item : int) returns r : result
	body Stack(size : int) separate
.sp .5
	resource Queue             # spec of an abstract resource
	  op insert(item : int)
	  op remove() returns item : int
	end
.sp .5
	resource ReadQueue         # extend Queue with read operation
	  extend Queue
	  op read() returns item : int   # read item at front of queue
	body ReadQueue(maxsize : int) separate
.PE
.sh 3 "Resource Bodies"
.(b
resource_body  ::=  |1body_component*
                    /1@end@  resource_identifier{{o}}
.)b
.(b
body_component  ::=  |1declaration   #   proc   #   process   #   import_clause   #
                     /1initialization   #   finalization
.)b
.(b
initialization  ::=  @initial@  block  @end@  @initial@{{o}}
.)b
.(b
finalization  ::=  @final@  block  @end@  @final@{{o}}
.)b
.(b
block  ::=  block_component{{*}}
.)b
.(b
block_component  ::=  declaration   #   statement   #   import_clause
.)b
.lp
A resource body gives the implementation of a concrete resource.
The body contains procs, which implement actions,
and declarations,
which introduce objects shared by all components inside the body.
The body can also contain processes,
which are special forms of procs (see Sec. 4).
A body can optionally include one initialization component and/or
one finalization component.
The initialization component is executed when the resource is created;
the finalization component is executed when the resource is destroyed
(see Sec. 6.3).
.pp
Note that body components can be declared in any order.
For example, declarations and procs may be intermixed.
This is useful for grouping together variables
and procs that use them.
Similarly, declarations and statements within blocks may be intermixed.
For example, an array's size can depend on an input value.
Also note that resource bodies and blocks may be empty;
this is sometimes useful when developing a program.
Finally, note that both resource bodies and blocks can contain
import clauses.
.PS L
%Example:
.sp .5
	body Stack    # exclusive access to each instance required
	  var store[1:size] : int, top : int := 0
	  proc push(item) returns r
	    if top<size -> top++; store[top] := item; r := OK
	    [] top=size -> r := OVERFLOW
	    fi
	  end
	  proc pop(item) returns r
	    if top>0 -> item := store[top]; top--; r := OK
	    [] top=0 -> r := UNDERFLOW
	    fi
	  end
	end Stack
.PE
.sh 2 "Scope Rules and Naming"
.lp
All objects are visible from the point of their declaration
to the end of the block in which they are declared.
Blocks include global components, resources, and procs
as well as the syntactic construct named `block' defined earlier.
A resource spec and its body together form a single block;
thus, objects declared in the spec cannot be redeclared
in the resource declaration portion of the body.
Objects are also visible in nested blocks until an object
with the same identifier is declared in such a nested block.
Although it is generally bad programming practice,
it is valid in a nested block to reference an object declared
in an outer block,
and then to declare in that block an object of the same name.
.pp
Identifiers declared in the same block must generally be unique.
The exceptions are record fields, and parameter and result
identifiers.
These identifiers are required to be unique only
with respect to others in the same record definition,
resource parameters, or operation specification.
.pp
An object exported from a global or spec component is visible
within components that import it from the point of the import
clause to the end of the importing block.
Imported objects are generally referenced by a \fIqualified name\fR of
the form component_identifier.object_identifier.
Hence, imported objects can have the same names as local ones.
However, if the name of an imported object is unique in
the importing scope and does not conflict with the name
of a predefined function,
it is not necessary to use a qualified name.
.sh 2 "Program Execution"
.lp
Execution of a program begins with implicit
creation of one instance of the main resource
(see Appendix 3).
That resource's initialization code is executed;
it can in turn create other resources.
.pp
Execution of a program terminates immediately when
@stop@ is executed or an error occurs.
Otherwise, when all processes become terminated or blocked,
the main resource is implicitly destroyed.
If that resource contains finalization code,
it is executed; this enables the programmer to regain control
one last time, perhaps to print summary statistics.
Subsequent termination halts execution entirely.
.pp
At present, no distributed termination detection algorithm
is implemented.
Thus programs that execute on multiple virtual machines must
be terminated by execution of @stop@.
