Modula-3: introduction, ordinal types, file types, features, objects

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6178 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
amigalemming 2004-08-30 20:10:59 +00:00
commit 3deb35f298
2 changed files with 221 additions and 87 deletions

View file

@ -642,11 +642,16 @@
<!-- INDEX -->
<ul>
<li><a href="Modula3.html#modula3_overview">Overview</a>
<ul>
<li><a href="Modula3.html#whyscripting">Why not scripting ?</a>
<li><a href="Modula3.html#whymodula3">Why Modula-3 ?</a>
<li><a href="Modula3.html#whycpp">Why C / C++ ?</a>
<li><a href="Modula3.html#whyswig">Why SWIG ?</a>
</ul>
<li><a href="Modula3.html#conception">Conception</a>
<ul>
<li><a href="Modula3.html#cinterface">Interfaces to C libraries</a>
<li><a href="Modula3.html#noplan">Interfaces to C++ libraries</a>
<li><a href="Modula3.html#cppinterface">No plan?</a>
<li><a href="Modula3.html#cppinterface">Interfaces to C++ libraries</a>
</ul>
<li><a href="Modula3.html#preliminaries">Preliminaries</a>
<ul>
@ -660,10 +665,14 @@
<li><a href="Modula3.html#class">Objects</a>
<li><a href="Modula3.html#imports">Imports</a>
<li><a href="Modula3.html#exceptions">Exceptions</a>
<li><a href="Modula3.html#swig_pragmas">Pragmas</a>
<li><a href="Modula3.html#typemap_example">Example</a>
<li><a href="Modula3.html#remarks">Remarks</a>
</ul>
<li><a href="Modula3.html#hints">More hints to the generator</a>
<ul>
<li><a href="Modula3.html#features">Features</a>
<li><a href="Modula3.html#pragmas">Pragmas</a>
</ul>
<li><a href="Modula3.html#remarks">Remarks</a>
</ul>
<!-- INDEX -->

View file

