[Up]
[SIGAda]
[ACM]
How to do things in ASIS
Or, Answers to ASIS email questions from the SIGAda-ASIS-Tech
(ASIS Technical) mailing list
How does one get range bound numeric values from ASIS?
Justin Jackson & Richard Willson, BAe New Malden UK
What is puzzling us at the moment, despite peering at the web examples
mentioned in the replies, is how to get the numeric value of range
bounds - be they for scalars or arrays - given that these may not be
simple literals. For example :
...............
Min : constant := 1;
Max : constant := 10;
type Index is Min .. Max;
type Vec_T is array (Index) of Integer;
...............
Although we can see which ASIS queries give us the expressions for the
range of the Index & Vec_T types, we cannot see how to get the numeric
values without explicitly handling all the possible cases ( e.g.
literals, attributes, named constants, arithmetic expressions
containing any or all of these, etc)
While we do not of course expect ASIS to tell us the bounds if they
are set dynamically, we do need to know how to get the numeric values
in the limited case of compile-time determined ranges.
If a straightforward ASIS query can't do this, does anyone know of an
alternative approach?
Email Response from Joe Wisniewski
There are a lot of issues that potentially could be addressed by this
good question of yours. I hope that my response is not too pedantic so
as to insult you. I will try and answer your question by first stating
some architectural requrements/implementation facts, general helpful
comments.
- Whenever you write an ASIS application, make plans for additional
layer(s) of ASIS calls, or at least until we all decide (if) on a
common set of layer/utilities to implement for and with the community.
- If you take an overall look at the ASIS architecture, within each
package, there are functions that maneuver within an element_kind
(expression, declarations, etc.) and there are "gateway" functions
that allow maneuvering from one element_kind to another (exp =>
declarations, definitions => declarations) etc.
- Note the excellent commentary in 2.0 specification as far as
appropriate element_kinds for inputs and expected element_kinds in the
function return result. THESE ARE CRITICAL. When writing an ASIS
application you will use this aspect of the commentary (or should)
more than anything else to get you from point A to point .....
whatever.
And this leads me closer to the answer to your question. Hang with me.
- If one wanted to teach someone about recursive programming in Ada,
ASIS is the perfect vehicle for this; either directly via the
traverse_element call or at the application level.
For a very simple silly example, suppose one had the expression:
(((((((x+2)))))))
in order to get to the innermost expression, take a look at the
function Asis.Expressions.Parenthesized_Expression.
It strips off the outermost parens. So either in the
application or through traverse_element you are going to have
to recursively call parenthesized_expression. And yes, this
means that you have to handle the different kinds of
expression_kinds that come back, because again referring back
to my point about the function preconditions, an ASIS function
will ONLY handle elements that it expects. You will
undoubtedly become familiar with the inappropriate_element
exception when you violate a function precondition.
- So to answer your question, no there is not "one" ASIS call to get
from any one syntactical construct to another, at anything except the
lowest level. That is where the utilities issue comes into play. To
get to bounds, you seemed to imply that you knew how to use the
Upper_Bound, Lower_Bound calls. So then what to do? Depending on what
you want to do with the resulting expression, you will probably have
to interrogate the expression_kind of the resulting expression. Again,
traverse_element might help you, but traverse_element "walks" the
element_tree, so to speak. To deal with different "kinds" of a
specific element kind, you are going to have to handle that yourself.
(If I am mis-stating this somehow, someone please correct me.)
This discussion could move in a lot of other different directions from
here, based on exactly what your comments, thoughts are.
If it is possible to sum up the "ASIS philosophy" is a statement or
two, you always HAVE to know where you are when traversing the syntax,
if there are specific actions that you need to take along the way. If
you are only interested in dealing with a specific element_kind, say
statements, and don't care at all, about any other kind of element,
then traverse_element is very good for this. But, in general, you
have to know what kind of element you have to know what to call to get
you to the next step.
I sure hope this helps.
[Up]
[SIGAda]
[ACM]
Last update 7 June 1999.
Questions, comments to
Clyde Roby (CRoby@IDA.Org)