1 module orelang.operator.FilterOperator;
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 FilterOperator : 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           if (efunc.getClosure.eval([elem]).getBool) {
31             ret ~= elem;
32           }
33         }
34 
35         return new Value(ret);
36       } else {
37         Value[] ret;
38 
39         foreach (elem; array) {
40           //ret ~= efunc.getIOperator.call(engine, [elem]);
41           if (efunc.getIOperator.call(engine, [elem]).getBool) {
42             ret ~= elem;
43           }
44         }
45 
46         return new Value(ret);
47       }
48     } else {
49         if (!(eargs1.type == ValueType.ImmediateValue) && !(eargs1.getImmediateValue.value.type == ValueType.Array)) {
50           throw new Exception("map requires array and function as a Operator");
51         }
52 
53         Value[] array = eargs1.getImmediateValue.value.getArray;
54 
55         if (efunc.type == ValueType.Closure) {
56           Value[] ret;
57 
58           foreach (elem; array) {
59             //ret ~= efunc.getClosure.eval([elem]);
60             if (efunc.getClosure.eval([elem]).getBool) {
61               ret ~= elem;
62             }
63           }
64 
65           return new Value(ret);
66         } else {
67           Value[] ret;
68 
69           foreach (elem; array) {
70             //ret ~= efunc.getIOperator.call(engine, [elem]);
71             if (efunc.getIOperator.call(engine, [elem]).getBool) {
72               ret ~= elem;
73             }
74           }
75 
76           return new Value(ret);
77         }
78       }
79   }
80 }