use crate::Compiler::Core::Tokenizer::token::{Token, TokenType};
pub struct TokenSplitResult {
pub config_tokens: Vec<Token>,
pub rest_tokens: Vec<Token>,
}
pub fn split_config_tokens(tokens: Vec<Token>) -> TokenSplitResult {
let config_start = match tokens
.iter()
.position(|t| matches!(t.token_type, TokenType::SectionConfig))
{
Some(i) => i,
None => {
return TokenSplitResult {
config_tokens: vec![],
rest_tokens: tokens,
}
}
};
let open_paren = match tokens[config_start..]
.iter()
.position(|t| matches!(t.token_type, TokenType::Symbol('(')))
{
Some(rel) => config_start + rel,
None => {
let rest = tokens[..config_start].to_vec();
let cfg = tokens[config_start..].to_vec();
return TokenSplitResult { config_tokens: cfg, rest_tokens: rest };
}
};
let mut depth: i32 = 0;
let mut close_paren: Option<usize> = None;
for (offset, token) in tokens[open_paren..].iter().enumerate() {
match &token.token_type {
TokenType::Symbol('(') => depth += 1,
TokenType::Symbol(')') => {
depth -= 1;
if depth == 0 {
close_paren = Some(open_paren + offset);
break;
}
}
TokenType::SectionDLM
| TokenType::SectionEnums
| TokenType::SectionImports
| TokenType::SectionQuickFuncs
| TokenType::SectionData
| TokenType::SectionSecurity
| TokenType::EndOfFile => break,
_ => {}
}
}
let close_paren = close_paren.unwrap_or_else(|| {
tokens
.iter()
.rposition(|t| !matches!(t.token_type, TokenType::EndOfFile))
.unwrap_or(tokens.len().saturating_sub(1))
});
let config_tokens: Vec<Token> = tokens[config_start..=close_paren].to_vec();
let mut rest_tokens: Vec<Token> = tokens[..config_start].to_vec();
if close_paren + 1 < tokens.len() {
rest_tokens.extend_from_slice(&tokens[close_paren + 1..]);
}
TokenSplitResult { config_tokens, rest_tokens }
}