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

History | View | Annotate | Download (26.4 KB)

1 43512 jjdelcerro
package org.gvsig.expressionevaluator.impl;
2
3
import java.util.ArrayList;
4 44139 jjdelcerro
import java.util.Collections;
5 43512 jjdelcerro
import java.util.Iterator;
6
import java.util.List;
7 43519 jjdelcerro
import org.apache.commons.lang3.StringUtils;
8 44738 jjdelcerro
import org.apache.commons.lang3.tuple.ImmutablePair;
9
import org.apache.commons.lang3.tuple.Pair;
10 43512 jjdelcerro
import org.gvsig.expressionevaluator.Code;
11
import static org.gvsig.expressionevaluator.Code.CALLER;
12
import static org.gvsig.expressionevaluator.Code.CONSTANT;
13 44006 jjdelcerro
import static org.gvsig.expressionevaluator.Code.IDENTIFIER;
14
import static org.gvsig.expressionevaluator.Code.UNDEFINED;
15 44198 jjdelcerro
import static org.gvsig.expressionevaluator.Code.CODES;
16 43512 jjdelcerro
import org.gvsig.expressionevaluator.Code.Caller;
17
import org.gvsig.expressionevaluator.Code.Constant;
18 44198 jjdelcerro
import static org.gvsig.expressionevaluator.Code.EMPTY_FORMATTER;
19 43512 jjdelcerro
import org.gvsig.expressionevaluator.Code.Identifier;
20 43939 jjdelcerro
import org.gvsig.expressionevaluator.Code.Method;
21 44243 jjdelcerro
//import org.gvsig.expressionevaluator.Code.Method;
22 43512 jjdelcerro
import org.gvsig.expressionevaluator.CodeBuilder;
23 44139 jjdelcerro
import org.gvsig.expressionevaluator.Codes;
24 44198 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder;
25 44207 jjdelcerro
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ADD;
26
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_AND;
27
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_CONCAT;
28
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_DIV;
29
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_EQ;
30
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GE;
31
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_GT;
32
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ILIKE;
33
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_IS;
34
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LE;
35
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LIKE;
36
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_LT;
37
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_MOD;
38
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_MULT;
39
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NE;
40
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NEGATE;
41
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_NOT;
42
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_OR;
43
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_REGEXP;
44
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_SUBST;
45 44198 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder.Value;
46 44644 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
47 44198 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionUtils;
48
import org.gvsig.expressionevaluator.Formatter;
49 43512 jjdelcerro
import org.gvsig.expressionevaluator.Function;
50 43521 jjdelcerro
import org.gvsig.expressionevaluator.Interpreter;
51 44198 jjdelcerro
import org.gvsig.expressionevaluator.SymbolTable;
52 44139 jjdelcerro
import org.gvsig.expressionevaluator.impl.function.programming.GetitemFunction;
53 44389 jjdelcerro
import org.gvsig.tools.dynobject.DynObject;
54
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
55 43512 jjdelcerro
import org.gvsig.tools.exception.BaseException;
56
import org.gvsig.tools.visitor.Visitor;
57
58 44009 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
59 44198 jjdelcerro
public class DefaultCodeBuilder implements CodeBuilder {
60 43512 jjdelcerro
61 44198 jjdelcerro
    public abstract class BaseCode implements Code {
62 43512 jjdelcerro
63
        @Override
64
        public int code() {
65
            return UNDEFINED;
66
        }
67
68
        @Override
69
        public void accept(Visitor visitor) throws BaseException {
70
            visitor.visit(this);
71
        }
72
73 44198 jjdelcerro
        @Override
74
        public Value toValue(ExpressionBuilder builder) {
75
            return null;
76
        }
77
78
        @Override
79
        public Value toValue() {
80
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
81
            return this.toValue(builder);
82
        }
83
84
        @Override
85
        public void link(SymbolTable symbolTable) {
86
            if( this.code() == Code.CALLER ) {
87
                Caller caller = (Caller) this;
88 44620 jjdelcerro
                Function fn = symbolTable.function(caller.name());
89
                if( fn != null ) {
90
                    caller.function(fn);
91 44198 jjdelcerro
                }
92
                if( caller.parameters() != null ) {
93
                    for( Code arg : caller.parameters() ) {
94 44738 jjdelcerro
                        if( arg!=null ) {
95
                          arg.link(symbolTable);
96
                        }
97 44198 jjdelcerro
                    }
98
                }
99
            }
100
        }
101 43512 jjdelcerro
    }
102
103
    class BaseConstant extends BaseCode implements Constant {
104
105 44211 jjdelcerro
        private Object value;
106 43512 jjdelcerro
107
        public BaseConstant(Object value) {
108
            this.value = value;
109
        }
110
111
        @Override
112
        public int code() {
113
            return CONSTANT;
114
        }
115
116
        @Override
117
        public Object value() {
118
            return this.value;
119
        }
120
121 44211 jjdelcerro
        public void value(Object v) {
122
            this.value = v;
123
        }
124
125 43521 jjdelcerro
        @Override
126 44198 jjdelcerro
        public Value toValue(ExpressionBuilder builder) {
127
            return builder.constant(this.value);
128
        }
129
130
        @Override
131 43521 jjdelcerro
        public String toString() {
132 44198 jjdelcerro
            return this.toString(EMPTY_FORMATTER);
133
        }
134
135
        @Override
136
        public String toString(Formatter<Code> formatter) {
137
            if( formatter.canApply(this) ) {
138
                return formatter.format(this);
139
            }
140 43521 jjdelcerro
            Object v = this.value();
141 44644 jjdelcerro
            return manager.getReprMethod(v).repr(v);
142 43521 jjdelcerro
        }
143
144 43512 jjdelcerro
    }
145
146 44154 jjdelcerro
    public interface RecursionControlSupport {
147
148
        public boolean enterCode(int max);
149
150
        public void exitCode();
151
152
        public void resetRecursionState();
153
    }
154
155
    private class RecursionSupport implements RecursionControlSupport {
156
157
        private int counter;
158
159
        public RecursionSupport() {
160
            this.counter = 0;
161
        }
162 43512 jjdelcerro
163 44154 jjdelcerro
        @Override
164
        public boolean enterCode(int max) {
165
            this.counter += 1;
166
            return this.counter < max;
167
        }
168 43512 jjdelcerro
169 44154 jjdelcerro
        @Override
170
        public void exitCode() {
171
            this.counter -= 1;
172
        }
173
174
        @Override
175
        public void resetRecursionState() {
176
            this.counter = 0;
177
        }
178
179
    }
180
181
    public class BaseIdentifier extends BaseCode implements Identifier, RecursionControlSupport {
182
183 44198 jjdelcerro
        private final String name;
184
        private final RecursionSupport recursionSupport;
185 44154 jjdelcerro
186 43512 jjdelcerro
        public BaseIdentifier(String name) {
187
            this.name = name;
188 44154 jjdelcerro
            this.recursionSupport = new RecursionSupport();
189 43512 jjdelcerro
        }
190
191
        @Override
192
        public int code() {
193
            return IDENTIFIER;
194
        }
195
196
        @Override
197
        public String name() {
198
            return this.name;
199
        }
200
201 43521 jjdelcerro
        @Override
202 44198 jjdelcerro
        public Value toValue(ExpressionBuilder builder) {
203
            return builder.variable(this.name);
204
        }
205
206
        @Override
207 43521 jjdelcerro
        public String toString() {
208 44198 jjdelcerro
            return this.toString(EMPTY_FORMATTER);
209
        }
210
211
        @Override
212
        public String toString(Formatter<Code> formatter) {
213
            if( formatter.canApply(this) ) {
214
                return formatter.format(this);
215
            }
216 43521 jjdelcerro
            StringBuilder builder = new StringBuilder();
217 44006 jjdelcerro
            builder.append("\"");
218 43521 jjdelcerro
            builder.append(this.name());
219 44006 jjdelcerro
            builder.append("\"");
220 43521 jjdelcerro
            return builder.toString();
221
        }
222
223 44154 jjdelcerro
        @Override
224
        public boolean enterCode(int max) {
225
            return this.recursionSupport.enterCode(max);
226
        }
227
228
        @Override
229
        public void exitCode() {
230
            this.recursionSupport.exitCode();
231
        }
232
233
        @Override
234
        public void resetRecursionState() {
235
            this.recursionSupport.resetRecursionState();
236
        }
237
238 43512 jjdelcerro
    }
239
240 44139 jjdelcerro
    public class BaseCodes implements Codes {
241 43512 jjdelcerro
242 44738 jjdelcerro
        private final List<Pair<String,Code>> codes;
243
        private boolean useNames;
244 43512 jjdelcerro
245 44139 jjdelcerro
        public BaseCodes() {
246
            this.codes = new ArrayList<>();
247 44738 jjdelcerro
            this.useNames = false;
248 43512 jjdelcerro
        }
249
250
        @Override
251 44738 jjdelcerro
        public boolean useArgNames() {
252
          return this.useNames;
253
        }
254
255
        @Override
256
        public boolean useArgNames(boolean useNames) {
257
          this.useNames = useNames;
258
          return this.useNames;
259
        }
260
261
        @Override
262 44198 jjdelcerro
        public int code() {
263
            return CODES;
264
        }
265
266
        @Override
267 44139 jjdelcerro
        public int size() {
268
            if( codes == null ) {
269 43512 jjdelcerro
                return 0;
270
            }
271 44139 jjdelcerro
            return this.codes.size();
272 43512 jjdelcerro
        }
273
274 44748 jjdelcerro
        public void add(String name, Code parameter) {
275
          if( !StringUtils.isBlank(name) ) {
276
            for (int i = 0; i < codes.size(); i++) {
277
              Pair<String, Code> arg = codes.get(i);
278
              if( StringUtils.equalsIgnoreCase(name, arg.getKey()) ) {
279
                codes.set(i, new ImmutablePair<>(name, parameter));
280
                return;
281
              }
282
            }
283
          }
284
          this.codes.add(new ImmutablePair<>(name, parameter));
285 44738 jjdelcerro
        }
286
287 43512 jjdelcerro
        public void add(Code arg) {
288 44738 jjdelcerro
            this.codes.add(new ImmutablePair<>(null, arg));
289 43512 jjdelcerro
        }
290
291 44243 jjdelcerro
        public void insert(int pos, Code arg) {
292 44738 jjdelcerro
            this.codes.add(pos, new ImmutablePair<>(null, arg));
293 44243 jjdelcerro
        }
294
295 43512 jjdelcerro
        @Override
296 44748 jjdelcerro
        public boolean contains(String name) {
297
          for (Pair<String, Code> arg : this.codes) {
298
            if( StringUtils.equalsIgnoreCase(arg.getKey(), name) ) {
299
              return true;
300
            }
301
          }
302
          return false;
303
        }
304
305
        @Override
306 44738 jjdelcerro
        public boolean contains(String name, int index) {
307
          String argNameX = name + String.valueOf(index).trim();
308
          for (Pair<String, Code> arg : this.codes) {
309
            if( StringUtils.equalsIgnoreCase(arg.getKey(), argNameX) ) {
310
              return true;
311
            }
312
          }
313
          return false;
314
        }
315
316
        @Override
317 43512 jjdelcerro
        public Iterator<Code> iterator() {
318 44738 jjdelcerro
          final Iterator<Pair<String, Code>> it = this.codes.iterator();
319
          return new Iterator<Code>() {
320
            @Override
321
            public boolean hasNext() {
322
              return it.hasNext();
323
            }
324
325
            @Override
326
            public Code next() {
327
              Pair<String, Code> arg = it.next();
328
              return arg.getValue();
329
            }
330
          };
331 43512 jjdelcerro
        }
332
333
        @Override
334
        public Code get(int n) {
335 44738 jjdelcerro
            return this.codes.get(n).getValue();
336 43512 jjdelcerro
        }
337
338
        @Override
339 44738 jjdelcerro
        public Code get(String name) {
340
          for (Pair<String, Code> arg : this.codes) {
341
            if( StringUtils.equalsIgnoreCase(name, arg.getKey()) ) {
342
              return arg.getValue();
343
            }
344
          }
345
          return null;
346
        }
347
348 44748 jjdelcerro
        @Override
349 44738 jjdelcerro
        public String getName(int n) {
350
            return this.codes.get(n).getKey();
351
        }
352
353
        @Override
354 44139 jjdelcerro
        public boolean isEmpty() {
355
            return this.codes.isEmpty();
356
        }
357
358
        @Override
359
        public List<Code> toList() {
360 44738 jjdelcerro
            List<Code> l = new ArrayList<>();
361
            for (Pair<String, Code> arg : this.codes) {
362
              l.add(arg.getValue());
363
            }
364
            return Collections.unmodifiableList(l);
365 44139 jjdelcerro
        }
366
367
        @Override
368 43512 jjdelcerro
        public void accept(Visitor visitor) throws BaseException {
369 44738 jjdelcerro
            for( Pair<String,Code> arg : this.codes ) {
370
                arg.getValue().accept(visitor);
371 43512 jjdelcerro
            }
372
        }
373
374 43521 jjdelcerro
        @Override
375
        public String toString() {
376 44198 jjdelcerro
            return this.toString(EMPTY_FORMATTER);
377
        }
378
379
        @Override
380
        public Value toValue(ExpressionBuilder builder) {
381
            throw new UnsupportedOperationException();
382
        }
383
384
        @Override
385
        public Value toValue() {
386
            throw new UnsupportedOperationException();
387
        }
388
389
        @Override
390
        public String toString(Formatter<Code> formatter) {
391
            if( formatter.canApply(this) ) {
392
                return formatter.format(this);
393
            }
394 44139 jjdelcerro
            if( codes != null ) {
395 43521 jjdelcerro
                StringBuilder builder = new StringBuilder();
396
                boolean skipcoma = true;
397 44738 jjdelcerro
                for( Pair<String, Code> arg : codes ) {
398
                    if( arg == null ) {
399
                      continue;
400
                    }
401
                    String name = arg.getKey();
402
                    Code code = arg.getValue();
403 44139 jjdelcerro
                    if( code == null ) {
404
                        continue;
405
                    }
406 43521 jjdelcerro
                    if( skipcoma ) {
407
                        skipcoma = false;
408
                    } else {
409
                        builder.append(", ");
410
                    }
411 44738 jjdelcerro
                    if( name==null || !useNames ) {
412
                        builder.append(code.toString(formatter));
413
                    } else {
414
                        builder.append(name);
415
                        builder.append(":");
416
                        builder.append(code.toString(formatter));
417
                    }
418 43521 jjdelcerro
                }
419
                return builder.toString();
420
            }
421
            return "";
422
        }
423
424 44198 jjdelcerro
        @Override
425
        public void link(SymbolTable symbolTable) {
426 44738 jjdelcerro
            for (Pair<String,Code> arg : this.codes) {
427
                arg.getValue().link(symbolTable);
428 44198 jjdelcerro
            }
429
        }
430
431 43512 jjdelcerro
    }
432
433 44154 jjdelcerro
    public class BaseCaller extends BaseCode implements Caller, RecursionControlSupport {
434 43512 jjdelcerro
435
        private final String name;
436 44139 jjdelcerro
        private final Codes args;
437 43512 jjdelcerro
        private Function function;
438
        private final int type;
439 44198 jjdelcerro
        private final RecursionSupport recursionSupport;
440 43512 jjdelcerro
441 44139 jjdelcerro
        public BaseCaller(String name, int type, Codes args) {
442 43512 jjdelcerro
            this.name = name;
443
            this.args = args;
444
            this.type = type;
445
            this.function = null;
446 44154 jjdelcerro
            this.recursionSupport = new RecursionSupport();
447 43512 jjdelcerro
        }
448
449
        @Override
450
        public int code() {
451
            return CALLER;
452
        }
453
454
        @Override
455 43521 jjdelcerro
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
456
            return this.function.call(interpreter, args);
457 43512 jjdelcerro
        }
458
459
        @Override
460
        public String name() {
461
            return this.name;
462
        }
463
464
        @Override
465
        public Function function() {
466
            return this.function;
467
        }
468
469
        @Override
470
        public Function function(Function function) {
471
            this.function = function;
472 44738 jjdelcerro
            if( this.args!=null && this.function!=null ) {
473
              this.args.useArgNames(this.function.allowArgNames());
474
            }
475 43512 jjdelcerro
            return this.function;
476
        }
477
478
        @Override
479 44198 jjdelcerro
        public Codes parameters() {
480 43512 jjdelcerro
            return this.args;
481
        }
482
483
        @Override
484
        public int type() {
485
            return this.type;
486
        }
487
488
        @Override
489
        public void accept(Visitor visitor) throws BaseException {
490
            visitor.visit(this);
491 44052 omartinez
            if(this.args!=null) {
492
                this.args.accept(visitor);
493
            }
494 43512 jjdelcerro
        }
495
496 43521 jjdelcerro
        @Override
497 44198 jjdelcerro
        public Value toValue(ExpressionBuilder builder) {
498
            switch(this.type) {
499
                case UNARY_OPERATOR:
500
                    return builder.function(
501 44207 jjdelcerro
                            OPERATOR_NEGATE.equalsIgnoreCase(this.name())?
502 44198 jjdelcerro
                                "-" :
503
                                this.name(),
504
                            this.parameters().get(0).toValue(builder)
505
                    );
506
                case BINARY_OPERATOR:
507
                    return builder.binaryOperator(
508
                            this.name(),
509
                            this.parameters().get(0).toValue(builder),
510
                            this.parameters().get(1).toValue(builder)
511
                    );
512
                case FUNCTION:
513
                default:
514
                    ExpressionBuilder.Function f = builder.function(this.name());
515
                    if( this.parameters()!=null ) {
516
                        for (Code parameter : this.parameters()) {
517
                            f.parameter(parameter.toValue(builder));
518
                        }
519
520
                    }
521
                    return f;
522
523
            }
524
        }
525
526
        @Override
527 43521 jjdelcerro
        public String toString() {
528 44198 jjdelcerro
            return this.toString(EMPTY_FORMATTER);
529
        }
530
531
        @Override
532
        public String toString(Formatter<Code> formatter) {
533
            if( formatter.canApply(this) ) {
534
                return formatter.format(this);
535
            }
536 44379 jjdelcerro
            Code code;
537 43521 jjdelcerro
            StringBuilder builder = new StringBuilder();
538 44198 jjdelcerro
            switch(this.type) {
539
                case UNARY_OPERATOR:
540 44207 jjdelcerro
                    if( OPERATOR_NEGATE.equalsIgnoreCase(this.name()) ) {
541 44198 jjdelcerro
                        builder.append("-");
542
                    } else {
543
                        builder.append(this.name());
544
                    }
545
                    builder.append("(");
546
                    builder.append(this.parameters().get(0).toString(formatter));
547
                    builder.append(")");
548
                    break;
549
                case BINARY_OPERATOR:
550
                    builder.append("(");
551 44379 jjdelcerro
                    code = this.parameters().get(0);
552
                    if( code == null ) {
553
                        builder.append("?NULL?");
554
                    } else {
555
                        builder.append(code.toString(formatter));
556
                    }
557 44198 jjdelcerro
                    builder.append(" ");
558
                    builder.append(this.name());
559
                    builder.append(" ");
560 44379 jjdelcerro
                    code = this.parameters().get(1);
561
                    if( code == null ) {
562
                        builder.append("?NULL?");
563
                    } else {
564
                        builder.append(code.toString(formatter));
565
                    }
566 44198 jjdelcerro
                    builder.append(")");
567
                    break;
568
                case FUNCTION:
569
                default:
570 44748 jjdelcerro
                    if( StringUtils.equalsIgnoreCase(this.name(),ExpressionBuilder.FUNCTION_GETATTR) ) {
571 44738 jjdelcerro
                      Code arg0 = this.parameters().get(0);
572
                      Code arg1 = this.parameters().get(1);
573
                      if( arg0 instanceof Code.Identifier && arg1 instanceof Code.Constant ) {
574
                        builder.append(arg0.toString(formatter));
575
                        builder.append(".\"");
576
                        builder.append(((Code.Constant)arg1).value());
577
                        builder.append("\"");
578
                      } else {
579
                        builder.append(this.name());
580
                        builder.append("(");
581
                        builder.append(arg0.toString(formatter));
582
                        builder.append(", ");
583
                        builder.append(arg1.toString(formatter));
584
                        builder.append(")");
585
                      }
586
                    } else {
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 44198 jjdelcerro
                    }
594 43521 jjdelcerro
            }
595
            return builder.toString();
596
        }
597
598 44154 jjdelcerro
        @Override
599
        public boolean enterCode(int max) {
600
            return this.recursionSupport.enterCode(max);
601
        }
602
603
        @Override
604
        public void exitCode() {
605
            this.recursionSupport.exitCode();
606
        }
607
608
        @Override
609
        public void resetRecursionState() {
610
            this.recursionSupport.resetRecursionState();
611
        }
612 43512 jjdelcerro
    }
