// /*-------------------------------------------------------------------*\ // | Concrete Instance Body : Conversion_Operations // \*-------------------------------------------------------------------*/ ///------------------------------------------------------------------------ /// Global Context -------------------------------------------------------- ///------------------------------------------------------------------------ #include "RAW_Foundation.h" ///------------------------------------------------------------------------ /// Error Table ///------------------------------------------------------------------------ object char* error_table[] = { // 0 "=================================================================\n" " ::= {\"true\"|\"false\"} \n" " ::= {' ', '\\t', '\\n'}*\n" "-----------------------------------------------------------------\n" "t is in language of OK_Text\n" "=================================================================", // 1 "0 <= i <= 255", // 2 "t /= empty_string", // 3 "-2147483649.0 < r < 2147483648.0", // 4 "=================================================================\n" " ::= ['+'|'-'] \n" " ::= {' ', '\\t', '\\n'}*\n" " ::= {'0','1','2','3','4','5','6','7','8','9'}+\n" "-----------------------------------------------------------------\n" "t is in language of OK_Text and\n" "-2147483648 <= TO_INTEGER(t) <= 2147483647\n" "=================================================================", // 5 "=================================================================\n" " ::= \n" " ::= {' ', '\\t', '\\n'}*\n" " ::= ['+'|'-'] ['.' ]\n" " [{'e'|'E'} ['+'|'-'] ]\n" " ::= {'0','1','2','3','4','5','6','7','8','9'}+\n" "-----------------------------------------------------------------\n" "t is in language of OK_Text and\n" "-1.7976931348623157e+308 <= TO_REAL(t) <= 1.7976931348623157e+308\n" "=================================================================" }; ///------------------------------------------------------------------------ /// Local Operations ------------------------------------------------------ ///------------------------------------------------------------------------ procedure_body Remove_Leading_White_Space ( alters Text& t ) { object Boolean done; object Character c; while (not done) { if (t.Length () == 0) { done = true; } else if (not Is_Space (t[0])) { done = true; } else { t.Remove (0, c); } } } //------------------------------------------------------------------------- procedure_body Remove_Trailing_White_Space ( alters Text& t ) { object Boolean done; object Character c; while (not done) { if (t.Length () == 0) { done = true; } else if (not Is_Space (t[t.Length () - 1])) { done = true; } else { t.Remove (t.Length () - 1, c); } } } //------------------------------------------------------------------------- procedure_body Skip_Digits ( preserves Text& t, alters Integer& i ) { object Integer length = t.Length (); while (i < length) { if (Is_Digit (t[i])) { i++; } else { return; } } } ///------------------------------------------------------------------------ /// Public Operations ----------------------------------------------------- ///------------------------------------------------------------------------ function_body Boolean Can_Convert_To_Character ( preserves Integer x ) { return ((To_Integer (Minimum_Character ()) <= x) and (x <= To_Integer (Maximum_Character ()))); } //------------------------------------------------------------------------- function_body Boolean Can_Convert_To_Integer ( preserves Real x ) { return ((To_Real (Minimum_Integer ()) <= x) and (x <= To_Real (Maximum_Integer ()))); } //------------------------------------------------------------------------- function_body Boolean Can_Convert_To_Boolean ( preserves Text x ) { object Text temp = x; Remove_Leading_White_Space (temp); Remove_Trailing_White_Space (temp); return ((temp == "true") or (temp == "false")); } //------------------------------------------------------------------------- function_body Boolean Can_Convert_To_Character ( preserves Text x ) { return (x.Length () > 0); } //------------------------------------------------------------------------- function_body Boolean Can_Convert_To_Integer ( preserves Text x ) { object Text temp = x; object Integer zero_base, digit, result; object Character c; // Prepare for careful check Remove_Leading_White_Space (temp); Remove_Trailing_White_Space (temp); // Special cases if (temp.Length () == 0) { return false; } if (temp == "-2147483648") { return true; } // Remove leading sign, if any; then check for empty string if ((temp[0] == '-') or (temp[0] == '+')) { temp.Remove (0, c); } if (temp.Length () == 0) { return false; } // Do conversion, as far as possible, checking for overflow at // each digit zero_base = To_Integer ('0'); while (temp.Length () > 0) { // Check for digit if (not Is_Digit (temp[0])) { return false; } // Check for overflow temp.Remove (0, c); digit = To_Integer (c) - zero_base; if (result > ((Maximum_Integer () - digit) / 10)) { return false; } // Update conversion result to check for next digit result = 10 * result + digit; } // Made it through all checks return true; } //------------------------------------------------------------------------- function_body Boolean Can_Convert_To_Real ( preserves Text x ) { object Text temp = x; object Integer i, length; object double f; // Prepare for careful check Remove_Leading_White_Space (temp); Remove_Trailing_White_Space (temp); length = temp.Length (); // Skip over optional sign if (i >= length) { return false; } if ((temp[i] == '-') or (temp[i] == '+')) { i++; } // Skip over digits before optional fraction and exponent if (i >= length) { return false; } if (not Is_Digit (temp[i])) { return false; } Skip_Digits (temp, i); // Skip over optional fraction if (i < length) { if (temp[i] == '.') { i++; // Skip over digits after '.' if (i >= length) { return false; } if (not Is_Digit (temp[i])) { return false; } Skip_Digits (temp, i); } } // Skip over optional exponent if (i < length) { if ((temp[i] == 'e') or (temp[i] == 'E')) { i++; // Skip over optional sign after 'e'/'E' if (i >= length) { return false; } if ((temp[i] == '-') or (temp[i] == '+')) { i++; } // Skip over digits after 'e'/'E' if (i >= length) { return false; } if (not Is_Digit (temp[i])) { return false; } Skip_Digits (temp, i); } } // Make sure there is nothing else left if (i < length) { return false; } // Format is OK, so make sure number is within range return (sscanf (x.Contents (), "%lf", &f) == 1); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- function_body char To_char ( preserves Character x ) { return x.c; } //------------------------------------------------------------------------- function_body char To_char ( preserves Text x ) { return ((To_Character (x)).c); } //------------------------------------------------------------------------- function_body int To_int ( preserves Character x ) { return ((int) x.c); } //------------------------------------------------------------------------- function_body int To_int ( preserves Integer x ) { return x.i; } //------------------------------------------------------------------------- function_body int To_int ( preserves Text x ) { return (To_Integer (x)).i; } //------------------------------------------------------------------------- function_body double To_double ( preserves Real x ) { return x.f; } //------------------------------------------------------------------------- function_body double To_double ( preserves Text x ) { return ((To_Real (x)).f); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- function_body Character To_Character ( preserves int x ) { return (To_Character (Integer (x))); } //------------------------------------------------------------------------- function_body Integer To_Integer ( preserves char x ) { return (Integer ((int) (unsigned char) x)); } //------------------------------------------------------------------------- function_body Integer To_Integer ( preserves double x ) { return (To_Integer (Real (x))); } //------------------------------------------------------------------------- function_body Real To_Real ( preserves int x ) { return (Real ((double) x)); } //------------------------------------------------------------------------- function_body Text To_Text ( preserves char x ) { return (To_Text (Character (x))); } //------------------------------------------------------------------------- function_body Text To_Text ( preserves int x ) { return (To_Text (Integer (x))); } //------------------------------------------------------------------------- function_body Text To_Text ( preserves double x, preserves int precision, preserves int science_format ) { return (To_Text (Real (x), precision, science_format)); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- function_body Boolean To_Boolean ( preserves Text x ) { checking_assert (Can_Convert_To_Boolean (x), error_table[0]); object Text temp = x; Remove_Leading_White_Space (temp); Remove_Trailing_White_Space (temp); return (temp == "true"); // because it must contain "false" otherwise } //------------------------------------------------------------------------- function_body Character To_Character ( preserves Integer x ) { checking_assert (Can_Convert_To_Character (x), error_table[1]); return Character ((char) x.i); } //------------------------------------------------------------------------- function_body Character To_Character ( preserves Text x ) { checking_assert (Can_Convert_To_Character (x), error_table[2]); return x[0]; } //------------------------------------------------------------------------- function_body Integer To_Integer ( preserves Character x ) { return Integer ((int) (unsigned char) x.c); } //------------------------------------------------------------------------- function_body Integer To_Integer ( preserves Real x ) { checking_assert (Can_Convert_To_Integer (x), error_table[3]); return Integer ((int) x.f); } //------------------------------------------------------------------------- function_body Integer To_Integer ( preserves Text x ) { checking_assert (Can_Convert_To_Integer (x), error_table[4]); object int result; sscanf (x.Contents (), "%d", &result); return (Integer (result)); } //------------------------------------------------------------------------- function_body Real To_Real ( preserves Integer x ) { return Real ((double) x.i); } //------------------------------------------------------------------------- function_body Real To_Real ( preserves Text x ) { checking_assert (Can_Convert_To_Real (x), error_table[5]); object double result; sscanf (x.Contents (), "%lf", &result); return (Real (result)); } //------------------------------------------------------------------------- function_body Text To_Text ( preserves Boolean x ) { if (x) { return Text ("true"); } else { return Text ("false"); } } //------------------------------------------------------------------------- function_body Text To_Text ( preserves Character x ) { object Text result; result.Add (0, x); return result; } //------------------------------------------------------------------------- function_body Text To_Text ( preserves Integer x ) { object char buf[100]; sprintf (buf, "%d", x.i); return Text (buf); } //------------------------------------------------------------------------- function_body Text To_Text ( preserves Real x, preserves Integer precision, preserves Boolean science_format ) { static object char format[50]; static object char result[100]; sprintf (format, "%%.%d", To_int (precision)); if (science_format) { strcat (format, "E"); } else { strcat (format, "lf"); } sprintf (result, format, x.f); return Text (result); } //-------------------------------------------------------------------------