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 @ 47248

History | View | Annotate | Download (32.6 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
            if( this.code() == Code.CALLABLE ) {
112
                Callable caller = (Callable) this;
113
                Function fn = symbolTable.function(caller.name());
114
                if( fn != null ) {
115
                    caller.function(fn);
116
                }
117
                if( caller.parameters() != null ) {
118
                    for( Code arg : caller.parameters() ) {
119
                        if( arg!=null ) {
120
                          arg.link(symbolTable);
121
                        }
122
                    }
123
                }
124
            }
125
        }
126

    
127
        @Override
128
        public void link() {
129
            SymbolTable symbolTable = ExpressionEvaluatorLocator.getExpressionEvaluatorManager().getInmutableSymbolTable();
130
            this.link(symbolTable);
131
        }
132
        
133
        @Override
134
        public void replace(Code target, Code replacement) {
135
        }
136
        
137
        
138
    }
139

    
140
    static class BaseConstant extends BaseCode implements Constant {
141

    
142
        private Object value;
143
        private final ExpressionEvaluatorManager manager;
144

    
145
        public BaseConstant(ExpressionEvaluatorManager manager, Object value) {
146
            this.manager = manager;
147
            this.value = value;
148
        }
149

    
150
        @Override
151
        public Code clone() throws CloneNotSupportedException {
152
            return (Code) super.clone();
153
        }
154

    
155
        @Override
156
        public int code() {
157
            return CONSTANT;
158
        }
159

    
160
        @Override
161
        public Object value() {
162
            return this.value;
163
        }
164

    
165
        public void value(Object v) {
166
            this.value = v;
167
        }
168

    
169
        @Override
170
        public Value toValue(ExpressionBuilder builder) {
171
            ExpressionBuilder.Constant v = builder.constant(this.value);
172
            v.copyPropertiesFrom(builder);
173
            return v;
174
        }
175

    
176
        @Override
177
        public String toString() {
178
            return this.toString(EMPTY_FORMATTER);
179
        }
180
        
181
        @Override
182
        public String toString(Formatter<Code> formatter) {
183
            if( formatter.canApply(this) ) {
184
                return formatter.format(this);
185
            }
186
            Object v = this.value();
187
            return manager.getReprMethod(v).repr(v);
188
        }
189

    
190
    }
191

    
192
    public interface RecursionControlSupport {
193
        
194
        public boolean enterCode(int max);
195
        
196
        public void exitCode();
197
        
198
        public void resetRecursionState();
199
    }
200
    
201
    private static class RecursionSupport implements RecursionControlSupport, Cloneable {
202
    
203
        private int counter;
204
        
205
        public RecursionSupport() {
206
            this.counter = 0;
207
        }
208

    
209
        @Override
210
        public RecursionControlSupport clone() throws CloneNotSupportedException {
211
            RecursionControlSupport x = (RecursionControlSupport) super.clone();
212
            return x;
213
        }
214

    
215
        @Override
216
        public boolean enterCode(int max) {
217
            this.counter += 1;
218
            return this.counter < max;
219
        }
220

    
221
        @Override
222
        public void exitCode() {
223
            this.counter -= 1;
224
        }
225

    
226
        @Override
227
        public void resetRecursionState() {
228
            this.counter = 0;
229
        }
230
        
231
    }
232
    
