1 module orelang.operator.ForeachOperator;
2 import orelang.expression.ImmediateValue,
3        orelang.expression.IExpression,
4        orelang.operator.IOperator,
5        orelang.Closure,
6        orelang.Engine,
7        orelang.Value;
8 import std.algorithm,
9        std.array;
10 
11 class ForeachOperator : IOperator {
12   /**
13    * call
14    */
15   public Value call(Engine engine, Value[] args) {
16     engine.sync_storage = true;
17     scope(exit) engine.sync_storage = false;
18 
19     Value efunc  = engine.eval(args[0]);
20     Value eargs1 = engine.eval(args[1]);
21 
22     if (eargs1.type == ValueType.Array) {
23       Value[] array = eargs1.getArray;
24 
25       if (efunc.type == ValueType.Closure) {
26         Value[] ret;
27 
28         foreach (elem; array) {
29           ret ~= efunc.getClosure.eval([elem]);
30         }
31 
32         return new Value(ret);
33       } else {
34         Value[] ret;
35 
36         foreach (elem; array) {
37           ret ~= efunc.getIOperator.call(engine, [elem]);
38         }
39 
40         return new Value(ret);
41       }
42     } else {
43         if (!(eargs1.type == ValueType.ImmediateValue) && !(eargs1.getImmediateValue.value.type == ValueType.Array)) {
44           throw new Exception("for-each requires array and function as a Operator");
45         }
46 
47         Value[] array = eargs1.getImmediateValue.value.getArray;
48 
49         if (efunc.type == ValueType.Closure) {
50           Value[] ret;
51 
52           foreach (elem; array) {
53             ret ~= efunc.getClosure.eval([elem]);
54           }
55 
56           return new Value(ret);
57         } else {
58           Value[] ret;
59 
60           foreach (elem; array) {
61             ret ~= efunc.getIOperator.call(engine, [elem]);
62           }
63 
64           return new Value(ret);
65         }
66       }
67   }
68 }