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

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