reflect 0.0.1

The "but I thought Rust doesn't have reflection?" memorial brand new way of defining procedural macros.
Documentation
use Function;
use Ident;
use Push;
use RuntimeFunction;
use Type;
use Value;
use ValueNode;
use ValueRef;

use std::cell::RefCell;
use std::rc::Rc;

#[derive(Debug, Clone)]
pub struct MakeImpl {
    pub(crate) wip: Rc<RefCell<WipImpl>>,
}

#[derive(Debug, Clone)]
pub(crate) struct WipImpl {
    pub(crate) of: Type,
    pub(crate) ty: Type,
    pub(crate) functions: Vec<Rc<RefCell<WipFunction>>>,
}

#[derive(Debug, Clone)]
pub struct MakeFunction<'a> {
    pub(crate) wip: &'a WipFunction,
}

#[derive(Debug, Clone)]
pub(crate) struct WipFunction {
    pub(crate) self_ty: Type,
    pub(crate) f: Function,
    pub(crate) values: RefCell<Vec<ValueNode>>,
    pub(crate) invokes: RefCell<Vec<Invoke>>,
    pub(crate) ret: Option<ValueRef>,
}

#[derive(Debug, Clone)]
pub(crate) struct Invoke {
    pub(crate) function: Function,
    pub(crate) args: Vec<ValueRef>,
}

impl MakeImpl {
    pub fn make_function<F>(&self, f: F, run: fn(MakeFunction) -> Value)
    where
        F: RuntimeFunction,
    {
        let mut wip = WipFunction {
            self_ty: self.wip.borrow().ty.clone(),
            f: f.SELF(),
            values: RefCell::new(Vec::new()),
            invokes: RefCell::new(Vec::new()),
            ret: None,
        };
        wip.ret = Some(run(MakeFunction { wip: &wip }).index);
        self.wip
            .borrow_mut()
            .functions
            .push(Rc::new(RefCell::new(wip)));
    }
}

impl<'a> MakeFunction<'a> {
    pub fn unit(&self) -> Value<'a> {
        self.wip.unit()
    }

    pub fn string(&self, s: &str) -> Value<'a> {
        self.wip.string(s)
    }

    pub fn arg(&self, mut index: usize) -> Value<'a> {
        use Receiver::*;

        let node = match match self.wip.f.sig.receiver {
            SelfByValue if index == 0 => Some(self.wip.self_ty.clone()),
            SelfByReference if index == 0 => Some(self.wip.self_ty.clone().reference()),
            SelfByReferenceMut if index == 0 => Some(self.wip.self_ty.clone().reference_mut()),
            NoSelf => None,
            SelfByValue | SelfByReference | SelfByReferenceMut => {
                index -= 1;
                None
            }
        } {
            Some(receiver) => ValueNode::Binding {
                name: Ident::new("self"),
                ty: receiver,
            },
            None => ValueNode::Binding {
                name: Ident::new(format!("__arg{}", index)),
                ty: self.wip.f.sig.inputs[index].clone(),
            },
        };

        Value {
            function: self.wip,
            index: self.wip.values.borrow_mut().index_push(node),
        }
    }
}

impl WipFunction {
    pub(crate) fn node(&self, index: ValueRef) -> ValueNode {
        self.values.borrow()[index.0].clone()
    }

    fn unit(&self) -> Value {
        let node = ValueNode::Unit;
        Value {
            function: self,
            index: self.values.borrow_mut().index_push(node),
        }
    }

    fn string(&self, s: &str) -> Value {
        let node = ValueNode::Str(s.to_owned());
        Value {
            function: self,
            index: self.values.borrow_mut().index_push(node),
        }
    }
}