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

History | View | Annotate | Download (27 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 org.gvsig.expressionevaluator.Code;
9
import static org.gvsig.expressionevaluator.Code.CONSTANT;
10
import static org.gvsig.expressionevaluator.Code.IDENTIFIER;
11
import static org.gvsig.expressionevaluator.Code.UNDEFINED;
12
import static org.gvsig.expressionevaluator.Code.CODES;
13
import org.gvsig.expressionevaluator.Code.Constant;
14
import static org.gvsig.expressionevaluator.Code.EMPTY_FORMATTER;
15
import org.gvsig.expressionevaluator.Code.Identifier;
16
import org.gvsig.expressionevaluator.Code.Method;
17
//import org.gvsig.expressionevaluator.Code.Method;
18
import org.gvsig.expressionevaluator.CodeBuilder;
19
import org.gvsig.expressionevaluator.Codes;
20
import org.gvsig.expressionevaluator.ExpressionBuilder;
21
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_TUPLE;
22
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ADD;
23
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_AND;
24
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_CONCAT;
25
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_DIV;
26
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_EQ;
27
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GE;
28
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GT;
29
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ILIKE;
30
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_IS;
31
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LE;
32
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LIKE;
33
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LT;
34
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_MULT;
35
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NE;
36
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NEGATE;
37
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NOT;
38
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_OR;
39
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_REGEXP;
40
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_SUBST;
41
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
42
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
43
import org.gvsig.expressionevaluator.ExpressionUtils;
44
import org.gvsig.expressionevaluator.Formatter;
45
import org.gvsig.expressionevaluator.Function;
46
import org.gvsig.expressionevaluator.Interpreter;
47
import org.gvsig.expressionevaluator.SymbolTable;
48
import org.gvsig.tools.dynobject.DynObject;
49
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
50
import org.gvsig.tools.exception.BaseException;
51
import org.gvsig.tools.visitor.Visitor;
52
import static org.gvsig.expressionevaluator.Code.CALLABLE;
53
import org.gvsig.expressionevaluator.Code.Callable;
54
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_DICT;
55
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETITEM;
56
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_LET;
57
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_MOD;
58

    
59
@SuppressWarnings("UseSpecificCatch")
60
public class DefaultCodeBuilder implements CodeBuilder {
61

    
62
    public static abstract class BaseCode implements Code {
63

    
64
        @Override
65
        public int code() {
66
            return UNDEFINED;
67
        }
68

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

    
80
        @Override
81
        public Value toValue(ExpressionBuilder builder) {
82
            return null;
83
        }
84

    
85
        @Override
86
        public Value toValue() {
87
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
88
            return this.toValue(builder);
89
        }
90
        
91
        @Override
92
        public void link(SymbolTable symbolTable) {
93
            if( this.code() == Code.CALLABLE ) {
94
                Callable caller = (Callable) this;
95
                Function fn = symbolTable.function(caller.name());
96
                if( fn != null ) {
97
                    caller.function(fn);
98
                }
99
                if( caller.parameters() != null ) {
100
                    for( Code arg : caller.parameters() ) {
101
                        if( arg!=null ) {
102
                          arg.link(symbolTable);
103
                        }
104
                    }
105
                }
106
            }
107
        }
108
        
109
        @Override
110
        public void replace(Code target, Code replacement) {
111
        }
112
        
113
        
114
    }
115

    
116
    static class BaseConstant extends BaseCode implements Constant {
117

    
118
        private Object value;
119
        private final ExpressionEvaluatorManager manager;
120

    
121
        public BaseConstant(ExpressionEvaluatorManager manager, Object value) {
122
            this.manager = manager;
123
            this.value = value;
124
        }
125

    
126
        @Override
127
        public Code clone() throws CloneNotSupportedException {
128
            return (Code) super.clone();
129
        }
130

    
131
        @Override
132
        public int code() {
133
            return CONSTANT;
134
        }
135

    
136
        @Override
137
        public Object value() {
138
            return this.value;
139
        }
140

    
141
        public void value(Object v) {
142
            this.value = v;
143
        }
144

    
145
        @Override
146
        public Value toValue(ExpressionBuilder builder) {
147
            return builder.constant(this.value);
148
        }
149

    
150
        @Override
151
        public String toString() {
152
            return this.toString(EMPTY_FORMATTER);
153
        }
154
        
155
        @Override
156
        public String toString(Formatter<Code> formatter) {
157
            if( formatter.canApply(this) ) {
158
                return formatter.format(this);
159
            }
160
            Object v = this.value();
161
            return manager.getReprMethod(v).repr(v);
162
        }
163

    
164
    }
165

    
166
    public interface RecursionControlSupport {
167
        
168
        public boolean enterCode(int max);
169
        
170
        public void exitCode();
171
        
172
        public void resetRecursionState();
173
    }
174
    
175
    private static class RecursionSupport implements RecursionControlSupport, Cloneable {
176
    
177
        private int counter;
178
        
179
        public RecursionSupport() {
180
            this.counter = 0;
181
        }
182

    
183
        @Override
184
        public RecursionControlSupport clone() throws CloneNotSupportedException {
185
            RecursionControlSupport x = (RecursionControlSupport) super.clone();
186
            return x;
187
        }
188

    
189
        @Override
190
        public boolean enterCode(int max) {
191
            this.counter += 1;
192
            return this.counter < max;
193
        }
194

    
195
        @Override
196
        public void exitCode() {
197
            this.counter -= 1;
198
        }
199

    
200
        @Override
201
        public void resetRecursionState() {
202
            this.counter = 0;
203
        }
204
        
205
    }
206
    
207
    public static class BaseIdentifier extends BaseCode implements Identifier, RecursionControlSupport {
208

    
209
        private final String name;
210
        private final RecursionSupport recursionSupport;
211

    
212
        public BaseIdentifier(String name) {
213
            this.name = name;
214
            this.recursionSupport = new RecursionSupport();
215
        }
216

    
217
        @Override
218
        public Code clone() throws CloneNotSupportedException {
219
            return (Code) super.clone();
220
        }
221

    
222
        @Override
223
        public int code() {
224
            return IDENTIFIER;
225
        }
226

    
227
        @Override
228
        public String name() {
229
            return this.name;
230
        }
231

    
232
        @Override
233
        public Value toValue(ExpressionBuilder builder) {
234
            return builder.variable(this.name);
235
        }
236

    
237
        @Override
238
        public String toString() {
239
            return this.toString(EMPTY_FORMATTER);
240
        }
241
        
242
        @Override
243
        public String toString(Formatter<Code> formatter) {
244
            if( formatter.canApply(this) ) {
245
                return formatter.format(this);
246
            }
247
            StringBuilder builder = new StringBuilder();
248
            builder.append("\"");
249
            builder.append(this.name());
250
            builder.append("\"");
251
            return builder.toString();
252
        }
253

    
254
        @Override
255
        public boolean enterCode(int max) {
256
            return this.recursionSupport.enterCode(max);
257
        }
258

    
259
        @Override
260
        public void exitCode() {
261
            this.recursionSupport.exitCode();
262
        }
263

    
264
        @Override
265
        public void resetRecursionState() {
266
            this.recursionSupport.resetRecursionState();
267
        }
268

    
269
    }
270

    
271
    public static class BaseCodes implements Codes {
272

    
273
        private List<Code> codes;
274

    
275
        public BaseCodes() {
276
            this.codes = new ArrayList<>();
277
        }
278

    
279
        @Override
280
        public Codes clone() throws CloneNotSupportedException {
281
            BaseCodes x = (BaseCodes)super.clone();
282
            x.codes = new ArrayList<>();
283
            for (int i = 0; i < this.codes.size(); i++) {
284
                x.add(this.codes.get(i).clone());
285
            }
286
            return x;
287
        }
288

    
289
        @Override
290
        public int code() {
291
            return CODES;
292
        }
293
        
294
        @Override
295
        public int size() {
296
            if( codes == null ) {
297
                return 0;
298
            }
299
            return this.codes.size();
300
        }
301

    
302
        public void add(Code arg) {
303
            this.codes.add(arg);
304
        }
305

    
306
        public void set(int pos, Code arg) {
307
            this.codes.set(pos, arg);
308
        }
309

    
310
        public void insert(int pos, Code arg) {
311
            this.codes.add(pos, arg);
312
        }
313

    
314
        @Override
315
        public Iterator<Code> iterator() {
316
          final Iterator<Code> it = this.codes.iterator();
317
          return it;
318
        }
319

    
320
        @Override
321
        public Code get(int n) {
322
            return this.codes.get(n);
323
        }
324

    
325
        @Override
326
        public boolean isEmpty() {
327
            return this.codes.isEmpty();
328
        }
329

    
330
        @Override
331
        public List<Code> toList() {
332
            return Collections.unmodifiableList(this.codes);
333
        }
334

    
335
        @Override
336
        public void accept(Visitor visitor) throws BaseException {
337
            for( Code arg : this.codes ) {
338
                if(arg!=null) {
339
                    arg.accept(visitor);
340
                }
341
            }
342
        }
343

    
344
        @Override
345
        public String toString() {
346
            return this.toString(EMPTY_FORMATTER);
347
        }
348
        
349
        @Override
350
        public Value toValue(ExpressionBuilder builder) {
351
            throw new UnsupportedOperationException();
352
        }
353

    
354
        @Override
355
        public Value toValue() {
356
            throw new UnsupportedOperationException();
357
        }
358

    
359
        @Override
360
        public String toString(Formatter<Code> formatter) {
361
            if( formatter.canApply(this) ) {
362
                return formatter.format(this);
363
            }
364
            if( codes != null ) {
365
                StringBuilder builder = new StringBuilder();
366
                boolean skipcoma = true;
367
                for( Code arg : codes ) {
368
                    if( arg == null ) {
369
                      continue;
370
                    }
371
                    if( skipcoma ) {
372
                        skipcoma = false;
373
                    } else {
374
                        builder.append(", ");
375
                    }
376
                    builder.append(arg.toString(formatter));
377
                }
378
                return builder.toString();
379
            }
380
            return "";
381
        }
382

    
383
        @Override
384
        public void link(SymbolTable symbolTable) {
385
            for (Code arg : this.codes) {
386
                arg.link(symbolTable);
387
            }
388
        }
389

    
390
        @Override
391
        public void replace(Code target, Code replacement) {
392
            for (int i = 0; i < this.codes.size(); i++) {
393
                Code code = this.codes.get(i);
394
                if( code == target ) {
395
                    codes.set(i, replacement);
396
                } else {
397
                    code.replace(target, replacement);
398
                }
399
            }
400
        }
401
        
402
    }
403

    
404
    public class BaseCaller extends BaseCode implements Callable, RecursionControlSupport {
405

    
406
        private final String name;
407
        private Codes args;
408
        private Function function;
409
        private final int type;
410
        private RecursionSupport recursionSupport;
411

    
412
        public BaseCaller(String name, int type, Codes args) {
413
            this.name = name;
414
            this.args = args;
415
            this.type = type;
416
            this.function = null;
417
            this.recursionSupport = new RecursionSupport();
418
        }
419

    
420
        @Override
421
        public Code clone() throws CloneNotSupportedException {
422
            BaseCaller x = (BaseCaller) super.clone();
423
            x.recursionSupport = (RecursionSupport) this.recursionSupport.clone();
424
            x.args = this.args.clone();
425
            return x;
426
        }
427

    
428
        @Override
429
        public int code() {
430
            return CALLABLE;
431
        }
432

    
433
        @Override
434
        public void replace(Code target, Code replacement) {
435
            this.args.replace(target, replacement);
436
        }
437

    
438
        @Override
439
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
440
            return this.function.call(interpreter, args);
441
        }
442

    
443
        @Override
444
        public String name() {
445
            return this.name;
446
        }
447

    
448
        @Override
449
        public Function function() {
450
            return this.function;
451
        }
452

    
453
        @Override
454
        public Function function(Function function) {
455
            this.function = function;
456
            return this.function;
457
        }
458

    
459
        @Override
460
        public Codes parameters() {
461
            return this.args;
462
        }
463

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

    
469
        @Override
470
        public void accept(Visitor visitor) throws BaseException {
471
            visitor.visit(this);
472
            if(this.args!=null) {
473
                this.args.accept(visitor);
474
            }
475
        }
476

    
477
        @Override
478
        public Value toValue(ExpressionBuilder builder) {
479
            switch(this.type) {
480
                case UNARY_OPERATOR:
481
                    return builder.function(
482
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
483
                                "-" :
484
                                this.name(),
485
                            this.parameters().get(0).toValue(builder)
486
                    );
487
                case BINARY_OPERATOR:
488
                    return builder.binaryOperator(
489
                            this.name(),
490
                            this.parameters().get(0).toValue(builder),
491
                            this.parameters().get(1).toValue(builder)
492
                    );
493
                case FUNCTION:
494
                default:
495
                    ExpressionBuilder.Function f = builder.function(this.name());
496
                    if( this.parameters()!=null ) {
497
                        for (Code parameter : this.parameters()) {
498
                            if (parameter==null) { 
499
                                f.parameter(null);
500
                            } else {
501
                                f.parameter(parameter.toValue(builder));
502
                            }
503
                        }  
504
                    }
505
                    return f;
506

    
507
            }
508
        }
509

    
510
        @Override
511
        public String toString() {
512
            return this.toString(EMPTY_FORMATTER);
513
        }
514
        
515
        @Override
516
        public String toString(Formatter<Code> formatter) {
517
            if( formatter.canApply(this) ) {
518
                return formatter.format(this);
519
            }
520
            Code code;
521
            StringBuilder builder = new StringBuilder();
522
            switch(this.type) {
523
                case UNARY_OPERATOR:
524
                    if( OPERATOR_NEGATE.equalsIgnoreCase(this.name()) ) {
525
                        builder.append("-");
526
                    } else {
527
                        builder.append(this.name());
528
                    }
529
                    builder.append("(");
530
                    builder.append(this.parameters().get(0).toString(formatter));
531
                    builder.append(")");
532
                    break;
533
                case BINARY_OPERATOR:
534
                    builder.append("(");
535
                    code = this.parameters().get(0);
536
                    if( code == null ) {                    
537
                        builder.append("?NULL?");
538
                    } else {
539
                        builder.append(code.toString(formatter));
540
                    }
541
                    builder.append(" ");
542
                    builder.append(this.name());
543
                    builder.append(" ");
544
                    code = this.parameters().get(1);
545
                    if( code == null ) {                    
546
                        builder.append("?NULL?");
547
                    } else {
548
                        builder.append(code.toString(formatter));
549
                    }
550
                    builder.append(")");
551
                    break;
552
                case FUNCTION:
553
                default:
554
                    String s = null;
555
                    if( this.function()!=null ) {
556
                        s = this.function().toString(args, formatter);
557
                    }
558
                    if( s == null ) {
559
                        builder.append(this.name());
560
                        builder.append("(");
561
                        if( this.parameters()!=null ) {
562
                            builder.append(this.parameters().toString(formatter));
563
                        }
564
                        builder.append(")");
565
                    } else {
566
                        builder.append(s);
567
                    }
568
            }
569
            return builder.toString();
570
        }
571

    
572
        @Override
573
        public boolean enterCode(int max) {
574
            return this.recursionSupport.enterCode(max);
575
        }
576

    
577
        @Override
578
        public void exitCode() {
579
            this.recursionSupport.exitCode();
580
        }
581

    
582
        @Override
583
        public void resetRecursionState() {
584
            this.recursionSupport.resetRecursionState();
585
        }
586
    }
587

    
588
    public static class BaseMethod extends BaseCode implements Method {
589

    
590
        private Code instance;
591
        private final String methodname;
592
        private Codes args;
593
        
594
        public BaseMethod(Code instance, String methodname, Codes args) {
595
            this.instance = instance;
596
            this.methodname = methodname;
597
            this.args = args;
598
        }
599

    
600
        @Override
601
        public Code clone() throws CloneNotSupportedException {
602
            BaseMethod x = (BaseMethod) super.clone();
603
            x.args = this.args.clone();
604
            return x;
605
        }
606
        
607
        @Override
608
        public int code() {
609
            return METHOD;
610
        }
611
        
612
        @Override
613
        public void replace(Code target, Code replacement) {
614
            if( target == this.instance ) {
615
              this.instance = replacement;
616
            }
617
            this.args.replace(target, replacement);
618
        }
619

    
620
        @Override
621
        public String methodname() {
622
            return this.methodname;
623
        }
624

    
625
        @Override
626
        public Code instance() {
627
            return this.instance;
628
        }
629

    
630
        @Override
631
        public Codes parameters() {
632
            return this.args;
633
        }
634

    
635
        @Override
636
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
637
            Object theInstance = interpreter.run(instance);
638
            if( theInstance instanceof SimpleScript ) {
639
                try {
640
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
641
                } catch(NoSuchMethodException ex) {
642
                    // Ignore... continue calling instance method
643
                }                
644
            } else if( theInstance instanceof DynObject ) {
645
                DynObject dynobj = (DynObject) theInstance;
646
                try {
647
                    return dynobj.invokeDynMethod(methodname, args);
648
                } catch(DynMethodNotSupportedException ex) {
649
                    // Ignore... continue calling instance method
650
                }
651
            }
652
            return InstanceUtils.callmethod(theInstance, methodname, args);
653
        }
654

    
655
        @Override
656
        public String toString() {
657
            return this.toString(EMPTY_FORMATTER);
658
        }
659

    
660
        @Override
661
        public Value toValue(ExpressionBuilder builder) {
662
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
663
            if( this.parameters()!=null ) {
664
                for (Code parameter : this.parameters()) {
665
                    m.parameter(parameter.toValue(builder));
666
                }
667
            }
668
            return m;
669
        }
670

    
671
        @Override
672
        public String toString(Formatter<Code> formatter) {
673
            if( formatter.canApply(this) ) {
674
                return formatter.format(this);
675
            }
676
            StringBuilder builder = new StringBuilder();
677
            builder.append(this.instance.toString(formatter));
678
            builder.append("->");
679
            builder.append(this.methodname());
680
            builder.append("(");
681
            if( this.parameters()!=null ) {
682
                builder.append(this.parameters().toString(formatter));
683
            }
684
            builder.append(")");
685
            return builder.toString();
686
        }
687

    
688
        @Override
689
        public String name() {
690
            return this.methodname();
691
        }
692

    
693
        @Override
694
        public Function function() {
695
            return null;
696
        }
697

    
698
        @Override
699
        public Function function(Function function) {
700
            return null;
701
        }
702

    
703
        @Override
704
        public int type() {
705
            return Code.METHOD;
706
        }
707
        
708
        
709
    }    
