1 module orelang.operator.DynamicOperator; 2 import orelang.operator.IOperator, 3 orelang.Engine, 4 orelang.Value; 5 import kontainer.orderedAssocArray; 6 /** 7 * Dynamic Operator 8 */ 9 10 class DynamicOperator : IOperator { 11 private { 12 string[] funcArgs; 13 Value funcBody; 14 OrderedAssocArray!(string, Value) opArgs; 15 } 16 17 this (string[] funcArgs, Value funcBody) { 18 this.funcArgs = funcArgs; 19 this.funcBody = funcBody; 20 this.opArgs = new OrderedAssocArray!(string, Value); 21 } 22 23 this (string[] funcArgs, Value funcBody, OrderedAssocArray!(string, Value) opArgs) { 24 this.funcArgs = funcArgs; 25 this.funcBody = funcBody; 26 this.opArgs = opArgs; 27 } 28 29 public Value call(Engine engine, Value[] args) { 30 size_t i = 0; 31 Engine _engine = engine.clone; 32 33 size_t allFuncArgs = this.opArgs.length + this.funcArgs.length; 34 35 if (this.funcArgs.length < args.length && args.length <= allFuncArgs) { 36 size_t j; 37 size_t orders = args.length - this.funcArgs.length; 38 foreach (arg; this.opArgs) { 39 if (j < orders) { 40 _engine.defineVariable(arg.key, engine.eval(args[i++])); 41 } else { 42 _engine.defineVariable(arg.key, engine.eval(arg.value)); 43 } 44 j++; 45 } 46 } else { 47 foreach (arg; this.opArgs) { 48 _engine.defineVariable(arg.key, engine.eval(arg.value)); 49 } 50 } 51 52 foreach (arg; this.funcArgs) { 53 if (arg[0] == '&') { 54 Value[] arr; 55 56 arr = args[i..$]; 57 58 _engine.defineVariable(arg[1..$], new Value(arr)); 59 break; 60 } else { 61 _engine.defineVariable(arg, engine.eval(args[i++])); 62 } 63 } 64 65 return _engine.eval(this.funcBody); 66 } 67 68 override string toString() { 69 string base = "orelang.operator.DynamicOperator.DynamicOperator {"; 70 import std..string; 71 string _body = "[funcArgs : [" ~ funcArgs.join(", ") ~ "], " ~ "funcBody : " ~ funcBody.toString ~ "]"; 72 73 return base ~ _body ~ "}"; 74 } 75 }