value_expr/
context.rs

1use super::data::*;
2use super::valuer::*;
3use std::collections::HashMap;
4use std::mem;
5use std::sync::Arc;
6
7#[derive(Debug)]
8struct Aged<T> {
9    age: i32,
10    value: T,
11}
12#[derive(Debug)]
13struct Named<T> {
14    map: HashMap<String, Vec<Aged<T>>>,
15}
16#[derive(Debug)]
17struct FnDef {
18    body: Value,
19    params: Vec<String>,
20}
21#[derive(Default)]
22pub struct ContextHelper {
23    pointer: i32,
24    fn_named: Named<Arc<FnDef>>,
25    var_named: Named<i32>,
26}
27pub trait ContextHolder: Sized {
28    fn ctx(&mut self) -> &mut ContextHelper;
29    fn ctx_ref(&self) -> &ContextHelper;
30    fn ctx_log(&self, msg: &str) {
31        println!("{}", msg);
32    }
33    fn ctx_call(&mut self, _func: &str, _values: &Vec<Value>) -> Option<i32> {
34        None
35    }
36}
37impl<T> Default for Named<T> {
38    fn default() -> Self {
39        Self {
40            map: HashMap::new(),
41        }
42    }
43}
44impl<T> Named<T> {
45    fn get(&self, key: &str, age: i32) -> Option<&T> {
46        match self.map.get(key) {
47            None => None,
48            Some(vec) => vec.iter().rev().find(|a| a.age <= age).map(|a| &a.value),
49        }
50    }
51    fn set(&mut self, key: &str, value: T, age: i32) -> Option<T> {
52        let frames = self.map.entry(key.to_string()).or_insert(Vec::new());
53        while let Some(frame) = frames.last_mut() {
54            if frame.age > age {
55                frames.pop();
56            } else if frame.age == age {
57                return Some(mem::replace(&mut frame.value, value));
58            } else {
59                break;
60            }
61        }
62        frames.push(Aged { age, value });
63        None
64    }
65    fn clear(&mut self, age: i32) {
66        let mut need_remove = vec![];
67        for (key, frames) in &mut self.map {
68            while let Some(frame) = frames.last_mut() {
69                if frame.age > age {
70                    frames.pop();
71                } else {
72                    break;
73                }
74            }
75            if frames.is_empty() {
76                need_remove.push(key.to_string());
77            }
78        }
79        for key in need_remove {
80            self.map.remove(&key);
81        }
82    }
83}
84impl ContextHelper {
85    fn ident_get(&self, ident: &str) -> i32 {
86        let age = self.pointer;
87        self.var_named
88            .get(ident, age)
89            .map(|e| *e)
90            .unwrap_or_default()
91    }
92    fn ident_set(&mut self, ident: &str, value: i32) {
93        let age = self.pointer;
94        self.var_named.set(ident, value, age);
95    }
96    fn fn_def(&mut self, name: &str, body: Value, params: Vec<String>) {
97        self.fn_named
98            .set(name, Arc::new(FnDef { body, params }), self.pointer);
99    }
100}
101trait ContextHelper0<T: ContextHolder> {
102    fn scope_with<F: FnOnce(&mut T) -> i32>(ctx: &mut T, func: F) -> i32 {
103        let helper = ctx.ctx();
104        let point = helper.pointer;
105        helper.pointer += 1;
106        let res = func(ctx);
107        let helper = ctx.ctx();
108        helper.pointer = point;
109        helper.fn_named.clear(point);
110        helper.var_named.clear(point);
111        res
112    }
113    fn fn_call(ctx: &mut T, name: &str, args: Vec<i32>) -> i32 {
114        Self::scope_with(ctx, |ctx| {
115            let helper = ctx.ctx();
116            let pointer = helper.pointer;
117            let func = helper.fn_named.get(name, pointer).unwrap().clone();
118            for (idx, param) in func.params.iter().enumerate() {
119                helper.var_named.set(
120                    param,
121                    args.get(idx).map(|e| *e).unwrap_or_default(),
122                    pointer,
123                );
124            }
125            let res = func.body.to_i32(ctx);
126            res
127        })
128    }
129    fn _if(ctx: &mut T, args: &Vec<Value>) -> i32 {
130        match args.len() {
131            0 => 0,
132            1 => {
133                if i2b!(args[0].to_i32(ctx)) {
134                    0
135                } else {
136                    0
137                }
138            }
139            2 => {
140                if i2b!(args[0].to_i32(ctx)) {
141                    args[1].to_i32(ctx)
142                } else {
143                    0
144                }
145            }
146            _ => {
147                let res = if i2b!(args[0].to_i32(ctx)) {
148                    args[1].to_i32(ctx)
149                } else {
150                    args[2].to_i32(ctx)
151                };
152                args[3..].to_i32(ctx);
153                res
154            }
155        }
156    }
157    fn _while(ctx: &mut T, args: &Vec<Value>) -> i32 {
158        let mut res = 0;
159        while i2b!(args[0].to_i32(ctx)) {
160            res = args[1..].to_i32(ctx);
161        }
162        res
163    }
164    fn _log(ctx: &mut T, args: &Vec<Value>) -> i32 {
165        let msg = args[0].as_ident();
166        let args = args[1..].to_i32_vec(ctx);
167        ctx.ctx_log(&format!("{} {:?}", msg, args));
168        args.last().map(|e| *e).unwrap_or(0)
169    }
170    fn _assert(ctx: &mut T, args: &Vec<Value>) -> i32 {
171        assert!(i2b!(args[0].to_i32(ctx)));
172        1
173    }
174    fn _fn(ctx: &mut T, args: &Vec<Value>) -> i32 {
175        ctx.ctx().fn_def(
176            &args[0].as_ident(),
177            args[1].clone(),
178            args[2..].iter().map(|e| e.as_ident()).collect(),
179        );
180        1
181    }
182    fn _call(ctx: &mut T, args: &Vec<Value>) -> i32 {
183        let ident = args[0].as_ident();
184        let args = args[1..].to_i32_vec(ctx);
185        Self::fn_call(ctx, &ident, args)
186    }
187    fn _scope(ctx: &mut T, args: &Vec<Value>) -> i32 {
188        Self::scope_with(ctx, |ctx| args.to_i32(ctx))
189    }
190    fn call_with(ctx: &mut T, func: &str, values: &Vec<Value>) -> i32 {
191        match func {
192            "_if" => Self::_if(ctx, values),
193            "_while" => Self::_while(ctx, values),
194            "_log" => Self::_log(ctx, values),
195            "_assert" => Self::_assert(ctx, values),
196            "_fn" => Self::_fn(ctx, values),
197            "_call" => Self::_call(ctx, values),
198            "_scope" => Self::_scope(ctx, values),
199            _ => {
200                let args = values.to_i32_vec(ctx);
201                Self::fn_call(ctx, func, args)
202            }
203        }
204    }
205}
206impl<T: ContextHolder> ContextHelper0<T> for ContextHelper {}
207
208impl Value {
209    fn as_ident(&self) -> String {
210        if let Value::Ident(ident) = self {
211            ident.clone()
212        } else {
213            unreachable!()
214        }
215    }
216}
217
218trait ValuedVec<T> {
219    fn to_i32_vec(&self, ctx: &mut T) -> Vec<i32>;
220}
221impl<T: Context, V: Valued<T>> ValuedVec<T> for [V] {
222    fn to_i32_vec(&self, ctx: &mut T) -> Vec<i32> {
223        self.iter().map(|e| e.to_i32(ctx)).collect()
224    }
225}
226
227impl<T: ContextHolder> Context for T {
228    fn call(&mut self, func: &str, values: &Vec<Value>) -> i32 {
229        match self.ctx_call(func, values) {
230            Some(res) => res,
231            None => ContextHelper::call_with(self, func, values),
232        }
233    }
234
235    fn ident_get(&self, ident: &str) -> i32 {
236        self.ctx_ref().ident_get(ident)
237    }
238
239    fn ident_set(&mut self, ident: &str, value: i32) {
240        self.ctx().ident_set(ident, value)
241    }
242}
243
244impl ContextHolder for ContextHelper {
245    fn ctx(&mut self) -> &mut ContextHelper {
246        self
247    }
248
249    fn ctx_ref(&self) -> &ContextHelper {
250        self
251    }
252}
253
254#[cfg(test)]
255mod tests {
256    use super::*;
257
258    impl ContextHelper {
259        pub fn exec(&mut self, str: &str) {
260            let v = Value::parse_str(str).unwrap().to_i32(self);
261            println!("exec_value_is: {}", v);
262        }
263    }
264
265    #[test]
266    fn test() {
267        let mut ctx = ContextHelper::default();
268
269        //条件
270        ctx.exec(
271            "(
272            _assert(_if(1,2,3)==2),
273            _assert(_if(-1,2,3)==3),
274            )",
275        );
276        //函数
277        ctx.exec(
278            "(
279            _fn(add,a+b,a,b),
280            _assert(add(1)==1),
281            _assert(add(1,2)==3),
282            _assert(_call(add,1,2)==3)
283            )",
284        );
285        //循环
286        ctx.exec(
287            "_log(_while,
288            i=10,
289            _while(i<100000,
290                _if(i%10000==0,_log(i_is,i)),
291                i+=1,
292                i
293            )
294            )",
295        );
296        //递归
297        ctx.exec(
298            "(
299            _fn(fib1,_if(n<2,a2,fib1(n-1,a2,a1+a2)),n,a1,a2),
300            _fn(fib,fib1(n,1,1),n),
301            _log(fib,fib(0),fib(1),fib(2),fib(3),fib(10),fib(19)),
302            _assert(6765==fib(19))
303            )",
304        );
305        //作用域
306        ctx.exec(
307            "(
308            _scope(a=100,_log(a,a),_assert(a==100)),
309            _scope(a=100,_scope(_assert(a==100))),
310            _scope(a=100,a=200,_assert(a==200)),
311            _scope(a=100,_scope(a=200),_assert(a==100)),
312            _fn(f1,_assert(a==0)),
313            _scope(a=100,_fn(f1,_assert(a==100))),
314            _scope(a=100,_fn(f1,(a=200,_assert(a==200))),_assert(a==100))
315            )",
316        );
317    }
318}