613
614 44243 jjdelcerro
    public class BaseMethod extends BaseCode implements Method {
615 43939 jjdelcerro
616 44243 jjdelcerro
        private final Code instance;
617 43939 jjdelcerro
        private final String methodname;
618 44243 jjdelcerro
        private final Codes args;
619 43939 jjdelcerro
620 44243 jjdelcerro
        public BaseMethod(Code instance, String methodname, Codes args) {
621
            this.instance = instance;
622 43939 jjdelcerro
            this.methodname = methodname;
623 44243 jjdelcerro
            this.args = args;
624 43939 jjdelcerro
        }
625
626
        @Override
627
        public int code() {
628
            return METHOD;
629
        }
630
631
        @Override
632
        public String methodname() {
633
            return this.methodname;
634
        }
635
636
        @Override
637 44243 jjdelcerro
        public Code instance() {
638
            return this.instance;
639 43939 jjdelcerro
        }
640
641
        @Override
642 44243 jjdelcerro
        public Codes parameters() {
643
            return this.args;
644
        }
645
646
        @Override
647
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
648
            Object theInstance = interpreter.run(instance);
649 44389 jjdelcerro
            if( theInstance instanceof SimpleScript ) {
650
                try {
651
                    return ((SimpleScript)theInstance).invokeFunction(methodname, args);
652
                } catch(NoSuchMethodException ex) {
653
                    // Ignore... continue calling instance method
654
                }
655
            } else if( theInstance instanceof DynObject ) {
656
                DynObject dynobj = (DynObject) theInstance;
657
                try {
658
                    return dynobj.invokeDynMethod(methodname, args);
659
                } catch(DynMethodNotSupportedException ex) {
660
                    // Ignore... continue calling instance method
661
                }
662
            }
663 44243 jjdelcerro
            return InstanceUtils.callmethod(theInstance, methodname, args);
664
        }
