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

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