#![allow(missing_docs)] use crate::parsing::c::lex::tokens::*;
use crate::parsing::c::source_bytes::source_haystack_words;
const PHASE_WITNESS_TOKENS: &[(u32, &str)] = &[
(TOK_TYPEDEF, "typedef"),
(TOK_INT, "int"),
(TOK_IDENTIFIER, "T"),
(TOK_SEMICOLON, ";"),
(TOK_VOID, "void"),
(TOK_IDENTIFIER, "f"),
(TOK_LPAREN, "("),
(TOK_VOID, "void"),
(TOK_RPAREN, ")"),
(TOK_LBRACE, "{"),
(TOK_IDENTIFIER, "T"),
(TOK_IDENTIFIER, "v"),
(TOK_SEMICOLON, ";"),
(TOK_RBRACE, "}"),
];
pub(in crate::parsing::c::parse::vast) const PHASE_WITNESS_ROWS: u32 =
PHASE_WITNESS_TOKENS.len() as u32;
pub(in crate::parsing::c::parse::vast) const PHASE_WITNESS_SOURCE_LEN: u32 = witness_source_len();
const fn witness_source_len() -> u32 {
let mut total = 0usize;
let mut index = 0usize;
while index < PHASE_WITNESS_TOKENS.len() {
if index > 0 {
total += 1;
}
total += PHASE_WITNESS_TOKENS[index].1.len();
index += 1;
}
total as u32
}
#[cfg(any(test, feature = "cpu-parity"))]
pub(in crate::parsing::c::parse::vast) struct PhaseWitness {
pub(in crate::parsing::c::parse::vast) source: Vec<u8>,
pub(in crate::parsing::c::parse::vast) node_bytes: Vec<u8>,
pub(in crate::parsing::c::parse::vast) node_words: Vec<u32>,
}
#[cfg(any(test, feature = "cpu-parity"))]
impl PhaseWitness {
pub(in crate::parsing::c::parse::vast) fn build() -> Self {
let mut source = Vec::with_capacity(PHASE_WITNESS_SOURCE_LEN as usize);
let mut tok_types = Vec::with_capacity(PHASE_WITNESS_TOKENS.len());
let mut tok_starts = Vec::with_capacity(PHASE_WITNESS_TOKENS.len());
let mut tok_lens = Vec::with_capacity(PHASE_WITNESS_TOKENS.len());
for (kind, text) in PHASE_WITNESS_TOKENS {
if !source.is_empty() {
source.push(b' ');
}
tok_types.push(*kind);
tok_starts.push(source.len() as u32);
tok_lens.push(text.len() as u32);
source.extend_from_slice(text.as_bytes());
}
let node_bytes = super::reference_c11_build_vast_nodes(&tok_types, &tok_starts, &tok_lens);
let node_words = node_bytes
.chunks_exact(4)
.map(|chunk| u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]))
.collect();
Self {
source,
node_bytes,
node_words,
}
}
pub(in crate::parsing::c::parse::vast) fn lexeme(&self, row: u32) -> &[u8] {
let base = row as usize * super::VAST_NODE_STRIDE_U32 as usize;
let start = self.node_words[base + 5] as usize;
let len = self.node_words[base + 6] as usize;
&self.source[start..start + len]
}
pub(in crate::parsing::c::parse::vast) fn haystack_bytes(
&self,
packed_haystack: bool,
) -> Vec<u8> {
let words = source_haystack_words(PHASE_WITNESS_SOURCE_LEN, packed_haystack) as usize;
let mut bytes = vec![0u8; words * 4];
if packed_haystack {
bytes[..self.source.len()].copy_from_slice(&self.source);
} else {
for (word, byte) in bytes.chunks_exact_mut(4).zip(&self.source) {
word[0] = *byte;
}
}
bytes
}
}