-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.