665
666
        @Override
667 43939 jjdelcerro
        public String toString() {
668 44198 jjdelcerro
            return this.toString(EMPTY_FORMATTER);
669
        }
670
671
        @Override
672
        public Value toValue(ExpressionBuilder builder) {
673 44243 jjdelcerro
            ExpressionBuilder.Method m = builder.method(this.instance.toValue(builder), this.methodname);
674 44198 jjdelcerro
            if( this.parameters()!=null ) {
675
                for (Code parameter : this.parameters()) {
676
                    m.parameter(parameter.toValue(builder));
677
                }
678
            }
679
            return m;
680
        }
681
682
        @Override
683
        public String toString(Formatter<Code> formatter) {
684
            if( formatter.canApply(this) ) {
685
                return formatter.format(this);
686
            }
687 43939 jjdelcerro
            StringBuilder builder = new StringBuilder();
688 44243 jjdelcerro
            builder.append(this.instance.toString(formatter));
689 43939 jjdelcerro
            builder.append("->");
690
            builder.append(this.methodname());
691
            builder.append("(");
692 44198 jjdelcerro
            if( this.parameters()!=null ) {
693
                builder.append(this.parameters().toString(formatter));
694 43939 jjdelcerro
            }
695
            builder.append(")");
696
            return builder.toString();
697
        }
