Chapter 2 
=========

  The Program Description Language 


2.1 Introduction 

  The  Eiffel/S  compiler  translates  an  Eiffel  program  by  first 
  handling the ``root''  class, then all classes  the root class uses 
  or from which it  inherits, and so on.  Since the classes belonging 
  to a program are  to be found in  various clusters one must somehow 
  tell the compiler where they are to found. This is the main task of 
  the PDL file. 

  A PDL file contains an ASCII  text written in the language PDL. The 
  essential pieces of information in such a file are: 

* What will the executable program be called? 

* Which is the ``root'' class and with which creation procedure shall 
  the program be started? 

* In which clusters should the compiler look for classes? 

  In  many cases  this  is already  the  complete description  of the 
  contents of a PDL file. Therefore we start with an example. 

    Example 

  program my_prog 
    root TEST : make 
     cluster 
      "." 
      end 
      "/eiffel/basic" 
      end 
    end -- program my_prog 

  Here we are  creating a program with  name my_prog. The ``root'' 
  class  is TEST  and  the creation  procedure  is called  make. The 
  compiler   is   to  use  the   current  cluster   and  the  cluster 
  /eiffel/basic when searching for classes. 

  These  few  instructions are  all  the Eiffel/S  compiler  needs to 
  produce an  executable program.  Note that  it is  not necessary or 
  even possible to tell the compiler which classes it is to translate 
  (except for the ``root'' class --- it has to start somewhere). 


2.2  Default PDL  file. 
=======================

  You  only need  to tell  it the  name of  the executable 
  program,  the  root  class and  the  root  creation  procedure. The 
  cluster clauses are then entered automatically (namely all clusters 
  that  belong  to the  original  product package).  If  the compiler 
  cannot   find  some  class  then   you  must  alter  the  PDL  file 
  accordingly. 



2.3 Validity 
============

  The   Eiffel/S  compiler  tests  more  than  just  the  syntactical 
  correctness  of the  PDL  file. It  also  tests conformance  to the 
  following rules: 


* No two classes in  the given clusters may  have the same name after 
  application of all rename clauses (see below). 


* The class ANY must appear in exactly one cluster. 
  The reason for the first rule is clear: if there were two classes 
  with the same name the compiler could not know which one was meant. 
  The  second rule  is  necessary since  every  class which  does not 
  explicitly inherit from any other class automatically inherits from 
  ANY. 


2.4 Structure of a PDL file 
===========================


  We now give an exact although informal description of a PDL file. 


2.4.1 Comments
============== 

  Comments follow the Eiffel convention  and can appear anywhere in a 
  PDL file. They begin with -- and extend to the end of the line. 

2.4.2 Keywords 
==============

  all      in 
  as       interface 
  cluster  link 
  end      make 
  exclude  program 
  find     rename 
  for      root 
  hfiles   use 
  lib


