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

History | View | Annotate | Download (24.6 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7
import org.apache.commons.lang3.StringUtils;
8
import org.gvsig.expressionevaluator.Code;
9
import static org.gvsig.expressionevaluator.Code.CALLER;
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.Caller;
15
import org.gvsig.expressionevaluator.Code.Constant;
16
import static org.gvsig.expressionevaluator.Code.EMPTY_FORMATTER;
17
import org.gvsig.expressionevaluator.Code.Identifier;
18
import org.gvsig.expressionevaluator.Code.Method;
19
//import org.gvsig.expressionevaluator.Code.Method;
20
import org.gvsig.expressionevaluator.CodeBuilder;
21
import org.gvsig.expressionevaluator.Codes;
22
import org.gvsig.expressionevaluator.ExpressionBuilder;
23
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_TUPLE;
24
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ADD;
25
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_AND;
26
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_CONCAT;
27
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_DIV;
28
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_EQ;
29
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GE;
30
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GT;
31
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ILIKE;
32
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_IS;
33
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LE;
34
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LIKE;
35
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LT;
36
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_MOD;
37
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_MULT;
38
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NE;
39
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NEGATE;
40
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NOT;
41
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_OR;
42
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_REGEXP;
43
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_SUBST;
44
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
45
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
46
import org.gvsig.expressionevaluator.ExpressionUtils;
47
import org.gvsig.expressionevaluator.Formatter;
48
import org.gvsig.expressionevaluator.Function;
49
import org.gvsig.expressionevaluator.Interpreter;
50
import org.gvsig.expressionevaluator.SymbolTable;
51
import org.gvsig.expressionevaluator.impl.function.programming.GetitemFunction;
52
import org.gvsig.tools.dynobject.DynObject;
53
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
54
import org.gvsig.tools.exception.BaseException;
55
import org.gvsig.tools.visitor.Visitor;
56

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

    
60
    public abstract class BaseCode implements Code {
61

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

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

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

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

    
108
    class BaseConstant extends BaseCode implements Constant {
109

    
110
        private Object value;
111

    
112
        public BaseConstant(Object value) {
113
            this.value = value;
114
        }
115

    
116
        @Override
117
        public int code() {
118
            return CONSTANT;
119
        }
120

    
121
        @Override
122
        public Object value() {
123
            return this.value;
124
        }
125

    
126
        public void value(Object v) {
127
            this.value = v;
128
        }
129

    
130
        @Override
131
        public Value toValue(ExpressionBuilder builder) {
132
            return builder.constant(this.value);
133
        }
134

    
135
        @Override
136
        public String toString() {
137
            return this.toString(EMPTY_FORMATTER);
138
        }
139
        
140
        @Override
141
        public String toString(Formatter<Code> formatter) {
142
            if( formatter.canApply(this) ) {
143
                return formatter.format(this);
144
            }
145
            Object v = this.value();
146
            return manager.getReprMethod(v).repr(v);
147
        }
148

    
149
    }
150

    
151
    public interface RecursionControlSupport {
152
        
153
        public boolean enterCode(int max);
154
        
155
        public void exitCode();
156
        
157
        public void resetRecursionState();
158
    }
159
    
160
    private class RecursionSupport implements RecursionControlSupport {
161
    
162
        private int counter;
163
        
164
        public RecursionSupport() {
165
            this.counter = 0;
166
        }
167

    
168
        @Override
169
        public boolean enterCode(int max) {
170
            this.counter += 1;
171
            return this.counter < max;
172
        }
173

    
174
        @Override
175
        public void exitCode() {
176
            this.counter -= 1;
177
        }
178

    
179
        @Override
180
        public void resetRecursionState() {
181
            this.counter = 0;
182
        }
183
        
184
    }
185
    
186
    public class BaseIdentifier extends BaseCode implements Identifier, RecursionControlSupport {
187

    
188
        private final String name;
189
        private final RecursionSupport recursionSupport;
190

    
191
        public BaseIdentifier(String name) {
192
            this.name = name;
193
            this.recursionSupport = new RecursionSupport();
194
        }
195

    
196
        @Override
197
        public int code() {
198
            return IDENTIFIER;
199
        }
200

    
201
        @Override
202
        public String name() {
203
            return this.name;
204
        }
205

    
206
        @Override
207
        public Value toValue(ExpressionBuilder builder) {
208
            return builder.variable(this.name);
209
        }
210

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

    
228
        @Override
229
        public boolean enterCode(int max) {
230
            return this.recursionSupport.enterCode(max);
231
        }
232

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

    
238
        @Override
239
        public void resetRecursionState() {
240
            this.recursionSupport.resetRecursionState();
241
        }
242

    
243
    }
244

    
245
    public class BaseCodes implements Codes {
246

    
247
        private final List<Code> codes;
248

    
249
        public BaseCodes() {
250
            this.codes = new ArrayList<>();
251
        }
252

    
253
        @Override
254
        public int code() {
255
            return CODES;
256
        }
257
        
258
        @Override
259
        public int size() {
260
            if( codes == null ) {
261
                return 0;
262
            }
263
            return this.codes.size();
264
        }
265

    
266
        public void add(Code arg) {
267
            this.codes.add(arg);
268
        }
269

    
270
        public void set(int pos, Code arg) {
271
            this.codes.set(pos, arg);
272
        }
273

    
274
        public void insert(int pos, Code arg) {
275
            this.codes.add(pos, arg);
276
        }
277

    
278
        @Override
279
        public Iterator<Code> iterator() {
280
          final Iterator<Code> it = this.codes.iterator();
281
          return it;
282
        }
283

    
284
        @Override
285
        public Code get(int n) {
286
            return this.codes.get(n);
287
        }
288

    
289
        @Override
290
        public boolean isEmpty() {
291
            return this.codes.isEmpty();
292
        }
293

    
294
        @Override
295
        public List<Code> toList() {
296
            return Collections.unmodifiableList(this.codes);
297
        }
298

    
299
        @Override
300
        public void accept(Visitor visitor) throws BaseException {
301
            for( Code arg : this.codes ) {
302
                arg.accept(visitor);
303
            }
304
        }
305

    
306
        @Override
307
        public String toString() {
308
            return this.toString(EMPTY_FORMATTER);
309
        }
310
        
311
        @Override
312
        public Value toValue(ExpressionBuilder builder) {
313
            throw new UnsupportedOperationException();
314
        }
315

    
316
        @Override
317
        public Value toValue() {
318
            throw new UnsupportedOperationException();
319
        }
320

    
321
        @Override
322
        public String toString(Formatter<Code> formatter) {
323
            if( formatter.canApply(this) ) {
324
                return formatter.format(this);
325
            }
326
            if( codes != null ) {
327
                StringBuilder builder = new StringBuilder();
328
                boolean skipcoma = true;
329
                for( Code arg : codes ) {
330
                    if( arg == null ) {
331
                      continue;
332
                    }
333
                    if( skipcoma ) {
334
                        skipcoma = false;
335
                    } else {
336
                        builder.append(", ");
337
                    }
338
                    builder.append(arg.toString(formatter));
339
                }
340
                return builder.toString();
341
            }
342
            return "";
343
        }
344

    
345
        @Override
346
        public void link(SymbolTable symbolTable) {
347
            for (Code arg : this.codes) {
348
                arg.link(symbolTable);
349
            }
350
        }
351

    
352
        @Override
353
        public void replace(Code target, Code replacement) {
354
            for (int i = 0; i < this.codes.size(); i++) {
355
                Code code = this.codes.get(i);
356
                if( code == target ) {
357
                    codes.set(i, replacement);
358
                } else {
359
                    code.replace(target, replacement);
360
                }
361
            }
362
        }
363
        
364
    }
365

    
366
    public class BaseCaller extends BaseCode implements Caller, RecursionControlSupport {
367

    
368
        private final String name;
369
        private final Codes args;
370
        private Function function;
371
        private final int type;
372
        private final RecursionSupport recursionSupport;
373

    
374
        public BaseCaller(String name, int type, Codes args) {
375
            this.name = name;
376
            this.args = args;
377
            this.type = type;
378
            this.function = null;
379
            this.recursionSupport = new RecursionSupport();
380
        }
381

    
382
        @Override
383
        public int code() {
384
            return CALLER;
385
        }
386

    
387
        @Override
388
        public void replace(Code target, Code replacement) {
389
            this.args.replace(target, replacement);
390
        }
391

    
392
        @Override
393
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
394
            return this.function.call(interpreter, args);
395
        }
396

    
397
        @Override
398
        public String name() {
399
            return this.name;
400
        }
401

    
402
        @Override
403
        public Function function() {
404
            return this.function;
405
        }
406

    
407
        @Override
408
        public Function function(Function function) {
409
            this.function = function;
410
            return this.function;
411
        }
412

    
413
        @Override
414
        public Codes parameters() {
415
            return this.args;
416
        }
417

    
418
        @Override
419
        public int type() {
420
            return this.type;
421
        }
422

    
423
        @Override
424
        public void accept(Visitor visitor) throws BaseException {
425
            visitor.visit(this);
426
            if(this.args!=null) {
427
                this.args.accept(visitor);
428
            }
429
        }
430

    
431
        @Override
432
        public Value toValue(ExpressionBuilder builder) {
433
            switch(this.type) {
434
                case UNARY_OPERATOR:
435
                    return builder.function(
436
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
437
                                "-" :
438
                                this.name(),
439
                            this.parameters().get(0).toValue(builder)
440
                    );
441
                case BINARY_OPERATOR:
442
                    return builder.binaryOperator(
443
                            this.name(),
444
                            this.parameters().get(0).toValue(builder),
445
                            this.parameters().get(1).toValue(builder)
446
                    );
447
                case FUNCTION:
448
                default:
449
                    ExpressionBuilder.Function f = builder.function(this.name());
450
                    if( this.parameters()!=null ) {
451
                        for (Code parameter : this.parameters()) {
452
                            f.parameter(parameter.toValue(builder));
453
                        }  
454
                    }
455
                    return f;
456

    
457
            }
458
        }
459

    
460
        @Override
461
        public String toString() {
462
            return this.toString(EMPTY_FORMATTER);
463
        }
464
        
465
        @Override
466
        public String toString(Formatter<Code> formatter) {
467
            if( formatter.canApply(this) ) {
468
                return formatter.format(this);
469
            }
470
            Code code;
471
            StringBuilder builder = new StringBuilder();
472
            switch(this.type) {
473
                case UNARY_OPERATOR:
474
                    if( OPERATOR_NEGATE.equalsIgnoreCase(this.name()) ) {
475
                        builder.append("-");
476
                    } else {
477
                        builder.append(this.name());
478
                    }
479
                    builder.append("(");
480
                    builder.append(this.parameters().get(0).toString(formatter));
481
                    builder.append(")");
482
                    break;
483
                case BINARY_OPERATOR:
484
                    builder.append("(");
485
                    code = this.parameters().get(0);
486
                    if( code == null ) {                    
487
                        builder.append("?NULL?");
488
                    } else {
489
                        builder.append(code.toString(formatter));
490
                    }
491
                    builder.append(" ");
492
                    builder.append(this.name());
493
                    builder.append(" ");
494
                    code = this.parameters().get(1);
495
                    if( code == null ) {                    
496
                        builder.append("?NULL?");
497
                    } else {
498
                        builder.append(code.toString(formatter));
499
                    }
500
                    builder.append(")");
501
                    break;
502
                case FUNCTION:
503
                default:
504
                    if( StringUtils.equalsIgnoreCase(this.name(),ExpressionBuilder.FUNCTION_GETATTR) ) {
505
                      Code arg0 = this.parameters().get(0);
506
                      Code arg1 = this.parameters().get(1);
507
                      if( arg0 instanceof Code.Identifier && arg1 instanceof Code.Identifier ) {
508
                        builder.append(arg0.toString(formatter));
509
                        builder.append(".");
510
                        builder.append(arg1.toString());
511
                      } else {
512
                        builder.append(this.name());
513
                        builder.append("(");
514
                        builder.append(arg0.toString(formatter));
515
                        builder.append(", ");
516
                        builder.append(arg1.toString(formatter));
517
                        builder.append(")");
518
                      }
519
                    } else {
520
                      builder.append(this.name());
521
                      builder.append("(");
522
                      if( this.parameters()!=null ) {
523
                          builder.append(this.parameters().toString(formatter));
524
                      }
525
                      builder.append(")");
526
                    }
527
            }
528
            return builder.toString();
529
        }
530

    
531
        @Override
532
        public boolean enterCode(int max) {
533
            return this.recursionSupport.enterCode(max);
534
        }
535

    
536
        @Override
537
        public void exitCode() {
538
            this.recursionSupport.exitCode();
539
        }
540

    
541
        @Override
542
        public void resetRecursionState() {
543
            this.recursionSupport.resetRecursionState();
544
        }
545
    }
546

    
547
    public class BaseMethod extends BaseCode implements Method {
548

    
549
        private Code instance;
550
        private final String methodname;
551
        private final Codes args;
552
        
553
        public BaseMethod(Code instance, String methodname, Codes args) {
554
            this.instance = instance;
555
            this.methodname = methodname;
556
            this.args = args;
557
        }
558

    
559
        @Override
560
        public int code() {
561
            return METHOD;
562
        }
563
        
564
        @Override
565
        public void replace(Code target, Code replacement) {
566
            if( target == this.instance ) {
567
              this.instance = replacement;
568
            }
569
            this.args.replace(target, replacement);
570
        }
571

    
572
        @Override
573
        public String methodname() {
574
            return this.methodname;
575
        }
576

    
577
        @Override
578
        public Code instance() {
579
            return this.instance;
580
        }
581

    
582
        @Override
583
        public Codes parameters() {
584
            return this.args;
585
        }
586

    
587
        @Override
588
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
589
            Object theInstance = interpreter.run(instance);
590
            if( theInstance instanceof SimpleScript ) {
591
                try {
592
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
593
                } catch(NoSuchMethodException ex) {
594
                    // Ignore... continue calling instance method
595
                }                
596
            } else if( theInstance instanceof DynObject ) {
597
                DynObject dynobj = (DynObject) theInstance;
598
                try {
599
                    return dynobj.invokeDynMethod(methodname, args);
600
                } catch(DynMethodNotSupportedException ex) {
601
                    // Ignore... continue calling instance method
602
                }
603
            }
604
            return InstanceUtils.callmethod(theInstance, methodname, args);
605
        }
606

    
607
        @Override
608
        public String toString() {
609
            return this.toString(EMPTY_FORMATTER);
610
        }
611

    
612
        @Override
613
        public Value toValue(ExpressionBuilder builder) {
614
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
615
            if( this.parameters()!=null ) {
616
                for (Code parameter : this.parameters()) {
617
                    m.parameter(parameter.toValue(builder));
618
                }
619
            }
620
            return m;
621
        }
622

    
623
        @Override
624
        public String toString(Formatter<Code> formatter) {
625
            if( formatter.canApply(this) ) {
626
                return formatter.format(this);
627
            }
628
            StringBuilder builder = new StringBuilder();
629
            builder.append(this.instance.toString(formatter));
630
            builder.append("->");
631
            builder.append(this.methodname());
632
            builder.append("(");
633
            if( this.parameters()!=null ) {
634
                builder.append(this.parameters().toString(formatter));
635
            }
636
            builder.append(")");
637
            return builder.toString();
638
        }
639
        
640
        
641
    }    
