Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

Oberon-M and Wikipedia sample code (PointerBirds) (Developers)

posted by Rugxulo Homepage, Usono, 15.03.2012, 00:39

(N.B. I know most people here don't directly care about this, but just humor me.)

The Wikipedia article for Oberon-2 quotes an interesting example: PointerBirds. With a few tweaks, it will compile correctly for Oberon-M for DOS. (Others compile it too if you make sure the filename matches the internal MODULE name.) For clarity and documentation purposes, I will mention my changes here:

1). First, make sure it's in CR+LF format as OC.EXE doesn't like otherwise. "unix2dos -k -q ptrbirds.mod" should suffice.

2). To minimize changes, you will need to create an Out.mod using Term.mod unless you want to change all occurrences of Out.Ln to Term.WL and Out.String to Term.WS.

3). The most glaring change is a "WITH" syntax difference between original Oberon and Oberon-2. Originally it didn't support '|' for other options, so you're stuck to either a single typeguard for each statement or IS (test but can't modify) + WITH ("regional typeguard") combined, which I preferred here for consistency.

4). The weird thing about Oberon is that there isn't really a clearly-defined "main" module. I guess any client module can call any other client module. In XDS, for instance, this is important when (needing to tell it to) link to .EXE and is forced via pragma "<* +MAIN *>", which other compilers hate, or (obsolete, deprecated) "(*$MAIN+ *)" [sic! else it probably won't get recognized or link like you want!].

In other words, there are several exported procedures etc. here, despite PointerBirds being the "main" module, so OC.EXE gets confused and demands you create a .REF for it first. (And, no, I tried linking anyways or hacking, didn't help.) So you have to do one of two things: manually delete all export stars '*' since it's not being used to export to anything or (to minimize changes) create a bogus main module that imports PointerBirds and has its own empty "BEGIN END" initialization.

5). Compile and link order seems to matter, so you have to be careful else the runtime will whine about certain modules being outdated. In other words, compile the heaviest dependencies (e.g. Term) first and "main" last, but presumably you must always link with sys.obj last.

Long story short, here's the (hopefully minimized) unified Diff:


diff -wasruN old/birds.mod new/birds.mod
--- old/birds.mod       1970-01-01 00:00:00 +0000
+++ new/birds.mod       2012-03-14 17:55:26 +0000
@@ -0,0 +1,3 @@
+MODULE birds;
+IMPORT ptrbirds;
+BEGIN END birds.
diff -wasruN old/birds.out new/birds.out
--- old/birds.out       1970-01-01 00:00:00 +0000
+++ new/birds.out       2012-03-14 18:02:32 +0000
@@ -0,0 +1,18 @@
+
+Cuckoo!
+
+Quack!
+
+Cuckoo!
+
+Quack!
+
+Quack!
+
+Cuckoo!
+
+Cuckoo!
+
+Quack!
+
+Tweet!
diff -wasruN old/make.bat new/make.bat
--- old/make.bat        1970-01-01 00:00:00 +0000
+++ new/make.bat        2012-03-14 18:01:46 +0000
@@ -0,0 +1,15 @@
+@echo off
+REM Oberon-M 1.2 for DOS
+
+for %%m in (term out ptrbirds birds) do if exist %%m.mod oc %%m def 8086
+for %%o in (term out ptrbirds birds) do if not exist %%o.obj goto end
+
+:jwlink
+jwlink format dos file birds,ptrbirds,out,term,sys
+if exist birds.exe goto end
+
+:alink
+hackomf birds.obj
+alink -oEXE birds.obj ptrbirds.obj out.obj term.obj sys.obj
+
+:end
diff -wasruN old/out.mod new/out.mod
--- old/out.mod 1970-01-01 00:00:00 +0000
+++ new/out.mod 2012-03-14 17:56:08 +0000
@@ -0,0 +1,5 @@
+MODULE Out;
+IMPORT Term;
+PROCEDURE Ln* ; BEGIN Term.WL END Ln;
+PROCEDURE String* (str: ARRAY OF CHAR); BEGIN Term.WS(str) END String;
+END Out.
diff -wasruN old/ptrbirds.mod new/ptrbirds.mod
--- old/ptrbirds.mod    2012-03-13 12:54:30 +0000
+++ new/ptrbirds.mod    2012-03-14 18:08:20 +0000
@@ -1,4 +1,4 @@
-MODULE PointerBirds;
+MODULE ptrbirds;
     IMPORT Out;
 
     TYPE
@@ -27,13 +27,13 @@
 
     PROCEDURE SetSound*( bird : Bird );
     BEGIN
-        WITH bird : Cuckoo DO
+        IF bird IS Cuckoo THEN WITH bird : Cuckoo DO
              SetCuckooSound(bird)
-           | bird : Duck   DO
+           END ELSIF bird IS Duck THEN WITH bird : Duck   DO
              SetDuckSound(bird)
-        ELSE
+        END ELSE WITH bird : Bird DO
              bird.sound := "Tweet!"
-        END
+        END END
     END SetSound;
 
 BEGIN
@@ -81,4 +81,4 @@
   
    SetSound(pb);
    Out.Ln; Out.String( pb^.sound ); Out.Ln
-END PointerBirds.
+END ptrbirds.

 

Complete thread:

Back to the forum
Board view  Mix view
22049 Postings in 2034 Threads, 396 registered users, 241 users online (0 registered, 241 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum