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

History | View | Annotate | Download (24.2 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.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_MOD;
35
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_MULT;
36
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NE;
37
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NEGATE;
38
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NOT;
39
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_OR;
40
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_REGEXP;
41
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_SUBST;
42
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
43
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
44
import org.gvsig.expressionevaluator.ExpressionUtils;
45
import org.gvsig.expressionevaluator.Formatter;
46
import org.gvsig.expressionevaluator.Function;
47
import org.gvsig.expressionevaluator.Interpreter;
48
import org.gvsig.expressionevaluator.SymbolTable;
49
import org.gvsig.expressionevaluator.impl.function.programming.GetitemFunction;
50
import org.gvsig.tools.dynobject.DynObject;
51
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
52
import org.gvsig.tools.exception.BaseException;
53
import org.gvsig.tools.visitor.Visitor;
54
import static org.gvsig.expressionevaluator.Code.CALLABLE;
55
import org.gvsig.expressionevaluator.Code.Callable;
56
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETITEM;
57
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_MOD;
58

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

    
62
    public abstract class BaseCode implements Code {
63

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

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

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

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

    
110
    class BaseConstant extends BaseCode implements Constant {
111

    
112
        private Object value;
113

    
114
        public BaseConstant(Object value) {
115
            this.value = value;
116
        }
117

    
118
        @Override
119
        public int code() {
120
            return CONSTANT;
121
        }
122

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

    
128
        public void value(Object v) {
129
            this.value = v;
130
        }
131

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

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

    
151
    }
152

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

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

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

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

    
190
        private final String name;
191
        private final RecursionSupport recursionSupport;
192

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

    
198
        @Override
199
        public int code() {
200
            return IDENTIFIER;
201
        }
202

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

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

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

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

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

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

    
245
    }
246

    
247
    public class BaseCodes implements Codes {
248

    
249
        private final List<Code> codes;
250

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

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

    
268
        public void add(Code arg) {
269
            this.codes.add(arg);
270
        }
271

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

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

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

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

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

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

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

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

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

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

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

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

    
368
    public class BaseCaller extends BaseCode implements Callable, RecursionControlSupport {
369

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

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

    
384
        @Override
385
        public int code() {
386
            return CALLABLE;
387
        }
388

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

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

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

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

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

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

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

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

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

    
459
            }
460
        }
461

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

    
524
        @Override
525
        public boolean enterCode(int max) {
526
            return this.recursionSupport.enterCode(max);
527
        }
528

    
529
        @Override
530
        public void exitCode() {
531
            this.recursionSupport.exitCode();
532
        }
533

    
534
        @Override
535
        public void resetRecursionState() {
536
            this.recursionSupport.resetRecursionState();
537
        }
538
    }
539

    
540
    public class BaseMethod extends BaseCode implements Method {
541

    
542
        private Code instance;
543
        private final String methodname;
544
        private final Codes args;
545
        
546
        public BaseMethod(Code instance, String methodname, Codes args) {
547
            this.instance = instance;
548
            this.methodname = methodname;
549
            this.args = args;
550
        }
551

    
552
        @Override
553
        public int code() {
554
            return METHOD;
555
        }
556
        
557
        @Override
558
        public void replace(Code target, Code replacement) {
559
            if( target == this.instance ) {
560
              this.instance = replacement;
561
            }
562
            this.args.replace(target, replacement);
563
        }
564

    
565
        @Override
566
        public String methodname() {
567
            return this.methodname;
568
        }
569

    
570
        @Override
571
        public Code instance() {
572
            return this.instance;
573
        }
574

    
575
        @Override
576
        public Codes parameters() {
577
            return this.args;
578
        }
579

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

    
600
        @Override
601
        public String toString() {
602
            return this.toString(EMPTY_FORMATTER);
603
        }
604

    
605
        @Override
606
        public Value toValue(ExpressionBuilder builder) {
607
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
608
            if( this.parameters()!=null ) {
609
                for (Code parameter : this.parameters()) {
610
                    m.parameter(parameter.toValue(builder));
611
                }
612
            }
613
            return m;
614
        }
615

    
616
        @Override
617
        public String toString(Formatter<Code> formatter) {
618
            if( formatter.canApply(this) ) {
619
                return formatter.format(this);
620
            }
621
            StringBuilder builder = new StringBuilder();
622
            builder.append(this.instance.toString(formatter));
623
            builder.append("->");
624
            builder.append(this.methodname());
625
            builder.append("(");
626
            if( this.parameters()!=null ) {
627
                builder.append(this.parameters().toString(formatter));
628
            }
629
            builder.append(")");
630
            return builder.toString();
631
        }
632
        
633
        
634
    }    
635

    
636
    protected ExpressionEvaluatorManager manager;
637
    
638
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
639
        this.manager = manager;
640
    }
641
    
642
    @Override
643
    public CodeBuilder clone() throws CloneNotSupportedException {
644
        // This implementation of CodeBuilder does not maintain state, so 
645
        // we only call the super class.
646
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
647
        return other;
648
    }
649

    
650
    @Override
651
    public Constant constant(Object value) {
652
        return new BaseConstant(value);
653
    }
