Current section

Files

Jump to
caffeine_lang src caffeine_query_language@generator.erl
Raw

src/caffeine_query_language@generator.erl

-module(caffeine_query_language@generator).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_query_language/generator.gleam").
-export([substitute_words/2, extract_words/1, resolve_slo_to_expression/2]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/caffeine_query_language/generator.gleam", 18).
?DOC(false).
-spec substitute_words(
caffeine_query_language@ast:exp(any()),
gleam@dict:dict(binary(), binary())
) -> caffeine_query_language@ast:exp(caffeine_query_language@ast:substituted()).
substitute_words(Exp, Substitutions) ->
case Exp of
{primary, {primary_word, {word, Name}}} ->
Value = begin
_pipe = gleam_stdlib:map_get(Substitutions, Name),
gleam@result:unwrap(_pipe, Name)
end,
{primary, {primary_word, {word, Value}}};
{primary, {primary_exp, Inner}} ->
{primary, {primary_exp, substitute_words(Inner, Substitutions)}};
{time_slice_expr, Spec} ->
Query = begin
_pipe@1 = gleam_stdlib:map_get(
Substitutions,
erlang:element(2, Spec)
),
gleam@result:unwrap(_pipe@1, erlang:element(2, Spec))
end,
{time_slice_expr,
{time_slice_exp,
Query,
erlang:element(3, Spec),
erlang:element(4, Spec),
erlang:element(5, Spec)}};
{operator_expr, Left, Right, Op} ->
{operator_expr,
substitute_words(Left, Substitutions),
substitute_words(Right, Substitutions),
Op}
end.
-file("src/caffeine_query_language/generator.gleam", 53).
?DOC(" Accumulates unique word names into a Set.\n").
-spec extract_words_loop(
caffeine_query_language@ast:exp(any()),
gleam@set:set(binary())
) -> gleam@set:set(binary()).
extract_words_loop(Exp, Acc) ->
case Exp of
{primary, {primary_word, {word, Name}}} ->
gleam@set:insert(Acc, Name);
{primary, {primary_exp, Inner}} ->
extract_words_loop(Inner, Acc);
{time_slice_expr, _} ->
Acc;
{operator_expr, Left, Right, _} ->
extract_words_loop(Right, extract_words_loop(Left, Acc))
end.
-file("src/caffeine_query_language/generator.gleam", 46).
?DOC(false).
-spec extract_words(caffeine_query_language@ast:exp(any())) -> list(binary()).
extract_words(Exp) ->
_pipe = extract_words_loop(Exp, gleam@set:new()),
_pipe@1 = gleam@set:to_list(_pipe),
gleam@list:sort(_pipe@1, fun gleam@string:compare/2).
-file("src/caffeine_query_language/generator.gleam", 92).
?DOC(
" Validate that all words in an expression exist in the substitutions dict.\n"
" Returns an error listing any missing indicator names.\n"
).
-spec validate_words_exist(
caffeine_query_language@ast:exp(any()),
gleam@dict:dict(binary(), binary()),
fun(() -> {ok, binary()} | {error, binary()})
) -> {ok, binary()} | {error, binary()}.
validate_words_exist(Exp, Substitutions, Next) ->
Missing = begin
_pipe = extract_words(Exp),
gleam@list:filter(
_pipe,
fun(Word) -> case gleam_stdlib:map_get(Substitutions, Word) of
{ok, _} ->
false;
{error, _} ->
true
end end
)
end,
case Missing of
[] ->
Next();
_ ->
{error,
<<"evaluation references undefined indicators: "/utf8,
(gleam@string:join(Missing, <<", "/utf8>>))/binary>>}
end.
-file("src/caffeine_query_language/generator.gleam", 68).
?DOC(false).
-spec resolve_slo_to_expression(binary(), gleam@dict:dict(binary(), binary())) -> {ok,
binary()} |
{error, binary()}.
resolve_slo_to_expression(Value_expr, Substitutions) ->
gleam@result:'try'(
begin
_pipe = caffeine_query_language@parser:parse_expr(Value_expr),
gleam@result:map_error(
_pipe,
fun(Err) -> <<"Parse error: "/utf8, Err/binary>> end
)
end,
fun(Parsed) ->
Exp = case caffeine_query_language@resolver:resolve_primitives(
Parsed
) of
{ok, {good_over_total, Num, Den}} ->
{ok, {operator_expr, Num, Den, 'div'}};
{ok, {time_slice, _, _, _, _}} ->
{error,
<<"time_slice expressions are not supported for expression resolution"/utf8>>};
{error, _} ->
{ok, Parsed}
end,
gleam@result:'try'(
Exp,
fun(Exp@1) ->
validate_words_exist(
Exp@1,
Substitutions,
fun() ->
{ok,
begin
_pipe@1 = substitute_words(
Exp@1,
Substitutions
),
caffeine_query_language@printer:exp_to_string(
_pipe@1
)
end}
end
)
end
)
end
).