[ Prev ] [ Index ] [ Next ]

Libraries

Created Tuesday 18 November 2008

Status

Being implemented, waiting for the compiler to bootstrap (and waiting for free time, won't happend before the 20th of December 2008)

Abstract

This specification describe a compiler enhancement that would make it able to handle different project with potential conflicting prototype names.

Definitions

Syntax

The prototype name would be changed to accept semicolons (':'). The last part is known as the prototype basename, the complete whole makes the prototype pathname (that may be fully qualified if all path elements are included). The 'name' slot in the Section Header still only specified the prototype basename.

Libraries

Libraries would be found in a system directory (for example /usr/share/lisaaclib/<libname>). That setting could be overridden with an environment variable (much like the PATH). For each project, it would be also possible to add additional search paths either absolute or relative to the project's directory. And for each import, it should be possible to change the name of the library to use another prefix (if the system prefix doesn't suit your project). See Traps to see why this is important.

Traps

During implementation, there are few issues we have to take care of. These are very subtle corner cases that can ruin the implementation.

Imagine for example a library called MyLib, the version currently released is the version 1. Everyone accesses the prototypes of MyLib using the "MYLIB::" prefix. Now imagine that a new version has been released, completely incompatible with the last one. But unfortunately, they haven't changed the name and people still access the prototypes of the new version (version 2) using the prefix "MYLIB::". Now, we have a very large project that uses MyLib version 2. The code has been completely developed and we cannot change easily how we call the prototypes of MyLib. We use the prefix "MYLIB::". But we also use another library, LibFoo, and LibFoo uses MyLib version 1, and uses the prefix "MYLIB::" for the MyLib prototypes.

If the compiler assumed that MYLIB corresponded to the same library in each case, we are in serious troubles. The solution would be to have two libraries on our system: MYLIB1 and MYLIB2. And specify in our project that we want to import MYLIB2 and use the prefix MYLIB. The project LibFoo would instead import MYLIB1 and give it the prefix MYLIB. There is no coherency problem as the two projects are completely separate. Within the context, it is clear which library is used.

Implementation

Each member of the pathname is called an item (PRJ_ITM). An item has a name and can be browsed for sub-items. An item can be either:

An item has the following properties:

Lookup rules

See in the patches the prototype ABSTRACT_PROJECT. The lookup algorithm is fully commented (the comments are outdated it seems) in the slot safe_get_fully_qualified_namefromat.

For a pathname like PROJECT:DIR:DIR:PROTO, we define the following parts:

The algorithm is different if the pathname contains any wildcard.

The current project is defined as the project of the prototype currently being parsed (the prototype that contains the type we are looking for)

• With wildcards

— If there is a wildcard, the path is cut in two parts, the part before the wildcard, and the part after the wildcard. — First, we walk through the items child of the current project — if no such item is found, issue an error — ...

• No wildcard

...

Strategy

Modify the compiler to include some hooks when prototype fetching is done to be able to add some other code than the current path.li to load the prototype requested. That is what is currently done in the patch hooks.patch (some other changes may have slipped through and it may not be complete).

Then write the code to load the prototypes according to their pathname.

Project files (.lip files)

Project files are necessary, and they will have a Lisaac-like syntax. But I don't have much ideas on how it will look like. I especially don't know of what use the inheritance could be. Any inputs?

I started to write two examples (see patches), but I don't know how good this is:

Section Header

  + name := BUILTIN:PROJECT;

  - author        := "Mildred Ki'Lya <mildred593(at)online.fr>";
  - copyright     := "2008 Mildred Ki'Lya";
  - comment       := "";

  // Copyright (c) 2008 Mildred Ki'Lya <mildred593(at)online.fr>
  //
  // Permission is hereby granted, free of charge, to any person
  // obtaining a copy of this software and associated documentation
  // files (the "Software"), to deal in the Software without
  // restriction, including without limitation the rights to use,
  // copy, modify, merge, publish, distribute, sublicense, and/or sell
  // copies of the Software, and to permit persons to whom the
  // Software is furnished to do so, subject to the following
  // conditions:
  //
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  // OTHER DEALINGS IN THE SOFTWARE.

Section Public

  - main <-
  (
    import_private "STD";
    scan public path ".";

    // TODO:
    // import_private "TOTO_v1";
    // import_private "TOTO_v2" alias "TOTO";
  );

  + basename   :STRING_CONSTANT;
  + prototype  :STRING_CONSTANT;
  + entry_slot :STRING_CONSTANT := "main";
  + language   :STRING_CONSTANT := "C";

  - private :INTEGER := 0;
  - public  :INTEGER := 1;

  - scan pub:INTEGER path path:STRING_CONSTANT <- scan pub path path name NULL;
  - scan pub:INTEGER path path:STRING_CONSTANT name name:STRING_CONSTANT <- `1`;

  - import_private lib:STRING_CONSTANT <- import(private, lib);
  - import_public  lib:STRING_CONSTANT <- import(public, lib);
  - import (pub:INTEGER, lib:STRING_CONSTANT) <- `2`;

  - import_path_add_first path:STRING_CONSTANT <- `10`;
  - import_path_add_last  path:STRING_CONSTANT <- `11`;
  - import_path_clear                          <- `12`;

// kate: hl Lisaac v0.2; indent-width 2; space-indent on; replace-tabs off;
// kate: tab-width 8; remove-trailing-space on;
'''
and:

'''
Section Header

  + name := PROJECT;

  - author        := "Mildred Ki'Lya <mildred593(at)online.fr>";
  - copyright     := "2008 Mildred Ki'Lya";
  - comment       := "";

  // Copyright (c) 2008 Mildred Ki'Lya <mildred593(at)online.fr>
  //
  // Permission is hereby granted, free of charge, to any person
  // obtaining a copy of this software and associated documentation
  // files (the "Software"), to deal in the Software without
  // restriction, including without limitation the rights to use,
  // copy, modify, merge, publish, distribute, sublicense, and/or sell
  // copies of the Software, and to permit persons to whom the
  // Software is furnished to do so, subject to the following
  // conditions:
  //
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  // OTHER DEALINGS IN THE SOFTWARE.

Section Insert

  - builtin_project :BUILTIN::PROJECT;

Section Public

  - main <-
  (
    scan public path "src";

    import_path_add_first ".";
    import_public  "LIB_PUB"
    import_private "LIB_PRIV"
    import_private "STD";

    language   := "C";
    prototype  := "TEST";
  )

// kate: hl Lisaac v0.2; indent-width 2; space-indent on; replace-tabs off;
// kate: tab-width 8; remove-trailing-space on;

Compatibility issues

The current code load prototypes on demand. That means, until some features of the prototype gets used in living code, the prototype isn't loaded at all. The existence of the prototype isn't even checked.

It is possible to maintain the same behaviour, but it add complexity. The fact is that the new code will search for the prototypes as soon as it encounter them in the code. If we were to keep the old behaviour, it would require to create a fake ITM_TYPE (if I remember the prototype name correctly) that would only produce an error when the prototype it stands for is required).

We need to check the prototype existence when the prototype pathname is encountered in order to avoid having almost as many ITM_TYPE (again, perhaps it's another prototype) as we can find the prototype mentioned in the source code. If we don't resolve the wildcards that early, that is what will happen.

See also


Backlinks: :Computer:Lisaac:Specs