Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / html / swig / Modula3.html
CommitLineData
86530b38
AT
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<html>
3<head>
4<title>SWIG and Modula-3</title>
5<link rel="stylesheet" type="text/css" href="style.css">
6</head>
7<body bgcolor="#FFFFFF">
8<H1><a name="Modula3"></a>20 SWIG and Modula-3</H1>
9<!-- INDEX -->
10<div class="sectiontoc">
11<ul>
12<li><a href="#modula3_overview">Overview</a>
13<ul>
14<li><a href="#whyscripting">Why not scripting ?</a>
15<li><a href="#whymodula3">Why Modula-3 ?</a>
16<li><a href="#whycpp">Why C / C++ ?</a>
17<li><a href="#whyswig">Why SWIG ?</a>
18</ul>
19<li><a href="#conception">Conception</a>
20<ul>
21<li><a href="#cinterface">Interfaces to C libraries</a>
22<li><a href="#cppinterface">Interfaces to C++ libraries</a>
23</ul>
24<li><a href="#preliminaries">Preliminaries</a>
25<ul>
26<li><a href="#compilers">Compilers</a>
27<li><a href="#commandline">Additional Commandline Options</a>
28</ul>
29<li><a href="#modula3_typemaps">Modula-3 typemaps</a>
30<ul>
31<li><a href="#inoutparam">Inputs and outputs</a>
32<li><a href="#ordinals">Subranges, Enumerations, Sets</a>
33<li><a href="#class">Objects</a>
34<li><a href="#imports">Imports</a>
35<li><a href="#exceptions">Exceptions</a>
36<li><a href="#typemap_example">Example</a>
37</ul>
38<li><a href="#hints">More hints to the generator</a>
39<ul>
40<li><a href="#features">Features</a>
41<li><a href="#pragmas">Pragmas</a>
42</ul>
43<li><a href="#remarks">Remarks</a>
44</ul>
45</div>
46<!-- INDEX -->
47
48
49
50<p>
51This chapter describes SWIG's support of
52<a href="http://www.m3.org/">Modula-3</a>.
53You should be familiar with the
54<a href="SWIG.html#SWIG">basics</a>
55of SWIG,
56especially
57<a href="Typemaps.html">typemaps</a>.
58</p>
59
60<H2><a name="modula3_overview"></a>20.1 Overview</H2>
61
62
63<p>
64The Modula-3 support is very basic and highly experimental!
65Many features are still not designed satisfyingly
66and I need more discussion about the odds and ends.
67Don't rely on any feature, incompatible changes are likely in the future!
68The Modula-3 generator was already useful for interfacing
69to the libraries
70</p>
71
72<ol>
73<li>
74<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
75PLPlot
76</a>
77</li>
78<li>
79<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/">
80FFTW
81</a> .
82</li>
83</ol>
84
85
86<p>
87I took some more time to explain
88why I think it's right what I'm doing.
89So the introduction got a bit longer than it should ... ;-)
90</p>
91
92
93<H3><a name="whyscripting"></a>20.1.1 Why not scripting ?</H3>
94
95
96<p>
97SWIG started as wrapper from the fast compiled languages C and C++
98to high level scripting languages like Python.
99Although scripting languages are designed
100to make programming life easier
101by hiding machine internals from the programmer
102there are several aspects of todays scripting languages
103that are unfavourable in my opinion.
104</p>
105
106<p>
107Besides C, C++, Cluster (a Modula derivate for Amiga computers)
108I evaluated several scripting like languages in the past:
109Different dialects of BASIC,
110Perl, ARexx (a variant of Rexx for Amiga computers),
111shell scripts.
112I found them too inconsistent,
113too weak in distinguishing types,
114too weak in encapsulating pieces of code.
115Eventually I have started several projects in Python
116because of the fine syntax.
117But when projects became larger
118I lost the track.
119I got convinced that one can not have
120maintainable code in a language
121that is not statically typed.
122In fact the main advantages of scripting languages
123e.g. matching regular expressions,
124complex built-in datatypes like lists, dictionaries,
125are not advantages of the language itself
126but can be provided by function libraries.
127</p>
128
129<H3><a name="whymodula3"></a>20.1.2 Why Modula-3 ?</H3>
130
131
132<p>
133Modula-3 is a compiler language
134in the tradition of Niklaus Wirth's Modula 2,
135which is in turn a successor of the popular Pascal.
136I have chosen Modula-3
137because of its
138logical syntax,
139strong modularization,
140the type system which is very detailed
141for machine types compared to other languages.
142Of course it supports all of the modern games
143like exceptions, objects, garbage collection, threads.
144While C++ programmers must
145control three languages,
146namely the preprocessor, C and ++,
147Modula-3 is made in one go
148and the language definition is really compact.
149</p>
150
151<p>
152On the one hand Modula-3 can be safe
153(but probably less efficient) in normal modules
154while providing much static and dynamic safety.
155On the other hand you can write efficient
156but less safe code in the style of C
157within <tt>UNSAFE</tt> modules.
158</p>
159
160<p>
161Unfortunately Modula's safety and strength
162requires more writing than scripting languages do.
163Today if I want to safe characters
164I prefer Haskell (similar to OCAML) -
165it's statically typed, too.
166</p>
167
168
169<H3><a name="whycpp"></a>20.1.3 Why C / C++ ?</H3>
170
171
172<p>
173Although it is no problem to write Modula-3 programs
174that performs as fast as C
175most libraries are not written in Modula-3 but in C.
176Fortunately the binary interface of most function libraries
177can be addressed by Modula-3.
178Even more fortunately even non-C libraries may provide C header files.
179This is where SWIG becomes helpful.
180</p>
181
182<H3><a name="whyswig"></a>20.1.4 Why SWIG ?</H3>
183
184
185<p>
186The C headers and the possibility to interface to C libraries
187still leaves the work for you
188to write Modula-3 interfaces to them.
189To make things comfortable you will also need
190wrappers that convert between high-level features of Modula-3
191(garbage collecting, exceptions)
192and the low level of the C libraries.
193</p>
194
195<p>
196SWIG converts C headers to Modula-3 interfaces for you.
197You could call the C functions without loss
198of efficiency but it won't be joy
199because you could not pass <tt>TEXT</tt>s
200or open arrays and
201you would have to process error return codes
202rather then exceptions.
203But using some typemaps SWIG will also generate
204wrappers that bring the whole Modula-3 comfort to you.
205If the library API is ill designed
206writing appropriate typemaps can be still time-consuming.
207E.g. C programmers are very creative to work-around
208missing data types like (real) enumerations and sets.
209You should turn such work-arounds back to the Modula-3 way
210otherwise you lose static safety and consistency.
211</p>
212
213<p>
214
215But you have still a problem:
216C library interfaces are often ill.
217They lack for certain information
218because C compilers wouldn't care about.
219You should integrate detailed type information
220by adding <tt>typedef</tt>s and <tt>const</tt>s
221and you should persuade the C library programmer
222to add this information to his interface.
223Only this way other language users can benefit from your work
224and only this way you can easily update your interfaces
225when a new library version is released.
226
227You will realise that writing <b>good</b> SWIG interfaces
228is very costly and it will only amortise
229when considering evolving libraries.
230</p>
231
232
233<p>
234Without SWIG you would probably never consider
235to call C++ libraries from Modula-3.
236But with SWIG this is worth a consideration.
237SWIG can write C wrappers to C++ functions and object methods
238that may throw exceptions.
239In fact it breaks down C++ libraries to C interfaces
240which can be in turn called from Modula-3.
241To make it complete you can hide the C interface
242with Modula-3 classes and exceptions.
243</p>
244
245<p>
246Although SWIG does the best it can do
247it can only serve as a one-way strategy.
248That means you can use C++ libraries
249with Modula-3 (even with call back functions),
250but it's certainly not possible to smoothly
251integrate Modula-3 code into a C / C++ project.
252</p>
253
254
255<H2><a name="conception"></a>20.2 Conception</H2>
256
257
258<H3><a name="cinterface"></a>20.2.1 Interfaces to C libraries</H3>
259
260
261<p>
262Modula-3 has an integrated support for calling C functions.
263This is also extensively used by the standard Modula-3 libraries
264to call OS functions.
265The Modula-3 part of SWIG and the corresponding SWIG library
266<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
267contain code that uses these features.
268Because of the built-in support there is no need
269for calling the SWIG kernel to generate wrappers written in C.
270All conversion and argument checking can be done in Modula-3
271and the interfacing is quite efficient.
272All you have to do is to write pieces of Modula-3 code
273that SWIG puts together.
274</p>
275
276<table border summary="Modula-3 C library support">
277<tr><th colspan=2>C library support integrated in Modula-3<th></tr>
278<tr>
279<td>Pragma <tt>&lt;* EXTERNAL *&gt;</tt></td>
280<td>Precedes a declaration of a PROCEDURE that is implemented
281in an external library instead of a Modula-3 module.</td>
282</tr>
283<tr>
284<td>Pragma <tt>&lt;* CALLBACK *&gt;</tt></td>
285<td>Precedes a declaration of a PROCEDURE that should be called
286by external library code.</td>
287</tr>
288<tr>
289<td>Module <tt>Ctypes</tt></td>
290<td>Contains Modula-3 types that match some basic C types.</td>
291</tr>
292<tr>
293<td>Module <tt>M3toC</tt></td>
294<td>Contains routines that convert between Modula-3's <tt>TEXT</tt> type
295and C's <tt>char *</tt> type.</td>
296</tr>
297</table>
298
299<p>
300In each run of SWIG the Modula-3 part
301generates several files:
302</p>
303<table border summary="Modula-3 generated files">
304<tr>
305 <th>Module name scheme</th>
306 <th>Identifier for <tt>%insert</tt></th>
307 <th>Description</th>
308</tr>
309<tr>
310 <td>Module<tt>Raw.i3</tt></td>
311 <td><tt>m3rawintf</tt></td>
312 <td>Declaration of types that are equivalent to those of the C library,
313 <tt>EXTERNAL</tt> procedures as interface to the C library functions</td>
314</tr>
315<tr>
316 <td>Module<tt>Raw.m3</tt></td>
317 <td><tt>m3rawimpl</tt></td>
318 <td>Almost empty.</td>
319</tr>
320<tr>
321 <td>Module<tt>.i3</tt></td>
322 <td><tt>m3wrapintf</tt></td>
323 <td>Declaration of comfortable wrappers to the C library functions.</td>
324</tr>
325<tr>
326 <td>Module<tt>.m3</tt></td>
327 <td><tt>m3wrapimpl</tt></td>
328 <td>Implementation of the wrappers that
329 convert between Modula-3 and C types,
330 check for validity of values,
331 hand-over resource management to the garbage collector using <tt>WeakRef</tt>s
332 and raises exceptions.</td>
333</tr>
334<tr>
335 <td><tt>m3makefile</tt></td>
336 <td><tt>m3makefile</tt></td>
337 <td>Add the modules above to the Modula-3 project and
338 specify the name of the Modula-3 wrapper library
339 to be generated.
340
341 Today I'm not sure if it is a good idea
342 to create a <tt>m3makefile</tt> in each run,
343 because SWIG must be started for each Modula-3 module it creates.
344 Thus the m3makefile is overwritten each time. :-(
345 </td>
346</tr>
347</table>
348
349<p>
350Here's a scheme of how the function calls to Modula-3 wrappers
351are redirected to C library functions:
352</p>
353
354<table summary="Modula-3 C library">
355<tr>
356 <td align=center>
357 Modula-3 wrapper<br>
358 Module<tt>.i3</tt><br>
359 generated by Modula-3 part of SWIG
360 </td>
361 <td></td>
362 <td align=center></td>
363</tr>
364<tr>
365 <td align=center>
366 <!-- pre tag overrides centering -->
367 |<br>
368 v
369 </td>
370 <td></td>
371 <td align=center></td>
372</tr>
373<tr>
374 <td align=center>
375 Modula-3 interface to C<br>
376 Module<tt>Raw.i3</tt><br>
377 generated by Modula-3 part of SWIG
378 </td>
379 <td>--&gt;</td>
380 <td align=center>
381 C library
382 </td>
383</tr>
384</table>
385
386
387<p>
388I have still no good conception how one can split C library interfaces
389into type oriented interfaces.
390A Module in Modula-3 represents an Abstract DataType
391(or call it a static classes, i.e. a class without virtual methods).
392E.g. if you have a principal type, say <tt>Database</tt>,
393it is good Modula-3 style to set up one Module with the name <tt>Database</tt>
394where the database type is declared with the name <tt>T</tt>
395and where all functions are declared that operates on it.
396</p>
397
398<p>
399The normal operation of SWIG is to generate a fixed set of files per call.
400To generate multiple modules one has to write one SWIG interface
401(different SWIG interfaces can share common data) per module.
402Identifiers belonging to a different module may ignored (<tt>%ignore</tt>)
403and the principal type must be renamed (<tt>%typemap</tt>).
404</p>
405
406
407<H3><a name="cppinterface"></a>20.2.2 Interfaces to C++ libraries</H3>
408
409
410<p>
411Interfaces to C++ files are much more complicated and
412there are some more design decisions that are not made, yet.
413Modula-3 has no support for C++ functions
414but C++ compilers should support generating C++ functions
415with a C interface.
416</p>
417
418<p>
419Here's a scheme of how the function calls to Modula-3 wrappers
420a redirected to C library functions:
421</p>
422
423<table summary="Modula-3 C++ library">
424<tr>
425 <td align=center>
426 Modula-3 wrapper<br>
427 Module<tt>.i3</tt><br>
428 generated by Modula-3 part of SWIG
429 </td>
430 <td></td>
431 <td align=center>C++ library</td>
432</tr>
433<tr>
434 <td align=center>
435 <!-- pre tag overrides centering -->
436 |<br>
437 v
438 </td>
439 <td></td>
440 <td align=center>
441 ^<br>
442 |
443 </td>
444</tr>
445<tr>
446 <td align=center>
447 Modula-3 interface to C<br>
448 Module<tt>Raw.i3</tt><br>
449 generated by Modula-3 part of SWIG
450 </td>
451 <td>--&gt;</td>
452 <td align=center>
453 C interface to C++<br>
454 module<tt>_wrap.cxx</tt><br>
455 generated by the SWIG core
456 </td>
457</tr>
458</table>
459
460<p>
461Wrapping C++ libraries arises additional problems:
462</p>
463<ul>
464<li>
465Is it sensible to wrap C++ classes with Modula-3 classes?
466</li>
467<li>
468How to find the wrapping Modula-3 class
469for a class pointer that is returned by a C++ routine?
470</li>
471<li>
472How to deal with multiple inheritance
473which was neglected for Modula-3 for good reasons?
474</li>
475<li>
476Is it possible to sub-class C++ classes with Modula-3 code?
477This issue is addressed by directors,
478a feature that was experimentally added to some Language modules
479like
480<a href="Java.html#java_directors">Java</a> and
481<a href="Python.html#directors">Python</a>.
482</li>
483<li>
484How to manage storage with the garbage collector of Modula-3?
485Support for
486<a href="Customization.html#ownership">
487<tt>%newobject</tt> and <tt>%typemap(newfree)</tt></a>
488isn't implemented, yet.
489What's about resources that are managed by the garbage collector
490but shall be passed back to the storage management of the C++ library?
491This is a general issue which is not solved in a satisfying fashion
492as far as I know.
493</li>
494<li>
495How to turn C++ exceptions into Modula-3 exceptions?
496There's also no support for
497<a href="Customization.html#exception">
498<tt>%exception</tt></a>, yet.
499</li>
500</ul>
501
502<p>
503Be warned:
504There is no C++ library I wrote a SWIG interface for,
505so I'm not sure if this is possible or sensible, yet.
506</p>
507
508<H2><a name="preliminaries"></a>20.3 Preliminaries</H2>
509
510
511<H3><a name="compilers"></a>20.3.1 Compilers</H3>
512
513
514<p>
515There are different Modula-3 compilers around:
516cm3, pm3, ezm3, Klagenfurth Modula-3, Cambridge Modula-3.
517SWIG itself does not contain compiler specific code
518but the library file
519<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
520may do so.
521For testing examples I use Critical Mass cm3.
522</p>
523
524
525<H3><a name="commandline"></a>20.3.2 Additional Commandline Options</H3>
526
527
528<p>
529There are some experimental command line options
530that prevent SWIG from generating interface files.
531Instead files are emitted that may assist you
532when writing SWIG interface files.
533</p>
534
535<table border summary="Modula-3 specific options">
536<tr>
537<th>Modula-3 specific options</th>
538<th>Description</th>
539</tr>
540
541<tr>
542<td valign=top>-generateconst &lt;file&gt;</td>
543<td>
544Disable generation of interfaces and wrappers.
545Instead write code for computing numeric values of constants
546to the specified file.
547<br>
548C code may contain several constant definitions
549written as preprocessor macros.
550Other language modules of SWIG use
551compute-once-use-readonly variables or
552functions to wrap such definitions.
553All of them can invoke C code dynamically
554for computing the macro values.
555But if one wants to turn them into Modula-3
556integer constants, enumerations or set types,
557the values of these expressions has to be known statically.
558Although definitions like <tt>(1 &lt;&lt; FLAG_MAXIMIZEWINDOW)</tt>
559must be considered as good C style
560they are hard to convert to Modula-3
561since the value computation can use every feature of C.
562<br>
563Thus I implemented these switch
564to extract all constant definitions
565and write a C program that output the values of them.
566It works for numeric constants only
567and treats all of them as <tt>double</tt>.
568Future versions may generate a C++ program
569that can detect the type of the macros
570by overloaded output functions.
571Then strings can also be processed.
572</td>
573</tr>
574
575<tr>
576<td valign=top>-generaterename &lt;file&gt;</td>
577<td>
578Disable generation of interfaces and wrappers.
579Instead generate suggestions for <tt>%rename</tt>.
580<br>
581C libraries use a naming style
582that is neither homogenous nor similar to that of Modula-3.
583C function names often contain a prefix denoting the library
584and some name components separated by underscores
585or capitalization changes.
586To get library interfaces that are really Modula-3 like
587you should rename the function names with the <tt>%rename</tt> directive.
588This switch outputs a list of such directives
589with a name suggestion generated by a simple heuristic.
590</td>
591</tr>
592
593<tr>
594<td valign=top>-generatetypemap &lt;file&gt;</td>
595<td>
596Disable generation of interfaces and wrappers.
597Instead generate templates for some basic typemaps.
598</td>
599</tr>
600</table>
601
602<H2><a name="modula3_typemaps"></a>20.4 Modula-3 typemaps</H2>
603
604
605<H3><a name="inoutparam"></a>20.4.1 Inputs and outputs</H3>
606
607
608<p>
609Each C procedure has a bunch of inputs and outputs.
610Inputs are passed as function arguments,
611outputs are updated referential arguments and
612the function value.
613</p>
614
615<p>
616Each C type can have several typemaps
617that apply only in case if a type is used
618for an input argument, for an output argument,
619or for a return value.
620A further typemap may specify
621the direction that is used for certain parameters.
622I have chosen this separation
623in order to be able to write general typemaps for the typemap library
624<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
625.
626In the library code the final usage of the type is not known.
627Using separate typemaps for each possible use
628allows appropriate definitions for each case.
629If these pre-definitions are fine
630then the direction of the function parameter
631is the only hint the user must give.
632</p>
633
634<p>
635The typemaps specific to Modula-3 have a common name scheme:
636A typemap name starts with "m3",
637followed by "raw" or "wrap"
638depending on whether it controls the generation
639of the Module<tt>Raw.i3</tt> or the Module<tt>.i3</tt>, respectively.
640It follows an "in" for typemaps applied to input argument,
641"out" for output arguments, "arg" for all kind of arguments,
642"ret" for returned values.
643</p>
644
645<p>
646The main task of SWIG is to build wrapper function,
647i.e. functions that convert values between C and Modula-3
648and call the corresponding C function.
649Modula-3 wrapper functions generated by SWIG
650consist of the following parts:
651</p>
652<ul>
653<li>Generate <tt>PROCEDURE</tt> signature.</li>
654<li>Declare local variables.</li>
655<li>Convert input values from Modula-3 to C.</li>
656<li>Check for input value integrity.</li>
657<li>Call the C function.</li>
658<li>Check returned values, e.g. error codes.</li>
659<li>Convert and write back values into Modula-3 records.</li>
660<li>Free temporary storage.</li>
661<li>Return values.</li>
662</ul>
663
664<table border summary="Modula-3 typemaps">
665<tr>
666 <th>Typemap</th>
667 <th>Example</th>
668 <th>Description</th>
669</tr>
670<tr>
671 <td>m3wrapargvar</td>
672 <td><tt>$1: INTEGER := $1_name;</tt></td>
673 <td>
674 Declaration of some variables needed for temporary results.
675 </td>
676</tr>
677<tr>
678 <td>m3wrapargconst</td>
679 <td><tt>$1 = "$1_name";</tt></td>
680 <td>
681 Declaration of some constant, maybe for debug purposes.
682 </td>
683</tr>
684<tr>
685 <td>m3wrapargraw</td>
686 <td><tt>ORD($1_name)</tt></td>
687 <td>
688 The expression that should be passed as argument to the raw Modula-3 interface function.
689 </td>
690</tr>
691<tr>
692 <td>m3wrapargdir</td>
693 <td><tt>out</tt></td>
694 <td>
695 Referential arguments can be used for input, output, update.
696 ???
697 </td>
698</tr>
699<tr>
700 <td>m3wrapinmode</td>
701 <td><tt>READONLY</tt></td>
702 <td>
703 One of Modula-3 parameter modes
704 <tt>VALUE</tt> (or empty),
705 <tt>VAR</tt>,
706 <tt>READONLY</tt>
707 </td>
708</tr>
709<tr>
710 <td>m3wrapinname</td>
711 <td></td>
712 <td>
713 New name of the input argument.
714 </td>
715</tr>
716<tr>
717 <td>m3wrapintype</td>
718 <td></td>
719 <td>
720 Modula-3 type of the input argument.
721 </td>
722</tr>
723<tr>
724 <td>m3wrapindefault</td>
725 <td></td>
726 <td>
727 Default value of the input argument
728 </td>
729</tr>
730<tr>
731 <td>m3wrapinconv</td>
732 <td><tt>$1 := M3toC.SharedTtoS($1_name);</tt></td>
733 <td>
734 Statement for converting the Modula-3 input value to C compliant value.
735 </td>
736</tr>
737<tr>
738 <td>m3wrapincheck</td>
739 <td><tt>IF Text.Length($1_name) &gt; 10 THEN RAISE E("str too long"); END;</tt></td>
740 <td>
741 Check the integrity of the input value.
742 </td>
743</tr>
744<tr>
745 <td>m3wrapoutname</td>
746 <td></td>
747 <td>
748 Name of the <tt>RECORD</tt> field to be used for returning multiple values.
749 This applies to referential output arguments that shall be turned
750 into return values.
751 </td>
752</tr>
753<tr>
754 <td>m3wrapouttype</td>
755 <td></td>
756 <td>
757 Type of the value that is returned instead of a referential output argument.
758 </td>
759</tr>
760<tr>
761 <td>m3wrapoutconv</td>
762 <td></td>
763 <td>
764 </td>
765</tr>
766<tr>
767 <td>m3wrapoutcheck</td>
768 <td></td>
769 <td>
770 </td>
771</tr>
772<tr>
773 <td>m3wrapretraw</td>
774 <td></td>
775 <td>
776 </td>
777</tr>
778<tr>
779 <td>m3wrapretname</td>
780 <td></td>
781 <td>
782 </td>
783</tr>
784<tr>
785 <td>m3wraprettype</td>
786 <td></td>
787 <td>
788 </td>
789</tr>
790<tr>
791 <td>m3wrapretvar</td>
792 <td></td>
793 <td>
794 </td>
795</tr>
796<tr>
797 <td>m3wrapretconv</td>
798 <td></td>
799 <td>
800 </td>
801</tr>
802<tr>
803 <td>m3wrapretcheck</td>
804 <td></td>
805 <td>
806 </td>
807</tr>
808<tr>
809 <td>m3wrapfreearg</td>
810 <td><tt>M3toC.FreeSharedS(str,arg1);</tt></td>
811 <td>
812 Free resources that were temporarily used in the wrapper.
813 Since this step should never be skipped,
814 SWIG will put it in the <tt>FINALLY</tt> branch
815 of a <tt>TRY .. FINALLY</tt> structure.
816 </td>
817</tr>
818</table>
819
820
821<H3><a name="ordinals"></a>20.4.2 Subranges, Enumerations, Sets</H3>
822
823
824<p>
825Subranges, enumerations, and sets are machine oriented types
826that make Modula very strong and expressive compared
827with the type systems of many other languages.
828</p>
829
830<ul>
831<li>
832Subranges are used for statically restricted choices of integers.
833</li>
834<li>
835Enumerations are used for named choices.
836</li>
837<li>
838Sets are commonly used for flag (option) sets.
839</li>
840</ul>
841
842<p>
843Using them extensively makes Modula code very safe and readable.
844</p>
845
846<p>
847C supports enumerations, too, but they are not as safe as the ones of Modula.
848Thus they are abused for many things:
849For named choices, for integer constant definitions, for sets.
850To make it complete every way of defining a value in C
851(<tt>#define</tt>, <tt>const int</tt>, <tt>enum</tt>)
852is somewhere used for defining something
853that must be handled completely different in Modula-3
854(<tt>INTEGER</tt>, enumeration, <tt>SET</tt>).
855</p>
856
857<p>
858I played around with several <tt>%feature</tt>s and <tt>%pragma</tt>s
859that split the task up into converting
860the C bit patterns (integer or bit set)
861into Modula-3 bit patterns (integer or bit set)
862and change the type as requested.
863See the corresponding
864<a href="../../Examples/modula3/enum/example.i">example</a>.
865This is quite messy and not satisfying.
866So the best what you can currently do is
867to rewrite constant definitions manually.
868Though this is a tedious work
869that I'd like to automate.
870</p>
871
872
873<H3><a name="class"></a>20.4.3 Objects</H3>
874
875
876<p>
877Declarations of C++ classes are mapped to <tt>OBJECT</tt> types
878while it is tried to retain the access hierarchy
879"public - protected - private" using partial revelation.
880Though the
881<a href="../../Examples/modula3/class/example.i">implementation</a>
882is not really useful, yet.
883</p>
884
885
886<H3><a name="imports"></a>20.4.4 Imports</H3>
887
888
889<p>
890Pieces of Modula-3 code provided by typemaps
891may contain identifiers from foreign modules.
892If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
893contains code using the function <tt>M3toC.SharedTtoS</tt>
894you may declare <tt>%typemap("m3wrapinconv:import") blah * %{M3toC%}</tt>.
895Then the module <tt>M3toC</tt> is imported
896if the <tt>m3wrapinconv</tt> typemap for <tt>blah *</tt>
897is used at least once.
898Use <tt>%typemap("m3wrapinconv:import") blah * %{MyConversions AS M3toC%}</tt>
899if you need module renaming.
900Unqualified import is not supported.
901</p>
902
903<p>
904It is cumbersome to add this typemap to each piece of Modula-3 code.
905It is especially useful when writing general typemaps
906for the typemap library
907<a href="../../Lib/modula3/modula3.swg"><tt>modula3.swg</tt></a>
908.
909For a monolithic module you might be better off
910if you add the imports directly:
911</p>
912
913<div class="code">
914<pre>
915%insert(m3rawintf) %{
916IMPORT M3toC;
917%}
918</pre></div>
919
920
921<H3><a name="exceptions"></a>20.4.5 Exceptions</H3>
922
923
924<p>
925Modula-3 provides another possibility
926of an output of a function: exceptions.
927</p>
928
929<p>
930Any piece of Modula-3 code that SWIG inserts
931due to a typemap can raise an exception.
932This way you can also convert an error code
933from a C function into a Modula-3 exception.
934</p>
935
936<p>
937The <tt>RAISES</tt> clause is controlled
938by typemaps with the <tt>throws</tt> extension.
939If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
940contains code that may raise the exceptions <tt>OSError.E</tt>
941you should declare
942<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
943</p>
944
945<H3><a name="typemap_example"></a>20.4.6 Example</H3>
946
947
948<p>
949The generation of wrappers in Modula-3 needs very fine control
950to take advantage of the language features.
951Here is an example of a generated wrapper
952where almost everything is generated by a typemap:
953</p>
954
955<div class="code"><pre>
956<I> (* %relabel m3wrapinmode m3wrapinname m3wrapintype m3wrapindefault *)</I>
957 PROCEDURE Name (READONLY str : TEXT := "" )
958<I> (* m3wrapoutcheck:throws *)</I>
959 : NameResult RAISES {E} =
960 CONST
961 arg1name = "str"; <I>(* m3wrapargconst *)</I>
962 VAR
963 arg0 : C.char_star; <I>(* m3wrapretvar *)</I>
964 arg1 : C.char_star; <I>(* m3wrapargvar *)</I>
965 arg2 : C.int;
966 result : RECORD
967<I> (*m3wrapretname m3wraprettype*)</I>
968 unixPath : TEXT;
969<I> (*m3wrapoutname m3wrapouttype*)</I>
970 checksum : CARDINAL;
971 END;
972 BEGIN
973 TRY
974 arg1 := M3toC.SharedTtoS(str); <I>(* m3wrapinconv *)</I>
975 IF Text.Length(arg1) &gt; 10 THEN <I>(* m3wrapincheck *)</I>
976 RAISE E("str too long");
977 END;
978<I> (* m3wrapretraw m3wrapargraw *)</I>
979 arg0 := MessyToUnix (arg1, arg2);
980 result.unixPath := M3toC.CopyStoT(arg0); <I>(* m3wrapretconv *)</I>
981 result.checksum := arg2; <I>(* m3wrapoutconv *)</I>
982 IF result.checksum = 0 THEN <I>(* m3wrapoutcheck *)</I>
983 RAISE E("invalid checksum");
984 END;
985 FINALLY
986 M3toC.FreeSharedS(str,arg1); <I>(* m3wrapfreearg *)</I>
987 END;
988 END Name;
989</pre></div>
990
991
992<H2><a name="hints"></a>20.5 More hints to the generator</H2>
993
994
995<H3><a name="features"></a>20.5.1 Features</H3>
996
997
998<table border summary="Modula-3 features">
999<tr>
1000 <th>Feature</th>
1001 <th>Example</th>
1002 <th>Description</th>
1003</tr>
1004<tr>
1005 <td>multiretval</td>
1006 <td><tt>%m3multiretval get_box;</tt> or
1007 <tt>%feature("modula3:multiretval") get_box;</tt></td>
1008 <td>Let the denoted function return a <tt>RECORD</tt>
1009 rather than a plain value.
1010 This <tt>RECORD</tt> contains all arguments with "out" direction
1011 including the return value of the C function (if there is one).
1012 If more than one argument is "out"
1013 then the function <b>must</b> have the <tt>multiretval</tt> feature activated,
1014 but it is explicitly requested from the user to prevent mistakes.</td>
1015</tr>
1016<tr>
1017 <td>constnumeric</td>
1018 <td><tt>%constnumeric(12) twelve;</tt> or
1019 <tt>%feature("constnumeric","12") twelve;</tt></td>
1020 <td>This feature can be used to tell Modula-3's back-end of SWIG
1021 the value of an identifier.
1022 This is necessary in the cases
1023 where it was defined by a non-trivial C expression.
1024 This feature is used by the
1025 <tt>-generateconst</tt> <a href="#options">option</a>.
1026 In future it may be generalized to other kind of values
1027 such as strings.
1028 </td>
1029</tr>
1030</table>
1031
1032<H3><a name="pragmas"></a>20.5.2 Pragmas</H3>
1033
1034
1035<table border summary="Modula-3 pragmas">
1036<tr>
1037 <th>Pragma</th>
1038 <th>Example</th>
1039 <th>Description</th>
1040</tr>
1041<tr>
1042 <td>unsafe</td>
1043 <td><tt>%pragma(modula3) unsafe="true";</tt></td>
1044 <td>Mark the raw interface modules as <tt>UNSAFE</tt>.
1045 This will be necessary in many cases.</td>
1046</tr>
1047<tr>
1048 <td>library</td>
1049 <td><tt>%pragma(modula3) library="m3fftw";</tt></td>
1050 <td>Specifies the library name for the wrapper library to be created.
1051 It should be distinct from the name of the library to be wrapped.</td>
1052</tr>
1053</table>
1054
1055<H2><a name="remarks"></a>20.6 Remarks</H2>
1056
1057
1058<ul>
1059<li>
1060The Modula-3 part of SWIG doesn't try to generate nicely formatted code.
1061Use <tt>m3pp</tt> to postprocess the Modula files,
1062it does a very good job here.
1063</li>
1064</ul>
1065
1066</body>
1067</html>