added basic Modula-3 support
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5776 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
ad57fc3545
commit
483d8b4367
57 changed files with 6645 additions and 380 deletions
360
SWIG/Doc/Manual/Modula3.html
Normal file
360
SWIG/Doc/Manual/Modula3.html
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
<!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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue