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 }