233
    public static class BaseIdentifier extends BaseCode implements Identifier, RecursionControlSupport {
234

    
235
        private final String name;
236
        private final RecursionSupport recursionSupport;
237

    
238
        public BaseIdentifier(String name) {
239
            this.name = name;
240
            this.recursionSupport = new RecursionSupport();
241
        }
242

    
243
        @Override
244
        public Code clone() throws CloneNotSupportedException {
245
            return (Code) super.clone();
246
        }
247

    
248
        @Override
249
        public int code() {
250
            return IDENTIFIER;
251
        }
252

    
253
        @Override
254
        public String name() {
255
            return this.name;
256
        }
257

    
258
        @Override
259
        public Value toValue(ExpressionBuilder builder) {
260
            ExpressionBuilder.Variable v = builder.variable(this.name);
261
            v.copyPropertiesFrom(builder);
262
            return v;
263
        }
264

    
265
        @Override
266
        public String toString() {
267
            return this.toString(EMPTY_FORMATTER);
268
        }
269
        
270
        @Override
271
        public String toString(Formatter<Code> formatter) {
272
            if( formatter.canApply(this) ) {
273
                return formatter.format(this);
274
            }
275
            StringBuilder builder = new StringBuilder();
276
            builder.append("\"");
277
            builder.append(this.name());
278
            builder.append("\"");
279
            return builder.toString();
280
        }
281

    
282
        @Override
283
        public boolean enterCode(int max) {
284
            return this.recursionSupport.enterCode(max);
285
        }
286

    
287
        @Override
288
        public void exitCode() {
289
            this.recursionSupport.exitCode();
290
        }
291

    
292
        @Override
293
        public void resetRecursionState() {
294
            this.recursionSupport.resetRecursionState();
295
        }
296

    
297
    }
298

    
299
    public static class BaseCodes implements Codes, MutableCodes {
300

    
301
        private List<Code> codes;
302

    
303
        public BaseCodes() {
304
            this.codes = new ArrayList<>();
305
        }
306

    
307
        @Override
308
        public Codes clone() throws CloneNotSupportedException {
309
            BaseCodes x = (BaseCodes)super.clone();
310
            x.codes = new ArrayList<>();
311
            for (int i = 0; i < this.codes.size(); i++) {
312
                Code code = this.codes.get(i);
313
                if(code != null){
314
                    x.add(code.clone());
315
                } else {
316
                    x.add(null);
317
                }
318
            }
319
            return x;
320
        }
321

    
322
        @Override
323
        public int code() {
324
            return CODES;
325
        }
326
        
327
        @Override
328
        public int size() {
329
            if( codes == null ) {
330
                return 0;
331
            }
332
            return this.codes.size();
333
        }
334

    
335
        @Override
336
        public void add(Code arg) {
337
            this.codes.add(arg);
338
        }
339

    
340
        @Override
341
        public void set(int pos, Code arg) {
342
            this.codes.set(pos, arg);
343
        }
344

    
345
        @Override
346
        public void insert(int pos, Code arg) {
347
            this.codes.add(pos, arg);
348
        }
349

    
350
        @Override
351
        public Iterator<Code> iterator() {
352
          final Iterator<Code> it = this.codes.iterator();
353
          return it;
354
        }
355

    
356
        @Override
357
        public Code get(int n) {
358
            return this.codes.get(n);
359
        }
360

    
361
        @Override
362
        public boolean isEmpty() {
363
            return this.codes.isEmpty();
364
        }
365

    
366
        @Override
367
        public List<Code> toList() {
368
            return Collections.unmodifiableList(this.codes);
369
        }
370

    
371
        @Override
372
        public void accept(Visitor visitor) throws BaseException {
373
            this.accept(visitor, null);
374
        }
375

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

    
397
        @Override
398
        public Value toValue() {
399
            throw new UnsupportedOperationException();
400
        }
401

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

    
426
        @Override
427
        public void link(SymbolTable symbolTable) {
428
            for (Code arg : this.codes) {
429
                arg.link(symbolTable);
430
            }
431
        }
432

    
433
        @Override
434
        public void link() {
435
            SymbolTable symbolTable = ExpressionEvaluatorLocator.getExpressionEvaluatorManager().getInmutableSymbolTable();
436
            this.link(symbolTable);
437
        }
438
               
439
        @Override
440
        public void replace(Code target, Code replacement) {
441
            for (int i = 0; i < this.codes.size(); i++) {
442
                Code code = this.codes.get(i);
443
                if( code == null ) {
444
                    continue;
445
                }
446
                if( code == target ) {
447
                    codes.set(i, replacement);
448
                } else {
449
                    code.replace(target, replacement);
450
                }
451
            }
452
        }
453
        
454
    }
