Skip to content

Implement support for case statements in Ada #171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 27, 2019

Conversation

NlightNFotis
Copy link
Contributor

This implements support for case statements in Ada. There was already support in for case expressions, which are pretty similar but their evaluation returns a value by default. I heavily modified the support for that to get this to work.

This is still a WIP. I want to add tests (I have them already, but they need to be cleaned up), and I also want to add tests for the case expression feature which seemed to be undocumented and untested as a feature. This is just to facilitate some early reviewing for the actual functionality.

@hannes-steffenhagen-diffblue
Copy link
Contributor

hannes-steffenhagen-diffblue commented Mar 22, 2019

Does this work for when others, ranges or alternatives?

i.e.

case x of
  when others => this_always_happens;
end case;
case x of
  when 0 | 1 | 2 => valid_ternary;
  when 3 => is_a_three;
  when others => is_something_else;
end case;
case x of
  when 0..15 => can_convert_to_hex_digit;
  when others => can_not;
end case;

see here for things that can appear in a case statement

@xbauch
Copy link
Contributor

xbauch commented Mar 22, 2019

This looks sensible to me.

Copy link
Collaborator

@martin-cs martin-cs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the right kind of direction


This_Alt : Node_Id := First (Alternatives (N));
begin
-- Do-while loop because there must be at least one alternative.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I am just old and paranoid BUT ... if you are assuming something it is best to make it an assert rather than a comment; even if it is 'obvious'.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely worth asserting, but the grammar does indeed guarantee this is true for now (but again, worth checking anyway, who knows what's going to happen in Ada 2023)
https://www.adaic.org/resources/add_content/standards/05rm/html/RM-3-8-1.html#S0073

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parent link of one Hannes posted (case statements)
https://www.adaic.org/resources/add_content/standards/05rm/html/RM-5-4.html

@NlightNFotis NlightNFotis marked this pull request as ready for review March 25, 2019 10:24
@NlightNFotis NlightNFotis self-assigned this Mar 25, 2019
@NlightNFotis
Copy link
Contributor Author

Just a heads up for this. It covers everything and works reliably for everything but ranges in the case statements. That fails, but it fails because Do_Expression doesn't handle ranges (this is my understanding at least, because it doesn't recognise the Node_Irep, it's falling in the when others case).

I am working on it, but it seems to be slightly expanded as scope, so I'd rather this go in as it is (it works and has tests) and then the ranges support goes in as part of a different PR.

Make_Case_Test
(Discrete_Choices (This_Alt_Copy)));
Set_Then_Case (This_Test, This_Stmt);
Append_Op (Ret, This_Test);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this line (and 1829) could be moved after the if-then-else block.

@xbauch
Copy link
Contributor

xbauch commented Mar 26, 2019

@NlightNFotis I would tend to agree: leave the ranges for another PR and just add a failing test here.

Copy link
Contributor

@xbauch xbauch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

when 0 | 1 | 2 => return "Valid ternary";
when 3 => return "Invalid ternary";
when others => return "";
end case;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this test not assert this function returns the right value?

when Elevation => return "Elevation sensor";
when Azimuth => return "Azimuth sensor";
when Distance => return "Distance sensor";
when others => return "";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert result

Sensor : Sensor_Type := Elevation;
begin
case Sensor is
when others => return "";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will approve once test cases are updated

return First_Alt_Test;
end if;
declare
Big_Or : constant Irep := New_Irep (I_Op_Or);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cute

Big_Or : constant Irep := New_Irep (I_Op_Or);
begin
Append_Op (Big_Or, First_Alt_Test);
Set_Type (Big_Or, New_Irep (I_Bool_Type));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make_Bool_Type, although even better we should probably just have a constant Bool_Type := Make_Bool_Type somewhere in this module so we don't keep recreating new ireps for all of these unnecessarily

@NlightNFotis NlightNFotis merged commit 4eac8bf into diffblue:master Mar 27, 2019
@NlightNFotis NlightNFotis deleted the case_statement_support branch March 27, 2019 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants