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}
27impl Value {
28    fn as_ident(&self) -> String {
29        if let Value::Ident(ident) = self {
30            ident.clone()
31        } else {
32            unreachable!()
33        }
34    }
35}
36impl<T> Named<T> {
37    fn get(&self, key: &str, age: i32) -> Option<&T> {
38        match self.map.get(key) {
39            None => None,
40            Some(vec) => vec.iter().rev().find(|a| a.age <= age).map(|a| &a.value),
41        }
42    }
43    fn set(&mut self, key: &str, value: T, age: i32) -> Option<T> {
44        let frames = self.map.entry(key.to_string()).or_insert(Vec::new());
45        while let Some(frame) = frames.last_mut() {
46            if frame.age > age {
47                frames.pop();
48            } else if frame.age == age {
49                return Some(mem::replace(&mut frame.value, value));
50            } else {
51                break;
52            }
53        }
54        frames.push(Aged { age, value });
55        None
56    }
57    fn clear(&mut self, age: i32) {
58        let mut need_remove = vec![];
59        for (key, frames) in &mut self.map {
60            while let Some(frame) = frames.last_mut() {
61                if frame.age > age {
62                    frames.pop();
63                } else {
64                    break;
65                }
66            }
67            if frames.is_empty() {
68                need_remove.push(key.to_string());
69            }
70        }
71        for key in need_remove {
72            self.map.remove(&key);
73        }
74    }
75}
76impl<T> Default for Named<T> {
77    fn default() -> Self {
78        Self {
79            map: HashMap::new(),
80        }
81    }
82}
83impl<T: Copy + Default> Named<T> {
84    fn get_or_default(&self, key: &str, age: i32) -> T {
85        self.get(key, age).copied().unwrap_or_default()
86    }
87}
88impl ContextHelper {
89    pub fn call_with<C, H>(ctx: &mut C, helper: &H, func: &str, values: &Vec<Value>) -> i32
90    where
91        C: Context,
92        H: Fn(&mut C) -> &mut ContextHelper,
93    {
94        ContextHelper1::call(ctx, helper, func, values)
95    }
96}
97impl Context for ContextHelper {
98    fn call(&mut self, func: &str, values: &Vec<Value>) -> i32 {
99        ContextHelper::call_with(self, &|e| e, func, values)
100    }
101
102    fn ident_get(&self, ident: &str) -> i32 {
103        self.var_named.get_or_default(ident, self.pointer)
104    }
105
106    fn ident_set(&mut self, ident: &str, value: i32) {
107        self.var_named.set(ident, value, self.pointer);
108    }
109}
110struct ContextHelper1<C, H>(C, H);
111impl<C: Context, H: Fn(&mut C) -> &mut ContextHelper> ContextHelper1<C, H> {
112    fn scope_with<F: FnOnce(&mut C) -> i32>(ctx: &mut C, h: &H, func: F) -> i32 {
113        let helper = h(ctx);
114        let point = helper.pointer;
115        helper.pointer += 1;
116        let res = func(ctx);
117        let helper = h(ctx);
118        helper.pointer = point;
119        helper.fn_named.clear(point);
120        helper.var_named.clear(point);
121        res
122    }
123    fn call_vanilla(ctx: &mut C, h: &H, name: &str, args: Vec<i32>) -> i32 {
124        Self::scope_with(ctx, h, |ctx| {
125            let helper = h(ctx);
126            let pointer = helper.pointer;
127            let func = helper
128                .fn_named
129                .get(name, pointer)
130                .map(Arc::clone)
131                .expect(&format!("function not found: {}", name));
132            for (idx, param) in func.params.iter().enumerate() {
133                helper.var_named.set(
134                    param,
135                    args.get(idx).map(|e| *e).unwrap_or_default(),
136                    pointer,
137                );
138            }
139            func.body.to_i32(ctx)
140        })
141    }
142    fn _if(ctx: &mut C, args: &Vec<Value>) -> i32 {
143        let res = if i2b!(args.to_i32_one(ctx, 0)) {
144            args.to_i32_one(ctx, 1)
145        } else {
146            args.to_i32_one(ctx, 2)
147        };
148        if args.len() > 3 {
149            args[3..].to_i32_last(ctx);
150        }
151        res
152    }
153    fn _while(ctx: &mut C, args: &Vec<Value>) -> i32 {
154        let mut res = 0;
155        while i2b!(args.to_i32_one(ctx, 0)) {
156            res = args[1..].to_i32_last(ctx);
157        }
158        res
159    }
160    fn _log(ctx: &mut C, args: &Vec<Value>) -> i32 {
161        let msg = args[0].as_ident();
162        let args = args[1..].to_i32_vec(ctx);
163        println!("{} {:?}", msg, args);
164        args.last().map(|e| *e).unwrap_or_default()
165    }
166    fn _assert(ctx: &mut C, args: &Vec<Value>) -> i32 {
167        assert!(i2b!(args.to_i32_one(ctx, 0)));
168        args[1..].to_i32_last(ctx)
169    }
170    fn _fn(ctx: &mut C, h: &H, args: &Vec<Value>) -> i32 {
171        let helper = h(ctx);
172        helper.fn_named.set(
173            &args[0].as_ident(),
174            Arc::new(FnDef {
175                body: args[1].clone(),
176                params: args[2..].iter().map(|e| e.as_ident()).collect(),
177            }),
178            helper.pointer,
179        );
180        1
181    }
182    fn _call(ctx: &mut C, h: &H, args: &Vec<Value>) -> i32 {
183        let ident = args[0].as_ident();
184        let args = args[1..].to_i32_vec(ctx);
185        Self::call_vanilla(ctx, h, &ident, args)
186    }
187    fn _scope(ctx: &mut C, h: &H, args: &Vec<Value>) -> i32 {
188        Self::scope_with(ctx, h, |ctx| args.to_i32_last(ctx))
189    }
190    fn call(ctx: &mut C, h: &H, 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, h, values),
197            "_call" => Self::_call(ctx, h, values),
198            "_scope" => Self::_scope(ctx, h, values),
199            _ => {
200                let args = values.to_i32_vec(ctx);
201                Self::call_vanilla(ctx, h, func, args)
202            }
203        }
204    }
205}