#include /* * Support code for the Data.JSString module. This code presents a JSString * as a sequence of code points and hides the underlying encoding ugliness of * the JavaScript strings. * * Use Data.JSString.Raw for direct access to the JSThis makes the operations more expen */ /* * Some workarounds here for JS engines that do not support proper * code point access */ #ifdef GHCJS_TRACE_JSSTRING #define TRACE_JSSTRING(args...) h$log("jsstring: ", args); #else #define TRACE_JSSTRING(args...) #endif #define IS_ASTRAL(cp) ((cp)>=0x10000) #define IS_HI_SURR(cp) ((cp|1023)===0xDBFF) #define IS_LO_SURR(cp) ((cp|1023)===0xDFFF) #define FROM_SURR(hi,lo) ((((hi)-0xD800)<<10)+(lo)-0xDC00+0x10000) #define HI_SURR(cp) ((((cp)-0x10000)>>>10)+0xDC00) #define LO_SURR(cp) (((cp)&0x3FF)+0xD800) var h$jsstringEmpty = MK_JSVAL(''); var h$jsstringHead, h$jsstringTail, h$jsstringCons, h$jsstringSingleton, h$jsstringSnoc, h$jsstringUncons, h$jsstringIndex, h$jsstringUncheckedIndex; var h$fromCodePoint; if(String.prototype.fromCodePoint) { h$fromCodePoint = String.fromCodePoint; } else { // polyfill from https://github.com/mathiasbynens/String.fromCodePoint (MIT-license) h$fromCodePoint = (function() { var stringFromCharCode = String.fromCharCode; var floor = Math.floor; return function(_) { var MAX_SIZE = 0x4000; var codeUnits = []; var highSurrogate; var lowSurrogate; var index = -1; var length = arguments.length; if (!length) { return ''; } var result = ''; while (++index < length) { var codePoint = Number(arguments[index]); if ( !isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity` codePoint < 0 || // not a valid Unicode code point codePoint > 0x10FFFF || // not a valid Unicode code point floor(codePoint) != codePoint // not an integer ) { throw RangeError('Invalid code point: ' + codePoint); } if (codePoint <= 0xFFFF) { // BMP code point codeUnits.push(codePoint); } else { // Astral code point; split in surrogate halves // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae codePoint -= 0x10000; highSurrogate = (codePoint >> 10) + 0xD800; lowSurrogate = (codePoint % 0x400) + 0xDC00; codeUnits.push(highSurrogate, lowSurrogate); } if (index + 1 == length || codeUnits.length > MAX_SIZE) { result += stringFromCharCode.apply(null, codeUnits); codeUnits.length = 0; } } return result; } })(); } if(String.prototype.codePointAt) { h$jsstringSingleton = function(ch) { TRACE_JSSTRING("(codePointAt) singleton: " + ch); return String.fromCodePoint(ch); } h$jsstringHead = function(str) { TRACE_JSSTRING("(codePointAt) head: " + str); var cp = str.codePointAt(0); return (cp === undefined) ? -1 : (cp|0); } h$jsstringTail = function(str) { TRACE_JSSTRING("(codePointAt) tail: " + str); var l = str.length; if(l===0) return null; var ch = str.codePointAt(0); if(ch === undefined) return null; // string length is at least two if ch comes from a surrogate pair return str.substr(IS_ASTRAL(ch)?2:1); } h$jsstringCons = function(ch, str) { TRACE_JSSTRING("(codePointAt) cons: " + ch + " '" + str + "'"); return String.fromCodePoint(ch)+str; } h$jsstringSnoc = function(str, ch) { TRACE_JSSTRING("(codePointAt) snoc: '" + str + "' " + ch); return str+String.fromCodePoint(ch); } h$jsstringUncons = function(str) { TRACE_JSSTRING("(codePointAt) uncons: '" + str + "'"); var l = str.length; if(l===0) { RETURN_UBX_TUP2(-1, null); } var ch = str.codePointAt(0); if(ch === undefined) { RETURN_UBX_TUP2(-1, null); } RETURN_UBX_TUP2(ch, str.substr(IS_ASTRAL(ch)?2:1)); } // index is the first part of the character h$jsstringIndex = function(i, str) { TRACE_JSSTRING("(codePointAt) index: " + i + " '" + str + "'"); var ch = str.codePointAt(i); if(ch === undefined) return -1; return ch; } h$jsstringUncheckedIndex = function(i, str) { TRACE_JSSTRING("(codePointAt) uncheckedIndex: " + i + " '" + str.length + "'"); return str.codePointAt(i); } } else { h$jsstringSingleton = function(ch) { TRACE_JSSTRING("(no codePointAt) singleton: " + ch); return (IS_ASTRAL(ch)) ? String.fromCharCode(HI_SURR(ch), LO_SURR(ch)) : String.fromCharCode(ch); } h$jsstringHead = function(str) { TRACE_JSSTRING("(no codePointAt) head: " + str); var l = str.length; if(l===0) return -1; var ch = str.charCodeAt(0); if(IS_HI_SURR(ch)) { return (l>1) ? FROM_SURR(ch, str.charCodeAt(1)) : -1; } else { return ch; } } h$jsstringTail = function(str) { TRACE_JSSTRING("(no codePointAt) tail: " + str); var l = str.length; if(l===0) return null; var ch = str.charCodeAt(0); if(IS_HI_SURR(ch)) { return (l>1)?str.substr(2):null; } else return str.substr(1); } h$jsstringCons = function(ch, str) { TRACE_JSSTRING("(no codePointAt) cons: " + ch + " '" + str + "'"); return ((IS_ASTRAL(ch)) ? String.fromCharCode(HI_SURR(ch), LO_SURR(ch)) : String.fromCharCode(ch)) + str; } h$jsstringSnoc = function(str, ch) { TRACE_JSSTRING("(no codePointAt) snoc: '" + str + "' " + ch); return str + ((IS_ASTRAL(ch)) ? String.fromCharCode(HI_SURR(ch), LO_SURR(ch)) : String.fromCharCode(ch)); } h$jsstringUncons = function(str) { TRACE_JSSTRING("(no codePointAt) uncons: '" + str + "'"); var l = str.length; if(l===0) { RETURN_UBX_TUP2(-1, null); } var ch = str.charCodeAt(0); if(IS_HI_SURR(ch)) { if(l > 1) { RETURN_UBX_TUP2(FROM_SURR(ch, str.charCodeAt(1)), str.substr(2)); } else { RETURN_UBX_TUP2(-1, null); } } else { RETURN_UBX_TUP2(ch, str.substr(1)); } } // index is the first part of the character h$jsstringIndex = function(i, str) { // TRACE_JSSTRING("(no codePointAt) index: " + i + " '" + str + "'"); var ch = str.charCodeAt(i); if(ch != ch) return -1; // NaN test return (IS_HI_SURR(ch)) ? FROM_SURR(ch, str.charCodeAt(i+1)) : ch; } h$jsstringUncheckedIndex = function(i, str) { TRACE_JSSTRING("(no codePointAt) uncheckedIndex: " + i + " '" + str.length + "'"); var ch = str.charCodeAt(i); return (IS_HI_SURR(ch)) ? FROM_SURR(ch, str.charCodeAt(i+1)) : ch; } } function h$jsstringUnsnoc(str) { TRACE_JSSTRING("unsnoc: '" + str + "'"); var l = str.length; if(l===0) { RETURN_UBX_TUP2(-1, null); } var ch = str.charCodeAt(l-1); if(IS_LO_SURR(ch)) { if(l !== 1) { RETURN_UBX_TUP2(FROM_SURR(str.charCodeAt(l-2),ch), str.substr(0,l-2)); } else { RETURN_UBX_TUP2(-1, null); } } else { RETURN_UBX_TUP2(ch, str.substr(0,l-1)); } } function h$jsstringPack(xs) { var r = '', i = 0, a = [], c; while(IS_CONS(xs)) { c = CONS_HEAD(xs); a[i++] = UNWRAP_NUMBER(c); if(i >= 60000) { r += h$fromCodePoint.apply(null, a); a = []; i = 0; } xs = CONS_TAIL(xs); } if(i > 0) r += h$fromCodePoint.apply(null, a); TRACE_JSSTRING("pack: '" + r + "'"); return r; } function h$jsstringPackReverse(xs) { var a = [], i = 0, c; while(IS_CONS(xs)) { c = CONS_HEAD(xs); a[i++] = UNWRAP_NUMBER(c); xs = CONS_TAIL(xs); } if(i===0) return ''; var r = h$jsstringConvertArray(a.reverse()); TRACE_JSSTRING("packReverse: '" + r + "'"); return r; } function h$jsstringPackArray(arr) { TRACE_JSSTRING("pack array: " + arr); return h$jsstringConvertArray(arr); } function h$jsstringPackArrayReverse(arr) { TRACE_JSSTRING("pack array reverse: " + arr); return h$jsstringConvertArray(arr.reverse()); } function h$jsstringConvertArray(arr) { if(arr.length < 60000) { return h$fromCodePoint.apply(null, arr); } else { var r = ''; for(var i=0; i1) ? FROM_SURR(str.charCodeAt(l-2), ch) : -1; } else return ch; } // index is the last part of the character function h$jsstringIndexR(i, str) { TRACE_JSSTRING("indexR: " + i + " '" + str + "'"); if(i < 0 || i > str.length) return -1; var ch = str.charCodeAt(i); return (IS_LO_SURR(ch)) ? FROM_SURR(str.charCodeAt(i-1), ch) : ch; } function h$jsstringNextIndex(i, str) { TRACE_JSSTRING("nextIndex: " + i + " '" + str + "'"); return i + (IS_HI_SURR(str.charCodeAt(i))?2:1); } function h$jsstringTake(n, str) { TRACE_JSSTRING("take: " + n + " '" + str + "'"); if(n <= 0) return ''; var i = 0, l = str.length, ch; if(n >= l) return str; while(n--) { ch = str.charCodeAt(i++); if(IS_HI_SURR(ch)) i++; if(i >= l) return str; } return str.substr(0,i); } function h$jsstringDrop(n, str) { TRACE_JSSTRING("drop: " + n + " '" + str + "'"); if(n <= 0) return str; var i = 0, l = str.length, ch; if(n >= l) return ''; while(n--) { ch = str.charCodeAt(i++); if(IS_HI_SURR(ch)) i++; if(i >= l) return ''; } return str.substr(i); } function h$jsstringSplitAt(n, str) { TRACE_JSSTRING("splitAt: " + n + " '" + str + "'"); if(n <= 0) { RETURN_UBX_TUP2("", str); } else if(n >= str.length) { RETURN_UBX_TUP2(str, ""); } var i = 0, l = str.length, ch; while(n--) { ch = str.charCodeAt(i++); if(IS_HI_SURR(ch)) i++; if(i >= l) { RETURN_UBX_TUP2(str, ""); } } RETURN_UBX_TUP2(str.substr(0,i),str.substr(i)); } function h$jsstringTakeEnd(n, str) { TRACE_JSSTRING("takeEnd: " + n + " '" + str + "'"); if(n <= 0) return ''; var l = str.length, i = l-1, ch; if(n >= l) return str; while(n-- && i > 0) { ch = str.charCodeAt(i--); if(IS_LO_SURR(ch)) i--; } return (i<0) ? str : str.substr(i+1); } function h$jsstringDropEnd(n, str) { TRACE_JSSTRING("dropEnd: " + n + " '" + str + "'"); if(n <= 0) return str; var l = str.length, i = l-1, ch; if(n >= l) return ''; while(n-- && i > 0) { ch = str.charCodeAt(i--); if(IS_LO_SURR(ch)) i--; } return (i<0) ? '' : str.substr(0,i+1); } function h$jsstringIntercalate(x, ys) { TRACE_JSSTRING("intercalate: '" + x + "'"); var a = [], i = 0; while(IS_CONS(ys)) { if(i) a[i++] = x; a[i++] = JSVAL_VAL(CONS_HEAD(ys)); ys = CONS_TAIL(ys); } return a.join(''); } function h$jsstringIntersperse(ch, ys) { TRACE_JSSTRING("intersperse: " + ch + " '" + ys + "'"); var i = 0, l = ys.length, j = 0, a = [], ych; if(IS_ASTRAL(ch)) { while(j < l) { if(i) a[i++] = ch; ych = ys.charCodeAt(j++); a[i++] = ych; if(IS_HI_SURR(ych)) a[i++] = ys.charCodeAt(j++); } } else { while(j < l) { if(i) a[i++] = ch; ych = ys.charCodeAt(j++); a[i++] = ych; if(IS_HI_SURR(ych)) a[i++] = ys.charCodeAt(j++); } } return h$jsstringConvertArray(a); } function h$jsstringConcat(xs) { TRACE_JSSTRING("concat"); var a = [], i = 0; while(IS_CONS(xs)) { a[i++] = JSVAL_VAL(CONS_HEAD(xs)); xs = CONS_TAIL(xs); } return a.join(''); } var h$jsstringStripPrefix, h$jsstringStripSuffix, h$jsstringIsPrefixOf, h$jsstringIsSuffixOf, h$jsstringIsInfixOf; if(String.prototype.startsWith) { h$jsstringStripPrefix = function(p, x) { TRACE_JSSTRING("(startsWith) stripPrefix: '" + p + "' '" + x + "'"); if(x.startsWith(p)) { return MK_JUST(MK_JSVAL(x.substr(p.length))); } else { return HS_NOTHING; } } h$jsstringIsPrefixOf = function(p, x) { TRACE_JSSTRING("(startsWith) isPrefixOf: '" + p + "' '" + x + "'"); return x.startsWith(p); } } else { h$jsstringStripPrefix = function(p, x) { TRACE_JSSTRING("(no startsWith) stripPrefix: '" + p + "' '" + x + "'"); if(x.indexOf(p) === 0) { // this has worse complexity than it should return MK_JUST(MK_JSVAL(x.substr(p.length))); } else { return HS_NOTHING; } } h$jsstringIsPrefixOf = function(p, x) { TRACE_JSSTRING("(no startsWith) isPrefixOf: '" + p + "' '" + x + "'"); return x.indexOf(p) === 0; // this has worse complexity than it should } } if(String.prototype.endsWith) { h$jsstringStripSuffix = function(s, x) { TRACE_JSSTRING("(endsWith) stripSuffix: '" + s + "' '" + x + "'"); if(x.endsWith(s)) { return MK_JUST(MK_JSVAL(x.substr(0,x.length-s.length))); } else { return HS_NOTHING; } } h$jsstringIsSuffixOf = function(s, x) { TRACE_JSSTRING("(endsWith) isSuffixOf: '" + s + "' '" + x + "'"); return x.endsWith(s); } } else { h$jsstringStripSuffix = function(s, x) { TRACE_JSSTRING("(no endsWith) stripSuffix: '" + s + "' '" + x + "'"); var i = x.lastIndexOf(s); // this has worse complexity than it should var l = x.length - s.length; if(i !== -1 && i === l) { return MK_JUST(MK_JSVAL(x.substr(0,l))); } else { return HS_NOTHING; } } h$jsstringIsSuffixOf = function(s, x) { TRACE_JSSTRING("(no endsWith) isSuffixOf: '" + s + "' '" + x + "'"); var i = x.lastIndexOf(s); // this has worse complexity than it should return i !== -1 && i === x.length - s.length; } } if(String.prototype.includes) { h$jsstringIsInfixOf = function(i, x) { TRACE_JSSTRING("(includes) isInfixOf: '" + i + "' '" + x + "'"); return x.includes(i); } } else { h$jsstringIsInfixOf = function(i, x) { TRACE_JSSTRING("(no includes) isInfixOf: '" + i + "' '" + x + "'"); return x.indexOf(i) !== -1; // this has worse complexity than it should } } function h$jsstringCommonPrefixes(x, y) { TRACE_JSSTRING("commonPrefixes: '" + x + "' '" + y + "'"); var lx = x.length, ly = y.length, i = 0, cx; var l = lx <= ly ? lx : ly; if(lx === 0 || ly === 0 || x.charCodeAt(0) !== y.charCodeAt(0)) { return HS_NOTHING; } while(++i= 0) r = MK_CONS(a[i], r); return r; } function h$jsstringSplitOn1(n, p, x) { TRACE_JSSTRING("splitOn1: " + n + " '" + p + "' '" + x + "'"); var i = x.indexOf(p, n); if(i === -1) { RETURN_UBX_TUP2(-1, null); } var r1 = (i==n) ? "" : x.substr(n, i-n); RETURN_UBX_TUP2(i + p.length, r1); } function h$jsstringSplitOn(p, x) { TRACE_JSSTRING("splitOn: '" + p + "' '" + x + "'"); var a = x.split(p); var r = HS_NIL, i = a.length; while(--i>=0) r = MK_CONS(MK_JSVAL(a[i]), r); return r; } // returns -1 for end of input, start of next token otherwise // word in h$ret1 // this function assumes that there are no whitespace characters >= 0x10000 function h$jsstringWords1(n, x) { TRACE_JSSTRING("words1: " + n + " '" + x + "'"); var m = n, s = n, l = x.length; if(m >= l) return -1; // skip leading spaces do { if(m >= l) return -1; } while(h$isSpace(x.charCodeAt(m++))); // found start of word s = m - 1; while(m < l) { if(h$isSpace(x.charCodeAt(m++))) { // found end of word var r1 = (m-s<=1) ? "" : x.substr(s,m-s-1); RETURN_UBX_TUP2(m, r1); } } // end of string if(s < l) { var r1 = s === 0 ? x : x.substr(s); RETURN_UBX_TUP2(m, r1); } RETURN_UBX_TUP2(-1, null); } function h$jsstringWords(x) { TRACE_JSSTRING("words: '" + x + "'"); var a = null, i = 0, n, s = -1, m = 0, w, l = x.length, r = HS_NIL; outer: while(m < l) { // skip leading spaces do { if(m >= l) { s = m; break outer; } } while(h$isSpace(x.charCodeAt(m++))); // found start of word s = m - 1; while(m < l) { if(h$isSpace(x.charCodeAt(m++))) { // found end of word w = (m-s<=1) ? h$jsstringEmpty : MK_JSVAL(x.substr(s,m-s-1)); if(i) a[i++] = w; else { a = [w]; i = 1; } s = m; break; } } } // end of string if(s !== -1 && s < l) { w = MK_JSVAL(s === 0 ? x : x.substr(s)); if(i) a[i++] = w; else { a = [w]; i = 1; } } // build resulting list while(--i>=0) r = MK_CONS(a[i], r); return r; } // returns -1 for end of input, start of next token otherwise // line in h$ret1 function h$jsstringLines1(n, x) { TRACE_JSSTRING("lines1: " + n + " '" + x + "'"); var m = n, l = x.length; if(n >= l) return -1; while(m < l) { if(x.charCodeAt(m++) === 10) { // found newline if(n > 0 && n === l-1) return -1; // it was the last character var r1 = (m-n<=1) ? "" : x.substr(n,m-n-1); RETURN_UBX_TUP2(m, r1); } } // end of string RETURN_UBX_TUP2(m, x.substr(n)); } function h$jsstringLines(x) { TRACE_JSSTRING("lines: '" + x + "'"); var a = null, m = 0, i = 0, l = x.length, s = 0, r = HS_NIL, w; if(l === 0) return HS_NIL; outer: while(true) { s = m; do { if(m >= l) break outer; } while(x.charCodeAt(m++) !== 10); w = (m-s<=1) ? h$jsstringEmpty : MK_JSVAL(x.substr(s,m-s-1)); if(i) a[i++] = w; else { a = [w]; i = 1; } } if(s < l) { w = MK_JSVAL(x.substr(s)); if(i) a[i++] = w; else { a = [w]; i = 1; } } while(--i>=0) r = MK_CONS(a[i], r); return r; } function h$jsstringGroup(x) { TRACE_JSSTRING("group: '" + x + "'"); var xl = x.length; if(xl === 0) return HS_NIL; var i = xl-1, si, ch, s=xl, r=HS_NIL; var tch = x.charCodeAt(i--); if(IS_LO_SURR(tch)) tch = FROM_SURR(x.charCodeAt(i--), tch); while(i >= 0) { si = i; ch = x.charCodeAt(i--); if(IS_LO_SURR(ch)) { ch = FROM_SURR(x.charCodeAt(i--), ch); } if(ch != tch) { tch = ch; r = MK_CONS(MK_JSVAL(x.substr(si+1,s-si)), r); s = si; } } return MK_CONS(MK_JSVAL(x.substr(0,s+1)), r); } function h$jsstringChunksOf1(n, s, x) { TRACE_JSSTRING("chunksOf1: " + n + " " + s + " '" + x + "'"); var m = s, c = 0, l = x.length, ch; if(n <= 0 || l === 0 || s >= l) return -1 while(++m < l) { ch = x.charCodeAt(m - 1); if(IS_HI_SURR(ch)) ++m; if(++c >= n) break; } var r1 = (m >= l && s === c) ? x : x.substr(s,m-s); RETURN_UBX_TUP2(m, r1); } function h$jsstringChunksOf(n, x) { TRACE_JSSTRING("chunksOf: " + n + " '" + x + "'"); var l = x.length; if(l===0 || n <= 0) return HS_NIL; if(l <= n) return MK_CONS(MK_JSVAL(x), HS_NIL); var a = [], i = 0, s = 0, ch, m = 0, c, r = HS_NIL; while(m < l) { s = m; c = 0; while(m < l && ++c <= n) { ch = x.charCodeAt(m++); if(IS_HI_SURR(ch)) ++m; } if(c) a[i++] = x.substr(s, m-s); } while(--i>=0) r = MK_CONS(MK_JSVAL(a[i]), r); return r; } function h$jsstringCount(pat, src) { TRACE_JSSTRING("count: '" + pat + "' '" + src + "'"); var i = 0, n = 0, pl = pat.length, sl = src.length; while(i>= 1; } while(n > 1); return r+str; } // this does not deal with combining diacritics, Data.Text does not either var h$jsstringReverse; if(Array.from) { h$jsstringReverse = function(str) { TRACE_JSSTRING("(Array.from) reverse: '" + str + "'"); return Array.from(str).reverse().join(''); } } else { h$jsstringReverse = function(str) { TRACE_JSSTRING("(no Array.from) reverse: '" + str + "'"); var l = str.length, a = [], o = 0, i = 0, c, c1, s = ''; while(i < l) { c = str.charCodeAt(i); if(IS_HI_SURR(c)) { a[i] = str.charCodeAt(i+1); a[i+1] = c; i += 2; } else a[i++] = c; if(i-o > 60000) { s = String.fromCharCode.apply(null, a.reverse()) + s; o = -i; a = []; } } return (i===0) ? s : String.fromCharCode.apply(null,a.reverse()) + s; } } function h$jsstringUnpack(str) { TRACE_JSSTRING("unpack: '" + str + "'"); var r = HS_NIL, i = str.length-1, c; while(i >= 0) { c = str.charCodeAt(i--); if(IS_LO_SURR(c)) c = FROM_SURR(str.charCodeAt(i--), c) r = MK_CONS(c, r); } return r; } #if __GLASGOW_HASKELL__ >= 800 function h$jsstringDecInteger(val) { TRACE_JSSTRING("decInteger"); if(IS_INTEGER_S(val)) { return '' + INTEGER_S_DATA(val); } else if(IS_INTEGER_Jp(val)) { return h$ghcjsbn_showBase(INTEGER_J_DATA(val), 10); } else { return '-' + h$ghcjsbn_showBase(INTEGER_J_DATA(val), 10); } } #else function h$jsstringDecInteger(val) { TRACE_JSSTRING("decInteger"); if(IS_INTEGER_S(val)) { return '' + INTEGER_S_DATA(val); } else { return INTEGER_J_DATA(val).toString(); } } #endif function h$jsstringDecI64(hi,lo) { TRACE_JSSTRING("decI64: " + hi + " " + lo); var lo0 = (lo < 0) ? lo+4294967296:lo; if(hi < 0) { if(hi === -1) return ''+(lo0-4294967296); lo0 = 4294967296 - lo0; var hi0 = -1 - hi; var x0 = hi0 * 967296; var x1 = (lo0 + x0) % 1000000; var x2 = hi0*4294+Math.floor((x0+lo0-x1)/1000000); return '-' + x2 + h$jsstringDecIPadded6(x1); } else { if(hi === 0) return ''+lo0; var x0 = hi * 967296; var x1 = (lo0 + x0) % 1000000; var x2 = hi*4294+Math.floor((x0+lo0-x1)/1000000); return '' + x2 + h$jsstringDecIPadded6(x1); } } function h$jsstringDecW64(hi,lo) { TRACE_JSSTRING("decW64: " + hi + " " + lo); var lo0 = (lo < 0) ? lo+4294967296 : lo; if(hi === 0) return ''+lo0; var hi0 = (hi < 0) ? hi+4294967296 : hi; var x0 = hi0 * 967296; var x1 = (lo0 + x0) % 1000000; var x2 = hi0*4294+Math.floor((x0+lo0-x1)/1000000); return '' + x2 + h$jsstringDecIPadded6(x1); } #if __GLASGOW_HASKELL__ >= 800 function h$jsstringHexInteger(val) { TRACE_JSSTRING("hexInteger"); if(IS_INTEGER_S(val)) { return '' + INTEGER_S_DATA(val); } else { // we assume it's nonnegative. this condition is checked by the Haskell code return h$ghcjsbn_showBase(INTEGER_J_DATA(val), 16); } } #else function h$jsstringHexInteger(val) { TRACE_JSSTRING("hexInteger"); if(IS_INTEGER_S(val)) { return '' + INTEGER_S_DATA(val); } else { return INTEGER_J_DATA(val).toRadix(16); } } #endif function h$jsstringHexI64(hi,lo) { var lo0 = lo<0 ? lo+4294967296 : lo; if(hi === 0) return lo0.toString(16); return ((hi<0)?hi+4294967296:hi).toString(16) + h$jsstringHexIPadded8(lo0); } function h$jsstringHexW64(hi,lo) { var lo0 = lo<0 ? lo+4294967296 : lo; if(hi === 0) return lo0.toString(16); return ((hi<0)?hi+4294967296:hi).toString(16) + h$jsstringHexIPadded8(lo0); } // n in [0, 1000000000) function h$jsstringDecIPadded9(n) { TRACE_JSSTRING("decIPadded9: " + n); if(n === 0) return '000000000'; var pad = (n>=100000000)?'': (n>=10000000)?'0': (n>=1000000)?'00': (n>=100000)?'000': (n>=10000)?'0000': (n>=1000)?'00000': (n>=100)?'000000': (n>=10)?'0000000': '00000000'; return pad+n; } // n in [0, 1000000) function h$jsstringDecIPadded6(n) { TRACE_JSSTRING("decIPadded6: " + n); if(n === 0) return '000000'; var pad = (n>=100000)?'': (n>=10000)?'0': (n>=1000)?'00': (n>=100)?'000': (n>=10)?'0000': '00000'; return pad+n; } // n in [0, 2147483648) function h$jsstringHexIPadded8(n) { TRACE_JSSTRING("hexIPadded8: " + n); if(n === 0) return '00000000'; var pad = (n>=0x10000000)?'': (n>=0x1000000)?'0': (n>=0x100000)?'00': (n>=0x10000)?'000': (n>=0x1000)?'0000': (n>=0x100)?'00000': (n>=0x10)?'000000': '0000000'; return pad+n.toString(16); } function h$jsstringZeroes(n) { var r; switch(n&7) { case 0: r = ''; break; case 1: r = '0'; break; case 2: r = '00'; break; case 3: r = '000'; break; case 4: r = '0000'; break; case 5: r = '00000'; break; case 6: r = '000000'; break; case 7: r = '0000000'; } for(var i=n>>3;i>0;i--) r = r + '00000000'; return r; } function h$jsstringDoubleToFixed(decs, d) { if(decs >= 0) { if(Math.abs(d) < 1e21) { var r = d.toFixed(Math.min(20,decs)); if(decs > 20) r = r + h$jsstringZeroes(decs-20); return r; } else { var r = d.toExponential(); var ei = r.indexOf('e'); var di = r.indexOf('.'); var e = parseInt(r.substr(ei+1)); return r.substring(0,di) + r.substring(di,ei) + h$jsstringZeroes(di-ei+e) + ((decs > 0) ? ('.' + h$jsstringZeroes(decs)) : ''); } } var r = Math.abs(d).toExponential(); var ei = r.indexOf('e'); var e = parseInt(r.substr(ei+1)); var m = d < 0 ? '-' : ''; r = r.substr(0,1) + r.substring(2,ei); if(e >= 0) { return (e > r.length) ? m + r + h$jsstringZeroes(r.length-e-1) + '.0' : m + r.substr(0,e+1) + '.' + r.substr(e+1); } else { return m + '0.' + h$jsstringZeroes(-e-1) + r; } } function h$jsstringDoubleToExponent(decs, d) { var r; if(decs ===-1) { r = d.toExponential().replace('+',''); } else { r = d.toExponential(Math.max(1, Math.min(20,decs))).replace('+',''); } if(r.indexOf('.') === -1) { r = r.replace('e', '.0e'); } if(decs > 20) r = r.replace('e', h$jsstringZeroes(decs-20)+'e'); return r; } function h$jsstringDoubleGeneric(decs, d) { var r; if(decs === -1) { r = d.toString(10).replace('+',''); } else { r = d.toPrecision(Math.max(decs+1,1)).replace('+',''); } if(decs !== 0 && r.indexOf('.') === -1) { if(r.indexOf('e') !== -1) { r = r.replace('e', '.0e'); } else { r = r + '.0'; } } return r; } function h$jsstringAppend(x, y) { TRACE_JSSTRING("append: '" + x + "' '" + y + "'"); return x+y; } function h$jsstringCompare(x, y) { TRACE_JSSTRING("compare: '" + x + "' '" + y + "'"); return (xy)?1:0); } function h$jsstringUnlines(xs) { var r = ''; while(IS_CONS(xs)) { r = r + JSVAL_VAL(CONS_HEAD(xs)) + '\n'; xs = CONS_TAIL(xs); } return r; } function h$jsstringUnwords(xs) { if(IS_NIL(xs)) return ''; var r = JSVAL_VAL(CONS_HEAD(xs)); xs = CONS_TAIL(xs); while(IS_CONS(xs)) { r = r + ' ' + JSVAL_VAL(CONS_HEAD(xs)); xs = CONS_TAIL(xs); } return r; } function h$jsstringReplace(pat, rep, src) { TRACE_JSSTRING("replace: '" + pat + "' '" + rep + "' '" + src + "'"); var r = src.replace(pat, rep, 'g'); // the 'g' flag is not supported everywhere, check and fall back if necessary if(r.indexOf(pat) !== -1) { r = src.split(pat).join(rep); } return r; } function h$jsstringReplicateChar(n, ch) { TRACE_JSSTRING("replicateChar: " + n + " " + ch); return h$jsstringReplicate(n, h$jsstringSingleton(ch)); } function h$jsstringIsInteger(str) { return /^-?\d+$/.test(str); } function h$jsstringIsNatural(str) { return /^\d+$/.test(str); } function h$jsstringReadInt(str) { if(!/^-?\d+/.test(str)) return null; var x = parseInt(str, 10); var x0 = x|0; return (x===x0) ? x0 : null; } function h$jsstringLenientReadInt(str) { var x = parseInt(str, 10); var x0 = x|0; return (x===x0) ? x0 : null; } function h$jsstringReadWord(str) { if(!/^\d+/.test(str)) return null; var x = parseInt(str, 10); var x0 = x|0; if(x0<0) return (x===x0+2147483648) ? x0 : null; else return (x===x0) ? x0 : null; } function h$jsstringReadDouble(str) { return parseFloat(str, 10); } function h$jsstringLenientReadDouble(str) { return parseFloat(str, 10); } function h$jsstringReadInteger(str) { TRACE_JSSTRING("readInteger: " + str); if(!/^(-)?\d+$/.test(str)) { return null; } else if(str.length <= 9) { return MK_INTEGER_S(parseInt(str, 10)); } else { #if __GLASGOW_HASKELL__ >= 800 return h$ghcjsbn_readInteger(str); #else return MK_INTEGER_J(new BigInteger(str, 10)); #endif } } function h$jsstringReadInt64(str) { if(!/^(-)?\d+$/.test(str)) { RETURN_UBX_TUP3(0, 0, 0); } if(str.charCodeAt(0) === 45) { // '-' return h$jsstringReadValue64(str, 1, true); } else { return h$jsstringReadValue64(str, 0, false); } } function h$jsstringReadWord64(str) { if(!/^\d+$/.test(str)) { RETURN_UBX_TUP3(0, 0, 0); } return h$jsstringReadValue64(str, 0, false); } var h$jsstringLongs = null; function h$jsstringReadValue64(str, start, negate) { var l = str.length, i = start; while(i < l) { if(str.charCodeAt(i) !== 48) break; i++; } if(i >= l) RETURN_UBX_TUP3(1, 0, 0); // only zeroes if(h$jsstringLongs === null) { h$jsstringLongs = []; for(var t=10; t<=1000000000; t*=10) { h$jsstringLongs.push(goog.math.Long.fromInt(t)); } } var li = l-i; if(li < 10 && !negate) { RETURN_UBX_TUP3(1, 0, parseInt(str.substr(i), 10)); } var r = goog.math.Long.fromInt(parseInt(str.substr(li,9),10)); li += 9; while(li < l) { r = r.multiply(h$jsstringLongs[Math.min(l-li-1,8)]) .add(goog.math.Long.fromInt(parseInt(str.substr(li,9), 10))); li += 9; } if(negate) { r = r.negate(); } RETURN_UBX_TUP3(1, r.getHighBits(), r.getLowBits()); } function h$jsstringExecRE(i, str, re) { re.lastIndex = i; var m = re.exec(str); if(m === null) return -1; var a = [], x, j = 1, r = HS_NIL; while(true) { x = m[j]; if(typeof x === 'undefined') break; a[j-1] = x; j++; } j-=1; while(--j>=0) r = MK_CONS(MK_JSVAL(a[j]), r); RETURN_UBX_TUP3(m.index, m[0], r); } function h$jsstringReplaceRE(pat, replacement, str) { return str.replace(pat, replacement); } function h$jsstringSplitRE(limit, re, str) { re.lastIndex = i; var s = (limit < 0) ? str.split(re) : str.split(re, limit); var i = s.length, r = HS_NIL; while(--i>=0) r = MK_CONS(MK_JSVAL(a[i]), r); return r; }