Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.lib / org.gvsig.expressionevaluator.lib.impl / src / main / java / org / gvsig / expressionevaluator / impl / DefaultCodeBuilder.java @ 47299

History | View | Annotate | Download (33 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7
import java.util.Map;
8
import java.util.function.Predicate;
9
import org.gvsig.expressionevaluator.Code;
10
import static org.gvsig.expressionevaluator.Code.CONSTANT;
11
import static org.gvsig.expressionevaluator.Code.IDENTIFIER;
12
import static org.gvsig.expressionevaluator.Code.UNDEFINED;
13
import static org.gvsig.expressionevaluator.Code.CODES;
14
import org.gvsig.expressionevaluator.Code.Constant;
15
import static org.gvsig.expressionevaluator.Code.EMPTY_FORMATTER;
16
import org.gvsig.expressionevaluator.Code.Identifier;
17
import org.gvsig.expressionevaluator.Code.Method;
18
//import org.gvsig.expressionevaluator.Code.Method;
19
import org.gvsig.expressionevaluator.CodeBuilder;
20
import org.gvsig.expressionevaluator.Codes;
21
import org.gvsig.expressionevaluator.ExpressionBuilder;
22
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_TUPLE;
23
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ADD;
24
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_AND;
25
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_CONCAT;
26
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_DIV;
27
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_EQ;
28
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GE;
29
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GT;
30
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ILIKE;
31
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_IS;
32
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LE;
33
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LIKE;
34
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LT;
35
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_MULT;
36
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NE;
37
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NEGATE;
38
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NOT;
39
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_OR;
40
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_REGEXP;
41
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_SUBST;
42
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
43
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
44
import org.gvsig.expressionevaluator.ExpressionUtils;
45
import org.gvsig.expressionevaluator.Formatter;
46
import org.gvsig.expressionevaluator.Function;
47
import org.gvsig.expressionevaluator.Interpreter;
48
import org.gvsig.expressionevaluator.SymbolTable;
49
import org.gvsig.tools.dynobject.DynObject;
50
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
51
import org.gvsig.tools.exception.BaseException;
52
import org.gvsig.tools.visitor.Visitor;
53
import static org.gvsig.expressionevaluator.Code.CALLABLE;
54
import org.gvsig.expressionevaluator.Code.Callable;
55
import static org.gvsig.expressionevaluator.Code.Callable.BINARY_OPERATOR;
56
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_DICT;
57
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETITEM;
58
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_LET;
59
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_MOD;
60
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_BETWEEN;
61
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_IN;
62
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
63
import org.gvsig.expressionevaluator.MutableCodes;
64
import org.gvsig.expressionevaluator.MutableSymbolTable;
65
import org.gvsig.expressionevaluator.impl.function.programming.CodeBlockFunction;
66
import org.gvsig.expressionevaluator.impl.function.programming.CreateFnFunction.UserFunction;
67
import org.gvsig.tools.util.GetItemByKey;
68
import org.gvsig.tools.visitor.FilteredVisitable;
69

    
70
@SuppressWarnings("UseSpecificCatch")
71
public class DefaultCodeBuilder implements CodeBuilder {
72

    
73
    public static abstract class BaseCode implements Code {
74

    
75
        @Override
76
        public int code() {
77
            return UNDEFINED;
78
        }
79

    
80
        @Override
81
        public Code clone() throws CloneNotSupportedException {
82
            BaseCode x = (BaseCode) super.clone();
83
            return x;
84
        }
85
        
86
        @Override
87
        public void accept(Visitor visitor) throws BaseException {
88
            this.accept(visitor, null);
89
        }
90

    
91
        @Override
92
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
93
            if( exclude==null || !exclude.test(this) ) {
94
                visitor.visit(this);
95
            }
96
        }
97
        
98
        @Override
99
        public Value toValue(ExpressionBuilder builder) {
100
            return null;
101
        }
102

    
103
        @Override
104
        public Value toValue() {
105
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
106
            return this.toValue(builder);
107
        }
108
        
109
        @Override
110
        public void link(SymbolTable symbolTable) {
111
            this.link(symbolTable, true);
112
        }
113

    
114
        @Override
115
        public void link(SymbolTable symbolTable, boolean force) {
116
            if( this.code() == Code.CALLABLE ) {
117
                Callable caller = (Callable) this;
118
                if( force || caller.function()==null ) {
119
                    Function fn = symbolTable.function(caller.name());
120
                    if( fn != null ) {
121
                        caller.function(fn);
122
                    }
123
                }
124
                if( caller.parameters() != null ) {
125
                    for( Code arg : caller.parameters() ) {
126
                        if( arg!=null ) {
127
                          arg.link(symbolTable, force);
128
                        }
129
                    }
130
                }
131
            }
132
        }
133

    
134
        @Override
135
        public void link() {
136
            SymbolTable symbolTable = ExpressionEvaluatorLocator.getExpressionEvaluatorManager().getInmutableSymbolTable();
137
            this.link(symbolTable);
138
        }
139
        
140
        @Override
141
        public void replace(Code target, Code replacement) {
142
        }
143
        
144
        
145
    }
146

    
147
    static class BaseConstant extends BaseCode implements Constant {
148

    
149
        private Object value;
150
        private final ExpressionEvaluatorManager manager;
151

    
152
        public BaseConstant(ExpressionEvaluatorManager manager, Object value) {
153
            this.manager = manager;
154
            this.value = value;
155
        }
156

    
157
        @Override
158
        public Code clone() throws CloneNotSupportedException {
159
            return (Code) super.clone();
160
        }
161

    
162
        @Override
163
        public int code() {
164
            return CONSTANT;
165
        }
166

    
167
        @Override
168
        public Object value() {
169
            return this.value;
170
        }
171

    
172
        public void value(Object v) {
173
            this.value = v;
174
        }
175

    
176
        @Override
177
        public Value toValue(ExpressionBuilder builder) {
178
            ExpressionBuilder.Constant v = builder.constant(this.value);
179
            v.copyPropertiesFrom(builder);
180
            return v;
181
        }
182

    
183
        @Override
184
        public String toString() {
185
            return this.toString(EMPTY_FORMATTER);
186
        }
187
        
188
        @Override
189
        public String toString(Formatter<Code> formatter) {
190
            if( formatter.canApply(this) ) {
191
                return formatter.format(this);
192
            }
193
            Object v = this.value();
194
            return manager.getReprMethod(v).repr(v);
195
        }
196

    
197
    }
198

    
199
    public interface RecursionControlSupport {
200
        
201
        public boolean enterCode(int max);
202
        
203
        public void exitCode();
204
        
205
        public void resetRecursionState();
206
    }
207
    
208
    private static class RecursionSupport implements RecursionControlSupport, Cloneable {
209
    
210
        private int counter;
211
        
212
        public RecursionSupport() {
213
            this.counter = 0;
214
        }
215

    
216
        @Override
217
        public RecursionControlSupport clone() throws CloneNotSupportedException {
218
            RecursionControlSupport x = (RecursionControlSupport) super.clone();
219
            return x;
220
        }
221

    
222
        @Override
223
        public boolean enterCode(int max) {
224
            this.counter += 1;
225
            return this.counter < max;
226
        }
227

    
228
        @Override
229
        public void exitCode() {
230
            this.counter -= 1;
231
        }
232

    
233
        @Override
234
        public void resetRecursionState() {
235
            this.counter = 0;
236
        }
237
        
238
    }
239
    
240
    public static class BaseIdentifier extends BaseCode implements Identifier, RecursionControlSupport {
241

    
242
        private final String name;
243
        private final RecursionSupport recursionSupport;
244

    
245
        public BaseIdentifier(String name) {
246
            this.name = name;
247
            this.recursionSupport = new RecursionSupport();
248
        }
249

    
250
        @Override
251
        public Code clone() throws CloneNotSupportedException {
252
            return (Code) super.clone();
253
        }
254

    
255
        @Override
256
        public int code() {
257
            return IDENTIFIER;
258
        }
259

    
260
        @Override
261
        public String name() {
262
            return this.name;
263
        }
264

    
265
        @Override
266
        public Value toValue(ExpressionBuilder builder) {
267
            ExpressionBuilder.Variable v = builder.variable(this.name);
268
            v.copyPropertiesFrom(builder);
269
            return v;
270
        }
271

    
272
        @Override
273
        public String toString() {
274
            return this.toString(EMPTY_FORMATTER);
275
        }
276
        
277
        @Override
278
        public String toString(Formatter<Code> formatter) {
279
            if( formatter.canApply(this) ) {
280
                return formatter.format(this);
281
            }
282
            StringBuilder builder = new StringBuilder();
283
            builder.append("\"");
284
            builder.append(this.name());
285
            builder.append("\"");
286
            return builder.toString();
287
        }
288

    
289
        @Override
290
        public boolean enterCode(int max) {
291
            return this.recursionSupport.enterCode(max);
292
        }
293

    
294
        @Override
295
        public void exitCode() {
296
            this.recursionSupport.exitCode();
297
        }
298

    
299
        @Override
300
        public void resetRecursionState() {
301
            this.recursionSupport.resetRecursionState();
302
        }
303

    
304
    }
305

    
306
    public static class BaseCodes implements Codes, MutableCodes {
307

    
308
        private List<Code> codes;
309

    
310
        public BaseCodes() {
311
            this.codes = new ArrayList<>();
312
        }
313

    
314
        @Override
315
        public Codes clone() throws CloneNotSupportedException {
316
            BaseCodes x = (BaseCodes)super.clone();
317
            x.codes = new ArrayList<>();
318
            for (int i = 0; i < this.codes.size(); i++) {
319
                Code code = this.codes.get(i);
320
                if(code != null){
321
                    x.add(code.clone());
322
                } else {
323
                    x.add(null);
324
                }
325
            }
326
            return x;
327
        }
328

    
329
        @Override
330
        public int code() {
331
            return CODES;
332
        }
333
        
334
        @Override
335
        public int size() {
336
            if( codes == null ) {
337
                return 0;
338
            }
339
            return this.codes.size();
340
        }
341

    
342
        @Override
343
        public void add(Code arg) {
344
            this.codes.add(arg);
345
        }
346

    
347
        @Override
348
        public void set(int pos, Code arg) {
349
            this.codes.set(pos, arg);
350
        }
351

    
352
        @Override
353
        public void insert(int pos, Code arg) {
354
            this.codes.add(pos, arg);
355
        }
356

    
357
        @Override
358
        public Iterator<Code> iterator() {
359
          final Iterator<Code> it = this.codes.iterator();
360
          return it;
361
        }
362

    
363
        @Override
364
        public Code get(int n) {
365
            return this.codes.get(n);
366
        }
367

    
368
        @Override
369
        public boolean isEmpty() {
370
            return this.codes.isEmpty();
371
        }
372

    
373
        @Override
374
        public List<Code> toList() {
375
            return Collections.unmodifiableList(this.codes);
376
        }
377

    
378
        @Override
379
        public void accept(Visitor visitor) throws BaseException {
380
            this.accept(visitor, null);
381
        }
382

    
383
        @Override
384
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
385
            if( this.codes != null ) {
386
                for( Code arg : this.codes ) {
387
                    if(arg!=null ) {
388
                        arg.accept(visitor, exclude);
389
                    }
390
                }
391
            }
392
        }
393
        
394
        @Override
395
        public String toString() {
396
            return this.toString(EMPTY_FORMATTER);
397
        }
398
        
399
        @Override
400
        public Value toValue(ExpressionBuilder builder) {
401
            throw new UnsupportedOperationException();
402
        }
403

    
404
        @Override
405
        public Value toValue() {
406
            throw new UnsupportedOperationException();
407
        }
408

    
409
        @Override
410
        public String toString(Formatter<Code> formatter) {
411
            if( formatter.canApply(this) ) {
412
                return formatter.format(this);
413
            }
414
            if( codes != null ) {
415
                StringBuilder builder = new StringBuilder();
416
                boolean skipcoma = true;
417
                for( Code arg : codes ) {
418
                    if( arg == null ) {
419
                      continue;
420
                    }
421
                    if( skipcoma ) {
422
                        skipcoma = false;
423
                    } else {
424
                        builder.append(", ");
425
                    }
426
                    builder.append(arg.toString(formatter));
427
                }
428
                return builder.toString();
429
            }
430
            return "";
431
        }
432

    
433
        @Override
434
        public void link(SymbolTable symbolTable) {
435
            this.link(symbolTable, true);
436
        }
437
        
438
        @Override
439
        public void link(SymbolTable symbolTable, boolean force) {
440
            for (Code arg : this.codes) {
441
                arg.link(symbolTable, force);
442
            }
443
        }
444

    
445
        @Override
446
        public void link() {
447
            SymbolTable symbolTable = ExpressionEvaluatorLocator.getExpressionEvaluatorManager().getInmutableSymbolTable();
448
            this.link(symbolTable);
449
        }
450
               
451
        @Override
452
        public void replace(Code target, Code replacement) {
453
            for (int i = 0; i < this.codes.size(); i++) {
454
                Code code = this.codes.get(i);
455
                if( code == null ) {
456
                    continue;
457
                }
458
                if( code == target ) {
459
                    codes.set(i, replacement);
460
                } else {
461
                    code.replace(target, replacement);
462
                }
463
            }
464
        }
465
        
466
    }
