summaryrefslogtreecommitdiff
path: root/vendor/logos-codegen/src/generator/rope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/logos-codegen/src/generator/rope.rs')
-rw-r--r--vendor/logos-codegen/src/generator/rope.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/vendor/logos-codegen/src/generator/rope.rs b/vendor/logos-codegen/src/generator/rope.rs
new file mode 100644
index 00000000..ae3b07ad
--- /dev/null
+++ b/vendor/logos-codegen/src/generator/rope.rs
@@ -0,0 +1,39 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+
+use crate::generator::{Context, Generator};
+use crate::graph::Rope;
+
+impl Generator<'_> {
+ pub fn generate_rope(&mut self, rope: &Rope, mut ctx: Context) -> TokenStream {
+ let miss = ctx.miss(rope.miss.first(), self);
+ let read = ctx.read(rope.pattern.len());
+ let then = self.goto(rope.then, ctx.advance(rope.pattern.len()));
+
+ let pat = match rope.pattern.to_bytes() {
+ Some(bytes) => byte_slice_literal(&bytes),
+ None => {
+ let ranges = rope.pattern.iter();
+
+ quote!([#(#ranges),*])
+ }
+ };
+
+ quote! {
+ match #read {
+ Some(#pat) => #then,
+ _ => #miss,
+ }
+ }
+ }
+}
+
+fn byte_slice_literal(bytes: &[u8]) -> TokenStream {
+ if bytes.iter().any(|&b| !(0x20..0x7F).contains(&b)) {
+ return quote!(&[#(#bytes),*]);
+ }
+
+ let slice = std::str::from_utf8(bytes).unwrap();
+
+ syn::parse_str(&format!("b{:?}", slice)).unwrap()
+}