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}