forked from katzen-cafe/iowo
lang: add highlighting to errors
This commit is contained in:
parent
29cdcfbe0c
commit
4bcaf945d7
6 changed files with 128 additions and 15 deletions
37
Cargo.lock
generated
37
Cargo.lock
generated
|
@ -469,6 +469,12 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -519,6 +525,23 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is-terminal"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_ci"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
|
@ -546,6 +569,7 @@ dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"indoc",
|
"indoc",
|
||||||
"logos",
|
"logos",
|
||||||
|
"owo-colors",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
"rowan",
|
"rowan",
|
||||||
]
|
]
|
||||||
|
@ -697,6 +721,9 @@ name = "owo-colors"
|
||||||
version = "4.0.0"
|
version = "4.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f"
|
checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f"
|
||||||
|
dependencies = [
|
||||||
|
"supports-color",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "petgraph"
|
name = "petgraph"
|
||||||
|
@ -974,6 +1001,16 @@ version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "supports-color"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89"
|
||||||
|
dependencies = [
|
||||||
|
"is-terminal",
|
||||||
|
"is_ci",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "svg-filters"
|
name = "svg-filters"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
@ -16,6 +16,7 @@ rowan = "0.15.15"
|
||||||
drop_bomb = "0.1.5"
|
drop_bomb = "0.1.5"
|
||||||
enumset = "1.1.3"
|
enumset = "1.1.3"
|
||||||
indoc = "2"
|
indoc = "2"
|
||||||
|
owo-colors = {version = "4", features = ["supports-colors"]}
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
use enumset::enum_set;
|
||||||
|
|
||||||
use crate::lst_parser::syntax_kind::SyntaxKind;
|
use crate::lst_parser::syntax_kind::SyntaxKind;
|
||||||
|
|
||||||
|
use super::syntax_kind::TokenSet;
|
||||||
|
|
||||||
pub struct Input<'src, 'toks> {
|
pub struct Input<'src, 'toks> {
|
||||||
raw: &'toks Vec<(SyntaxKind, &'src str)>,
|
raw: &'toks Vec<(SyntaxKind, &'src str)>,
|
||||||
/// indices of the "meaningful" tokens (not whitespace etc)
|
/// indices of the "meaningful" tokens (not whitespace etc)
|
||||||
|
@ -10,14 +14,19 @@ pub struct Input<'src, 'toks> {
|
||||||
newlines: Vec<usize>,
|
newlines: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const MEANINGLESS_TOKS: TokenSet = enum_set!(SyntaxKind::WHITESPACE | SyntaxKind::NEWLINE);
|
||||||
|
|
||||||
impl<'src, 'toks> Input<'src, 'toks> {
|
impl<'src, 'toks> Input<'src, 'toks> {
|
||||||
pub fn new(raw_toks: &'toks Vec<(SyntaxKind, &'src str)>) -> Self {
|
pub fn new(raw_toks: &'toks Vec<(SyntaxKind, &'src str)>) -> Self {
|
||||||
let meaningful = raw_toks
|
let meaningful = raw_toks
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(i, tok)| match tok.0 {
|
.filter_map(|(i, tok)| {
|
||||||
SyntaxKind::WHITESPACE | SyntaxKind::NEWLINE => None,
|
if MEANINGLESS_TOKS.contains(tok.0) {
|
||||||
_ => Some(i),
|
None
|
||||||
|
} else {
|
||||||
|
Some(i)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let newlines = raw_toks
|
let newlines = raw_toks
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
use owo_colors::{unset_override, OwoColorize};
|
||||||
use rowan::{GreenNode, GreenNodeBuilder, GreenNodeData, GreenTokenData, Language, NodeOrToken};
|
use rowan::{GreenNode, GreenNodeBuilder, GreenNodeData, GreenTokenData, Language, NodeOrToken};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use crate::lst_parser::syntax_kind::{Lang, SyntaxKind};
|
use crate::lst_parser::{
|
||||||
|
input::MEANINGLESS_TOKS,
|
||||||
|
syntax_kind::{Lang, SyntaxKind},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{error::SyntaxError, events::Event};
|
use super::{error::SyntaxError, events::Event};
|
||||||
|
|
||||||
|
@ -14,47 +18,109 @@ impl std::fmt::Debug for Output {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let mut errs: Vec<&SyntaxError> = self.errors.iter().collect();
|
let mut errs: Vec<&SyntaxError> = self.errors.iter().collect();
|
||||||
errs.reverse();
|
errs.reverse();
|
||||||
debug_print_green_node(NodeOrToken::Node(&self.green_node), f, 0, &mut errs)
|
|
||||||
|
debug_print_green_node(NodeOrToken::Node(&self.green_node), f, 0, &mut errs, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_print_green_node(
|
fn debug_print_green_node(
|
||||||
node: NodeOrToken<&GreenNodeData, &GreenTokenData>,
|
node: NodeOrToken<&GreenNodeData, &GreenTokenData>,
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
f: &mut dyn std::fmt::Write,
|
||||||
lvl: i32,
|
lvl: i32,
|
||||||
errs: &mut Vec<&SyntaxError>,
|
errs: &mut Vec<&SyntaxError>,
|
||||||
|
colored: bool,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
for _ in 0..lvl {
|
for _ in 0..lvl {
|
||||||
f.write_str(" ")?;
|
f.write_str(" ")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
match node {
|
if !colored {
|
||||||
|
owo_colors::set_override(false);
|
||||||
|
} else {
|
||||||
|
owo_colors::set_override(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = match node {
|
||||||
NodeOrToken::Node(n) => {
|
NodeOrToken::Node(n) => {
|
||||||
let kind = Lang::kind_from_raw(node.kind());
|
let kind = Lang::kind_from_raw(node.kind());
|
||||||
if kind != SyntaxKind::PARSE_ERR {
|
if kind != SyntaxKind::PARSE_ERR {
|
||||||
writeln!(f, "{:?} {{", Lang::kind_from_raw(node.kind()))?;
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{:?} {}",
|
||||||
|
Lang::kind_from_raw(node.kind()).bright_yellow().bold(),
|
||||||
|
"{".yellow()
|
||||||
|
)?;
|
||||||
} else {
|
} else {
|
||||||
let err = errs
|
let err = errs
|
||||||
.pop()
|
.pop()
|
||||||
.expect("all error syntax nodes should correspond to an error");
|
.expect("all error syntax nodes should correspond to an error")
|
||||||
|
.bright_red();
|
||||||
|
|
||||||
writeln!(f, "{:?}: {err:?} {{", kind)?;
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{:?}{} {err:?} {}",
|
||||||
|
kind.bright_red().bold(),
|
||||||
|
":".red(),
|
||||||
|
"{".bright_red().bold()
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
for c in n.children() {
|
for c in n.children() {
|
||||||
debug_print_green_node(c, f, lvl + 1, errs)?;
|
debug_print_green_node(c, f, lvl + 1, errs, colored)?;
|
||||||
}
|
}
|
||||||
for _ in 0..lvl {
|
for _ in 0..lvl {
|
||||||
f.write_str(" ")?;
|
f.write_str(" ")?;
|
||||||
}
|
}
|
||||||
f.write_str("}\n")
|
if kind != SyntaxKind::PARSE_ERR {
|
||||||
|
write!(f, "{}", "}\n".yellow())
|
||||||
|
} else {
|
||||||
|
write!(f, "{}", "}\n".bright_red().bold())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NodeOrToken::Token(t) => {
|
NodeOrToken::Token(t) => {
|
||||||
writeln!(f, "{:?} {:?};", Lang::kind_from_raw(t.kind()), t.text())
|
let tok = Lang::kind_from_raw(t.kind());
|
||||||
|
if MEANINGLESS_TOKS.contains(tok) {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{:?} {:?}{}",
|
||||||
|
Lang::kind_from_raw(t.kind()).white(),
|
||||||
|
t.text().white(),
|
||||||
|
";".white()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{:?} {:?}{}",
|
||||||
|
Lang::kind_from_raw(t.kind()).bright_cyan().bold(),
|
||||||
|
t.text().green(),
|
||||||
|
";".yellow()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if !colored {
|
||||||
|
owo_colors::unset_override();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Output {
|
impl Output {
|
||||||
|
pub fn debug_colored(&self) -> String {
|
||||||
|
let mut out = String::new();
|
||||||
|
let mut errs: Vec<&SyntaxError> = self.errors.iter().collect();
|
||||||
|
errs.reverse();
|
||||||
|
|
||||||
|
let _ = debug_print_green_node(
|
||||||
|
NodeOrToken::Node(&self.green_node),
|
||||||
|
&mut out,
|
||||||
|
0,
|
||||||
|
&mut errs,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
pub fn from_parser_output(
|
pub fn from_parser_output(
|
||||||
mut raw_toks: Vec<(SyntaxKind, &str)>,
|
mut raw_toks: Vec<(SyntaxKind, &str)>,
|
||||||
(mut events, errs): (Vec<Event>, Vec<SyntaxError>),
|
(mut events, errs): (Vec<Event>, Vec<SyntaxError>),
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn main() {
|
||||||
let p_out = dbg!(parser.finish());
|
let p_out = dbg!(parser.finish());
|
||||||
let o = Output::from_parser_output(toks, p_out);
|
let o = Output::from_parser_output(toks, p_out);
|
||||||
|
|
||||||
println!("Out: {:?}", o);
|
println!("{}", o.debug_colored());
|
||||||
|
|
||||||
// let parse_res = parser::parse(&f);
|
// let parse_res = parser::parse(&f);
|
||||||
// println!("parse: {:?}", parse_res);
|
// println!("parse: {:?}", parse_res);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
meow 1 (3 | add 1)
|
meow | gay |
|
||||||
|
|
Loading…
Reference in a new issue