Packages

BEAM stack trace in Gleam: a stack trace of stack frames with module name, function name, arity, file name and line number.

Current section

Files

Jump to
stacky src stacky.erl
Raw

src/stacky.erl

-module(stacky).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([erlang_module_name/1, gleam_module_name/1, function_name/1, function_arity/1, erlang_file_name/1, erlang_line_number/1, frame_to_string/1, print_frame_ln/1, frame/2, trace/0, main/0]).
-export_type([stack_trace/0, stack_frame/0, erlang_module_name/0, function_name/0, function_arity/0, erlang_file_name/0, erlang_line_number/0]).
-type stack_trace() :: {stack_trace, list(stack_frame())}.
-type stack_frame() :: {stack_frame,
erlang_module_name(),
function_name(),
function_arity(),
erlang_file_name(),
erlang_line_number()}.
-type erlang_module_name() :: {erlang_module_name, binary()}.
-type function_name() :: {function_name, binary()}.
-type function_arity() :: {function_arity, integer()}.
-type erlang_file_name() :: {erlang_file_name, binary()}.
-type erlang_line_number() :: {erlang_line_number, integer()}.
-spec erlang_module_name(stack_frame()) -> binary().
erlang_module_name(Stack_frame) ->
{erlang_module_name, Erlang_module_name} = erlang:element(2, Stack_frame),
Erlang_module_name.
-spec gleam_module_name(stack_frame()) -> binary().
gleam_module_name(Stack_frame) ->
Erlang_module_name = begin
_pipe = Stack_frame,
erlang_module_name(_pipe)
end,
_assert_subject = gleam@regex:from_string(<<"@@"/utf8>>),
{ok, Double_at_re} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"stacky"/utf8>>,
function => <<"gleam_module_name"/utf8>>,
line => 91})
end,
_assert_subject@1 = gleam@regex:from_string(<<"@"/utf8>>),
{ok, Single_at_re} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"stacky"/utf8>>,
function => <<"gleam_module_name"/utf8>>,
line => 92})
end,
Has_double_ats = begin
_pipe@1 = Erlang_module_name,
_pipe@2 = gleam@regex:scan(Double_at_re, _pipe@1),
gleam@list:is_empty(_pipe@2)
end
=:= false,
Has_ats = begin
_pipe@3 = Erlang_module_name,
_pipe@4 = gleam@regex:scan(Single_at_re, _pipe@3),
gleam@list:is_empty(_pipe@4)
end
=:= false,
case {Has_double_ats, Has_ats} of
{true, _} ->
<<Erlang_module_name/binary, " (gleam internal module)"/utf8>>;
{false, false} ->
Erlang_module_name;
{false, true} ->
_pipe@5 = Erlang_module_name,
gleam@string:replace(_pipe@5, <<"@"/utf8>>, <<"/"/utf8>>)
end.
-spec function_name(stack_frame()) -> binary().
function_name(Stack_frame) ->
{function_name, Function_name} = erlang:element(3, Stack_frame),
Function_name.
-spec function_arity(stack_frame()) -> integer().
function_arity(Stack_frame) ->
{function_arity, Function_arity} = erlang:element(4, Stack_frame),
Function_arity.
-spec erlang_file_name(stack_frame()) -> binary().
erlang_file_name(Stack_frame) ->
{erlang_file_name, Erlang_file_name} = erlang:element(5, Stack_frame),
Erlang_file_name.
-spec erlang_line_number(stack_frame()) -> integer().
erlang_line_number(Stack_frame) ->
{erlang_line_number, Erlang_line_number} = erlang:element(6, Stack_frame),
Erlang_line_number.
-spec frame_to_string(stack_frame()) -> binary().
frame_to_string(Stack_frame) ->
Erlang_module_name = begin
_pipe = Stack_frame,
gleam_module_name(_pipe)
end,
Function_name = begin
_pipe@1 = Stack_frame,
function_name(_pipe@1)
end,
Function_arity = begin
_pipe@2 = Stack_frame,
_pipe@3 = function_arity(_pipe@2),
gleam@int:to_string(_pipe@3)
end,
Erlang_file_name = begin
_pipe@4 = Stack_frame,
erlang_file_name(_pipe@4)
end,
Erlang_line_number = begin
_pipe@5 = Stack_frame,
_pipe@6 = erlang_line_number(_pipe@5),
gleam@int:to_string(_pipe@6)
end,
<<<<<<<<<<<<<<<<Erlang_module_name/binary, "."/utf8>>/binary,
Function_name/binary>>/binary,
" - arity: "/utf8>>/binary,
Function_arity/binary>>/binary,
" - erlang file: "/utf8>>/binary,
Erlang_file_name/binary>>/binary,
":"/utf8>>/binary,
Erlang_line_number/binary>>.
-spec print_frame_ln(stack_frame()) -> nil.
print_frame_ln(Stack_frame) ->
gleam_erlang_ffi:sleep(100),
_pipe = Stack_frame,
_pipe@1 = frame_to_string(_pipe),
gleam@io:println(_pipe@1),
gleam_erlang_ffi:sleep(100).
-spec list_at(list(GMJ), integer()) -> {ok, GMJ} | {error, nil}.
list_at(List, Index) ->
case Index >= 0 of
true ->
_pipe = List,
_pipe@1 = gleam@list:drop(_pipe, Index),
gleam@list:first(_pipe@1);
false ->
{error, nil}
end.
-spec frame(stack_trace(), integer()) -> stack_frame().
frame(Stacktrace, Index) ->
{stack_trace, Stacktrace@1} = Stacktrace,
case begin
_pipe = Stacktrace@1,
list_at(_pipe, Index)
end of
{ok, Stackframe} ->
Stackframe;
{error, _} ->
Panic_msg = <<<<"No stack frame at index "/utf8,
(gleam@int:to_string(Index))/binary>>/binary,
"."/utf8>>,
erlang:error(#{gleam_error => panic,
message => Panic_msg,
module => <<"stacky"/utf8>>,
function => <<"frame"/utf8>>,
line => 76})
end.
-spec trace() -> stack_trace().
trace() ->
Erlang_stack_trace = stacky_ffi:stacky_erlang_stacktrace(),
_pipe = Erlang_stack_trace,
_pipe@1 = gleam@list:map(
_pipe,
fun(Frame) ->
{Erlang_module_name,
Function_name,
Function_arity,
Erlang_file_name,
Erlang_line_number} = Frame,
{stack_frame,
{erlang_module_name, Erlang_module_name},
{function_name, Function_name},
{function_arity, Function_arity},
{erlang_file_name, Erlang_file_name},
{erlang_line_number, Erlang_line_number}}
end
),
{stack_trace, _pipe@1}.
-spec main() -> nil.
main() ->
Stack = begin
_pipe = trace(),
pprint:debug(_pipe)
end,
Frame = begin
_pipe@1 = Stack,
_pipe@2 = frame(_pipe@1, 0),
pprint:debug(_pipe@2)
end,
_pipe@3 = Frame,
_pipe@4 = gleam_module_name(_pipe@3),
pprint:debug(_pipe@4),
_pipe@5 = Frame,
_pipe@6 = function_name(_pipe@5),
pprint:debug(_pipe@6),
_pipe@7 = Frame,
print_frame_ln(_pipe@7).