Skip to content

Commit b4ec76a

Browse files
committed
parse floats with exponent and format float to the exact number of dps
1 parent badd601 commit b4ec76a

File tree

3 files changed

+67
-24
lines changed

3 files changed

+67
-24
lines changed

src/JSON.mo

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module JSON {
2525

2626
public func show(json : JSON) : Text = switch (json) {
2727
case (#Number(v)) { Int.toText(v); };
28-
case (#Float(v)) { Float.format(#fix 2, v); };
28+
case (#Float(v)) { Float.format(#exact, v); };
2929
case (#String(v)) { "\"" # v # "\""; };
3030
case (#Array(v)) {
3131
var s = "[";
@@ -179,16 +179,6 @@ module JSON {
179179
}
180180
);
181181

182-
private func parseFloat() : P.Parser<Char, (Int, List.List<Char>)> {
183-
C.seq<Char, Int, List.List<Char>>(
184-
C.Int.int(),
185-
C.right(
186-
C.Character.char('.'),
187-
C.many1(C.Character.digit()),
188-
),
189-
);
190-
};
191-
192182
private func listToNat(list : List.List<Char>) : Nat {
193183
var n = 0;
194184

@@ -200,22 +190,58 @@ module JSON {
200190
};
201191

202192
private func floatParser() : P.Parser<Char, JSON> = C.map(
203-
parseFloat(),
204-
func((n, decimal_list) : (Int, List.List<Char>)) : JSON {
205-
let n_of_decimals = Float.fromInt(List.size(decimal_list));
193+
C.oneOf([
194+
parseFloatWithExp(),
195+
parseFloat(),
196+
]),
197+
func(n : Float) : JSON = #Float(n),
198+
);
206199

207-
let num = Float.fromInt(n);
208-
let decimals = Float.fromInt(listToNat(decimal_list)) / (10 ** n_of_decimals);
200+
private func parseFloat() : P.Parser<Char, Float> {
201+
C.map(
202+
C.seq<Char, Int, List.List<Char>>(
203+
C.Int.int(),
204+
C.right(
205+
C.Character.char('.'),
206+
C.many1(C.Character.digit()),
207+
),
208+
),
209+
func((n, decimal_list) : (Int, List.List<Char>)) : Float {
210+
let n_of_decimals = Float.fromInt(List.size(decimal_list));
209211

210-
let isNegative = num < 0;
212+
let num = Float.fromInt(n);
213+
let decimals = Float.fromInt(listToNat(decimal_list)) / (10 ** n_of_decimals);
211214

212-
let float = if (isNegative) {
213-
num - decimals;
214-
} else {
215-
num + decimals;
216-
};
215+
let isNegative = num < 0;
216+
217+
let float = if (isNegative) {
218+
num - decimals;
219+
} else {
220+
num + decimals;
221+
};
222+
223+
float;
224+
},
225+
);
226+
};
217227

218-
#Float(float);
228+
private func parseFloatWithExp() : P.Parser<Char, Float> = C.map(
229+
C.seq(
230+
C.oneOf([
231+
parseFloat(),
232+
C.map(
233+
C.Int.int(),
234+
func(i : Int) : Float = Float.fromInt(i),
235+
),
236+
]),
237+
C.right(
238+
C.oneOf([C.String.string("e"), C.String.string("E")]),
239+
C.Int.int(),
240+
),
241+
),
242+
func((n, exponent) : (Float, Int)) : Float {
243+
let exp = Float.fromInt(exponent);
244+
n * (10 ** exp);
219245
},
220246
);
221247

test/Show.mo

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import Debug "mo:base-0.7.3/Debug";
55
assert (JSON.show(#String("hello")) == "\"hello\"");
66
assert (JSON.show(#Number(1)) == "1");
77
assert (JSON.show(#Number(-1)) == "-1");
8-
assert (JSON.show(#Float(3.14)) == "3.14");
8+
assert (JSON.show(#Number(-1)) == "-1");
9+
10+
assert (JSON.show(#Float(-3.14)) == "-3.1400000000000001");
11+
assert (JSON.show(#Float(1.234e-4)) == "0.00012339999999999999");
12+
assert (JSON.show(#Float(43e-02)) == "0.42999999999999999");
913

1014
assert (
1115
JSON.show(

test/Value.mo

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import Debug "mo:base-0.7.3/Debug";
2+
13
import JSON "../src/JSON";
24

35
switch (JSON.parse("{ }")) {
@@ -117,4 +119,15 @@ switch (JSON.parse(" 1.23")) {
117119
case (_) { assert (false) };
118120
};
119121
};
122+
};
123+
124+
switch (JSON.parse(" 1.234e-4")) {
125+
// Test with spaces.
126+
case (null) { assert (false) };
127+
case (?v) {
128+
switch (v) {
129+
case (#Float(0.000_123_400_000_000_000_02)) {};
130+
case (_) { assert (false) };
131+
};
132+
};
120133
};

0 commit comments

Comments
 (0)