710

    
711
    protected ExpressionEvaluatorManager manager;
712
    
713
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
714
        this.manager = manager;
715
    }
716
    
717
    @Override
718
    public CodeBuilder clone() throws CloneNotSupportedException {
719
        // This implementation of CodeBuilder does not maintain state, so 
720
        // we only call the super class.
721
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
722
        return other;
723
    }
724

    
725
    @Override
726
    public Constant constant(Object value) {
727
        return new BaseConstant(this.manager, value);
728
    }
729

    
730
    @Override
731
    public Identifier identifier(String name) {
732
        return new BaseIdentifier(name);
733
    }
734

    
735
    @Override
736
    public BaseCodes args() {
737
        return new BaseCodes();
738
    }
739

    
740
    @Override
741
    public Callable tuple() {
742
      BaseCodes args = this.args();
743
      return function(FUNCTION_TUPLE, args);
744
    }
745
    
746
    @Override
747
    public Callable tuple(Codes args) {
748
      if( args == null ) {
749
        args = this.args();
750
      }
751
      return function(FUNCTION_TUPLE, args);
752
    }
753

    
754
    @Override
755
    public Callable function(String name, int type, Codes args) {
756
        return new BaseCaller(name, type, args);
757
    }
758

    
759
    @Override
760
    public Callable function(String name, Codes args) {
761
        return function(name, Callable.FUNCTION, args);
762
    }