698 44243 jjdelcerro
699
700 43939 jjdelcerro
    }
701 44644 jjdelcerro
702
    protected ExpressionEvaluatorManager manager;
703 43939 jjdelcerro
704 44644 jjdelcerro
    public DefaultCodeBuilder(ExpressionEvaluatorManager manager) {
705
        this.manager = manager;
706
    }
707
708 43512 jjdelcerro
    @Override
709 43809 jjdelcerro
    public CodeBuilder clone() throws CloneNotSupportedException {
710
        // This implementation of CodeBuilder does not maintain state, so
711
        // we only call the super class.
712
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
713
        return other;
714
    }
715
716
    @Override
717 43512 jjdelcerro
    public Constant constant(Object value) {
718
        return new BaseConstant(value);
719
    }
720
721
    @Override
722
    public Identifier identifier(String name) {
723
        return new BaseIdentifier(name);
724
    }
725
726
    @Override
727 44139 jjdelcerro
    public BaseCodes args() {
728
        return new BaseCodes();
729 43512 jjdelcerro
    }
730
731
    @Override
732 44139 jjdelcerro
    public Caller function(String name, int type, Codes args) {
733 43512 jjdelcerro
        return new BaseCaller(name, type, args);
734
    }
735
736
    @Override
737 44139 jjdelcerro
    public Caller function(String name, Codes args) {
738 43512 jjdelcerro
        return function(name, Caller.FUNCTION, args);
739
    }
