[m-users.] uint32 FFI problem

Julian Fondren jfondren at minimaltype.com
Sun Jul 7 12:00:04 AEST 2019


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


More information about the users mailing list