[m-rev.] [dotnet] diff: support methods and constructors.

Tyson Dowd trd at cs.mu.OZ.AU
Fri Apr 20 03:45:36 AEST 2001


Hi,

This code isn't yet perfect, but it goes a good way towards getting
this stuff working.

===================================================================


Estimated hours taken: 10

intgen/reflect.cs:
	Add interface and implementation for constructors and methods.


Index: intgen/reflect.cs
===================================================================
RCS file: /home/mercury1/repository/dotnet/intgen/reflect.cs,v
retrieving revision 1.7
diff -u -r1.7 reflect.cs
--- intgen/reflect.cs	2001/04/11 15:25:12	1.7
+++ intgen/reflect.cs	2001/04/19 17:19:12
@@ -13,8 +13,8 @@
 public static void Main(string[] args) {
 
 	if (args.Length > 0) {
-		Assembly	asm = Assembly.Load(args[0]);
-		Type[]		types;
+		Assembly asm = Assembly.Load(args[0]);
+		Type[] types;
 
 		if (args.Length > 1) {
 			Type[] t = new Type[1];
@@ -117,10 +117,6 @@
 
 public static void GenerateInterfaceForType(Type t, string assemblyname) {
 
-	System.String[] split_type_name;
-
-	split_type_name = t.FullName.Split(dotnet_seperator.ToCharArray());
-
 	Console.Write("\t% type " + t.FullName + "\n");
 
 	Console.Write(":- module '");
@@ -131,48 +127,34 @@
 
 	Console.WriteLine("\n:- interface.\n");
 
-    Console.Write(":- impure func new = ");
-    OutputTypeNameAsMercuryType(t);
-	Console.WriteLine(".");
-	
 	foreach (MemberInfo m in members) {
-		GenerateInterfaceForMember(m);
+		GenerateInterfaceForMember(t, m);
 		Console.WriteLine();
 	}
 
 	Console.WriteLine("\n:- implementation.\n");
-
-    Console.WriteLine(":- pragma foreign_decl(\"MC++\", \"");
-    Console.Write("#using \"\"");
-    Console.Write(assemblyname);
-    Console.WriteLine(".dll\"\"");
-    Console.WriteLine("\").");
 
-    Console.WriteLine(":- pragma foreign_code(\"MC++\", new = (Object::out),");
-	Console.WriteLine("\t\t[will_not_call_mercury, thread_safe], \"");
-
-	Console.Write("\tObject = new ");
-	Console.Write(split_type_name[0]);
-	for (int i = 1; i < split_type_name.Length; i++) {
-		Console.Write(cpp_seperator);
-		Console.Write(split_type_name[i]);
-	}
-	Console.WriteLine("();");
-
+	Console.WriteLine(":- pragma foreign_decl(\"MC++\", \"");
+	Console.Write("#using \"\"");
+	Console.Write(assemblyname);
+	Console.WriteLine(".dll\"\"");
 	Console.WriteLine("\").");
 
+		// Write the implementations.
 	foreach (MemberInfo m in members) {
-		GenerateImplementationForMember(m);
+		GenerateImplementationForMember(t, m);
 		Console.WriteLine();
 	}
 
+
+		// Write the :- end_module.
 	Console.Write(":- end_module '");
 	Console.Write(t.Name);
 	Console.WriteLine("'.");
 	Console.WriteLine("");
 }
 
-public static void GenerateInterfaceForMember(MemberInfo m) {
+public static void GenerateInterfaceForMember(Type t, MemberInfo m) {
 	Console.Write("\t% member " + m.Name + "\n");
 
 	switch (m.MemberType) {
@@ -182,7 +164,7 @@
 	break;
 
 	case MemberTypes.Constructor:
-	Console.WriteLine("\t% constructor XXX unimplemented");
+	GenerateInterfaceForConstructor(t, (ConstructorInfo) m);
 	break;
 
 	case MemberTypes.Custom:
@@ -212,11 +194,10 @@
 	case MemberTypes.TypeInfo:
 	Console.WriteLine("\t% typeinfo XXX unimplemented");
 	break;
-
 	}
 }
 
-public static void GenerateImplementationForMember(MemberInfo m) {
+public static void GenerateImplementationForMember(Type t, MemberInfo m) {
 	Console.Write("\t% member " + m.Name + "\n");
 
 	switch (m.MemberType) {
@@ -226,7 +207,7 @@
 	break;
 
 	case MemberTypes.Constructor:
-	Console.WriteLine("\t% constructor XXX unimplemented");
+	GenerateImplementationForConstructor(t, (ConstructorInfo) m);
 	break;
 
 	case MemberTypes.Custom:
@@ -242,7 +223,7 @@
 	break;
 
 	case MemberTypes.Method:
-	Console.WriteLine("\t% method XXX unimplemented");
+	GenerateImplementationForMethod(t, (MethodInfo) m);
 	break;
 
 	case MemberTypes.NestedType:
@@ -260,9 +241,59 @@
 	}
 }
 
+//---------------------------------------------------------------------------//
+// CONSTRUCTORS
+//---------------------------------------------------------------------------//
+
+public static void GenerateInterfaceForConstructor(Type t,
+		ConstructorInfo c) {
+
+	ParameterInfo[] parameters = c.GetParameters();
+
+	Console.Write(":- impure func 'new'");
+	OutputTypeModeParameters(parameters);
+	Console.Write(" = (");
+	OutputTypeNameAsMercuryType(t);
+	Console.Write("::out)");
+	Console.WriteLine(" is det.");
+}
+
+public static void GenerateImplementationForConstructor(Type t,
+		ConstructorInfo c) {
+
+	System.String[] split_type_name;
+
+	split_type_name = t.FullName.Split(dotnet_seperator.ToCharArray());
+
+	ParameterInfo[] parameters = c.GetParameters();
+
+	Console.Write(":- pragma foreign_code(\"MC++\", new");
+	OutputNameModeParameters(parameters);
+	Console.WriteLine(" = (Object::out),");
+	Console.WriteLine("\t\t[will_not_call_mercury, thread_safe], \"");
+
+	Console.Write("\tObject = new ");
+	Console.Write(split_type_name[0]);
+	for (int i = 1; i < split_type_name.Length; i++) {
+		Console.Write(cpp_seperator);
+		Console.Write(split_type_name[i]);
+	}
+	OutputNameParameters(parameters);
+	Console.WriteLine(";");
+	OutputByrefAssigments(parameters);
+
+	Console.WriteLine("\").");
+}
+
+
+//---------------------------------------------------------------------------//
+// METHODS
+//---------------------------------------------------------------------------//
+
+
 public static void GenerateInterfaceForMethod(MethodInfo m) {
 	if (m == null) {
-		Console.WriteLine("\t% XXXXXXXXXXXXXXXXXXXX ");
+		throw new Exception("null methodinfo is bad");
 	}
 
 	Type returntype = m.ReturnType;
@@ -279,18 +310,7 @@
 			Console.Write(":- func '" + m.Name + "'");
 		}
 
-		if (parameters.Length > 0) {
-			int i;
-			Console.Write("(");
-			
-			OutputParameterAsMercuryParameter(parameters[0]);
-			for (i = 1; i < parameters.Length; i++) {
-				Console.Write(", ");
-				OutputParameterAsMercuryParameter(
-					parameters[i]);
-			}
-			Console.Write(")");
-		}
+		OutputTypeModeParameters(parameters);
 
 		if (is_pred) {
 			// don't do anything here.
@@ -300,64 +320,64 @@
 			Console.Write("::out)");
 		}
 		Console.WriteLine(" is det.");
+	} else {
+		Console.WriteLine("% XXX instance methods unimplemented.");
 	}
 		
 }
 
-public static void OutputParameterAsMercuryParameter(ParameterInfo pinfo) {
-
-	OutputTypeNameAsMercuryType(pinfo.ParameterType);
+public static void GenerateImplementationForMethod(Type t,
+		MethodInfo m) {
 
-
-	if (pinfo.IsOut) {
-		Console.Write("::out");
-	} else if (pinfo.ParameterType.IsByRef) {
-		Console.Write("::in, ");
-		OutputTypeNameAsMercuryType(pinfo.ParameterType);
-		Console.Write("::out");
-	} else {
-		Console.Write("::in");
+	Type returntype = m.ReturnType;
+	bool is_pred = false;
+	if (returntype.Name == "Void") {
+		is_pred = true;
 	}
-}
+	ParameterInfo[] parameters = m.GetParameters();
+	System.String[] split_type_name;
+	split_type_name = t.FullName.Split(dotnet_seperator.ToCharArray());
 
-	// Returns whether the type is a by-ref
-public static void OutputTypeNameAsMercuryType(Type t) {
+	if (m.IsStatic) {
 
-	Type element_type;
+		Console.Write(
+			":- pragma foreign_code(\"MC++\", '" + m.Name + "'");
+		OutputNameModeParameters(parameters);
 
-	if (t.IsByRef) {
-		element_type = t.GetElementType();	
-		OutputTypeNameAsMercuryType(element_type);
-	} else if (t.IsArray) {
-		element_type = t.GetElementType();
-		Console.Write("array(");
-		OutputTypeNameAsMercuryType(element_type);
-		Console.Write(")");
-	} else {
-		switch (t.FullName) {
-			case "System.String":
-			Console.Write("string");
-			break;
+		if (!is_pred) {
+			Console.WriteLine(" = (Result::out),");
+		}
 
-			case "System.Char":
-			Console.Write("char");
-			break;
+		Console.WriteLine("\t\t[will_not_call_mercury, thread_safe], \"");
 
-			case "System.Int":
-			Console.Write("int");
-			break;
+		if (!is_pred) {
+			Console.Write("\tResult = ");
+		}
 
-			default:
-			Console.Write("'" + t.FullName + "'");
-			break;
+		Console.Write(split_type_name[0]);
+		for (int i = 1; i < split_type_name.Length; i++) {
+			Console.Write(cpp_seperator);
+			Console.Write(split_type_name[i]);
 		}
+		Console.Write(cpp_seperator);
+		Console.Write(m.Name);
+		
+		OutputNameParameters(parameters);
+		Console.WriteLine(";");
+		OutputByrefAssigments(parameters);
 
+	Console.WriteLine("\").");
 
 
+	} else {
+		Console.WriteLine("% XXX instance methods unimplemented.");
 	}
 }
 
+
 //---------------------------------------------------------------------------//
+// PROPERTIES
+//---------------------------------------------------------------------------//
 
 public static void GenerateInterfaceForProperty(PropertyInfo property)
 {
@@ -410,11 +430,151 @@
 }
 
 //---------------------------------------------------------------------------//
+// Support code
+//---------------------------------------------------------------------------//
 
+public static void OutputNameParameters(ParameterInfo[] parameters) {
+	Console.Write("(");
+	if (parameters.Length > 0) {
+		int i;
+		
+		OutputMercuryVarName(parameters[0]);
+		for (i = 1; i < parameters.Length; i++) {
+			Console.Write(", ");
+				OutputMercuryVarName(parameters[i]);
+		}
+	}
+	Console.Write(")");
+}
 
 
-public static void test(string s1, out string s2, ref string s3) {
+public static void OutputNameModeParameters(ParameterInfo[] parameters) {
+	if (parameters.Length > 0) {
+		int i;
+		Console.Write("(");
+		
+		OutputParameterAsNameMode(parameters[0]);
+		for (i = 1; i < parameters.Length; i++) {
+			Console.Write(", ");
+				OutputParameterAsNameMode(
+				parameters[i]);
+		}
+		Console.Write(")");
+	}
+}
+
+
+public static void OutputTypeModeParameters(ParameterInfo[] parameters) {
+	if (parameters.Length > 0) {
+		int i;
+		Console.Write("(");
+		
+		OutputParameterAsTypeMode(parameters[0]);
+		for (i = 1; i < parameters.Length; i++) {
+			Console.Write(", ");
+			OutputParameterAsTypeMode(parameters[i]);
+		}
+		Console.Write(")");
+	}
+}
+
+	// Output VarName1::mode, VarName2::mode, etc
+	// Byrefs become
+	// V_VarName1::in, VOut_VarName1::out
+public static void OutputParameterAsNameMode(ParameterInfo pinfo) {
+
+	OutputMercuryVarName(pinfo);
+
+	if (pinfo.IsOut) {
+		Console.Write("::out");
+	} else if (pinfo.ParameterType.IsByRef) {
+		Console.Write("::in, ");
+		OutputMercuryVarNameByref(pinfo);
+		Console.Write("::out");
+	} else {
+		Console.Write("::in");
+	}
+}
+
+
+	// Output TypeName1::mode1, TypeName2::mode2, etc
+public static void OutputParameterAsTypeMode(ParameterInfo pinfo) {
+
+	OutputTypeNameAsMercuryType(pinfo.ParameterType);
+
+	if (pinfo.IsOut) {
+		Console.Write("::out");
+	} else if (pinfo.ParameterType.IsByRef) {
+		Console.Write("::in, ");
+		OutputTypeNameAsMercuryType(pinfo.ParameterType);
+		Console.Write("::out");
+	} else {
+		Console.Write("::in");
+	}
+}
+
+public static void OutputByrefAssigments(ParameterInfo[] parameters) {
 
+	foreach (ParameterInfo pinfo in parameters) {
+		if (pinfo.ParameterType.IsByRef && !pinfo.IsOut) {
+			OutputMercuryVarNameByref(pinfo);
+			Console.Write(" = ");
+			OutputMercuryVarName(pinfo);
+			Console.WriteLine(";");
+		}
+	}
+}
+
+public static void OutputTypeNameAsMercuryType(Type t) {
+
+	Type element_type;
+
+		// XXX also need to handle pointers (*)
+	if (t.IsByRef) {
+		element_type = t.GetElementType();	
+		OutputTypeNameAsMercuryType(element_type);
+	} else if (t.IsArray) {
+		element_type = t.GetElementType();
+		Console.Write("array(");
+		OutputTypeNameAsMercuryType(element_type);
+		Console.Write(")");
+	} else {
+		switch (t.FullName) {
+			case "System.String":
+			Console.Write("string");
+			break;
+
+			case "System.Char":
+			Console.Write("char");
+			break;
+
+			case "System.Int":
+			Console.Write("int");
+			break;
+
+			default:
+			Console.Write("'" + t.FullName + "'");
+			break;
+		}
+
+
+
+	}
+}
+
+public static void OutputMercuryVarName(ParameterInfo p) {
+	string newname = "V_" + p.Name;
+	Console.Write(newname);
+}
+
+public static void OutputMercuryVarNameByref(ParameterInfo p) {
+	string newname = "VOut_" + p.Name;
+	Console.Write(newname);
+}
+
+
+
+public static void test(string s1, out string s2, ref string s3) {
 	s3 = "boo";
 	s2 = s1;	
 }


-- 
       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-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