740 43939 jjdelcerro
741 43512 jjdelcerro
    @Override
742 44243 jjdelcerro
    public Code method(Code instance, String methodname, Codes methodargs) {
743
        Method m = new BaseMethod(instance, methodname, methodargs);
744 43939 jjdelcerro
        return m;
745
    }
746
747
    @Override
748 43512 jjdelcerro
    public Caller operator(String name, Code arg1) {
749 44139 jjdelcerro
        BaseCodes args = args();
750
        args.add(arg1);
751 43512 jjdelcerro
        return function(name, Caller.UNARY_OPERATOR, args);
752
    }
753
754
    @Override
755
    public Caller operator(String name, Code arg1, Code arg2) {
756 44139 jjdelcerro
        BaseCodes args = args();
757
        args.add(arg1);
758
        args.add(arg2);
759 43512 jjdelcerro
        return function(name, Caller.BINARY_OPERATOR, args);
760
    }
761 44198 jjdelcerro
762 43512 jjdelcerro
    @Override
763
    public Code not(Code op1) {
764 44207 jjdelcerro
        return operator(OPERATOR_NOT, op1);
765 43512 jjdelcerro
    }
766
767
    @Override
768 44098 jjdelcerro
    public Code negate(Code op1) {
769 44207 jjdelcerro
        return operator(OPERATOR_NEGATE, op1);
770 44098 jjdelcerro
    }
