[Oberon] Numerical CASE Statements in Project Oberon
Chris Burrows
chris at cfbsoftware.com
Sun Nov 29 00:02:23 CET 2015
I am not talking about Ada or the Astrobe ARM compiler. I am talking about the Wirth's Oberon RISC5 compiler as used in Project Oberon. One example of the technique I used can be seen in the Project Oberon source code in ORG.Index:
IF x.mode IN {ORB.Var, RegI} THEN x.a := y.a * s + x.a
ELSIF x.mode = ORB.Par THEN x.b := y.a * s + x.b
This could have been, but was not, written as:
IF (x.mode = ORB.Var) OR (x.mode = RegI) THEN x.a := y.a * s + x.a
ELSIF x.mode = ORB.Par THEN x.b := y.a * s + x.b
x.mode is an INTEGER and {ORB.Var, RegI} is a SET constant just as in my version of your example t is an INTEGER and {7, 9..10}. This is perfectly valid RISC5 Oberon code.
If you want to advocate the use of 'numeric' CASE statements try again. Pick an example (preferably real world rather than hypothetical) that is not as easily transformed into IF THEN ELSE. The only type of example I can think of is one that uses a disjoint set of several characters e.g. {"a", "e", "i", "o", "u"}. That is the only significant argument I can think of that remains in support of the usefulness of 'numeric' CASE statements
Note also that the definition of SET in the Oberon Report has now become less restrictive
Oct 2013: the sets of integers between 0 and 31
Mar 2014: the sets of integers between 0 and an implementation-dependent limit
(Although the current RISC5 compiler has the limit set at 31).
------
In the following I AM now talking about the Astrobe ARM compiler:
A comparison of the releative efficiency / performance of IF THEN ELSE and CASE statements in the Astrobe ARM Oberon compiler is included in section 6.2 "CASE Statements" in the Astrobe Oberon Programmers Guide. You can download a copy from:
http://www.astrobe.com/Oberon.htm
The conclusion was:
"Timing tests using an example with ~30 cases, assuming each word occurs with the same frequency, indicates that the CASE solution is 4 times faster than the IF-THEN ladder solution. However, the CASE approach generates 5% more code."
Those sorts of results could make a significant difference to an application and were achieved using a jump table.
------
I do use Peter's Oberon RISC emulator to check disk images etc. but I have only used it on Windows and would have no idea what is causing the problem you have seen. You will just have to roll your sleeves up and start debugging :-; At the risk of stating the obvious, assuming you have been making your changes incrementally, go back to the last version that worked, check the changes you made at that time and isolate the issue down to a test case. By that time you will either have worked out the answer yourself or will have something simple to report to Peter to identify.
Cheers,
Chris
>
> From: Jan de Kruyf [mailto:jan.de.kruyf at gmail.com]
> Sent: Sunday, 29 November 2015 7:04 AM
> To: chris at cfbsoftware.com; ETH Oberon and related systems
> Subject: Re: [Oberon] Numerical CASE Statements in Project Oberon
>
> This is Ada, or set membership Chris, but you might have it included
> in your compiler.
>
> "x IN s stands for "x is an element of s". x must be of type INTEGER,
> and s of type SET."
>
> both in O-2 and O-7.
> While I was comparing character or integer conditionals. Sure, in
> real life if your cases are under 32 you might choose to use a set
> rather than a case construct.
> ---
>
> But I want to ask you something that you might know:
> For starters I modified the Parser and the code Generator under
> norebo from Peter de Wachter which is a derivative of his RISC
> intepreter. In any case this worked fine.
>
> Then I modified the Scanner of the compiler to have the case
> construct. This also implied recompiling ORB.
> Everything compiled fine, but noway can I get the complete compiler
> to run.
>
> It brakes on a STR or LDR instruction that is used as a Linux kernel
> signal / call, but the IO address is not right the runtime says.
>
> So I am a bit at loss here. Did Peter modify the compiler source code
> at all to accomodate his Linux interface or is it some silly bug I
> introduced?
>
> Have you used his interpreter at all?
>
> Thanks,
>
> j.
>
>
> On Sat, Nov 28, 2015 at 2:18 PM, Chris Burrows
> <chris at cfbsoftware.com> wrote:
> Maybe so, but that is not a fair comparison. I would have written
> your IF THEN ELSE example as:
>
> IF t DIV 32 = 0 THEN
> IF t IN {7, 9..10} THEN
> t := 11
> ELSIF t IN {13, 14..16} THEN
> t := 12
> END
> END;
>
> Which is only 32 instructions using your same method of counting.
>
> If (as in your example) you knew for sure that t was in the range of
> 0..31 you wouldn't need the initial DIV statement either,
>
> Regards,
> Chris Burrows
> CFB Software
> http://www.astrobe.com
>
>
> >
> > From: Oberon [mailto:oberon-bounces at lists.inf.ethz.ch] On Behalf Of
> > Jan de Kruyf
> > Sent: Friday, 27 November 2015 2:04 AM
> > To: ETH Oberon and related systems
> > Subject: Re: [Oberon] Numerical CASE Statements in Project Oberon
> >
> > Here is some news:
> >
> > We get cleanly compiling code.
> >
> > With this test module:
> > -------
> > MODULE TestIf;
> > VAR t : INTEGER;
> >
> > BEGIN
> > t := 10;
> > IF ((t >= 9) & (t <= 11)) OR (t = 7) THEN
> > t := 11;
> > ELSIF (t = 13) OR ((t >= 14) & (t <= 16)) THEN
> > t := 12
> > END;
> >
> > CASE t OF
> > 9 .. 11, 7 : t := 11;
> > |13, 14 .. 16 : t := 12
> > END;
> >
> > END TestIf.
> > -----------
> >
> > When I only compile the IF structure I get 37 assembly
> instructions,
> > average seek for named values is 13.66 instruction times.
> > When I only compile the CASE structure I get 40 assembly
> instructions,
> > average seek for named values is 7.33 .
> > (this is from doing a hand count through the search structure)
> >
> > A lot of waste in the IF is generated by reloading the 't' variable
> > for every compare, while I steal a register to keep 't' loaded.
> >
> > j.
> >
> >
More information about the Oberon
mailing list