Using Modula-3 under OS/2

Written by Carsten Whimster

Please note that this is a vintage article originally published in 1996, while it holds up remarkably well considering its age there are outdated references and information contained in the text, and minor modifications have been made to the text in places to make it clearer. Regarding getting hold of the OS/2 Modula-3 compiler, you should use the versions linked to on the SRC Modula-3 page rather than what is in the text below.

Introduction
This document is an attempt at letting the rank novice get out there and try out the OS/2 Modula-3 port done by Klaus Preschern. Note that I have nothing to do with the port, and all the kudos for that should go to Klaus. So should the bugs with Modula-3, if there are any. Conversely, I wrote this document independently, and if there are any problems in it, please do not bother Klaus as he had nothing to do with it.

Our e-mail addresses are klausp@ping.at (Klaus Preschern) and Carsten_whimster@iqpac.com (Carsten Whimster).

For Experienced Users
If you are reasonably familiar with UNIX, OS/2, Modula-3, and EMX, you probably don't need this document at all. Just get the files below, and read the readme.1st written by Klaus.


 * Quick Note About Format

In the instructions below, when I write something like "Do 'gzip -d m3.taz'", I mean that you should type the following on an OS/2 command line prompt: gzip -d m3.taz without the quotes.

How to Get Modula-3 for OS/2
Get the files from the sites linked to in the SRC Modula-3 page, unless you already have some of these, in which case check the versions, and read the note below: The files are as follows: For the emx versions, type 'emxrev'. This yields the following with the above files installed: EMX	 revision = 36 EMXIO	 revision = 30 EMXLIBC revision = 35 EMXLIBCM revision = 35 EMXLIBCS revision = 35 EMXWRAP revision = 30 Note: If you have any of these files already, make sure that they are identical or newer than the above versions. If not, get them. If yours are the same or newer, you can try using them instead. If something does not work, then try using the above files.

How to Install Modula-3 for OS/2
If you already have emx and gcc, jump to point 3, after checking that the versions are sufficiently new as mentioned above.
 * 1) Copy EMXRT.ZIP, EMXDEV.ZIP and GNUDEV.ZIP to some root directory. Since this is an 'alpha' type release (not everything is finished yet), I personally followed the author's suggestion and used drive E:, and I would recommend that you do the same, if at all possible.
 * 2) Unzip EMXRT.ZIP, EMXDEV.ZIP and GNUDEV.ZIP in that order (ie. 'unzip emxrt' and so on). This will create a directory \emx with a series of sub-directories in it. I successfully changed the name of this directory to \Emx, having a preference for capitalized directory names, but I also changed the name of all the corresponding paths in the CONFIG.SYS to match. Remember that much of this stuff is ported from UNIX which is case-sensitive w.r.t the file-system. It may not be necessary, but it is good insurance. If you do something different here, and you get it to work, mail Klaus Preschern and myself, and tell us what you had to do, so that we can update the documents.
 * 3) Copy DISKACC.DLL to \emx\dll.
 * 4) Copy BASH.EXE, TAR.EXE, and GZIP.EXE to \emx\bin.
 * 5) Copy M3.TAZ to the same root directory as the one you chose for the above files, ie. hopefully E:\. If you do something different here, and you get it to work, mail Klaus Preschern and myself and tell us what you had to do, so that we can update the documents.
 * 6) Add the lines in the downloaded file CONFIG.SYS to your real config.sys, making sure to correctly modify any drive settings you changed above.
 * Note: I was not able to get the line SET EMXSHELL=E:\Emx\bin\bash.exe to work satisfactorily. I use YAOS, and so had to omit this line. When I included this line, my aliases and many other things simply stopped working! It seems to have something to do with single versus double \'s in paths, among other things. I just REMmed out the EMXSHELL line in the config.sys for now. This never caused any problems. It may be just a difference in the alias format.
 * Klaus adds: "I do not know what "YAOS" is, but I had problems with long command lines without bash (i.e. when building M3 libraries with many object files)."
 * It is true that most OS/2 shells, CMD and YAOS included, have a maximum command line length of 256 characters, I believe. Look it up if you are worried.
 * 1) Reboot to let the above changes take effect.
 * 2) Do 'gzip -d M3.TAZ' in the root directory of above. This will create an m3.tar file, and remove the m3.taz file.
 * 3) Do 'tar xvf m3.tar' to the newly created m3.tar. This will create an m3 directory in the root of your chosen drive. I didn't dare change the name of this to M3, Modula-3 or anything else, given the alpha status of the package. If you do something different here, and you get it to work, mail Klaus Preschern and myself...
 * 4) Check the quake templates for OS/2 in the \m3\install\lib\m3\pkg\m3build\templates directory. I had a quick look, and it seems as if the only file that might need changing is the OS2 file, and if you used drive E: and the recommended directory names, this should not be necessary. If you do something different, and you get it to work... well you know.
 * 5) Mentally thank Eberhart Mattes, Klaus Preschern and all other people involved in getting this together, and become an active OS/2 Modula-3 programmer.

