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