Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

457
vendor/pp-rs/src/pp/if_parser.rs vendored Normal file
View File

@@ -0,0 +1,457 @@
use crate::token::{Integer, PreprocessorError, Punct};
use super::{Define, Location, MacroProcessor, MeLexer, Step, StepExit, Token, TokenValue};
use std::{collections::HashMap, convert::TryInto, rc::Rc, vec};
struct IfLexer<'macros> {
tokens: vec::IntoIter<Token>,
defines: &'macros HashMap<String, Rc<Define>>,
}
pub(super) struct IfParser<'macros> {
lexer: IfLexer<'macros>,
macro_processor: MacroProcessor,
location: Location,
parsing_if: bool,
carry: Option<Token>,
}
impl<'macros> IfParser<'macros> {
/// Builds a new IfParser that can be reused
///
/// `parsing_if` indicates wether or not non defined macros should be
/// replaced with 0
pub fn new(
tokens: Vec<Token>,
defines: &'macros HashMap<String, Rc<Define>>,
location: Location,
parsing_if: bool,
) -> Self {
IfParser {
lexer: IfLexer {
tokens: tokens.into_iter(),
defines,
},
macro_processor: MacroProcessor::default(),
location,
parsing_if,
carry: None,
}
}
/// Helper method to consume the next token without define expansion
fn raw_next(&mut self) -> Option<Token> {
self.carry
.take()
.or_else(|| self.macro_processor.step(&mut self.lexer).ok())
}
/// Helper method to consume the next token with define expansion
fn next(&mut self) -> Step<Option<Token>> {
let token = match self.raw_next() {
Some(t) => t,
None => return Ok(None),
};
Ok(match token.value {
TokenValue::Ident(ref name) if name != "defined" => {
match self.add_define(name, token.location)? {
Some(t) => Some(t),
None => self.next()?,
}
}
_ => Some(token),
})
}
/// Helper method to get the next token with define expansion
pub fn peek(&mut self) -> Step<Option<Token>> {
self.carry = self.next()?;
Ok(self.carry.clone())
}
/// Helper method to consume the next token without define expansion
///
/// Returns an EOI error if there are no further tokens
fn expect_raw_next(&mut self) -> Step<Token> {
self.raw_next().ok_or(StepExit::Error((
PreprocessorError::UnexpectedEndOfInput,
self.location,
)))
}
/// Helper method to consume the next token with define expansion
///
/// Returns an EOI error if there are no further tokens
fn expect_next(&mut self) -> Step<Token> {
self.next()?.ok_or(StepExit::Error((
PreprocessorError::UnexpectedEndOfInput,
self.location,
)))
}
/// Helper method to get the next token with define expansion
///
/// Returns an EOI error if there are no further tokens
fn expect_peek(&mut self) -> Step<Token> {
self.peek()?.ok_or(StepExit::Error((
PreprocessorError::UnexpectedEndOfInput,
self.location,
)))
}
fn add_define(&mut self, name: &str, location: Location) -> Step<Option<Token>> {
if self
.macro_processor
.start_define_invocation(name, location, &mut self.lexer)?
{
Ok(None)
} else if self.parsing_if {
Ok(Some(Token {
value: TokenValue::Integer(Integer {
value: 0,
signed: true,
width: 64,
}),
location,
}))
} else {
Err(StepExit::Error((
PreprocessorError::UnexpectedToken(TokenValue::Ident(name.to_string())),
location,
)))
}
}
fn handle_defined(&mut self) -> Step<i64> {
let next = self.expect_raw_next()?;
match next.value {
TokenValue::Ident(ref name) => Ok(self.lexer.defines.get(name).is_some() as i64),
TokenValue::Punct(Punct::LeftParen) => {
let name_token = self.expect_raw_next()?;
let name = match name_token.value {
TokenValue::Ident(name) => Ok(name),
value => Err(StepExit::Error((
PreprocessorError::UnexpectedToken(value),
name_token.location,
))),
}?;
let close_brace = self.expect_next()?;
match close_brace.value {
TokenValue::Punct(Punct::RightParen) => {
Ok(self.lexer.defines.get(&name).is_some() as i64)
}
value => Err(StepExit::Error((
PreprocessorError::UnexpectedToken(value),
close_brace.location,
))),
}
}
value => Err(StepExit::Error((
PreprocessorError::UnexpectedToken(value),
next.location,
))),
}
}
fn parse_atom(&mut self) -> Step<i64> {
let token = self.expect_next()?;
match token.value {
TokenValue::Ident(name) => {
debug_assert_eq!(name, "defined");
self.handle_defined()
}
TokenValue::Integer(int) => Ok(int.value as i64),
TokenValue::Punct(Punct::LeftParen) => {
let val = self.parse_logical_or()?;
let close_brace = self.expect_next()?;
match close_brace.value {
TokenValue::Punct(Punct::RightParen) => Ok(val),
value => Err(StepExit::Error((
PreprocessorError::UnexpectedToken(value),
close_brace.location,
))),
}
}
value => Err(StepExit::Error((
PreprocessorError::UnexpectedToken(value),
token.location,
))),
}
}
fn parse_unary(&mut self) -> Step<i64> {
match self.expect_peek()?.value {
TokenValue::Punct(punct) => match punct {
Punct::Plus | Punct::Minus | Punct::Bang | Punct::Tilde => {
self.next()?;
let val = self.parse_unary()?;
Ok(match punct {
Punct::Plus => val,
Punct::Minus => -val,
Punct::Bang => (val == 0) as i64,
Punct::Tilde => !val,
_ => unreachable!(),
})
}
_ => self.parse_atom(),
},
_ => self.parse_atom(),
}
}
fn parse_multiplicative(&mut self) -> Step<i64> {
let mut left = self.parse_unary()?;
while let Some(TokenValue::Punct(punct)) = self.peek()?.map(|t| t.value) {
if let Punct::Star | Punct::Slash | Punct::Percent = punct {
self.next()?;
let right = self.parse_unary()?;
match punct {
Punct::Star => {
left = left.checked_mul(right).ok_or(StepExit::Error((
PreprocessorError::IntegerOverflow,
self.location,
)))?
}
Punct::Slash => {
left = left.checked_div(right).ok_or(StepExit::Error((
PreprocessorError::DivisionByZero,
self.location,
)))?
}
Punct::Percent => {
left = left.checked_rem(right).ok_or(StepExit::Error((
PreprocessorError::DivisionByZero,
self.location,
)))?
}
_ => unreachable!(),
}
} else {
break;
}
}
Ok(left)
}
fn parse_additive(&mut self) -> Step<i64> {
let mut left = self.parse_multiplicative()?;
while let Some(TokenValue::Punct(punct)) = self.peek()?.map(|t| t.value) {
if let Punct::Plus | Punct::Minus = punct {
self.next()?;
let right = self.parse_multiplicative()?;
match punct {
Punct::Plus => {
left = left.checked_add(right).ok_or(StepExit::Error((
PreprocessorError::IntegerOverflow,
self.location,
)))?
}
Punct::Minus => {
left = left.checked_sub(right).ok_or(StepExit::Error((
PreprocessorError::IntegerOverflow,
self.location,
)))?
}
_ => unreachable!(),
}
} else {
break;
}
}
Ok(left)
}
fn parse_shift(&mut self) -> Step<i64> {
let mut left = self.parse_additive()?;
while let Some(TokenValue::Punct(punct)) = self.peek()?.map(|t| t.value) {
if let Punct::LeftShift | Punct::RightShift = punct {
self.next()?;
let right = self.parse_additive()?;
match punct {
Punct::LeftShift => {
let right = right.try_into().map_err(|_| {
StepExit::Error((PreprocessorError::IntegerOverflow, self.location))
})?;
left = left.checked_shl(right).ok_or(StepExit::Error((
PreprocessorError::IntegerOverflow,
self.location,
)))?
}
Punct::RightShift => {
let right = right.try_into().map_err(|_| {
StepExit::Error((PreprocessorError::IntegerOverflow, self.location))
})?;
left = left.checked_shr(right).ok_or(StepExit::Error((
PreprocessorError::IntegerOverflow,
self.location,
)))?
}
_ => unreachable!(),
}
} else {
break;
}
}
Ok(left)
}
fn parse_comparative(&mut self) -> Step<i64> {
let mut left = self.parse_shift()?;
while let Some(TokenValue::Punct(punct)) = self.peek()?.map(|t| t.value) {
if let Punct::LeftAngle | Punct::RightAngle | Punct::LessEqual | Punct::GreaterEqual =
punct
{
self.next()?;
let right = self.parse_shift()?;
match punct {
Punct::LeftAngle => left = (left < right) as i64,
Punct::RightAngle => left = (left > right) as i64,
Punct::LessEqual => left = (left <= right) as i64,
Punct::GreaterEqual => left = (left >= right) as i64,
_ => unreachable!(),
}
} else {
break;
}
}
Ok(left)
}
fn parse_equality(&mut self) -> Step<i64> {
let mut left = self.parse_comparative()?;
while let Some(TokenValue::Punct(punct)) = self.peek()?.map(|t| t.value) {
if let Punct::EqualEqual | Punct::NotEqual = punct {
self.next()?;
let right = self.parse_comparative()?;
match punct {
Punct::EqualEqual => left = (left == right) as i64,
Punct::NotEqual => left = (left != right) as i64,
_ => unreachable!(),
}
} else {
break;
}
}
Ok(left)
}
fn parse_bit_and(&mut self) -> Step<i64> {
let mut left = self.parse_equality()?;
while let Some(TokenValue::Punct(Punct::Ampersand)) = self.peek()?.map(|t| t.value) {
self.next()?;
let right = self.parse_equality()?;
left &= right
}
Ok(left)
}
fn parse_bit_xor(&mut self) -> Step<i64> {
let mut left = self.parse_bit_and()?;
while let Some(TokenValue::Punct(Punct::Caret)) = self.peek()?.map(|t| t.value) {
self.next()?;
let right = self.parse_bit_and()?;
left ^= right
}
Ok(left)
}
fn parse_bit_or(&mut self) -> Step<i64> {
let mut left = self.parse_bit_xor()?;
while let Some(TokenValue::Punct(Punct::Pipe)) = self.peek()?.map(|t| t.value) {
self.next()?;
let right = self.parse_bit_xor()?;
left |= right
}
Ok(left)
}
fn parse_logical_and(&mut self) -> Step<i64> {
let mut left = self.parse_bit_or()?;
while let Some(TokenValue::Punct(Punct::LogicalAnd)) = self.peek()?.map(|t| t.value) {
self.next()?;
let right = self.parse_bit_or()?;
left = (left != 0 && right != 0) as i64;
}
Ok(left)
}
fn parse_logical_or(&mut self) -> Step<i64> {
let mut left = self.parse_logical_and()?;
while let Some(TokenValue::Punct(Punct::LogicalOr)) = self.peek()?.map(|t| t.value) {
self.next()?;
let right = self.parse_logical_and()?;
left = (left != 0 || right != 0) as i64;
}
Ok(left)
}
pub fn evaluate_expression(&mut self) -> Step<i64> {
self.parse_logical_or()
}
}
impl<'macros> MeLexer for IfLexer<'macros> {
fn step(&mut self) -> Step<Token> {
self.tokens.next().ok_or(StepExit::Finished)
}
fn get_define(&self, name: &str) -> Option<&Rc<Define>> {
self.defines.get(name)
}
fn apply_line_offset(&self, line: u32, _: Location) -> Step<u32> {
Ok(line)
}
}