-module(william).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/william.gleam").
-export([new/0, tokenise/2, to_highlight/1, highlight/1, to_ansi/1, to_html/1, to_source/1, ignore_whitespace/1, ignore_comments/1]).
-export_type([highlight_token/0, highlight_context/0, token/0, base/0, string_delimiter/0, mode/0, container/0, lexer/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.
-type highlight_token() :: {highlight_error, binary()} |
{highlight_key, binary()} |
{highlight_table, binary()} |
{highlight_string, binary()} |
{highlight_number, binary()} |
{highlight_date_time, binary()} |
{highlight_literal, binary()} |
{highlight_operator, binary()} |
{highlight_punctuation, binary()} |
{highlight_comment, binary()} |
{highlight_whitespace, binary()}.
-type highlight_context() :: normal | table_header.
-type token() :: {end_of_line, binary()} |
{whitespace, binary()} |
{comment, binary()} |
{bare_key, binary()} |
{string, string_delimiter(), binary()} |
{boolean, binary()} |
{integer, base(), binary()} |
{float, binary()} |
{date_time, binary()} |
equal |
dot |
comma |
open_table |
close_table |
open_array_table |
close_array_table |
open_bracket |
close_bracket |
open_brace |
close_brace |
{unexpected, binary()} |
{invalid_number, binary()} |
{unterminated_string, string_delimiter(), binary()}.
-type base() :: binary | octal | decimal | hexadecimal.
-type string_delimiter() :: basic_string |
literal_string |
multiline_basic_string |
multiline_literal_string.
-type mode() :: key_mode | value_mode | after_value_mode | table_mode.
-type container() :: array_container | inline_table_container.
-opaque lexer() :: {lexer,
boolean(),
boolean(),
splitter:splitter(),
splitter:splitter(),
splitter:splitter(),
splitter:splitter(),
splitter:splitter(),
splitter:splitter(),
splitter:splitter()}.
-file("src/william.gleam", 325).
?DOC(
" Create a new Lexer with default settings.\n"
"\n"
" Lexers can be cached and reused to parse many source files efficiently.\n"
).
-spec new() -> lexer().
new() ->
{lexer,
false,
false,
splitter:new([<<"\r\n"/utf8>>, <<"\n"/utf8>>, <<"\r"/utf8>>]),
splitter:new(
[<<"\r\n"/utf8>>,
<<"\n"/utf8>>,
<<"\r"/utf8>>,
<<" "/utf8>>,
<<"\t"/utf8>>,
<<"#"/utf8>>,
<<","/utf8>>,
<<"]"/utf8>>,
<<"}"/utf8>>,
<<"["/utf8>>,
<<"{"/utf8>>,
<<"="/utf8>>,
<<"\""/utf8>>,
<<"'"/utf8>>]
),
splitter:new(
[<<"\r\n"/utf8>>,
<<"\n"/utf8>>,
<<"\r"/utf8>>,
<<" "/utf8>>,
<<"\t"/utf8>>,
<<"#"/utf8>>,
<<","/utf8>>,
<<"]"/utf8>>,
<<"}"/utf8>>]
),
splitter:new(
[<<"\r\n"/utf8>>,
<<"\n"/utf8>>,
<<"\r"/utf8>>,
<<"\\"/utf8>>,
<<"\""/utf8>>]
),
splitter:new(
[<<"\r\n"/utf8>>, <<"\n"/utf8>>, <<"\r"/utf8>>, <<"'"/utf8>>]
),
splitter:new(
[<<"\"\"\"\"\""/utf8>>,
<<"\"\"\"\""/utf8>>,
<<"\"\"\""/utf8>>,
<<"\\"/utf8>>]
),
splitter:new([<<"'''''"/utf8>>, <<"''''"/utf8>>, <<"'''"/utf8>>])}.
-file("src/william.gleam", 594).
-spec emit(lexer(), token(), list(token())) -> list(token()).
emit(Lexer, Token, Acc) ->
case Token of
{whitespace, _} ->
case erlang:element(2, Lexer) of
true ->
Acc;
false ->
[Token | Acc]
end;
{end_of_line, _} ->
case erlang:element(2, Lexer) of
true ->
Acc;
false ->
[Token | Acc]
end;
{comment, _} ->
case erlang:element(3, Lexer) of
true ->
Acc;
false ->
[Token | Acc]
end;
_ ->
[Token | Acc]
end.
-file("src/william.gleam", 784).
-spec unexpected(lexer(), binary(), binary()) -> {token(), binary()}.
unexpected(Lexer, Input, Acc) ->
{Unexpected, Rest} = splitter_ffi:split_before(
erlang:element(6, Lexer),
Input
),
{{unexpected, <<Acc/binary, Unexpected/binary>>}, Rest}.
-file("src/william.gleam", 1311).
-spec invalid_number(lexer(), binary(), binary()) -> {token(), binary()}.
invalid_number(Lexer, Input, Acc) ->
{Unexpected, Rest} = splitter_ffi:split_before(
erlang:element(5, Lexer),
Input
),
{{invalid_number, <<Acc/binary, Unexpected/binary>>}, Rest}.
-file("src/william.gleam", 1320).
-spec is_value_terminator(binary()) -> boolean().
is_value_terminator(Input) ->
case Input of
<<""/utf8>> ->
true;
<<" "/utf8, _/binary>> ->
true;
<<"\t"/utf8, _/binary>> ->
true;
<<"\r\n"/utf8, _/binary>> ->
true;
<<"\n"/utf8, _/binary>> ->
true;
<<"\r"/utf8, _/binary>> ->
true;
<<"#"/utf8, _/binary>> ->
true;
<<","/utf8, _/binary>> ->
true;
<<"]"/utf8, _/binary>> ->
true;
<<"}"/utf8, _/binary>> ->
true;
_ ->
false
end.
-file("src/william.gleam", 1299).
-spec number_end(lexer(), binary(), binary(), fun((binary()) -> token())) -> {token(),
binary()}.
number_end(Lexer, Input, Acc, Token) ->
case is_value_terminator(Input) of
true ->
{Token(Acc), Input};
false ->
invalid_number(Lexer, Input, Acc)
end.
-file("src/william.gleam", 1283).
-spec take_digit(binary()) -> {ok, {binary(), binary()}} | {error, nil}.
take_digit(Input) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
{ok, {<<"0"/utf8>>, Rest}};
<<"1"/utf8, Rest@1/binary>> ->
{ok, {<<"1"/utf8>>, Rest@1}};
<<"2"/utf8, Rest@2/binary>> ->
{ok, {<<"2"/utf8>>, Rest@2}};
<<"3"/utf8, Rest@3/binary>> ->
{ok, {<<"3"/utf8>>, Rest@3}};
<<"4"/utf8, Rest@4/binary>> ->
{ok, {<<"4"/utf8>>, Rest@4}};
<<"5"/utf8, Rest@5/binary>> ->
{ok, {<<"5"/utf8>>, Rest@5}};
<<"6"/utf8, Rest@6/binary>> ->
{ok, {<<"6"/utf8>>, Rest@6}};
<<"7"/utf8, Rest@7/binary>> ->
{ok, {<<"7"/utf8>>, Rest@7}};
<<"8"/utf8, Rest@8/binary>> ->
{ok, {<<"8"/utf8>>, Rest@8}};
<<"9"/utf8, Rest@9/binary>> ->
{ok, {<<"9"/utf8>>, Rest@9}};
_ ->
{error, nil}
end.
-file("src/william.gleam", 1272).
-spec take_two_digits(binary()) -> {ok, {binary(), binary()}} | {error, nil}.
take_two_digits(Input) ->
case take_digit(Input) of
{ok, {First, Rest}} ->
case take_digit(Rest) of
{ok, {Second, Rest@1}} ->
{ok, {<<First/binary, Second/binary>>, Rest@1}};
{error, _} ->
{error, nil}
end;
{error, _} ->
{error, nil}
end.
-file("src/william.gleam", 1260).
-spec offset(lexer(), binary(), binary()) -> {token(), binary()}.
offset(Lexer, Input, Acc) ->
case take_two_digits(Input) of
{ok, {Hour, <<":"/utf8, Rest/binary>>}} ->
case take_two_digits(Rest) of
{ok, {Minute, Rest@1}} ->
number_end(
Lexer,
Rest@1,
<<<<<<Acc/binary, Hour/binary>>/binary, ":"/utf8>>/binary,
Minute/binary>>,
fun(Field@0) -> {date_time, Field@0} end
);
_ ->
invalid_number(Lexer, Input, Acc)
end;
_ ->
invalid_number(Lexer, Input, Acc)
end.
-file("src/william.gleam", 1245).
-spec date_time_end(lexer(), binary(), binary(), boolean()) -> {token(),
binary()}.
date_time_end(Lexer, Input, Acc, Allow_offset) ->
case Input of
<<"Z"/utf8, Rest/binary>> when Allow_offset ->
number_end(
Lexer,
Rest,
<<Acc/binary, "Z"/utf8>>,
fun(Field@0) -> {date_time, Field@0} end
);
<<"z"/utf8, Rest@1/binary>> when Allow_offset ->
number_end(
Lexer,
Rest@1,
<<Acc/binary, "z"/utf8>>,
fun(Field@0) -> {date_time, Field@0} end
);
<<"+"/utf8, Rest@2/binary>> when Allow_offset ->
offset(Lexer, Rest@2, <<Acc/binary, "+"/utf8>>);
<<"-"/utf8, Rest@3/binary>> when Allow_offset ->
offset(Lexer, Rest@3, <<Acc/binary, "-"/utf8>>);
_ ->
number_end(
Lexer,
Input,
Acc,
fun(Field@0) -> {date_time, Field@0} end
)
end.
-file("src/william.gleam", 1224).
-spec fraction_digits(lexer(), binary(), binary(), boolean()) -> {token(),
binary()}.
fraction_digits(Lexer, Input, Acc, Allow_offset) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
fraction_digits(Lexer, Rest, <<Acc/binary, "0"/utf8>>, Allow_offset);
<<"1"/utf8, Rest@1/binary>> ->
fraction_digits(
Lexer,
Rest@1,
<<Acc/binary, "1"/utf8>>,
Allow_offset
);
<<"2"/utf8, Rest@2/binary>> ->
fraction_digits(
Lexer,
Rest@2,
<<Acc/binary, "2"/utf8>>,
Allow_offset
);
<<"3"/utf8, Rest@3/binary>> ->
fraction_digits(
Lexer,
Rest@3,
<<Acc/binary, "3"/utf8>>,
Allow_offset
);
<<"4"/utf8, Rest@4/binary>> ->
fraction_digits(
Lexer,
Rest@4,
<<Acc/binary, "4"/utf8>>,
Allow_offset
);
<<"5"/utf8, Rest@5/binary>> ->
fraction_digits(
Lexer,
Rest@5,
<<Acc/binary, "5"/utf8>>,
Allow_offset
);
<<"6"/utf8, Rest@6/binary>> ->
fraction_digits(
Lexer,
Rest@6,
<<Acc/binary, "6"/utf8>>,
Allow_offset
);
<<"7"/utf8, Rest@7/binary>> ->
fraction_digits(
Lexer,
Rest@7,
<<Acc/binary, "7"/utf8>>,
Allow_offset
);
<<"8"/utf8, Rest@8/binary>> ->
fraction_digits(
Lexer,
Rest@8,
<<Acc/binary, "8"/utf8>>,
Allow_offset
);
<<"9"/utf8, Rest@9/binary>> ->
fraction_digits(
Lexer,
Rest@9,
<<Acc/binary, "9"/utf8>>,
Allow_offset
);
_ ->
date_time_end(Lexer, Input, Acc, Allow_offset)
end.
-file("src/william.gleam", 1203).
-spec fraction(lexer(), binary(), binary(), boolean()) -> {token(), binary()}.
fraction(Lexer, Input, Acc, Allow_offset) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
fraction_digits(Lexer, Rest, <<Acc/binary, "0"/utf8>>, Allow_offset);
<<"1"/utf8, Rest@1/binary>> ->
fraction_digits(
Lexer,
Rest@1,
<<Acc/binary, "1"/utf8>>,
Allow_offset
);
<<"2"/utf8, Rest@2/binary>> ->
fraction_digits(
Lexer,
Rest@2,
<<Acc/binary, "2"/utf8>>,
Allow_offset
);
<<"3"/utf8, Rest@3/binary>> ->
fraction_digits(
Lexer,
Rest@3,
<<Acc/binary, "3"/utf8>>,
Allow_offset
);
<<"4"/utf8, Rest@4/binary>> ->
fraction_digits(
Lexer,
Rest@4,
<<Acc/binary, "4"/utf8>>,
Allow_offset
);
<<"5"/utf8, Rest@5/binary>> ->
fraction_digits(
Lexer,
Rest@5,
<<Acc/binary, "5"/utf8>>,
Allow_offset
);
<<"6"/utf8, Rest@6/binary>> ->
fraction_digits(
Lexer,
Rest@6,
<<Acc/binary, "6"/utf8>>,
Allow_offset
);
<<"7"/utf8, Rest@7/binary>> ->
fraction_digits(
Lexer,
Rest@7,
<<Acc/binary, "7"/utf8>>,
Allow_offset
);
<<"8"/utf8, Rest@8/binary>> ->
fraction_digits(
Lexer,
Rest@8,
<<Acc/binary, "8"/utf8>>,
Allow_offset
);
<<"9"/utf8, Rest@9/binary>> ->
fraction_digits(
Lexer,
Rest@9,
<<Acc/binary, "9"/utf8>>,
Allow_offset
);
_ ->
invalid_number(Lexer, Input, Acc)
end.
-file("src/william.gleam", 1188).
-spec time_seconds(lexer(), binary(), binary(), boolean()) -> {token(),
binary()}.
time_seconds(Lexer, Input, Acc, Allow_offset) ->
case take_two_digits(Input) of
{ok, {Second, <<"."/utf8, Rest/binary>>}} ->
fraction(
Lexer,
Rest,
<<<<Acc/binary, Second/binary>>/binary, "."/utf8>>,
Allow_offset
);
{ok, {Second@1, Rest@1}} ->
date_time_end(
Lexer,
Rest@1,
<<Acc/binary, Second@1/binary>>,
Allow_offset
);
_ ->
invalid_number(Lexer, Input, Acc)
end.
-file("src/william.gleam", 1170).
-spec time_minutes(lexer(), binary(), binary(), boolean()) -> {token(),
binary()}.
time_minutes(Lexer, Input, Acc, Allow_offset) ->
case take_two_digits(Input) of
{ok, {Minute, Rest}} ->
Acc@1 = <<Acc/binary, Minute/binary>>,
case Rest of
<<":"/utf8, Rest@1/binary>> ->
time_seconds(
Lexer,
Rest@1,
<<Acc@1/binary, ":"/utf8>>,
Allow_offset
);
_ ->
date_time_end(Lexer, Rest, Acc@1, Allow_offset)
end;
_ ->
invalid_number(Lexer, Input, Acc)
end.
-file("src/william.gleam", 1162).
-spec date_time(lexer(), binary(), binary()) -> {token(), binary()}.
date_time(Lexer, Input, Acc) ->
case take_two_digits(Input) of
{ok, {Hour, <<":"/utf8, Rest/binary>>}} ->
time_minutes(
Lexer,
Rest,
<<<<Acc/binary, Hour/binary>>/binary, ":"/utf8>>,
true
);
_ ->
invalid_number(Lexer, Input, Acc)
end.
-file("src/william.gleam", 1148).
-spec date_tail(lexer(), binary(), binary()) -> {token(), binary()}.
date_tail(Lexer, Input, Acc) ->
case Input of
<<"T"/utf8, Rest/binary>> ->
date_time(Lexer, Rest, <<Acc/binary, "T"/utf8>>);
<<"t"/utf8, Rest@1/binary>> ->
date_time(Lexer, Rest@1, <<Acc/binary, "t"/utf8>>);
<<" "/utf8, Rest@2/binary>> ->
case take_two_digits(Rest@2) of
{ok, {Hour, <<":"/utf8, Rest@3/binary>>}} ->
time_minutes(
Lexer,
Rest@3,
<<<<<<Acc/binary, " "/utf8>>/binary, Hour/binary>>/binary,
":"/utf8>>,
true
);
_ ->
number_end(
Lexer,
Input,
Acc,
fun(Field@0) -> {date_time, Field@0} end
)
end;
_ ->
number_end(
Lexer,
Input,
Acc,
fun(Field@0) -> {date_time, Field@0} end
)
end.
-file("src/william.gleam", 1137).
-spec date(lexer(), binary(), binary()) -> {token(), binary()}.
date(Lexer, Input, Acc) ->
case take_two_digits(Input) of
{ok, {Month, <<"-"/utf8, Rest/binary>>}} ->
case take_two_digits(Rest) of
{ok, {Day, Rest@1}} ->
date_tail(
Lexer,
Rest@1,
<<<<<<Acc/binary, Month/binary>>/binary, "-"/utf8>>/binary,
Day/binary>>
);
_ ->
invalid_number(Lexer, Input, Acc)
end;
_ ->
invalid_number(Lexer, Input, Acc)
end.
-file("src/william.gleam", 1111).
-spec exponent(lexer(), binary(), binary()) -> {token(), binary()}.
exponent(Lexer, Input, Acc) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
exponent(Lexer, Rest, <<Acc/binary, "0"/utf8>>);
<<"1"/utf8, Rest@1/binary>> ->
exponent(Lexer, Rest@1, <<Acc/binary, "1"/utf8>>);
<<"2"/utf8, Rest@2/binary>> ->
exponent(Lexer, Rest@2, <<Acc/binary, "2"/utf8>>);
<<"3"/utf8, Rest@3/binary>> ->
exponent(Lexer, Rest@3, <<Acc/binary, "3"/utf8>>);
<<"4"/utf8, Rest@4/binary>> ->
exponent(Lexer, Rest@4, <<Acc/binary, "4"/utf8>>);
<<"5"/utf8, Rest@5/binary>> ->
exponent(Lexer, Rest@5, <<Acc/binary, "5"/utf8>>);
<<"6"/utf8, Rest@6/binary>> ->
exponent(Lexer, Rest@6, <<Acc/binary, "6"/utf8>>);
<<"7"/utf8, Rest@7/binary>> ->
exponent(Lexer, Rest@7, <<Acc/binary, "7"/utf8>>);
<<"8"/utf8, Rest@8/binary>> ->
exponent(Lexer, Rest@8, <<Acc/binary, "8"/utf8>>);
<<"9"/utf8, Rest@9/binary>> ->
exponent(Lexer, Rest@9, <<Acc/binary, "9"/utf8>>);
<<"_0"/utf8, Rest@10/binary>> ->
exponent(Lexer, Rest@10, <<Acc/binary, "_0"/utf8>>);
<<"_1"/utf8, Rest@11/binary>> ->
exponent(Lexer, Rest@11, <<Acc/binary, "_1"/utf8>>);
<<"_2"/utf8, Rest@12/binary>> ->
exponent(Lexer, Rest@12, <<Acc/binary, "_2"/utf8>>);
<<"_3"/utf8, Rest@13/binary>> ->
exponent(Lexer, Rest@13, <<Acc/binary, "_3"/utf8>>);
<<"_4"/utf8, Rest@14/binary>> ->
exponent(Lexer, Rest@14, <<Acc/binary, "_4"/utf8>>);
<<"_5"/utf8, Rest@15/binary>> ->
exponent(Lexer, Rest@15, <<Acc/binary, "_5"/utf8>>);
<<"_6"/utf8, Rest@16/binary>> ->
exponent(Lexer, Rest@16, <<Acc/binary, "_6"/utf8>>);
<<"_7"/utf8, Rest@17/binary>> ->
exponent(Lexer, Rest@17, <<Acc/binary, "_7"/utf8>>);
<<"_8"/utf8, Rest@18/binary>> ->
exponent(Lexer, Rest@18, <<Acc/binary, "_8"/utf8>>);
<<"_9"/utf8, Rest@19/binary>> ->
exponent(Lexer, Rest@19, <<Acc/binary, "_9"/utf8>>);
_ ->
number_end(Lexer, Input, Acc, fun(Field@0) -> {float, Field@0} end)
end.
-file("src/william.gleam", 1089).
-spec exponent_start(lexer(), binary(), binary(), binary(), binary()) -> {token(),
binary()}.
exponent_start(Lexer, Before_marker, Input, Acc, Marker) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
exponent(
Lexer,
Rest,
<<<<Acc/binary, Marker/binary>>/binary, "0"/utf8>>
);
<<"1"/utf8, Rest@1/binary>> ->
exponent(
Lexer,
Rest@1,
<<<<Acc/binary, Marker/binary>>/binary, "1"/utf8>>
);
<<"2"/utf8, Rest@2/binary>> ->
exponent(
Lexer,
Rest@2,
<<<<Acc/binary, Marker/binary>>/binary, "2"/utf8>>
);
<<"3"/utf8, Rest@3/binary>> ->
exponent(
Lexer,
Rest@3,
<<<<Acc/binary, Marker/binary>>/binary, "3"/utf8>>
);
<<"4"/utf8, Rest@4/binary>> ->
exponent(
Lexer,
Rest@4,
<<<<Acc/binary, Marker/binary>>/binary, "4"/utf8>>
);
<<"5"/utf8, Rest@5/binary>> ->
exponent(
Lexer,
Rest@5,
<<<<Acc/binary, Marker/binary>>/binary, "5"/utf8>>
);
<<"6"/utf8, Rest@6/binary>> ->
exponent(
Lexer,
Rest@6,
<<<<Acc/binary, Marker/binary>>/binary, "6"/utf8>>
);
<<"7"/utf8, Rest@7/binary>> ->
exponent(
Lexer,
Rest@7,
<<<<Acc/binary, Marker/binary>>/binary, "7"/utf8>>
);
<<"8"/utf8, Rest@8/binary>> ->
exponent(
Lexer,
Rest@8,
<<<<Acc/binary, Marker/binary>>/binary, "8"/utf8>>
);
<<"9"/utf8, Rest@9/binary>> ->
exponent(
Lexer,
Rest@9,
<<<<Acc/binary, Marker/binary>>/binary, "9"/utf8>>
);
_ ->
invalid_number(Lexer, Before_marker, Acc)
end.
-file("src/william.gleam", 1057).
-spec float(lexer(), binary(), binary()) -> {token(), binary()}.
float(Lexer, Input, Acc) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
float(Lexer, Rest, <<Acc/binary, "0"/utf8>>);
<<"1"/utf8, Rest@1/binary>> ->
float(Lexer, Rest@1, <<Acc/binary, "1"/utf8>>);
<<"2"/utf8, Rest@2/binary>> ->
float(Lexer, Rest@2, <<Acc/binary, "2"/utf8>>);
<<"3"/utf8, Rest@3/binary>> ->
float(Lexer, Rest@3, <<Acc/binary, "3"/utf8>>);
<<"4"/utf8, Rest@4/binary>> ->
float(Lexer, Rest@4, <<Acc/binary, "4"/utf8>>);
<<"5"/utf8, Rest@5/binary>> ->
float(Lexer, Rest@5, <<Acc/binary, "5"/utf8>>);
<<"6"/utf8, Rest@6/binary>> ->
float(Lexer, Rest@6, <<Acc/binary, "6"/utf8>>);
<<"7"/utf8, Rest@7/binary>> ->
float(Lexer, Rest@7, <<Acc/binary, "7"/utf8>>);
<<"8"/utf8, Rest@8/binary>> ->
float(Lexer, Rest@8, <<Acc/binary, "8"/utf8>>);
<<"9"/utf8, Rest@9/binary>> ->
float(Lexer, Rest@9, <<Acc/binary, "9"/utf8>>);
<<"_0"/utf8, Rest@10/binary>> ->
float(Lexer, Rest@10, <<Acc/binary, "_0"/utf8>>);
<<"_1"/utf8, Rest@11/binary>> ->
float(Lexer, Rest@11, <<Acc/binary, "_1"/utf8>>);
<<"_2"/utf8, Rest@12/binary>> ->
float(Lexer, Rest@12, <<Acc/binary, "_2"/utf8>>);
<<"_3"/utf8, Rest@13/binary>> ->
float(Lexer, Rest@13, <<Acc/binary, "_3"/utf8>>);
<<"_4"/utf8, Rest@14/binary>> ->
float(Lexer, Rest@14, <<Acc/binary, "_4"/utf8>>);
<<"_5"/utf8, Rest@15/binary>> ->
float(Lexer, Rest@15, <<Acc/binary, "_5"/utf8>>);
<<"_6"/utf8, Rest@16/binary>> ->
float(Lexer, Rest@16, <<Acc/binary, "_6"/utf8>>);
<<"_7"/utf8, Rest@17/binary>> ->
float(Lexer, Rest@17, <<Acc/binary, "_7"/utf8>>);
<<"_8"/utf8, Rest@18/binary>> ->
float(Lexer, Rest@18, <<Acc/binary, "_8"/utf8>>);
<<"_9"/utf8, Rest@19/binary>> ->
float(Lexer, Rest@19, <<Acc/binary, "_9"/utf8>>);
<<"e+"/utf8, Rest@20/binary>> ->
exponent_start(Lexer, Input, Rest@20, Acc, <<"e+"/utf8>>);
<<"e-"/utf8, Rest@21/binary>> ->
exponent_start(Lexer, Input, Rest@21, Acc, <<"e-"/utf8>>);
<<"e"/utf8, Rest@22/binary>> ->
exponent_start(Lexer, Input, Rest@22, Acc, <<"e"/utf8>>);
<<"E+"/utf8, Rest@23/binary>> ->
exponent_start(Lexer, Input, Rest@23, Acc, <<"E+"/utf8>>);
<<"E-"/utf8, Rest@24/binary>> ->
exponent_start(Lexer, Input, Rest@24, Acc, <<"E-"/utf8>>);
<<"E"/utf8, Rest@25/binary>> ->
exponent_start(Lexer, Input, Rest@25, Acc, <<"E"/utf8>>);
_ ->
number_end(Lexer, Input, Acc, fun(Field@0) -> {float, Field@0} end)
end.
-file("src/william.gleam", 1003).
-spec decimal(lexer(), binary(), binary(), integer(), boolean()) -> {token(),
binary()}.
decimal(Lexer, Input, Acc, Digits, Date_time) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
decimal(
Lexer,
Rest,
<<Acc/binary, "0"/utf8>>,
Digits + 1,
Date_time
);
<<"1"/utf8, Rest@1/binary>> ->
decimal(
Lexer,
Rest@1,
<<Acc/binary, "1"/utf8>>,
Digits + 1,
Date_time
);
<<"2"/utf8, Rest@2/binary>> ->
decimal(
Lexer,
Rest@2,
<<Acc/binary, "2"/utf8>>,
Digits + 1,
Date_time
);
<<"3"/utf8, Rest@3/binary>> ->
decimal(
Lexer,
Rest@3,
<<Acc/binary, "3"/utf8>>,
Digits + 1,
Date_time
);
<<"4"/utf8, Rest@4/binary>> ->
decimal(
Lexer,
Rest@4,
<<Acc/binary, "4"/utf8>>,
Digits + 1,
Date_time
);
<<"5"/utf8, Rest@5/binary>> ->
decimal(
Lexer,
Rest@5,
<<Acc/binary, "5"/utf8>>,
Digits + 1,
Date_time
);
<<"6"/utf8, Rest@6/binary>> ->
decimal(
Lexer,
Rest@6,
<<Acc/binary, "6"/utf8>>,
Digits + 1,
Date_time
);
<<"7"/utf8, Rest@7/binary>> ->
decimal(
Lexer,
Rest@7,
<<Acc/binary, "7"/utf8>>,
Digits + 1,
Date_time
);
<<"8"/utf8, Rest@8/binary>> ->
decimal(
Lexer,
Rest@8,
<<Acc/binary, "8"/utf8>>,
Digits + 1,
Date_time
);
<<"9"/utf8, Rest@9/binary>> ->
decimal(
Lexer,
Rest@9,
<<Acc/binary, "9"/utf8>>,
Digits + 1,
Date_time
);
<<"_0"/utf8, Rest@10/binary>> ->
decimal(
Lexer,
Rest@10,
<<Acc/binary, "_0"/utf8>>,
Digits + 1,
false
);
<<"_1"/utf8, Rest@11/binary>> ->
decimal(
Lexer,
Rest@11,
<<Acc/binary, "_1"/utf8>>,
Digits + 1,
false
);
<<"_2"/utf8, Rest@12/binary>> ->
decimal(
Lexer,
Rest@12,
<<Acc/binary, "_2"/utf8>>,
Digits + 1,
false
);
<<"_3"/utf8, Rest@13/binary>> ->
decimal(
Lexer,
Rest@13,
<<Acc/binary, "_3"/utf8>>,
Digits + 1,
false
);
<<"_4"/utf8, Rest@14/binary>> ->
decimal(
Lexer,
Rest@14,
<<Acc/binary, "_4"/utf8>>,
Digits + 1,
false
);
<<"_5"/utf8, Rest@15/binary>> ->
decimal(
Lexer,
Rest@15,
<<Acc/binary, "_5"/utf8>>,
Digits + 1,
false
);
<<"_6"/utf8, Rest@16/binary>> ->
decimal(
Lexer,
Rest@16,
<<Acc/binary, "_6"/utf8>>,
Digits + 1,
false
);
<<"_7"/utf8, Rest@17/binary>> ->
decimal(
Lexer,
Rest@17,
<<Acc/binary, "_7"/utf8>>,
Digits + 1,
false
);
<<"_8"/utf8, Rest@18/binary>> ->
decimal(
Lexer,
Rest@18,
<<Acc/binary, "_8"/utf8>>,
Digits + 1,
false
);
<<"_9"/utf8, Rest@19/binary>> ->
decimal(
Lexer,
Rest@19,
<<Acc/binary, "_9"/utf8>>,
Digits + 1,
false
);
<<".0"/utf8, Rest@20/binary>> ->
float(Lexer, Rest@20, <<Acc/binary, ".0"/utf8>>);
<<".1"/utf8, Rest@21/binary>> ->
float(Lexer, Rest@21, <<Acc/binary, ".1"/utf8>>);
<<".2"/utf8, Rest@22/binary>> ->
float(Lexer, Rest@22, <<Acc/binary, ".2"/utf8>>);
<<".3"/utf8, Rest@23/binary>> ->
float(Lexer, Rest@23, <<Acc/binary, ".3"/utf8>>);
<<".4"/utf8, Rest@24/binary>> ->
float(Lexer, Rest@24, <<Acc/binary, ".4"/utf8>>);
<<".5"/utf8, Rest@25/binary>> ->
float(Lexer, Rest@25, <<Acc/binary, ".5"/utf8>>);
<<".6"/utf8, Rest@26/binary>> ->
float(Lexer, Rest@26, <<Acc/binary, ".6"/utf8>>);
<<".7"/utf8, Rest@27/binary>> ->
float(Lexer, Rest@27, <<Acc/binary, ".7"/utf8>>);
<<".8"/utf8, Rest@28/binary>> ->
float(Lexer, Rest@28, <<Acc/binary, ".8"/utf8>>);
<<".9"/utf8, Rest@29/binary>> ->
float(Lexer, Rest@29, <<Acc/binary, ".9"/utf8>>);
<<"e+"/utf8, Rest@30/binary>> ->
exponent_start(Lexer, Input, Rest@30, Acc, <<"e+"/utf8>>);
<<"e-"/utf8, Rest@31/binary>> ->
exponent_start(Lexer, Input, Rest@31, Acc, <<"e-"/utf8>>);
<<"e"/utf8, Rest@32/binary>> ->
exponent_start(Lexer, Input, Rest@32, Acc, <<"e"/utf8>>);
<<"E+"/utf8, Rest@33/binary>> ->
exponent_start(Lexer, Input, Rest@33, Acc, <<"E+"/utf8>>);
<<"E-"/utf8, Rest@34/binary>> ->
exponent_start(Lexer, Input, Rest@34, Acc, <<"E-"/utf8>>);
<<"E"/utf8, Rest@35/binary>> ->
exponent_start(Lexer, Input, Rest@35, Acc, <<"E"/utf8>>);
<<":"/utf8, Rest@36/binary>> when Date_time andalso (Digits =:= 2) ->
time_minutes(Lexer, Rest@36, <<Acc/binary, ":"/utf8>>, false);
<<"-"/utf8, Rest@37/binary>> when Date_time andalso (Digits =:= 4) ->
date(Lexer, Rest@37, <<Acc/binary, "-"/utf8>>);
_ ->
To_token = fun(Value) -> {integer, decimal, Value} end,
number_end(Lexer, Input, Acc, To_token)
end.
-file("src/william.gleam", 987).
-spec based_integer_end(lexer(), binary(), binary(), base(), boolean()) -> {token(),
binary()}.
based_integer_end(Lexer, Input, Acc, Base, Last_was_underscore) ->
case Last_was_underscore of
false ->
To_token = fun(Value) -> {integer, Base, Value} end,
number_end(Lexer, Input, Acc, To_token);
true ->
invalid_number(Lexer, Input, Acc)
end.
-file("src/william.gleam", 950).
-spec hexadecimal(lexer(), binary(), binary(), boolean()) -> {token(), binary()}.
hexadecimal(Lexer, Input, Acc, Last_was_underscore) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
hexadecimal(Lexer, Rest, <<Acc/binary, "0"/utf8>>, false);
<<"1"/utf8, Rest@1/binary>> ->
hexadecimal(Lexer, Rest@1, <<Acc/binary, "1"/utf8>>, false);
<<"2"/utf8, Rest@2/binary>> ->
hexadecimal(Lexer, Rest@2, <<Acc/binary, "2"/utf8>>, false);
<<"3"/utf8, Rest@3/binary>> ->
hexadecimal(Lexer, Rest@3, <<Acc/binary, "3"/utf8>>, false);
<<"4"/utf8, Rest@4/binary>> ->
hexadecimal(Lexer, Rest@4, <<Acc/binary, "4"/utf8>>, false);
<<"5"/utf8, Rest@5/binary>> ->
hexadecimal(Lexer, Rest@5, <<Acc/binary, "5"/utf8>>, false);
<<"6"/utf8, Rest@6/binary>> ->
hexadecimal(Lexer, Rest@6, <<Acc/binary, "6"/utf8>>, false);
<<"7"/utf8, Rest@7/binary>> ->
hexadecimal(Lexer, Rest@7, <<Acc/binary, "7"/utf8>>, false);
<<"8"/utf8, Rest@8/binary>> ->
hexadecimal(Lexer, Rest@8, <<Acc/binary, "8"/utf8>>, false);
<<"9"/utf8, Rest@9/binary>> ->
hexadecimal(Lexer, Rest@9, <<Acc/binary, "9"/utf8>>, false);
<<"A"/utf8, Rest@10/binary>> ->
hexadecimal(Lexer, Rest@10, <<Acc/binary, "A"/utf8>>, false);
<<"B"/utf8, Rest@11/binary>> ->
hexadecimal(Lexer, Rest@11, <<Acc/binary, "B"/utf8>>, false);
<<"C"/utf8, Rest@12/binary>> ->
hexadecimal(Lexer, Rest@12, <<Acc/binary, "C"/utf8>>, false);
<<"D"/utf8, Rest@13/binary>> ->
hexadecimal(Lexer, Rest@13, <<Acc/binary, "D"/utf8>>, false);
<<"E"/utf8, Rest@14/binary>> ->
hexadecimal(Lexer, Rest@14, <<Acc/binary, "E"/utf8>>, false);
<<"F"/utf8, Rest@15/binary>> ->
hexadecimal(Lexer, Rest@15, <<Acc/binary, "F"/utf8>>, false);
<<"a"/utf8, Rest@16/binary>> ->
hexadecimal(Lexer, Rest@16, <<Acc/binary, "a"/utf8>>, false);
<<"b"/utf8, Rest@17/binary>> ->
hexadecimal(Lexer, Rest@17, <<Acc/binary, "b"/utf8>>, false);
<<"c"/utf8, Rest@18/binary>> ->
hexadecimal(Lexer, Rest@18, <<Acc/binary, "c"/utf8>>, false);
<<"d"/utf8, Rest@19/binary>> ->
hexadecimal(Lexer, Rest@19, <<Acc/binary, "d"/utf8>>, false);
<<"e"/utf8, Rest@20/binary>> ->
hexadecimal(Lexer, Rest@20, <<Acc/binary, "e"/utf8>>, false);
<<"f"/utf8, Rest@21/binary>> ->
hexadecimal(Lexer, Rest@21, <<Acc/binary, "f"/utf8>>, false);
<<"_"/utf8, Rest@22/binary>> when not Last_was_underscore ->
Acc@1 = <<Acc/binary, "_"/utf8>>,
hexadecimal(Lexer, Rest@22, Acc@1, true);
_ ->
based_integer_end(
Lexer,
Input,
Acc,
hexadecimal,
Last_was_underscore
)
end.
-file("src/william.gleam", 927).
-spec octal(lexer(), binary(), binary(), boolean()) -> {token(), binary()}.
octal(Lexer, Input, Acc, Last_was_underscore) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
octal(Lexer, Rest, <<Acc/binary, "0"/utf8>>, false);
<<"1"/utf8, Rest@1/binary>> ->
octal(Lexer, Rest@1, <<Acc/binary, "1"/utf8>>, false);
<<"2"/utf8, Rest@2/binary>> ->
octal(Lexer, Rest@2, <<Acc/binary, "2"/utf8>>, false);
<<"3"/utf8, Rest@3/binary>> ->
octal(Lexer, Rest@3, <<Acc/binary, "3"/utf8>>, false);
<<"4"/utf8, Rest@4/binary>> ->
octal(Lexer, Rest@4, <<Acc/binary, "4"/utf8>>, false);
<<"5"/utf8, Rest@5/binary>> ->
octal(Lexer, Rest@5, <<Acc/binary, "5"/utf8>>, false);
<<"6"/utf8, Rest@6/binary>> ->
octal(Lexer, Rest@6, <<Acc/binary, "6"/utf8>>, false);
<<"7"/utf8, Rest@7/binary>> ->
octal(Lexer, Rest@7, <<Acc/binary, "7"/utf8>>, false);
<<"_"/utf8, Rest@8/binary>> when not Last_was_underscore ->
Acc@1 = <<Acc/binary, "_"/utf8>>,
octal(Lexer, Rest@8, Acc@1, true);
_ ->
based_integer_end(Lexer, Input, Acc, octal, Last_was_underscore)
end.
-file("src/william.gleam", 910).
-spec binary(lexer(), binary(), binary(), boolean()) -> {token(), binary()}.
binary(Lexer, Input, Acc, Last_was_underscore) ->
case Input of
<<"0"/utf8, Rest/binary>> ->
binary(Lexer, Rest, <<Acc/binary, "0"/utf8>>, false);
<<"1"/utf8, Rest@1/binary>> ->
binary(Lexer, Rest@1, <<Acc/binary, "1"/utf8>>, false);
<<"_"/utf8, Rest@2/binary>> when not Last_was_underscore ->
Acc@1 = <<Acc/binary, "_"/utf8>>,
binary(Lexer, Rest@2, Acc@1, true);
_ ->
based_integer_end(Lexer, Input, Acc, binary, Last_was_underscore)
end.
-file("src/william.gleam", 772).
-spec literal_or_unexpected(lexer(), binary(), token(), binary()) -> {token(),
binary()}.
literal_or_unexpected(Lexer, Rest, Token, Original) ->
case is_value_terminator(Rest) of
true ->
{Token, Rest};
false ->
unexpected(Lexer, Original, <<""/utf8>>)
end.
-file("src/william.gleam", 731).
-spec value(lexer(), binary()) -> {token(), binary()}.
value(Lexer, Input) ->
case Input of
<<"true"/utf8, Rest/binary>> ->
literal_or_unexpected(
Lexer,
Rest,
{boolean, <<"true"/utf8>>},
Input
);
<<"false"/utf8, Rest@1/binary>> ->
literal_or_unexpected(
Lexer,
Rest@1,
{boolean, <<"false"/utf8>>},
Input
);
<<"inf"/utf8, Rest@2/binary>> ->
literal_or_unexpected(Lexer, Rest@2, {float, <<"inf"/utf8>>}, Input);
<<"+inf"/utf8, Rest@3/binary>> ->
literal_or_unexpected(
Lexer,
Rest@3,
{float, <<"+inf"/utf8>>},
Input
);
<<"-inf"/utf8, Rest@4/binary>> ->
literal_or_unexpected(
Lexer,
Rest@4,
{float, <<"-inf"/utf8>>},
Input
);
<<"nan"/utf8, Rest@5/binary>> ->
literal_or_unexpected(Lexer, Rest@5, {float, <<"nan"/utf8>>}, Input);
<<"+nan"/utf8, Rest@6/binary>> ->
literal_or_unexpected(
Lexer,
Rest@6,
{float, <<"+nan"/utf8>>},
Input
);
<<"-nan"/utf8, Rest@7/binary>> ->
literal_or_unexpected(
Lexer,
Rest@7,
{float, <<"-nan"/utf8>>},
Input
);
<<"+0b"/utf8, _/binary>> ->
invalid_number(Lexer, Input, <<""/utf8>>);
<<"+0o"/utf8, _/binary>> ->
invalid_number(Lexer, Input, <<""/utf8>>);
<<"+0x"/utf8, _/binary>> ->
invalid_number(Lexer, Input, <<""/utf8>>);
<<"-0b"/utf8, _/binary>> ->
invalid_number(Lexer, Input, <<""/utf8>>);
<<"-0o"/utf8, _/binary>> ->
invalid_number(Lexer, Input, <<""/utf8>>);
<<"-0x"/utf8, _/binary>> ->
invalid_number(Lexer, Input, <<""/utf8>>);
<<"+"/utf8, Rest@8/binary>> ->
case take_digit(Rest@8) of
{ok, {Digit, Rest@9}} ->
decimal(Lexer, Rest@9, <<"+"/utf8, Digit/binary>>, 1, false);
{error, _} ->
invalid_number(Lexer, Rest@8, <<"+"/utf8>>)
end;
<<"-"/utf8, Rest@10/binary>> ->
case take_digit(Rest@10) of
{ok, {Digit@1, Rest@11}} ->
decimal(
Lexer,
Rest@11,
<<"-"/utf8, Digit@1/binary>>,
1,
false
);
{error, _} ->
invalid_number(Lexer, Rest@10, <<"-"/utf8>>)
end;
<<"."/utf8, _/binary>> ->
invalid_number(Lexer, Input, <<""/utf8>>);
<<"0b"/utf8, Rest@12/binary>> ->
binary(Lexer, Rest@12, <<"0b"/utf8>>, true);
<<"0o"/utf8, Rest@13/binary>> ->
octal(Lexer, Rest@13, <<"0o"/utf8>>, true);
<<"0x"/utf8, Rest@14/binary>> ->
hexadecimal(Lexer, Rest@14, <<"0x"/utf8>>, true);
<<"0"/utf8, Rest@15/binary>> ->
decimal(Lexer, Rest@15, <<"0"/utf8>>, 1, true);
<<"1"/utf8, Rest@16/binary>> ->
decimal(Lexer, Rest@16, <<"1"/utf8>>, 1, true);
<<"2"/utf8, Rest@17/binary>> ->
decimal(Lexer, Rest@17, <<"2"/utf8>>, 1, true);
<<"3"/utf8, Rest@18/binary>> ->
decimal(Lexer, Rest@18, <<"3"/utf8>>, 1, true);
<<"4"/utf8, Rest@19/binary>> ->
decimal(Lexer, Rest@19, <<"4"/utf8>>, 1, true);
<<"5"/utf8, Rest@20/binary>> ->
decimal(Lexer, Rest@20, <<"5"/utf8>>, 1, true);
<<"6"/utf8, Rest@21/binary>> ->
decimal(Lexer, Rest@21, <<"6"/utf8>>, 1, true);
<<"7"/utf8, Rest@22/binary>> ->
decimal(Lexer, Rest@22, <<"7"/utf8>>, 1, true);
<<"8"/utf8, Rest@23/binary>> ->
decimal(Lexer, Rest@23, <<"8"/utf8>>, 1, true);
<<"9"/utf8, Rest@24/binary>> ->
decimal(Lexer, Rest@24, <<"9"/utf8>>, 1, true);
_ ->
unexpected(Lexer, Input, <<""/utf8>>)
end.
-file("src/william.gleam", 661).
-spec bare_key(binary(), binary()) -> {binary(), binary()}.
bare_key(Input, Acc) ->
case Input of
<<"A"/utf8, Rest/binary>> ->
bare_key(Rest, <<Acc/binary, "A"/utf8>>);
<<"B"/utf8, Rest@1/binary>> ->
bare_key(Rest@1, <<Acc/binary, "B"/utf8>>);
<<"C"/utf8, Rest@2/binary>> ->
bare_key(Rest@2, <<Acc/binary, "C"/utf8>>);
<<"D"/utf8, Rest@3/binary>> ->
bare_key(Rest@3, <<Acc/binary, "D"/utf8>>);
<<"E"/utf8, Rest@4/binary>> ->
bare_key(Rest@4, <<Acc/binary, "E"/utf8>>);
<<"F"/utf8, Rest@5/binary>> ->
bare_key(Rest@5, <<Acc/binary, "F"/utf8>>);
<<"G"/utf8, Rest@6/binary>> ->
bare_key(Rest@6, <<Acc/binary, "G"/utf8>>);
<<"H"/utf8, Rest@7/binary>> ->
bare_key(Rest@7, <<Acc/binary, "H"/utf8>>);
<<"I"/utf8, Rest@8/binary>> ->
bare_key(Rest@8, <<Acc/binary, "I"/utf8>>);
<<"J"/utf8, Rest@9/binary>> ->
bare_key(Rest@9, <<Acc/binary, "J"/utf8>>);
<<"K"/utf8, Rest@10/binary>> ->
bare_key(Rest@10, <<Acc/binary, "K"/utf8>>);
<<"L"/utf8, Rest@11/binary>> ->
bare_key(Rest@11, <<Acc/binary, "L"/utf8>>);
<<"M"/utf8, Rest@12/binary>> ->
bare_key(Rest@12, <<Acc/binary, "M"/utf8>>);
<<"N"/utf8, Rest@13/binary>> ->
bare_key(Rest@13, <<Acc/binary, "N"/utf8>>);
<<"O"/utf8, Rest@14/binary>> ->
bare_key(Rest@14, <<Acc/binary, "O"/utf8>>);
<<"P"/utf8, Rest@15/binary>> ->
bare_key(Rest@15, <<Acc/binary, "P"/utf8>>);
<<"Q"/utf8, Rest@16/binary>> ->
bare_key(Rest@16, <<Acc/binary, "Q"/utf8>>);
<<"R"/utf8, Rest@17/binary>> ->
bare_key(Rest@17, <<Acc/binary, "R"/utf8>>);
<<"S"/utf8, Rest@18/binary>> ->
bare_key(Rest@18, <<Acc/binary, "S"/utf8>>);
<<"T"/utf8, Rest@19/binary>> ->
bare_key(Rest@19, <<Acc/binary, "T"/utf8>>);
<<"U"/utf8, Rest@20/binary>> ->
bare_key(Rest@20, <<Acc/binary, "U"/utf8>>);
<<"V"/utf8, Rest@21/binary>> ->
bare_key(Rest@21, <<Acc/binary, "V"/utf8>>);
<<"W"/utf8, Rest@22/binary>> ->
bare_key(Rest@22, <<Acc/binary, "W"/utf8>>);
<<"X"/utf8, Rest@23/binary>> ->
bare_key(Rest@23, <<Acc/binary, "X"/utf8>>);
<<"Y"/utf8, Rest@24/binary>> ->
bare_key(Rest@24, <<Acc/binary, "Y"/utf8>>);
<<"Z"/utf8, Rest@25/binary>> ->
bare_key(Rest@25, <<Acc/binary, "Z"/utf8>>);
<<"a"/utf8, Rest@26/binary>> ->
bare_key(Rest@26, <<Acc/binary, "a"/utf8>>);
<<"b"/utf8, Rest@27/binary>> ->
bare_key(Rest@27, <<Acc/binary, "b"/utf8>>);
<<"c"/utf8, Rest@28/binary>> ->
bare_key(Rest@28, <<Acc/binary, "c"/utf8>>);
<<"d"/utf8, Rest@29/binary>> ->
bare_key(Rest@29, <<Acc/binary, "d"/utf8>>);
<<"e"/utf8, Rest@30/binary>> ->
bare_key(Rest@30, <<Acc/binary, "e"/utf8>>);
<<"f"/utf8, Rest@31/binary>> ->
bare_key(Rest@31, <<Acc/binary, "f"/utf8>>);
<<"g"/utf8, Rest@32/binary>> ->
bare_key(Rest@32, <<Acc/binary, "g"/utf8>>);
<<"h"/utf8, Rest@33/binary>> ->
bare_key(Rest@33, <<Acc/binary, "h"/utf8>>);
<<"i"/utf8, Rest@34/binary>> ->
bare_key(Rest@34, <<Acc/binary, "i"/utf8>>);
<<"j"/utf8, Rest@35/binary>> ->
bare_key(Rest@35, <<Acc/binary, "j"/utf8>>);
<<"k"/utf8, Rest@36/binary>> ->
bare_key(Rest@36, <<Acc/binary, "k"/utf8>>);
<<"l"/utf8, Rest@37/binary>> ->
bare_key(Rest@37, <<Acc/binary, "l"/utf8>>);
<<"m"/utf8, Rest@38/binary>> ->
bare_key(Rest@38, <<Acc/binary, "m"/utf8>>);
<<"n"/utf8, Rest@39/binary>> ->
bare_key(Rest@39, <<Acc/binary, "n"/utf8>>);
<<"o"/utf8, Rest@40/binary>> ->
bare_key(Rest@40, <<Acc/binary, "o"/utf8>>);
<<"p"/utf8, Rest@41/binary>> ->
bare_key(Rest@41, <<Acc/binary, "p"/utf8>>);
<<"q"/utf8, Rest@42/binary>> ->
bare_key(Rest@42, <<Acc/binary, "q"/utf8>>);
<<"r"/utf8, Rest@43/binary>> ->
bare_key(Rest@43, <<Acc/binary, "r"/utf8>>);
<<"s"/utf8, Rest@44/binary>> ->
bare_key(Rest@44, <<Acc/binary, "s"/utf8>>);
<<"t"/utf8, Rest@45/binary>> ->
bare_key(Rest@45, <<Acc/binary, "t"/utf8>>);
<<"u"/utf8, Rest@46/binary>> ->
bare_key(Rest@46, <<Acc/binary, "u"/utf8>>);
<<"v"/utf8, Rest@47/binary>> ->
bare_key(Rest@47, <<Acc/binary, "v"/utf8>>);
<<"w"/utf8, Rest@48/binary>> ->
bare_key(Rest@48, <<Acc/binary, "w"/utf8>>);
<<"x"/utf8, Rest@49/binary>> ->
bare_key(Rest@49, <<Acc/binary, "x"/utf8>>);
<<"y"/utf8, Rest@50/binary>> ->
bare_key(Rest@50, <<Acc/binary, "y"/utf8>>);
<<"z"/utf8, Rest@51/binary>> ->
bare_key(Rest@51, <<Acc/binary, "z"/utf8>>);
<<"0"/utf8, Rest@52/binary>> ->
bare_key(Rest@52, <<Acc/binary, "0"/utf8>>);
<<"1"/utf8, Rest@53/binary>> ->
bare_key(Rest@53, <<Acc/binary, "1"/utf8>>);
<<"2"/utf8, Rest@54/binary>> ->
bare_key(Rest@54, <<Acc/binary, "2"/utf8>>);
<<"3"/utf8, Rest@55/binary>> ->
bare_key(Rest@55, <<Acc/binary, "3"/utf8>>);
<<"4"/utf8, Rest@56/binary>> ->
bare_key(Rest@56, <<Acc/binary, "4"/utf8>>);
<<"5"/utf8, Rest@57/binary>> ->
bare_key(Rest@57, <<Acc/binary, "5"/utf8>>);
<<"6"/utf8, Rest@58/binary>> ->
bare_key(Rest@58, <<Acc/binary, "6"/utf8>>);
<<"7"/utf8, Rest@59/binary>> ->
bare_key(Rest@59, <<Acc/binary, "7"/utf8>>);
<<"8"/utf8, Rest@60/binary>> ->
bare_key(Rest@60, <<Acc/binary, "8"/utf8>>);
<<"9"/utf8, Rest@61/binary>> ->
bare_key(Rest@61, <<Acc/binary, "9"/utf8>>);
<<"-"/utf8, Rest@62/binary>> ->
bare_key(Rest@62, <<Acc/binary, "-"/utf8>>);
<<"_"/utf8, Rest@63/binary>> ->
bare_key(Rest@63, <<Acc/binary, "_"/utf8>>);
_ ->
{Acc, Input}
end.
-file("src/william.gleam", 619).
-spec mode_after_string(mode()) -> mode().
mode_after_string(Mode) ->
case Mode of
value_mode ->
after_value_mode;
_ ->
Mode
end.
-file("src/william.gleam", 829).
-spec literal_string(lexer(), binary(), binary()) -> {token(), binary()}.
literal_string(Lexer, Input, Acc) ->
{Before, Delimiter, Rest} = splitter_ffi:split(
erlang:element(8, Lexer),
Input
),
case Delimiter of
<<"'"/utf8>> ->
{{string, literal_string, <<Acc/binary, Before/binary>>}, Rest};
<<"\r\n"/utf8>> ->
{{unterminated_string,
literal_string,
<<Acc/binary, Before/binary>>},
<<Delimiter/binary, Rest/binary>>};
<<"\n"/utf8>> ->
{{unterminated_string,
literal_string,
<<Acc/binary, Before/binary>>},
<<Delimiter/binary, Rest/binary>>};
<<"\r"/utf8>> ->
{{unterminated_string,
literal_string,
<<Acc/binary, Before/binary>>},
<<Delimiter/binary, Rest/binary>>};
<<""/utf8>> ->
{{unterminated_string,
literal_string,
<<Acc/binary, Before/binary>>},
<<""/utf8>>};
_ ->
{{unterminated_string,
literal_string,
<<<<Acc/binary, Before/binary>>/binary, Delimiter/binary>>},
Rest}
end.
-file("src/william.gleam", 891).
-spec multiline_literal_string(lexer(), binary(), binary()) -> {token(),
binary()}.
multiline_literal_string(Lexer, Input, Acc) ->
{Before, Delimiter, Rest} = splitter_ffi:split(
erlang:element(10, Lexer),
Input
),
case Delimiter of
<<"'''''"/utf8>> ->
{{string,
multiline_literal_string,
<<<<Acc/binary, Before/binary>>/binary, "''"/utf8>>},
Rest};
<<"''''"/utf8>> ->
{{string,
multiline_literal_string,
<<<<Acc/binary, Before/binary>>/binary, "'"/utf8>>},
Rest};
<<"'''"/utf8>> ->
{{string, multiline_literal_string, <<Acc/binary, Before/binary>>},
Rest};
<<""/utf8>> ->
{{unterminated_string,
multiline_literal_string,
<<Acc/binary, Before/binary>>},
<<""/utf8>>};
_ ->
{{unterminated_string,
multiline_literal_string,
<<<<Acc/binary, Before/binary>>/binary, Delimiter/binary>>},
Rest}
end.
-file("src/william.gleam", 803).
-spec basic_string_escape(lexer(), binary(), binary()) -> {token(), binary()}.
basic_string_escape(Lexer, Input, Acc) ->
case Input of
<<""/utf8>> ->
{{unterminated_string, basic_string, Acc}, <<""/utf8>>};
<<"\r\n"/utf8, _/binary>> ->
{{unterminated_string, basic_string, Acc}, Input};
<<"\n"/utf8, _/binary>> ->
{{unterminated_string, basic_string, Acc}, Input};
<<"\r"/utf8, _/binary>> ->
{{unterminated_string, basic_string, Acc}, Input};
<<"\""/utf8, Rest/binary>> ->
basic_string(Lexer, Rest, <<Acc/binary, "\""/utf8>>);
<<"\\"/utf8, Rest@1/binary>> ->
basic_string(Lexer, Rest@1, <<Acc/binary, "\\"/utf8>>);
_ ->
{Escaped, Delimiter, Rest@2} = splitter_ffi:split(
erlang:element(7, Lexer),
Input
),
case {Escaped, Delimiter} of
{<<""/utf8>>, <<""/utf8>>} ->
{{unterminated_string, basic_string, Acc}, <<""/utf8>>};
{_, <<""/utf8>>} ->
{{unterminated_string,
basic_string,
<<Acc/binary, Escaped/binary>>},
<<""/utf8>>};
{<<""/utf8>>, _} ->
basic_string(
Lexer,
Rest@2,
<<Acc/binary, Delimiter/binary>>
);
{_, _} ->
basic_string(
Lexer,
<<Delimiter/binary, Rest@2/binary>>,
<<Acc/binary, Escaped/binary>>
)
end
end.
-file("src/william.gleam", 789).
-spec basic_string(lexer(), binary(), binary()) -> {token(), binary()}.
basic_string(Lexer, Input, Acc) ->
{Before, Delimiter, Rest} = splitter_ffi:split(
erlang:element(7, Lexer),
Input
),
case Delimiter of
<<"\""/utf8>> ->
{{string, basic_string, <<Acc/binary, Before/binary>>}, Rest};
<<"\r\n"/utf8>> ->
{{unterminated_string, basic_string, <<Acc/binary, Before/binary>>},
<<Delimiter/binary, Rest/binary>>};
<<"\n"/utf8>> ->
{{unterminated_string, basic_string, <<Acc/binary, Before/binary>>},
<<Delimiter/binary, Rest/binary>>};
<<"\r"/utf8>> ->
{{unterminated_string, basic_string, <<Acc/binary, Before/binary>>},
<<Delimiter/binary, Rest/binary>>};
<<"\\"/utf8>> ->
basic_string_escape(
Lexer,
Rest,
<<<<Acc/binary, Before/binary>>/binary, "\\"/utf8>>
);
<<""/utf8>> ->
{{unterminated_string, basic_string, <<Acc/binary, Before/binary>>},
<<""/utf8>>};
_ ->
{{unterminated_string,
basic_string,
<<<<Acc/binary, Before/binary>>/binary, Delimiter/binary>>},
Rest}
end.
-file("src/william.gleam", 869).
-spec multiline_basic_string_escape(lexer(), binary(), binary()) -> {token(),
binary()}.
multiline_basic_string_escape(Lexer, Input, Acc) ->
case Input of
<<""/utf8>> ->
{{unterminated_string, multiline_basic_string, Acc}, <<""/utf8>>};
<<"\""/utf8, Rest/binary>> ->
multiline_basic_string(Lexer, Rest, <<Acc/binary, "\""/utf8>>);
<<"\\"/utf8, Rest@1/binary>> ->
multiline_basic_string(Lexer, Rest@1, <<Acc/binary, "\\"/utf8>>);
_ ->
{Escaped, Delimiter, Rest@2} = splitter_ffi:split(
erlang:element(9, Lexer),
Input
),
case {Escaped, Delimiter} of
{<<""/utf8>>, <<""/utf8>>} ->
{{unterminated_string, multiline_basic_string, Acc},
<<""/utf8>>};
{_, <<""/utf8>>} ->
{{unterminated_string,
multiline_basic_string,
<<Acc/binary, Escaped/binary>>},
<<""/utf8>>};
{<<""/utf8>>, _} ->
multiline_basic_string(
Lexer,
Rest@2,
<<Acc/binary, Delimiter/binary>>
);
{_, _} ->
multiline_basic_string(
Lexer,
<<Delimiter/binary, Rest@2/binary>>,
<<Acc/binary, Escaped/binary>>
)
end
end.
-file("src/william.gleam", 846).
-spec multiline_basic_string(lexer(), binary(), binary()) -> {token(), binary()}.
multiline_basic_string(Lexer, Input, Acc) ->
{Before, Delimiter, Rest} = splitter_ffi:split(
erlang:element(9, Lexer),
Input
),
case Delimiter of
<<"\"\"\"\"\""/utf8>> ->
{{string,
multiline_basic_string,
<<<<Acc/binary, Before/binary>>/binary, "\"\""/utf8>>},
Rest};
<<"\"\"\"\""/utf8>> ->
{{string,
multiline_basic_string,
<<<<Acc/binary, Before/binary>>/binary, "\""/utf8>>},
Rest};
<<"\"\"\""/utf8>> ->
{{string, multiline_basic_string, <<Acc/binary, Before/binary>>},
Rest};
<<"\\"/utf8>> ->
multiline_basic_string_escape(
Lexer,
Rest,
<<<<Acc/binary, Before/binary>>/binary, "\\"/utf8>>
);
<<""/utf8>> ->
{{unterminated_string,
multiline_basic_string,
<<Acc/binary, Before/binary>>},
<<""/utf8>>};
_ ->
{{unterminated_string,
multiline_basic_string,
<<<<Acc/binary, Before/binary>>/binary, Delimiter/binary>>},
Rest}
end.
-file("src/william.gleam", 640).
-spec mode_after_comma(list(container())) -> mode().
mode_after_comma(Containers) ->
case Containers of
[inline_table_container | _] ->
key_mode;
[array_container | _] ->
value_mode;
[] ->
value_mode
end.
-file("src/william.gleam", 633).
-spec close_inline_table(list(container())) -> list(container()).
close_inline_table(Containers) ->
case Containers of
[inline_table_container | Containers@1] ->
Containers@1;
_ ->
Containers
end.
-file("src/william.gleam", 626).
-spec close_array(list(container())) -> list(container()).
close_array(Containers) ->
case Containers of
[array_container | Containers@1] ->
Containers@1;
_ ->
Containers
end.
-file("src/william.gleam", 656).
-spec comment(lexer(), binary()) -> {token(), binary()}.
comment(Lexer, Input) ->
{Body, Rest} = splitter_ffi:split_before(erlang:element(4, Lexer), Input),
{{comment, <<"#"/utf8, Body/binary>>}, Rest}.
-file("src/william.gleam", 648).
-spec whitespace(binary(), binary()) -> {token(), binary()}.
whitespace(Input, Acc) ->
case Input of
<<" "/utf8, Rest/binary>> ->
whitespace(Rest, <<Acc/binary, " "/utf8>>);
<<"\t"/utf8, Rest@1/binary>> ->
whitespace(Rest@1, <<Acc/binary, "\t"/utf8>>);
_ ->
{{whitespace, Acc}, Input}
end.
-file("src/william.gleam", 612).
-spec reset_mode_after_newline(mode(), list(container())) -> mode().
reset_mode_after_newline(Mode, Containers) ->
case Containers of
[] ->
key_mode;
_ ->
Mode
end.
-file("src/william.gleam", 584).
-spec unexpected_token(lexer(), binary(), list(token()), list(container())) -> list(token()).
unexpected_token(Lexer, Input, Acc, Containers) ->
{Token, Rest} = unexpected(Lexer, Input, <<""/utf8>>),
start(
Lexer,
Rest,
emit(Lexer, Token, Acc),
after_value_mode,
Containers,
false
).
-file("src/william.gleam", 574).
-spec value_token(lexer(), binary(), list(token()), list(container())) -> list(token()).
value_token(Lexer, Input, Acc, Containers) ->
{Token, Rest} = value(Lexer, Input),
start(
Lexer,
Rest,
emit(Lexer, Token, Acc),
after_value_mode,
Containers,
false
).
-file("src/william.gleam", 557).
-spec key_token(lexer(), binary(), list(token()), mode(), list(container())) -> list(token()).
key_token(Lexer, Input, Acc, Mode, Containers) ->
{Key, Rest} = bare_key(Input, <<""/utf8>>),
case Key of
<<""/utf8>> ->
unexpected_token(Lexer, Input, Acc, Containers);
_ ->
Acc@1 = emit(Lexer, {bare_key, Key}, Acc),
start(Lexer, Rest, Acc@1, Mode, Containers, false)
end.
-file("src/william.gleam", 380).
-spec start(
lexer(),
binary(),
list(token()),
mode(),
list(container()),
boolean()
) -> list(token()).
start(Lexer, Input, Acc, Mode, Containers, At_line_start) ->
case Input of
<<""/utf8>> ->
lists:reverse(Acc);
<<"\r\n"/utf8, Rest/binary>> ->
Acc@1 = emit(Lexer, {end_of_line, <<"\r\n"/utf8>>}, Acc),
Mode@1 = reset_mode_after_newline(Mode, Containers),
start(Lexer, Rest, Acc@1, Mode@1, Containers, true);
<<"\n"/utf8, Rest@1/binary>> ->
Acc@2 = emit(Lexer, {end_of_line, <<"\n"/utf8>>}, Acc),
Mode@2 = reset_mode_after_newline(Mode, Containers),
start(Lexer, Rest@1, Acc@2, Mode@2, Containers, true);
<<"\r"/utf8, Rest@2/binary>> ->
Acc@3 = emit(Lexer, {end_of_line, <<"\r"/utf8>>}, Acc),
Mode@3 = reset_mode_after_newline(Mode, Containers),
start(Lexer, Rest@2, Acc@3, Mode@3, Containers, true);
<<" "/utf8, Rest@3/binary>> ->
{Token, Rest@4} = whitespace(Rest@3, <<" "/utf8>>),
Acc@4 = emit(Lexer, Token, Acc),
start(Lexer, Rest@4, Acc@4, Mode, Containers, At_line_start);
<<"\t"/utf8, Rest@5/binary>> ->
{Token@1, Rest@6} = whitespace(Rest@5, <<"\t"/utf8>>),
Acc@5 = emit(Lexer, Token@1, Acc),
start(Lexer, Rest@6, Acc@5, Mode, Containers, At_line_start);
<<"#"/utf8, Rest@7/binary>> ->
{Token@2, Rest@8} = comment(Lexer, Rest@7),
Acc@6 = emit(Lexer, Token@2, Acc),
start(Lexer, Rest@8, Acc@6, Mode, Containers, At_line_start);
<<"[["/utf8, Rest@9/binary>> ->
case {At_line_start, Containers} of
{true, []} ->
Acc@7 = emit(Lexer, open_array_table, Acc),
start(Lexer, Rest@9, Acc@7, table_mode, Containers, false);
{_, _} ->
Acc@8 = emit(Lexer, open_bracket, Acc),
Input@1 = <<"["/utf8, Rest@9/binary>>,
Containers@1 = [array_container | Containers],
start(
Lexer,
Input@1,
Acc@8,
value_mode,
Containers@1,
false
)
end;
<<"["/utf8, Rest@10/binary>> ->
case {At_line_start, Containers} of
{true, []} ->
Acc@9 = emit(Lexer, open_table, Acc),
start(Lexer, Rest@10, Acc@9, table_mode, Containers, false);
{_, _} ->
Acc@10 = emit(Lexer, open_bracket, Acc),
Containers@2 = [array_container | Containers],
start(
Lexer,
Rest@10,
Acc@10,
value_mode,
Containers@2,
false
)
end;
<<"]]"/utf8, Rest@11/binary>> ->
case Mode of
table_mode ->
Acc@11 = emit(Lexer, close_array_table, Acc),
start(
Lexer,
Rest@11,
Acc@11,
after_value_mode,
Containers,
false
);
_ ->
Acc@12 = emit(Lexer, close_bracket, Acc),
Acc@13 = emit(Lexer, close_bracket, Acc@12),
Containers@3 = close_array(close_array(Containers)),
start(
Lexer,
Rest@11,
Acc@13,
after_value_mode,
Containers@3,
false
)
end;
<<"]"/utf8, Rest@12/binary>> ->
case Mode of
table_mode ->
Acc@14 = emit(Lexer, close_table, Acc),
start(
Lexer,
Rest@12,
Acc@14,
after_value_mode,
Containers,
false
);
_ ->
Acc@15 = emit(Lexer, close_bracket, Acc),
Containers@4 = close_array(Containers),
start(
Lexer,
Rest@12,
Acc@15,
after_value_mode,
Containers@4,
false
)
end;
<<"{"/utf8, Rest@13/binary>> ->
Acc@16 = emit(Lexer, open_brace, Acc),
Containers@5 = [inline_table_container | Containers],
start(Lexer, Rest@13, Acc@16, key_mode, Containers@5, false);
<<"}"/utf8, Rest@14/binary>> ->
Acc@17 = emit(Lexer, close_brace, Acc),
Containers@6 = close_inline_table(Containers),
start(Lexer, Rest@14, Acc@17, after_value_mode, Containers@6, false);
<<","/utf8, Rest@15/binary>> ->
Acc@18 = emit(Lexer, comma, Acc),
start(
Lexer,
Rest@15,
Acc@18,
mode_after_comma(Containers),
Containers,
false
);
<<"="/utf8, Rest@16/binary>> ->
Acc@19 = emit(Lexer, equal, Acc),
start(Lexer, Rest@16, Acc@19, value_mode, Containers, false);
<<"."/utf8, Rest@17/binary>> ->
case Mode of
key_mode ->
Acc@20 = emit(Lexer, dot, Acc),
start(Lexer, Rest@17, Acc@20, Mode, Containers, false);
table_mode ->
Acc@20 = emit(Lexer, dot, Acc),
start(Lexer, Rest@17, Acc@20, Mode, Containers, false);
value_mode ->
value_token(Lexer, Input, Acc, Containers);
after_value_mode ->
unexpected_token(Lexer, Input, Acc, Containers)
end;
<<"\"\"\""/utf8, Rest@18/binary>> ->
{Token@3, Rest@19} = multiline_basic_string(
Lexer,
Rest@18,
<<""/utf8>>
),
Mode@4 = mode_after_string(Mode),
start(
Lexer,
Rest@19,
emit(Lexer, Token@3, Acc),
Mode@4,
Containers,
false
);
<<"\""/utf8, Rest@20/binary>> ->
{Token@4, Rest@21} = basic_string(Lexer, Rest@20, <<""/utf8>>),
Mode@5 = mode_after_string(Mode),
start(
Lexer,
Rest@21,
emit(Lexer, Token@4, Acc),
Mode@5,
Containers,
false
);
<<"'''"/utf8, Rest@22/binary>> ->
{Token@5, Rest@23} = multiline_literal_string(
Lexer,
Rest@22,
<<""/utf8>>
),
Mode@6 = mode_after_string(Mode),
start(
Lexer,
Rest@23,
emit(Lexer, Token@5, Acc),
Mode@6,
Containers,
false
);
<<"'"/utf8, Rest@24/binary>> ->
{Token@6, Rest@25} = literal_string(Lexer, Rest@24, <<""/utf8>>),
Mode@7 = mode_after_string(Mode),
start(
Lexer,
Rest@25,
emit(Lexer, Token@6, Acc),
Mode@7,
Containers,
false
);
_ ->
case Mode of
key_mode ->
key_token(Lexer, Input, Acc, Mode, Containers);
table_mode ->
key_token(Lexer, Input, Acc, Mode, Containers);
value_mode ->
value_token(Lexer, Input, Acc, Containers);
after_value_mode ->
unexpected_token(Lexer, Input, Acc, Containers)
end
end.
-file("src/william.gleam", 370).
?DOC(" Parse TOML source code into a list of lexer tokens.\n").
-spec tokenise(lexer(), binary()) -> list(token()).
tokenise(Lexer, Input) ->
case Input of
<<"\x{FEFF}"/utf8, Rest/binary>> ->
Acc = emit(Lexer, {whitespace, <<"\x{FEFF}"/utf8>>}, []),
start(Lexer, Rest, Acc, key_mode, [], true);
_ ->
start(Lexer, Input, [], key_mode, [], true)
end.
-file("src/william.gleam", 1328).
-spec string_delimiter(string_delimiter()) -> binary().
string_delimiter(Delimiter) ->
case Delimiter of
basic_string ->
<<"\""/utf8>>;
literal_string ->
<<"'"/utf8>>;
multiline_basic_string ->
<<"\"\"\""/utf8>>;
multiline_literal_string ->
<<"'''"/utf8>>
end.
-file("src/william.gleam", 176).
-spec highlight_normal_token(token()) -> highlight_token().
highlight_normal_token(Token) ->
case Token of
{bare_key, Name} ->
{highlight_key, Name};
{boolean, Value} ->
{highlight_literal, Value};
close_array_table ->
{highlight_punctuation, <<"]]"/utf8>>};
close_brace ->
{highlight_punctuation, <<"}"/utf8>>};
close_bracket ->
{highlight_punctuation, <<"]"/utf8>>};
close_table ->
{highlight_punctuation, <<"]"/utf8>>};
comma ->
{highlight_punctuation, <<","/utf8>>};
{comment, Str} ->
{highlight_comment, Str};
{date_time, Value@1} ->
{highlight_date_time, Value@1};
dot ->
{highlight_operator, <<"."/utf8>>};
{end_of_line, Str@1} ->
{highlight_whitespace, Str@1};
equal ->
{highlight_operator, <<"="/utf8>>};
{float, Value@2} ->
{highlight_number, Value@2};
{integer, _, Value@3} ->
{highlight_number, Value@3};
{invalid_number, Str@2} ->
{highlight_error, Str@2};
open_array_table ->
{highlight_punctuation, <<"[["/utf8>>};
open_brace ->
{highlight_punctuation, <<"{"/utf8>>};
open_bracket ->
{highlight_punctuation, <<"["/utf8>>};
open_table ->
{highlight_punctuation, <<"["/utf8>>};
{string, Delimiter, Value@4} ->
{highlight_string,
<<<<(string_delimiter(Delimiter))/binary, Value@4/binary>>/binary,
(string_delimiter(Delimiter))/binary>>};
{unexpected, Str@3} ->
{highlight_error, Str@3};
{unterminated_string, Delimiter@1, Value@5} ->
{highlight_error,
<<(string_delimiter(Delimiter@1))/binary, Value@5/binary>>};
{whitespace, Str@4} ->
{highlight_whitespace, Str@4}
end.
-file("src/william.gleam", 42).
-spec highlight_loop(
list(token()),
highlight_context(),
list(highlight_token())
) -> list(highlight_token()).
highlight_loop(Tokens, Context, Acc) ->
case {Context, Tokens} of
{_, []} ->
Acc;
{_, [open_table | Tokens@1]} ->
highlight_loop(
Tokens@1,
table_header,
[{highlight_punctuation, <<"["/utf8>>} | Acc]
);
{_, [open_array_table | Tokens@2]} ->
highlight_loop(
Tokens@2,
table_header,
[{highlight_punctuation, <<"[["/utf8>>} | Acc]
);
{table_header, [close_table | Tokens@3]} ->
highlight_loop(
Tokens@3,
normal,
[{highlight_punctuation, <<"]"/utf8>>} | Acc]
);
{table_header, [close_array_table | Tokens@4]} ->
highlight_loop(
Tokens@4,
normal,
[{highlight_punctuation, <<"]]"/utf8>>} | Acc]
);
{table_header, [{bare_key, Name} | Tokens@5]} ->
highlight_loop(
Tokens@5,
table_header,
[{highlight_table, Name} | Acc]
);
{table_header, [{string, Delimiter, Value} | Tokens@6]} ->
Delim = string_delimiter(Delimiter),
Table = {highlight_table,
<<<<Delim/binary, Value/binary>>/binary, Delim/binary>>},
highlight_loop(Tokens@6, table_header, [Table | Acc]);
{normal, [{string, Delimiter@1, Value@1}, equal | Tokens@7]} ->
Delim@1 = string_delimiter(Delimiter@1),
Key = {highlight_key,
<<<<Delim@1/binary, Value@1/binary>>/binary, Delim@1/binary>>},
highlight_loop([equal | Tokens@7], normal, [Key | Acc]);
{normal,
[{string, Delimiter@2, Value@2}, {whitespace, Ws}, equal | Tokens@8]} ->
Delim@2 = string_delimiter(Delimiter@2),
Key@1 = {highlight_key,
<<<<Delim@2/binary, Value@2/binary>>/binary, Delim@2/binary>>},
highlight_loop(
[{whitespace, Ws}, equal | Tokens@8],
normal,
[Key@1 | Acc]
);
{normal, [{string, Delimiter@3, Value@3}, dot | Tokens@9]} ->
Delim@3 = string_delimiter(Delimiter@3),
Key@2 = {highlight_key,
<<<<Delim@3/binary, Value@3/binary>>/binary, Delim@3/binary>>},
highlight_loop([dot | Tokens@9], normal, [Key@2 | Acc]);
{normal,
[{string, Delimiter@4, Value@4},
{whitespace, Ws@1},
dot |
Tokens@10]} ->
Delim@4 = string_delimiter(Delimiter@4),
Key@3 = {highlight_key,
<<<<Delim@4/binary, Value@4/binary>>/binary, Delim@4/binary>>},
highlight_loop(
[{whitespace, Ws@1}, dot | Tokens@10],
normal,
[Key@3 | Acc]
);
{_, [Token | Tokens@11]} ->
highlight_loop(
Tokens@11,
Context,
[highlight_normal_token(Token) | Acc]
)
end.
-file("src/william.gleam", 36).
?DOC(" Convert a list of lexer tokens into a list of `HighlightToken`.\n").
-spec to_highlight(list(token())) -> list(highlight_token()).
to_highlight(Tokens) ->
Tokens@1 = highlight_loop(Tokens, normal, []),
lists:reverse(Tokens@1).
-file("src/william.gleam", 31).
?DOC(
" Parse TOML source code into a list of `HighlightToken` using default\n"
" settings.\n"
"\n"
" The resulting token list can be highlighted by using functions like\n"
" `to_ansi`, `to_html`, or by pattern matching on it yourself.\n"
).
-spec highlight(binary()) -> list(highlight_token()).
highlight(Source) ->
to_highlight(tokenise(new(), Source)).
-file("src/william.gleam", 96).
?DOC(
" Format a list of `HighlightToken` into ANSI highlighting for display in a\n"
" terminal.\n"
).
-spec to_ansi(list(highlight_token())) -> binary().
to_ansi(Tokens) ->
gleam@list:fold(
Tokens,
<<""/utf8>>,
fun(Acc, Token) ->
Highlighted = case Token of
{highlight_comment, Str} ->
gleam_community@ansi:italic(gleam_community@ansi:gray(Str));
{highlight_date_time, Str@1} ->
gleam_community@ansi:blue(Str@1);
{highlight_error, Str@2} ->
gleam_community@ansi:bg_bright_red(
gleam_community@ansi:white(Str@2)
);
{highlight_key, Str@3} ->
gleam_community@ansi:yellow(Str@3);
{highlight_literal, Str@4} ->
gleam_community@ansi:green(Str@4);
{highlight_number, Str@5} ->
gleam_community@ansi:green(Str@5);
{highlight_operator, Str@6} ->
gleam_community@ansi:magenta(Str@6);
{highlight_punctuation, Str@7} ->
Str@7;
{highlight_string, Str@8} ->
gleam_community@ansi:green(Str@8);
{highlight_table, Str@9} ->
gleam_community@ansi:cyan(Str@9);
{highlight_whitespace, Str@10} ->
Str@10
end,
<<Acc/binary, Highlighted/binary>>
end
).
-file("src/william.gleam", 208).
-spec span(binary(), binary()) -> binary().
span(Class, Text) ->
<<<<<<<<"<span class=\""/utf8, Class/binary>>/binary, "\">"/utf8>>/binary,
(houdini:escape(Text))/binary>>/binary,
"</span>"/utf8>>.
-file("src/william.gleam", 156).
?DOC(
" Format a list of `HighlightToken` as HTML.\n"
"\n"
" Each non-whitespace token is wrapped inside a `<span>` tag with a class\n"
" indicating the type.\n"
"\n"
" Class names are based on [`contour`](https://hexdocs.pm/contour):\n"
"\n"
" | Token | CSS class |\n"
" | ----------- | -------------- |\n"
" | Comment | hl-comment |\n"
" | Date/time | hl-function |\n"
" | Error | hl-error |\n"
" | Key | hl-attribute |\n"
" | Literal | hl-literal |\n"
" | Number | hl-number |\n"
" | Operator | hl-operator |\n"
" | Punctuation | hl-punctuation |\n"
" | String | hl-string |\n"
" | Table name | hl-module |\n"
" | Whitespace | no class |\n"
"\n"
" Place the output within\n"
" `<pre><code class=\"language-toml\">...</code></pre>` and add styling for\n"
" these CSS classes to get highlighting on your website. Here's some CSS you\n"
" could use:\n"
"\n"
" ```css\n"
" pre code {\n"
" .hl-comment { color: #d4d4d4; font-style: italic }\n"
" .hl-function { color: #9ce7ff }\n"
" .hl-attribute { color: #ffd596 }\n"
" .hl-operator { color: #ffaff3 }\n"
" .hl-string { color: #c8ffa7 }\n"
" .hl-number { color: #c8ffa7 }\n"
" .hl-literal { color: #c8ffa7 }\n"
" .hl-module { color: #ffddfa }\n"
" .hl-punctuation { color: inherit }\n"
" .hl-error { background: red; color: white }\n"
" }\n"
" ```\n"
).
-spec to_html(list(highlight_token())) -> binary().
to_html(Tokens) ->
gleam@list:fold(
Tokens,
<<""/utf8>>,
fun(Acc, Token) ->
Highlighted = case Token of
{highlight_comment, Str} ->
span(<<"hl-comment"/utf8>>, Str);
{highlight_date_time, Str@1} ->
span(<<"hl-function"/utf8>>, Str@1);
{highlight_error, Str@2} ->
span(<<"hl-error"/utf8>>, Str@2);
{highlight_key, Str@3} ->
span(<<"hl-attribute"/utf8>>, Str@3);
{highlight_literal, Str@4} ->
span(<<"hl-literal"/utf8>>, Str@4);
{highlight_number, Str@5} ->
span(<<"hl-number"/utf8>>, Str@5);
{highlight_operator, Str@6} ->
span(<<"hl-operator"/utf8>>, Str@6);
{highlight_punctuation, Str@7} ->
span(<<"hl-punctuation"/utf8>>, Str@7);
{highlight_string, Str@8} ->
span(<<"hl-string"/utf8>>, Str@8);
{highlight_table, Str@9} ->
span(<<"hl-module"/utf8>>, Str@9);
{highlight_whitespace, Str@10} ->
Str@10
end,
<<Acc/binary, Highlighted/binary>>
end
).
-file("src/william.gleam", 218).
-spec token_source(token()) -> binary().
token_source(Token) ->
case Token of
{bare_key, Name} ->
Name;
{boolean, Value} ->
Value;
close_array_table ->
<<"]]"/utf8>>;
close_brace ->
<<"}"/utf8>>;
close_bracket ->
<<"]"/utf8>>;
close_table ->
<<"]"/utf8>>;
comma ->
<<","/utf8>>;
{comment, Str} ->
Str;
{date_time, Value@1} ->
Value@1;
dot ->
<<"."/utf8>>;
{end_of_line, Str@1} ->
Str@1;
equal ->
<<"="/utf8>>;
{float, Value@2} ->
Value@2;
{integer, _, Value@3} ->
Value@3;
{invalid_number, Str@2} ->
Str@2;
open_array_table ->
<<"[["/utf8>>;
open_brace ->
<<"{"/utf8>>;
open_bracket ->
<<"["/utf8>>;
open_table ->
<<"["/utf8>>;
{string, Delimiter, Value@4} ->
<<<<(string_delimiter(Delimiter))/binary, Value@4/binary>>/binary,
(string_delimiter(Delimiter))/binary>>;
{unexpected, Str@3} ->
Str@3;
{unterminated_string, Delimiter@1, Value@5} ->
<<(string_delimiter(Delimiter@1))/binary, Value@5/binary>>;
{whitespace, Str@4} ->
Str@4
end.
-file("src/william.gleam", 213).
?DOC(" Convert a list of tokens back into their source representation.\n").
-spec to_source(list(token())) -> binary().
to_source(Tokens) ->
gleam@list:fold(
Tokens,
<<""/utf8>>,
fun(Acc, Token) -> <<Acc/binary, (token_source(Token))/binary>> end
).
-file("src/william.gleam", 360).
?DOC(" Skip whitespace and end-of-line tokens in the resulting token list.\n").
-spec ignore_whitespace(lexer()) -> lexer().
ignore_whitespace(Lexer) ->
{lexer,
true,
erlang:element(3, Lexer),
erlang:element(4, Lexer),
erlang:element(5, Lexer),
erlang:element(6, Lexer),
erlang:element(7, Lexer),
erlang:element(8, Lexer),
erlang:element(9, Lexer),
erlang:element(10, Lexer)}.
-file("src/william.gleam", 365).
?DOC(" Skip comment tokens in the resulting token list.\n").
-spec ignore_comments(lexer()) -> lexer().
ignore_comments(Lexer) ->
{lexer,
erlang:element(2, Lexer),
true,
erlang:element(4, Lexer),
erlang:element(5, Lexer),
erlang:element(6, Lexer),
erlang:element(7, Lexer),
erlang:element(8, Lexer),
erlang:element(9, Lexer),
erlang:element(10, Lexer)}.