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