42 lines
1.1 KiB
Erlang
42 lines
1.1 KiB
Erlang
-module(akh_source_map).
|
|
-moduledoc """
|
|
The source map translates the byte offsets returned by the lexer into lines and
|
|
columns for display. Internally, it uses the balanced binary tree from
|
|
`m:gb_trees` to avoid linear lookup times.
|
|
""".
|
|
|
|
-export([
|
|
new/0,
|
|
insert/2,
|
|
location/2
|
|
]).
|
|
|
|
-export_type([source_map/0]).
|
|
|
|
-opaque source_map() :: {gb_trees:tree(non_neg_integer(), pos_integer()), Line :: pos_integer()}.
|
|
|
|
-type location() :: {Line :: pos_integer(), Column :: pos_integer()}.
|
|
|
|
-doc """
|
|
Returns a new source map.
|
|
""".
|
|
-spec new() -> source_map().
|
|
new() -> {gb_trees:empty(), 1}.
|
|
|
|
-doc """
|
|
Insert the next line break at byte offset `Offset`.
|
|
""".
|
|
-spec insert(Offset :: non_neg_integer(), SourceMap :: source_map()) -> source_map().
|
|
insert(Offset, {Tree, Line}) -> {gb_trees:insert(Offset - 1, Line + 1, Tree), Line + 1}.
|
|
|
|
-doc """
|
|
Get line and column info for byte offset `Offset`.
|
|
""".
|
|
-spec location(Offset :: non_neg_integer(), SourceMap :: source_map()) -> location().
|
|
location(Offset, {Tree, _}) ->
|
|
case gb_trees:smaller(Offset, Tree) of
|
|
{Start, Line} ->
|
|
{Line, Offset - Start};
|
|
none ->
|
|
{1, Offset}
|
|
end.
|