001/****************************************************************************
002 * Copyright/Copyleft:
003 *
004 * For this source the LGPL Lesser General Public License,
005 * published by the Free Software Foundation is valid.
006 * It means:
007 * 1) You can use this source without any restriction for any desired purpose.
008 * 2) You can redistribute copies of this source to everybody.
009 * 3) Every user of this source, also the user of redistribute copies
010 *    with or without payment, must accept this license for further using.
011 * 4) But the LPGL ist not appropriate for a whole software product,
012 *    if this source is only a part of them. It means, the user
013 *    must publish this part of source,
014 *    but don't need to publish the whole source of the own product.
015 * 5) You can study and modify (improve) this source
016 *    for own using or for redistribution, but you have to license the
017 *    modified sources likewise under this LGPL Lesser General Public License.
018 *    You mustn't delete this Copyright/Copyleft inscription in this source file.
019 *
020 * @author JcHartmut: hartmut.schorrig@vishia.de
021 * @version 2008-04-06  (year-month-day)
022 * list of changes:
023 * 2008-04-06 JcHartmut: some correction
024 * 2008-03-15 JcHartmut: creation
025 *
026 ****************************************************************************/
027package org.vishia.java2C;
028
029import java.io.FileNotFoundException;
030import java.io.IOException;
031import java.text.ParseException;
032import java.util.Collection;
033import java.util.Iterator;
034import java.util.LinkedList;
035import java.util.List;
036
037import org.vishia.mainCmd.Report;
038import org.vishia.util.Assert;
039import org.vishia.zbnf.ZbnfParseResultItem;
040
041
042  
043  
044/**This class handle the second pass of the translation.
045 * An instance is built only temporary to run the pass. All Data are stored in the {@link ClassData}.
046 * Instances of ClassData will be created while running the first pass, there are stored in 
047 * the singleton {@link AllData}. Than they are used to run the Second Pass.
048 * 
049 * @author JcHartmut
050 *
051 */
052public class SecondPass extends GenerateClass
053{
054  
055  /**Version, history and license.
056   * <ul>
057   * <li>2014-09-05 Hartmut new: generates <code>|kPtrVal_Modifier_reflectJc</code> in the reflection on {@link FieldData#modeAccess} == 'M'.
058   * <li>2008 Hartmut created:    
059   * </ul>
060   * <br><br>
061   * <b>Copyright/Copyleft</b>:
062   * For this source the LGPL Lesser General Public License,
063   * published by the Free Software Foundation is valid.
064   * It means:
065   * <ol>
066   * <li> You can use this source without any restriction for any desired purpose.
067   * <li> You can redistribute copies of this source to everybody.
068   * <li> Every user of this source, also the user of redistribute copies
069   *    with or without payment, must accept this license for further using.
070   * <li> But the LPGL is not appropriate for a whole software product,
071   *    if this source is only a part of them. It means, the user
072   *    must publish this part of source,
073   *    but don't need to publish the whole source of the own product.
074   * <li> You can study and modify (improve) this source
075   *    for own using or for redistribution, but you have to license the
076   *    modified sources likewise under this LGPL Lesser General Public License.
077   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
078   * </ol>
079   * If you are intent to use this sources without publishing its usage, you can get
080   * a second license subscribing a special contract with the author. 
081   * 
082   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
083   */
084  public final static String sVersion = "2014-09-05"; 
085
086  
087  
088  /**Stores the necessity of generating a <code>mtthis</code> reference for the own method table.
089   * This variable is set to false on start of any {@link #write_methodDefinition(org.vishia.java2C.ClassData.MethodWithZbnfItem, String, LocalIdents)}
090   * and set to true if any dynamic call with <code>thiz</code>-reference is generated.
091   * Depending on this, a line to prepare a <code>mtthis</code> variable: The reference to the
092   * own method table, is prepared. 
093   */
094  boolean bUse_mtthis;
095  
096  /**Stores the necessity of generating a <code>STACKTRC_ENTRY</code> and <code>STACKTRC_LEAVE</code>.
097   * This variable is set on start of any {@link #write_methodDefinition(org.vishia.java2C.ClassData.MethodWithZbnfItem, String, LocalIdents)}
098   * depending on the {@link Method#noStacktrace()}.
099   */
100  boolean noStacktrace;
101
102  /**This class holds the common values of a statement block and handles the generation of a statement block.
103   * 
104   * {@link StatementBlock#gen_simpleMethodCall(ZbnfParseResultItem, String, LocalIdents.IdentInfos, ClassData[] retType, LocalIdents) }
105   */
106
107  /**Initializes an instance to run the second pass of a given class.
108   * The instance is generated only temporary to run the passes, see {@link GenerateClass}. 
109   * @param genClass.writeContent Interface to write the content. Note: The content is not written immediately 
110   *   in a file, but temporary stored in some StringBuilder. The reason is the order of parts of C-File and H-File.
111   * @param pkgIdents singleton information of all classes there are knwon yet.
112   * @param classData The data of this class saves between parsing, first and second pass. 
113   *        This classData also contain the ZBNF parse result items.
114   * @param runRequiredFirstPass Interface to cause the parsing and running of a first pass
115   *        of a up-to-now unknown class. 
116   *        This interface is implemented at the main level of the Java2C-translator
117   */
118  //SecondPass(iWriteContent genClass.writeContent, TreeMap<String, ClassData> pkgIdents, ClassData classData, RunRequiredFirstPass_ifc runRequiredFirstPass)
119  SecondPass(iWriteContent writeContent, GenerateFile parentGenerateFile
120  , LocalIdents fileLevelIdents, ClassData classData
121  , RunRequiredFirstPass_ifc runRequiredFirstPass
122  , Report log
123  )
124  { super(writeContent, parentGenerateFile, fileLevelIdents, runRequiredFirstPass, log, false);
125    this.classData = classData;
126  }
127
128
129  /**writes the constructor-, method-, static variable- definition and reflection into the C-File.
130   * Inside it is written and called:<ul>
131   * <li>all definitions of static variables with there initialization or 0-initiatialization.
132   * <li>{@link #write_constructorDefinition(ZbnfParseResultItem, String)}
133   * <li>{@link #write_methodDefinition(ZbnfParseResultItem, String)}
134   * </ul>
135   *  
136   * @param itemClass The class start item of zbnf parse result.
137   * @param sOuterClassName Name of the environment class not used yet
138   * @throws IOException
139   * @throws ParseException
140   * @throws InstantiationException 
141   * @throws IllegalAccessException 
142   * @throws IllegalArgumentException 
143   */
144  void runSecondPassClass(ZbnfParseResultItem itemClass, String sOuterClassName)
145  throws IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
146  {
147    String sClassNameWithout_s = classData.getClassIdentName();
148    //String sClassName = classData.getClassCtype_s();
149    log.writeInfoln("2. pass: " + classData.sClassNameJavaFullqualified + "->" + sClassNameWithout_s);
150    
151    ZbnfParseResultItem itemDescription = itemClass.getChild("description");
152    if(itemDescription != null)
153    { StringBuilder uResult = new StringBuilder();
154      write_Description(itemDescription, uResult);
155      writeContent.writeClassC(uResult.toString());
156    }
157    
158    writeContent.writeClassC("\n\nconst char sign_Mtbl_" + sClassNameWithout_s + "[] = \"" 
159                     + sClassNameWithout_s + "\"; //to mark method tables of all implementations\n");      
160    //A method table isn't need if the class is a simple data class or an interface.
161    //If the class doesn't base on Object, a method table is not able to use.
162    boolean bMtbl = (classData.inheritanceInfo != null && classData.isBasedOnObject() 
163        && !classData.isInterface() && !classData.isAbstract);
164    //boolean bMtbl = (classData.inheritanceInfo != null && !classData.isInterface());
165    if(bMtbl){
166      /**Writes the declaration of the method table definition, because it may be necessary for <code>mtthis</code>. 
167       * See also usage of MtblDef_*/   
168      writeContent.writeClassC("\ntypedef struct MtblDef_" + sClassNameWithout_s + "_t { Mtbl_" 
169                       + sClassNameWithout_s + " mtbl; MtblHeadJc end; } MtblDef_" + sClassNameWithout_s + ";");      
170      writeContent.writeClassC("\n extern MtblDef_" + sClassNameWithout_s + " const mtbl" + sClassNameWithout_s + ";");      
171    }    
172
173    Java2C_Main.singleton.console.reportln(Report.debug, "Java2C-SecondPass.run: class=" // + sourceOfClassData
174        + classData.getClassIdentName() + (bMtbl ? ", mtbl" : "")
175        );
176    
177    StatementBlock staticQuasiBlock = new StatementBlock(this, classData.classLevelIdents, true, false, 1);
178    for(ClassData.InitInfoVariable staticVariable : classData.staticVariables)
179    { String sName = staticVariable.identInfos.getName();
180      if(sName.equals("searchTrc"))
181        stop();
182      FieldData identInfos = classData.classLevelIdents.get(sName);
183      String sTypeCode = identInfos.gen_Declaration(writeContent);  //at block level
184      char kind = staticVariable.identInfos.modeAccess;
185      String sStaticDef = "";
186      //if(staticVariable.bConst)
187      if(identInfos.modeStatic=='S')
188      { sStaticDef += "const ";   //final type in java, in headerfile with const static 
189      }
190      sStaticDef += sTypeCode;
191      //sStaticDef += sTypeClassIdent + (kind=='@' ? "REF " : " ") + sName + "_" + sClassNameWithout_s;
192      sStaticDef += " " + sName + "_" + sClassNameWithout_s;
193      for(int dimension1 = 0; dimension1 < staticVariable.identInfos.getDimensionArray(); dimension1++)
194      { final String sDimension = staticVariable.identInfos.fixArraySizes == null ? null
195                                : staticVariable.identInfos.fixArraySizes[dimension1];
196        sStaticDef += "[" + ( sDimension == null ? "" : sDimension) + "]"; 
197      }
198      
199      if(staticVariable.zbnfInit == null)
200      { //no init value
201        if("@".indexOf(kind)>=0)
202        { //embedded struct or enhanced reference, null-initializing
203          sStaticDef += " = { 0, null };";
204        }
205        else if("$".indexOf(kind)>=0)
206        { //embedded struct or enhanced reference, null-initializing
207          sStaticDef += " = { 0 };";
208        }
209        else if("*".indexOf(kind)>=0)
210        { //normal reference, null-initializing
211          sStaticDef += " = null;";
212        }
213        else
214        { sStaticDef += "= 0;";
215        }
216      }
217      else
218      { if(sName.equals("intArrayStatic"))
219          stop();  //kk1
220        sStaticDef = staticQuasiBlock.gen_VariableDefWithSimpleInitValue(staticVariable.identInfos, staticVariable.zbnfInit); 
221      }
222      writeContent.writeClassC("\n" + sStaticDef);      
223    }
224    
225    
226    /**Don't write methods if it is an interface. */
227    //for(ClassData.MethodWithZbnfItem methodDef: classData.listMethodWithZbnf){ 
228    ClassData.MethodWithZbnfItem methodDef;
229    while((methodDef = classData.methodsWithZbnf.poll()) !=null){
230      //Note: The methods will be ^ed in the first-pass.  
231      if(methodDef.method.sJavaName.equals("toString"))
232        stop();
233      if(methodDef.zbnfMethod ==null || methodDef.zbnfMethod.getChild("excludeImpl") ==null){
234        if(methodDef.isConstructor())
235        { //Note: at least the default constructor is defined in the first-pass.
236          //boolean bArgumentSensitive = classData.nrofConstructor >1;
237                write_constructorDefinition(methodDef, sClassNameWithout_s); //, bArgumentSensitive);
238        }
239        else
240        { write_methodDefinition(methodDef, sClassNameWithout_s, classData.classLevelIdents);
241        }
242      }
243    }
244    
245    if(classData.isFinalizeNeed()){
246      /* NOTE: the write_finalizeDefinition() have to be called after all write_methodDefinition(),
247       * because the ClassData.zbnfFinalizeMethod is set in write_methodDefinition().
248       */
249      write_finalizeDefinition(itemClass, sClassNameWithout_s, classData.classLevelIdents);
250    }
251
252    write_Reflections();
253        
254    
255  }
256
257  
258  
259  
260  
261  
262  
263  
264  /**Writes out the reflection inclusively the method table definition.
265   * A method table isn't need if the class is either a simple data class without virtual methods
266   * or if it is an interface: The method table refers the implementation methods of the instantiation, 
267   * an interface hasn't an instantiation. 
268   */
269  void write_Reflections()
270  {  
271    String sClassNameWithout_s = classData.getClassIdentName();
272    if(sClassNameWithout_s.equals("SimpleDataStruct_Test"))
273      stop();
274    String sClassName = classData.getClassCtype_s();
275    boolean isObject;
276    //A method table isn't need if the class is a simple data class or an interface.
277    //If the class doesn't base on Object, a method table is not able to use.
278    boolean bMtbl = (classData.inheritanceInfo != null && classData.isBasedOnObject()
279         && !classData.isInterface() && !classData.isAbstract);
280    if(bMtbl){
281      writeContent.writeClassC("\n\n\n/**J2C: Reflections and Method-table *************************************************/");      
282      writeContent.writeClassC("\nconst MtblDef_" + sClassNameWithout_s + " mtbl" + sClassNameWithout_s + " = {");      
283      String content = classData.genMethodTableContent(classData.inheritanceInfo, sClassNameWithout_s, 0);
284      writeContent.writeClassC(content);
285      writeContent.writeClassC(", { signEnd_Mtbl_ObjectJc, null } }; //Mtbl\n\n");
286    }
287
288    final String referenceReflectionSuperClass;
289    final String referenceReflectionIfc;
290    //String sPathSuper;
291    final ClassData superClass = classData.getSuperClassData();
292    if(superClass != null)
293    { final String sNameSuper = superClass.getClassCtype_s();
294      //final String reflectionSuperClass = superClass == null ? null : "&reflection_";
295      final String offsetMtbl = bMtbl 
296        ? ", OFFSET_Mtbl(Mtbl_" + sClassNameWithout_s + ", " + superClass.getClassIdentName() + ")" 
297        : ", 0 /*J2C: no Mtbl*/";
298        writeContent.writeClassC("\n extern_C struct ClassJc_t const reflection_" + sNameSuper + ";");      
299      writeContent.writeClassC("\n static struct superClasses_" + sClassName + "_t");      
300      writeContent.writeClassC("\n { ObjectArrayJc head;");      
301      writeContent.writeClassC("\n   ClassOffset_idxMtblJc data[1];");      
302      writeContent.writeClassC("\n }superclasses_" + sClassName + " =");      
303      writeContent.writeClassC("\n { CONST_ObjectArrayJc(ClassOffset_idxMtblJc, 1, OBJTYPE_ClassOffset_idxMtblJc, null, null)");      
304      writeContent.writeClassC("\n , { {&reflection_" + sNameSuper + offsetMtbl + " }");      
305      writeContent.writeClassC("\n   }");      
306      writeContent.writeClassC("\n };\n");      
307      referenceReflectionSuperClass = "(ClassOffset_idxMtblJcARRAY*)&superclasses_" + sClassName;
308      isObject = classData.isBasedOnObject();
309    }
310    else
311    { referenceReflectionSuperClass = "null";
312      isObject = false;
313    }
314
315    final ClassData[] ifcs = classData.getInterfaces();
316    if(ifcs  != null)
317    { for(ClassData ifc: ifcs){
318        final String sNameIfc = ifc.getClassCtype_s();
319        writeContent.writeClassC("\n extern_C struct ClassJc_t const reflection_" + sNameIfc + ";");      
320      }
321      writeContent.writeClassC("\n static struct ifcClasses_" + sClassName + "_t");      
322      writeContent.writeClassC("\n { ObjectArrayJc head;");      
323      writeContent.writeClassC("\n   ClassOffset_idxMtblJc data[" + ifcs.length + "];");      
324      writeContent.writeClassC("\n }interfaces_" + sClassName + " =");      
325      writeContent.writeClassC("\n { CONST_ObjectArrayJc(ClassOffset_idxMtblJc, 1, OBJTYPE_ClassOffset_idxMtblJc, null, null)");      
326      String sSep = "\n, {";
327      for(ClassData ifc: ifcs){
328        final String sNameIfc = ifc.getClassCtype_s();
329        writeContent.writeClassC(sSep+ " {&reflection_" + sNameIfc + ", OFFSET_Mtbl(Mtbl_" + sClassNameWithout_s + ", " + ifc.getClassIdentName() + ") }");      
330        sSep = "\n  ,";
331      }
332      writeContent.writeClassC("\n  }");      
333      writeContent.writeClassC("\n};\n");      
334      referenceReflectionIfc = "(ClassOffset_idxMtblJcARRAY*)&interfaces_" + sClassName;
335      isObject = classData.isBasedOnObject();
336    }
337    else
338    { referenceReflectionIfc = "null";
339      isObject = false;
340    }
341
342    final String sFieldReference;
343    //if(classData.classLevelIdentsOwn != null && classData.classLevelIdentsOwn.size() >0)
344    int nrofReflectionField = 0;
345    if(classData.classLevelIdentsOwn != null) 
346    { for(FieldData field: classData.classLevelIdentsOwn)
347      { if(field.modeStatic != 'd')  //defines not.
348        { nrofReflectionField +=1; }
349      }
350    }  
351    
352    if(nrofReflectionField >0)
353    { sFieldReference = "(FieldJcArray const*)&reflection_Fields_" + sClassName;
354      writeContent.writeClassC("\nextern_C struct ClassJc_t const reflection_" + sClassName + ";");      
355      Collection<ClassData> types = classData.classLevelUsageTypes.values();
356      for(ClassData type : types)
357      { if(!type.isPrimitiveType())
358        writeContent.writeClassC("\nextern_C struct ClassJc_t const reflection_" + type.sClassNameC + ";");      
359      }
360      writeContent.writeClassC("\nconst struct Reflection_Fields_" + sClassName + "_t");      
361      writeContent.writeClassC("\n{ ObjectArrayJc head; FieldJc data[" + nrofReflectionField + "];");      
362      writeContent.writeClassC("\n} reflection_Fields_" + sClassName + " =");      
363      writeContent.writeClassC("\n{ CONST_ObjectArrayJc(FieldJc, " + nrofReflectionField + ", OBJTYPE_FieldJc, null, &reflection_Fields_" + sClassName + ")");      
364      writeContent.writeClassC("\n, {");
365      char cSeparator = ' ';
366      for(FieldData field: classData.classLevelIdentsOwn)
367      { if(field.getName().equals("object"))
368          stop();
369        if(field.modeStatic != 'd')  //defines not.
370        {
371          int dimensionArray = field.getDimensionArray();
372          //if(field.)
373          if(field.getName().equals("constString"))
374            stop();
375          writeContent.writeClassC("\n   " + cSeparator + " { \"" + field.getName() + "\"");
376          if(field.getDimensionArray() ==0){
377                writeContent.writeClassC("\n    , 0 //nrofArrayElements"); //dimensionArray ==0");
378          } else {
379                writeContent.writeClassC("\n    , " + (field.fixArraySizes == null ? "0" : field.fixArraySizes[0]) + " //nrofArrayElements");
380          }
381          { final char modeElement;
382            final String sModeContainerReference;
383            if(dimensionArray > 0)  //TODO also on List<Type> etc.
384            { modeElement = field.modeArrayElement;
385              switch(field.modeAccess)
386              { case 'P': case 'X': case '*': sModeContainerReference = "|kReferencedContainer_Modifier_reflectJc "; break;
387                case 'Y': case '$': sModeContainerReference = "|kEmbeddedContainer_Modifier_reflectJc "; break; 
388                case '@':
389                case 't':
390                case 'M': sModeContainerReference = "|kPtrVal_Modifier_reflectJc "; break;
391                case '&': sModeContainerReference = "|kEnhancedRefContainer_Modifier_reflectJc "; break; 
392                case 'Q':
393                case '%': sModeContainerReference = ""; break;
394                default: throw new IllegalArgumentException("illegal FieldData.modeAccess: " + field.modeAccess);
395              }
396            }
397            else
398            { modeElement = field.modeAccess;
399              sModeContainerReference = "";
400            }
401            if(field.typeClazz.isPrimitiveType())
402            { int nrofBytes;
403              switch(field.typeClazz.cVaArgIdent)
404              { case 'Z': nrofBytes = 4; break;
405                case 'B': nrofBytes = 1; break;
406                case 'S': nrofBytes = 2; break;
407                case 'J': nrofBytes = 8; break;
408                case 'D': nrofBytes = 8; break;
409                default: nrofBytes = 4;
410              }
411              if(field.typeClazz == CRuntimeJavalikeClassData.clazz_s0)
412              { writeContent.writeClassC("\n    , REFLECTION_char");
413                writeContent.writeClassC("\n    , mReference_Modifier_reflectJc");
414              }
415              else
416              {
417                writeContent.writeClassC("\n    , REFLECTION_" + field.getTypeName());
418                writeContent.writeClassC("\n    , " + nrofBytes + " << kBitPrimitiv_Modifier_reflectJc ");
419              }
420              //TODO arrays of primitives, now showing as simple primitive.
421            }
422            else
423            { writeContent.writeClassC("\n    , &reflection_" + field.getTypeName());
424              final String sModeElement;
425              switch(modeElement)
426              { case '*': sModeElement = "kReference_Modifier_reflectJc "; break;
427                case '$': sModeElement = "kEmbedded_Modifier_reflectJc "; break; 
428                case '@':
429                case 't':
430                case '&': sModeElement = "kEnhancedReference_Modifier_reflectJc /*" + modeElement + "*/ "; break; 
431                case '%': sModeElement = "0"; break;
432                default: throw new IllegalArgumentException("illegal modeElement: " + modeElement);
433              }
434              writeContent.writeClassC("\n    , " + sModeElement); 
435              
436              ClassData fieldSuperClass = field.typeClazz; 
437              //search the last superclass, may be ObjectJc:
438              while(fieldSuperClass != null && fieldSuperClass != field.typeClazz.getSuperClassData())
439              { fieldSuperClass = fieldSuperClass.getSuperClassData();
440              }
441              if(fieldSuperClass == CRuntimeJavalikeClassData.clazzObjectJc)
442              { writeContent.writeClassC("|mObjectJc_Modifier_reflectJc ");
443              }
444              
445            }
446            
447            if(field.fixArraySizes!=null){ writeContent.writeClassC("|kStaticArray_Modifier_reflectJc "); }
448            else if(field.getDimensionArray() == 1){ writeContent.writeClassC("|kObjectArrayJc_Modifier_reflectJc "); }
449            
450            if("sS".indexOf(field.modeStatic)>=0){ writeContent.writeClassC("|mSTATIC_Modifier_reflectJc "); }
451            
452            writeContent.writeClassC(sModeContainerReference + "//bitModifiers");
453          }   
454          //offsetToObjectifcBase
455          if("sS".indexOf(field.modeStatic)>=0)
456          {
457            writeContent.writeClassC("\n    , 0 //compiler problem, not a constant,TODO: (int16)(&" + field.getName() + "_" + field.declaringClazz.getClassIdentName()
458                + ") //lo part of memory address of static member");
459            writeContent.writeClassC("\n    , 0 //compiler problem, not a constant,TODO: (int16)((int32)(&" + field.getName() + "_" + field.declaringClazz.getClassIdentName()
460                + ")>>16) //hi part of memory address of static member instead offsetToObjectifcBase, TRICKY because compatibilty.");
461          }
462          else
463          {
464            writeContent.writeClassC("\n    , (int16)((int32)(&((" + sClassName + "*)(0x1000))->" + field.getName()
465                + ") - (int32)(" + sClassName + "*)0x1000)");  //offset calculated by C-compiler
466            writeContent.writeClassC("\n    , 0  //offsetToObjectifcBase");
467          
468          }
469          writeContent.writeClassC("\n    , &reflection_" + sClassName);
470          writeContent.writeClassC("\n    }");
471          cSeparator = ',';
472        }
473      }
474      writeContent.writeClassC("\n} };");
475    }
476    else{ sFieldReference = "null //attributes and associations"; }
477    
478    final String sClassNameReflection;
479    if(sClassName.length() > 28)
480    { int len = sClassName.length();
481      sClassNameReflection = sClassName.substring(0, 18) + "_" + sClassName.substring(len-9, len);
482    }
483    else
484    { sClassNameReflection = sClassName;
485    }
486    writeContent.writeClassC("\nconst ClassJc reflection_" + sClassName + " = ");      
487    writeContent.writeClassC("\n{ CONST_ObjectJc(OBJTYPE_ClassJc + sizeof(ClassJc), &reflection_ObjectJc, &reflection_ClassJc) ");      
488    writeContent.writeClassC("\n, \"" + sClassNameReflection + "\"");      
489    if(isObject)
490    { writeContent.writeClassC("\n, (int16)((int32)(&((" + sClassName + "*)(0x1000))->base.object"
491          + ") - (int32)(" + sClassName + "*)0x1000)");  //offset calculated by C-compiler
492      
493    }
494    else
495    { writeContent.writeClassC("\n,  0 //position of ObjectJc");      
496    }
497    writeContent.writeClassC("\n, sizeof(" + sClassName + ")");      
498    writeContent.writeClassC("\n, " + sFieldReference);      
499    writeContent.writeClassC("\n, null //method");      
500    writeContent.writeClassC("\n, " + referenceReflectionSuperClass + " //superclass");      
501    writeContent.writeClassC("\n, " + referenceReflectionIfc + " //interfaces");      
502    writeContent.writeClassC("\n, " + (isObject ? "mObjectJc_Modifier_reflectJc" : "0    //modifiers"));      
503    if(bMtbl){
504      writeContent.writeClassC("\n, &mtbl" + sClassNameWithout_s + ".mtbl.head");      
505    }
506    writeContent.writeClassC("\n};\n");      
507  }
508  
509  
510  
511  
512  
513  /**writes a constructor definition as C-method into the C-File.
514   * The interface-method {@link iWriteContent#writeClassC(String)} is used to do it.
515   * The content isn't written directly in the file, because some include-lines 
516   * generated while running any methods and constructors of second pass should be written
517   * before the text of this method.
518   * <br>
519   * Inside it is written and called:<ul>
520   * <li><code>MemC rawMem</code> as first and <code>ThCxt* _thCxt</code>
521   *   as last argument of constructor head.
522   * <li>{@link gen_variableDefinition(ZbnfParseResultItem, LocalIdents, List, char intension)}
523   *   to generate the arguments of the constructor, in Java2C.zbnf <code>< argumentList></code>
524   *   and <code>< argument></code>
525   * <li><code>{  StacktraceJc stacktrace...</code>-expressions.  
526   * <li>Test of size of rawMem, RuntimeException if it is to less.
527   * <li><code>memset(thiz, 0, sizeof(*thiz));</code> of the used mem area of the class (C-struct).
528   *   Like in Java all class elements of this instance are set to zero in default.
529   * <li>call of super constructors or call of <code>ctorc_ObjectJc(rawMem);</code>
530   * <li><code>setReflection_ObjectJc(...)</code> to set reflection and jump table infos for the instance.       
531   * <li>call of constructor of all initialized references and especially embedded instances.  
532   * <li>{@link StatementBlock#gen_value(ZbnfParseResultItem, ClassData[], LocalIdents, char)}
533   *   to generate the initial value assignment of class variable. The list {@link ClassData.variablesToInit}
534   *   of the {@link classData} is used to get all variables to initialze. That list elements contain
535   *   the reference to the parse result item elements of parsed initial values in Java code.
536   * <li>{@link StatementBlock#gen_statementBlock(ZbnfParseResultItem, int, LocalIdents)}
537   *   is used to generate the statement block of the constructor.  
538   * </ul>
539   * While generating the constructor it is possible that a type is used inside, which is unknown yet.
540   * Than an include is generated. Because the internal structure of the type should be known,
541   * the parsing of the Java Code and the run of its first pass is processed while running the method generation.
542   * The second pass of this file is running later. This actions are done using 
543   * {@link RunRequiredFirstPass_ifc#runRequestedFirstPass(String)}.
544   *  
545   * @param itemConstructor Parse result of <code>constructorDefinition::=...</code>
546   *        If it is null, than this method is used to create a default constructor with all initializations.
547   * @param sClassName Full Name of the class in C-Style where the constructor is member of.
548   *        The class name is used as return type and as C-methodidentifier-postfix. 
549   * @throws IOException
550   * @throws ParseException
551   * @throws InstantiationException 
552   * @throws IllegalAccessException 
553   * @throws IllegalArgumentException 
554   */
555  private void write_constructorDefinition
556  ( ClassData.MethodWithZbnfItem methodDef
557  , String sClassName
558  //, boolean bArgumentSensitive
559  )
560  throws IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
561  { //LocalIdents localIdents = new LocalIdents(classData.classLevelIdents);
562    String sDeclaringClassIdentName = classData.getClassIdentName();
563    assert(sClassName.equals(sDeclaringClassIdentName));
564    //String sClassName_s = classData.getClassCtype_s();
565    boolean isBasedOnObject = classData.isBasedOnObject();
566    ZbnfParseResultItem zbnfConstructor = methodDef.zbnfMethod;
567    //StatementBlock statementBlockCtorFrame = new StatementBlock(new LocalIdents(classData.classLevelIdents, null), true);
568    StatementBlock statementBlockCtorFrame = new StatementBlock(this, methodDef.method.getMethodIdents(), true, false, 1);
569
570    if(sClassName.equals("ReadTargetFromText"))
571      stop();
572    
573    /**Generate the body. */
574    final StringBuilder uBody = new StringBuilder(10000);
575    final String sLine_mtthis;
576    bUse_mtthis = false;
577    if(zbnfConstructor != null){
578      /**NOTE: first generate the body, because the bUse_mtthis may be set. */
579      uBody.append(StatementBlock.gen_statementBlock(zbnfConstructor, null, 1, statementBlockCtorFrame, classData.classTypeInfo, this, 'c'));  //it is a statementBlock
580    } else {
581      uBody.append("/*J2C:No body for constructor*/\n");
582    }
583    if(bUse_mtthis){
584      sLine_mtthis = "\n  Mtbl_" + sDeclaringClassIdentName + " const* mtthis = &mtbl" + sDeclaringClassIdentName + ".mtbl;";
585    } else {
586      sLine_mtthis = "";
587    }
588    StringBuilder uContent = new StringBuilder(10000);
589    writeContent.writeClassC("\n\n/*Constructor */");
590    if(zbnfConstructor == null)
591    { writeContent.writeClassC("/**J2C: autogenerated as default constructor. */");
592    }
593    //NOTE: is part of gen_methodHead(): else { writeContent.writeClassC("/**" + get_description(itemConstructor) + "*/"); }
594      
595    //Method method = gen_methodHead(itemConstructor, classData, "ctorO", statementBlockCtorFrame.localIdents, classData.classTypeInfo, bArgumentSensitive, 'c'); 
596    //String sMethodHead = method.getMethodHeadDefiniton();
597    writeContent.writeClassC("\n" + methodDef.method.gen_MethodHeadDefinition()); //sMethodHead);
598
599    if(isBasedOnObject)
600    { writeContent.writeClassC("\n{ " + sClassName + "_s* thiz = (" + sClassName + "_s*)othis;  //upcasting to the real class.");
601      //writeContent.writeClassC("\n  int sizeObj = getSizeInfo_ObjectJc(othis);");
602      //writeContent.writeClassC("\n  extern ClassJc const reflection_" + sClassName + "_s;");
603      writeContent.writeClassC(sLine_mtthis); //may be empty
604      writeContent.writeClassC("\n  STACKTRC_TENTRY(\"ctorO_" + sClassName + "\");");
605  
606      //TODO: super(xyz)
607      writeContent.writeClassC("\n  checkConsistence_ObjectJc(othis, sizeof(" + sClassName + "_s), null, _thCxt);  ");
608    }
609    else
610    { writeContent.writeClassC("\n{ " + sClassName + "_s* thiz = PTR_MemC(mthis, " + sClassName + "_s);  //reference casting to the real class.");
611      writeContent.writeClassC("\n  int sizeObj = size_MemC(mthis);");
612      writeContent.writeClassC(sLine_mtthis); //may be empty
613      writeContent.writeClassC("\n  STACKTRC_TENTRY(\"ctor_" + sClassName + "\");");
614      writeContent.writeClassC("\n  if(sizeof(" + sClassName + "_s) > sizeObj) THROW_s0(IllegalArgumentException, \"faut size\", sizeObj);");
615    }
616    /**Super call*/
617    { ClassData superClass = classData.getSuperClassData();
618      if(superClass != null && superClass != CRuntimeJavalikeClassData.clazzObjectJc){
619        final String nameCtor = classData.isBasedOnObject()?  "ctorO" : "ctorM";
620        ZbnfParseResultItem zbnfSuperCall = zbnfConstructor == null ? null : zbnfConstructor.getChild("superCall");
621        CCodeData ccode;
622        StringBuilder uSuperCtor = new StringBuilder(4000);
623        if(zbnfSuperCall != null){
624          stop();
625          ccode = statementBlockCtorFrame.gen_InternalMethodCall(zbnfSuperCall, null, zbnfConstructor, nameCtor, superClass, null, classData.ctorCodeInfo.cCode); //, superClass.classLevelIdents);
626          uSuperCtor.append(ccode.cCode);
627        } else if(methodDef.supermethod != null){
628                //In anonymous classes, the super constructor should be called with the values of param.
629                //The user writes new SuperType(param){....}
630                
631                uSuperCtor.append(methodDef.supermethod.sCName).append("(");
632                uSuperCtor.append("&thiz->base.object");
633                if(methodDef.supermethod.paramsType !=null){
634                        for(FieldData param: methodDef.supermethod.paramsType){
635                                uSuperCtor.append(", ").append(param.getName());
636                } }
637                if(methodDef.supermethod.need_thCxt){
638                        uSuperCtor.append(", _thCxt)");  
639          } else {
640                uSuperCtor.append(")");  
641          }
642        }
643
644        else {
645          /**Call the default constructor: */
646          ccode = statementBlockCtorFrame.gen_InternalMethodCall(null, null, zbnfConstructor, nameCtor, superClass, null, classData.ctorCodeInfo.cCode); //, superClass.classLevelIdents);
647          uSuperCtor.append(ccode.cCode);
648        }
649        writeContent.writeClassC("\n  //J2C:super Constructor\n  ");
650        uSuperCtor.append(";");
651        writeContent.writeClassC(uSuperCtor.toString());
652      }  
653    }  
654    if(isBasedOnObject) {
655      /**Sets the reflection after call of super constructor, because the super constructor sets it also, but to super class. */
656      writeContent.writeClassC("\n  setReflection_ObjectJc(othis, &reflection_" + sClassName + "_s, sizeof(" + sClassName + "_s));  ");
657    }
658    if(classData.isNonStaticInner){
659        writeContent.writeClassC("\n  thiz->outer = outer;");
660    }
661    /**Initialize all class variables. */
662    String sAllInit= "";
663    writeContent.writeClassC("\n  //j2c: Initialize all class variables:\n  {");
664    for(ClassData.InitInfoVariable variableToInit : classData.getVariablesToInit())
665    { 
666      String sName = variableToInit.identInfos.getName();
667      if(sName.equals("timeOpen"))
668        stop();
669      if("sSd".indexOf(variableToInit.identInfos.modeStatic)<0)  //don't regard static variable here!
670      {
671        ClassData[] typeValue1 = new ClassData[1];  //classData of the part of expression
672        CCodeData cVariableToInit = new CCodeData("thiz->" + sName, variableToInit.identInfos);
673        if(cVariableToInit.cCode.equals("thiz->main2"))
674          stop();  //kk1
675        String cInit = statementBlockCtorFrame.gen_assignValue(cVariableToInit, "=", typeValue1, variableToInit.zbnfInit, null, zbnfConstructor, 3, classData.classLevelIdents, 'i');
676        sAllInit += "\n    " + cInit + ";";
677      }      
678    }      
679    writeContent.writeClassC(statementBlockCtorFrame.gen_NewObjReferences(2));
680    writeContent.writeClassC(statementBlockCtorFrame.gen_TempStringBufferReferences(2));
681    writeContent.writeClassC(statementBlockCtorFrame.gen_persistringVarDefinitions(2));
682    writeContent.writeClassC(statementBlockCtorFrame.gen_TempRefs(2));
683    writeContent.writeClassC(sAllInit);
684    writeContent.writeClassC(statementBlockCtorFrame.gen_ActivateGarbageCollection(2, false, null));
685    writeContent.writeClassC("\n  }");
686    
687    /**Writes the body. */
688    writeContent.writeClassC(uBody.toString());
689    writeContent.writeClassC("\n  STACKTRC_LEAVE;");
690    writeContent.writeClassC("\n  return thiz;\n}\n\n");
691  }
692
693  
694  
695  
696  public void write_finalizeDefinition
697  ( ZbnfParseResultItem zbnfClass
698  , String sClassName
699  , LocalIdents idents
700  ) throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
701  { String sClearRef = "";
702    /*
703        List<ZbnfParseResultItem> listVariables = zbnfClass.listChildren("variableDefinition");
704    if(listVariables != null)for(ZbnfParseResultItem zbnfVariable : listVariables)
705    { if(zbnfVariable.getChild("static")== null)
706      { //only non static members.
707        String sName = zbnfVariable.getChild("variableName").getParsedString();
708        if(sName.equals("msg"))
709          stop();
710        //ZbnfParseResultItem itemType = zbnfVariable.getChild("typeIdent");
711        FieldData identInfo = idents.get(sName);
712        char cModifier = identInfo.modeAccess;      
713        if("@&".indexOf(cModifier) >=0)
714        { //it is a reference, generate the test and clearBackRefJc
715          //writeContent.writeClassC("\n  if(thiz->" + sName + ".ref != null) clearBackRefJc(&(thiz->" + sName + ".refbase));");
716          sClearRef += "\n  CLEAR_REFJc(thiz->" + sName + ");";
717        }
718      }  
719    }
720    */
721    StringBuilder uClearRef = new StringBuilder(1000);
722    for(FieldData field: classData.classLevelIdentsOwn){
723        final String sName = field.getName();
724                if(field.modeStatic == '.' && field.modeAccess == '@'){ //only for non-static enhanced refs:
725                uClearRef.append("  CLEAR_REFJc(thiz->").append(sName).append(");\n");
726        }
727        if(field.modeStatic == '.' && field.modeAccess == '$'){ //non-static embedded instance
728                ClassData typeClazz = field.typeClazz;
729                while(typeClazz != null && !typeClazz.isFinalizeNeed()){
730                        typeClazz = typeClazz.getSuperClassData();
731                }
732                if(typeClazz != null){
733                        final String sTypeName = typeClazz.getClassIdentName();
734                        uClearRef.append("  finalize_").append(sTypeName).append("_F(&thiz->")
735                          .append(sName);
736                        if(field.modeArrayElement == 'B'){  //StringBuilder with fix buffer following
737                                uClearRef.append(".sb");
738                }
739                        if(field.typeClazz.isBasedOnObject()){
740                                uClearRef.append(".base.object");
741                        }
742                        uClearRef.append(", _thCxt); //J2C: finalizing the embedded instance.\n");
743                }
744        }
745    }
746    //superclass-finalizing:
747    final ClassData superclass = classData.getSuperClassData();
748    if(superclass != null && superclass.isFinalizeNeed()){
749            final String sNameSuperclass = superclass.getClassIdentName();
750            uClearRef.append("  finalize_").append(sNameSuperclass).append("_F(");
751            if(superclass.isBasedOnObject() || superclass == CRuntimeJavalikeClassData.clazzObjectJc){
752                                uClearRef.append("&thiz->base.object");
753                        } else {
754                                uClearRef.append("&thiz->base.super");
755                        }
756                uClearRef.append(", _thCxt); //J2C: finalizing the superclass.\n");
757    }
758          //
759    { /**Only if the finalize method has any content, it should be written: */  
760      String sClassCtype_s = classData.getClassCtype_s();
761      String sClassIdent = classData.getClassIdentName();
762      sMethodNameCurrent = "finalize_" + sClassIdent + "_F";
763      if(sClassIdent.equals("SetValueGenerator"))
764        stop();
765      writeContent.writeClassC("\n\n" + "void " + sMethodNameCurrent);
766      if(classData.isBasedOnObject()){
767        writeContent.writeClassC("(ObjectJc* othis, ThCxt* _thCxt)\n");
768        writeContent.writeClassC("{ " + sClassCtype_s + "* thiz = (" + sClassCtype_s + "*)othis;  //upcasting to the real class.\n ");
769      } else {
770        writeContent.writeClassC("(" + sClassIdent + "_s* thiz, ThCxt* _thCxt)\n{ ");
771      }
772      writeContent.writeClassC("STACKTRC_TENTRY(\"" + sMethodNameCurrent + "\");\n");
773      if(classData.getBodyForFinalize() != null)
774      { ZbnfParseResultItem itemBody = classData.getBodyForFinalize().getChild("methodbody");
775        if(itemBody != null)
776        { String sBody = StatementBlock.gen_statementBlock(itemBody, null, 1, null, CRuntimeJavalikeClassData.clazz_void.classTypeInfo, this, 'f');  //it is a statementBlock
777          writeContent.writeClassC(sBody);
778        }
779      }
780      writeContent.writeClassC(uClearRef);  
781      { writeContent.writeClassC("  STACKTRC_LEAVE;\n");
782      }
783      writeContent.writeClassC("}\n\n");
784    }     
785  }
786  
787  
788  
789  
790  
791  
792
793  /**writes a method definition as C-method into the C-File.
794   * The interface-method {@link iWriteContent#writeClassC(String)} is used to do it.
795   * The content isn't written directly in the file, because some include-lines 
796   * generated while running any methods and constructors of second pass should be written
797   * before the text of this method.
798   * <br>
799   * Inside it is written or called:<ul>
800   * <li><code>Type* thiz</code> as first and <code>ThCxt* _thCxt</code>
801   *   as last argument of method head.  
802   * <li>{@link gen_variableDefinition(ZbnfParseResultItem, LocalIdents, List, char intension)}
803   *   to generate the arguments of the constructor, in Java2C.zbnf <code>< argumentList></code>
804   *   and <code>< argument></code>
805   * <li><code>{  StacktraceJc stacktrace...</code>-expressions.  
806   * <li>{@link StatementBlock#gen_statementBlock(ZbnfParseResultItem, int, LocalIdents)}
807   *   is used to generate the statement block of the constructor.  
808   * </ul>
809   * While generating the method it is possible that a type is used inside, which is unknown yet.
810   * Than an include-line is generated. Because the internal structure of the type should be known,
811   * the parsing of the Java Code and the run of its first pass is processed while running the method generation.
812   * The second pass of this file is running later. This actions are done using 
813   * {@link RunRequiredFirstPass_ifc#runRequestedFirstPass(String)}.
814   *  
815   * @param parent Parse result of <code>methodDefinition::=...</code>
816   * @param sClassName Full Name of the class in C-Style where the method is member of.
817   *        The class name is used as thiz-type and as C-method-identifier-postfix. 
818   * @throws IOException
819   * @throws ParseException
820   * @throws InstantiationException 
821   * @throws IllegalAccessException 
822   * @throws IllegalArgumentException 
823   */
824  public void write_methodDefinition
825  ( ClassData.MethodWithZbnfItem methodDef
826  , String sClassName
827  , LocalIdents parentIdents
828  )
829  throws IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
830  { ZbnfParseResultItem zbnfMethod = methodDef.zbnfMethod;
831    //A statement block as frame for the whole method, especially the formal arguments are localIdents of it:
832    //StatementBlock statementBlockMethodFrame = new StatementBlock(new LocalIdents(classData.classLevelIdents,null), true);
833    StatementBlock statementBlockMethodFrame = new StatementBlock(this, methodDef.method.getMethodIdents(), true, false, 1);
834    //LocalIdents localIdents = new LocalIdents(classData.classLevelIdents);
835    this.sMethodNameCurrent = methodDef.method.sImplementationName;  //used for STACKTRC_ENTRY.
836    assert(classData == methodDef.method.declaringClass);
837    String sDeclaringClassIdentName = classData.getClassIdentName();
838    
839    this.noStacktrace = methodDef.method.noStacktrace();
840    
841    /**Return type: */
842    //ZbnfParseResultItem itemType = zbnfMethod.getChild("type");
843    //ClassData typeClazz = getType(itemType, parentIdents);
844    //String sType = typeClazz.getClassIdentName();
845    final FieldData typeClazz = methodDef.method.returnType;
846    //String sName = zbnfMethod.getChild("name").getParsedString();
847    final String sName = methodDef.method.sJavaName;
848    if(sName.equals("run"))  //NOTE: finalize Method see write_finalizeDefinition()
849      stop();
850    if(sName.equals("finalize"))  //NOTE: finalize Method see write_finalizeDefinition()
851    { //done in first pass: classData.setBodyForFinalize(zbnfMethod);
852    }
853    else
854    { 
855      ZbnfParseResultItem zbnfMethodDescription = zbnfMethod.getChild("description");
856      String sDescription = get_shortDescription(zbnfMethodDescription);
857      if(sDescription != null)
858      { writeContent.writeClassC("\n\n/**" + sDescription + "*/");
859      }
860      ZbnfParseResultItem zbnfBody = zbnfMethod.getChild("methodbody");
861      if(!classData.isInterface() && zbnfBody != null) {
862        bUse_mtthis = false;
863        final String sBody;
864        if(zbnfBody != null)
865        { /**NOTE: first generate the body, because the bUse_mtthis may be set. */
866          sBody = StatementBlock.gen_statementBlock(zbnfBody, null, 1, statementBlockMethodFrame, typeClazz, this, 'm');  //it is a statementBlock
867        }
868        else {
869          sBody = "/*J2C:No body of method given. It is abstract. */";
870          assert(false);
871        }
872        
873        writeContent.writeClassC("\n" + methodDef.method.gen_MethodHeadDefinition()); //sMethodHead);
874        writeContent.writeClassC("\n{ ");
875        if(classData != methodDef.method.firstDeclaringClass)
876        { /*the method is overridden, the reference to the instance is given as ithis, cast and test it. */
877          String sClassType_s = classData.getClassCtype_s();
878          writeContent.writeClassC(sClassType_s + "* thiz = (" + sClassType_s + "*)ithis;\n  ");
879        }
880        if(bUse_mtthis){
881          /**The method table should be prepared for this method.*/
882          String sLine = "Mtbl_" + sDeclaringClassIdentName + " const* mtthis = (Mtbl_" + sDeclaringClassIdentName 
883            + " const*)getMtbl_ObjectJc(&thiz->base.object, sign_Mtbl_" + sDeclaringClassIdentName + ");\n  ";
884          writeContent.writeClassC(sLine);
885        }
886        if(methodDef.method.need_thCxt){
887          writeContent.writeClassC("\n  STACKTRC_TENTRY(\"" + sMethodNameCurrent + "\");");
888        } else if(! noStacktrace){
889          writeContent.writeClassC("\n  STACKTRC_ENTRY(\"" + sMethodNameCurrent + "\");");
890        }
891        
892        writeContent.writeClassC("\n  ");  
893        writeContent.writeClassC(sBody);
894        
895        //if(!genBlockStatment.lastWasReturn)
896        if(! noStacktrace)
897        { writeContent.writeClassC("\n  STACKTRC_LEAVE;");
898        }
899        writeContent.writeClassC("\n}\n");
900      }
901      if(methodDef.method.isOverrideable()) {
902        String sClassIdentNameFirst = methodDef.method.firstDeclaringClass.getClassIdentName();
903        Method methodFirst = methodDef.method.primaryMethod;
904        if( methodFirst.sNameUnambiguous.equals("flush"))
905          stop();
906        /**Writes the dynamic call implementation variant: */
907        writeContent.writeClassC("\n/*J2C: dynamic call variant of the override-able method: */");
908        writeContent.writeClassC("\n" + methodDef.method.sReturnTypeDefinition + " " 
909                                + methodDef.method.sCName + methodDef.method.sMethodFormalListDefiniton);
910        final String thiz;
911        final String othis;
912        if(  methodFirst.declaringClass.isInterface() 
913          || methodFirst.declaringClass == CRuntimeJavalikeClassData.clazzObjectJc){
914          thiz = "ithis";
915          othis = "ithis";
916        }
917        else if(methodDef.method != methodFirst) {
918          /**It is a overridden method: */
919          thiz = "(" + methodFirst.declaringClass.sClassNameC + "*)" + "ithis";
920          othis = "&ithis->base.object";
921        }
922        else {
923          /** It is the first defined method: */
924          thiz = "thiz";
925          othis = "&thiz->base.object";
926        }
927        
928        writeContent.writeClassC("\n{ Mtbl_" + sClassIdentNameFirst + " const* mtbl = (Mtbl_" 
929            + sClassIdentNameFirst + " const*)getMtbl_ObjectJc(" + othis + ", sign_Mtbl_" + sClassIdentNameFirst + ");");
930        if(methodDef.method.returnType != null && methodDef.method.returnType.typeClazz != CRuntimeJavalikeClassData.clazz_void){
931          writeContent.writeClassC("\n  return ");
932        } else {
933          writeContent.writeClassC("\n  ");
934        }
935        writeContent.writeClassC("mtbl->" + methodFirst.sNameUnambiguous + "(" + thiz);
936        if(methodDef.method.paramsType != null) for(FieldData param: methodDef.method.paramsType){
937          writeContent.writeClassC(", " + param.getName());
938        }
939        if(methodDef.method.need_thCxt){ 
940          writeContent.writeClassC(", _thCxt"); 
941        }
942        writeContent.writeClassC(");");
943        writeContent.writeClassC("\n}\n");
944        
945      }
946    }  
947  }
948
949
950
951  public String gen_for_statement
952  ( final ZbnfParseResultItem zbnfStatement
953  , int indent
954  , final StatementBlock parentStatementBlock
955  //, final LocalIdents localIdentsP
956  , FieldData typeReturn
957  ) throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException  
958  { String ret = ""; //new StringBuffer();
959    //final LocalIdents localIdents;
960    ZbnfParseResultItem zbnfIteratorObject = zbnfStatement.getChild("variableDefinition");
961    final String startAssignment;
962    final StatementBlock statementBlock;
963    if(zbnfIteratorObject != null)
964    { statementBlock = new StatementBlock(parentStatementBlock);
965      statementBlock.localIdents = new LocalIdents(statementBlock.localIdents, null);  //new based on existing
966      List<ClassData.InitInfoVariable> variablesToInit1 = new LinkedList<ClassData.InitInfoVariable>();
967      CCodeData codeVariable = gen_variableDefinition(zbnfIteratorObject, null, statementBlock.localIdents, statementBlock, variablesToInit1, 'z');
968      indent +=1;
969      ret += "{ "+ codeVariable.cCode + GenerateClass.genIndent(false, indent); 
970      ClassData.InitInfoVariable variableToInit = variablesToInit1.get(0);
971      { String sName = variableToInit.identInfos.getName();
972        //String sType = variableToInit.identInfos.getTypeName();
973        ClassData[] typeValue = new ClassData[1];  //classData of the part of expression
974        final String startValue = statementBlock.gen_value(variableToInit.zbnfInit, null, zbnfStatement, typeValue
975                , statementBlock.localIdents, codeVariable.identInfo.modeStatic=='n', 'e');
976        startAssignment = sName + " = " + startValue; 
977      }          
978    }
979    else
980    { statementBlock = parentStatementBlock;
981      ZbnfParseResultItem zbnfStartAssignment = zbnfStatement.getChild("startAssignment");
982      startAssignment = statementBlock.gen_assignment(zbnfStartAssignment, null, indent+1, statementBlock.localIdents, 'b');
983    }
984    
985    ZbnfParseResultItem zbnfEndCondition = zbnfStatement.getChild("endCondition");
986    ClassData[] retTypeValue = new ClassData[1];
987    String sCondition = statementBlock.gen_value(zbnfEndCondition, null, zbnfStatement, retTypeValue, statementBlock.localIdents, true, 'e');
988    
989    final String sIteratorExpression;
990    final ZbnfParseResultItem zbnfIteratorExpression = zbnfStatement.getChild("iteratorAssignment");
991    if(zbnfIteratorExpression !=null){
992      sIteratorExpression = statementBlock.gen_assignment(zbnfIteratorExpression, null, indent, statementBlock.localIdents, 'z');
993    } else {
994        //If a iteratorAssignment isn't found, an iteratorExpression is present. See syntax.
995        //There the child is relevant for the simple value.
996        final ZbnfParseResultItem zbnfIteratorVariable = zbnfStatement.getChild("iteratorExpression").firstChild();
997      CCodeData cIterExpression = statementBlock.gen_simpleValue(zbnfIteratorVariable, null, zbnfStatement, statementBlock.localIdents, false, 'z', false);
998      sIteratorExpression = cIterExpression.cCode;
999    }
1000    //String sIteratorExpression = statementBlock.gen_value(zbnfIteratorExpression, retTypeValue, statementBlock.localIdents, 'e');
1001    
1002    ret += "for(" + startAssignment + "; "
1003        + sCondition + "; " + sIteratorExpression + ")"; // + (genIndent(indent));
1004    
1005    ZbnfParseResultItem itemWhileStatement = zbnfStatement.getChild("statement");
1006    String sStatement = itemWhileStatement != null 
1007                      ? statementBlock.gen_statement(itemWhileStatement, null, indent+1, statementBlock.localIdents, typeReturn, 'z') 
1008                      : ";";
1009    ret += sStatement;
1010    
1011    if(zbnfIteratorObject != null)
1012    { ret += genIndent(false, indent-1) + "}";
1013    }
1014    return ret;          
1015  }
1016
1017
1018  
1019  
1020
1021  void _assert(boolean cond){
1022    if(!cond)
1023      throw new RuntimeException("assertion");
1024  }
1025
1026
1027}