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 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}