External types

From Liberty Eiffel Wiki
Revision as of 14:12, 18 July 2007 by Cadrian (talk | contribs) (question)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

There are currently two competing mechanisms. Their expressivity is roughly the same (when you have one it is easy to emulate the other).

For syntactic experiments, we'll assume the following C files are used but the syntax will have to be flexible enough to work for other external languages (e.g. Java).

my_struct.h:

typedef struct {
  double x;
  int c;
} my_struct;

my_struct.c:

#include "my_struct.h"
use (my_struct *x) {
  x->x = 3.14;

  if(x->c == 0) x->c = 5;
  else          x->c++;

  printf("x = %f, c = %d\n", x->x, x->c);
}

The program should print

x = 3.14, c = 5
x = 3.14, c = 6

External attributes

A special marker is used to tell the Eiffel compiler that an attribute should be represented by a user-specified external type. The only meaningful thing that can be done with it is passing it as a parameter to external routines.

Issues:

  • what is the Eiffel type of the attribute?
  • when "passing" the attribute, do we pass a copy or a reference?

Two suggested versions

Faux procedures

class SHOW

creation
    make

feature
   make is
      do
         use($ext)
         use($ext)
      end

   use(x: POINTER) is
      external "plug_in"
      alias "{
         location: "./"
         module_name: "struct"
         feature_name: "use"
         }"
      end

   ext is
      external "plug_in"
      alias "{
         location: "./"
         module_name: "struct"
         attribute_type: "my_struct"
         }"
      end
end

Faux pointers

class SHOW

creation
   make

feature
   make is
      do
         use(ext)
         use(ext)
      end

   use(x: POINTER) is
      external "plug_in"
      alias "{
         location: "./"
         module_name: "struct"
         feature_name: "use"
         }"
      end

   ext: POINTER is
      external "plug_in"
      alias "{
         location: "./"
         module_name: "struct"
         attribute_type: "my_struct"
         }"
      end
end

External classes

A special marker is used to tell the Eiffel compile that a class should be represented by a user-specified external type. Methods of that class can be implemented by passing Current as a parameter to external routines. Whether Current is passed by copy or by reference could be determined by the reference/expanded status of the external class.

Issues:

  • Forces the programmer to write one class for each external type they want to wrap
  • It wouldn't be possible to inherit from/insert that kind of class
  • such classes should not inherit/insert other classes (ANY?)
  • Implementing some of ANY's operations for external types might be difficult
  • How are native eiffel attributes in such a class handled?
    • Forbid them is not nice, since this may yield to to need to write two classes in special cases, also this would be a special case, which is not nice in general.
    • Allowing, would force a dedicated ordering in the generated struct for the eiffel object
expanded class SHOW

external "plug_in"
   alias "{
      location: "./"
      module_name: "struct"
      attribute_type: "my_struct"
      }"

creation
    make

feature
    make is
        do
            -- Memory is zeroed, so we probably don't need to initialize x and
            -- c. If we do, we'll have to call a C function to do it.
            use($Current)
            use($Current)
        end

    use(x: POINTER) is
        external "plug_in"
        alias "{
            location: "./"
            module_name: "struct"
            feature_name: "use"
            }"
        end

end

Inline external classes

Ok, so there are actually three mechanisms, but this one is hybrid between the previous two (give the external attribute an Eiffel type that doesn't need to be defined anywhere else)

With this approach we can even allow this type for external features, which would solve the pass-by-value/reference question: do a copy or use a pointer to it.

Issues:

  • What is the scope of such a type? Only visible in the class it is written in? Are two external types with the same "name" in different classes the same?
  • What is the use of the type name? I'd just ommit it (ext: external is ...) --Cyril 15:12, 18 Jul 2007 (CEST)
class SHOW
creation
   make

feature
   make is
      do
         use($ext)
         use($ext)
      end

   use(x: POINTER) is
      external "plug_in"
      alias "{
         location: "./"
         module_name: "struct"
         feature_name: "use"
         }"
      end

   ext: external MY_STRUCT is  -- inline declaration of external type
      external "plug_in"
      alias "{
         location: "./"
         module_name: "struct"
         attribute_type: "my_struct"
         }"
      end
end