Nim: How to wrap a c struct that contains bitfields? - binding

The question is if I see a bitfield in a c struct as such:
struct Example
{
int A;
int B;
int C : 3;
int D : 3;
int E : 3;
int F : 8;
bool G : 1;
bool H : 1;
};
Would the correct binding in Nim be as such?
type Example {.packed, importc: "Example", "example.h".} = object
a {.importc: "a".} : int32
b {.importc: "b".} : int32
c {.bitsize: 3, importc: "c".} : int32
d {.bitsize: 3, importc: "d".} : int32
e {.bitsize: 3, importc: "e".} : int32
f {.bitsize: 8, importc: "f".} : int32
g {.bitsize: 1, importc: "g".} : bool
h {.bitsize: 1, importc: "h".} : bool
or as such?
type Example {.importc: "Example", "example.h".} = object
a {.importc: "a".} : int32
b {.importc: "b".} : int32
c {.importc: "c".} : int32
d {.importc: "d".} : int32
e {.importc: "e".} : int32
f {.importc: "f".} : int32
g {.importc: "g".} : bool
h {.importc: "h".} : bool
Does the {.packed.} pragma align on the byte? Is the {.packed.} pragma even required here because I am importing from C?

The correctest binding is:
type Example {.importc: "struct Example",header:"example.h".} = object
A: cint
B: cint
C{.bitsize:3.}: cint
D{.bitsize:3.}: cint
E{.bitsize:3.}: cint
F{.bitsize:8.}: cint
G{.bitsize:1.}: bool
H{.bitsize:1.}: bool
note struct Example because you said it was a C struct. If you intend to compile with nim cpp you can use the above, importc:"Example" or just importc with no argument
and yes, if you know your target machine's ints are 32bits, int32 is much more convenient and is what i would use.
{.packed.} is not what you want, it is the equivalent of
struct __attribute__((__packed__)) Example {
...
}
and using it results in a struct that is 11 bytes instead of 12
you don't need to individually {.importc.} each member, unless you want to change its name, i.e.
type Example{.importc:"struct Example",header:"example.h".} = object
a{.importc:"A".}: cint
b{.importc:"B".}: cint
c{.importc:"C",bitsize:3.}: cint
...

Related

Why is it impossible to declare a type alias to an F# struct tuple?

It is impossible to define a type alias to a struct tuple in F#. Only with a workaround, it works.
let x = struct (1, 2)
> val x : struct (int * int) = struct (1, 2)
let y : struct (int * int) = struct (4, 5) // explicit type
> val y : struct (int * int) = struct (4, 5)
type S = struct (int * int) // straight definition
> error FS0010: Unexpected symbol '(' in member definition
type S = ValueTuple<int, int> // workaround
> [<Struct>]
type S = struct (int * int)
Is the error for "type S = struct (int * int)" a compiler bug?
Tried to file a bug and found the answer here: https://github.com/dotnet/fsharp/issues/7014
parenthesis around the type are required:
type Alias = (struct(int * int))

How can I link a label to a mutable variable in F#?

I want to create a label in F# which uses a mutable variable to return a value. Unfortunately F# sets this label to a constant value. If the value of the mutable changes, the value of the label remains. Isn't it a bit inconsistent? Is there a way to get the label ("a") being dependent of the mutable ("x")?
let mutable x = 0;
let a = x + 2; // I want not to set a to a constant value
let b two = x + two;
x <- 1;
let c = b 2;
let isConsistent = a = c;
val mutable x : int = 1
val a : int = 2
val b : two:int -> int
val c : int = 3
val isConsistent : bool = false
From your own comment you want a to be a function returning x + 2
Direct translation of that is :
let mutable x = 0
let a () = x + 2
let b two = x + two
x <- 1
let c = b 2
let isConsistent = a () = c // don't forget to call the function 'a'
(*
val mutable x : int = 1
val a : unit -> int
val b : two:int -> int
val c : int = 3
val isConsistent : bool = true
*)

What are the equivalent F# bitwise operators to OCaml's 'lsr' and 'asr'?

