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

History | View | Annotate | Download (28.9 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.ExpressionBuilder.FUNCTION_DICT;
56
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETITEM;
57
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_LET;
58
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_MOD;
59
import org.gvsig.tools.visitor.FilteredVisitable;
60

    
61
@SuppressWarnings("UseSpecificCatch")
62
public class DefaultCodeBuilder implements CodeBuilder {
63

    
64
    public static abstract class BaseCode implements Code {
65

    
66
        @Override
67
        public int code() {
68
            return UNDEFINED;
69
        }
70

    
71
        @Override
72
        public Code clone() throws CloneNotSupportedException {
73
            BaseCode x = (BaseCode) super.clone();
74
            return x;
75
        }
76
        
77
        @Override
78
        public void accept(Visitor visitor) throws BaseException {
79
            visitor.visit(this);
80
        }
81

    
82
        @Override
83
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
84
            if( !exclude.test(this) ) {
85
                visitor.visit(this);
86
            }
87
        }
88
        
89
        @Override
90
        public Value toValue(ExpressionBuilder builder) {
91
            return null;
92
        }
93

    
94
        @Override
95
        public Value toValue() {
96
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
97
            return this.toValue(builder);
98
        }
99
        
100
        @Override
101
        public void link(SymbolTable symbolTable) {
102
            if( this.code() == Code.CALLABLE ) {
103
                Callable caller = (Callable) this;
104
                Function fn = symbolTable.function(caller.name());
105
                if( fn != null ) {
106
                    caller.function(fn);
107
                }
108
                if( caller.parameters() != null ) {
109
                    for( Code arg : caller.parameters() ) {
110
                        if( arg!=null ) {
111
                          arg.link(symbolTable);
112
                        }
113
                    }
114
                }
115
            }
116
        }
117
        
118
        @Override
119
        public void replace(Code target, Code replacement) {
120
        }
121
        
122
        
123
    }
124

    
125
    static class BaseConstant extends BaseCode implements Constant {
126

    
127
        private Object value;
128
        private final ExpressionEvaluatorManager manager;
129

    
130
        public BaseConstant(ExpressionEvaluatorManager manager, Object value) {
131
            this.manager = manager;
132
            this.value = value;
133
        }
134

    
135
        @Override
136
        public Code clone() throws CloneNotSupportedException {
137
            return (Code) super.clone();
138
        }
139

    
140
        @Override
141
        public int code() {
142
            return CONSTANT;
143
        }
144

    
145
        @Override
146
        public Object value() {
147
            return this.value;
148
        }
149

    
150
        public void value(Object v) {
151
            this.value = v;
152
        }
153

    
154
        @Override
155
        public Value toValue(ExpressionBuilder builder) {
156
            return builder.constant(this.value);
157
        }
158

    
159
        @Override
160
        public String toString() {
161
            return this.toString(EMPTY_FORMATTER);
162
        }
163
        
164
        @Override
165
        public String toString(Formatter<Code> formatter) {
166
            if( formatter.canApply(this) ) {
167
                return formatter.format(this);
168
            }
169
            Object v = this.value();
170
            return manager.getReprMethod(v).repr(v);
171
        }
172

    
173
    }
174

    
175
    public interface RecursionControlSupport {
176
        
177
        public boolean enterCode(int max);
178
        
179
        public void exitCode();
180
        
181
        public void resetRecursionState();
182
    }
183
    
184
    private static class RecursionSupport implements RecursionControlSupport, Cloneable {
185
    
186
        private int counter;
187
        
188
        public RecursionSupport() {
189
            this.counter = 0;
190
        }
191

    
192
        @Override
193
        public RecursionControlSupport clone() throws CloneNotSupportedException {
194
            RecursionControlSupport x = (RecursionControlSupport) super.clone();
195
            return x;
196
        }
197

    
198
        @Override
199
        public boolean enterCode(int max) {
200
            this.counter += 1;
201
            return this.counter < max;
202
        }
203

    
204
        @Override
205
        public void exitCode() {
206
            this.counter -= 1;
207
        }
208

    
209
        @Override
210
        public void resetRecursionState() {
211
            this.counter = 0;
212
        }
213
        
214
    }
215
    
216
    public static class BaseIdentifier extends BaseCode implements Identifier, RecursionControlSupport {
217

    
218
        private final String name;
219
        private final RecursionSupport recursionSupport;
220

    
221
        public BaseIdentifier(String name) {
222
            this.name = name;
223
            this.recursionSupport = new RecursionSupport();
224
        }
225

    
226
        @Override
227
        public Code clone() throws CloneNotSupportedException {
228
            return (Code) super.clone();
229
        }
230

    
231
        @Override
232
        public int code() {
233
            return IDENTIFIER;
234
        }
235

    
236
        @Override
237
        public String name() {
238
            return this.name;
239
        }
240

    
241
        @Override
242
        public Value toValue(ExpressionBuilder builder) {
243
            return builder.variable(this.name);
244
        }
245

    
246
        @Override
247
        public String toString() {
248
            return this.toString(EMPTY_FORMATTER);
249
        }
250
        
251
        @Override
252
        public String toString(Formatter<Code> formatter) {
253
            if( formatter.canApply(this) ) {
254
                return formatter.format(this);
255
            }
256
            StringBuilder builder = new StringBuilder();
257
            builder.append("\"");
258
            builder.append(this.name());
259
            builder.append("\"");
260
            return builder.toString();
261
        }
262

    
263
        @Override
264
        public boolean enterCode(int max) {
265
            return this.recursionSupport.enterCode(max);
266
        }
267

    
268
        @Override
269
        public void exitCode() {
270
            this.recursionSupport.exitCode();
271
        }
272

    
273
        @Override
274
        public void resetRecursionState() {
275
            this.recursionSupport.resetRecursionState();
276
        }
277

    
278
    }
279

    
280
    public static class BaseCodes implements Codes {
281

    
282
        private List<Code> codes;
283

    
284
        public BaseCodes() {
285
            this.codes = new ArrayList<>();
286
        }
287

    
288
        @Override
289
        public Codes clone() throws CloneNotSupportedException {
290
            BaseCodes x = (BaseCodes)super.clone();
291
            x.codes = new ArrayList<>();
292
            for (int i = 0; i < this.codes.size(); i++) {
293
                x.add(this.codes.get(i).clone());
294
            }
295
            return x;
296
        }
297

    
298
        @Override
299
        public int code() {
300
            return CODES;
301
        }
302
        
303
        @Override
304
        public int size() {
305
            if( codes == null ) {
306
                return 0;
307
            }
308
            return this.codes.size();
309
        }
310

    
311
        public void add(Code arg) {
312
            this.codes.add(arg);
313
        }
314

    
315
        public void set(int pos, Code arg) {
316
            this.codes.set(pos, arg);
317
        }
318

    
319
        public void insert(int pos, Code arg) {
320
            this.codes.add(pos, arg);
321
        }
322

    
323
        @Override
324
        public Iterator<Code> iterator() {
325
          final Iterator<Code> it = this.codes.iterator();
326
          return it;
327
        }
328

    
329
        @Override
330
        public Code get(int n) {
331
            return this.codes.get(n);
332
        }
333

    
334
        @Override
335
        public boolean isEmpty() {
336
            return this.codes.isEmpty();
337
        }
338

    
339
        @Override
340
        public List<Code> toList() {
341
            return Collections.unmodifiableList(this.codes);
342
        }
343

    
344
        @Override
345
        public void accept(Visitor visitor) throws BaseException {
346
            for( Code arg : this.codes ) {
347
                if(arg!=null) {
348
                    arg.accept(visitor);
349
                }
350
            }
351
        }
352

    
353
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
354
            if( !exclude.test(this) ) {
355
                for( Code arg : this.codes ) {
356
                    if(arg!=null) {
357
                        arg.accept(visitor, exclude);
358
                    }
359
                }
360
            }
361
        }
362
        
363
        @Override
364
        public String toString() {
365
            return this.toString(EMPTY_FORMATTER);
366
        }
367
        
368
        @Override
369
        public Value toValue(ExpressionBuilder builder) {
370
            throw new UnsupportedOperationException();
371
        }
372

    
373
        @Override
374
        public Value toValue() {
375
            throw new UnsupportedOperationException();
376
        }
377

    
378
        @Override
379
        public String toString(Formatter<Code> formatter) {
380
            if( formatter.canApply(this) ) {
381
                return formatter.format(this);
382
            }
383
            if( codes != null ) {
384
                StringBuilder builder = new StringBuilder();
385
                boolean skipcoma = true;
386
                for( Code arg : codes ) {
387
                    if( arg == null ) {
388
                      continue;
389
                    }
390
                    if( skipcoma ) {
391
                        skipcoma = false;
392
                    } else {
393
                        builder.append(", ");
394
                    }
395
                    builder.append(arg.toString(formatter));
396
                }
397
                return builder.toString();
398
            }
399
            return "";
400
        }
401

    
402
        @Override
403
        public void link(SymbolTable symbolTable) {
404
            for (Code arg : this.codes) {
405
                arg.link(symbolTable);
406
            }
407
        }
408

    
409
        @Override
410
        public void replace(Code target, Code replacement) {
411
            for (int i = 0; i < this.codes.size(); i++) {
412
                Code code = this.codes.get(i);
413
                if( code == target ) {
414
                    codes.set(i, replacement);
415
                } else {
416
                    code.replace(target, replacement);
417
                }
418
            }
419
        }
420
        
421
    }
