Oberon || Compiler & Tools || Library || Module Index || Search Engine
The grammar is given in EBNF (extended Backus-Naur form), nonterminals are set in italic, terminals either in double quotes or in bold (in case of keywords):
Abstraction = AnyText "\n%%\n" TypeDecl [ProxyParams] { Operation } "\n%%\n" AnyText . ProxyParams = PROXY PARAMS "\n" { ProxyParameter } . ProxyParameter = TransferType Identifier Type "\n" . TransferType = REF | COPY | COPYORNIL | LCOPY | BaseType . TypeDecl = [PERSISTENT] (SERIAL|PARALLEL) TYPE QualIdent "\n" . Operation = OPERATION Identifier "\n" { Parameter } . Parameter = ParamType Identifier Type "\n" . ParamType = (IN | OUT | INOUT | RVAL) TransferType | RETURNS SUCCESS . BaseType = (* one of the basetypes which are supported by NetIO *) Type = Identifier | QualIdent | ARRAY OF CHAR . AnyText = (* Oberon declarations *) .
The text which defines an abstraction is divided into three parts which are separated by lines which just contain a %%-token (this construct is similar to yacc(1) and lex(1)). The first and the last part are plain Oberon text which are taken as provided without further checking. The part in the middle defines the abstraction and is replaced by the Oberon declarations and procedures which are generated by genrem. Note that (unlike as in Oberon) newlines are not considered as white space but as separators (as defined by the grammar).
The abstraction is defined by the type of the objects we are operating on together with some parameters of RemoteObjects (TypeDecl and ProxyParams) which is followed by an unlimited number of operations (Operation).
The optional keyword PERSISTENT must be given if the type is an extension of PersistentDisciplines.Object (extensions just of PersistentObjects.Object are not useful in this context). The selection SERIAL or PARALLEL is mapped to the associated access mode RemoteObjects.AccessMode of RemoteObjects. The type itself is specified by the qualified type identifier which is imported from the module which defines the abstraction. RemoteObjects allows the creation of proxy objects to be parameterized by the supporting module. These parameters may be optionally given as ProxyParams.
The rest of this section specifies the operations of the abstraction together with their parameters. The names of the operations are to be given as simple identifiers (not qualified) and must match exactly the name of the operation in the module which defines the abstraction. Each parameter is to be given on an extra line and is specified by its parameter type, its transfer type, its identifier, and its Oberon type. Note that the order of parameters is significant and must match exactly the order of the formal parameters of the associated procedure.
Oberon supports two parameter types: call by value and call by reference (so-called VAR-parameters). The semantics of call by reference cannot be hold in full for operations across address space boundaries. A substitute for this technique is call by value return where, on invocation, a copy is made of the parameter (as in the case of call by value), and, on returning, a copy of the possibly updated value of this parameter is assigned back to the actual parameter.
Following parameter types are supported by genrem:
IN call by value INOUT call by value return OUT like call by value return but just returning a value RVAL like OUT but as RETURN-valueNote that the return value is handled like other parameters here except that it must be given as RVAL-parameter. Consequently, no more than one RVAL-parameter may be specified.
The transfer type specifies how values are to be converted into sequences of bytes. Currently, following transfer types are supported:
REF RemoteObjects.Export and RemoteObjects.Import COPY PersistentObjects.Write and PersistentObjects.Read, COPYORNIL PersistentObjects.WriteObjectOrNIL and PersistentObjects.ReadObjectOrNIL LCOPY LinearizedStructures.Write and LinearizedStructures.Read Byte NetIO.WriteByte and NetIO.ReadByte Char NetIO.WriteChar and NetIO.ReadChar Boolean NetIO.WriteBoolean and NetIO.ReadBoolean ShortInt NetIO.WriteShortInt and NetIO.ReadShortInt Integer NetIO.WriteInteger and NetIO.ReadInteger LongInt NetIO.WriteLongInt and NetIO.ReadLongInt Real NetIO.WriteReal and NetIO.ReadReal LongReal NetIO.WriteLongReal and NetIO.ReadLongReal Set NetIO.WriteSet and NetIO.ReadSet String NetIO.WriteString and NetIO.ReadString ConstString NetIO.WriteConstString and NetIO.ReadConstString Event PersistentEvents.Write and PersistentEvents.Read
Instead of the parameter type and the transfer type it is possible to specify RETURNS SUCCESS in cases of a BOOLEAN-valued RETURN-type.
The Oberon type of the parameter may be given as type identifier (for one of the Oberon base types) or as qualified identifier (if it is defined elsewhere) or as ARRAY OF CHAR for strings.
The trailer must contain
CreateProxy needs and is allowed to use the Services.Type of the proxy object type type and the filled interface record if. Both variables are global and initialized by InitIFs. Further, CreateProxy should call RelatedEvents.QueueEvents for the created proxy object.
If proxy parameters were specified by PROXY PARAMS, genrem generates a type declaration for ProxyParameters and the necessary interface procedures for PersistentObjects. Note that CreateProxyParams should be used then to create the proxy parameter object in GetParams.
In some cases it may be necessary to add more declarations and procedures to the resulting module text. Additional declarations with the exception of procedures may be given in the header. Further procedures may be added to trailer but not to the header.
genrem RemoteXXX.rm >RemoteXXX.omThis rule can be easily put into makefiles for GNU-make (see mmo):
GenremSrc := $(shell echo *.rm) GenremTargets := $(patsubst %.rm,%.om,$(GenremSrc)) $(GenremTargets): %.om: %.rm genrem $^ >$@
DEFINITION IntSequences; IMPORT Objects, Services; TYPE IntSequence = POINTER TO IntSequenceRec; IntSequenceRec = RECORD (Services.ObjectRec) END; NextProc = PROCEDURE (is: IntSequence) : INTEGER; SkipProc = PROCEDURE (is: IntSequence; positions: INTEGER); RewindProc = PROCEDURE (is: IntSequence); Interface = POINTER TO InterfaceRec; InterfaceRec = RECORD (Objects.ObjectRec) next: NextProc; skip: SkipProc; rewind: RewindProc; END; PROCEDURE Next(is: IntSequence) : INTEGER; PROCEDURE Skip(is: IntSequence; positions: INTEGER); PROCEDURE Rewind(is: IntSequence); PROCEDURE Init(is: IntSequence; if: Interface); END IntSequences.An associated input file for genrem:
MODULE RemoteIntSequences; IMPORT IntSequences, Messages, NetIO, RelatedEvents, RemoteObjects, Services, Streams; %% SERIAL TYPE IntSequences.IntSequence OPERATION Next RVAL Integer nextval INTEGER OPERATION Skip IN Integer positions INTEGER OPERATION Rewind %% PROCEDURE CreateProxy(VAR object: Services.Object; params: PersistentObjects.Object); VAR is: IntSequence; BEGIN NEW(is); Services.Init(is, type); IntSequences.Init(is, if); RelatedEvents.QueueEvents(is); object := is; END CreateProxy; BEGIN InitIFs; END RemoteIntSequences.
Following error messages may be generated by genrem:
Oberon || Compiler & Tools || Library || Module Index || Search Engine