Recent

Author Topic: Pascal-ish Syntax for bit access.  (Read 30006 times)

Edson

  • Hero Member
  • *****
  • Posts: 1296
Pascal-ish Syntax for bit access.
« on: March 30, 2017, 03:02:01 am »
I am developing a Pascal Compiler, with bit access variables. So I need some syntax that let me declare some kind of variables, with the ability to be accessed, globaly or bit by bit. Something like this:

Code: Pascal  [Select][+][-]
  1. VAR
  2.   foo: byte;
  3. ...
  4.   foo := 255;
  5.   foo.bit0 := 1;  //set bit 0
  6.  

FAIK Object Pascal, have no support to this kind of access.
Then, I was thinking in include a new type (and the support in the compiler):

Code: Pascal  [Select][+][-]
  1. VAR
  2.   foo: bitPackedByte;  //let me access as byte or individually bits
  3.  

or

Code: Pascal  [Select][+][-]
  1. VAR
  2.   foo: bitPackedByte
  3.              bit0;   //let me access bit 0
  4.              TheBit1;   //let me access bit 1
  5.          end;  
  6.  

Suggestions?
Maybe I need to expand the syntax, until the point of to create a new language  :o
« Last Edit: March 30, 2017, 04:40:29 pm by Edson »
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Pascal Syntax for bit access.
« Reply #1 on: March 30, 2017, 04:08:04 am »
My redneck opinion on the matter is, use an existing theme make it easier for everyone to remember and it will get used more. In this case I will go with the array metaphore. egg
Code: [Select]
var
  MyFlagsofTheWorld:Qword;
begin
  MyFlagsofTheWorld[34] := 1;//or 0

Leledumbo

  • Hero Member
  • *****
  • Posts: 8744
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Pascal Syntax for bit access.
« Reply #2 on: March 30, 2017, 05:03:35 am »
This is how you would do it in current FPC:
Code: Pascal  [Select][+][-]
  1. type
  2.   TBinary = 0..1; // you can also use boolean if you want, it will be mapped to the same 0..1, you just have to use false/true instead
  3.   TByteBit = bitpacked array [0..7] of TBinary;
  4. var
  5.   BB: TByteBit;
  6. begin
  7.   Byte(BB) := 255; // sets all bits to 1
  8.   WriteLn(BinStr(Byte(BB),8));
  9.   // sets even bits to 0
  10.   BB[0] := 0;
  11.   BB[2] := 0;
  12.   BB[4] := 0;
  13.   BB[6] := 0;
  14.   WriteLn(BinStr(Byte(BB),8));
  15. end.
  16.  

guest58172

  • Guest
Re: Pascal Syntax for bit access.
« Reply #3 on: March 30, 2017, 05:20:11 am »
With more powerful generics:
Code: Pascal  [Select][+][-]
  1. generic procedure SetBit<T>(var stuff: T; nth: Byte; bit: boolean);

Otherwise a compiler intrinsic. Maybe better because if you want set a bit on a record the other solutions might become problematic.

Thaddy

  • Hero Member
  • *****
  • Posts: 14161
  • Probably until I exterminate Putin.
Re: Pascal Syntax for bit access.
« Reply #4 on: March 30, 2017, 06:20:42 am »
Leledumbo's answer is correct, although I would indeed use boolean
Code: Pascal  [Select][+][-]
  1. type
  2.   TMybits = bitpacked array[0..255] of boolean; // not limited to byte length, btw
  3. var bits:TMybits;
  4. begin
  5.   Bits := Default(TMyBits);    // set all bits off
  6.   Bits[1]:= true;              // set bit on
  7.   Bits[200] := not Bits[200]   // toggle bit
  8.   .. etc
  9. end.

We also have the TBits class...
See http://wiki.freepascal.org/Bit_manipulation

I paricularly like bit sets, that I use a lot with electronics (RPi interfaces)
« Last Edit: March 30, 2017, 07:04:52 am by Thaddy »
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14161
  • Probably until I exterminate Putin.
Re: Pascal Syntax for bit access.
« Reply #5 on: March 30, 2017, 06:28:02 am »
With more powerful generics:
Code: Pascal  [Select][+][-]
  1. generic procedure SetBit<T>(var stuff: T; nth: Byte; bit: boolean);

Otherwise a compiler intrinsic. Maybe better because if you want set a bit on a record the other solutions might become problematic.
I don't see why that is the case. We have indexed properties for that. See the above wiki link.
Specialize a type, not a var.

Edson

  • Hero Member
  • *****
  • Posts: 1296