455

    
456
    public class BaseCaller extends BaseCode implements Callable, RecursionControlSupport {
457

    
458
        private final String name;
459
        private Codes args;
460
        private Function function;
461
        private final int type;
462
        private RecursionSupport recursionSupport;
463

    
464
        public BaseCaller(String name, int type, Codes args) {
465
            this.name = name;
466
            this.args = args;
467
            this.type = type;
468
            this.function = null;
469
            this.recursionSupport = new RecursionSupport();
470
        }
471

    
472
        @Override
473
        public Code clone() throws CloneNotSupportedException {
474
            BaseCaller x = (BaseCaller) super.clone();
475
            x.recursionSupport = (RecursionSupport) this.recursionSupport.clone();
476
            if (this.args!=null){
477
                x.args = this.args.clone();
478
            }
479
            return x;
480
        }
481

    
482
        @Override
483
        public int code() {
484
            return CALLABLE;
485
        }
486

    
487
        @Override
488
        public void replace(Code target, Code replacement) {
489
            this.args.replace(target, replacement);
490
        }
491

    
492
        @Override
493
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
494
            return this.function.call(interpreter, args);
495
        }
496

    
497
        @Override
498
        public String name() {
499
            return this.name;
500
        }
501

    
502
        @Override
503
        public Function function() {
504
            return this.function;
505
        }
506

    
507
        @Override
508
        public Function function(Function function) {
509
            this.function = function;
510
            return this.function;
511
        }
512

    
513
        @Override
514
        public Codes parameters() {
515
            return this.args;
516
        }
517

    
518
        @Override
519
        public int type() {
520
            return this.type;
521
        }
522

    
523
        @Override
524
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
525
            if( exclude!=null && exclude.test(this) ) {
526
                return;
527
            }
528
            super.accept(visitor, exclude);
529
            if(this.args!=null ) {
530
                this.args.accept(visitor, exclude);
531
            }
532
        }
533

    
534
        @Override
535
        public Value toValue(ExpressionBuilder builder) {
536
            ExpressionBuilder.Value value;
537
            switch(this.type) {
538
                case UNARY_OPERATOR:
539
                    value = builder.function(
540
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
541
                                    "-" :
542
                                    this.name(),
543
                            this.parameters().get(0).toValue(builder)
544
                    );
545
                    break;
546

    
547
                case BINARY_OPERATOR:
548
                    value =  builder.binaryOperator(
549
                            this.name(),
550
                            this.parameters().get(0).toValue(builder),
551
                            this.parameters().get(1).toValue(builder)
552
                    );
553
                    break;
554
                case FUNCTION:
555
                default:
556
                    if(this.function == null){
557
                        ExpressionBuilder.Function f = builder.function(this.name());
558
                        if( this.parameters()!=null ) {
559
                            for (Code parameter : this.parameters()) {
560
                                if (parameter==null) { 
561
                                    f.parameter(null);
562
                                } else {
563
                                    f.parameter(parameter.toValue(builder));
564
                                }
565
                            }  
566
                        }
567
                        value = f;
568
                    } else {
569
                        value = this.function.toValue(builder, this.parameters());
570
                    }
571
                    break;
572

    
573
            }
574
            value.copyPropertiesFrom(builder);
575
            return value;
576
        }
577

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

    
640
        @Override
641
        public boolean enterCode(int max) {
642
            return this.recursionSupport.enterCode(max);
643
        }
644

    
645
        @Override
646
        public void exitCode() {
647
            this.recursionSupport.exitCode();
648
        }
649

    
650
        @Override
651
        public void resetRecursionState() {
652
            this.recursionSupport.resetRecursionState();
653
        }
654
    }
655

    
656
    public static class BaseMethod extends BaseCode implements Method {
657

    
658
        private Code instance;
659
        private final String methodname;
660
        private Codes args;
661
        
662
        public BaseMethod(Code instance, String methodname, Codes args) {
663
            this.instance = instance;
664
            this.methodname = methodname;
665
            this.args = args;
666
        }
667

    
668
        @Override
669
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
670
            if( exclude!=null && exclude.test(this) ) {
671
                return;
672
            }
673
            super.accept(visitor, exclude);
674
            if(this.instance!=null) {
675
               this.instance.accept(visitor, exclude);
676
            }            
677
            if(this.args!=null) {
678
                this.args.accept(visitor, exclude);
679
            }            
680
        }