422

    
423
    public class BaseCaller extends BaseCode implements Callable, RecursionControlSupport {
424

    
425
        private final String name;
426
        private Codes args;
427
        private Function function;
428
        private final int type;
429
        private RecursionSupport recursionSupport;
430

    
431
        public BaseCaller(String name, int type, Codes args) {
432
            this.name = name;
433
            this.args = args;
434
            this.type = type;
435
            this.function = null;
436
            this.recursionSupport = new RecursionSupport();
437
        }
438

    
439
        @Override
440
        public Code clone() throws CloneNotSupportedException {
441
            BaseCaller x = (BaseCaller) super.clone();
442
            x.recursionSupport = (RecursionSupport) this.recursionSupport.clone();
443
            if (this.args!=null){
444
                x.args = this.args.clone();
445
            }
446
            return x;
447
        }
448

    
449
        @Override
450
        public int code() {
451
            return CALLABLE;
452
        }
453

    
454
        @Override
455
        public void replace(Code target, Code replacement) {
456
            this.args.replace(target, replacement);
457
        }
458

    
459
        @Override
460
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
461
            return this.function.call(interpreter, args);
462
        }
463

    
464
        @Override
465
        public String name() {
466
            return this.name;
467
        }
468

    
469
        @Override
470
        public Function function() {
471
            return this.function;
472
        }
