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 ctx.exec(
271 "(
272 _assert(_if(1,2,3)==2),
273 _assert(_if(-1,2,3)==3),
274 )",
275 );
276 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 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 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 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}