Re: Pascal Syntax for bit access.
« Reply #6 on: March 30, 2017, 07:09:59 am »
Good ideas. I like Leledumbo's code, using arrays of bits.
But my compiler is for small devices (Microchip PIC), and haven't support for arrays of bits, and much less for generics.
I think this must be some intrinsic for the language and compiler. The MikroPascal compiler can access using:

Code: Pascal  [Select][+][-]
  1.   byte_variable := 255;   //assigment like byte
  2.   byte_variable.0 := 1;    //assigment like bit
  3.   byte_variable.SOMEBIT := 0;    //assigment like bit with name
  4.  
And I think it's OK. But I don't see how MikroPascal, define the name of the bits. It seems to be some internal to the compiler.
I think there must be a way to define the name of every bits, using some kind of Pascal syntax. Maybe like this:

Code: Pascal  [Select][+][-]
  1. VAR
  2.   foo1: byteBit;  //bits are named 0, 1 or bit0, bit1, ...
  3.   foo2: byteBit   //alternative definition, with a different names for bits
  4.              bit0;  
  5.              TheBit1;
  6.              TheBit2;
  7.              OtherBit
  8.           end;  
  9.  
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Kays

  • Hero Member
  • *****
  • Posts: 569
  • Whasup!?
    • KaiBurghardt.de
Re: Pascal Syntax for bit access.
« Reply #7 on: March 30, 2017, 10:15:24 am »
I am developing a Pascal Compiler, […]
:o You're developing a compiler? Oy.
The FPC doesn't suit your case, or what? You know, you're welcome to contribute, don't you [rhetorical]?

[…] I need some syntax that let me declare some kind of variables, with the ability to be accessed, globaly or bit by bit. […]
There are already sets providing some sort of bitwise read/write access. Or do you want that as an additional language construct to all types, in order to disclose the internal memory structure?

Somehow that sounds to me contrary to Pascal's paradigms. One chunk of memory has one interpretation (data type).



Code: Pascal  [Select][+][-]
  1. VAR
  2.   foo: []  //let me access as byte or individually bits
  3.  
I would refrain from providing some general way – working out of the box – to access all the bits. Instead the programmer should explicitly request “Hey, also I'd like to interpret that chunk of memory as a set of independent bits”, e.g. like so:
Code: Pascal  [Select][+][-]
  1. var
  2.         // statements with colon ':',
  3.         // define variables allocating _new_ memory
  4.         foobar: byte;
  5.         // analog the 'type' section introduce aliases
  6.         // to _same_ _spots_ we already allocated
  7.         foobit = bits(@foobar);
Now, the bits data type is some record structure or a (bitpacked) array of boolean values (like already suggested). This statement should be valid, iff sizeOf(foobar) = sizeOf(foobits) (so a byte is as large as bits).

Taking this approach variables still reside on the stack, but you (as a developer) don't have to typecast them every single time you'd like to access them, since a second identifier is gained.

PS: The topic's title reads “Pascal Syntax for bit access.”. Well, to be fair you'd like to come up with some Pascal-ish syntax. ;)
« Last Edit: March 30, 2017, 11:08:14 am by Kays »
Yours Sincerely
Kai Burghardt

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Pascal Syntax for bit access.
« Reply #8 on: March 30, 2017, 10:17:57 am »
Delphi doesn't, but FPC does; besides the bitpacked array shown by Leledumbo is there also the record variant
Code: Pascal  [Select][+][-]
  1. Type
  2.        TBit = 0..1;
  3.         TBitPackedByte = bitpacked record
  4.                                  bit0 : TBit;
  5.                                  bit1 : TBit;
  6.                                  bit2 : TBit;
  7.                                  unused : TBit;
  8.                                  bit4 : TBit;
  9.                                  bit56 : 0..3; // two bits.
  10.                                  bit7 : TBit;
  11.                                 end;
  12.  

The embedded world with its memory mapped special function registers  is full of this.
« Last Edit: March 30, 2017, 03:18:39 pm by marcov »

mischi

  • Full Member
  • ***
  • Posts: 170
Re: Pascal Syntax for bit access.
« Reply #9 on: March 30, 2017, 10:22:05 am »
You can also use a set. Sets with up to 32 elements are stored in a longint. Setting/unsetting bits is done by adding/removing elements from the set. Code snippet:
Code: Pascal  [Select][+][-]
  1. var
  2.   bitset: set of (bit0, bit1, bit2, bit3, ..., bit32);
  3. begin
  4.   bitset := [bit0, bit4];
  5.   bitset := bitset + [bit6];
  6.   bitset := bitset - [bit2];
  7.   if bit3 in bitset then ...
  8.  
