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