@ -8,11 +8,16 @@
<!-- INDEX -->
<ul>
<li><a href="#modula3_overview">Overview</a>
<ul>
<li><a href="#whyscripting">Why not scripting ?</a>
<li><a href="#whymodula3">Why Modula-3 ?</a>
<li><a href="#whycpp">Why C / C++ ?</a>
<li><a href="#whyswig">Why SWIG ?</a>
</ul>
<li><a href="#conception">Conception</a>
<ul>
<li><a href="#cinterface">Interfaces to C libraries</a>
<li><a href="#noplan">Interfaces to C++ libraries</a>
<li><a href="#cppinterface">No plan?</a>
<li><a href="#cppinterface">Interfaces to C++ libraries</a>
</ul>
<li><a href="#preliminaries">Preliminaries</a>
<ul>
@ -26,10 +31,14 @@
<li><a href="#class">Objects</a>
<li><a href="#imports">Imports</a>
<li><a href="#exceptions">Exceptions</a>
<li><a href="#swig_pragmas">Pragmas</a>
<li><a href="#typemap_example">Example</a>
<li><a href="#remarks">Remarks</a>
</ul>
<li><a href="#hints">More hints to the generator</a>
<ul>
<li><a href="#features">Features</a>
<li><a href="#pragmas">Pragmas</a>
</ul>
<li><a href="#remarks">Remarks</a>
</ul>
<!-- INDEX -->
@ -40,7 +49,8 @@ This chapter describes SWIG's support of
You should be familiar with the
<a href="SWIG.html#SWIG">basics</a>
of SWIG,
especially typemaps.
especially
<a href="Typemaps.html">typemaps</a>.
<H2><a name="modula3_overview"></a>20.1 Overview</H2>
@ -49,28 +59,31 @@ especially typemaps.
The Modula-3 support is very basic and highly experimental!
Many features are still not designed satisfyingly
and I need more discussion about the odds and ends.
Don't rely on any feature, incompatible changes are likely in the future!
The Modula-3 generator was already useful for interfacing
to the libraries
</p>
<ol>
<li>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
PLPlot
</a>
and
</li>
<li>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/">
FFTW
</a>
.
<!--
<p>
The following introduction may help you
when you are uncertain about using
the Modula-3 support or SWIG at all.
</p>
</a> .
</li>
</ol>
<a name="n3"></a><DISABLED>18.1.1 Why not scripting ?</DISABLED>
I took some more time to explain
why I think it's right what I'm doing.
So the introduction got a bit longer than it should ... ;-)
<H3><a name="whyscripting"></a>20.1.1 Why not scripting ?</H3>
<p>
@ -106,12 +119,12 @@ are not advantages of the language itself
but can be provided by function libraries.
</p>
<a name="n4"></a><DISABLED>18.1.2 Why Modula-3 ?</DISABLED>
<H3><a name="whymodula3"></a>20.1.2 Why Modula-3 ?</H3>
<p>
Modula-3 is a compiler language
in the tradition of Niklas Wirth's Modula 2,
in the tradition of Niklaus Wirth's Modula 2,
which is in turn a successor of the popular Pascal.
I have chosen Modula-3
because of its
@ -144,7 +157,7 @@ it's statically typed, too.
</p>
<a name="n5"></a><DISABLED>18.1.3 Why C / C++ ?</DISABLED>
<H3><a name="whycpp"></a>20.1.3 Why C / C++ ?</H3>
<p>
@ -157,7 +170,7 @@ Even more fortunately even non-C libraries may provide C header files.
This is where SWIG becomes helpful.
</p>
<a name="n6"></a><DISABLED>18.1.4 Why SWIG ?</DISABLED>
<H3><a name="whyswig"></a>20.1.4 Why SWIG ?</H3>
<p>
@ -228,7 +241,7 @@ with Modula-3 (even with call back functions),
but it's certainly not possible to smoothly
integrate Modula-3 code into a C / C++ project.
</p>
-->
<H2><a name="conception"></a>20.2 Conception</H2>
@ -256,7 +269,7 @@ that SWIG puts together.
<tr>
<td>Pragma <tt>&lt;* EXTERNAL *&gt;</tt></td>
<td>Precedes a declaration of a PROCEDURE that is implemented
in an external library instead of a Modula-3 implemenation.</td>
in an external library instead of a Modula-3 module.</td>
</tr>
<tr>
<td>Pragma <tt>&lt;* CALLBACK *&gt;</tt></td>
@ -265,7 +278,7 @@ by external library code.</td>
</tr>
<tr>
<td>Module <tt>Ctypes</tt></td>
<td>Contains Modula-3 types that match some basic C type.</td>
<td>Contains Modula-3 types that match some basic C types.</td>
</tr>
<tr>
<td>Module <tt>M3toC</tt></td>
@ -279,21 +292,30 @@ In each run of SWIG the Modula-3 part
generates several files:
</p>
<table border summary="Modula-3 generated files">
<tr>
<th>Module name scheme</th>
<th>Identifier for <tt>%insert</tt></th>
<th>Description</th>
</tr>
<tr>
<td>Module<tt>Raw.i3</tt></td>
<td><tt>m3rawintf</tt></td>
<td>Declaration of types that are equivalent to those of the C library,
<tt>EXTERNAL</tt> of the C library functions</td>
<tt>EXTERNAL</tt> procedures as interface to the C library functions</td>
</tr>
<tr>
<td>Module<tt>Raw.m3</tt></td>
<td><tt>m3rawimpl</tt></td>
<td>Almost empty.</td>
</tr>
<tr>
<td>Module<tt>.i3</tt></td>
<td><tt>m3wrapintf</tt></td>
<td>Declaration of comfortable wrappers to the C library functions.</td>
</tr>
<tr>
<td>Module<tt>.m3</tt></td>
<td><tt>m3wrapimpl</tt></td>
<td>Implementation of the wrappers that
convert between Modula-3 and C types,
check for validity of values,
@ -301,6 +323,7 @@ generates several files:
and raises exceptions.</td>
</tr>
<tr>
<td><tt>m3makefile</tt></td>
<td><tt>m3makefile</tt></td>
<td>Add the modules above to the Modula-3 project and
specify the name of the Modula-3 wrapper library
@ -315,7 +338,7 @@ generates several files:
</table>
Here's a scheme of how the function calls to Modula-3 wrappers
a redirected to C library functions:
are redirected to C library functions:
<table summary="Modula-3 C library">
<tr>
<td align=center>
@ -349,7 +372,27 @@ a redirected to C library functions:
</table>
<H3><a name="noplan"></a>20.2.2 Interfaces to C++ libraries</H3>
<p>
I have still no good conception how one can split C library interfaces
into type oriented interfaces.
A Module in Modula-3 represents an Abstract DataType
(or call it a static classes, i.e. a class without virtual methods).
E.g. if you have a principal type, say <tt>Database</tt>,
it is good Modula-3 style to set up one Module with the name <tt>Database</tt>
where the database type is declared with the name <tt>T</tt>
and where all functions are declared that operates on it.
</p>
<p>
The normal operation of SWIG is to generate a fixed set of files per call.
To generate multiple modules one has to write one SWIG interface
(different SWIG interfaces can share common data) per module.
Identifiers belonging to a different module may ignored (<tt>%ignore</tt>)
and the principal type must be renamed (<tt>%typemap</tt>).
</p>
<H3><a name="cppinterface"></a>20.2.2 Interfaces to C++ libraries</H3>
<p>
@ -404,7 +447,7 @@ Wrapping C++ libraries arises additional problems:
</p>
<ul>
<li>
Is it sensible to wrap C++ class with Modula-3 classes?
Is it sensible to wrap C++ classes with Modula-3 classes?
</li>
<li>
How to find the wrapping Modula-3 class
@ -447,28 +490,6 @@ There is no C++ library I wrote a SWIG interface for,
so I'm not sure if this is possible or sensible, yet.
</p>
<H3><a name="cppinterface"></a>20.2.3 No plan?</H3>
<p>
I have still no good conception how one can split C library interfaces
into type oriented interfaces.
I.e. if you have a principal type, say <tt>Database</tt>,
it is good Modula-3 style to set up one Module with the name <tt>Database</tt>
where the database type is declared with the name <tt>T</tt>
and where all functions are declared that operates on it.
Thus Modules in Modula-3 are a kind of static classes.
</p>
<p>
The normal operation of SWIG is to generate a fixed set of files per call.
To generate multiple modules one has to write one SWIG interface
(different SWIG interfaces can share common data) per module.
Identifiers belonging to a different module may ignored (<tt>%ignore</tt>)
and the principal type must be renamed (<tt>%typemap</tt>).
</p>
<H2><a name="preliminaries"></a>20.3 Preliminaries</H2>
@ -481,7 +502,7 @@ SWIG itself does not contain compiler specific code
but the library file
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
may do so.
For testing examples I used Critical Mass cm3.
For testing examples I use Critical Mass cm3.
<H3><a name="commandline"></a>20.3.2 Additional Commandline Options</H3>
@ -492,13 +513,14 @@ that prevent SWIG from generating interface files.
Instead files are emitted that may assist you
when writing SWIG interface files.
<table summary="Modula-3 specific options">
<table border summary="Modula-3 specific options">
<tr>
<th>Modula-3 specific options</th>
<th>Description</th>
</tr>
<tr>
<td>-generateconst &lt;file&gt;</td>
<td valign=top>-generateconst &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead write code for computing numeric values of constants
@ -513,7 +535,7 @@ All of them can invoke C code dynamically
for computing the macro values.
But if one wants to turn them into Modula-3
integer constants, enumerations or set types,
the value of these expressions has to be known statically.
the values of these expressions has to be known statically.
Although definitions like <tt>(1 &lt;&lt; FLAG_MAXIMIZEWINDOW)</tt>
must be considered as good C style
they are hard to convert to Modula-3
@ -523,16 +545,16 @@ Thus I implemented these switch
to extract all constant definitions
and write a C program that output the values of them.
It works for numeric constants only
and treats all of them as double.
and treats all of them as <tt>double</tt>.
Future versions may generate a C++ program
that can detect the type of the macros
by overloaded output functions.
Then strings can also be processable.
Then strings can also be processed.
</td>
</tr>
<tr>
<td>-generaterename &lt;file&gt;</td>
<td valign=top>-generaterename &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead generate suggestions for <tt>%rename</tt>.
@ -550,7 +572,7 @@ with a name suggestion generated by a simple heuristic.
</tr>
<tr>
<td>-generatetypemap &lt;file&gt;</td>
<td valign=top>-generatetypemap &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead generate templates for some basic typemaps.
@ -573,11 +595,21 @@ the function value.
<p>
Each C type can have several typemaps
that apply only in case the types are used
as input argument, as output argument,
or as return value.
that apply only in case if a type is used
for an input argument, for an output argument,
or for a return value.
A further typemap may specify
the direction that is used for certain parameters.
I have chosen this separation
in order to be able to write general typemaps for the typemap library
<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
.
In the library code the final usage of the type is not known.
Using separate typemaps for each possible use
allows appropriate definitions for each case.
If these pre-definitions are fine
then the direction of the function parameter
is the only hint the user must give.
</p>
<p>
@ -585,7 +617,7 @@ The typemaps specific to Modula-3 have a common name scheme:
A typemap name starts with "m3",
followed by "raw" or "wrap"
depending on whether it controls the generation
of the Module<tt>.i3</tt> or the Module<tt>Raw.i3</tt>, respectively.
of the Module<tt>Raw.i3</tt> or the Module<tt>.i3</tt>, respectively.
It follows an "in" for typemaps applied to input argument,
"out" for output arguments, "arg" for all kind of arguments,
"ret" for returned values.
@ -763,9 +795,56 @@ consist of the following parts:
<H3><a name="ordinals"></a>20.4.2 Subranges, Enumerations, Sets</H3>
Subranges, enumerations, and sets are machine oriented types
that make Modula very strong and expressive compared
with the type systems of many other languages.
<ul>
<li>
Subranges are used for statically restricted choices of integers.
</li>
<li>
Enumerations are used for named choices.
</li>
<li>
Sets are commonly used for flag (option) sets.
</li>
</ul>
Using them extensively makes Modula code very safe and readable.
C supports enumerations, too, but they are not as safe as the ones of Modula.
Thus they are abused for many things:
For named choices, for integer constant definitions, for sets.
To make it complete every way of defining a value in C
(<tt>#define</tt>, <tt>const int</tt>, <tt>enum</tt>)
is somewhere used for defining something
that must be handled completely different in Modula-3
(<tt>INTEGER</tt>, enumeration, <tt>SET</tt>).
I played around with several <tt>%feature</tt>s and <tt>%pragma</tt>s
that split the task up into converting
the C bit patterns (integer or bit set)
into Modula-3 bit patterns (integer or bit set)
and change the type as requested.
See the corresponding
<a href="../../Examples/modula3/enum/example.i">example</a>.
This is quite messy and not satisfying.
So the best what you can currently do is
to rewrite constant definitions manually.
Though this is a tedious work
that I'd like to automate.
<H3><a name="class"></a>20.4.3 Objects</H3>
Declarations of C++ classes are mapped to <tt>OBJECT</tt> types
while it is tried to retain the access hierarchy
"public - protected - private" using partial revelation.
Though the
<a href="../../Examples/modula3/class/example.i">implementation</a>
is not really useful, yet.
<H3><a name="imports"></a>20.4.4 Imports</H3>
@ -808,34 +887,16 @@ of an output of a function: exceptions.
Any piece of Modula-3 code that SWIG inserts
due to a typemap can raise an exception.
This way you can also convert an error code
from a C function into an Modula-3 exception.
from a C function into a Modula-3 exception.
The <tt>RAISES</tt> clause is controlled
by typemaps with the <tt>except</tt> extension.
by typemaps with the <tt>throws</tt> extension.
If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
contains code that may raise the exceptions <tt>OSError.E</tt>
you should declare
<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
<H3><a name="swig_pragmas"></a>20.4.6 Pragmas</H3>
<table border summary="Modula-3 pragmas">
<tr>
<td>unsafe</td>
<td><tt>%pragma(modula3) unsafe="true";</tt></td>
<td>Mark the raw interface modules as <tt>UNSAFE</tt>.
This will be necessary in many cases.</td>
</tr>
<tr>
<td>library</td>
<td><tt>%pragma(modula3) library="m3fftw";</tt></td>
<td>Specifies the library name for the wrapper library to be created.
It should be distinct from the name of the library to be wrapped.</td>
</tr>
</table>
<H3><a name="typemap_example"></a>20.4.7 Example</H3>
<H3><a name="typemap_example"></a>20.4.6 Example</H3>
The generation of wrappers in Modula-3 needs very fine control
@ -877,7 +938,71 @@ where almost everything is generated by a typemap:
END Name;
</pre></blockquote>
<H3><a name="remarks"></a>20.4.8 Remarks</H3>
<H2><a name="hints"></a>20.5 More hints to the generator</H2>
<H3><a name="features"></a>20.5.1 Features</H3>
<table border summary="Modula-3 features">
<tr>
<th>Feature</th>
<th>Example</th>
<th>Description</th>
</tr>
<tr>
<td>multiretval</td>
<td><tt>%m3multiretval get_box;</tt> or
<tt>%feature("modula3:multiretval") get_box;</tt></td>
<td>Let the denoted function return a <tt>RECORD</tt>
rather than a plain value.
This <tt>RECORD</tt> contains all arguments with "out" direction
including the return value of the C function (if there is one).
If more than one argument is "out"
then the function <b>must</b> have the <tt>multiretval</tt> feature activated,
but it is explicitly requested from the user to prevent mistakes.</td>
</tr>
<tr>
<td>constnumeric</td>
<td><tt>%constnumeric(12) twelve;</tt> or
<tt>%feature("constnumeric","12") twelve;</tt></td>
<td>This feature can be used to tell Modula-3's back-end of SWIG
the value of an identifier.
This is necessary in the cases
where it was defined by a non-trivial C expression.
This feature is used by the
<tt>-generateconst</tt> <a href="#options">option</a>.
In future it may be generalized to other kind of values
such as strings.
</td>
</tr>
</table>
<H3><a name="pragmas"></a>20.5.2 Pragmas</H3>
<table border summary="Modula-3 pragmas">
<tr>
<th>Pragma</th>
<th>Example</th>
<th>Description</th>
</tr>
<tr>
<td>unsafe</td>
<td><tt>%pragma(modula3) unsafe="true";</tt></td>
<td>Mark the raw interface modules as <tt>UNSAFE</tt>.
This will be necessary in many cases.</td>
</tr>
<tr>
<td>library</td>
<td><tt>%pragma(modula3) library="m3fftw";</tt></td>
<td>Specifies the library name for the wrapper library to be created.
It should be distinct from the name of the library to be wrapped.</td>
</tr>
</table>
<H2><a name="remarks"></a>20.6 Remarks</H2>
<ul>