473

    
474
        @Override
475
        public Function function(Function function) {
476
            this.function = function;
477
            return this.function;
478
        }
479

    
480
        @Override
481
        public Codes parameters() {
482
            return this.args;
483
        }
484

    
485
        @Override
486
        public int type() {
487
            return this.type;
488
        }
489

    
490
        @Override
491
        public void accept(Visitor visitor) throws BaseException {
492
            visitor.visit(this);
493
            if(this.args!=null) {
494
                this.args.accept(visitor);
495
            }
496
        }
497

    
498
        @Override
499
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
500
            if( !exclude.test(this) ) {
501
                visitor.visit(this);
502
                if(this.args!=null) {
503
                    this.args.accept(visitor, exclude);
504
                }
505
            }
506
        }
507

    
508
        @Override
509
        public Value toValue(ExpressionBuilder builder) {
510
            switch(this.type) {
511
                case UNARY_OPERATOR:
512
                    return builder.function(
513
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
514
                                "-" :
515
                                this.name(),
516
                            this.parameters().get(0).toValue(builder)
517
                    );
518
                case BINARY_OPERATOR:
519
                    return builder.binaryOperator(
520
                            this.name(),
521
                            this.parameters().get(0).toValue(builder),
522
                            this.parameters().get(1).toValue(builder)
523
                    );
524
                case FUNCTION:
525
                default:
526
                    ExpressionBuilder.Function f = builder.function(this.name());
527
                    if( this.parameters()!=null ) {
528
                        for (Code parameter : this.parameters()) {
529
                            if (parameter==null) { 
530
                                f.parameter(null);
531
                            } else {
532
                                f.parameter(parameter.toValue(builder));
533
                            }
534
                        }  
535
                    }
536
                    return f;
537

    
538
            }
539
        }
