[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