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

History | View | Annotate | Download (29.6 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7
import 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
            visitor.visit(this);
80
        }
81

    
82
        @Override
83
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
84
            if( !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
            for( Code arg : this.codes ) {
351
                if(arg!=null) {
352
                    arg.accept(visitor);
353
                }
354
            }
355
        }
356

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

    
377
        @Override
378
        public Value toValue() {
379
            throw new UnsupportedOperationException();
380
        }
381

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

    
406
        @Override
407
        public void link(SymbolTable symbolTable) {
408
            for (Code arg : this.codes) {
409
                arg.link(symbolTable);
410
            }
411
        }
412

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

    
427
    public class BaseCaller extends BaseCode implements Callable, RecursionControlSupport {
428

    
429
        private final String name;
430
        private Codes args;
431
        private Function function;
432
        private final int type;
433
        private RecursionSupport recursionSupport;
434

    
435
        public BaseCaller(String name, int type, Codes args) {
436
            this.name = name;
437
            this.args = args;
438
            this.type = type;
439
            this.function = null;
440
            this.recursionSupport = new RecursionSupport();
441
        }
442

    
443
        @Override
444
        public Code clone() throws CloneNotSupportedException {
445
            BaseCaller x = (BaseCaller) super.clone();
446
            x.recursionSupport = (RecursionSupport) this.recursionSupport.clone();
447
            if (this.args!=null){
448
                x.args = this.args.clone();
449
            }
450
            return x;
451
        }
452

    
453
        @Override
454
        public int code() {
455
            return CALLABLE;
456
        }
457

    
458
        @Override
459
        public void replace(Code target, Code replacement) {
460
            this.args.replace(target, replacement);
461
        }
462

    
463
        @Override
464
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
465
            return this.function.call(interpreter, args);
466
        }
467

    
468
        @Override
469
        public String name() {
470
            return this.name;
471
        }
472

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

    
478
        @Override
479
        public Function function(Function function) {
480
            this.function = function;
481
            return this.function;
482
        }
483

    
484
        @Override
485
        public Codes parameters() {
486
            return this.args;
487
        }
488

    
489
        @Override
490
        public int type() {
491
            return this.type;
492
        }
493

    
494
        @Override
495
        public void accept(Visitor visitor) throws BaseException {
496
            visitor.visit(this);
497
            if(this.args!=null) {
498
                this.args.accept(visitor);
499
            }
500
        }
501

    
502
        @Override
503
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
504
            if( !exclude.test(this) ) {
505
                visitor.visit(this);
506
                if(this.args!=null) {
507
                    this.args.accept(visitor, exclude);
508
                }
509
            }
510
        }
511

    
512
        @Override
513
        public Value toValue(ExpressionBuilder builder) {
514
            ExpressionBuilder.Value value;
515
            switch(this.type) {
516
                case UNARY_OPERATOR:
517
                    value = builder.function(
518
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
519
                                    "-" :
520
                                    this.name(),
521
                            this.parameters().get(0).toValue(builder)
522
                    );
523
                    break;
524

    
525
                case BINARY_OPERATOR:
526
                    value =  builder.binaryOperator(
527
                            this.name(),
528
                            this.parameters().get(0).toValue(builder),
529
                            this.parameters().get(1).toValue(builder)
530
                    );
531
                    break;
532
                case FUNCTION:
533
                default:
534
                    ExpressionBuilder.Function f = builder.function(this.name());
535
                    if( this.parameters()!=null ) {
536
                        for (Code parameter : this.parameters()) {
537
                            if (parameter==null) { 
538
                                f.parameter(null);
539
                            } else {
540
                                f.parameter(parameter.toValue(builder));
541
                            }
542
                        }  
543
                    }
544
                    value = f;
545
                    break;
546

    
547
            }
548
            value.copyPropertiesFrom(builder);
549
            return value;
550
        }
551

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

    
614
        @Override
615
        public boolean enterCode(int max) {
616
            return this.recursionSupport.enterCode(max);
617
        }
618

    
619
        @Override
620
        public void exitCode() {
621
            this.recursionSupport.exitCode();
622
        }
623

    
624
        @Override
625
        public void resetRecursionState() {
626
            this.recursionSupport.resetRecursionState();
627
        }
628
    }
