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

History | View | Annotate | Download (29 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7
import java.util.Map;
8
import java.util.function.Predicate;
9
import org.gvsig.expressionevaluator.Code;
10
import static org.gvsig.expressionevaluator.Code.CONSTANT;
11
import static org.gvsig.expressionevaluator.Code.IDENTIFIER;
12
import static org.gvsig.expressionevaluator.Code.UNDEFINED;
13
import static org.gvsig.expressionevaluator.Code.CODES;
14
import org.gvsig.expressionevaluator.Code.Constant;
15
import static org.gvsig.expressionevaluator.Code.EMPTY_FORMATTER;
16
import org.gvsig.expressionevaluator.Code.Identifier;
17
import org.gvsig.expressionevaluator.Code.Method;
18
//import org.gvsig.expressionevaluator.Code.Method;
19
import org.gvsig.expressionevaluator.CodeBuilder;
20
import org.gvsig.expressionevaluator.Codes;
21
import org.gvsig.expressionevaluator.ExpressionBuilder;
22
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_TUPLE;
23
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ADD;
24
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_AND;
25
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_CONCAT;
26
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_DIV;
27
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_EQ;
28
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GE;
29
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GT;
30
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ILIKE;
31
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_IS;
32
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LE;
33
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LIKE;
34
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LT;
35
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_MULT;
36
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NE;
37
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NEGATE;
38
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NOT;
39
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_OR;
40
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_REGEXP;
41
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_SUBST;
42
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
43
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
44
import org.gvsig.expressionevaluator.ExpressionUtils;
45
import org.gvsig.expressionevaluator.Formatter;
46
import org.gvsig.expressionevaluator.Function;
47
import org.gvsig.expressionevaluator.Interpreter;
48
import org.gvsig.expressionevaluator.SymbolTable;
49
import org.gvsig.tools.dynobject.DynObject;
50
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
51
import org.gvsig.tools.exception.BaseException;
52
import org.gvsig.tools.visitor.Visitor;
53
import static org.gvsig.expressionevaluator.Code.CALLABLE;
54
import org.gvsig.expressionevaluator.Code.Callable;
55
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_DICT;
56
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETITEM;
57
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_LET;
58
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_MOD;
59
import org.gvsig.tools.visitor.FilteredVisitable;
60

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

    
64
    public static abstract class BaseCode implements Code {
65

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

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

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

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

    
125
    static class BaseConstant extends BaseCode implements Constant {
126

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

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

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

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

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

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

    
154
        @Override
155
        public Value toValue(ExpressionBuilder builder) {
156
            ExpressionBuilder.Constant v = builder.constant(this.value);
157
            v.copyPropertiesFrom(builder);
158
            return v;
159
        }
160

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

    
175
    }
176

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

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

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

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

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

    
220
        private final String name;
221
        private final RecursionSupport recursionSupport;
222

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

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

    
233
        @Override
234
        public int code() {
235
            return IDENTIFIER;
236
        }
237

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

    
243
        @Override
244
        public Value toValue(ExpressionBuilder builder) {
245
            ExpressionBuilder.Variable v = builder.variable(this.name);
246
            v.copyPropertiesFrom(builder);
247
            return v;
248
        }
249

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

    
267
        @Override
268
        public boolean enterCode(int max) {
269
            return this.recursionSupport.enterCode(max);
270
        }
271

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

    
277
        @Override
278
        public void resetRecursionState() {
279
            this.recursionSupport.resetRecursionState();
280
        }
281

    
282
    }
283

    
284
    public static class BaseCodes implements Codes {
285

    
286
        private List<Code> codes;
287

    
288
        public BaseCodes() {
289
            this.codes = new ArrayList<>();
290
        }
291

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

    
302
        @Override
303
        public int code() {
304
            return CODES;
305
        }
306
        
307
        @Override
308
        public int size() {
309
            if( codes == null ) {
310
                return 0;
311
            }
312
            return this.codes.size();
313
        }
314

    
315
        public void add(Code arg) {
316
            this.codes.add(arg);
317
        }
318

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

    
323
        public void insert(int pos, Code arg) {
324
            this.codes.add(pos, arg);
325
        }
326

    
327
        @Override
328
        public Iterator<Code> iterator() {
329
          final Iterator<Code> it = this.codes.iterator();
330
          return it;
331
        }
332

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

    
338
        @Override
339
        public boolean isEmpty() {
340
            return this.codes.isEmpty();
341
        }
342

    
343
        @Override
344
        public List<Code> toList() {
345
            return Collections.unmodifiableList(this.codes);
346
        }
347

    
348
        @Override
349
        public void accept(Visitor visitor) throws BaseException {
350
            this.accept(visitor, null);
351
        }
352

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
490
        @Override
491
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
492
            if( exclude!=null && exclude.test(this) ) {
493
                return;
494
            }
495
            super.accept(visitor, exclude);
496
            if(this.args!=null ) {
497
                this.args.accept(visitor, exclude);
498
            }
499
        }
500

    
501
        @Override
502
        public Value toValue(ExpressionBuilder builder) {
503
            ExpressionBuilder.Value value;
504
            switch(this.type) {
505
                case UNARY_OPERATOR:
506
                    value = builder.function(
507
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
508
                                    "-" :
509
                                    this.name(),
510
                            this.parameters().get(0).toValue(builder)
511
                    );
512
                    break;
513

    
514
                case BINARY_OPERATOR:
515
                    value =  builder.binaryOperator(
516
                            this.name(),
517
                            this.parameters().get(0).toValue(builder),
518
                            this.parameters().get(1).toValue(builder)
519
                    );
520
                    break;
521
                case FUNCTION:
522
                default:
523
                    ExpressionBuilder.Function f = builder.function(this.name());
524
                    if( this.parameters()!=null ) {
525
                        for (Code parameter : this.parameters()) {
526
                            if (parameter==null) { 
527
                                f.parameter(null);
528
                            } else {
529
                                f.parameter(parameter.toValue(builder));
530
                            }
531
                        }  
532
                    }
533
                    value = f;
534
                    break;
535

    
536
            }
537
            value.copyPropertiesFrom(builder);
538
            return value;
539
        }
540

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

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

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

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

    
619
    public static class BaseMethod extends BaseCode implements Method {
620

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

    
631
        @Override
632
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
633
            if( exclude!=null && exclude.test(this) ) {
634
                return;
635
            }
636
            super.accept(visitor, exclude);
637
            if(this.instance!=null) {
638
               this.instance.accept(visitor, exclude);
639
            }            
640
            if(this.args!=null) {
641
                this.args.accept(visitor, exclude);
642
            }            
643
        }
644

    
645
        @Override
646
        public Code clone() throws CloneNotSupportedException {
647
            BaseMethod x = (BaseMethod) super.clone();
648
            x.args = this.args.clone();
649
            return x;
650
        }
651
        
652
        @Override
653
        public int code() {
654
            return METHOD;
655
        }
656
        
657
        @Override
658
        public void replace(Code target, Code replacement) {
659
            if( target == this.instance ) {
660
              this.instance = replacement;
661
            }
662
            this.args.replace(target, replacement);
663
        }
664

    
665
        @Override
666
        public String methodname() {
667
            return this.methodname;
668
        }
669

    
670
        @Override
671
        public Code instance() {
672
            return this.instance;
673
        }
674

    
675
        @Override
676
        public Codes parameters() {
677
            return this.args;
678
        }
679

    
680
        @Override
681
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
682
            Object theInstance = interpreter.run(instance);
683
            if( theInstance instanceof SimpleScript ) {
684
                try {
685
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
686
                } catch(NoSuchMethodException ex) {
687
                    // Ignore... continue calling instance method
688
                }                
689
            } else if( theInstance instanceof DynObject ) {
690
                DynObject dynobj = (DynObject) theInstance;
691
                try {
692
                    return dynobj.invokeDynMethod(methodname, args);
693
                } catch(DynMethodNotSupportedException ex) {
694
                    // Ignore... continue calling instance method
695
                }
696
            }
697
            return InstanceUtils.callmethod(theInstance, methodname, args);
698
        }
