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