681

    
682
        @Override
683
        public Code clone() throws CloneNotSupportedException {
684
            BaseMethod x = (BaseMethod) super.clone();
685
            if(this.args != null){
686
                x.args = this.args.clone();
687
            } else {
688
                x.args = null;
689
            }
690
            return x;
691
        }
692
        
693
        @Override
694
        public int code() {
695
            return METHOD;
696
        }
697
        
698
        @Override
699
        public void replace(Code target, Code replacement) {
700
            if( target == this.instance ) {
701
              this.instance = replacement;
702
            }
703
            this.args.replace(target, replacement);
704
        }
705

    
706
        @Override
707
        public String methodname() {
708
            return this.methodname;
709
        }
710

    
711
        @Override
712
        public Code instance() {
713
            return this.instance;
714
        }
715

    
716
        @Override
717
        public Codes parameters() {
718
            return this.args;
719
        }
720

    
721
        @Override
722
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
723
            Object theInstance = interpreter.run(instance);
724
            if( theInstance instanceof SimpleScript ) {
725
                try {
726
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
727
                } catch(NoSuchMethodException ex) {
728
                    // Ignore... continue 
729
                }                
730
            } 
731
            if( theInstance instanceof DynObject ) {
732
                DynObject dynobj = (DynObject) theInstance;
733
                try {
734
                    return dynobj.invokeDynMethod(methodname, args);
735
                } catch(DynMethodNotSupportedException ex) {
736
                    // Ignore... continue 
737
                }
738
            }
739
            if( theInstance instanceof GetItemByKey ) {
740
                try {
741
                    Object method = ((GetItemByKey)theInstance).get(methodname);
742
                    if( method instanceof UserFunction ) {
743
                        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
744
                        MutableSymbolTable localSymbolTable = manager.createSymbolTable();
745
                        localSymbolTable.setVar("self", theInstance);
746
                        return ((UserFunction)method).call(interpreter, localSymbolTable, args);
747
                    } else if( method instanceof Function ) {
748
                        return ((Function)method).call(interpreter, args);
749
                    }
750
                } catch(Throwable t) {
751
                    // Ignore... continue 
752
                }
753
            }
754
            return InstanceUtils.callmethod(theInstance, methodname, args);
755
        }
756

    
757
        @Override
758
        public String toString() {
759
            return this.toString(EMPTY_FORMATTER);
760
        }
761

    
762
        @Override
763
        public Value toValue(ExpressionBuilder builder) {
764
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
765
            if( this.parameters()!=null ) {
766
                for (Code parameter : this.parameters()) {
767
                    m.parameter(parameter.toValue(builder));
768
                }
769
            }
770
            m.copyPropertiesFrom(builder);
771
            return m;
772
        }
773

    
774
        @Override
775
        public String toString(Formatter<Code> formatter) {
776
            if( formatter.canApply(this) ) {
777
                return formatter.format(this);
778
            }
779
            StringBuilder builder = new StringBuilder();
780
            builder.append(this.instance.toString(formatter));
781
            builder.append(".");
782
            builder.append(this.methodname());
783
            builder.append("(");
784
            if( this.parameters()!=null ) {
785
                builder.append(this.parameters().toString(formatter));
786
            }
787
            builder.append(")");
788
            return builder.toString();
789
        }
790

    
791
        @Override
792
        public String name() {
793
            return this.methodname();
794
        }
795

    
796
        @Override
797
        public Function function() {
798
            return null;
799
        }
800

    
801
        @Override
802
        public Function function(Function function) {
803
            return null;
804
        }
805

    
806
        @Override
807
        public int type() {
808
            return Code.METHOD;
809
        }
810
        
811
        
812
    }    
813

    
814
    protected ExpressionEvaluatorManager manager;
815
    
816
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
817
        this.manager = manager;
818
    }
819
    
