mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44:20 +03:00
Add parse errors formatter
This commit is contained in:
parent
0d820c8a91
commit
2578f0a6b4
@ -154,7 +154,9 @@ public final class Main {
|
|||||||
.then(scopedStages.create("Execution", new ExecutionStage()))
|
.then(scopedStages.create("Execution", new ExecutionStage()))
|
||||||
.perform(stagesData, input);
|
.perform(stagesData, input);
|
||||||
} catch (OwnLangParserException ex) {
|
} catch (OwnLangParserException ex) {
|
||||||
System.err.println(ex.getParseErrors());
|
final var error = new ParseErrorsFormatterStage()
|
||||||
|
.perform(stagesData, ex.getParseErrors());
|
||||||
|
System.err.println(error);
|
||||||
} catch (StoppedException ex) {
|
} catch (StoppedException ex) {
|
||||||
// skip
|
// skip
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.annimon.ownlang.stages;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.Console;
|
||||||
|
import com.annimon.ownlang.parser.Pos;
|
||||||
|
import com.annimon.ownlang.parser.Range;
|
||||||
|
import com.annimon.ownlang.parser.error.ParseError;
|
||||||
|
import com.annimon.ownlang.parser.error.ParseErrors;
|
||||||
|
|
||||||
|
public class ParseErrorsFormatterStage implements Stage<ParseErrors, String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String perform(StagesData stagesData, ParseErrors input) {
|
||||||
|
final var sb = new StringBuilder();
|
||||||
|
final String source = stagesData.get(SourceLoaderStage.TAG_SOURCE);
|
||||||
|
final var lines = source.split("\r?\n");
|
||||||
|
for (ParseError parseError : input) {
|
||||||
|
sb.append(Console.newline());
|
||||||
|
sb.append(parseError);
|
||||||
|
sb.append(Console.newline());
|
||||||
|
final Range range = parseError.range().normalize();
|
||||||
|
printPosition(sb, range, lines);
|
||||||
|
if (parseError.hasStackTrace()) {
|
||||||
|
sb.append("Stack trace:");
|
||||||
|
sb.append(Console.newline());
|
||||||
|
for (StackTraceElement el : parseError.stackTraceElements()) {
|
||||||
|
sb.append(" ").append(el).append(Console.newline());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printPosition(StringBuilder sb, Range range, String[] lines) {
|
||||||
|
final Pos start = range.start();
|
||||||
|
final int linesCount = lines.length;;
|
||||||
|
if (range.isOnSameLine()) {
|
||||||
|
if (start.row() < linesCount) {
|
||||||
|
sb.append(lines[start.row()]);
|
||||||
|
sb.append(Console.newline());
|
||||||
|
sb.append(" ".repeat(start.col()));
|
||||||
|
sb.append("^".repeat(range.end().col() - start.col() + 1));
|
||||||
|
sb.append(Console.newline());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (start.row() < linesCount) {
|
||||||
|
String line = lines[start.row()];
|
||||||
|
sb.append(line);
|
||||||
|
sb.append(Console.newline());
|
||||||
|
sb.append(" ".repeat(start.col()));
|
||||||
|
sb.append("^".repeat(Math.max(1, line.length() - start.col())));
|
||||||
|
sb.append(Console.newline());
|
||||||
|
}
|
||||||
|
final Pos end = range.end();
|
||||||
|
if (end.row() < linesCount) {
|
||||||
|
sb.append(lines[end.row()]);
|
||||||
|
sb.append(Console.newline());
|
||||||
|
sb.append("^".repeat(end.col()));
|
||||||
|
sb.append(Console.newline());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user