763
    
764
    @Override
765
    public Code method(Code instance, String methodname, Codes methodargs) {
766
        Method m = new BaseMethod(instance, methodname, methodargs);
767
        return m;
768
    }
769
    
770
    @Override
771
    public Callable operator(String name, Code arg1) {
772
        BaseCodes args = args();
773
        args.add(arg1);
774
        return function(name, Callable.UNARY_OPERATOR, args);
775
    }
776

    
777
    @Override
778
    public Callable operator(String name, Code arg1, Code arg2) {
779
        BaseCodes args = args();
780
        args.add(arg1);
781
        args.add(arg2);
782
        return function(name, Callable.BINARY_OPERATOR, args);
783
    }
784
    
785
    @Override
786
    public Code not(Code op1) {
787
        return operator(OPERATOR_NOT, op1);
788
    }
789

    
790
    @Override
791
    public Code negate(Code op1) {
792
        return operator(OPERATOR_NEGATE, op1);
793
    }
794

    
795
    @Override
796
    public Code concat(Code op1, Code op2) {
797
        return operator(OPERATOR_CONCAT, op1, op2);
798
    }
799

    
800
    @Override
801
    public Code let(String identifier, Code value) {
802
        BaseCodes args = args();
803
        args.add(this.constant(identifier));
804
        args.add(value);
805
        return function(FUNCTION_LET, Callable.FUNCTION, args);
806
    }
