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.