[Oberon] CASE without ELSE

Chris Burrows chris at cfbsoftware.com
Thu Feb 15 21:51:46 CET 2018


> -----Original Message-----
> From: Oberon [mailto:oberon-bounces at lists.inf.ethz.ch] On Behalf Of
> Josef Templ
> Sent: Friday, 16 February 2018 12:58 AM
> To: oberon at lists.inf.ethz.ch
> Subject: [Oberon] CASE without ELSE
> 
> Hi everybody,
> 
> recently I noticed that there is no ELSE clause in the CASE statement
> of the latest Oberon language version.
> Has this been removed intentionally or accidentally? Or is there
> something new instead of it?
> 

As far as I know it was removed intentionally. The original programmer has to explicitly handle all cases. This helps a subsequent maintainer of the software to understand the programmers intentions. He does not have to try and guess whether an overlooked case was accidental or not.

> If it has been removed intentionally:
> Is there a significant simplification in the compiler or a speedup at
> runtime?
> 

Not if the CASE statement is efficiently implemented as a jump table (for runtime speed) - assuming the compiler traps missing cases as runtime errors.

> On the other side, it puts some burden onto the programmer to work
> around it.
> As an example: I tried to implement a simple command interpreter that
> reads a character
> from a serial line (connected to a keyboard) and executes a related
> procedure in an embedded target.
> The natural language construct, I thought, would be a CASE for that
> kind of problem.
> Pressing an invalid key could be ignored easily by the ELSE clause of
> the CASE.
> 

Suppose you had 5 commands "I", "L", "T", "Q", and "X". In the Astrobe RISC and Cortex-M Oberon compilers on of the simplest (but not the most elegant or efficient) way to do this would be something like 

(*untested*)
IF String.Pos(ch, "ILTQX", 0) < 0 THEN
  (* Process error *)
ELSE
  CASE ch OF
   "L": ....


Ideally you would map your command characters to symbolic constants at the earliest opportunity and then use those in your logic. Something like this:

CONST
  Inspect = 0;
  Load = 1;
  Transfer = 2;
  Exit = 3;
  Invalid = 4;

VAR
  Command: INTEGER;

PROCEDURE ToCommand(ch: CHAR): INTEGER;
(* Use an array map or a hash table to map your characters to command values *)
...
...


CASE command OF
  Inspect: ... |
  ....
  Invalid: (* Process error *)
END;

Regards,
Chris Burrows
CFB Software
http://www.astrobe.com/RISC5





More information about the Oberon mailing list