summaryrefslogtreecommitdiff
path: root/Doc/Manual/Modula3.html
blob: ffbf6132dc442e5ae59d04e942f0b1c3c0bf934b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and Modula-3</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="Modula3"></a>29 SWIG and Modula-3</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Modula3_modula3_overview">Overview</a>
<ul>
<li><a href="#Modula3_motivation">Motivation</a>
</ul>
<li><a href="#Modula3_conception">Conception</a>
<ul>
<li><a href="#Modula3_cinterface">Interfaces to C libraries</a>
<li><a href="#Modula3_cppinterface">Interfaces to C++ libraries</a>
</ul>
<li><a href="#Modula3_preliminaries">Preliminaries</a>
<ul>
<li><a href="#Modula3_compilers">Compilers</a>
<li><a href="#Modula3_commandline">Additional Commandline Options</a>
</ul>
<li><a href="#Modula3_typemaps">Modula-3 typemaps</a>
<ul>
<li><a href="#Modula3_inoutparam">Inputs and outputs</a>
<li><a href="#Modula3_ordinals">Subranges, Enumerations, Sets</a>
<li><a href="#Modula3_class">Objects</a>
<li><a href="#Modula3_imports">Imports</a>
<li><a href="#Modula3_exceptions">Exceptions</a>
<li><a href="#Modula3_typemap_example">Example</a>
</ul>
<li><a href="#Modula3_hints">More hints to the generator</a>
<ul>
<li><a href="#Modula3_features">Features</a>
<li><a href="#Modula3_pragmas">Pragmas</a>
</ul>
<li><a href="#Modula3_remarks">Remarks</a>
</ul>
</div>
<!-- INDEX -->



<p>
This chapter describes SWIG's support for
<a href="http://modula3.org/">Modula-3</a>.
You should be familiar with the
<a href="SWIG.html#SWIG">basics</a>
of SWIG,
especially
<a href="Typemaps.html#Typemaps">typemaps</a>.
</p>

<H2><a name="Modula3_modula3_overview"></a>29.1 Overview</H2>


<p>
Modula-3 is a compiled language in the tradition of Niklaus Wirth's Modula 2,
which is in turn a successor to Pascal.
</p>

<p>
SWIG's Modula-3 support is currently 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!
However, 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>
</li>
<li>
<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/">
FFTW
</a>
</li>
</ol>

<H3><a name="Modula3_motivation"></a>29.1.1 Motivation</H3>


<p>
Although it is possible to write Modula-3 code that performs as well as C/C++
most existing libraries are not written in Modula-3 but in C or C++, and
even libraries in other languages may provide C header files.
</p>

<p>
Fortunately Modula-3 can call C functions, but you have to write Modula-3
interfaces to them, and to make things comfortable you will also need
wrappers that convert between high-level features of Modula-3 (garbage
collecting, exceptions) and the explicit tracking of allocated memory and
exception codes used by C APIs.
</p>

<p>
SWIG converts C headers to Modula-3 interfaces for you, and using typemaps
you can pass <tt>TEXT</tt>s or open arrays, and convert error return codes
into exceptions.
</p>

<p>
If the library API is ill designed
writing appropriate typemaps can still be 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>

<p>
Without SWIG you would probably never consider trying to call C++ libraries
from Modula-3, but with SWIG this is becomes feasible.
SWIG can generate C wrappers to C++ functions and object methods
that may throw exceptions, and then wrap these C wrappers for Modula-3.
To make it complete you can then hide the C interface with Modula-3 classes and
exceptions.
</p>

<p>
SWIG allows you to call C and C++ libraries from Modula-3 (even with call back
functions), but it doesn't allow you to easily integrate a Modula-3 module into
a C/C++ project.
</p>

<H2><a name="Modula3_conception"></a>29.2 Conception</H2>


<H3><a name="Modula3_cinterface"></a>29.2.1 Interfaces to C libraries</H3>


<p>
Modula-3 has integrated support for calling C functions.
This is also extensively used by the standard Modula-3 libraries
to call OS functions.
The Modula-3 part of SWIG and the corresponding SWIG library
modula3.swg
contain code that uses these features.
Because of the built-in support there is no need
for calling the SWIG kernel to generate wrappers written in C.
All conversion and argument checking can be done in Modula-3
and the interfacing is quite efficient.
All you have to do is to write pieces of Modula-3 code
that SWIG puts together.
</p>

