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

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

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

    
61
    public abstract class BaseCode implements Code {
62

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

    
68
        @Override
69
        public void accept(Visitor visitor) throws BaseException {
70
            visitor.visit(this);
71
        }
72

    
73
        @Override
74
        public Value toValue(ExpressionBuilder builder) {
75
            return null;
76
        }
77

    
78
        @Override
79
        public Value toValue() {
80
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
81
            return this.toValue(builder);
82
        }
83
        
84
        @Override
85
        public void link(SymbolTable symbolTable) {
86
            if( this.code() == Code.CALLER ) {
87
                Caller caller = (Caller) this;
88
                Function fn = symbolTable.function(caller.name());
89
                if( fn != null ) {
90
                    caller.function(fn);
91
                }
92
                if( caller.parameters() != null ) {
93
                    for( Code arg : caller.parameters() ) {
94
                        if( arg!=null ) {
95
                          arg.link(symbolTable);
96
                        }
97
                    }
98
                }
99
            }
100
        }
101
    }
102

    
103
    class BaseConstant extends BaseCode implements Constant {
104

    
105
        private Object value;
106

    
107
        public BaseConstant(Object value) {
108
            this.value = value;
109
        }
110

    
111
        @Override
112
        public int code() {
113
            return CONSTANT;
114
        }
115

    
116
        @Override
117
        public Object value() {
118
            return this.value;
119
        }
120

    
121
        public void value(Object v) {
122
            this.value = v;
123
        }
124

    
125
        @Override
126
        public Value toValue(ExpressionBuilder builder) {
127
            return builder.constant(this.value);
128
        }
129

    
130
        @Override
131
        public String toString() {
132
            return this.toString(EMPTY_FORMATTER);
133
        }
134
        
135
        @Override
136
        public String toString(Formatter<Code> formatter) {
137
            if( formatter.canApply(this) ) {
138
                return formatter.format(this);
139
            }
140
            Object v = this.value();
141
            return manager.getReprMethod(v).repr(v);
142
        }
143

    
144
    }
145

    
146
    public interface RecursionControlSupport {
147
        
148
        public boolean enterCode(int max);
149
        
150
        public void exitCode();
151
        
152
        public void resetRecursionState();
153
    }
154
    
155
    private class RecursionSupport implements RecursionControlSupport {
156
    
157
        private int counter;
158
        
159
        public RecursionSupport() {
160
            this.counter = 0;
161
        }
162

    
163
        @Override
164
        public boolean enterCode(int max) {
165
            this.counter += 1;
166
            return this.counter < max;
167
        }
168

    
169
        @Override
170
        public void exitCode() {
171
            this.counter -= 1;
172
        }
173

    
174
        @Override
175
        public void resetRecursionState() {
176
            this.counter = 0;
177
        }
178
        
179
    }
180
    
181
    public class BaseIdentifier extends BaseCode implements Identifier, RecursionControlSupport {
182

    
183
        private final String name;
184
        private final RecursionSupport recursionSupport;
185

    
186
        public BaseIdentifier(String name) {
187
            this.name = name;
188
            this.recursionSupport = new RecursionSupport();
189
        }
190

    
191
        @Override
192
        public int code() {
193
            return IDENTIFIER;
194
        }
195

    
196
        @Override
197
        public String name() {
198
            return this.name;
199
        }
200

    
201
        @Override
202
        public Value toValue(ExpressionBuilder builder) {
203
            return builder.variable(this.name);
204
        }
205

    
206
        @Override
207
        public String toString() {
208
            return this.toString(EMPTY_FORMATTER);
209
        }
210
        
211
        @Override
212
        public String toString(Formatter<Code> formatter) {
213
            if( formatter.canApply(this) ) {
214
                return formatter.format(this);
215
            }
216
            StringBuilder builder = new StringBuilder();
217
            builder.append("\"");
218
            builder.append(this.name());
219
            builder.append("\"");
220
            return builder.toString();
221
        }
222

    
223
        @Override
224
        public boolean enterCode(int max) {
225
            return this.recursionSupport.enterCode(max);
226
        }
227

    
228
        @Override
229
        public void exitCode() {
230
            this.recursionSupport.exitCode();
231
        }
232

    
233
        @Override
234
        public void resetRecursionState() {
235
            this.recursionSupport.resetRecursionState();
236
        }
237

    
238
    }
