Article View: comp.lang.modula2
Article #1552Re: multiple implementations
From: Bill Seurer
Date: Mon, 12 Oct 1992 20:07
Date: Mon, 12 Oct 1992 20:07
122 lines
4337 bytes
4337 bytes
In article <718850232snx@black.demon.co.uk>, tchannon@black.demon.co.uk (Tim Channon) writes:
|> > Does anyone know of any good techniques for managing multiple implementation
|> > modules? A trivial example is for a Stack to have an array implementation
|> > and a linked list implementation. How do you name your files and how do
|>
|> Pragmas?
|>
|> TC.
|> E-mail: tchannon@black.demon.co.uk or tchannon@cix.compulink.co.uk
|>
Nah, you can do it with straight Modula-2 and a bit of indirection. I
wrote an IBM technical report on this but I don't know if they are
available externally.
This technique was used in something called Cedar Objects that was
mentioned in a class I took one time. This very topic (multiple
implementations using a "single" definition) was the advanced assignment
for the class. Almost everyone (including me) had great difficulty
getting it right in the class, but it turns out not to be so tough after
all.
Basically it goes like this... (Excuse any Modula-2 typos)
1) Create a definition module for an abstraction using an opaque type.
However, leave out the "create" function.
Example: Simple (compressed to save space) CARDINAL stack.
DEFINITION MODULE Stack;
TYPE
T (*Opaque*);
PROCEDURE Push (stack: T;
item: CARDINAL);
PROCEDURE Pop (stack: T): CARDINAL;
END Stack;
2) Implement the abstraction as a pointer to a record which contains
the data's address and a bunch of procedure variables, one for each
procedure in the definition.
IMPLEMENTATION MODULE Stack;
IMPORT PrivateStack;
TYPE
T = PrivateStack.T;
PROCEDURE Push (stack: T;
item: CARDINAL);
BEGIN
stack^.Push (stack, item);
END Push;
PROCEDURE Pop (stack: T): CARDINAL;
BEGIN
RETURN stack^.Pop (stack);
END Pop;
END Stack.
DEFINITION MODULE PrivateStack;
TYPE
T = POINTER TO StackRecord;
PushProc = PROCEDURE (T, CARDINAL);
PopProc = PROCEDURE (T): CARDINAL;
StackRecord = RECORD
data: SYSTEM.ADDRESS;
pop: PopProc;
push: PushProc;
END;
END PrivateStack;
No PrivateStack implementation is needed.
3) Now create the separate implementations.
I will show just one.
DEFINITION MODULE ArrayStack;
IMPORT Stack;
PROCEDURE Create(): Stack.T;
END ArrayStack.
IMPLEMENTATION MODULE ArrayStack;
IMPORT Stack, PrivateStack;
TYPE
RealData = POINTER TO RealDataRecord;
RealDataRecord = RECORD
topIndex: CARDINAL;
data: ARRAY[1..99] OF CARDINAL;
END;
PROCEDURE Create(): Stack.T;
VAR
new: PrivateStack.T;
data: RealData;
BEGIN
NEW (new);
new^.pop := Pop;
new^.push := Push;
NEW (data);
new^.data := data;
new^.data^.top := 0;
RETURN Stack.T(new);
END Create;
PROCEDURE Pop...as you'd expect;
PROCEDURE Push...as you'd expect;
END ArrayStack.
4) Use your Nifty New Type! You call the specific Create procedure and
the general procedures for everything else.
I bet I made a mistake up there somewhere, but it does work (I have used it)
and there are various things one can do to improve it (like exposing the
opaque type to reduce the calls). Of course this is
a poor example but it was quite short.
One thing for sure that isn't quite right are the castings to and from
the opaque type. I have found how this must be done is quite compiler
specific.
--
- Bill Seurer Language and Compiler Development IBM Rochester, MN
Internet: BillSeurer@vnet.ibm.com America On-Line: BillSeurer@aol.com
Technical Details
Message-ID:
<1992Oct12.200703.11026@rchland.ibm.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!iggy.GW.Vitalink.COM!cs.widener.edu!eff!sol.ctr.columbia.edu!zaphod.mps.ohio-state.edu!darwin.sura.net!gatech!news.ans.net!newsgate.watson.ibm.com!yktnews!admin!nordruth!seurerReferences:
<01GPRDWLKI6Q0004IE@RCKHRST1.BITNET> <718850232snx@black.demon.co.uk>Show Full Headers
Complete Article Headers
Newsgroups: comp.lang.modula2 Path: arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!iggy.GW.Vitalink.COM!cs.widener.edu!eff!sol.ctr.columbia.edu!zaphod.mps.ohio-state.edu!darwin.sura.net!gatech!news.ans.net!newsgate.watson.ibm.com!yktnews!admin!nordruth!seurer From: seurer@rchland.vnet.ibm.com (Bill Seurer) Subject: Re: multiple implementations Sender: news@rchland.ibm.com Message-ID: <1992Oct12.200703.11026@rchland.ibm.com> Date: Mon, 12 Oct 1992 20:07:03 GMT Reply-To: BillSeurer@vnet.ibm.com Disclaimer: This posting represents the poster's views, not necessarily those of IBM References: <01GPRDWLKI6Q0004IE@RCKHRST1.BITNET> <718850232snx@black.demon.co.uk> Nntp-Posting-Host: nordruth.rchland.ibm.com Organization: IBM Rochester Lines: 122