540

    
541
        @Override
542
        public String toString() {
543
            return this.toString(EMPTY_FORMATTER);
544
        }
545
        
546
        @Override
547
        public String toString(Formatter<Code> formatter) {
548
            if( formatter.canApply(this) ) {
549
                return formatter.format(this);
550
            }
551
            Code code;
552
            StringBuilder builder = new StringBuilder();
553
            switch(this.type) {
554
                case UNARY_OPERATOR:
555
                    if( OPERATOR_NEGATE.equalsIgnoreCase(this.name()) ) {
556
                        builder.append("-");
557
                    } else {
558
                        builder.append(this.name());
559
                    }
560
                    builder.append("(");
561
                    builder.append(this.parameters().get(0).toString(formatter));
562
                    builder.append(")");
563
                    break;
564
                case BINARY_OPERATOR:
565
                    builder.append("(");
566
                    code = this.parameters().get(0);
567
                    if( code == null ) {                    
568
                        builder.append("?NULL?");
569
                    } else {
570
                        builder.append(code.toString(formatter));
571
                    }
572
                    builder.append(" ");
573
                    builder.append(this.name());
574
                    builder.append(" ");
575
                    code = this.parameters().get(1);
576
                    if( code == null ) {                    
577
                        builder.append("?NULL?");
578
                    } else {
579
                        builder.append(code.toString(formatter));
580
                    }
581
                    builder.append(")");
582
                    break;
583
                case FUNCTION:
584
                default:
585
                    String s = null;
586
                    if( this.function()!=null ) {
587
                        s = this.function().toString(args, formatter);
588
                    }
589
                    if( s == null ) {
590
                        builder.append(this.name());
591
                        builder.append("(");
592
                        if( this.parameters()!=null ) {
593
                            builder.append(this.parameters().toString(formatter));
594
                        }
595
                        builder.append(")");
596
                    } else {
597
                        builder.append(s);
598
                    }
599
            }
600
            return builder.toString();
601
        }
602

    
603
        @Override
604
        public boolean enterCode(int max) {
605
            return this.recursionSupport.enterCode(max);
606
        }
607

    
608
        @Override
609
        public void exitCode() {
610
            this.recursionSupport.exitCode();
611
        }
612

    
613
        @Override
614
        public void resetRecursionState() {
615
            this.recursionSupport.resetRecursionState();
616
        }
617
    }
618

    
619
    public static class BaseMethod extends BaseCode implements Method {
620

    
621
        private Code instance;
622
        private final String methodname;
623
        private Codes args;
624
        
625
        public BaseMethod(Code instance, String methodname, Codes args) {
626
            this.instance = instance;
627
            this.methodname = methodname;
628
            this.args = args;
629
        }
630

    
631
        @Override
632
        public void accept(Visitor visitor) throws BaseException {
633
            visitor.visit(this);
634
            if(this.instance!=null) {
635
                this.instance.accept(visitor);
636
            }            
637
            if(this.args!=null) {
638
                this.args.accept(visitor);
639
            }            
640
        }
641
        
642
        @Override
643
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
644
            if( !exclude.test(this) ) {
645
                visitor.visit(this);
646
                if(this.instance!=null) {
647
                    this.instance.accept(visitor, exclude);
648
                }            
649
                if(this.args!=null) {
650
                    this.args.accept(visitor, exclude);
651
                }            
652
            }
653
        }
654

    
655
        @Override
656
        public Code clone() throws CloneNotSupportedException {
657
            BaseMethod x = (BaseMethod) super.clone();
658
            x.args = this.args.clone();
659
            return x;
660
        }
661
        
662
        @Override
663
        public int code() {
664
            return METHOD;
665
        }
666
        
667
        @Override
668
        public void replace(Code target, Code replacement) {
669
            if( target == this.instance ) {
670
              this.instance = replacement;
671
            }
672
            this.args.replace(target, replacement);
673
        }
674

    
675
        @Override
676
        public String methodname() {
677
            return this.methodname;
678
        }
679

    
680
        @Override
681
        public Code instance() {
682
            return this.instance;
683
        }
