-module(caffeine_lang@frontend@parser). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_lang/frontend/parser.gleam"). -export([parse_blueprints_file/1, parse_expects_file/1]). -export_type([parser_state/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 parser_state() :: {parser_state, list(caffeine_lang@frontend@token:token()), integer(), integer()}. -file("src/caffeine_lang/frontend/parser.gleam", 57). ?DOC(" Filter out whitespace and comment tokens.\n"). -spec filter_whitespace_comments(list(caffeine_lang@frontend@token:token())) -> list(caffeine_lang@frontend@token:token()). filter_whitespace_comments(Tokens) -> gleam@list:filter(Tokens, fun(Tok) -> case Tok of whitespace_newline -> false; {whitespace_indent, _} -> false; {comment_line, _} -> false; {comment_section, _} -> false; _ -> true end end). -file("src/caffeine_lang/frontend/parser.gleam", 70). ?DOC(" Peek at the current token without consuming it.\n"). -spec peek(parser_state()) -> caffeine_lang@frontend@token:token(). peek(State) -> case erlang:element(2, State) of [Tok | _] -> Tok; [] -> e_o_f end. -file("src/caffeine_lang/frontend/parser.gleam", 78). ?DOC(" Consume current token and advance state.\n"). -spec advance(parser_state()) -> parser_state(). advance(State) -> case erlang:element(2, State) of [_ | Rest] -> {parser_state, Rest, erlang:element(3, State), erlang:element(4, State)}; [] -> State end. -file("src/caffeine_lang/frontend/parser.gleam", 86). ?DOC(" Expect a specific token, consuming it if matched.\n"). -spec expect(parser_state(), caffeine_lang@frontend@token:token(), binary()) -> {ok, parser_state()} | {error, caffeine_lang@frontend@parser_error:parser_error()}. expect(State, Expected, Expected_name) -> case peek(State) of Tok when Tok =:= Expected -> {ok, advance(State)}; Tok@1 -> {error, {unexpected_token, Expected_name, caffeine_lang@frontend@token:to_string(Tok@1), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 136). ?DOC( " Check if current position is a type alias definition.\n" " Looks for pattern: Identifier ( Identifier(\"Type\") )\n" ). -spec is_type_alias(parser_state()) -> boolean(). is_type_alias(State) -> case erlang:element(2, State) of [{identifier, _}, symbol_left_paren, {identifier, <<"Type"/utf8>>} | _] -> true; _ -> false end. -file("src/caffeine_lang/frontend/parser.gleam", 223). -spec parse_extendable_kind(parser_state()) -> {ok, {caffeine_lang@frontend@ast:extendable_kind(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_extendable_kind(State) -> case peek(State) of keyword_requires -> {ok, {extendable_requires, advance(State)}}; keyword_provides -> {ok, {extendable_provides, advance(State)}}; Tok -> {error, {unexpected_token, <<"Requires or Provides"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 301). -spec parse_artifacts_loop(parser_state(), list(binary())) -> {ok, {list(binary()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_artifacts_loop(State, Acc) -> case peek(State) of symbol_plus -> State@1 = advance(State), case peek(State@1) of {literal_string, Name} -> State@2 = advance(State@1), parse_artifacts_loop(State@2, [Name | Acc]); Tok -> {error, {unexpected_token, <<"artifact name"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State@1), erlang:element(4, State@1)}} end; _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 283). -spec parse_artifacts(parser_state()) -> {ok, {list(binary()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_artifacts(State) -> case peek(State) of {literal_string, Name} -> State@1 = advance(State), parse_artifacts_loop(State@1, [Name]); Tok -> {error, {unexpected_token, <<"artifact name"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 453). -spec parse_string_literal(parser_state()) -> {ok, {binary(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_string_literal(State) -> case peek(State) of {literal_string, S} -> {ok, {S, advance(State)}}; Tok -> {error, {unexpected_token, <<"string"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 502). -spec parse_extends_list_loop(parser_state(), list(binary())) -> {ok, {list(binary()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_extends_list_loop(State, Acc) -> case peek(State) of symbol_comma -> State@1 = advance(State), case peek(State@1) of {identifier, Name} -> State@2 = advance(State@1), parse_extends_list_loop(State@2, [Name | Acc]); Tok -> {error, {unexpected_token, <<"identifier"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State@1), erlang:element(4, State@1)}} end; _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 483). -spec parse_extends_list(parser_state()) -> {ok, {list(binary()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_extends_list(State) -> case peek(State) of symbol_right_bracket -> {ok, {[], State}}; {identifier, Name} -> State@1 = advance(State), parse_extends_list_loop(State@1, [Name]); Tok -> {error, {unexpected_token, <<"identifier"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 468). -spec parse_optional_extends(parser_state()) -> {ok, {list(binary()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_optional_extends(State) -> case peek(State) of keyword_extends -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_left_bracket, <<"["/utf8>>), fun(State@2) -> gleam@result:'try'( parse_extends_list(State@2), fun(_use0) -> {Extends, State@3} = _use0, gleam@result:'try'( expect( State@3, symbol_right_bracket, <<"]"/utf8>> ), fun(State@4) -> {ok, {Extends, State@4}} end ) end ) end ); _ -> {ok, {[], State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 819). ?DOC( " Parses types valid as Dict keys: String primitive or type alias ref.\n" " Only String is allowed as a primitive key (JSON keys must be strings).\n" ). -spec parse_dict_key_type(parser_state()) -> {ok, {caffeine_lang@common@accepted_types:accepted_types(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_dict_key_type(State) -> case peek(State) of keyword_string -> State@1 = advance(State), {ok, {{primitive_type, string}, State@1}}; {identifier, Name} -> case gleam_stdlib:string_starts_with(Name, <<"_"/utf8>>) of true -> State@2 = advance(State), {ok, {{type_alias_ref, Name}, State@2}}; false -> {error, {unknown_type, Name, erlang:element(3, State), erlang:element(4, State)}} end; Tok -> {error, {unknown_type, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 969). -spec expect_x(parser_state()) -> {ok, parser_state()} | {error, caffeine_lang@frontend@parser_error:parser_error()}. expect_x(State) -> case peek(State) of keyword_x -> {ok, advance(State)}; Tok -> {error, {invalid_refinement, <<"expected 'x', got "/utf8, (caffeine_lang@frontend@token:to_string(Tok))/binary>>, erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 1099). ?DOC(" Convert a Literal to its string representation for use in refinements/defaults.\n"). -spec literal_to_string(caffeine_lang@frontend@ast:literal()) -> binary(). literal_to_string(Literal) -> case Literal of {literal_string, S} -> S; {literal_integer, N} -> erlang:integer_to_binary(N); {literal_float, F} -> gleam_stdlib:float_to_string(F); literal_true -> <<"True"/utf8>>; literal_false -> <<"False"/utf8>>; {literal_list, _} -> <<"[]"/utf8>>; {literal_struct, _} -> <<"{}"/utf8>> end. -file("src/caffeine_lang/frontend/parser.gleam", 845). -spec parse_optional_type(parser_state()) -> {ok, {caffeine_lang@common@accepted_types:accepted_types(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_optional_type(State) -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_left_paren, <<"("/utf8>>), fun(State@2) -> gleam@result:'try'( parse_type(State@2), fun(_use0) -> {Inner, State@3} = _use0, gleam@result:'try'( expect(State@3, symbol_right_paren, <<")"/utf8>>), fun(State@4) -> {ok, {{modifier_type, {optional, Inner}}, State@4}} end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 687). -spec parse_type(parser_state()) -> {ok, {caffeine_lang@common@accepted_types:accepted_types(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type(State) -> case peek(State) of keyword_string -> parse_type_with_refinement(State, string); keyword_integer -> parse_type_with_refinement(State, {numeric_type, integer}); keyword_float -> parse_type_with_refinement(State, {numeric_type, float}); keyword_boolean -> parse_type_with_refinement(State, boolean); keyword_list -> parse_list_type(State); keyword_dict -> parse_dict_type(State); keyword_optional -> parse_optional_type(State); keyword_defaulted -> parse_defaulted_type(State); {identifier, Name} -> case gleam_stdlib:string_starts_with(Name, <<"_"/utf8>>) of true -> State@1 = advance(State), {ok, {{type_alias_ref, Name}, State@1}}; false -> {error, {unknown_type, Name, erlang:element(3, State), erlang:element(4, State)}} end; Tok -> {error, {unknown_type, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 144). -spec parse_type_alias(parser_state(), binary()) -> {ok, {caffeine_lang@frontend@ast:type_alias(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type_alias(State, Name) -> case Name of <<"_"/utf8>> -> {error, {invalid_type_alias_name, Name, <<"type alias name must have at least one character after the underscore"/utf8>>, erlang:element(3, State), erlang:element(4, State)}}; _ -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_left_paren, <<"("/utf8>>), fun(State@2) -> case peek(State@2) of {identifier, <<"Type"/utf8>>} -> State@3 = advance(State@2), gleam@result:'try'( expect( State@3, symbol_right_paren, <<")"/utf8>> ), fun(State@4) -> gleam@result:'try'( expect( State@4, symbol_colon, <<":"/utf8>> ), fun(State@5) -> gleam@result:'try'( parse_type(State@5), fun(_use0) -> {Type_, State@6} = _use0, {ok, {{type_alias, Name, Type_}, State@6}} end ) end ) end ); Tok -> {error, {unexpected_token, <<"Type"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State@2), erlang:element(4, State@2)}} end end ) end. -file("src/caffeine_lang/frontend/parser.gleam", 115). -spec parse_type_aliases_loop( parser_state(), list(caffeine_lang@frontend@ast:type_alias()) ) -> {ok, {list(caffeine_lang@frontend@ast:type_alias()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type_aliases_loop(State, Acc) -> case peek(State) of {identifier, Name} -> case is_type_alias(State) of true -> gleam@result:'try'( parse_type_alias(State, Name), fun(_use0) -> {Type_alias, State@1} = _use0, parse_type_aliases_loop(State@1, [Type_alias | Acc]) end ); false -> {ok, {lists:reverse(Acc), State}} end; _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 109). ?DOC( " Parse zero or more type aliases at file start.\n" " Type alias syntax: _name (Type): \n" ). -spec parse_type_aliases(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:type_alias()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type_aliases(State) -> parse_type_aliases_loop(State, []). -file("src/caffeine_lang/frontend/parser.gleam", 582). -spec parse_type_field(parser_state()) -> {ok, {caffeine_lang@frontend@ast:field(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type_field(State) -> case peek(State) of {identifier, Name} -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_colon, <<":"/utf8>>), fun(State@2) -> gleam@result:'try'( parse_type(State@2), fun(_use0) -> {Type_, State@3} = _use0, {ok, {{field, Name, {type_value, Type_}}, State@3}} end ) end ); {literal_string, Name@1} -> {error, {quoted_field_name, Name@1, erlang:element(3, State), erlang:element(4, State)}}; Tok -> {error, {unexpected_token, <<"field name"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 562). -spec parse_type_fields_loop( parser_state(), list(caffeine_lang@frontend@ast:field()) ) -> {ok, {list(caffeine_lang@frontend@ast:field()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type_fields_loop(State, Acc) -> case peek(State) of symbol_comma -> State@1 = advance(State), case peek(State@1) of symbol_right_brace -> {ok, {lists:reverse(Acc), State@1}}; _ -> gleam@result:'try'( parse_type_field(State@1), fun(_use0) -> {Field, State@2} = _use0, parse_type_fields_loop(State@2, [Field | Acc]) end ) end; _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 540). -spec parse_type_fields(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:field()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type_fields(State) -> case peek(State) of symbol_right_brace -> {ok, {[], State}}; {identifier, _} -> gleam@result:'try'( parse_type_field(State), fun(_use0) -> {Field, State@1} = _use0, parse_type_fields_loop(State@1, [Field]) end ); {literal_string, Name} -> {error, {quoted_field_name, Name, erlang:element(3, State), erlang:element(4, State)}}; Tok -> {error, {unexpected_token, <<"field name or }"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 531). -spec parse_type_struct(parser_state()) -> {ok, {caffeine_lang@frontend@ast:struct(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type_struct(State) -> gleam@result:'try'( expect(State, symbol_left_brace, <<"{"/utf8>>), fun(State@1) -> gleam@result:'try'( parse_type_fields(State@1), fun(_use0) -> {Fields, State@2} = _use0, gleam@result:'try'( expect(State@2, symbol_right_brace, <<"}"/utf8>>), fun(State@3) -> {ok, {{struct, Fields}, State@3}} end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 793). -spec parse_list_type(parser_state()) -> {ok, {caffeine_lang@common@accepted_types:accepted_types(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_list_type(State) -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_left_paren, <<"("/utf8>>), fun(State@2) -> gleam@result:'try'( parse_collection_inner_type(State@2), fun(_use0) -> {Element, State@3} = _use0, gleam@result:'try'( expect(State@3, symbol_right_paren, <<")"/utf8>>), fun(State@4) -> {ok, {{collection_type, {list, Element}}, State@4}} end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 743). ?DOC( " Parses types valid inside collections: primitives, nested collections, or type alias refs.\n" " Does not allow modifiers (Optional/Defaulted) or refinements directly.\n" ). -spec parse_collection_inner_type(parser_state()) -> {ok, {caffeine_lang@common@accepted_types:accepted_types(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_collection_inner_type(State) -> case peek(State) of keyword_string -> State@1 = advance(State), {ok, {{primitive_type, string}, State@1}}; keyword_integer -> State@2 = advance(State), {ok, {{primitive_type, {numeric_type, integer}}, State@2}}; keyword_float -> State@3 = advance(State), {ok, {{primitive_type, {numeric_type, float}}, State@3}}; keyword_boolean -> State@4 = advance(State), {ok, {{primitive_type, boolean}, State@4}}; keyword_list -> parse_list_type(State); keyword_dict -> parse_dict_type(State); {identifier, Name} -> case gleam_stdlib:string_starts_with(Name, <<"_"/utf8>>) of true -> State@5 = advance(State), {ok, {{type_alias_ref, Name}, State@5}}; false -> {error, {unknown_type, Name, erlang:element(3, State), erlang:element(4, State)}} end; Tok -> {error, {unknown_type, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 803). -spec parse_dict_type(parser_state()) -> {ok, {caffeine_lang@common@accepted_types:accepted_types(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_dict_type(State) -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_left_paren, <<"("/utf8>>), fun(State@2) -> gleam@result:'try'( parse_dict_key_type(State@2), fun(_use0) -> {Key, State@3} = _use0, gleam@result:'try'( expect(State@3, symbol_comma, <<","/utf8>>), fun(State@4) -> gleam@result:'try'( parse_collection_inner_type(State@4), fun(_use0@1) -> {Value, State@5} = _use0@1, gleam@result:'try'( expect( State@5, symbol_right_paren, <<")"/utf8>> ), fun(State@6) -> {ok, {{collection_type, {dict, Key, Value}}, State@6}} end ) end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 1089). -spec parse_literal_struct_value(parser_state()) -> {ok, {caffeine_lang@frontend@ast:literal(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal_struct_value(State) -> gleam@result:'try'( expect(State, symbol_left_brace, <<"{"/utf8>>), fun(State@1) -> gleam@result:'try'( parse_literal_fields(State@1), fun(_use0) -> {Fields, State@2} = _use0, gleam@result:'try'( expect(State@2, symbol_right_brace, <<"}"/utf8>>), fun(State@3) -> {ok, {{literal_struct, Fields}, State@3}} end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 618). -spec parse_literal_fields(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:field()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal_fields(State) -> case peek(State) of symbol_right_brace -> {ok, {[], State}}; {identifier, _} -> gleam@result:'try'( parse_literal_field(State), fun(_use0) -> {Field, State@1} = _use0, parse_literal_fields_loop(State@1, [Field]) end ); {literal_string, Name} -> {error, {quoted_field_name, Name, erlang:element(3, State), erlang:element(4, State)}}; Tok -> {error, {unexpected_token, <<"field name or }"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 660). -spec parse_literal_field(parser_state()) -> {ok, {caffeine_lang@frontend@ast:field(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal_field(State) -> case peek(State) of {identifier, Name} -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_colon, <<":"/utf8>>), fun(State@2) -> gleam@result:'try'( parse_literal(State@2), fun(_use0) -> {Literal, State@3} = _use0, {ok, {{field, Name, {literal_value, Literal}}, State@3}} end ) end ); {literal_string, Name@1} -> {error, {quoted_field_name, Name@1, erlang:element(3, State), erlang:element(4, State)}}; Tok -> {error, {unexpected_token, <<"field name"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 1033). -spec parse_literal(parser_state()) -> {ok, {caffeine_lang@frontend@ast:literal(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal(State) -> case peek(State) of {literal_string, S} -> {ok, {{literal_string, S}, advance(State)}}; {literal_integer, N} -> {ok, {{literal_integer, N}, advance(State)}}; {literal_float, F} -> {ok, {{literal_float, F}, advance(State)}}; literal_true -> {ok, {literal_true, advance(State)}}; literal_false -> {ok, {literal_false, advance(State)}}; symbol_left_bracket -> parse_literal_list(State); symbol_left_brace -> parse_literal_struct_value(State); Tok -> {error, {unexpected_token, <<"literal value"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 609). -spec parse_literal_struct(parser_state()) -> {ok, {caffeine_lang@frontend@ast:struct(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal_struct(State) -> gleam@result:'try'( expect(State, symbol_left_brace, <<"{"/utf8>>), fun(State@1) -> gleam@result:'try'( parse_literal_fields(State@1), fun(_use0) -> {Fields, State@2} = _use0, gleam@result:'try'( expect(State@2, symbol_right_brace, <<"}"/utf8>>), fun(State@3) -> {ok, {{struct, Fields}, State@3}} end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 206). -spec parse_extendable(parser_state(), binary()) -> {ok, {caffeine_lang@frontend@ast:extendable(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_extendable(State, Name) -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_left_paren, <<"("/utf8>>), fun(State@2) -> gleam@result:'try'( parse_extendable_kind(State@2), fun(_use0) -> {Kind, State@3} = _use0, gleam@result:'try'( expect(State@3, symbol_right_paren, <<")"/utf8>>), fun(State@4) -> gleam@result:'try'( expect(State@4, symbol_colon, <<":"/utf8>>), fun(State@5) -> gleam@result:'try'(case Kind of extendable_requires -> parse_type_struct(State@5); extendable_provides -> parse_literal_struct(State@5) end, fun(_use0@1) -> {Body, State@6} = _use0@1, {ok, {{extendable, Name, Kind, Body}, State@6}} end) end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 193). -spec parse_extendables_loop( parser_state(), list(caffeine_lang@frontend@ast:extendable()) ) -> {ok, {list(caffeine_lang@frontend@ast:extendable()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_extendables_loop(State, Acc) -> case peek(State) of {identifier, Name} -> gleam@result:'try'( parse_extendable(State, Name), fun(_use0) -> {Extendable, State@1} = _use0, parse_extendables_loop(State@1, [Extendable | Acc]) end ); _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 187). ?DOC(" Parse zero or more extendables at file start.\n"). -spec parse_extendables(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:extendable()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_extendables(State) -> parse_extendables_loop(State, []). -file("src/caffeine_lang/frontend/parser.gleam", 345). -spec parse_blueprint_item(parser_state()) -> {ok, {caffeine_lang@frontend@ast:blueprint_item(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_blueprint_item(State) -> gleam@result:'try'( expect(State, symbol_star, <<"*"/utf8>>), fun(State@1) -> gleam@result:'try'( parse_string_literal(State@1), fun(_use0) -> {Name, State@2} = _use0, gleam@result:'try'( parse_optional_extends(State@2), fun(_use0@1) -> {Extends, State@3} = _use0@1, gleam@result:'try'( expect(State@3, symbol_colon, <<":"/utf8>>), fun(State@4) -> gleam@result:'try'( expect( State@4, keyword_requires, <<"Requires"/utf8>> ), fun(State@5) -> gleam@result:'try'( parse_type_struct(State@5), fun(_use0@2) -> {Requires, State@6} = _use0@2, gleam@result:'try'( expect( State@6, keyword_provides, <<"Provides"/utf8>> ), fun(State@7) -> gleam@result:'try'( parse_literal_struct( State@7 ), fun(_use0@3) -> {Provides, State@8} = _use0@3, {ok, {{blueprint_item, Name, Extends, Requires, Provides}, State@8}} end ) end ) end ) end ) end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 332). -spec parse_blueprint_items_loop( parser_state(), list(caffeine_lang@frontend@ast:blueprint_item()) ) -> {ok, {list(caffeine_lang@frontend@ast:blueprint_item()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_blueprint_items_loop(State, Acc) -> case peek(State) of symbol_star -> gleam@result:'try'( parse_blueprint_item(State), fun(_use0) -> {Item, State@1} = _use0, parse_blueprint_items_loop(State@1, [Item | Acc]) end ); _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 326). -spec parse_blueprint_items(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:blueprint_item()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_blueprint_items(State) -> parse_blueprint_items_loop(State, []). -file("src/caffeine_lang/frontend/parser.gleam", 273). -spec parse_blueprints_block(parser_state()) -> {ok, {caffeine_lang@frontend@ast:blueprints_block(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_blueprints_block(State) -> gleam@result:'try'( expect(State, keyword_blueprints, <<"Blueprints"/utf8>>), fun(State@1) -> gleam@result:'try'( expect(State@1, keyword_for, <<"for"/utf8>>), fun(State@2) -> gleam@result:'try'( parse_artifacts(State@2), fun(_use0) -> {Artifacts, State@3} = _use0, gleam@result:'try'( parse_blueprint_items(State@3), fun(_use0@1) -> {Items, State@4} = _use0@1, {ok, {{blueprints_block, Artifacts, Items}, State@4}} end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 253). -spec parse_blueprints_blocks_loop( parser_state(), list(caffeine_lang@frontend@ast:blueprints_block()) ) -> {ok, {list(caffeine_lang@frontend@ast:blueprints_block()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_blueprints_blocks_loop(State, Acc) -> case peek(State) of keyword_blueprints -> gleam@result:'try'( parse_blueprints_block(State), fun(_use0) -> {Block, State@1} = _use0, parse_blueprints_blocks_loop(State@1, [Block | Acc]) end ); e_o_f -> {ok, {lists:reverse(Acc), State}}; Tok -> {error, {unexpected_token, <<"Blueprints"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 244). ?DOC(" Parse one or more blueprints blocks.\n"). -spec parse_blueprints_blocks(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:blueprints_block()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_blueprints_blocks(State) -> case peek(State) of e_o_f -> {error, {empty_file, erlang:element(3, State), erlang:element(4, State)}}; _ -> parse_blueprints_blocks_loop(State, []) end. -file("src/caffeine_lang/frontend/parser.gleam", 28). ?DOC(" Parses a blueprints file from source text.\n"). -spec parse_blueprints_file(binary()) -> {ok, caffeine_lang@frontend@ast:blueprints_file()} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_blueprints_file(Source) -> gleam@result:'try'( begin _pipe = caffeine_lang@frontend@tokenizer:tokenize(Source), gleam@result:map_error( _pipe, fun(Field@0) -> {tokenizer_error, Field@0} end ) end, fun(Tokens) -> State = {parser_state, filter_whitespace_comments(Tokens), 1, 1}, gleam@result:'try'( parse_type_aliases(State), fun(_use0) -> {Type_aliases, State@1} = _use0, gleam@result:'try'( parse_extendables(State@1), fun(_use0@1) -> {Extendables, State@2} = _use0@1, gleam@result:'try'( parse_blueprints_blocks(State@2), fun(_use0@2) -> {Blocks, _} = _use0@2, {ok, {blueprints_file, Type_aliases, Extendables, Blocks}} end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 426). -spec parse_expect_item(parser_state()) -> {ok, {caffeine_lang@frontend@ast:expect_item(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_expect_item(State) -> gleam@result:'try'( expect(State, symbol_star, <<"*"/utf8>>), fun(State@1) -> gleam@result:'try'( parse_string_literal(State@1), fun(_use0) -> {Name, State@2} = _use0, gleam@result:'try'( parse_optional_extends(State@2), fun(_use0@1) -> {Extends, State@3} = _use0@1, gleam@result:'try'( expect(State@3, symbol_colon, <<":"/utf8>>), fun(State@4) -> case peek(State@4) of keyword_requires -> {error, {unexpected_token, <<"Provides"/utf8>>, <<"Requires"/utf8>>, erlang:element(3, State@4), erlang:element(4, State@4)}}; _ -> gleam@result:'try'( expect( State@4, keyword_provides, <<"Provides"/utf8>> ), fun(State@5) -> gleam@result:'try'( parse_literal_struct( State@5 ), fun(_use0@2) -> {Provides, State@6} = _use0@2, {ok, {{expect_item, Name, Extends, Provides}, State@6}} end ) end ) end end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 413). -spec parse_expect_items_loop( parser_state(), list(caffeine_lang@frontend@ast:expect_item()) ) -> {ok, {list(caffeine_lang@frontend@ast:expect_item()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_expect_items_loop(State, Acc) -> case peek(State) of symbol_star -> gleam@result:'try'( parse_expect_item(State), fun(_use0) -> {Item, State@1} = _use0, parse_expect_items_loop(State@1, [Item | Acc]) end ); _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 407). -spec parse_expect_items(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:expect_item()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_expect_items(State) -> parse_expect_items_loop(State, []). -file("src/caffeine_lang/frontend/parser.gleam", 393). -spec parse_expects_block(parser_state()) -> {ok, {caffeine_lang@frontend@ast:expects_block(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_expects_block(State) -> gleam@result:'try'( expect(State, keyword_expectations, <<"Expectations"/utf8>>), fun(State@1) -> gleam@result:'try'( expect(State@1, keyword_for, <<"for"/utf8>>), fun(State@2) -> gleam@result:'try'( parse_string_literal(State@2), fun(_use0) -> {Blueprint, State@3} = _use0, gleam@result:'try'( parse_expect_items(State@3), fun(_use0@1) -> {Items, State@4} = _use0@1, {ok, {{expects_block, Blueprint, Items}, State@4}} end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 373). -spec parse_expects_blocks_loop( parser_state(), list(caffeine_lang@frontend@ast:expects_block()) ) -> {ok, {list(caffeine_lang@frontend@ast:expects_block()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_expects_blocks_loop(State, Acc) -> case peek(State) of keyword_expectations -> gleam@result:'try'( parse_expects_block(State), fun(_use0) -> {Block, State@1} = _use0, parse_expects_blocks_loop(State@1, [Block | Acc]) end ); e_o_f -> {ok, {lists:reverse(Acc), State}}; Tok -> {error, {unexpected_token, <<"Expectations"/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 364). ?DOC(" Parse one or more expects blocks.\n"). -spec parse_expects_blocks(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:expects_block()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_expects_blocks(State) -> case peek(State) of e_o_f -> {error, {empty_file, erlang:element(3, State), erlang:element(4, State)}}; _ -> parse_expects_blocks_loop(State, []) end. -file("src/caffeine_lang/frontend/parser.gleam", 44). ?DOC(" Parses an expects file from source text.\n"). -spec parse_expects_file(binary()) -> {ok, caffeine_lang@frontend@ast:expects_file()} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_expects_file(Source) -> gleam@result:'try'( begin _pipe = caffeine_lang@frontend@tokenizer:tokenize(Source), gleam@result:map_error( _pipe, fun(Field@0) -> {tokenizer_error, Field@0} end ) end, fun(Tokens) -> State = {parser_state, filter_whitespace_comments(Tokens), 1, 1}, gleam@result:'try'( parse_extendables(State), fun(_use0) -> {Extendables, State@1} = _use0, gleam@result:'try'( parse_expects_blocks(State@1), fun(_use0@1) -> {Blocks, _} = _use0@1, {ok, {expects_file, Extendables, Blocks}} end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 640). -spec parse_literal_fields_loop( parser_state(), list(caffeine_lang@frontend@ast:field()) ) -> {ok, {list(caffeine_lang@frontend@ast:field()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal_fields_loop(State, Acc) -> case peek(State) of symbol_comma -> State@1 = advance(State), case peek(State@1) of symbol_right_brace -> {ok, {lists:reverse(Acc), State@1}}; _ -> gleam@result:'try'( parse_literal_field(State@1), fun(_use0) -> {Field, State@2} = _use0, parse_literal_fields_loop(State@2, [Field | Acc]) end ) end; _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 1075). -spec parse_literal_list_loop( parser_state(), list(caffeine_lang@frontend@ast:literal()) ) -> {ok, {list(caffeine_lang@frontend@ast:literal()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal_list_loop(State, Acc) -> case peek(State) of symbol_comma -> State@1 = advance(State), gleam@result:'try'( parse_literal(State@1), fun(_use0) -> {Literal, State@2} = _use0, parse_literal_list_loop(State@2, [Literal | Acc]) end ); _ -> {ok, {lists:reverse(Acc), State}} end. -file("src/caffeine_lang/frontend/parser.gleam", 1063). -spec parse_literal_list_contents(parser_state()) -> {ok, {list(caffeine_lang@frontend@ast:literal()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal_list_contents(State) -> case peek(State) of symbol_right_bracket -> {ok, {[], State}}; symbol_right_brace -> {ok, {[], State}}; _ -> gleam@result:'try'( parse_literal(State), fun(_use0) -> {First, State@1} = _use0, parse_literal_list_loop(State@1, [First]) end ) end. -file("src/caffeine_lang/frontend/parser.gleam", 903). -spec parse_defaulted_refinement_body( parser_state(), caffeine_lang@common@accepted_types:accepted_types() ) -> {ok, {caffeine_lang@common@refinement_types:refinement_types(caffeine_lang@common@accepted_types:accepted_types()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_defaulted_refinement_body(State, Defaulted) -> case peek(State) of symbol_left_brace -> State@1 = advance(State), gleam@result:'try'( parse_literal_list_contents(State@1), fun(_use0) -> {Values, State@2} = _use0, gleam@result:'try'( expect(State@2, symbol_right_brace, <<"}"/utf8>>), fun(State@3) -> String_values = gleam@list:map( Values, fun literal_to_string/1 ), {ok, {{one_of, Defaulted, gleam@set:from_list(String_values)}, State@3}} end ) end ); symbol_left_paren -> State@4 = advance(State), gleam@result:'try'( parse_literal(State@4), fun(_use0@1) -> {Min, State@5} = _use0@1, gleam@result:'try'( expect(State@5, symbol_dot_dot, <<".."/utf8>>), fun(State@6) -> gleam@result:'try'( parse_literal(State@6), fun(_use0@2) -> {Max, State@7} = _use0@2, gleam@result:'try'( expect( State@7, symbol_right_paren, <<")"/utf8>> ), fun(State@8) -> {ok, {{inclusive_range, Defaulted, literal_to_string(Min), literal_to_string(Max)}, State@8}} end ) end ) end ) end ); Tok -> {error, {unexpected_token, <<"{ or ("/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 883). ?DOC(" Parse refinement on a Defaulted type: { x | x in { ... } } or { x | x in ( ... ) }\n"). -spec parse_defaulted_refinement( parser_state(), caffeine_lang@common@accepted_types:accepted_types() ) -> {ok, {caffeine_lang@common@refinement_types:refinement_types(caffeine_lang@common@accepted_types:accepted_types()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_defaulted_refinement(State, Defaulted) -> gleam@result:'try'( expect(State, symbol_left_brace, <<"{"/utf8>>), fun(State@1) -> gleam@result:'try'( expect_x(State@1), fun(State@2) -> gleam@result:'try'( expect(State@2, symbol_pipe, <<"|"/utf8>>), fun(State@3) -> gleam@result:'try'( expect_x(State@3), fun(State@4) -> gleam@result:'try'( expect( State@4, keyword_in, <<"in"/utf8>> ), fun(State@5) -> gleam@result:'try'( parse_defaulted_refinement_body( State@5, Defaulted ), fun(_use0) -> {Refinement, State@6} = _use0, gleam@result:'try'( expect( State@6, symbol_right_brace, <<"}"/utf8>> ), fun(State@7) -> {ok, {Refinement, State@7}} end ) end ) end ) end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 855). -spec parse_defaulted_type(parser_state()) -> {ok, {caffeine_lang@common@accepted_types:accepted_types(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_defaulted_type(State) -> State@1 = advance(State), gleam@result:'try'( expect(State@1, symbol_left_paren, <<"("/utf8>>), fun(State@2) -> gleam@result:'try'( parse_type(State@2), fun(_use0) -> {Inner, State@3} = _use0, gleam@result:'try'( expect(State@3, symbol_comma, <<","/utf8>>), fun(State@4) -> gleam@result:'try'( parse_literal(State@4), fun(_use0@1) -> {Default, State@5} = _use0@1, gleam@result:'try'( expect( State@5, symbol_right_paren, <<")"/utf8>> ), fun(State@6) -> Defaulted = {modifier_type, {defaulted, Inner, literal_to_string(Default)}}, case peek(State@6) of symbol_left_brace -> gleam@result:'try'( parse_defaulted_refinement( State@6, Defaulted ), fun(_use0@2) -> {Refinement, State@7} = _use0@2, {ok, {{refinement_type, Refinement}, State@7}} end ); _ -> {ok, {Defaulted, State@6}} end end ) end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 981). -spec parse_refinement_body( parser_state(), caffeine_lang@common@primitive_types:primitive_types() ) -> {ok, {caffeine_lang@common@refinement_types:refinement_types(caffeine_lang@common@accepted_types:accepted_types()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_refinement_body(State, Primitive) -> case peek(State) of symbol_left_brace -> State@1 = advance(State), gleam@result:'try'( parse_literal_list_contents(State@1), fun(_use0) -> {Values, State@2} = _use0, gleam@result:'try'( expect(State@2, symbol_right_brace, <<"}"/utf8>>), fun(State@3) -> String_values = gleam@list:map( Values, fun literal_to_string/1 ), {ok, {{one_of, {primitive_type, Primitive}, gleam@set:from_list(String_values)}, State@3}} end ) end ); symbol_left_paren -> State@4 = advance(State), gleam@result:'try'( parse_literal(State@4), fun(_use0@1) -> {Min, State@5} = _use0@1, gleam@result:'try'( expect(State@5, symbol_dot_dot, <<".."/utf8>>), fun(State@6) -> gleam@result:'try'( parse_literal(State@6), fun(_use0@2) -> {Max, State@7} = _use0@2, gleam@result:'try'( expect( State@7, symbol_right_paren, <<")"/utf8>> ), fun(State@8) -> {ok, {{inclusive_range, {primitive_type, Primitive}, literal_to_string(Min), literal_to_string(Max)}, State@8}} end ) end ) end ) end ); Tok -> {error, {unexpected_token, <<"{ or ("/utf8>>, caffeine_lang@frontend@token:to_string(Tok), erlang:element(3, State), erlang:element(4, State)}} end. -file("src/caffeine_lang/frontend/parser.gleam", 952). -spec parse_refinement( parser_state(), caffeine_lang@common@primitive_types:primitive_types() ) -> {ok, {caffeine_lang@common@refinement_types:refinement_types(caffeine_lang@common@accepted_types:accepted_types()), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_refinement(State, Primitive) -> gleam@result:'try'( expect(State, symbol_left_brace, <<"{"/utf8>>), fun(State@1) -> gleam@result:'try'( expect_x(State@1), fun(State@2) -> gleam@result:'try'( expect(State@2, symbol_pipe, <<"|"/utf8>>), fun(State@3) -> gleam@result:'try'( expect_x(State@3), fun(State@4) -> gleam@result:'try'( expect( State@4, keyword_in, <<"in"/utf8>> ), fun(State@5) -> gleam@result:'try'( parse_refinement_body( State@5, Primitive ), fun(_use0) -> {Refinement, State@6} = _use0, gleam@result:'try'( expect( State@6, symbol_right_brace, <<"}"/utf8>> ), fun(State@7) -> {ok, {Refinement, State@7}} end ) end ) end ) end ) end ) end ) end ). -file("src/caffeine_lang/frontend/parser.gleam", 727). -spec parse_type_with_refinement( parser_state(), caffeine_lang@common@primitive_types:primitive_types() ) -> {ok, {caffeine_lang@common@accepted_types:accepted_types(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_type_with_refinement(State, Primitive) -> State@1 = advance(State), case peek(State@1) of symbol_left_brace -> gleam@result:'try'( parse_refinement(State@1, Primitive), fun(_use0) -> {Refinement, State@2} = _use0, {ok, {{refinement_type, Refinement}, State@2}} end ); _ -> {ok, {{primitive_type, Primitive}, State@1}} end. -file("src/caffeine_lang/frontend/parser.gleam", 1054). -spec parse_literal_list(parser_state()) -> {ok, {caffeine_lang@frontend@ast:literal(), parser_state()}} | {error, caffeine_lang@frontend@parser_error:parser_error()}. parse_literal_list(State) -> gleam@result:'try'( expect(State, symbol_left_bracket, <<"["/utf8>>), fun(State@1) -> gleam@result:'try'( parse_literal_list_contents(State@1), fun(_use0) -> {Elements, State@2} = _use0, gleam@result:'try'( expect(State@2, symbol_right_bracket, <<"]"/utf8>>), fun(State@3) -> {ok, {{literal_list, Elements}, State@3}} end ) end ) end ).