771
772
    @Override
773 44139 jjdelcerro
    public Code concat(Code op1, Code op2) {
774 44207 jjdelcerro
        return operator(OPERATOR_CONCAT, op1, op2);
775 44139 jjdelcerro
    }
776
777
    @Override
778 43512 jjdelcerro
    public Code add(Code op1, Code op2) {
779 44207 jjdelcerro
        return operator(OPERATOR_ADD, op1, op2);
780 43512 jjdelcerro
    }
781
782
    @Override
783
    public Code subst(Code op1, Code op2) {
784 44207 jjdelcerro
        return operator(OPERATOR_SUBST, op1, op2);
785 43512 jjdelcerro
    }
786
787
    @Override
788
    public Code mult(Code op1, Code op2) {
789 44207 jjdelcerro
        return operator(OPERATOR_MULT, op1, op2);
790 43512 jjdelcerro
    }
791
792
    @Override
793
    public Code div(Code op1, Code op2) {
794 44207 jjdelcerro
        return operator(OPERATOR_DIV, op1, op2);
795 43512 jjdelcerro
    }
796
797
    @Override
798
    public Code mod(Code op1, Code op2) {
799 44207 jjdelcerro
        return operator(OPERATOR_MOD, op1, op2);
800 43512 jjdelcerro
    }