699

    
700
        @Override
701
        public String toString() {
702
            return this.toString(EMPTY_FORMATTER);
703
        }
704

    
705
        @Override
706
        public Value toValue(ExpressionBuilder builder) {
707
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
708
            if( this.parameters()!=null ) {
709
                for (Code parameter : this.parameters()) {
710
                    m.parameter(parameter.toValue(builder));
711
                }
712
            }
713
            m.copyPropertiesFrom(builder);
714
            return m;
715
        }
716

    
717
        @Override
718
        public String toString(Formatter<Code> formatter) {
719
            if( formatter.canApply(this) ) {
720
                return formatter.format(this);
721
            }
722
            StringBuilder builder = new StringBuilder();
723
            builder.append(this.instance.toString(formatter));
724
            builder.append(".");
725
            builder.append(this.methodname());
726
            builder.append("(");
727
            if( this.parameters()!=null ) {
728
                builder.append(this.parameters().toString(formatter));
729
            }
730
            builder.append(")");
731
            return builder.toString();
732
        }
733

    
734
        @Override
735
        public String name() {
736
            return this.methodname();
737
        }
738

    
739
        @Override
740
        public Function function() {
741
            return null;
742
        }
743

    
744
        @Override
745
        public Function function(Function function) {
746
            return null;
747
        }