Note: Klaus Preschern's readme.1st mentions that you should check the files m3build.c, m3where.c and m3ship.c for hard-coded drive and directory stuff, but these files are actually in \m3\install\lib\m3\pkg\m3build\src, not in \m3\install\bin. These can be recompiled with 'gcc m3build.c' and so on. If you recompile these, you should copy them to \m3\install\bin. There should be 2 occurrences of "e:" in each of these files, as *quake and *template_dir. Change these variables to reflect where you put stuff. If you do something different etc. You are done!

Testing Your Modula-3 for OS/2 Installation
To try Modula-3 out, do the following:
 * 1) Create a directory for your projects wherever you keep these things, eg. (the name of this is arbitrary):
 * [E:\]md \Dev\Projects\Modula-3
 * Figure 1: Creating the projects directory.
 * 1) Go there, create a directory for a test program, go there, create yet another sub-directory called src (this name is fixed and crucial) and go there:
 * [E:\]cd \Dev\Projects\Modula-3\
 * [E:\Dev\Projects\Modula-3]md First
 * [E:\Dev\Projects\Modula-3]cd First
 * [E:\Dev\Projects\Modula-3\First]md src
 * [E:\Dev\Projects\Modula-3\First]cd src
 * [E:\Dev\Projects\Modula-3\First\src]
 * Figure 2: Creating auxiliary directories.
 * 1) Type the following program into a file called Main.m3 (this name is crucial for this example):
 * E:\Dev\Projects\Modula-3\First\src]e Main.m3
 * MODULE Main;
 * IMPORT IO;
 * BEGIN
 * IO.Put("Hi World!");
 * END Main.
 * Figure 3: Creating your first Modula-3 program.
 * Note the creative and casual deviance from the more traditional "Hello World!" program. Note also that Modula-3 is case- sensitive, so be sure to type everything verbatim. Also note the semicolons at the end of each line, pretty much like Pascal, and the period at the end of the program.
 * 1) Type the following into a file called m3makefile:
 * [E:\Dev\Projects\Modula-3\First\src]e m3makefile
 * % this is a comment in the m3makefile
 * % this line tells m3 where to find the libraries
 * import("libm3")
 * % this line tells m3 what .m3 files exist (for this project only
 * % the "Main" one)
 * implementation("Main")
 * % this line tells m3 what to call the executable
 * program("First")
 * Figure 4: A Modula-3 "makefile".
 * 1) Type m3build:
 * [E:\Dev\Projects\Modula-3\First\src]m3build
 * Figure 5: Building the example.
 * You will see something like:
 * mkdir ../OS2 --- building in ../OS2 ---
 * m3 -w1 -why -g -o First -FE:/Tmp/qk000001.tmp
 * new source -> compiling ../src/Main.m3
 * -> linking First
 * Figure 6: Output during the compile.
 * You will have noticed that a directory called "OS2" was created next to your "src" directory within your "First" directory. It is the Modula-3 default to create a directory named for the platform to put the compiled files in, in our case "OS2".
 * 1) Run the program:
 * [E:\Dev\Projects\Modula-3\First]..\OS2\First
 * Hi World!
 * Figure 7: Output of the example.
 * 1) Marvel at the size of the executable. Static linking is all that is available at the moment.
 * [E:\Dev\Projects\Modula-3\First]..\OS2\First
 * Hi World!
 * Figure 7: Output of the example.
 * 1) Marvel at the size of the executable. Static linking is all that is available at the moment.