684

    
685
        @Override
686
        public Codes parameters() {
687
            return this.args;
688
        }
689

    
690
        @Override
691
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
692
            Object theInstance = interpreter.run(instance);
693
            if( theInstance instanceof SimpleScript ) {
694
                try {
695
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
696
                } catch(NoSuchMethodException ex) {
697
                    // Ignore... continue calling instance method
698
                }                
699
            } else if( theInstance instanceof DynObject ) {
700
                DynObject dynobj = (DynObject) theInstance;
701
                try {
702
                    return dynobj.invokeDynMethod(methodname, args);
703
                } catch(DynMethodNotSupportedException ex) {
704
                    // Ignore... continue calling instance method
705
                }
706
            }
707
            return InstanceUtils.callmethod(theInstance, methodname, args);
708
        }
709

    
710
        @Override
711
        public String toString() {
712
            return this.toString(EMPTY_FORMATTER);
713
        }
714

    
715
        @Override
716
        public Value toValue(ExpressionBuilder builder) {
717
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
718
            if( this.parameters()!=null ) {
719
                for (Code parameter : this.parameters()) {
720
                    m.parameter(parameter.toValue(builder));
721
                }
722
            }
723
            return m;
724
        }
725

    
726
        @Override
727
        public String toString(Formatter<Code> formatter) {
728
            if( formatter.canApply(this) ) {
729
                return formatter.format(this);
730
            }
731
            StringBuilder builder = new StringBuilder();
732
            builder.append(this.instance.toString(formatter));
733
            builder.append(".");
734
            builder.append(this.methodname());
735
            builder.append("(");
736
            if( this.parameters()!=null ) {
737
                builder.append(this.parameters().toString(formatter));
738
            }
739
            builder.append(")");
740
            return builder.toString();
741
        }
742

    
743
        @Override
744
        public String name() {
745
            return this.methodname();
746
        }
747

    
748
        @Override
749
        public Function function() {
750
            return null;
751
        }
752

    
753
        @Override
754
        public Function function(Function function) {
755
            return null;
756
        }
757

    
758
        @Override
759
        public int type() {
760
            return Code.METHOD;
761
        }
762
        
763
        
764
    }    
765

    
766
    protected ExpressionEvaluatorManager manager;
767
    
768
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
769
        this.manager = manager;
770
    }
771
    
772
    @Override
773
    public CodeBuilder clone() throws CloneNotSupportedException {
774
        // This implementation of CodeBuilder does not maintain state, so 
775
        // we only call the super class.
776
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
777
        return other;
778
    }
779

    
780
    @Override
781
    public Constant constant(Object value) {
782
        return new BaseConstant(this.manager, value);
783
    }
784

    
785
    @Override
786
    public Identifier identifier(String name) {
787
        return new BaseIdentifier(name);
788
    }
789

    
790
    @Override
791
    public BaseCodes args() {
792
        return new BaseCodes();
793
    }
794

    
795
    @Override
796
    public Callable tuple() {
797
      BaseCodes args = this.args();
798
      return function(FUNCTION_TUPLE, args);
799
    }
800
    
801
    @Override
802
    public Callable tuple(Codes args) {
803
      if( args == null ) {
804
        args = this.args();
805
      }
806
      return function(FUNCTION_TUPLE, args);
807
    }
808

    
809
    @Override
810
    public Callable function(String name, int type, Codes args) {
811
        return new BaseCaller(name, type, args);
812
    }
813

    
814
    @Override
815
    public Callable function(String name, Codes args) {
816
        return function(name, Callable.FUNCTION, args);
817
    }
818
    
819
    @Override
820
    public Code method(Code instance, String methodname, Codes methodargs) {
821
        Method m = new BaseMethod(instance, methodname, methodargs);
822
        return m;
823
    }
824
    
825
    @Override
826
    public Callable operator(String name, Code arg1) {
827
        BaseCodes args = args();
828
        args.add(arg1);
829
        return function(name, Callable.UNARY_OPERATOR, args);
830
    }
831

    
832
    @Override
833
    public Callable operator(String name, Code arg1, Code arg2) {
834
        BaseCodes args = args();
835
        args.add(arg1);
836
        args.add(arg2);
837
        return function(name, Callable.BINARY_OPERATOR, args);
838
    }
