[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