A More Complicated Example

 * 1) Go to the projects directory again, create another test program directory, and go there:
 * [E:\Dev\Projects\Modula-3\First]cd ..
 * [E:\Dev\Projects\Modula-3]md Second
 * [E:\Dev\Projects\Modula-3]cd Second
 * [E:\Dev\Projects\Modula-3\Second]
 * Figure 8: Creating another project directory.
 * 1) Create yet another src directory (name crucial) and go there:
 * [E:\Dev\Projects\Modula-3\Second]md src
 * [E:\Dev\Projects\Modula-3\Second]cd src
 * [E:\Dev\Projects\Modula-3\Second\src]
 * Figure 9: Creating auxiliary directories.
 * 1) Create the files as below:
 * (File: m3makefile)
 * % this line tells m3 where to find the libraries.
 * % normally "libm3" should be here. you may also need other
 * % libraries, in which case you add more lines like the one
 * % below, each with a path to the library you need.
 * import("libm3")
 * % this type of line tells m3 what .i3/.m3 file pairs exist.
 * % one of these lines is needed for each pair of .i3/.m3 files.
 * module("Helper")
 * % this type of line tells m3 what .m3 files exist without .i3
 * % files.  normally this is only the "Main" file,  which  doesn't have
 * % to be named "Main", as long as there is an "EXPORTS Main" line
 * % at the top of the file.
 * implementation("Second")
 * % this line tells m3 what to call the executable
 * program("Daring")
 * (File second.m3)
 * MODULE Second EXPORTS Main;
 * IMPORT Helper;
 * VAR
 * retVal: BOOLEAN;
 * BEGIN
 * retVal := Helper.PutText;
 * END Second.
 * (File helper.i3)
 * INTERFACE Helper;
 * PROCEDURE PutText: BOOLEAN;
 * END Helper.
 * (File: helper.m3)
 * MODULE Helper;
 * IMPORT IO;
 * VAR
 * retString: TEXT;
 * PROCEDURE PutText: BOOLEAN =
 * BEGIN
 * IO.Put(retString);
 * RETURN TRUE;
 * END PutText;
 * BEGIN
 * retString := "Hi again, World!";
 * END Helper.
 * Figure 10: Our second example.
 * 1) Type m3build:
 * [E:\Dev\Projects\Modula-3\Second\src]m3build
 * Figure 11: Building the example.
 * You will see something like:
 * mkdir ../OS2 --- building in ../OS2 ---
 * m3 -w1 -why -g -o Daring -FE:/Tmp/qk000001.tmp
 * new source -> compiling ../src/Helper.i3
 * new source -> compiling ../src/Helper.m3
 * new source -> compiling ../src/Second.m3
 * -> linking Daring
 * Figure 12: Output during the compile.
 * 1) Run the program:
 * [E:\Dev\Projects\Modula-3\First]..\OS2\Daring
 * Hi again, World!
 * Figure 13: Output of our example.
 * [E:\Dev\Projects\Modula-3\First]..\OS2\Daring
 * Hi again, World!
 * Figure 13: Output of our example.

This example demonstrates some of Modula-3's nicer features, such as enforced interfaces, nice built-in data types, extensive included libraries, easy-to-learn multi-module programming and so on.

Problems
If you had any problems, please go over everything again, carefully, and note any deviations from what is given here. Likely it is one of deviations which caused your problems. In particular, look for differences in case (upper/lower case is frequently crucial under UNIX, and much of this software was ported from UNIX), and drive and directory naming conventions.

You can post problems to the comp.lang.modula3 newsgroup. If you feel that the problem is OS/2-related, then prefix your post's subject with "OS/2: ..." to let others avoid having to read it only to discover that they didn't want to read it after all. If you are posting problems of any kind, always describe your system, with at least: which version of Modula-3 you are using, which version of OS/2 you are using, what anomalies exist in your setup, and what your config.sys has which is related to Modula-3, if relevant.

If you still can't find anything wrong, try mailing me at Carsten_whimster@iqpac.com. Please use the subject "M3: ..." so that I can sort my mail properly. Also, please allow me a couple of days to respond before you get desperate. I likely will not be able to tell you what is wrong either, though. Please do not mail me about Modula-3 programming.

Finally, you could try Klaus, but keep in mind that he may be busy before bugging him, and be polite. Limitations - Threads are not implemented yet. - Trestle (the windowing stuff) is not implemented yet, i.e. no PM yet, and some more stuff as well. This is all documented in Klaus' files.

Summary
This was a brief introduction to Modula-3 for OS/2, where to get it, what files to get, how to install it, and how to compile a couple of quick programs.

Now that you have verified that Modula-3 for OS/2 works for you, you probably need something more to chew on. I would suggest getting the Harbison book as a tutorial, getting the SPwM3 book as a more in-depth book, digging up some more example source code on the official SRC site at: ftp://ftp.labs.hpe.com/pub/DEC/SRC/hypertext/Modula-3/modula3.html

Information for both the above books exists on the SRC site. Go through the more extensive tutorials at: http://www.cs.columbia.edu/graphics/modula3/tutorial/www/m3_toc.html

Also make sure that you look through the interface files in \m3\install\lib\m3\pkg\libm3\src to get a feel for what comes with Modula-3. Finally, get onto the newsgroup comp.lang.modula3, post intelligent posts which can make all OS/2 Modula-3 users proud, and most importantly, write Modula-3 programs for OS/2 and release them.

Good luck!