[m-users.] Dealing with lists of enums as bitflags in C

emacstheviking objitsu at gmail.com
Tue Jul 9 17:13:28 AEST 2019


Zoltan, Julian..... whooooaaaaa!   That's information overload but having
just read it twice, it seems to be exactly what I am trying to do... I love
that fact that Julians code has a real sample of a lambda function as well,
and the implementation of flags_to_list is sublime!

OK, well that will keep me busy for a while not only reading it but truly
understanding it all to the point where I feel happy to use it and know
what is going on.

Again, thanks for the detail of your replies, it is really really
appreciated from this end! Mercury isn't the most widely written about
thing out here in non-academia land, there is google but mostly it ends up
at RosettaCode which also has been useful at times.

Thanks again,
Sean.


On Tue, 9 Jul 2019 at 00:15, Zoltan Somogyi <zoltan.somogyi at runbox.com>
wrote:

>
>
> On Mon, 8 Jul 2019 23:46:14 +0100, emacstheviking <objitsu at gmail.com>
> wrote:
> > By using the --make-target option to poke at the generated code I can see
> > that it comes into the C code as MR_Word, not MR_Word*thought and then I
> > tracked down the definitions of the MR_is_list_empty macros etc and
> > realised pretty quickly that there is no "MR_get_next" as it should be as
> > simple as pointer arithmetic but so far it has escaped my best efforts.
>
> The definition of MR_list_tail is right next to MR_list_head in
> runtime/mercury_tags.h.
> It follows the tail pointer field of the cons cell. There is no pointer
> arithmetic
> involved, because assuming contiguity of cons cells wouldn't work in the
> general case
> (since lists can be constructed dynamically).
>
> > have seen that the array is composed as a static array of values from the
> > MR_TAG_COMMON but I lost the trail at that point. Here is my code:
> >
> > :- pred sdl_createwindow(string::in, int::in, int::in, int::in, int::in,
> > list(window_flag)::in, io::di, io::uo) is det.
> > :- pragma foreign_proc("C",
> >     sdl_createwindow(Title::in, X::in, Y::in, W::in, H::in, Flags::in,
> > _IO0::di, _IO::uo),
> >     [promise_pure,will_not_call_mercury,does_not_affect_liveness],
> > "
> > Uint32 flags = 0;
> > if (Flags) {
> >     MR_Word* flagPtr = &Flags;
> >     while(!MR_list_is_empty(*flagPtr)) {
> >         Uint32 f = MR_list_head(*flagPtr);
> >         flags |= f;
> >         printf(""FLAGS: %u\\n"", flags);
> >         flagPtr++;
> >     }
> > }
>
> This is written as C code. In low level grades, the output of the Mercury
> compiler
> *looks* like C code, but it is actually assembly code in C syntax for
> portability.
> This is why (almost) everything has type MR_Word, which means only that
> it can be stored in a general purpose register.
>
> To see how you can traverse a list, see e.g. MR_typecheck_arguments in
> runtime/mercury_construct.c.
>
> Note that a list of integers or enums is about the most complex data
> structure
> for whose traversal in C the Mercury runtime system has any support for.
> For anything more complex, you need to know as much about Mercury's
> data representation rules as an implementor.
>
> Even in this case, I would recommend writing the code to OR the flags
> together
> in Mercury. This would require declaring the window_flag type to be a
> member
> of the enum typeclass, using the identity function as the implementation
> of the
> to_int method.)The Mercury compiler should be able to generate just as good
> C code as you could write yourself. And the Mercury code should be
> debuggable
> *without* general protection faults.
>
> Zoltan.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20190709/c268d7f2/attachment.html>


More information about the users mailing list