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