642

    
643
    protected ExpressionEvaluatorManager manager;
644
    
645
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
646
        this.manager = manager;
647
    }
648
    
649
    @Override
650
    public CodeBuilder clone() throws CloneNotSupportedException {
651
        // This implementation of CodeBuilder does not maintain state, so 
652
        // we only call the super class.
653
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
654
        return other;
655
    }
656

    
657
    @Override
658
    public Constant constant(Object value) {
659
        return new BaseConstant(value);
660
    }
661

    
662
    @Override
663
    public Identifier identifier(String name) {
664
        return new BaseIdentifier(name);
665
    }
666

    
667
    @Override
668
    public BaseCodes args() {
669
        return new BaseCodes();
670
    }
671

    
672
    @Override
673
    public Caller tuple() {
674
      BaseCodes args = this.args();
675
      return function(FUNCTION_TUPLE, args);
676
    }
677
    
678
    @Override
679
    public Caller tuple(Codes args) {
680
      if( args == null ) {
681
        args = this.args();
682
      }
683
      return function(FUNCTION_TUPLE, args);
684
    }
685

    
686
    @Override
687
    public Caller function(String name, int type, Codes args) {
688
        return new BaseCaller(name, type, args);
689
    }
690

    
691
    @Override
692
    public Caller function(String name, Codes args) {
693
        return function(name, Caller.FUNCTION, args);
694
    }