I find the usage pretty obvious. It leaves the implementation to the compiler.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Pascal Syntax for bit access.
« Reply #10 on: March 30, 2017, 10:30:16 am »
You can also use a set. Sets with up to 32 elements are stored in a longint.

This depends on mode an architecture and $packenum/$packset directives.
Code: Pascal  [Select][+][-]
  1. {$packset 1}
  2. var
  3.   bitset: set of (bit0, bit1, bit2, bit3,bit4,bit5,bit6);
  4. begin
  5.   writeln(sizeof(bitset));
  6. end.
  7.  
prints 1. {$mode delphi} implies {$packset 1}


serbod

  • Full Member
  • ***
  • Posts: 142
Re: Pascal Syntax for bit access.
« Reply #11 on: March 30, 2017, 01:54:08 pm »
Code: Pascal  [Select][+][-]
  1. type
  2.   TByteBitset: set of (bit0, bit1, bit2, bit3, ..., bit7);
  3. var
  4.   MyByte: Byte;
  5.   MyByteBitset: TByteBitset absolute MyByte;
  6.  


Kays

  • Hero Member
  • *****
  • Posts: 569
  • Whasup!?
    • KaiBurghardt.de
Re: Pascal Syntax for bit access.
« Reply #12 on: March 30, 2017, 03:17:28 pm »
Code: Pascal  [Select][+][-]
  1. type
  2.   TByteBitset: set of (bit0, bit1, bit2, bit3, ..., bit7);
  3. var
  4.   MyByte: Byte;
  5.   MyByteBitset: TByteBitset absolute MyByte;
  6.  
Bingo! We already got it. There's no need to come up with an own syntax.
Yours Sincerely
Kai Burghardt

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Pascal Syntax for bit access.
« Reply #13 on: March 30, 2017, 03:50:47 pm »
Good ideas. I like Leledumbo's code, using arrays of bits.
In my eyes the more clean solution, also because it is more easy to iterate arrays.

Also a possibility (for general purpose) could be to use a type helper in FPC.

Quote
But my compiler is for small devices (Microchip PIC), and haven't support for arrays of bits, and much less for generics.
I think this must be some intrinsic for the language and compiler. The MikroPascal compiler can access using:
I do not claim to have any experience with that compiler but, i think that code you showed is a bit misleading.

As far as the public available documentation for this compiler showed me so far, it seems more like marcov's solution

Here is more written about inidividual bits and here is written a bit (phun intended) about predefined register and accessing individual bits.

Somewhere in these documentation i ended up at the c version of their compiler documentation, which writes about record structures, here:
Code: C  [Select][+][-]
  1. typedef struct {
  2.   lo_nibble  : 4;
  3.   hi_nibble  : 4;
  4.   high_byte  : 8;} myunsigned;
  5.  

And which matches the bitpacked record structure as shown by marcov.

So, afaik that implies that those individual bit field names are not made out of random names but are actually predefined.

As such, those field names depend on which type the variable actually is (thereby assuming the compiler does not support overloads for generic/global type definitions -> but i might be wrong about that as i do not know the compiler)

Also note that ((in)direct access to hardware) registers seem to be a special case, which is logical/natural for embedded targets.
« Last Edit: March 30, 2017, 03:58:15 pm by molly »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Pascal Syntax for bit access.
« Reply #14 on: March 30, 2017, 04:09:00 pm »
But my compiler is for small devices (Microchip PIC), and haven't support for arrays of bits, and much less for generics.

Microchip part headers contain large listings of registers structs (records in Pascal)

So the .SOMEBIT is probably using a declaration of a record like I posted (and Molly posted the C equivalent syntax), and the variablename.0   (.bitnumber) syntax is a different extension.

Note that microchips only can access addresses under 8192 at bitlevel. (this is where most registers are)

The convention in Microchip own compilers is usually that if there is a byte level register MYREG at address 50, there are two declarations. One byte typed is called MYREG, and one with a record to access named bits called MYREGbits,
 so with -bits appended.  They are then put on the same address using a variant of absolute (to place them on a hardcoded address, rather than a different variable).

I don't use mikro's compiler variants, so I don't know if they follow the same convention. I nowadays mostly use C30/XC16 (16-bits dsPICE), but have used 8-bits in the distant past (mostly the ethernet part pic18PFJ60 or something like it)

FPC only supports absolute to addresses on dos (and I assume the embedded targets). You might want to checkout the CPU specific headers of the various embedded targets that FPC supports (avr,arm,m68k)

 

TinyPortal © 2005-2018