I have been looking at an OCaml implementation of Hash Array Mapped Tries and noticed that three distinct bit-level operators are used:
lsl: left shift
lsr: right shift
asr: unsigned right shift
I would like to port this to F# but am unsure of the exact behavior of the F# bitwise operators.
The F# language reference gives two bitwise operators:
<<<: left shift
>>>: right shift
How would I use these operators to replicate the OCaml originals?
Regards,
Michael
Inspecting the implementation of operator <<< and >>> hints at a solution (https://github.com/Microsoft/visualfsharp/blob/fsharp4/src/fsharp/FSharp.Core/prim-types.fs)
let inline mask (n:int) (m:int) = (# "and" n m : int #)
[<NoDynamicInvocation>]
let inline (<<<) (x: ^T) (n:int) : ^T =
(^T: (static member (<<<) : ^T * int -> ^T) (x,n))
when ^T : int32 = (# "shl" x (mask n 31) : int #)
when ^T : uint32 = (# "shl" x (mask n 31) : uint32 #)
when ^T : int64 = (# "shl" x (mask n 63) : int64 #)
when ^T : uint64 = (# "shl" x (mask n 63) : uint64 #)
when ^T : nativeint = (# "shl" x n : nativeint #)
when ^T : unativeint = (# "shl" x n : unativeint #)
when ^T : int16 = (# "conv.i2" (# "shl" x (mask n 15) : int32 #) : int16 #)
when ^T : uint16 = (# "conv.u2" (# "shl" x (mask n 15) : uint32 #) : uint16 #)
when ^T : sbyte = (# "conv.i1" (# "shl" x (mask n 7 ) : int32 #) : sbyte #)
when ^T : byte = (# "conv.u1" (# "shl" x (mask n 7 ) : uint32 #) : byte #)
[<NoDynamicInvocation>]
let inline (>>>) (x: ^T) (n:int) : ^T =
(^T: (static member (>>>) : ^T * int -> ^T) (x,n))
when ^T : int32 = (# "shr" x (mask n 31) : int32 #)
when ^T : uint32 = (# "shr.un" x (mask n 31) : uint32 #)
when ^T : int64 = (# "shr" x (mask n 63) : int64 #)
when ^T : uint64 = (# "shr.un" x (mask n 63) : uint64 #)
when ^T : nativeint = (# "shr" x n : nativeint #)
when ^T : unativeint = (# "shr.un" x n : unativeint #)
when ^T : int16 = (# "conv.i2" (# "shr" x (mask n 15) : int32 #) : int16 #)
when ^T : uint16 = (# "conv.u2" (# "shr.un" x (mask n 15) : uint32 #) : uint16 #)
when ^T : sbyte = (# "conv.i1" (# "shr" x (mask n 7 ) : int32 #) : sbyte #)
when ^T : byte = (# "conv.u1" (# "shr.un" x (mask n 7 ) : uint32 #) : byte #)
This code uses inline IL as well type-overloading only available to F# devs but the interesting rows seems to be:
when ^T : int32 = (# "shr" x (mask n 31) : int32 #)
when ^T : uint32 = (# "shr.un" x (mask n 31) : uint32 #)
To shift right the int32 version then uses shr (signed shift right) which corresponds to asr, the uint32 uses shr.un (unsigned shift right) which corresponds to lsr.
The shift left versions all uses shl.
So for int32 a potential solution could be:
module ShiftOps =
let inline ( lsl ) (x: int32) (n:int) : int32 = x <<< n
let inline ( lsr ) (x: int32) (n:int) : int32 = int32 (uint32 x >>> n)
let inline ( asr ) (x: int32) (n:int) : int32 = x >>> n
open ShiftOps
[<EntryPoint>]
let main argv =
printfn "0x%x" <| -1 lsr 4
printfn "0x%x" <| -1 asr 4
printfn "0x%x" <| -1 lsl 4
0
In F# the kind of right shift is determined by the first operand. If it is unsigned, then the shift will be zero-padding, i.e., asr, otherwise it will be logical.

In F# what are these collection-looking things?

In F# there are many different collection-looking syntaxes that compile into something. What are they all, and what do they mean?
let s1 = [a, b, c, d]
let s2 = [a; b; c; d]
let s3 = (a, b, c, d)
let s4 = (a, b, c, d)
let s5 = [|a, b, c, d|]
let s6 = [|a; b; c; d|]
let s7 = a, b, c, d
let s8 = { aa = 3; bb = 4 }
[a, b, c, d] is a list with a single 4-tuple as element.
[a; b; c; d] is a four-element list.
(a, b, c, d) is a 4-tuple.
[|a, b, c, d|] is an array with a single 4-tuple as element.
[|a; b; c; d|] is a four-element array.
a, b, c, d is a 4-tuple.
{ aa = 3; bb = 4 } is a value of a record type with two fields aa and bb.
Answer provided by райтфолд gives you answer, I'll try give you a way to get answer by yourself next time you have a question like this.
The easiest way is to use F# interactive (you can start it from Visual Studio from View -> Other Windows -> F# Interactive). Just type F# code, add double semicolon ;; and hit ENTER. To make your declarations work you have to declare a, b, c and d first. Let's make them all integers:
> let a = 1
let b = 2
let c = 3
let d = 4
;;
val a : int = 1
val b : int = 2
val c : int = 3
val d : int = 4
Now you can try your declarations:
> let s1 = [a, b, c, d];;
val s1 : (int * int * int * int) list = [(1, 2, 3, 4)]
F# Interactive prints back the type of expression that was evaluated. In that case it's (int * int * int * int) list. How to read that? * is used to divide elements of a tuple type, so (int * int * int * int) means a tuple with four elements, all types as int. Following list means a list of those. So (int * int * int * int) list is a list of tuples with four int-typed elements each.
> let s2 = [a; b; c; d];;
val s2 : int list = [1; 2; 3; 4]
Similar concept, this time it's a list of int elements.
> let s3 = (a, b, c, d);;
val s3 : int * int * int * int = (1, 2, 3, 4)
This one was already explained above: int * int * int * int is a four element tuple with all elements typed as int.
> let s5 = [|a, b, c, d|]
let s6 = [|a; b; c; d|];;
val s5 : (int * int * int * int) [] = [|(1, 2, 3, 4)|]
val s6 : int [] = [|1; 2; 3; 4|]
These are very similar to s1 and s2, but instead of list element type is followed by [] - that means it's an array. s5 is an array of (int * int * int * int) elements and s6 is an array of int elements.
> let s7 = a, b, c, d;;
val s7 : int * int * int * int = (1, 2, 3, 4)
Same as s3.
> let s8 = { aa = 3; bb = 4 };;
let s8 = { aa = 3; bb = 4 };;
-----------^^
stdin(18,12): error FS0039: The record label 'aa' is not defined
This one is tricky. To make it work you have to declare record type first:
> type myRecordType = { aa: int; bb: int };;
type myRecordType =
{aa: int;
bb: int;}
with that it works and prints that s8 is an instance of myRecordType:
> let s8 = { aa = 3; bb = 4 };;
val s8 : myRecordType = {aa = 3;
bb = 4;}
let s1 = [a, b, c, d]
Equivalent to [(a, b, c, d)]: a list containing one quadruple (tuple of 4 elements).
let s2 = [a; b; c; d]
A list with 4 elements.
let s3 = (a, b, c, d)
A quadruple.
let s4 = (a, b, c, d)
The same quadruple.
let s5 = [|a, b, c, d|]
Equivalent to [|(a, b, c, d)|]: an array containing one quadruple.
let s6 = [|a; b; c; d|]
An array with 4 elements.
let s7 = a, b, c, d
A quadruple (can omit brackets in this case and when there is no ambiguity).
let s8 = { aa = 3; bb = 4 }
A record definition.

F#: How to write the classic swap function?

In C# the classic swap function is:
void swap (ref int a, ref int b){
int temp = a;
a = b;
b = temp;
}
int a = 5;
int b = 10;
swap( ref a, ref b);
How would I write that with F#?
(Note, I do not want the functional equivalent. I actually need pass by reference semantics.)
Example to Jared's code:
let mutable (a, b) = (1, 2)
let swap (left : 'a byref) (right : 'a byref) =
let temp = left
left <- right
right <- temp
printfn "a: %i - b: %i" a b
swap (&a) (&b)
printfn "a: %i - b: %i" a b
Normally, you would use ref-cells instead of mutable let's.
Try the following
let swap (left : 'a byref) (right : 'a byref) =
let temp = left
left <- right
right <- temp
/// A function that swaps the order of two values in a tuple
let Swap (a, b) = (b, a)

Resources