467

    
468
    public class BaseCaller extends BaseCode implements Callable, RecursionControlSupport {
469

    
470
        private final String name;
471
        private Codes args;
472
        private Function function;
473
        private final int type;
474
        private RecursionSupport recursionSupport;
475

    
476
        public BaseCaller(String name, int type, Codes args) {
477
            this.name = name;
478
            this.args = args;
479
            this.type = type;
480
            this.function = null;
481
            this.recursionSupport = new RecursionSupport();
482
        }
483

    
484
        @Override
485
        public Code clone() throws CloneNotSupportedException {
486
            BaseCaller x = (BaseCaller) super.clone();
487
            x.recursionSupport = (RecursionSupport) this.recursionSupport.clone();
488
            if (this.args!=null){
489
                x.args = this.args.clone();
490
            }
491
            return x;
492
        }
493

    
494
        @Override
495
        public int code() {
496
            return CALLABLE;
497
        }
498

    
499
        @Override
500
        public void replace(Code target, Code replacement) {
501
            this.args.replace(target, replacement);
502
        }
503

    
504
        @Override
505
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
506
            return this.function.call(interpreter, args);
507
        }
508

    
509
        @Override
510
        public String name() {
511
            return this.name;
512
        }
513

    
514
        @Override
515
        public Function function() {
516
            return this.function;
517
        }
