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

History | View | Annotate | Download (28.8 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
            super.accept(visitor, exclude);
493
            if(this.args!=null) {
494
                this.args.accept(visitor, exclude);
495
            }
496
        }
497

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

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

    
533
            }
534
            value.copyPropertiesFrom(builder);
535
            return value;
536
        }
537

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

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

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

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

    
616
    public static class BaseMethod extends BaseCode implements Method {
617

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

    
628
        @Override
629
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
630
            super.accept(visitor, exclude);
631
            if(this.instance!=null) {
632
               this.instance.accept(visitor, exclude);
633
            }            
634
            if(this.args!=null) {
635
                this.args.accept(visitor, exclude);
636
            }            
637
        }
638

    
639
        @Override
640
        public Code clone() throws CloneNotSupportedException {
641
            BaseMethod x = (BaseMethod) super.clone();
642
            x.args = this.args.clone();
643
            return x;
644
        }
645
        
646
        @Override
647
        public int code() {
648
            return METHOD;
649
        }
650
        
651
        @Override
652
        public void replace(Code target, Code replacement) {
653
            if( target == this.instance ) {
654
              this.instance = replacement;
655
            }
656
            this.args.replace(target, replacement);
657
        }
658

    
659
        @Override
660
        public String methodname() {
661
            return this.methodname;
662
        }
663

    
664
        @Override
665
        public Code instance() {
666
            return this.instance;
667
        }
668

    
669
        @Override
670
        public Codes parameters() {
671
            return this.args;
672
        }
673

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

    
694
        @Override
695
        public String toString() {
696
            return this.toString(EMPTY_FORMATTER);
697
        }
698

    
699
        @Override
700
        public Value toValue(ExpressionBuilder builder) {
701
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
702
            if( this.parameters()!=null ) {
703
                for (Code parameter : this.parameters()) {
704
                    m.parameter(parameter.toValue(builder));
705
                }
706
            }
707
            m.copyPropertiesFrom(builder);
708
            return m;
709
        }
710

    
711
        @Override
712
        public String toString(Formatter<Code> formatter) {
713
            if( formatter.canApply(this) ) {
714
                return formatter.format(this);
715
            }
716
            StringBuilder builder = new StringBuilder();
717
            builder.append(this.instance.toString(formatter));
718
            builder.append(".");
719
            builder.append(this.methodname());
720
            builder.append("(");
721
            if( this.parameters()!=null ) {
722
                builder.append(this.parameters().toString(formatter));
723
            }
724
            builder.append(")");
725
            return builder.toString();
726
        }
727

    
728
        @Override
729
        public String name() {
730
            return this.methodname();
731
        }
732

    
733
        @Override
734
        public Function function() {
735
            return null;
736
        }
737

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

    
743
        @Override
744
        public int type() {
745
            return Code.METHOD;
746
        }
747
        
748
        
749
    }    
750

    
751
    protected ExpressionEvaluatorManager manager;
752
    
753
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
754
        this.manager = manager;
755
    }
756
    
757
    @Override
758
    public CodeBuilder clone() throws CloneNotSupportedException {
759
        // This implementation of CodeBuilder does not maintain state, so 
760
        // we only call the super class.
761
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
762
        return other;
763
    }
764

    
765
    @Override
766
    public Constant constant(Object value) {
767
        return new BaseConstant(this.manager, value);
768
    }
769

    
770
    @Override
771
    public Identifier identifier(String name) {
772
        return new BaseIdentifier(name);
773
    }
774

    
775
    @Override
776
    public BaseCodes args() {
777
        return new BaseCodes();
778
    }
779

    
780
    @Override
781
    public Callable tuple() {
782
      BaseCodes args = this.args();
783
      return function(FUNCTION_TUPLE, args);
784
    }
785
    
786
    @Override
787
    public Callable tuple(Codes args) {
788
      if( args == null ) {
789
        args = this.args();
790
      }
791
      return function(FUNCTION_TUPLE, args);
792
    }
793

    
794
    @Override
795
    public Callable function(String name, int type, Codes args) {
796
        return new BaseCaller(name, type, args);
797
    }