748

    
749
        @Override
750
        public int type() {
751
            return Code.METHOD;
752
        }
753
        
754
        
755
    }    
756

    
757
    protected ExpressionEvaluatorManager manager;
758
    
759
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
760
        this.manager = manager;
761
    }
762
    
763
    @Override
764
    public CodeBuilder clone() throws CloneNotSupportedException {
765
        // This implementation of CodeBuilder does not maintain state, so 
766
        // we only call the super class.
767
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
768
        return other;
769
    }
770

    
771
    @Override
772
    public Constant constant(Object value) {
773
        return new BaseConstant(this.manager, value);
774
    }
775

    
776
    @Override
777
    public Identifier identifier(String name) {
778
        return new BaseIdentifier(name);
779
    }
780

    
781
    @Override
782
    public BaseCodes args() {
783
        return new BaseCodes();
784
    }
785

    
786
    @Override
787
    public Callable tuple() {
788
      BaseCodes args = this.args();
789
      return function(FUNCTION_TUPLE, args);
790
    }
791
    
792
    @Override
793
    public Callable tuple(Codes args) {
794
      if( args == null ) {
795
        args = this.args();
796
      }
797
      return function(FUNCTION_TUPLE, args);
798
    }
799

    
800
    @Override
801
    public Callable function(String name, int type, Codes args) {
802
        return new BaseCaller(name, type, args);
803
    }
804

    
805
    @Override
806
    public Callable function(String name, Codes args) {
807
        return function(name, Callable.FUNCTION, args);
808
    }
809
    
810
    @Override
811
    public Code method(Code instance, String methodname, Codes methodargs) {
812
        Method m = new BaseMethod(instance, methodname, methodargs);
813
        return m;
814
    }
815
    
816
    @Override
817
    public Callable operator(String name, Code arg1) {
818
        BaseCodes args = args();
819
        args.add(arg1);
820
        return function(name, Callable.UNARY_OPERATOR, args);
821
    }
822

    
823
    @Override
824
    public Callable operator(String name, Code arg1, Code arg2) {
825
        BaseCodes args = args();
826
        args.add(arg1);
827
        args.add(arg2);
828
        return function(name, Callable.BINARY_OPERATOR, args);
829
    }
830
    
831
    @Override
832
    public Code not(Code op1) {
833
        return operator(OPERATOR_NOT, op1);
834
    }
835

    
836
    @Override
837
    public Code negate(Code op1) {
838
        return operator(OPERATOR_NEGATE, op1);
839
    }
840

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

    
846
    @Override
