diff --git a/lib/back/closure_translator.ml b/lib/back/closure_translator.ml index 97ed582..6b37d55 100644 --- a/lib/back/closure_translator.ml +++ b/lib/back/closure_translator.ml @@ -74,6 +74,10 @@ let ff_match_constr = C.VARIABLE "ff_match_constr" let ff_match_tuple = C.VARIABLE "ff_match_tuple" +let ff_match_fail = C.VARIABLE "ff_match_fail" + +let ff_match_fail_stmt = C.(COMPUTATION (CALL (ff_match_fail, []))) + let header = {| #include "fun_rt.hpp" @@ -315,7 +319,8 @@ and trans_expr ctx e = ( res, [ C.DOWHILE - (C.CONSTANT (C.CONST_INT "0"), make_stmt_seq (e_stmts @ branches)); + ( C.CONSTANT (C.CONST_INT "0"), + make_stmt_seq (e_stmts @ branches @ [ ff_match_fail_stmt ]) ); ] ) | ECmp (op, e0, e1) -> let is_eq_v = create_decl "is_eq" ctx in diff --git a/runtime/include/fun_rt_core.hpp b/runtime/include/fun_rt_core.hpp index df7cb46..122e808 100644 --- a/runtime/include/fun_rt_core.hpp +++ b/runtime/include/fun_rt_core.hpp @@ -177,6 +177,8 @@ bool ff_match_tuple(ff_obj_t cond, ff_obj_t* const (&payloads)[N]) { return true; } +void ff_match_fail(); + ff_obj_t ff_is_equal(ff_obj_t x, ff_obj_t y); bool ff_is_equal_aux(const ff_obj_t& x, const ff_obj_t& y); diff --git a/runtime/src/fun_rt_core.cpp b/runtime/src/fun_rt_core.cpp index 7890808..7225734 100644 --- a/runtime/src/fun_rt_core.cpp +++ b/runtime/src/fun_rt_core.cpp @@ -153,6 +153,10 @@ bool ff_match_constr(int64_t id, ff_obj_t cond, ff_obj_t* payload) { return true; } +void ff_match_fail() { + throw std::runtime_error("Match failure!"); +} + bool ff_is_equal_aux(const ff_obj_t& x, const ff_obj_t& y) { if (x.tag != y.tag) { return false;