629

    
630
    public static class BaseMethod extends BaseCode implements Method {
631

    
632
        private Code instance;
633
        private final String methodname;
634
        private Codes args;
635
        
636
        public BaseMethod(Code instance, String methodname, Codes args) {
637
            this.instance = instance;
638
            this.methodname = methodname;
639
            this.args = args;
640
        }
641

    
642
        @Override
643
        public void accept(Visitor visitor) throws BaseException {
644
            visitor.visit(this);
645
            if(this.instance!=null) {
646
                this.instance.accept(visitor);
647
            }            
648
            if(this.args!=null) {
649
                this.args.accept(visitor);
650
            }            
651
        }
652
        
653
        @Override
654
        public void accept(Visitor visitor, Predicate<FilteredVisitable> exclude) throws BaseException {
655
            if( !exclude.test(this) ) {
656
                visitor.visit(this);
657
                if(this.instance!=null) {
658
                    this.instance.accept(visitor, exclude);
659
                }            
660
                if(this.args!=null) {
661
                    this.args.accept(visitor, exclude);
662
                }            
663
            }
664
        }
665

    
666
        @Override
667
        public Code clone() throws CloneNotSupportedException {
668
            BaseMethod x = (BaseMethod) super.clone();
669
            x.args = this.args.clone();
670
            return x;
671
        }
672
        
673
        @Override
674
        public int code() {
675
            return METHOD;
676
        }
677
        
678
        @Override
679
        public void replace(Code target, Code replacement) {
680
            if( target == this.instance ) {
681
              this.instance = replacement;
682
            }
683
            this.args.replace(target, replacement);
684
        }
685

    
686
        @Override
687
        public String methodname() {
688
            return this.methodname;
689
        }
690

    
691
        @Override
692
        public Code instance() {
693
            return this.instance;
694
        }
695

    
696
        @Override
697
        public Codes parameters() {
698
            return this.args;
699
        }
700

    
701
        @Override
702
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
703
            Object theInstance = interpreter.run(instance);
704
            if( theInstance instanceof SimpleScript ) {
705
                try {
706
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
707
                } catch(NoSuchMethodException ex) {
708
                    // Ignore... continue calling instance method
709
                }                
710
            } else if( theInstance instanceof DynObject ) {
711
                DynObject dynobj = (DynObject) theInstance;
712
                try {
713
                    return dynobj.invokeDynMethod(methodname, args);
714
                } catch(DynMethodNotSupportedException ex) {
715
                    // Ignore... continue calling instance method
716
                }
717
            }
718
            return InstanceUtils.callmethod(theInstance, methodname, args);
719
        }
720

    
721
        @Override
722
        public String toString() {
723
            return this.toString(EMPTY_FORMATTER);
724
        }
725

    
726
        @Override
727
        public Value toValue(ExpressionBuilder builder) {
728
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
729
            if( this.parameters()!=null ) {
730
                for (Code parameter : this.parameters()) {
731
                    m.parameter(parameter.toValue(builder));
732
                }
733
            }
734
            m.copyPropertiesFrom(builder);
735
            return m;
736
        }
737

    
738
        @Override
739
        public String toString(Formatter<Code> formatter) {
740
            if( formatter.canApply(this) ) {
741
                return formatter.format(this);
742
            }
743
            StringBuilder builder = new StringBuilder();
744
            builder.append(this.instance.toString(formatter));
745
            builder.append(".");
746
            builder.append(this.methodname());
747
            builder.append("(");
748
            if( this.parameters()!=null ) {
749
                builder.append(this.parameters().toString(formatter));
750
            }
751
            builder.append(")");
752
            return builder.toString();
753
        }
754

    
755
        @Override
756
        public String name() {
757
            return this.methodname();
758
        }
759

    
760
        @Override
761
        public Function function() {
762
            return null;
763
        }
764

    
765
        @Override
766
        public Function function(Function function) {
767
            return null;
768
        }
769

    
770
        @Override
771
        public int type() {
772
            return Code.METHOD;
773
        }
774
        
775
        
776
    }    
777

    
778
    protected ExpressionEvaluatorManager manager;
779
    
780
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
781
        this.manager = manager;
782
    }
783
    
784
    @Override
785
    public CodeBuilder clone() throws CloneNotSupportedException {
786
        // This implementation of CodeBuilder does not maintain state, so 
787
        // we only call the super class.
788
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
789
        return other;
790
    }
791

    
792
    @Override
793
    public Constant constant(Object value) {
794
        return new BaseConstant(this.manager, value);
795
    }
796

    
797
    @Override
798
    public Identifier identifier(String name) {
799
        return new BaseIdentifier(name);
800
    }
801

    
802
    @Override
803
    public BaseCodes args() {
804
        return new BaseCodes();
805
    }
806

    
807
    @Override
808
    public Callable tuple() {
809
      BaseCodes args = this.args();
810
      return function(FUNCTION_TUPLE, args);
811
    }
812
    
813
    @Override
814
    public Callable tuple(Codes args) {
815
      if( args == null ) {
816
        args = this.args();
817
      }
818
      return function(FUNCTION_TUPLE, args);
819
    }
820

    
821
    @Override
822
    public Callable function(String name, int type, Codes args) {
823
        return new BaseCaller(name, type, args);
824
    }
825

    
826
    @Override
827
    public Callable function(String name, Codes args) {
828
        return function(name, Callable.FUNCTION, args);
829
    }
830
    
831
    @Override
832
    public Code method(Code instance, String methodname, Codes methodargs) {
833
        Method m = new BaseMethod(instance, methodname, methodargs);
834
        return m;
835
    }
836
    
837
    @Override
