{ : 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 [Right file_name & ":" & (Z.show line) & ": " & message & 'nil])) When [start < (STRING.length text)] (show_token text start end) End 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.whitespace text i) In Let {i _} (SCAN.token text i) 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} 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]) ; In Begin (STDIO.print_line (STRING.clip text line_start line_end)) Iterate i From line_start When [i != start] (STDIO.print " ") (Continue [i + 1]) End Iterate i From start When [i != end] (STDIO.print "^") (Continue [i + 1]) End (STDIO.print_line "") End | [(STRING.fetch text j) = `\n`] (Continue [j + 1] [line + 1] [j + 1]) | True (Continue [j + 1] line line_start) ; Where Let OS Package "os" Let SCAN Package "scan" Let STDIO Package "stdio" Let STRING Package "string" Let Z Package "z"