Current section
Files
Jump to
Current section
Files
src/kdleam@scanner.erl
-module(kdleam@scanner).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/kdleam/scanner.gleam").
-export([new/1, at/2, peek/1, peek_next/1, is_eof/1, position/1, make_error/2, codepoint/1, is_newline/1, advance/1, expect/2, consume_newline/1, skip_bom/1, consume_token/2, radix_prefixes/0, radix_of_marker/1, try_tokens/2, is_ascii_digit/1, is_hex_digit/1, is_unicode_space/1, is_disallowed/1, reserved_keywords/0, is_reserved_keyword/1, is_identifier_char/1, can_be_bare/1, join/1, repeat/2, clean_underscores/1, to_upper_hex/1]).
-export_type([scanner/0, string_kind/0, line_form/0, node_context/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type scanner() :: {scanner,
binary(),
list(binary()),
integer(),
integer(),
integer()}.
-type string_kind() :: quoted | raw.
-type line_form() :: single_line | multiline.
-type node_context() :: top_level | in_children.
-file("src/kdleam/scanner.gleam", 31).
?DOC(false).
-spec new(binary()) -> scanner().
new(Input) ->
{scanner, Input, gleam@string:to_graphemes(Input), 0, 1, 1}.
-file("src/kdleam/scanner.gleam", 193).
?DOC(false).
-spec at(list(binary()), integer()) -> gleam@option:option(binary()).
at(Chars, Index) ->
case {Chars, Index} of
{[], _} ->
none;
{[Ch | _], 0} ->
{some, Ch};
{[_ | Rest], N} when N > 0 ->
at(Rest, N - 1);
{_, _} ->
none
end.
-file("src/kdleam/scanner.gleam", 42).
?DOC(false).
-spec peek(scanner()) -> gleam@option:option(binary()).
peek(S) ->
at(erlang:element(3, S), erlang:element(4, S)).
-file("src/kdleam/scanner.gleam", 47).
?DOC(false).
-spec peek_next(scanner()) -> gleam@option:option(binary()).
peek_next(S) ->
at(erlang:element(3, S), erlang:element(4, S) + 1).
-file("src/kdleam/scanner.gleam", 52).
?DOC(false).
-spec is_eof(scanner()) -> boolean().
is_eof(S) ->
erlang:element(4, S) >= erlang:length(erlang:element(3, S)).
-file("src/kdleam/scanner.gleam", 57).
?DOC(false).
-spec position(scanner()) -> {integer(), integer()}.
position(S) ->
{erlang:element(5, S), erlang:element(6, S)}.
-file("src/kdleam/scanner.gleam", 62).
?DOC(false).
-spec make_error(scanner(), kdleam@error:kdl_error_tag()) -> kdleam@error:kdl_error().
make_error(S, Tag) ->
kdleam@error:make(erlang:element(5, S), erlang:element(6, S), Tag).
-file("src/kdleam/scanner.gleam", 311).
?DOC(false).
-spec codepoint(binary()) -> integer().
codepoint(Ch) ->
case gleam@string:to_utf_codepoints(Ch) of
[Cp | _] ->
gleam_stdlib:identity(Cp);
[] ->
0
end.
-file("src/kdleam/scanner.gleam", 228).
?DOC(false).
-spec is_newline(binary()) -> boolean().
is_newline(Ch) ->
(((((((Ch =:= <<"\n"/utf8>>) orelse (Ch =:= <<"\r"/utf8>>)) orelse (Ch =:= <<"\r\n"/utf8>>))
orelse (codepoint(Ch) =:= 16#85))
orelse (codepoint(Ch) =:= 16#0B))
orelse (codepoint(Ch) =:= 16#0C))
orelse (codepoint(Ch) =:= 16#2028))
orelse (codepoint(Ch) =:= 16#2029).
-file("src/kdleam/scanner.gleam", 67).
?DOC(false).
-spec advance(scanner()) -> {gleam@option:option(binary()), scanner()}.
advance(S) ->
case peek(S) of
none ->
{none, S};
{some, Ch} ->
Next_pos = erlang:element(4, S) + 1,
case is_newline(Ch) of
true ->
{{some, Ch},
{scanner,
erlang:element(2, S),
erlang:element(3, S),
Next_pos,
erlang:element(5, S) + 1,
1}};
false ->
{{some, Ch},
{scanner,
erlang:element(2, S),
erlang:element(3, S),
Next_pos,
erlang:element(5, S),
erlang:element(6, S) + 1}}
end
end.
-file("src/kdleam/scanner.gleam", 84).
?DOC(false).
-spec expect(scanner(), binary()) -> {ok, scanner()} |
{error, kdleam@error:kdl_error()}.
expect(S, Expected) ->
case peek(S) of
{some, Ch} when Ch =:= Expected ->
{_, Next} = advance(S),
{ok, Next};
{some, Ch@1} ->
{error, make_error(S, {unexpected_char, Ch@1})};
none ->
{error, make_error(S, unexpected_eof)}
end.
-file("src/kdleam/scanner.gleam", 96).
?DOC(false).
-spec consume_newline(scanner()) -> {boolean(), scanner()}.
consume_newline(S) ->
case peek(S) of
{some, Ch} ->
case is_newline(Ch) of
true ->
Was_cr = Ch =:= <<"\r"/utf8>>,
{_, After_first} = advance(S),
case {Was_cr, peek(After_first)} of
{true, {some, <<"\n"/utf8>>}} ->
{true,
{scanner,
erlang:element(2, After_first),
erlang:element(3, After_first),
erlang:element(4, After_first) + 1,
erlang:element(5, After_first),
1}};
{_, _} ->
{true, After_first}
end;
false ->
{false, S}
end;
_ ->
{false, S}
end.
-file("src/kdleam/scanner.gleam", 118).
?DOC(false).
-spec skip_bom(scanner()) -> scanner().
skip_bom(S) ->
case peek(S) of
{some, <<"\x{FEFF}"/utf8>>} ->
{scanner,
erlang:element(2, S),
erlang:element(3, S),
erlang:element(4, S) + 1,
erlang:element(5, S),
1};
_ ->
S
end.
-file("src/kdleam/scanner.gleam", 130).
?DOC(false).
-spec consume_token_chars(scanner(), list(binary())) -> {boolean(), scanner()}.
consume_token_chars(S, Chars) ->
case Chars of
[] ->
{true, S};
[Ch | Rest] ->
case peek(S) of
{some, G} when G =:= Ch ->
{_, Next} = advance(S),
consume_token_chars(Next, Rest);
_ ->
{false, S}
end
end.
-file("src/kdleam/scanner.gleam", 126).
?DOC(false).
-spec consume_token(scanner(), binary()) -> {boolean(), scanner()}.
consume_token(S, Token) ->
consume_token_chars(S, gleam@string:to_graphemes(Token)).
-file("src/kdleam/scanner.gleam", 145).
?DOC(false).
-spec radix_prefixes() -> list({binary(), integer()}).
radix_prefixes() ->
[{<<"0x"/utf8>>, 16},
{<<"0X"/utf8>>, 16},
{<<"0o"/utf8>>, 8},
{<<"0O"/utf8>>, 8},
{<<"0b"/utf8>>, 2},
{<<"0B"/utf8>>, 2}].
-file("src/kdleam/scanner.gleam", 161).
?DOC(false).
-spec radix_of_marker_loop(binary(), list({binary(), integer()})) -> gleam@option:option(integer()).
radix_of_marker_loop(Ch, Prefixes) ->
case Prefixes of
[] ->
none;
[{Prefix, Base} | Rest] ->
case at(gleam@string:to_graphemes(Prefix), 1) =:= {some, Ch} of
true ->
{some, Base};
false ->
radix_of_marker_loop(Ch, Rest)
end
end.
-file("src/kdleam/scanner.gleam", 157).
?DOC(false).
-spec radix_of_marker(binary()) -> gleam@option:option(integer()).
radix_of_marker(Ch) ->
radix_of_marker_loop(Ch, radix_prefixes()).
-file("src/kdleam/scanner.gleam", 176).
?DOC(false).
-spec try_tokens(scanner(), list({binary(), DVB})) -> {gleam@option:option(DVB),
scanner()}.
try_tokens(S, Candidates) ->
case Candidates of
[] ->
{none, S};
[{Token, Value} | Rest] ->
{Ok, Next} = consume_token(S, Token),
case Ok of
true ->
{{some, Value}, Next};
false ->
try_tokens(S, Rest)
end
end.
-file("src/kdleam/scanner.gleam", 203).
?DOC(false).
-spec is_ascii_digit(binary()) -> boolean().
is_ascii_digit(Ch) ->
I = codepoint(Ch),
(I >= 48) andalso (I =< 57).
-file("src/kdleam/scanner.gleam", 209).
?DOC(false).
-spec is_hex_digit(binary()) -> boolean().
is_hex_digit(Ch) ->
I = codepoint(Ch),
(is_ascii_digit(Ch) orelse ((I >= 65) andalso (I =< 70))) orelse ((I >= 97)
andalso (I =< 102)).
-file("src/kdleam/scanner.gleam", 215).
?DOC(false).
-spec is_unicode_space(binary()) -> boolean().
is_unicode_space(Ch) ->
I = codepoint(Ch),
(((((((Ch =:= <<"\t"/utf8>>) orelse (Ch =:= <<" "/utf8>>)) orelse (I =:= 16#00A0))
orelse (I =:= 16#1680))
orelse ((I >= 16#2000) andalso (I =< 16#200A)))
orelse (I =:= 16#202F))
orelse (I =:= 16#205F))
orelse (I =:= 16#3000).
-file("src/kdleam/scanner.gleam", 240).
?DOC(false).
-spec is_disallowed(binary()) -> boolean().
is_disallowed(Ch) ->
I = codepoint(Ch),
(((((((I >= 0) andalso (I =< 8)) orelse ((I >= 16#0E) andalso (I =< 16#1F)))
orelse (I =:= 16#7F))
orelse ((I >= 16#200E) andalso (I =< 16#200F)))
orelse ((I >= 16#202A) andalso (I =< 16#202E)))
orelse ((I >= 16#2066) andalso (I =< 16#2069)))
orelse (I =:= 16#FEFF).
-file("src/kdleam/scanner.gleam", 252).
?DOC(false).
-spec reserved_keywords() -> list(binary()).
reserved_keywords() ->
[<<"true"/utf8>>,
<<"false"/utf8>>,
<<"null"/utf8>>,
<<"inf"/utf8>>,
<<"-inf"/utf8>>,
<<"nan"/utf8>>].
-file("src/kdleam/scanner.gleam", 257).
?DOC(false).
-spec is_reserved_keyword(binary()) -> boolean().
is_reserved_keyword(Value) ->
gleam@list:contains(reserved_keywords(), Value).
-file("src/kdleam/scanner.gleam", 276).
?DOC(false).
-spec starts_like_signed_number(binary(), binary()) -> boolean().
starts_like_signed_number(Value, First) ->
case (First =:= <<"+"/utf8>>) orelse (First =:= <<"-"/utf8>>) of
false ->
false;
true ->
case gleam@string:to_graphemes(Value) of
[_, Second | _] ->
case is_ascii_digit(Second) of
true ->
true;
false ->
case Second =:= <<"."/utf8>> of
true ->
case gleam@string:to_graphemes(Value) of
[_, <<"."/utf8>>, Third | _] ->
is_ascii_digit(Third);
_ ->
false
end;
false ->
false
end
end;
_ ->
false
end
end.
-file("src/kdleam/scanner.gleam", 300).
?DOC(false).
-spec is_identifier_char(binary()) -> boolean().
is_identifier_char(Ch) ->
((not is_unicode_space(Ch) andalso not is_newline(Ch)) andalso not is_disallowed(
Ch
))
andalso not gleam@list:contains(
[<<"\\"/utf8>>,
<<"/"/utf8>>,
<<"("/utf8>>,
<<")"/utf8>>,
<<"{"/utf8>>,
<<"}"/utf8>>,
<<";"/utf8>>,
<<"["/utf8>>,
<<"]"/utf8>>,
<<"\""/utf8>>,
<<"#"/utf8>>,
<<"="/utf8>>],
Ch
).
-file("src/kdleam/scanner.gleam", 262).
?DOC(false).
-spec can_be_bare(binary()) -> boolean().
can_be_bare(Value) ->
case gleam@string:to_graphemes(Value) of
[] ->
false;
[First | Rest] ->
All_ident = gleam@list:all([First | Rest], fun is_identifier_char/1),
First_digit = is_ascii_digit(First),
((All_ident andalso not is_reserved_keyword(Value)) andalso not First_digit)
andalso not starts_like_signed_number(Value, First)
end.
-file("src/kdleam/scanner.gleam", 319).
?DOC(false).
-spec join(list(binary())) -> binary().
join(Chars) ->
gleam@string:join(Chars, <<""/utf8>>).
-file("src/kdleam/scanner.gleam", 324).
?DOC(false).
-spec repeat(binary(), integer()) -> binary().
repeat(S, N) ->
case N =< 0 of
true ->
<<""/utf8>>;
false ->
<<S/binary, (repeat(S, N - 1))/binary>>
end.
-file("src/kdleam/scanner.gleam", 332).
?DOC(false).
-spec clean_underscores(binary()) -> binary().
clean_underscores(Raw) ->
_pipe = Raw,
gleam@string:replace(_pipe, <<"_"/utf8>>, <<""/utf8>>).
-file("src/kdleam/scanner.gleam", 337).
?DOC(false).
-spec to_upper_hex(integer()) -> binary().
to_upper_hex(I) ->
case gleam@int:to_base_string(I, 16) of
{ok, Value} ->
string:uppercase(Value);
{error, _} ->
<<""/utf8>>
end.