[m-rev.] diff: implement some formatting functions for .NET

Tyson Dowd trd at miscrit.be
Tue Aug 28 19:35:09 AEST 2001


Hi,

My aim was to get error/1 exceptions to print correctly, but I also
tried to get some of tests/general/string_format_test.m to work.

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


Estimated hours taken: 5
Branches: main

library/string.m:
	Implement string__append_list and various formatting functions
	in C#.
	Implement a very simple (and incomplete) conversion of printf style
	formatting to .NET formatting.  It is probably a better idea to
	implement printf formatting in Mercury in future, as neither
	.NET nor Java provides printf.

runtime/mercury_mcpp.cpp:
	Add some code to manipulate Mercury lists in the low-level data
	representation.


Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.154
diff -u -r1.154 string.m
--- library/string.m	2001/08/14 10:18:50	1.154
+++ library/string.m	2001/08/27 15:30:10
@@ -1020,11 +1020,18 @@
 }").
 
 :- pragma foreign_proc("C#",
-		string__append_list(_Strs::in) = (_Str::uo),
-		[will_not_call_mercury, thread_safe], "{
-	mercury.runtime.Errors.SORRY(""foreign code for this function"");
-	_Str = null;
-}").
+		string__append_list(Strs::in) = (Str::uo),
+		[will_not_call_mercury, thread_safe], "
+{
+        System.Text.StringBuilder tmp = new System.Text.StringBuilder();
+
+        while (mercury.runtime.LowLevelData.list_is_cons(Strs)) {
+		tmp.Append(mercury.runtime.LowLevelData.list_get_head(Strs));
+                Strs = mercury.runtime.LowLevelData.list_get_tail(Strs);
+        }
+        Str = tmp.ToString();
+}
+").
 
 :- pragma foreign_proc("C#",
 		string__join_list(_Sep::in, _Strs::in) = (_Str::uo),
@@ -1428,11 +1435,38 @@
 	).
 specifier_to_string(string(Chars)) = from_char_list(Chars).
 
-	% Construct a format string suitable to passing to sprintf.
+
+	% Construct a format string.
 :- func make_format(list(char), maybe(list(char)),
 		maybe(list(char)), string, string) = string.
 
