Skip to content
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

Add support for switch with case statement instead of block statement #134

Merged
merged 6 commits into from
Feb 19, 2025

Conversation

xdufour
Copy link
Contributor

@xdufour xdufour commented Jan 19, 2025

As demonstrated by https://godbolt.org/z/zoh6c3Psq, a edge case for the syntax of the switch statement: https://learn.microsoft.com/en-us/cpp/c-language/switch-statement-c?view=msvc-170,

switch ( expression ) statement

where statement, although almost always a block-statement, isn't required to be one.

It can instead be a case statement, and even potentially multiple labelled statements, such that the resulting syntax is:

switch ( expression ) case constant-expression : statement

This PR adds support for this edge case in sh.c: comp_switch(), in order for the Godbolt snippet above to generate the following sh code and produce the expected output:

case 123 in
  123)
    printf "F"
  ;;
esac
case 456 in
  123|456)
    printf "E"
  ;;
esac

sh.c Outdated
while (get_op(node) == '{') {
statement = get_child(node, 0);
node = get_child(node, 1);
if (node == 0 || (get_op(node) != '{' && get_op(node) != CASE_KW)) fatal_error("comp_statement: switch without body");
Copy link
Collaborator

@laurenthuberdeau laurenthuberdeau Jan 19, 2025

Choose a reason for hiding this comment

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

I think changing the switch parser so that it always produces a { node (i.e. wrap the result in new_ast2('{', child1, 0) if the node is not 0 and not of type { ) would be best. That way it would also work with the following switch statement (which prints nothing):

switch (456) {
  putchar('B');
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough - it does simplify this edge case down to the more typical syntax the parser would expect as well.

After a quick test, it doesn't seem to work per say with the given example:
tests/_sh/switch.c:112:0 Expected case in switch. Fallthrough is not supported.

However, gcc 14.2 emits a warning saying it is an unreachable statement that will never get executed - so I would think it is fine to enforce it as ill-formed?

@laurenthuberdeau
Copy link
Collaborator

Thanks for the PR!

@laurenthuberdeau laurenthuberdeau merged commit bc734b4 into udem-dlteam:main Feb 19, 2025
37 checks passed
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.

2 participants