798

    
799
    @Override
800
    public Callable function(String name, Codes args) {
801
        return function(name, Callable.FUNCTION, args);
802
    }
803
    
804
    @Override
805
    public Code method(Code instance, String methodname, Codes methodargs) {
806
        Method m = new BaseMethod(instance, methodname, methodargs);
807
        return m;
808
    }
809
    
810
    @Override
811
    public Callable operator(String name, Code arg1) {
812
        BaseCodes args = args();
813
        args.add(arg1);
814
        return function(name, Callable.UNARY_OPERATOR, args);
815
    }
816

    
817
    @Override
818
    public Callable operator(String name, Code arg1, Code arg2) {
819
        BaseCodes args = args();
820
        args.add(arg1);
821
        args.add(arg2);
822
        return function(name, Callable.BINARY_OPERATOR, args);
823
    }
824
    
825
    @Override
826
    public Code not(Code op1) {
827
        return operator(OPERATOR_NOT, op1);
828
    }
829

    
830
    @Override
831
    public Code negate(Code op1) {
832
        return operator(OPERATOR_NEGATE, op1);
833
    }
834

    
835
    @Override
836
    public Code concat(Code op1, Code op2) {
837
        return operator(OPERATOR_CONCAT, op1, op2);
838
    }
839

    
840
    @Override
841
    public Code let(String identifier, Code value) {
842
        BaseCodes args = args();
843
        args.add(this.constant(identifier));
844
        args.add(value);
845
        return function(FUNCTION_LET, Callable.FUNCTION, args);
846
    }
847

    
848
    @Override
849
    public Code add(Code op1, Code op2) {
850
        return operator(OPERATOR_ADD, op1, op2);
851
    }
852

    
853
    @Override
854
    public Code subst(Code op1, Code op2) {
855
        return operator(OPERATOR_SUBST, op1, op2);
856
    }
857

    
858
    @Override
859
    public Code mult(Code op1, Code op2) {
860
        return operator(OPERATOR_MULT, op1, op2);
861
    }
862

    
863
    @Override
864
    public Code div(Code op1, Code op2) {
865
        return operator(OPERATOR_DIV, op1, op2);
866
    }
867

    
868
    @Override
869
    public Code mod(Code op1, Code op2) {
870
        BaseCodes args = args();
871
        args.add(op1);
872
        args.add(op2);
873
        return function(FUNCTION_MOD, args);
874
    }
875

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

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

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

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

    
896
    @Override
897
    public Code regexp(Code op1, Code op2) {
898
        return operator(OPERATOR_REGEXP, op1, op2);
899
    }
900

    
901
    @Override
902
    public Code lt(Code op1, Code op2) {
903
        return operator(OPERATOR_LT, op1, op2);
904
    }
905

    
906
    @Override
907
    public Code gt(Code op1, Code op2) {
908
        return operator(OPERATOR_GT, op1, op2);
909
    }
910

    
911
    @Override
912
    public Code le(Code op1, Code op2) {
913
        return operator(OPERATOR_LE, op1, op2);
914
    }
915

    
916
    @Override
917
    public Code ge(Code op1, Code op2) {
918
        return operator(OPERATOR_GE, op1, op2);
919
    }
920

    
921
    @Override
922
    public Code eq(Code op1, Code op2) {
923
        return operator(OPERATOR_EQ, op1, op2);
924
    }
925

    
926
    @Override
927
    public Code ne(Code op1, Code op2) {
928
        return operator(OPERATOR_NE, op1, op2);
929
    }
930

    
931
    @Override
932
    public Code is(Code op1, Code op2) {
933
        return operator(OPERATOR_IS, op1, op2);
934
    }
935

    
936
    @Override
937
    public Code getattr(Code obj, String attrname) {
938
        BaseCodes args = args();
939
        args.add(obj);
940
        args.add(constant(attrname));
941
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
942
    }    
943

    
944
    @Override
945
    public Code getitem(Code obj, Code index) {
946
        BaseCodes args = args();
947
        args.add(obj);
948
        args.add(index);
949
        return function(FUNCTION_GETITEM, args);
950
    }
951

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

    
972
}