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 }