518

    
519
        @Override
520
        public Function function(Function function) {
521
            this.function = function;
522
            return this.function;
523
        }
524

    
525
        @Override
526
        public Codes parameters() {
527
            return this.args;
528
        }
529

    
530
        @Override
531
        public int type() {
532
            return this.type;
533
        }
534

    
535
        @Override
536
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
537
            if( exclude!=null && exclude.test(this) ) {
538
                return;
539
            }
540
            super.accept(visitor, exclude);
541
            if(this.args!=null ) {
542
                this.args.accept(visitor, exclude);
543
            }
544
        }
545

    
546
        @Override
547
        public Value toValue(ExpressionBuilder builder) {
548
            ExpressionBuilder.Value value;
549
            switch(this.type) {
550
                case UNARY_OPERATOR:
551
                    value = builder.function(
552
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
553
                                    "-" :
554
                                    this.name(),
555
                            this.parameters().get(0).toValue(builder)
556
                    );
557
                    break;
558

    
559
                case BINARY_OPERATOR:
560
                    value =  builder.binaryOperator(
561
                            this.name(),
562
                            this.parameters().get(0).toValue(builder),
563
                            this.parameters().get(1).toValue(builder)
564
                    );
565
                    break;
566
                case FUNCTION:
567
                default:
568
                    if(this.function == null){
569
                        ExpressionBuilder.Function f = builder.function(this.name());
570
                        if( this.parameters()!=null ) {
571
                            for (Code parameter : this.parameters()) {
572
                                if (parameter==null) { 
573
                                    f.parameter(null);
574
                                } else {
575
                                    f.parameter(parameter.toValue(builder));
576
                                }
577
                            }  
578
                        }
579
                        value = f;
580
                    } else {
581
                        value = this.function.toValue(builder, this.parameters());
582
                    }
583
                    break;
584

    
585
            }
586
            value.copyPropertiesFrom(builder);
587
            return value;
588
        }
