The status of ASIS

I must admit being ignorant about ASIS. So my questions are:

  • What is the status of the standard?
  • Are the template packages here the actual stand of?

IIRC, it is [mostly] defunct, and IIRC only supports Ada 2005 (? maybe only Ada 95); or at least that’s how one of the big project’s authors seemed to be framing it —Adalog? Simon J Wright’s stuff? I’ve forgotten— and wanted to see it updated to support more modern Ada standards. That said, IIUC, it’s still quite usable, as AdaControl is still usable/used.

AFAIK…

It has not been updated since Ada 2005 (I believe it does not cover the full 2005 standard). It was removed from GCC/GNAT since… v10? AdaCore does continue to support it though for its customers (but I believe it is just maintenance, not really any development). There were proponents inside the AEiC and Ada Users Society to try to find stakeholders that would try to maintain it and update it for newer Ada versions. But alas, that has not happened and it does not look like it will…

Jean-Pierre Rosen published a paper in Ada-Europe a few years ago comparing ASIS and Libadalang and he did not find it satisfactory. However, libadalang has been improving and is flexible/can be scripted, soooo…

Best regards,
Fer

Thanks for responses guys.

(ASIS looked nicely structured to me. The only point I did not like was that elements were chosen to be subtypes rather than a tagged hierarchy. There is nothing wrong with subtypes if they were discriminated in order to select the specific node type. I see the reason - to avoid containers. But since the implementation would be a wrapped access type or handle anyway, one could make it a definite type.)

Having said that, what is the alternative? Very important projects need such a tool. E.g. Ada Control or an advanced DSA implementation…

It is decently structured; I think it could be refreshed/updated fairly easily, if the ARG were to adopt the metalanguage proposal I’m working on. — So, yes, the issue is under my consideration.

IFAIK, there is no real alternative, a lot of “the industry” has been infected with the C/Python/plain-text mentalities, where the solution is to push more work and complexity onto the user instead of solving the whole problem.

As far as old-tech goes, I think Ada would do really well with DIANA and ASIS — remember:

  • DIANA is about a good, uniform IR which stores the source as a structure (a DAG, which is also attributed), and is designed so that it cannot store non-syntactically-correct code.
  • ASIS is about querying and manipulating the [conceptual] structures.
  • These could be combined into a DB-engine such that the DIANA is the storage/data and the ASIS is the query-engine.

The ASIS standard is a current international standard; official name: “ISO/IEC 15291: Information technology — Programming languages — Ada Semantic Interface Specification (ASIS)”. It is based on Ada 95.

The main ASIS implementation, ASIS-for-GNAT, implemented that ISO standard and has over the years been expanded to newer Ada language editions, up to full Ada 2012, plus a few extras from Ada 2022 (such as the target symbol @).

Other compiler vendors have/had ASIS implementations as well. TTBOMK those are all based on Ada 95.

Work in WG9 on the ISO standard is stalled on the one hand due to insufficient resources and on the other hand because it was felt a semantically higher level interface was needed which would’ve required even more resources.

Work on the main implementation is maintenance-only since several years, due to the switch to libadalang.

In the Ada community there was interest to advance the standard and work on implementations. At the 2022 Ada-Europe conference in Gent, there was a BoF session on ASIS that identified a step-wise approach to make progress:

  1. Use the spec of the latest available ASIS-for-GNAT as the basis to (informally first) upgrade the ASIS standard to Ada 2012.
  2. Add the new elements from Ada 2022 to that upgraded ASIS, such as the parallel constructs.
  3. Work on a freely available ASIS for Ada 2022 implementation, either based on ASIS-for-GNAT or independently. (If the former, consider a redesign of the loading of withed units, as that’s a major performance issue when processing larger code bases.)
  4. If there are enough resources and interest, consider defining a layer above ASIS for Ada 2022 to provide a semantically higher level interface.

Unfortunately, until now no volunteers stepped forward to work on all that. Maybe in the mean-time that’s changing, and we might (re)start an ASIS working group?

Hear, hear! AdaControl is a very powerful and useful tool!

I considered implementing ASIS, but it seems pointless in this state.

Interesting. I thought that the use clause should be the major offender in the case of building lists of visible entities matching given name at given location. The with clause is basically deserialization of the syntax tree stored in the Ada library. OK, GNAT does not have the library…

What does it include? Sematic analysis, all names resolved, intermediate code?

Any connection to Ada library as it was intended by Ada 83, now replaced / implemented by gprbuild?

