5

I'm writing a compiler that compiles to C, one thing I'm attempting to do is implement a construct like Rust's match:

// { some function
    let mut foo = 32;
    match foo {
        3 => return "hey",
        4 | 5 | 6 => return "foo",
        9 ... 12 => return "blah",
        _ => return "bar",
    }
// }

How would a construct like this look in C code? I was thinking something simple like this could be a switch construct like so:

switch (foo) {
    case 3: return "hey";
    case 4: case 5: case 6: return "foo";
    case 9: case 10: case 11: case 12: return "blah";
    default: return "bar";
}

And most importantly, how would it look for more complicated examples like this:

let pair = (0, -2);

match pair {
    (0, y) => println!("First is `0` and `y` is `{:?}`", y),
    (x, 0) => println!("`x` is `{:?}` and last is `0`", x),
    _      => println!("It doesn't matter what they are"),
}

Where the tuple is destructured and can handle values too?

  • I'm not familiar with Rust, but Swift has a switch statement with this same functionality, and it is spelled mostly like the C switch. Here's the doc: developer.apple.com/library/prerelease/content/documentation/… – Josh Caswell Sep 26 '16 at 16:47
  • @JoshCaswell I'm not sure what the spelling has to do with the implementation or semantics... – 8bittree Sep 26 '16 at 17:23
  • I'm not sure which facet the question is actually about, so I thought another example would be useful, @8bittree. "And most importantly, how would it look..." suggests that syntax is under consideration. – Josh Caswell Sep 26 '16 at 17:25
  • 1
    @JoshCaswell and Jee, I think the main issue here might be how to implement pattern matching and destructuring in C. match isn't the only place these can happen in Rust, e.g. let (a,b) = (1,2);. Solving the simpler situations might make the solution for match more obvious. Knowing how you're implementing tuples and other complex data types may also help. – 8bittree Sep 26 '16 at 17:35
  • This is called generalized pattern matching. It must be built into the language. C does not have this functionality. – gardenhead Sep 26 '16 at 18:00
4

Let's consider a super basic example. Your language only has two types, int and pair. Pairs can hold other pairs. For your "cases", you also have unbound variables.

So when you pass in the value to match, you can have an int or a pair. The pattern to match can be an int, a pair, or an unbound-variable. The pattern matching algorithm then goes:

if my pattern is an int, and the input is an int, if they're equal, do this.
if my pattern is a var, assign the value to the var, and do this.
if my pattern is a pair, and the input is a pair, then if 
    pattern-match(pattern.first, value.first) && 
    pattern-match(pattern.second, value.second), do this.
otherwise, try the next pattern.

For basic Lisps, which only have symbols and pairs - that's all they need. For other languages, you may need to extend the basics to handle other types, and maybe other structures.

And hopefully you can see how this becomes dicey once you have mutable state.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.