[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