847
    public Code let(String identifier, Code value) {
848
        BaseCodes args = args();
849
        args.add(this.constant(identifier));
850
        args.add(value);
851
        return function(FUNCTION_LET, Callable.FUNCTION, args);
852
    }
853

    
854
    @Override
855
    public Code add(Code op1, Code op2) {
856
        return operator(OPERATOR_ADD, op1, op2);
857
    }
858

    
859
    @Override
860
    public Code subst(Code op1, Code op2) {
861
        return operator(OPERATOR_SUBST, op1, op2);
862
    }
863

    
864
    @Override
865
    public Code mult(Code op1, Code op2) {
866
        return operator(OPERATOR_MULT, op1, op2);
867
    }
868

    
869
    @Override
870
    public Code div(Code op1, Code op2) {
871
        return operator(OPERATOR_DIV, op1, op2);
872
    }
873

    
874
    @Override
875
    public Code mod(Code op1, Code op2) {
876
        BaseCodes args = args();
877
        args.add(op1);
878
        args.add(op2);
879
        return function(FUNCTION_MOD, args);
880
    }
881

    
882
    @Override
883
    public Code or(Code op1, Code op2) {
884
        return operator(OPERATOR_OR, op1, op2);
885
    }
886

    
887
    @Override
888
    public Code and(Code op1, Code op2) {
889
        return operator(OPERATOR_AND, op1, op2);
890
    }
891

    
892
    @Override
893
    public Code like(Code op1, Code op2) {
894
        return operator(OPERATOR_LIKE, op1, op2);
895
    }
896

    
897
    @Override
898
    public Code ilike(Code op1, Code op2) {
899
        return operator(OPERATOR_ILIKE, op1, op2);
900
    }
901

    
902
    @Override
903
    public Code regexp(Code op1, Code op2) {
904
        return operator(OPERATOR_REGEXP, op1, op2);
905
    }
906

    
907
    @Override
908
    public Code lt(Code op1, Code op2) {
909
        return operator(OPERATOR_LT, op1, op2);
910
    }
911

    
912
    @Override
913
    public Code gt(Code op1, Code op2) {
914
        return operator(OPERATOR_GT, op1, op2);
915
    }
916

    
917
    @Override
918
    public Code le(Code op1, Code op2) {
919
        return operator(OPERATOR_LE, op1, op2);
920
    }
921

    
922
    @Override
923
    public Code ge(Code op1, Code op2) {
924
        return operator(OPERATOR_GE, op1, op2);
925
    }
926

    
927
    @Override
928
    public Code eq(Code op1, Code op2) {
929
        return operator(OPERATOR_EQ, op1, op2);
930
    }
931

    
932
    @Override
933
    public Code ne(Code op1, Code op2) {
934
        return operator(OPERATOR_NE, op1, op2);
935
    }
936

    
937
    @Override
938
    public Code is(Code op1, Code op2) {
939
        return operator(OPERATOR_IS, op1, op2);
940
    }
941

    
942
    @Override
943
    public Code getattr(Code obj, String attrname) {
944
        BaseCodes args = args();
945
        args.add(obj);
946
        args.add(constant(attrname));
947
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
948
    }    
949

    
950
    @Override
951
    public Code getitem(Code obj, Code index) {
952
        BaseCodes args = args();
953
        args.add(obj);
954
        args.add(index);
955
        return function(FUNCTION_GETITEM, args);
956
    }
957

    
958
    @Override
959
    public Code dict(Map<String,Code>map ) {
960
        BaseCodes args = args();
961
        for (Map.Entry<String, Code> entry : map.entrySet()) {
962
            String key = entry.getKey();
963
            Code value = entry.getValue();
964
            args.add(constant(key));
965
            args.add(value);
966
        }
967
        return function(FUNCTION_DICT, args);
968
    }
969
    
970
    @Override
971
    public Code $HostExpression(Code obj, String mode_specifier) {
972
        BaseCodes args = args();
973
        args.add(obj);
974
        args.add(constant(mode_specifier));
975
        return function(ExpressionBuilder.FUNCTION_$HOSTEXPRESSION, args);
976
    }    
977

    
978
}