[m-rev.] [dotnet-foreign] diff: handle properties
Peter Ross
petdr at cs.mu.OZ.AU
Sat Jun 16 11:02:02 AEST 2001
Hi,
===================================================================
Estimated hours taken: 8
Branches: dotnet-foreign
Treat functions with the name get_PropertyName and predicates with the
name set_PropertyName as properties in the generated IL.
compiler/ilasm.m:
Add the property alternative to class members, and output it into
the decl stream.
compiler/mlds_to_il.m:
Create property il assembler statements for exported names in the
form get_Name/set_Name.
Index: compiler/ilasm.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ilasm.m,v
retrieving revision 1.5.4.6
diff -u -r1.5.4.6 ilasm.m
--- compiler/ilasm.m 2001/06/03 09:01:00 1.5.4.6
+++ compiler/ilasm.m 2001/06/16 00:54:35
@@ -47,7 +47,7 @@
extends, % what is the parent class
implements, % what interfaces are
% implemented
- list(class_member) % methods and fields
+ list(class_member) % methods and fields
)
% .namespace declaration
; namespace(
@@ -123,6 +123,13 @@
maybe(int32), % offset for explicit layout
field_initializer % initializer
)
+ % .property (a class property)
+ ; property(
+ ilds__type, % property type
+ ilds__id, % property name
+ maybe(methodhead), % get property
+ maybe(methodhead) % set property
+ )
% .class (a nested class)
; nested_class(
list(classattr), % attributes for the class
@@ -459,6 +466,31 @@
io__write_string(" "),
output_id(IlId),
output_field_initializer(Initializer).
+
+ilasm__output_class_member(
+ property(Type, Name, MaybeGet, MaybeSet), Info0, Info) -->
+ io__write_string(".property instance "),
+ output_type(Type, Info0, Info1),
+ io__write_string(" "),
+ output_id(Name),
+ io__write_string("() {"),
+ ( { MaybeGet = yes(methodhead(_, GetMethodName, GetSignature, _)) },
+ io__nl,
+ io__write_string("\t.get instance "),
+ output_name_signature_and_call_conv(GetSignature,
+ yes(GetMethodName), Info1, Info2)
+ ; { MaybeGet = no },
+ { Info2 = Info1 }
+ ),
+ ( { MaybeSet = yes(methodhead(_, SetMethodName, SetSignature, _)) },
+ io__nl,
+ io__write_string("\t.set instance "),
+ output_name_signature_and_call_conv(SetSignature,
+ yes(SetMethodName), Info2, Info)
+ ; { MaybeSet = no },
+ { Info = Info2 }
+ ),
+ io__write_string("\n}\n").
ilasm__output_class_member(nested_class(Attrs, Id, Extends, Implements,
Contents), Info0, Info) -->
Index: compiler/mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.15.4.21
diff -u -r1.15.4.21 mlds_to_il.m
--- compiler/mlds_to_il.m 2001/06/08 15:36:14 1.15.4.21
+++ compiler/mlds_to_il.m 2001/06/16 00:54:39
@@ -549,8 +549,8 @@
ConstructorILDefn) },
{ Decls = [comment_term(MLDSDefnTerm),
class([public], TypeName,
- Extends, implements([]),
- [ConstructorILDefn | ILDefns])] }
+ Extends, implements([]), [ConstructorILDefn |
+ list__condense(ILDefns)])] }
;
{ Decls = [comment_term(MLDSDefnTerm),
comment("This type unimplemented.")] }
@@ -565,7 +565,8 @@
Defns, ILDefnsA),
list__map_foldl(defn_to_class_decl(yes),
Ctors, ILDefnsB),
- { ILDefns = ILDefnsA ++ ILDefnsB },
+ { ILDefns = merge_properties(list__condense(ILDefnsA) ++
+ list__condense(ILDefnsB)) },
{
Inherits = [mlds__foreign_type(ForeignType,
Assembly)]
@@ -596,7 +597,64 @@
{ Decls = [] }
).
+:- func merge_properties(list(class_member)) = list(class_member).
+merge_properties(ClassMembers)
+ = merge_duplicates(Equals, merge_properties, ClassMembers) :-
+ Equals = (pred(property(Type, Name, _, _)::in,
+ property(Type, Name, _, _)::in) is semidet).
+
+:- func merge_properties(class_member, class_member) = class_member.
+
+merge_properties(PropertyA, PropertyB)
+ = property(Type, Name, MaybeGet, MaybeSet) :-
+ (
+ PropertyA = property(Type0, Name0, MaybeGetA, MaybeSetA),
+ PropertyB = property(Type0, Name0, MaybeGetB, MaybeSetB)
+ ->
+ ( MaybeGetA = yes(GetA),
+ ( MaybeGetB = yes(_GetB),
+ error("merge_properties: two gets")
+ ; MaybeGetB = no,
+ MaybeGet = yes(GetA)
+ )
+ ; MaybeGetA = no,
+ ( MaybeGetB = yes(GetB),
+ MaybeGet = yes(GetB)
+ ; MaybeGetB = no,
+ MaybeGet = no
+ )
+ ),
+ ( MaybeSetA = yes(SetA),
+ ( MaybeSetB = yes(_SetB),
+ error("merge_properties: two sets")
+ ; MaybeSetB = no,
+ MaybeSet = yes(SetA)
+ )
+ ; MaybeSetA = no,
+ ( MaybeSetB = yes(SetB),
+ MaybeSet = yes(SetB)
+ ; MaybeSetB = no,
+ MaybeSet = no
+ )
+ ),
+ Type = Type0,
+ Name = Name0
+ ;
+ error("merge_properties: not properties")
+ ).
+
+:- func merge_duplicates(pred(T, T), func(T, T) = T, list(T)) = list(T).
+:- mode merge_duplicates(pred(in, in) is semidet,
+ func(in, in) = out is det, in) = out is det.
+
+merge_duplicates(_Equals, _Merge, []) = [].
+merge_duplicates(Equals, Merge, [H | T])
+ = [list__foldl(Merge, Dups, H) |
+ merge_duplicates(Equals, Merge, Rest)] :-
+ list__filter((pred(X::in) is semidet :- Equals(H, X)), T, Dups, Rest).
+
+
%-----------------------------------------------------------------------------
%
@@ -721,8 +779,8 @@
%
% Code to turn MLDS definitions into IL class declarations.
%
-
-:- pred defn_to_class_decl(bool, mlds__defn, class_member, il_info, il_info).
+:- pred defn_to_class_decl(bool, mlds__defn, list(class_member),
+ il_info, il_info).
:- mode defn_to_class_decl(in, in, out, in, out) is det.
% XXX shouldn't we re-use the code for creating fieldrefs here?
@@ -735,7 +793,7 @@
mlds_type_to_ilds_type(DataRep, Type)) },
{ Name = data(DataName) ->
mangle_dataname(DataName, MangledName),
- ILClassMember = field([], ILType, MangledName, no, none)
+ ILClassMember = [field([], ILType, MangledName, no, none)]
;
error("definintion name was not data/1")
}.
@@ -814,7 +872,28 @@
{ MethodDefn = make_method_defn(InstrsTree) },
{ MethodHead = methodhead(MethodAttrs, Id, ILSignature, ImplAttrs) },
- { ILClassMember = method(MethodHead, MethodDefn) }.
+ { Method = method(MethodHead, MethodDefn) },
+
+ { (Id = id(IdName), string__append("get_", PropertyName, IdName)) ->
+ ILSignature = signature(_, ReturnType, _),
+ ( ReturnType = simple_type(SimpleType) ->
+ ILDSType = ilds__type([], SimpleType)
+ ;
+ error("mlds__to_il: no return type for get method")
+ ),
+ Property = property(ILDSType, id(PropertyName),
+ yes(MethodHead), no),
+ ILClassMember = [Method, Property]
+ ; (Id = id(IdName), string__append("set_", PropertyName, IdName)) ->
+ ILSignature = signature(_, _, ILParams),
+ ILDSType - _Name = list__det_head(list__reverse(ILParams)),
+ Property = property(ILDSType, id(PropertyName),
+ no, yes(MethodHead)),
+ ILClassMember = [Method, Property]
+ ;
+ ILClassMember = [Method]
+ }.
+
defn_to_class_decl(_, mlds__defn(EntityName, _Context, _DeclFlags,
mlds__class(ClassDefn)), ILClassMember) -->
@@ -829,8 +908,9 @@
{ make_constructor(DataRep, FullClassName, ClassDefn,
ConstructorILDefn) },
{ Extends = mlds_inherits_to_ilds_inherits(DataRep, Inherits) },
- { ILClassMember = nested_class([public], TypeName, Extends,
- implements([]), [ConstructorILDefn | ILDefns]) }
+ { ILClassMember = [nested_class([public], TypeName, Extends,
+ implements([]), [ConstructorILDefn |
+ list__condense(ILDefns)])] }
;
{ error("expected type entity name for a nested class") }
).
----
Peter Ross
PhD Student University of Melbourne
http://www.cs.mu.oz.au/~petdr/
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list