Source code: org/media/mn8/parser/mn8TreeWalker.java
1 // $ANTLR 2.7.1: "mn8TreeWalker.g" -> "mn8TreeWalker.java"$
2
3 package org.media.mn8.parser;
4
5 import org.media.mn8.*;
6 import org.media.mn8.event.*;
7 import org.media.mn8.concepts.*;
8 import java.util.Vector;
9 import java.util.Hashtable;
10 import java.util.Stack;
11 import java.lang.Thread;
12 import antlr.*;
13
14 import java.io.PrintStream;
15
16 import antlr.TreeParser;
17 import antlr.Token;
18 import antlr.collections.AST;
19 import antlr.RecognitionException;
20 import antlr.ANTLRException;
21 import antlr.NoViableAltException;
22 import antlr.MismatchedTokenException;
23 import antlr.SemanticException;
24 import antlr.collections.impl.BitSet;
25 import antlr.ASTPair;
26 import antlr.collections.impl.ASTArray;
27
28
29 /**
30 * The final Tree Walker for mn8. This is responsible
31 * of the interpretation.<br>
32 * This class is automaticaly generated by
33 * <a href="http://www.antlr.org">ANTLR</a>.
34 * @author <a href="mailto:remus@nolimits.ro">Remus Pereni</a>
35 * @version $Revision: 1.89 $ $Date: 2002/10/18 22:20:03 $
36 */
37 public class mn8TreeWalker extends antlr.TreeParser
38 implements mn8TreeWalkerTokenTypes
39 {
40
41 /** Are we in debug or not */
42 boolean debug = mn8RuntimeFlags.isDebug();
43
44 /** Are ve in verbose or not */
45 boolean verbose = mn8RuntimeFlags.isVerbose();
46
47 /** The current scope stack */
48 private ScopeStack _stack = null;
49
50 private Hashtable _firstOfTable = new Hashtable();
51
52 public static int lineNr = -1;
53
54 /** Flag indicating if the interpretor is ready to return or not.
55 */
56 public boolean readyToReturn = false;
57
58 /** The currently executing concept. Important for runtime information
59 * like is the current method static, and so on.
60 */
61 private mn8Concept _thisConcept = null;
62
63 /** The currently executing method. Important for runtime information
64 * like is the current method static, and so on.
65 */
66 private mn8ScriptMethod _thisMethod = null;
67
68 private Vector superList = null;
69
70 /** The currently executing script name, important for error reporting
71 */
72 private String _scriptName = mn8Loader.getScriptName();
73
74 private ElementConcept _previousElem = null;
75
76 /** The curent code line number for error reporting.
77 */
78 private int _curentLineNr = 0;
79
80 private Stack _eachLevel = new Stack();
81
82 private Stack _eachBySignature = new Stack();
83
84 /** The current output stream. Important only if we run it
85 * in an multithreaded environment (servlet for instance).
86 */
87 private PrintStream _out = null;
88
89 /** The current error stream. Important only if we run it
90 * in an multithreaded environment (servlet for instance).
91 */
92 private PrintStream _err = null;
93
94 /** When we enter a scope we keep track of how deep we are
95 * this is important because if we have to leave (return, exit)
96 * then we have to pop out the scopes
97 */
98 private int _scopeDeep = 0;
99
100 /** Indicates whenever an method is invoked on the SUPER keyword */
101 private boolean _isSuperInvocation = false;
102
103 private static final int CALL_CIRCUMSTANCE_INST_THIS = 0;
104
105 private static final int CALL_CIRCUMSTANCE_INST_PARENT = 1;
106
107 private static final int CALL_CIRCUMSTANCE_STATIC = 2;
108
109 private static final int CALL_CIRCUMSTANCE_SUPER = 3;
110
111 private static final int CALL_CIRCUMSTANCE_STATIC_PARENT = 4;
112
113 public void exit() {
114 readyToReturn = true;
115 }
116
117
118 public void reportWarning( String message ) {
119 System.err.println("__debug:" + message);
120 }
121
122
123 public void reportError( String message ) {
124 System.err.println("__debug:" + message);
125 }
126
127
128 private void setLineNr(int lineNr) {
129 this.lineNr = lineNr;
130 _curentLineNr = lineNr;
131 }
132
133
134 private void addByToSignatureStack(String bySig) {
135 _eachBySignature.setElementAt(_eachBySignature.peek().toString() + " " + bySig + " ",
136 _eachBySignature.size()-1);
137 }
138
139
140 private int getByEachIndex( String bySig ) {
141 for( int i = _eachBySignature.size() -1; i >= 0 ; i--) {
142 if( _eachBySignature.elementAt(i).toString().indexOf(" " + bySig + " ") >= 0){
143 return i;
144 }
145 }
146 return -1;
147 }
148
149 public ScopeStack getStack() {
150 return _stack;
151 }
152
153
154 boolean checkExpression( AST expr ) throws RecognitionException {
155 Concept concept = expression( expr );
156 if( concept instanceof LogicalConcept ) {
157 return ((LogicalConcept) concept).getValue();
158 } else {
159 LogicalConcept logValue = null;
160 if( concept.hasConceptMethod(new StringConcept("toLogicalConcept:")).getValue()) {
161 logValue = (LogicalConcept) executeMethod("toLogicalConcept:", concept, null);
162 }
163 if( logValue != null ) {
164 return logValue.getValue();
165 }
166 else {
167 throw new NotLogicalExpressionException (concept.getConceptType().getValue(), expr.getLine());
168 }
169 }
170 }
171
172
173 Concept executeOp(String op, JavaConcept op1, JavaConcept op2, int line)
174 throws RecognitionException {
175 Concept result = new NilConcept();
176 mn8Method method = getConceptDefinition(op1).getConceptOperator(op + ":"
177 + op2.getConceptType().getValue());
178 if( method == null ) {
179 throw new RecognitionException("Unsuported operation: " +
180 op1.getConceptType().getValue() + " " + op + " " +
181 op2.getConceptType().getValue(), "", line );
182 } else {
183 SeriesConcept param = new SeriesConcept();
184 param.getVector().add(op2);
185 result = method.invoke( op1, (SeriesConcept)param.clone() );
186 return result;
187 }
188 }
189
190
191 Concept executeOp(String op, JavaConcept op1, int line)
192 throws RecognitionException {
193 Concept result = new NilConcept();
194 mn8Method method = getConceptDefinition(op1).getConceptOperator(op + ":");
195 if( method == null ) {
196 throw new RecognitionException("Unsuported operation: " +
197 op1.getConceptType().getValue() + " " + op,
198 "", line );
199 } else {
200 SeriesConcept param = new SeriesConcept();
201 result = method.invoke( op1, (SeriesConcept)param.clone() );
202 return result;
203 }
204 }
205
206
207 public static ConceptDefinition getConceptDefinition(Concept forConcept) {
208 return mn8Loader.getConceptDefinition( forConcept.getConceptType().getValue() );
209 }
210
211
212 public Concept executeStaticMethod( String methodSig, String concetType, SeriesConcept param) {
213 return executeStaticMethod(methodSig, concetType, param, _curentLineNr);
214 }
215
216
217 public static Concept executeStaticMethod (String methodSig, String conceptType, SeriesConcept param, int lineNr) {
218 Concept result = null;
219 ConceptDefinition concDef = mn8Loader.getConceptDefinition( conceptType );
220 mn8Method method = null;
221
222 if( !methodSig.trim().toLowerCase().startsWith("create:") ) {
223 method = concDef.getConceptMethod( methodSig.toLowerCase() );
224 } else {
225 Concept instance = mn8Loader.getConceptDefinition(conceptType).getConceptInstance();
226 return executeMethod(methodSig, instance, param, lineNr);
227 }
228
229
230 if( method != null && method.isStatic().getValue()) {
231 method.setLineNr(lineNr);
232 result = method.invoke( conceptType, param == null ? null : (SeriesConcept)param.clone() );
233 return result;
234 } else {
235 throw new NotStaticMethodException( conceptType, methodSig);
236 }
237 }
238
239
240 public Concept executeMethod(String methodSig, Concept on, SeriesConcept param) {
241 return executeMethod( methodSig, on, param, _curentLineNr);
242 }
243
244
245 public static Concept executeMethod(String methodSig, Concept on, SeriesConcept param, int lineNr) {
246 Concept result = null;
247 mn8Method method = null;
248
249 if( !methodSig.trim().toLowerCase().startsWith("create:") ) {
250 method = getConceptDefinition(on).getConceptMethod( methodSig.toLowerCase() );
251 } else {
252 method = getConceptDefinition(on).getConceptConstructor( methodSig.toLowerCase() );
253 }
254
255 if( method != null ) {
256 method.setLineNr(lineNr);
257 result = method.invoke( on, param == null ? null : (SeriesConcept)param.clone() );
258 return result;
259 } else {
260 throw new MethodNotFoundException( on.getConceptType().toString(), methodSig);
261 }
262 }
263
264
265 public Concept executeInheritedMethod(String inhConceptType, String methodSig, Concept on, SeriesConcept param) {
266 Concept result = null;
267 mn8Method method = null;
268
269 if( methodSig.trim().toLowerCase().startsWith("create:") ) {
270 method = mn8Loader.getConceptDefinition(inhConceptType).getConceptConstructor( methodSig.toLowerCase() );
271 } else {
272 method = mn8Loader.getConceptDefinition(inhConceptType).getConceptMethod( methodSig.toLowerCase() );
273 }
274
275 if( method != null ) {
276 method.setLineNr(_curentLineNr);
277 result = method.invoke( on, param == null ? null : (SeriesConcept)param.clone() );
278 return result;
279 } else {
280 throw new MethodNotFoundException( on.getConceptType().toString(), methodSig);
281 }
282 }
283
284
285 public Concept resolveIdentifier( AST i) {
286 Concept result = null;
287 if( verbose ) _err.println("Resolving identifier :" + i.getText());
288 if( i.getText().startsWith("$") ) {
289 if( _stack.isInstance( i.getText() ))
290 result = _stack.getInstance( i.getText());
291 else {
292 _stack.insertInstance( i.getText(), new NilConcept() );
293 result = _stack.getInstance( i.getText());
294 }
295 }
296 return result;
297 }
298
299
300 public void cleanFirstOfTableElements(Vector by) {
301 if( by == null) return;
302
303 for(int i = 0 ; i < by.size() ; i++)
304 _firstOfTable.remove( getIdentifierSignature( (AST) by.elementAt(i)));
305 }
306
307
308 private boolean isAscending( AST node ) {
309 if( node.getText().toLowerCase().equals("ascending") )
310 return true;
311 else
312 return false;
313 }
314
315
316 private String getIdentifierSignature ( AST node ) {
317 String result = null;
318
319 AST child = node.getFirstChild();
320 result = child.getText();
321 child = child.getFirstChild();
322 while( child != null ) {
323
324 if( child.getType() == mn8TokenTypes.METH ) {
325 child = child.getFirstChild();
326 result += "." + child.getText();
327 }
328
329 // ELEM
330 // + -- elemName (1- getFirstChild)
331 // + -- ELEM_VALREF ? (2 - getNextSibling)
332 // + -- ELEM ... (3 - getNextSibling)
333 if( child != null && child.getType() == mn8TokenTypes.ELEM ){
334 child = child.getFirstChild(); // 1
335 result += "/" + child.getText();
336 if( child.getNextSibling() != null && child.getNextSibling().getType() == mn8TokenTypes.ELEM_VALREF ) {
337 if( !( child.getNextSibling().getNextSibling() != null && child.getNextSibling().getNextSibling().getType() == mn8TokenTypes.ELEM) ) {
338 result += "/";
339 }
340 child = child.getNextSibling();
341 }
342
343 }
344
345 if( child != null && child.getType() == mn8TokenTypes.ATTR ){
346 child = child.getFirstChild();
347 result += "@" + child.getText();
348 }
349
350 if( child != null ) child = child.getNextSibling();
351 }
352 return result;
353 }
354
355
356 private SeriesConcept sort(SeriesConcept what, Vector by) throws RecognitionException {
357 Vector sortVect = what.getVector();
358 if( sortVect == null || sortVect.size() < 2 ) {
359 return what;
360 }
361
362 if( isAscending( (AST)by.elementAt(0) )) {
363 sortVect = quickSort(sortVect, by, 0, 0, sortVect.size() -1);
364 } else {
365 sortVect = quickSortDescending(sortVect, by, 0, 0, sortVect.size()-1);
366 }
367
368 sortVect= deepSort(sortVect, by, 0, 0, sortVect.size()-1);
369 computeFirstOfPositions(sortVect, by, 0);
370 return new SeriesConcept(sortVect);
371 }
372
373
374 private Vector quickSort(Vector what, Vector by, int byPos, int left, int right) throws RecognitionException {
375
376 if( left >= right ) return what;
377
378 if(right == left + 1 ) {
379 if( compareMoreThan(byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(left)),
380 byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(right)))) {
381 quickSortSwap(what, left, right);
382 }
383 return what;
384 }
385
386 // The pivot is left
387 Concept o1 = byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(left));
388 quickSortSwap(what, left, right);
389 int upTo = left;
390 int downTo = right - 1;
391
392 do {
393 // get me the first one from the left which is greater than pivot
394 while( upTo <= downTo && compareLessThanOrEqual(byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(upTo)), o1)) {
395 upTo++;
396 }
397
398 // get me the first one from right which is less or equals than pivot
399 while( upTo <= downTo && compareMoreThan( byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(downTo)), o1)) {
400 downTo-- ;
401 }
402
403 if( upTo < downTo ) {
404 quickSortSwap(what, downTo, upTo);
405 }
406 } while ( upTo < downTo );
407
408 quickSortSwap(what, right, upTo);
409 what = quickSort(what, by, byPos, left, upTo-1);
410 what = quickSort(what, by, byPos, upTo+1, right);
411 return what;
412 }
413
414
415 private Vector quickSortDescending(Vector what, Vector by, int byPos, int left, int right)
416 throws RecognitionException {
417
418 if( left >= right ) return what;
419
420 if(right == left + 1 ) {
421 if( compareLessThan(byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(left)),
422 byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(right)))) {
423 quickSortSwap(what, left, right);
424 }
425 return what;
426 }
427
428 // The pivot is left
429 Concept o1 = byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(left));
430 quickSortSwap(what, left, right);
431 int upTo = left;
432 int downTo = right - 1;
433
434 do {
435 // get me the first one from the left which is less or equals than pivot
436 while( upTo <= downTo && compareMoreThan(byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(upTo)), o1)) {
437 upTo++;
438 }
439
440 // get me the first one from right which is more than pivot
441 while( upTo <= downTo && compareLessThanOrEqual( byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(downTo)), o1)) {
442 downTo-- ;
443 }
444
445 if( upTo < downTo ) {
446 quickSortSwap(what, downTo, upTo);
447 }
448 } while ( upTo < downTo );
449
450 quickSortSwap(what, right, upTo);
451 what = quickSortDescending(what, by, byPos, left, upTo-1);
452 what = quickSortDescending(what, by, byPos, upTo+1, right);
453
454 return what;
455 }
456
457
458 private Vector quickSortSwap(Vector vector, int pos1, int pos2) {
459 Object obj = vector.elementAt(pos1);
460 vector.setElementAt(vector.elementAt(pos2), pos1);
461 vector.setElementAt(obj, pos2);
462 return vector;
463 }
464
465
466 private Vector deepSort( Vector what, Vector by, int byPos, int left, int right) throws RecognitionException {
467 if( byPos > by.size() - 1 || what.size() < 2 )
468 return what;
469
470 Concept c1 = null;
471 Concept c2 = null;
472 int start = left;
473 int stop;
474
475 while ( start < right - 1) {
476 stop = start;
477 c1 = byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(start));
478
479 do {
480 stop++;
481 c2 = byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(stop));
482 } while ( stop < right && compareEqual(c1, c2) );
483
484 if( stop > start + 1) {
485 int endPos = stop - 1;
486 if( compareEqual(c1, c2) ) {
487 endPos = stop;
488 }
489
490 if( byPos < by.size() -1){
491 if( isAscending( (AST)by.elementAt(byPos + 1) )) {
492 what = quickSort(what, by, byPos+1, start, endPos);
493 what = deepSort( what, by, byPos+1, start, endPos);
494 } else {
495 what = quickSortDescending(what, by, byPos+1, start, endPos);
496 what = deepSort( what, by, byPos+1, start, endPos);
497 }
498 }
499 }
500 start = stop;
501 }
502 return what;
503 }
504
505
506 private void computeFirstOfPositions (Vector what, Vector by, int byPos ) throws RecognitionException {
507 Vector firstOfPositions = new Vector();
508 Concept c1 = null;
509 Concept c2 = null;
510 int start = 0;
511 int stop;
512
513 while ( start < what.size() ) {
514 stop = start;
515 c1 = byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(start));
516 firstOfPositions.add(""+start);
517
518 do {
519 stop++;
520 if( stop < what.size() ) {
521 c2 = byIterator((AST) by.elementAt(byPos), (Concept)what.elementAt(stop));
522 }
523 } while ( stop < what.size() && compareEqual(c1, c2) );
524
525 start = stop;
526 }
527
528 _firstOfTable.put( getIdentifierSignature( (AST) by.elementAt(byPos)), firstOfPositions);
529
530 if( byPos < by.size() -1 ) {
531 computeFirstOfPositions(what, by, ++byPos);
532 }
533 }
534
535
536 private boolean compareLessThan(Object obj1, Object obj2) throws RecognitionException{
537 return ((LogicalConcept)executeOp("<", (JavaConcept) obj1, (JavaConcept) obj2, 99)).getValue();
538 }
539
540
541 private boolean compareMoreThan(Object obj1, Object obj2) throws RecognitionException{
542 return ((LogicalConcept)executeOp(">", (JavaConcept) obj1, (JavaConcept) obj2, 99)).getValue();
543 }
544
545
546 private boolean compareLessThanOrEqual(Object obj1, Object obj2) throws RecognitionException {
547 return ( ((LogicalConcept)executeOp("<", (JavaConcept) obj1, (JavaConcept) obj2, 99)).getValue() ||
548 ((LogicalConcept)executeOp("==", (JavaConcept) obj1, (JavaConcept) obj2, 99)).getValue());
549
550 }
551
552
553 private boolean compareEqual(Object obj1, Object obj2) throws RecognitionException {
554 return ((LogicalConcept)executeOp("==", (JavaConcept) obj1, (JavaConcept) obj2, 99)).getValue();
555 }
556
557
558
559 private boolean compareMoreThanOrEqual(Object obj1, Object obj2) throws RecognitionException {
560 return ( ((LogicalConcept)executeOp(">", (JavaConcept) obj1, (JavaConcept) obj2, 99)).getValue() ||
561 ((LogicalConcept)executeOp("==", (JavaConcept) obj1, (JavaConcept) obj2, 99)).getValue());
562
563 }
564
565
566 private String rangeCompareTypes( Concept from, Concept to ){
567 if( from.getConceptType().toString().equals( to.getConceptType().toString())) {
568 return from.getConceptType().toString();
569 }
570 else {
571 return null;
572 }
573 }
574
575
576
577 /** Helper method, having as parameters the values from the Tree Walker it will resolve if it is
578 * a static or not element reference and will act actordingly returning the element field.
579 * @param elName The name of the requested element.
580 * @param on The instance holding the element (dinamic).
581 * @param ifErrorLine The line number in the script file, in case of error.
582 * @return The element definition of the requested element.
583 */
584 private FieldDefinition getElementField( String elName, Concept on, int ifErrorLine) {
585 FieldDefinition field = null;
586 if( on.hasConceptElement( elName)){
587 field = on.getConceptElementField( elName );
588 return field;
589 }else {
590 if( on != null && Helper.isElement(on) && ((Element)on).getElementName().equalsIgnoreCase(elName)) {
591 ElementConcept elem = (ElementConcept) on;
592 _previousElem = elem;
593 return new DummyFieldConcept( elem.getElementName(),
594 elem,
595 false,
596 elem.getElementLabel(),
597 elem.getConceptType().toString());
598 }
599 throw new ElementNotFoundException( on.getConceptType().toString(), elName, ifErrorLine);
600 }
601 }
602
603
604 /** Helper method, having as parameters the values from the Tree Walker it will resolve if it is
605 * a static or not element reference and will act actordingly returning the element field.
606 * @param elName The name of the requested element.
607 * @param conceptType The concept holding the element (static element).
608 * @param ifErrorLine The line number in the script file, in case of error.
609 * @return The element definition of the requested element.
610 */
611 private FieldDefinition getStaticElementField( String elName, String conceptType, int ifErrorLine ) {
612 FieldDefinition field = null;
613 if( mn8Loader.getConceptDefinition(conceptType).hasConceptElement( elName )){
614 field = mn8Loader.getConceptDefinition(conceptType).getConceptElementField( elName );
615 if( field.isStatic() ) {
616 return field;
617 } else {
618 throw new NotStaticElementException( conceptType , elName, ifErrorLine);
619 }
620 }else {
621 throw new ElementNotFoundException( conceptType , elName, ifErrorLine);
622 }
623 }
624
625
626 /** Helper method, having as parameters the values from the Tree Walker it will resolve if it is
627 * a static or not element reference and will act actordingly returning the element field.
628 * @param elName The name of the requested element.
629 * @param on The instance holding the element (dinamic).
630 * @param conceptType The concept holding the element (static element).
631 * @param ifErrorLine The line number in the script file, in case of error.
632 * @return The element definition of the requested element.
633 */
634 private FieldDefinition getElementField( String elName, Concept on, String conceptType, int ifErrorLine ) {
635 if( on != null ) { // not static
636 return getElementField( elName, on, ifErrorLine);
637 } else { // static
638 return getStaticElementField( elName, conceptType, ifErrorLine);
639 }
640 }
641
642
643 private void setElementValue( FieldDefinition elField, Concept on, String conceptType, Concept value, int ifErrorLine ) {
644 if( on != null ) {
645 Element element = (Element)elField.getValue(on);
646 element.setElementValue(value);
647 elField.setValue(on, (ElementConcept)element);
648 } else if ( elField.isStatic() ) {
649 Element element = (Element)elField.getValue(null);
650 element.setElementValue(value);
651 elField.setValue(null, (ElementConcept)element);
652 } else {
653 throw new NotStaticElementException( conceptType , elField.getName(), ifErrorLine);
654 }
655 }
656
657
658 private Concept getElementValue( FieldDefinition elField, Concept on, String conceptType, int ifErrorLine ) {
659 mn8Method method = null;
660 if( on != null ) {
661 try {
662 method = on.getConceptDefinition().getConceptMethod("get" + elField.getName().toLowerCase() + ":");
663 } catch (RuntimeException rex) {}
664 if( method == null ) {
665 Element element = (Element)elField.getValue(on);
666 return element.getElementValue();
667 } else {
668 return method.invoke(on, null);
669 }
670 } else if ( elField.isStatic() ) {
671 try {
672 method = mn8Loader.getConceptDefinition(conceptType).getConceptMethod("get" + elField.getName().toLowerCase() + ":");
673 } catch (RuntimeException rex) {}
674 if( method == null ) {
675 Element element = (Element)elField.getValue(null);
676 return element.getElementValue();
677 } else {
678 return method.invoke(on, null);
679 }
680 } else {
681 throw new NotStaticElementException( conceptType , elField.getName(), ifErrorLine);
682 }
683 }
684
685
686 private Concept getElement( FieldDefinition elField, Concept on, String conceptType, int ifErrorLine ) {
687 mn8Method method = null;
688 if( on != null ) {
689 try {
690 method = on.getConceptDefinition().getConceptMethod("get" + elField.getName().toLowerCase() + ":");
691 } catch (RuntimeException rex) {}
692 if( method == null ) {
693 return elField.getValue(on);
694 } else {
695 return method.invoke(on, null);
696 }
697 } else if ( elField.isStatic() ) {
698 try {
699 method = mn8Loader.getConceptDefinition(conceptType).getConceptMethod("get" + elField.getName().toLowerCase() + ":");
700 } catch (RuntimeException rex) {}
701 if( method == null ) {
702 return elField.getValue(null);
703 } else {
704 return method.invoke(on, null);
705 }
706 } else {
707 throw new NotStaticElementException( conceptType , elField.getName(), ifErrorLine);
708 }
709 }
710
711
712 /** Helper method, having as parameters the values from the Tree Walker it will resolve if it is
713 * a static or not element reference and will act actordingly returning the attributes field.
714 * @param atName The name of the requested attribute.
715 * @param on The instance holding the attribute (dinamic).
716 * @param ifErrorLine The line number in the script file, in case of error.
717 * @return The attribute definition of the requested attribute.
718 */
719 private FieldDefinition getAttributeField( String atName, Concept on, int ifErrorLine) {
720 FieldDefinition field = null;
721
722 if( on.hasConceptAttribute( atName )){
723 field = on.getConceptAttributeField( new StringConcept(atName) );
724 return field;
725 }else {
726 if( _previousElem != null && _previousElem.hasConceptAttribute(new StringConcept(atName)).getValue()) {
727 return _previousElem.getConceptAttributeField(new StringConcept(atName));
728 }
729 throw new AttributeNotFoundException( on.getConceptType().toString(), atName, ifErrorLine);
730 }
731 }
732
733
734 /** Helper method, having as parameters the values from the Tree Walker it will resolve if it is
735 * a static or not element reference and will act actordingly returning the attributes field.
736 * @param atName The name of the requested attribute.
737 * @param conceptType The concept holding the attribute (static attribute).
738 * @param ifErrorLine The line number in the script file, in case of error.
739 * @return The attribute definition of the requested attribute.
740 */
741 private FieldDefinition getStaticAttributeField( String atName, String conceptType, int ifErrorLine ) {
742 FieldDefinition field = null;
743 if( mn8Loader.getConceptDefinition(conceptType).hasConceptAttribute( atName )){
744 field = mn8Loader.getConceptDefinition(conceptType).getAttributeField( atName );
745 if( field.isStatic() ) {
746 return field;
747 } else {
748 throw new NotStaticAttributeException( conceptType, atName, ifErrorLine);
749 }
750 }else {
751 throw new AttributeNotFoundException( conceptType, atName, ifErrorLine);
752 }
753 }
754
755
756 /** Helper method, having as parameters the values from the Tree Walker it will resolve if it is
757 * a static or not element reference and will act actordingly returning the attributes field.
758 * @param atName The name of the requested attribute.
759 * @param on The instance holding the attribute (dinamic).
760 * @param conceptType The concept holding the attribute (static attribute).
761 * @param ifErrorLine The line number in the script file, in case of error.
762 * @return The attribute definition of the requested attribute.
763 */
764 private FieldDefinition getAttributeField( String atName, Concept on, String conceptType, int ifErrorLine ) {
765 if( on != null ) { // not static
766 return getAttributeField( atName, on, ifErrorLine);
767 } else { // static
768 return getStaticAttributeField( atName, conceptType, ifErrorLine);
769 }
770 }
771
772
773 private void setAttributeValue( FieldDefinition attrField, Concept on, String conceptType, Concept value, int ifErrorLine ) {
774 mn8Method method = null;
775 if( on != null ) {
776 try {
777 if( !( attrField instanceof DummyFieldConcept ))
778 method = on.getConceptDefinition().getConceptMethod("set"
779 + attrField.getName().toLowerCase() + ":" + value.getConceptType().toString().toLowerCase());
780 } catch (RuntimeException rex) {}
781
782 if( method == null ) {
783 Attribute attribute = (Attribute)attrField.getValue(on);
784 attribute.setAttributeValue(value);
785 attrField.setValue(on, (AttributeConcept)attribute);
786 } else {
787 SeriesConcept param = new SeriesConcept();
788 param.add(value);
789 method.invoke(on, param);
790 }
791 } else if ( attrField.isStatic() ) {
792 try {
793 method = mn8Loader.getConceptDefinition(conceptType).getConceptMethod("set"
794 + attrField.getName().toLowerCase() + ":" + value.getConceptType().toString().toLowerCase());
795 } catch (RuntimeException rex) {}
796
797 if( method == null ) {
798 Attribute attribute = (Attribute)attrField.getValue(null);
799 attribute.setAttributeValue(value);
800 attrField.setValue(null, (AttributeConcept)attribute);
801 } else {
802 SeriesConcept param = new SeriesConcept();
803 param.add(value);
804 method.invoke(on, param);
805 }
806 } else {
807 throw new NotStaticAttributeException(conceptType, attrField.getName(), ifErrorLine);
808 }
809 }
810
811
812 private Concept getAttributeValue( FieldDefinition attrField, Concept on, String conceptType, int ifErrorLine ) {
813 mn8Method method = null;
814 if( on != null ) {
815 try {
816 if( !(attrField instanceof DummyFieldConcept))
817 method = on.getConceptDefinition().getConceptMethod("get" + attrField.getName().toLowerCase() + ":");
818 } catch (RuntimeException rex) {}
819
820 if( method == null ) {
821 Attribute attribute = null;
822 if( on instanceof TransparentElement ) {
823 attribute = (Attribute)attrField.getValue(((TransparentElement)on).getValue());
824 } else {
825 attribute = (Attribute)attrField.getValue(on);
826 }
827 return attribute.getAttributeValue();
828 } else {
829 return method.invoke(on, null);
830 }
831 } else if ( attrField.isStatic() ) {
832 try {
833 method = mn8Loader.getConceptDefinition(conceptType).getConceptMethod("get" + attrField.getName().toLowerCase() + ":");
834 } catch (RuntimeException rex) {}
835
836 if( method == null ) {
837 Attribute attribute = (Attribute)attrField.getValue(null);
838 return attribute.getAttributeValue();
839 } else {
840 return method.invoke(on, null);
841 }
842 } else {
843 throw new NotStaticAttributeException(conceptType, attrField.getName(), ifErrorLine);
844 }
845 }
846
847
848
849 /**
850 * Helper method to help determine and react on the circumstances of a method, attribute,
851 * element call.
852 * @return The circumstances (0- instance on this, 1 - instance on parent, 2- static call
853 */
854 int getCallCircumstances(Concept parent, String onType) {
855
856 if( _isSuperInvocation ) { // The SUPER.method has the highest priority.
857 _isSuperInvocation = false;
858 return CALL_CIRCUMSTANCE_SUPER;
859 } else if ( parent != null ) { // We have a normal invocation $z.xx
860 return CALL_CIRCUMSTANCE_INST_PARENT;
861 } else if ( onType != null ) { // We have a static invocation String.xx
862 return CALL_CIRCUMSTANCE_STATIC_PARENT;
863 } else {
864 if ( _thisMethod.isStatic().getValue() ) { // We have a static direct invocation .xx
865 return CALL_CIRCUMSTANCE_STATIC;
866 } else { // We have a direct invocation THIS.xx
867 return CALL_CIRCUMSTANCE_INST_THIS;
868 }
869 }
870 }
871
872
873
874 /**
875 * Helper method which computes a method signature, used for retrieving methods from
876 * concepts, based on the method name and a series containing the parameters of the
877 * method.
878 * @param methodName The method name as StringConcept
879 * @param params The parameter instantace variables as a Series. The type of this
880 * instances will be used to generate the signature.
881 * @return The method signature as a String.
882 */
883 String computeMethodSignature(StringConcept methodName, SeriesConcept params ) {
884 String methodSig;
885
886 if( params != null ) {
887 methodSig = methodName.toString() + ":" ;
888 for( int i = 0; i < params.getVector().size(); i++ )
889 methodSig += ( i > 0 ? "," : "") + ((Concept)params.getVector().elementAt(i)).getConceptType().getValue();
890 } else {
891 methodSig = "" + methodName.toString() + ":";
892 }
893
894 return methodSig;
895 }
896
897
898 /** Helper method implementing the logic for the method invocation.
899 * @param call_circumstances The circumstances of the method invocation (_INST_THIS, _INST_PARENT, _STATIC, _STATIC_PARENT, _SUPER).
900 * @param root The AST root of the method invocation. Used for extracting the line number for error handling.
901 * @param methodSig The method signature. Used for retrieving the right method.
902 * @param parmas The method invocation parameters.
903 * @param on The instance on which the method is called or null.
904 * @param onType The type on which the method is called or null.
905 * @return The result of the method invocation.
906 */
907 Concept methodInvocationLogic( int call_circumstances, AST root, String methodSig, SeriesConcept params, Concept on, String onType) {
908 if( on != null && on instanceof TransparentElement ) {
909 on = ((TransparentElement)on).getValue();
910 }
911
912 Concept result = on;
913 try {
914 switch (call_circumstances) {
915 case CALL_CIRCUMSTANCE_INST_THIS: {
916 if( _thisConcept != null ) {
917 //conceptType = _thisConcept.getConceptType().toString();
918 result = executeMethod(methodSig, _thisConcept , params);
919 } else {
920 new ErrorConcept( "error"
921 , "unexpectedError"
922 , "Expecting direct method invocation on THIS, but THIS is nil!"
923 , root.getLine());
924 }
925 break;
926 }
927
928 case CALL_CIRCUMSTANCE_INST_PARENT: {
929 if( on != null ) {
930 result = executeMethod(methodSig, result, params);
931 } else {
932 new ErrorConcept( "error"
933 , "unexpectedError"
934 , "Expecting method invocation on a concept instance, but the concept instance is null!"
935 , root.getLine());
936 }
937 break;
938 }
939
940 case CALL_CIRCUMSTANCE_STATIC_PARENT: {
941 if( onType != null && !"".equals(onType) ) {
942 result = executeStaticMethod(methodSig, onType , params);
943 } else {
944 new ErrorConcept( "error"
945 , "unexpectedError"
946 , "The type is expected in the case of a static method invocation!"
947 , root.getLine());
948 }
949 break;
950 }
951
952 case CALL_CIRCUMSTANCE_STATIC: {
953 result = executeStaticMethod(methodSig, _thisMethod.getDeclaringConcept().toString(), params);
954 break;
955 }
956
957 case CALL_CIRCUMSTANCE_SUPER: {
958 String conc = ((StringConcept)superList.elementAt(0)).toString();
959 result = executeInheritedMethod(conc, methodSig, _thisConcept, params);
960 superList = null;
961 break;
962 }
963
964 default : {
965 new ErrorConcept( "error"
966 , "unexpectedError"
967 , "I'm not able to determine the invocation circumstances of this method!"
968 , root.getLine());
969 }
970 }
971 } catch (ConceptNotFoundException mex) {
972 mex.lineNr = _curentLineNr;
973 mex.scriptName = _scriptName;
974 result = new NilConcept();
975 if( mn8RuntimeFlags.isDebug()) {
976 mex.printStackTrace();
977 }
978 new ErrorConcept(mex.type, mex.id, mex.getSimpleMessage(), mex.lineNr);
979 } catch (MethodNotFoundException mex) {
980 mex.lineNr = _curentLineNr;
981 mex.scriptName = _scriptName;
982 result = new NilConcept();
983 if( mn8RuntimeFlags.isDebug()) {
984 mex.printStackTrace();
985 }
986 new ErrorConcept(mex.type, mex.id, mex.getSimpleMessage(), mex.lineNr);
987 } catch (NotStaticMethodException mex) {
988 mex.lineNr = _curentLineNr;
989 mex.scriptName = _scriptName;
990 result = new NilConcept();
991 if( mn8RuntimeFlags.isDebug()) {
992 mex.printStackTrace();
993 }
994 new ErrorConcept(mex.type, mex.id, mex.getSimpleMessage(), mex.lineNr);
995 }
996 return result;
997 }
998
999
1000 /** Helper method implementing the logic for the attribute reference.
1001 * @param call_circumstances The circumstances of the method invocation (_INST_THIS, _INST_PARENT, _STATIC, _STATIC_PARENT, _SUPER).
1002 * @param root The AST root of the attribute reference. Used for extracting the line number for error handling.
1003 * @param attributeName The name of the requested attribute. Used for retrieving the right attribute.
1004 * @param on The instance on which the attribute is searched.
1005 * @param onType The type on which the attribute is searched.
1006 * @return The value of the attribute.
1007 */
1008 Concept attributeReferenceLogic( int call_circumstances, AST root, StringConcept attributeName, Concept on, String onType, Concept newValue) {
1009 if( on != null && on instanceof TransparentElement ) {
1010 on = ((TransparentElement)on).getValue();
1011 }
1012 Concept result = on;
1013 FieldDefinition attributeField = null;
1014 try {
1015 switch (call_circumstances) {
1016 case CALL_CIRCUMSTANCE_INST_THIS: {
1017 if( _thisConcept != null ) {
1018 attributeField = getAttributeField( attributeName.toString()
1019 , _thisConcept
1020 , _thisMethod.getDeclaringConcept().toString()
1021 , root.getLine() );
1022 if( newValue == null ) {
1023 result = getAttributeValue( attributeField
1024 , _thisConcept
1025 , _thisMethod.getDeclaringConcept().toString()
1026 , root.getLine());
1027 } else {
1028 setAttributeValue( attributeField
1029 , _thisConcept
1030 , _thisMethod.getDeclaringConcept().toString()
1031 , newValue
1032 , root.getLine());
1033 result = newValue;
1034 }
1035 } else {
1036 new ErrorConcept( "error"
1037 , "unexpectedError"
1038 , "Expecting direct attribute reference on THIS, but THIS is nil!"
1039 , root.getLine());
1040 }
1041 break;
1042 }
1043
1044 case CALL_CIRCUMSTANCE_INST_PARENT: {
1045 if( on != null ) {
1046 attributeField = getAttributeField( attributeName.toString(), on, root.getLine() );
1047 if( newValue == null ) {
1048 result = getAttributeValue( attributeField, on, null, root.getLine());
1049 } else {
1050 setAttributeValue( attributeField, on, null, newValue, root.getLine());
1051 result = newValue;
1052 }
1053 } else {
1054 new ErrorConcept( "error"
1055 , "unexpectedError"
1056 , "Expecting attribute reference on a concept instance, but the concept instance is null!"
1057 , root.getLine());
1058 }
1059 break;
1060 }
1061
1062 case CALL_CIRCUMSTANCE_STATIC_PARENT: {
1063 if( onType != null && !"".equals(onType) ) {
1064 attributeField = getAttributeField( attributeName.toString(), null, onType, root.getLine() );
1065 if( newValue == null ) {
1066 result = getAttributeValue( attributeField, null, onType, root.getLine() );
1067 } else {
1068 setAttributeValue( attributeField, null, onType, newValue, root.getLine() );
1069 result = newValue;
1070 }
1071 } else {
1072 new ErrorConcept( "error"
1073 , "unexpectedError"
1074 , "The type is expected in the case of a static attribute reference!"
1075 , root.getLine());
1076 }
1077 break;
1078 }
1079
1080 case CALL_CIRCUMSTANCE_STATIC: {
1081 attributeField = getAttributeField( attributeName.toString()
1082 , _thisConcept
1083 , _thisMethod.getDeclaringConcept().toString()
1084 , root.getLine() );
1085 if( newValue == null ) {
1086 result = getAttributeValue( attributeField
1087 , _thisConcept
1088 , _thisMethod.getDeclaringConcept().toString()
1089 , root.getLine());
1090 } else {
1091 setAttributeValue( attributeField
1092 , _thisConcept
1093 , _thisMethod.getDeclaringConcept().toString()
1094 , newValue
1095 , root.getLine());
1096 result = newValue;
1097 }
1098 break;
1099 }
1100
1101 default : {
1102 new ErrorConcept( "error"
1103 , "unexpectedError"
1104 , "I'm not able to determine the invocation circumstances of this attribute!"
1105 , root.getLine());
1106 break;
1107 }
1108 }
1109 } catch (ConceptNotFoundException mex) {
1110 mex.lineNr = _curentLineNr;
1111 mex.scriptName = _scriptName;
1112 result = new NilConcept();
1113 if( mn8RuntimeFlags.isDebug()) {
1114 mex.printStackTrace();
1115 }
1116 new ErrorConcept(mex.type, mex.id, mex.getSimpleMessage(), mex.lineNr);
1117 } catch (FieldNotFoundException ex) {
1118 ex.lineNr = _curentLineNr;
1119 ex.scriptName = _scriptName;
1120 result = new NilConcept();
1121 if( mn8RuntimeFlags.isDebug()) {
1122 ex.printStackTrace();
1123 }
1124 result = (new ErrorConcept(ex.type, ex.id, ex.getSimpleMessage(), ex.lineNr)).result;
1125 } catch (AttributeNotFoundException ex) {
1126 ex.lineNr = _curentLineNr;
1127 ex.scriptName = _scriptName;
1128 result = new NilConcept();
1129 if( mn8RuntimeFlags.isDebug()) {
1130 ex.printStackTrace();
1131 }
1132 result = (new ErrorConcept(ex.type, ex.id, ex.getSimpleMessage(), ex.lineNr)).result;
1133 } catch (NotStaticAttributeException ex) {
1134 ex.lineNr = _curentLineNr;
1135 ex.scriptName = _scriptName;
1136 result = new NilConcept();
1137 if( mn8RuntimeFlags.isDebug()) {
1138 ex.printStackTrace();
1139 }
1140 result = (new ErrorConcept(ex.type, ex.id, ex.getSimpleMessage(), ex.lineNr)).result;
1141 }
1142 return result;
1143 }
1144
1145
1146 /** Helper method implementing the logic for the attribute reference.
1147 * @param call_circumstances The circumstances of the method invocation (_INST_THIS, _INST_PARENT, _STATIC, _STATIC_PARENT, _SUPER).
1148 * @param root The AST root of the attribute reference. Used for extracting the line number for error handling.
1149 * @param attributeName The name of the requested attribute. Used for retrieving the right attribute.
1150 * @param on The instance on which the attribute is searched.
1151 * @param onType The type on which the attribute is searched.
1152 * @return The value of the attribute.
1153 */
1154 Concept elementReferenceLogic( int call_circumstances, AST root, StringConcept elementName, Concept on, String onType, boolean valueRequested, Concept newValue) {
1155 if( on != null && on instanceof TransparentElement ) {
1156 on = ((TransparentElement)on).getValue();
1157 }
1158
1159 Concept result = on;
1160 FieldDefinition elementField = null;
1161 try {
1162 switch (call_circumstances) {
1163 case CALL_CIRCUMSTANCE_INST_THIS: {
1164 if( _thisConcept != null ) {
1165 elementField = getElementField( elementName.toString()
1166 , _thisConcept
1167 , _thisMethod.getDeclaringConcept().toString()
1168 , root.getLine() );
1169 if( newValue == null ) {
1170 result = getElement( elementField
1171 , _thisConcept
1172 , _thisMethod.getDeclaringConcept().toString()
1173 , root.getLine());
1174 } else {
1175 setElementValue( elementField
1176 , _thisConcept
1177 , null
1178 , newValue
1179 , root.getLine() );
1180 }
1181 } else {
1182 new ErrorConcept( "error"
1183 , "unexpectedError"
1184 , "Expecting direct element reference on THIS, but THIS is nil!"
1185 , root.getLine());
1186 }
1187 break;
1188 }
1189
1190 case CALL_CIRCUMSTANCE_INST_PARENT: {
1191 if( on != null ) {
1192 elementField = getElementField( elementName.toString(), on, null, root.getLine() );
1193 if( newValue == null ) {
1194 result = getElement( elementField, on, null, root.getLine());
1195 } else {
1196 setElementValue( elementField, on, null, newValue, root.getLine());
1197 }
1198 } else {
1199 new ErrorConcept( "error"
1200 , "unexpectedError"
1201 , "Expecting element reference on a concept instance, but the concept instance is null!"
1202 , root.getLine());
1203 }
1204 break;
1205 }
1206
1207 case CALL_CIRCUMSTANCE_STATIC_PARENT: {
1208 if( onType != null && !"".equals(onType) ) {
1209 elementField = getElementField( elementName.toString(), null, onType, root.getLine() );
1210 if( newValue == null ) {
1211 result = getElement( elementField, null, onType, root.getLine() );
1212 } else {
1213 setElementValue( elementField, null, onType, newValue, root.getLine());
1214 }
1215 } else {
1216 new ErrorConcept( "error"
1217 , "unexpectedError"
1218 , "The type is expected in the case of a static element reference!"
1219 , root.getLine());
1220 }
1221 break;
1222 }
1223
1224 case CALL_CIRCUMSTANCE_STATIC: {
1225 elementField = getElementField( elementName.toString()
1226 , null
1227 , _thisMethod.getDeclaringConcept().toString()
1228 , root.getLine() );
1229 if( newValue == null ) {
1230 result = getElement( elementField
1231 , _thisConcept
1232 , _thisMethod.getDeclaringConcept().toString()
1233 , root.getLine());
1234 } else {
1235 setElementValue( elementField
1236 , null
1237 , _thisMethod.getDeclaringConcept().toString()
1238 , newValue
1239 , root.getLine());
1240 }
1241 break;
1242 }
1243
1244 default : {
1245 new ErrorConcept( "error"
1246 , "unexpectedError"
1247 , "I'm not able to determine the invocation circumstances of this element!"
1248 , root.getLine());
1249 break;
1250 }
1251 }
1252 if( newValue != null ) {
1253 result = newValue;
1254 } else if ( valueRequested ) {
1255 result = ((Element)result).getElementValue();
1256 }
1257
1258 } catch (ConceptNotFoundException mex) {
1259 mex.lineNr = _curentLineNr;
1260 mex.scriptName = _scriptName;
1261 result = new NilConcept();
1262 if( mn8RuntimeFlags.isDebug()) {
1263 mex.printStackTrace();
1264 }
1265 new ErrorConcept(mex.type, mex.id, mex.getSimpleMessage(), mex.lineNr);
1266 } catch (FieldNotFoundException ex) {
1267 ex.lineNr = _curentLineNr;
1268 ex.scriptName = _scriptName;
1269 result = new NilConcept();
1270 if( mn8RuntimeFlags.isDebug()) {
1271 ex.printStackTrace();
1272 }
1273 result = (new ErrorConcept(ex.type, ex.id, ex.getSimpleMessage(), ex.lineNr)).result;
1274 } catch (ElementNotFoundException ex) {
1275 ex.lineNr = _curentLineNr;
1276 ex.scriptName = _scriptName;
1277 result = new NilConcept();
1278 if( mn8RuntimeFlags.isDebug()) {
1279 ex.printStackTrace();
1280 }
1281 result = (new ErrorConcept(ex.type, ex.id, ex.getSimpleMessage(), ex.lineNr)).result;
1282 } catch (NotStaticElementException ex) {
1283 ex.lineNr = _curentLineNr;
1284 ex.scriptName = _scriptName;
1285 result = new NilConcept();
1286 if( mn8RuntimeFlags.isDebug()) {
1287 ex.printStackTrace();
1288 }
1289 result = (new ErrorConcept(ex.type, ex.id, ex.getSimpleMessage(), ex.lineNr)).result;
1290 }
1291 return result;
1292 }
1293
1294public mn8TreeWalker() {
1295 tokenNames = _tokenNames;
1296}
1297
1298 public final Concept interpretationUnit(AST _t,