Skip to main content

MacroContext

Struct MacroContext 

Source
pub struct MacroContext<'a, 'b, 'arena> { /* private fields */ }
Expand description

Context for a running macro.

Implementations§

Source§

impl<'a, 'b, 'arena> MacroContext<'a, 'b, 'arena>

Source

pub fn parser<'s>( &self, token_stream: &'s TokenStream, span: Span, ) -> Parser<'s>

Construct a parser over a token stream, bounded by the compiler options this macro is being expanded under.

The syntax tree this parser produces is walked by recursing over it, so how deep it is allowed to get is bounded by the max-ast-depth option. A parser built with Parser::from_token_stream instead uses that option’s default, since it has no way of seeing what the compiler was configured with.

A macro which only needs to know where each of its arguments ends does not need a tree at all - see MacroContext::exprs, which splits an input without either recursing over it or holding it to that bound.

span is the span to use if the stream is empty - typically MacroContext::input_span.

§Examples
use rune::ast;
use rune::macros::{self, quote};

macros::test(|cx| {
    let stream = quote!(1 + 2).into_token_stream(cx)?;

    let mut p = cx.parser(&stream, cx.input_span());
    let expr = p.parse_all::<ast::Expr>()?;
    let value = cx.eval(&expr)?;

    let integer = value.as_integer::<u32>().context("Expected integer")?;
    assert_eq!(3, integer);
    Ok(())
})?;
Source

pub fn exprs(&mut self, stream: &TokenStream) -> Result<Vec<TokenStream>>

Split a token stream into the comma separated expressions it is made of, each one being the tokens it was written as.

This is what a macro which takes a list of arguments uses to find where each one ends. The split is done by the same parser the compiler uses, which walks its input over an explicit stack, and each expression is handed back as tokens rather than as a syntax tree - so a macro built out of this neither recurses over its own input nor holds it to the much smaller max-ast-depth which bounds MacroContext::parser.

What comes back is where each argument ends rather than what it means: the tokens are handed on as they were written, and whatever they turn out to say is reported where the macro puts them, since that is where they are lowered.

§Examples
use rune::macros::{self, quote};

macros::test(|cx| {
    let stream = quote!("Hello {}", 1 + 2).into_token_stream(cx)?;

    let exprs = cx.exprs(&stream)?;
    assert_eq!(exprs.len(), 2);

    let value = cx.eval_stream(&exprs[1])?;
    assert_eq!(value.as_integer::<u32>()?, 3);
    Ok(())
})?;
Source

pub fn eval_stream(&mut self, stream: &TokenStream) -> Result<Value>

Evaluate the tokens of an expression as a constant.

This is MacroContext::eval over the tokens an expression was written as, which is what a macro that split its input with MacroContext::exprs holds.

§Examples
use rune::macros::{self, quote};

macros::test(|cx| {
    let stream = quote!(1 + 2).into_token_stream(cx)?;

    let value = cx.eval_stream(&stream)?;
    assert_eq!(value.as_integer::<u32>()?, 3);
    Ok(())
})?;
Source

pub fn eval(&mut self, target: &Expr) -> Result<Value>

Evaluate the given target as a constant expression.

§Panics

This will panic if it’s called outside of a macro context.

§Examples
use rune::ast;
use rune::macros::{self, quote};
use rune::parse::{Parser};

macros::test(|cx| {
    let stream = quote!(1 + 2).into_token_stream(cx)?;

    let mut p = Parser::from_token_stream(&stream, cx.input_span());
    let expr = p.parse_all::<ast::Expr>()?;
    let value = cx.eval(&expr)?;

    let integer = value.as_integer::<u32>().context("Expected integer")?;
    assert_eq!(3, integer);
    Ok(())
})?;
Source

pub fn lit<T>(&mut self, lit: T) -> Result<Lit>
where T: IntoLit,

Construct a new literal from within a macro context.

§Examples
use rune::ast;
use rune::macros;

macros::test(|cx| {
    let lit = cx.lit("hello world")?;
    assert!(matches!(lit, ast::Lit::Str(..)));
    Ok(())
})?;
Source

pub fn ident(&mut self, ident: &str) -> Result<Ident>

Construct a new identifier from the given string from inside of a macro context.

§Examples
use rune::ast;
use rune::macros;

macros::test(|cx| {
    let lit = cx.ident("foo")?;
    assert!(matches!(lit, ast::Ident { .. }));
    Ok(())
})?;
Source

pub fn label(&mut self, label: &str) -> Result<Label>

Construct a new label from the given string. The string should be specified without the leading ', so "foo" instead of "'foo".

This constructor does not panic when called outside of a macro context but requires access to a span and storage.

§Examples
use rune::ast;
use rune::macros;

macros::test(|cx| {
    let lit = cx.label("foo")?;
    assert!(matches!(lit, ast::Label { .. }));
    Ok(())
})?;
Source

pub fn stringify<T>( &mut self, tokens: &T, ) -> Result<Stringify<'_, 'a, 'b, 'arena>>
where T: ToTokens,

Stringify the token stream.

Source

pub fn resolve<'r, T>(&'r self, item: T) -> Result<T::Output>
where T: Resolve<'r>,

Resolve the value of a token.

Source

pub fn insert_source(&mut self, name: &str, source: &str) -> Result<SourceId>

Insert the given source so that it has a SourceId that can be used in combination with parsing functions such as parse_source.

Source

pub fn parse_source<T>(&self, id: SourceId) -> Result<T>
where T: Parse,

Parse the given input as the given type that implements Parse.

Source

pub fn macro_span(&self) -> Span

The span of the macro call including the name of the macro.

If the macro call was stringify!(a + b) this would refer to the whole macro call.

Source

pub fn input_span(&self) -> Span

The span of the macro stream (the argument).

If the macro call was stringify!(a + b) this would refer to a + b.

Auto Trait Implementations§

§

impl<'a, 'b, 'arena> !RefUnwindSafe for MacroContext<'a, 'b, 'arena>

§

impl<'a, 'b, 'arena> !Send for MacroContext<'a, 'b, 'arena>

§

impl<'a, 'b, 'arena> !Sync for MacroContext<'a, 'b, 'arena>

§

impl<'a, 'b, 'arena> !UnwindSafe for MacroContext<'a, 'b, 'arena>

§

impl<'a, 'b, 'arena> Freeze for MacroContext<'a, 'b, 'arena>

§

impl<'a, 'b, 'arena> Unpin for MacroContext<'a, 'b, 'arena>

§

impl<'a, 'b, 'arena> UnsafeUnpin for MacroContext<'a, 'b, 'arena>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more