[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.

  1. 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.

  2. 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.

  3. 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.

  4. 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:


    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.

  5. 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)