[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