///|
fn noexpand_macro(
context : MacroExpander,
) -> MacroReplacement raise ParseFailure {
let token = context.pop_token()
if context.is_expandable(token.text) {
token.noexpand = true
token.treat_as_relax = true
}
token_expansion([token])
}
///|
fn expandafter_macro(
context : MacroExpander,
) -> MacroReplacement raise ParseFailure {
let token = context.pop_token()
let _ = context.expand_once(expandable_only=true)
token_expansion([token])
}
///|
fn first_of_two_macro(
context : MacroExpander,
) -> MacroReplacement raise ParseFailure {
guard context.consume_args(2, None).get(0) is Some(tokens) else {
raise InternalInvariant(message="Missing first macro argument")
}
token_expansion(tokens)
}
///|
fn second_of_two_macro(
context : MacroExpander,
) -> MacroReplacement raise ParseFailure {
guard context.consume_args(2, None).get(1) is Some(tokens) else {
raise InternalInvariant(message="Missing second macro argument")
}
token_expansion(tokens)
}
///|
fn if_next_char_macro(
context : MacroExpander,
) -> MacroReplacement raise ParseFailure {
let args = context.consume_args(3, None)
context.consume_spaces()
let next = context.future()
let selected = if args[0].length() == 1 && args[0][0].text == next.text {
args[1]
} else {
args[2]
}
token_expansion(selected)
}
///|
fn text_or_math_macro(
context : MacroExpander,
) -> MacroReplacement raise ParseFailure {
let args = context.consume_args(2, None)
if context.mode == Text {
token_expansion(args[0])
} else {
token_expansion(args[1])
}
}