Current section
Files
Jump to
Current section
Files
lib/common/errors/row_col_detecter.ex
defmodule Error.RowColDetecter do
@moduledoc """
Module that identifies the row and column inside the source code string of the fault token identified in the lexing process.
"""
@doc """
Given a token and a source code string, it will return a tuple containing the row and column of the token inside the source code.
As a side note, the source code string must be raw, which means it should contain the newline and tabs special characters.
## Specs
```token``` fault token identified in the `Lexer` output.
```raw_source_code_string``` contains the source code string with special characters removals like newline or tabs.
"""
def find_row_col(token, raw_source_code_string) do
{num_row, row} = find_row(token, raw_source_code_string)
num_col = find_col(token, row)
{num_row + 1, num_col + 1}
end
defp find_row(token, source_code_string) do
chunks = String.split(source_code_string, "\n")
num_row = chunks
|> find(token, _row=true)
row = Enum.at(chunks, num_row)
{num_row, row}
end
defp find_col(token, row) do
String.split(row, " ")
|> find(token, _row=false)
end
defp find(list, token, _row=true) do
Enum.reduce_while(list, 0, fn x, acc ->
if String.contains?(x, "#{token.expression}"),
do: {:halt, acc},
else: {:cont, acc + 1}
end)
end
defp find(list, token, _row=false) do
Enum.reduce_while(list, 0, fn x, acc ->
if String.contains?(x, "#{token.expression}"),
do: {:halt, acc},
else: {:cont, acc + String.length(x) + 1}
end)
end
end