astmaker 0.2.0

Build Abstract Syntax Trees and tree-walking models quickly in Rust.
Documentation
use astmaker::{ast, model};


ast!{
  location = ();

  pub node Program = {
    instructions: Vec<Node<Instruction>>,
  }

  pub node Instruction =
    | Word -> Node<Word>

    | Number -> Node<Number>
    ;

  pub node Word = {}
  pub node Number = {}
}

pub struct LifetimeModel<'a> {
  n_words: usize,
  n_numbers: usize,
  data: &'a mut usize,
}

model!{
  impl<'a> LifetimeModel -> () {
    where Program => {
      for child in node.data.instructions.iter_mut() {
        context.visit(child);
      }

      *context.data = context.n_words + context.n_numbers;
    },
    where Instruction => {
      match node.data.as_mut() {
        Instruction::Word(child) => context.visit(child),
        Instruction::Number(child) => context.visit(child),
      }
    },
    where Word => {
      context.n_words += 1;
    },
    where Number => {
      context.n_numbers += 1;
    },
  }
}


#[test]
fn eval() {
  let mut tree = Node::new((), Program {
    instructions: vec![
      Node::new((), Instruction::Word(
        Node::new((), Word {})
      )),
      Node::new((), Instruction::Number(
        Node::new((), Number {})
      )),
      Node::new((), Instruction::Word(
        Node::new((), Word {})
      )),
    ],
  });

  let mut data: usize = 0;
  let mut model: LifetimeModel = LifetimeModel {
    n_words: 0,
    n_numbers: 0,
    data: &mut data,
  };
  model.visit(&mut tree);
  assert_eq!(model.n_words, 2);
  assert_eq!(model.n_numbers, 1);
  assert_eq!(data, 3);
}