Case statement won't compile

I had some code that worked, then after a change won’t compile, but I don’t
understand why.

The code that compiled and worked had three value constructors and a FSS
that switched states between two states, AtomicA and Atomic B. You can see
this i the code here:

datatype pstate =
| AtomicA of ()
| AtomicB of ()
| Hang of ()

typedef state = @{ addr= uint8, ps= pstate }
fun process (ch:int, s: &state) : void = let
val sn = case s.ps of
| AtomicA () => let
val _ = case cast{char}(ch) of
| ‘z’ => let
val _ = do_something()
in s.addr := s.addr; s.ps :=
AtomicA end
| _ => let _ in _ end
in _ end
| AtomicB () => let _
val _ = case cast{char}(ch) of
| ‘z’ => let
val _ = do_something()
in s.addr := s.addr; s.ps :=
AtomicB end
| _ => let _ in _ end
in _ end

          | Hang () => _

in
end

Then I added two constructors, and made the transitions more complex, as
the case for AtomicA can change to one of two states. Then it won’t compile
and gives the error:

undefined reference to `atsruntime_handle_unmatchedval’

The range of lines is the entire top self case statement.

I change the top level case from “case” to “case+” and it compiles.

Can anyone explain why this makes it compile?

Note that all cases are covered because they all have a “_” pattern at the
bottom to match on.

datatype pstate =
| AtomicA of ()
| NonAtomicA of ()
| AtomicB of ()
| NonAtomicB of ()
| Hang of ()

typedef state = @{ addr= uint8, ps= pstate }
fun process (ch:int, s: &state) : void = let
val sn = case s.ps of
| AtomicA () => let
val _ = case cast{char}(ch) of
| ‘z’ => let
val _ = do_something()
in s.addr := s.addr; s.ps :=
NonAtomicA end
| ‘T’ => let
val mode = serial_poll()
val ns = if mode = 1 then AtomicA
else AtomicB
in s.addr := s.addr; s.ps := ns
end
| _ => let _ in _ end
in _ end
| AtomicB () => let _
val _ = case cast{char}(ch) of
| ‘z’ => let
val _ = do_something()
in s.addr := s.addr; s.ps :=
NonAtomicB end
| ‘T’ => let
val mode = serial_poll()
val ns = if mode = 1 then AtomicA
else AtomicB
in s.addr := s.addr; s.ps := ns
end
| _ => let _ in _ end
in _ end
| NonAtomicA () => let
in _ end
| NonAtomicB () => let _
in _ end

          | Hang () => _

in
end

In ATS, pls use either case+ or case-; if you use case, the compiler
currently always add a run-time catchall.On Oct 1, 2015 5:43 PM, “Mike Jones” proc...@gmail.com wrote:

I had some code that worked, then after a change won’t compile, but I
don’t understand why.

The code that compiled and worked had three value constructors and a FSS
that switched states between two states, AtomicA and Atomic B. You can see
this i the code here:

datatype pstate =
| AtomicA of ()
| AtomicB of ()
| Hang of ()

typedef state = @{ addr= uint8, ps= pstate }
fun process (ch:int, s: &state) : void = let
val sn = case s.ps of
| AtomicA () => let
val _ = case cast{char}(ch) of
| ‘z’ => let
val _ = do_something()
in s.addr := s.addr; s.ps :=
AtomicA end
| _ => let _ in _ end
in _ end
| AtomicB () => let _
val _ = case cast{char}(ch) of
| ‘z’ => let
val _ = do_something()
in s.addr := s.addr; s.ps :=
AtomicB end
| _ => let _ in _ end
in _ end

          | Hang () => _

in
_
end

Then I added two constructors, and made the transitions more complex, as
the case for AtomicA can change to one of two states. Then it won’t compile
and gives the error:

undefined reference to `atsruntime_handle_unmatchedval’

The range of lines is the entire top self case statement.

I change the top level case from “case” to “case+” and it compiles.

Can anyone explain why this makes it compile?

Note that all cases are covered because they all have a “_” pattern at the
bottom to match on.

datatype pstate =
| AtomicA of ()
| NonAtomicA of ()
| AtomicB of ()
| NonAtomicB of ()
| Hang of ()

typedef state = @{ addr= uint8, ps= pstate }
fun process (ch:int, s: &state) : void = let
val sn = case s.ps of
| AtomicA () => let
val _ = case cast{char}(ch) of
| ‘z’ => let
val _ = do_something()
in s.addr := s.addr; s.ps :=
NonAtomicA end
| ‘T’ => let
val mode = serial_poll()
val ns = if mode = 1 then
AtomicA else AtomicB
in s.addr := s.addr; s.ps := ns
end
| _ => let _ in _ end
in _ end
| AtomicB () => let _
val _ = case cast{char}(ch) of
| ‘z’ => let
val _ = do_something()
in s.addr := s.addr; s.ps :=
NonAtomicB end
| ‘T’ => let
val mode = serial_poll()
val ns = if mode = 1 then
AtomicA else AtomicB
in s.addr := s.addr; s.ps := ns
end
| _ => let _ in _ end
in _ end
| NonAtomicA () => let
in _ end
| NonAtomicB () => let _
in _ end

          | Hang () => _

in
_
end


You received this message because you are subscribed to the Google Groups
“ats-lang-users” group.
To unsubscribe from this group and stop receiving emails from it, send an
email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.
Visit this group at http://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit
https://groups.google.com/d/msgid/ats-lang-users/c87bd596-75a6-45b9-b63a-c3a65992c14a%40googlegroups.com
https://groups.google.com/d/msgid/ats-lang-users/c87bd596-75a6-45b9-b63a-c3a65992c14a%40googlegroups.com?utm_medium=email&utm_source=footer
.