I think that depends on the implementation; if you take inspiration from DIANA, you could use an extensible IR representing the queries/updates as the core and extend that out to later Ada features fairly easily — the DIANA-2022 update that Charlie5 and I did is supposed to have unification of LRM declared-equivalent features (eg return/extended-return) so executing some of those updates may be nearly trivially simple.

This is why having a DIANA-based system for experimentation would be very useful: you could prototype it out and then provide that implementation as a “for free” open-source reference [not authoritative, obviously as (a) it could have mistakes, and (b) the authority is the spec, and (c) there is no requirement to use DIANA or any other IR] — also, something that might be worth considering is how operating off of some meaningful structure (vs “plain text”) as your conceptual point has knock-on effects: you can “handwave” tokenizing/lexing/parsing as “not relevant” and assume good code, perhaps with the conceptual equivalent of an exception-handler for deviations from that ‘normal’.

The implications of the lack of a library have some interesting/surprising results.

That was a part of my question. I asked before, in another thread, if DIANA were a candidate for AST serialization, since I had implemented a syntax analyzer for Ada 2022 and wanted to know if there were interesting backends. But I learned that DIANA is more than AST and rather represents the outcome of the semantic analysis phase. As such it would not be suitable for ASIS, the old ASIS, I mean. If the new ASIS should not only cover the new Ada constructs like aspects, loop iterators, parallel loops and blocks, but also represent semantic, that would be a huge leap.

The ASIS-for-GNAT implementation used s.c. “tree-files” for all compilation units that were generated by GNAT when called with the appropriate option. ASIS-queries then loaded those tree-files to access information they needed. IIRC, whenever info was needed about an entity from a with-ed unit, the currently used tree-file was “swapped” with the tree-file of that with-ed unit. All this “swapping” of tree-files was very, very time-consuming, so much that for large codebases it took almost all processing time.

Those tree-files were large (not to say often huge), so keeping everything in memory was out of the question for codebases on the order of millions of lines of code.

I would’ve expected a caching system for such “loaded tree-files”, so that the info about the most used compilation units would be in memory, and only rarely used units might have to be re-loaded occasionally. But the feedback we got was that with the current design of the GNAT-for-ASIS implementation this was not feasible…

Hence the suggestion, if future work would be based on the GNAT-for-ASIS implementation, to reconsider the design/implementation of this “inter-compilation-unit info retrieval”…

ASIS itself provides an API to retrieve information about Ada source code, but at a relatively low level, close to the syntax of the language. The idea was to define a second API (in a first step implementable using the ASIS API) but at a much higher level, closer to the semantics of the language, hence easier to be used by developers of Ada tools such as for static analysis.

For example, to go from a variable occurrence to its definition, using the ASIS API one has to follow all steps through the tree from the node for the variable, via the enclosing nodes (such as: expression, …, statement, statement list, …, procedure, …, package, …, declarations, …), to the node for the variable declaration. A higher-level API should provide an operation to retrieve the corresponding variable declaration for a variable occurrence.

As said, not enough effort was available at the time to pursue both the evolution of ASIS to later Ada standards, as well as the design of a higher-level layer. Starting discussions about the latter took most of the minimal amount of effort that could be spent, so nothing was left for the former, and in the end the whole process stalled.

Large caveat: the above is what I remember from casual reading and talking about the subject, so there might be inaccuracies…

I’m not sure that’s quite the killer that you might assume: DIANA was designed to be easily source-text recoverable; while the structure does have semantic attributes, I think you can “mostly ignore” them if you’re not working at that level. (I believe the Rev. 3 DIANA RM described it as an attributed AST, though I maybe misremembering that source.)

IIUC, there is nothing really keeping ASIS from operating on a DIANA implementation. (Though, admittedly, I ought to reread the spec; I have an old copy from DTIC.mil; you can find a lot of good stuff there.)

I wonder how much of that tree was duplicate or [easily] derivable information from DIANA. Since the DIANA tree was meant to have other information attached (eg results of a static-analyzer), even if it doesn’t have the data directly, it could be attached to these as ‘ASIS_Nodes’.