589

    
590
        @Override
591
        public String toString() {
592
            return this.toString(EMPTY_FORMATTER);
593
        }
594
        
595
        @Override
596
        public String toString(Formatter<Code> formatter) {
597
            if( formatter.canApply(this) ) {
598
                return formatter.format(this);
599
            }
600
            Code code;
601
            StringBuilder builder = new StringBuilder();
602
            switch(this.type) {
603
                case UNARY_OPERATOR:
604
                    if( OPERATOR_NEGATE.equalsIgnoreCase(this.name()) ) {
605
                        builder.append("-");
606
                    } else {
607
                        builder.append(this.name());
608
                    }
609
                    builder.append("(");
610
                    builder.append(this.parameters().get(0).toString(formatter));
611
                    builder.append(")");
612
                    break;
613
                case BINARY_OPERATOR:
614
                    builder.append("(");
615
                    code = this.parameters().get(0);
616
                    if( code == null ) {                    
617
                        builder.append("?NULL?");
618
                    } else {
619
                        builder.append(code.toString(formatter));
620
                    }
621
                    builder.append(" ");
622
                    builder.append(this.name());
623
                    builder.append(" ");
624
                    code = this.parameters().get(1);
625
                    if( code == null ) {                    
626
                        builder.append("?NULL?");
627
                    } else {
628
                        builder.append(code.toString(formatter));
629
                    }
630
                    builder.append(")");
631
                    break;
632
                case FUNCTION:
633
                default:
634
                    String s = null;
635
                    if( this.function()!=null ) {
636
                        s = this.function().toString(args, formatter);
637
                    }
638
                    if( s == null ) {
639
                        builder.append(this.name());
640
                        builder.append("(");
641
                        if( this.parameters()!=null ) {
642
                            builder.append(this.parameters().toString(formatter));
643
                        }
644
                        builder.append(")");
645
                    } else {
646
                        builder.append(s);
647
                    }
648
            }
649
            return builder.toString();
650
        }
