@@ -12,6 +12,7 @@ import Util.System
1212
1313import Numeric
1414import Data.Char
15+import Data.Bits
1516import Data.List (intercalate)
1617import qualified Data.Vector.Unboxed as V
1718import System.Process
@@ -145,8 +146,26 @@ showCStr s = '"' : foldr ((++) . showChar) "\"" s
145146 | ord c < 0x10 = "\"\"\\x0" ++ showHex (ord c) "\"\""
146147 | ord c < 0x20 = "\"\"\\x" ++ showHex (ord c) "\"\""
147148 | ord c < 0x7f = [c] -- 0x7f = \DEL
148− | ord c < 0x100 = "\"\"\\x" ++ showHex (ord c) "\"\""
149− | otherwise = error $ "non-8-bit character in string literal: " ++ show c
149+ | otherwise = showHexes (utf8bytes (ord c))
150+
151+ utf8bytes :: Int -> [Int]
152+ utf8bytes x = let (h : bytes) = split [] x in
153+ headHex h (length bytes) : map toHex bytes
154+ where
155+ split acc 0 = acc
156+ split acc x = let xbits = x .&. 0x3f
157+ xrest = shiftR x 6 in
158+ split (xbits : acc) xrest
159+
160+ headHex h 1 = h + 0xc0
161+ headHex h 2 = h + 0xe0
162+ headHex h 3 = h + 0xf0
163+ headHex h n = error "Can't happen: Invalid UTF8 character"
164+
165+ toHex i = i + 0x80
166+
167+ showHexes = foldr ((++) . showUTF8) ""
168+ showUTF8 c = "\"\"\\x" ++ showHex c "\"\""
150169
151170bcc :: Int -> BC -> String
152171bcc i (ASSIGN l r) = indent i ++ creg l ++ " = " ++ creg r ++ ";\n"
@@ -424,11 +443,6 @@ doOp v (LSLe (ATInt ITBig)) [l, r] = v ++ "idris_bigLe(vm, " ++ creg l ++ ", " +
424443doOp v (LSGt (ATInt ITBig)) [l, r] = v ++ "idris_bigGt(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
425444doOp v (LSGe (ATInt ITBig)) [l, r] = v ++ "idris_bigGe(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
426445
427−doOp v LStrConcat [l,r] = v ++ "idris_concat(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
428−doOp v LStrLt [l,r] = v ++ "idris_strlt(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
429−doOp v LStrEq [l,r] = v ++ "idris_streq(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
430−doOp v LStrLen [x] = v ++ "idris_strlen(vm, " ++ creg x ++ ")"
431−
432446doOp v (LIntFloat ITNative) [x] = v ++ "idris_castIntFloat(" ++ creg x ++ ")"
433447doOp v (LFloatInt ITNative) [x] = v ++ "idris_castFloatInt(" ++ creg x ++ ")"
434448doOp v (LSExt ITNative ITBig) [x] = v ++ "idris_castIntBig(vm, " ++ creg x ++ ")"
@@ -529,11 +543,18 @@ doOp v LFFloor [x] = v ++ flUnOp "floor" (creg x)
529543doOp v LFCeil [x] = v ++ flUnOp "ceil" (creg x)
530544doOp v LFNegate [x] = v ++ "MKFLOAT(vm, -GETFLOAT(" ++ (creg x) ++ "))"
531545
546+-- String functions which don't need to know we're UTF8
547+doOp v LStrConcat [l,r] = v ++ "idris_concat(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
548+doOp v LStrLt [l,r] = v ++ "idris_strlt(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
549+doOp v LStrEq [l,r] = v ++ "idris_streq(vm, " ++ creg l ++ ", " ++ creg r ++ ")"
550+
551+-- String functions which need to know we're UTF8
532552doOp v LStrHead [x] = v ++ "idris_strHead(vm, " ++ creg x ++ ")"
533553doOp v LStrTail [x] = v ++ "idris_strTail(vm, " ++ creg x ++ ")"
534554doOp v LStrCons [x, y] = v ++ "idris_strCons(vm, " ++ creg x ++ "," ++ creg y ++ ")"
535555doOp v LStrIndex [x, y] = v ++ "idris_strIndex(vm, " ++ creg x ++ "," ++ creg y ++ ")"
536556doOp v LStrRev [x] = v ++ "idris_strRev(vm, " ++ creg x ++ ")"
557+doOp v LStrLen [x] = v ++ "idris_strlen(vm, " ++ creg x ++ ")"
537558
538559doOp v LAllocate [x] = v ++ "idris_buffer_allocate(vm, " ++ creg x ++ ")"
539560doOp v LAppendBuffer [a, b, c, d, e, f] = v ++ "idris_appendBuffer(vm, " ++ creg a ++ "," ++ creg b ++ "," ++ creg c ++ "," ++ creg d ++ "," ++ creg e ++ "," ++ creg f ++ ")"