239

    
240
    public class BaseCodes implements Codes {
241

    
242
        private final List<Pair<String,Code>> codes;
243
        private boolean useNames;
244

    
245
        public BaseCodes() {
246
            this.codes = new ArrayList<>();
247
            this.useNames = false;
248
        }
249

    
250
        @Override
251
        public boolean useArgNames() {
252
          return this.useNames;
253
        }
254

    
255
        @Override
256
        public boolean useArgNames(boolean useNames) {
257
          this.useNames = useNames;
258
          return this.useNames;
259
        }
260
        
261
        @Override
262
        public int code() {
263
            return CODES;
264
        }
265
        
266
        @Override
267
        public int size() {
268
            if( codes == null ) {
269
                return 0;
270
            }
271
            return this.codes.size();
272
        }
273

    
274
        public void add(String name, Code parameter) {
275
          if( !StringUtils.isBlank(name) ) {
276
            for (int i = 0; i < codes.size(); i++) {
277
              Pair<String, Code> arg = codes.get(i);
278
              if( StringUtils.equalsIgnoreCase(name, arg.getKey()) ) {
279
                codes.set(i, new ImmutablePair<>(name, parameter));
280
                return;
281
              }              
282
            }
283
          }
284
          this.codes.add(new ImmutablePair<>(name, parameter));
285
        }
286

    
287
        public void add(Code arg) {
288
            this.codes.add(new ImmutablePair<>(null, arg));
289
        }
290

    
291
        public void insert(int pos, Code arg) {
292
            this.codes.add(pos, new ImmutablePair<>(null, arg));
293
        }
294

    
295
        @Override
296
        public boolean contains(String name) {
297
          for (Pair<String, Code> arg : this.codes) {
298
            if( StringUtils.equalsIgnoreCase(arg.getKey(), name) ) {
299
              return true;
300
            }
301
          }
302
          return false;
303
        }
304
        
305
        @Override
306
        public boolean contains(String name, int index) {
307
          String argNameX = name + String.valueOf(index).trim();
308
          for (Pair<String, Code> arg : this.codes) {
309
            if( StringUtils.equalsIgnoreCase(arg.getKey(), argNameX) ) {
310
              return true;
311
            }
312
          }
313
          return false;
314
        }
315
        
316
        @Override
317
        public Iterator<Code> iterator() {
318
          final Iterator<Pair<String, Code>> it = this.codes.iterator();
319
          return new Iterator<Code>() {
320
            @Override
321
            public boolean hasNext() {
322
              return it.hasNext();
323
            }
324

    
325
            @Override
326
            public Code next() {
327
              Pair<String, Code> arg = it.next();
328
              return arg.getValue();
329
            }
330
          };
331
        }
332

    
333
        @Override
334
        public Code get(int n) {
335
            return this.codes.get(n).getValue();
336
        }
337

    
338
        @Override
339
        public Code get(String name) {
340
          for (Pair<String, Code> arg : this.codes) {
341
            if( StringUtils.equalsIgnoreCase(name, arg.getKey()) ) {
342
              return arg.getValue();
343
            }
344
          }
345
          return null;
346
        }
347

    
348
        @Override
349
        public String getName(int n) {
350
            return this.codes.get(n).getKey();
351
        }
352

    
353
        @Override
354
        public boolean isEmpty() {
355
            return this.codes.isEmpty();
356
        }
357

    
358
        @Override
359
        public List<Code> toList() {
360
            List<Code> l = new ArrayList<>();
361
            for (Pair<String, Code> arg : this.codes) {
362
              l.add(arg.getValue());
363
            }
364
            return Collections.unmodifiableList(l);
365
        }
366

    
367
        @Override
368
        public void accept(Visitor visitor) throws BaseException {
369
            for( Pair<String,Code> arg : this.codes ) {
370
                arg.getValue().accept(visitor);
371
            }
372
        }
373

    
374
        @Override
375
        public String toString() {
376
            return this.toString(EMPTY_FORMATTER);
377
        }
378
        
379
        @Override
380
        public Value toValue(ExpressionBuilder builder) {
381
            throw new UnsupportedOperationException();
382
        }
383

    
384
        @Override
385
        public Value toValue() {
386
            throw new UnsupportedOperationException();
387
        }
388

    
389
        @Override
390
        public String toString(Formatter<Code> formatter) {
391
            if( formatter.canApply(this) ) {
392
                return formatter.format(this);
393
            }
394
            if( codes != null ) {
395
                StringBuilder builder = new StringBuilder();
396
                boolean skipcoma = true;
397
                for( Pair<String, Code> arg : codes ) {
398
                    if( arg == null ) {
399
                      continue;
400
                    }
401
                    String name = arg.getKey();
402
                    Code code = arg.getValue();
403
                    if( code == null ) {
404
                        continue;
405
                    }
406
                    if( skipcoma ) {
407
                        skipcoma = false;
408
                    } else {
409
                        builder.append(", ");
410
                    }
411
                    if( name==null || !useNames ) {
412
                        builder.append(code.toString(formatter));
413
                    } else {
414
                        builder.append(name);
415
                        builder.append(":");
416
                        builder.append(code.toString(formatter));
417
                    }
418
                }
419
                return builder.toString();
420
            }
421
            return "";
422
        }
423

    
424
        @Override
425
        public void link(SymbolTable symbolTable) {
426
            for (Pair<String,Code> arg : this.codes) {
427
                arg.getValue().link(symbolTable);
428
            }
429
        }
430

    
431
    }
