git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5776 626c5289-ae23-0410-ae9c-e8d60b6d4f22
360 lines
No EOL
10 KiB
HTML
360 lines
No EOL
10 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<title>SWIG and Modula-3</title>
|
|
</head>
|
|
<body bgcolor="#FFFFFF">
|
|
<a name="n1"></a><H1>18 SWIG and Modula-3</H1>
|
|
<!-- INDEX -->
|
|
<ul>
|
|
<li><a href="#n2">Overview</a>
|
|
<li><a href="#n3">Preliminaries</a>
|
|
<ul>
|
|
<li><a href="#n4">Compilers</a>
|
|
<li><a href="#n5">Additional Commandline Options</a>
|
|
</ul>
|
|
<li><a href="#n6">Modula-3 typemaps</a>
|
|
<ul>
|
|
<li><a href="#n7">Inputs and outputs</a>
|
|
<li><a href="#n8">Exceptions</a>
|
|
<li><a href="#n9">Subranges, Enumerations, Sets</a>
|
|
<li><a href="#n10">Objects</a>
|
|
<li><a href="#n11">Example</a>
|
|
</ul>
|
|
</ul>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
This chapter describes SWIG's support of
|
|
<a href="http://www.m3.org/">Modula-3</a>.
|
|
You should be familiar with the
|
|
<a href="SWIG.html">basics</a>
|
|
of SWIG,
|
|
especially typemaps.
|
|
|
|
<a name="overview"></a>
|
|
<a name="n2"></a><H2>18.1 Overview</H2>
|
|
|
|
|
|
<p>
|
|
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.
|
|
The Modula-3 generator was already useful for interfacing
|
|
to the
|
|
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
|
|
PLPlot
|
|
</a>
|
|
library.
|
|
|
|
<!--
|
|
<p>
|
|
The following introduction may help you
|
|
when you are uncertain about using
|
|
the Modula-3 support or SWIG at all.
|
|
|
|
|
|
<a name="whycxx"></a>
|
|
<a name="n3"></a><DISABLED>18.1.1 Why not scripting ?</DISABLED>
|
|
|
|
|
|
<p>
|
|
SWIG started as wrapper from the fast compiled languages C and C++
|
|
to high level scripting languages like Python.
|
|
Although scripting languages are designed
|
|
to make programming life easier
|
|
by hiding machine internals from the programmer
|
|
there are several aspects of todays scripting languages
|
|
that are unfavourable in my opinion.
|
|
|
|
<p>
|
|
Besides C, C++, Cluster (a Modula derivate for Amiga computers)
|
|
I evaluated several scripting like languages in the past:
|
|
Different dialects of BASIC,
|
|
Perl, ARexx (a variant of Rexx for Amiga computers),
|
|
shell scripts.
|
|
I found them too inconsistent,
|
|
too weak in distinguishing types,
|
|
too weak in encapsulating pieces of code.
|
|
Eventually I have started several projects in Python
|
|
because of the fine syntax.
|
|
But when projects became larger
|
|
I lost the track.
|
|
I got convinced that one can not have
|
|
maintainable code in a language
|
|
that is not statically typed.
|
|
In fact the main advantages of scripting languages
|
|
e.g. matching regular expressions,
|
|
complex built-in datatypes like lists, dictionaries,
|
|
are not advantages of the language itself
|
|
but can be provided by function libraries.
|
|
|
|
<a name="whymodula3"></a>
|
|
<a name="n4"></a><DISABLED>18.1.2 Why Modula-3 ?</DISABLED>
|
|
|
|
|
|
<p>
|
|
Modula-3 is a compiler language
|
|
in the tradition of Niklas Wirth's Modula 2,
|
|
which is in turn a successor of the popular Pascal.
|
|
I have chosen Modula-3
|
|
because of its
|
|
logical syntax,
|
|
strong modularization,
|
|
the type system which is very detailed
|
|
for machine types compared to other languages.
|
|
Of course it supports all of the modern games
|
|
like exceptions, objects, garbage collection, threads.
|
|
While C++ programmers must
|
|
control three languages,
|
|
namely the preprocessor, C and ++,
|
|
Modula-3 is made in one go
|
|
and the language definition is really compact.
|
|
|
|
On the one hand Modula-3 can be safe
|
|
(but probably less efficient) in normal modules
|
|
while providing much static and dynamic safety.
|
|
On the other hand you can write efficient
|
|
but less safe code in the style of C
|
|
within UNSAFE modules.
|
|
|
|
<p>
|
|
Unfortunately Modula's safety and strength
|
|
requires more writing than scripting languages do.
|
|
Today if I want to safe characters
|
|
I prefer Haskell (similar to OCAML) -
|
|
it's statically typed, too.
|
|
|
|
|
|
<a name="whycxx"></a>
|
|
<a name="n5"></a><DISABLED>18.1.3 Why C / C++ ?</DISABLED>
|
|
|
|
|
|
<p>
|
|
|
|
Although it is no problem to write Modula-3 programs
|
|
that performs as fast as C
|
|
most libraries are not written in Modula-3 but in C.
|
|
Fortunately the binary interface of most function libraries
|
|
can be addressed by Modula-3.
|
|
Even more fortunately even non-C libraries may provide C header files.
|
|
This is where SWIG becomes helpful.
|
|
|
|
<a name="whycxx"></a>
|
|
<a name="n6"></a><DISABLED>18.1.4 Why SWIG ?</DISABLED>
|
|
|
|
|
|
<p>
|
|
|
|
The C headers and the possibility to interface to C libraries
|
|
still leaves the work for you
|
|
to write Modula-3 interfaces to them.
|
|
To make things comfortable you will also need
|
|
wrappers that convert between high-level features of Modula-3
|
|
(garbage collecting, exceptions)
|
|
and the low level of the C libraries.
|
|
|
|
<p>
|
|
|
|
SWIG converts C headers to Modula-3 interfaces for you.
|
|
You could call the C functions without loss
|
|
of efficiency but it won't be joy
|
|
because you could not pass TEXTs
|
|
or open arrays and
|
|
you would have to process error return codes
|
|
rather then exceptions.
|
|
But using some typemaps SWIG will also generate
|
|
wrappers that bring the whole Modula-3 comfort to you.
|
|
If the library API is ill designed
|
|
writing appropriate typemaps can be still time-consuming.
|
|
E.g. C programmers are very creative to work-around
|
|
missing data types like (real) enumerations and sets.
|
|
You should turn such work-arounds back to the Modula-3 way
|
|
otherwise you lose static safety and consistency.
|
|
|
|
<p>
|
|
|
|
But you have still a problem:
|
|
C library interfaces are often ill.
|
|
They lack for certain information
|
|
because C compilers wouldn't care about.
|
|
You should integrate detailed type information
|
|
by adding <tt>typedef</tt>s and <tt>const</tt>s
|
|
and you should persuade the C library programmer
|
|
to add this information to his interface.
|
|
Only this way other language users can benefit from your work
|
|
and only this way you can easily update your interfaces
|
|
when a new library version is released.
|
|
|
|
You will realise that writing <b>good</b> SWIG interfaces
|
|
is very costly and it will only amortise
|
|
when considering evolving libraries.
|
|
|
|
<p>
|
|
|
|
Without SWIG you would probably never consider
|
|
to call C++ libraries from Modula-3.
|
|
But with SWIG this is worth a consideration.
|
|
SWIG can write C wrappers to C++ functions and object methods
|
|
that may throw exceptions.
|
|
In fact it breaks down C++ libraries to C interfaces
|
|
which can be in turn called from Modula-3.
|
|
To make it complete you can hide the C interface
|
|
with Modula-3 classes and exceptions.
|
|
|
|
<p>
|
|
|
|
Although SWIG does the best it can do
|
|
it can only serve as a one-way strategy.
|
|
That means you can use C++ libraries
|
|
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.
|
|
-->
|
|
|
|
<a name="preliminaries"></a>
|
|
<a name="n3"></a><H2>18.2 Preliminaries</H2>
|
|
|
|
|
|
<a name="compilers"></a>
|
|
<a name="n4"></a><H3>18.2.1 Compilers</H3>
|
|
|
|
|
|
There are different Modula-3 compilers around:
|
|
cm3, pm3, ezm3, Klagenfurth Modula-3, Cambridge Modula-3.
|
|
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.
|
|
|
|
<a name="commandline"></a>
|
|
<a name="n5"></a><H3>18.2.2 Additional Commandline Options</H3>
|
|
|
|
|
|
There some experimental command line options
|
|
that prevent SWIG from generating interface files.
|
|
Instead files are emitted that may assist
|
|
writing SWIG interface files.
|
|
|
|
<table>
|
|
<tr>
|
|
<th>Modula-3 specific options</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-generateconst <file></td>
|
|
<td>
|
|
Disable generation of interfaces and wrappers.
|
|
Instead generate code for computing numeric values of constants.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-generaterename <file></td>
|
|
<td>
|
|
Disable generation of interfaces and wrappers.
|
|
Instead generate suggestions for %rename.
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-generatetypemap <file></td>
|
|
<td>
|
|
Disable generation of interfaces and wrappers.
|
|
Instead generate templates for some basic typemaps.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<a name="typemaps"></a>
|
|
<a name="n6"></a><H2>18.3 Modula-3 typemaps</H2>
|
|
|
|
|
|
<a name="inoutparam"></a>
|
|
<a name="n7"></a><H3>18.3.1 Inputs and outputs</H3>
|
|
|
|
|
|
Each C procedure has a bunch of inputs and outputs.
|
|
Aside from global variables
|
|
inputs are passed as call arguments,
|
|
outputs are updated reference arguments and
|
|
the function value.
|
|
|
|
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.
|
|
A further typemap may specify
|
|
the direction that is used for certain parameters.
|
|
|
|
<a name="exceptions"></a>
|
|
<a name="n8"></a><H3>18.3.2 Exceptions</H3>
|
|
|
|
|
|
Modula-3 provides another possibility
|
|
of an output of a function: exceptions.
|
|
|
|
Any piecec 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.
|
|
|
|
The <tt>RAISES</tt> clause is controlled
|
|
by typemaps with the <tt>except</tt> extension.
|
|
|
|
<a name="ordinals"></a>
|
|
<a name="n9"></a><H3>18.3.3 Subranges, Enumerations, Sets</H3>
|
|
|
|
|
|
<a name="class"></a>
|
|
<a name="n10"></a><H3>18.3.4 Objects</H3>
|
|
|
|
|
|
<a name="typemap_examlpe"></a>
|
|
<a name="n11"></a><H3>18.3.5 Example</H3>
|
|
|
|
|
|
The generation of wrappers in Modula-3 needs very fine control
|
|
to take advantage of the language features.
|
|
Here is an example of a generated wrapper
|
|
where almost everything is generated by a typemap:
|
|
|
|
<blockquote><pre>
|
|
<I> (* %relabel m3wrapinmode m3wrapinname m3wrapintype m3wrapindefault *)</I>
|
|
PROCEDURE Name (READONLY str : TEXT := "" )
|
|
<I> (* m3wrapoutcheck:throws *)</I>
|
|
: NameResult RAISES {E} =
|
|
VAR
|
|
arg0 : C.char_star; <I>(* m3wrapretvar *)</I>
|
|
arg1 : C.char_star; <I>(* m3wrapargvar *)</I>
|
|
arg2 : C.int;
|
|
result : RECORD
|
|
<I> (*m3wrapretname m3wraprettype*)</I>
|
|
unixPath : TEXT;
|
|
<I> (*m3wrapoutname m3wrapouttype*)</I>
|
|
checksum : CARDINAL;
|
|
END;
|
|
BEGIN
|
|
TRY
|
|
arg1 := M3toC.SharedTtoS(str); <I>(* m3wrapinconv *)</I>
|
|
IF Text.Length(arg1) > 10 THEN <I>(* m3wrapincheck *)</I>
|
|
RAISE E("str too long");
|
|
END;
|
|
<I> (* m3wrapretraw m3wrapargraw *)</I>
|
|
arg0 := MessyToUnix (arg1, arg2);
|
|
result.unixPath := M3toC.CopyStoT(arg0); <I>(* m3wrapretconv *)</I>
|
|
result.checksum := arg2; <I>(* m3wrapoutconv *)</I>
|
|
IF result.checksum = 0 THEN <I>(* m3wrapoutcheck *)</I>
|
|
RAISE E("invalid checksum");
|
|
END;
|
|
FINALLY
|
|
M3toC.FreeSharedS(str,arg1); <I>(* m3wrapfreearg *)</I>
|
|
END;
|
|
END Name;
|
|
</pre></blockquote>
|
|
|
|
|
|
</body>
|
|
</html> |