001    package org.vishia.java2C;
002    
003    import java.io.FileNotFoundException;
004    import java.io.IOException;
005    import java.text.ParseException;
006    import java.util.Iterator;
007    import java.util.LinkedList;
008    import java.util.List;
009    
010    import org.vishia.zbnf.ZbnfParseResultItem;
011    
012    /**This class generates all statements in one block. It is instanciated temporary
013     * for any statement block. 
014     * @author Hartmut
015     *
016     */
017    public class StatementBlock
018    {
019            private final GenerateClass genClass;
020            private final SecondPass secondpass;
021    
022      /**The number of call of <code>new</code> in this blockStatment. 
023       * The call of new is counted, generates some special statements in C.
024       */
025      private int nrofNew; 
026      
027      private int nrofPersistentStrings = 0;
028      
029      private LinkedList<FieldData> tempRef;
030      
031      /**Counter for <code>"_temp" + nrofTempRefForConcat</code> of this block.
032       */
033      private int nrofTempRefForConcat;
034      
035      /**Counter for <code>"_temp" + nrofStringBufForConcat</code> of this block.
036       */
037      private int nrofStringBufForConcat;
038      
039      /**Counter for <code>"_mtbl8_9"</code> of this block.
040       */
041      private int nrofMTBRef;
042      
043      /**If set >0, a StringBuilderJc-instance with this direct buffer size 
044       * should be generate in this block-level. */
045      private int sizeStringBuilderInStack = 0;
046      
047      private boolean needPtrStringBuilderInThCxt = false;
048      
049      private LinkedList<Integer> sizesStringBufferConcat;
050      
051      
052      /**Indentation of the block.
053       * It is valid for the statements. The opened and close curly bracket have indent-1. 
054       */
055      private final int indent;
056      
057      /**The deepness of block nesting. */
058      public final int blockNestingCnt;
059    
060      /**Saves, whether the last generated statement is a return. If it is not so, 
061       * some instructions at end of block have to be done.
062       */
063      public boolean lastWasReturn = false;
064    
065      /**The identifiers valid at this block level. 
066       * Note: The definition is not final because at first the LocalIdents of the level above
067       * are referenced here. Only if any variable or type defined in this block, an own instance
068       * is created and the reference is replaced.*/
069      public LocalIdents localIdents;
070     
071      
072      /**If any dynamic call occurs in this statement block without local knowledge of the correct interface type,
073       * a helpness variable is created. This list contains all of it.
074       */
075      private List<FieldData> mtblVariables;
076      
077      /**The parent statement block. It is necessary at ex. for gen_ActivateGarbageCollection()
078       * called at return statement.
079       * @param parentIdents
080       */
081      final StatementBlock parent;
082      
083      StatementBlock(StatementBlock parent)
084      { //without any own variable of the block, it are equal to parent idents.
085        //if any variable definition is found, a new LocalIdents(parent) is called.
086        this.genClass = parent.genClass;
087        this.secondpass = parent.secondpass;
088        this.parent = parent;
089        this.indent = parent.indent +1;
090        if(parent != null){
091          blockNestingCnt = parent.blockNestingCnt +1;
092          nrofNew = 0; //(parent.nrofNew & 0xff) + 0x100;
093          localIdents = parent.localIdents;
094        }
095        else {
096          blockNestingCnt = 0;
097          nrofNew = 0;
098          localIdents = null;
099        }
100      }
101      
102      StatementBlock(GenerateClass genClass, LocalIdents parentLocalIdents, boolean bClassLevel, int indent)
103      { //without any own variable of the block, it are equal to parent idents.
104        //if any variable definition is found, a new LocalIdents(parent) is called.
105            this.genClass = genClass;
106            this.secondpass = genClass instanceof SecondPass ? (SecondPass)genClass : null; //unused then
107            this.parent = null;
108          this.indent = indent;
109          blockNestingCnt = 0;
110          nrofNew = 0;
111          localIdents = parentLocalIdents;
112        }
113     
114        
115        
116        /**Returns a new identifier for a newObject. Counts the {@link #nrofNew} thereby.
117       */
118      public String gen_newObj()
119      { nrofNew +=1;
120        return "newObj" + blockNestingCnt + "_"  + nrofNew;
121      }
122    
123      /**Generates all variables which are used for newObject (<code>new</code> operator).
124       * @param indent indentation.
125       * @return String with C-Code
126       */
127      String gen_NewObjReferences(int indent)
128      { String ret = "";
129        if(nrofNew >0)
130        { ret += //genIndent(indent+1) + 
131                 "ObjectJc ";
132          int ctNrofNew = 0;
133          while(++ctNrofNew < nrofNew)
134          { ret += "*newObj" + blockNestingCnt + "_" + ctNrofNew + "=null, "; //1..n-1 with ','
135          }
136          ret += "*newObj" + blockNestingCnt + "_"  + ctNrofNew + "=null;";  //the last without ','
137          ret += " //J2C: temporary Objects for new operations" + GenerateClass.genIndent(indent+1);
138        }
139        return ret;
140      }    
141      
142      
143      
144      /**Returns a new identifier for a persistent String. Counts the {@link #nrofPersistentStrings} thereby.
145       */
146      public String gen_persistringVariable()
147      { nrofPersistentStrings +=1;
148        return "_persistring" + blockNestingCnt + "_"  + nrofPersistentStrings;
149      }
150    
151      /**Generates all StringJc-variables which are used to build persistent Strings.
152       * @param indent indentation.
153       * @return String with C-Code
154       */
155      String gen_persistringVarDefinitions(int indent)
156      { String ret = "";
157        if(nrofPersistentStrings >0)
158        { ret += //genIndent(indent+1) + 
159                 "StringJc ";
160          int ctNrofPersistentStrings = 0;
161          while(++ctNrofPersistentStrings < nrofPersistentStrings)
162          { ret += "_persistring" + blockNestingCnt + "_" + ctNrofPersistentStrings + "=NULL_StringJc, "; //1..n-1 with ','
163          }
164          ret += "_persistring" + blockNestingCnt + "_"  + ctNrofPersistentStrings + "=NULL_StringJc;";  //the last without ','
165          ret += " //J2C: temporary persistent Strings" + GenerateClass.genIndent(indent+1);
166        }
167        return ret;
168      }    
169      
170      
171      
172      /**Counts the {@link #nrof} and returns the name of a reference for new Objects.
173       */
174      public String gen_tempString()
175      { nrofStringBufForConcat +=1;
176        return "_tempString" + blockNestingCnt + "_"  + nrofStringBufForConcat;
177      }
178    
179      
180      /**Generates all variables which are used for new statements.
181       * @param indent indentation.
182       * @return String with C-Code
183       */
184      String gen_TempStringBufferReferences(int indent)
185      { String ret = "";
186        if(sizeStringBuilderInStack >0){
187                      ret += "struct _stringBuilder_t{ StringBuilderJc u; char _b[" + sizeStringBuilderInStack + "-4]; }"
188                  + "_stringBuilder = { CONST_addSizeStack_StringBuilderJc(&_stringBuilder.u, "+ sizeStringBuilderInStack + "-4), {0}};"
189                  + GenerateClass.genIndent(indent+1);
190        }
191        if(needPtrStringBuilderInThCxt){
192          ret += "StringBuilderJc* _stringBuilderThCxt = threadBuffer_StringBuilderJc(_thCxt);"
193                  + GenerateClass.genIndent(indent+1);
194        }
195        if(nrofStringBufForConcat >0)
196        { Iterator<Integer> iSize = (sizesStringBufferConcat != null) ? sizesStringBufferConcat.iterator() : null;
197            int sizeInfo = (iSize != null && iSize.hasNext()) ? iSize.next() : 0;
198          int ctnrofStringBufForConcat = 0;
199          ret += " //J2C: temporary Stringbuffer for String concatenation" + GenerateClass.genIndent(indent+1);
200          while(++ctnrofStringBufForConcat <= nrofStringBufForConcat)
201          { if((sizeInfo >>16) == ctnrofStringBufForConcat){
202              String sName = "_tempString" + blockNestingCnt + "_" + ctnrofStringBufForConcat; 
203              int sizeBuffer = sizeInfo & 0xffff;
204              ret += "struct " + sName + "_t{ StringBuilderJc u; char _b[" + sizeBuffer + "-4]; }"
205                  + sName + " = { CONST_addSizeStack_StringBuilderJc(&" + sName + ".u, "+ sizeBuffer + "-4), {0}};"
206                  + GenerateClass.genIndent(indent+1);
207              //next sizeInfo, maybe 0:
208              sizeInfo = (iSize != null && iSize.hasNext()) ? iSize.next() : 0;
209            } else {
210              ret += "StringBuilderJc* _tempString" + blockNestingCnt + "_" + ctnrofStringBufForConcat + "=null; "
211                  + GenerateClass.genIndent(indent+1);
212            }
213          }
214        }
215        return ret;
216      }    
217      
218      
219      
220      
221      /**Generates a new identifier for a _temp8_9-variable and fills it with the given value.
222       * @param src the type which should stores in the ref
223       * @param modeDef 'n':_new8_9 created '&':_mtb8_9 else:_temp8_9
224       * @return
225       */
226      private final String tempRefForConcat(FieldData src)
227      { if(tempRef == null)
228        { /**First call*/
229          nrofTempRefForConcat = 0;
230          tempRef = new LinkedList<FieldData>(); 
231        }
232        nrofTempRefForConcat +=1;
233        if(src.modeAccess == '%')
234            stop();
235        final String name1;
236        final char accessMode;
237        final char accessModeNoMtb;
238        switch(src.modeAccess){
239        case 't': accessModeNoMtb = 't'; break;
240        case '&': accessModeNoMtb = '*'; break; //store MTB-ref in normal ref. 
241        case '@': accessModeNoMtb = '*'; break; //store enhanced ref in normal ref. 
242        case '*': accessModeNoMtb = '*'; break;
243        default: accessModeNoMtb = '?'; assert(false);
244        }
245        char modeDef = src.modeAccess == '&' ? '&'  //dedicates an MTB-ref
246                             : src.modeStatic;              //'n' for stack-local field which contains new instance
247        switch(modeDef){
248        case 'n': name1 = "_new"; accessMode = accessModeNoMtb; break;   //stores result of return-new method
249        case '&': name1 = "_mtb"; accessMode = '&'; break;   //stores MTB
250        default:  name1 = "_temp"; accessMode = accessModeNoMtb; break;  //stores concatenation temp result. 
251        }
252        String name = name1 + blockNestingCnt + "_" + nrofTempRefForConcat; 
253        if(name.equals("_mtb0_1"))
254            stop();
255            final FieldData ref = new FieldData(name, src.typeClazz, null, null, null
256                    , src.modeStatic, accessMode, 0, null, '.', null); 
257        tempRef.add(ref);
258        return name;
259      }
260    
261      /**Generates a new identifier for a _mtbl8_9-variable and fills it with the given value.
262       * @param ref the value which should stores in the ref
263       * @return
264       */
265      private final String genTemp_mtblRef(FieldData typeMtb, CCodeData ref)
266      { final String sRet;
267            final String sMtbl = tempRefForConcat(typeMtb); 
268        final String sTypeMtb = typeMtb.typeClazz.getClassIdentName();
269        final String sSrcRef = typeMtb.testAndcast(ref, '*');
270        sRet = "( " + sMtbl + ".ref = " + sSrcRef 
271             + GenerateClass.genIndent(indent+2) + ", "  + sMtbl + ".mtbl = (Mtbl_" + sTypeMtb + " const*)getMtbl_ObjectJc(&" + sMtbl 
272             + ".ref->base.object, sign_Mtbl_" + sTypeMtb + ")" 
273             + GenerateClass.genIndent(indent+2) + ", " + sMtbl + ")"
274             + GenerateClass.genIndent(indent+1);
275        return sRet;
276      }
277    
278      /**Generates all variables which are used for temporary references for concatenation-disentangle.
279       * @param indent indentation.
280       * @return String with C-Code
281       */
282      String gen_TempRefs(int indent)
283      { final String ret;
284            if(tempRef != null)
285        { StringBuilder uRet = new StringBuilder(1000);
286          int idx = 1;
287          //ret = GenerateClass.genIndent(indent+1);
288          for(FieldData tempRefField: tempRef){
289            if(tempRefField.getName().equals("_mtb0_1"))
290                    stop();
291            if(tempRefField.modeAccess != '?'){
292                    String sType = tempRefField.typeClazz.sClassNameC;
293              /*
294                    final char modeDefinition = tempRefType.modeStatic;
295              String sName = (modeDefinition == 'n' ? " _new" : " _temp") + blockNestingCnt + "_" + idx; 
296              final String sAccess;
297              final String sInit;
298              switch(tempRefType.modeAccess)
299              { case '~': case '*': sAccess = "*"; sInit = " = null;"; break;
300                case 't': sAccess = ""; sInit = " = NULL_StringJc;"; break;
301                default: sAccess = null; sInit = null; assert(false);
302              }
303              ret += sType + sAccess + sName + sInit;  //all in one line, it may be not some more
304              */
305                    String sVariable = tempRefField.gen_VariableDefinition('b');
306              uRet.append(sVariable).append("; ");  
307            }
308            idx +=1;
309          }
310          uRet.append("//J2C: temporary references for concatenation")
311              .append(GenerateClass.genIndent(indent+1));
312          ret = uRet.toString();
313        } else {
314            ret = "";
315        }
316        return ret;
317      }    
318      
319      
320      /**generates the statement for <code>activateGarbageCollectorAccess_BlockHeapJc()</code>.
321       * This is placed on end of a statement block or before an <code>return</code>-statement,
322       * if inside new-statements are generated.
323       * 
324       * @param indent number of indentations. 2 spaces per indentation are produced.
325       * @return The statement as string with indentation +1, but without newline.
326       */
327      public String gen_ActivateGarbageCollection(int indent, boolean bRet, CCodeData cCodeReturn)
328      { String ret = "";
329        //final boolean bReturnRef;
330        //final int indent1;
331        //final String retBlock;
332        //String retDeduceStatement;
333        final String sAddrExcl;
334        StatementBlock blockLevel = this;
335        if(  cCodeReturn != null 
336          && cCodeReturn.identInfo.typeClazz.isString()
337          ) {
338          sAddrExcl = "PTR_StringJc(" + cCodeReturn.cCode + ")";
339              } else if(  cCodeReturn != null 
340          && !cCodeReturn.identInfo.typeClazz.isPrimitiveType()
341          && !cCodeReturn.cCode.equals("ythis")
342          ) {
343          /**Problem: The method may return an instance in the block heap. Don't activate garbage collection for it: */
344          //retDeduceStatement = GenerateClass.genIndent(indent) + "{ struct BlockHeapJc_t* heap = null; struct BlockHeapBlockJc_t* returnedBlock = deduceBlockHeapBlockFromObject(" + cCodeReturn.cCode + ", &heap);";
345          //bReturnRef = true;
346          //indent1 = indent+1;
347          //retBlock = "returnedBlock";
348          sAddrExcl = cCodeReturn.cCode;
349        } else {  
350          //bReturnRef = false;
351          //retDeduceStatement = null;
352          //indent1 = indent;
353          //retBlock = "null";
354          sAddrExcl = "null";
355        }
356        do {
357          int ctNrofNew = 0;
358          while(++ctNrofNew <= blockLevel.nrofNew)
359          { //if(retDeduceStatement != null){ 
360            //  ret += retDeduceStatement; retDeduceStatement = null;
361            //}
362            ret += GenerateClass.genIndent(indent) + "activateGarbageCollectorAccess_BlockHeapJc(newObj" 
363                   + blockLevel.blockNestingCnt + "_"  + ctNrofNew + ", " + sAddrExcl + ");";
364          }
365          ctNrofNew = 0;
366          //
367          while(++ctNrofNew <= blockLevel.nrofPersistentStrings)
368          { //if(retDeduceStatement != null){ 
369            //  ret += retDeduceStatement; retDeduceStatement = null;
370            //}
371            ret += GenerateClass.genIndent(indent) + "activateGarbageCollectorAccess_BlockHeapJc(PTR_StringJc(_persistring" 
372                   + blockLevel.blockNestingCnt + "_"  + ctNrofNew + "), " + sAddrExcl + ");";
373          }
374          ctNrofNew = 0;
375          //
376          Iterator<Integer> iSize = (sizesStringBufferConcat != null) ? sizesStringBufferConcat.iterator() : null;
377            int sizeInfo = (iSize != null && iSize.hasNext()) ? iSize.next() : 0;
378          while(++ctNrofNew <= blockLevel.nrofStringBufForConcat)
379          { //if(retDeduceStatement != null){ 
380            //  ret += retDeduceStatement; retDeduceStatement = null;
381            //}
382            if((sizeInfo >>16) == ctNrofNew){
383              //no garbage, get next sizeInfo, maybe 0:
384              sizeInfo = (iSize != null && iSize.hasNext()) ? iSize.next() : 0;
385            } else {
386              ret += GenerateClass.genIndent(indent) + "activateGarbageCollectorAccess_BlockHeapJc(&_tempString" 
387                   + blockLevel.blockNestingCnt + "_"  + ctNrofNew + "->base.object, " + sAddrExcl + ");";
388            }  
389          }
390          if(blockLevel.tempRef != null)
391          { /**Activates Garbage Collection for all temp-references, 
392             * which holds references to return-new data.
393             */
394            //int idx = 1;
395            for(FieldData tempRefType: blockLevel.tempRef){
396              //String sType = tempRefType.typeClazz.sClassNameC;
397              final char modeDefinition = tempRefType.modeStatic;
398              if(modeDefinition == 'n') {
399                String sName = tempRefType.getName(); //(modeDefinition == 'n' ? "_new" : "_temp") + blockLevel.blockNestingCnt + "_" + idx; 
400                final String sAccess;
401                switch(tempRefType.modeAccess)
402                { case '~': case '*': sAccess = sName; break;
403                  case 't': sAccess = "PTR_StringJc(" + sName + ")"; break;
404                  case '$': case '%':  assert(false);
405                  default: sAccess = null; assert(false);
406                }
407                //if(retDeduceStatement != null){ 
408                //  ret += retDeduceStatement; retDeduceStatement = null;
409                //}
410                ret += GenerateClass.genIndent(indent) + "activateGarbageCollectorAccess_BlockHeapJc(" + sAccess + ", "+ sAddrExcl + ");";
411                //idx +=1;
412              }  
413            }
414          }
415        } while(bRet && (blockLevel = blockLevel.parent) != null);  //repeat it only if return for all block levels.
416        /*if(   bReturnRef                   //a deduce statement is prepared.
417           && retDeduceStatement == null   //and it is written.
418           ){
419          ret += GenerateClass.genIndent(indent) + "}";
420          }
421        */
422        return ret;
423      }
424      
425      
426      
427      
428      /**generates a statement from given parse result item < statement>.
429       * It may be a simple call, an assignment, an if-statement and so on or a < statementBlock>
430       * <ul>
431       * <li>A comment in /*...* / found in Java-code before the statement are generated also in C
432       *     before the statement in an extra line calling {@link get_description(ZbnfParseResultItem)}
433       * <li>On < assignment> in ZBNF, {@link gen_assignment(ZbnfParseResultItem, int indent, LocalIdents)} is be called immediate.    
434       * <li>On < statementBlock> in ZBNF, {@link gen_statementBlock(ZbnfParseResultItem, int indent, LocalIdents)} 
435       *     is be called immediate with a new instance of {@link StatementBlock}.    
436       * <li>An < if_statement> in ZBNF consists of a < condition>, a < statement> and optional a < elseStatement>.
437       *    The condition will be translated in C with {@link gen_value(ZbnfParseResultItem, LocalIdents, char)}.
438       *    As well as the condition occupies more as one line in Java, in C it is written yet in one line.
439       *    Typically it is a suitable behavior. But if the condition expression is complex,
440       *    it is not so ideal in C. The reason for this behavior: The parser ignore new lines, 
441       *    all are white spaces. The C-code is correct, but possibly not ideal readable. It is a good style
442       *    for writing comprehensible code separating a complex expressions in smaller parts. 
443       *    To divide a conditional expression in smaller parts, some local boolean variable may be used.
444       *    It is anyhow effective at machine level.
445       *    <br>
446       *    If the < statement> is really a simple statement, it will be written after the <code>if(...)</code> in the same line.
447       *    But typically it is a statement block, and will be written in extra lines with the correct indentation.
448       *    <br>
449       *    If a construct <code>else if(...)</code> is given in Java, the <code>if(...)</code> after <code>else</code>
450       *    is a simple statement. Therefore it was be produced as <code>else if(...)</code> also in C.
451       *    It can be understand as a chain of if. 
452       * <li>The behavior of the other control statements are adequate.
453       * <li>On < return> statement some additional statements to finish a subroutine are generated,
454       *     especially the handling of the <code>StacktraceJc</code>. 
455       *     The {@link gen_ActivateGarbageCollection(int)} is called 
456       *     because the statement block may contain one or some new-Statements.
457       * <li>on < methodCall> in Java2C.zbnf-script, the {@link gen_simpleValue(ZbnfParseResultItem, LocalIdents, char intension)}
458       *    is called with intension='m'. The methodcall is translated like a simple value, 
459       *    it is syntactically the same. (void-value).
460       * <li>On < throwNew> in Java2C.zbnf-script, the {@link gen_throwNew(ZbnfParseResultItem, LocalIdents)} is be called.
461       * <li>On < break_statement> in Java2C.zbnf-script, a simple <code>break</code> is generated. 
462       *    It are the same relations in Java likewise in C.
463       * </ul>    
464       * 
465       * @param parent The ZBNF parse result item which is a < statement>
466       * @param indent Number of nesting level of the block to generate indentations of a line.
467       * @param localIdents The indentation of the block: TODO use it as class element.
468       * @param typeReturn The return type of the superior method if it contains a return statement.
469       * @param intension Intension of call: 'c'-constructor body, 'm'-method body, 'b'-internal block, 'z'-part of if, while etc., 'f'-finalize body. 
470       * @return The statement in C stated without indentation and ended without newline, but with the end-semicolon.
471       *         If the statement occupies more as one line, the indentation is generated correctly using the indent argument. 
472       * @throws ParseException
473       * @throws InstantiationException 
474       * @throws IllegalAccessException 
475       * @throws IOException 
476       * @throws IllegalArgumentException 
477       * @throws FileNotFoundException 
478       */
479      public String gen_statement
480      ( ZbnfParseResultItem parent
481      , int indent
482      , LocalIdents localIdents
483      , FieldData typeReturn
484      , char intension
485      )
486      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
487      { String ret = "";
488        ClassData[] typeValue = new ClassData[1];  //classData of the part of expression
489        //String ret = GenerateClass.genIndent(indent);
490        ZbnfParseResultItem zbnfDescription = parent.getChild("description");
491        if(true){
492          String sDescription = genClass.get_shortDescription(zbnfDescription);
493          if(sDescription != null)
494          { ret += "/*" + sDescription + "*/" + GenerateClass.genIndent(indent);
495            if(sDescription.equals("*Determines the position of an asterisk"))
496                    stop();
497          }
498        } else {
499          /**long description: */
500          String sDescription1 = zbnfDescription.getChild("text").getParsedString();
501          ret += "/*" + sDescription1 + "*/" + GenerateClass.genIndent(indent);
502        }
503        /**Iterate all parts of statement::=... */
504        Iterator<ZbnfParseResultItem> iterStatement= parent.iterChildren();  //may consist of some parts one after another, not a loop.
505        //NOTE: a <statement> has only one child because a statement syntax component is a alternative without loop.
506        while(iterStatement.hasNext())
507        { ZbnfParseResultItem itemStatement = iterStatement.next();
508          lastWasReturn = false;  //default, set to true if it is a return.
509          
510          String semanticStatement = itemStatement.getSemantic();
511          if(semanticStatement.equals("assignment"))
512          { ret += gen_assignment(itemStatement, zbnfDescription, indent, localIdents, intension) + ";";
513          }
514          else if(semanticStatement.equals("return"))
515          { ret += gen_returnStatement(itemStatement, zbnfDescription, typeReturn);
516          }
517          else if(semanticStatement.equals("statementBlock"))
518          { ret += secondpass.gen_statementBlock(itemStatement, indent, this, typeReturn, 'b');
519          }
520          else if(semanticStatement.equals("if_statement"))
521          { ZbnfParseResultItem itemCondition = itemStatement.getChild("condition");
522            String sCondition = gen_value(itemCondition, zbnfDescription, typeValue, localIdents, true, 'e');
523            ret += "if(" + sCondition + ") ";
524            ZbnfParseResultItem ifStatement = itemStatement.getChild("statement");
525            String sIfStatement = ifStatement != null ? gen_statement(ifStatement, indent, localIdents, typeReturn, 'z') : ";";
526            ret += sIfStatement;
527            ZbnfParseResultItem elseStatement = itemStatement.getChild("elseStatement");
528            if(elseStatement != null)
529            { ret += GenerateClass.genIndent(indent) + "else ";
530              String sElseStatement = gen_statement(elseStatement, indent, localIdents, typeReturn, 'z');
531              ret += sElseStatement;
532            }
533          }
534          else if(semanticStatement.equals("switch_statement"))
535          { ZbnfParseResultItem itemSwitchValue = itemStatement.getChild("switchValue");
536            String sSwitchValue = gen_value(itemSwitchValue, zbnfDescription, typeValue, localIdents, true, 'e');
537            ret += "switch(" + sSwitchValue + "){";
538            List<ZbnfParseResultItem> listCases = itemStatement.listChildren("case");
539            if(listCases != null)for(ZbnfParseResultItem itemCase: listCases)
540            { List<ZbnfParseResultItem> zbnfCaseValues = itemCase.listChildren("caseValue");
541              for(ZbnfParseResultItem zbnfCaseValue: zbnfCaseValues)
542              { String sCaseValue = gen_value(zbnfCaseValue, zbnfDescription, typeValue, localIdents, true, 'e');  //should be a constant
543                ret += GenerateClass.genIndent(indent+1) + "case " + sCaseValue + ": ";
544              }
545              List<ZbnfParseResultItem> zbnfCaseStatements = itemCase.listChildren("statement");
546              if(zbnfCaseStatements != null)for(ZbnfParseResultItem zbnfCaseStatement: zbnfCaseStatements)
547              { String sCaseStatement = gen_statement(zbnfCaseStatement, indent+1, localIdents, typeReturn, 'z');
548                ret += sCaseStatement;
549              }
550            }
551            ZbnfParseResultItem zbnfDefault = itemStatement.getChild("default");
552            if(zbnfDefault != null)
553            { ret += GenerateClass.genIndent(indent+1) + "default: ";
554              List<ZbnfParseResultItem> zbnfCaseStatements = zbnfDefault.listChildren("statement");
555              if(zbnfCaseStatements != null)for(ZbnfParseResultItem zbnfCaseStatement: zbnfCaseStatements)
556              { String sCaseStatement = gen_statement(zbnfCaseStatement, indent+1, localIdents, typeReturn, 'z');
557                ret += sCaseStatement;
558              }
559            }  
560            ret += GenerateClass.genIndent(indent) + "}/*switch*/;";
561          }
562          else if(semanticStatement.equals("while_statement"))
563          { ZbnfParseResultItem itemCondition = itemStatement.getChild("condition");
564            String sCondition = gen_value(itemCondition, zbnfDescription, typeValue, localIdents, true, 'e');
565            ret += GenerateClass.genIndent(indent) + "while(" + sCondition + ")";
566            ZbnfParseResultItem itemWhileStatement = itemStatement.getChild("statement");
567            String sWhileStatement = itemWhileStatement != null 
568                                   ? gen_statement(itemWhileStatement, indent+1, localIdents, typeReturn, 'z') 
569                                   : ";";
570            ret += sWhileStatement;
571          }
572          else if(semanticStatement.equals("dowhile_statement"))
573          { ZbnfParseResultItem itemCondition = itemStatement.getChild("condition");
574            String sCondition = gen_value(itemCondition, zbnfDescription, typeValue, localIdents, true, 'e');
575            ZbnfParseResultItem itemWhileStatement = itemStatement.getChild("statement");
576            ret += "do ";
577            String sWhileStatement = itemWhileStatement != null ? gen_statement(itemWhileStatement, indent+1, localIdents, typeReturn, 'z') : ";";
578            ret += sWhileStatement;
579            ret += "while(" + sCondition + ");";
580                      
581          }
582          else if(semanticStatement.equals("for_statement")) 
583          { ret += secondpass.gen_for_statement(itemStatement, indent, this, typeReturn);
584          }
585          else if(semanticStatement.equals("comment"))
586          { String sComment = itemStatement.getParsedString();
587            ret += "/*" + sComment + "*/" + GenerateClass.genIndent(indent);
588          }
589          else if(semanticStatement.equals("methodCall"))
590          { CCodeData methodCall = gen_simpleValue(itemStatement, zbnfDescription, localIdents, true, 'm', false);
591            ret += methodCall.cCode + ";";
592          }
593          else if(semanticStatement.equals("throwNew"))
594          { String sMethodCall = gen_throwNew(itemStatement, zbnfDescription, localIdents, typeReturn);
595            ret += sMethodCall + ";";
596          }
597          else if(semanticStatement.equals("try_statement"))
598          { String sTry = gen_try_statement(itemStatement, indent, localIdents);
599            ret += sTry;
600          }
601          else if(semanticStatement.equals("break_statement"))
602          { ret += "break;";
603          }
604          else if(semanticStatement.equals("emtypStatementBlock"))
605          { ret += GenerateClass.genIndent(indent) + "{ }";
606          }
607          else if(semanticStatement.equals("emptyStatement"))
608          { ret += GenerateClass.genIndent(indent) + ";";
609          }
610          else if(semanticStatement.equals("variable"))
611          { //it may be an assignment or such as i++
612            CCodeData codeVariable = gen_simpleValue(itemStatement, zbnfDescription, localIdents, true, 'm', false);
613            ret += codeVariable.cCode + ";";
614          }
615          else if(semanticStatement.equals("description"))
616          { /**ignore it, shown above. */ 
617          }
618          else if(semanticStatement.equals("synchronizedBock"))
619          { String cCode = gen_synchronizedBlock(itemStatement, typeReturn, indent);
620            ret += cCode;
621          }
622          else if(semanticStatement.equals("descriptionInline"))
623          { String sDescription = itemStatement.getParsedString();
624            ret += "//" + sDescription + GenerateClass.genIndent(indent);
625          }
626          else
627          { ret += "unknownStatement(); /*unknown statement with semantic: " + semanticStatement + "*/";
628            //throw new ParseException("Java2C-ERROR:unknown statement semantic: " + semanticStatement, 0);
629          }
630        }
631        return ret;
632      }
633    
634            
635      
636      /**generates a return statement.
637       * 
638       * @param itemStatement
639       * @param zbnfDescription
640       * @param typeReturn
641       * @return
642       * @throws FileNotFoundException
643       * @throws IllegalArgumentException
644       * @throws ParseException
645       * @throws IOException
646       * @throws IllegalAccessException
647       * @throws InstantiationException
648       */
649      private String gen_returnStatement
650            ( ZbnfParseResultItem itemStatement
651            , ZbnfParseResultItem zbnfDescription
652            , FieldData typeReturn
653            ) 
654            throws FileNotFoundException, IllegalArgumentException, ParseException, IOException, IllegalAccessException, InstantiationException
655            { String ret = "";
656            if(! secondpass.noStacktrace){
657          ret += "{ STACKTRC_LEAVE;";   //the brace is necessary if the return in Java is a single statement of an if.
658        }
659        
660        ZbnfParseResultItem itemExpr = itemStatement.firstChild();
661        final String returnStatement;
662        final CCodeData retValue;
663        if(itemExpr != null && itemExpr.getSemantic().equals("value"))
664        { //String retValue = gen_value(itemExpr, typeValue, localIdents, 'e');
665          retValue = gen_value(itemExpr, zbnfDescription, typeReturn.modeStatic=='r', 'e');
666          String sRetValue = typeReturn.testAndcast(retValue, '.');
667          if(typeReturn.typeClazz == CRuntimeJavalikeClassData.clazz_bool)
668            stop();
669          //ret += "return " + typeReturn.testAndcast(typeValue[0], retValue, 'r') + ";";
670          if(zbnfDescription != null && zbnfDescription.getChild("returnInThreadCxt")!=null){
671                    if(  typeReturn.typeClazz == CRuntimeJavalikeClassData.clazzStringJc
672                            && typeReturn.getDimensionArray()==0
673                            ){
674                            sRetValue = "copyToThreadCxt_StringJc(" + sRetValue + ", _thCxt)";
675                    } else {
676                      //other types are not supported yet
677                            throw new IllegalArgumentException("@java2c=returnInThreadCxt unexpected here.");
678                    }
679          }
680          returnStatement = "return " + sRetValue + ";";
681              }
682        else
683        { retValue = null;
684          returnStatement = "return;";
685        }
686        ret += gen_ActivateGarbageCollection(indent+1, true, retValue) + GenerateClass.genIndent(indent+1);
687        ret += returnStatement;
688        if(! secondpass.noStacktrace){
689          ret += GenerateClass.genIndent(indent) + "}";
690        }
691        //to indicate that no additional 'STACKTRC_LEAVE;' should be generate:
692        lastWasReturn = true;
693        return ret;
694            }
695      
696      
697      
698      String gen_synchronizedBlock(ZbnfParseResultItem zbnfSync, FieldData typeReturn, int indent) 
699      throws FileNotFoundException, IllegalArgumentException, ParseException, IOException, IllegalAccessException, InstantiationException
700      {
701        StringBuilder ret = new StringBuilder(10000);
702        
703        ZbnfParseResultItem zbnfSyncObj = zbnfSync.getChild("synchronizedObject").firstChild();
704        CCodeData cCodeSyncObj = gen_simpleValue(zbnfSyncObj, null, localIdents, false, 'm', true);
705        String sSyncObj = CRuntimeJavalikeClassData.fieldObjectJc.testAndcast(cCodeSyncObj, '*');
706        
707        ZbnfParseResultItem zbnfSyncBlock = zbnfSync.getChild("statementBlock");
708        String cCodeSyncBlock = secondpass.gen_statementBlock(zbnfSyncBlock, indent+1, this, typeReturn, 'b');
709        
710        ret.append(GenerateClass.genIndent(indent)).append("synchronized_ObjectJc(").append(sSyncObj).append("); {")
711           .append(GenerateClass.genIndent(indent+1));
712        ret.append(cCodeSyncBlock);
713        ret.append(GenerateClass.genIndent(indent)).append("}").append(" endSynchronized_ObjectJc(").append(sSyncObj).append(");");
714        return ret.toString();
715      }
716      
717      
718      
719      
720      //String gen_initEmbeddedInstance(CCodeData reference, int indent)
721      String genInitEmbeddedInstance(ZbnfParseResultItem zbnfNewObject, ZbnfParseResultItem zbnfDescription
722            , FieldData fieldInfo, String sCCodeInstance, int indent) 
723      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
724      { final String ret; // = "";
725        final String sName = fieldInfo.getName();
726        if(sName.equals("objWhereFieldIsFound"))
727            stop();
728        //final String sTypeIdentC = fieldInfo.typeClazz.getClassIdentName();
729        /*The reference to the embedded instance: */
730        String sInstanceRef = null;  //TODO ##a if the instance is a non static inner class, in Java: instance.new(...) 
731        CCodeData reference = gen_reference(null, zbnfNewObject.getChild("reference"),zbnfDescription, localIdents, genClass.classData.thisCodeInfo, 'b'); //new CCodeData(sInstanceRef, fieldInfo);
732        /*Generate init of the ObjectJc part: */
733        if(fieldInfo.modeArrayElement == 'B')
734        { /*A fix StringBuffer is to be init: final Java StringBuffer buffer = new StringBuffer(123); */
735          int fixSizeStringBuffer = fieldInfo.getFixSizeStringBuffer();
736          String sInit = "//J2C: constructor for embedded fix-size-StringBuffer"
737          + GenerateClass.genIndent(indent)
738          + "init_ObjectJc(&" + sCCodeInstance + ".sb.base.object, sizeof(StringBuilderJc) + " 
739          +         fixSizeStringBuffer + " - 4"   //it contains the size of the StringBuffer
740          +         ", 0);"
741          + GenerateClass.genIndent(indent)
742          + "ctorO_I_StringBuilderJc(&" + sCCodeInstance + ".sb.base.object, "
743          +         fixSizeStringBuffer   //it contains the size of the StringBuffer
744          +         ", _thCxt)"
745          ;
746          ret = sInit;
747        }
748        else if(fieldInfo.typeClazz == CRuntimeJavalikeClassData.clazz_va_list){
749            /**A special case: Va_listFW should be initialized with variable argument list. */
750            ZbnfParseResultItem args = zbnfNewObject == null ? null : zbnfNewObject.getChild("actualArguments");
751            ZbnfParseResultItem arg1 = args.firstChild();     //the only one parameter for the 'new Va_list(...)'
752            CCodeData actParam = gen_value(arg1, null, false, 'a');  //it is a <value>-expression
753            ret = "va_start(" + sCCodeInstance + ".args, " + actParam.cCode + "); " + sCCodeInstance + ".typeArgs = " + actParam.cCode;
754        }
755        else
756        { /*All other cases, not a @java2c=fixStringBuffer. : */
757          final CCodeData codeCtor;
758          final String sClassNameNew; 
759          ClassData classNew = genClass.getType(zbnfNewObject.getChild("newClass"), localIdents);
760          ZbnfParseResultItem zbnfEnvClass = zbnfNewObject.getChild("envIdent");
761          if(zbnfEnvClass != null){
762            stop();
763          }
764          if(zbnfNewObject.getChild("impliciteImplementationClass")!=null){
765            sClassNameNew = "C_" + sName;
766            if(sClassNameNew.equals("C_refTempSimpleClass"))
767                    stop();
768            /**The anonymous class is an inner class of this, use this.classData to search. */
769            classNew = localIdents.getType(sClassNameNew, genClass.fileLevelIdents);
770          } else {
771            //sClassNameNew = zbnfNewObject.getChildString("newClass/@name");
772          }
773          //final ClassData declaringClass = classData.classLevelIdents.getType(sClassNameNew, fileLevelIdents);
774          final String sCtorSuffix;
775          if(classNew !=null && classNew.isNonStaticInner){
776            //A ctor of an inner non-static class is registered as a method ctor_InnerName in the outer class,
777            //because the this-reference of the outer class should be given.
778            //The ClassData.searchMethod(...)-method searches in the outer class automatically
779            //and uses the correct this-reference then.
780            sCtorSuffix = "_" + classNew.getClassNameJava();
781          } else {
782            sCtorSuffix = "";
783          }
784          //
785          if(fieldInfo.typeClazz.bEmbedded){
786            //if(fieldInfo.modeAccess == '%'){
787            String sNameCtor = "INIT" + sCtorSuffix;
788            String sReference = sCCodeInstance;
789            //NOTE: the 'reference' is need on non-static calls, but INIT is static anyway.
790            codeCtor = gen_InternalMethodCall(zbnfNewObject, null, sNameCtor, classNew, reference, sReference); //, localIdents);
791            ret = "//J2C: constructor for embedded element"
792                + GenerateClass.genIndent(indent) + codeCtor.cCode;
793          } else if(!fieldInfo.typeClazz.isBasedOnObject())
794          { /**The embedded instance doesn't base on Object: */
795            String sReference = "build_MemC(&" + sCCodeInstance + ", sizeof(" + sCCodeInstance + "))";
796            String sNameCtor = "ctorM" + sCtorSuffix;
797            //NOTE: the 'reference' is need on non-static calls, if it is a non-static inner class-ctor.
798            codeCtor = gen_InternalMethodCall(zbnfNewObject, null, sNameCtor, classNew, reference, sReference); //, localIdents);
799            ret = "//J2C: constructor for embedded element-MemC"
800                      //+ "clear_MemC("
801                + GenerateClass.genIndent(indent) + codeCtor.cCode;
802          }
803          else
804          { String sReference = sCCodeInstance;
805            String sRefObject = "&(" + sReference + ".base.object)";
806            String sNameCtor = "ctorO" + sCtorSuffix;
807            //Note: searches the ctor in the classNew firstly, search in the outer class than.
808            codeCtor = gen_InternalMethodCall(zbnfNewObject, zbnfDescription, sNameCtor, classNew, reference, sRefObject); //, localIdents);
809            ret = "//J2C: constructor for embedded element-ObjectJc"
810                + GenerateClass.genIndent(indent) 
811                + "init_ObjectJc(" + sRefObject + ", sizeof(" + sReference + "), 0); "
812                + GenerateClass.genIndent(indent)
813                + codeCtor.cCode;
814          }
815        }  
816        return ret;
817      }
818      
819      
820      
821    
822      /**generates an assignment-statement from given parse result item < statement>.
823       * The < assignment> consist of a < ?leftValue>, an < assignOperator> and a < value>.
824       * <br>
825       * The < leftValue> is translated via call of 
826       * {@link gen_variable(ZbnfParseResultItem, LocalIdents , char intension, LocalIdents.IdentInfos[] retIdentInfo)}
827       * with intension='='. The argument retIdentInfo is a call by returned reference. 
828       * The returned object contains informations about the kind of the left-value variable, 
829       * especially if it is an enhanced reference.
830       * <br>
831       * The value is translated via call of {@link gen_value(ZbnfParseResultItem, LocalIdents, char intension)}
832       * with intension='e'.
833       * <br>
834       * If the left value is an enhanced reference, a call of <code>clearBackRefJc(variable)</code>
835       * is produced before the new reference is set to it, and <code>setBackRefJc(variable)</code>
836       * after it is set. This subroutines implement the necessities of Garbage Collection for that enhanced references.
837       * 
838       * @param zbnfAssignment The ZBNF parse result item which is a < assignment>
839       * @param indent Number of nesting level of the block to generate indentations of a line.
840       * @param localIdents The indentation of the block: TODO use it as class element.
841       * @param intension Intension of call: 'c'-constructor body, 'm'-method body, 'b'-internal block, 'z'-part of if, while etc., 'f'-finalize body. 
842       * @return
843       * @throws ParseException
844       * @throws InstantiationException 
845       * @throws IllegalAccessException 
846       * @throws IOException 
847       * @throws IllegalArgumentException 
848       * @throws FileNotFoundException 
849       */
850      public String gen_assignment(ZbnfParseResultItem zbnfAssignment, ZbnfParseResultItem zbnfDescription, int indent, LocalIdents localIdents, char intension) 
851      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
852      { //String ret = GenerateClass.genIndent(indent);
853        final String ret; // = "";
854        ClassData[] typeValue = new ClassData[1];  //classData of the part of expression
855        //LocalIdents.IdentInfos typeLeftValue[] = new LocalIdents.IdentInfos[1];
856        //String sVariableC;
857        final CCodeData leftVariable;
858        final String sAssignOperatorC;
859        final boolean isIncrementOrDecrement;
860        
861        { ZbnfParseResultItem zbnfLeftValue = zbnfAssignment.getChild("leftValue");  //##a
862          if(zbnfLeftValue == null)
863          { throw new ParseException("leftValue expected",0);
864          }
865          { //test
866            String sName = zbnfLeftValue.getChild("variableName").getParsedString();
867            if(sName.equals("xb"))
868              stop();
869          }
870          
871          leftVariable = gen_variableAccess(zbnfLeftValue, zbnfDescription, localIdents, '=', genClass.classData.thisCodeInfo); //, typeLeftValue); 
872        }
873        { ZbnfParseResultItem zbnfAssignOperator = zbnfAssignment.getChild("@assignOperator");;
874          if(zbnfAssignOperator != null)
875          { sAssignOperatorC = zbnfAssignOperator.getParsedText();
876            isIncrementOrDecrement = false;
877          }
878          else if(zbnfAssignment.getChild("increment") != null)
879          { sAssignOperatorC = "++";
880            isIncrementOrDecrement = true;
881          }
882          else if(zbnfAssignment.getChild("decrement") != null)
883          { sAssignOperatorC = "--";
884            isIncrementOrDecrement = true;
885          }
886          else
887          { assert(false);
888            isIncrementOrDecrement = false;
889            sAssignOperatorC = null;
890          }
891        }
892        if(isIncrementOrDecrement)
893        { /**no zbnfValue given, no right value to assign. */ 
894          ret = leftVariable.cCode + sAssignOperatorC;
895        }
896        else
897        { ZbnfParseResultItem zbnfValue = zbnfAssignment.getChild("value");
898          ret = gen_assignValue(leftVariable, sAssignOperatorC, typeValue, zbnfValue, zbnfDescription, indent, localIdents, intension); 
899        }  
900        return ret;
901    
902      }
903    
904    
905      
906      
907      /**Generates an assignment with given value.
908       * @param leftVariable The code snippet to access the variable to which the value should be assigned.
909       *                     The access modes are important. At example it may be an array type.
910       * @param sAssignOperatorC
911       * @param typeValue
912       * @param zbnfAssignment
913       * @param indent
914       * @param localIdents
915       * @param intension
916       * @return
917       * @throws FileNotFoundException
918       * @throws IllegalArgumentException
919       * @throws ParseException
920       * @throws IOException
921       * @throws IllegalAccessException
922       * @throws InstantiationException
923       */
924      /**
925       * @param leftVariable
926       * @param sAssignOperatorC
927       * @param typeValue
928       * @param zbnfValue
929       * @param zbnfDescription
930       * @param indent
931       * @param localIdents
932       * @param intension
933       * @return
934       * @throws FileNotFoundException
935       * @throws IllegalArgumentException
936       * @throws ParseException
937       * @throws IOException
938       * @throws IllegalAccessException
939       * @throws InstantiationException
940       */
941      String gen_assignValue
942      ( final CCodeData leftVariable
943      , final String sAssignOperatorC
944      , ClassData[] typeValue
945      , ZbnfParseResultItem zbnfValue
946      , ZbnfParseResultItem zbnfDescription
947      , int indent, LocalIdents localIdents, char intension
948      ) throws FileNotFoundException, IllegalArgumentException, ParseException, IOException, IllegalAccessException, InstantiationException
949      { String ret;
950        if(leftVariable.cCode.equals("ifc3"))
951          stop();
952        final ZbnfParseResultItem zbnfNewObject;
953                    final ZbnfParseResultItem zbnfNewArray;
954                    { String sSemantic = zbnfValue.getSemantic();
955                      if(sSemantic.equals("newObject"))
956                      { zbnfNewObject = zbnfValue;
957                        zbnfNewArray = null;            //variante at variable declaration
958                      }
959                      else if(sSemantic.equals("newArray"))
960                      { zbnfNewArray = zbnfValue;
961                        zbnfNewObject = null;
962                      }
963                      else
964                      { zbnfNewObject = zbnfValue.getChild("newObject"); //inside a value.
965                        zbnfNewArray = zbnfValue.getChild("newArray");
966                      }
967                    }  
968                    if(leftVariable.dimensionArrayOrFixSize == 0 && leftVariable.getTypeName().equals("StringJc"))
969                    {
970                      ret = gen_StringAssignment(indent, leftVariable, sAssignOperatorC, zbnfValue, zbnfDescription, localIdents, intension);  
971                    }
972                    else if(  (  leftVariable.modeAccess == '$' 
973                              || leftVariable.modeAccess == '%'   //some call-by-value types are designated with %, OS_Timestamp, MemC, 
974                              || leftVariable.modeAccess == 't' ) //a StringJc, from Java: String text = new String(..); 
975                           && zbnfNewObject != null)
976                    { /*variable = new Type(), variable is embedded:
977                        generate no new, but call of constructor. 
978                        The Type of new should be the same as the type of the embedded instance.
979                        It is so, because an embedded instance is only used, if this condition is met. */
980                      ClassData typeOfNew = genClass.getType(zbnfNewObject.getChild("newClass"), localIdents);  //itemNewObject.getChild("newClass").getParsedString();
981                      /*induce to generate the necesarry include statement:
982                        typeOfNew may be null if the type is a external type. */
983                      if(typeOfNew != null)
984                      { genClass.writeContent.addIncludeC(typeOfNew.sFileName, "embedded ctor");
985                      }
986                      ret = genInitEmbeddedInstance(zbnfNewObject, zbnfDescription, leftVariable.identInfo, leftVariable.cCode, indent);
987                    }
988                    else if(leftVariable.modeAccess == 'Y' && zbnfNewObject != null)
989                    { /**Java: variable = new Type(). The variable is embedded:
990                       * generate no new, because the variable is embedded, but call the constructor: */
991                      ClassData typeOfNew = genClass.getType(zbnfNewObject.getChild("newClass"), localIdents);  //itemNewObject.getChild("newClass").getParsedString();
992                      /**induce to generate the necesarry include statement:
993                       * typeOfNew may be null if the type is a external type. */
994                      if(typeOfNew != null)
995                      { genClass.writeContent.addIncludeC(typeOfNew.sFileName, "embedded ctor-Y");
996                      }
997                      String sInstanceRef = null;  //TODO if the instance is a non static inner class, in Java: instance.new(...) 
998                      CCodeData reference = new CCodeData(sInstanceRef, typeOfNew.classTypeInfo);
999                      //ClassData[] retTypeValue = new ClassData[1];
1000                      String sObject = "(ObjectJc*)&(" + leftVariable.cCode + ")";
1001                      CCodeData codeCtor = gen_InternalMethodCall(zbnfNewObject, null, "ctorO", reference.identInfo.typeClazz, reference, sObject); //, localIdents);
1002                      ret = codeCtor.cCode;
1003                    }
1004                    else if(zbnfNewArray != null)
1005                    { /**On initialization, if it is a fix array, the zbnfNewArray is evaluated already 
1006                       * to determine the array size. It is an expression like <code>new int[23]</code>. 
1007                       * Only if it is an pointer to an array, the zbnfNewArray contains relevant informations.
1008                       */
1009                      ret = "/*J2C: newArray*/" + GenerateClass.genIndent(indent);
1010                      if(leftVariable.cCode.equals("ythis->yTEST"))
1011                        stop();
1012                      if(leftVariable.identInfo.getDimensionArray() >0 )
1013                      {
1014                        stop();
1015                        char kind = leftVariable.identInfo.modeAccess;
1016                        String sReference = leftVariable.cCode;
1017                        switch(kind)
1018                        { case 'Y':
1019                          case '$':
1020                          { //embedded array with head and fix size, call constructor
1021                            String sElementType = leftVariable.identInfo.getTypeName();
1022                            String sizeArray = leftVariable.identInfo.fixArraySizes[0];
1023                            String sCtor = "init_ObjectJc(&" + sReference 
1024                                         + ".head.object, sizeof_ARRAYJc(" + sElementType + ", " + sizeArray + ")" 
1025                                         + ", 0);   //J2C: ctor embedded array."
1026                                         + GenerateClass.genIndent(indent)
1027                                         + "ctorO_ObjectArrayJc(&" + sReference 
1028                                         + ".head.object, " + sizeArray + ", sizeof(" + sElementType + "), null, 0);"
1029                                         ;
1030                            ret += sCtor + "//J2C: constructor for embedded array";
1031                          }break;
1032                          case 'X':
1033                          case '*':
1034                          { /**reference to an ObjectArrayJc, initialize it with a new instance. */
1035                            String sNewArray = gen_newArray(zbnfNewArray, typeValue, localIdents, leftVariable.identInfo);
1036                            ret = leftVariable.cCode + " = " + sNewArray + ";  //J2C: assign a new ObjectArrayJc. ";
1037                          }break;
1038                          case 'Q':
1039                          case '%':
1040                          { /**embedded simple array. Fill it with 0. */
1041                            String sElementType = leftVariable.identInfo.getTypeName();
1042                            String sizeArray = leftVariable.identInfo.fixArraySizes[0];
1043                            ret= "init0_MemC(build_MemC(&" + leftVariable.cCode + ", " 
1044                                 + sizeArray + " * sizeof(" + sElementType + "))); //J2C: init the embedded simple array";
1045                            
1046                          }break;
1047                          case 'P':
1048                          { /**Reference to a simple array without head, get memory for it. */
1049                            ret = "/*TODO reference to simple array */";
1050                          }break;
1051                          case '@':
1052                          {
1053                            ret = "/*TODO enhanced reference to ObjectArrayJc*/";
1054                            
1055                          }break;
1056                          default: assert(false);
1057                        }
1058                      }
1059                    }
1060                    else 
1061                    { /**A value to assign is given. */
1062                      CCodeData value;
1063                      if(zbnfNewObject != null)
1064                      { /**the zbnfValue is a newObject*/
1065                            ZbnfParseResultItem itemReference = zbnfNewObject.getChild("reference");
1066            CCodeData reference;
1067            if(itemReference != null)
1068            { String[] unused = new String[1];
1069              reference = gen_reference(unused, itemReference, zbnfDescription, localIdents, genClass.classData.thisCodeInfo, 'm'); 
1070            } else {
1071                    reference = genClass.classData.thisCodeInfo;
1072            }
1073              //if(zbnfNewObject.getChild)
1074                            value = gen_newObject(zbnfNewObject, reference); //, localIdents);
1075                      }
1076                      else if(zbnfNewArray != null)
1077                      { String sValue = gen_newArray(zbnfNewArray, typeValue, localIdents, null);
1078                        value = new CCodeData(sValue, typeValue[0].classTypeInfo);
1079                      }
1080                      else
1081                      {
1082                        //String sValueC = gen_value(zbnfValue, typeValue, localIdents, 'e');
1083                        value = gen_value(zbnfValue, zbnfDescription, leftVariable.identInfo.modeStatic=='r', intension);
1084                      }
1085                      typeValue[0] = value.identInfo.typeClazz;
1086                      ret = gen_AssignCheckCast(leftVariable, sAssignOperatorC, value);
1087                    }
1088                          
1089        return ret;
1090      }
1091      
1092      
1093      
1094      /**Generates the assignment with check of necessity of cast.
1095       * @param leftVariable The destination variable with name, type etc.
1096       * @param sAssignOperatorC The operator, mostly "=", maybe "+=" etc.
1097       * @param value The right value with name, type etc. 
1098       * @return The assignment code in C
1099       */
1100      String gen_AssignCheckCast(final CCodeData leftVariable, final String sAssignOperatorC, final CCodeData value)
1101      { String ret;
1102            String sValueC = value.cCode;
1103        char modeAccessDst = leftVariable.modeAccess == '@' || leftVariable.modeAccess == '&' 
1104                             ? '*'   //access to the .ref-element
1105                             : leftVariable.modeAccess; 
1106        if(leftVariable.cCode.equals("byteRepresentation"))
1107          stop();
1108        final String dstValue = leftVariable.identInfo.testAndcast(value, modeAccessDst);
1109        if(!sValueC.equals(dstValue))
1110          stop();
1111        if(leftVariable.cCode.equals("ifc"))
1112          stop();
1113        if(leftVariable.modeAccess == '@')
1114        { 
1115          /**it is an enhanced reference: */
1116          if(sValueC.equals("null"))
1117          { ret = "CLEARREFJc(" + leftVariable.cCode + ")"; 
1118          }
1119          else
1120          { /**For reflection_Name. */
1121            String sLeftType = leftVariable.identInfo.typeClazz.getClassCtype_s();
1122            ret = "SETREFJc(" + leftVariable.cCode + ", " + dstValue + ", " + sLeftType + ")"; 
1123          }
1124        }
1125        else if(leftVariable.modeAccess == '&')
1126        { 
1127          //it is an mtbl reference:
1128          if(leftVariable.cCode.equals("ifc22"))
1129            stop();
1130          String sLeftType = leftVariable.identInfo.typeClazz.getClassIdentName();
1131          ret = "SETMTBJc(" + leftVariable.cCode + ", " + dstValue + ", " + sLeftType + ")"; 
1132        }
1133        else
1134        { //normal assignment, at ex. a numerical value to a int variable
1135          ret = leftVariable.cCode + " " + sAssignOperatorC + " " + dstValue; 
1136        }
1137        return ret;
1138      } 
1139    
1140      
1141      
1142      /**Generates an assignment to a String.
1143       * @param indent
1144       * @param sVariableC
1145       * @param typeLeftValue
1146       * @param sAssignOperatorC
1147       * @param sValueC
1148       * @param typeValue
1149       * @param intension Intension of call: 'c'-constructor body, 'm'-method body, 'b'-internal block, 'z'-part of if, while etc., 'f'-finalize body. 
1150       * @return
1151       * @throws ParseException
1152       * @throws InstantiationException 
1153       * @throws IllegalAccessException 
1154       * @throws IOException 
1155       * @throws IllegalArgumentException 
1156       * @throws FileNotFoundException 
1157       */
1158      public String gen_StringAssignment
1159      ( int indent
1160      , CCodeData leftValue  //, LocalIdents.IdentInfos typeLeftValue
1161      , String sAssignOperatorC
1162      , ZbnfParseResultItem zbnfValue
1163      , ZbnfParseResultItem zbnfDescription
1164      , LocalIdents localIdents
1165      , char intension
1166      ) throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
1167      { final String ret; // = "";
1168        String sVariableC = leftValue.cCode;
1169        /**The variable name of a StringBuilder-instance, which is used to this String already.
1170         * It may be null. */
1171        if(sVariableC.equals("ssn"))
1172          stop();
1173        genClass.writeContent.addIncludeC("Jc/StringJc", "string assignment");
1174        final String sStringExpr;  
1175        if(sAssignOperatorC.equals("+="))
1176        { //concatenation required!
1177          final String sFirstString;
1178          String sStringBuilderToUse = leftValue.identInfo.sStringBuilderName;  
1179          if(sStringBuilderToUse != null){
1180            sFirstString = null;  //force append to existing buffer
1181          } else {
1182            sFirstString = sVariableC;  //start with the variable to build a new String appended on that.
1183          }
1184            CCodeData value  = gen_ConcatenatedStrings
1185          ( sFirstString    //sFirstString
1186          , leftValue.identInfo.typeClazz  //firstType
1187          , leftValue.modeAccess  
1188          , zbnfValue.iterChildren()  //iterZbnf
1189          , zbnfDescription
1190          , sStringBuilderToUse
1191          , localIdents
1192          , intension
1193          );
1194          sStringExpr =  value.cCode;
1195        }
1196        else
1197        { ClassData[] retType = new ClassData[1];
1198          //String zTest = zbnfValue.toString();
1199          //if(zTest.startsWith(" [2731..2740]"))
1200          //  stop();
1201          /**Use 'gen_value', do not call 'gen_ConcatenatedStrings', because the expression
1202           * may be a simple value, not an concatenation. */
1203          CCodeData codeValue = gen_value(zbnfValue, zbnfDescription, leftValue.identInfo.modeStatic=='r', intension);
1204          String sValueC = codeValue.cCode;
1205          retType[0] = codeValue.identInfo.typeClazz;
1206          String sType = codeValue.identInfo.typeClazz.getClassIdentName();
1207          /**The codeValue.sTempRef is not null, if a annotation java2c=toStringNonPersist
1208           * is found for the statement. */
1209          if(codeValue.sTempRef != null)
1210            stop();
1211          leftValue.identInfo.sStringBuilderName = codeValue.sTempRef;
1212          
1213          /*Iterator<ZbnfParseResultItem> iter= zbnfValue.iterChildren();
1214            String sValueC = gen_ConcatenatedStrings("", null, '.', iter, zbnfDescription, null, localIdents, intension);
1215          */
1216          if(sValueC.equals("null"))
1217          { sStringExpr = "null_StringJc";
1218          }
1219          //else if(sType.equals("char const*") && sAssignOperatorC.equals("="))
1220          else if(codeValue.identInfo.typeClazz == CRuntimeJavalikeClassData.clazz_s0 && sAssignOperatorC.equals("="))
1221          { //The called expression in C returns a 0-terminated string, cast it to StringJc:
1222            sStringExpr = "z_StringJc(" +sValueC + ")"; 
1223          }
1224          //else if(sType.equals("char const*") && sAssignOperatorC.equals("+="))
1225          else if(codeValue.identInfo.typeClazz == CRuntimeJavalikeClassData.clazz_s0 && sAssignOperatorC.equals("+="))
1226          { sStringExpr = "add_s0_StringJc(" + sVariableC + ", " + sValueC + ")"; 
1227          }
1228          else if(sType.equals("StringBuilderJc") && sAssignOperatorC.equals("="))
1229          { sStringExpr = "toString_StringBuilderJc(&(" +sValueC + ")->base.object, _thCxt)"; 
1230          }
1231          else if(sType.equals("StringBuilderJc") && sAssignOperatorC.equals("+="))
1232          { sStringExpr = "add_StringJc(" + sVariableC + ", toString_StringBuilderJc(&(" +sValueC + ")->base.object, _thCxt), _thCxt)"; 
1233          }
1234          else if(sType.equals("StringJc") && sAssignOperatorC.equals("="))
1235          { sStringExpr = "" +sValueC; 
1236          }
1237          else if(sType.equals("StringJc") && sAssignOperatorC.equals("+="))
1238          { sStringExpr = "add_StringJc(" + sVariableC + ", " + sValueC + ")"; 
1239          }
1240          else if(sAssignOperatorC.equals("="))
1241          { //An Object, use the toString Method.
1242            sStringExpr = "/*#*/toString_"+ sType + "((ObjectJc*)(" + sValueC + "), _thCxt)"; 
1243          }
1244          else if(sAssignOperatorC.equals("+="))
1245          { //An Object, use the toString Method.
1246            sStringExpr = "add_StringJc(" + sVariableC + ", toString_"+ sType + "((ObjectJc*)(" + sValueC + "), _thCxt), _thCxt)"; 
1247          }
1248          else throw new ParseException("unexpected syntax",0);
1249        }    
1250        final String sStringExpr2;
1251        if(zbnfDescription != null && zbnfDescription.getChild("declarePersist")!=null){
1252            sStringExpr2 = "declarePersist_StringJc(" + sStringExpr + ")";
1253        } else {
1254            sStringExpr2 = sStringExpr;
1255        }
1256          
1257        if(leftValue.identInfo.nClassLevel ==0
1258            || (zbnfDescription != null && zbnfDescription.getChild("toStringNonPersist")!=null)
1259            ){
1260            /**Simple assignment to local variable or if it shouldn't be persistent. */
1261            ret = sVariableC + " = " + sStringExpr2 + "/*J2C:non-persistent*/";
1262        } else {
1263          ret = "set_StringJc(&(" + sVariableC + "), " + sStringExpr2 + ")";
1264        }
1265        return ret;
1266      }
1267      
1268    
1269      /**generates an access to a value in a variable or a using of a variable as left value. 
1270       * The variable may be referenced. It means, it is a variable in the referenced object.
1271       * <br>
1272       * If no reference is given, it may be either it a local variable or a class variable. 
1273       * With help of the argument localIdents the variable can be found in the context.
1274       * <ul><li>If it is a class variable, In C <code>ythis-></code> is written before.
1275       *     <li>If it is a variable of a super class, In C <code>ythis->super.</code> is written before.
1276       *     <li>If it is a variable of a outer class, In C <code>ythis->outer-></code> is written before.
1277       *     <li>If it is a local stack variable, the name is directly used in C like in Java.
1278       * </ul>    
1279       * <br>
1280       * If it is a referenced variable, the identifier info of the referencing object is used,
1281       * The reference is build correctly either with <code>-></code> or <code>.</code>,
1282       * depended on the reference kind. It may be an embedded struct.
1283       * The LocalIdents of the referencing object are used to desire it.
1284       * <br>
1285       * If the variable is an enhanced reference and the intension is ones of "Rrmex", 
1286       * the code <code>REFJc(variable)</code> is generated  to get the stored reference as value.
1287       * <code>REFJc(variable)</code> is a Macro to get the reference pointer inside an enhanced referende.
1288       * Especially if it is left value, the code of enhanced reference itself is generated.  
1289       * <br>
1290       * A variable may have a pre- or post- increment or -decrement like --x or y++.
1291       * 
1292       * @param itemVariable The ZBNF parse result item of the < ?variable>-semantic.
1293       *                     It is a part of a simpleValue-syntax-prescript.
1294       * @param localIdents The Identifier info of the environment.
1295       * @param intension Info about the location respectively cause to call this method.
1296       *                  e-expression R-first reference r-nested reference =:leftvalue ...
1297       * @param retIdentInfo information about the variable in its context.
1298       * @return generated String of variable access for the C-code
1299       * @throws ParseException
1300       * @throws InstantiationException 
1301       * @throws IllegalAccessException 
1302       * @throws IOException 
1303       * @throws IllegalArgumentException 
1304       * @throws FileNotFoundException 
1305       */
1306      public CCodeData gen_variableAccess(
1307                    final ZbnfParseResultItem itemVariable, final ZbnfParseResultItem zbnfDescription
1308                    , LocalIdents localIdents
1309        , char intension, CCodeData cCodeReferenceInput
1310        ) 
1311      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
1312      { //String ret = "";
1313        String cCodeBase = "";
1314        int nrofParanthesis = 0;
1315        
1316        final FieldData identInfo; // = retIdentInfo[0];  
1317        
1318        String sIdent = itemVariable.getChild("variableName").getParsedString();
1319        if(sIdent.equals("length"))
1320          stop();
1321        ZbnfParseResultItem itemReference = itemVariable.getChild("reference");
1322        final CCodeData reference;
1323        boolean bFinish = false;
1324        String[] sConcatenatedReference = new String[1]; 
1325        if(itemReference != null)
1326        { reference = gen_reference(sConcatenatedReference, itemReference, zbnfDescription, localIdents, genClass.classData.thisCodeInfo, intension); //, typeReference); // retIdentInfo);
1327          if(reference.sTempRef != null) {
1328            cCodeBase = "(" + reference.cCode;
1329            nrofParanthesis +=1;
1330            reference.cCode = reference.sTempRef;
1331          }
1332          if(   (  reference.dimensionArrayOrFixSize >0 
1333                || reference.identInfo.typeClazz == CRuntimeJavalikeClassData.clazzByteStringJc ) 
1334             && sIdent.equals("length")){
1335            //the length of an array is to be get dependend from the modeAccess: 
1336            identInfo = CRuntimeJavalikeClassData.clazz_int32.classTypeInfo;
1337            switch(reference.modeAccess){
1338              case 'B': cCodeBase += "length_ByteStringJc(" + reference.cCode + ")"; break; //simple array
1339                    case '%': cCodeBase += "ARRAYLEN(" + reference.cCode + ")"; break; //simple array
1340                    case 'Y': case '$': cCodeBase += reference.cCode + ".head.length";         break; //array struct embedded
1341              case 'Q': case '&': cCodeBase += "ARRAYLEN(" + reference.cCode + ")"; break; //simple array of pointer
1342              case 'X': case '*': cCodeBase += reference.cCode + "->head.length";        break; //array struct simple referenced
1343              case '@': cCodeBase += "REFJc(" + reference.cCode + ")->head.length";    break; //array struct enhanced referenced
1344              case 'P': throw new ParseException("A .length of a simple referenced array isn't able to determine.", 0);
1345              default: assert(false);
1346            }
1347            bFinish = true;
1348          }
1349          else
1350          { localIdents = reference.getClassLevelIdents(); //retIdentInfoRef[0].typeClazz.classLevelIdents;
1351            identInfo = localIdents.get(sIdent);  //search it. localIdents are them from a reference,
1352          }
1353        }
1354        else
1355        { if(sIdent.equals("this"))
1356          { identInfo = genClass.classData.classTypeInfo;
1357            cCodeBase = "ythis";
1358            bFinish = true;
1359          }
1360          else
1361          { if(sIdent.equals("linkedList")&& genClass.classData.sClassNameC.equals("stressTest_TestContainer_Test_s"))
1362              stop();
1363            identInfo = localIdents.get(sIdent);  //search it. localIdents are from input,
1364          }
1365          
1366          //if(cCodeReferenceInput == null || cCodeReferenceInput.modeAccess == 'C')
1367          { if(identInfo == null)
1368            { reference = null;
1369            }
1370            else if("Ssd".indexOf(identInfo.modeStatic)>=0)
1371            { reference = Java2C_Main.singleton.staticReferenceDummy;
1372            }
1373            else if(identInfo.getClassLevel()>0)
1374            { reference = cCodeReferenceInput;  //it is a ident of the environment.
1375                             //classData.thisCodeInfo;
1376            }
1377            else
1378            { reference = Java2C_Main.singleton.localReferenceDummy;
1379            }
1380          }
1381          //else
1382          { //reference = cCodeReferenceInput;
1383          }
1384        }
1385        while(nrofParanthesis > 0){
1386          nrofParanthesis-=1;
1387          cCodeBase += ")";
1388        }
1389        //Info about the identifier of the variable in local context:
1390        if(identInfo == null) 
1391            throw new IllegalArgumentException("unknown identifier: \""+ sIdent + "\" in environment of: " + localIdents
1392                    + ". \nTip: A hand-written stc-file may be incomplete.");
1393        char cModeAccess = identInfo.modeAccess;
1394        
1395        if(!bFinish)
1396        { /*bFinish means, the code generation of the base access is done. */
1397          //the ident Info should be exists, otherwise an exception is thrown here.
1398          int nClassLevel;
1399          assert(identInfo != null); // || sIdent.equals("exc"));  //TODO exc in CATCH
1400          { nClassLevel = identInfo.getClassLevel();
1401            //char cModifier = identInfo.sModifier.charAt(0);
1402            if("Ssd".indexOf(identInfo.modeStatic)>=0)
1403            { //the identifier is static or defined with #define
1404              cCodeBase += sIdent + "_" + identInfo.declaringClazz.getClassIdentName();
1405            }
1406            else
1407            { String superOuter = "";
1408              int nOuterLevel = identInfo.getOuterLevel();
1409              while(--nOuterLevel > 0)
1410              { superOuter += "outer->";  //member of a outer class. It is referenced with 'outer'
1411              }
1412              while(--nClassLevel > 0)
1413              { superOuter += "base.super.";  //member of a super class. It is an embedded struct named 'super'
1414              }
1415              String referenceSeparator;
1416              switch(reference.modeAccess)
1417              { case '@': referenceSeparator = "->"; break; //the identifier of this scope is an enhanced reference.
1418                case '$':  //the identifier of this scope is an embedded struct.
1419                case 'Y':  //the identifier of this scope is an embedded array element
1420                case 't':  //the identifier of this scope is a StringJc.
1421                          referenceSeparator = "."; break;
1422                case '~':
1423                case '*': referenceSeparator = "->"; break;
1424                //case '%': referenceSeparator = ""; assert(reference.cCode.equals("")); break;
1425                case '%': referenceSeparator = reference.cCode.equals("") ? "" : "."; 
1426                  stop();  //note: OS_TimeStamp as reference was here, time_sec ?
1427                  break;
1428                case 'C': //class static variable 
1429                  referenceSeparator = ""; assert(reference.cCode.equals("")); 
1430                  break;
1431                default: throw new ParseException("unexpected modeAccess", reference.modeAccess);
1432              }
1433              if(reference.modeAccess == '@')
1434              {
1435                cCodeBase += "REFJc(" + reference.cCode + ")" + referenceSeparator + superOuter + sIdent;
1436              }
1437              else
1438              {
1439                cCodeBase += reference.cCode + referenceSeparator + superOuter + sIdent;
1440              }  
1441              if(identInfo.modeArrayElement == 'B')
1442              { cCodeBase += ".sb";  //access to the StringBuilderJc inside the struct.
1443                assert(cModeAccess == '$'); 
1444                cModeAccess = '$';   //because access to StringBuffer-element.
1445              }
1446              //TODO test wether it is a local overwritten variable against a class element.
1447            }
1448          }
1449        }  
1450        int dimensionArray = identInfo.getDimensionArray();
1451        List<ZbnfParseResultItem> listArrayIndices = itemVariable.listChildren("arrayIndex");
1452        final String cCode3;
1453        if(listArrayIndices != null) 
1454        { final String cCodeArray;
1455          switch(identInfo.modeAccess){
1456            case 'B': cCodeArray = "data_ByteStringJc(" + cCodeBase + ")";    break; //simple array
1457            case 'Q': case '%': cCodeArray = cCodeBase;    break; //simple array
1458            case 'Y': case '$': cCodeArray = cCodeBase + ".data"; cModeAccess = identInfo.modeArrayElement; break; //array struct embedded
1459            case 'P': case '&': cCodeArray = cCodeBase;    break; //simple array of pointer
1460            case 'X': case '*': cCodeArray = cCodeBase + "->data"; cModeAccess = identInfo.modeArrayElement; break; //array struct simple referenced
1461            case '@': cCodeArray = "REFJc(" + cCodeBase + ")->data"; cModeAccess = '*'; break; //array struct enhanced referenced
1462            default: throw new ParseException("unexpected modeAccess", identInfo.modeAccess);
1463          }      
1464          String cCodeIndices = "";
1465          for(ZbnfParseResultItem item: listArrayIndices)
1466          { ClassData[] typeIndex = new ClassData[1];  //classData of the part of expression
1467            String sIdxValue = gen_value(item, null, typeIndex, localIdents, true, 'e');
1468            cCodeIndices+= "[" + sIdxValue + "]";  //fix array
1469            dimensionArray -=1;
1470          }
1471          cCode3 = cCodeArray + cCodeIndices;
1472          if(dimensionArray == 0)
1473          { cModeAccess = identInfo.modeArrayElement; //access to the element.
1474          }
1475        }
1476        else
1477        { cCode3 = cCodeBase;
1478        }
1479        final String cCode4;
1480        if(itemVariable.getChild("postDecrement")!= null)
1481        { cCode4 = cCode3 + "--"; 
1482        }
1483        else if(itemVariable.getChild("postIncrement")!= null)
1484        { cCode4 = cCode3 + "++";
1485        }
1486        else if(itemVariable.getChild("preDecrement")!= null)
1487        { cCode4 = "--" + cCode3; 
1488        }
1489        else if(itemVariable.getChild("preIncrement")!= null)
1490        { cCode4 ="++" + cCode3;
1491        }
1492        else
1493        { cCode4 = cCode3;
1494        }
1495        final String cCode5;
1496        if(sConcatenatedReference[0]!=null){
1497          /**A call of methods and maybe assignment to internal temporary references is returned: */
1498          cCode5 = GenerateClass.genIndent(indent+1) + "(" + sConcatenatedReference[0] + cCode4 + GenerateClass.genIndent(indent+1) + ")";
1499        }
1500        else {
1501          cCode5 = cCode4;
1502        }
1503        //The modeAccess is the access to an array element if the variable is so. identInfo is the info of the array variable type.
1504        final CCodeData retData = new CCodeData(cCode5, identInfo, cModeAccess, dimensionArray); //identInfo.modeArray);
1505        return retData;
1506      }
1507    
1508    
1509    
1510      /**generates an reference to a variable or method call from parse result < reference>. 
1511       * <ul>
1512       * <li>If <code>this.</code> is found in Java, designed with < this> in zbnf parse result,
1513       *  <code>ythis-></code> is generated.
1514       *  
1515       * <li>If <code>super.</code> is found in Java, designed with < super> in zbnf parse result,
1516       *  <code>ythis->super.</code> is generated.
1517       *  
1518       * <li>If a < referenceAssociation> is found, the access to it is generated in C calling
1519       *   {@link gen_variable(ZbnfParseResultItem, LocalIdents, char intension, FieldData[])}.
1520       
1521       *   It follows either by <code>.</code> or <code>-></code> or the <code></code>
1522       *   The type of the variable returned in the FieldData[] 
1523       *   is stored as retIdentInfo and is used to determine if <code>.</code> or <code>-></code>
1524       *   follows after the variable. The variable may be an embedded reference,
1525       *   than <code>.</code> should be following. 
1526       *   The <code>.ref</code> part of an enhanced reference is generated in gen_variable().
1527       *    
1528       * <li>If a < referenceMethod> is found, {@link gen_simpleMethodCall(ZbnfParseResultItem, String sInstanceRef, FieldData, ClassData, LocalIdents)}
1529       *   is called to produce an call of the method in C. The type of return-value of the method
1530       *   supplied in the FieldData-arg is used as retIdentInfo.
1531       * </ul>
1532       * 
1533       * A reference can be referenced again, writing at ex.<code>myRef.itsRef.</code> or 
1534       * <code>myRef.method().itsRef.</code>. In Java2C.zbnf the references are understand syntactically 
1535       * as repetition. Therefore here all references are concatenated. The following separator
1536       * <code>.</code> or <code>-></code> is determined always from type of the reference before.
1537       * The type-info of the last reference is returned in retInfo. 
1538       * 
1539       * @param concatedReference Part of reference, which are build with concatenated methods in Java.
1540       *        In the result it is to be write as a expression separated with comma.
1541       * @param zbnfReferences The ZBNF parse result item of the < reference>.
1542       * @param localIdents The Identifier info of the environment.
1543       * @param intension Info about the location respectively cause to call this method.
1544       *                  e-expression R-first reference r-nested reference =:leftvalue ...
1545       * @param retIdentInfo information about the last reference type.
1546       * @return String representing the reference in C.
1547       * @throws ParseException
1548       * @throws InstantiationException 
1549       * @throws IllegalAccessException 
1550       * @throws IOException 
1551       * @throws IllegalArgumentException 
1552       * @throws FileNotFoundException 
1553       */
1554      CCodeData gen_reference
1555      ( String[] concatenatedReference
1556      , final ZbnfParseResultItem zbnfReferenceP
1557      , final ZbnfParseResultItem zbnfDescription
1558      , final LocalIdents localIdentsParent
1559      , CCodeData envClassCode
1560      , char intension
1561      ) 
1562      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
1563      { LocalIdents refIdents = localIdentsParent;
1564        int countNestedRef = 0; //to test
1565        String ret = "";
1566        CCodeData referenceCode = envClassCode;
1567        if(zbnfReferenceP !=null){  //if null then a reference isn't given, envClassCode is ok.
1568          ZbnfParseResultItem zbnfReference = zbnfReferenceP;
1569          do
1570          { Iterator<ZbnfParseResultItem> iterReferences = zbnfReference.iteratorChildren();
1571            intension = 'R';  //the left element of a reference.
1572            
1573            ZbnfParseResultItem itemRef = null;
1574            //The initial values are returned if hasNext() fails at begin.
1575            /**Only the first child should be evaluated. a second child is <reference>, it will be tested after them.
1576             * The syntax in Java2C.zbnf was changed. In the past it was a repetition, therefore while was okay.
1577             * Not it is a recursion, but here solved with a do...while (next-child != null).
1578             */
1579            int countWhile = 0;
1580            while(  iterReferences.hasNext())
1581            { if(++countNestedRef >= 2)
1582                stop();
1583              itemRef = iterReferences.next();
1584              String semantic = itemRef.getSemantic();
1585              if(!semantic.equals("reference"))
1586              { assert(++countWhile == 1);
1587                if(semantic.equals("this"))
1588                { referenceCode = genClass.classData.thisCodeInfo;
1589                }
1590                else if(semantic.equals("super"))
1591                { CCodeData superAccessCode = genClass.classData.inheritanceInfo.superInheritance.classData.thisCodeInfo;
1592                  referenceCode = new CCodeData("(&ythis->base.super)", superAccessCode.identInfo);
1593                }
1594                else if(semantic.equals("referenceMethod"))
1595                { /**the reference is built from a method call. That are concatenated methods.
1596                   * Either the reference is stored in an _temp# 
1597                   * or it is a return this-method. Than the same reference is used.
1598                   */
1599                  CCodeData methodCall = gen_simpleMethodCall
1600                        ( itemRef
1601                        , zbnfDescription    
1602                        , referenceCode //envInstance             //the generated instance reference, it is the reference up to now.
1603                        , localIdentsParent  //the idents for build values for method arguments 
1604                        , true  //nonPersistent
1605                        , 'r'
1606                        );
1607                  if(concatenatedReference[0]==null){ concatenatedReference[0] = ""; }
1608                  if(!methodCall.isReturnThis()){
1609                    /**use a _temp# */
1610                    String sTempRef = tempRefForConcat(methodCall.identInfo);
1611                    concatenatedReference[0] += sTempRef + "= " + methodCall.cCode + GenerateClass.genIndent(indent+1) + ", ";
1612                    referenceCode = methodCall;
1613                    referenceCode.cCode = sTempRef;
1614                  } else {
1615                    /**use the same reference, because the method returns this. */
1616                    concatenatedReference[0] += methodCall.cCode + GenerateClass.genIndent(indent+1) +  ", ";
1617                    /**Let the reference equals as it is. */
1618                  }
1619                }
1620                else if(semantic.equals("referenceAssociation"))
1621                { String sAssociationName = itemRef.getChild("variableName").getParsedString();
1622                  //sAssociationName may be a type.
1623                  if(sAssociationName.equals("SpecialCharStrings") || sAssociationName.equals("singleton_LeapSecondsJc") || sAssociationName.equals("singleton"))
1624                    stop();
1625                  /**Check whether the pretended association is a type, 
1626                   * thus the referenced element is a static one and the pretended association is the class defines it.
1627                   */
1628                  ClassData typeClass = refIdents.getType(sAssociationName, genClass.fileLevelIdents);
1629                  if(typeClass != null)
1630                  { //it is a type, not a variable:
1631                    referenceCode = typeClass.typeCodeInfo;
1632                  }
1633                  else
1634                  {
1635                    referenceCode = gen_variableAccess(itemRef, zbnfDescription, refIdents, intension, referenceCode); //, retIdentInfo); //itemRef.getParsedString();
1636                    //NOTE: retIdentInfo[0] = setted in gen_variable with the type info of the detected variable.
1637                    if(referenceCode.cCode.equals("leapSeconds"))
1638                      stop();
1639                  }
1640        
1641                } //if referenceAssociation
1642        
1643                //if(referenceCode.type != null)
1644                { String sFileName = referenceCode.getTypeHeaderfilename(); //retIdentInfo[0].typeClazz.sFileName;
1645                  if(sFileName != null)
1646                  { genClass.writeContent.addIncludeC(sFileName, "reference-association: " + referenceCode.identInfo.getName());
1647                  }
1648                  refIdents = referenceCode.getClassLevelIdents();  
1649                }
1650                //else
1651                { //a type without typeClass is not recognize in Java2C, it will be an external type.
1652                  //refIdents = null;  //there don't have to use in a next nested reference, because the type is unknown. 
1653                  //stop();
1654                }
1655                intension = 'r'; //for the next nested reference.
1656              }  
1657            } //while, all references are evaluated one after another.
1658            
1659            zbnfReference = zbnfReference.getChild("reference"); //nested reference is a next reference!
1660            if(zbnfReference != null)
1661              stop();
1662          } while(zbnfReference != null); 
1663          if(ret.length()>0)
1664          { assert(false);
1665            //referenceCode.bUseTempRef =true;
1666            referenceCode.cCode = ret;
1667          }
1668        }
1669        return referenceCode;
1670      }
1671    
1672      
1673      public String gen_value(ZbnfParseResultItem parent, ZbnfParseResultItem zbnfDescription, ClassData[] retType, LocalIdents localIdents, boolean maybeNonPersistent, char intension) 
1674      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
1675      { CCodeData codeValue = gen_value(parent, zbnfDescription, maybeNonPersistent, intension);
1676        retType[0] = codeValue.identInfo.typeClazz;
1677        return codeValue.cCode;
1678      }
1679    
1680      /**generates the expression to get a value. From syntax item <...?value>.
1681       * In the syntax of < value> it is a repetion of <code>{ [|< unaryOperator>] < simpleValue?> ? < binaryOperator> }</code>.
1682       * Therefore {@link #gen_simpleValue(ZbnfParseResultItem, LocalIdents, char)} is called inside.
1683       * All components of the < value> are processed in one while-loop because it is stored one after another.
1684       * That includes also the <code>[< ?conditional>...</code> construct 
1685       * in which is this method is called recursively.
1686       * <br>
1687       * The priority of operators is checked in the Java context. The input to the Java2C-translator
1688       * should be a well compiled java source code. Therefore it needn't considered here.
1689       * 
1690       * @param parent The parse result item which has the semantic <...?value>.
1691       * @param intension intension of generating: 
1692       *        <ul><li>'e'-value in an expression, enhanced references are taken with .ref
1693       *            <li>'l'-left value, 
1694       *            <li>'a'-argument
1695       *        </ul>    
1696       * @return
1697       * @throws ParseException 
1698       * @throws InstantiationException 
1699       * @throws IllegalAccessException 
1700       * @throws IOException 
1701       * @throws IllegalArgumentException 
1702       * @throws FileNotFoundException 
1703       * @throws InstantiationException 
1704       */
1705      public CCodeData gen_value
1706      ( final ZbnfParseResultItem parent
1707      , ZbnfParseResultItem zbnfDescription
1708      , boolean maybeNonPersistent
1709      , final char intension
1710      ) 
1711      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
1712      { String expr = ""; //"/*gen_value=" + intension + "*/";
1713        /**Maybe used to concatenate Strings. */
1714        String sTempRef = null;   
1715        Iterator<ZbnfParseResultItem> iter= parent.iterChildren();
1716        ClassData typeVal = null;
1717        boolean isBoolean = false;
1718        char modeAccess ='.', modeStatic = '.', modeArrayElement = '.';
1719        int dimensionArray = 0;
1720        String sSemantic;;
1721        String sLiteral = null;
1722        CCodeData codeValue = null;
1723        /**If true, then a reference is need. If the value is a enhanced or MTBL-reference, 
1724         * then .ref should be generated. It depends from the operator before. */
1725        boolean bRefNeed = false;
1726        while(iter.hasNext())
1727        { ZbnfParseResultItem item = iter.next();
1728          sSemantic = item.getSemantic();
1729          /**Because the Java.zbnf-script defines a < value> respectively < simpleValue?> in a flatten way,
1730           * the < simpleValue> is not an extra result item. All items of a value expression are disposed
1731           * one after another: an optional < unaryOperator> is always followed by a peculiarity of a 
1732           * < simpleValue>, after them a < binaryOperator> may be followed. 
1733           * The < conditional> is the last one in this disposal. 
1734           * But this correct order of items should not be tested here. It is dedicated by the syntax of Java
1735           * and the syntax of ZBNF script.
1736           */
1737          if(sSemantic.equals("StringLiteralMethod"))
1738          { /* ZBNF-syntax: simpleValue::=<?> ... <""?simpleStringLiteral>[ \. <simpleMethodCall?StringLiteralMethod> ]
1739             * Because a simpleValue doesn't create a own ZBNF-component, its components are visible here. 
1740             * Inside {@link #gen_simpleValue(ZbnfParseResultItem, ClassData[], LocalIdents, char) 
1741             * the <""?simpleStringLiteral> isn't known. It is the sInstance.
1742             * NOTE: The form z_StringJc("literal") is not able to use in C because forex the literal
1743             * "example\0second" is a String of 14 chars in Java, including the \0.
1744             * The routine z_StringJc("example\0second") will build only a String with 7 chars, ending on \0.
1745             * That is false. Therefore the number of chars is calculated here and given. 
1746             */
1747            assert(sLiteral.charAt(0) == '\"');
1748            int zLiteral = sLiteral.length();
1749            assert(sLiteral.charAt(zLiteral -1) == '\"');
1750            int nrofBackslash =0;  //any backslash builds one char with the following one.
1751            for(int ii = 1; ii < zLiteral; ii++){
1752                    if(sLiteral.charAt(ii) == '\\'){
1753                            nrofBackslash +=1;
1754                    }
1755            }
1756            int nrofCharsLiteral = zLiteral - 2 -nrofBackslash;  //without ""
1757            
1758            String sInstance = "zI_StringJc(" + sLiteral + "," + nrofCharsLiteral + ")";
1759            
1760            CCodeData envInstance = new CCodeData(sInstance, CRuntimeJavalikeClassData.clazzStringJc.classTypeInfo);  
1761            CCodeData codeExpr =
1762            gen_simpleMethodCall( item, null, envInstance, localIdents, maybeNonPersistent, '.');     //localIdents used for method arguments. 
1763            expr += codeExpr.cCode;
1764            typeVal = codeExpr.identInfo.typeClazz;  //the return type of the method, at ex. "xyz".indexOf(char) returns int.
1765            modeAccess = codeExpr.modeAccess;
1766            modeStatic = codeExpr.identInfo.modeStatic;  //maybe 'r' for nonPersistent
1767            sLiteral = null;
1768          }
1769          else
1770          { if(sLiteral != null)
1771            { expr += sLiteral;
1772              sLiteral = null;
1773            }
1774            
1775            if(sSemantic.equals("unaryOperator"))
1776            { String operator = item.getParsedText();
1777              expr += operator;
1778            }
1779            else if(sSemantic.equals("binaryOperator"))
1780            { String operator = item.getParsedText();
1781              if(  typeVal != null 
1782                && operator.equals("+")         
1783                && ( !typeVal.isPrimitiveType()  //+ on not primitive type can only be a String concatenation.
1784                            //|| typeVal.getClassIdentName().equals("char const*")
1785                            || typeVal == CRuntimeJavalikeClassData.clazz_s0
1786                    )
1787                )
1788              { CCodeData firstValue = new CCodeData(expr, typeVal.classTypeInfo, modeAccess);
1789                    CCodeData cString = gen_ConcatenatedStrings(expr, typeVal, modeAccess, iter, zbnfDescription, null, localIdents, intension);
1790                expr = cString.cCode;
1791                typeVal = cString.identInfo.typeClazz; //Java2C_Main.singleton.standardClassData.clazzStringJc;
1792                modeStatic = cString.identInfo.modeStatic;  //maybe 'r' for nonPersistent
1793                sTempRef = cString.sTempRef; //maybe null
1794              }
1795              else
1796              {
1797                expr += " " + operator + " ";
1798              }  
1799            }
1800            else if(sSemantic.equals("cmpOperator"))
1801            { String operator = item.getParsedText();
1802              if( codeValue != null 
1803                && (  operator.equals("==")        //NOTE: compare to null
1804                   || operator.equals("!=")
1805                   )
1806                && codeValue.getTypeName().equals("StringJc")
1807                && codeValue.dimensionArrayOrFixSize == 0
1808                )
1809              { //normally a StringJc comes as struct, here the pointer to the chars are compared.
1810                //StringJc is equal the osal-oriented OS_ValuePtr.
1811                //expr = "getPtr_OS_ValuePtr((" + expr + "), char const*) " + operator + " ";  
1812                expr = expr + ".ptr__" + operator + " ";  //TODO use isNull_StringJc(expr), 
1813                //which strings are equal?
1814              }
1815              else if(codeValue != null && "@&".indexOf(codeValue.modeAccess)>=0){
1816                    expr += ".ref" + operator + " ";
1817              }
1818              else
1819              {
1820                expr += " " + operator + " ";
1821              }
1822              bRefNeed = true;
1823              typeVal = CRuntimeJavalikeClassData.clazz_bool;
1824              modeAccess = '%';  //boolean immediate value.
1825              modeStatic = '.';  //not non-persistent
1826              isBoolean = true;
1827            }
1828            else if(sSemantic.equals("booleanOperator"))
1829            { String operator = item.getParsedText();
1830              expr += " " + operator + " ";
1831              typeVal = CRuntimeJavalikeClassData.clazz_bool;
1832              modeAccess = '%';  //boolean immediate value.      
1833              modeStatic = '.';  //not non-persistent
1834              isBoolean = true;
1835            }
1836            else if(sSemantic.equals("conditional")) // condition ? truevalue : falsevalue
1837            { //it should be the last one in the disposal of parts of value.
1838              expr += " ? ";
1839              ZbnfParseResultItem zbnfTrueValue = item.getChild("trueValue");
1840              CCodeData trueValue = gen_value(zbnfTrueValue, zbnfDescription, true, intension);
1841              if(trueValue.identInfo.modeStatic =='r'){ modeStatic = 'r'; } //it is non-persistent.
1842              expr += trueValue.cCode;
1843              ZbnfParseResultItem zbnfFalseValue = item.getChild("falseValue");
1844              CCodeData falseValue = gen_value(zbnfFalseValue, zbnfDescription, true, intension);
1845              expr += " : ";
1846              expr += falseValue.cCode;
1847              if(falseValue.identInfo.modeStatic =='r'){ modeStatic = 'r'; } //it is non-persistent.
1848              //the trueValue and the falseValue should have the same properties.
1849              typeVal = trueValue.identInfo.typeClazz;
1850              modeAccess = trueValue.modeAccess;
1851              modeArrayElement = trueValue.identInfo.modeArrayElement;
1852              isBoolean = false;   
1853            }    
1854            else if(sSemantic.equals("assignment"))
1855            { expr += " = /*? assignment*/";
1856            }
1857            else if(sSemantic.equals("simpleStringLiteral"))
1858            { sLiteral = "\"" + item.getParsedString() + "\"";
1859              if(sLiteral.startsWith("\"integral"))
1860                stop();
1861              typeVal = CRuntimeJavalikeClassData.clazz_s0;
1862              modeAccess = 't';
1863              modeStatic = '.'; //not non-persistent 
1864            }  
1865            else if(sSemantic.equals("instanceType"))
1866            { ClassData instanceType = genClass.getType(item, localIdents);
1867                    genClass.writeContent.addIncludeC(instanceType.sFileName, "instanceof"); 
1868              String sInstanceType = instanceType.getClassCtype_s();
1869              CCodeData cCodeExpr = new CCodeData(expr, new FieldData(null, typeVal, null,null,null, '.', modeAccess, dimensionArray, null, modeArrayElement, null));
1870              String cCodeReference = CRuntimeJavalikeClassData.fieldObjectJc.testAndcast(cCodeExpr, '*');
1871              expr = " instanceof_ObjectJc(" + cCodeReference + ", &reflection_" + sInstanceType + ")";
1872              /**Result of expression with current content is the following type: */ 
1873              typeVal = CRuntimeJavalikeClassData.clazz_bool;
1874              modeAccess = '&';
1875              modeArrayElement = '.';
1876              modeStatic = '.';
1877              dimensionArray = 0;
1878            }
1879            else //it is any peculiarity of simpleValue, need not: if(semantic.equals("simpleValue"))
1880            { codeValue = gen_simpleValue(item, zbnfDescription, localIdents, maybeNonPersistent, intension, bRefNeed);
1881              expr += codeValue.cCode;
1882              modeStatic = codeValue.identInfo.modeStatic;
1883              if(expr.startsWith("ifc22"))
1884                stop();
1885              if(!isBoolean)
1886              { //the right operator wins, TODO test both!
1887                ClassData typeValNew = codeValue.identInfo.typeClazz;
1888                int castScore;
1889                if(typeVal ==null){
1890                    //first time to determine the type of the expression, it is the first expression part.
1891                    typeVal = typeValNew;
1892                    modeAccess = codeValue.modeAccess;
1893                    //Note: The codeValue.identInfo may be an array, but codeValue may be the access to an element.
1894                    dimensionArray = codeValue.dimensionArrayOrFixSize;  
1895                    modeArrayElement = dimensionArray >0 ? codeValue.identInfo.modeArrayElement : '.'; 
1896                    modeStatic =  codeValue.identInfo.modeStatic;
1897                } else if(typeValNew == typeVal || (castScore = typeValNew.matchedToTypeSrc(typeVal)) == ClassData.CastInfo.kCastEqual) {
1898                    //no change of type.
1899                    stop();
1900                } else if(castScore >=ClassData.CastInfo.kCastAutomatic){
1901                    //The current type value is able to cast in the new automaticly. 
1902                    //Then take the new because it is more common:
1903                    typeVal = typeValNew;
1904                    modeAccess = codeValue.modeAccess;
1905                } else {
1906                    //the new typevalue is lesser, because the current is not able to cast.
1907                    stop();
1908                }
1909              }
1910            }
1911          }//not "StringLiteralMethod"  
1912        }//while
1913        //the expression is a repetition of the parts in while loop, 
1914        //they are concatenated together in expr.
1915        if(sLiteral != null)
1916        { expr += sLiteral;  //the first and only was a simpleStringLiteral
1917        }
1918        assert(modeAccess != '.');
1919        assert(typeVal != null);
1920        
1921        if(expr.equals("ythis->formatField"))
1922          stop();
1923        
1924        /*switch(modeAccess)
1925        { case '$':
1926          { //the result is an embedded struct. because a value should be either an immediate value
1927            //or a pointer, it should be referenced.
1928            modeAccess = '*'; //a simple reference
1929            expr = "&(" + expr + ")";  //build the pointer.
1930          }break;
1931          case '@':
1932          { stop();
1933            
1934          }break;
1935        }*/  
1936        FieldData valueInfo = new FieldData
1937          ("$value", typeVal, null, null, null, modeStatic, modeAccess, dimensionArray, null, modeArrayElement, null); 
1938        CCodeData retCode = new CCodeData(expr, valueInfo);
1939        retCode.sTempRef = sTempRef;  //maybe null
1940        return retCode;
1941      }
1942    
1943    
1944      /**This routine generates an concatenated String.  
1945       * 
1946       * @param sFirstString The first part of String expression found in gen_Value before calling this routine.
1947       * @param firstType The associated type to the sFirstString
1948       * @param firstModeAccess
1949       * @param iterZbnf iterator through parse result.
1950       * @param zbnfDescription description parse result of the whole expression (statement)
1951       * @param sStringBuilderTmp A given temporary StringBuilder to use.
1952       * @param localIdents
1953       * @param creationMode
1954       * @return
1955       * @throws ParseException
1956       * @throws FileNotFoundException
1957       * @throws IllegalArgumentException
1958       * @throws IOException
1959       * @throws IllegalAccessException
1960       * @throws InstantiationException
1961       */
1962      CCodeData gen_ConcatenatedStrings
1963      ( String sFirstString
1964      , ClassData firstType
1965      , char firstModeAccess
1966      , Iterator<ZbnfParseResultItem> iterZbnf
1967      , ZbnfParseResultItem zbnfDescription
1968      , String sStringBuilderToUse
1969      , LocalIdents localIdents, char xxxintension
1970      ) throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
1971      { //String sString;
1972        StringBuilder uExpr = new StringBuilder(200); 
1973        ClassData type = firstType;
1974        String sType;
1975        genClass.writeContent.addIncludeC("Jc/StringJc", "string concatenation");
1976        /**The first part of concatenation is given, test the type and build a new StringBuffer to concatenate.
1977         * The new StringBuffer should be managed in 'newObjx' like all new Objects, see {@link nrofNew}.
1978         */
1979        //NOTE: the newObj is of type ObjectJc*, cast it directly, it is the same mem location.
1980        //sString = "(StringBuilderJc*)(" + gen_newObj() + " = (ObjectJc*)";
1981        final String sTempString;
1982        ZbnfParseResultItem zbnfStringBuilderInStack;
1983        if(sStringBuilderToUse != null){
1984            /**An append operation with known StringBuilder-buffer. */
1985            sTempString = sStringBuilderToUse;
1986          if(sFirstString != null){
1987            /**The call of the routine is invoked from gen_value(...) or from gen_StringAssignment(...)
1988             * with new used buffer: */
1989            assert(false);
1990            uExpr.append( GenerateClass.genIndent(indent+1) + "( setLength_StringBuilderJc(" + sStringBuilderToUse + ", 0, _thCxt)"
1991                    + GenerateClass.genIndent(indent+1) + ", ");        
1992          } else {
1993            /**The call of the routine is not invoked from gen_value(...) but from gen_StringAssignment(...)
1994             * with operation +=: */
1995            uExpr.append( GenerateClass.genIndent(indent+1) + "( ");  //append, do not change
1996          }
1997        }
1998        else if(zbnfDescription != null && (zbnfStringBuilderInStack = zbnfDescription.getChild("StringBuilderInStack")) != null){
1999          int sizeStringBuilderInStack = (int)zbnfStringBuilderInStack.getParsedInteger();
2000          //sTempString = gen_StringBuilderInStack(sizeStringBuilderInStack);
2001          if(this.sizeStringBuilderInStack < sizeStringBuilderInStack){
2002            this.sizeStringBuilderInStack = sizeStringBuilderInStack;
2003          }
2004          sTempString = "&_stringBuilder.u";
2005            uExpr.append( GenerateClass.genIndent(indent+1) + "( setLength_StringBuilderJc(" + sTempString + ", 0, _thCxt)"
2006                  + GenerateClass.genIndent(indent+1) + ", ");        
2007        } 
2008        else if(zbnfDescription != null && (zbnfStringBuilderInStack = zbnfDescription.getChild("StringBuilderInThreadCxt")) != null){
2009          sTempString = "_stringBuilderThCxt";
2010          this.needPtrStringBuilderInThCxt = true;
2011            uExpr.append( GenerateClass.genIndent(indent+1) + "( setLength_StringBuilderJc(" + sTempString + ", 0, _thCxt)"
2012                  + GenerateClass.genIndent(indent+1) + ", ");        
2013        } 
2014        else {
2015          sTempString= gen_tempString();
2016          uExpr.append( GenerateClass.genIndent(indent+1) + "( " + sTempString + " = new_StringBuilderJc(-1, _thCxt)" 
2017                  + GenerateClass.genIndent(indent+1) + ", setStringConcatBuffer_StringBuilderJc(" + sTempString + ")" 
2018                  + GenerateClass.genIndent(indent+1) + ", ");
2019        }
2020        sType = type.getClassIdentName();
2021        boolean bNext = false;
2022        if(sFirstString != null){
2023            bNext = true;
2024            //if     (sType.equals("char const*")){ 
2025            if (type == CRuntimeJavalikeClassData.clazz_s0){ 
2026            uExpr.append( "append_z_StringBuilderJc(" + sTempString + ", " + sFirstString + ", _thCxt)");  
2027          }
2028          else if(sType.equals("StringJc")){      
2029            uExpr.append( "append_s_StringBuilderJc(" + sTempString + ", " + sFirstString + ", _thCxt)");  
2030          }
2031          else if(sType.equals("StringBuilderJc")){
2032            sFirstString = FieldData.testAndChangeAccess('*', sFirstString, firstModeAccess);
2033            uExpr.append( "append_u_StringBuilderJc(" + sTempString + ", " + sFirstString + ", _thCxt)");  
2034          }
2035          else {
2036            int scoreInt32 = type.matchedToTypeSrc(CRuntimeJavalikeClassData.clazz_int32);
2037            int scoreFloat = type.matchedToTypeSrc(CRuntimeJavalikeClassData.clazz_float);
2038            int scoreDouble = type.matchedToTypeSrc(CRuntimeJavalikeClassData.clazz_double);
2039            if(scoreDouble == ClassData.CastInfo.kCastEqual){
2040              uExpr.append( "append_D_StringBuilderJc(" + sTempString + ", " + sFirstString + ", _thCxt)");  
2041            } else if(scoreFloat ==ClassData.CastInfo.kCastEqual){
2042              uExpr.append( "append_F_StringBuilderJc(" + sTempString + ", " + sFirstString + ", _thCxt)");  
2043            } else if(scoreInt32 >ClassData.CastInfo.kCastNo){ //castable to int32
2044                uExpr.append( "append_I_StringBuilderJc(" + sTempString + ", " + sFirstString + ", _thCxt)");  
2045            } else {
2046                    throw new IllegalArgumentException("conversion to append_StringBuilder failed, type: " + sType);
2047            }
2048          } 
2049        }
2050        while(iterZbnf.hasNext())
2051        { ZbnfParseResultItem item = iterZbnf.next();
2052          StringBuilder expr = new StringBuilder(100);
2053          //ClassData[] retType1 = new ClassData[1];  //classData of the part of expression
2054          String sSemantic = item.getSemantic();
2055          
2056          if(sSemantic.equals("binaryOperator"))
2057          { //there is only possible a '+'
2058            //String operator = item.getParsedText();
2059              
2060          }
2061          else
2062          { if(sSemantic.equals("conditional"))
2063            { //it should be the last one in the disposal of parts of value.
2064              expr.append(" ? ");
2065              ZbnfParseResultItem zbnfTrueValue = item.getChild("trueValue");
2066              CCodeData trueValue = gen_value(zbnfTrueValue, null, true, 't');
2067              expr.append(trueValue.cCode);
2068              ZbnfParseResultItem zbnfFalseValue = item.getChild("falseValue");
2069              CCodeData falseValue = gen_value(zbnfFalseValue, null, true, 't');
2070              expr.append(" : ");
2071              expr.append(falseValue.cCode);
2072              type = falseValue.identInfo.typeClazz;
2073            }    
2074            else //it is any peculiarity of simpleValue, need not: if(semantic.equals("simpleValue"))
2075            { CCodeData methodCode = gen_simpleValue(item, null, localIdents, true, 't', true);
2076              expr.append(methodCode.cCode);
2077              type = methodCode.identInfo.typeClazz;
2078            }
2079            //TODO calculate retType
2080            //type = retType1[0];  //the simple calc
2081            sType = type == null ? "void" : type.getClassIdentName();
2082            final String sConcat;
2083            if     (sType.equals("char const*"))         {  sConcat = "append_z_StringBuilderJc(" + sTempString + ", "+ expr + ", _thCxt)";  }
2084            else if(sType.equals("StringJc"))      {  sConcat = "append_s_StringBuilderJc("  + sTempString + ", "+ expr + ", _thCxt)";  }
2085            else if(sType.equals("StringBuilderJc")){  sConcat = "append_u_StringBuilderJc(" + sTempString + ", "+ expr + ", _thCxt)";  }
2086            else if(sType.equals("int16"))         {  sConcat = "append_I_StringBuilderJc(" + sTempString + ", "+ expr + ", _thCxt)";  }
2087            else if(sType.equals("int32"))         {  sConcat = "append_I_StringBuilderJc(" + sTempString + ", "+ expr + ", _thCxt)";  }
2088            else if(sType.equals("int64"))         {  sConcat = "append_J_StringBuilderJc(" + sTempString + ", "+ expr + ", _thCxt)";  }
2089            else if(sType.equals("float"))         {  sConcat = "append_F_StringBuilderJc(" + sTempString + ", "+ expr + ", _thCxt)";  }
2090            else if(sType.equals("double"))        {  sConcat = "append_D_StringBuilderJc(" + sTempString + ", "+ expr + ", _thCxt)";  }
2091            else                                   {  sConcat = "append_L_StringBuilderJc/*" + sType + "*/(" + sTempString + ", " + expr + ", _thCxt)";  }
2092            if(bNext){
2093              uExpr.append( GenerateClass.genIndent(indent+1) + ", ");
2094            }
2095            uExpr.append( sConcat);
2096            bNext = true;
2097          }  
2098        }
2099        
2100        boolean toStringNonPersist = zbnfDescription != null && zbnfDescription.getChild("toStringNonPersist")!= null;    
2101        if(toStringNonPersist){
2102            uExpr.append( GenerateClass.genIndent(indent+1) + ", toStringNonPersist_StringBuilderJc(&(" + sTempString + ")->base.object, _thCxt)" + GenerateClass.genIndent(indent+1) +")");
2103        } else {
2104            uExpr.append( GenerateClass.genIndent(indent+1) + ", toString_StringBuilderJc(&(" + sTempString + ")->base.object, _thCxt)" + GenerateClass.genIndent(indent+1) +")");
2105        }
2106        CCodeData codeRet = new CCodeData(uExpr.toString(), CRuntimeJavalikeClassData.clazzStringJc.classTypeInfo);
2107        if(zbnfDescription !=null && zbnfDescription.getChild("toStringNonPersist") !=null){
2108            /**Because the String Buffer should not be persistent, it can be used for append operation to the same String.
2109             * To transport the information, which StringBuilder is used, its name will be placed
2110             * in the return data. This is only done because the toString can be non-persistent.
2111             * In the other way the StringBuilder is freezed and it have not be used for further operations.
2112             * Therefore its name isn't meanfully. */
2113            codeRet.sTempRef = sTempString;
2114        }
2115        return codeRet;      
2116        //return "toString_StringBuilderJc(" + sString + ")";
2117      }
2118    
2119    
2120    
2121    
2122      /**generates the code for ZBNF-< simpleValue>. 
2123       * A simpleValue is a value without operators, a non calculated value, in opposite to a < value>.
2124       * But a simpleValue may be an expression accessing a referenced value.
2125       * Examples are: var, this.var, super.var, ref.var, "xyz", method(a.b),
2126       *               "xyz".indexof(cc), method().val
2127       * <ul>
2128       * <li>A simpleValue may be a < variable>, converted with {@link #gen_variable(ZbnfParseResultItem, LocalIdents, char, org.vishia.java2C.FieldData[])},
2129       *     but a < variable> can be more as that, especially a left value. This is not considered here.
2130       * <li>A simple value may be a casted value, written in the syntax in Java2C.zbnf with < ?casting> ( < type> ) < value>.
2131       * <li>There is a special case of casting: (String)null will be converted to null_StringJc, because the simple null fails in C.    
2132       * <li>A simple value may be such as <code>this</code> or <code>super</code>.
2133       * <li>A simple value can be a new Object, generated with {@link #gen_newObject(ZbnfParseResultItem, CCodeData, LocalIdents)}. 
2134       * <li>A < methodCall> is also a variant of simple value. Thats why this method is also used to generate a < methodCall>
2135       *     in statements. A < methodCall> tests wether it is referenced, than {@link #gen_simpleMethodCall(ZbnfParseResultItem, String, org.vishia.java2C.FieldData, LocalIdents)}
2136       *     is called.
2137       * </ul>
2138       * @param zbnfItem One of the alternatives in <code>simpleValue::=...</code>
2139       * @param localIdents of the environment
2140       * @param intension calling intension.
2141       * @return
2142       * @throws ParseException
2143       * @throws InstantiationException 
2144       * @throws IllegalAccessException 
2145       * @throws IOException 
2146       * @throws IllegalArgumentException 
2147       * @throws FileNotFoundException 
2148       */
2149      public CCodeData gen_simpleValue(
2150              ZbnfParseResultItem zbnfItem, ZbnfParseResultItem zbnfDescription
2151            , final LocalIdents localIdents
2152            , boolean maybeNonPersistent
2153        , final char intension, final boolean bRefNeed)
2154      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
2155      { CCodeData simpleValue; // = new CCodeData(); // = "";
2156        ClassData[] retType = new ClassData[1];
2157        String sSemantic = zbnfItem.getSemantic();
2158        simpleValue = genClass.genConstantValue(zbnfItem);  //simpleStringLiteral, hexValue etc.
2159        if(simpleValue != null)
2160        { //done
2161          retType[0] = simpleValue.identInfo.typeClazz;
2162        }
2163        else if(sSemantic.equals("casting"))
2164        { ZbnfParseResultItem zbnfValue = zbnfItem.getChild("value");
2165            if(zbnfValue == null){ 
2166                    zbnfValue = zbnfItem;  //it contains the value elements. 
2167            }
2168            CCodeData codeValue = gen_value(zbnfValue, zbnfDescription, true, 'e');
2169            ZbnfParseResultItem zbnfType = zbnfItem.getChild("type");    //<typeIdent>
2170            ClassData typeClazz = genClass.getType(zbnfType, localIdents);
2171          String castType = typeClazz.getClassIdentName();
2172          final FieldData castedField;
2173          if(codeValue.identInfo.modeStatic =='r'){
2174            castedField = new FieldData(typeClazz.classTypeInfo, 0, 0, '.', 'r');
2175          } else {
2176            castedField = typeClazz.classTypeInfo;
2177          }
2178          simpleValue = new CCodeData("(" + castType + ")", castedField);
2179          zbnfItem = zbnfItem.next();                     //<simpleValue>
2180          String valueToCast = codeValue.cCode; 
2181            //gen_value(zbnfItem, zbnfDescription, retType, localIdents, true, 'e');
2182          if(valueToCast.equals("null") && castType.equals("StringJc"))
2183          { //special case (StringJc)null
2184            simpleValue.cCode = "null_StringJc";
2185          }
2186          else
2187          { //common case: (castType) value
2188            simpleValue.cCode += valueToCast;
2189          }  
2190          retType[0] = typeClazz;  //overwrites the retType from simpleValue().
2191        }
2192        else if(sSemantic.equals("parenthesisExpression"))
2193        { simpleValue = gen_value(zbnfItem, zbnfDescription, true, 'e');
2194          simpleValue.cCode = "(" + simpleValue.cCode + ")";
2195        }
2196        else if(sSemantic.equals("variable"))
2197        { //FieldData typeLastVariable[] = new FieldData[1];
2198          simpleValue = gen_variableAccess(zbnfItem, zbnfDescription, localIdents, intension, genClass.classData.thisCodeInfo); //, typeLastVariable);
2199          if(simpleValue.modeAccess == '@'){
2200            //simpleValue.cCode += ".ref"; }  
2201            simpleValue.cCode = "REFJc(" + simpleValue.cCode + ")"; 
2202            simpleValue.modeAccess = '*';
2203          } else if(simpleValue.modeAccess == '&' && bRefNeed){
2204            simpleValue.cCode += ".ref";  //method-table-reference, get the reference itself
2205          }
2206          //if(  simpleValue.identInfo.fixArraySizes != null 
2207          //  && simpleValue.identInfo.modeAccess == '$'
2208          //  && simpleValue.dimensionArrayOrFixSize >0
2209          //  )
2210          if(simpleValue.modeAccess == 'Y')
2211          { /**it is defined as an embedded array structure:
2212             * cast it to its known array pointer type. Otherwise it isn't useable.
2213             * NOTE: The representation of a value is a reference in all cases. 
2214             */
2215            String sArrayPostifx = simpleValue.identInfo.modeArrayElement == '*' ? "_YP_t*" : "_Y_t*";
2216            simpleValue.cCode = "(struct " + simpleValue.identInfo.typeClazz.getClassIdentName() + sArrayPostifx + ")" 
2217                              + "(&( " + simpleValue.cCode + "))";
2218            simpleValue.modeAccess = 'X'; //it is now a reference to an array.
2219          }
2220          
2221          retType[0] = simpleValue.identInfo.typeClazz; //typeLastVariable[0].typeClazz;
2222        }
2223        else if(sSemantic.equals("newObject"))
2224        { simpleValue = gen_newObject(zbnfItem, null); //, localIdents);
2225        }
2226        else if(sSemantic.equals("newArray"))
2227        { String sValue = gen_newArray(zbnfItem, retType, localIdents, null);
2228          simpleValue = new CCodeData(sValue, retType[0].classTypeInfo);
2229        }
2230        else if(sSemantic.equals("methodCall"))
2231        { { String sMethodName = zbnfItem.getChild("methodName").getParsedString();
2232            if(sMethodName.equals("format"))
2233              stop();
2234          }
2235          ZbnfParseResultItem itemReference = zbnfItem.getChild("reference");
2236          CCodeData reference;
2237          final String cCode;
2238          String[] sConcatenatedReference = new String[1]; 
2239          if(itemReference != null)
2240          { 
2241            reference = gen_reference(sConcatenatedReference, itemReference, zbnfDescription, localIdents, genClass.classData.thisCodeInfo, 'm'); //, typeReference); // retIdentInfo);
2242            if(true){}
2243            else if(reference.isReturnThis()){
2244              cCode = "(" + reference.cCode;
2245              reference.cCode = "_temp" + nrofTempRefForConcat;
2246            }
2247            else if(reference.sTempRef !=null) {
2248              cCode = "(" + reference.cCode;
2249              reference.cCode = reference.sTempRef;
2250            }
2251            else{ cCode = null; }
2252          }
2253          else
2254          { //no reference before method call, either it is a static method or this-method.
2255            reference = genClass.classData.thisCodeInfo;
2256            cCode = null;
2257          }
2258          //if it is a static method, the sInstance will be ignored.
2259          simpleValue = gen_simpleMethodCall
2260                        ( zbnfItem
2261                        , zbnfDescription    
2262                        , reference //sInstanceRef
2263                        , localIdents     //used for method arguments. 
2264                        , maybeNonPersistent
2265                        , intension
2266                        );
2267          if(sConcatenatedReference[0]!=null){
2268            /**A call of methods and maybe assignment to internal temporary references is returned: */
2269            simpleValue.cCode = GenerateClass.genIndent(indent+1) + "( " + sConcatenatedReference[0] + simpleValue.cCode + GenerateClass.genIndent(indent+1) + ")";
2270          } 
2271          if(false && cCode != null){
2272            /**_temp is used, take the setting of _temp in simpleValue.cCode. */
2273            simpleValue.cCode = cCode + simpleValue.cCode + ")";
2274          }  
2275        }
2276        else
2277        { throw new ParseException("unexpected semantic:" + sSemantic,0);
2278        }
2279        return simpleValue;
2280      }
2281    
2282    
2283      /**generates a simple method call. It includes the evaluation of actual parameters 
2284       * using {@link #gen_value(ZbnfParseResultItem, ClassData[], LocalIdents, char)}.
2285       * The method-name is built with the Java-method-name, following by the class name as postfix.
2286       * In C all methods should have a unique name.
2287       * <br>
2288       * If it is a class method, the reference of the class is generated as the first argument.
2289       * Depended on the kind of the class reference, a <code>&(ref)</code> is generated if it is an embedded reference.
2290       * @param parent
2291       * @param sInstanceRef The generated C-Code for the reference to the methods class-instance. 
2292       *        It is the output from {@link #gen_reference(String[], ZbnfParseResultItem, LocalIdents, char, org.vishia.java2C.FieldData[])}
2293       *        For static methods this parameter is null.
2294       *        If it is a constructor call, this  is either the reference to the outer class or null.
2295       * @param envInstanceInfo The type-info of the class from which the method is member of.
2296       * @param localIdents The local identifier of this statement block level used for parameter values.
2297       * @param maybeNonPersist The result is accepted as non-persistent too.
2298       * @return
2299       * @throws ParseException
2300       * @throws InstantiationException 
2301       * @throws IllegalAccessException 
2302       * @throws IOException 
2303       * @throws IllegalArgumentException 
2304       * @throws FileNotFoundException 
2305       * @throws InstantiationException 
2306       */
2307      private CCodeData gen_simpleMethodCall
2308      ( ZbnfParseResultItem zbnfMethod
2309      , ZbnfParseResultItem zbnfDescription    
2310      , CCodeData envInstance
2311      , LocalIdents localIdents
2312      , boolean maybeNonPersistent
2313      , char intension
2314      )
2315      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
2316      { String sMethodNameJava = zbnfMethod.getChild("methodName").getParsedString();
2317        if(sMethodNameJava.equals("txAnswer"))
2318          stop();
2319        String sNewObject = null; //no new Object, for param nrofNew
2320        if(sMethodNameJava.equals("_sizeof"))
2321        { 
2322          return new CCodeData("sizeof(" + envInstance.identInfo.getName() + ")", CRuntimeJavalikeClassData.clazz_int.classTypeInfo);
2323        }
2324        else { 
2325          ClassData classOfMethod = envInstance.identInfo.instanceClazz != null 
2326                                  ? envInstance.identInfo.instanceClazz 
2327                                  : envInstance.identInfo.typeClazz ; 
2328          CCodeData methodCode = gen_InternalMethodCall(
2329                    zbnfMethod, zbnfDescription, sMethodNameJava, classOfMethod, envInstance
2330                    , sNewObject//, localIdents
2331                    );
2332          if(methodCode.cCode.contains("createInstance"))
2333            stop();
2334          if(methodCode.identInfo.modeStatic == 'n'){
2335            /**Because the return value of the method may be a new instance, which isn't activated for garbage collection yet,
2336             * it is stored in a temp reference and activated on return. */
2337            String sTempRef = tempRefForConcat(methodCode.identInfo);
2338            String cCode = "(" + sTempRef + " = " + methodCode.cCode + ")";
2339            methodCode.cCode = cCode;
2340          }
2341          final String sTypeRetrurn = methodCode.getTypeName();
2342              
2343          if(methodCode.identInfo.modeStatic == 'r' //non-persistent StringJc
2344            && intension != 't'  //no string concatenation.
2345            && (zbnfDescription== null || zbnfDescription.getChild("toStringNonPersist") == null)
2346            && !maybeNonPersistent
2347            && methodCode.identInfo.modeAccess == 't'  //String type
2348            ){
2349            /**If the type of the parameter is 'StringJc', the cCode represents any expression
2350             * which expression type is 'StringJc'. The String may be stored non-persistent.
2351             * To establish cleaned data conditions, the String should be made persistent.
2352             * But this action is not done, if the user prevent it by setting an annotation against it.
2353             */ 
2354            String sTempVariable = gen_persistringVariable();
2355            String sEnvType = envInstance.identInfo.typeClazz.getClassIdentName();
2356            if(sMethodNameJava.equals("toString") && sEnvType.equals("StringBuilderJc")){
2357              /**Change the name of the called method. */
2358                    methodCode.cCode = sTempVariable + " = toStringPersist" + methodCode.cCode.substring(8); 
2359            } else {
2360                    methodCode.cCode = sTempVariable + " = persist_StringJc(" + methodCode.cCode + ")";
2361            }
2362          }
2363          return methodCode;
2364        }  
2365      }
2366    
2367    
2368      
2369      
2370      
2371      /**generates either a new or a simple method call. It includes the evaluation of actual parameters 
2372       * using {@link #gen_value(ZbnfParseResultItem, ClassData[], LocalIdents, char)}.
2373       * The method-name is built with the Java-method-name, following by the class name as postfix.
2374       * In C all methods should have a unique name.
2375       * <br>
2376       * If it is a class method, the reference of the class is generated as the first argument.
2377       * Depended on the kind of the class reference, a <code>&(ref)</code> is generated if it is an embedded reference.
2378       TODO
2379       * @param zbnfMethod Zbnf parse result item from <code>simpleMethodCall::=</code> 
2380       *        or <code>newObject::=</code> or <code>[<?superCall> super ...]</code>,
2381       *        may be null if a default constructor is called. 
2382       * @param sMethodNameJava The methodname from Java
2383       * @param declaringClass The class where the method should be member of. 
2384       *        Mostly it is the ClassData of the envInstance: {@link CCodeData#identInfo} and there
2385       *        {@link FieldData#typeClazz}, but if the super class is accessed, it is the super class of them. 
2386       * @param envInstance Type and name of the reference to the instance, from which the method is called. 
2387       *        It is the output from {@link #gen_reference(String[], ZbnfParseResultItem, LocalIdents, char, org.vishia.java2C.FieldData[])}
2388       *        For static methods this parameter is null.<br>
2389       *        If it is a constructor call, this  is either the reference to the outer class: 
2390       *        The constructor respectively new(...) is a method of the outer class: outer.new(...)
2391       *        Or null it should be null: The constructor respectively new(...) of not-inner classes is a static method.
2392       * @param sNewObject If it is a constructor call, the generated C-Code for access the new Object, else null.
2393       *        it is used as second argument of ctor(...) respectively first argument of ctor(...) if envInstance == null.
2394       * @param localIdents The local identifier of this statement block level used for parameter values.
2395       * @return
2396       * @throws ParseException
2397       * @throws InstantiationException 
2398       * @throws IllegalAccessException 
2399       * @throws IOException 
2400       * @throws IllegalArgumentException 
2401       * @throws FileNotFoundException 
2402       * @throws InstantiationException 
2403       */
2404      CCodeData gen_InternalMethodCall
2405      ( ZbnfParseResultItem zbnfMethod
2406      , ZbnfParseResultItem zbnfDescription    
2407      , String sMethodNameJava
2408      , ClassData declaringClass
2409      , final CCodeData envInstance
2410      , String sNewObject
2411      //, LocalIdents localIdents
2412      )
2413      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
2414      //, InstantiationException
2415      {
2416        String ret;
2417        boolean bEmbeddedType = false;
2418        String sMethodEnvType;
2419        boolean ctorCall = false;
2420        boolean toStringNonPersist = zbnfDescription != null && zbnfDescription.getChild("toStringNonPersist")!= null;    
2421        if(sMethodNameJava.equals("this")){
2422            //call of another ctor of the same class, search ctor
2423            sMethodNameJava = "ctorO";
2424            ctorCall = true;
2425        } else if(sMethodNameJava.equals("super")){
2426            stop();
2427        }
2428        if(sMethodNameJava.equals("setBigEndian") || sMethodNameJava.equals("ctorO_C_INNER"))
2429            stop();
2430        if(envInstance != null) // it is not a implicit this-access
2431        { //The reference type is defined in an other class, include it!
2432          boolean bTypeSign = true;
2433          switch(envInstance.modeAccess)       //envInstanceInfo.sModifier.charAt(0))
2434          { case '%': case '$': bEmbeddedType = true; break;
2435            default: bTypeSign = false;
2436          }
2437          if(bTypeSign)
2438          { //sMethodEnvType = sMethodEnvType.substring(1);
2439          }
2440          sMethodEnvType = envInstance.getTypeName();
2441        }
2442        else
2443        { //a static method, no environment instance is given.
2444          sMethodEnvType = genClass.classData.sClassNameC;
2445        }
2446        if(sMethodEnvType.equals("FormatterJc")) //&& sMethodEnvType.equals("Target"))
2447          stop();
2448        //List<String> paramsC;
2449        //List<ClassData> paramsType;
2450        if(declaringClass != null)
2451        { genClass.writeContent.addIncludeC(declaringClass.sFileName, "method call");
2452        }
2453        final List<CCodeData> actParams = gatherActParams(zbnfMethod, zbnfDescription, sMethodNameJava);
2454        final Method method;
2455        String[] sPathMtbl = new String[1];
2456        if(sMethodNameJava.equals("txAnswer"))
2457          stop();
2458        method = declaringClass.searchMethod(sMethodNameJava, actParams, true, sPathMtbl);
2459        if(method == null){
2460            //Because methods are searched strict, it may not be found though there are known in Java.
2461            //reasons: typical, missed in stc-file.
2462            //Give a explicite message:
2463            StringBuilder uMsg = new StringBuilder(200);
2464            uMsg.append("method not found: ").append(sMethodNameJava).append("-_$: void %..return");
2465            String sSep = "(";
2466            if(actParams !=null){
2467              for(CCodeData param: actParams){
2468                            uMsg.append(sSep).append(param.identInfo.writeStruct());  //the type info
2469                            sSep = ", ";
2470                    }
2471                } uMsg.append(");");
2472                if(actParams !=null){
2473              uMsg.append(" called with param: ");
2474                    for(CCodeData param: actParams){
2475                            uMsg.append(param.cCode).append(", ");
2476                    }
2477                }
2478            uMsg.append("\nsearched in class: ");
2479            uMsg.append(declaringClass.getClassNameJavaFullqualified()).append(".java");
2480            uMsg.append(".\nSource of class: \"").append(declaringClass.sSourceOfClassData);
2481            uMsg.append("\".\nHint: Check the pre-translated or manual given stc-file. The method may be defined also in outer- or super- classes. ");
2482            throw new IllegalArgumentException(uMsg.toString()); 
2483        }
2484        if(method.sCName.startsWith("ctor"))
2485            stop();
2486        if(method.sCName.equals("ctorO_f_FileOutputStreamJc")) // && envInstance.cCode.equals(""))
2487          stop();
2488        final String sInstanceRef; //param value for ythis
2489        //assert(method.isStatic() && envInstance == null || method.sCName.startsWith("ctor"));
2490        if(!method.isStatic() &&  envInstance != null && envInstance.cCode != null)
2491        //if(envInstance != null && envInstance.cCode != null)
2492        { /**The C-reference of this for calling the method. A cast to super types and/or a access correction is done. 
2493           * At example from embedded instance to a reference, writing &cCode. */
2494          if(envInstance.modeAccess == 'C'){
2495            /**A class type, it should be a static method! */
2496            if(method.isUnknownMethod()){
2497              sInstanceRef = null;   //force exception if used.
2498            } else {
2499              throw new IllegalArgumentException("method is not static:" + method.sCName);
2500            }  
2501          } else {
2502            /**cast to the  method's class, but the cast ability from the envInstance to the method's class is tested too. */ 
2503            sInstanceRef = method.firstDeclaringClass.classTypeInfo.testAndcast(envInstance, '.');
2504          }
2505        } else { 
2506          sInstanceRef = null;   //force exception if used.
2507        }
2508        
2509        /**Method name for C is found, it is the complete name inclusively type information.
2510         * at example append_i_StringBuilderJc when searched StringBuffer.append(int) */
2511        if(envInstance != null && envInstance.identInfo.instanceClazz != null){
2512          /**call non-dynamic, type cast necessary: */
2513          /**Simple method call: */
2514          if(method.sCName.equals("toString_StringBuilderJc") && toStringNonPersist){
2515            ret = "toStringNonPersist_StringBuilderJc(";
2516          } else {
2517            ret = method.sImplementationName + "(";
2518          }
2519        }
2520        else if(method.isOverrideable()){
2521          if(envInstance.modeAccess == '&' && method.declaringClass == envInstance.identInfo.typeClazz){
2522            /**The envInstance contains the required method table. */
2523            ret = envInstance.cCode + ".mtbl->" + method.sPathToMtbl + method.primaryMethod.sNameUnambiguous + "(";
2524          } 
2525          //else if(envInstance.cCode.equals("ythis")){
2526          else if(envInstance.modeAccess == '~'){
2527            /**Access of the own instance. */
2528            secondpass.bUse_mtthis = true;
2529            if(declaringClass == method.declaringClass){
2530              ret = "mtthis->" + method.sPathToMtbl + method.primaryMethod.sNameUnambiguous + "(";
2531            } else {
2532                    //Method of a base class ////
2533            
2534                    ret = "mtthis->" + sPathMtbl[0] + method.sPathToMtbl + method.primaryMethod.sNameUnambiguous + "(";
2535            }
2536          }
2537          else if(false && envInstance.modeAccess == '@' && method.declaringClass == envInstance.identInfo.typeClazz){
2538            /**The envInstance is an enhanced reference with the appropriate type. */
2539            ret = "/*enhancedRef-Instance*/";
2540          } 
2541          else {
2542            /**A method table should be build temporary. Problem is: it is in line. 
2543             * A variable should be defined already.
2544             * Therefore an auto generated method table reference is need as stack variable. 
2545             * It may be possible it is exitsting already: */
2546            String nameMtbl = envInstance.cCode.replace("->", "_");
2547            String sMtblRef = "mtbl_" + nameMtbl + "_";
2548            FieldData mtblRef = localIdents.get(sMtblRef);
2549            if(mtblRef == null){
2550              /**Create it: */
2551              mtblRef = new FieldData(sMtblRef, envInstance.identInfo.typeClazz, null, null, null, '.', 'm', 0, null, '.', genClass.classData);
2552              localIdents.putLocalElement(sMtblRef, mtblRef);
2553              if(mtblVariables == null){ mtblVariables = new LinkedList<FieldData>(); }
2554              mtblVariables.add(mtblRef);
2555            }
2556            String sMtblType = mtblRef.typeClazz.getClassIdentName(); 
2557            //ret =  GenerateClass.genIndent(indent) + "//J2C: set mtbl reference";
2558            //ret = "( " +  sMtblRef + " =(Mtbl_" + sMtblType 
2559            ret = "((Mtbl_" + sMtblType 
2560                 + " const*)getMtbl_ObjectJc(&(" + sInstanceRef + ")->base.object, sign_Mtbl_"  
2561                 + sMtblType + ") )->" + method.sPathToMtbl + method.primaryMethod.sNameUnambiguous + "(";
2562            //ret = sMtblRef + "->" + method.sNameUnambiguous + "(";
2563          }
2564        } else if(method.sCName.equals("toString_StringBuilderJc") && toStringNonPersist){
2565          ret = "toStringNonPersist_StringBuilderJc(";
2566        } else {
2567          /**Simple method call: */
2568          ret = method.sCName + "(";
2569        }
2570        if(method.returnType.typeClazz == CRuntimeJavalikeClassData.clazz_unknown){
2571          ret += "/*J2C:unknownMethod*/";
2572        }
2573        if(ret.equals("alloc_MemC("))
2574          stop();
2575        
2576        FieldData[] formalParams = method.paramsType;
2577      
2578        String sParamSep;
2579        if( !method.isStatic()   //mode cant't be a static
2580          &&( sInstanceRef != null && sInstanceRef.length()>0)
2581          )
2582        { if(method.firstDeclaringClass.isInterface()){
2583            /**The reference to the class instance as first parameter is reference to an interface via ObjectJc. */
2584            ret += "&((" + sInstanceRef + ")->base.object)";  //type of interface, but this is expected.
2585          }
2586          else {
2587            /**The reference to the class instance as first parameter. */
2588            if(envInstance.identInfo.instanceClazz != null){
2589              ret += sInstanceRef;  //type of interface, but this is expected.
2590            }
2591            else if(method.sPathToBase.length()>0){
2592                    if(method.firstDeclaringClass != null){
2593                ret += sInstanceRef + "/*J2cT1*/";
2594                    } else {        
2595                ret += "(&(" + sInstanceRef + ")->" + method.sPathToBase.substring(1) + ")"; //NOTE: starts with "."  
2596                    }
2597            } 
2598            else {
2599              ret += sInstanceRef;
2600            }
2601          }  
2602          sParamSep = ", ";
2603        }  
2604        else
2605        { //call of static method because no sInstanceRef or its a static method
2606          if(( sInstanceRef != null && sInstanceRef.length()>0))
2607            assert(sInstanceRef.equals("ythis")); //NOTE: ythis-reference is provided always, if no reference is given. 
2608          sParamSep = "/*static*/";
2609        }
2610        if(ctorCall){
2611            //call of another ctorO of the same class. Java: this(param); as first statement.
2612          ret += "othis";     //it should be defined in the head of the enclosing ctor
2613          sParamSep = ", ";
2614        }
2615        if(sNewObject != null)
2616        { //to generate new Object with ctor(alloc...)
2617          ret += sParamSep + sNewObject;
2618          sParamSep = ", ";
2619        }
2620        
2621        if(actParams != null)
2622        { int idxParam = 0;
2623          /*
2624          if(paramsType == null || formalParams == null)
2625          { for(String param: paramsC)
2626            { ret += sParamSep + param;
2627              sParamSep = ", ";
2628            }
2629          }
2630          else
2631          */
2632          { //Iterator<ClassData> iterActParam = paramsType.iterator();
2633            StringBuilder sTypeVaArg = null;
2634            StringBuilder sValueVaArg = null;
2635            //for(String param: paramsC)
2636            for(CCodeData actParam: actParams)
2637            { //ClassData actParam = iterActParam.next();
2638              final String actParamFinit;
2639              if(sTypeVaArg != null)
2640              { //there are variable arguments.
2641                sValueVaArg.append(sParamSep).append(actParam.cCode);
2642                sTypeVaArg.append(actParam.identInfo.getTypeChar());
2643                actParamFinit = "";
2644              }
2645              else if(formalParams == null)
2646              { //no method found
2647                if(actParam.modeAccess == '$'){
2648                  /**Argument of a unknown method, if it is embedded, dereference it" */
2649                  actParamFinit = sParamSep + "(&(" + actParam.cCode + "))";
2650                  
2651                } else {
2652                  /**Argument of a unknown method, take it without casting. " */
2653                  actParamFinit = sParamSep + actParam.cCode;
2654                }
2655              }
2656              else
2657              { FieldData formalParam = formalParams[idxParam];
2658                idxParam +=1;
2659                    if(formalParam.typeClazz == CRuntimeJavalikeClassData.clazz_va_argRaw)
2660                { //all following arguments are variable.
2661                  idxParam -=1;  //don't increment.
2662                            sTypeVaArg = new StringBuilder();
2663                  sValueVaArg = new StringBuilder();
2664                  sValueVaArg.append(sParamSep).append(actParam.cCode);
2665                  sTypeVaArg.append(actParam.identInfo.getTypeChar());
2666                  actParamFinit = "";
2667                } else if(formalParam.modeAccess == '&'){
2668                  final String sActParam = genTemp_mtblRef(formalParam, actParam);
2669                  actParamFinit = GenerateClass.genIndent(indent+1) + sParamSep + sActParam;
2670                } else {
2671                  /**Normal assignment, access correction may be neccessary. */
2672                  final String sActParam = formalParam.testAndcast(actParam, '.');
2673                  actParamFinit = sParamSep + sActParam;
2674                }
2675              }
2676              ret+= actParamFinit;
2677              sParamSep = ", ";
2678            }
2679            if(sTypeVaArg != null)
2680            { //variable arguments
2681              ret += sParamSep + "\"" + sTypeVaArg + '\"' + sValueVaArg; 
2682            }
2683          }  
2684        }  
2685        if(method.sCName.equals("start_ThreadJc")){
2686          ret += ", " + gen_StackSize(zbnfDescription);
2687        }
2688        if(method.need_thCxt)
2689        { ret += sParamSep + "_thCxt)";
2690        }
2691        else
2692        { ret += ")";
2693        }
2694        final FieldData retInfo;
2695        final char modeAccess;
2696        final char returnMode = method.isReturnNew() ? 'n' : method.isReturnThis() ? 't' : '.'; 
2697        final boolean bReturnThis = method.isReturnThis();
2698        if(bReturnThis){
2699          if(  envInstance.modeAccess == method.returnType.modeAccess
2700            || envInstance.modeAccess == '~' && method.returnType.modeAccess == '*'
2701            ){
2702            retInfo = envInstance.identInfo;   //same as calling instance, there are stored at ex. an instanceClass. 
2703            modeAccess = envInstance.modeAccess;
2704          } 
2705          else if(envInstance.modeAccess== '~'){
2706            /**The type is the same, but the special case 'call own method' is detect. */
2707            assert(false);
2708            assert(method.returnType.modeAccess == '*');
2709            retInfo = new FieldData(envInstance.identInfo, 0, 0, '~', '.');
2710            modeAccess = envInstance.modeAccess;
2711          }
2712          else {
2713            /**The type is the same, but the provision instance has another access,
2714             * typical it is: The calling instance is an embedded one, but the return is a reference.
2715             */
2716            retInfo = new FieldData(envInstance.identInfo, 0, 0, method.returnType.modeAccess, '.');
2717            modeAccess = method.returnType.modeAccess;
2718          }
2719        } else {
2720          /**Other return as this. */
2721          retInfo = method.returnType;       //standard FieldData-description of a returned instance.
2722          modeAccess = method.returnType.modeAccess;
2723        }  
2724        return new CCodeData(ret, retInfo, modeAccess, returnMode);
2725        
2726      }
2727      
2728      
2729      
2730      
2731      /**
2732       * @param zbnfMethod
2733       * @param zbnfDescription
2734       * 
2735       * @throws IllegalAccessException 
2736       * @throws IOException 
2737       * @throws ParseException 
2738       * @throws IllegalArgumentException 
2739       * @throws FileNotFoundException 
2740       * @throws InstantiationException 
2741       */
2742      List<CCodeData> gatherActParams(ZbnfParseResultItem zbnfMethod, ZbnfParseResultItem zbnfDescription
2743      , String sMethodNameJava
2744      ) throws FileNotFoundException, IllegalArgumentException, ParseException, IOException, IllegalAccessException, InstantiationException
2745      { final List<CCodeData> actParams;
2746        final FieldData[] actParamsArray;
2747        if(sMethodNameJava.equals("arraycopy"))
2748            stop();
2749        ZbnfParseResultItem args = zbnfMethod == null ? null : zbnfMethod.getChild("actualArguments");
2750        /**The actual arguments are evaluated in value AND in theire type.
2751         * The types are stored in paramsType. They are relevant for searching the correct method.
2752         */
2753        if(args != null)
2754        { //paramsC = new LinkedList<String>();
2755          //paramsType = new LinkedList<ClassData>();
2756          actParams = new LinkedList<CCodeData>();
2757          Iterator<ZbnfParseResultItem> iterArgs = args.iterChildren();
2758          while(iterArgs.hasNext())
2759          { ZbnfParseResultItem arg = iterArgs.next();
2760            String argSemantic = arg.getSemantic();
2761            //ClassData[] typeValue = new ClassData[1];  //classData of the part of expression
2762            if(argSemantic.equals("value"))
2763            { CCodeData actParam = gen_value(arg, zbnfDescription, true, 'a');
2764              actParams.add(actParam);
2765              //String sValue = gen_value(arg, typeValue, localIdents, 'a');
2766              //paramsC.add(sValue);
2767              //paramsType.add(typeValue[0]);
2768            }
2769            else if(argSemantic.equals("objectAccess"))
2770            { actParams.add(new CCodeData("?objectAccess", CRuntimeJavalikeClassData.clazz_void.classTypeInfo));
2771            }
2772            else
2773            { actParams.add(new CCodeData("?unknown", CRuntimeJavalikeClassData.clazz_void.classTypeInfo));
2774            }
2775          }
2776          actParamsArray = new FieldData[actParams.size()];
2777          int idxActParams = 0;
2778          for(CCodeData actParam: actParams)
2779          { actParamsArray[idxActParams++] = actParam.identInfo; //NOTE: not used, searchMethod needs CCodeData, not only FieldData, because an array access should be recognized.
2780          }
2781        }
2782        else
2783        { //no parameter of the method call.
2784          //paramsC = null;
2785          //paramsType = null;
2786          actParams = null;
2787          actParamsArray = null;
2788        }
2789        //if(envInstanceInfo.typeClazz != null)
2790        //if(envInstance.type != null)
2791        /**In Java the methods are recognized with their parameter types, so in C++ 
2792         * (overload methods, parameter sensitive method calls). 
2793         * But in C the method name is unambiguously assigned to one method.
2794         * Therefore the method name have to be built sensitive to the java parameter.
2795         * The method will be searched with knowledge of actual parameter types.
2796         */
2797        //ClassData.Method method = envInstanceInfo.typeClazz.searchMethod(sMethodName, paramsType);
2798        /**test if call via method table is necessary: */
2799        return actParams;
2800      }
2801      
2802      
2803      
2804      String gen_StackSize(ZbnfParseResultItem zbnfDescription) //, LocalIdents localIdents) 
2805      throws FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException, ParseException
2806      { StringBuilder ret = new StringBuilder(100);
2807        ret.append("-1"); //default stacktrace
2808        if(zbnfDescription != null){
2809          ZbnfParseResultItem zbnfStackSize = zbnfDescription.getChild("stackSize");
2810          if(zbnfStackSize != null){
2811            List<ZbnfParseResultItem> listItems = zbnfStackSize.listChildren();
2812            String separator = "";
2813            ret.setLength(0);
2814            for(ZbnfParseResultItem item: listItems){
2815              String semantic = item.getSemantic();
2816              if(semantic.equals("type")){
2817                String sType = item.getParsedString();
2818                /**It may be called a nested translation: */
2819                ClassData instanceType = localIdents.getType(sType, genClass.fileLevelIdents); 
2820                String sInstanceType = instanceType.getClassCtype_s();
2821                ret.append(separator).append("sizeof(").append(sInstanceType).append(")");
2822              }
2823              else if(semantic.equals("bytes")){
2824                long bytes = item.getParsedInteger();
2825                ret.append(separator).append(bytes);
2826              }
2827              separator = "+";
2828            }
2829          }
2830        }
2831        return ret.toString();
2832      }
2833      
2834      /**generates the expression for a new Type(...) expression.
2835       * For a new Object, a MemC-instance is necessary. It will be generated in
2836       * {@link #gen_statementBlock(ZbnfParseResultItem, int, LocalIdents)}.
2837       * The variable {@link #nrofNew} is used and incremented for that.
2838       * 
2839       * @param zbnfNewObject The zbnf parse result item of the < newObject>
2840       * @param reference A reference before .new, used for inner non-static classes, or null for static or first-level classes.
2841       * @param idents The identifier of the environment.
2842       * @return generated C-code.
2843       * @throws ParseException
2844       * @throws InstantiationException 
2845       * @throws IllegalAccessException 
2846       * @throws IOException 
2847       * @throws IllegalArgumentException 
2848       * @throws FileNotFoundException 
2849       */
2850      private CCodeData gen_newObject(
2851            ZbnfParseResultItem zbnfNewObject
2852      , final CCodeData referenceP
2853      //, LocalIdents idents
2854      ) 
2855      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
2856      { final ClassData typeOfNew;
2857        final ClassData refClass;
2858              final LocalIdents localIdentsNewObj;
2859              final LocalIdents idents = this.localIdents;
2860              if(referenceP != null){
2861          //typeOfNew = getType(zbnfNewObject.getChild("newClass"), reference.identInfo.typeClazz.classLevelIdents);  //itemNewObject.getChild("newClass").getParsedString();
2862          refClass = referenceP.identInfo.typeClazz;
2863          localIdentsNewObj = referenceP.getClassLevelIdents();  //search the new Type only in reference context.
2864              } else {
2865          //typeOfNew = getType(zbnfNewObject.getChild("newClass"), idents);  //itemNewObject.getChild("newClass").getParsedString();
2866          refClass = genClass.classData;
2867          localIdentsNewObj = idents;     //search it in context.
2868              }
2869            
2870            FieldData fieldNew = genClass.createFieldDataNewObject(zbnfNewObject, null, localIdentsNewObj, idents, this, null, refClass, 'b', '*', '.', true);
2871            typeOfNew = fieldNew.instanceClazz;
2872            //retTypeValue[0] = typeOfNew;
2873        String sTypeNewObject = typeOfNew.getClassCtype_s();
2874        if(sTypeNewObject.equals("StringJc"))
2875        {
2876          //reference = new CCodeData(null, typeOfNew.classTypeInfo);//static method call but the method class is given here. 
2877          /**call of a new_StringJc(...)-method: */
2878          return gen_InternalMethodCall(zbnfNewObject, null, "new", typeOfNew, referenceP, null); //, idents);
2879          //return gen_InternalMethodCall(zbnfNewObject, null, "new", reference.identInfo.typeClazz, reference, null, idents);
2880        }
2881        else
2882        { //induce to generate the necesarry include statement:
2883          //typeOfNew may be null if the type is a external type.
2884          if(typeOfNew != null)
2885          { genClass.writeContent.addIncludeC(typeOfNew.sFileName, "new object");
2886          }
2887          //retTypeValue[0] = typeOfNew;
2888          if(sTypeNewObject.equals("C_INNER_TestAnonymous_Test_s"))
2889            stop();
2890          //String sInstanceRef = null;  //TODO if the instance is a non static inner class, in Java: instance.new(...) 
2891          //String sInstanceRef = genClass.classData.thisCodeInfo;
2892          String sInstanceRef = "ythis";
2893          String sNewObject = "(" + gen_newObj() + " = alloc_ObjectJc(sizeof_" + sTypeNewObject + ", 0, _thCxt))";
2894          final CCodeData reference =
2895            typeOfNew.isNonStaticInner 
2896            ? ( referenceP !=null //if the reference is given, use it.
2897                    ? referenceP
2898                    : new CCodeData(sInstanceRef, refClass.classTypeInfo))  //this  ////
2899            : null;   //!nonStaticInner, then no reference, the referenceP is the type.
2900          final ClassData declaringClass;
2901          final String sNameCtor;
2902          if(typeOfNew.isNonStaticInner){
2903            /**ctor of a non-static inner class: The ctor is defined in the outer class
2904             * because it needs the this-reference of the outer class. */
2905            declaringClass = reference.identInfo.typeClazz;
2906            sNameCtor = (typeOfNew.isBasedOnObject()?  "ctorO_" : "ctorM_") + typeOfNew.getClassNameJava();
2907          } else {
2908            /**ctor of a static inner or package-level-class: Search the ctor
2909             * inside the type-of-new-class, it will be static there. */
2910            declaringClass = typeOfNew;
2911            sNameCtor = fieldNew.typeClazz.isBasedOnObject()?  "ctorO" : "ctorM";
2912          }
2913          //return gen_InternalMethodCall(zbnfNewObject, null, "ctorO", reference.identInfo.typeClazz, reference, sNewObject, idents);
2914          return gen_InternalMethodCall(zbnfNewObject, null, sNameCtor, declaringClass, reference, sNewObject); //, idents);
2915        }
2916      }
2917    
2918    
2919    
2920      /**generates the expression for a new Type[...] expression.
2921       * For a new Object, a Object-instance is necessary. It will be generated using
2922       * {@link #gen_newObj()}.
2923       * The variable {@link #nrofNew} is used and incremented for that.
2924       * <br>
2925       * If a variable is given, and it is an embedded instance, no new Object is allocated,
2926       * but the constructor for the given embedded instance is called.
2927       * 
2928       * @param zbnfNewArray The zbnf parse result item of the < newObject>
2929       * @param idents The identifier of the environment.
2930       * @param variable The variable to assign to, or null
2931       * @return generated C-code.
2932       * @throws ParseException
2933       * @throws InstantiationException 
2934       * @throws IllegalAccessException 
2935       * @throws IOException 
2936       * @throws IllegalArgumentException 
2937       * @throws FileNotFoundException 
2938       */
2939      public String gen_newArray(ZbnfParseResultItem zbnfNewArray, ClassData[] retTypeValue, LocalIdents idents, FieldData variable) 
2940      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
2941      { String sRet;
2942        ClassData typeOfNew = genClass.getType(zbnfNewArray.getChild("newClass"), idents);  //itemNewObject.getChild("newClass").getParsedString();
2943        retTypeValue[0] = typeOfNew;
2944        String sTypeNewObject = typeOfNew.getClassCtype_s();
2945        String sIdentNameNewObject = typeOfNew.getClassIdentName();
2946        //induce to generate the necesarry include statement:
2947        //typeOfNew may be null if the type is a external type.
2948        if(typeOfNew != null && typeOfNew.sFileName != null)
2949        { genClass.writeContent.addIncludeC(typeOfNew.sFileName, "new array");
2950        }
2951        //retTypeValue[0] = typeOfNew;
2952        List<ZbnfParseResultItem> listValues = zbnfNewArray.listChildren("value");
2953        int dimension = listValues.size();
2954        ZbnfParseResultItem zbnfValue = listValues.get(0);
2955        ClassData[] retType = new ClassData[1];
2956        String nrofElements = gen_value(zbnfValue, null, retType, idents, true, 'e');
2957        final String sInstance;
2958        assert(variable.modeAccess != '$');  //X and Y are used.
2959        if(variable.modeAccess == 'Q')
2960        { //use the embedded given variable
2961          String sName = variable.getName();
2962          sInstance = "&" + sName;  
2963        }
2964        else if(variable.modeAccess == 'Y')
2965        { //use the embedded given variable
2966          String sName = variable.getName();
2967          sInstance = "&" + sName + ".head.object";  //TODO: inherition, than not only .object
2968        }
2969        else
2970        { //create a new Object
2971          //String sInstanceRef = null;  //TODO if the instance is a non static inner class, in Java: instance.new(...) 
2972          sInstance = "(" + gen_newObj() + " = alloc_ObjectJc( sizeof(ObjectArrayJc) + (" + nrofElements + ") * sizeof(" + sTypeNewObject + "), mIsLargeSize_objectIdentSize_ObjectJc, _thCxt))";
2973        }
2974        //call the constructor
2975        String sReflection = (typeOfNew.isPrimitiveType() ? "REFLECTION_" : "&reflection_") + sTypeNewObject;  //reflections of primitive type are defined as simple constants.
2976        sRet = "(" + sIdentNameNewObject + "_Y*)ctorO_ObjectArrayJc(" + sInstance + ", " + nrofElements + ", sizeof(" + sTypeNewObject + ")," + sReflection + ", 0)";
2977        return sRet;
2978      }
2979    
2980    
2981    
2982      /**generates the expression for a < try_Statment> .
2983       * 
2984       * @param zbnfThrowNew
2985       * @param localIdents
2986       * @return
2987       * @throws ParseException
2988       * @throws InstantiationException 
2989       * @throws IllegalAccessException 
2990       * @throws IOException 
2991       * @throws IllegalArgumentException 
2992       * @throws FileNotFoundException 
2993       */
2994      public String gen_try_statement(ZbnfParseResultItem zbnfThrowNew, int indent, LocalIdents localIdents)
2995      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
2996      { String expr = "";
2997        //ClassData[] typeValue = new ClassData[1];  //classData of the part of expression
2998        
2999        ZbnfParseResultItem zbnfStatement = zbnfThrowNew.getChild("statementBlock");
3000        String statementBlock = 
3001            secondpass.gen_statementBlock
3002          ( zbnfStatement, indent, this
3003          , CRuntimeJavalikeClassData.clazz_void.classTypeInfo 
3004          , 'b'
3005          );
3006        expr += "TRY" + statementBlock + "_TRY";
3007        List<ZbnfParseResultItem> listZbnfCatch = zbnfThrowNew.listChildren("catchBlock");
3008        if(listZbnfCatch!=null) for(ZbnfParseResultItem zbnfCatch : listZbnfCatch)
3009        { ZbnfParseResultItem zbnfExcType  = zbnfCatch.getChild("ExceptionType");
3010          ClassData typeClazz = genClass.getType(zbnfExcType, localIdents);
3011          String sExceptionType = typeClazz.getClassIdentName();
3012          String sExceptionVariable = zbnfCatch.getChild("exceptionVariable").getParsedString();
3013          ZbnfParseResultItem zbnfExceptionStatement = zbnfCatch.getChild("statementBlock");
3014          LocalIdents catchIdents = new LocalIdents(localIdents, null);
3015          catchIdents.putLocalElement(sExceptionVariable, Java2C_Main.singleton.standardClassData.clazzExceptionJc.classTypeInfo);
3016          StatementBlock statementBlockCatchFrame = new StatementBlock(genClass, catchIdents, true, indent+1);
3017          String sExceptionStatement = 
3018            secondpass.gen_statementBlock
3019            ( zbnfExceptionStatement, indent+1, statementBlockCatchFrame
3020            , CRuntimeJavalikeClassData.clazz_void.classTypeInfo 
3021            , 'b'
3022            );
3023          expr += GenerateClass.genIndent(indent) + "CATCH(" + sExceptionType + ", " + sExceptionVariable + ")"
3024                + GenerateClass.genIndent(indent) + sExceptionStatement;
3025        }
3026        expr += GenerateClass.genIndent(indent) + "END_TRY";
3027        return expr;
3028      }
3029    
3030    
3031    
3032    
3033    
3034      /**generates the expression for a <throwNew> .
3035       * 
3036       * @param zbnfThrowNew
3037       * @param localIdents
3038       * @return
3039       * @throws ParseException
3040       * @throws InstantiationException 
3041       * @throws IllegalAccessException 
3042       * @throws IOException 
3043       * @throws IllegalArgumentException 
3044       * @throws FileNotFoundException 
3045       */
3046      public String gen_throwNew(ZbnfParseResultItem zbnfThrowNew, ZbnfParseResultItem zbnfDescription
3047            , LocalIdents localIdents, FieldData typeReturn)
3048      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
3049      { String expr = "{ ";
3050        ClassData[] typeValue = new ClassData[1];  //classData of the part of expression
3051    
3052        //String sExceptionClass = zbnfThrowNew.getChild("exceptionClass").getParsedString();
3053        ZbnfParseResultItem zbnfType = zbnfThrowNew.getChild("exceptionClass");
3054        ClassData exceptionType = genClass.getType(zbnfType, localIdents);
3055        String sExceptionClass = exceptionType.getClassIdentName(); 
3056        ZbnfParseResultItem itemText = zbnfThrowNew.getChild("text");
3057        if(itemText != null)
3058        { //String sText = itemText.getParsedString();
3059          String sText = gen_value(itemText, zbnfDescription, typeValue, localIdents, true, 'a');
3060          if(sText.contains("Not available in expand mode."))
3061            stop();
3062          String sThrow;
3063          if(typeValue[0] == CRuntimeJavalikeClassData.clazz_s0) { sThrow = "throw_s0Jc(ident_";}
3064          else if(typeValue[0] == CRuntimeJavalikeClassData.clazzStringJc) { sThrow = "throw_sJc(ident_";}
3065          else if(typeValue[0] == CRuntimeJavalikeClassData.clazzExceptionJc) { sThrow = "throw_EJc(ident_"; }
3066          else { 
3067            sThrow = "throw_??(ident_";
3068            assert(false);
3069          }
3070          expr += sThrow + sExceptionClass + "Jc, " + sText + ", ";
3071        }
3072        else
3073        { expr += "THROW_s(" + sExceptionClass + ", xxx, "  ;
3074        }
3075        ZbnfParseResultItem itemValue = zbnfThrowNew.getChild("value2");
3076        String sValue;
3077        if(itemValue == null)
3078        {
3079          sValue = "0";
3080        }
3081        else
3082        {
3083          sValue = gen_value(itemValue, null, typeValue, localIdents, true, 'a');
3084        }
3085        expr += sValue + ", &_thCxt->stacktraceThreadContext, __LINE__);";
3086        if(typeReturn.typeClazz != CRuntimeJavalikeClassData.clazz_void){
3087            if(typeReturn.typeClazz == CRuntimeJavalikeClassData.clazzStringJc){
3088            //if(typeReturn.testAndcast(null, 0))
3089              expr += " return null_StringJc; }";
3090          } else if(typeReturn.typeClazz.bEmbedded){
3091            //if(typeReturn.testAndcast(null, 0))
3092              expr += " return null_"+ typeReturn.typeClazz.getClassIdentName() +"; }";
3093          } else {
3094            //if(typeReturn.testAndcast(null, 0))
3095            expr += " return 0; }";  //should match to all types.
3096          }
3097        }else {
3098            expr += " }";
3099        }
3100        return expr;
3101      }
3102    
3103    
3104    
3105    
3106    
3107      /**generates the initial assignments to variables. Called only inside a 
3108       * {@link #gen_statementBlock(ZbnfParseResultItem , int, StatementBlock, ClassData, char)}
3109       *
3110       * @param zbnfVariableDefinition Item of &lt; variableDefinition>
3111       * @throws IOException
3112       * @throws ParseException
3113       * @throws InstantiationException 
3114       * @throws IllegalAccessException 
3115       * @throws IOException 
3116       * @throws IllegalArgumentException 
3117       * @throws FileNotFoundException 
3118       */
3119      public String gen_VariableInitAssignment(ZbnfParseResultItem zbnfVariableDefinition, int indent) //, LocalIdents idents)
3120      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
3121      {
3122        String ret;
3123        final LocalIdents idents = this.localIdents;
3124        ClassData[] typeValue = new ClassData[1];  //classData of the part of expression
3125        ZbnfParseResultItem zbnfDescription = zbnfVariableDefinition.getChild("description"); //may be null.
3126        { //ZbnfParseResultItem itemAttrib = iterAttrib.next();
3127          CCodeData leftVariable = gen_variableAccess(zbnfVariableDefinition, zbnfDescription, localIdents, 'i', genClass.classData.thisCodeInfo);
3128          
3129          String sName = zbnfVariableDefinition.getChild("variableName").getParsedString();
3130          FieldData infoVariable = localIdents.get(sName);
3131          if(sName.equals("ifc3"))
3132            stop();
3133          assert(infoVariable != null);
3134          ZbnfParseResultItem zbnfAssignment = zbnfVariableDefinition.getChild("value");
3135          if(zbnfAssignment != null)
3136          { 
3137            ret = gen_assignValue(leftVariable, "=", typeValue, zbnfAssignment, zbnfDescription, indent, localIdents, 'i') 
3138                  + ";";
3139            /*
3140            
3141            final String value = gen_value(zbnfAssignment, typeValue, idents, 'e');
3142            final FieldData typeVariable = idents.get(sName);
3143            final String dstValue = typeVariable.testAndcast(typeValue[0], value);
3144            //TODO: assignment to StringJc!
3145            ret = GenerateClass.genIndent(indent) + sName + " = " + dstValue + ";";
3146            */
3147          }
3148          else if( (zbnfAssignment = zbnfVariableDefinition.getChild("newObject")) != null)
3149          { //an assignment with new...
3150            if(infoVariable.modeAccess == '%'){
3151                    //a type, which are only used in form of an value, forex MemSegmJc. 
3152                    //It is initialized in Java calling a new(param). But the reference is a instance in C.
3153                    //In Java the reference should be final because an assignment isn't admissible.
3154              String sCtor = genInitEmbeddedInstance(zbnfAssignment, zbnfDescription, infoVariable, sName, indent);
3155              ret = GenerateClass.genIndent(indent) + sCtor + ";";
3156                    //ret = GenerateClass.genIndent(indent) + "INIT_null_" + infoVariable.typeClazz.getClassIdentName() + "(" + sName + ");  //TODO parameter"; 
3157            }
3158            else if("$".indexOf(infoVariable.modeAccess) >=0)
3159            { //call the constructor
3160              String sCtor = genInitEmbeddedInstance(zbnfAssignment, zbnfDescription, infoVariable, sName, indent);
3161              ret = GenerateClass.genIndent(indent) + sCtor + ";";
3162            }
3163            else
3164            { CCodeData codeNewObject = gen_newObject(zbnfAssignment, null); //, localIdents); //, idents);
3165              ret = GenerateClass.genIndent(indent) + sName + " = " + codeNewObject.cCode + ";";
3166            }  
3167          }
3168          else if( (zbnfAssignment = zbnfVariableDefinition.getChild("newArray")) != null)
3169          { //an assignment with new...
3170            if(infoVariable.getName()!=null && infoVariable.getName().equals("idxP"))
3171                    stop();
3172            String sNewArray = gen_newArray(zbnfAssignment, typeValue, idents, infoVariable);
3173            if(infoVariable.modeAccess == 'Y')
3174            { ret = GenerateClass.genIndent(indent) + sNewArray + ";"; //no assignment, it is embedded.
3175            }
3176            else if(infoVariable.modeAccess == 'X') //X: array reference.
3177            { ret = GenerateClass.genIndent(indent) + sName + " = " + sNewArray + ";";
3178            }
3179            else if(infoVariable.modeAccess == 'Q'){ //embedded simple array. 
3180                    //It is initialized on definition already.
3181                    ret = "";  //no initializatin
3182            } else {
3183                    ret = "";
3184                    assert(false);
3185            }
3186          }
3187          else
3188          { //no asignment TODO use 3. param from gen_variableDefinition: variablesToInit, but not at classlevel
3189            //ret = GenerateClass.genIndent(indent) + sName + " = 0; /*assignment not found*/";
3190            ret = "/*no initvalue*/";
3191          }
3192        }
3193        return ret;
3194      }
3195    
3196    
3197    
3198      /**Generates the definition of variable with its initialization.
3199       * It is able to use first for static variable, it is not able to use for complexly initilizations,
3200       * which depends from pre-calculated values.
3201          **TODO: To sophisticate something obout the sources of the value, it should be returned
3202           * whether the value is only build with constants, or with some variables.
3203           * It should be returned from gen_value.
3204           * Than here only a constant value may be considered. It is necessary for C static variable,
3205           * but also for immediately initializiation of variable.
3206           * If any dynamically values are used, the initialization don't may execute here.
3207           * This routine should return null.
3208           *
3209       * @param variable
3210       * @param zbnfInitAssignment
3211       * @return
3212       * @throws ParseException
3213       * @throws FileNotFoundException
3214       * @throws IllegalArgumentException
3215       * @throws IOException
3216       * @throws IllegalAccessException
3217       * @throws InstantiationException
3218       */
3219      String gen_VariableDefWithSimpleInitValue(FieldData variable, ZbnfParseResultItem zbnfInitAssignment) 
3220      throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
3221      {
3222        String ret;
3223        String leftVariableDef = variable.gen_VariableDefinition('b');
3224        
3225        final String semanticInitAssignment = zbnfInitAssignment.getSemantic();
3226        if(semanticInitAssignment.equals("constArray"))
3227        { String separator = "{ ";
3228          List<ZbnfParseResultItem> listValues = zbnfInitAssignment.listChildren();  //all are kind of simpleValue
3229          FieldData identInfoElement = null;
3230          ret = leftVariableDef + " = ";
3231          for(ZbnfParseResultItem zbnfValue: listValues)
3232          { CCodeData codeValue = genClass.genConstantValue(zbnfValue);
3233            ret += separator + codeValue.cCode;
3234            separator = ", ";
3235            identInfoElement = codeValue.identInfo;  //the last wins. But there should be all the same.
3236          }
3237          ret += "};";
3238          //return ret;
3239          //return new CCodeData(ret, identInfoElement, '%', 1);
3240        }
3241        else if(semanticInitAssignment.equals("newObject")){
3242          ret = leftVariableDef + ";";
3243          //return ret;
3244        }
3245        else if(semanticInitAssignment.equals("newArray")){
3246          ret = leftVariableDef + ";";
3247          //return ret;
3248        }
3249        else if(semanticInitAssignment.equals("value")){
3250          /**There are able to use only special constellations of value, especially constant values.
3251           */
3252          CCodeData value = gen_value(zbnfInitAssignment, null, variable.modeStatic=='r', 's');
3253          /**TODO: To sophisticate something obout the sources of the value, it should be returned
3254           * whether the value is only build with constants, or with some variables.
3255           * It should be returned from gen_value.
3256           * Than here only a constant value may be considered. It is necessary for C static variable,
3257           * but also for immediately initializiation of variable.
3258           * If any dynamically values are used, the initialization don't may execute here.
3259           * This routine should return null.
3260           */
3261          if(  variable.typeClazz == CRuntimeJavalikeClassData.clazzStringJc
3262            && value.identInfo.typeClazz == CRuntimeJavalikeClassData.clazz_s0
3263            ){
3264            ret = leftVariableDef + " = CONST_z_StringJc(" + value.cCode + ");";
3265          }
3266          else{
3267            /**The value is gotten, it may be constant. But a simple possible cast may be necessary: */
3268            final String dstValue = variable.testAndcast(value, '.');
3269            ret = leftVariableDef + " = " + dstValue + ";"; 
3270          }
3271          //return ret;
3272        }
3273        else
3274        { assert(false);
3275          ClassData[] typeValue1 = new ClassData[1];  //classData of the part of expression
3276          CCodeData leftVariable = new CCodeData(leftVariableDef, variable);
3277          ret = gen_assignValue(leftVariable, "=", typeValue1
3278                       , zbnfInitAssignment, null, 0, genClass.classData.classLevelIdents, 'i') + ";";
3279        }
3280        return ret;
3281      }
3282    
3283      void stop(){}
3284      
3285    }//class StatementBlock
3286    
3287    
3288