432

    
433
    public class BaseCaller extends BaseCode implements Caller, RecursionControlSupport {
434

    
435
        private final String name;
436
        private final Codes args;
437
        private Function function;
438
        private final int type;
439
        private final RecursionSupport recursionSupport;
440

    
441
        public BaseCaller(String name, int type, Codes args) {
442
            this.name = name;
443
            this.args = args;
444
            this.type = type;
445
            this.function = null;
446
            this.recursionSupport = new RecursionSupport();
447
        }
448

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

    
454
        @Override
455
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
456
            return this.function.call(interpreter, args);
457
        }
458

    
459
        @Override
460
        public String name() {
461
            return this.name;
462
        }
463

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

    
469
        @Override
470
        public Function function(Function function) {
471
            this.function = function;
472
            if( this.args!=null && this.function!=null ) {
473
              this.args.useArgNames(this.function.allowArgNames());
474
            }
475
            return this.function;
476
        }
477

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

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

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

    
496
        @Override
497
        public Value toValue(ExpressionBuilder builder) {
498
            switch(this.type) {
499
                case UNARY_OPERATOR:
500
                    return builder.function(
501
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
502
                                "-" :
503
                                this.name(),
504
                            this.parameters().get(0).toValue(builder)
505
                    );
506
                case BINARY_OPERATOR:
507
                    return builder.binaryOperator(
508
                            this.name(),
509
                            this.parameters().get(0).toValue(builder),
510
                            this.parameters().get(1).toValue(builder)
511
                    );
512
                case FUNCTION:
513
                default:
514
                    ExpressionBuilder.Function f = builder.function(this.name());
515
                    if( this.parameters()!=null ) {
516
                        for (Code parameter : this.parameters()) {
517
                            f.parameter(parameter.toValue(builder));
518
                        }
519
                        
520
                    }
521
                    return f;
522

    
523
            }
524
        }
525

    
526
        @Override
527
        public String toString() {
528
            return this.toString(EMPTY_FORMATTER);
529
        }
530
        
531
        @Override
532
        public String toString(Formatter<Code> formatter) {
533
            if( formatter.canApply(this) ) {
534
                return formatter.format(this);
535
            }
536
            Code code;
537
            StringBuilder builder = new StringBuilder();
538
            switch(this.type) {
539
                case UNARY_OPERATOR:
540
                    if( OPERATOR_NEGATE.equalsIgnoreCase(this.name()) ) {
541
                        builder.append("-");
542
                    } else {
543
                        builder.append(this.name());
544
                    }
545
                    builder.append("(");
546
                    builder.append(this.parameters().get(0).toString(formatter));
547
                    builder.append(")");
548
                    break;
549
                case BINARY_OPERATOR:
550
                    builder.append("(");
551
                    code = this.parameters().get(0);
552
                    if( code == null ) {                    
553
                        builder.append("?NULL?");
554
                    } else {
555
                        builder.append(code.toString(formatter));
556
                    }
557
                    builder.append(" ");
558
                    builder.append(this.name());
559
                    builder.append(" ");
560
                    code = this.parameters().get(1);
561
                    if( code == null ) {                    
562
                        builder.append("?NULL?");
563
                    } else {
564
                        builder.append(code.toString(formatter));
565
                    }
566
                    builder.append(")");
567
                    break;
568
                case FUNCTION:
569
                default:
570
                    if( StringUtils.equalsIgnoreCase(this.name(),ExpressionBuilder.FUNCTION_GETATTR) ) {
571
                      Code arg0 = this.parameters().get(0);
572
                      Code arg1 = this.parameters().get(1);
573
                      if( arg0 instanceof Code.Identifier && arg1 instanceof Code.Constant ) {
574
                        builder.append(arg0.toString(formatter));
575
                        builder.append(".\"");
576
                        builder.append(((Code.Constant)arg1).value());
577
                        builder.append("\"");
578
                      } else {
579
                        builder.append(this.name());
580
                        builder.append("(");
581
                        builder.append(arg0.toString(formatter));
582
                        builder.append(", ");
583
                        builder.append(arg1.toString(formatter));
584
                        builder.append(")");
585
                      }
586
                    } else {
587
                      builder.append(this.name());
588
                      builder.append("(");
589
                      if( this.parameters()!=null ) {
590
                          builder.append(this.parameters().toString(formatter));
591
                      }
592
                      builder.append(")");
593
                    }
594
            }
595
            return builder.toString();
596
        }