807

    
808
    @Override
809
    public Code add(Code op1, Code op2) {
810
        return operator(OPERATOR_ADD, op1, op2);
811
    }
812

    
813
    @Override
814
    public Code subst(Code op1, Code op2) {
815
        return operator(OPERATOR_SUBST, op1, op2);
816
    }
817

    
818
    @Override
819
    public Code mult(Code op1, Code op2) {
820
        return operator(OPERATOR_MULT, op1, op2);
821
    }
822

    
823
    @Override
824
    public Code div(Code op1, Code op2) {
825
        return operator(OPERATOR_DIV, op1, op2);
826
    }
827

    
828
    @Override
829
    public Code mod(Code op1, Code op2) {
830
        BaseCodes args = args();
831
        args.add(op1);
832
        args.add(op2);
833
        return function(FUNCTION_MOD, args);
834
    }
835

    
836
    @Override
837
    public Code or(Code op1, Code op2) {
838
        return operator(OPERATOR_OR, op1, op2);
839
    }
840

    
841
    @Override
842
    public Code and(Code op1, Code op2) {
843
        return operator(OPERATOR_AND, op1, op2);
844
    }
845

    
846
    @Override
847
    public Code like(Code op1, Code op2) {
848
        return operator(OPERATOR_LIKE, op1, op2);
849
    }
