Current section
Files
Jump to
Current section
Files
src/handles@internal@tokenizer.erl
-module(handles@internal@tokenizer).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([do_run/3, run/1]).
-export_type([token/0, action/0]).
-type token() :: {constant, integer(), binary()} |
{property, integer(), list(binary())} |
{partial, integer(), binary(), list(binary())} |
{block_start, integer(), handles@internal@block:kind(), list(binary())} |
{block_end, integer(), handles@internal@block:kind()}.
-type action() :: {add_token, binary(), integer(), token()} |
{stop, handles@error:tokenizer_error()} |
done.
-spec split_body(binary()) -> list(binary()).
split_body(Body) ->
_pipe = Body,
_pipe@1 = gleam@string:trim(_pipe),
_pipe@2 = gleam@string:split(_pipe@1, <<" "/utf8>>),
gleam@list:filter(
_pipe@2,
fun(It) ->
begin
_pipe@3 = It,
_pipe@4 = gleam@string:trim(_pipe@3),
gleam@string:length(_pipe@4)
end
> 0
end
).
-spec split_arg(binary()) -> list(binary()).
split_arg(Arg) ->
case begin
_pipe = Arg,
gleam@string:trim(_pipe)
end of
<<"."/utf8>> ->
[];
Arg@1 ->
gleam@string:split(Arg@1, <<"."/utf8>>)
end.
-spec capture_tag_body(binary(), integer()) -> {ok, {binary(), binary()}} |
{error, handles@error:tokenizer_error()}.
capture_tag_body(Input, Index) ->
_pipe = Input,
_pipe@1 = gleam@string:split_once(_pipe, <<"}}"/utf8>>),
gleam@result:map_error(_pipe@1, fun(_) -> {unbalanced_tag, Index + 2} end).
-spec tokenize(binary(), integer()) -> action().
tokenize(Input, Index) ->
case Input of
<<""/utf8>> ->
done;
<<"{{>"/utf8, Rest/binary>> ->
case capture_tag_body(Rest, Index) of
{error, Err} ->
{stop, Err};
{ok, {Body, Rest@1}} ->
case split_body(Body) of
[] ->
{stop, {missing_partial_id, Index + 2}};
[_] ->
{stop, {missing_argument, Index + 2}};
[Id, Arg] ->
{add_token,
Rest@1,
(Index + 5) + gleam@string:length(Body),
{partial, Index + 2, Id, split_arg(Arg)}};
_ ->
{stop, {unexpected_multiple_arguments, Index + 2}}
end
end;
<<"{{#"/utf8, Rest@2/binary>> ->
case capture_tag_body(Rest@2, Index) of
{error, Err@1} ->
{stop, Err@1};
{ok, {Body@1, Rest@3}} ->
case split_body(Body@1) of
[] ->
{stop, {missing_block_kind, Index + 2}};
[_] ->
{stop, {missing_argument, Index + 2}};
[<<"if"/utf8>>, Arg@1] ->
{add_token,
Rest@3,
(Index + 5) + gleam@string:length(Body@1),
{block_start, Index + 2, 'if', split_arg(Arg@1)}};
[<<"unless"/utf8>>, Arg@2] ->
{add_token,
Rest@3,
(Index + 5) + gleam@string:length(Body@1),
{block_start,
Index + 2,
unless,
split_arg(Arg@2)}};
[<<"each"/utf8>>, Arg@3] ->
{add_token,
Rest@3,
(Index + 5) + gleam@string:length(Body@1),
{block_start, Index + 2, each, split_arg(Arg@3)}};
[_, _] ->
{stop, {unexpected_block_kind, Index + 2}};
_ ->
{stop, {unexpected_multiple_arguments, Index + 2}}
end
end;
<<"{{/"/utf8, Rest@4/binary>> ->
case capture_tag_body(Rest@4, Index) of
{error, Err@2} ->
{stop, Err@2};
{ok, {Body@2, Rest@5}} ->
case split_body(Body@2) of
[] ->
{stop, {missing_block_kind, Index + 2}};
[_, _] ->
{stop, {unexpected_argument, Index + 2}};
[<<"if"/utf8>>] ->
{add_token,
Rest@5,
(Index + 5) + gleam@string:length(Body@2),
{block_end, Index + 2, 'if'}};
[<<"unless"/utf8>>] ->
{add_token,
Rest@5,
(Index + 5) + gleam@string:length(Body@2),
{block_end, Index + 2, unless}};
[<<"each"/utf8>>] ->
{add_token,
Rest@5,
(Index + 5) + gleam@string:length(Body@2),
{block_end, Index + 2, each}};
[_] ->
{stop, {unexpected_block_kind, Index + 2}};
_ ->
{stop, {unexpected_argument, Index + 2}}
end
end;
<<"{{"/utf8, Rest@6/binary>> ->
case capture_tag_body(Rest@6, Index) of
{error, Err@3} ->
{stop, Err@3};
{ok, {Body@3, Rest@7}} ->
case split_body(Body@3) of
[] ->
{stop, {missing_argument, Index + 2}};
[Arg@4] ->
{add_token,
Rest@7,
(Index + 4) + gleam@string:length(Body@3),
{property, Index + 2, split_arg(Arg@4)}};
_ ->
{stop, {unexpected_multiple_arguments, Index + 2}}
end
end;
_ ->
case begin
_pipe = Input,
_pipe@1 = gleam@string:split_once(_pipe, <<"{{"/utf8>>),
gleam@result:map(
_pipe@1,
fun(_capture) ->
gleam@pair:map_second(
_capture,
fun(It) -> <<"{{"/utf8, It/binary>> end
)
end
)
end of
{ok, {Str, Rest@8}} ->
{add_token,
Rest@8,
Index + gleam@string:length(Str),
{constant, Index, Str}};
_ ->
{add_token,
<<""/utf8>>,
Index + gleam@string:length(Input),
{constant, Index, Input}}
end
end.
-spec do_run(binary(), integer(), list(token())) -> {ok, list(token())} |
{error, handles@error:tokenizer_error()}.
do_run(Input, Index, Tokens) ->
case tokenize(Input, Index) of
done ->
{ok, lists:reverse(Tokens)};
{stop, Err} ->
{error, Err};
{add_token, Rest, Index@1, Token} ->
do_run(Rest, Index@1, [Token | Tokens])
end.
-spec run(binary()) -> {ok, list(token())} |
{error, handles@error:tokenizer_error()}.
run(Input) ->
do_run(Input, 0, []).