Interesting; as I remarked, DIANA is actually rather close to the source. (An interesting contemporaneous alternative was AIR (Ada Intermediate Representation) mentioned in one of my old books.

The key question is if that would be a list of defining identifiers matching the name visible (use clauses ignored?) at the occurrence or the single defining identifier matching the type. I have the former without use clauses because the syntax tree is accompanied by a cross-reference of the visibility scopes.

But full name resolution is a way bigger number and even use clauses are problematic because of the insane visibility rule that a variable or constant visible through a use clause would make mutually invisible all homographs including package names! So

   use Ada;
   use A;
   use Text_IO; -- Might might get hidden by A, if A has Text_IO constant declared in it

One would need a quite non-trivial algorithm to make it both fast and correct.

There was also the GELA ASIS project, apparently Russian-developed, independent of Adacore’s products, which (with minor difficulty) I managed to build, then never got around to doing anything substantial with. Ada-2005 support is suggested,

This Github repo is I think the source I used; it also seems to have been packaged for Fedora, with some further development (version 0.3.3-9 vs 0.32)

The source site linked from the Fedora archive appears to be no longer active.

http://gela.ada-ru.org/gela_asis

I have no connection with the project other than having built it about ten years ago.

The GELA/ANDF compiler, used to be available too.

Out of curiosity since I have been diving into this stuff in my spare time, how do you handle situations where the syntax is still ambiguous without semantic analysis, think something(1) which could be a function call or an indexing operation or something which could be a variable name or a procedure call or an implicit dereference (in all cases they have different syntax categories from each other). Do you just pick a generic one and go or do you have to do some small semantic analysis?

The answer is that I ignore the descriptive part of Ada syntax. I do not use Ada grammar to generate parser. The parser is table-driven in expressions and recursive-descent elsewhere.

something(1) is parsed as

*()
|_ something
|_ 1

It is an Expression node which operation is Left_Index having two arguments (children): identifier something and integer literal 1. For example something + 1 would be parsed exactly same, only the operation would be Add.

There are many cases where Ada syntax uses different names for the same syntactic construct. E.g. discriminants and parameter profile are same thing.

Some small semantic checks are done when Ada limits general constructs, e.g. where others or named association may appear. I hope I caught them all, though what Ada holds for “name” in different contexts, I am not so sure. In the tree x_Name is an expression checked for all constraints. Another case are attributes with some crazy stuff like X'Base'Base'Basead infinitum. I collapse these where a subtype indication expected and stay convinced I missed nothing, until proven otherwise… :grinning_face: In expressions it is left as is:

'
|_ X
|_ Base
|_ Base
|_ Base

(’ is considered associative)

I think Ada grammar can be significantly simplified by removing semantic stuff from it since it does not work anyway. RM is full of explanations why this or that construct cannot be taken as-is. Like, yes, parentheses are required but not really when … etc.

This discussion has been running some times before Dirk told me about it, so here is some information about the various points.

  1. Thanks for the nice words about AdaControl!

2) The standard:
The latest standard is for Ada 95. AdaCore has made extensions that follow the ASIS spirit up to Ada 2012. It would be relatively easy to make a new version of the ASIS standard with these extensions, but WG9 is not willing to spend time with NO current implementation…

3) AdaCore’s policy
AdaCore had warned me in advance that their ASIS implementation would no support Ada 2022. Since many extensions are in the form aspects (that could be queried), it did not seem so bad. It was a complete surprise when they completely removed all ASIS support. They provide a tree generator to paying customers (actually the latest compiler that supported ASIS), but they never made a public distribution of it. Of course, this is free software, so any supported user could make it public…

3) About name resolution
ASIS provides a view that correspond to the fully decorated AST, i.e. name resolution, overloading, use clauses, etc. are fully resolved. A simple query (Corresponding_Name_Declaration) brings you from any identifier to its declaration.

4) About tree files
A tree file is somehow a dump of the AST (and symbol table) of a unit. It is generated as part of the compilation. Note that it means that all analysis and name resolution have been made by a (supposedly) validated compiler, which gives greater confidence than when the ASIS implementation is a complete analyzer made from scratch.

The tree file includes all necessary information for the given unit, including (transitively) all information from the specifications of the withed units (but not their bodies). That’s why tree files are so huge (and slow to read). On the other hand, it implies that there is no tree swapping unless you need to access the body of a withed unit - which happens as soon as you want to do flow analysis, or access the body of an instantiated generic.

5) About generics
ASIS allows you to go from an instantiation to the (substituted) body of the unit. Therefore, analyzing the result of an instantiation is not especially difficult. However, it more or less assumes a macro-expansion of generics. I think Randy gave up on the idea of implementing ASIS when he discovered that (Janus-Ada has shared generics).

That’s all for now, I’d be happy to answer any further questions you may have!

Thanks for the information. It is much do digest.

P.S. Does this mean AdaControl is dead? That would be very sad.

No. There is an option in AdaControl to choose a “tree generator”, and as explained, you can use a version of Gnat (like 2019) that supports ASIS. Of course, you won’t have access to 2022+ features, but I don’t think it is that important.