smarter emitting of ints/floats

This commit is contained in:
alisdair sullivan 2011-07-10 10:54:04 -07:00
parent 5060f86921
commit 668b43b7e6

View file

@ -565,30 +565,30 @@ negative(Bin, Stack, Opts, Acc) ->
zero(<<?end_object/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) -> zero(<<?end_object/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end} {event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end}
end}; end};
zero(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts, Acc) -> zero(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end} {event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end}
end}; end};
zero(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) -> zero(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
key(Rest, [key|Stack], Opts) key(Rest, [key|Stack], Opts)
end}; end};
zero(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts, Acc) -> zero(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
value(Rest, Stack, Opts) value(Rest, Stack, Opts)
end}; end};
zero(<<?decimalpoint/?utfx, Rest/binary>>, Stack, Opts, Acc) -> zero(<<?decimalpoint/?utfx, Rest/binary>>, Stack, Opts, Acc) ->
initial_decimal(Rest, Stack, Opts, [?decimalpoint] ++ Acc); initial_decimal(Rest, Stack, Opts, {Acc, []});
zero(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) -> zero(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
maybe_done(Rest, Stack, Opts) maybe_done(Rest, Stack, Opts)
end}; end};
zero(<<>>, [], Opts, Acc) -> zero(<<>>, [], Opts, Acc) ->
{incomplete, fun(end_stream) -> {incomplete, fun(end_stream) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_json, fun() -> zero(<<>>, [], Opts, Acc) end} {event, end_json, fun() -> zero(<<>>, [], Opts, Acc) end}
end} end}
; (Stream) -> zero(Stream, [], Opts, Acc) ; (Stream) -> zero(Stream, [], Opts, Acc)
@ -608,36 +608,34 @@ zero(Bin, Stack, Opts, Acc) ->
integer(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_nonzero(S) -> integer(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_nonzero(S) ->
integer(Rest, Stack, Opts, [S] ++ Acc); integer(Rest, Stack, Opts, [S] ++ Acc);
integer(<<?end_object/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) -> integer(<<?end_object/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end} {event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end}
end}; end};
integer(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts, Acc) -> integer(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end} {event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end}
end}; end};
integer(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) -> integer(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
key(Rest, [key|Stack], Opts) key(Rest, [key|Stack], Opts)
end}; end};
integer(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts, Acc) -> integer(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
value(Rest, Stack, Opts) value(Rest, Stack, Opts)
end}; end};
integer(<<?decimalpoint/?utfx, Rest/binary>>, Stack, Opts, Acc) -> integer(<<?decimalpoint/?utfx, Rest/binary>>, Stack, Opts, Acc) ->
initial_decimal(Rest, Stack, Opts, [?decimalpoint] ++ Acc); initial_decimal(Rest, Stack, Opts, {Acc, []});
integer(<<?zero/?utfx, Rest/binary>>, Stack, Opts, Acc) -> integer(<<?zero/?utfx, Rest/binary>>, Stack, Opts, Acc) ->
integer(Rest, Stack, Opts, [?zero] ++ Acc); integer(Rest, Stack, Opts, [?zero] ++ Acc);
integer(<<$e/?utfx, Rest/binary>>, Stack, Opts, Acc) -> integer(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when S =:= $e; S =:= $E ->
e(Rest, Stack, Opts, "e0." ++ Acc); e(Rest, Stack, Opts, {lists:reverse(Acc), [], []});
integer(<<$E/?utfx, Rest/binary>>, Stack, Opts, Acc) ->
e(Rest, Stack, Opts, "e0." ++ Acc);
integer(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) -> integer(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
maybe_done(Rest, Stack, Opts) maybe_done(Rest, Stack, Opts)
end}; end};
integer(<<>>, [], Opts, Acc) -> integer(<<>>, [], Opts, Acc) ->
{incomplete, fun(end_stream) -> {incomplete, fun(end_stream) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_json, fun() -> integer(<<>>, [], Opts, Acc) end} {event, end_json, fun() -> integer(<<>>, [], Opts, Acc) end}
end} end}
; (Stream) -> integer(Stream, [], Opts, Acc) ; (Stream) -> integer(Stream, [], Opts, Acc)
@ -654,11 +652,9 @@ integer(Bin, Stack, Opts, Acc) ->
end. end.
initial_decimal(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) initial_decimal(<<S/?utfx, Rest/binary>>, Stack, Opts, {Int, Frac})
when ?is_nonzero(S) -> when S =:= ?zero; ?is_nonzero(S) ->
decimal(Rest, Stack, Opts, [S] ++ Acc); decimal(Rest, Stack, Opts, {Int, [S] ++ Frac});
initial_decimal(<<?zero/?utfx, Rest/binary>>, Stack, Opts, Acc) ->
decimal(Rest, Stack, Opts, [?zero] ++ Acc);
initial_decimal(Bin, Stack, Opts, Acc) -> initial_decimal(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of case ?partial_codepoint(Bin) of
true -> true ->
@ -675,37 +671,35 @@ initial_decimal(Bin, Stack, Opts, Acc) ->
end. end.
decimal(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_nonzero(S) -> decimal(<<S/?utfx, Rest/binary>>, Stack, Opts, {Int, Frac})
decimal(Rest, Stack, Opts, [S] ++ Acc); when S=:= ?zero; ?is_nonzero(S) ->
decimal(Rest, Stack, Opts, {Int, [S] ++ Frac});
decimal(<<?end_object/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) -> decimal(<<?end_object/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end} {event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end}
end}; end};
decimal(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts, Acc) -> decimal(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end} {event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end}
end}; end};
decimal(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) -> decimal(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
key(Rest, [key|Stack], Opts) key(Rest, [key|Stack], Opts)
end}; end};
decimal(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts, Acc) -> decimal(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
value(Rest, Stack, Opts) value(Rest, Stack, Opts)
end}; end};
decimal(<<?zero/?utfx, Rest/binary>>, Stack, Opts, Acc) -> decimal(<<S/?utfx, Rest/binary>>, Stack, Opts, {Int, Frac})
decimal(Rest, Stack, Opts, [?zero] ++ Acc); when S =:= $e; S =:= $E ->
decimal(<<$e/?utfx, Rest/binary>>, Stack, Opts, Acc) -> e(Rest, Stack, Opts, {Int, Frac, []});
e(Rest, Stack, Opts, "e" ++ Acc);
decimal(<<$E/?utfx, Rest/binary>>, Stack, Opts, Acc) ->
e(Rest, Stack, Opts, "e" ++ Acc);
decimal(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) -> decimal(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
maybe_done(Rest, Stack, Opts) maybe_done(Rest, Stack, Opts)
end}; end};
decimal(<<>>, [], Opts, Acc) -> decimal(<<>>, [], Opts, Acc) ->
{incomplete, fun(end_stream) -> {incomplete, fun(end_stream) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_json, fun() -> decimal(<<>>, [], Opts, Acc) end} {event, end_json, fun() -> decimal(<<>>, [], Opts, Acc) end}
end} end}
; (Stream) -> decimal(Stream, [], Opts, Acc) ; (Stream) -> decimal(Stream, [], Opts, Acc)
@ -722,12 +716,12 @@ decimal(Bin, Stack, Opts, Acc) ->
end. end.
e(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) e(<<S/?utfx, Rest/binary>>, Stack, Opts, {Int, Frac, Exp})
when S =:= ?zero; ?is_nonzero(S) -> when S =:= ?zero; ?is_nonzero(S) ->
exp(Rest, Stack, Opts, [S] ++ Acc); exp(Rest, Stack, Opts, {Int, Frac, [S] ++ Exp});
e(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) e(<<S/?utfx, Rest/binary>>, Stack, Opts, {Int, Frac, Exp})
when S =:= ?positive; S =:= ?negative -> when S =:= ?positive; S =:= ?negative ->
ex(Rest, Stack, Opts, [S] ++ Acc); ex(Rest, Stack, Opts, {Int, Frac, [S] ++ Exp});
e(Bin, Stack, Opts, Acc) -> e(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of case ?partial_codepoint(Bin) of
true -> true ->
@ -740,9 +734,9 @@ e(Bin, Stack, Opts, Acc) ->
end. end.
ex(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) ex(<<S/?utfx, Rest/binary>>, Stack, Opts, {Int, Frac, Exp})
when S =:= ?zero; ?is_nonzero(S) -> when S =:= ?zero; ?is_nonzero(S) ->
exp(Rest, Stack, Opts, [S] ++ Acc); exp(Rest, Stack, Opts, {Int, Frac, [S] ++ Exp});
ex(Bin, Stack, Opts, Acc) -> ex(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of case ?partial_codepoint(Bin) of
true -> true ->
@ -755,33 +749,32 @@ ex(Bin, Stack, Opts, Acc) ->
end. end.
exp(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_nonzero(S) -> exp(<<S/?utfx, Rest/binary>>, Stack, Opts, {Int, Frac, Exp})
exp(Rest, Stack, Opts, [S] ++ Acc); when S =:= ?zero; ?is_nonzero(S) ->
exp(Rest, Stack, Opts, {Int, Frac, [S] ++ Exp});
exp(<<?end_object/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) -> exp(<<?end_object/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end} {event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end}
end}; end};
exp(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts, Acc) -> exp(<<?end_array/?utfx, Rest/binary>>, [array|Stack], Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end} {event, end_array, fun() -> maybe_done(Rest, Stack, Opts) end}
end}; end};
exp(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) -> exp(<<?comma/?utfx, Rest/binary>>, [object|Stack], Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
key(Rest, [key|Stack], Opts) key(Rest, [key|Stack], Opts)
end}; end};
exp(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts, Acc) -> exp(<<?comma/?utfx, Rest/binary>>, [array|_] = Stack, Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
value(Rest, Stack, Opts) value(Rest, Stack, Opts)
end}; end};
exp(<<?zero/?utfx, Rest/binary>>, Stack, Opts, Acc) ->
exp(Rest, Stack, Opts, [?zero] ++ Acc);
exp(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) -> exp(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
maybe_done(Rest, Stack, Opts) maybe_done(Rest, Stack, Opts)
end}; end};
exp(<<>>, [], Opts, Acc) -> exp(<<>>, [], Opts, Acc) ->
{incomplete, fun(end_stream) -> {incomplete, fun(end_stream) ->
{event, {float, lists:reverse(Acc)}, fun() -> {event, format_number(Acc), fun() ->
{event, end_json, fun() -> exp(<<>>, [], Opts, Acc) end} {event, end_json, fun() -> exp(<<>>, [], Opts, Acc) end}
end} end}
; (Stream) -> exp(Stream, [], Opts, Acc) ; (Stream) -> exp(Stream, [], Opts, Acc)
@ -798,6 +791,18 @@ exp(Bin, Stack, Opts, Acc) ->
end. end.
format_number(Int) when is_list(Int) ->
{integer, list_to_integer(lists:reverse(Int))};
format_number({Int, Frac}) ->
{float, list_to_float(lists:reverse(Frac ++ "." ++ Int))};
format_number({Int, [], Exp}) ->
{float, list_to_float(lists:reverse(Exp ++ "e0." ++ Int))};
format_number({Int, Frac, Exp}) ->
{float, list_to_float(lists:reverse(Exp ++ "e" ++ Frac ++ "." ++ Int))}.
tr(<<$r/?utfx, Rest/binary>>, Stack, Opts) -> tr(<<$r/?utfx, Rest/binary>>, Stack, Opts) ->
tru(Rest, Stack, Opts); tru(Rest, Stack, Opts);
tr(Bin, Stack, Opts) -> tr(Bin, Stack, Opts) ->