<table border summary="Modula-3 C library support">
<tr><th colspan=2>C library support integrated in Modula-3<th></tr>
<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 module.</td>
</tr>
<tr>
<td>Pragma <tt>&lt;* CALLBACK *&gt;</tt></td>
<td>Precedes a declaration of a PROCEDURE that should be called
by external library code.</td>
</tr>
<tr>
<td>Module <tt>Ctypes</tt></td>
<td>Contains Modula-3 types that match some basic C types.</td>
</tr>
<tr>
<td>Module <tt>M3toC</tt></td>
<td>Contains routines that convert between Modula-3's <tt>TEXT</tt> type
and C's <tt>char *</tt> type.</td>
</tr>
</table>

<p>
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> 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,
      hand-over resource management to the garbage collector using <tt>WeakRef</tt>s
      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
      to be generated.

    Today I'm not sure if it is a good idea
    to create a <tt>m3makefile</tt> in each run,
    because SWIG must be started for each Modula-3 module it creates.
    Thus the m3makefile is overwritten each time. :-(
  </td>
</tr>
</table>

<p>
Here's a scheme of how the function calls to Modula-3 wrappers
are redirected to C library functions:
</p>

<table summary="Modula-3 C library">
<tr>
  <td align=center>
    Modula-3 wrapper<br>
    Module<tt>.i3</tt><br>
    generated by Modula-3 part of SWIG
  </td>
  <td></td>
  <td align=center></td>
</tr>
<tr>
  <td align=center>
    <!-- pre tag overrides centering -->
    |<br>
    v
  </td>
  <td></td>
  <td align=center></td>
</tr>
<tr>
  <td align=center>
    Modula-3 interface to C<br>
    Module<tt>Raw.i3</tt><br>
    generated by Modula-3 part of SWIG
  </td>
  <td>--&gt;</td>
  <td align=center>
    C library
  </td>
</tr>
</table>


<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="Modula3_cppinterface"></a>29.2.2 Interfaces to C++ libraries</H3>


<p>
Interfaces to C++ files are much more complicated and
there are some more design decisions that are not made, yet.
Modula-3 has no support for C++ functions
but C++ compilers should support generating C++ functions
with a C interface.
</p>

<p>
Here's a scheme of how the function calls to Modula-3 wrappers
are redirected to C library functions:
</p>

<table summary="Modula-3 C++ library">
<tr>
  <td align=center>
    Modula-3 wrapper<br>
    Module<tt>.i3</tt><br>
    generated by Modula-3 part of SWIG
  </td>
  <td></td>
  <td align=center>C++ library</td>
</tr>
<tr>
  <td align=center>
    <!-- pre tag overrides centering -->
    |<br>
    v
  </td>
  <td></td>
  <td align=center>
    ^<br>
    |
  </td>
</tr>
<tr>
  <td align=center>
    Modula-3 interface to C<br>
    Module<tt>Raw.i3</tt><br>
    generated by Modula-3 part of SWIG
  </td>
  <td>--&gt;</td>
  <td align=center>
    C interface to C++<br>
    module<tt>_wrap.cxx</tt><br>
    generated by the SWIG core
  </td>
</tr>
</table>

<p>
Wrapping C++ libraries arises additional problems:
</p>
<ul>
<li>
Is it sensible to wrap C++ classes with Modula-3 classes?
</li>
<li>
How to find the wrapping Modula-3 class
for a class pointer that is returned by a C++ routine?
</li>
<li>
How to deal with multiple inheritance
which was neglected for Modula-3 for good reasons?
</li>
<li>
Is it possible to sub-class C++ classes with Modula-3 code?
This issue is addressed by directors,
a feature that was experimentally added to some Language modules
like
<a href="Java.html#Java_directors">Java</a> and
<a href="Python.html#Python_directors">Python</a>.
</li>
<li>
How to manage storage with the garbage collector of Modula-3?
Support for
<a href="Customization.html#Customization_ownership">
<tt>%newobject</tt> and <tt>%typemap(newfree)</tt></a>
isn't implemented, yet.
What's about resources that are managed by the garbage collector
but shall be passed back to the storage management of the C++ library?
This is a general issue which is not solved in a satisfying fashion
as far as I know.
</li>
<li>
How to turn C++ exceptions into Modula-3 exceptions?
There's also no support for
<a href="Customization.html#Customization_exception">
<tt>%exception</tt></a>, yet.
</li>
</ul>

<p>
Be warned:
There is no C++ library I wrote a SWIG interface for,
so I'm not sure if this is possible or sensible, yet.
</p>

<H2><a name="Modula3_preliminaries"></a>29.3 Preliminaries</H2>


<H3><a name="Modula3_compilers"></a>29.3.1 Compilers</H3>


<p>
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 modula3.swg library file
may do so.
For testing examples I use Critical Mass cm3.
</p>


<H3><a name="Modula3_commandline"></a>29.3.2 Additional Commandline Options</H3>


<p>
There are some experimental command line options
that prevent SWIG from generating interface files.
Instead files are emitted that may assist you
when writing SWIG interface files.
</p>

<table border summary="Modula-3 specific options">
<tr>
<th>Modula-3 specific options</th>
<th>Description</th>
</tr>

<tr>
<td valign=top>-generateconst &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead write code for computing numeric values of constants
to the specified file.
<br>
C code may contain several constant definitions
written as preprocessor macros.
Other language modules of SWIG use
compute-once-use-readonly variables or
functions to wrap such definitions.
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 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
since the value computation can use every feature of C.
<br>
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 <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 processed.
</td>
</tr>

<tr>
<td valign=top>-generaterename &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead generate suggestions for <tt>%rename</tt>.
<br>
C libraries use a naming style
that is neither homogeneous nor similar to that of Modula-3.
C function names often contain a prefix denoting the library
and some name components separated by underscores
or capitalization changes.
To get library interfaces that are really Modula-3 like
you should rename the function names with the <tt>%rename</tt> directive.
This switch outputs a list of such directives
with a name suggestion generated by a simple heuristic.
</td>
</tr>

<tr>
<td valign=top>-generatetypemap &lt;file&gt;</td>
<td>
Disable generation of interfaces and wrappers.
Instead generate templates for some basic typemaps.
</td>
</tr>
</table>

<H2><a name="Modula3_typemaps"></a>29.4 Modula-3 typemaps</H2>


<H3><a name="Modula3_inoutparam"></a>29.4.1 Inputs and outputs</H3>


<p>
Each C procedure has a bunch of inputs and outputs.
Inputs are passed as function arguments,
outputs are updated referential arguments and
the function value.
</p>

<p>
Each C type can have several typemaps
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 modula3.swg typemap library.
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>
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>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.
</p>

<p>
The main task of SWIG is to build wrapper function,
i.e. functions that convert values between C and Modula-3
and call the corresponding C function.
Modula-3 wrapper functions generated by SWIG
consist of the following parts:
</p>
<ul>
<li>Generate <tt>PROCEDURE</tt> signature.</li>
<li>Declare local variables.</li>
<li>Convert input values from Modula-3 to C.</li>
<li>Check for input value integrity.</li>
<li>Call the C function.</li>
<li>Check returned values, e.g. error codes.</li>
<li>Convert and write back values into Modula-3 records.</li>
<li>Free temporary storage.</li>
<li>Return values.</li>
</ul>

<table border summary="Modula-3 typemaps">
<tr>
  <th>Typemap</th>
  <th>Example</th>
  <th>Description</th>
</tr>
<tr>
  <td>m3wrapargvar</td>
  <td><tt>$1: INTEGER := $1_name;</tt></td>
  <td>
    Declaration of some variables needed for temporary results.
  </td>
</tr>
<tr>
  <td>m3wrapargconst</td>
  <td><tt>$1 = "$1_name";</tt></td>
  <td>
    Declaration of some constant, maybe for debug purposes.
  </td>
</tr>
<tr>
  <td>m3wrapargraw</td>
  <td><tt>ORD($1_name)</tt></td>
  <td>
    The expression that should be passed as argument to the raw Modula-3 interface function.
  </td>
</tr>
<tr>
  <td>m3wrapargdir</td>
  <td><tt>out</tt></td>
  <td>
    Referential arguments can be used for input, output, update.
    ???
  </td>
</tr>
<tr>
  <td>m3wrapinmode</td>
  <td><tt>READONLY</tt></td>
  <td>
    One of Modula-3 parameter modes
    <tt>VALUE</tt> (or empty),
    <tt>VAR</tt>,
    <tt>READONLY</tt>
  </td>
</tr>
<tr>
  <td>m3wrapinname</td>
  <td></td>
  <td>
    New name of the input argument.
  </td>
</tr>
<tr>
  <td>m3wrapintype</td>
  <td></td>
  <td>
    Modula-3 type of the input argument.
  </td>
</tr>
<tr>
  <td>m3wrapindefault</td>
  <td></td>
  <td>
    Default value of the input argument
  </td>
</tr>
<tr>
  <td>m3wrapinconv</td>
  <td><tt>$1 := M3toC.SharedTtoS($1_name);</tt></td>
  <td>
    Statement for converting the Modula-3 input value to C compliant value.
  </td>
</tr>
<tr>
  <td>m3wrapincheck</td>
  <td><tt>IF Text.Length($1_name) &gt; 10 THEN RAISE E("str too long"); END;</tt></td>
  <td>
    Check the integrity of the input value.
  </td>
</tr>
<tr>
  <td>m3wrapoutname</td>
  <td></td>
  <td>
    Name of the <tt>RECORD</tt> field to be used for returning multiple values.
    This applies to referential output arguments that shall be turned
    into return values.
  </td>
</tr>
<tr>
  <td>m3wrapouttype</td>
  <td></td>
  <td>
    Type of the value that is returned instead of a referential output argument.
  </td>
</tr>
<tr>
  <td>m3wrapoutconv</td>
  <td></td>
  <td>
  </td>
</tr>
<tr>
  <td>m3wrapoutcheck</td>
  <td></td>
  <td>
  </td>
</tr>
<tr>
  <td>m3wrapretraw</td>
  <td></td>
  <td>
  </td>
</tr>
<tr>
  <td>m3wrapretname</td>
  <td></td>
  <td>
  </td>
</tr>
<tr>
  <td>m3wraprettype</td>
  <td></td>
  <td>
  </td>
</tr>
<tr>
  <td>m3wrapretvar</td>
  <td></td>
  <td>
  </td>
</tr>
<tr>
  <td>m3wrapretconv</td>
  <td></td>
  <td>
  </td>
</tr>
<tr>
  <td>m3wrapretcheck</td>
  <td></td>
  <td>
  </td>
</tr>
<tr>
  <td>m3wrapfreearg</td>
  <td><tt>M3toC.FreeSharedS(str,arg1);</tt></td>
  <td>
    Free resources that were temporarily used in the wrapper.
    Since this step should never be skipped,
    SWIG will put it in the <tt>FINALLY</tt> branch
    of a <tt>TRY .. FINALLY</tt> structure.
  </td>
</tr>
</table>


<H3><a name="Modula3_ordinals"></a>29.4.2 Subranges, Enumerations, Sets</H3>


<p>
Subranges, enumerations, and sets are machine oriented types
that make Modula very strong and expressive compared
with the type systems of many other languages.
</p>

<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>

<p>
Using them extensively makes Modula code very safe and readable.
</p>

<p>
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>).
</p>

