From ad514f56b6cda288e605c44990ef16d30e6dee53 Mon Sep 17 00:00:00 2001 From: stuebinm Date: Thu, 2 Sep 2021 23:31:39 +0200 Subject: remove grmtools the parser using grmtools was way oversized for just doing escape sequences, and only really existed since I wanted to play around with it. The new implementation depends on no external crates, uses just an iter wrapped into a nicely composable function, and appears to be exactly equivalent (but faster). --- isabelle-unicode/Cargo.toml | 10 +++++++ isabelle-unicode/src/lib.rs | 70 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 isabelle-unicode/Cargo.toml create mode 100644 isabelle-unicode/src/lib.rs (limited to 'isabelle-unicode') diff --git a/isabelle-unicode/Cargo.toml b/isabelle-unicode/Cargo.toml new file mode 100644 index 0000000..2e5ff9f --- /dev/null +++ b/isabelle-unicode/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "isabelle-unicode" +version = "0.1.0" +authors = ["stuebinm "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +symbolmacro = { path = "../symbolmacro" } diff --git a/isabelle-unicode/src/lib.rs b/isabelle-unicode/src/lib.rs new file mode 100644 index 0000000..8394e57 --- /dev/null +++ b/isabelle-unicode/src/lib.rs @@ -0,0 +1,70 @@ + +symbolmacro::make_symbols!(); + +// TODO: is it possible to be polymorphic over slice types here? +pub trait PrettyUnicode { + fn to_pretty_unicode(self) -> Option; +} + +impl PrettyUnicode for &str { + fn to_pretty_unicode(self) -> Option { + // split at escape sequences + let mut chunks = self.split("\\<"); + + // first chunk contains no escape + let prefix = chunks.next()?; + + // line with escape sequences replaced by unicode + let mut pretty = chunks + .filter_map(|chunk| { + // extract this symbol's name + let ident : Option<&str> = chunk + .split(">") + .next(); + + // get this symbol's unicode representation + let symbol : char = ident + .map(symbol) + .flatten() + .unwrap_or('�'); + + // how much of the rest do we need? + let offset = ident? + .len() + + 1; + Some((symbol, &chunk[offset..])) + }) + .fold(prefix.to_owned(), |mut acc, (symbol, rest)| { + // TODO: this may cause some unnecessary reallocs + // (since the line length is known in advance) + acc.push(symbol); + acc.push_str(rest); + // lol rust is sufficiently imperative to have mutable + // strings but also sufficiently functional that this + // version of fold pretends like it doesn't + acc + }); + + // add a newline + pretty.push('\n'); + Some(pretty) + } +} + +// fn main() { + +// let stdin = io::stdin(); + +// stdin.lock() +// .lines() +// .filter_map(|line| match line { +// Ok(line) if line.trim().is_empty() +// => Some("\n".to_string()), +// Ok(line) +// => line.to_pretty_unicode(), +// Err(_) +// => None +// }) +// .for_each(|line| print!("{}", line)); + +// } -- cgit v1.2.3