801
802
    @Override
803
    public Code or(Code op1, Code op2) {
804 44207 jjdelcerro
        return operator(OPERATOR_OR, op1, op2);
805 43512 jjdelcerro
    }
806
807
    @Override
808
    public Code and(Code op1, Code op2) {
809 44207 jjdelcerro
        return operator(OPERATOR_AND, op1, op2);
810 43512 jjdelcerro
    }
811
812
    @Override
813
    public Code like(Code op1, Code op2) {
814 44207 jjdelcerro
        return operator(OPERATOR_LIKE, op1, op2);
815 43512 jjdelcerro
    }
816
817
    @Override
818
    public Code ilike(Code op1, Code op2) {
819 44207 jjdelcerro
        return operator(OPERATOR_ILIKE, op1, op2);
820 43512 jjdelcerro
    }
821
822
    @Override
823 43532 jjdelcerro
    public Code regexp(Code op1, Code op2) {
824 44207 jjdelcerro
        return operator(OPERATOR_REGEXP, op1, op2);
825 43532 jjdelcerro
    }
826
827
    @Override
828 43512 jjdelcerro
    public Code lt(Code op1, Code op2) {
829 44207 jjdelcerro
        return operator(OPERATOR_LT, op1, op2);
830 43512 jjdelcerro
    }
