reflect/
wip.rs

1use crate::{
2    Function, Ident, Path, Push, RuntimeFunction, StaticBorrow, Type, Value, ValueNode, ValueRef,
3    WIP,
4};
5use std::cell::RefCell;
6use std::rc::Rc;
7
8#[derive(Debug, Clone)]
9pub struct MakeImpl<'a> {
10    pub(crate) wip: &'a WipImpl,
11}
12
13#[derive(Debug, Clone)]
14pub(crate) struct WipImpl {
15    pub(crate) trait_ty: Option<Type>,
16    pub(crate) ty: Type,
17    pub(crate) functions: RefCell<Vec<WipFunction>>,
18}
19
20#[derive(Debug, Clone)]
21pub struct MakeFunction {
22    private: (),
23}
24
25#[derive(Debug, Clone)]
26pub(crate) struct WipFunction {
27    // self_ty is None for freestanding functions
28    pub(crate) self_ty: Option<Type>,
29    pub(crate) f: Function,
30    pub(crate) values: Vec<ValueNode>,
31    pub(crate) invokes: Vec<Invoke>,
32    pub(crate) macros: Vec<MacroInvoke>,
33    pub(crate) ret: Option<ValueRef>,
34}
35
36#[derive(Debug, Clone)]
37pub(crate) struct Invoke {
38    pub(crate) function: Function,
39    pub(crate) args: Vec<ValueRef>,
40}
41
42#[derive(Debug, Clone)]
43pub(crate) struct MacroInvoke {
44    pub(crate) macro_path: Path,
45    pub(crate) args: Vec<ValueRef>,
46}
47
48impl<'a> MakeImpl<'a> {
49    pub fn make_function<F>(&self, f: F, run: fn(MakeFunction) -> Value)
50    where
51        F: RuntimeFunction,
52    {
53        WIP.with(|old_wip| {
54            *old_wip.borrow_mut() = Some(WipFunction {
55                self_ty: Some(self.wip.ty.clone()),
56                f: f.SELF(),
57                values: Vec::new(),
58                invokes: Vec::new(),
59                macros: Vec::new(),
60                ret: None,
61            });
62        });
63
64        let ret = Some(run(MakeFunction { private: () }).index);
65        let mut wip = WIP.with(|wip| wip.borrow_mut().take().unwrap());
66        wip.ret = ret;
67
68        self.wip.functions.borrow_mut().push(wip);
69    }
70}
71
72impl MakeFunction {
73    pub fn unit(&self) -> Value {
74        WIP.with_borrow_mut(WipFunction::unit)
75    }
76
77    pub fn string(&self, s: &str) -> Value {
78        WIP.with_borrow_mut(|wip| wip.string(s))
79    }
80
81    pub fn arg(&self, mut index: usize) -> Value {
82        use crate::Receiver::*;
83        let wip = WIP.with(Rc::clone);
84        let wip = &mut *wip.borrow_mut();
85        let wip = wip.as_mut().unwrap();
86
87        let node = match match wip.f.sig.receiver {
88            SelfByValue if index == 0 => wip.self_ty.clone(),
89            SelfByReference if index == 0 => wip.self_ty.clone().map(|ty| ty.reference()),
90            SelfByReferenceMut if index == 0 => wip.self_ty.clone().map(|ty| ty.reference_mut()),
91            NoSelf => None,
92            SelfByValue | SelfByReference | SelfByReferenceMut => {
93                index -= 1;
94                None
95            }
96        } {
97            Some(receiver) => ValueNode::Binding {
98                name: Ident::new("self"),
99                ty: receiver,
100            },
101            None => ValueNode::Binding {
102                name: Ident::new(format!("__arg{}", index)),
103                ty: wip.f.sig.inputs[index].clone(),
104            },
105        };
106        Value {
107            index: wip.values.index_push(node),
108        }
109    }
110}
111
112impl WipFunction {
113    pub(crate) fn node(&self, index: ValueRef) -> ValueNode {
114        self.values[index.0].clone()
115    }
116
117    fn unit(&mut self) -> Value {
118        let node = ValueNode::Tuple(Vec::new());
119        Value {
120            index: self.values.index_push(node),
121        }
122    }
123
124    fn string(&mut self, s: &str) -> Value {
125        let node = ValueNode::Str(s.to_owned());
126        Value {
127            index: self.values.index_push(node),
128        }
129    }
130}