#![allow(dead_code)]
use vyre_libs::parsing::go::lex::{
go_compact_tokens, go_lexer, go_quote_flags, go_scan_emit_flags, go_scan_quote_flags,
};
use vyre_reference::value::Value;
pub(crate) fn pack_source(source: &str) -> Vec<u8> {
source
.as_bytes()
.iter()
.flat_map(|byte| u32::from(*byte).to_le_bytes())
.collect()
}
pub(crate) fn zeroed_u32_words(words: usize) -> Vec<u8> {
vec![0u8; words * 4]
}
pub(crate) fn run(program: &vyre::Program, inputs: Vec<Vec<u8>>) -> Vec<Vec<u8>> {
vyre_reference::reference_eval(
program,
&inputs.into_iter().map(Value::from).collect::<Vec<_>>(),
)
.expect("reference execution must succeed")
.into_iter()
.map(|value| value.to_bytes())
.collect()
}
pub(crate) fn run_by_name(program: &vyre::Program, named: &[(&str, Vec<u8>)]) -> Vec<Vec<u8>> {
let inputs: Vec<Vec<u8>> = program
.buffers()
.iter()
.filter(|decl| decl.access() != vyre::ir::BufferAccess::Workgroup)
.map(|decl| {
named
.iter()
.find(|(name, _)| *name == decl.name())
.map(|(_, bytes)| bytes.clone())
.unwrap_or_else(|| {
let bytes = decl
.static_byte_len()
.ok()
.flatten()
.unwrap_or_else(|| panic!("{} must be statically sized", decl.name()));
vec![0u8; bytes]
})
})
.collect();
run(program, inputs)
}
pub(crate) struct DenseTokens {
pub(crate) types: Vec<u8>,
pub(crate) starts: Vec<u8>,
pub(crate) lens: Vec<u8>,
pub(crate) count: usize,
}
pub(crate) fn tokenize(source: &str) -> DenseTokens {
let haystack_words = source.len().max(1);
let quote_flags = go_quote_flags("haystack", "quote_flags", haystack_words as u32);
let flags = run(
"e_flags,
vec![pack_source(source), zeroed_u32_words(haystack_words)],
);
let quote_scan = go_scan_quote_flags("quote_flags", "quote_ranks", haystack_words as u32);
let quote_scan_outputs = run_by_name("e_scan, &[("quote_flags", flags[0].clone())]);
let quote_ranks = quote_scan_outputs[vyre_reference::output_index("e_scan, "quote_ranks")
.expect("the quote scan must return its quote_ranks buffer")]
.clone();
let lexer = go_lexer(
"haystack",
"quote_ranks",
"sparse_types",
"sparse_starts",
"sparse_lens",
"emit_flags",
haystack_words as u32,
);
let sparse = run(
&lexer,
vec![
pack_source(source),
quote_ranks,
zeroed_u32_words(haystack_words),
zeroed_u32_words(haystack_words),
zeroed_u32_words(haystack_words),
zeroed_u32_words(haystack_words),
],
);
let scan = go_scan_emit_flags("emit_flags", "emit_offsets", haystack_words as u32);
let scan_outputs = run_by_name(&scan, &[("emit_flags", sparse[3].clone())]);
let emit_offsets = scan_outputs[vyre_reference::output_index(&scan, "emit_offsets")
.expect("the scan program must return its emit_offsets buffer")]
.clone();
let compact = go_compact_tokens(
"sparse_types",
"sparse_starts",
"sparse_lens",
"emit_flags",
"emit_offsets",
"out_tok_types",
"out_tok_starts",
"out_tok_lens",
"out_counts",
haystack_words as u32,
);
let dense = run(
&compact,
vec![
sparse[0].clone(),
sparse[1].clone(),
sparse[2].clone(),
sparse[3].clone(),
emit_offsets,
zeroed_u32_words(haystack_words),
zeroed_u32_words(haystack_words),
zeroed_u32_words(haystack_words),
zeroed_u32_words(1),
],
);
DenseTokens {
count: super::decode_u32_words(&dense[3])[0] as usize,
types: dense[0].clone(),
starts: dense[1].clone(),
lens: dense[2].clone(),
}
}