<p>
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 example in the 
Examples/modula3/enum/example.i file.
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.
</p>


<H3><a name="Modula3_class"></a>29.4.3 Objects</H3>


<p>
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 example in 
Examples/modula3/class/example.i
is not really useful, yet.
</p>


<H3><a name="Modula3_imports"></a>29.4.4 Imports</H3>


<p>
Pieces of Modula-3 code provided by typemaps
may contain identifiers from foreign modules.
If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
contains code using the function <tt>M3toC.SharedTtoS</tt>
you may declare <tt>%typemap("m3wrapinconv:import") blah * %{M3toC%}</tt>.
Then the module <tt>M3toC</tt> is imported
if the <tt>m3wrapinconv</tt> typemap for <tt>blah *</tt>
is used at least once.
Use <tt>%typemap("m3wrapinconv:import") blah * %{MyConversions AS M3toC%}</tt>
if you need module renaming.
Unqualified import is not supported.
</p>

<p>
It is cumbersome to add this typemap to each piece of Modula-3 code.
It is especially useful when writing general typemaps
for the modula3.swg typemap library.
For a monolithic module you might be better off
if you add the imports directly:
</p>

<div class="code">
<pre>
%insert(m3rawintf) %{
IMPORT M3toC;
%}
</pre></div>


<H3><a name="Modula3_exceptions"></a>29.4.5 Exceptions</H3>