597

    
598
        @Override
599
        public boolean enterCode(int max) {
600
            return this.recursionSupport.enterCode(max);
601
        }
602

    
603
        @Override
604
        public void exitCode() {
605
            this.recursionSupport.exitCode();
606
        }
607

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

    
614
    public class BaseMethod extends BaseCode implements Method {
615

    
616
        private final Code instance;
617
        private final String methodname;
618
        private final Codes args;
619
        
620
        public BaseMethod(Code instance, String methodname, Codes args) {
621
            this.instance = instance;
622
            this.methodname = methodname;
623
            this.args = args;
624
        }
625

    
626
        @Override
627
        public int code() {
628
            return METHOD;
629
        }
630
        
631
        @Override
632
        public String methodname() {
633
            return this.methodname;
634
        }
635

    
636
        @Override
637
        public Code instance() {
638
            return this.instance;
639
        }
640

    
641
        @Override
642
        public Codes parameters() {
643
            return this.args;
644
        }
645

    
646
        @Override
647
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
648
            Object theInstance = interpreter.run(instance);
649
            if( theInstance instanceof SimpleScript ) {
650
                try {
651
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
652
                } catch(NoSuchMethodException ex) {
653
                    // Ignore... continue calling instance method
654
                }                
655
            } else if( theInstance instanceof DynObject ) {
656
                DynObject dynobj = (DynObject) theInstance;
657
                try {
658
                    return dynobj.invokeDynMethod(methodname, args);
659
                } catch(DynMethodNotSupportedException ex) {
660
                    // Ignore... continue calling instance method
661
                }
662
            }
663
            return InstanceUtils.callmethod(theInstance, methodname, args);
664
        }
665

    
666
        @Override
667
        public String toString() {
668
            return this.toString(EMPTY_FORMATTER);
669
        }
670

    
671
        @Override
672
        public Value toValue(ExpressionBuilder builder) {
673
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
674
            if( this.parameters()!=null ) {
675
                for (Code parameter : this.parameters()) {
676
                    m.parameter(parameter.toValue(builder));
677
                }
678
            }
679
            return m;
680
        }
681

    
682
        @Override
683
        public String toString(Formatter<Code> formatter) {
684
            if( formatter.canApply(this) ) {
685
                return formatter.format(this);
686
            }
687
            StringBuilder builder = new StringBuilder();
688
            builder.append(this.instance.toString(formatter));
689
            builder.append("->");
690
            builder.append(this.methodname());
691
            builder.append("(");
692
            if( this.parameters()!=null ) {
693
                builder.append(this.parameters().toString(formatter));
694
            }
695
            builder.append(")");
696
            return builder.toString();
697
        }
698
        
699
        
700
    }    
701

    
702
    protected ExpressionEvaluatorManager manager;
703
    
704
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
705
        this.manager = manager;
706
    }
707
    
708
    @Override
709
    public CodeBuilder clone() throws CloneNotSupportedException {
710
        // This implementation of CodeBuilder does not maintain state, so 
711
        // we only call the super class.
712
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
713
        return other;
714
    }
715

    
716
    @Override
717
    public Constant constant(Object value) {
718
        return new BaseConstant(value);
719
    }
720

    
721
    @Override
722
    public Identifier identifier(String name) {
723
        return new BaseIdentifier(name);
724
    }
725

    
726
    @Override
727
    public BaseCodes args() {
728
        return new BaseCodes();
729
    }
730

    
731
    @Override
