use std::char;
use std::convert::TryInto;
use texlang::traits::*;
use texlang::*;
pub const THE_DOC: &str = "Output text describing some inputted tokens";
pub fn get_the<S: TexlangState>() -> command::BuiltIn<S> {
command::BuiltIn::new_expansion(the_primitive_fn)
}
fn the_primitive_fn<S: TexlangState>(
the_token: token::Token,
input: &mut vm::ExpansionInput<S>,
) -> command::Result<Vec<token::Token>> {
let token = match input.next()? {
None => return Err(error::SimpleEndOfInputError::new(input.vm(), "TODO").into()),
Some(token) => token,
};
Ok(match &token.value() {
token::Value::ControlSequence(name) => {
if let Some(command::Command::Variable(cmd)) = input.commands_map().get_command(name) {
match cmd.clone().value(token, input.as_mut())? {
variable::ValueRef::Int(i) => int_to_tokens(the_token, *i),
variable::ValueRef::CatCode(i) => int_to_tokens(the_token, (*i as u8).into()),
}
} else {
vec![token]
}
}
_ => vec![token],
})
}
fn int_to_tokens(the_token: token::Token, mut i: i32) -> Vec<token::Token> {
if i == 0 {
return vec![token::Token::new_other('0', the_token.trace_key())];
}
let negative = i < 0;
let mut tokens = Vec::new();
while i != 0 {
let digit = (i % 10).abs();
tokens.push(token::Token::new_other(
char::from_digit(digit.try_into().unwrap(), 10).unwrap(),
the_token.trace_key(),
));
i /= 10;
}
if negative {
tokens.push(token::Token::new_other('-', the_token.trace_key()));
}
tokens.reverse();
tokens
}