2.4.3 File and path names in PDL 
================================

  A file or path name in PDL must always be enclosed in quotes ("). 
  Path names may include components of the form 

  $identifier 

  where identifier is a legal name of an environment variable. Such a 
  component  will  be  replaced  by  the  value  of  the  environment 
  variable. 


Example 

  Suppose that an environment variable  EIFFEL_S is defined and has the 
  value /usr/eiffel. Then the path 

  $EIFFEL_S/library/basic 

  will be translated into 

  /usr/eiffel/library/basic 



Remark 

  Paths may  be given  either according  to the  UNIX or  the MS-DOS 
  convention. 


2.4.4 Separators 
================

  Except where the contrary is  explicitly stated the comma is always 
  optional. Thus you may  give a list of  paths or class names either 
  with or without comma. 

2.4.5 General structure 
=======================

  "program" filename 
    "root" classname ":" creation_procedure 
    "cluster" 
    cluster_descriptions 
    [ "make" [ "(" flags ")" ] file_list ] 
    [ "link" file_list ] 
    [ "lib" file_list ]
    "end" 

  filename is the  name the executable  program is to  have. The root 
  clause specifies first the name of the root class and then the name 
  of the creation procedure with which program execution begins. 


  At this point  it is perhaps  appropriate to remind  the reader how 
  the execution of an Eiffel program is started: 


* After the program  has been called,  a direct instance  of the root 
  class is created. 

* The given creation procedure is  called with the previously created 
  object as current. 

    Before proceeding to the really  interesting part of the PDL file 
  - namely the  cluster clause -- we  discuss the optional clauses 
  make and link. 


  As you  know, in  Eiffel one  can call  external routines  that are 
  written in another language. The  Eiffel compiler can determine the 
  names of these  routines but it  cannot tell where  to find them or 
  how they are to be translated. 


  The two clauses make and link are provided to solve this problem. 


2.4.6 The make clause 
=====================

  This (optional)  clause is  followed by a  list of  path names that 
  specify which ``makefiles'' are to  be executed by the program make 
  . These  makefiles could  for example  be used  to compile  C files 
  conditionally. As  a further  option you may  give a  list of flags 
  enclosed in parentheses that are to be passed to make. 


Example 

  make (-DEANSI -s) " $EIFFEL_S/my_lib/makefile", "./c_compile" 

  This has the effect of causing make to be called --- first with 

  /usr/eiffel/my_lib/makefile, 

  and then with 

  ./c_compile 

  as input. Both times make is called with the flags -DEANSI and -s. 
  In this example we have again assumed that the environment variable 
  EIFFEL_S has the value /usr/eiffel. 


  You may of course have arbitrarily many make clauses in a PDL file. 


2.4.7 The link & lib clause 
===========================

  This (optional) clause  specifies which object  files and libraries 
  are to be linked to the program. 


Example 

  link "my_c_file.o", "../other.o"
 
  lib "my_lib_file.a", -lm"

  This clause  causes my_c_file.o and ../other.o to  be included in  
  the list of object files and ../my_lib.a to be  the next to  last 
  library in the list for the linker. The  last library is -lm (the 
  math library under UNIX). 


  Note that  the list  of libraries  to be  linked is  constructed as 
  follows: 


* First the Eiffel/S runtime library. 

* Then the libraries  that appear in  the link clause  --- in exactly 
  the order given by you. 

    It is permissible to have several link & lib clauses. 


2.4.8 Cluster description 
=========================

  The description of the clusters is the most important part of a PDL 
  file. Here is where you tell  the Eiffel/S compiler how to find the 
  Eiffel  source texts.  Each cluster  description has  the following 
  general form: 

  cluster_path [ cluster_properties ] end 

  Here cluster_path  is a  path name  enclosed in  quotes ("). If 
  cluster_properties is omitted  (the usual case)  the the Eiffel/S 
  compiler regards all  files in this  cluster that end  with ".e" as 
  being Eiffel source. 


Example 

  ... 
    cluster 
     "." 
     end 
     "/usr/eiffel/library/basic" 
     end 
    end 



  Let us suppose the  compiler has discovered that  a class with name 
  MY_CLASS belongs  to the program.  Then it  searches the clusters 
  "." (= current cluster) and /usr/eiffel/library/basic for a file my 
  _class.e.  If it  finds such  a  file it  assumes that  this file 
  contains the class text  for the class MY_CLASS.  If it does not 
  find  such a  file then  it terminates  with a  corresponding error 
  message. 


Note 

  The order in which clusters are searched is irrelevant since no two 
  classes with the same name are allowed to occur (see Section 2.3). 


2.4.9 Cluster properties 
========================

  In some cases it  is not sufficient just  to list all clusters. The 
  clauses described below  allow a more  precise specification of how 
  the compiler is to treat the files of a cluster. We begin by giving 
  the general structure of a cluster properties clause: 

  rename    rename_list  
  use       use_list  
  find      find_list  
  exclude   file_list 
  interface class_list 
  hfiles    class_list 

  class_list  is  a  list  of  Eiffel  class  names  --- optionally 
  separated with  commas. file_list is  a list of  file names, also 
  optionally separated with  commas. Please note  that file names are 
  always enclosed in quotation marks ("). 


2.4.10 Renaming
===============


  The rename clause has the form 

  rename classname as classname, 
         classname as classname ... 

  You may give arbitrarily  many as clauses ---  but there must be at 
  least one. Commas may optionally be used as separators. 


Example 

  A clause of the form 

  rename CURSOR as WINDOW_CURSOR 

  means that the class CURSOR, which  must be in this cluster, is to 
  be renamed as WINDOW_CURSOR.  The class previously called CURSOR 
  is now only known under the new name. For the compiler this has the 
  following effect: 


  If the  compiler looks for  a class CURSOR  it will not  find it in 
  this cluster.  If, however, it  looks for  a class WINDOW_CLUSTER 
  then it will find it here. 


  The rename instruction can  be used to avoid  name clashes --- i.e. 
  if two (or more) classes have the  same name one can rename all but 
  one of them and thus eliminate  the conflict. If, however, what one 
  is trying to  do is use just  one of several  classes with the same 
  name (i.e. the others are not to be used at all), then we recommend 
  using the exclude clause (see below). 


2.4.11 Use 
==========

  The use clause has the form 

  use class_list for (class_list | all), 
      class_list for (class_list | all), ... 

  You may give arbitrarily many for  clauses --- but there must be at 
  least one. Commas may optionally be used as separators. 


  The meaning  of this  clause can be  explained most  easily with an 
  example. 


Example 

  Let us suppose you have the following PDL file: 

  ... 
    cluster 
    "cluster_1" 
    rename
      CURSOR as WINDOW_CURSOR 
    end 
    "cluster_2" 
    rename 
      CURSOR as LIST_CURSOR 
    end 
    end 



  Suppose further that in  cluster_1 there is a  class C1 that uses 
  CURSOR and in  cluster_2 a class  C2 that also  uses CURSOR. The 
  problem  here is  that  the Eiffel/S  compiler  has two  classes to 
  choose from for C1 and C2: WINDOW_CURSOR and LIST_CURSOR (both 
  were called CURSOR  until now). Somehow you  must tell the compiler 
  which of the two classes is to  be used. The use clause is provided 
  for doing this. 


  If we suppose, for  example, that C1 is  to use WINDOW_CURSOR but 
  C2 is to use LIST_CURSOR, then our example looks as follows: 

  ... 
  cluster 
    "cluster_1" 
    rename 
      CURSOR as WINDOW_CURSOR 
    use 
      WINDOW_CURSOR for C1 
    end 


    "cluster_2" 
    rename 
      CURSOR as LIST_CURSOR 
    use 
      LIST_CURSOR for C2 
    end 
  end 

  If  you specify  for all  then  the use  instruction holds  for all 
  classes of  the given  cluster. You  can of  course specify several 
  classes: 

  ...  
  rename 
    CURSOR  as WINDOW_CURSOR,  
    BUTTON as  WINDOW_BUTTON 
  use 
    WINDOW_CURSOR, WINDOW_BUTTON for all 
  end 
  ... 

  We now give the precise meaning of use and rename by looking at how 
  the compiler works. 


  Let  us suppose  again  that there  is a  class  C1 in  the cluster 
  cluster_1 that is to be  translated by the compiler. Suppose this 
  class has an attribute (or a  parent or an entity) of type CURSOR. 
  The compiler proceeds as follows: 


* If  in the  cluster properties  clause for  cluster_1 there  is a 
  clause 

  use 
    XXX, ... for C1 -- or all 

  and if there is also a clause 

  rename 
    CURSOR as XXX 

  for   cluster_1  or  some   other  cluster  then  replace  CURSOR 
  everywhere in C1 by XXX. 


* In every other case use the name CURSOR for C1. 

    Thus  from the  point  of view  of class  C1  either CURSOR  is a 
  synonym for XXX or the name stands for itself. 


  
2.4.12 Find 
===========

  The find clause has the form 

  find classname in filename, 
       classname in filename, ... 

  You may give arbitrarily  many in clauses ---  but there must be at 
  least one. Commas may optionally be used as separators. 


  The Eiffel/S compiler  usually looks for  the ASCII file containing 
  the class text by  using the class name. If  it finds that it needs 
  to translate a  class C then it  looks for a file  with name c.e in 
  the given clusters. It can happen,  however, that the class text of 
  the given class is in some other file. 


Example 

  Suppose  the  class is  called  VERY_LONG_CLASSNAME.  For most 
  operating systems the file name 

  very_long_classname.e 

  would be too long. In such  cases you must choose another file name 
  --- say v_l_name.e. This file  then contains the class text of 
  the   class  VERY_LONG_CLASSNAME,  but  how  is  the  Eiffel/S 
  compiler supposed to know that?  Quite simply: in the corresponding 
  cluster description you include a clause 

  find VERY_LONG_CLASSNAME in "v_l_name.e" 

  Thus  find establishes  a  simple mapping  of  class names  to file 
  names. 


Remark 

  As file name you may of course use any legal file name; it need not 
  end  with ".e".  We  recommend, however,  that  you stick  to this 
  convention. 


  
2.4.13 Exclude 
==============

  The exclude clause has the form 

  exclude file_list 

  This means that  all file names  from the list  file_list will be 
  ignored when searching the cluster.  For the Eiffel/S compiler this 
  has the  same effect as  if the files  simply did not  exist. As we 
  mentioned earlier, in case of a  name clash this method can be used 
  to exclude all but one of the classes involved in the clash. 


  
2.4.14 Interface 
================

  The interface clause has the form 

  interface class_list 

  This clause specifies which  classes of the cluster  are to be used 
  as interface  classes. A full  description of these  classes can be 
  found in Chapter 5. Here we  merely mention that these classes (and 
  only these classes) may be used by external routines. 


2.4.15 hfiles 
=============


  The hfiles clause has the form 

  hfiles class_list 

  The Eiffel/S  compiler produces  for the  given classes  ".h" files 
  that contain the  exact structure of the  objects of the respective 
  class type.  You can use  these ".h"  files in order  to access the 
  attributes of  the class  directly. Please  read Chapter  4 to find 
  more information about this topic. 