651

    
652
        @Override
653
        public boolean enterCode(int max) {
654
            return this.recursionSupport.enterCode(max);
655
        }
656

    
657
        @Override
658
        public void exitCode() {
659
            this.recursionSupport.exitCode();
660
        }
661

    
662
        @Override
663
        public void resetRecursionState() {
664
            this.recursionSupport.resetRecursionState();
665
        }
666
    }
667

    
668
    public static class BaseMethod extends BaseCode implements Method {
669

    
670
        private Code instance;
671
        private final String methodname;
672
        private Codes args;
673
        
674
        public BaseMethod(Code instance, String methodname, Codes args) {
675
            this.instance = instance;
676
            this.methodname = methodname;
677
            this.args = args;
678
        }
679

    
680
        @Override
681
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
682
            if( exclude!=null && exclude.test(this) ) {
683
                return;
684
            }
685
            super.accept(visitor, exclude);
686
            if(this.instance!=null) {
687
               this.instance.accept(visitor, exclude);
688
            }            
689
            if(this.args!=null) {
690
                this.args.accept(visitor, exclude);
691
            }            
692
        }
693

    
694
        @Override
695
        public Code clone() throws CloneNotSupportedException {
696
            BaseMethod x = (BaseMethod) super.clone();
697
            if(this.args != null){
698
                x.args = this.args.clone();
699
            } else {
700
                x.args = null;
701
            }
702
            return x;
703
        }