732
    public Caller function(String name, int type, Codes args) {
733
        return new BaseCaller(name, type, args);
734
    }
735

    
736
    @Override
737
    public Caller function(String name, Codes args) {
738
        return function(name, Caller.FUNCTION, args);
739
    }
740
    
741
    @Override
742
    public Code method(Code instance, String methodname, Codes methodargs) {
743
        Method m = new BaseMethod(instance, methodname, methodargs);
744
        return m;
745
    }
746
    
747
    @Override
748
    public Caller operator(String name, Code arg1) {
749
        BaseCodes args = args();
750
        args.add(arg1);
751
        return function(name, Caller.UNARY_OPERATOR, args);
752
    }
753

    
754
    @Override
755
    public Caller operator(String name, Code arg1, Code arg2) {
756
        BaseCodes args = args();
757
        args.add(arg1);
758
        args.add(arg2);
759
        return function(name, Caller.BINARY_OPERATOR, args);
760
    }
761
    
762
    @Override
763
    public Code not(Code op1) {
764
        return operator(OPERATOR_NOT, op1);
765
    }
766

    
767
    @Override
768
    public Code negate(Code op1) {
769
        return operator(OPERATOR_NEGATE, op1);
770
    }
771

    
772
    @Override
773
    public Code concat(Code op1, Code op2) {
774
        return operator(OPERATOR_CONCAT, op1, op2);
775
    }
776

    
777
    @Override
778
    public Code add(Code op1, Code op2) {
779
        return operator(OPERATOR_ADD, op1, op2);
780
    }
781

    
782
    @Override
783
    public Code subst(Code op1, Code op2) {
784
        return operator(OPERATOR_SUBST, op1, op2);
785
    }
786

    
787
    @Override
788
    public Code mult(Code op1, Code op2) {
789
        return operator(OPERATOR_MULT, op1, op2);
790
    }
791

    
792
    @Override
793
    public Code div(Code op1, Code op2) {
794
        return operator(OPERATOR_DIV, op1, op2);
795
    }
796

    
797
    @Override
798
    public Code mod(Code op1, Code op2) {
799
        return operator(OPERATOR_MOD, op1, op2);
800
    }
801

    
802
    @Override
803
    public Code or(Code op1, Code op2) {
804
        return operator(OPERATOR_OR, op1, op2);
805
    }
806

    
807
    @Override
808
    public Code and(Code op1, Code op2) {
809
        return operator(OPERATOR_AND, op1, op2);
810
    }
811

    
812
    @Override
813
    public Code like(Code op1, Code op2) {
814
        return operator(OPERATOR_LIKE, op1, op2);
815
    }
816

    
817
    @Override
818
    public Code ilike(Code op1, Code op2) {
819
        return operator(OPERATOR_ILIKE, op1, op2);
820
    }
821

    
822
    @Override
823
    public Code regexp(Code op1, Code op2) {
824
        return operator(OPERATOR_REGEXP, op1, op2);
825
    }
826

    
827
    @Override
828
    public Code lt(Code op1, Code op2) {
829
        return operator(OPERATOR_LT, op1, op2);
830
    }
831

    
832
    @Override
833
    public Code gt(Code op1, Code op2) {
834
        return operator(OPERATOR_GT, op1, op2);
835
    }
836

    
837
    @Override
838
    public Code le(Code op1, Code op2) {
839
        return operator(OPERATOR_LE, op1, op2);
840
    }
841

    
842
    @Override
843
    public Code ge(Code op1, Code op2) {
844
        return operator(OPERATOR_GE, op1, op2);
845
    }
846

    
847
    @Override
848
    public Code eq(Code op1, Code op2) {
849
        return operator(OPERATOR_EQ, op1, op2);
850
    }
851

    
852
    @Override
853
    public Code ne(Code op1, Code op2) {
854
        return operator(OPERATOR_NE, op1, op2);
855
    }
856

    
857
    @Override
858
    public Code is(Code op1, Code op2) {
859
        return operator(OPERATOR_IS, op1, op2);
860
    }
861

    
862
    @Override
863
    public Code getattr(Code obj, String attrname) {
864
        BaseCodes args = args();
865
        args.add(obj);
866
        args.add(constant(attrname));
867
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
868
    }    
869

    
870
    @Override
871
    public Code getitem(Code obj, Code index) {
872
        BaseCodes args = args();
873
        args.add(obj);
874
        args.add(index);
875
        return function(GetitemFunction.NAME, args);
876
    }
877

    
878
    
879
    
880
}