In an object-oriented program, a message is sent to an object to invoke the
method defined for the class of the object. In our language, expressions are
evaluated within the scope of a base object (the object receiving the message)
and possibly a context object (the object defining the current implementation
of the method). The run-time environment includes a method map , a
collection of context method maps
, and an object store
. As
our expressions do not alter object state, the store is static.
The semantics of expressions is given by the judgment
. The
expression
is evaluated with base object
, within the scope of
context object
, in the current run-time environment of the dynamic
method map
, the collection of context method maps
, and static
object store
. The expression evaluates to the object
. The
judgments for epsilon, identifier, self and context expression are simply:
Method invocation is the only composite expression. The evaluation of
expression is given by the following rule:
The reference is evaluated to produce the receiver object
.
The reference
is evaluated to produce the context object
that will modify the dynamic method map for the duration of the call. The
dynamic method map
yields the current method implementation
and
its defining context object
for the signature
. The dynamic method map is updated based on the
implementations given in the static map defined by the collection of context
method maps
for the class of the context object
. Finally, the
expression
is evaluated for the receiver object
, within the
scope of the context object
, given the new run-time environment
consisting of the store
, the collection of context method maps
, and the updated dynamic method map
. The result is the object
.
Notice that the lookup of the implementation of method is performed
before the update of the dynamic method map
. An alternative semantics
is to first do the update of
and then do the lookup. We feel that we
have chosen the more natural possibility.