695
    
696
    @Override
697
    public Code method(Code instance, String methodname, Codes methodargs) {
698
        Method m = new BaseMethod(instance, methodname, methodargs);
699
        return m;
700
    }
701
    
702
    @Override
703
    public Caller operator(String name, Code arg1) {
704
        BaseCodes args = args();
705
        args.add(arg1);
706
        return function(name, Caller.UNARY_OPERATOR, args);
707
    }
708

    
709
    @Override
710
    public Caller operator(String name, Code arg1, Code arg2) {
711
        BaseCodes args = args();
712
        args.add(arg1);
713
        args.add(arg2);
714
        return function(name, Caller.BINARY_OPERATOR, args);
715
    }
716
    
717
    @Override
718
    public Code not(Code op1) {
719
        return operator(OPERATOR_NOT, op1);
720
    }
721

    
722
    @Override
723
    public Code negate(Code op1) {
724
        return operator(OPERATOR_NEGATE, op1);
725
    }
726

    
727
    @Override
728
    public Code concat(Code op1, Code op2) {
729
        return operator(OPERATOR_CONCAT, op1, op2);
730
    }
731

    
732
    @Override
733
    public Code add(Code op1, Code op2) {
734
        return operator(OPERATOR_ADD, op1, op2);
735
    }
736

    
737
    @Override
