Difference between revisions of "External types"
(added a few comments) |
(question) |
||
(10 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
There are currently two competing mechanisms. Their expressivity is roughly the same (when you have one it is easy to emulate the other). |
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 = |
= External attributes = |
||
Line 7: | Line 30: | ||
* what is the Eiffel type of the attribute? |
* what is the Eiffel type of the attribute? |
||
* when "passing" the attribute, do we pass a copy or a reference? |
* 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 = |
= External classes = |
||
Line 20: | Line 109: | ||
** Allowing, would force a dedicated ordering in the generated struct for the eiffel object |
** Allowing, would force a dedicated ordering in the generated struct for the eiffel object |
||
+ | expanded class SHOW |
||
− | = Inline external types = |
||
+ | |||
− | I think we should not call them inline external classes [[User:Ramack|Ramack]] 16:17, 17 Jul 2007 (CEST) |
||
+ | 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) |
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) |
||
Line 28: | Line 148: | ||
Issues: |
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 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 (<tt>ext: external is ...</tt>) --[[User:Cadrian|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 |
Revision as of 14:12, 18 July 2007
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