Packages

Generate typed Gleam modules from a SQL schema file

Current section

Files

Jump to
glsql src glsql@lexer.erl
Raw

src/glsql@lexer.erl

-module(glsql@lexer).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/glsql/lexer.gleam").
-export([lex/1]).
-file("src/glsql/lexer.gleam", 112).
-spec in_range(binary(), binary(), binary()) -> boolean().
in_range(C, Low, High) ->
(gleam@string:compare(C, Low) /= lt) andalso (gleam@string:compare(C, High)
/= gt).
-file("src/glsql/lexer.gleam", 116).
-spec is_digit(binary()) -> boolean().
is_digit(C) ->
in_range(C, <<"0"/utf8>>, <<"9"/utf8>>).
-file("src/glsql/lexer.gleam", 124).
-spec is_word_char(binary()) -> boolean().
is_word_char(C) ->
(((is_digit(C) orelse in_range(C, <<"a"/utf8>>, <<"z"/utf8>>)) orelse in_range(
C,
<<"A"/utf8>>,
<<"Z"/utf8>>
))
orelse (C =:= <<"_"/utf8>>))
orelse (C =:= <<"$"/utf8>>).
-file("src/glsql/lexer.gleam", 132).
-spec take_while(
list(binary()),
fun((binary()) -> boolean()),
integer(),
binary()
) -> {binary(), list(binary()), integer()}.
take_while(Chars, Pred, Pos, Acc) ->
case Chars of
[C | Rest] ->
case Pred(C) of
true ->
take_while(Rest, Pred, Pos + 1, <<Acc/binary, C/binary>>);
false ->
{Acc, Chars, Pos}
end;
[] ->
{Acc, [], Pos}
end.
-file("src/glsql/lexer.gleam", 120).
-spec is_number_char(binary()) -> boolean().
is_number_char(C) ->
is_digit(C) orelse (C =:= <<"."/utf8>>).
-file("src/glsql/lexer.gleam", 213).
-spec starts_with_seq(list(binary()), list(binary())) -> boolean().
starts_with_seq(Chars, Seq) ->
case Seq of
[] ->
true;
[S | Srest] ->
case Chars of
[C | Crest] ->
(C =:= S) andalso starts_with_seq(Crest, Srest);
[] ->
false
end
end.
-file("src/glsql/lexer.gleam", 190).
-spec scan_dollar_quote_body(list(binary()), binary(), integer(), binary()) -> {ok,
{binary(), list(binary()), integer()}} |
{error, nil}.
scan_dollar_quote_body(Chars, Tag, Pos, Acc) ->
Closer = gleam@string:to_graphemes(
<<<<"$"/utf8, Tag/binary>>/binary, "$"/utf8>>
),
case Chars of
[] ->
{error, nil};
_ ->
case starts_with_seq(Chars, Closer) of
true ->
Closer_len = erlang:length(Closer),
{ok,
{Acc,
gleam@list:drop(Chars, Closer_len),
Pos + Closer_len}};
false ->
{C@1, Rest@1} = case Chars of
[C | Rest] -> {C, Rest};
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"glsql/lexer"/utf8>>,
function => <<"scan_dollar_quote_body"/utf8>>,
line => 206,
value => _assert_fail,
start => 5578,
'end' => 5608,
pattern_start => 5589,
pattern_end => 5600})
end,
scan_dollar_quote_body(
Rest@1,
Tag,
Pos + 1,
<<Acc/binary, C@1/binary>>
)
end
end.
-file("src/glsql/lexer.gleam", 170).
-spec is_tag_char(binary()) -> boolean().
is_tag_char(C) ->
((is_digit(C) orelse in_range(C, <<"a"/utf8>>, <<"z"/utf8>>)) orelse in_range(
C,
<<"A"/utf8>>,
<<"Z"/utf8>>
))
orelse (C =:= <<"_"/utf8>>).
-file("src/glsql/lexer.gleam", 174).
-spec try_dollar_quote_open(list(binary()), integer()) -> {ok,
{binary(), list(binary()), integer()}} |
{error, nil}.
try_dollar_quote_open(Chars, Pos) ->
case Chars of
[<<"$"/utf8>> | Rest] ->
{Tag, Rest@1, Tag_end} = take_while(
Rest,
fun is_tag_char/1,
Pos + 1,
<<""/utf8>>
),
case Rest@1 of
[<<"$"/utf8>> | Rest@2] ->
{ok, {Tag, Rest@2, Tag_end + 1}};
_ ->
{error, nil}
end;
_ ->
{error, nil}
end.
-file("src/glsql/lexer.gleam", 224).
-spec take_delimited(list(binary()), binary(), integer(), binary()) -> {ok,
{binary(), list(binary()), integer()}} |
{error, nil}.
take_delimited(Chars, Delim, Pos, Acc) ->
case Chars of
[] ->
{error, nil};
[C | Rest] ->
case C =:= Delim of
true ->
{ok, {Acc, Rest, Pos + 1}};
false ->
take_delimited(
Rest,
Delim,
Pos + 1,
<<Acc/binary, C/binary>>
)
end
end.
-file("src/glsql/lexer.gleam", 159).
-spec skip_block_comment(list(binary()), integer()) -> {ok,
{list(binary()), integer()}} |
{error, glsql@error:error()}.
skip_block_comment(Chars, Pos) ->
case Chars of
[] ->
{error, {lex_error, <<"Unterminated block comment"/utf8>>, Pos}};
[<<"*"/utf8>>, <<"/"/utf8>> | Rest] ->
{ok, {Rest, Pos + 2}};
[_ | Rest@1] ->
skip_block_comment(Rest@1, Pos + 1)
end.
-file("src/glsql/lexer.gleam", 148).
-spec take_until_newline(list(binary()), integer()) -> {nil,
list(binary()),
integer()}.
take_until_newline(Chars, Pos) ->
case Chars of
[] ->
{nil, [], Pos};
[<<"\n"/utf8>> | Rest] ->
{nil, Rest, Pos + 1};
[_ | Rest@1] ->
take_until_newline(Rest@1, Pos + 1)
end.
-file("src/glsql/lexer.gleam", 103).
-spec punct(
glsql@token:token(),
list(binary()),
integer(),
list(glsql@token:positioned())
) -> {ok, list(glsql@token:positioned())} | {error, glsql@error:error()}.
punct(Tok, Rest, Pos, Acc) ->
do_lex(Rest, Pos + 1, [{positioned, Tok, Pos, Pos + 1} | Acc]).
-file("src/glsql/lexer.gleam", 13).
-spec do_lex(list(binary()), integer(), list(glsql@token:positioned())) -> {ok,
list(glsql@token:positioned())} |
{error, glsql@error:error()}.
do_lex(Chars, Pos, Acc) ->
case Chars of
[] ->
{ok, Acc};
[<<" "/utf8>> | Rest] ->
do_lex(Rest, Pos + 1, Acc);
[<<"\n"/utf8>> | Rest] ->
do_lex(Rest, Pos + 1, Acc);
[<<"\t"/utf8>> | Rest] ->
do_lex(Rest, Pos + 1, Acc);
[<<"\r"/utf8>> | Rest] ->
do_lex(Rest, Pos + 1, Acc);
[<<"\r\n"/utf8>> | Rest@1] ->
do_lex(Rest@1, Pos + 1, Acc);
[<<"-"/utf8>>, <<"-"/utf8>> | Rest@2] ->
{_, Rest@3, Pos@1} = take_until_newline(Rest@2, Pos + 2),
do_lex(Rest@3, Pos@1, Acc);
[<<"/"/utf8>>, <<"*"/utf8>> | Rest@4] ->
case skip_block_comment(Rest@4, Pos + 2) of
{ok, {Rest@5, Pos@2}} ->
do_lex(Rest@5, Pos@2, Acc);
{error, E} ->
{error, E}
end;
[<<"("/utf8>> | Rest@6] ->
punct(l_paren, Rest@6, Pos, Acc);
[<<")"/utf8>> | Rest@7] ->
punct(r_paren, Rest@7, Pos, Acc);
[<<","/utf8>> | Rest@8] ->
punct(comma, Rest@8, Pos, Acc);
[<<";"/utf8>> | Rest@9] ->
punct(semicolon, Rest@9, Pos, Acc);
[<<"."/utf8>> | Rest@10] ->
punct(dot, Rest@10, Pos, Acc);
[<<"["/utf8>> | Rest@11] ->
punct(l_bracket, Rest@11, Pos, Acc);
[<<"]"/utf8>> | Rest@12] ->
punct(r_bracket, Rest@12, Pos, Acc);
[<<"\""/utf8>> | Rest@13] ->
case take_delimited(Rest@13, <<"\""/utf8>>, Pos + 1, <<""/utf8>>) of
{ok, {Text, Rest@14, End}} ->
do_lex(
Rest@14,
End,
[{positioned, {quoted_ident, Text}, Pos, End} | Acc]
);
{error, nil} ->
{error,
{lex_error,
<<"Unterminated quoted identifier"/utf8>>,
Pos}}
end;
[<<"'"/utf8>> | Rest@15] ->
case take_delimited(Rest@15, <<"'"/utf8>>, Pos + 1, <<""/utf8>>) of
{ok, {Text@1, Rest@16, End@1}} ->
do_lex(
Rest@16,
End@1,
[{positioned, {string_lit, Text@1}, Pos, End@1} | Acc]
);
{error, nil} ->
{error,
{lex_error, <<"Unterminated string literal"/utf8>>, Pos}}
end;
[<<"$"/utf8>> | _] ->
case try_dollar_quote_open(Chars, Pos) of
{error, nil} ->
{Text@2, Rest@17, End@2} = take_while(
Chars,
fun is_word_char/1,
Pos,
<<""/utf8>>
),
do_lex(
Rest@17,
End@2,
[{positioned, {word, Text@2}, Pos, End@2} | Acc]
);
{ok, {Tag, Body, Body_pos}} ->
case scan_dollar_quote_body(
Body,
Tag,
Body_pos,
<<""/utf8>>
) of
{ok, {Text@3, Rest@18, End@3}} ->
do_lex(
Rest@18,
End@3,
[{positioned, {string_lit, Text@3}, Pos, End@3} |
Acc]
);
{error, nil} ->
{error,
{lex_error,
<<"Unterminated dollar-quoted string"/utf8>>,
Pos}}
end
end;
[C | Rest@19] ->
case is_digit(C) of
true ->
{Text@4, Rest@20, End@4} = take_while(
Chars,
fun is_number_char/1,
Pos,
<<""/utf8>>
),
do_lex(
Rest@20,
End@4,
[{positioned, {number, Text@4}, Pos, End@4} | Acc]
);
false ->
case is_word_char(C) of
true ->
{Text@5, Rest@21, End@5} = take_while(
Chars,
fun is_word_char/1,
Pos,
<<""/utf8>>
),
do_lex(
Rest@21,
End@5,
[{positioned, {word, Text@5}, Pos, End@5} | Acc]
);
false ->
do_lex(
Rest@19,
Pos + 1,
[{positioned, {symbol, C}, Pos, Pos + 1} | Acc]
)
end
end
end.
-file("src/glsql/lexer.gleam", 8).
-spec lex(binary()) -> {ok, list(glsql@token:positioned())} |
{error, glsql@error:error()}.
lex(Src) ->
_pipe = do_lex(gleam@string:to_graphemes(Src), 0, []),
gleam@result:map(_pipe, fun lists:reverse/1).