adam@2048: (* Copyright (c) 2008, 2014, Adam Chlipala adamc@14: * All rights reserved. adamc@14: * adamc@14: * Redistribution and use in source and binary forms, with or without adamc@14: * modification, are permitted provided that the following conditions are met: adamc@14: * adamc@14: * - Redistributions of source code must retain the above copyright notice, adamc@14: * this list of conditions and the following disclaimer. adamc@14: * - Redistributions in binary form must reproduce the above copyright notice, adamc@14: * this list of conditions and the following disclaimer in the documentation adamc@14: * and/or other materials provided with the distribution. adamc@14: * - The names of contributors may not be used to endorse or promote products adamc@14: * derived from this software without specific prior written permission. adamc@14: * adamc@14: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" adamc@14: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE adamc@14: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE adamc@14: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE adamc@14: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR adamc@14: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF adamc@14: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS adamc@14: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN adamc@14: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) adamc@14: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE adamc@14: * POSSIBILITY OF SUCH DAMAGE. adamc@14: *) adamc@14: adamc@14: structure Prim :> PRIM = struct adamc@14: adam@2048: datatype string_mode = Normal | Html adam@2048: adamc@14: datatype t = adamc@14: Int of Int64.int adamc@14: | Float of Real64.real adam@2048: | String of string_mode * string adamc@821: | Char of char adamc@14: adamc@14: open Print.PD adamc@14: open Print adamc@14: adamc@14: fun p_t t = adamc@14: case t of adamc@14: Int n => string (Int64.toString n) adamc@14: | Float n => string (Real64.toString n) adam@2048: | String (_, s) => box [string "\"", string (String.toString s), string "\""] adamc@942: | Char ch => box [string "#\"", string (String.toString (String.str ch)), string "\""] adamc@14: adamc@276: fun int2s n = adamc@276: if Int64.compare (n, Int64.fromInt 0) = LESS then adamc@276: "-" ^ Int64.toString (Int64.~ n) ^ "LL" adamc@276: else adamc@276: Int64.toString n ^ "LL" adamc@276: adamc@582: fun int2s' n = adamc@582: if Int64.compare (n, Int64.fromInt 0) = LESS then adamc@582: "-" ^ Int64.toString (Int64.~ n) adamc@582: else adamc@582: Int64.toString n adamc@582: adam@1468: val float2s = String.translate (fn #"~" => "-" | ch => str ch) o Real64.toString adamc@276: adamc@567: fun toString t = adamc@567: case t of adamc@582: Int n => int2s' n adamc@567: | Float n => float2s n adam@2048: | String (_, s) => s adamc@821: | Char ch => str ch adamc@567: adamc@1053: fun pad (n, ch, s) = adamc@1053: if size s >= n then adamc@1053: s adamc@1053: else adamc@1053: str ch ^ pad (n-1, ch, s) adamc@1053: adam@1656: fun quoteDouble ch = adam@1656: case ch of adam@1656: #"'" => str ch adam@1656: | _ => Char.toCString ch adam@1656: adam@1656: fun toCChar ch = adam@1656: case ch of adam@1656: #"\"" => str ch adam@1656: | _ => Char.toCString ch adam@1656: adam@1656: val toCString = String.translate quoteDouble adam@1656: adamc@276: fun p_t_GCC t = adamc@276: case t of adamc@276: Int n => string (int2s n) adamc@276: | Float n => string (float2s n) adam@2048: | String (_, s) => box [string "\"", string (toCString s), string "\""] adam@1656: | Char ch => box [string "'", string (toCChar ch), string "'"] adamc@276: adamc@183: fun equal x = adamc@183: case x of adamc@183: (Int n1, Int n2) => n1 = n2 adamc@183: | (Float n1, Float n2) => Real64.== (n1, n2) adam@2048: | (String (_, s1), String (_, s2)) => s1 = s2 adamc@821: | (Char ch1, Char ch2) => ch1 = ch2 adamc@183: adamc@183: | _ => false adamc@183: adamc@479: fun compare (p1, p2) = adamc@479: case (p1, p2) of adamc@479: (Int n1, Int n2) => Int64.compare (n1, n2) adamc@479: | (Int _, _) => LESS adamc@479: | (_, Int _) => GREATER adamc@479: adamc@479: | (Float n1, Float n2) => Real64.compare (n1, n2) adamc@479: | (Float _, _) => LESS adamc@821: | (_, Float _) => GREATER adamc@479: adam@2048: | (String (_, n1), String (_, n2)) => String.compare (n1, n2) adamc@821: | (String _, _) => LESS adamc@821: | (_, String _) => GREATER adamc@821: adamc@821: | (Char ch1, Char ch2) => Char.compare (ch1, ch2) adamc@479: adamc@14: end