[net.lang.ada] bit manipulation and logical operators

bruceb@telesoft.UUCP (Bruce Bergman @favorite) (02/22/86)

[line eater offering]

HELP!

I am fairly new to Ada.  I love the language and I'm certain it's
bound to become my favorite, but right now, I'm having a hard time
dealing with some restrictions.

I come from a C background (alright - no razzberries...) and as such
I have no fear of using bit and word logical operators like AND, OR,
and XOR.  In Ada, this is a realizable fear.

I may be missing some part of the language, and if I am, please tell
me, but how in the crap can I get the equivalent of AND, OR, and XOR
in Ada?  Does anyone out there have any packages, routines, etc., for
these entities?

I'll gladly read any responses up to, but not including, a dissertation
on Ada vs. C...

bruce
-- 
                 bang!-
allegra!\              \
crash!   \     gould9!--\
ihnp4!    \              \
           >--sdcsvax!---->--telesoft!bruceb  (Bruce Bergman N7HAW)
noscvax!  /              /
scgvaxd! /   sdencore!--/
ucbvax! /              /
              talaris!-

vilot@gsg.UUCP (Michael Vilot) (02/26/86)

In article <306@telesoft.UUCP> bruceb@telesoft.UUCP (Bruce Bergman @favorite) writes:
>I come from a C background (alright - no razzberries...) and as such
>I have no fear of using bit and word logical operators like AND, OR,
>and XOR.  In Ada, this is a realizable fear.
>
>I may be missing some part of the language, and if I am, please tell
>me, but how in the crap can I get the equivalent of AND, OR, and XOR
>in Ada?

Of course, it's hard to tell what you are trying to do without some idea
of  the  application.   A  typical  use  of  these  operators  is to use
collections of  bits  as  status  variables,  and  to  use  the  logical
operators  to  selectively  mask  parts  of  words  to get at the status
information.

In Ada, the intent is to deal with this issue on a more abstract  level.
While  the  data  may  be *stored* as a collection of bits packed into a
word, each bit of status information *really* (the way you _think_ about
it)  is  a  Boolean  indicator.  In the more general case of, say 3 bits
representing 8 states, this status information is an enumeration  class.

So,  on  implementations   supporting   representation   specifications,
consider the example given in the Ada Language Reference Manual, Chapter
13, Section 13.4, paragraph 9 [ 13.4(9) ] -- page 13-6:

    WORD : constant := 4; -- storage unit is byte, 4 bytes per word

    type STATE  is (A, M, W, P);                  
    type MODE   is (FIX, DEC, EXP, SIGNIF);
    type BYTE_MASK  is array (0..7)  of BOOLEAN;  
    type STATE_MASK is array (STATE) of BOOLEAN;  
    type MODE_MASK  is array (MODE)  of BOOLEAN;  

-- These type definitions allow a more abstract manipulation
-- They can be mapped onto a physical implementation just once, and
-- referenced by their logical names and properties

    type PROGRAM_STATUS_WORD is
      record
        SYSTEM_MASK     : BYTE_MASK;
        PROTECTION_KEY  : INTEGER range 0 .. 3;
        MACHINE_STATE   : STATE_MASK;
        INTERRUPT_CAUSE : INTERRUPTION_CODE;
        ILC             : INTEGER range 0 .. 3;
        CC              : INTEGER range 0 .. 3;
        PROGRAM_MASK    : MODE_MASK;
        INST_ADDRESS    : ADDRESS;
      end record;

-- The record representation clause lets you force the compiler to
-- pack the information.  See the rest of Chapter 13 for all the
-- related cautions and warnings.

    for PROGRAM_STATUS_WORD use
      record at mod 8;
        SYSTEM_MASK     at 0*WORD range  0 ..  7;
        PROTECTION_KEY  at 0*WORD range 10 .. 11;  -- bits 8,9 unused
        MACHINE_STATE   at 0*WORD range 12 .. 15;
        INTERRUPT_CAUSE at 0*WORD range 16 .. 31;
        ILC             at 1*WORD range  0 ..  1;  -- second word
        CC              at 1*WORD range  2 ..  3;
        PROGRAM_MASK    at 1*WORD range  4 ..  7;
        INST_ADDRESS    at 1*WORD range  8 .. 31;
      end record;
    for PROGRAM_STATUS_WORD'SIZE use 8*SYSTEM_STORAGE_UNIT;

-- Now, this information can be manipulated  * logically * :
    ...

      SOME_WORD : PROGRAM_STATUS_WORD;
      PART_MASK : constant STATE_MASK := (FALSE, FALSE, TRUE, FALSE);
    begin
      if SOME_WORD.PROGRAM_MASK(FIX) = TRUE then
         SOME_WORD.MACHINE_STATE := PART_MASK;
      else
         SOME_WORD.MACHINE_STATE(A) := FALSE;
      end if;
    ...
-- and still have the * physical * bits turn out the way the 
-- machine expects.
-- 
Michael J. Vilot			decvax!gsg!vilot	(UUCP)
General Systems Group			vilot@wang-inst		(CSNET)
51 Main Street  			MVilot@USC-ISIF		(ARPA)
Salem, NH  03079			(603) 893-1000		(DDD)