Skip to content

Commit 3cf3b90

Browse files
committed
implement missing JSString read functions and fix existing ones
1 parent 6dadc27 commit 3cf3b90

File tree

2 files changed

+75
-36
lines changed

2 files changed

+75
-36
lines changed

Data/JSString/Read.hs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,20 @@ module Data.JSString.Read ( isInteger
66
, isNatural
77
, readInt
88
, readIntMaybe
9+
, lenientReadInt
10+
, readInt64
11+
, readInt64Maybe
12+
, readWord64
13+
, readWord64Maybe
914
, readDouble
1015
, readDoubleMaybe
1116
, readInteger
1217
, readIntegerMaybe
1318
) where
14-
import GHC.Exts (Any, ByteArray#, Int#, Int64#, Word64#, Int(..))
19+
20+
import GHCJS.Types
21+
22+
import GHC.Exts (Any, Int#, Int64#, Word64#, Int(..))
1523
import GHC.Int (Int64(..))
1624
import GHC.Word (Word64(..))
1725
import Unsafe.Coerce
@@ -128,10 +136,10 @@ readIntegerMaybe j = convertNullMaybe js_readInteger j
128136

129137
-- ----------------------------------------------------------------------------
130138

131-
convertNullMaybe :: (JSString -> ByteArray#) -> JSString -> Maybe a
139+
convertNullMaybe :: (JSString -> JSRef) -> JSString -> Maybe a
132140
convertNullMaybe f j
133141
| js_isNull r = Nothing
134-
| otherwise = unsafeCoerce (js_toHeapObject r)
142+
| otherwise = Just (unsafeCoerce (js_toHeapObject r))
135143
where
136144
r = f j
137145
{-# INLINE convertNullMaybe #-}
@@ -142,21 +150,21 @@ readError xs = error ("Data.JSString.Read." ++ xs)
142150
-- ----------------------------------------------------------------------------
143151

144152
foreign import javascript unsafe
145-
"$1===null" js_isNull :: ByteArray# -> Bool
153+
"$r = $1===null;" js_isNull :: JSRef -> Bool
146154
foreign import javascript unsafe
147-
"$r=$1;" js_toHeapObject :: ByteArray# -> Any
155+
"$r=$1;" js_toHeapObject :: JSRef -> Any
148156
foreign import javascript unsafe
149-
"h$jsstringReadInteger" js_readInteger :: JSString -> ByteArray#
157+
"h$jsstringReadInteger" js_readInteger :: JSString -> JSRef
150158
foreign import javascript unsafe
151-
"h$jsstringReadInt" js_readInt :: JSString -> ByteArray#
159+
"h$jsstringReadInt" js_readInt :: JSString -> JSRef
152160
foreign import javascript unsafe
153-
"h$jsstringLenientReadInt" js_lenientReadInt :: JSString -> ByteArray#
161+
"h$jsstringLenientReadInt" js_lenientReadInt :: JSString -> JSRef
154162
foreign import javascript unsafe
155163
"h$jsstringReadInt64" js_readInt64 :: JSString -> (# Int#, Int64# #)
156164
foreign import javascript unsafe
157165
"h$jsstringReadWord64" js_readWord64 :: JSString -> (# Int#, Word64# #)
158166
foreign import javascript unsafe
159-
"h$jsstringReadDouble" js_readDouble :: JSString -> ByteArray#
167+
"h$jsstringReadDouble" js_readDouble :: JSString -> JSRef
160168
foreign import javascript unsafe
161169
"h$jsstringIsInteger" js_isInteger :: JSString -> Bool
162170
foreign import javascript unsafe

jsbits/jsstring.js

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -958,49 +958,80 @@ function h$jsstringLenientReadInt(str) {
958958
}
959959

960960
function h$jsstringReadWord(str) {
961-
if(!/^\d+/.test(str)) return null;
962-
var x = parseInt(str, 10);
963-
var x0 = x|0;
964-
if(x0<0) return (x===x0+2147483648) ? x0 : null;
965-
else return (x===x0) ? x0 : null;
961+
if(!/^\d+/.test(str)) return null;
962+
var x = parseInt(str, 10);
963+
var x0 = x|0;
964+
if(x0<0) return (x===x0+2147483648) ? x0 : null;
965+
else return (x===x0) ? x0 : null;
966966
}
967967

968968
function h$jsstringReadDouble(str) {
969-
969+
return parseFloat(str, 10);
970970
}
971971

972972
function h$jsstringLenientReadDouble(str) {
973973
return parseFloat(str, 10);
974974
}
975975

976976
function h$jsstringReadInteger(str) {
977-
throw "h$jsstringReadInteger not implemented";
977+
TRACE_JSSTRING("readInteger: " + str);
978+
if(!/^(-)?\d+$/.test(str)) {
979+
return null;
980+
} else if(str.length <= 9) {
981+
return MK_INTEGER_S(parseInt(str, 10));
982+
} else {
983+
return MK_INTEGER_J(new BigInteger(str, 10));
984+
}
978985
}
979986

980987
function h$jsstringReadInt64(str) {
981-
throw "h4JsstringReadInt64 not implemented";
988+
if(!/^(-)?\d+$/.test(str)) {
989+
RETURN_UBX_TUP3(0, 0, 0);
990+
}
991+
if(str.charCodeAt(0) === 45) { // '-'
992+
return h$jsstringReadValue64(str, 1, true);
993+
} else {
994+
return h$jsstringReadValue64(str, 0, false);
995+
}
982996
}
983997

984998
function h$jsstringReadWord64(str) {
985-
if(!/^\d+$/.test(str)) return 0;
986-
var l = str.length, i = 0;
987-
while(i < l) {
988-
if(str.charCodeAt(i) !== 48) break;
989-
i++;
990-
}
991-
if(i >= l) RETURN_UBX_TUP3(1, 0, 0); // only zeroes
992-
var li = l-i;
993-
if(li > 20) return 0; // too big
994-
if(li < 10) RETURN_UBX_TUP3(1, 0, parseInt(str.substr(i), 10));
995-
if(li < 18) {
996-
var x1 = parseInt(str.substr(i+9), 10);
997-
var x2 = parseInt(str.substr(i,9), 10);
998-
var x3 = ((x2 % 10) * 1000000000 + x1)|0;
999-
// var x4 = throw "jsstringReadWord64";
1000-
throw "jsstringReadWord64"; // fixme
1001-
RETURN_UBX_TUP3(1, x4, x3);
1002-
}
1003-
999+
if(!/^\d+$/.test(str)) {
1000+
RETURN_UBX_TUP3(0, 0, 0);
1001+
}
1002+
return h$jsstringReadValue64(str, 0, false);
1003+
}
1004+
1005+
var h$jsstringLongs = null;
1006+
1007+
function h$jsstringReadValue64(str, start, negate) {
1008+
var l = str.length, i = start;
1009+
while(i < l) {
1010+
if(str.charCodeAt(i) !== 48) break;
1011+
i++;
1012+
}
1013+
if(i >= l) RETURN_UBX_TUP3(1, 0, 0); // only zeroes
1014+
if(h$jsstringLongs === null) {
1015+
h$jsstringLongs = [];
1016+
for(var t=10; t<=1000000000; t*=10) {
1017+
h$jsstringLongs.push(goog.math.Long.fromInt(t));
1018+
}
1019+
}
1020+
var li = l-i;
1021+
if(li < 10 && !negate) {
1022+
RETURN_UBX_TUP3(1, 0, parseInt(str.substr(i), 10));
1023+
}
1024+
var r = goog.math.Long.fromInt(parseInt(str.substr(li,9),10));
1025+
li += 9;
1026+
while(li < l) {
1027+
r = r.multiply(h$jsstringLongs[Math.min(l-li-1,8)])
1028+
.add(goog.math.Long.fromInt(parseInt(str.substr(li,9), 10)));
1029+
li += 9;
1030+
}
1031+
if(negate) {
1032+
r = r.negate();
1033+
}
1034+
RETURN_UBX_TUP3(1, r.getHighBits(), r.getLowBits());
10041035
}
10051036

10061037
function h$jsstringExecRE(i, str, re) {

0 commit comments

Comments
 (0)