738
    public Code subst(Code op1, Code op2) {
739
        return operator(OPERATOR_SUBST, op1, op2);
740
    }
741

    
742
    @Override
743
    public Code mult(Code op1, Code op2) {
744
        return operator(OPERATOR_MULT, op1, op2);
745
    }
746

    
747
    @Override
748
    public Code div(Code op1, Code op2) {
749
        return operator(OPERATOR_DIV, op1, op2);
750
    }
751

    
752
    @Override
753
    public Code mod(Code op1, Code op2) {
754
        return operator(OPERATOR_MOD, op1, op2);
755
    }
756

    
757
    @Override
758
    public Code or(Code op1, Code op2) {
759
        return operator(OPERATOR_OR, op1, op2);
760
    }
761

    
762
    @Override
763
    public Code and(Code op1, Code op2) {
764
        return operator(OPERATOR_AND, op1, op2);
765
    }
766

    
767
    @Override
768
    public Code like(Code op1, Code op2) {
769
        return operator(OPERATOR_LIKE, op1, op2);
770
    }
771

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

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

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

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

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

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

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

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

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

    
817
    @Override
818
    public Code getattr(Code obj, String attrname) {
819
        BaseCodes args = args();
820
        args.add(obj);
821
        args.add(identifier(attrname));
822
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
823
    }    
824

    
825
    @Override
826
    public Code getitem(Code obj, Code index) {
827
        BaseCodes args = args();
828
        args.add(obj);
829
        args.add(index);
830
        return function(GetitemFunction.NAME, args);
831
    }
832

    
833
    
834
    
835
}