Skip to content

Commit

Permalink
compiler: forbid cascading match cases
Browse files Browse the repository at this point in the history
Erlang's `case` expression does not have an equivalent that we can
translate this to idiomatically, so we're forbidding it for now.

We'll revisit later on.

Close #9
  • Loading branch information
leostera committed Oct 30, 2020
1 parent d933a9b commit 0f80890
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 13 deletions.
14 changes: 14 additions & 0 deletions src/compiler/ocaml_to_erlang/error.ml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ let ppf = Format.err_formatter
let file_a_bug =
{| If you think this is a bug, please file an issue here: https://github.com/AbstractMachinesLab/caramel/issues/new |}

let unsupported_fallthrough_cases () =
Format.fprintf ppf
{|We have found a case expression that falls through to the next case, like:

match x with
| 0 | 1 -> true <--- this branch falls through
| _ -> false

Since these patterns are not possible in Erlang, Caramel does not support them
at the moment.
\n
|};
exit 1

let unsupported_let_rec_inside_of_function_body () =
Format.fprintf ppf
{|We have found a let rec binding within a function.
Expand Down
1 change: 1 addition & 0 deletions src/compiler/ocaml_to_erlang/fun.ml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ and mk_pattern :
let value = mk_pattern expr ~var_names in
Pat.tuple [ tag; value ]
| Tpat_constant const -> Erlang.Ast.Pattern_match (const_to_literal const)
| Tpat_or (_, _, _) -> Error.unsupported_fallthrough_cases ()
(* NOTE: here's where the translation of pattern
* matching at the function level should happen. *)
| _ -> Erlang.Ast.Pattern_ignore
Expand Down
5 changes: 0 additions & 5 deletions tests/compiler/expressions.t/match.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,3 @@ let match_tuples () =

let match_atoms () =
match `Hello with `Xavier -> true | `Joe -> true | _ -> false

let match_fall_through () =
match 0 with
| 1 | 2 -> true
| _ -> false
4 changes: 4 additions & 0 deletions tests/compiler/expressions.t/match_fallthrough.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let match_fall_through () =
match 0 with
| 1 | 2 -> true
| _ -> false
23 changes: 15 additions & 8 deletions tests/compiler/expressions.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
list.ml
literals.ml
match.ml
match_fallthrough.ml
names.ml
names_primes.ml
record_update.ml
Expand Down Expand Up @@ -381,7 +382,6 @@
-export_type([int_pair/0]).

-export([match_atoms/0]).
-export([match_fall_through/0]).
-export([match_ignore/0]).
-export([match_int/0]).
-export([match_list/0]).
Expand Down Expand Up @@ -459,13 +459,6 @@
_ -> false
end.

-spec match_fall_through() -> boolean().
match_fall_through() ->
case 0 of
_ -> true;
_ -> false
end.


$ caramelc compile names.ml
File "names.ml", line 15, characters 2-13:
Expand Down Expand Up @@ -629,3 +622,17 @@
}.


$ caramelc compile match_fallthrough.ml
We have found a case expression that falls through to the next case, like:

match x with
| 0 | 1 -> true <--- this branch falls through
| _ -> false

Since these patterns are not possible in Erlang, Caramel does not support them
at the moment.
\n
[1]
$ cat match_fallthrough.erl
cat: match_fallthrough.erl: No such file or directory
[1]

0 comments on commit 0f80890

Please sign in to comment.