use crate::Token;
use std::mem;
pub(crate) fn find_preceding_comment_start(tokens: &[Token], idx: usize) -> usize {
if idx == 0 {
return 0;
}
let mut i = idx;
while i > 0 {
i -= 1;
match tokens[i] {
Token::Comment(_) => {
continue;
}
Token::Space | Token::Tab => {
}
Token::NewLine => {
if i > 0 && tokens[i-1] == Token::NewLine {
return i + 1;
}
}
_ => {
return i + 1;
}
}
}
0
}
pub(crate) fn has_type_keywords_in_params(tokens: &[Token]) -> bool {
let mut inside_parens = false;
let mut paren_depth = 0;
for token in tokens {
match token {
Token::OpenParen => {
inside_parens = true;
paren_depth += 1;
}
Token::CloseParen => {
paren_depth -= 1;
if paren_depth == 0 {
inside_parens = false;
}
}
Token::Object(obj) if inside_parens && paren_depth == 1 => {
if matches!(
*obj,
"void" | "int" | "char" | "float" | "double" | "long"
| "short" | "unsigned" | "signed" | "struct" | "union"
| "enum" | "const" | "volatile" | "restrict"
) {
return true;
}
}
_ => {}
}
}
false
}
pub(crate) fn has_operators_in_params(tokens: &[Token]) -> bool {
let mut inside_parens = false;
let mut paren_depth = 0;
for token in tokens {
match token {
Token::OpenParen => {
inside_parens = true;
paren_depth += 1;
}
Token::CloseParen => {
paren_depth -= 1;
if paren_depth == 0 {
inside_parens = false;
}
}
Token::Plus | Token::Minus | Token::Asterisk | Token::ForwardSlash
| Token::Carrot | Token::Period | Token::OpenSquareBracket
if inside_parens && paren_depth == 1 => {
return true;
}
_ => {}
}
}
false
}
pub(crate) fn skip_to(tokens: &[Token], target: Token, idx: &mut usize) {
for i in (*idx + 1)..tokens.len() {
*idx = i;
if tokens[i] == target {
return;
}
}
*idx = tokens.len();
}
pub(crate) fn skip_to_oneof(tokens: &[Token], targets: &[Token], idx: &mut usize) {
for i in (*idx + 1)..tokens.len() {
*idx = i;
for target in targets {
if mem::discriminant(&tokens[i]) == mem::discriminant(target) {
return;
}
}
}
}
pub(crate) fn skip_to_end_comment(tokens: &[Token], idx: &mut usize) {
assert_eq!(
mem::discriminant(&tokens[*idx]),
mem::discriminant(&Token::Comment(""))
);
while *idx < tokens.len()
&& (mem::discriminant(&tokens[*idx]) == mem::discriminant(&Token::Comment(""))
|| tokens[*idx] == Token::NewLine)
{
if tokens[*idx] == Token::NewLine && *idx+1 < tokens.len() && tokens[*idx + 1] == Token::NewLine {
break;
}
*idx += 1;
}
}