Current section

Files

Jump to
eyg_parser src eyg@parser@parser.erl
Raw

src/eyg@parser@parser.erl

-module(eyg@parser@parser).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/eyg/parser/parser.gleam").
-export([destructured/2, build_list/2, build_record/2, build_overwrite/2, do_patterns/2, describe_reason/1, expression/1, block/1]).
-export_type([reason/0, pattern/0]).
-type reason() :: unexpect_end |
{unexpected_token, eyg@parser@token:token(), integer()} |
{missing_equals, integer()} |
{missing_arrow, integer()} |
{unclosed_function_body, integer()} |
{expected_effect_name, binary(), integer()} |
{expected_builtin_name, integer()} |
{invalid_cid_reference, integer()} |
{invalid_import_path, integer()} |
{trailing_tokens, eyg@parser@token:token(), integer()} |
{invalid_character, binary(), integer()} |
{unterminated_string_literal, integer()} |
{invalid_escape_sequence, binary(), integer()}.
-type pattern() :: {assign, binary()} |
{destructure,
list({{binary(), {integer(), integer()}},
gleam@option:option({{integer(), integer()},
{binary(), {integer(), integer()}}})})}.
-file("src/eyg/parser/parser.gleam", 100).
-spec destructured(
list({{binary(), {integer(), integer()}},
gleam@option:option({{integer(), integer()},
{binary(), {integer(), integer()}}})}),
{eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}}
) -> {eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}}.
destructured(Matches, Term) ->
gleam@list:fold(
Matches,
Term,
fun(Acc, Pair) ->
{Field, Assign} = Pair,
{Field@1, Fspan} = Field,
{Cspan@1, {Var@1, _}} = case Assign of
{some, {Cspan, {Var, Vspan}}} ->
{Cspan, {Var, Vspan}};
none ->
{Fspan, {Field@1, Fspan}}
end,
Aspan = {erlang:element(1, Fspan), erlang:element(2, Cspan@1)},
Lspan = {erlang:element(1, Fspan),
erlang:element(2, erlang:element(2, Term))},
{{'let',
Var@1,
{{apply,
{{select, Field@1}, Fspan},
{{variable, <<"$"/utf8>>}, Cspan@1}},
Aspan},
Acc},
Lspan}
end
).
-file("src/eyg/parser/parser.gleam", 371).
-spec fail(list({eyg@parser@token:token(), integer()})) -> {ok, any()} |
{error, reason()}.
fail(Tokens) ->
case Tokens of
[] ->
{error, unexpect_end};
[{T, Start} | _] ->
{error, {unexpected_token, T, Start}}
end.
-file("src/eyg/parser/parser.gleam", 49).
-spec do_destructure(
list({eyg@parser@token:token(), integer()}),
list({{binary(), {integer(), integer()}},
gleam@option:option({{integer(), integer()},
{binary(), {integer(), integer()}}})})
) -> {ok,
{list({{binary(), {integer(), integer()}},
gleam@option:option({{integer(), integer()},
{binary(), {integer(), integer()}}})}),
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
do_destructure(Tokens, Acc) ->
case Tokens of
[{right_brace, _} | Rest] ->
{ok, {Acc, Rest}};
[{{name, Field}, F}, {colon, C}, {{name, Var}, V} | Rest@1] ->
Field@1 = {Field, {F, F + string:length(Field)}},
Colon = {C, C + 1},
Var@1 = {Var, {V, V + string:length(Var)}},
Acc@1 = [{Field@1, {some, {Colon, Var@1}}} | Acc],
case Rest@1 of
[{right_brace, _} | Rest@2] ->
{ok, {Acc@1, Rest@2}};
[{comma, _} | Rest@3] ->
do_destructure(Rest@3, Acc@1);
_ ->
fail(Rest@1)
end;
[{{name, Field@2}, Start} | Rest@4] ->
Field@3 = {Field@2, {Start, Start + string:length(Field@2)}},
Acc@2 = [{Field@3, none} | Acc],
case Rest@4 of
[{right_brace, _} | Rest@5] ->
{ok, {Acc@2, Rest@5}};
[{comma, _} | Rest@6] ->
do_destructure(Rest@6, Acc@2);
_ ->
fail(Rest@4)
end;
_ ->
fail(Tokens)
end.
-file("src/eyg/parser/parser.gleam", 78).
-spec one_pattern(list({eyg@parser@token:token(), integer()})) -> {ok,
{pattern(), list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
one_pattern(Tokens) ->
case Tokens of
[{{name, Label}, _} | Rest] ->
{ok, {{assign, Label}, Rest}};
[{left_brace, _} | Rest@1] ->
gleam@result:'try'(
do_destructure(Rest@1, []),
fun(_use0) ->
{Matches, Rest@2} = _use0,
{ok, {{destructure, Matches}, Rest@2}}
end
);
_ ->
fail(Tokens)
end.
-file("src/eyg/parser/parser.gleam", 378).
-spec next_pos(list({any(), FHY}), FHY) -> FHY.
next_pos(Rest, Fallback) ->
case Rest of
[{_, At} | _] ->
At;
[] ->
Fallback
end.
-file("src/eyg/parser/parser.gleam", 419).
-spec build_list(
list({integer(),
{eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}}}),
{eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}}
) -> {eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}}.
build_list(Reversed, Acc) ->
case Reversed of
[{From, Item} | Rest] ->
{_, {_, C}} = Acc,
{_, {_, B}} = Item,
build_list(
Rest,
{{apply,
{{apply, {cons, {From, From + 1}}, Item}, {From, B}},
Acc},
{From, C}}
);
[] ->
Acc
end.
-file("src/eyg/parser/parser.gleam", 505).
-spec build_record(
list({{FMD, FME},
binary(),
{eyg@ir@tree:expression({FMD, FME}), {FMD, FME}}}),
{eyg@ir@tree:expression({FMD, FME}), {FMD, FME}}
) -> {eyg@ir@tree:expression({FMD, FME}), {FMD, FME}}.
build_record(Reversed, Acc) ->
case Reversed of
[{Span, Label, Item} | Rest] ->
{_, {_, C}} = Acc,
{_, {_, B}} = Item,
{A, _} = Span,
build_record(
Rest,
{{apply, {{apply, {{extend, Label}, Span}, Item}, {A, B}}, Acc},
{A, C}}
);
[] ->
Acc
end.
-file("src/eyg/parser/parser.gleam", 524).
-spec build_overwrite(
list({{FMV, FMW},
binary(),
{eyg@ir@tree:expression({FMV, FMW}), {FMV, FMW}}}),
{eyg@ir@tree:expression({FMV, FMW}), {FMV, FMW}}
) -> {eyg@ir@tree:expression({FMV, FMW}), {FMV, FMW}}.
build_overwrite(Reversed, Acc) ->
case Reversed of
[{Span, Label, Item} | Rest] ->
{_, {_, C}} = Acc,
{_, {_, B}} = Item,
{A, _} = Span,
build_overwrite(
Rest,
{{apply,
{{apply, {{overwrite, Label}, Span}, Item}, {A, B}},
Acc},
{A, C}}
);
[] ->
Acc
end.
-file("src/eyg/parser/parser.gleam", 589).
-spec pop(list(FNH)) -> {ok, {FNH, list(FNH)}} | {error, reason()}.
pop(Tokens) ->
case Tokens of
[T | Rest] ->
{ok, {T, Rest}};
[] ->
{error, unexpect_end}
end.
-file("src/eyg/parser/parser.gleam", 89).
-spec do_patterns(list({eyg@parser@token:token(), integer()}), list(pattern())) -> {ok,
{list(pattern()), list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
do_patterns(Tokens, Acc) ->
gleam@result:'try'(
one_pattern(Tokens),
fun(_use0) ->
{Pattern, Tokens@1} = _use0,
Acc@1 = [Pattern | Acc],
gleam@result:'try'(
pop(Tokens@1),
fun(_use0@1) ->
{{Next, Start}, Rest} = _use0@1,
case Next of
comma ->
do_patterns(Rest, Acc@1);
right_paren ->
{ok, {Acc@1, Rest}};
_ ->
{error, {unexpected_token, Next, Start}}
end
end
)
end
).
-file("src/eyg/parser/parser.gleam", 596).
-spec describe_reason(reason()) -> binary().
describe_reason(Reason) ->
case Reason of
{unexpected_token, Token, Position} ->
<<<<<<"unexpected `"/utf8,
(eyg@parser@token:to_string(Token))/binary>>/binary,
"` at position "/utf8>>/binary,
(erlang:integer_to_binary(Position))/binary>>;
unexpect_end ->
<<"unexpected end of input"/utf8>>;
{invalid_character, Char, Position@1} ->
<<<<<<<<"invalid character '"/utf8, Char/binary>>/binary,
"' at position "/utf8>>/binary,
(erlang:integer_to_binary(Position@1))/binary>>/binary,
"\nhint: remove or replace this character — EYG does not use it"/utf8>>;
{unterminated_string_literal, Position@2} ->
<<<<"unterminated string literal at position "/utf8,
(erlang:integer_to_binary(Position@2))/binary>>/binary,
"\nhint: close the string with a double-quote `\"`"/utf8>>;
{invalid_escape_sequence, Escape_char, Position@3} ->
<<<<<<<<"invalid escape sequence `\\"/utf8, Escape_char/binary>>/binary,
"` in string at position "/utf8>>/binary,
(erlang:integer_to_binary(Position@3))/binary>>/binary,
"\nhint: valid escapes are \\n (newline), \\t (tab), \\r (carriage return), \\\" (quote), \\\\ (backslash)"/utf8>>;
{missing_equals, Position@4} ->
<<<<"expected `=` after let binding name at position "/utf8,
(erlang:integer_to_binary(Position@4))/binary>>/binary,
"\nhint: let bindings use the form `let name = expression`"/utf8>>;
{missing_arrow, Position@5} ->
<<<<"expected `->` followed by `{` in function definition at position "/utf8,
(erlang:integer_to_binary(Position@5))/binary>>/binary,
"\nhint: functions are written as `(arg) -> { body }`"/utf8>>;
{unclosed_function_body, Open_at} ->
<<<<"unclosed function body — expected `}` to close the `{` opened at position "/utf8,
(erlang:integer_to_binary(Open_at))/binary>>/binary,
"\nhint: every `{` in a function body must be closed with `}`"/utf8>>;
{expected_effect_name, Keyword, Position@6} ->
<<<<<<<<<<<<"expected an uppercase effect name after `"/utf8,
Keyword/binary>>/binary,
"` at position "/utf8>>/binary,
(erlang:integer_to_binary(Position@6))/binary>>/binary,
"\nhint: effect names must start with an uppercase letter, e.g. `"/utf8>>/binary,
Keyword/binary>>/binary,
" Log`"/utf8>>;
{expected_builtin_name, Position@7} ->
<<<<"expected a builtin identifier after `!` at position "/utf8,
(erlang:integer_to_binary(Position@7))/binary>>/binary,
"\nhint: builtins use lowercase names, e.g. `!int_add`"/utf8>>;
{invalid_cid_reference, Position@8} ->
<<<<"invalid content identifier (CID) after `#` at position "/utf8,
(erlang:integer_to_binary(Position@8))/binary>>/binary,
"\nhint: CID references use a valid base32-encoded CID, e.g. `#bafyreig...`"/utf8>>;
{invalid_import_path, Position@9} ->
<<<<"expected a string path after `import` at position "/utf8,
(erlang:integer_to_binary(Position@9))/binary>>/binary,
"\nhint: import paths must be string literals, e.g. `import \"./module.eyg.json\"`"/utf8>>;
{trailing_tokens, Token@1, Position@10} ->
Token_str = case Token@1 of
{unexpected_grapheme, Raw} ->
gleam@string:slice(Raw, 0, 1);
_ ->
eyg@parser@token:to_string(Token@1)
end,
<<<<<<<<<<"unexpected `"/utf8, Token_str/binary>>/binary,
"` at position "/utf8>>/binary,
(erlang:integer_to_binary(Position@10))/binary>>/binary,
" — the expression is complete but there are leftover tokens"/utf8>>/binary,
"\nhint: EYG uses function calls for operations, not infix operators"/utf8>>
end.
-file("src/eyg/parser/parser.gleam", 335).
-spec after_expression(
{eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}},
list({eyg@parser@token:token(), integer()})
) -> {ok,
{{eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}},
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
after_expression(Exp, Rest) ->
case Rest of
[{left_paren, _} | Rest@1] ->
gleam@result:'try'(
expression(Rest@1),
fun(_use0) ->
{Arg, Rest@2} = _use0,
gleam@result:'try'(
do_args(Rest@2, [Arg]),
fun(_use0@1) ->
{Args, _, Rest@3} = _use0@1,
Args@1 = lists:reverse(Args),
Exp@1 = gleam@list:fold(
Args@1,
Exp,
fun(Acc, Arg@1) ->
{_, {Start, _}} = Acc,
{_, {_, End}} = Arg@1,
{{apply, Acc, Arg@1}, {Start, End + 1}}
end
),
after_expression(Exp@1, Rest@3)
end
)
end
);
[{dot, Dot_at}, {{name, Label}, Name_at} | Rest@4] ->
End@1 = Name_at + string:length(Label),
Select = {{select, Label}, {Dot_at, End@1}},
{_, {Start@1, _}} = Exp,
Span = {Start@1, End@1},
after_expression({{apply, Select, Exp}, Span}, Rest@4);
_ ->
{ok, {Exp, Rest}}
end.
-file("src/eyg/parser/parser.gleam", 360).
-spec do_args(
list({eyg@parser@token:token(), integer()}),
list({eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}})
) -> {ok,
{list({eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}}),
integer(),
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
do_args(Tokens, Acc) ->
case Tokens of
[{right_paren, End} | Rest] ->
{ok, {Acc, End + 1, Rest}};
[{comma, _} | Rest@1] ->
gleam@result:'try'(
expression(Rest@1),
fun(_use0) ->
{Arg, Rest@2} = _use0,
do_args(Rest@2, [Arg | Acc])
end
);
_ ->
fail(Tokens)
end.
-file("src/eyg/parser/parser.gleam", 169).
-spec expression(list({eyg@parser@token:token(), integer()})) -> {ok,
{{eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}},
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
expression(Tokens) ->
gleam@result:'try'(
pop(Tokens),
fun(_use0) ->
{{Token, Start}, Rest} = _use0,
gleam@result:'try'(case Token of
{name, Label} ->
Span = {Start, Start + string:length(Label)},
{ok, {{{variable, Label}, Span}, Rest}};
'let' ->
gleam@result:'try'(
one_pattern(Rest),
fun(_use0@1) ->
{Pattern, Rest@1} = _use0@1,
gleam@result:'try'(case Rest@1 of
[{equal, _} | Rest@2] ->
{ok, Rest@2};
[{_, At} | _] ->
{error, {missing_equals, At}};
[] ->
{error, unexpect_end}
end, fun(Rest@3) ->
gleam@result:'try'(
expression(Rest@3),
fun(_use0@2) ->
{Value, Rest@4} = _use0@2,
gleam@result:'try'(
expression(Rest@4),
fun(_use0@3) ->
{Then, Rest@5} = _use0@3,
{_, {_, End}} = Then,
Span@1 = {Start, End},
Exp = case Pattern of
{assign, Label@1} ->
{{'let',
Label@1,
Value,
Then},
Span@1};
{destructure,
Matches} ->
{{'let',
<<"$"/utf8>>,
Value,
destructured(
Matches,
Then
)},
Span@1}
end,
{ok, {Exp, Rest@5}}
end
)
end
)
end)
end
);
left_paren ->
gleam@result:'try'(
do_patterns(Rest, []),
fun(_use0@4) ->
{Patterns_reversed, Rest@6} = _use0@4,
gleam@result:'try'(case Rest@6 of
[{right_arrow, _},
{left_brace, Brace_at} |
Rest@7] ->
{ok, {Rest@7, Brace_at}};
[{right_arrow, _}, {_, At@1} | _] ->
{error, {missing_arrow, At@1}};
[{right_arrow, Arrow_at}] ->
{error,
{missing_arrow, Arrow_at + 2}};
[{_, At@2} | _] ->
{error, {missing_arrow, At@2}};
[] ->
{error, unexpect_end}
end, fun(_use0@5) ->
{Rest@8, Brace_at@1} = _use0@5,
gleam@result:'try'(
expression(Rest@8),
fun(_use0@6) ->
{Body, Rest@9} = _use0@6,
gleam@result:'try'(
case Rest@9 of
[{right_brace, End@1} |
Rest@10] ->
{ok,
{Rest@10, End@1}};
_ ->
{error,
{unclosed_function_body,
Brace_at@1}}
end,
fun(_use0@7) ->
{Rest@11, End@2} = _use0@7,
Span@2 = {Start,
End@2 + 1},
Exp@1 = gleam@list:fold(
Patterns_reversed,
Body,
fun(
Body@1,
Pattern@1
) ->
case Pattern@1 of
{assign,
Label@2} ->
{{lambda,
Label@2,
Body@1},
Span@2};
{destructure,
Matches@1} ->
{{lambda,
<<"$"/utf8>>,
destructured(
Matches@1,
Body@1
)},
Span@2}
end
end
),
{ok, {Exp@1, Rest@11}}
end
)
end
)
end)
end
);
{integer, Raw} ->
Value@2 = case gleam_stdlib:parse_int(Raw) of
{ok, Value@1} -> Value@1;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"eyg/parser/parser"/utf8>>,
function => <<"expression"/utf8>>,
line => 228,
value => _assert_fail,
start => 7243,
'end' => 7280,
pattern_start => 7254,
pattern_end => 7263})
end,
Span@3 = {Start, Start + string:length(Raw)},
{ok, {{{integer, Value@2}, Span@3}, Rest}};
minus ->
gleam@result:'try'(
pop(Rest),
fun(_use0@8) ->
{{Next, From}, Rest@12} = _use0@8,
case Next of
{integer, Raw@1} ->
Value@4 = case gleam_stdlib:parse_int(
Raw@1
) of
{ok, Value@3} -> Value@3;
_assert_fail@1 ->
erlang:error(
#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"eyg/parser/parser"/utf8>>,
function => <<"expression"/utf8>>,
line => 236,
value => _assert_fail@1,
start => 7511,
'end' => 7548,
pattern_start => 7522,
pattern_end => 7531}
)
end,
Span@4 = {Start,
From + string:length(Raw@1)},
{ok,
{{{integer, -1 * Value@4}, Span@4},
Rest@12}};
_ ->
{error,
{unexpected_token, Token, Start}}
end
end
);
{string, Value@5} ->
Span@5 = {Start, (Start + string:length(Value@5)) + 2},
{ok, {{{string, Value@5}, Span@5}, Rest}};
left_square ->
do_list(Rest, Start, []);
left_brace ->
do_record(Rest, Start, []);
{uppername, Label@3} ->
Span@6 = {Start, Start + string:length(Label@3)},
{ok, {{{tag, Label@3}, Span@6}, Rest}};
match ->
case Rest of
[{left_brace, _} | Rest@13] ->
gleam@result:'try'(
clauses(Rest@13, Start),
fun(_use0@9) ->
{Exp@2, _, Rest@14} = _use0@9,
{ok, {Exp@2, Rest@14}}
end
);
_ ->
gleam@result:'try'(
expression(Rest),
fun(_use0@10) ->
{Subject, Rest@15} = _use0@10,
case Rest@15 of
[{left_brace, Inner} | Rest@16] ->
gleam@result:'try'(
clauses(Rest@16, Inner),
fun(_use0@11) ->
{Exp@3, End@3, Rest@17} = _use0@11,
Span@7 = {Start, End@3},
{ok,
{{{apply,
Exp@3,
Subject},
Span@7},
Rest@17}}
end
);
_ ->
fail(Rest@15)
end
end
)
end;
perform ->
case Rest of
[{{uppername, Label@4}, End@4} | Rest@18] ->
Span@8 = {Start, End@4 + string:length(Label@4)},
{ok, {{{perform, Label@4}, Span@8}, Rest@18}};
_ ->
{error,
{expected_effect_name,
<<"perform"/utf8>>,
next_pos(Rest, Start + 7)}}
end;
handle ->
case Rest of
[{{uppername, Label@5}, End@5} | Rest@19] ->
Span@9 = {Start, End@5 + string:length(Label@5)},
{ok, {{{handle, Label@5}, Span@9}, Rest@19}};
_ ->
{error,
{expected_effect_name,
<<"handle"/utf8>>,
next_pos(Rest, Start + 6)}}
end;
bang ->
case Rest of
[{{name, Label@6}, End@6} | Rest@20] ->
Span@10 = {Start,
End@6 + string:length(Label@6)},
{ok, {{{builtin, Label@6}, Span@10}, Rest@20}};
_ ->
{error,
{expected_builtin_name,
next_pos(Rest, Start + 1)}}
end;
hash ->
case Rest of
[{{name, Label@7}, End@7} | Rest@21] ->
Span@11 = {Start,
End@7 + string:length(Label@7)},
case multiformats@cid@v1:from_string(Label@7) of
{ok, {Cid, _}} ->
{ok,
{{{reference, Cid}, Span@11},
Rest@21}};
{error, _} ->
{error, {invalid_cid_reference, End@7}}
end;
_ ->
{error,
{invalid_cid_reference,
next_pos(Rest, Start + 1)}}
end;
at ->
case Rest of
[{{name, Label@8}, End@8} | Rest@22] ->
Span@12 = {Start,
End@8 + string:length(Label@8)},
{ok,
{{{release,
Label@8,
0,
{cid,
297,
{multihash,
sha256,
<<143,
171,
132,
193,
178,
239,
11,
237,
187,
22,
81,
164,
153,
54,
34,
109,
16,
139,
216,
209,
66,
180,
135,
86,
79,
251,
7,
31,
89,
235,
100,
152>>}}},
Span@12},
Rest@22}};
_ ->
fail(Rest)
end;
import ->
case Rest of
[{{string, Value@6}, End@9} | Rest@23] ->
Span@13 = {Start,
(End@9 + string:length(Value@6)) + 2},
{ok,
{{{release,
Value@6,
0,
{cid,
297,
{multihash,
sha256,
<<143,
171,
132,
193,
178,
239,
11,
237,
187,
22,
81,
164,
153,
54,
34,
109,
16,
139,
216,
209,
66,
180,
135,
86,
79,
251,
7,
31,
89,
235,
100,
152>>}}},
Span@13},
Rest@23}};
_ ->
{error,
{invalid_import_path,
next_pos(Rest, Start + 6)}}
end;
{unexpected_grapheme, Raw@2} ->
{error,
{invalid_character,
gleam@string:slice(Raw@2, 0, 1),
Start}};
{unterminated_string, _} ->
{error, {unterminated_string_literal, Start}};
{invalid_escape, Raw@3} ->
{error,
{invalid_escape_sequence,
gleam@string:slice(Raw@3, 1, 1),
Start}};
_ ->
{error, {unexpected_token, Token, Start}}
end, fun(_use0@12) ->
{Exp@4, Rest@24} = _use0@12,
after_expression(Exp@4, Rest@24)
end)
end
).
-file("src/eyg/parser/parser.gleam", 124).
-spec block(list({eyg@parser@token:token(), integer()})) -> {ok,
{{eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}},
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
block(Tokens) ->
gleam@result:'try'(
pop(Tokens),
fun(_use0) ->
{{Token, Start}, Rest} = _use0,
case Token of
'let' ->
gleam@result:'try'(
one_pattern(Rest),
fun(_use0@1) ->
{Pattern, Rest@1} = _use0@1,
gleam@result:'try'(case Rest@1 of
[{equal, _} | Rest@2] ->
{ok, Rest@2};
[{_, At} | _] ->
{error, {missing_equals, At}};
[] ->
{error, unexpect_end}
end, fun(Rest@3) ->
gleam@result:'try'(
expression(Rest@3),
fun(_use0@2) ->
{Value, Rest@4} = _use0@2,
case block(Rest@4) of
{ok, {Then, Rest@5}} ->
{_, {_, End}} = Then,
Span = {Start, End},
Exp = case Pattern of
{assign, Label} ->
{{'let',
Label,
Value,
Then},
Span};
{destructure, Matches} ->
{{'let',
<<"$"/utf8>>,
Value,
destructured(
Matches,
Then
)},
Span}
end,
{ok, {Exp, Rest@5}};
{error, unexpect_end} ->
Span@1 = {Start, Start},
Then@1 = {vacant, {0, 0}},
Exp@1 = case Pattern of
{assign, Label@1} ->
{{'let',
Label@1,
Value,
Then@1},
Span@1};
{destructure, Matches@1} ->
{{'let',
<<"$"/utf8>>,
Value,
destructured(
Matches@1,
Then@1
)},
Span@1}
end,
{ok, {Exp@1, Rest@4}};
{error, Other} ->
{error, Other}
end
end
)
end)
end
);
_ ->
expression(Tokens)
end
end
).
-file("src/eyg/parser/parser.gleam", 386).
-spec do_list(
list({eyg@parser@token:token(), integer()}),
integer(),
list({integer(),
{eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}}})
) -> {ok,
{{eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}},
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
do_list(Tokens, Start, Acc) ->
case Tokens of
[] ->
{error, unexpect_end};
[{right_square, End} | Rest] ->
Span = {Start, End + 1},
{ok, {build_list(Acc, {tail, Span}), Rest}};
_ ->
gleam@result:'try'(
expression(Tokens),
fun(_use0) ->
{Item, Rest@1} = _use0,
Acc@1 = [{Start, Item} | Acc],
case Rest@1 of
[{comma, _}, {dot_dot, _} | Rest@2] ->
gleam@result:'try'(
expression(Rest@2),
fun(_use0@1) ->
{Tail, Rest@3} = _use0@1,
gleam@result:'try'(
pop(Rest@3),
fun(_use0@2) ->
{{Token, Start@1}, Rest@4} = _use0@2,
case Token of
right_square ->
{ok,
{build_list(Acc@1, Tail),
Rest@4}};
_ ->
{error,
{unexpected_token,
Token,
Start@1}}
end
end
)
end
);
[{comma, Start@2} | Rest@5] ->
do_list(Rest@5, Start@2, Acc@1);
[{right_square, Start@3} | Rest@6] ->
Span@1 = {Start@3, Start@3 + 1},
{ok, {build_list(Acc@1, {tail, Span@1}), Rest@6}};
[{T, Start@4} | _] ->
{error, {unexpected_token, T, Start@4}};
[] ->
{error, unexpect_end}
end
end
)
end.
-file("src/eyg/parser/parser.gleam", 440).
-spec do_record(
list({eyg@parser@token:token(), integer()}),
integer(),
list({{integer(), integer()},
binary(),
{eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}}})
) -> {ok,
{{eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}},
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
do_record(Rest, Start, Acc) ->
gleam@result:'try'(
pop(Rest),
fun(_use0) ->
{{Token, Kstart}, Rest@1} = _use0,
case Token of
right_brace ->
{ok, {{empty, {Start, Kstart + 1}}, Rest@1}};
{name, Label} ->
gleam@result:'try'(
pop(Rest@1),
fun(_use0@1) ->
{{Token@1, Next}, Rest@2} = _use0@1,
case Token@1 of
colon ->
gleam@result:'try'(
expression(Rest@2),
fun(_use0@2) ->
{Value, Rest@3} = _use0@2,
Acc@1 = [{{Start, Next + 1},
Label,
Value} |
Acc],
case Rest@3 of
[{comma, Start@1} | Rest@4] ->
do_record(
Rest@4,
Start@1,
Acc@1
);
[{right_brace, Start@2} |
Rest@5] ->
Span = {Start@2,
Start@2 + 1},
{ok,
{build_record(
Acc@1,
{empty, Span}
),
Rest@5}};
_ ->
fail(Rest@3)
end
end
);
comma ->
Acc@2 = [{{Start,
Kstart + string:length(Label)},
Label,
{{variable, Label},
{Kstart,
Kstart + string:length(
Label
)}}} |
Acc],
do_record(Rest@2, Next, Acc@2);
right_brace ->
Acc@3 = [{{Start,
Kstart + string:length(Label)},
Label,
{{variable, Label},
{Kstart,
Kstart + string:length(
Label
)}}} |
Acc],
Span@1 = {Next, Next + 1},
{ok,
{build_record(Acc@3, {empty, Span@1}),
Rest@2}};
_ ->
{error, {unexpected_token, Token@1, Start}}
end
end
);
dot_dot ->
gleam@result:'try'(
expression(Rest@1),
fun(_use0@3) ->
{Value@1, Rest@6} = _use0@3,
gleam@result:'try'(
pop(Rest@6),
fun(_use0@4) ->
{{Token@2, Start@3}, Rest@7} = _use0@4,
gleam@result:'try'(case Token@2 of
right_brace ->
{ok, Rest@7};
_ ->
{error,
{unexpected_token,
Token@2,
Start@3}}
end, fun(Rest@8) ->
{ok,
{build_overwrite(Acc, Value@1),
Rest@8}}
end)
end
)
end
);
_ ->
{error, {unexpected_token, Token, Start}}
end
end
).
-file("src/eyg/parser/parser.gleam", 561).
-spec do_clauses(
list({eyg@parser@token:token(), integer()}),
integer(),
list({integer(),
binary(),
{integer(), integer()},
{eyg@ir@tree:expression({integer(), integer()}), {integer(), integer()}}})
) -> {ok,
{list({integer(),
binary(),
{integer(), integer()},
{eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}}}),
{eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}},
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
do_clauses(Tokens, Start, Acc) ->
gleam@result:'try'(
pop(Tokens),
fun(_use0) ->
{{Token, Clause}, Rest} = _use0,
case Token of
right_brace ->
{ok, {Acc, {no_cases, {Start, Clause + 1}}, Rest}};
{uppername, Label} ->
gleam@result:'try'(
expression(Rest),
fun(_use0@1) ->
{Branch, Rest@1} = _use0@1,
Acc@1 = [{Start,
Label,
{Clause, Clause + string:length(Label)},
Branch} |
Acc],
case Rest@1 of
[{_, Last} | _] ->
do_clauses(Rest@1, Last, Acc@1);
[] ->
{error, unexpect_end}
end
end
);
bar ->
gleam@result:'try'(
expression(Rest),
fun(_use0@2) ->
{{Otherwise, Span}, Rest@2} = _use0@2,
case Rest@2 of
[{right_brace, _} | Rest@3] ->
{ok, {Acc, {Otherwise, Span}, Rest@3}};
_ ->
fail(Rest@2)
end
end
);
_ ->
{error, {unexpected_token, Token, Clause}}
end
end
).
-file("src/eyg/parser/parser.gleam", 546).
-spec clauses(list({eyg@parser@token:token(), integer()}), integer()) -> {ok,
{{eyg@ir@tree:expression({integer(), integer()}),
{integer(), integer()}},
integer(),
list({eyg@parser@token:token(), integer()})}} |
{error, reason()}.
clauses(Tokens, Start) ->
gleam@result:'try'(
do_clauses(Tokens, Start, []),
fun(_use0) ->
{Clauses, Tail, Rest} = _use0,
{_, {_, End}} = Tail,
Exp@1 = gleam@list:fold(
Clauses,
Tail,
fun(Exp, Clause) ->
{Start@1, Label, Cspan, Branch} = Clause,
Case_ = {{'case', Label}, Cspan},
{_, {_, Branch_end}} = Branch,
Inner = {{apply, Case_, Branch},
{erlang:element(1, Cspan), Branch_end}},
{_, {_, Final}} = Tail,
{{apply, Inner, Exp}, {Start@1, Final}}
end
),
{ok, {Exp@1, End, Rest}}
end
).