-make_format(Flags, MaybeWidth, MaybePrec, LengthMod, Spec) = String :-
+make_format(Flags, MaybeWidth, MaybePrec, LengthMod, Spec) = 
+	( using_sprintf ->
+		make_format_sprintf(Flags, MaybeWidth, MaybePrec, LengthMod,
+			Spec)
+	;
+		make_format_dotnet(Flags, MaybeWidth, MaybePrec, LengthMod,
+			Spec)
+	).
+
+
+:- pred using_sprintf is semidet.
+
+:- pragma foreign_proc("C", using_sprintf,
+	[will_not_call_mercury, thread_safe], "
+	SUCCESS_INDICATOR = TRUE;
+").
+:- pragma foreign_proc("MC++", using_sprintf,
+	[will_not_call_mercury, thread_safe], "
+	SUCCESS_INDICATOR = FALSE;
+").
+		
+
+	% Construct a format string suitable to passing to sprintf.
+:- func make_format_sprintf(list(char), maybe(list(char)),
+		maybe(list(char)), string, string) = string.
+
+make_format_sprintf(Flags, MaybeWidth, MaybePrec, LengthMod, Spec) = String :-
 	(
 		MaybeWidth = yes(Width)
 	;
@@ -1450,6 +1484,43 @@
 				from_char_list(Width),
 				from_char_list(Prec), LengthMod, Spec]).
 
+
+	% Construct a format string suitable to passing to .NET's formatting
+	% functions.
+	% XXX this code is not yet complete.  We need to do a lot more work
+	% to make this work perfectly.
+:- func make_format_dotnet(list(char), maybe(list(char)),
+		maybe(list(char)), string, string) = string.
+
+make_format_dotnet(_Flags, MaybeWidth, MaybePrec, _LengthMod, Spec0) = String :-
+	(
+		MaybeWidth = yes(Width0),
+		Width = [',' | Width0]
+	;
+		MaybeWidth = no,
+		Width = []
+	),
+	(
+		MaybePrec = yes(Prec)
+	;
+		MaybePrec = no,
+		Prec = []
+	),
+	( 	Spec0 = "i" -> Spec = "d"
+	;	Spec0 = "f" -> Spec = "e"
+	;	Spec = Spec0
+	),
+	String = string__append_list([
+		"{0", 
+		from_char_list(Width),
+		":",
+		Spec,
+		from_char_list(Prec),
+%		LengthMod,
+%		from_char_list(Flags),
+		"}"]).
+
+
 :- func int_length_modifer = string.
 :- pragma foreign_proc("C", 
 	int_length_modifer = (LengthModifier::out),
@@ -1459,10 +1530,9 @@
 }").
 
 :- pragma foreign_proc("C#", 
-	int_length_modifer = (_LengthModifier::out),
+	int_length_modifer = (LengthModifier::out),
 		[will_not_call_mercury, thread_safe], "{
-	mercury.runtime.Errors.SORRY(""foreign code for this function"");
-	_LengthModifier = null;
+	LengthModifier = """";
 }").
 
 
@@ -1478,10 +1548,9 @@
 	MR_restore_transient_hp();
 }").
 :- pragma foreign_proc("C#",
-	format_float(_FormatStr::in, _Val::in) = (_Str::out),
+	format_float(FormatStr::in, Val::in) = (Str::out),
 		[will_not_call_mercury, thread_safe], "{
-	mercury.runtime.Errors.SORRY(""foreign code for this function"");
-	_Str = null;
+	Str = System.String.Format(FormatStr, Val);
 }").
 
 	% Create a string from a int using the format string.
@@ -1496,10 +1565,9 @@
 	MR_restore_transient_hp();
 }").
 :- pragma foreign_proc("C#",
-	format_int(_FormatStr::in, _Val::in) = (_Str::out),
+	format_int(FormatStr::in, Val::in) = (Str::out),
 		[will_not_call_mercury, thread_safe], "{
-	mercury.runtime.Errors.SORRY(""foreign code for this function"");
-	_Str = null;
+	Str = System.String.Format(FormatStr, Val);
 }").
 
 	% Create a string from a string using the format string.
@@ -1512,10 +1580,9 @@
 	Str = MR_make_string(MR_PROC_LABEL, FormatStr, Val);
 }").
 :- pragma foreign_proc("C#", 
-	format_string(_FormatStr::in, _Val::in) = (_Str::out),
+	format_string(FormatStr::in, Val::in) = (Str::out),
 		[will_not_call_mercury, thread_safe], "{
-	mercury.runtime.Errors.SORRY(""foreign code for this function"");
-	_Str = null;
+	Str = System.String.Format(FormatStr, Val);
 }").
 
 	% Create a string from a char using the format string.
@@ -1530,10 +1597,9 @@
 	MR_restore_transient_hp();
 }").
 :- pragma foreign_proc("C#", 
-	format_char(_FormatStr::in, _Val::in) = (_Str::out),
+	format_char(FormatStr::in, Val::in) = (Str::out),
 		[will_not_call_mercury, thread_safe], "{
-	mercury.runtime.Errors.SORRY(""foreign code for this function"");
-	_Str = null;
+	Str = System.String.Format(FormatStr, Val);
 }").
 
 
Index: runtime/mercury_mcpp.cpp
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_mcpp.cpp,v
retrieving revision 1.9
diff -u -r1.9 mercury_mcpp.cpp
--- runtime/mercury_mcpp.cpp	2001/08/27 12:15:36	1.9
+++ runtime/mercury_mcpp.cpp	2001/08/27 15:30:10
@@ -80,6 +80,18 @@
 	return w[index];
 }
 
+static bool list_is_cons(MR_Word w) {
+	return (System::Convert::ToInt32(w[0]) != 0);
+}
+
+static MR_Box list_get_head(MR_Word w) {
+	return w[1];
+}
+
+static MR_Word list_get_tail(MR_Word w) {
+	return dynamic_cast<MR_Word>(w[2]);
+}
+
 };
 
 __gc public class Errors {

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