[m-users.] uint32 FFI problem

emacstheviking objitsu at gmail.com
Sun Jul 7 20:18:42 AEST 2019


Julian, Peter,

@Peter ---> you hit the nail on the head and...
@Julian  ---> explained how the nail was constructed in great detail.

Thank you both, I now fully get it...my problem then somewhere is actually
reading the documentation and seeing the relevant bits! [ or uint32-s even
;) ]

The fundamental problem here was just not knowing how to express a literal
value as a different type I guess.
I knew that changing my C code was merely a feeble way to "remove" the
problem where you have not both provided me with the correct information to
"do things properly".

I have since read
https://www.mercurylang.org/information/doc-latest/mercury_ref/Primitive-types.html#Primitive-types
much much more closely!   When learning things I sometimes have a tendency
to skip the details in order to get to the coalface a little quicker...I am
intrigued my Mercury and it's ability to cross comple to Erlang and Java...
I use both in my day job and the prospect of slipping a little mercury into
the mix in the future, having gained at leat basic competency, would be
really interesting indeed!

Thanks again everybody.
Sean.


On Sun, 7 Jul 2019 at 03:46, Julian Fondren <jfondren at minimaltype.com>
wrote:

> On 2019-07-06 15:05, emacstheviking wrote:
> > Getting to grips with the FFI and starting to create/port my GNU
> > Prolog SDL2 wrapper from long ago. The "extras/graphics" folder is
> > amazing amount of work but I liked SDL so I figured if I ever complete
> > it to standard then it might complete the set!
> >
> > I can't figure out why I can't use "uint32" in the predicate
> > declaration, currently I use int but cast the value:
> >
> > :- pred sdl_delay(int::in, io::di, io::uo) is det.
> > :- pragma foreign_proc("C",
> >   sdl_delay(MSecs::in, _IO0::di, _IO::uo),
> >   [promise_pure,will_not_call_mercury,does_not_affect_liveness],
> > "
> > SDL_Delay((Uint32)MSecs);
> > ").
> >
> > What I *want* to do is this:
> >
> > :- pred sdl_delay(uint32::in, io::di, io::uo) is det.
> > :- pragma foreign_proc("C",
> >   sdl_delay(MSecs::in, _IO0::di, _IO::uo),
> >   [promise_pure,will_not_call_mercury,does_not_affect_liveness],
> > "
> > SDL_Delay(MSecs);
> > ").
> >
> > But when I do thois the compiler is angry with me:   :(
>
> It seems like you think you're fixing this by changing the C code, but
> really you are correcting the error by changing your Mercury.
> Consider:
>
>    :- module uintx.
>    :- interface.
>    :- import_module io.
>    :- pred main(io::di, io::uo) is det.
>    :- implementation.
>    :- import_module uint32.
>
>    :- pred do_nothing(uint32::in) is det.
>    do_nothing(_).
>
>    main(!IO) :-
>        do_nothing(42).
>
> This fails to compile with a very similar error:
>
>    $ mmc uintx
>    uintx.m:012: In clause for predicate `main'/2:
>    uintx.m:012:   in argument 1 of call to predicate
> `uintx.do_nothing'/1:
>    uintx.m:012:   type error: argument has type `int',
>    uintx.m:012:   expected type was `uint32'.
>
> do_nothing/1 and your wanted sdl_delay accept an int32, but here and
> in your code an int being passed to it. The type error,
>
>    uintx.m:012:   type error: argument has type `int',
>    uintx.m:012:   expected type was `uint32'.
>
> is between the pred definition (expected type) and a given parameter
> (argument has type) in a given invocation (line 12 in main/2):
>
>    uintx.m:012: In clause for predicate `main'/2:
>    uintx.m:012:   in argument 1 of call to predicate
> `uintx.do_nothing'/1:
>
> You've fixed this by changing your predicate definition to no longer
> expect an int32 -- the change in your C code is incidental to thix
> fix. The other way to fix this is of course to change the type of the
> argument that is passed where this predicate is called:
>
> This compiles without error:
>
>    :- module uintx.
>    :- interface.
>    :- import_module io.
>    :- pred main(io::di, io::uo) is det.
>    :- implementation.
>    :- import_module uint32.
>
>    :- pred do_nothing(uint32::in) is det.
>    do_nothing(_).
>
>    main(!IO) :-
>        do_nothing(cast_from_int(42)).
>
> > sdl2.m:067: In clause for predicate `main'/2:
> > sdl2.m:067:   in argument 1 of call to predicate `sdl2.sdl_delay'/3:
> > sdl2.m:067:   type error: argument has type `int',
> > sdl2.m:067:   expected type was `uint32'.
> > sdl2.m:067:   The partial type assignment was:
> > sdl2.m:067:     IsUp_4: bool.bool
> > sdl2.m:067:     V_5: string
> > sdl2.m:067:     STATE_VARIABLE_IO_0_7: io.state
> > sdl2.m:067:     STATE_VARIABLE_IO_8: io.state
> > sdl2.m:067:     V_9: string
> > sdl2.m:067:     V_10: list.list(string.poly_type)
> > sdl2.m:067:     STATE_VARIABLE_IO_11_11: io.state
> > sdl2.m:067:     STATE_VARIABLE_IO_12_12: io.state
> > sdl2.m:067:     STATE_VARIABLE_IO_19_19: io.state
> > sdl2.m:067:     V_20: string
> >
> > i can see it's a type error but I thought that uint32 was a built in
> > mercury type that would translate into the C code without issue.  ?!?!
>
> A bare literal like 42 is an int, though. I haven't looked at Haskell
> in years and years, so this might've changed, but I remember its
> networking library had a type called 'Port' which was an integer type
> without its own literal syntax, so you had to use fromIntegral to
> avoid a similar type error.
>
> > Sean.
> > _______________________________________________
> > users mailing list
> > users at lists.mercurylang.org
> > https://lists.mercurylang.org/listinfo/users
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20190707/857eac80/attachment.html>


More information about the users mailing list