[m-dev.] Generating methods for foreign classes

Tyson Dowd trd at cs.mu.OZ.AU
Thu May 24 15:18:57 AEST 2001


On 24-May-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 23-May-2001, Peter Ross <peter.ross at miscrit.be> wrote:
> > The following is a diff which currently generates for the following decl
> > 
> > :- pragma foreign_class(
> >                 'Employee'(employee), % instance used to determine
> >                                       % methods implementations
> >                 [],                   % List of constructor functions NYI
> >                 "Employee"            % Name of exported class
> >             ).
> > 
> > the following IL
> > 
> > .namespace 'use_person'
> > {
> >   .class public 'Employee' extends ['Person']'Person'.'Person'
> >   {
> >     .field private class ['mscorlib']'System'.'Object'[] 'state'
> >   }
> > }
> 
> Hmm, that seems odd; the source decl doesn't mention the word
> "person", yet it occurs four times in the generated code.

Pete was probably assuming that I had given a talk about this stuff and
you knew what he was talking about.  I will talk about it tomorrow.

Basically this is our prototype scheme for writing OO style inhertitance
in Mercury.

'Employee' is a type class that inherits from the 'Person' type class.
The Mercury compiler picks up 'Person' from the type class constraints.
 
> I think your example is incomplete.  I don't understand it.

[You should try running the dotnet/intgen/reflect.cs code].

Imagine you have the usual class Person.

public class Person {
	...
	public instance string Name();
	...
}

I'm not going to go into too much detail, but basically it will
generate:

:- typeclass 'Object'(T) where [
	... instance methods for object ...
].

:- typeclass 'Person'(T) <= 'Object'(T) where [
	func 'Name' = string
].

There will also be some instance declarations and implementations and
stuff.

Now you add your own typeclass 'Employee'.

:- typeclass 'Employee'(T) <= 'Person(T) where [
	pred salary(int, T, T),
	mode salary(in, di, uo) is det
].

And you give an instance.

	% I assume we use an embedded superclass to model the
	% inheritance relationship.
:- type employee --->
		employee(
			person :: 'Person',
			salary :: int
		).

	% I will assume we use delegation to handle methods that we
	% don't want to override.
:- instance 'Employee'(employee) where [
	salary(X) = X ^ salary,
	name(X) = name(X ^ person)
].

Now this instance is perfectly fine Mercury code (well, I haven't
compiled it but it should be close to right).  But you want to export it
as a .NET class that extends a known .NET class.  That's what pragma
foreign_class is doing.

So now Pete's example should make more sense.

> Also what happens in grade `il' rather than `ilc'?

'state' has a different type.  It will be type employee_0, which is a
class defined according to the :- type declaration for employee.

> > Now if the instance decl is
> > 
> > :- instance 'Employee'(employee) where [
> >     pred('Salary'/3) is salary
> > ].

Ok, so Pete used a slightly different thing here, which is not quite
what I did, but close.

> > 
> > :- pred salary(int::in, employee::di, employee::uo) is det.
> > 
> > I now want to generate a .NET method body along the lines of 
> > 
> > .method void Salary(int s)
> > {
> >     ldarg s
> >     ldarg this_pointer
> >     ldfld store
> >     ldarg this_pointer
> >     ldflda store
> >     call mercury_salary_3(int, object[], object[]&)
> > }
> > 
> > Any hints on the best way to do this using the MLDS?
> 
> I don't really understand what you're trying to do.
> It would help if you could try explaining it a bit more.

I think he means s/store/state/g

In C#:

namespace 'use_person' {
	public class Employee extends Person.Person {
		private class System.Object[] state;
		public void Salary(int s) {
			mercury_salary_3(s, state, &state);
		}
	}
}

In MLDS the body of Salary would look something like:

call(Signature, FunctionRval, yes(ThisRval),
	[
		lval(var("s")), 
		lval(field(no, ThisRval, named_field("state")...)),
		mem_ref(lval(field(no, ThisRval, named_field("state")...))
	],
	[], yes)

But the big problem is that I don't know what ThisRval should be.
There doesn't appear to be an rval for "this".  I think it might be
missing from the MLDS actually.

-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list