654

    
655
    @Override
656
    public Identifier identifier(String name) {
657
        return new BaseIdentifier(name);
658
    }
659

    
660
    @Override
661
    public BaseCodes args() {
662
        return new BaseCodes();
663
    }
664

    
665
    @Override
666
    public Callable tuple() {
667
      BaseCodes args = this.args();
668
      return function(FUNCTION_TUPLE, args);
669
    }
670
    
671
    @Override
672
    public Callable tuple(Codes args) {
673
      if( args == null ) {
674
        args = this.args();
675
      }
676
      return function(FUNCTION_TUPLE, args);
677
    }
678

    
679
    @Override
680
    public Callable function(String name, int type, Codes args) {
681
        return new BaseCaller(name, type, args);
682
    }
683

    
684
    @Override
685
    public Callable function(String name, Codes args) {
686
        return function(name, Callable.FUNCTION, args);
687
    }
688
    
689
    @Override
690
    public Code method(Code instance, String methodname, Codes methodargs) {
691
        Method m = new BaseMethod(instance, methodname, methodargs);
692
        return m;
693
    }
694
    
695
    @Override
696
    public Callable operator(String name, Code arg1) {
697
        BaseCodes args = args();
698
        args.add(arg1);
699
        return function(name, Callable.UNARY_OPERATOR, args);
700
    }
701

    
702
    @Override
703
    public Callable operator(String name, Code arg1, Code arg2) {
704
        BaseCodes args = args();
705
        args.add(arg1);
706
        args.add(arg2);
707
        return function(name, Callable.BINARY_OPERATOR, args);
708
    }
709
    
710
    @Override
711
    public Code not(Code op1) {
712
        return operator(OPERATOR_NOT, op1);
713
    }
714

    
715
    @Override
716
    public Code negate(Code op1) {
717
        return operator(OPERATOR_NEGATE, op1);
718
    }
719

    
720
    @Override
721
    public Code concat(Code op1, Code op2) {
722
        return operator(OPERATOR_CONCAT, op1, op2);
723
    }
724

    
725
    @Override
726
    public Code add(Code op1, Code op2) {
727
        return operator(OPERATOR_ADD, op1, op2);
728
    }
729

    
730
    @Override
731
    public Code subst(Code op1, Code op2) {
732
        return operator(OPERATOR_SUBST, op1, op2);
733
    }
734

    
735
    @Override
736
    public Code mult(Code op1, Code op2) {
737
        return operator(OPERATOR_MULT, op1, op2);
738
    }
739

    
740
    @Override
741
    public Code div(Code op1, Code op2) {
742
        return operator(OPERATOR_DIV, op1, op2);
743
    }
744

    
745
    @Override
746
    public Code mod(Code op1, Code op2) {
747
        BaseCodes args = args();
748
        args.add(op1);
749
        args.add(op2);
750
        return function(FUNCTION_MOD, args);
751
    }
752

    
753
    @Override
754
    public Code or(Code op1, Code op2) {
755
        return operator(OPERATOR_OR, op1, op2);
756
    }
757

    
758
    @Override
759
    public Code and(Code op1, Code op2) {
760
        return operator(OPERATOR_AND, op1, op2);
761
    }
762

    
763
    @Override
764
    public Code like(Code op1, Code op2) {
765
        return operator(OPERATOR_LIKE, op1, op2);
766
    }
767

    
768
    @Override
769
    public Code ilike(Code op1, Code op2) {
770
        return operator(OPERATOR_ILIKE, op1, op2);
771
    }
772

    
773
    @Override
774
    public Code regexp(Code op1, Code op2) {
775
        return operator(OPERATOR_REGEXP, op1, op2);
776
    }
777

    
778
    @Override
779
    public Code lt(Code op1, Code op2) {
780
        return operator(OPERATOR_LT, op1, op2);
781
    }
782

    
783
    @Override
784
    public Code gt(Code op1, Code op2) {
785
        return operator(OPERATOR_GT, op1, op2);
786
    }
787

    
788
    @Override
789
    public Code le(Code op1, Code op2) {
790
        return operator(OPERATOR_LE, op1, op2);
791
    }
792

    
793
    @Override
794
    public Code ge(Code op1, Code op2) {
795
        return operator(OPERATOR_GE, op1, op2);
796
    }
797

    
798
    @Override
799
    public Code eq(Code op1, Code op2) {
800
        return operator(OPERATOR_EQ, op1, op2);
801
    }
802

    
803
    @Override
804
    public Code ne(Code op1, Code op2) {
805
        return operator(OPERATOR_NE, op1, op2);
806
    }
807

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

    
813
    @Override
814
    public Code getattr(Code obj, String attrname) {
815
        BaseCodes args = args();
816
        args.add(obj);
817
        args.add(constant(attrname));
818
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
819
    }    
820

    
821
    @Override
822
    public Code getitem(Code obj, Code index) {
823
        BaseCodes args = args();
824
        args.add(obj);
825
        args.add(index);
826
        return function(FUNCTION_GETITEM, args);
827
    }
828

    
829
    
830
    
831
}