<p>
Modula-3 provides another possibility
of an output of a function: exceptions.
</p>

<p>
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 a Modula-3 exception.
</p>

<p>
The <tt>RAISES</tt> clause is controlled
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>.
</p>

<H3><a name="Modula3_typemap_example"></a>29.4.6 Example</H3>


<p>
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:
</p>

<div class="code"><pre>
<I>         (* %relabel  m3wrapinmode m3wrapinname m3wrapintype  m3wrapindefault *)</I>
  PROCEDURE Name     (READONLY       str       :    TEXT    :=      ""       )
<I>              (* m3wrapoutcheck:throws *)</I>
     : NameResult RAISES {E} =
    CONST
      arg1name = "str";                  <I>(* m3wrapargconst *)</I>
    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) &gt; 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></div>


<H2><a name="Modula3_hints"></a>29.5 More hints to the generator</H2>


<H3><a name="Modula3_features"></a>29.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="#Modula3_commandline">option</a>.
      In future it may be generalized to other kind of values
      such as strings.
      </td>
</tr>
</table>

<H3><a name="Modula3_pragmas"></a>29.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="Modula3_remarks"></a>29.6 Remarks</H2>


<ul>
<li>
The Modula-3 part of SWIG doesn't try to generate nicely formatted code.
If you need to read the generated code, use <tt>m3pp</tt> to postprocess the
Modula files.
</li>
</ul>

</body>
</html>