[Oberon] Alternatives for cases.

peter at easthope.ca peter at easthope.ca
Thu Mar 7 21:15:55 CET 2019


From:	Chris Burrows <chris at cfbsoftware.com>
Date:	Thu, 7 Mar 2019 07:13:32 +1030
> This is one of my test CASEs ... Try implementing 
> that using procedures and see what you think.

After compiling in A2, MM on CBcase.Inc "string".

> Consider the resulting readability 

Extremely readable of course!  (I wrote it.  =8~) )

Seriously, yes, the volume is bigger than the IF form; but absence of 
IF is a benefit and the compactness of Inc is noticeable.  Where FOR 
is available, the WHILEs can be replaced.

> maintainability

Organization is apparent.  Maintainability as good as the IF form.

> code size

See above.

> speed of execution

I've never tried to time execution in Oberon.  Your numbers 
are convincing.

From:	=?utf-8?Q?J=C3=B6rg_Straube?= <joerg.straube at iaeth.ch>
Date:	Thu, 7 Mar 2019 07:45:28 +0100
> your „case[choice]()“ is basically what a „CASE choice OF“ 
> does. So there is no clear runtime benefit of your aporoach vs. CASE.
> 
> But you have to declare PROCEDUREs that is not needed in case of CASE. 
> A procedure generates quite some overhead during BEGIN and END. So the 
> runtime behaviour of the jump as such is comparable to CASE but the 
> code you jump to takes longer in your approach compared to CASE.

OK, thanks.

> From:	Andreas Pirklbauer <andreas_pirklbauer at yahoo.com>
> Date:	Thu, 7 Mar 2019 07:57:47 +0100
> In addition, the compiler will generate array index checks during case selec=
> tion for the case array.
> 
> The CASE statement clearly has less overhead.

Thanks.

What introduction to compilers is recommendable now?  Wirth's _Compiler 
Construction_? Something more recent?

From:	Chris Burrows <chris at cfbsoftware.com>
Date:	Thu, 7 Mar 2019 22:15:40 +1030
>          Data (bytes)    Code (bytes)    Time (ms)
> PROCs     540            1404              65
> IF-ELSE     8             864              53
> CASE        8            1080              42

Nice!  Satisfying that costs for PROCs are only fractionally  worse 
than conventional statements.  Not orders of magnitude.  I'm convinced 
to use IF and CASE.

Regards,               ... Lyall E.

==============================  *)
MODULE CBcase IN Oberon;
	IMPORT Texts, Oberon;
	VAR 
		i, others, letters, digits, capitals, vowels: INTEGER;
		case: ARRAY 256 OF PROCEDURE;
		W: Texts.Writer;
		parScn: Texts.Scanner;

	PROCEDURE   O(); BEGIN INC(others)  END O;
	PROCEDURE   L(); BEGIN INC(letters)  END L;
	PROCEDURE   D(); BEGIN INC(digits)  END D;
	PROCEDURE  LC(); BEGIN INC(letters); INC(capitals) END LC;
	PROCEDURE  VL(); BEGIN INC(vowels); INC(letters) END VL;
	PROCEDURE VLC(); BEGIN INC(vowels); INC(letters); INC(capitals) END VLC;

	PROCEDURE InitCase();
	BEGIN
		i :=    0;     WHILE i <  256      DO case[i] :=  O; INC(i) END;

		i := ORD("b"); WHILE i <= ORD("z") DO case[i] :=  L; INC(i) END;
		i := ORD("B"); WHILE i <= ORD("Z") DO case[i] := LC; INC(i) END;
		i := ORD("0"); WHILE i <= ORD("9") DO case[i] :=  D; INC(i) END;

		case[ORD("a")] := VL; case[ORD("e")] := VL; case[ORD("i")] := VL;
		case[ORD("o")] := VL; case[ORD("u")] := VL;

		case[ORD("A")] := VLC; case[ORD("E")] := VLC; case[ORD("I")] := VLC;
		case[ORD("O")] := VLC; case[ORD("U")] := VLC;
		Texts.WriteString(W, "case array initialized."); Texts.WriteLn(W);
		Texts.Append(Oberon.Log, W.buf) 
	END InitCase;
	
	PROCEDURE Report();
	BEGIN
		Texts.WriteString(W, "others = ");   Texts.WriteInt(W, others, 0);  Texts.WriteLn(W);
		Texts.WriteString(W, "letters = ");  Texts.WriteInt(W, letters, 0); Texts.WriteLn(W);
		Texts.WriteString(W, "digits = ");   Texts.WriteInt(W, digits, 0);  Texts.WriteLn(W);
		Texts.WriteString(W, "capitals = "); Texts.WriteInt(W, capitals, 0);Texts.WriteLn(W);
		Texts.WriteString(W, "vowels = ");   Texts.WriteInt(W, vowels, 0);  Texts.WriteLn(W);
		Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
	END Report;
	
	PROCEDURE Inc*;
		VAR 
			i: INTEGER;
			ch: CHAR;
	BEGIN
		Texts.OpenScanner(parScn, Oberon.Par.text, Oberon.Par.pos);
		Texts.Scan(parScn);
		IF parScn.class = Texts.String THEN
			Texts.WriteString(W, "parScn.s = "); Texts.WriteString(W, parScn.s); Texts.WriteLn(W);
			i := 0;
			WHILE (i < MAX(INTEGER)) & (parScn.s[i] # 0X) DO
				case[ORD(parScn.s[i])];
				INC(i);
				Report()
			END
		ELSE
			Texts.WriteString(W, "Parameter of commmand not appropriate."); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
		END;
		Texts.Append(Oberon.Log, W.buf)
	END Inc;

BEGIN
	Texts.OpenWriter(W);
	others := 0; letters := 0; digits := 0; capitals := 0; vowels := 0;
	InitCase()
END CBcase.

CBcase.Inc "abc"


-- 
Message composed and transmitted by software designed to avoid the 
complication and vulnerability of antivirus software.

123456789 123456789 123456789 123456789 123456789 123456789 123456789
Pender Is., BC: +1 604 670 0140     Washington State: +1 360 639 0202
http://easthope.ca/Peter.html              Bcc: peter at easthope. ca


More information about the Oberon mailing list