1#[derive(Debug, Clone)]
169pub enum UnOp {
170 Not,
171 Neg,
172}
173#[derive(Debug, Clone)]
174pub enum BinOp {
175 Add,
176 Sub,
177 Mul,
178 Div,
179 Rem,
180 And,
181 Or,
182 BitXor,
183 BitAnd,
184 BitOr,
185 Shl,
186 Shr,
187 Eq,
188 Lt,
189 Le,
190 Ne,
191 Ge,
192 Gt,
193}
194#[derive(Debug, Clone)]
195pub enum AssignOp {
196 Assign,
197 AddAssign,
198 SubAssign,
199 MulAssign,
200 DivAssign,
201 RemAssign,
202 BitXorAssign,
203 BitAndAssign,
204 BitOrAssign,
205 ShlOrAssign,
206 ShrOrAssign,
207}
208#[derive(Debug, Clone)]
209pub enum Value {
210 Integer(i32),
212 Unary(UnOp, Box<Value>),
214 Binary(BinOp, Box<Value>, Box<Value>),
216 Paren(Vec<Value>),
218 FuncLike(String, Vec<Value>),
220 Ident(String),
222 Assign(AssignOp, String, Box<Value>),
224 Copy(Arc<Value>),
226}
227
228macro_rules! i2b {
229 ($expr:expr) => {
230 $expr > 0
231 };
232}
233macro_rules! b2i {
234 ($expr:expr) => {
235 if $expr {
236 1
237 } else {
238 0
239 }
240 };
241}
242
243mod parser {
244 use super::*;
245 use proc_macro2::TokenStream;
246 use std::str::FromStr;
247 use syn::parse::discouraged::Speculative;
248 use syn::parse::{Parse, ParseStream};
249 use syn::{parenthesized, token, Ident, LitInt, Token};
250
251 #[derive(Eq, PartialEq, Ord, PartialOrd)]
252 enum Precedence {
253 Any,
254 Or,
255 And,
256 Compare,
257 BitOr,
258 BitXor,
259 BitAnd,
260 Shift,
261 Arithmetic,
262 Term,
263 }
264
265 impl Precedence {
266 fn of(op: &BinOp) -> Self {
267 match op {
268 BinOp::Add | BinOp::Sub => Precedence::Arithmetic,
269 BinOp::Mul | BinOp::Div | BinOp::Rem => Precedence::Term,
270 BinOp::And => Precedence::And,
271 BinOp::Or => Precedence::Or,
272 BinOp::BitXor => Precedence::BitXor,
273 BinOp::BitAnd => Precedence::BitAnd,
274 BinOp::BitOr => Precedence::BitOr,
275 BinOp::Shl | BinOp::Shr => Precedence::Shift,
276 BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
277 Precedence::Compare
278 }
279 }
280 }
281 }
282
283 impl Parse for UnOp {
284 fn parse(input: ParseStream) -> syn::Result<Self> {
285 let lookahead = input.lookahead1();
286 if lookahead.peek(Token![!]) {
287 input.parse::<Token![!]>().map(|_| Self::Not)
288 } else if lookahead.peek(Token![-]) {
289 input.parse::<Token![-]>().map(|_| Self::Neg)
290 } else {
291 Err(input.error("expected unary operator"))
292 }
293 }
294 }
295
296 impl Parse for BinOp {
297 fn parse(input: ParseStream) -> syn::Result<Self> {
298 if input.peek(Token![&&]) {
299 input.parse::<Token![&&]>().map(|_| Self::And)
300 } else if input.peek(Token![||]) {
301 input.parse::<Token![||]>().map(|_| Self::Or)
302 } else if input.peek(Token![<<]) {
303 input.parse::<Token![<<]>().map(|_| Self::Shl)
304 } else if input.peek(Token![>>]) {
305 input.parse::<Token![>>]>().map(|_| Self::Shr)
306 } else if input.peek(Token![==]) {
307 input.parse::<Token![==]>().map(|_| Self::Eq)
308 } else if input.peek(Token![<=]) {
309 input.parse::<Token![<=]>().map(|_| Self::Le)
310 } else if input.peek(Token![!=]) {
311 input.parse::<Token![!=]>().map(|_| Self::Ne)
312 } else if input.peek(Token![>=]) {
313 input.parse::<Token![>=]>().map(|_| Self::Ge)
314 } else if input.peek(Token![+]) {
315 input.parse::<Token![+]>().map(|_| Self::Add)
316 } else if input.peek(Token![-]) {
317 input.parse::<Token![-]>().map(|_| Self::Sub)
318 } else if input.peek(Token![*]) {
319 input.parse::<Token![*]>().map(|_| Self::Mul)
320 } else if input.peek(Token![/]) {
321 input.parse::<Token![/]>().map(|_| Self::Div)
322 } else if input.peek(Token![%]) {
323 input.parse::<Token![%]>().map(|_| Self::Rem)
324 } else if input.peek(Token![^]) {
325 input.parse::<Token![^]>().map(|_| Self::BitXor)
326 } else if input.peek(Token![&]) {
327 input.parse::<Token![&]>().map(|_| Self::BitAnd)
328 } else if input.peek(Token![|]) {
329 input.parse::<Token![|]>().map(|_| Self::BitOr)
330 } else if input.peek(Token![<]) {
331 input.parse::<Token![<]>().map(|_| Self::Lt)
332 } else if input.peek(Token![>]) {
333 input.parse::<Token![>]>().map(|_| Self::Gt)
334 } else {
335 Err(input.error("expected binary operator"))
336 }
337 }
338 }
339
340 impl Parse for AssignOp {
341 fn parse(input: ParseStream) -> syn::Result<Self> {
342 if input.peek(Token![=]) {
343 input.parse::<Token![=]>().map(|_| Self::Assign)
344 } else if input.peek(Token![+=]) {
345 input.parse::<Token![+=]>().map(|_| Self::AddAssign)
346 } else if input.peek(Token![-=]) {
347 input.parse::<Token![-=]>().map(|_| Self::SubAssign)
348 } else if input.peek(Token![*=]) {
349 input.parse::<Token![*=]>().map(|_| Self::MulAssign)
350 } else if input.peek(Token![/=]) {
351 input.parse::<Token![/=]>().map(|_| Self::DivAssign)
352 } else if input.peek(Token![%=]) {
353 input.parse::<Token![%=]>().map(|_| Self::RemAssign)
354 } else if input.peek(Token![^=]) {
355 input.parse::<Token![^=]>().map(|_| Self::BitXorAssign)
356 } else if input.peek(Token![&=]) {
357 input.parse::<Token![&=]>().map(|_| Self::BitAndAssign)
358 } else if input.peek(Token![|=]) {
359 input.parse::<Token![|=]>().map(|_| Self::BitOrAssign)
360 } else if input.peek(Token![<<=]) {
361 input.parse::<Token![<<=]>().map(|_| Self::ShlOrAssign)
362 } else if input.peek(Token![>>=]) {
363 input.parse::<Token![>>=]>().map(|_| Self::ShrOrAssign)
364 } else {
365 Err(input.error("expected assign operator"))
366 }
367 }
368 }
369
370 impl Parse for Value {
371 fn parse(input: ParseStream) -> syn::Result<Self> {
372 let lhs = unary_value(input)?;
373 parse_value(input, lhs, Precedence::Any)
374 }
375 }
376
377 fn unary_value(input: ParseStream) -> syn::Result<Value> {
378 if input.peek(Token![!]) || input.peek(Token![-]) {
379 Ok(Value::Unary(input.parse()?, Box::new(unary_value(input)?)))
380 } else {
381 atom_value(input)
382 }
383 }
384
385 fn atom_value(input: ParseStream) -> syn::Result<Value> {
386 if input.peek(token::Paren) {
387 let content;
388 parenthesized!(content in input);
389 let data = content
390 .parse_terminated(Value::parse, Token![,])?
391 .into_iter()
392 .collect();
393 return Ok(Value::Paren(data));
394 }
395 if input.peek(LitInt) {
396 let integer = input.parse::<LitInt>()?.base10_parse::<i32>()?;
397 return Ok(Value::Integer(integer));
398 }
399 if input.peek(Ident) {
400 let ident = input.parse::<Ident>()?.to_string();
401 if input.peek(token::Paren) {
402 let content;
403 parenthesized!(content in input);
404 let data = content
405 .parse_terminated(Value::parse, Token![,])?
406 .into_iter()
407 .collect();
408 return Ok(Value::FuncLike(ident, data));
409 }
410 if !input.peek(Token![==]) {
411 let ahead = input.fork();
412 if let Ok(op) = ahead.parse::<AssignOp>() {
413 input.advance_to(&ahead);
414 return Ok(Value::Assign(op, ident, input.parse()?));
415 }
416 }
417 return Ok(Value::Ident(ident));
418 }
419 Err(input.lookahead1().error())
420 }
421
422 fn peek_precedence(input: ParseStream) -> Precedence {
423 if let Ok(op) = input.fork().parse() {
424 Precedence::of(&op)
425 } else {
426 Precedence::Any
427 }
428 }
429
430 fn parse_value(input: ParseStream, mut lhs: Value, base: Precedence) -> syn::Result<Value> {
431 loop {
432 let ahead = input.fork();
433 if let Some(op) = match ahead.parse::<BinOp>() {
434 Ok(op) if Precedence::of(&op) >= base => Some(op),
435 _ => None,
436 } {
437 input.advance_to(&ahead);
438 let precedence = Precedence::of(&op);
439 let mut rhs = unary_value(input)?;
440 loop {
441 let next = peek_precedence(input);
442 if next > precedence {
443 rhs = parse_value(input, rhs, next)?;
444 } else {
445 break;
446 }
447 }
448 lhs = Value::Binary(op, Box::new(lhs), Box::new(rhs));
449 } else {
450 break;
451 }
452 }
453 Ok(lhs)
454 }
455
456 impl Value {
457 pub fn parse_str(input: &str) -> syn::Result<Self> {
458 syn::parse2(TokenStream::from_str(input)?)
459 }
460 }
461
462 #[cfg(test)]
463 mod tests {
464 use crate::Value;
465
466 #[test]
467 fn test() {
468 let test = |e| Value::parse_str(e).unwrap();
469 test("1");
470 test("-1");
471 test("1+2");
472 test("(1,2,3)");
473 test("(1+2,3,a(1))");
474 test("a");
475 test("a+=1");
476 }
477 }
478}
479mod valuer {
480 use super::*;
481
482 pub trait IValue<T: ?Sized> {
483 fn to_i32(&self, ctx: &mut T) -> i32;
484 }
485 pub trait IContext {
486 fn call(&mut self, func: &str, values: &Vec<Value>) -> i32;
487 fn ident_get(&self, ident: &str) -> i32;
488 fn ident_set(&mut self, ident: &str, value: i32);
489 }
490
491 impl UnOp {
492 pub fn to_i32<T: IContext, V: IValue<T>>(&self, ctx: &mut T, value: V) -> i32 {
493 match self {
494 UnOp::Not => b2i!(!i2b!(value.to_i32(ctx))),
495 UnOp::Neg => -value.to_i32(ctx),
496 }
497 }
498 }
499
500 impl BinOp {
501 pub fn to_i32<T: IContext, V: IValue<T>>(&self, ctx: &mut T, left: V, right: V) -> i32 {
502 match self {
503 BinOp::Add => left.to_i32(ctx) + right.to_i32(ctx),
504 BinOp::Sub => left.to_i32(ctx) - right.to_i32(ctx),
505 BinOp::Mul => left.to_i32(ctx) * right.to_i32(ctx),
506 BinOp::Div => left.to_i32(ctx) / right.to_i32(ctx),
507 BinOp::Rem => left.to_i32(ctx) % right.to_i32(ctx),
508 BinOp::BitXor => left.to_i32(ctx) ^ right.to_i32(ctx),
509 BinOp::BitAnd => left.to_i32(ctx) & right.to_i32(ctx),
510 BinOp::BitOr => left.to_i32(ctx) | right.to_i32(ctx),
511 BinOp::Shl => left.to_i32(ctx) << right.to_i32(ctx),
512 BinOp::Shr => left.to_i32(ctx) >> right.to_i32(ctx),
513 BinOp::And => b2i!(i2b!(left.to_i32(ctx)) && i2b!(right.to_i32(ctx))),
514 BinOp::Or => b2i!(i2b!(left.to_i32(ctx)) || i2b!(right.to_i32(ctx))),
515 BinOp::Eq => b2i!(left.to_i32(ctx) == right.to_i32(ctx)),
516 BinOp::Lt => b2i!(left.to_i32(ctx) < right.to_i32(ctx)),
517 BinOp::Le => b2i!(left.to_i32(ctx) <= right.to_i32(ctx)),
518 BinOp::Ne => b2i!(left.to_i32(ctx) != right.to_i32(ctx)),
519 BinOp::Ge => b2i!(left.to_i32(ctx) >= right.to_i32(ctx)),
520 BinOp::Gt => b2i!(left.to_i32(ctx) > right.to_i32(ctx)),
521 }
522 }
523 }
524
525 impl AssignOp {
526 pub fn to_i32<T: IContext, V: IValue<T>>(&self, ctx: &mut T, ident: &str, value: V) -> i32 {
527 let v = match self {
528 AssignOp::Assign => value.to_i32(ctx),
529 AssignOp::AddAssign => ctx.ident_get(ident) + value.to_i32(ctx),
530 AssignOp::SubAssign => ctx.ident_get(ident) - value.to_i32(ctx),
531 AssignOp::MulAssign => ctx.ident_get(ident) * value.to_i32(ctx),
532 AssignOp::DivAssign => ctx.ident_get(ident) / value.to_i32(ctx),
533 AssignOp::RemAssign => ctx.ident_get(ident) % value.to_i32(ctx),
534 AssignOp::BitXorAssign => ctx.ident_get(ident) ^ value.to_i32(ctx),
535 AssignOp::BitAndAssign => ctx.ident_get(ident) & value.to_i32(ctx),
536 AssignOp::BitOrAssign => ctx.ident_get(ident) | value.to_i32(ctx),
537 AssignOp::ShlOrAssign => ctx.ident_get(ident) << value.to_i32(ctx),
538 AssignOp::ShrOrAssign => ctx.ident_get(ident) >> value.to_i32(ctx),
539 };
540 ctx.ident_set(ident, v);
541 v
542 }
543 }
544
545 impl<T: IContext, V: IValue<T>> IValue<T> for [V] {
546 fn to_i32(&self, ctx: &mut T) -> i32 {
547 let mut last = 0;
548 for value in self.iter() {
549 last = value.to_i32(ctx);
550 }
551 last
552 }
553 }
554
555 impl<T: IContext> IValue<T> for Value {
556 fn to_i32(&self, ctx: &mut T) -> i32 {
557 match self {
558 Value::Integer(v) => *v,
559 Value::Unary(op, v) => op.to_i32(ctx, v),
560 Value::Binary(op, l, r) => op.to_i32(ctx, l, r),
561 Value::Paren(v) => v.to_i32(ctx),
562 Value::FuncLike(v, args) => ctx.call(v, args),
563 Value::Ident(ident) => ctx.ident_get(ident),
564 Value::Assign(op, ident, v) => op.to_i32(ctx, ident, v),
565 Value::Copy(v) => v.to_i32(ctx),
566 }
567 }
568 }
569
570 impl<T: IContext> IValue<T> for &Box<Value> {
571 fn to_i32(&self, ctx: &mut T) -> i32 {
572 self.as_ref().to_i32(ctx)
573 }
574 }
575
576 impl IContext for () {
577 fn call(&mut self, _func: &str, _values: &Vec<Value>) -> i32 {
578 unreachable!()
579 }
580
581 fn ident_get(&self, _ident: &str) -> i32 {
582 unreachable!()
583 }
584
585 fn ident_set(&mut self, _ident: &str, _value: i32) {
586 unreachable!()
587 }
588 }
589
590 impl Value {
591 fn optimize_value(&self) -> Option<i32> {
592 match self {
593 Value::Integer(v) => Some(*v),
594 Value::Unary(op, v) => {
595 Some(op.to_i32(&mut (), Value::Integer(v.optimize_value()?)))
596 }
597 Value::Binary(op, l, r) => {
598 let left = l.optimize_value()?;
599 match op {
600 BinOp::And => {
601 if !i2b!(left) {
602 return Some(b2i!(false));
603 }
604 }
605 BinOp::Or => {
606 if i2b!(left) {
607 return Some(b2i!(true));
608 }
609 }
610 _ => {}
611 }
612 Some(op.to_i32(
613 &mut (),
614 Value::Integer(left),
615 Value::Integer(r.optimize_value()?),
616 ))
617 }
618 Value::Paren(v) => {
619 let mut res = 0;
620 for x in v {
621 res = x.optimize_value()?
622 }
623 Some(res)
624 }
625 Value::FuncLike(_, _) => None,
626 Value::Ident(_) => None,
627 Value::Assign(_, _, _) => None,
628 Value::Copy(_) => None,
629 }
630 }
631 pub fn optimize(self) -> Self {
632 match self.optimize_value() {
633 None => self,
634 Some(v) => Self::Integer(v),
635 }
636 }
637 }
638
639 #[cfg(test)]
640 mod tests {
641 use crate::valuer::{IContext, IValue};
642 use crate::Value;
643
644 #[test]
645 fn test() {
646 struct C;
647 impl IContext for C {
648 fn call(&mut self, func: &str, values: &Vec<Value>) -> i32 {
649 match func {
650 "add" => {
651 let args: Vec<_> = values.iter().map(|e| e.to_i32(self)).collect();
652 args[0] + args[1]
653 }
654 &_ => {
655 unreachable!()
656 }
657 }
658 }
659
660 fn ident_get(&self, _ident: &str) -> i32 {
661 unreachable!()
662 }
663
664 fn ident_set(&mut self, _ident: &str, _value: i32) {
665 unreachable!()
666 }
667 }
668 impl C {
669 fn test(&mut self, str: &str) -> i32 {
670 Value::parse_str(str).unwrap().to_i32(self)
671 }
672 }
673 let mut c = C {};
674 let ctx = &mut c;
675 assert_eq!(ctx.test("1+1"), 2);
676 assert_eq!(ctx.test("add(1,2*5)"), 11);
677 }
678 }
679}
680mod context {
681 use crate::{IContext, IValue, Value};
682 use std::collections::HashMap;
683 use std::sync::Arc;
684
685 #[derive(Debug)]
686 pub struct FnDef {
687 #[allow(dead_code)]
688 pub fid: i32,
689 pub func: Value,
690 pub params: HashMap<String, i32>,
691 }
692 #[derive(Debug)]
693 pub struct FnFrame {
694 pub func: Arc<FnDef>,
695 pub args: Vec<i32>,
696 }
697 #[derive(Debug)]
698 pub struct VarFrame {
699 pub age: i32,
700 pub value: i32,
701 }
702 #[derive(Default)]
703 pub struct ContextHelper {
704 pointer: i32,
705 array0: Vec<i32>,
706 array_map: HashMap<i32, Vec<i32>>,
707 fn_map: HashMap<i32, Arc<FnDef>>,
708 fn_name: HashMap<String, i32>,
709 fn_stack: Vec<FnFrame>,
710 var_stack: HashMap<String, Vec<VarFrame>>,
711 }
712 pub trait IContextHelper: Sized {
713 fn ctx(&mut self) -> &mut ContextHelper;
714 fn ctx_ref(&self) -> &ContextHelper;
715 fn ctx_log(&self, msg: &str);
716 fn ctx_call(&mut self, _func: &str, _values: &Vec<Value>) -> Option<i32> {
717 None
718 }
719 #[doc(hidden)]
720 fn next_key(&mut self, key: i32) -> i32 {
721 if key > 0 {
722 key
723 } else {
724 let ctx = self.ctx();
725 ctx.pointer += 1;
726 ctx.pointer
727 }
728 }
729 #[doc(hidden)]
730 fn scope_begin(&mut self) -> i32 {
731 let ctx = self.ctx();
732 let point = ctx.pointer;
733 ctx.pointer += 1;
734 point
735 }
736 #[doc(hidden)]
737 fn scope_end(&mut self, point: i32) {
738 self.ctx().pointer = point;
739 for (_, frames) in &mut self.ctx().var_stack {
740 while let Some(frame) = frames.last_mut() {
741 if frame.age > point {
742 frames.pop();
743 } else {
744 break;
745 }
746 }
747 }
748 }
749 #[doc(hidden)]
750 fn array_def(&mut self, key: i32, elements: Vec<i32>) -> i32 {
751 let key = self.next_key(key);
752 self.ctx().array_map.insert(key, elements);
753 key
754 }
755 #[doc(hidden)]
756 fn array_get(&self, key: i32) -> &Vec<i32> {
757 let ctx = self.ctx_ref();
758 match ctx.array_map.get(&key) {
759 Some(v) => v,
760 None => &ctx.array0,
761 }
762 }
763 #[doc(hidden)]
764 fn fn_def(&mut self, fid: i32, func: &Value, params: HashMap<String, i32>) -> i32 {
765 let fid = self.next_key(fid);
766 self.ctx().fn_map.insert(
767 fid,
768 Arc::new(FnDef {
769 fid,
770 func: func.clone(),
771 params,
772 }),
773 );
774 fid
775 }
776 #[doc(hidden)]
777 fn fn_call(&mut self, fid: i32, args: Vec<i32>) -> i32 {
778 let point = self.scope_begin();
779 let func = self.ctx().fn_map.get(&fid).unwrap().clone();
780 self.ctx().fn_stack.push(FnFrame {
781 func: func.clone(),
782 args,
783 });
784 let res = func.func.to_i32(self);
785 self.ctx().fn_stack.pop();
786 self.scope_end(point);
787 res
788 }
789 #[doc(hidden)]
790 fn _if(&mut self, args: &Vec<Value>) -> i32 {
791 match args.len() {
792 0 => 0,
793 1 => {
794 if i2b!(args[0].to_i32(self)) {
795 0
796 } else {
797 0
798 }
799 }
800 2 => {
801 if i2b!(args[0].to_i32(self)) {
802 args[1].to_i32(self)
803 } else {
804 0
805 }
806 }
807 _ => {
808 let res = if i2b!(args[0].to_i32(self)) {
809 args[1].to_i32(self)
810 } else {
811 args[2].to_i32(self)
812 };
813 args[3..].to_i32(self);
814 res
815 }
816 }
817 }
818 #[doc(hidden)]
819 fn _fn(&mut self, args: &Vec<Value>) -> i32 {
820 let fid = if let Value::Ident(ident) = &args[0] {
821 let fid = self.next_key(0);
822 self.ctx().fn_name.insert(ident.clone(), fid);
823 fid
824 } else {
825 args[0].to_i32(self)
826 };
827 let mut params = HashMap::new();
828 for idx in 2..args.len() {
829 if let Value::Ident(ident) = &args[idx] {
830 params.insert(ident.clone(), idx as i32 - 2);
831 }
832 }
833 self.fn_def(fid, &args[1], params);
834 fid
835 }
836 #[doc(hidden)]
837 fn _call(&mut self, args: &Vec<Value>) -> i32 {
838 let fid = if let Value::Ident(ident) = &args[0] {
839 self.ctx().fn_name.get(ident).map(|e| *e).unwrap()
840 } else {
841 args[0].to_i32(self)
842 };
843 let args = args[1..].to_i32_vec(self);
844 self.fn_call(fid, args)
845 }
846 #[doc(hidden)]
847 fn _call_inline(&mut self, args: &Vec<Value>) -> i32 {
848 match args.len() {
849 0 => 0,
850 1 => args[0].to_i32(self),
851 _ => {
852 let fid = self.fn_def(0, &args[0], HashMap::new());
853 let args = args[1..].to_i32_vec(self);
854 self.fn_call(fid, args)
855 }
856 }
857 }
858 #[doc(hidden)]
859 fn _scope(&mut self, args: &Vec<Value>) -> i32 {
860 let point = self.scope_begin();
861 let res = args.to_i32(self);
862 self.scope_end(point);
863 res
864 }
865 #[doc(hidden)]
866 fn _while(&mut self, args: &Vec<Value>) -> i32 {
867 let mut res = 0;
868 while i2b!(args[0].to_i32(self)) {
869 res = args[1..].to_i32(self);
870 }
871 res
872 }
873 #[doc(hidden)]
874 fn _log(&mut self, args: &Vec<Value>) -> i32 {
875 let msg = if let Some(Value::Ident(ident)) = args.first() {
876 ident
877 } else {
878 "<<value>>"
879 };
880 let args = args[1..].to_i32_vec(self);
881 self.ctx_log(&format!("{} {:?}", msg, args));
882 args.last().map(|e| *e).unwrap_or(0)
883 }
884 #[doc(hidden)]
885 fn _assert(&mut self, args: &Vec<Value>) -> i32 {
886 assert!(i2b!(args[0].to_i32(self)));
887 1
888 }
889 #[doc(hidden)]
890 fn _debug(&mut self, _args: &Vec<Value>) -> i32 {
891 let msg = format!("var stack:{:?}", self.ctx().var_stack);
892 self.ctx_log(&msg);
893 0
894 }
895 }
896 impl<T: IContextHelper> IContext for T {
897 fn call(&mut self, func: &str, values: &Vec<Value>) -> i32 {
898 if let Some(res) = self.ctx_call(func, values) {
899 return res;
900 }
901 match func {
902 "_if" => self._if(values),
903 "_fn" => self._fn(values),
904 "_call" => self._call(values),
905 "_call_inline" => self._call_inline(values),
906 "_scope" => self._scope(values),
907 "_while" => self._while(values),
908 "_log" => self._log(values),
909 "_assert" => self._assert(values),
910 "_debug" => self._debug(values),
911 _ => {
912 let args = values.to_i32_vec(self);
913 match self.ctx().fn_name.get(func).map(|e| *e) {
914 Some(fid) => self.fn_call(fid, args),
915 None => {
916 unreachable!("unknown function: {}", func);
917 }
918 }
919 }
920 }
921 }
922
923 fn ident_get(&self, ident: &str) -> i32 {
924 if let Some(FnFrame { func, args }) = self.ctx_ref().fn_stack.last() {
925 if let Some(idx) = func.params.get(ident) {
926 return args.get(*idx as usize).map(|e| *e).unwrap_or(0);
927 }
928 }
929 if let Some(fid) = self.ctx_ref().fn_name.get(ident) {
930 return *fid;
931 }
932 if let Some(vec) = self.ctx_ref().var_stack.get(ident) {
933 let age = self.ctx_ref().pointer;
934 if let Some(frame) = vec.iter().rev().find(|frame| frame.age <= age) {
935 return frame.value;
936 }
937 }
938 0
939 }
940
941 fn ident_set(&mut self, ident: &str, value: i32) {
942 if let Some(FnFrame { func, args }) = self.ctx().fn_stack.last_mut() {
943 if let Some(idx) = func.params.get(ident) {
944 let idx = *idx as usize;
945 for _ in args.len()..=idx {
946 args.push(0);
947 }
948 args[idx] = value;
949 return;
950 }
951 }
952 let ctx = self.ctx();
953 let age = ctx.pointer;
954 let frames = ctx.var_stack.entry(ident.to_string()).or_insert(vec![]);
955 while let Some(frame) = frames.last_mut() {
956 if frame.age > age {
957 frames.pop();
958 } else if frame.age == age {
959 frame.value = value;
960 return;
961 } else {
962 break;
963 }
964 }
965 frames.push(VarFrame { age, value });
966 }
967 }
968
969 trait IValueVec<T> {
970 fn to_i32_vec(&self, ctx: &mut T) -> Vec<i32>;
971 }
972 impl<T: IContext, V: IValue<T>> IValueVec<T> for [V] {
973 fn to_i32_vec(&self, ctx: &mut T) -> Vec<i32> {
974 self.iter().map(|v| v.to_i32(ctx)).collect()
975 }
976 }
977
978 #[derive(Default)]
979 pub struct DemoContext {
980 ctx: ContextHelper,
981 }
982 impl DemoContext {
983 pub fn exec(&mut self, str: &str) {
984 let v = Value::parse_str(str).unwrap().to_i32(self);
985 println!("exec_value_is: {}", v);
986 }
987 }
988 impl IContextHelper for DemoContext {
989 fn ctx(&mut self) -> &mut ContextHelper {
990 &mut self.ctx
991 }
992
993 fn ctx_ref(&self) -> &ContextHelper {
994 &self.ctx
995 }
996
997 fn ctx_log(&self, msg: &str) {
998 println!("{}", msg);
999 }
1000 }
1001
1002 #[cfg(test)]
1003 mod tests {
1004 use super::*;
1005 #[test]
1006 fn test() {
1007 let mut ctx = DemoContext::default();
1008 ctx.exec(
1010 "(
1011 _assert(_if(1,2,3)==2),
1012 _assert(_if(-1,2,3)==3),
1013 )",
1014 );
1015 ctx.exec(
1017 "(
1018 _fn(add,a+b,a,b),
1019 _assert(add(1)==1),
1020 _assert(add(1,2)==3),
1021 _assert(_call(add,1,2)==3)
1022 )",
1023 );
1024 ctx.exec(
1026 "_log(_while,
1027 i=10,
1028 _while(i<100000,
1029 _if(i%10000==0,_log(i_is,i)),
1030 i+=1,
1031 i
1032 )
1033 )",
1034 );
1035 ctx.exec(
1037 "(
1038 _fn(fib1,_if(n<2,a2,fib1(n-1,a2,a1+a2)),n,a1,a2),
1039 _fn(fib,fib1(n,1,1),n),
1040 _log(fib,fib(0),fib(1),fib(2),fib(3),fib(10),fib(19)),
1041 _assert(6765==fib(19))
1042 )",
1043 );
1044 ctx.exec(
1046 "(
1047 _scope(a=100,_assert(a==100)),
1048 _scope(a=100,_scope(_assert(a==100))),
1049 _scope(a=100,a=200,_assert(a==200)),
1050 _scope(a=100,_scope(a=200),_assert(a==100)),
1051 _fn(f1,_assert(a==0)),
1052 _scope(a=100,_fn(f1,_assert(a==100))),
1053 _scope(a=100,_fn(f1,(a=200,_assert(a==200))),_assert(a==100))
1054 )",
1055 );
1056 }
1057 }
1058}
1059
1060pub use context::{ContextHelper, DemoContext, IContextHelper};
1061use std::sync::Arc;
1062pub use valuer::{IContext, IValue};