request switch statement with common block
Andre Artus
andre.artus at gmail.com
Sun Aug 4 21:07:50 PDT 2013
>> Andre Artus:
>> int number;
>> string message;
>> switch (number)
>> {
>> default: // valid: ends with 'throw'
>> throw new Exception("unknown number");
>> case 3:
>> message ~= "three "; break;
>> case 4:
>> message ~= "four "; continue;
>> case 5:
>> message ~= "five "; goto case;
>> case 6:
>> message ~= "six "; break;
>> case 1:
>> case 2:
>> message = "one or two";
>> }
>>
>> With the inclusion of 'default' the condition covers the whole
>> range of 'int'. The programmer may only want the pre and post
>> code to be executed for every other case (1..6).
> MattCoder:
> Like I said, it would be nice if we could extend some D
> features without change the compiler source, maybe like macros
> in LISP.
It may not always be the case, but in my experience this often
leads to write-only code.
I'm pretty new to D, so I'm not quite up to speed with the
metaprogramming abilities, but I'm under the impression that this
is what mixin's are for.
> MattCoder:
> The switch statement should have an event handler like:
> onBeforeMatch or onAfterMatch to handle this.
>
> But for what I saw on this thread, this is only possible
> changing the compiler source. :/
>
> Matheus.
In order to produce the most sane (in my opinion) construct the
code cannot be rewritten as JS suggested:
> JS:
>
> if (cond) { <common_body1> }
> switch (cond)
> {
> case <symbol> : <case body> [break or return or fallthrough]
> ...
> <default> : <default_body> [break or return or fallthrough]
> }
> if (cond) { <common_body2> }
> if (!cond) { <else_body> }
As I mentioned before `switch` takes an expression that evaluates
to integral or char[], the condition is completed in the `case`.
The condition leading to the 'common' entry and exit code must
replicate that of the complete switch statement. This begs the
question about how to handle `default`. It would be difficult to
correctly reason about the code without additional information.
The only suggestion that leads to sane results in all (maybe?)
cases is that made by Ary Borenszweig.
> Ary Borenszweig:
>
> switch(cond) {
> case A:
> common_code();
> // something
> case B:
> common_code();
> // something else
> }
I would think that the common code could be factored into a
function taking a void delegate (analogous to C# Action<T>
delegate) then passing the case specific code as a lambda. This
is something I have done in C#, but not yet in D.
In C# you would something like this:
private void UseAGoodNameDescribingCommonCode(Action action)
{
// Entry code
action();
// Exit code
}
switch(expression) {
case A:
UseAGoodNameDescribingCommonCode(() => {
// something
});
break;
case B:
UseAGoodNameDescribingCommonCode(() => {
// something
});
break;
default:
// Something else
}
It's very clear where it's being applied, and where it is not.
If the compiler was rewriting the following:
switch(expression) {
common_entry: // should not be order specific i.e. overloading
'common'
// entry code
break;
common_exit:
// exit code
break;
case A:
// something
break;
case B:
// something else
break;
default:
// default something
}
It could produce something like this:
switch(expression) {
common_entry: // should not be order specific i.e. overloading
'common'
// entry code
goto pop_label();
common_exit:
// exit code
break;
case A:
// could set var or register used push/pop for clarity of intent
push_label(A_prime);
goto case common_entry;
label A_prime:
// something
goto case common_exit;
// break not needed here;
case B:
// rinse & repeat
label B_prime:
// rinse & repeat
default:
// default something
}
What to do with default needs to be disambiguated.
More information about the Digitalmars-d
mailing list