850

    
851
    @Override
852
    public Code ilike(Code op1, Code op2) {
853
        return operator(OPERATOR_ILIKE, op1, op2);
854
    }
855

    
856
    @Override
857
    public Code regexp(Code op1, Code op2) {
858
        return operator(OPERATOR_REGEXP, op1, op2);
859
    }
860

    
861
    @Override
862
    public Code lt(Code op1, Code op2) {
863
        return operator(OPERATOR_LT, op1, op2);
864
    }
865

    
866
    @Override
867
    public Code gt(Code op1, Code op2) {
868
        return operator(OPERATOR_GT, op1, op2);
869
    }
870

    
871
    @Override
872
    public Code le(Code op1, Code op2) {
873
        return operator(OPERATOR_LE, op1, op2);
874
    }
875

    
876
    @Override
877
    public Code ge(Code op1, Code op2) {
878
        return operator(OPERATOR_GE, op1, op2);
879
    }
880

    
881
    @Override
882
    public Code eq(Code op1, Code op2) {
883
        return operator(OPERATOR_EQ, op1, op2);
884
    }
885

    
886
    @Override
887
    public Code ne(Code op1, Code op2) {
888
        return operator(OPERATOR_NE, op1, op2);
889
    }
890

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

    
896
    @Override
897
    public Code getattr(Code obj, String attrname) {
898
        BaseCodes args = args();
899
        args.add(obj);
900
        args.add(constant(attrname));
901
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
902
    }    
903

    
904
    @Override
905
    public Code getitem(Code obj, Code index) {
906
        BaseCodes args = args();
907
        args.add(obj);
908
        args.add(index);
909
        return function(FUNCTION_GETITEM, args);
910
    }
911

    
912
    @Override
913
    public Code dict(Map<String,Code>map ) {
914
        BaseCodes args = args();
915
        for (Map.Entry<String, Code> entry : map.entrySet()) {
916
            String key = entry.getKey();
917
            Code value = entry.getValue();
918
            args.add(constant(key));
919
            args.add(value);
920
        }
921
        return function(FUNCTION_DICT, args);
922
    }
923
    
924
}