820
    @Override
821
    public CodeBuilder clone() throws CloneNotSupportedException {
822
        // This implementation of CodeBuilder does not maintain state, so 
823
        // we only call the super class.
824
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
825
        return other;
826
    }
827

    
828
    @Override
829
    public Constant constant(Object value) {
830
        return new BaseConstant(this.manager, value);
831
    }
832

    
833
    @Override
834
    public Identifier identifier(String name) {
835
        return new BaseIdentifier(name);
836
    }
837

    
838
    @Override
839
    public BaseCodes args() {
840
        return new BaseCodes();
841
    }
842

    
843
    @Override
844
    public Callable tuple() {
845
      MutableCodes args = this.args();
846
      return function(FUNCTION_TUPLE, args);
847
    }
848
    
849
    @Override
850
    public Callable tuple(Codes args) {
851
      if( args == null ) {
852
        args = this.args();
853
      }
854
      return function(FUNCTION_TUPLE, args);
855
    }
856

    
857
    @Override
858
    public Callable tuple(Code... items) {
859
        BaseCodes args = this.args();
860
        if (items != null) {
861
            for (Code item : items) {
862
                args.add(item);
863
            }
864
        }
865
        return function(FUNCTION_TUPLE, args);
866
    }
867

    
868
    @Override
869
    public Callable function(String name, int type, Codes args) {
870
        return new BaseCaller(name, type, args);
871
    }
872

    
873
    @Override
874
    public Callable function(String name, Codes args) {
875
        return function(name, Callable.FUNCTION, args);
876
    }
877
    
878
    @Override
879
    public Code method(Code instance, String methodname, Codes methodargs) {
880
        Method m = new BaseMethod(instance, methodname, methodargs);
881
        return m;
882
    }
883
    
884
    @Override
885
    public Callable operator(String name, Code arg1) {
886
        MutableCodes args = args();
887
        args.add(arg1);
888
        return function(name, Callable.UNARY_OPERATOR, args);
889
    }
890

    
891
    @Override
892
    public Callable operator(String name, Code arg1, Code arg2) {
893
        MutableCodes args = args();
894
        args.add(arg1);
895
        args.add(arg2);
896
        return function(name, Callable.BINARY_OPERATOR, args);
897
    }
898
    
899
    @Override
900
    public Code not(Code op1) {
901
        return operator(OPERATOR_NOT, op1);
902
    }
903

    
904
    @Override
905
    public Code negate(Code op1) {
906
        return operator(OPERATOR_NEGATE, op1);
907
    }
908

    
909
    @Override
910
    public Code concat(Code op1, Code op2) {
911
        return operator(OPERATOR_CONCAT, op1, op2);
912
    }
913

    
914
    @Override
915
    public Code let(String identifier, Code value) {
916
        MutableCodes args = args();
917
        args.add(this.constant(identifier));
918
        args.add(value);
919
        return function(FUNCTION_LET, Callable.FUNCTION, args);
920
    }
921

    
922
    @Override
923
    public Code add(Code op1, Code op2) {
924
        return operator(OPERATOR_ADD, op1, op2);
925
    }
926

    
927
    @Override
928
    public Code subst(Code op1, Code op2) {
929
        return operator(OPERATOR_SUBST, op1, op2);
930
    }
931

    
932
    @Override
933
    public Code mult(Code op1, Code op2) {
934
        return operator(OPERATOR_MULT, op1, op2);
935
    }
936

    
937
    @Override
938
    public Code div(Code op1, Code op2) {
939
        return operator(OPERATOR_DIV, op1, op2);
940
    }
941

    
942
    @Override
943
    public Code mod(Code op1, Code op2) {
944
        MutableCodes args = args();
945
        args.add(op1);
946
        args.add(op2);
947
        return function(FUNCTION_MOD, args);
948
    }
949

    
950
    @Override
951
    public Code or(Code op1, Code op2) {
952
        return operator(OPERATOR_OR, op1, op2);
953
    }
954

    
955
    @Override
956
    public Code and(Code op1, Code op2) {
957
        return operator(OPERATOR_AND, op1, op2);
958
    }
