1 module orelang.operator.LetOperator;
2 import orelang.expression.ImmediateValue,
3        orelang.operator.DynamicOperator,
4        orelang.expression.IExpression,
5        orelang.operator.IOperator,
6        orelang.Closure,
7        orelang.Engine,
8        orelang.Value;
9 import std.algorithm,
10        std.array;
11 
12 class LetOperator : IOperator {
13   /**
14    * call
15    */
16   public Value call(Engine engine, Value[] args) {
17     if (!(args[0].type == ValueType.Array)) {
18       string  name   = args[0].getString;
19       Value[] binds  = args[1].getArray;
20       Value  _body   = args[2];
21       Engine _engine = engine.clone();
22 
23       string[] names;
24       Value[] vars;
25 
26       foreach (bind; binds) {
27         string bname = bind.getArray[0].getString;
28         Value  val   = bind.getArray[1];
29 
30         names ~= bname;
31         vars  ~= val;
32       }
33 
34       _engine.defineVariable(name, new Value(new DynamicOperator(names, _body)));
35       Value ret = (_engine.getVariable(name).getIOperator).call(_engine, vars);
36 
37       if (ret.type == ValueType.Null) {
38         return new Value(0.0);
39       } else {
40         return ret;
41       }
42     } else {
43       Value[] binds  = args[0].getArray;
44       Value  _body   = args[1];
45       Engine _engine = engine.clone();
46 
47       foreach (bind; binds) {
48         string name = bind.getArray[0].getString;
49         Value  val  = engine.eval(bind.getArray[1]);
50 
51         _engine.defineVariable(name, val);
52       }
53 
54       return _engine.eval(_body);
55     }
56   }
57 }