Current section
Files
Jump to
Current section
Files
src/handles@internal@engine.erl
-module(handles@internal@engine).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([run/3]).
-export_type([action/0]).
-type action() :: {set_ctx, handles@ctx:value()} |
{run_ast, list(handles@internal@parser:ast())}.
-spec eval(
list(action()),
handles@ctx:value(),
gleam@dict:dict(binary(), list(handles@internal@parser:ast())),
gleam@string_builder:string_builder()
) -> {ok, gleam@string_builder:string_builder()} |
{error, handles@error:runtime_error()}.
eval(Actions, Ctx, Partials, Builder) ->
case Actions of
[] ->
{ok, Builder};
[{set_ctx, New_ctx} | Rest_action] ->
eval(Rest_action, New_ctx, Partials, Builder);
[{run_ast, []} | Rest_action@1] ->
eval(Rest_action@1, Ctx, Partials, Builder);
[{run_ast, [{constant, _, Value} | Rest_ast]} | Rest_action@2] ->
eval(
[{run_ast, Rest_ast} | Rest_action@2],
Ctx,
Partials,
gleam@string_builder:append(Builder, Value)
);
[{run_ast, [{property, Index, Path} | Rest_ast@1]} | Rest_action@3] ->
case handles@internal@ctx_utils:get_property(Path, Ctx, Index) of
{error, Err} ->
{error, Err};
{ok, Value@1} ->
eval(
[{run_ast, Rest_ast@1} | Rest_action@3],
Ctx,
Partials,
gleam@string_builder:append(Builder, Value@1)
)
end;
[{run_ast, [{partial, Index@1, Id, Path@1} | Rest_ast@2]} |
Rest_action@4] ->
case gleam@dict:get(Partials, Id) of
{error, _} ->
{error, {unknown_partial, Index@1, Id}};
{ok, Partial_ast} ->
case handles@internal@ctx_utils:get(Path@1, Ctx, Index@1) of
{error, Err@1} ->
{error, Err@1};
{ok, Inner_ctx} ->
eval(
[{set_ctx, Inner_ctx},
{run_ast, Partial_ast},
{set_ctx, Ctx},
{run_ast, Rest_ast@2} |
Rest_action@4],
Ctx,
Partials,
Builder
)
end
end;
[{run_ast,
[{block, Start_index, _, 'if', Path@2, Children} | Rest_ast@3]} |
Rest_action@5] ->
case handles@internal@ctx_utils:get_bool(Path@2, Ctx, Start_index) of
{error, Err@2} ->
{error, Err@2};
{ok, false} ->
eval(
[{run_ast, Rest_ast@3} | Rest_action@5],
Ctx,
Partials,
Builder
);
{ok, true} ->
eval(
[{run_ast, Children},
{run_ast, Rest_ast@3} |
Rest_action@5],
Ctx,
Partials,
Builder
)
end;
[{run_ast,
[{block, Start_index@1, _, unless, Path@3, Children@1} |
Rest_ast@4]} |
Rest_action@6] ->
case handles@internal@ctx_utils:get_bool(Path@3, Ctx, Start_index@1) of
{error, Err@3} ->
{error, Err@3};
{ok, true} ->
eval(
[{run_ast, Rest_ast@4} | Rest_action@6],
Ctx,
Partials,
Builder
);
{ok, false} ->
eval(
[{run_ast, Children@1},
{run_ast, Rest_ast@4} |
Rest_action@6],
Ctx,
Partials,
Builder
)
end;
[{run_ast,
[{block, Start_index@2, _, each, Path@4, Children@2} |
Rest_ast@5]} |
Rest_action@7] ->
case handles@internal@ctx_utils:get_list(Path@4, Ctx, Start_index@2) of
{error, Err@4} ->
{error, Err@4};
{ok, []} ->
eval(
[{run_ast, Rest_ast@5} | Rest_action@7],
Ctx,
Partials,
Builder
);
{ok, Ctxs} ->
eval(
begin
_pipe = Ctxs,
_pipe@1 = gleam@list:flat_map(
_pipe,
fun(New_ctx@1) ->
[{set_ctx, New_ctx@1},
{run_ast, Children@2},
{set_ctx, Ctx}]
end
),
lists:append(
_pipe@1,
[{run_ast, Rest_ast@5} | Rest_action@7]
)
end,
Ctx,
Partials,
Builder
)
end
end.
-spec run(
list(handles@internal@parser:ast()),
handles@ctx:value(),
gleam@dict:dict(binary(), list(handles@internal@parser:ast()))
) -> {ok, gleam@string_builder:string_builder()} |
{error, handles@error:runtime_error()}.
run(Ast, Ctx, Partials) ->
eval([{run_ast, Ast}], Ctx, Partials, gleam@string_builder:new()).