* Re: Ada language help
2016-11-02 14:12 Ada language help ugur kazar
2016-11-02 14:57 ` Jeffrey R. Carter
@ 2016-11-02 21:11 ` Shark8
2016-11-03 13:57 ` ugur kazar
1 sibling, 1 reply; 4+ messages in thread
From: Shark8 @ 2016-11-02 21:11 UTC (permalink / raw)
Jeffrey is right, you should start out writing the generic's interface when you're doing this; however, if you have no Ada experience, then we should probably go over types and record-discriminants before actually doing the project:
The simplest type is that which is completely public, arguably [re-]defining a new type from existing types is easier than a completely new type (because they inherit operations), but here's an example of a few completely public types:
Type Percent is range 0..100;
Type Word is new Integer;
Type Point is record
X, Y : Integer;
end record;
All very simple.
Well, let's change things up a bit and throw in discriminants -- we can rewrite the type Point as the following:
Type Point(X, Y : integer) is null record;
This defines point as an "empty record" with two discriminants -- discriminants being essentially constant fields -- and this alters how it can be used:
* You CANNOT define an unconstrained variable/constant, so no X : Point; --...
* You CANNOT change the discriminant's values.
* ANY variable constrained by initialization MUST obey those constraints; this is wht if you say something like EX : STRING := "Dave"; can't later be assigned with EX := "Bob"; -- The length of "Dave" (four characters) constrains EX and "Bob" has only a length of three. (You *could* do EX:= "Mike" though.)
* Discriminants can often be thought of like parameters; though this gets a bit cloudy w/ access discriminants. (You don't need access discriminants for this, so I won't cover them.)
Discriminants can also be used to "dynamically bind/define" records; as an example:
Type Level is ( LOW, MEDIUM, HIGH );
Type Alert( Priority : Level; Length : Natural ) is record
Message : String(1..Length);
end record;
This defines an "alert", giving both message-length and priority as parameters -- so, given the attributes listed above, a message defined this way cannot have a length-data mismatch -- which precludes the whole Heartbleed bug.
Having covered public types and discriminants, let's cover private types -- private types are those which have an implementation that [generally] isn't viewable/accessible to the rest of your program. (The exception is in child units which can "see" into their parent's private area.) -- So here's an example of a private-type:
Package Example is
Type Useless is private;
Private
-- Cyclic Counter type.
Type Useless is range 1..4;
End Example;
This type lives up to its name, "Useless", because there's no way that the rest of your programs can manipulate such a variable -- you need to define the operations yourself:
Package Example is
Type Counter is private;
Procedure Inc( X : in out Counter );
Function Initialize return Counter;
Function Get( X : Counter ) return Positive;
Private
-- Cyclic Counter type.
Type Counter is range 1..4;
Function Initialize return Counter is (Counter'First);
End Example;
Package Body Example is
Procedure Inc( X : in out Counter ) is
begin
X:= (if X = Counter'Last then Counter'First else X+1);
end Inc;
Function Get( X : Counter ) return Positive is
begin
Return Positive( X ); -- Manually convert.
end Get;
End Example;
And now you have an interface for your type "Counter" -- writing the generic-interface is first thinking in terms of the interface, the parameters for the type are what the generic can assume about the type, so if you write a generic parameter as a private type the generic can only treat it as a private type (there is no 'specialization' as in C++) because you are writing in a generic manner.
So, that's about all the pieces you really need to know/understand to get this homework done. -- Hope that helps.
^ permalink raw reply [flat|nested] 4+ messages in thread