The RAPID compilation model

Although you may think of RAPID as a graphical user interface design tool (and it is), fundamentally RAPID is a compiler.  That is to say, RAPID translates from one language (a .GUI file) to another (Ada).  In fact, the very first version of RAPID had no graphical user interface at all; it only translated GUIs to Ada.

RAPID shares most of the functionality of a very simple compiler (there is no optimizer).  The first task of a compiler is to lex the input, or break it up into tokens (groups of related characters).  In RAPID, lexical analysis is done by the File_Helpers package. The procedure File_Helpers.Get_Line uses Text_IO.Get_Line to read a line from the input file, and then splits the line into a series of string tokens. The tokens are stored in the File_Helpers.Token array. The Read_Widget procedures in the Gui.Widget package hierarchy are responsible for converting the token strings into typed Ada entities, such as Integer, Float, Boolean, or enumeration values. (If the required Ada type is String then the token need not be converted.)

In RAPID, parsing the input is done by following a simple LL(1) grammar.  The grammar indicates what order different tokens appear in.  Since opening a file is on the file menu, so we start in the package File_Menu with the Open_Choice procedure.  This takes care of the file open dialog and setting some state.  Then, since each file contains a single window, we call the Read_Window method of a GUI_Window object (found in the package Gui.Window).  As can be seen in the grammar, a window has a name, width and height, which are read first.  Then, the menubar is read by the Read_Menubar procedure in Menu_IO and the widgets are read by the Read_Widgets procedure in Widget_IO (which calls the Read_Widget methods in the Gui.Widget hierarchy).  Below is a picture of the data structure created for a window:

Then, when the user presses compile (which, since on the tools menu is in Tools_Menu.Compile_Choice), the procedure Gui.Window.Generate_Window is called.  This calls Menu_Generate.Generate_Menu_Code to generate the menu code and appropriate methods on each widget to generate its declaration and creation code.

Suppose the window is named, "Window1".  The code is then generated in the files window1.ad[bs] (containing the procedure Generate_Window).  The code that appears in the Generate_Window procedure to create the widgets comes from the Generate_Widget_Creation method for each widget type.  The widgets are declared in the spec (in our example, window1.ads) by the Generate_Widget_Declaration method.  For more information on these methods, see the information on the GUI widget implementation.

A special case is radio buttons.  Since these come in groups, a linked list is created of the groups, and all of the groups are generated together (to avoid duplication by generating the same group over and over again for each radio button contained within it).  This is done by Widget_IO.Generate_Radio_Groups.