704
        
705
        @Override
706
        public int code() {
707
            return METHOD;
708
        }
709
        
710
        @Override
711
        public void replace(Code target, Code replacement) {
712
            if( target == this.instance ) {
713
              this.instance = replacement;
714
            }
715
            this.args.replace(target, replacement);
716
        }
717

    
718
        @Override
719
        public String methodname() {
720
            return this.methodname;
721
        }
722

    
723
        @Override
724
        public Code instance() {
725
            return this.instance;
726
        }
727

    
728
        @Override
729
        public Codes parameters() {
730
            return this.args;
731
        }
732

    
733
        @Override
734
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
735
            Object theInstance = interpreter.run(instance);
736
            if( theInstance instanceof SimpleScript ) {
737
                try {
738
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
739
                } catch(NoSuchMethodException ex) {
740
                    // Ignore... continue 
741
                }                
742
            } 
743
            if( theInstance instanceof DynObject ) {
744
                DynObject dynobj = (DynObject) theInstance;
745
                try {
746
                    return dynobj.invokeDynMethod(methodname, args);
747
                } catch(DynMethodNotSupportedException ex) {
748
                    // Ignore... continue 
749
                }
750
            }
751
            if( theInstance instanceof GetItemByKey ) {
752
                try {
753
                    Object method = ((GetItemByKey)theInstance).get(methodname);
754
                    if( method instanceof UserFunction ) {
755
                        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
756
                        MutableSymbolTable localSymbolTable = manager.createSymbolTable();
757
                        localSymbolTable.setVar("self", theInstance);
758
                        return ((UserFunction)method).call(interpreter, localSymbolTable, args);
759
                    } else if( method instanceof Function ) {
760
                        return ((Function)method).call(interpreter, args);
761
                    }
762
                } catch(Throwable t) {
763
                    // Ignore... continue 
764
                }
765
            }
766
            return InstanceUtils.callmethod(theInstance, methodname, args);
767
        }
768

    
769
        @Override
770
        public String toString() {
771
            return this.toString(EMPTY_FORMATTER);
772
        }
773

    
774
        @Override
775
        public Value toValue(ExpressionBuilder builder) {
776
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
777
            if( this.parameters()!=null ) {
778
                for (Code parameter : this.parameters()) {
779
                    m.parameter(parameter.toValue(builder));
780
                }
781
            }
782
            m.copyPropertiesFrom(builder);
783
            return m;
784
        }
785

    
786
        @Override
787
        public String toString(Formatter<Code> formatter) {
788
            if( formatter.canApply(this) ) {
789
                return formatter.format(this);
790
            }
791
            StringBuilder builder = new StringBuilder();
792
            builder.append(this.instance.toString(formatter));
793
            builder.append(".");
794
            builder.append(this.methodname());
795
            builder.append("(");
796
            if( this.parameters()!=null ) {
797
                builder.append(this.parameters().toString(formatter));
798
            }
799
            builder.append(")");
800
            return builder.toString();
801
        }
802

    
803
        @Override
804
        public String name() {
805
            return this.methodname();
806
        }
807

    
808
        @Override
809
        public Function function() {
810
            return null;
811
        }
812

    
813
        @Override
814
        public Function function(Function function) {
815
            return null;
816
        }
817

    
818
        @Override
819
        public int type() {
820
            return Code.METHOD;
821
        }
822
        
823
        
824
    }    
825

    
826
    protected ExpressionEvaluatorManager manager;
827
    
828
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
829
        this.manager = manager;
830
    }
831
    
832
    @Override
833
    public CodeBuilder clone() throws CloneNotSupportedException {
834
        // This implementation of CodeBuilder does not maintain state, so 
835
        // we only call the super class.
836
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
837
        return other;
838
    }
