comp.lang.ada
 help / color / mirror / Atom feed
From: dan@irvine.com (Dan Eilers)
Subject: Hacker's Ada FAQ
Date: 1 Apr 2004 10:42:52 -0800
Date: 2004-04-01T10:42:52-08:00	[thread overview]
Message-ID: <aff68d75.0404011042.1d10eefa@posting.google.com> (raw)

Hacker's Ada FAQ
1 April 2004


Disclaimer:

The editor of this FAQ accepts absolutely no responsibility
whatsoever for the "advise" given herein.  The solutions have not
been rigorously tested, and do not even pretend to comport with
accepted software engineering principles.  What happens to work
on one compiler is almost certain not to work on another compiler,
or even on a different release of the same compiler.
You have been warned.


1)   Ada as a PDL.

Q. I want to use Ada as a PDL (Programming Design Language) but
the compiler complains about missing details that I wish to
leave TBD for now, such as the initializers for constants.
Even worse, this happens in my lowest level packages, preventing
me from using the compiler to at least check the syntax of all
my packages.  Help!

A.  AI-00078 confirms that RM 10.1.4(6) allows an implementation to
add illegal compilation units to the Ada environment.  But since you
might forget which constants you have left TBD, it is best to mark
them using pragma errors(off).  Since this pragma is non-standard,
it is best to also use pragma warnings(off).

   package pak1 is
      pragma Warnings (Off);
   private
      pragma Errors (Off);
      max_speed: constant float;      -- TBD
      upper_bound: constant integer;  -- TBD      
      switch: constant boolean;       -- TBD
      pragma Errors (On);
   end pak1;


2)  Redundant parameter lists

Q.  I am used to languages that don't enforce a strict separation
of package specifications and bodies.  So it seems redundant and
potentially error prone to have to repeat the parameters for
subprograms.  Help!

A.  It is acceptable to use pragma errors(off) when a subprogram
has more than 10 parameters.


   package pak2 is
      generic
      procedure p2(i,j,k,l,m,n: integer; q,r,s,x,y,z: float);
   end pak2;

   package body pak2 is
      pragma Warnings (Off);

      pragma Errors (Off);
      procedure p2 is separate;
      pragma Errors (On);
   end pak2;
 

3)  internal representation of enumerations

Q.  I need to get at the internal representation of object of an
enumeration type.  Pascal offers "union" types, but Ada doesn't
seem to allow that.  Do I have to resort to unchecked_conversion
or non-standard attributes?

A.  Try wrapping the union type in a record.  Occasionally this
will work.


  function char_to_int(ch: character) return integer is
     pragma Warnings (Off);

     type union (b: boolean := false) is record
        case b is
           when false  => i: integer;
           when true   => c: character;
        end case;
     end record;

     type wrapper is record
        u: union;
     end record;

     type wrapper_ptr is access wrapper;

     x: wrapper_ptr := new wrapper;

     pragma Errors (Off);
     j: integer renames x.u.i;
     pragma Errors (On);

  begin
     x.u := (b => true, c => ch);
     return j;
  end char_to_int;

  with text_io; use text_io;
  with char_to_int;
  procedure main is
  begin
     put_line(integer'image(char_to_int('A')));
  end;


4)  Changing IN parameters

Q.  I'm trying to write my own random number package, modeled
after Ada.Numeric.Discrete_Random.  But I can't figure out how
to change the generator, since it is an IN parameter to function
Random.

A.  Try using a type conversion.


    package Random_Numbers is

       pragma Pure;

       type Generator is limited private;

       function Random (G : Generator) return Float;

    private

       type State_Type is record i: integer := 0; end record;

       type Generator is tagged limited record
            State : State_Type;
       end record;

    end Random_Numbers;

    package body random_numbers is
       pragma Warnings (Off);

       procedure newstate(x: in out State_type) is
       begin
          x.i := x.i + 1;    -- just increment for now
       end;

       procedure assign(x: generator'class; new_value: State_Type)
       is
          procedure doit(x: in out generator) is
          begin
             x.state := new_value;
          end;
          subtype T is generator;
       begin
          pragma Errors (Off);
          doit(T(x));
          pragma Errors (On);
       end assign;

       function Random (G : Generator) return Float is
          State : State_Type := G.State;
       begin
          newstate(State);
          assign(G, State);
          return float(State.i);     -- just return state for now
       end;
    end random_numbers;

    with random_numbers;
    with text_io;
    procedure main is
       g: random_numbers.generator;
    begin
       for i in 1..10 loop
          text_io.put_line(float'image(random_numbers.random(g)));
       end loop;
    end;



5)  Wanting it both ways.

Q.  I can't make up my mind what value I should use when
constraining a record with a boolean discriminant.  Is there
any way to let the compiler choose this for me?

A.  Try using private types.

   package pak5 is
      pragma Warnings (Off);
      type T1(b: boolean) is tagged null record;
      type T2(i: integer) is new T1(b => false) with private;
   private
      pragma Errors (Off);
      type T2(i: integer) is new T1(b => true) with null record;
      pragma Errors (On);
   end pak5;



             reply	other threads:[~2004-04-01 18:42 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-04-01 18:42 Dan Eilers [this message]
2004-04-02  9:47 ` Hacker's Ada FAQ Preben Randhol
2004-04-02  9:50   ` Lutz Donnerhacke
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox