@@ -10,6 +10,7 @@ import Idris.Core.TT
1010import Paths_idris
1111import Util.System
1212
13+import Numeric
1314import Data.Char
1415import Data.List (intercalate)
1516import System.Process
@@ -104,6 +105,22 @@ toC f code
104105 indent 1 ++ "INITFRAME;\n" ++
105106 concatMap (bcc 1) code ++ "}\n\n"
106107
108+showCStr :: String -> String
109+showCStr s = '"' : foldr ((++) . showChar) "\"" s
110+ where
111+ showChar :: Char -> String
112+ showChar '"' = "\\\""
113+ showChar '\\' = "\\\\"
114+ showChar c
115+ -- Note: we need the double quotes around the codes because otherwise
116+ -- "\n3" would get encoded as "\x0a3", which is incorrect.
117+ -- Instead, we opt for "\x0a""3" and let the C compiler deal with it.
118+ | ord c < 0x10 = "\"\"\\x0" ++ showHex (ord c) "\"\""
119+ | ord c < 0x20 = "\"\"\\x" ++ showHex (ord c) "\"\""
120+ | ord c < 0x7f = [c] -- 0x7f = \DEL
121+ | ord c < 0x100 = "\"\"\\x" ++ showHex (ord c) "\"\""
122+ | otherwise = error $ "non-8-bit character in string literal: " ++ show c
123+
107124bcc :: Int -> BC -> String
108125bcc i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
109126bcc i (ASSIGNCONST l c)
@@ -114,7 +131,7 @@ bcc i (ASSIGNCONST l c)
114131 | otherwise = "MKBIGC(vm,\"" ++ show i ++ "\")"
115132 mkConst (Fl f) = "MKFLOAT(vm, " ++ show f ++ ")"
116133 mkConst (Ch c) = "MKINT(" ++ show (fromEnum c) ++ ")"
117− mkConst (Str s) = "MKSTR(vm, " ++ show s ++ ")"
134+ mkConst (Str s) = "MKSTR(vm, " ++ showCStr s ++ ")"
118135 mkConst (B8 x) = "idris_b8const(vm, " ++ show x ++ ")"
119136 mkConst (B16 x) = "idris_b16const(vm, " ++ show x ++ ")"
120137 mkConst (B32 x) = "idris_b32const(vm, " ++ show x ++ ")"