{
:show
}
Where
Define (show file_name text message i)
Let {line start} (locate_token text i)
Let end i
In
Begin {
(STDIO.print_line
(STRING.concat
[file_name & ":" & (Z.show line) & ": " & message & 'nil]))
When [start < (STRING.length text)] {
(show_token text start end)
}
}
Where
Define (locate_token text j)
Let {k line}
Iterate {i line k} From {0 1 0}
If [i = j]
{k line}
If [(STRING.fetch text i) = `\n`]
(Continue [i + 1] [line + 1] i)
(Continue [i + 1] line k)
In
Iterate i From k
Let start (SCAN.skip_whitespace text i)
In
Let {i _} (SCAN.token text start)
In
If [i = j]
{line start}
(Continue i)
Define (show_token text start end)
Let n (STRING.length text)
In
Iterate {j line line_start} From {0 0 0}
Begin Cond {
| [j = n]
(OS.die "Unexpected EOF.")
| [j = start]
Let line_end
Iterate i From j
Cond {
| [i = n]
(OS.die "Unexpected EOF.")
| [(STRING.fetch text i) = `\n`]
i
| True
(Continue [i + 1])
}
(STDIO.print_line (STRING.clip text line_start line_end))
Iterate i From line_start
When [i != start] {
(STDIO.print " ")
(Continue [i + 1])
}
Iterate i From start
When [i != end] {
(STDIO.print "^")
(Continue [i + 1])
}
(STDIO.print_line "")
| [(STRING.fetch text j) = `\n`]
(Continue [j + 1] [line + 1] [j + 1])
| True
(Continue [j + 1] line line_start)
}
Where
Open Z
{
:Infix <
:Infix =
:Infix !=
:Infix +
}
Open LIST {:Infix &}
Where
Let LIST Package "list"
Let OS Package "os"
Let SCAN Package "scan"
Let STDIO Package "stdio"
Let STRING Package "string"
Let Z Package "z"