959

    
960
    @Override
961
    public Code like(Code op1, Code op2) {
962
        return operator(OPERATOR_LIKE, op1, op2);
963
    }
964

    
965
    @Override
966
    public Code ilike(Code op1, Code op2) {
967
        return operator(OPERATOR_ILIKE, op1, op2);
968
    }
969

    
970
    @Override
971
    public Code regexp(Code op1, Code op2) {
972
        return operator(OPERATOR_REGEXP, op1, op2);
973
    }
974

    
975
    @Override
976
    public Code lt(Code op1, Code op2) {
977
        return operator(OPERATOR_LT, op1, op2);
978
    }
979

    
980
    @Override
981
    public Code gt(Code op1, Code op2) {
982
        return operator(OPERATOR_GT, op1, op2);
983
    }
984

    
985
    @Override
986
    public Code le(Code op1, Code op2) {
987
        return operator(OPERATOR_LE, op1, op2);
988
    }
989

    
990
    @Override
991
    public Code ge(Code op1, Code op2) {
992
        return operator(OPERATOR_GE, op1, op2);
993
    }
994

    
995
    @Override
996
    public Code eq(Code op1, Code op2) {
997
        return operator(OPERATOR_EQ, op1, op2);
998
    }
999

    
1000
    @Override
1001
    public Code ne(Code op1, Code op2) {
1002
        return operator(OPERATOR_NE, op1, op2);
1003
    }
1004

    
1005
    @Override
1006
    public Code is(Code op1, Code op2) {
1007
        return operator(OPERATOR_IS, op1, op2);
1008
    }
1009

    
1010
    @Override
1011
    public Code getattr(Code obj, String attrname) {
1012
        MutableCodes args = args();
1013
        args.add(obj);
1014
        args.add(constant(attrname));
1015
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
1016
    }    
1017

    
1018
    @Override
1019
    public Code getitem(Code obj, Code index) {
1020
        MutableCodes args = args();
1021
        args.add(obj);
1022
        args.add(index);
1023
        return function(FUNCTION_GETITEM, args);
1024
    }
1025

    
1026
    @Override
1027
    public Code dict(Map<String,Code>map ) {
1028
        MutableCodes args = args();
1029
        for (Map.Entry<String, Code> entry : map.entrySet()) {
1030
            String key = entry.getKey();
1031
            Code value = entry.getValue();
1032
            args.add(constant(key));
1033
            args.add(value);
1034
        }
1035
        return function(FUNCTION_DICT, args);
1036
    }
1037
    
1038
    @Override
1039
    public Code $HostExpression(Code obj, String mode_specifier) {
1040
        BaseCodes args = args();
1041
        args.add(obj);
1042
        args.add(constant(mode_specifier));
1043
        return function(ExpressionBuilder.FUNCTION_$HOSTEXPRESSION, args);
1044
    }    
1045

    
1046
    @Override
1047
    public Code $HostExpression(Code obj) {
1048
        MutableCodes args = args();
1049
        args.add(obj);
1050
        return function(ExpressionBuilder.FUNCTION_$HOSTEXPRESSION, args);
1051
    }    
1052

    
1053
    @Override
1054
    public Callable block(Code... codes) {
1055
        MutableCodes args = args();
1056
        if( codes!=null ) {
1057
            for (Code code : codes) {
1058
                args.add(code);
1059
            }
1060
        }
1061
        return function(CodeBlockFunction.NAME,args);
1062
    }
1063

    
1064
    @Override
1065
    public Code in(Code value1, Code value2) {
1066
        MutableCodes args = args();
1067
        args.add(value1);
1068
        args.add(value2);
1069
        return function(OPERATOR_IN, args);
1070
    }
1071

    
1072
    @Override
1073
    public Code between(Code value1, Code value2, Code value3) {
1074
        MutableCodes args = args();
1075
        args.add(value1);
1076
        args.add(value2);
1077
        args.add(value3);
1078
        return function(OPERATOR_BETWEEN, args);
1079
    }
1080

    
1081
    
1082
}