839

    
840
    @Override
841
    public Constant constant(Object value) {
842
        return new BaseConstant(this.manager, value);
843
    }
844

    
845
    @Override
846
    public Identifier identifier(String name) {
847
        return new BaseIdentifier(name);
848
    }
849

    
850
    @Override
851
    public BaseCodes args() {
852
        return new BaseCodes();
853
    }
854

    
855
    @Override
856
    public Callable tuple() {
857
      MutableCodes args = this.args();
858
      return function(FUNCTION_TUPLE, args);
859
    }
860
    
861
    @Override
862
    public Callable tuple(Codes args) {
863
      if( args == null ) {
864
        args = this.args();
865
      }
866
      return function(FUNCTION_TUPLE, args);
867
    }
868

    
869
    @Override
870
    public Callable tuple(Code... items) {
871
        BaseCodes args = this.args();
872
        if (items != null) {
873
            for (Code item : items) {
874
                args.add(item);
875
            }
876
        }
877
        return function(FUNCTION_TUPLE, args);
878
    }
879

    
880
    @Override
881
    public Callable function(String name, int type, Codes args) {
882
        return new BaseCaller(name, type, args);
883
    }
884

    
885
    @Override
886
    public Callable function(String name, Codes args) {
887
        return function(name, Callable.FUNCTION, args);
888
    }
889
    
890
    @Override
891
    public Code method(Code instance, String methodname, Codes methodargs) {
892
        Method m = new BaseMethod(instance, methodname, methodargs);
893
        return m;
894
    }
895
    
896
    @Override
897
    public Callable operator(String name, Code arg1) {
898
        MutableCodes args = args();
899
        args.add(arg1);
900
        return function(name, Callable.UNARY_OPERATOR, args);
901
    }
902

    
903
    @Override
904
    public Callable operator(String name, Code arg1, Code arg2) {
905
        MutableCodes args = args();
906
        args.add(arg1);
907
        args.add(arg2);
908
        return function(name, Callable.BINARY_OPERATOR, args);
909
    }
910
    
911
    @Override
912
    public Code not(Code op1) {
913
        return operator(OPERATOR_NOT, op1);
914
    }
915

    
916
    @Override
917
    public Code negate(Code op1) {
918
        return operator(OPERATOR_NEGATE, op1);
919
    }
920

    
921
    @Override
922
    public Code concat(Code op1, Code op2) {
923
        return operator(OPERATOR_CONCAT, op1, op2);
924
    }
925

    
926
    @Override
927
    public Code let(String identifier, Code value) {
928
        MutableCodes args = args();
929
        args.add(this.constant(identifier));
930
        args.add(value);
931
        return function(FUNCTION_LET, Callable.FUNCTION, args);
932
    }
933

    
934
    @Override
935
    public Code add(Code op1, Code op2) {
936
        return operator(OPERATOR_ADD, op1, op2);
937
    }
938

    
939
    @Override
940
    public Code subst(Code op1, Code op2) {
941
        return operator(OPERATOR_SUBST, op1, op2);
942
    }
943

    
944
    @Override
945
    public Code mult(Code op1, Code op2) {
946
        return operator(OPERATOR_MULT, op1, op2);
947
    }
948

    
949
    @Override
950
    public Code div(Code op1, Code op2) {
951
        return operator(OPERATOR_DIV, op1, op2);
952
    }
953

    
954
    @Override
955
    public Code mod(Code op1, Code op2) {
956
        MutableCodes args = args();
957
        args.add(op1);
958
        args.add(op2);
959
        return function(FUNCTION_MOD, args);
960
    }
961

    
962
    @Override
963
    public Code or(Code op1, Code op2) {
964
        return operator(OPERATOR_OR, op1, op2);
965
    }
966

    
967
    @Override
968
    public Code and(Code op1, Code op2) {
969
        return operator(OPERATOR_AND, op1, op2);
970
    }
971

    
972
    @Override