838
    public Callable operator(String name, Code arg1) {
839
        BaseCodes args = args();
840
        args.add(arg1);
841
        return function(name, Callable.UNARY_OPERATOR, args);
842
    }
843

    
844
    @Override
845
    public Callable operator(String name, Code arg1, Code arg2) {
846
        BaseCodes args = args();
847
        args.add(arg1);
848
        args.add(arg2);
849
        return function(name, Callable.BINARY_OPERATOR, args);
850
    }
851
    
852
    @Override
853
    public Code not(Code op1) {
854
        return operator(OPERATOR_NOT, op1);
855
    }
856

    
857
    @Override
858
    public Code negate(Code op1) {
859
        return operator(OPERATOR_NEGATE, op1);
860
    }
861

    
862
    @Override
863
    public Code concat(Code op1, Code op2) {
864
        return operator(OPERATOR_CONCAT, op1, op2);
865
    }
866

    
867
    @Override
868
    public Code let(String identifier, Code value) {
869
        BaseCodes args = args();
870
        args.add(this.constant(identifier));
871
        args.add(value);
872
        return function(FUNCTION_LET, Callable.FUNCTION, args);
873
    }
874

    
875
    @Override
876
    public Code add(Code op1, Code op2) {
877
        return operator(OPERATOR_ADD, op1, op2);
878
    }
879

    
880
    @Override
881
    public Code subst(Code op1, Code op2) {
882
        return operator(OPERATOR_SUBST, op1, op2);
883
    }
884

    
885
    @Override
886
    public Code mult(Code op1, Code op2) {
887
        return operator(OPERATOR_MULT, op1, op2);
888
    }
889

    
890
    @Override
891
    public Code div(Code op1, Code op2) {
892
        return operator(OPERATOR_DIV, op1, op2);
893
    }
894

    
895
    @Override
896
    public Code mod(Code op1, Code op2) {
897
        BaseCodes args = args();
898
        args.add(op1);
899
        args.add(op2);
900
        return function(FUNCTION_MOD, args);
901
    }
902

    
903
    @Override
904
    public Code or(Code op1, Code op2) {
905
        return operator(OPERATOR_OR, op1, op2);
906
    }
907

    
908
    @Override
909
    public Code and(Code op1, Code op2) {
910
        return operator(OPERATOR_AND, op1, op2);
911
    }
912

    
913
    @Override
914
    public Code like(Code op1, Code op2) {
915
        return operator(OPERATOR_LIKE, op1, op2);
916
    }
917

    
918
    @Override
919
    public Code ilike(Code op1, Code op2) {
920
        return operator(OPERATOR_ILIKE, op1, op2);
921
    }
922

    
923
    @Override
924
    public Code regexp(Code op1, Code op2) {
925
        return operator(OPERATOR_REGEXP, op1, op2);
926
    }
927

    
928
    @Override
929
    public Code lt(Code op1, Code op2) {
930
        return operator(OPERATOR_LT, op1, op2);
931
    }
932

    
933
    @Override
934
    public Code gt(Code op1, Code op2) {
935
        return operator(OPERATOR_GT, op1, op2);
936
    }
937

    
938
    @Override
939
    public Code le(Code op1, Code op2) {
940
        return operator(OPERATOR_LE, op1, op2);
941
    }
942

    
943
    @Override
944
    public Code ge(Code op1, Code op2) {
945
        return operator(OPERATOR_GE, op1, op2);
946
    }
947

    
948
    @Override
949
    public Code eq(Code op1, Code op2) {
950
        return operator(OPERATOR_EQ, op1, op2);
951
    }
952

    
953
    @Override
954
    public Code ne(Code op1, Code op2) {
955
        return operator(OPERATOR_NE, op1, op2);
956
    }
957

    
958
    @Override
959
    public Code is(Code op1, Code op2) {
960
        return operator(OPERATOR_IS, op1, op2);
961
    }
962

    
963
    @Override
964
    public Code getattr(Code obj, String attrname) {
965
        BaseCodes args = args();
966
        args.add(obj);
967
        args.add(constant(attrname));
968
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
969
    }    
970

    
971
    @Override
972
    public Code getitem(Code obj, Code index) {
973
        BaseCodes args = args();
974
        args.add(obj);
975
        args.add(index);
976
        return function(FUNCTION_GETITEM, args);
977
    }
978

    
979
    @Override
980
    public Code dict(Map<String,Code>map ) {
981
        BaseCodes args = args();
982
        for (Map.Entry<String, Code> entry : map.entrySet()) {
983
            String key = entry.getKey();
984
            Code value = entry.getValue();
985
            args.add(constant(key));
986
            args.add(value);
987
        }
988
        return function(FUNCTION_DICT, args);
989
    }
990
    
991
    @Override
992
    public Code $HostExpression(Code obj, String mode_specifier) {
993
        BaseCodes args = args();
994
        args.add(obj);
995
        args.add(constant(mode_specifier));
996
        return function(ExpressionBuilder.FUNCTION_$HOSTEXPRESSION, args);
997
    }    
998

    
999
}