839
    
840
    @Override
841
    public Code not(Code op1) {
842
        return operator(OPERATOR_NOT, op1);
843
    }
844

    
845
    @Override
846
    public Code negate(Code op1) {
847
        return operator(OPERATOR_NEGATE, op1);
848
    }
849

    
850
    @Override
851
    public Code concat(Code op1, Code op2) {
852
        return operator(OPERATOR_CONCAT, op1, op2);
853
    }
854

    
855
    @Override
856
    public Code let(String identifier, Code value) {
857
        BaseCodes args = args();
858
        args.add(this.constant(identifier));
859
        args.add(value);
860
        return function(FUNCTION_LET, Callable.FUNCTION, args);
861
    }
862

    
863
    @Override
864
    public Code add(Code op1, Code op2) {
865
        return operator(OPERATOR_ADD, op1, op2);
866
    }
867

    
868
    @Override
869
    public Code subst(Code op1, Code op2) {
870
        return operator(OPERATOR_SUBST, op1, op2);
871
    }
872

    
873
    @Override
874
    public Code mult(Code op1, Code op2) {
875
        return operator(OPERATOR_MULT, op1, op2);
876
    }
877

    
878
    @Override
879
    public Code div(Code op1, Code op2) {
880
        return operator(OPERATOR_DIV, op1, op2);
881
    }
882

    
883
    @Override
884
    public Code mod(Code op1, Code op2) {
885
        BaseCodes args = args();
886
        args.add(op1);
887
        args.add(op2);
888
        return function(FUNCTION_MOD, args);
889
    }
890

    
891
    @Override
892
    public Code or(Code op1, Code op2) {
893
        return operator(OPERATOR_OR, op1, op2);
894
    }
895

    
896
    @Override
897
    public Code and(Code op1, Code op2) {
898
        return operator(OPERATOR_AND, op1, op2);
899
    }
900

    
901
    @Override
902
    public Code like(Code op1, Code op2) {
903
        return operator(OPERATOR_LIKE, op1, op2);
904
    }
905

    
906
    @Override
907
    public Code ilike(Code op1, Code op2) {
908
        return operator(OPERATOR_ILIKE, op1, op2);
909
    }
910

    
911
    @Override
912
    public Code regexp(Code op1, Code op2) {
913
        return operator(OPERATOR_REGEXP, op1, op2);
914
    }
915

    
916
    @Override
917
    public Code lt(Code op1, Code op2) {
918
        return operator(OPERATOR_LT, op1, op2);
919
    }
920

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

    
926
    @Override
927
    public Code le(Code op1, Code op2) {
928
        return operator(OPERATOR_LE, op1, op2);
929
    }
930

    
931
    @Override
932
    public Code ge(Code op1, Code op2) {
933
        return operator(OPERATOR_GE, op1, op2);
934
    }
935

    
936
    @Override
937
    public Code eq(Code op1, Code op2) {
938
        return operator(OPERATOR_EQ, op1, op2);
939
    }
940

    
941
    @Override
942
    public Code ne(Code op1, Code op2) {
943
        return operator(OPERATOR_NE, op1, op2);
944
    }
945

    
946
    @Override
947
    public Code is(Code op1, Code op2) {
948
        return operator(OPERATOR_IS, op1, op2);
949
    }
950

    
951
    @Override
952
    public Code getattr(Code obj, String attrname) {
953
        BaseCodes args = args();
954
        args.add(obj);
955
        args.add(constant(attrname));
956
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
957
    }    
958

    
959
    @Override
960
    public Code getitem(Code obj, Code index) {
961
        BaseCodes args = args();
962
        args.add(obj);
963
        args.add(index);
964
        return function(FUNCTION_GETITEM, args);
965
    }
966

    
967
    @Override
968
    public Code dict(Map<String,Code>map ) {
969
        BaseCodes args = args();
970
        for (Map.Entry<String, Code> entry : map.entrySet()) {
971
            String key = entry.getKey();
972
            Code value = entry.getValue();
973
            args.add(constant(key));
974
            args.add(value);
975
        }
976
        return function(FUNCTION_DICT, args);
977
    }
978
    
979
}