973
    public Code like(Code op1, Code op2) {
974
        return operator(OPERATOR_LIKE, op1, op2);
975
    }
976

    
977
    @Override
978
    public Code ilike(Code op1, Code op2) {
979
        return operator(OPERATOR_ILIKE, op1, op2);
980
    }
981

    
982
    @Override
983
    public Code regexp(Code op1, Code op2) {
984
        return operator(OPERATOR_REGEXP, op1, op2);
985
    }
986

    
987
    @Override
988
    public Code lt(Code op1, Code op2) {
989
        return operator(OPERATOR_LT, op1, op2);
990
    }
991

    
992
    @Override
993
    public Code gt(Code op1, Code op2) {
994
        return operator(OPERATOR_GT, op1, op2);
995
    }
996

    
997
    @Override
998
    public Code le(Code op1, Code op2) {
999
        return operator(OPERATOR_LE, op1, op2);
1000
    }
1001

    
1002
    @Override
1003
    public Code ge(Code op1, Code op2) {
1004
        return operator(OPERATOR_GE, op1, op2);
1005
    }
1006

    
1007
    @Override
1008
    public Code eq(Code op1, Code op2) {
1009
        return operator(OPERATOR_EQ, op1, op2);
1010
    }
1011

    
1012
    @Override
1013
    public Code ne(Code op1, Code op2) {
1014
        return operator(OPERATOR_NE, op1, op2);
1015
    }
1016

    
1017
    @Override
1018
    public Code is(Code op1, Code op2) {
1019
        return operator(OPERATOR_IS, op1, op2);
1020
    }
1021

    
1022
    @Override
1023
    public Code getattr(Code obj, String attrname) {
1024
        MutableCodes args = args();
1025
        args.add(obj);
1026
        args.add(constant(attrname));
1027
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
1028
    }    
1029

    
1030
    @Override
1031
    public Code getitem(Code obj, Code index) {
1032
        MutableCodes args = args();
1033
        args.add(obj);
1034
        args.add(index);
1035
        return function(FUNCTION_GETITEM, args);
1036
    }
1037

    
1038
    @Override
1039
    public Code dict(Map<String,Code>map ) {
1040
        MutableCodes args = args();
1041
        for (Map.Entry<String, Code> entry : map.entrySet()) {
1042
            String key = entry.getKey();
1043
            Code value = entry.getValue();
1044
            args.add(constant(key));
1045
            args.add(value);
1046
        }
1047
        return function(FUNCTION_DICT, args);
1048
    }
1049
    
1050
    @Override
1051
    public Code $HostExpression(Code obj, String mode_specifier) {
1052
        BaseCodes args = args();
1053
        args.add(obj);
1054
        args.add(constant(mode_specifier));
1055
        return function(ExpressionBuilder.FUNCTION_$HOSTEXPRESSION, args);
1056
    }    
1057

    
1058
    @Override
1059
    public Code $HostExpression(Code obj) {
1060
        MutableCodes args = args();
1061
        args.add(obj);
1062
        return function(ExpressionBuilder.FUNCTION_$HOSTEXPRESSION, args);
1063
    }    
1064

    
1065
    @Override
1066
    public Callable block(Code... codes) {
1067
        MutableCodes args = args();
1068
        if( codes!=null ) {
1069
            for (Code code : codes) {
1070
                args.add(code);
1071
            }
1072
        }
1073
        return function(CodeBlockFunction.NAME,args);
1074
    }
1075

    
1076
    @Override
1077
    public Code in(Code value1, Code value2) {
1078
        MutableCodes args = args();
1079
        args.add(value1);
1080
        args.add(value2);
1081
        return function(OPERATOR_IN, args);
1082
    }
1083

    
1084
    @Override
1085
    public Code between(Code value1, Code value2, Code value3) {
1086
        MutableCodes args = args();
1087
        args.add(value1);
1088
        args.add(value2);
1089
        args.add(value3);
1090
        return function(OPERATOR_BETWEEN, args);
1091
    }
1092

    
1093
    
1094
}