poke-devel
[Top][All Lists]

## Re: Generalizing the big/little attribute

 From: Jose E. Marchesi Subject: Re: Generalizing the big/little attribute Date: Wed, 22 Jul 2020 11:27:02 +0200 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

```Hi Bruno!
Sorry for the delay in replying to this.

First of all, thank you very much for your suggestions.  There is a lot
to improve/complete in Poke's design!  Much appreciated :)

Currently, big/little applies only integral struct fields:

deftype test =
struct
{
little uint32 a;                        // OK
little uint8[3] b;                      // ERROR
little struct { uint8 x; uint8 y; } c;  // ERROR
};

A simple generalization to make it apply to integral types, then

deftype test =
struct
{
little uint32 a;                        // OK
little uint8[3] b;                      // would be OK
little struct { uint8 x; uint8 y; } c;  // ERROR
};

However, another generalization would be more powerful:
[...]

The big/little attribute, as you mention, is currently associated with
struct fields.  It is not associated with integral types.  Implementing
the "simple generalization" would involve adding a new attribute to
struct types, with the endianness to use.  This would be easy.

However, at this point I would generalize the endianness in a way it
becomes an attribute of certain types, not struct fields.  This way, you
could write [1]:

deftype MSBInt32 = big int<32>;
deftype MSBOff32 = offset<big int<32>,B>;
deftype MSBArray = big int<32>[10];
deftype Foo = little struct { MSBInt32 magic_in_big; ... };
deftype IntegralFoo = struct little uint<32> { ... };

Integral values can't be mapped themselves, so the endianness attribute
of an integral type becomes relevant when using an l-value map:

(poke) MSBInt32 @ 0#B = 666

This would require a few changes in the type system:

- Two integer types with different endianness are different types.
- Casting/coercing a ENDIAN1 u?int<N> type into ENDIAN2 u?int<M>
involves changing the endianness from ENDIAN1 to ENDIAN2.

But overall I don't think it will require a lot of work.

So, in any place where you can use a type name, you could also add a
little/big attribute, and it has a recursive effect.

Using the approach of associating endianness to types, it would be
natural to support a new type specifier `{little,big} typename', that
constructs a proper (derived) type itself:

deftype LSBInt32 = | little MSBInt32 |;
+--- type spec ---+

and

(poke) | little MSBInt32 | @ 0#B
+--- type spec ---+

Then we could use `{little,big} typename' anywhere a type specifier is
expected, like casts, function formal arguments, etc.

Method invocations would not only have an implicit SELF argument, but
maybe also an implicit ENDIANNESS_OVERRIDE argument?

If you mean that any mapping performed in an method (or in a function
called from a method) will inherit the endianness of the struct, I don't
think that is a good idea.  Using the schema proposed above the
referenced struct fields would be available in whatever endianness their
type mandates, which may be different to the endianness of the struct
(see the magic_in_big field above):

big struct
{
[...]

int i;

method foo = int:
{
return i + uint<8> +
}
};

WDYT?

[1] We may have to wrestle/massage the syntax to avoid ambiguities, but
let's asume for now this syntax works :)

```

reply via email to