831
832
    @Override
833
    public Code gt(Code op1, Code op2) {
834 44207 jjdelcerro
        return operator(OPERATOR_GT, op1, op2);
835 43512 jjdelcerro
    }
836
837
    @Override
838
    public Code le(Code op1, Code op2) {
839 44207 jjdelcerro
        return operator(OPERATOR_LE, op1, op2);
840 43512 jjdelcerro
    }
841
842
    @Override
843
    public Code ge(Code op1, Code op2) {
844 44207 jjdelcerro
        return operator(OPERATOR_GE, op1, op2);
845 43512 jjdelcerro
    }
846
847
    @Override
848
    public Code eq(Code op1, Code op2) {
849 44207 jjdelcerro
        return operator(OPERATOR_EQ, op1, op2);
850 43512 jjdelcerro
    }
851
852
    @Override
853
    public Code ne(Code op1, Code op2) {
854 44207 jjdelcerro
        return operator(OPERATOR_NE, op1, op2);
855 43512 jjdelcerro
    }
856
857
    @Override
858
    public Code is(Code op1, Code op2) {
859 44207 jjdelcerro
        return operator(OPERATOR_IS, op1, op2);
860 43512 jjdelcerro
    }
861
862 43939 jjdelcerro
    @Override
863
    public Code getattr(Code obj, String attrname) {
864 44139 jjdelcerro
        BaseCodes args = args();
865
        args.add(obj);
866
        args.add(constant(attrname));
867 44748 jjdelcerro
        return function(ExpressionBuilder.FUNCTION_GETATTR, args);
868 43939 jjdelcerro
    }
869
870 44139 jjdelcerro
    @Override
871
    public Code getitem(Code obj, Code index) {
872
        BaseCodes args = args();
873
        args.add(obj);
874
        args.add(index);
875
        return function(GetitemFunction.NAME, args);
876
    }
877
878
879 44198 jjdelcerro
880 43512 jjdelcerro
}